diff --git a/.htaccess b/.htaccess
index a936070078e11dd48efdda9c4f5eb1d1fb9d6c32..0654970d0361d0925f2a271bf72101b1c16784c9 100644
--- a/.htaccess
+++ b/.htaccess
@@ -1,3 +1,4 @@
+Options -Indexes
 RewriteEngine On
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
diff --git a/README.md b/README.md
index 9591a34744d6c9bbe4a9af7f0d2130707f974119..99cf896e6bcc09502d53100f30415da85bded2fc 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@ For installing PHP dependencies run:
 
     composer install
 
+Install also the bcmath PHP package (used in X.509 parser).
+
 To setup the database edit scripts in the sql folder and run them:
 
     mysql -u root -p < sql/create-db-and-user.sql
diff --git a/oauth2/facebook_login.php b/auth/oauth2/facebook_login.php
similarity index 97%
rename from oauth2/facebook_login.php
rename to auth/oauth2/facebook_login.php
index e89404eddf27bfb84feb2b8b447be209348b4060..e6d59870a30602330fb5c82222bf88f889163354 100755
--- a/oauth2/facebook_login.php
+++ b/auth/oauth2/facebook_login.php
@@ -22,7 +22,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-include '../include/init.php';
+include '../../include/init.php';
 startSession();
 
 $Facebook = $AUTHENTICATION_METHODS['Facebook'];
diff --git a/oauth2/facebook_token.php b/auth/oauth2/facebook_token.php
similarity index 98%
rename from oauth2/facebook_token.php
rename to auth/oauth2/facebook_token.php
index 7e05a14fc6a7f4c0c482f6d9e2b4220076683c24..1daca05bde24a7711f9191d52f55dfdb5fa4f5e0 100755
--- a/oauth2/facebook_token.php
+++ b/auth/oauth2/facebook_token.php
@@ -22,7 +22,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-include '../include/init.php';
+include '../../include/init.php';
 startSession();
 
 $Facebook = $AUTHENTICATION_METHODS['Facebook'];
@@ -80,7 +80,7 @@ $fbUser = $response->getGraphUser();
 
 $typedId = $fbUser["id"];
 
