diff --git a/classes/UserHandler.php b/classes/UserHandler.php
index 1963a2223a789b3ab7c9df1751a1b88acc9abbb0..f65c2946173c21302d77df939f6d114f066a6ffa 100644
--- a/classes/UserHandler.php
+++ b/classes/UserHandler.php
@@ -68,6 +68,10 @@ class UserHandler {
         $userId1 = $user1->id;
         $userId2 = $user2->id;
 
+        if ($userId1 === $userId2) {
+            return $user1;
+        }
+
         // Call Grouper for moving groups and privileges from one user to the other
         if (isset($this->locator->config->gms)) {
 
diff --git a/classes/login/ShibbolethLogin.php b/classes/login/ShibbolethLogin.php
index 072361860a723de3396556b60589eae342f1f47c..faa7c1fb164f3dee711ad48f92f42fc4fd81b718 100644
--- a/classes/login/ShibbolethLogin.php
+++ b/classes/login/ShibbolethLogin.php
@@ -31,8 +31,7 @@ class ShibbolethLogin extends LoginHandler {
                         $identity->eppn = $eppn;
                     });
         } else {
-            http_response_code(500);
-            die("Shib-Session-ID not found!");
+            throw new ServerErrorException("Shib-Session-ID not found!");
         }
     }
 
diff --git a/css/animation.css b/css/animation.css
deleted file mode 100644
index be95362c851d3dd2a72cbbf8936fcd804271a077..0000000000000000000000000000000000000000
--- a/css/animation.css
+++ /dev/null
@@ -1,151 +0,0 @@
-@charset "UTF-8";
-/*
-   Animation example, for spinners
-*/
-.animate-spin {
-    -moz-animation: spin 2s infinite linear;
-    -o-animation: spin 2s infinite linear;
-    -webkit-animation: spin 2s infinite linear;
-    animation: spin 2s infinite linear;
-    display: inline-block;
-}
-@-moz-keyframes spin {
-    0% {
-        -moz-transform: rotate(0deg);
-        -o-transform: rotate(0deg);
-        -webkit-transform: rotate(0deg);
-        transform: rotate(0deg);
-    }
-
-    100% {
-        -moz-transform: rotate(359deg);
-        -o-transform: rotate(359deg);
-        -webkit-transform: rotate(359deg);
-        transform: rotate(359deg);
-    }
-}
-@-webkit-keyframes spin {
-    0% {
-        -moz-transform: rotate(0deg);
-        -o-transform: rotate(0deg);
-        -webkit-transform: rotate(0deg);
-        transform: rotate(0deg);
-    }
-
-    100% {
-        -moz-transform: rotate(359deg);
-        -o-transform: rotate(359deg);
-        -webkit-transform: rotate(359deg);
-        transform: rotate(359deg);
-    }
-}
-@-o-keyframes spin {
-    0% {
-        -moz-transform: rotate(0deg);
-        -o-transform: rotate(0deg);
-        -webkit-transform: rotate(0deg);
-        transform: rotate(0deg);
-    }
-
-    100% {
-        -moz-transform: rotate(359deg);
-        -o-transform: rotate(359deg);
-        -webkit-transform: rotate(359deg);
-        transform: rotate(359deg);
-    }
-}
-@-ms-keyframes spin {
-    0% {
-        -moz-transform: rotate(0deg);
-        -o-transform: rotate(0deg);
-        -webkit-transform: rotate(0deg);
-        transform: rotate(0deg);
-    }
-
-    100% {
-        -moz-transform: rotate(359deg);
-        -o-transform: rotate(359deg);
-        -webkit-transform: rotate(359deg);
-        transform: rotate(359deg);
-    }
-}
-@keyframes spin {
-    0% {
-        -moz-transform: rotate(0deg);
-        -o-transform: rotate(0deg);
-        -webkit-transform: rotate(0deg);
-        transform: rotate(0deg);
-    }
-
-    100% {
-        -moz-transform: rotate(359deg);
-        -o-transform: rotate(359deg);
-        -webkit-transform: rotate(359deg);
-        transform: rotate(359deg);
-    }
-}
-
-/*!
- * animate.css -http://daneden.me/animate
- * Version - 3.5.2
- * Licensed under the MIT license - http://opensource.org/licenses/MIT
- *
- * Copyright (c) 2017 Daniel Eden
- */
-.animated {
-    animation-duration: 1s;
-    animation-fill-mode: both;
-}
-
-.animated.infinite {
-    animation-iteration-count: infinite;
-}
-
-.animated.hinge {
-    animation-duration: 2s;
-}
-
-.animated.flipOutX,
-.animated.flipOutY,
-.animated.bounceIn,
-.animated.bounceOut {
-    animation-duration: .75s;
-}
-
-
-@keyframes bounceIn {
-    from, 20%, 40%, 60%, 80%, to {
-        animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
-    }
-
-    0% {
-        opacity: 0;
-        transform: scale3d(.3, .3, .3);
-    }
-
-    20% {
-        transform: scale3d(1.1, 1.1, 1.1);
-    }
-
-    40% {
-        transform: scale3d(.9, .9, .9);
-    }
-
-    60% {
-        opacity: 1;
-        transform: scale3d(1.03, 1.03, 1.03);
-    }
-
-    80% {
-        transform: scale3d(.97, .97, .97);
-    }
-
-    to {
-        opacity: 1;
-        transform: scale3d(1, 1, 1);
-    }
-}
-
-.bounceIn {
-    animation-name: bounceIn;
-}
\ No newline at end of file
diff --git a/css/style.css b/css/style.css
index 53aa45bb0555f9b05f478972580db200e04f0621..91f0f6062221109fd82f1427ebd4a6586066047a 100644
--- a/css/style.css
+++ b/css/style.css
@@ -108,6 +108,10 @@ body {
     font-size: 42px;
 }
 
