Index: main/plugin-core/i18n/messages_en.xml
===================================================================
--- main/plugin-core/i18n/messages_en.xml	(revision 33858)
+++ main/plugin-core/i18n/messages_en.xml	(working copy)
@@ -66,6 +66,10 @@
          + -->
     <message key="PLUGINS_CORE_RIGHTS_USERS_LABEL">Users management</message>
     <message key="PLUGINS_CORE_RIGHTS_USERS_DESCRIPTION">Users management</message>
+    
+    <message key="PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_LABEL">Impersonate</message>
+    <message key="PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_DESCRIPTION">Connect with the login of the selected user.</message>
+
     <!-- Ribbon -->
     <message key="RIBBON_TABS_TAB_RIGHTS_HANDLE_LABEL">Users, groups and rights</message>
     <message key="RIBBON_TABS_TAB_USERS_GROUPS_GROUP_USERS_LABEL">CMS users</message>
@@ -92,6 +96,7 @@
     <message key="PLUGINS_CORE_USERS_DELETE_CONFIRM">Are you sure you want to delete these(s) user(s)?</message>
     <message key="PLUGINS_CORE_USERS_DELETE_ERROR">An error occurred: unable to delete user(s)</message>
     <message key="PLUGINS_CORE_USERS_INFOS_ERROR">An error occurred while retrieving user's information</message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_ERROR">An error occurred: unable to connect with the login of the selected user.</message>
     <!-- Helper -->
     <message key="PLUGINS_CORE_USERS_DIALOG_ADD_TITLE">New user ...</message>
     <message key="PLUGINS_CORE_USERS_DIALOG_EDIT_TITLE">Edit ...</message>
@@ -125,6 +130,14 @@
     <message key="PLUGINS_CORE_UITOOL_USER_RIGHTS_RIGHTS_BY_CONTEXT_HINT_2">&lt;/b&gt;.&lt;br/&gt;Each right is assigned on one or more contexts.</message>
     <message key="PLUGINS_CORE_UITOOL_USER_RIGHTS_ERROR">An error occurred : the user rights can not be displayed</message>
     
+    <!-- +
+         | IMPERSONATE USER
+         + -->
+    <message key="PLUGINS_CORE_UITOOL_USER_IMPERSONATE_LABEL">Impersonate</message>
+    <message key="PLUGINS_CORE_UITOOL_USER_IMPERSONATE_DESCRIPTION">Connect to the CMS with the login of the selected user.</message> 
+    <message key="PLUGINS_CORE_UITOOL_USER_IMPERSONATE_MULTI_FORBIDDEN">Several users are currently selected.&lt;br/&gt;Select a single user in order to be able to connect with his login</message>
+    
+    
 	<!-- USER JDBC -->
 	<message key="PLUGINS_CORE_USERS_JDBC_FIELD_LOGIN_LABEL">Login ID</message>
 	<message key="PLUGINS_CORE_USERS_JDBC_FIELD_LOGIN_DESCRIPTION">Unique login ID for user&lt;br/&gt;3-64 characters (letters, digits or '_')</message>
@@ -223,8 +236,14 @@
     <message key="PLUGINS_CORE_PROFILES_SWITCH_TO_EDITION_DESCRIPTION">Switches to editing mode to edit rights (addition or deletion) of the selected profile</message>
     <message key="PLUGINS_CORE_PROFILES_SWITCH_TO_VIEW">Overview</message>
     <message key="PLUGINS_CORE_PROFILES_SWITCH_TO_VIEW_DESCRIPTION">Switches to view mode of the profile's rights</message>
-    <message key="PLUGINS_CORE_PROFILES_HANDLE_SAVE_MODIFICATIONS">Save</message>
-    <message key="PLUGINS_CORE_PROFILES_HANDLE_SAVE_MODIFICATIONS_HINT">Save changes on profile</message>
+    <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS">Save</message>
+    <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS_DESCRIPTION">Save changes on profile</message>
+    <message key="PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS">Discard changes</message>
+    <message key="PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS_DESCRIPTION">Discard the current changes of the profile.</message>
+    
+    <message key="PLUGINS_CORE_PROFILES_RIGHTS_CONFIRM_TITLE">Save</message>
+    <message key="PLUGINS_CORE_PROFILES_RIGHTS_CONFIRM_DESCRIPTION">The attributed rights have been modified. Do you wish to save those changes ?</message>
+    
     <message key="PLUGINS_CORE_PROFILES_SELECT_ALL">Select all</message>
     <message key="PLUGINS_CORE_PROFILES_SELECT_ALL_DESCRIPTION">Select all rights</message>
     <message key="PLUGINS_CORE_PROFILES_UNSELECT_ALL">Unselect all</message>
@@ -293,6 +312,18 @@
 	<message key="PLUGINS_CORE_RIGHTS_CONTEXTS_APPLICATION_HELP_AFFECT">In order to assign profiles, a user/group can be selected from the list.</message>
 	<message key="PLUGINS_CORE_RIGHTS_CONTEXTS_APPLICATION_HELP_PROFIL">Select profiles that you want to assign to users/groups.&lt;br/&gt;Click on the link 'Confirm changes' to save the assignments.</message>
 