-$user = RAP\UserHandler::findUserByIdentity(RAP\Identity::FACEBOOK, $typedId, null);
+$user = RAP\UserHandler::findUserByIdentity(RAP\Identity::FACEBOOK, $typedId);
 
 if ($user === null) {
     $user = new RAP\User();
diff --git a/oauth2/google_token.php b/auth/oauth2/google_token.php
similarity index 98%
rename from oauth2/google_token.php
rename to auth/oauth2/google_token.php
index 990ee84b9e76584665fb101b5f9342033808c364..59e9c014873c9ec099805eb38846a0b2ef91bdb5 100644
--- a/oauth2/google_token.php
+++ b/auth/oauth2/google_token.php
@@ -22,7 +22,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-include '../include/init.php';
+include '../../include/init.php';
 startSession();
 
 $Google = $AUTHENTICATION_METHODS['Google'];
@@ -74,7 +74,7 @@ if ($client->getAccessToken()) {
 
     $typedId = explode('/', $res->getResourceName())[1];
 
-    $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::GOOGLE, $typedId, null);
+    $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::GOOGLE, $typedId);
 
     if ($user === null) {
         $user = new RAP\User();
diff --git a/saml2/aai.php b/auth/saml2/aai.php
similarity index 93%
rename from saml2/aai.php
rename to auth/saml2/aai.php
index ff23b16b8e14287341a5619072017bf7d6ecadda..02a728d79af0c585b2c8e5d00ef4a45fb5d5faa0 100644
--- a/saml2/aai.php
+++ b/auth/saml2/aai.php
@@ -22,14 +22,14 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-include '../include/init.php';
+include '../../include/init.php';
 startSession();
 
 if (isset($_SERVER['Shib-Session-ID'])) {
 
     $eppn = $_SERVER['eppn'];
 
-    $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::EDU_GAIN, $eppn, null);
+    $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::EDU_GAIN, $eppn);
 
     if ($user === null) {
         $user = new RAP\User();
@@ -48,5 +48,6 @@ if (isset($_SERVER['Shib-Session-ID'])) {
 
     RAP\CallbackHandler::manageLoginRedirect($user);
 } else {
-    throw new Exception("Shib-Session-ID not found!");
+    http_response_code(500);
+    die("Shib-Session-ID not found!");
 }
diff --git a/auth/x509/certlogin.php b/auth/x509/certlogin.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2319ea6ad1dc425e51cd6f74727526668d716e1
--- /dev/null
+++ b/auth/x509/certlogin.php
@@ -0,0 +1,80 @@
+<?php
+
+/* ----------------------------------------------------------------------------
+ *               INAF - National Institute for Astrophysics
+ *               IRA  - Radioastronomical Institute - Bologna
+ *               OATS - Astronomical Observatory - Trieste
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2016 Istituto Nazionale di Astrofisica
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License Version 3 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.
+ */
+
+
+include '../../include/init.php';
+startSession();
+
+function saveUserFromX509Data($x509Data) {
+
+    global $session;
+
+    $user = new RAP\User();
+
+    $identity = new RAP\Identity(RAP\Identity::X509);
+    $identity->email = $x509Data->email;
+    $identity->name = $x509Data->name;
+    $identity->surname = $x509Data->surname;
+    $identity->typedId = $x509Data->serialNumber;
+    $identity->institution = $x509Data->institution;
+
+    $user->addIdentity($identity);
+
+    RAP\UserHandler::saveUser($user);
+
+    $session->x509DataToRegister = null;
+
+    return $user;
+}
+
+if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name !== null) {
+
+    $user = saveUserFromX509Data($session->x509DataToRegister);
+} else {
+
+    if (isset($_SERVER['SSL_CLIENT_VERIFY']) && isset($_SERVER['SSL_CLIENT_V_REMAIN']) &&
+            $_SERVER['SSL_CLIENT_VERIFY'] === 'SUCCESS' && $_SERVER['SSL_CLIENT_V_REMAIN'] > 0) {
+
+        $x509Data = RAP\X509Data::parse($_SERVER);
+
+        $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::X509, $x509Data->serialNumber);
+
+        if ($user === null) {
+
+            if ($x509Data->name === null) {
+                $session->x509DataToRegister = $x509Data;
+                $session->save();
+                header('Location: ' . $BASE_PATH . '/x509-name-surname');
+                die();
+            } else {
+                $user = saveUserFromX509Data($x509Data);
+            }
+        }
+    } else {
+        http_response_code(500);
+        die("Unable to verify client certificate");
+    }
+}
+
+RAP\CallbackHandler::manageLoginRedirect($user);
diff --git a/classes/DAO.php b/classes/DAO.php
index 713eff90539f3f46ba8add7d430c68ffb797cb68..888f66c71e0a754c3f92a9f7eead4a7b58b1679c 100644
--- a/classes/DAO.php
+++ b/classes/DAO.php
@@ -50,9 +50,8 @@ abstract class DAO {
      * Return a User object, null if nothing was found.
      * @param type $type Identity type (EDU_GAIN, X509, GOOGLE, ...)
      * @param type $identifier value used to search the identity in the database
-     * @param type $dbIdentifier identifier of the database (used only for local identities)
      */
-    public abstract function findUserByIdentity($type, $identifier, $dbIdentifier);
+    public abstract function findUserByIdentity($type, $identifier);
 
     public abstract function searchUser($searchText);
 
diff --git a/classes/Identity.php b/classes/Identity.php
index c611494dd7b1472c1bc755a70fe127c1adc159e2..e731aaba914c59c2300944b24c0af8778cc59596 100644
--- a/classes/Identity.php
+++ b/classes/Identity.php
@@ -56,11 +56,6 @@ class Identity {
      */
     public $email;
 
-    /**
-     * Unique identifier for local user database (specified in configuration file).
-     */
-    public $localDBId;
-
     /**
      * First name
      */
@@ -76,11 +71,6 @@ class Identity {
      */
     public $institution;
 
-    /**
-     * For local identities.
-     */
-    public $username;
-
     /**
      * For eduGAIN identities.
      */
diff --git a/classes/MySQLDAO.php b/classes/MySQLDAO.php
index ab2cddb174984eb907bf2a7aa2cfeac62cbd4614..d6343b2bcba89d101b566fb8dd0a44cb4a8b632d 100644
--- a/classes/MySQLDAO.php
+++ b/classes/MySQLDAO.php
@@ -42,11 +42,11 @@ class MySQLDAO extends DAO {
         global $log;
 
         $dbh = $this->getDBHandler();
-        $stmt = $dbh->prepare("INSERT INTO login_token (token, data) VALUES(:token, :data)");
+        $stmt = $dbh->prepare("INSERT INTO login_token (token, user_id) VALUES(:token, :user_id)");
 
         $params = array(
             ':token' => $token,
-            ':data' => $userId
+            ':user_id' => $userId
         );
 
         if ($stmt->execute($params)) {
@@ -61,13 +61,13 @@ class MySQLDAO extends DAO {
 
         $dbh = $this->getDBHandler();
 
-        $stmt = $dbh->prepare("SELECT data FROM login_token WHERE token = :token AND CURRENT_TIMESTAMP < TIMESTAMPADD(MINUTE,1,creation_time)");
+        $stmt = $dbh->prepare("SELECT user_id FROM login_token WHERE token = :token AND CURRENT_TIMESTAMP < TIMESTAMPADD(MINUTE,1,creation_time)");
         $stmt->bindParam(':token', $token);
 
         $stmt->execute();
 
         foreach ($stmt->fetchAll() as $row) {
-            return $row['data'];
+            return $row['user_id'];
         }
 
         return null;
@@ -86,8 +86,8 @@ class MySQLDAO extends DAO {
 
         $dbh = $this->getDBHandler();
 
-        $stmt = $dbh->prepare("INSERT INTO identity(`user_id`, `type`, `email`, `name`, `surname`, `institution`, `username`, `local_db_id`, `typed_id`, `eppn`)"
-                . " VALUES(:user_id, :type, :email, :name, :surname, :institution, :username, :local_db_id, :typed_id, :eppn)");
+        $stmt = $dbh->prepare("INSERT INTO identity(`user_id`, `type`, `email`, `name`, `surname`, `institution`, `typed_id`, `eppn`)"
+                . " VALUES(:user_id, :type, :email, :name, :surname, :institution, :typed_id, :eppn)");
 
         $stmt->bindParam(':user_id', $userId);
         $stmt->bindParam(':type', $identity->type);
@@ -95,8 +95,6 @@ class MySQLDAO extends DAO {
         $stmt->bindParam(':name', $identity->name);
         $stmt->bindParam(':surname', $identity->surname);
         $stmt->bindParam(':institution', $identity->institution);
-        $stmt->bindParam(':username', $identity->username);
-        $stmt->bindParam(':local_db_id', $identity->localDBId);
         $stmt->bindParam(':typed_id', $identity->typedId);
         $stmt->bindParam(':eppn', $identity->eppn);
 
@@ -122,11 +120,9 @@ class MySQLDAO extends DAO {
         $identity->id = $row['id'];
         $identity->typedId = $row['typed_id'];
         $identity->email = $row['email'];
-        $identity->localDBId = $row['local_db_id'];
         $identity->name = $row['name'];
         $identity->surname = $row['surname'];
         $identity->institution = $row['institution'];
-        $identity->username = $row['username'];
         $identity->eppn = $row['eppn'];
 
         return $identity;
@@ -140,7 +136,7 @@ class MySQLDAO extends DAO {
 
         $dbh = $this->getDBHandler();
 
-        $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `local_db_id`, `name`, `surname`, `institution`, `username`, `eppn`"
+        $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`"
                 . " FROM identity WHERE user_id = :user_id");
 
         $stmt->bindParam(':user_id', $userId);
@@ -169,29 +165,20 @@ class MySQLDAO extends DAO {
         return $user;
     }
 
-    public function findUserByIdentity($type, $identifier, $dbIdentifier) {
+    public function findUserByIdentity($type, $identifier) {
 
         $dbh = $this->getDBHandler();
 
         $query = "SELECT user_id FROM identity WHERE type = :type AND typed_id = :typed_id";
-        if (isset($dbIdentifier) && $dbIdentifier !== null) {
-            $query .= " AND local_db_id = :local_db_id";
-        }
 
         $stmt = $dbh->prepare($query);
         $stmt->bindParam(':type', $type);
         $stmt->bindParam(':typed_id', $identifier);
-        if (isset($dbIdentifier) && $dbIdentifier !== null) {
-            $stmt->bindParam(':local_db_id', $dbIdentifier);
-        }
 
         $stmt->execute();
 
         $result = $stmt->fetchAll();
 
-        global $log;
-        $log->debug("count = " . count($result));
-
         if (count($result) === 0) {
             return null;
         }
@@ -209,7 +196,7 @@ class MySQLDAO extends DAO {
 
         // TODO: Add additional email search...
 
-        $query = "SELECT `user_id`, `id`, `type`, `typed_id`, `email`, `local_db_id`, `name`, `surname`, `institution`, `username`, `eppn`"
+        $query = "SELECT `user_id`, `id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`"
                 . " FROM identity WHERE `email` LIKE :email OR `name` LIKE :name OR `surname` LIKE :surname";
 
         $stmt = $dbh->prepare($query);
@@ -223,15 +210,9 @@ class MySQLDAO extends DAO {
 
         $userMap = array();
 
-        //global $log;
-        //$log->debug('In searchUser');
-
         foreach ($stmt->fetchAll() as $row) {
 
-            //$log->debug($row['user_id']);
-
             $identity = $this->getIdentityByRow($row);
-            //$log->debug(json_encode($identity));
 
             $userId = $row['user_id'];
             if (array_key_exists($userId, $userMap)) {
diff --git a/classes/SessionData.php b/classes/SessionData.php
index b2a885ea5f9529bf29c597bf4f7af44010c84dfc..cc578f21031ade8cfaf4e26ee6242c5942830fe6 100644
--- a/classes/SessionData.php
+++ b/classes/SessionData.php
@@ -30,6 +30,7 @@ class SessionData {
     private $callbackTitle;
     public $user;
     public $userSearchResults;
+    public $x509DataToRegister;
 
     public function save() {
         $_SESSION['SessionData'] = $this;
diff --git a/classes/UserHandler.php b/classes/UserHandler.php
index 27223bb3fbc760e1d8484e052e0897696d940eab..58c046248fbd838b53953d33187f3237f5d36714 100644
--- a/classes/UserHandler.php
+++ b/classes/UserHandler.php
@@ -47,9 +47,9 @@ class UserHandler {
         }
     }
 
-    public static function findUserByIdentity($type, $identifier, $dbIdentifier) {
+    public static function findUserByIdentity($type, $identifier) {
 
-        return DAO::get()->findUserByIdentity($type, $identifier, $dbIdentifier);
+        return DAO::get()->findUserByIdentity($type, $identifier);
     }
 
     public static function joinUsers($userId1, $userId2) {
diff --git a/classes/X509Data.php b/classes/X509Data.php
index c907452c094a4f783e2c6470cbd4880f04a23f44..c1bb523d9c1ded4aa10b7c1cef60492efd0cbdcc 100644
--- a/classes/X509Data.php
+++ b/classes/X509Data.php
@@ -30,6 +30,9 @@ class X509Data {
     public $fullName;
     public $institution;
     public $serialNumber;
+    public $name;
+    public $surname;
+    public $candidateNames;
 
     /**
      * Retrieve full name from CN, removing the e-mail if necessary
@@ -81,23 +84,45 @@ class X509Data {
         $this->institution = $parsedX509["subject"]["O"];
     }
 
-    private function extractDNFields($dn) {
-        $dnSplit = explode(",", $dn);
-
-        foreach ($dnSplit as $dnField) {
-            $pos = strpos($dnField, "=");
-            $key = substr($dnField, 0, $pos - 1);
-            $value = substr($dnField, $pos + 1, strlen($dnField) - 1);
-            switch ($key) {
-                case 'CN':
-                    $this->parseCN($value);
-                    break;
-                case 'O':
-                    $this->institution = $value;
+    /**
+     * Credits: https://stackoverflow.com/a/1273535/771431
+     */
+    private static function bchexdec($hex) {
+        $dec = 0;
+        $len = strlen($hex);
+        for ($i = 1; $i <= $len; $i++) {
+            $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
+        }
+        return $dec;
+    }
+
+    private function fillNameAndSurnameOrCandidates() {
+        $nameSplit = explode(' ', $this->fullName);
+
+        if (count($nameSplit) === 2) {
+            $this->name = $nameSplit[0];
+            $this->surname = $nameSplit[1];
+        } else {
+            $this->candidateNames = [];
+            for ($i = 1; $i < count($nameSplit); $i++) {
+                $candidateName = "";
+                for ($j = 0; $j < $i; $j++) {
+                    if ($j > 0) {
+                        $candidateName .= ' ';
+                    }
+                    $candidateName .= $nameSplit[$j];
+                }
+                $this->candidateNames[] = $candidateName;
             }
         }
     }
 
+    public function selectCandidateName($candidateNameIndex) {
+        $candidateName = $this->candidateNames[$candidateNameIndex];
+        $this->name = $candidateName;
+        $this->surname = substr($this->fullName, strlen($candidateName) + 1);
+    }
+
     public static function parse($server) {
 
         $parsedData = new X509Data();
@@ -113,35 +138,39 @@ class X509Data {
         if ($parsedData->fullName === null) {
             if (isset($server['SSL_CLIENT_S_DN_CN'])) {
                 $parsedData->parseCN($server['SSL_CLIENT_S_DN_CN']);
-                if ($parsedData->fullName === null) {
-                    throw new \Exception("Unable to extract CN from DN");
-                }
             } else {
-                throw new \Exception("Unable to obtain DN from certificate");
+                throw new \Exception("Unable to retrieve CN from certificate");
             }
         }
 
         if ($parsedData->email === null) {
-            if (isset($_SERVER['SSL_CLIENT_SAN_Email_0'])) {
-                $parsedData->email = $_SERVER['SSL_CLIENT_SAN_Email_0'];
+            if (isset($server['SSL_CLIENT_SAN_Email_0'])) {
+                $parsedData->email = $server['SSL_CLIENT_SAN_Email_0'];
             } else {
                 throw new \Exception("Unable to retrieve e-mail address from certificate");
             }
         }
 
         if ($parsedData->serialNumber === null) {
-            if (isset($_SERVER['SSL_CLIENT_M_SERIAL'])) {
+            if (isset($server['SSL_CLIENT_M_SERIAL'])) {
                 // In this server variable the serial number is stored into an HEX format,
                 // while openssl_x509_parse function provides it in DEC format.
                 // Here a hex->dec conversion is performed, in order to store the
                 // serial number in a consistent format:
-                $hexSerial = $_SERVER['SSL_CLIENT_M_SERIAL'];
+                $hexSerial = $server['SSL_CLIENT_M_SERIAL'];
                 // TODO
+                $parsedData->serialNumber = X509Data::bchexdec($hexSerial);
             } else {
                 throw new Exception("Unable to retrieve serial number from certificate");
             }
         }
 
+        if ($parsedData->institution === null && isset($server['SSL_CLIENT_S_DN_O'])) {
+            $parsedData->institution = $server['SSL_CLIENT_S_DN_O'];
+        }
+
+        $parsedData->fillNameAndSurnameOrCandidates();
+
         return $parsedData;
     }
 
diff --git a/config.php b/config.php
index b29bb713eb6510684880fcd12af4297160b3ea8b..840befa7a49d356922dc238608aef6059e698396 100644
--- a/config.php
+++ b/config.php
@@ -52,25 +52,14 @@ $AUTHENTICATION_METHODS = array(
     'Google' => array(
         'id' => "***REMOVED***.apps.googleusercontent.com",
         'secret' => "***REMOVED***",
-        'callback' => $BASE_PATH . "/oauth2/google_token.php"),
+        'callback' => $BASE_PATH . "/auth/oauth2/google_token.php"),
     'Facebook' => array(
         'id' => "***REMOVED***",
         'secret' => "***REMOVED***",
         'version' => "v2.2",
-        'callback' => $BASE_PATH . "/oauth2/facebook_token.php"),
+        'callback' => $BASE_PATH . "/auth/oauth2/facebook_token.php"),
     'LinkedIn' => array(),
     'X.509' => array(),
-    'Direct' => array(
-        array(
-            'name' => 'IA2',
-            'label' => '',
-            'logo' => 'ia2-logo-60x60.png',
-            'description' => 'Use the IA2 logo if you have an IA2 account (provided by IA2 or self-registered)',
-            'type' => 'ldap',
-            'ldap_user_scope' => 'ou=custom_users,dc=oats,dc=inaf,dc=it',
-            'ldap_user_id_field' => 'uid'
-        )
-    )
 );
 
 $GROUPER = array(
diff --git a/css/chosen.min.css b/css/chosen.min.css
deleted file mode 100644
index a264b6d8797a223fa398fad195f07149c4d22088..0000000000000000000000000000000000000000
--- a/css/chosen.min.css
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Chosen v1.7.0 | (c) 2011-2017 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
-
-.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.chosen-container *{box-sizing:border-box}.chosen-container .chosen-drop{position:absolute;top:100%;z-index:1010;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15);clip:rect(0,0,0,0)}.chosen-container.chosen-with-drop .chosen-drop{clip:auto}.chosen-container a{cursor:pointer}.chosen-container .search-choice .group-name,.chosen-container .chosen-single .group-name{margin-right:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-weight:400;color:#999}.chosen-container .search-choice .group-name:after,.chosen-container .chosen-single .group-name:after{content:":";padding-left:2px;vertical-align:top}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:25px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:linear-gradient(#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;clip:rect(0,0,0,0)}.chosen-container .chosen-results{color:#444;position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;word-wrap:break-word;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{color:#777;display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;margin:0;padding:0 5px;width:100%;height:auto;border:1px solid #aaa;background-color:#fff;background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:0;height:25px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#999;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0;width:25px}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 5px 3px 0;padding:3px 20px 3px 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-color:#eee;background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-size:100% 19px;background-repeat:repeat-x;background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice span{word-wrap:break-word}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;border-bottom-right-radius:0;border-bottom-left-radius:0;background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#222!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi),only screen and (min-resolution:1.5dppx){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
\ No newline at end of file
diff --git a/css/style.css b/css/style.css
index f76e0fa5c0b4dcda79337c71b3593d90e619a635..9affc9a218da8eb85aadc4e0a952242850cdf9e6 100644
--- a/css/style.css
+++ b/css/style.css
@@ -14,10 +14,9 @@ body {
 }
 
 .home-box {
-    float: left;
+    display: inline-block;
     width: 240px;
     height: 165px;
-    padding: 2px;
     margin: 10px;
     border-radius: 15px;
     border: 1px solid #ccc;
diff --git a/img/ia2-logo-60x60.png b/img/ia2-logo-60x60.png
deleted file mode 100644
index f93ef2495577ed01ad2a5ac25578607dd9891670..0000000000000000000000000000000000000000
Binary files a/img/ia2-logo-60x60.png and /dev/null differ
diff --git a/include/front-controller.php b/include/front-controller.php
index 7ad325abcf2c337dc533476f9ed01cac95a1815a..8c334d7cbe48fe26f3a22f3f80287f4d8617a56a 100644
--- a/include/front-controller.php
+++ b/include/front-controller.php
@@ -30,22 +30,22 @@ Flight::route('GET /logout', function() {
 
 Flight::route('/google', function() {
     startSession();
-    Flight::redirect('/oauth2/google_token.php');
+    Flight::redirect('/auth/oauth2/google_token.php');
 });
 
 Flight::route('/facebook', function() {
     startSession();
-    Flight::redirect('/oauth2/facebook_login.php');
+    Flight::redirect('/auth/oauth2/facebook_login.php');
 });
 
 Flight::route('/eduGAIN', function() {
     startSession();
-    Flight::redirect('/saml2/aai.php');
+    Flight::redirect('/auth/saml2/aai.php');
 });
 
 Flight::route('/x509', function() {
     startSession();
-    Flight::redirect('/x509/certlogin.php');
+    Flight::redirect('/auth/x509/certlogin.php');
 });
 
 Flight::route('GET /confirm-join', function() {
@@ -101,3 +101,31 @@ Flight::route('POST /confirm-join', function() {
     Flight::render('join-success.php', array('title' => 'Success - RAP Join Request',
         'basePath' => $BASE_PATH));
 });
+
+Flight::route('GET /x509-name-surname', function() {
+
+    startSession();
+    global $session, $BASE_PATH;
+
+    if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name === null) {
+        Flight::render('x509-name-surname.php', array('title' => 'Select name and surname',
+            'fullName' => $session->x509DataToRegister->fullName,
+            'candidateNames' => $session->x509DataToRegister->candidateNames));
+    } else {
+        // Redirect to index
+        header("Location: " . $BASE_PATH);
+    }
+});
+
+Flight::route('POST /submit-x509-name', function() {
+
+    $selectedNameIndex = Flight::request()->data['selected-name'];
+    
+    startSession();
+    global $session, $BASE_PATH;
+
+    if ($session->x509DataToRegister !== null) {
+        $session->x509DataToRegister->selectCandidateName($selectedNameIndex);
+        header("Location: " . $BASE_PATH . '/x509');
+    }
+});
diff --git a/include/header.php b/include/header.php
index 29356dd43f6fc35a546977657bbd11615e9c09d9..7413c9aa95ee9d648dadfdede27e9df3d6782e3c 100644
--- a/include/header.php
+++ b/include/header.php
@@ -8,7 +8,6 @@
         <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
         <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
         <link rel="stylesheet" href="css/style.css" />
-        <script src="js/script.js"></script>
     </head>
     <body>
         <header id="main-header">
diff --git a/include/init.php b/include/init.php
index f74e1e30936f67149c51f66441eae2dc70e761c5..086d512461d038c60f952177a096019f21803651 100644
--- a/include/init.php
+++ b/include/init.php
@@ -40,6 +40,8 @@ include ROOT . '/vendor/autoload.php';
 include ROOT . '/config.php';
 
 // Setup logging
+// Monolog require timezone to be set
+date_default_timezone_set("Europe/Rome");
 $log = new Monolog\Logger('mainLogger');
 $log->pushHandler(new Monolog\Handler\StreamHandler($LOG_PATH, $LOG_LEVEL));
 
diff --git a/js/script.js b/js/index.js
similarity index 100%
rename from js/script.js
rename to js/index.js
diff --git a/js/x509-name-surname.js b/js/x509-name-surname.js
new file mode 100644
index 0000000000000000000000000000000000000000..fb1488295003e7ec0d0a05642fcb9d0e9fbcbff7
--- /dev/null
+++ b/js/x509-name-surname.js
@@ -0,0 +1,20 @@
+(function ($) {
+
+    var _fullName;
+    window.initPage = function (fullName) {
+        _fullName = fullName;
+    };
+
+    function fillSurnameFromSelectedCandidateName() {
+        var selectedName = $('#name-selector option:selected').text().trim();
+        var surname = _fullName.substring(selectedName.length + 1);
+        $('#surname-text').text(surname);
+    }
+
+    // When the document is loaded
+    $(document).ready(function () {
+        $(document).on('change', '#name-selector', fillSurnameFromSelectedCandidateName);
+        fillSurnameFromSelectedCandidateName();
+    });
+
+})(jQuery);
diff --git a/sql/setup-database.sql b/sql/setup-database.sql
index cff418a55e4cf7dcf68b8d0132b2c94331104b7c..60bdc47858125b2832c28a9938c56e82ca392f96 100644
--- a/sql/setup-database.sql
+++ b/sql/setup-database.sql
@@ -12,8 +12,6 @@ CREATE TABLE `identity` (
   `name` varchar(255) DEFAULT NULL,
   `surname` varchar(255) DEFAULT NULL,
   `institution` varchar(255) DEFAULT NULL,
-  `username` varchar(255) DEFAULT NULL,
-  `local_db_id` varchar(255) DEFAULT NULL,
   `eppn` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`),
   FOREIGN KEY (`user_id`) REFERENCES `user`(`id`)
@@ -30,7 +28,7 @@ CREATE TABLE `additional_email` (
 CREATE TABLE `login_token` (
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   `token` varchar(255) NOT NULL,
-  `data` text,
+  `user_id` text,
   `creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/views/index.php b/views/index.php
index e7eb9f06a9f7057681625e83b693213b223c40b5..e5ba7470c53b1d9d79743b7d2b8150dd4219824e 100644
--- a/views/index.php
+++ b/views/index.php
@@ -1,6 +1,7 @@
 <?php
 include 'include/header.php';
 ?>
+<script src="js/index.js"></script>
 
 <?php if ($session->user === null) { ?>
     <div class="row">
@@ -9,7 +10,7 @@ include 'include/header.php';
         </div>
     </div>
     <div class="row">
-        <div class="col-xs-12">
+        <div class="col-xs-12 text-center">
             <?php if (isset($auth['eduGAIN'])) { ?>
                 <div class="home-box">
                     <div class="img-wrapper">
@@ -52,22 +53,6 @@ include 'include/header.php';
                     Use the X.509 Logo to Login with your personal certificate (IGTF and TERENA-TACAR, are allowed).
                 </div>
             <?php } ?>
-            <?php
-            if (isset($auth['Direct'])) {
-                foreach ($auth['Direct'] as $directAuth) {
-                    ?>
-                    <div class="home-box">
-                        <div class="img-wrapper">
-                            <a href="#">
-                                <img src="img/<?php echo $directAuth['logo']; ?>" alt="" />
-                            </a>
-                        </div>
-                        <?php echo $directAuth['description']; ?>
-                    </div>
-                    <?php
-                }
-            }
-            ?>
         </div>
     </div>
 <?php } else { ?>
diff --git a/views/x509-name-surname.php b/views/x509-name-surname.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa5f159e70efbb4fc81d87cd5cc7ae1b8847bfe6
--- /dev/null
+++ b/views/x509-name-surname.php
@@ -0,0 +1,48 @@
+<?php
+include 'include/header.php';
+?>
+<script src="js/x509-name-surname.js"></script>
+<script>initPage('<?php echo $fullName; ?>');</script>
+
+<h1 class="text-center page-title">Name and surname selection</h1>
+
+<br/>
+<div class="text-center">
+    <p>Your name+surname is longer than 3 words. Please select the correct combination from the list below:</p>
+</div>
+
+<form action="submit-x509-name" method="POST">
+    <div class="row">
+        <div class="col-md-6 col-md-offset-3">
+            <table class="table">
+                <thead>
+                    <tr>
+                        <th>Name</th>
+                        <th>Surname</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    <tr>
+                        <td>
+                            <select class="form-control" id="name-selector" name="selected-name">
+                                <?php for ($i = 0; $i < count($candidateNames); $i++) { ?>
+                                    <option value="<?php echo $i; ?>" <?php echo $i === 0 ? 'selected' : ''; ?>>
+                                        <?php echo $candidateNames[$i]; ?>
+                                    </option>
+                                <?php } ?>
+                            </select>
+                        </td>
+                        <td><span id="surname-text"></span></td>
+                    </tr>
+                </tbody>
+            </table>        
+        </div>        
+    </div>
+
+    <div class="text-center">
+        <input class="btn btn-success" value="Confirm" type="submit" />
+    </div>
+</form>
+
+<?php
+include 'include/footer.php';
diff --git a/x509/certlogin.php b/x509/certlogin.php
deleted file mode 100644
index 1694ecff4558c966cc434ac5a37b215f7af3602f..0000000000000000000000000000000000000000
--- a/x509/certlogin.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/* ----------------------------------------------------------------------------
- *               INAF - National Institute for Astrophysics
- *               IRA  - Radioastronomical Institute - Bologna
- *               OATS - Astronomical Observatory - Trieste
- * ----------------------------------------------------------------------------
- *
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 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.
- */
-
-
-include '../include/init.php';
-startSession();
-
-if (isset($_SERVER['SSL_CLIENT_VERIFY']) && isset($_SERVER['SSL_CLIENT_V_REMAIN']) &&
-        $_SERVER['SSL_CLIENT_VERIFY'] === 'SUCCESS' && $_SERVER['SSL_CLIENT_V_REMAIN'] > 0) {
-
-    $email = null;
-
-    if (isset($_SERVER['SSL_CLIENT_CERT'])) {
-
-        $MYx509 = openssl_x509_parse($_SERVER['SSL_CLIENT_CERT']);
-
-        if (isset($MYx509["extensions"]["subjectAltName"])) {
-            $AyAlt = explode(":", $MYx509["extensions"]["subjectAltName"]);
-            if ($AyAlt[0] === "email") {
-                $email = $AyAlt[1];
-            }
-        }
-    }
-
-    if (isset($_SERVER['SSL_CLIENT_S_DN_CN'])) {
-        $fullName = $_SERVER['SSL_CLIENT_S_DN_CN'];
-    }
-}