+.page-title-wrapper a {
+    color: #fff;
+}
+
 #main-footer-wrapper {
     position: fixed;
     bottom: 0;
diff --git a/include/admin.php b/include/admin.php
index 3e3b7fafade74e09d1f090f98b17811460ff1711..8aab087497561b437f627cb43f5452008286c53e 100644
--- a/include/admin.php
+++ b/include/admin.php
@@ -25,9 +25,57 @@ function checkUser() {
 Flight::route('GET /admin', function() {
     checkUser();
 
-    global $VERSION;
+    global $locator;
     Flight::render('admin/index.php', array('title' => 'Admin panel',
-        'version' => $VERSION));
+        'version' => $locator->getVersion(),
+        'contextRoot' => $locator->config->contextRoot));
+});
+
+Flight::route('GET /admin-join', function() {
+    checkUser();
+
+    global $locator;
+    Flight::render('admin/join.php', array('title' => 'Admin panel - Join users',
+        'version' => $locator->getVersion(),
+        'contextRoot' => $locator->config->contextRoot));
+});
+
+Flight::route('POST /admin-join', function() {
+    checkUser();
+
+    global $locator;
+
+    $user1Id = filter_input(INPUT_POST, 'user1', FILTER_SANITIZE_STRING);
+    $user2Id = filter_input(INPUT_POST, 'user2', FILTER_SANITIZE_STRING);
+
+    if ($user1Id === null) {
+        throw new \RAP\BadRequestException("Missing parameter user1");
+    }
+    if ($user2Id === null) {
+        throw new \RAP\BadRequestException("Missing parameter user2");
+    }
+
+    $dao = $locator->getUserDAO();
+    $user1 = $dao->findUserById($user1Id);
+    $user2 = $dao->findUserById($user2Id);
+
+    $locator->getUserHandler()->joinUsers($user1, $user2);
+
+    Flight::redirect($locator->getBasePath() . '/admin-join');
+});
+
+Flight::route('GET /admin-search', function() {
+    checkUser();
+
+    $searchText = Flight::request()->query['query'];
+    if ($searchText === null) {
+        throw new \RAP\BadRequestException("Missing query parameter");
+    }
+
+    global $locator;
+    $users = $locator->getUserDAO()->searchUser($searchText);
+
+    Flight::json($users);
 });
 
 Flight::route('GET /admin/oauth2_clients', function() {
diff --git a/include/footer.php b/include/footer.php
index 39fdc446951d8e3936a02716fb077050de1e152a..d61aed3134f805ca3b37be42724bc940ad78c5b2 100644
--- a/include/footer.php
+++ b/include/footer.php
@@ -2,10 +2,8 @@
 <div class="row">
     <div class="col-sm-8 col-sm-offset-2">
         <div class="alert alert-info text-center">
-            <div class="animated bounceIn hinge">
-                <span class="glyphicon glyphicon-info-sign"></span>
-                <strong>Need help?</strong> Please read our <a href="https://sso.ia2.inaf.it/home/index.php?lang=en"><u>User guide</u></a> and <a href="https://sso.ia2.inaf.it/home/faq.php?lang=en"><u>FAQ</u></a>.
-            </div>
+            <span class="glyphicon glyphicon-info-sign"></span>
+            <strong>Need help?</strong> Please read our <a href="https://sso.ia2.inaf.it/home/index.php?lang=en" target="blank_"><u>User guide</u></a> and <a href="https://sso.ia2.inaf.it/home/faq.php?lang=en" target="blank_"><u>FAQ</u></a>.
         </div>
     </div>
 </div>
@@ -23,7 +21,7 @@
     <p id="footer-credits">This software has been adapted by the IA2 team from the Remote Authentication Portal written by Franco Tinarelli at INAF-IRA.</p>
     <div id="main-footer">
         Powered by
-        <img src="img/logo-ia2-small.png" alt="logo IA2" />
+        <img src="<?php echo $contextRoot; ?>/img/logo-ia2-small.png" alt="logo IA2" />
         <a href="http://www.ia2.inaf.it/" target="blank_">IA2</a>
     </div>
 </footer>
diff --git a/include/front-controller.php b/include/front-controller.php
index 135852847a09f260b3b54d0537edcbf04f222eb5..07fec11511c56268ffe05b20481ad603704ab68f 100644
--- a/include/front-controller.php
+++ b/include/front-controller.php
@@ -54,6 +54,7 @@ Flight::route('/', function() {
             $clients = $locator->getOAuth2ClientDAO()->getOAuth2Clients();
             Flight::render('services-list.php', array('title' => 'RAP',
                 'version' => $locator->getVersion(),
+                'contextRoot' => $locator->config->contextRoot,
                 'clients' => $clients,
                 'action' => $locator->getBasePath() . '/'));
             break;
@@ -62,8 +63,11 @@ Flight::route('/', function() {
 
 function renderMainPage(RAP\AuthPageModel $authPageModel) {
     global $locator;
-    Flight::render('main-page.php', array('title' => 'RAP',
-        'version' => $locator->getVersion(), 'model' => $authPageModel));
+    Flight::render('main-page.php', array(
+        'title' => 'RAP',
+        'version' => $locator->getVersion(),
+        'contextRoot' => $locator->config->contextRoot,
+        'model' => $authPageModel));
 }
 
 Flight::route('GET /auth/oauth2/authorize', function() {
@@ -234,17 +238,18 @@ Flight::route('/local', function() {
 Flight::route('GET /x509-name-surname', function() {
 
     session_start();
-    global $locator, $BASE_PATH, $VERSION;
+    global $locator;
     $session = $locator->getSession();
 
     if ($session->getX509DataToRegister() !== null && $session->getX509DataToRegister()->name === null) {
         Flight::render('x509-name-surname.php', array('title' => 'Select name and surname',
-            'version' => $VERSION,
+            'version' => $locator->getVersion(),
+            'contextRoot' => $locator->config->contextRoot,
             'fullName' => $session->getX509DataToRegister()->fullName,
             'candidateNames' => $session->getX509DataToRegister()->candidateNames));
     } else {
         // Redirect to index
-        header("Location: " . $BASE_PATH);
+        header("Location: " . $locator->getBasePath());
         die();
     }
 });
@@ -286,6 +291,7 @@ Flight::route('GET /tou-check', function() {
         Flight::render('tou-check.php', array('title' => 'Terms of Use acceptance',
             'user' => $locator->getSession()->getUser(),
             'version' => $locator->getVersion(),
+            'contextRoot' => $locator->config->contextRoot,
             'registration_url' => $locator->getBasePath() . '/register'));
     }
 });
@@ -301,7 +307,8 @@ Flight::route('GET /confirm-join', function() {
         Flight::render('confirm-join.php', array('title' => 'Confirm join',
             'user' => $locator->getSession()->getUser(),
             'user_to_join' => $locator->getSession()->getUserToJoin(),
-            'version' => $locator->getVersion()));
+            'version' => $locator->getVersion(),
+            'contextRoot' => $locator->config->contextRoot));
     }
 });
 
@@ -353,9 +360,10 @@ Flight::route('GET /account', function () {
     } else {
         $admin = $locator->getUserDAO()->isAdmin($user->id);
         Flight::render('account-management.php', array('title' => 'RAP Account Management',
-            'version' => $locator->getVersion(), 'session' => $locator->getSession(),
-            'admin' => $admin,
-            'contextRoot' => $locator->config->contextRoot));
+            'version' => $locator->getVersion(),
+            'contextRoot' => $locator->config->contextRoot,
+            'session' => $locator->getSession(),
+            'admin' => $admin));
     }
 });
 
@@ -376,11 +384,12 @@ Flight::route('GET /token-issuer', function () {
     if ($user === null) {
         Flight::redirect('/');
     } else {
-        $admin = $locator->getUserDAO()->isAdmin($user->id);
         Flight::render('token-issuer.php', array('title' => 'RAP Token Issuer',
-            'version' => $locator->getVersion(), 'session' => $locator->getSession(),
-            'config' => $config, 'csrfToken' => $csrfToken,
-            'contextRoot' => $locator->config->contextRoot));
+            'version' => $locator->getVersion(),
+            'contextRoot' => $locator->config->contextRoot,
+            'session' => $locator->getSession(),
+            'config' => $config,
+            'csrfToken' => $csrfToken));
     }
 });
 
diff --git a/include/header.php b/include/header.php
index 2935bed635faed050cec2fdce1e1245c32f13970..d65320243d12a38f60d249241dc074602a570897 100644
--- a/include/header.php
+++ b/include/header.php
@@ -7,9 +7,8 @@
         <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />
         <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?v=2" />
-        <link rel="stylesheet" href="css/animation.css?v=2" />
-        <script src="js/script.js?v=<?php echo $version; ?>"></script>
+        <link rel="stylesheet" href="<?php echo $contextRoot; ?>/css/style.css?v=<?php echo $version; ?>" />
+        <script src="<?php echo $contextRoot; ?>/js/script.js?v=<?php echo $version; ?>"></script>
     </head>
     <body>
         <header id="main-header">
@@ -17,7 +16,8 @@
                 Image Credits & Copyright: Colombari/E.Recurt
             </div>
             <div class="page-title-wrapper">
-                <h1 class="text-center">Remote Authentication Portal
+                <h1 class="text-center">
+                    <a href="<?php echo $contextRoot; ?>/">Remote Authentication Portal</a>
                     <span class="circle-wrapper">
                         <div class="circle">beta<br/>version!</div>
                     </span>
diff --git a/js/admin-join.js b/js/admin-join.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd5f820a17707139988882a07919f798aa050f23
--- /dev/null
+++ b/js/admin-join.js
@@ -0,0 +1,118 @@
+(function () {
+
+    function getUserPanel(user) {
+        $panelBody = $('<div class="panel-body"></div>');
+        for (var i = 0; i < user.identities.length; i++) {
+            identity = user.identities[i];
+            $identityEl = $('<dl class="dl-horizontal"><dt>');
+            $identityEl.append('<dt>Type</dt>');
+            $identityEl.append('<dd>' + identity.type + '</dd>');
+            $identityEl.append('<dt>Email</dt>');
+            $identityEl.append('<dd>' + identity.email + '</dd>');
+            if (identity.name) {
+                $identityEl.append('<dt>Name</dt>');
+                $identityEl.append('<dd>' + identity.name + '</dd>');
+            }
+            if (identity.surname) {
+                $identityEl.append('<dt>Surname</dt>');
+                $identityEl.append('<dd>' + identity.surname + '</dd>');
+            }
+            $panelBody.append($identityEl);
+        }
+        $panel = $('<div class="panel panel-default"></div>');
+        $panel.append($panelBody);
+        return $panel;
+    }
+
+    function getUser(usersList, id) {
+        for (var i = 0; i < usersList.length; i++) {
+            var user = usersList[i];
+            if (user.id === id) {
+                return user;
+            }
+        }
+        return null;
+    }
+
+    function createSelectUserFunction(usersList, $container) {
+        return function (event) {
+            $container.empty();
+            var user = getUser(usersList, $(event.target).val());
+            if (user) {
+                $container.append(getUserPanel(user));
+            }
+        };
+    }
+
+    function createSearchFunctionTimeout(input, select, usersList) {
+        var text = $(input).val();
+        return function () {
+            $.ajax({
+                url: 'admin-search?query=' + text,
+                type: "GET",
+                dataType: 'json',
+                xhrFields: {
+                    withCredentials: true
+                },
+                success: function (users) {
+                    // empty usersList:
+                    usersList.splice(0, usersList.length);
+                    var selectEl = $(select);
+                    selectEl.empty();
+                    for (var i = 0; i < users.length; i++) {
+                        var user = users[i];
+                        usersList.push(user);
+                        var label = null;
+                        var types = [];
+                        var primaryIdentity = null;
+                        for (var j = 0; j < user.identities.length; j++) {
+                            var identity = user.identities[j];
+                            if (identity.name !== null && identity.surname !== null) {
+                                label = identity.name + " " + identity.surname;
+                            }
+                            if (identity.primary) {
+                                primaryIdentity = identity;
+                            }
+                            types.push(identity.type);
+                        }
+                        if (label === null) {
+                            label = primaryIdentity.email;
+                        }
+                        label += " (" + types.join(", ") + ") [" + user.id + "]";
+                        selectEl.append('<option value="' + user.id + '">' + label + "</option>");
+                    }
+                    selectEl.attr("disabled", users.length === 0);
+                    $('#join-btn-admin').attr("disabled", users1.length === 0 || users2.length === 0);
+                    selectEl.trigger('change');
+                }
+            });
+        };
+    }
+
+    function createSearchFunction(timer, input, select, usersList) {
+        return function () {
+            clearTimeout(timer);
+            timer = setTimeout(createSearchFunctionTimeout(input, select, usersList), 500);
+        };
+    }
+
+    var timer1, timer2;
+
+    var input1 = $('#user1_search');
+    var input2 = $('#user2_search');
+    var select1 = $('#user1_select');
+    var select2 = $('#user2_select');
+
+    var users1 = [], users2 = [];
+
+    var search1 = createSearchFunction(timer1, input1, select1, users1);
+    var search2 = createSearchFunction(timer2, input2, select2, users2);
+
+    input1.on('keydown', search1);
+    input1.on('input', search1);
+    input2.on('keydown', search2);
+    input2.on('input', search2);
+
+    select1.on('change', createSelectUserFunction(users1, $('#user1_content')));
+    select2.on('change', createSelectUserFunction(users2, $('#user2_content')));
+})();
\ No newline at end of file
diff --git a/version.txt b/version.txt
index 359a5b952d49f3592571e2af081510656029298e..10bf840ed530af123660f5edb1544264d8f2def4 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-2.0.0
\ No newline at end of file
+2.0.1
\ No newline at end of file
diff --git a/views/account-management.php b/views/account-management.php
index 39712aba8c5797b11af5818f15d1232a6d90a8d6..21e4cdf15147c3ff97b4e44437c5ca4bcc1141cf 100644
--- a/views/account-management.php
+++ b/views/account-management.php
@@ -35,9 +35,10 @@ include 'include/header.php';
         <?php if ($admin) { ?>
             <div class="row">
                 <div class="col-sm-12">
-                    <a class="btn btn-default" href="<?php echo $contextRoot; ?>/admin" title="Admin panel" data-toggle="tooltip" data-placement="bottom">
+                    <h4>Admin tools</h4>
+                    <a class="btn btn-default" href="<?php echo $contextRoot; ?>/admin-join" title="Join users" data-toggle="tooltip" data-placement="bottom">
                         <span class="glyphicon glyphicon-wrench"></span>
-                        Admin
+                        Join Users
                     </a>
                 </div>
             </div>
diff --git a/views/admin/join.php b/views/admin/join.php
new file mode 100644
index 0000000000000000000000000000000000000000..03de8116f5601b2cdc3b29483cb8f9ba804091a6
--- /dev/null
+++ b/views/admin/join.php
@@ -0,0 +1,37 @@
+<?php
+include 'include/header.php';
+?>
+
+<h1 class="text-center"><a href="<?php echo $contextRoot; ?>/account">Account management</a> - Join users</h1>
+
+<form method="POST" action="<?php echo $contextRoot . '/admin-join'; ?>">
+    <div class="row">
+        <div class="col-xs-6">
+            <h2>User 1</h2>
+            <input type="text" class="form-control" id="user1_search" placeholder="Search..." /><br/>
+            <select class="form-control" disabled="disabled" name="user1" id="user1_select"></select>
+            <br/>
+            <div id="user1_content"></div>
+        </div>
+        <div class="col-xs-6">
+            <h2>User 2</h2>
+            <input type="text" class="form-control" id="user2_search" placeholder="Search..." /><br/>
+            <select class="form-control" disabled="disabled" name="user2" id="user2_select"></select>
+            <br/>
+            <div id="user2_content"></div>
+        </div>
+    </div>
+
+    <div class="row">
+        <div class="col-xs-12 text-center">
+            <input type="submit" class="btn btn-primary btn-lg" disabled="disabled" id="join-btn-admin" value="Join users" />
+        </div>
+    </div>
+</form>
+
+<script src="js/admin-join.js"></script>
+
+
+<br/><br/><br/>
+<?php
+include 'include/footer.php';