+    <!-- SUPER USER -->
+    <message key="PLUGINS_CORE_SUPERUSER_CATEGORY">Super user</message>
+    <message key="PLUGINS_CORE_RIGHTS_SUPERUSER_LABEL">Assign a super user</message>
+    <message key="PLUGINS_CORE_RIGHTS_SUPERUSER_DESCRIPTION">Right to assign a super user</message>
+
+    <message key="PLUGINS_CORE_SUPERUSER_LABEL">Assign super user</message>
+    <message key="PLUGINS_CORE_SUPERUSER_DESCRIPTION">Set the administrator of the site.</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_ERROR">An error occurred: the allocation has failed.</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_TITLE">Assign super user</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_SUCCESS">The allocation has been completed.</message>
+
+
 	<!-- RegExp -->
 	<message key="PLUGINS_CORE_REGEXP_INVALID_MAIL">The address is not a valid email address</message>
 	<message key="PLUGINS_CORE_REGEXP_INVALID_URL">The url is invalid. It has to start with either http:// or https://</message>
Index: main/plugin-core/i18n/messages_fr.xml
===================================================================
--- main/plugin-core/i18n/messages_fr.xml	(revision 33858)
+++ main/plugin-core/i18n/messages_fr.xml	(working copy)
@@ -59,12 +59,16 @@
 
     <!-- USER AND RIGHTS -->
     <message key="PLUGINS_CORE_USERANDRIGHTS_CATEGORY">Utilisateurs et droits</message>
-
+    
 	<!-- +
          | USERS 
          + -->
     <message key="PLUGINS_CORE_RIGHTS_USERS_LABEL">Gestion des utilisateurs</message>
     <message key="PLUGINS_CORE_RIGHTS_USERS_DESCRIPTION">Gestion des utilisateurs</message>
+    
+    <message key="PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_LABEL">Prendre le contrôle</message>
+    <message key="PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_DESCRIPTION">Se connecter avec les identifiants de l'utilisateur choisi.</message>
+    
     <!-- Ribbon -->
     <message key="RIBBON_TABS_TAB_RIGHTS_HANDLE_LABEL">Utilisateurs, groupes et droits</message>
     <message key="RIBBON_TABS_TAB_USERS_GROUPS_GROUP_USERS_LABEL">Utilisateurs du CMS</message>
@@ -91,6 +95,7 @@
     <message key="PLUGINS_CORE_USERS_DELETE_CONFIRM">Etes-vous sûr de vouloir supprimer ce ou ces utilisateur(s) ?</message>
     <message key="PLUGINS_CORE_USERS_DELETE_ERROR">Une erreur est survenue sur le serveur. Impossible de supprimer le ou les utilisateur(s).</message>
     <message key="PLUGINS_CORE_USERS_INFOS_ERROR">Une erreur est survenue: impossible de récupérer les informations sur cet utilisateur</message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_ERROR">Une erreur est survenue: impossible de se connecter avec les identifiants de l'utilisateur sélectionné.</message>
     <!-- Helper -->
     <message key="PLUGINS_CORE_USERS_DIALOG_ADD_TITLE">Nouvel utilisateur ...</message>
     <message key="PLUGINS_CORE_USERS_DIALOG_EDIT_TITLE">Modifier ...</message>
@@ -123,6 +128,16 @@
     <message key="PLUGINS_CORE_UITOOL_USER_RIGHTS_RIGHTS_BY_CONTEXT_HINT_2">&lt;/b&gt;.&lt;br/&gt;Chaque droit peut-être affecté sur un ou plusieurs contextes.</message>
     <message key="PLUGINS_CORE_UITOOL_USER_RIGHTS_ERROR">Une erreur est survenue : elle a empêchée l'affichage des droits de l'utilisateur</message>
     
+    <!-- +
+         | IMPERSONATE USER
+         + -->
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_LABEL">Prendre le contrôle</message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_DESCRIPTION">Se connecter au CMS avec les identifiants de l'utilisateur sélectionné.</message> 
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_MULTI_FORBIDDEN">Plusieurs utilisateurs sont actuellement sélectionnés.&lt;br/&gt;Sélectionnez un seul utilisateur afin de pouvoir se connecter avec ses identifiants.</message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS_TITLE">Prise de contrôle réussie</message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS">Vous êtes maintenant connecté avec les identifiants suivants : </message>
+    <message key="PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS_2">Vous allez être redirigé vers l'application.</message>
+    
     <!-- USER JDBC -->
     <message key="PLUGINS_CORE_USERS_JDBC_FIELD_LOGIN_LABEL">Identifiant</message>
     <message key="PLUGINS_CORE_USERS_JDBC_FIELD_LOGIN_DESCRIPTION">Identifiant unique de l'utilisateur (ou login)&lt;br/&gt;Entre 3 et 64 caractères (lettres, chiffres ou '_')</message>
@@ -222,13 +237,19 @@
     <message key="PLUGINS_CORE_PROFILES_SWITCH_TO_VIEW">Mode visualisation</message>
     <message key="PLUGINS_CORE_PROFILES_SWITCH_TO_VIEW_DESCRIPTION">Passe en mode visualisation des droits du profil</message>
     <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS">Sauvegarder</message>
-    <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS_DESCRIPTION">Sauvegarder les modifications effectué sur ce profil.</message>
+    <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS_DESCRIPTION">Sauvegarder les modifications effectuées sur ce profil.</message>
+    <message key="PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS">Annuler</message>
+    <message key="PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS_DESCRIPTION">Annuler les modifications en cours du profil.</message>
+    <message key="PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS_ERROR">Une erreur est survenue lors de la sauvegarde des droits du profil.</message>
+    <message key="PLUGINS_CORE_PROFILES_RIGHTS_CONFIRM_TITLE">Sauvegarde</message>
+    <message key="PLUGINS_CORE_PROFILES_RIGHTS_CONFIRM_DESCRIPTION">Vous avez fait des modifications dans les droits attribués. Souhaitez-vous les sauvegarder ?</message>
     <message key="PLUGINS_CORE_PROFILES_SELECT_ALL">Sélectionner tout</message>
     <message key="PLUGINS_CORE_PROFILES_SELECT_ALL_DESCRIPTION">Sélectionne tous les droits</message>
     <message key="PLUGINS_CORE_PROFILES_UNSELECT_ALL">Désélectionner tout</message>
     <message key="PLUGINS_CORE_PROFILES_UNSELECT_ALL_DESCRIPTION">Désélectionne tous les droits</message>
     <message key="PLUGINS_CORE_PROFILES_DESCRIPTION_NO_SELECTION">Ce bouton est désactivé car aucun profil n'est sélectionné ou le profil sélectionné n'est pas modifiable via cette interface.</message>
     <message key="PLUGINS_CORE_PROFILES_DESCRIPTION_NO_RIGHT">Ce bouton est désactivé car vos droits sont insuffisants.</message>
+    <message key="PLUGINS_CORE_PROFILES_">Ce bouton est désactivé car vos droits sont insuffisants.</message>
     <!-- Helper -->
     <message key="PLUGINS_CORE_PROFILES_DIALOG_ADD_TITLE">Nouveau profil ...</message>
     <message key="PLUGINS_CORE_PROFILES_DIALOG_EDIT_TITLE">Renommer ...</message>
@@ -291,6 +312,17 @@
     <message key="PLUGINS_CORE_RIGHTS_CONTEXTS_APPLICATION_HELP_AFFECT">Pour assigner des droits, ajoutez un utilisateur ou un groupe en cliquant sur les liens ci-dessus, ou sélectionnez directement un groupe ou un utilisateur dans la liste de droite.</message>
     <message key="PLUGINS_CORE_RIGHTS_CONTEXTS_APPLICATION_HELP_PROFIL">Choisissez le ou les profils à appliquer à l'utilisateur ou au groupe sélectionné.&lt;br/&gt;Cliquer sur le lien 'Valider les modifications' pour sauvegarder la nouvelle affectation.</message>
 	
+	<!-- SUPER USER -->
+	<message key="PLUGINS_CORE_SUPERUSER_CATEGORY">Affecter un gestionnaire</message>
+	<message key="PLUGINS_CORE_RIGHTS_SUPERUSER_LABEL">Droit d'affecter un gestionnaire</message>
+	<message key="PLUGINS_CORE_RIGHTS_SUPERUSER_DESCRIPTION">Gestionnaire</message>
+    
+    <message key="PLUGINS_CORE_SUPERUSER_LABEL">Affecter un gestionnaire</message>
+    <message key="PLUGINS_CORE_SUPERUSER_DESCRIPTION">Affecte un gestionnaire</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_TITLE">Affecter un gestionnaire</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_ERROR">Une erreur est survenue. Impossible d'affecter ce ou ces utilisateurs.</message>
+    <message key="PLUGINS_CORE_SUPERUSER_AFFECT_SUCCESS">L'affectation a été effectuée.</message>
+	
 	<!--  RegExp -->
 	<message key="PLUGINS_CORE_REGEXP_INVALID_MAIL">L'adresse saisie n'est pas une adresse mail valide</message>
 	<message key="PLUGINS_CORE_REGEXP_INVALID_URL">L'url est invalide. Elle doit commencée par http:// ou https://</message>
Index: main/plugin-core/plugin.xml
===================================================================
--- main/plugin-core/plugin.xml	(revision 33953)
+++ main/plugin-core/plugin.xml	(working copy)
@@ -618,6 +618,7 @@
     </feature>
     
     <feature name="core.users">
+
         <components>
             <component class="org.ametys.plugins.core.user.UserDAO" 
                        role="org.ametys.plugins.core.user.UserDAO" 
@@ -632,6 +633,12 @@
                     <description>PLUGINS_CORE_RIGHTS_USERS_DESCRIPTION</description>
                     <category>PLUGINS_CORE_USERANDRIGHTS_CATEGORY</category>
                 </right>
+                
+                <right id="Runtime_Rights_User_Impersonate">
+                    <label>PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_LABEL</label>
+                    <description>PLUGINS_CORE_RIGHTS_USERS_IMPERSONATE_DESCRIPTION</description>
+                    <category>PLUGINS_CORE_USERANDRIGHTS_CATEGORY</category>
+                </right>
             </extension>
             
             <extension id="org.ametys.core.Users"
@@ -758,6 +765,30 @@
                 <right>Runtime_Rights_User_Handle</right>
             </extension>
             
+            <extension id="org.ametys.core.users.Impersonate"
+                       point="org.ametys.core.ui.RibbonControlsManager"
+                       class="org.ametys.plugins.core.user.ImpersonateUserClientSideElement">
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <action>Ametys.plugins.core.users.UsersActions.impersonate</action>
+
+                    <label i18n="true">PLUGINS_CORE_USERS_IMPERSONATE_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_USERS_IMPERSONATE_DESCRIPTION</description>
+                    
+                    <selection-target-type>^user$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    <selection-description-multiselectionforbidden i18n="true">PLUGINS_CORE_USERS_IMPERSONATE_MULTI_FORBIDDEN</selection-description-multiselectionforbidden>
+
+                    <help>org.ametys.core.users.rights</help>
+                    <icon-small file="true">img/users/user_16.png</icon-small>
+                    <icon-medium file="true">img/users/user_32.png</icon-medium>
+                    <icon-large file="true">img/users/user_48.png</icon-large>
+                </class>
+                <script>
+                    <file>js/Ametys/plugins/core/users/UsersActions.js</file>
+                </script>
+                <right>Runtime_Rights_User_Impersonate</right>
+            </extension>
+            
             <extension id="org.ametys.core.UserRightsFactory"
                        point="org.ametys.core.ui.UIToolsFactoriesManager"
                        class="org.ametys.core.ui.StaticClientSideElement">
@@ -965,7 +996,7 @@
         <extensions>
             <extension point="org.ametys.core.right.RightsExtensionPoint"
                        id="org.ametys.core.profiles.right">
-                <right id="Runtime_Rights_Profile_Handle">
+                <right id="Runtime_Rights_Rights_Profile_Handle">
                     <label>PLUGINS_CORE_RIGHTS_PROFILES_LABEL</label>
                     <description>PLUGINS_CORE_RIGHTS_PROFILES_DESCRIPTION</description>
                     <category>PLUGINS_CORE_USERANDRIGHTS_CATEGORY</category>
@@ -1011,7 +1042,11 @@
                     <file>js/Ametys/plugins/core/profiles/ProfilesDAO.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesTool.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesTool/Profile.js</file>
+                    <file>js/Ametys/plugins/core/profiles/ProfilesTool/Right.js</file>
                 </scripts>
+                <css>
+                    <file>css/profiles.css</file>
+                </css>
             </extension>
             
             <extension id="org.ametys.core.rights.ProfileTab"
@@ -1082,13 +1117,44 @@
                 <right>Runtime_Rights_Rights_Profile_Handle</right>
             </extension>
             
-            <extension id="org.ametys.core.profiles.SaveRights"
+            <extension id="org.ametys.core.profiles.SwitchMode"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.plugins.core.group.ModifiableGroupsClientSideElement">
-                <class name="Ametys.ribbon.element.ui.ButtonController">
-                    <action>Ametys.plugins.core.profiles.ProfilesActions.save</action>
+                <class name="Ametys.plugins.core.profiles.controller.ViewModeController">
+                    <action>Ametys.plugins.core.profiles.ProfilesTool.switchMode</action>
+                    
+                    <enable-toggle>true</enable-toggle>
                     <tool-role>uitool-profile</tool-role>
                     <tool-enable-on-status>focus</tool-enable-on-status>
+                    <selection-target-type>^profile$</selection-target-type>
+                                        
+                    <label i18n="true">PLUGINS_CORE_PROFILES_SWITCH_TO_EDITION</label>
+                    <description i18n="true">PLUGINS_CORE_PROFILES_SWITCH_TO_EDITION_DESCRIPTION</description>
+                    <icon-small file="true">img/profiles/edit_16.png</icon-small>
+                    <icon-medium file="true">img/profiles/edit_32.png</icon-medium>
+                    <icon-large file="true">img/profiles/edit_48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/profiles/ProfilesDAO.js</file>
+                    <file>js/Ametys/plugins/core/profiles/ProfilesTool.js</file>
+                    <file>js/Ametys/plugins/core/profiles/controller/ViewModeController.js</file>
+                </scripts>
+                <right>Runtime_Rights_Rights_Profile_Handle</right>
+           </extension>
+           
+           <extension id="org.ametys.core.profiles.SaveRights"
+                       point="org.ametys.core.ui.RibbonControlsManager"
+                       class="org.ametys.plugins.core.group.ModifiableGroupsClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.profiles.ProfilesTool.save</action>
+                   
+                    <disabled>true</disabled>
+                    <selection-target-type>^profile$</selection-target-type>
+                    <selection-subtarget-type>^form$</selection-subtarget-type>
+                    <selection-subtarget-parameter>
+                        <name>isDirty</name>
+                        <value>true</value>
+                    </selection-subtarget-parameter>
                     
                     <label i18n="true">PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS</label>
                     <description i18n="true">PLUGINS_CORE_PROFILES_SAVE_MODIFICATIONS_DESCRIPTION</description>
@@ -1103,37 +1169,43 @@
                 <right>Runtime_Rights_Rights_Profile_Handle</right>
             </extension>
             
-            <extension id="org.ametys.core.profiles.SwitchMode"
+            <extension id="org.ametys.core.profiles.Discard"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.plugins.core.group.ModifiableGroupsClientSideElement">
-                <class name="Ametys.plugins.core.profiles.controller.ViewModeController">
-                    <action>Ametys.plugins.core.profiles.ProfilesTool.switchMode</action>
-                    <enable-toggle>true</enable-toggle>
-                    <tool-role>uitool-profile</tool-role>
-                    <tool-enable-on-status>focus</tool-enable-on-status>
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.profiles.ProfilesTool.discardChanges</action>
+                   
+                    <disabled>true</disabled>
+                    <selection-target-type>^profile$</selection-target-type>
+                    <selection-subtarget-type>^form$</selection-subtarget-type>
+                    <selection-subtarget-parameter>
+                        <name>isDirty</name>
+                        <value>true</value>
+                    </selection-subtarget-parameter>
                     
-                    <label i18n="true">PLUGINS_CORE_PROFILES_SWITCH_TO_EDITION</label>
-                    <description i18n="true">PLUGINS_CORE_PROFILES_SWITCH_TO_EDITION_DESCRIPTION</description>
-                    <icon-small file="true">img/profiles/edit_16.png</icon-small>
-                    <icon-medium file="true">img/profiles/edit_32.png</icon-medium>
-                    <icon-large file="true">img/profiles/edit_48.png</icon-large>
+                    <label i18n="true">PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS</label>
+                    <description i18n="true">PLUGINS_CORE_PROFILES_DONT_SAVE_MODIFICATIONS_DESCRIPTION</description>
+                    <icon-small file="true">img/profiles/save_16.png</icon-small>
+                    <icon-medium file="true">img/profiles/save_32.png</icon-medium>
+                    <icon-large file="true">img/profiles/save_48.png</icon-large>
                 </class>
                 <scripts>
                     <file>js/Ametys/plugins/core/profiles/ProfilesDAO.js</file>
-                    <file>js/Ametys/plugins/core/profiles/ProfilesTool.js</file>
-                    <file>js/Ametys/plugins/core/profiles/controller/ViewModeController.js</file>
+                    <file>js/Ametys/plugins/core/profiles/ProfilesActions.js</file>
                 </scripts>
                 <right>Runtime_Rights_Rights_Profile_Handle</right>
-           </extension>
+            </extension>
            
            <extension id="org.ametys.core.profiles.SelectAll"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.plugins.core.group.ModifiableGroupsClientSideElement">
-                <class name="Ametys.ribbon.element.ui.ButtonController">
+                <class name="Ametys.plugins.core.profiles.controller.SelectRightsController">
                     <action>Ametys.plugins.core.profiles.ProfilesTool.selectAll</action>
-                    <tool-role>uitool-profile</tool-role>
-                    <tool-enable-on-status>focus</tool-enable-on-status>
                     
+                    <disabled>true</disabled>
+                    <selection-target-type>^profile$</selection-target-type>
+                    <selection-subtarget-type>^form$</selection-subtarget-type>
+                                        
                     <label i18n="true">PLUGINS_CORE_PROFILES_SELECT_ALL</label>
                     <description i18n="true">PLUGINS_CORE_PROFILES_SELECT_ALL_DESCRIPTION</description>
                     <icon-small file="true">img/profiles/select_16.png</icon-small>
@@ -1141,6 +1213,7 @@
                     <icon-large file="true">img/profiles/select_48.png</icon-large>
                 </class>
                 <scripts>
+                    <file>js/Ametys/plugins/core/profiles/controller/SelectRightsController.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesDAO.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesActions.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesTool.js</file>
@@ -1148,12 +1221,16 @@
                 <right>Runtime_Rights_Rights_Profile_Handle</right>
             </extension>
             
-            <extension id="org.ametys.core.profiles.UnselectAll"
+           <extension id="org.ametys.core.profiles.UnselectAll"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.plugins.core.group.ModifiableGroupsClientSideElement">
-                <class name="Ametys.ribbon.element.ui.ButtonController">
+                <class name="Ametys.plugins.core.profiles.controller.SelectRightsController">
                     <action>Ametys.plugins.core.profiles.ProfilesTool.unselectAll</action>
                     
+                    <disabled>true</disabled>
+                    <selection-target-type>^profile$</selection-target-type>
+                    <selection-subtarget-type>^form$</selection-subtarget-type>
+                    
                     <label i18n="true">PLUGINS_CORE_PROFILES_UNSELECT_ALL</label>
                     <description i18n="true">PLUGINS_CORE_PROFILES_UNSELECT_ALL_DESCRIPTION</description>
                     <icon-small file="true">img/profiles/unselect_16.png</icon-small>
@@ -1161,6 +1238,7 @@
                     <icon-large file="true">img/profiles/unselect_48.png</icon-large>
                 </class>
                 <scripts>
+                    <file>js/Ametys/plugins/core/profiles/controller/SelectRightsController.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesDAO.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesActions.js</file>
                     <file>js/Ametys/plugins/core/profiles/ProfilesTool.js</file>
@@ -1170,4 +1248,38 @@
         </extensions>
     </feature>
     
+    <!-- +
+         | SUPER USER
+         + -->
+     <feature name="core.superuser">
+        <extensions>
+            <extension point="org.ametys.core.right.RightsExtensionPoint"
+                       id="org.ametys.core.superuser.right">
+                <right id="Runtime_Rights_Rights_SuperUser_Affect">
+                    <label>PLUGINS_CORE_RIGHTS_SUPERUSER_LABEL</label>
+                    <description>PLUGINS_CORE_RIGHTS_SUPER_DESCRIPTION</description>
+                    <category>PLUGINS_CORE_SUPERUSER_CATEGORY</category>
+                </right>
+            </extension>
+            
+            <extension id="org.ametys.core.superuser.Affect"
+                       point="org.ametys.core.ui.RibbonControlsManager"
+                       class="org.ametys.plugins.core.superuser.SuperUserClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.superuser.SuperUserActions.affectSuperUser</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_SUPERUSER_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_SUPERUSER_DESCRIPTION</description>
+                    
+                    <icon-small file="true">img/superuser/super_user_16.png</icon-small>
+                    <icon-medium file="true">img/superuser/super_user_32.png</icon-medium>
+                    <icon-large file="true">img/superuser/super_user_48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/superuser/SuperUserActions.js</file>
+                </scripts>
+                <right>Runtime_Rights_Rights_SuperUser_Affect</right>
+            </extension>
+        </extensions>
+     </feature>
 </plugin>
Index: main/plugin-core/resources/js/Ametys/plugins/core/superuser/SuperUserActions.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/superuser/SuperUserActions.js	(revision 0)
+++ main/plugin-core/resources/js/Ametys/plugins/core/superuser/SuperUserActions.js	(revision 0)
@@ -0,0 +1,93 @@
+/*
+ *  Copyright 2015 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @private
+ * Singleton class defining the actions related to the super user
+ */
+Ext.define('Ametys.plugins.core.superuser.SuperUserActions', {
+	singleton: true,
+	
+	/**
+	 * Give all the rights to a user on the context
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	affectSuperUser: function (controller)
+	{
+		Ametys.helper.SelectUser.act({
+			callback: Ext.bind(this._affectSuperUser, this, [controller, controller.getInitialConfig('context')], 1), 
+			cancelCallback: null, 
+			usersManagerRole: null, 
+			allowMultiselection: true, 
+			plugin: null
+		});	
+	},
+	
+	/**
+	 * @private
+	 * A callback method when a user has been selected
+	 * @param {String[]} users The array of users login to affect as super users
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller the button's controller
+	 * @param {String} context the rights context
+	 */
+	_affectSuperUser: function (users, controller, context) 
+	{
+		var logins = [];
+		for (var i in users)
+		{
+			logins.push(i);
+		}
+		
+		var context = context || this._getContext(controller);
+		
+		controller.serverCall
+		(
+			'affectSuperUser',
+			[logins, context],
+			Ext.bind(this._affectSuperUserCb, this),
+			{ 
+                errorMessage: { msg: "<i18n:text i18n:key='PLUGINS_CORE_SUPERUSER_AFFECT_ERROR'/>", category: Ext.getClassName(this)},
+                refreshing: true
+            } 
+		);
+	},
+	
+	/**
+	 * @private
+	 * Callback function invoked when the super user allocation process is complete
+	 * @param {Object} response the server's response
+	 * @param {Object} args the callback arguments
+	 */
+	_affectSuperUserCb: function(response, args)
+	{
+		Ametys.Msg.show ({
+			title: "<i18n:text i18n:key='PLUGINS_CORE_SUPERUSER_AFFECT_TITLE'/>",
+			msg: "<i18n:text i18n:key='PLUGINS_CORE_SUPERUSER_AFFECT_SUCCESS'/>",
+			buttons: Ext.Msg.OK,
+			icon: Ext.MessageBox.INFO
+		});
+	},
+	
+	/**
+	 * @protected
+	 * Get the context the user will be granted all rights to
+	 * @return the context
+	 */
+	_getContext: function()
+	{
+		return "";
+	}
+});
Index: main/plugin-core/resources/js/Ametys/plugins/core/users/UsersActions.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/users/UsersActions.js	(revision 33953)
+++ main/plugin-core/resources/js/Ametys/plugins/core/users/UsersActions.js	(working copy)
@@ -65,6 +65,19 @@
 			);
 		}
 	},
+	
+	/**
+	 * Impersonate the selected user
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function  
+	 */
+	impersonate: function(controller)
+	{
+		var userTarget = controller.getMatchingTargets()[0];
+		if (userTarget != null)
+		{
+			Ametys.plugins.core.users.UsersDAO.impersonate([userTarget.getParameters().id], null, {});
+		}
+	},
 
 	/**
 	 * Callback function invoked after the 'delete' confirm box is closed
Index: main/plugin-core/resources/js/Ametys/plugins/core/users/UsersDAO.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/users/UsersDAO.js	(revision 33953)
+++ main/plugin-core/resources/js/Ametys/plugins/core/users/UsersDAO.js	(working copy)
@@ -44,7 +44,7 @@
 			 * @param {Number} [options.priority] The message priority. See Ametys.data.ServerCall#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
 			 * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerCall#callMethod cancelCode.
 			 * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
-			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
+			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback be called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
 	    	 */
 			this.addCallables({
 			    role: "org.ametys.plugins.core.user.UserDAO",
@@ -79,7 +79,7 @@
 			 * @param {Number} [options.priority] The message priority. See Ametys.data.ServerCall#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
 			 * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerCall#callMethod cancelCode.
 			 * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
-			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
+			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback be called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
 	    	 */
 			this.addCallables({
 			    role: "org.ametys.plugins.core.user.UserDAO",
@@ -105,7 +105,7 @@
 	    	 * @param {String} [parameters.userManagerRole] The users manager's role. Can be null or empty to use the default one.
 	    	 * @param {String} [parameters.userMessageTargetType=user] The type of user target
 	    	 * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
-			 * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
+			 * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occurred, the callback may not be called depending on the value of errorMessage).
 			 * @param {Object} callback.arguments Other arguments specified in option.arguments                 
 			 * @param {Object} [options] Advanced options for the call.
 			 * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerCall#callMethod errorMessage.
@@ -114,7 +114,7 @@
 			 * @param {Number} [options.priority] The message priority. See Ametys.data.ServerCall#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
 			 * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerCall#callMethod cancelCode.
 			 * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
-			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
+			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback be called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
 	    	 */
 			this.addCallables({
 			    role: "org.ametys.plugins.core.user.UserDAO",
@@ -148,7 +148,7 @@
 			 * @param {Number} [options.priority] The message priority. See Ametys.data.ServerCall#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
 			 * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerCall#callMethod cancelCode.
 			 * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
-			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
+			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback be called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
 	    	 */
 			this.addCallables({
 			    role: "org.ametys.plugins.core.user.UserDAO",
@@ -158,6 +158,40 @@
 				    category: Ext.getClassName(this)
 				}
 			});
+			
+			/**
+	    	 * @callable
+	    	 * @param member Ametys.plugins.core.users.UsersDAO
+	    	 * @method impersonate
+	    	 * Impersonate the selected user
+	    	 * This calls the method 'impersonate' of the server DAO 'org.ametys.plugins.core.user.UserDAO'.
+	    	 * @param {Object[]} parameters The parameters to transmit to the server method
+	    	 * @param {String[]} parameters.login The user's login
+	    	 * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
+			 * @param {String} callback.user The user's properties
+			 * @param {String} callback.user.login the user's login
+			 * @param {String} callback.user.name the user's full name
+			 * @param {Object} callback.arguments Other arguments specified in option.arguments                 
+			 * @param {Object} [options] Advanced options for the call.
+			 * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerCall#callMethod errorMessage.
+			 * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerCall#callMethod waitMessage.
+			 * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods #beforeServerCall and #afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
+			 * @param {Number} [options.priority] The message priority. See Ametys.data.ServerCall#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
+			 * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerCall#callMethod cancelCode.
+			 * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
+			 * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback be called with a null parameter. See Ametys.data.ServerCall#callMethod ignoreOnError.
+	    	 */
+			this.addCallables({
+			    role: "org.ametys.plugins.core.user.UserDAO",
+				methodName: "impersonate",
+	     		callback: {
+	         		handler: this._impersonateUserCb
+	     		},
+				errorMessage: {
+				    msg: "<i18n:text i18n:key='PLUGINS_CORE_USERS_IMPERSONATE_ERROR'/>",
+				    category: Ext.getClassName(this)
+				}
+			});
 	 	},
 	 	
 	 	/**
@@ -228,8 +262,28 @@
 				type: Ametys.message.Message.DELETED,
 				targets: targets
 			});
-		}
+		},
 		
+		/**
+		 * @private
+		 * Callback function called after a user was created
+		 * @param {Object} user The user's information
+		 * @param {Object} args The callback arguments
+		 * @param {Object[]} params The callback parameters (server-side and client-side)
+		 */
+		_impersonateUserCb: function (user, args, params)
+		{
+			Ext.Msg.show ({
+	    		title: "<i18n:text i18n:key='PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS_TITLE'/>",
+	    		msg: "<i18n:text i18n:key='PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS'/> " + user.name + " (" + user.login + ").\n<i18n:text i18n:key='PLUGINS_CORE_USERS_IMPERSONATE_SUCCESS_2'/>",
+	    		buttons: Ext.Msg.OK,
+				icon: Ext.MessageBox.INFO,
+				fn: function() 
+				{ 
+					Ametys.reload();
+				}
+	    	});
+		}
 });
 
 Ext.define("Ametys.message.UserMessageTarget", {
Index: main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateAction.java
===================================================================
--- main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateAction.java	(revision 33943)
+++ main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateAction.java	(nonexistent)
@@ -1,82 +0,0 @@
-/*
- *  Copyright 2012 Anyware Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.ametys.plugins.core.user;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.cocoon.environment.ObjectModelHelper;
-import org.apache.cocoon.environment.Redirector;
-import org.apache.cocoon.environment.Request;
-import org.apache.cocoon.environment.SourceResolver;
-import org.apache.commons.lang.StringUtils;
-
-import org.ametys.core.authentication.AuthenticateAction;
-import org.ametys.core.user.User;
-import org.ametys.core.user.UsersManager;
-import org.ametys.core.util.cocoon.AbstractCurrentUserProviderServiceableAction;
-
-/**
- * This action impersonate the current user with the given login 
- */
-public class ImpersonateAction extends AbstractCurrentUserProviderServiceableAction
-{
-    private UsersManager _usersManager;
-    
-    @Override
-    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
-    {
-        Map<String, String> result = new HashMap<>();
-        
-        if (!_isSuperUser())
-        {
-            throw new IllegalStateException("Current user is not logged as administrator");
-        }
-
-        String login = parameters.getParameter("login", null);
-        if (StringUtils.isEmpty(login))
-        {
-            throw new IllegalArgumentException("'login' parameter is null or empty");
-        }
-        
-        if (_usersManager == null)
-        {
-            _usersManager = (UsersManager) manager.lookup(UsersManager.ROLE);
-        }
-        
-        User user = _usersManager.getUser(login);
-        if (user == null)
-        {
-            result.put("error", " There is no user with login '" + login + "' in the user manager");   
-        }
-        else
-        {
-            Request request = ObjectModelHelper.getRequest(objectModel);
-            request.getSession(true).setAttribute(AuthenticateAction.SESSION_USERLOGIN, login);
-            
-            result.put("login", login);
-            result.put("name", user.getFullName());
-            
-            if (getLogger().isInfoEnabled())
-            {
-                getLogger().info("Impersonification of user '" + login + "' from IP " + request.getRemoteAddr());
-            }
-        }
-        
-        return result;
-    }
-}
Index: main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateUserClientSideElement.java
===================================================================
--- main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateUserClientSideElement.java	(revision 0)
+++ main/plugin-core/src/org/ametys/plugins/core/user/ImpersonateUserClientSideElement.java	(revision 0)
@@ -0,0 +1,37 @@
+/*
+ *  Copyright 2015 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.plugins.core.user;
+
+import java.util.Map;
+
+import org.ametys.core.ui.StaticClientSideElement;
+
+/**
+ * This implementation creates a control only available if the current user is the super user
+ */
+public class ImpersonateUserClientSideElement extends StaticClientSideElement
+{
+    @Override
+    public Script getScript(Map<String, Object> contextParameters)
+    {
+        if (_currentUserProvider.isSuperUser())
+        {
+            return super.getScript(contextParameters);
+        }
+        
+        return null;
+    }
+}
Index: main/plugin-core/src/org/ametys/plugins/core/user/ModifiableUsersClientSideElement.java
===================================================================
--- main/plugin-core/src/org/ametys/plugins/core/user/ModifiableUsersClientSideElement.java	(revision 33858)
+++ main/plugin-core/src/org/ametys/plugins/core/user/ModifiableUsersClientSideElement.java	(working copy)
@@ -26,7 +26,6 @@
 
 /**
  * This implementation creates a control only available if the users manager is a {@link ModifiableUsersManager}
- *
  */
 public class ModifiableUsersClientSideElement extends StaticClientSideElement
 {
Index: main/plugin-core/src/org/ametys/plugins/core/user/UserDAO.java
===================================================================
--- main/plugin-core/src/org/ametys/plugins/core/user/UserDAO.java	(revision 33986)
+++ main/plugin-core/src/org/ametys/plugins/core/user/UserDAO.java	(working copy)
@@ -23,13 +23,19 @@
 import java.util.Map;
 
 import org.apache.avalon.framework.component.Component;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
 import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.Request;
 import org.apache.commons.lang3.StringUtils;
 
+import org.ametys.core.authentication.AuthenticateAction;
 import org.ametys.core.ui.Callable;
 import org.ametys.core.user.CurrentUserProvider;
 import org.ametys.core.user.InvalidModificationException;
@@ -48,7 +54,7 @@
  * DAO for manipulating {@link User}
  *
  */
-public class UserDAO extends AbstractLogEnabled implements Serviceable, Component
+public class UserDAO extends AbstractLogEnabled implements Component, Contextualizable, Serviceable 
 {
     /** The avalon role */
     public static final String ROLE = UserDAO.class.getName();
@@ -57,7 +63,14 @@
     protected ServiceManager _smanager;
     /** The current user provider. */
     protected CurrentUserProvider _currentUserProvider;
-
+    /** The Avalon context */
+    protected Context _context;
+    
+    public void contextualize(Context context) throws ContextException
+    {
+        _context = context;
+    }
+    
     public void service(ServiceManager smanager) throws ServiceException
     {
         _smanager = smanager;
@@ -276,10 +289,10 @@
     
     /**
      * Get the users edition model 
-     * @return The edition model as an object
      * @throws ServiceException If there is an issue with the service manager
      * @throws InvalidModificationException If modification is not possible 
      * @throws ProcessingException If there is another exception
+     * @return the users edition model as an object
      */
     @Callable
     public Map<String, Object> getEditionModel () throws ServiceException, InvalidModificationException, ProcessingException
@@ -290,10 +303,10 @@
     /**
      * Get the users edition model 
      * @param userManagerRole The users manager's role. Can be null or empty to use the default one.
-     * @return The edition model as an object
      * @throws ServiceException If there is an issue with the service manager
      * @throws InvalidModificationException If modification is not possible 
      * @throws ProcessingException If there is another exception
+     * @return The edition model as an object
      */
     @Callable
     public Map<String, Object> getEditionModel (String userManagerRole) throws ServiceException, InvalidModificationException, ProcessingException
@@ -379,6 +392,62 @@
     }
     
     /**
+     * Impersonate the selected user
+     * @param login the login of the user to impersonate
+     * @throws ServiceException If there is an issue with the service manager
+     * @return a map of information on the user
+     */
+    @Callable
+    public Map<String, String> impersonate(String login) throws ServiceException
+    {
+        Map<String, String> result = new HashMap<>();
+        if (_currentUserProvider == null)
+        {
+            try
+            {
+                _currentUserProvider = (CurrentUserProvider) _smanager.lookup(CurrentUserProvider.ROLE);
+            }
+            catch (ServiceException e)
+            {
+                throw new IllegalStateException(e);
+            }
+        }
+        
+        if (!_currentUserProvider.isSuperUser())
+        {
+            throw new IllegalStateException("Current user is not logged as administrator");
+        }
+
+        if (StringUtils.isEmpty(login))
+        {
+            throw new IllegalArgumentException("'login' parameter is null or empty");
+        }
+        
+        UsersManager usersManager = (UsersManager) _smanager.lookup(UsersManager.ROLE);
+        User user = usersManager.getUser(login);
+        if (user == null)
+        {
+            result.put("error", " There is no user with login '" + login + "' in the user manager");   
+        }
+        else
+        {
+            Request request = ContextHelper.getRequest(_context);
+            
+            request.getSession(true).setAttribute(AuthenticateAction.SESSION_USERLOGIN, login);
+            
+            result.put("login", login);
+            result.put("name", user.getFullName());
+            
+            if (getLogger().isInfoEnabled())
+            {
+                getLogger().info("Impersonation of the user '" + login + "' from IP " + request.getRemoteAddr());
+            }
+        }
+        
+        return result;
+    }
+    
+    /**
      * Provides the login of the current user.
      * @return the login which cannot be <code>null</code>.
      */
