Index: main/plugin-core/i18n/messages_en.xml
===================================================================
--- main/plugin-core/i18n/messages_en.xml	(revision 31811)
+++ main/plugin-core/i18n/messages_en.xml	(working copy)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-   Copyright 2014 Anyware Services
+   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.
@@ -202,39 +202,84 @@
 	<message key="PLUGINS_CORE_ADMINISTRATOR_PLUGINS_CHANGES_ERROR">Changes were not applied.</message>
 
 	<!-- ADMINITRATOR LOGS -->
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LABEL">Logs</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DESCRIPTION">Display the application logs</message>
+	
+	<!-- Log Tool -->
+	<message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_VISUALIZATION_LABEL">Visualization</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_VISUALIZATION_DESC">This tool allows you to visualize, delete, download and clean log entries.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_CONFIGURATION_LABEL">Configuration</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_CONFIGURATION_DESC">This tool allows you to configure the logging levels for the log categories.</message>
+	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_NAME">Name</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_DATE">Date</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_SIZE">Size</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_CATEGORY">Logs</message>
+    
+    <!-- View Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_LABEL">Display</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DESC">Display the selected file</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW">Display file</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW_CONFIRM">The file you are trying to display is large and cannot be sent without compression. Do you want to download the compressed file ?</message>
+    
+    <!-- Download Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_LABEL">Download</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_DESC">Download the selected file(s)</message>
+    
+    <!-- Delete Action -->	
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_LABEL">Delete</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DESC">Delete the selected file(s)</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_TITLE">Deletion</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIAOLG_CONFIRM">Do you really want to delete selected log files?\n\nThe delete process may fail if one a the selected files is currently in use.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_ERROR_GRAVE">A fatal error has occurred on the server.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_ERROR">An error occurred on the server. One or more files have not been deleted.\n\nThese files may be currently in use or have already been deleted.</message>
+
+    <!-- Purge Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE">Delete</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_LABEL">Delete old logs</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DESC">Remove obsolete log files (at least 12 days old).</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_CONFIRM">Do you want to delete all files older than 12 days?</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_SERVER_ERROR">An error occurred on the server.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_AMOUNT">log files have been removed</message>	
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_NONE">There is no log that is older than 12 days.</message>
+    	
+    
+    <!-- Log level tool -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_LABEL">Configuration</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_DESC">This tool allows you to modify for the runtime the log level category by category.</message>        	
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_SERVER_ERROR">An error occurred: the modifications might have not been taken into account.</message>
+    
+    <!-- Debug action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_LABEL">Change to DEBUG</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_DESC">Change the log level of the selected category to "debug".</message>    	
+
+    <!-- Warn action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_LABEL">Change to WARNING</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_DESC">Change the log level of the selected category to "warning".</message>    
+    
+    <!-- Info action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_LABEL">Change to INFO</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_DESC">Change the log level of the selected category to "info".</message>    
+    
+    <!-- Error action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_LABEL">Change to  ERROR</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_DESC">Change the log level of the selected category to "error".</message>    
+    
+    <!-- Force action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_LABEL">Force inheritance</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_DESC">Change the log level of the selected category to "force".</message>
+    
+    <!-- Inherit action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_LABEL">Change to INHERIT</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_DESC">Change the log level of the selected category to "inherit".</message>
+    
+
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TITLE">Logs</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP">Help</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP_TEXT">This screen allows you to display log files and remove obsolete ones.&lt;br/&gt;&lt;br/&gt;If your log files are large and you are in production, remember to switch to 'ERROR' log level in 'WEB-INF\\log4j.xml' files.&lt;br/&gt;&lt;br/&gt;You can also change log level temporally at runtime using the configuration button.</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE">Management</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_QUIT">Quit</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_VIEW">View</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW">Display file</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW_CONFIRM">The file you are trying to display is large and cannot be sent without compression. Do you want to download the compressed file ?</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DOWNLOAD">Download file(s)</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE">Delete file(s)</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_CONFIRM">Do you really want to delete selected log files?\n\nThe delete process may fail if one a the selected files is currently in use.</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR_GRAVE">A fatal error has occurred on the server. The current page should be refreshed.</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR">An error occurred on the server. One or more files have not been deleted.\n\nThese files may be currently in use or have already been deleted. The current page should be refreshed.</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE">Remove obsolete log files</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_CONFIRM">Do you want to delete all files older than 12 days?</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_ERROR_GRAVE">An error occurred on the server. The current page should be refreshed.</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_DONE">log files have been removed</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_NAME">Name</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_DATE">Date</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_SIZE">Size</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_GROUP_OTHERS">Log files with no date</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_LEVEL">Configuration</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP2_TEXT">This screen allows you to modify for the runtime the log level category by category.&lt;br/&gt;&lt;br/&gt;To modify permanently the log level you can configure the 'WEB-INF\\log4j.xml' file.</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_CONFIG_LOGKITROOT">Root</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_DEBUG">Change to DEBUG</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_INFO">Change to INFO</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_WARN">Change to WARNING</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_ERROR">Change to ERROR</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_INHERIT">Inherit mode</message>
 	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_FORCE">Force inheritance</message>
-	<message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_ERROR">An error occurred: modifications may not have been done.\nThe current page should be refreshed.</message>
 
 	<!-- ADMINITRATOR SYSTEM -->
 	<message key="PLUGINS_CORE_ADMINISTRATOR_SYSTEM_LABEL">Access</message>
@@ -833,12 +878,77 @@
     <message key="PLUGINS_CMS_HELPER_ENTERURL_LABEL">Address</message>
     <message key="PLUGINS_CMS_HELPER_ENTERURL_OK">Ok</message>
     <message key="PLUGINS_CMS_HELPER_ENTERURL_CANCEL">Cancel</message>
-	
-	<!-- +
+    
+    <!--+
+        | MESSAGES TRACKER
+        + -->
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_LABEL">Bus message tracker</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_DESCRIPTION">See bus messages</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_FOOTER">See Help for details</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_LABEL">Clear messages</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION">Click here to clear messages from message tracker.</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION2">Action inactive as message tracker window is not opened</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_FOOTER">See Help for détails</message>
+    
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_ID">N°</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_CREATIONDATE">Creation date</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_FIREDATE">Fire date</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_TYPE">Type</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_TARGET">Target</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_CALLSTACK">Creator call stack</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_NOTARGET">&amp;lt;no target&amp;gt;</message>
+    
+    <!--+
+        | REQUESTS TRACKER
+        + -->
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_LABEL">Server request tracker</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_DESCRIPTION">See messages sent to server</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_FOOTER">See Help for details</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_LABEL">Clear requests</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION">Click here to clear messages from message tracker.</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION2">Action inactive as message tracker window is not opened</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_FOOTER">See Help for détails</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_MESSAGE">Select request on the left to display details.</message>
+    
+    <message key="REQUESTSTRACKER_TOOL_COL_ID">N°</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE">Type</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE_ASYNC">Asynchronous</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE_SYNC">Synchronous</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_DATE">Date</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_DURATION">Duration</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_SIZE">Size</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN">Return</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_OK">Ok</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_CANCELED">Canceld</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_FAILURE">Failure</message>
+    
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_ID">N°</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_TYPE">Type</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VALUE">Call</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VAL1">Method</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VAL2">Url</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PLUGIN">Plugin</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_WORKSPACE">Workspace</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCROLE">Extension role</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCID">Component id</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCMETHOD">Method</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_URL">Address</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY">Priority</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_LONG_REQUEST">Long</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_SYNCHRONOUS">Synchronous</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_MAJOR">Major</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_NORMAL">Normal</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_MINOR">Minor</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_TYPE">Return</message>
+
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_URL">Url</message>
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_PARAMETERS">Parameters</message>
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_RESPONSE">Response</message>
+    
+    
+    <!-- +
          | Workspace
          + -->
-    <message key="WORKSPACE_AMETYS_MAIN_ERROR_NOJS">This application can't work without javascript</message>
-    <message key="WORKSPACE_AMETYS_SPLASHSCREEN_LOADING">Loading. Please wait ... </message>
     <message key="WORKSPACE_AMETYS_SPLASHSCREEN_APP_AMETYS_VERSION">powered by Ametys </message>
 	
 </catalogue>
Index: main/plugin-core/i18n/messages_fr.xml
===================================================================
--- main/plugin-core/i18n/messages_fr.xml	(revision 31811)
+++ main/plugin-core/i18n/messages_fr.xml	(working copy)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-   Copyright 2014 Anyware Services
+   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.
@@ -15,7 +15,7 @@
    limitations under the License.
    -->
 <catalogue xml:lang="fr">
-
+    
     <!-- ADMINISTRATOR PASSWORD -->
     <message key="PLUGINS_CORE_ADMINISTRATOR_PASSWORD_LABEL">Mot de passe</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_PASSWORD_DESCRIPTION">Modifier le mot de passe du compte 'admin'</message>
@@ -200,40 +200,75 @@
     <message key="PLUGINS_CORE_ADMINISTRATOR_PLUGINS_CHANGES_ERROR">Les changements n'ont pas été effectués.</message>
     
     <!-- ADMINITRATOR LOGS -->
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LABEL">Journaux</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DESCRIPTION">Visualiser les journaux de l'application</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TITLE">Journaux</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP">Aide</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP_TEXT">Cet écran vous permet de visualiser les fichiers de logs et aussi de supprimer les fichiers obsolètes.&lt;br/&gt;&lt;br/&gt;Si vos fichiers de logs ont une taille élevée et que vous êtes en production, pensez à augmenter le niveau de logs en mode 'ERROR' dans le fichier WEB-INF\\log4j.xml.&lt;br/&gt;&lt;br/&gt;Vous pouvez aussi changer temporairement le niveau de log pour l'execution en utilisant le bouton Configuration.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE">Gestion</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_QUIT">Quitter</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_VIEW">Visualisation</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW">Voir le fichier</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW_CONFIRM">Le fichier que vos souhaitez visualiser a une taille élevée et ne peut être envoyé sans compression pour éviter la saturation du serveur. Voulez-vous télécharger ce fichier en version compressée ?</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DOWNLOAD">Télécharger le(s) fichier(s)</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE">Effacer le(s) fichier(s)</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_CONFIRM">Etes-vous sûr de vouloir effacer le(s) journal(aux) sélectionné(s) ?\n\nIl est possible que l'opération échoue si un fichier à supprimer est le fichier de log actuel.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR_GRAVE">Une erreur est survenue sur le serveur. Il est conseillé d'actualiser la page avant de continuer.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR">Une erreur est survenue sur le serveur. Un ou plusieurs fichiers n'ont pas été supprimés.\n\nCes fichiers sont peut-être en cours d'utilisation ou ont déjà été supprimés. Il est conseillé d'actualiser la page avant de continuer.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE">Purger les journaux</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_CONFIRM">Etes-vous sûr de vouloir effacer tous les journaux datés de plus de 12 jours ?</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_ERROR_GRAVE">Une erreur est survenue sur le serveur. Il est conseillé d'actualiser la page avant de continuer.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_DONE">fichiers de journal ont été effacés par la purge</message>
+    
+    <!-- Log Tool -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LABEL">Visualisation</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_DESC">Cet outil permet de visualiser, effacer, télécharger et purger les journaux.</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_NAME">Nom</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_DATE">Date</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_SIZE">Taille</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_GROUP_OTHERS">Journaux non datés</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_LEVEL">Configuration</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP2_TEXT">Cet écran vous permet de modifier pour le temps de l'execution le niveau de logs catégorie par catégorie.&lt;br/&gt;&lt;br/&gt;Pour modifier de manière permanente le niveau de logs, configurez le fichier WEB-INF\\log4j.xml.</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_CONFIG_LOGKITROOT">Racine</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_DEBUG">Passer en DEBUG</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_INFO">Passer en INFO</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_WARN">Passer en WARNING</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_ERROR">Passer en ERROR</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_CATEGORY">Journaux</message>
+    
+    <!-- View Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_LABEL">Voir</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DESC">Voir le fichier sélectionné</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DIALOG_TITLE">Voir le fichier</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DIALOG_CONFIRM">Le fichier que vos souhaitez visualiser a une taille élevée et ne peut être envoyé sans compression pour éviter la saturation du serveur. Voulez-vous télécharger ce fichier en version compressée ?</message>
+    
+    <!-- Download Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_LABEL">Télécharger</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_DESC">Télécharger le ou les fichier(s) sélectionné(s)</message>
+    
+    <!-- Purge Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE">Purge</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_LABEL">Purger les journaux</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DESC">Effacer les journaux datés de plus de 12 jours.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DIALOG_TITLE">Purge</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DIALOG_CONFIRM">Etes-vous sûr de vouloir effacer tous les journaux datés de plus de 12 jours ?</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_ERROR_GRAVE">Une erreur est survenue sur le serveur.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_AMOUNT">fichiers de journal ont été effacés par la purge</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_NONE">Aucun journal n'est daté de plus de 12 jours.</message>
+    
+    <!-- Delete Action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_LABEL">Supprimer</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DESC">Supprimer le(s) fichier(s) sélectionnés</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_TITLE">Suppression</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_CONFIRM">Etes-vous sûr de vouloir effacer le(s) journal(aux) sélectionné(s) ?\n\nIl est possible que l'opération échoue si un fichier à supprimer est le fichier de log actuel.</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_ERROR">Une erreur est survenue sur le serveur. Un ou plusieurs fichiers n'ont pas été supprimés.\n\nCes fichiers sont peut-être en cours d'utilisation ou ont déjà été supprimés.</message>
+    
+    <!-- Log level tool -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_LABEL">Configuration</message>
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_DESC">Cet outil permet de configurer les niveaux de journalisation suivant les différentes catégories.</message>    
+    <message key="PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_SERVER_ERROR">Une erreur est survenue : les modifications n'ont peut-être pas été prises en compte.</message>
+    
+    <!-- Debug action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_LABEL">Passer en DEBUG</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_DESC">Changer le niveau de log de la catégorie sélectionnée en "debug".</message>
+    
+    <!-- Info action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_LABEL">Passer en INFO</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_DESC">Changer le niveau de log de la catégorie sélectionnée en "info".</message>
+    
+    <!-- Warn action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_LABEL">Passer en WARNING</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_DESC">Changer le niveau de log de la catégorie sélectionnée en "warning".</message>    
+    
+    <!-- Error action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_ERROR_LABEL">Passer en ERROR</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_ERROR_DESC">Changer le niveau de log de la catégorie sélectionnée en "error".</message>  
+
+    <!-- Force action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_LABEL">Forcer l'héritage</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_DESC">Forcer l'héritage de niveau de log de la catégorie sélectionnée.</message>
+    
+    <!-- Inherit action -->
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_LABEL">Hériter le mode</message>  
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_DESC">Changer le niveau de log de la catégorie sélectionnée à "héritage".</message> 
+        
+    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE">Gestion</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_INHERIT">Hériter le mode</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_FORCE">Forcer l'héritage</message>
-    <message key="PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_ERROR">Une erreur est survenue : les modifications n'ont peut-être pas été prises en compte.\nIl est conseillé d'actualiser la page avant de continuer.</message>
-
+    
     <!-- ADMINITRATOR SYSTEM -->
     <message key="PLUGINS_CORE_ADMINISTRATOR_SYSTEM_LABEL">Accès</message>
     <message key="PLUGINS_CORE_ADMINISTRATOR_SYSTEM_DESCRIPTION">Annonce utilisateur</message>
@@ -834,11 +869,84 @@
     <message key="PLUGINS_CMS_HELPER_ENTERURL_OK">Ok</message>
     <message key="PLUGINS_CMS_HELPER_ENTERURL_CANCEL">Annuler</message>
     
+   <!--+
+       | DEV RIGHTS
+       + -->
+    <message key="PLUGINS_CORE_RIGHTS_DEV_CATEGORY">Développeur</message>
+    <message key="PLUGINS_CORE_RIGHT_RIGHTS_DEV_REQUESTTRACKER_LABEL">Requêtes serveurs</message>
+    <message key="PLUGINS_CORE_RIGHT_RIGHTS_DEV_REQUESTTRACKER_DESCRIPTION">Accès à l'outil du suivi des requêtes serveurs</message>
+    <message key="PLUGINS_CORE_RIGHT_RIGHTS_DEV_MESSAGETRACKER_LABEL">Message du bus</message>
+    <message key="PLUGINS_CORE_RIGHT_RIGHTS_DEV_MESSAGETRACKER_DESCRIPTION">Accès à l'outil du suivi des messages du bus</message>
+    
+   <!--+
+       | MESSAGES TRACKER
+       + -->
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_LABEL">Suivi des messages du bus</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_DESCRIPTION">Voir les messages du bus</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_FOOTER">Voir l'aide pour plus de détails</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_LABEL">Effacer les messages affichés</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION">Cliquez sur ce bouton pour effacer les messages du bus actuellement visible dans la vue de suivi.</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION2">Ce bouton est désactivé car la fenêtre de suivi des messages du bus n'est actuellement pas ouverte</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_FOOTER">Voir l'aide pour plus de détails</message>
+    
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_ID">N°</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_CREATIONDATE">Date de creation</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_FIREDATE">Date d'envoi</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_TYPE">Type</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_TARGET">Cible</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_COL_CALLSTACK">Pile d'appel de création</message>
+    <message key="PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_TOOL_NOTARGET">&amp;lt;pas de cible&amp;gt;</message>
+    
+    <!--+
+        | REQUESTS TRACKER
+        + -->
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_LABEL">Suivi des requêtes serveur</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_DESCRIPTION">Voir les messages envoyés au serveur</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_FOOTER">Voir l'aide pour plus de détails</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_LABEL">Effacer les requêtes affichées</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION">Cliquez sur ce bouton pour effacer les messages de requêtes serveur actuellement visible dans la vue de suivi.</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION2">Ce bouton est désactivé car la fenêtre de suivi des requêtes du bus n'est actuellement pas ouverte</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_FOOTER">Voir l'aide pour plus de détails</message>
+    <message key="PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_MESSAGE">Selectionnez une requête dans la partie gauche pour afficher son détail.</message>
+    
+    <message key="REQUESTSTRACKER_TOOL_COL_ID">N°</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE">Type</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE_ASYNC">Asynchrone</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_TYPE_SYNC">Synchrone</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_DATE">Date</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_DURATION">Durée</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_SIZE">Taille</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN">Retour</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_OK">Ok</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_CANCELED">Annulé</message>
+    <message key="REQUESTSTRACKER_TOOL_COL_RETURN_FAILURE">Echec</message>
+    
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_ID">N°</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_TYPE">Type</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VALUE">Appel</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VAL1">Méthode</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_READABLE_VAL2">Url</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_WORKSPACE">Workspace</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PLUGIN">Plugin</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_URL">Adresse</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCROLE">Rôle extension</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCID">Id composant</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_CCMETHOD">Méthode</message> 
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY">Priorité</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_LONG_REQUEST">Longue</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_SYNCHRONOUS">Synchone</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_MAJOR">Majeure</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_NORMAL">Normale</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_PRIORITY_MINOR">Mineure</message>
+    <message key="REQUESTSTRACKER_TOOL_MESSAGE_COL_TYPE">Retour</message>
+
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_URL">Url</message>
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_PARAMETERS">Paramètres</message>
+    <message key="REQUESTSTRACKER_TOOL_DISPLAYMESSAGE_RESPONSE">Réponse</message>
+
     <!-- +
          | Workspace
          + -->
-    <message key="WORKSPACE_AMETYS_MAIN_ERROR_NOJS">Cette application ne peut pas fonctionner en l'absence de javascript</message>
-    <message key="WORKSPACE_AMETYS_SPLASHSCREEN_LOADING">Chargement en cours. Veuillez patienter ... </message>
     <message key="WORKSPACE_AMETYS_SPLASHSCREEN_APP_AMETYS_VERSION">motorisé par Ametys </message>
          
 </catalogue>
Index: main/plugin-core/plugin.xml
===================================================================
--- main/plugin-core/plugin.xml	(revision 31811)
+++ main/plugin-core/plugin.xml	(working copy)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-   Copyright 2014 Anyware Services
+   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.
@@ -1013,11 +1013,6 @@
         </extension-point>
         
         
-    <!--  TODO REMOVE THIS -->    
-        <extension-point id="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                		 class="org.ametys.runtime.plugins.core.ui.item.DesktopManager" 
-                		 config="/WEB-INF/param/workspace-admin.xml"/>
-
         <extension-point id="org.ametys.runtime.plugins.core.dispatcher.DispatchProcessExtensionPoint" 
                 		 class="org.ametys.runtime.plugins.core.dispatcher.DispatchProcessExtensionPoint"/>
                 		 
@@ -1307,174 +1302,740 @@
         </extensions>
     </feature>
     
-    
-
     <feature name="runtime.admin">
         <!-- 
-            This feature defines screen that may be uses in the administrator area
+            This feature defines the administration tabs and the ui for its tools 
          -->
         <extensions>
+            
             <!-- +
-                 |  ADMIN PASSWORD
+                 |  PASSWORD
                  + -->
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Password"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.password">
-                <!-- 
-                    This interaction allows the administrator to change its password
-                 -->
-				<class name="Ametys.plugins.core.administration.Password.act">
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_PASSWORD_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_PASSWORD_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/password/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/password/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/password/icon_large.png</param>
-				</class>   
-				<scripts>
-					<file>js/Ametys/plugins/core/administration/Password.js</file>
-				</scripts> 				   
+            <extension id="org.ametys.runtime.plugins.core.Password"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.Password.act</action>                    
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_PASSWORD_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_PASSWORD_DESCRIPTION</description>
+                    
+                    <icon-small file="true">img/administrator/password/password_16.png</icon-small>
+                    <!-- icon-medium file="true">img/administrator/password/icon_small.png</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/password/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/Password.js</file>
+                </scripts>
             </extension>
-            
+                 
             <!-- +
-                 |  ADMIN CONFIGURATION
+                 |  CONFIGURATION
                  + -->
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Config"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.config">
+            <extension  id="org.ametys.runtime.plugins.core.Config"
+                        point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                        class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
                     This interaction allows the administrator to change the main configuration of the application
                  -->
-				<class name="redirect">
-					<param name="Link">administrator/config/edit.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_CONFIG_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_CONFIG_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/config/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/config/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/config/icon_large.png</param>
-				</class>    				   
-                <Url>administrator/config/edit\.html</Url>
+				<class name="Ametys.ribbon.element.ui.ButtonController">
+					<action>Ametys.plugins.core.administration.Config.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_CONFIG_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_CONFIG_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/config/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/config/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/config/icon_large.png</icon-large>
+				</class>
+				<scripts>
+                    <file>js/Ametys/plugins/core/administration/Config.js</file>
+                </scripts>    				   
             </extension>
             
             <!-- +
-                 |  ADMIN JVMSTATUS
+                 |  JVMSTATUS
                  + -->
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.JVMStatus"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.status">
+            <extension  id="org.ametys.runtime.plugins.core.JVMStatus"
+                        point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                        class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
                     This interaction allows the administrator to check the status of the JVM
                  -->
-				<class name="redirect">
-					<param name="Link">administrator/jvmstatus/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_STATUS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_STATUS_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/jvmstatus/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/jvmstatus/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/jvmstatus/icon_large.png</param>
-				</class>    				   
-                <Url>administrator/jvmstatus/view\.html</Url>
-            </extension> 
-
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.JVMStatus.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_STATUS_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_STATUS_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/jvmstatus/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/jvmstatus/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/jvmstatus/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/JVMStatus.js</file>
+                </scripts>                     
+            </extension>
+                        
             <!-- +
-                 |  ADMIN PLUGINS
+                 |  LOGS
                  + -->           
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Plugins"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.plugins">
+            
+            <!-- Logs tab -->
+            <extension id="org.ametys.runtime.plugins.core.LogsTab"
+                       point="org.ametys.runtime.ribbon.RibbonTabsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.tab.TabController">
+                    <tool-role>^(uitool-admin-logs)$</tool-role>
+                </class>
+            </extension>
+            
+            <!-- Logs level tab -->
+            <extension id="org.ametys.runtime.plugins.core.LogsLevelTab"
+                       point="org.ametys.runtime.ribbon.RibbonTabsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.tab.TabController">
+                    <tool-role>^(uitool-admin-logslevel)$</tool-role>
+                </class>
+            </extension>
+            
+            <!-- Tools -->
+            <extension id="org.ametys.runtime.plugins.core.Logs"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
-                    This interaction allows the administrator to see plugins. Usefull for developpers.
+                    This button opens the logs' visualization tool
                  -->
-                <class name="redirect">
-					<param name="Link">administrator/plugins/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_PLUGINS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_PLUGINS_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/plugins/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/plugins/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/plugins/icon_large.png</param>
-				</class>    				   
-                <Url>administrator/plugins/view\.html</Url>
-            </extension> 
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-admin-logs</opentool-role>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_DESC</description>
+                    
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/tool/LogsTool.js</file>
+                </scripts>
+            </extension>
             
-            <!-- +
-                 |  ADMIN LOGS
-                 + -->           
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Logs"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.logs">
+            <extension id="org.ametys.runtime.plugins.core.LogsLevel"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
-                    This interaction allows the administrator to see and manage logs
+                    This button opens the logs' configuration tool
                  -->
-                <class name="redirect">
-					<param name="Link">administrator/logs/view.html</param>
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-admin-logslevel</opentool-role>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_DESC</description>
+                    
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/tool/LogsLevelTool.js</file>
+                </scripts>
+            </extension>
+            
+            <!-- Factories -->
+            <extension id="org.ametys.runtime.plugins.core.logs.LogsFactory"
+                       point="org.ametys.runtime.ui.UIToolsFactoriesManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-admin-logs</role>
+                    <toolClass>Ametys.plugins.core.administration.tool.LogsTool</toolClass>
+                    
+                    <title i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LABEL</title>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_DESC</description>
+                    
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                    
+                    <default-location>c</default-location>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/tool/LogsTool.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logs.LogsLevelFactory"
+                       point="org.ametys.runtime.ui.UIToolsFactoriesManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-admin-logslevel</role>
+                    <toolClass>Ametys.plugins.core.administration.tool.LogsLevelTool</toolClass>
+                    
+                    <title i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_LABEL</title>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_DESC</description>
+                    
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                    
+                    <default-location>c</default-location>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/tool/LogsLevelTool.js</file>
+                </scripts>
+            </extension> 
+            
+            <!-- Contextual actions -->
+            <extension id="org.ametys.runtime.plugins.core.logs.View"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.view</action>
+                    <selection-target-type>^logfile$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                </scripts>
+            </extension>  
+            
+            <extension id="org.ametys.runtime.plugins.core.logs.Download"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.download</action>
+                    <selection-target-type>^logfile$</selection-target-type>
+
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_DOWNLOAD_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                </scripts>
+            </extension>                        
+            
+            <extension id="org.ametys.runtime.plugins.core.logs.Delete"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.delete</action>
+                    <selection-target-type>^logfile$</selection-target-type>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                </scripts>
+            </extension>                        
+                                    
+            <extension id="org.ametys.runtime.plugins.core.logs.Purge"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.purge</action>
+                
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Debug"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>DEBUG</level>
+                                        
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_DEBUG_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Info"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>INFO</level>
+                
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INFO_DESC</description>
 
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/logs/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/logs/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/logs/icon_large.png</param>
-				</class>    				   
-                <Url>administrator/logs/view\.html</Url>
-            </extension>             
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Warn"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>WARN</level>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_WARN_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Error"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>ERROR</level>
+                
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_ERROR_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_ERROR_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Inherit"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>INHERIT</level>
+                
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_INHERIT_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
+            
+            <extension id="org.ametys.runtime.plugins.core.logslevel.Force"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.plugins.core.administrator.logs.LogsClientSideElement">
+                <class name="Ametys.plugins.core.administration.controller.LogLevelController">
+                    <action>Ametys.plugins.core.administration.actions.LogsActions.changeLogLevel</action>
+                    <selection-target-type>^(log-category)$</selection-target-type>
+                    <selection-enable-multiselection>false</selection-enable-multiselection>
+                    
+                    <level>FORCE</level>
+                
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_LOGS_LEVEL_FORCE_DESC</description>
+
+                    <icon-small file="true">img/administrator/logs/icon_16x16.png</icon-small>
+                    <icon-medium file="true">img/administrator/logs/icon_32x32.png</icon-medium>
+                    <icon-large file="true">img/administrator/logs/icon_48x48.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/actions/LogsActions.js</file>
+                    <file>js/Ametys/plugins/core/administration/controller/LogLevelController.js</file>
+                </scripts>
+            </extension>
 
             <!-- +
-                 |  ADMIN SYSTEM
+                 |  SYSTEM
                  + -->           
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.System"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.system">
+            <extension id="org.ametys.runtime.plugins.core.System"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
                     This interaction allows the administrator to handle the system (maintenance mode, welcome message...)
                  -->
-				<class name="redirect">
-					<param name="Link">administrator/system/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_SYSTEM_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_SYSTEM_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/system/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/system/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/system/icon_large.png</param>
-				</class>   
-                <Url>administrator/system/view\.html</Url>
-            </extension>   
+                 <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.System.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_SYSTEM_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_SYSTEM_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/system/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/system/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/system/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/System.js</file>
+                </scripts>
+            </extension> 
             
             <!-- +
-                 |  ADMIN SUPER USER
+                 |  SUPER USER
                  + -->           
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.SuperUser"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.administrator.superuser">
+            <extension id="org.ametys.runtime.plugins.core.SuperUser"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
                 <!-- 
                     This interaction allows the administrator to handle the system (maintenance mode, welcome message...)
                  -->
-				<class name="Ametys.plugins.core.administration.SuperUser.act">
-					<param name="label" i18n="true">PLUGINS_CORE_ADMINISTRATOR_SUPERUSER_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_ADMINISTRATOR_SUPERUSER_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/superuser/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/superuser/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/superuser/icon_large.png</param>
-				</class>   
+                 <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.SuperUser.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_SUPERUSER_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_SUPERUSER_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/superuser/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/superuser/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/superuser/icon_large.png</icon-large>
+                </class>
                 <scripts>
                     <file>js/Ametys/plugins/core/administration/SuperUser.js</file>
                     <file>js/Ametys/runtime/uihelper/SelectUser.js</file>
-				</scripts> 	
-				<css>
-					<file>css/selectuser.css</file>
-				</css> 		
+                </scripts>
+                <css>
+                    <file>css/selectuser.css</file>
+                </css>
             </extension>   
+            
+            <!-- +
+                 |  USERS 
+                 + -->
+            <extension id="org.ametys.runtime.plugins.core.Users"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <!-- 
+                    This interaction allow to handle users (read or read/write)
+                 -->
+                 <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.Users.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_USERS_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_USERS_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/users/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/users/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/users/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/Users.js</file>
+                </scripts>
+            </extension>
+          
+            <!-- +
+                 |  GROUPS 
+                 + -->
+            <extension id="org.ametys.runtime.plugins.core.Groups"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <!-- 
+                    This interaction allow to handle groups (read or read/write)
+                 -->
+                 <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.Groups.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_GROUPS_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_GROUPS_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/groups/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/groups/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/groups/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/Groups.js</file>
+                </scripts>
+            </extension>
+            
+            <!-- +
+                 |  PROFILES
+                 + -->           
+            <extension id="org.ametys.runtime.plugins.core.Profiles"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <!-- 
+                    This extensions display the profile screen
+                 -->
+                 <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.Profiles.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_RIGHTS_PROFILES_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_RIGHTS_PROFILES_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/profiles/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/profiles/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/profiles/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/Profiles.js</file>
+                </scripts>
+            </extension>
+            
+            <!-- +
+                 |  PLUGINS AND WORKSPACES
+                 + -->           
+            <extension id="org.ametys.runtime.plugins.core.Plugins"  
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager" 
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <!-- 
+                    This interaction allows the administrator to see plugins. Useful for developers.
+                 -->
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.administration.Plugins.act</action>
+                    
+                    <label i18n="true">PLUGINS_CORE_ADMINISTRATOR_PLUGINS_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_ADMINISTRATOR_PLUGINS_DESCRIPTION</description>
+                    
+                    <!-- icon-small file="true">img/administrator/plugins/icon_dock.png</icon-small>  FIXME -->
+                    <!-- icon-medium file="true">img/administrator/plugins/icon_medium.gif</icon-medium FIXME -->
+                    <icon-large file="true">img/administrator/plugins/icon_large.png</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/administration/Plugins.js</file>
+                </scripts>
+            </extension> 
                
         </extensions>
     </feature>
     
+     <!-- +  
+         |  MESSAGES TRACKER    
+         + -->     
+    <feature name="userinterface.messages-tracker">
+        <extensions>
+            <extension id="org.ametys.runtime.userinterface.MessageTrackerControlMenu"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.SimpleMenu">
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController"/>
+                <menu-items>
+                    <item ref="org.ametys.runtime.userinterface.MessageTrackerControl" primaryItem="true"/>
+                    <item ref="org.ametys.runtime.userinterface.MessageTrackerControl.clear"/>
+                </menu-items>
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.MessageTrackerControl"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-messagestracker</opentool-role>
+                    
+                    <label i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_DESCRIPTION</description>
+                    <help>org.ametys.runtime.messagetracker</help>
+                    
+                    <icon-small file="true">img/messages/messages_16.png</icon-small>
+                    <icon-medium file="true">img/messages/messages_32.png</icon-medium>
+                    <icon-large file="true">img/messages/messages_48.png</icon-large>
+                </class>   
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>                 
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.MessageTrackerControl.clear"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.system.messagetracker.MessageTrackerTool.removeAll</action>
+
+                    <tool-role>uitool-messagestracker</tool-role>
+                    <tool-enable-on-status>active</tool-enable-on-status>
+                    <tool-description-inactive i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION2</tool-description-inactive>
+
+                    <label i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_CLEAR_DESCRIPTION</description>
+                    <icon-small file="true">img/messages/delete_16.gif</icon-small>
+                    <icon-medium file="true">img/messages/delete_16.gif</icon-medium>
+                    <icon-large file="true">img/messages/delete_16.gif</icon-large>
+                </class>                       
+                <scripts>
+                    <file>js/Ametys/plugins/core/system/messagetracker/MessageTrackerTool.js</file>
+                    <file>js/Ametys/plugins/core/system/messagetracker/MessageTrackerTool/MessageEntry.js</file>
+                </scripts>
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.MessageTrackerFactory"
+                       point="org.ametys.runtime.ui.UIToolsFactoriesManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-messagestracker</role>
+                    <toolClass>Ametys.plugins.core.system.messagetracker.MessageTrackerTool</toolClass>
+                    
+                    <title i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_LABEL</title>
+                    <description i18n="true">PLUGINS_CORE_TOOLS_MESSAGES_TRACKER_DESCRIPTION</description>
+                    <help>org.ametys.runtime.messagetracker</help>
+                    <icon-small file="true">img/messages/messages_16.png</icon-small>
+                    <icon-medium file="true">img/messages/messages_32.png</icon-medium>
+                    <icon-large file="true">img/messages/messages_48.png</icon-large>
+                    
+                    <default-location>b</default-location>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/system/messagetracker/MessageTrackerTool.js</file>
+                    <file>js/Ametys/plugins/core/system/messagetracker/MessageTrackerTool/MessageEntry.js</file>
+                </scripts>
+                <css>
+                    <file>css/messagetracker.css</file>
+                </css>
+            </extension>
+        </extensions>
+    </feature>
+    
+    <!-- +  
+         |  REQUESTS TRACKER    
+         + -->     
+    <feature name="userinterface.requests-tracker">
+        <extensions>
+            <extension id="org.ametys.runtime.userinterface.RequestTrackerControlMenu"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.SimpleMenu">
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController"/>
+                <menu-items>
+                    <item ref="org.ametys.runtime.userinterface.RequestTrackerControl" primaryItem="true"/>
+                    <item ref="org.ametys.runtime.userinterface.RequestTrackerControl.clear"/>
+                </menu-items>
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.RequestTrackerControl"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-requeststracker</opentool-role>
+                    
+                    <label i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_LABEL</label>
+                    <default-description i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_DESCRIPTION</default-description>
+                    <help>org.ametys.runtime.requesttracker</help>
+                    
+                    <icon-small file="true">img/requests/requests_16.png</icon-small>
+                    <icon-medium file="true">img/requests/requests_32.png</icon-medium>
+                    <icon-large file="true">img/requests/requests_48.png</icon-large>
+                </class> 
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>                  
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.RequestTrackerControl.clear"
+                       point="org.ametys.runtime.ribbon.RibbonControlsManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.core.system.requesttracker.RequestTrackerTool.removeAll</action>
+                    
+                    <tool-role>uitool-requeststracker</tool-role>
+                    <tool-enable-on-status>active</tool-enable-on-status>
+                    <tool-description-inactive i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION2</tool-description-inactive>
+                    
+                    <label i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_LABEL</label>
+                    <description i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_DESCRIPTION</description>
+                    <description-footer i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_CLEAR_FOOTER</description-footer>
+                    <icon-small file="true">img/requests/delete_16.gif</icon-small>
+                    <icon-medium file="true">img/requests/delete_16.gif</icon-medium>
+                    <icon-large file="true">img/requests/delete_16.gif</icon-large>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool.js</file>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool/RequestEntry.js</file>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool/MessageEntry.js</file>
+                </scripts>
+                <right context-prefix="/contributor">CORE_Rights_MessageTracker</right>
+            </extension>
+            <extension id="org.ametys.runtime.userinterface.RequestTrackerFactory"
+                       point="org.ametys.runtime.ui.UIToolsFactoriesManager"
+                       class="org.ametys.runtime.ui.StaticClientSideElement">
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-requeststracker</role>
+                    <toolClass>Ametys.plugins.core.system.requesttracker.RequestTrackerTool</toolClass>
+                    
+                    <title i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_LABEL</title>
+                    <description i18n="true">PLUGINS_CORE_TOOLS_REQUESTS_TRACKER_DESCRIPTION</description>
+                    <help>org.ametys.runtime.requesttracker</help>
+                    <icon-small file="true">img/requests/requests_16.png</icon-small>
+                    <icon-medium file="true">img/requests/requests_32.png</icon-medium>
+                    <icon-large file="true">img/requests/requests_48.png</icon-large>
+                    
+                    <default-location>b</default-location>
+                </class>               
+                <scripts>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool.js</file>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool/RequestEntry.js</file>
+                    <file>js/Ametys/plugins/core/system/requesttracker/RequestTrackerTool/MessageEntry.js</file>
+                </scripts>
+                <css>
+                    <file>css/requesttracker.css</file>
+                </css>
+            </extension>
+        </extensions>
+    </feature>    
+    
+    <feature name="anycontent_rights">
+        <extensions>
+            <extension point="org.ametys.runtime.plugins.core.right.RightsExtensionPoint"
+                       id="core.dev.rights.requesttracker">
+                <right id="CORE_Rights_RequestTracker">
+                    <label>PLUGINS_CORE_RIGHT_RIGHTS_DEV_REQUESTTRACKER_LABEL</label>
+                    <description>PLUGINS_CORE_RIGHT_RIGHTS_DEV_REQUESTTRACKER_DESCRIPTION</description>
+                    <category>PLUGINS_CORE_RIGHTS_DEV_CATEGORY</category>
+                </right>
+            </extension>
+            
+            <extension point="org.ametys.runtime.plugins.core.right.RightsExtensionPoint"
+                       id="core.dev.rights.messagetracker">
+                <right id="CORE_Rights_MessageTracker">
+                    <label>PLUGINS_CORE_RIGHT_RIGHTS_DEV_MESSAGETRACKER_LABEL</label>
+                    <description>PLUGINS_CORE_RIGHT_RIGHTS_DEV_MESSAGETRACKER_DESCRIPTION</description>
+                    <category>PLUGINS_CORE_RIGHTS_DEV_CATEGORY</category>
+                </right>
+            </extension>
+        </extensions>
+    </feature>    
+    
     <!-- +
     	 |  VERSIONS
          + -->    
@@ -1487,35 +2048,6 @@
         </extensions>
     </feature>
 
-     <!-- +
-         |  USERS
-         + -->   
-    <feature name="runtime.users">
-        <!-- 
-            This feature contains only the interaction for handling users
-         -->
-        <extensions>
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Users"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.users">
-                <!-- 
-                    This interaction allow to handle users (read or read/write)
-                 -->
-                <class name="redirect">
-					<param name="Link">administrator/users/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_USERS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_USERS_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/users/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/users/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/users/icon_large.png</param>
-				</class>    				   
-                <Url>users/view\.html</Url>
-            </extension>      
-        </extensions>
-    </feature>
-    
     <feature name="runtime.users.rights">
         <!-- 
             This feature brings the rights needed to manage users
@@ -1826,35 +2358,6 @@
 		</extensions>
     </feature>
         
-    <!-- +
-         |  GROUPS
-         + -->   
-    <feature name="runtime.groups">
-        <!-- 
-            This feature contains only the interaction for handling groups
-         -->
-        <extensions>
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.Groups"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.groups">
-                <!-- 
-                    This interaction allow to handle groups (read or read/write)
-                 -->
-                <class name="redirect">
-					<param name="Link">administrator/groups/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_GROUPS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_GROUPS_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/groups/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/groups/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/groups/icon_large.png</param>
-				</class>    				   
-                <Url>groups/view\.html</Url>
-            </extension>      
-        </extensions>
-    </feature>
-    
     <feature name="runtime.groups.rights">
         <!-- 
             This feature brings the rights needed to manage groups
@@ -2165,35 +2668,6 @@
         </extensions>
     </feature>
     
-    <!-- +
-         |  RIGHTS
-         + -->   
-    <feature name="runtime.rights">
-        <!-- 
-            This feature contains interactions to handle rights based on profiles
-         -->
-        <extensions>
-            <extension  point="org.ametys.runtime.workspaces.admin.DesktopManager" 
-                        id="org.ametys.runtime.plugins.core.administrator.right.Profiles"
-                        class="org.ametys.runtime.plugins.core.ui.item.StaticAdminClientSideElement"
-                        logger="org.ametys.runtime.plugins.core.ui.rights.profiled.profile">
-                <!-- 
-                    This extensions display the profile screen
-                 -->
-                <class name="redirect">
-					<param name="Link">administrator/profiles/view.html</param>
-
-					<param name="label" i18n="true">PLUGINS_CORE_RIGHTS_PROFILES_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_CORE_RIGHTS_PROFILES_DESCRIPTION</param>
-					<param name="icon-small" file="true">img/administrator/profiles/icon_dock.png</param>
-					<param name="icon-medium" file="true">img/administrator/profiles/icon_medium.gif</param>
-					<param name="icon-large" file="true">img/administrator/profiles/icon_large.png</param>
-				</class>    				   
-                <Url>administrator/profiles/view\.html</Url>
-            </extension>    
-        </extensions>
-    </feature>
-    
     <feature name="runtime.rights.rights">
         <!-- 
             This feature declares rights for handling rights screens
Index: main/plugin-core/resources/css/administrator/logs.css
===================================================================
--- main/plugin-core/resources/css/administrator/logs.css	(revision 31873)
+++ main/plugin-core/resources/css/administrator/logs.css	(working copy)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2012 Anyware Services
+ *  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.
Index: main/plugin-core/resources/css/messagetracker.css
===================================================================
--- main/plugin-core/resources/css/messagetracker.css	(revision 31873)
+++ main/plugin-core/resources/css/messagetracker.css	(nonexistent)
@@ -1,30 +0,0 @@
-/*
- *  Copyright 2010 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.
- */
- 
-.callstack .filename {
-	color: #2a00ff;
-	text-decoration: none;
-}
-.callstack .filename:hover {
-    text-decoration: underline;
-}
-.callstack .line {
-	color: #9500ab;
-    font-style: italic;
-}
-.callstack .method {
-    color: #3f7f7f;
-}
Index: main/plugin-core/resources/css/requesttracker.css
===================================================================
--- main/plugin-core/resources/css/requesttracker.css	(revision 31873)
+++ main/plugin-core/resources/css/requesttracker.css	(nonexistent)
@@ -1,49 +0,0 @@
-/*
- *  Copyright 2010 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.
- */
-
-.message-details .x-panel-body {
-	padding: 5px;
-	font-family:Arial;
-	font-size:11px;
-	padding: 10px;
-	background-color: #FFF !important;
-}
-
-.message-details .x-panel-body div {
-	padding: 0 0 0 10px;
-}
-
-code.resquest-tracker {
-	color: #000000;
-	white-space: nowrap;
-	display: block;
-}
-code.resquest-tracker .tag {
-    color: #3f7f7f;
-}
-code.resquest-tracker .text {
-    color: #000000;
-}
-code.resquest-tracker .attr-name {
-	color: #9500ab;
-}
-code.resquest-tracker .attr-eq {
-    color: #000000;
-}
-code.resquest-tracker .attr-value {
-    color: #2a00ff;
-    font-style: italic;
-}
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Config.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Config.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Config.js	(working copy)
@@ -144,6 +144,12 @@
 		this._bound = true;
 	},
 
+	
+	act: function ()
+	{
+		alert("TODO")
+	},
+	
 	/**
 	 * Creates the main panel
 	 * @return {Ext.panel.Panel} The panel created
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Groups.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Groups.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Groups.js	(working copy)
@@ -68,6 +68,11 @@
 		this.pluginName = pluginName;
 		window.onbeforeunload = Ext.bind(this.checkBeforeQuit, this);
 	},
+	
+	act: function()
+	{
+		alert("TODO");
+	},
 
 	/**
 	 * Create the main screen
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/JVMStatus.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/JVMStatus.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/JVMStatus.js	(working copy)
@@ -84,6 +84,11 @@
 		this.pluginName = pluginName;
 	},
 
+	act: function ()
+	{
+		alert("TODO");
+	},
+	
 	/**
 	 * Create the panel for displaying this screen
 	 */
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Logs.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Logs.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Logs.js	(nonexistent)
@@ -1,886 +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.
- */
-
-/**
- * Class in chage of the log administration screen. See {@link #initialize} and {@link #createPanel}
- * @private
- */
-Ext.define('Ametys.plugins.core.administration.Logs', {
-	singleton: true,
-	
-	/**
-	 * @private
-	 * @property {Number} LOGS_VIEW_VIEW Index of the action VIEW in the VIEW panel
-	 */
-	LOGS_VIEW_VIEW: 0,
-	/**
-	 * @private
-	 * @property {Number} LOGS_VIEW_DOWNLOAD Index of the action DOWNLOAD in the VIEW panel
-	 */
-	LOGS_VIEW_DOWNLOAD: 1,
-	/**
-	 * @private
-	 * @property {Number} LOGS_VIEW_DELETE Index of the action DELETE in the VIEW panel
-	 */
-	LOGS_VIEW_DELETE: 2,
-	/**
-	 * @private
-	 * @property {Number} LOGS_VIEW_PURGE Index of the action PURGE in the VIEW panel
-	 */
-	LOGS_VIEW_PURGE: 3,
-	
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_DEBUG Index of the action DEBUG in the CONF panel
-	 */
-	LOGS_CONF_DEBUG: 4,
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_INFO Index of the action INFO in the CONF panel
-	 */
-	LOGS_CONF_INFO: 5,
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_WARN Index of the action WARN in the CONF panel
-	 */
-	LOGS_CONF_WARN: 6,
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_ERROR Index of the action ERROR in the CONF panel
-	 */
-	LOGS_CONF_ERROR: 7,
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_INHERIT Index of the action INHERIT in the CONF panel
-	 */
-	LOGS_CONF_INHERIT: 8,
-	/**
-	 * @private
-	 * @property {Number} LOGS_CONF_FORCE Index of the action FORCE in the CONF panel
-	 */
-	LOGS_CONF_FORCE: 9,
-
-	/**
-	 * @private
-	 * @property {Number} LOGS_OTHER_QUIT Index of the action QUIT in the all panels
-	 */
-	LOGS_OTHER_QUIT: 10,
-	
-	/**
-	 * @private
-	 * @property {String} pluginName The name of the plugin that declares this class
-	 */
-	/**
-	 * @private
-	 * @property {Ext.Panel} _cardPanel The main card panel 
-	 */
-	/**
-	 * @private
-	 * @property {Ext.grid.Panel} _logs The logs grid
-	 */
-	/**
-	 * @private
-	 * @property {Ext.Container} _contextualPanel The right panel
-	 */
-	/**
-	 * @property {Object[]} _navItems The navigation items
-	 * @private
-	 */
-	_navItems: [
-	    {label: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_VIEW'/>"},
-		{label: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_TAB_LEVEL'/>"}
-	],
-	
-	/**
-	 * @private
-	 * @property {Ametys.admin.rightpanel.NavigationPanel} _nav The navigation panel
-	 */
-	/**
-	 * @private
-	 * @property {Ametys.admin.rightpanel.ActionPanel} _actions The action panel
-	 */
-	/**
-	 * @private
-	 * @property {Ametys.admin.rightpanel.TextPanel} _helpPanel The action panel
-	 */
-	
-	/**
-	 * Initialize information needed
-	 * @param {String} pluginName The name of the plugin that declares this class
-	 */
-	initialize: function (pluginName)
-	{
-		this.pluginName = pluginName;
-	},
-
-	/**
-	 * Creates the main panel for this screen
-	 */
-	createPanel: function ()
-	{
-		this._cardPanel = new Ext.Panel({
-			region:'center',
-			layout:'card',
-			activeItem: 0,
-			
-			id:'system-card-panel',
-
-			border: false,
-			autoScroll : true,
-			
-			items: [this._drawLogsPanel(),
-			        this._drawConfPanel()]
-		});		
-		
-		this._contextualPanel = new Ext.Container({
-			region:'east',
-		
-			cls : 'admin-right-panel',
-			border: false,
-			width: 277,
-		    
-			items: [this._drawNavigationPanel (),
-			        this._drawActionsPanel (),
-			        this._drawHelpPanel ()]
-		});
-		
-		this._onLogsPanelShow();
-		this._onConfHide();
-		
-		return new Ext.Panel({
-			region: 'center',
-			
-			autoScroll: true,
-			
-			cls: 'transparent-panel',
-			border: false,
-			layout: 'border',
-			
-			items: [this._cardPanel, 
-			        this._contextualPanel],
-			
-			layoutConfig: {
-	        	autoWidth: true
-	    	}
-
-		});
-		
-	},
-
-	/**
-	 * @private
-	 * Listener when the log panel is shown
-	 */
-	_onLogsPanelShow: function()
-	{
-		this._helpPanel.items.get(0).show();
-		this._onSelectLog();
-	},
-	/**
-	 * @private
-	 * Listener when the log panel is hidden
-	 */
-	_onLogsPanelHide: function()
-	{
-		this._actions.hideElt(this.LOGS_VIEW_VIEW);
-		this._actions.hideElt(this.LOGS_VIEW_DOWNLOAD);
-		this._actions.hideElt(this.LOGS_VIEW_DELETE);
-		this._actions.hideElt(this.LOGS_VIEW_PURGE);
-		this._helpPanel.items.get(0).hide();
-	},
-	/**
-	 * @private
-	 * Draw the panel displaying the logs
-	 */
-	_drawLogsPanel: function()
-	{
-		var model = Ext.define('Ametys.plugins.core.administrator.Logs.Log', {
-		    extend: 'Ext.data.Model',
-		    fields: [
-		       {name: 'location'},
-		       {name: 'date', type: 'date', dateFormat: Ext.Date.patterns.ISO8601DateTime},
-		       {name: 'size', type: 'int'},
-		       {name: 'file'}
-		    ]
-		});
-
-		var store = Ext.create('Ext.data.Store', {
-			model: 'Ametys.plugins.core.administrator.Logs.Log',
-	        data: { logs: []},
-	        groupField: 'file',
-	        
-	        sortOnLoad: true,
-	        sorters: [ { property: 'date', direction: "DESC" } ],
-	        
-	        proxy: {
-	        	type: 'memory',
-	        	reader: {
-	        		type: 'json',
-	        		root: 'logs', // FIXME to remove in extjs 6
-	        		rootProperty: 'logs'
-	        	}
-	        }
-		});		
-		
-		var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
-		    groupHeaderTpl: '{name}'
-		});
-		
-		this._logs = new Ext.grid.Panel({
-			region: 'center',
-			
-			width: 610,
-			
-			id: 'detail-view-logs',
-			cls: 'detail-view-logs',
-			
-			features: [ groupingFeature ],
-			
-			animCollapse: true,
-			
-			listeners: {'selectionchange': Ext.bind(this._onSelectLog, this),
-						'hide': Ext.bind(this._onLogsPanelHide, this),
-						'show': Ext.bind(this._onLogsPanelShow, this)
-			},
-			
-		    store : store,
-			
-		    multiSelect: true,
-		    simpleSelect: false,
-
-		    hideHeaders : false,
-		    columnmove : false,
-		    columns: [
-		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_NAME'/>", flex: 1, width : 250, menuDisabled : true, sortable: true, dataIndex: 'location'},
-		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_DATE'/>", flex: 0, width : 150, renderer: Ext.util.Format.dateRenderer('d F Y'), menuDisabled : true, sortable: true, dataIndex:'date',  align :'center'},
-		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_SIZE'/>", flex: 0, width : 100, renderer: this._sizeRendered, menuDisabled : true, sortable: true, dataIndex: 'size', align :'right'}
-		    ]
-		});
-		
-		return this._logs;
-	},
-
-	/**
-	 * Listener when configuration panel is shown
-	 * @private
-	 */
-	_onConfShow: function()
-	{
-		this._helpPanel.items.get(1).show();
-		this._onSelectCategory();
-	},
-	/**
-	 * Listener when configuration panel is hidden
-	 * @private
-	 */
-	_onConfHide: function()
-	{
-		this._helpPanel.items.get(1).hide();
-		this._actions.hideElt(this.LOGS_CONF_DEBUG);
-		this._actions.hideElt(this.LOGS_CONF_INFO);
-		this._actions.hideElt(this.LOGS_CONF_WARN);
-		this._actions.hideElt(this.LOGS_CONF_ERROR);
-		this._actions.hideElt(this.LOGS_CONF_INHERIT);
-		this._actions.hideElt(this.LOGS_CONF_FORCE);
-	},
-	/**
-	 * Listener when a category is selected on the configuration panel
-	 * @private
-	 */
-	_onSelectCategory: function()
-	{
-		this._actions.items.get(this.LOGS_CONF_DEBUG).enable();
-		this._actions.items.get(this.LOGS_CONF_INFO).enable();
-		this._actions.items.get(this.LOGS_CONF_WARN).enable();
-		this._actions.items.get(this.LOGS_CONF_ERROR).enable();
-		this._actions.items.get(this.LOGS_CONF_INHERIT).enable();
-		this._actions.items.get(this.LOGS_CONF_FORCE).enable();
-
-		var selectedNode = this._categoryTree.getSelectionModel().getSelection()[0];
-		if (selectedNode == null)
-		{
-			this._actions.hideElt(this.LOGS_CONF_DEBUG);
-			this._actions.hideElt(this.LOGS_CONF_INFO);
-			this._actions.hideElt(this.LOGS_CONF_WARN);
-			this._actions.hideElt(this.LOGS_CONF_ERROR);
-			this._actions.hideElt(this.LOGS_CONF_INHERIT);
-			this._actions.hideElt(this.LOGS_CONF_FORCE);
-		}
-		else
-		{
-			this._actions.showElt(this.LOGS_CONF_DEBUG);
-			this._actions.showElt(this.LOGS_CONF_INFO);
-			this._actions.showElt(this.LOGS_CONF_WARN);
-			this._actions.showElt(this.LOGS_CONF_ERROR);
-			this._actions.showElt(this.LOGS_CONF_INHERIT);
-			this._actions.showElt(this.LOGS_CONF_FORCE);
-
-			switch (selectedNode.get('level'))
-			{
-				case "DEBUG": this._actions.items.get(this.LOGS_CONF_DEBUG).disable(); break;
-				case "INFO": this._actions.items.get(this.LOGS_CONF_INFO).disable(); break;
-				case "WARN": this._actions.items.get(this.LOGS_CONF_WARN).disable(); break;
-				case "ERROR": this._actions.items.get(this.LOGS_CONF_ERROR).disable(); break;
-				case "inherit": this._actions.items.get(this.LOGS_CONF_INHERIT).disable(); break;
-			}
-			
-			if (selectedNode.getDepth() == 0)
-			{
-				this._actions.items.get(this.LOGS_CONF_INHERIT).disable();
-			}
-		}
-	},
-	/**
-	 * @private
-	 * Change the log level of the selected category to the given level
-	 * @param {String} level The new level
-	 */
-	_changeLogLevel: function(level)
-	{
-		var selectedNode = this._categoryTree.getSelectionModel().getSelection()[0];
-		if (selectedNode == null || selectedNode.get('level') == level)
-		{
-			// should not happend... no node was selecting or the node selected already has the right level
-			this._onSelectCategory();
-		}
-		else
-		{
-			Ext.getBody().mask("<i18n:text i18n:key='KERNEL_LOADMASK_DEFAULT_MESSAGE' i18n:catalogue='kernel'/>");
-
-			var args = { level: level, category: selectedNode.get('fullname') };
-			Ametys.data.ServerComm.send({
-				plugin: this.pluginName, 
-				url: "administrator/logs/change-levels", 
-				parameters: args, 
-				priority: Ametys.data.ServerComm.PRIORITY_MAJOR, 
-				callback: {
-					handler: this._changeLogLevelCB, 
-					scope: this, 
-					arguments: [args, selectedNode]
-				},
-				responseType: null
-			});
-		}
-	},
-	/**
-	 * @private
-	 * {@link #_changeLogLevel} callback to effectively display the change
-	 * @param {Object} response The response to the request
-	 * @param {Object[]} argsArray First element is an object with id 'level' that is a string of the new level and with id 'category' that is a string with the modified catagory. The second element is the node in the tree to modify 
-	 */
-	_changeLogLevelCB: function (response, argsArray)
-	{
-		var args = argsArray[0];
-		var selectedNode = argsArray[1];
-
-		Ext.getBody().unmask();
-
-	    if (Ametys.data.ServerComm.handleBadResponse("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_ERROR'/>", response, "org.ametys.administration.Groups._selectGroup"))
-	    {
-	       return;
-	    }
-	    
-	    function getLevel(node)
-	    {
-	    	if (node.get('level') != 'inherit')
-	    	{
-	    		return node.get('level');
-	    	}
-	    	else
-	    	{
-	    		return getLevel(node.parentNode);
-	    	}
-	    }
-
-		function changeSNode(node, level, inherited, force)
-		{
-	        var selection = node == null;
-	        inherited = inherited == true;
-	        node = node != null ? node : selectedNode;
-
-	        if (!selection || !force)
-	        {
-	    		node.set('level', inherited ? "inherit" : level);
-	    		node.set('icon', Ametys.getPluginResourcesPrefix("core") + "/img/administrator/logs/loglevel_" + level.toLowerCase() + (inherited ? "-inherit" : "") + ".png");
-	        }		
-			
-			for (var i = 0; i < node.childNodes.length; i++)
-			{
-				var childNode = node.childNodes[i];
-				if (childNode.get('level') == "inherit" || force)
-				{
-					changeSNode(childNode, level, true, force);
-				}
-			}
-		}
-
-		if (args.level == 'FORCE')
-		{
-			var level = getLevel(selectedNode);
-			changeSNode(null, level, true, true);
-		}
-		else if (args.level == 'INHERIT')
-		{
-			var level = getLevel(selectedNode.parentNode);
-			changeSNode(null, level, true, false);
-		}
-		else
-		{
-			changeSNode(null, args.level, false, false);
-		}
-		
-		this._onSelectCategory();
-	},
-
-	/**
-	 * @private
-	 * Draw the panel for the configuration (the one with the tree)
-	 */
-	_drawConfPanel: function()
-	{
-		function createNode(name, fullname, category, parentLevel)
-		{
-			parentLevel = category.level == "inherit" ? parentLevel : category.level;
-			
-			var childNodes = [];
-			for (var c in category.child)
-			{
-				childNodes.push(createNode(c, (fullname != "" ? fullname + "." : "") + c, category.child[c], parentLevel));
-			}
-
-			var node = {
-		   		icon: Ametys.getPluginResourcesPrefix("core") + "/img/administrator/logs/loglevel_" + (category.level == "inherit" ? parentLevel.toLowerCase() + "-inherit": category.level.toLowerCase()) + ".png",
-		   		text: name,
-		   		fullname: fullname != "" ? fullname : "root",
-		   		level: category.level,
-		   		leaf: childNodes.length == 0
-			};
-			
-			node.children = childNodes;
-			
-			return node;
-		}
-		
-		var model = Ext.define('Ametys.plugins.core.administration.Logs.Category', { 
-		    extend: 'Ext.data.Model', 
-		    fields: [ 
-		        { name: 'id', type: 'int' }, 
-		        { name: 'icon', type: 'string' }, 
-		        { name: 'fullname', type: 'string', sortType: Ext.data.SortTypes.asNonAccentedUCString}, 
-		        { name: 'text', type: 'string', sortType: Ext.data.SortTypes.asNonAccentedUCString}, 
-		        { name: 'level', type: 'string', sortType: Ext.data.SortTypes.asNonAccentedUCString}, 
-		        { name: 'leaf', type: 'boolean'} 
-		    ] 
-		}); 
-
-		var rootNodeConf = createNode("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_CONFIG_LOGKITROOT'/>", "", logcategories);
-		rootNodeConf.expanded = true;
-		
-		var store = Ext.create('Ext.data.TreeStore', {
-			root : rootNodeConf,
-			model: model
-		})
-		
-		this._categoryTree = new Ext.tree.Panel({
-			id: 'monitoring-panel',
-			store: store,
-			
-			border: false,
-			autoScroll: true,
-			
-			listeners: {'show': Ext.bind(this._onConfShow, this),
-			            'hide': Ext.bind(this._onConfHide, this) 
-			}
-		});
-		
-		this._categoryTree.getSelectionModel().addListener("selectionchange", this._onSelectCategory, this);
-		
-		return this._categoryTree;
-	},
-
-	/**
-	 * Load data
-	 * @param {Object[]} data The data to load to the store
-	 */
-	load: function (data)
-	{
-		this._logs.getStore().loadData(data);
-	},
-
-	/**
-	 * Draw the navigation panel. This function needs the org.ametys.administration.JVMStatus._navItems was filled first.
-	 * @return {Ametys.admin.rightpanel.NavigationPanel} The navigation panel
-	 * @private
-	 */
-	_drawNavigationPanel: function ()
-	{
-		this._nav = new Ametys.admin.rightpanel.NavigationPanel ({title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_CONFIG_MENU'/>"});
-		
-		for (var i=0; i < this._navItems.length; i++)
-		{
-			var item = new Ametys.admin.rightpanel.NavigationPanel.NavigationItem ({
-				text: this._navItems[i].label,
-				
-				activeItem: i,
-				
-				cardLayout: 'system-card-panel',
-				toggleGroup : 'system-menu',
-				
-				allowDepress: false,
-				pressed: i == 0
-			});
-			
-			this._nav.add(item);
-		}
-		
-		return this._nav;
-	},
-	/**
-	 * Draw the actions panel.
-	 * @return {Ametys.admin.rightpanel.ActionPanel} The action panel
-	 * @private
-	 */
-	_drawActionsPanel: function ()
-	{
-		this._actions = new Ametys.admin.rightpanel.ActionPanel({title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE'/>"});
-		
-		// View file
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/file.png', 
-				 Ext.bind(this.viewFile, this));
-		
-		// Download files
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DOWNLOAD'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/download.png', 
-				 Ext.bind(this.downloadFiles, this));
-		
-		// Delete files
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/delete.png', 
-				 Ext.bind(this.deleteFiles, this));
-		
-		// Purge files
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/purge.png', 
-				 Ext.bind(this.purgeFiles, this));
-		
-		// Conf debug
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_DEBUG'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_debug.png', 
-				 Ext.bind(this._changeLogLevel, this, ['DEBUG']));
-		
-		// Conf info
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_INFO'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_info.png', 
-				 Ext.bind(this._changeLogLevel, this, ['INFO']));
-		
-		// Conf warn
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_WARN'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_warn.png', 
-				 Ext.bind(this._changeLogLevel, this, ['WARN']));
-		
-		// Conf error
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_TO_ERROR'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_error.png', 
-				 Ext.bind(this._changeLogLevel, this, ['ERROR']));
-		
-		// Inherit
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_INHERIT'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_inherit.png', 
-				 Ext.bind(this._changeLogLevel, this, ['INHERIT']));
-		
-		// Force
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_LOGLEVEL_FORCE'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/loglevel_btn_force.png', 
-				 Ext.bind(this._changeLogLevel, this, ['FORCE']));
-		
-		// Quit
-		this._actions.addAction("<i18n:text i18n:key='PLUGINS_CORE_USERS_HANDLE_QUIT'/>", 
-				 null,
-				 Ametys.getPluginResourcesPrefix(this.pluginName) + '/img/administrator/logs/quit.png', 
-				 Ext.bind(this.goBack, this));
-
-		return this._actions;
-	},
-
-	/**
-	 * Draw the help panel.
-	 * @return {Ametys.admin.rightpanel.TextPanel} The help panel
-	 * @private
-	 */
-	_drawHelpPanel: function ()
-	{
-		this._helpPanel = new Ametys.admin.rightpanel.TextPanel({title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP'/>"});
-		this._helpPanel.addText("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP_TEXT'/>");
-		this._helpPanel.addText("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HELP2_TEXT'/>");
-		
-		for (var i = 0; i < this._helpPanel.items.length; i++)
-		{
-			this._helpPanel.items.get(i).hide();
-		}
-		
-		return this._helpPanel;
-	},
-
-	/**
-	 * @private
-	 * Quit
-	 */
-	goBack: function ()
-	{
-	    document.location.href = Ametys.WORKSPACE_URI;
-	},
-
-	/**
-	 * @private
-	 * View the selected log file
-	 */
-	viewFile: function ()
-	{
-	    var elt = this._logs.getSelectionModel().getSelection()[0];
-	    
-	    if (elt.get('size') > 1024 * 1024)
-	    {
-	    	Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW'/>", 
-	    					 "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_VIEW_CONFIRM'/>", 
-	    					 Ext.bind(this.downloadFile, this, [elt]));
-	    }
-	    else
-	    {
-			window.location.href = Ametys.getPluginDirectPrefix(this.pluginName) + "/administrator/logs/view/" + encodeURIComponent(elt.get('location'));
-	    }
-	},
-
-	/**
-	 * @private
-	 * Download one file
-	 * @param {Ext.data.Model} elt The element of the file to download
-	 */
-	downloadFile: function (elt)
-	{
-		var url = Ametys.getPluginDirectPrefix(this.pluginName) + "/administrator/logs/download.zip";
-	    var args = "file=" + encodeURIComponent(elt.get('location'));
-	    
-	    window.location.href = url + "?" + args;
-	},
-	/**
-	 * @private
-	 * Download the selected log files
-	 */
-	downloadFiles: function ()
-	{
-	    var url = Ametys.getPluginDirectPrefix(this.pluginName) + "/administrator/logs/download.zip";
-	    var args = "";
-
-	    var elts = this._logs.getSelectionModel().getSelection();
-	    for (var i = 0; i < elts.length; i++)
-	    {
-	        var elt = elts[i];
-	        args += "file=" + encodeURIComponent(elt.get('location')) + "&";
-	    }
-	    
-	    window.location.href = url + "?" + args;
-	},
-
-	/**
-	 * @private
-	 * Delete the selected log files with a confirmation
-	 */
-	deleteFiles: function ()
-	{
-		Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE'/>", 
-						 "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_CONFIRM'/>", 
-						 Ext.bind(this.doDelete, this));
-	},
-	
-	/**
-	 * @private
-	 * Callback to actually delete the log files
-	 * @param {String} answer Will do the delteion if 'yes'
-	 */
-	doDelete: function (answer)
-	{
-		if (answer == 'yes')
-	    {
-	        var files = [];
-	    
-	        var elts = this._logs.getSelectionModel().getSelection();
-	        for (var i = 0; i < elts.length; i++)
-	        {
-	            var elt = elts[i];
-	            files.push(elt.get('location'));
-	        }
-	        
-	    	var result = Ametys.data.ServerComm.send({
-	    		plugin: this.pluginName, 
-	    		url: "administrator/logs/delete", 
-	    		parameters: { file: files }, 
-	    		priority: Ametys.data.ServerComm.PRIORITY_SYNCHRONOUS, 
-	    		callback: null, 
-	    		responseType: null
-	    	});
-	        if (Ametys.data.ServerComm.handleBadResponse("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR_GRAVE'/>", result, "Ametys.plugins.core.administration.Logs.doDelete"))
-	        {
-	           return;
-	        }
-
-	        var failuresString = Ext.dom.Query.selectValue("*/failure", result, "");
-	        
-	        for (var i = 0; i < elts.length; i++)
-	        {
-	            var elt = elts[i];
-	            if (failuresString.indexOf('/' + elt.get('location') + '/') < 0)
-	            {
-	            	this._logs.getStore().remove(elt);
-	            }
-	        }                            
-	        
-	        if (failuresString.length > 0)
-	        {
-	        	Ametys.Msg.show({
-					title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE'/>",
-					msg: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_DELETE_ERROR'/>",
-					buttons: Ext.Msg.OK,
-					icon: Ext.MessageBox.ERROR
-				});
-	        }
-	    }
-	},
-
-	/**
-	 * Purge the selected files with a confirmation dialog
-	 * @private
-	 */
-	purgeFiles: function ()
-	{
-		Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE'/>", 
-				         "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_CONFIRM'/>",
-				         Ext.bind(this.doPurge, this));
-	},
-	
-	/**
-	 * @private
-	 * Callback function to finally do the purge action
-	 * @param {String} anwser Will do the purge if 'yes'
-	 */
-	doPurge: function (anwser)
-	{
-		if (anwser == 'yes')
-	    {
-	    	var result = Ametys.data.ServerComm.send({
-	    		plugin: this.pluginName, 
-	    		url: "administrator/logs/purge", 
-	    		parameters: {}, 
-	    		priority: Ametys.data.ServerComm.PRIORITY_SYNCHRONOUS, 
-	    		callback: null, 
-	    		responseType: null
-	    	});
-	    	
-	        if (Ametys.data.ServerComm.handleBadResponse("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_ERROR_GRAVE'/>", result, "Ametys.plugins.core.administration.Logs.doPurge"))
-	        {
-	           return;
-	        }
-	        
-	        this._doneString = Ext.dom.Query.selectValue("*/done", result) || "";
-	        this._toRemove = [];
-	        
-	        var elts = this._logs.getStore().each(function(record) {
-	        	if (this._doneString.indexOf('/' + record.get('location') + '/') >= 0)
-	        	{
-	        		this._toRemove.push(record);
-	        	}
-	        }, this);
-	        
-	        for (var i = 0; i < this._toRemove.length; i++)
-	        {
-	        	this._logs.getStore().remove(this._toRemove[i]);
-	        }
-	        
-	        Ametys.Msg.show({
-					title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE'/>",
-					msg: this._toRemove.length + " " + "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_HANDLE_PURGE_DONE'/>",
-					buttons: Ext.Msg.OK,
-					icon: Ext.MessageBox.INFO
-				});
-	    }
-	},
-
-	/**
-	 * @private
-	 * Listener when a log file is selected
-	 */
-	_onSelectLog: function ()
-	{
-		var selectionSize  = this._logs.getSelectionModel().getSelection().length;
-		if (selectionSize > 0)
-		{
-			if (selectionSize == 1)
-			{
-				this._actions.showElt(0);
-			}
-			else
-			{
-				this._actions.hideElt(0);
-			}
-			this._actions.showElt(1);
-			this._actions.showElt(2);
-			this._actions.showElt(3);
-		}
-		else
-		{
-			this._actions.hideElt(0);
-			this._actions.hideElt(1);
-			this._actions.hideElt(2);
-			this._actions.showElt(3);
-		}
-	},
-
-	/**
-	 * @private
-	 * Returns the size filled with leading zeros to obtain a 20 caracters string
-	 * @param {Number} size The size to edit
-	 * @return {String} The number as a string with leading zeros. e.g. 00000012345678901234 
-	 */
-	_fillSize: function (size)
-	{
-	    while (size.length < 20)
-	    {
-	        size = "0" + size;
-	    }
-	    return size;
-	},
-
-	/**
-	 * @private
-	 * Returns a readable size for a size
-	 * @param {Number} size The size to render
-	 * @return {String} The readable size. e.g. 12 MB
-	 */
-	_sizeRendered: function (size)
-	{
-		return Ext.util.Format.fileSize(size);
-	}
-});
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Password.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Password.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Password.js	(working copy)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2012 Anyware Services
+ *  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.
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Plugins.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Plugins.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Plugins.js	(working copy)
@@ -104,6 +104,11 @@
 		this.pluginName = pluginName;
 	},
 
+	act: function()
+	{
+		alert("TODO");
+	},
+	
 	/**
 	 * Create the screen
 	 * @param {Object} rootNode1 The root node conf for _tree (plugins by file)
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Profiles.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Profiles.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Profiles.js	(working copy)
@@ -72,6 +72,11 @@
 		window.onbeforeunload = Ext.bind(this.checkBeforeQuit, this);
 	},
 	
+	act: function()
+	{
+		alert("TODO");
+	},
+	
 	/**
 	 * @private
 	 * Quit
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/System.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/System.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/System.js	(working copy)
@@ -72,6 +72,11 @@
 		this.pluginName = pluginName;
 	},
 	
+	act: function()
+	{
+		alert("TODO");
+	},
+	
 	/**
 	 * Creates the panel that rules the screen
 	 * @returns {Ext.Panel} The screen
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/Users.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/Users.js	(revision 31811)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/Users.js	(working copy)
@@ -55,6 +55,11 @@
 		this.pluginName = pluginName;
 	},
 	
+	act: function()
+	{
+		alert("TODO");
+	},
+	
 	/**
 	 * Creates the panel that rules the screen
 	 * @returns {Ext.Panel} The screen
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/actions/LogsActions.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/actions/LogsActions.js	(revision 0)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/actions/LogsActions.js	(revision 0)
@@ -0,0 +1,260 @@
+/*
+ *  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.
+ */
+
+/**
+ * Singleton class defining the actions related to the visualization of logs.
+ * @private
+ */
+Ext.define('Ametys.plugins.core.administration.actions.LogsActions', {
+	singleton: true,
+	
+	/**
+	 * View the selected log file
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	view: function(controller)
+	{
+		var target = controller.getMatchingTargets()[0];
+		if (target != null)
+		{
+			var targetParameters = target.getParameters();
+			if (targetParameters.size > 1024 * 1024)
+		    {
+		    	Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DIALOG_TITLE'/>", 
+		    					    "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_VIEW_DIALOG_CONFIRM'/>", 
+		    					    Ext.bind(this._downloadFiles, this, [controller]));
+		    }
+		    else
+		    {
+				window.location.href = Ametys.getPluginDirectPrefix(controller.getPluginName()) + "/administrator/logs/view/" + encodeURIComponent(targetParameters.location);
+		    }
+		}
+	},
+	
+	/**
+	 * Download the selected log file(s)
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	download: function (controller)
+	{
+		this._downloadFiles(controller);
+	},
+	
+	/**
+	 * @private
+	 * Download the selected log files
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller of the clicked button
+	 */
+	_downloadFiles: function (controller)
+	{
+	    var url = Ametys.getPluginDirectPrefix(controller.getPluginName()) + "/administrator/logs/download.zip";
+	    var args = "";
+
+	    var targets = controller.getMatchingTargets();
+	    for (var i = 0; i < targets.length; i++)
+	    {
+	        var target = targets[i];
+	        args += "file=" + encodeURIComponent(target.getParameters().location) + "&";
+	    }
+	    
+	    window.location.href = url + "?" + args;
+	},
+	
+	/**
+	 * Delete the selected log file(s) with a confirmation dialog
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	delete: function (controller)
+	{
+		Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_TITLE'/>", 
+							"<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_CONFIRM'/>", 
+							Ext.bind(this._delete, this, [controller], 1));
+	},
+	
+	/**
+	 * @private
+	 * Callback to actually delete the log files
+	 * @param {String} answer Will do the deletion if 'yes'
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller of the clicked button
+	 */
+	_delete: function(answer, controller)
+	{
+		if (answer == 'yes')
+	    {
+			var filesLocations = [];
+	        
+	        var targets = controller.getMatchingTargets();
+	        for (var i = 0; i < targets.length; i++)
+	        {
+	            var target = targets[i];
+	            filesLocations.push(target.getParameters().location);
+	        }
+	        
+	        controller.serverCall('deleteLogs', [filesLocations], Ext.bind(this._deleteCb, this),
+				{ errorMessage: { msg: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_ERROR'/>", category: 'Ametys.plugins.core.administration.actions.LogsActions'} }, 
+			true);
+	    }
+	},
+	
+	/**
+	 * @private 
+	 * Callback for the purge/deletion process
+	 * @param {Object} response the server's response
+	 * @param {String[]} failures the list of file locations for failed deletions
+	 * @param {String[]} successes the list of file locations for successful deletions
+	 */
+	_deleteCb: function(response)
+	{
+		this._sendDeletionMessage(response.successes);
+		
+        if (response.failures.length > 0)
+        {
+        	Ametys.Msg.show({
+				title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_DIALOG_TITLE'/>",
+				msg: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_DELETE_ERROR'/>",
+				buttons: Ext.Msg.OK,
+				icon: Ext.MessageBox.ERROR
+			});
+        }
+	},
+	
+	/**
+	 * Remove the at least 12 days old log files from the tool with a confirmation dialog
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	purge: function (controller)
+	{
+		Ametys.Msg.confirm ("<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DIALOG_TITLE'/>", 
+					         "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_DIALOG_CONFIRM'/>",
+					         Ext.bind(this._purge, this, [controller], 1));
+	},
+	
+	/**
+	 * @private
+	 * Purge the selected files with a confirmation dialog
+	 */
+	_purge: function (answer, controller)
+	{
+		if (answer == 'yes')
+	    {
+	        controller.serverCall('purgeLogs', null, Ext.bind(this._purgeCb, this),
+				{ errorMessage: { msg: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_SERVER_ERROR'/>", category: 'Ametys.plugins.core.administration.actions.LogsActions'} }, 
+			true);
+	    }	
+	},
+	
+	/**
+	 * @private
+	 * Callback for the purge process
+	 * @param {Object} response the server's response
+	 * @param {String[]} response.filesToPurge the files to remove from the logs tool
+	 */
+	_purgeCb: function(response)
+	{
+		var filesToPurge = response.filesToPurge;
+		this._sendDeletionMessage(filesToPurge);
+		
+        Ametys.Msg.show({
+			title: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE'/>",
+			msg: filesToPurge.length == 0 ? "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_NONE'/>" : filesToPurge.length + " " + "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_PURGE_AMOUNT'/>",
+			buttons: Ext.Msg.OK,
+			icon: Ext.MessageBox.INFO
+    	});
+	},
+	
+	/**
+	 * @private
+	 * Send a deletion message for the logs tool
+	 * @param {String[]} deletedFiles the deleted files or the files to remove from the store in the case of a purge
+	 */
+	_sendDeletionMessage: function(deletedFiles)
+	{
+		var targets = [];
+
+		Ext.Array.forEach(deletedFiles, function(deletedFile) {
+			
+			var target = Ext.create('Ametys.message.MessageTarget', {
+					type: 'logfile',
+					parameters: {location: deletedFile}
+				});
+			
+			targets.push(target);
+		});
+		
+		if (targets.length > 0)
+		{			
+			Ext.create('Ametys.message.Message', {
+				type: Ametys.message.Message.DELETED,
+				targets: targets
+			});
+		}
+	},
+	
+	/**
+	 * Change the logging level of the selected category to the configured #Ametys.plugins.core.administration.controller.LogLevelController._level
+	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
+	 */
+	changeLogLevel: function(controller)
+	{
+		var targets = controller.getMatchingTargets();
+		if (targets.length > 0)
+		{
+			var newLevel = controller._level,
+				category = targets[0].getParameters().category;
+			
+			controller.serverCall('changeLogLevel',
+					[newLevel, category], 
+					Ext.bind(this._changeLogLevelCB, this),
+					{ 
+						errorMessage: { 
+							msg: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_TOOL_LOGS_LEVEL_SERVER_ERROR'/>", 
+							category: 'Ametys.plugins.core.administration.actions.LogsActions' 
+						},
+						arguments: {
+							level: newLevel,
+							category: category
+						}
+					},
+					true
+			);
+		}
+	},
+	
+	/**
+	 * @private
+	 * Callback for the log level changing process
+	 * @param {Object} response the server's response
+	 * @param {Object} args the callback arguments
+	 */
+	_changeLogLevelCB: function(response, args)
+	{
+		var targets = [];
+		var target = Ext.create('Ametys.message.MessageTarget', {
+				type: 'log-category',
+				parameters: {level: args.level, category: args.category}
+			});
+		
+		targets.push(target);
+		
+		if (targets.length > 0)
+		{			
+			Ext.create('Ametys.message.Message', {
+				type: Ametys.message.Message.MODIFIED,
+				targets: targets
+			});
+		}
+	}
+});
\ No newline at end of file
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/controller/LogLevelController.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/controller/LogLevelController.js	(revision 0)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/controller/LogLevelController.js	(revision 0)
@@ -0,0 +1,87 @@
+/*
+ *  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.
+ */
+
+/**
+ * This class controls a ribbon button allowing to modify the log level of a given category 
+ * @private
+ */
+Ext.define('Ametys.plugins.core.administration.controller.LogLevelController', {
+	extend: 'Ametys.ribbon.element.ui.ButtonController',
+	
+	/**
+	 * @property {String} _level the logging level of the button
+	 * @private
+	 */
+	constructor: function(config)
+	{
+		this.callParent(arguments);
+		this._level = config.level;
+		
+		Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
+	},
+
+	/**
+	 * Listener when the content has been modified
+	 * Will update the state of the buttons effectively upon the current selection.
+	 * @param {Ametys.message.Message} message The modified message.
+	 * @protected
+	 */
+	_onModified: function (message)
+	{
+		this.refresh();
+	},
+	
+	updateState: function()
+	{
+		this._getStatus(this.getMatchingTargets());
+	},
+	
+	/**
+	 * Get the logging level of the selected target
+	 * @param targets The content targets
+	 * @private
+	 */
+	_getStatus: function (targets)
+	{
+		var enable = false,
+			isRoot = false;
+		
+		for (var i=0; i < targets.length; i++)
+		{
+			if (targets[i].getParameters().level != this._level)
+			{
+				enable = true;
+			}
+			
+			if (targets[i].getParameters().category == "root")
+			{
+				isRoot = true;
+			}
+		}
+		
+		if (this._level != "INHERIT")
+		{
+			// INFO, DEBUG, WARN or ERROR
+			
+			this.setDisabled(!enable);
+		}
+		else
+		{
+			// INHERIT
+			this.setDisabled(isRoot);
+		}
+	}
+});
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsLevelTool.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsLevelTool.js	(revision 0)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsLevelTool.js	(revision 0)
@@ -0,0 +1,272 @@
+/*
+ *  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.
+ */
+
+/**
+ * &lt;p&gt;This tool displays a tree if log categories, and allows the administrator to perform several operations such as :&lt;/p&gt;
+ * &lt;ul&gt;
+ * 	&lt;li&gt; change the log levels &lt;/li&gt;
+ * 	&lt;li&gt; force log level inheritance &lt;/li&gt;
+ * 	&lt;li&gt; inherit log level &lt;/li&gt;
+ * &lt;/ul&gt;
+ * @private
+ */
+Ext.define('Ametys.plugins.core.administration.tool.LogsLevelTool', {
+	extend: 'Ametys.tool.Tool',
+	
+	/**
+	 * @private
+	 * @property {Ext.tree.Panel} _logsTree The logs tree panel
+	 */
+	
+	constructor: function(config)
+	{
+		this.callParent(arguments);
+		Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
+	},
+		
+	getMBSelectionInteraction: function() 
+	{
+		return Ametys.tool.Tool.MB_TYPE_ACTIVE;
+	},
+	
+	createPanel: function ()
+	{
+		this._logsTree = this._drawLogsLevelPanel();
+		return this._logsTree;
+	},
+	
+	sendCurrentSelection: function()
+	{
+		this._onSelectCategory();
+	},
+	
+	/**
+	 * Refreshes the tool
+	 */
+	refresh: function ()
+	{
+		this.showRefreshing();
+		this._logsTree.getStore().load({node: this._logsTree.getRootNode(), callback: this.showRefreshed, scope: this});
+	},
+	
+	getTree: function()
+	{
+		return this._logsTree;
+	},
+	
+	/**
+	 * @private
+	 * Draw the tree panel for the log levels
+	 */
+	_drawLogsLevelPanel: function()
+	{
+		var store = Ext.create('Ext.data.TreeStore', {
+			model: 'Ametys.plugins.core.administration.Logs.Category',
+			
+			root: {
+				expanded: false
+			},			
+			
+	        proxy: {
+	        	type: 'ametys',
+				plugin: 'core',
+				url: 'administrator/logs-level',
+	        	reader: {
+	        		type: 'json',
+					rootProperty: 'children'
+	        	}
+	        },
+	        
+	        listeners: {
+	        	'load': Ext.bind(this._onLoad, this)
+	        }
+		});
+		
+		return new Ext.tree.Panel({
+			store: store,
+			rootVisible: false,
+			
+			border: false,
+			autoScroll: true,
+			
+			listeners: {
+				'selectionchange': Ext.bind(this._onSelectCategory, this)
+			}
+		});
+	},
+	
+    /**
+     * @private
+     * Listener when store is loaded
+     */
+	_onLoad: function()
+    {
+		var rootNode = this._logsTree.getRootNode();
+		
+		// Set the parent level field on each node of the tree
+		this._setParentLevels(rootNode.firstChild.data.level, rootNode.firstChild.childNodes);
+		
+        // Expand first nodes
+        this._logsTree.getRootNode().expandChildren(false, false, this._logsTree._onRootNodesChangedAndExpanded, this);
+    },
+    
+    /**
+     * @private
+     * Set the parent levels on the tree nodes
+     * @param {String} parentLevel the level of the parent node
+     * @param {Ext.data.NodeInterface[]} children the list of child nodes
+     */
+    _setParentLevels: function(parentLevel, children)
+    {
+    	var me = this;
+    	Ext.Array.forEach(children, function(child) {
+    		child.set('parentLevel', parentLevel);
+    		
+    		if (child.childNodes)
+			{
+    			parentLevel = child.data.level == "inherit" ? parentLevel : child.data.level;
+    			me._setParentLevels(parentLevel, child.childNodes);
+			}
+    	});
+    },
+    
+    /**
+     * @private
+     * When the newly loaded root nodes are expanded
+     */
+    _onRootNodesChangedAndExpanded: function()
+    {
+        // Select first node
+        this._logsTree.getSelectionModel().select(this._logsTree.getRootNode().firstChild);
+    },
+	
+    /**
+     * @private
+     * Send selection message
+     */
+	_onSelectCategory: function()
+	{
+		var targets = [];
+		
+		var selectedCategories = this._logsTree.getSelectionModel().getSelection();
+		Ext.Array.forEach(selectedCategories, function(selectedCategory) {
+			
+			target = Ext.create('Ametys.message.MessageTarget', {
+				type: 'log-category',
+				parameters: {id: selectedCategory.getId(), level: selectedCategory.data.level, category: selectedCategory.data.category}
+			});
+			
+			targets.push(target);
+		});
+		
+		Ext.create('Ametys.message.Message', {
+			type: Ametys.message.Message.SELECTION_CHANGED,
+			targets: targets
+		});
+	},
+    
+	_onModified: function(message)
+	{
+		var targets = message.getTargets("log-category");
+		if (targets.length > 0)
+		{
+			var store = this._logsTree.getStore();
+			var me = this;
+			
+			Ext.Array.forEach(targets, function(target) {
+				var category = target.getParameters().category;
+				var index = store.find("category", category); 
+				if (index != -1)
+				{
+					var level = target.getParameters().level,
+					    modifiedCategory = store.getAt(index); 
+					
+					if (level == 'FORCE')
+					{
+						var level = me._getLevel(modifiedCategory);
+						me._updateNode(null, level, true, true, modifiedCategory);
+					}
+					else if (level == 'INHERIT')
+					{
+						var level = me._getLevel(modifiedCategory.parentNode);
+						me._updateNode(null, level, true, false, modifiedCategory);
+					}
+					else
+					{
+						me._updateNode(null, level, false, false, modifiedCategory);
+					}
+				}
+			});
+			
+		}
+	},
+	
+	_getLevel: function(node)
+    {
+    	if (node.get('level') != 'inherit')
+    	{
+    		return node.get('level');
+    	}
+    	else
+    	{
+    		return this._getLevel(node.parentNode);
+    	}
+    },
+
+	_updateNode: function (node, level, inherited, force, modifiedCategory)
+	{
+		var selection = node == null;
+        inherited = inherited == true;
+        node = node != null ? node : modifiedCategory;
+
+        if (!selection || !force)
+        {
+    		node.set('level', inherited ? "inherit" : level);
+			
+    		// Find the first parent containing the appropriate level information
+    		var parentNode = node.parentNode;
+			while (parentNode.data.level == "inherit")
+			{
+				parentNode = parentNode.parentNode;
+			}
+			node.set('parentLevel', parentNode.data.level);
+        }		
+		
+		for (var i = 0; i < node.childNodes.length; i++)
+		{
+			var childNode = node.childNodes[i];
+			if (childNode.get('level') == "inherit" || force)
+			{
+				this._updateNode(childNode, level, true, force);
+			}
+		}
+	}
+});
+
+Ext.define('Ametys.plugins.core.administration.Logs.Category', { 
+    extend: 'Ext.data.TreeModel', 
+    fields: [ 
+        { name: 'id', type: 'string' }, 
+        { name: 'parentLevel', type: 'string'},
+        { name: 'icon', type: 'string', calculate: function(data) {
+        		return Ametys.getPluginResourcesPrefix("core") + "/img/administrator/logs/loglevel_" + (data.level.toLowerCase() == "inherit" ? data.parentLevel.toLowerCase() + "-inherit": data.level.toLowerCase()) + ".png"
+        	} 
+        }, 
+        { name: 'text', type: 'string', mapping: 'name', sortType: Ext.data.SortTypes.asNonAccentedUCString},
+        { name: 'category', type: 'string', mapping: 'fullname'},
+        { name: 'level', type: 'string', mapping: 'level', sortType: Ext.data.SortTypes.asNonAccentedUCString},
+    ] 
+}); 
Index: main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsTool.js
===================================================================
--- main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsTool.js	(revision 0)
+++ main/plugin-core/resources/js/Ametys/plugins/core/administration/tool/LogsTool.js	(revision 0)
@@ -0,0 +1,188 @@
+/*
+ *  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.
+ */
+
+/**
+ * &lt;p&gt;This tool displays the list of logs, and allows the administrator to perform several operations such as :&lt;/p&gt;
+ * &lt;ul&gt;
+ * 	&lt;li&gt; view logs &lt;/li&gt;
+ * 	&lt;li&gt; delete logs &lt;/li&gt;
+ * 	&lt;li&gt; download logs &lt;/li&gt;
+ * 	&lt;li&gt; clean obsolete logs &lt;/li&gt;
+ * &lt;/ul&gt;
+ * @private
+ */
+Ext.define('Ametys.plugins.core.administration.tool.LogsTool', {
+	extend: 'Ametys.tool.Tool',
+	
+	/**
+	 * @private
+	 * @property {Ext.grid.Panel} _logs The logs grid
+	 */
+	
+	constructor: function(config)
+	{
+		this.callParent(arguments);
+		Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onLogFileDeleted, this);
+	},
+	
+	getMBSelectionInteraction: function() 
+	{
+		return Ametys.tool.Tool.MB_TYPE_ACTIVE;
+	},
+	
+	createPanel: function ()
+	{
+		this._logs = this._drawLogsPanel();
+		return this._logs;
+	},
+	
+	setParams: function (params)
+	{
+		this.callParent(arguments);
+		this.refresh();
+	},
+	
+	sendCurrentSelection: function()
+	{
+		this._selectLog();
+	},
+	
+	/**
+	 * Refreshes the tool
+	 */
+	refresh: function ()
+	{
+		this.showRefreshing();
+		this._logs.getStore().load({callback: this.showRefreshed, scope: this});
+	},
+	
+	/**
+	 * @private
+	 * Draw the panel displaying the logs
+	 */
+	_drawLogsPanel: function()
+	{
+		var store = Ext.create('Ext.data.Store', {
+			model: 'Ametys.plugins.core.administration.tool.LogsTool.Log',
+	        groupField: 'name',
+	        
+	        sortOnLoad: true,
+	        sorters: [ { property: 'date', direction: "DESC" } ],
+	        
+	        proxy: {
+	        	type: 'ametys',
+				plugin: 'core',
+				url: 'administrator/logs',
+	        	reader: {
+	        		type: 'xml',
+					record: 'log',
+					rootProperty: 'logs'
+	        	}
+	        }
+		});		
+		
+		return new Ext.grid.Panel({
+			region: 'center',
+
+			stateful: true,
+			stateId: this.self.getName() + "$grid",
+
+			store : store,
+			
+			selModel : {
+		    	mode: 'MULTI'
+		    },
+		    
+		    listeners: {'selectionchange': Ext.bind(this._selectLog, this)},
+		    
+		    features: [{
+		        groupHeaderTpl: ['{columnName}: {name}'],
+		        ftype: 'grouping'
+		    }],
+			
+		    columns: [
+		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_NAME'/>", flex: 1, width : 250, menuDisabled : true, sortable: true, dataIndex: 'location'},
+		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_DATE'/>", flex: 0, width : 150, renderer: Ext.util.Format.dateRenderer('d F Y'), menuDisabled : true, sortable: true, dataIndex:'date',  align :'center'},
+		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_SIZE'/>", flex: 0, width : 100, renderer: this._sizeRendered, menuDisabled : true, sortable: true, dataIndex: 'size', align :'right'},
+		        {header: "<i18n:text i18n:key='PLUGINS_CORE_ADMINISTRATOR_LOGS_COL_CATEGORY'/>", flex: 0, width : 100, hidden: true, menuDisabled : true, sortable: true, dataIndex: 'name', align :'right'}
+		    ]
+		});
+	},
+	
+	/**
+	 * Sends a {Ametys.message.Message.SELECTION_CHANGED} message containing the
+	 * selected log files on the message bus 
+	 */
+	_selectLog: function()
+	{
+		var targets = [];
+
+		var selectedFiles = this._logs.getSelectionModel().getSelection();
+		Ext.Array.forEach(selectedFiles, function(selectedFile) {
+			
+			target = Ext.create('Ametys.message.MessageTarget', {
+				type: 'logfile',
+				parameters: {id: selectedFile.getId(), size: selectedFile.data.size, location: selectedFile.data.location}
+			});
+			
+			targets.push(target);
+		});
+		
+		Ext.create('Ametys.message.Message', {
+			type: Ametys.message.Message.SELECTION_CHANGED,
+			targets: targets
+		});
+	},
+	
+	/**
+	 * @private
+	 * Returns a readable size for a size
+	 * @param {Number} size The size to render
+	 * @return {String} The readable size. e.g. 12 MB
+	 */
+	_sizeRendered: function (size)
+	{
+		return Ext.util.Format.fileSize(size);
+	},
+	
+	_onLogFileDeleted: function(message)
+	{
+		var targets = message.getTargets("logfile");
+		if (targets.length > 0)
+		{
+			var store = this._logs.getStore();
+			Ext.Array.forEach(targets, function(target) {
+				var location = target.getParameters().location;
+				var index = store.find("location", location); 
+				if (index != -1)
+				{
+					store.removeAt(index);
+				}
+			});
+		}
+	}
+});
+
+Ext.define('Ametys.plugins.core.administration.tool.LogsTool.Log', {
+    extend: 'Ext.data.Model',
+    
+    fields: [
+       {name: 'location', mapping: 'location'},
+       {name: 'date', type: 'date', dateFormat: Ext.Date.patterns.ISO8601DateTime, mapping: 'lastModified'},
+       {name: 'size', type: 'int', mapping: 'size'},
+       {name: 'name', mapping: 'name'}
+    ]
+});
Index: main/plugin-core/sitemap.xmap
===================================================================
--- main/plugin-core/sitemap.xmap	(revision 31811)
+++ main/plugin-core/sitemap.xmap	(working copy)
@@ -66,11 +66,11 @@
 		<map:actions>
             <map:action name="set-header" src="org.apache.cocoon.acting.HttpHeaderAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.httpHeader"/>
 
+            <map:action name="administrator-logs-level" src="org.ametys.runtime.plugins.core.administrator.logs.GetLogsLevel" logger="org.ametys.runtime.plugins.core.administrator.sitemap.generator.logs" label="content"/>	            
+
             <map:action name="administrator-is-system-user" src="org.ametys.runtime.plugins.core.right.actions.IsAdminAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.isAdmin"/>
 			<map:action name="administrator-password-set" src="org.ametys.runtime.plugins.core.administrator.password.SetPasswordAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.setPassword"/>
             <map:action name="administrator-jvmstatus-gc" src="org.ametys.runtime.plugins.core.administrator.jvmstatus.GCAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.garbageCollect"/>
-            <map:action name="administrator-logs-delete" src="org.ametys.runtime.plugins.core.administrator.logs.LogsDeleteAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.logDelete"/>
-            <map:action name="administrator-change-levels" src="org.ametys.runtime.plugins.core.administrator.logs.ChangeLogLevelAction" logger="org.ametys.runtime.plugins.core.administrator.logs.ChangeLogLevelAction"/>
             <map:action name="administrator-system-update" src="org.ametys.runtime.plugins.core.administrator.system.UpdateSystemAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.updateSystem"/>
             <map:action name="administrator-config-save" src="org.ametys.runtime.plugins.core.administrator.configuration.SaveConfigAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.saveConfig"/>
             <map:action name="administrator-config-test" src="org.ametys.runtime.config.ParameterCheckerAction" logger="org.ametys.runtime.plugins.core.administrator.sitemap.action.dispatchRequest"/>
@@ -313,26 +313,8 @@
                 <map:read type="administrator-jvmstatus-monitoring-export" src="{1}"/>
             </map:match>
             
-            
-            <!-- +
-                 | Logs 
-                 + -->
-            <map:match pattern="administrator/logs/view.html">
-                <map:generate type="administrator-logs" label="content"/>
-                <map:transform type="xslt" src="pages/administrator/logs/view.xsl">
-                    <map:parameter name="contextPath" value="{request:contextPath}"/>
-                    <map:parameter name="pluginName" value="{request-attr:pluginName}"/>
-                    <map:parameter name="workspaceName" value="{request-attr:workspaceName}"/>
-                    <map:parameter name="workspaceURI" value="{request-attr:workspaceURI}"/>
-                </map:transform>
-                <map:transform type="i18n">
-                    <map:parameter name="locale" value="{locale:locale}"/>
-                    <map:parameter name="plugin" value="{request-attr:pluginName}"/>
-                </map:transform>
-                <map:serialize type="xml"/>
-            </map:match>
-        
 		</map:pipeline>
+		
 		<map:pipeline type="noncaching">
             <map:match pattern="administrator/logs/view/*.log">
                 <map:act type="set-header"> 
@@ -349,38 +331,25 @@
                 <map:serialize type="zip"/>
             </map:match>
 		</map:pipeline>
+		
 		<map:pipeline>
-            <map:match pattern="administrator/logs/delete">
-                <map:act type="administrator-logs-delete">
-                    <map:generate type="action-result">
-                        <map:parameter name="failure" value="{failure}"/>
-                    </map:generate>
-                    <map:serialize type="xml"/>
-                </map:act>
-            </map:match>
-
-            <map:match pattern="administrator/logs/purge">
-                <map:act type="administrator-logs-delete">
-                    <map:parameter name="purge" value="true"/>
-                
-                    <map:generate type="action-result">
-                        <map:parameter name="done" value="{done}"/>
-                    </map:generate>
-                    <map:serialize type="xml"/>
-                </map:act>
+		
+		    <!-- +
+                 | Logs 
+                 + -->
+            <map:match pattern="administrator/logs">
+                <map:generate type="administrator-logs"/>
+                <map:serialize type="xml"/>
             </map:match>
             
-            <map:match pattern="administrator/logs/change-levels">
-                <map:act type="administrator-change-levels">
-                    <map:generate type="action-result">
-                        <map:parameter name="error" value="{error}"/>
-                    </map:generate>
-                    <map:serialize type="xml"/>
+            <map:match pattern="administrator/logs-level">
+                <map:act type="administrator-logs-level">
+                    <map:read type="json"/>
                 </map:act>
             </map:match>
-            
+
             <!-- +
-                 | Plugins and workspaces managment tool
+                 | Plugins and workspaces management tool
                  + -->
             <map:match pattern="administrator/plugins/list.xml">
                 <map:generate type="administrator-plugins-list"/>
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/ChangeLogLevelAction.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/ChangeLogLevelAction.java	(revision 31873)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/ChangeLogLevelAction.java	(nonexistent)
@@ -1,119 +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.runtime.plugins.core.administrator.logs;
-
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.acting.AbstractAction;
-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.log4j.Level;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.spi.LoggerRepository;
-
-/**
- * Change the log level for specified categories.<br>
- * The categories are specified through request parameters with the following syntax :
- * priority_&lt;my.log.category&gt;=&lt;log-level&gt;
- */
-public class ChangeLogLevelAction extends AbstractAction implements ThreadSafe
-{
-    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
-    {
-        Request request = ObjectModelHelper.getRequest(objectModel);
-
-        if (getLogger().isInfoEnabled())
-        {
-            getLogger().info("Administrator change log level");
-        }
-
-        LoggerRepository loggerRepository = LogManager.getLoggerRepository();
-        
-        String category = request.getParameter("category");
-        String level = request.getParameter("level");
-
-        if (getLogger().isInfoEnabled())
-        {
-            getLogger().info("Log level changing category '" + category + "' " + level);
-        }
-
-        try
-        {
-            changeLogLevel(loggerRepository, category, level);
-        }
-        catch (Throwable t)
-        {
-            String errorMessage = "Cannot change log level correctly : changing category '" + category + "'";
-            getLogger().error(errorMessage, t);
-            Map<String, String> results = new HashMap<>();
-            results.put("error", "error");
-            return results;
-        }
-
-        return EMPTY_MAP;
-    }
-    
-    private void changeLogLevel(LoggerRepository loggerRepository, String category, String mode)
-    {
-        boolean inherited = "INHERIT".equals(mode) || "INHERITFORCED".equals(mode);
-        boolean force = "FORCE".equals(mode) || "INHERITFORCED".equals(mode);
-
-        Logger logger;
-        boolean isRoot = false;
-        
-        if ("root".equals(category))
-        {
-            isRoot = true;
-            logger = loggerRepository.getRootLogger();
-        }
-        else
-        {
-            logger = loggerRepository.getLogger(category);
-        }
-    
-        if (inherited && !isRoot)
-        {
-            logger.setLevel(null);
-        }
-        
-        if (force)
-        {
-            Enumeration<Logger> e = loggerRepository.getCurrentLoggers();
-            while (e.hasMoreElements())
-            {
-                Logger l = e.nextElement();
-                if (l.getParent() == logger)
-                {
-                    changeLogLevel(loggerRepository, l.getName(), "INHERITFORCED");
-                }
-            }
-        }
-
-        if (!inherited && !force)
-        {
-            Level level = Level.toLevel(mode);
-            logger.setLevel(level);
-        }
-    }
-}
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/GetLogsLevel.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/GetLogsLevel.java	(revision 0)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/GetLogsLevel.java	(revision 0)
@@ -0,0 +1,176 @@
+/*
+ *  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.runtime.plugins.core.administrator.logs;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.acting.ServiceableAction;
+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.lang3.StringUtils;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggerRepository;
+
+import org.ametys.runtime.cocoon.JSonReader;
+
+/**
+ * Get the log levels' 
+ */
+@SuppressWarnings("unchecked")
+public class GetLogsLevel extends ServiceableAction
+{
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
+    {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Map<String, Object> result = new HashMap<> ();
+        
+        try
+        {
+            LoggerRepository loggerRepository = LogManager.getLoggerRepository();
+            List<Logger> loggers = new ArrayList<Logger>();
+            Enumeration<org.apache.log4j.Logger> enumLogger = loggerRepository.getCurrentLoggers();
+            
+            while (enumLogger.hasMoreElements())
+            {
+                loggers.add(enumLogger.nextElement());
+            }
+            
+            loggers.add(loggerRepository.getRootLogger());
+            
+            Collections.sort(loggers, new LoggerComparator());
+            
+            Map<String, Object> logCategories = new HashMap<>();
+            Set<Map<String, String>> categoryLevels = new HashSet<Map<String, String>> ();
+            
+            for (Logger logger : loggers)
+            {
+                Level level = logger.getLevel();
+
+                String category = logger.getName();
+                if (category.equals("root"))
+                {
+                    logCategories.put("children", new ArrayList<> ());
+                    logCategories.put("name", "root");
+                    logCategories.put("fullname", "root");
+                    logCategories.put("level", level.toString());
+                }
+                else
+                {
+                    Map<String, String> categoryLevel = new HashMap<>();
+                    categoryLevel.put("category", category);
+                    categoryLevel.put("level", level == null ? "inherit" : level.toString());
+                    categoryLevels.add(categoryLevel);
+                }
+            }
+
+            String fullName = null;
+            for (Map<String, String> categoryLevel : categoryLevels)
+            {
+                fullName = categoryLevel.get("category");
+                createCategory((List<Map<String, Object>>) logCategories.get("children"), fullName, categoryLevel.get("level"), fullName);
+            }
+            
+            result.put("children", logCategories);
+        }
+        catch (Exception e) 
+        {
+             // nothing to do
+            getLogger().warn("Unable to access internal logger properties", e);
+        }
+        
+        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
+        return EMPTY_MAP;
+    }
+    
+    /**
+     * Creates a log category 
+     * @param children the list of categories already created
+     * @param categoryName the name of the category to create
+     * @param level the level of the category to create
+     * @param fullName the full name of the category
+     */
+    public void createCategory(List<Map<String, Object>> children, String categoryName, String level, String fullName)
+    {
+        int i = categoryName.indexOf(".");
+        if (i != -1)
+        {
+            // Creates intermediary tree nodes
+            String parentCategoryName = categoryName.substring(0, i);
+            String childCategoryName = categoryName.substring(i + 1);
+            
+            Map<String, Object> parentCategoryNode = _getNode(children, parentCategoryName);
+            
+            if (parentCategoryNode == null)
+            {
+                // We did not find any existing node, let's create it
+                parentCategoryNode = new HashMap<> ();
+                parentCategoryNode.put("children", new ArrayList<> ());
+                parentCategoryNode.put("level", "inherit");
+                parentCategoryNode.put("name", parentCategoryName);
+                parentCategoryNode.put("fullname", fullName.substring(0, fullName.indexOf(parentCategoryName)) + parentCategoryName);
+                
+                children.add(parentCategoryNode);
+            }
+            
+            createCategory((List<Map<String, Object>>) parentCategoryNode.get("children"), childCategoryName, level, fullName);
+        }
+        else
+        {
+            Map<String, Object> categoryNode = _getNode(children, categoryName);
+            if (categoryNode == null)
+            {
+                // Creates tree leaves
+                categoryNode = new HashMap<> ();
+                
+                categoryNode.put("children", new ArrayList<> ());
+                categoryNode.put("level", level);
+                categoryNode.put("name", categoryName);
+                categoryNode.put("fullname", fullName);
+    
+                children.add(categoryNode);
+            }
+            else
+            {
+                // The intermediary node was already created, let's update it
+                categoryNode.put("level", level);
+            }
+        }
+    }
+    
+    private Map<String, Object> _getNode(List<Map<String, Object>> children, String categoryName)
+    {
+        for (Map<String, Object> child : children)
+        {
+            if (StringUtils.equals((String) child.get("name"), categoryName))
+            {
+                return child;
+            }
+        }
+        return null;
+    }
+}
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LoggerComparator.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LoggerComparator.java	(revision 0)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LoggerComparator.java	(revision 0)
@@ -0,0 +1,61 @@
+/*
+ *  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.runtime.plugins.core.administrator.logs;
+
+import java.util.Comparator;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Comparator to compare two loggers by their name 
+ */
+public class LoggerComparator implements Comparator<Logger>
+{
+    public int compare(Logger o1, Logger o2)
+    {
+        String[] o1NameParts = o1.getName().split("\\.");
+        String[] o2NameParts = o2.getName().split("\\.");
+        int i = 0;
+        
+        for (; i < o1NameParts.length && i < o2NameParts.length; i++)
+        {
+            int compare = o1NameParts[i].compareTo(o2NameParts[i]);
+            
+            if (compare != 0)
+            {
+                return compare;
+            }
+            
+            // Same category, continue
+        }
+        
+        if (i == o1NameParts.length)
+        {
+            if (i != o2NameParts.length)
+            {
+                // o2 has a longer category
+                return 1;
+            }
+        }
+        else
+        {
+            // o1 has a longer category
+            return -1;
+        }
+        
+        return o1.getName().compareTo(o2.getName());
+    }
+}
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsClientSideElement.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsClientSideElement.java	(revision 0)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsClientSideElement.java	(revision 0)
@@ -0,0 +1,275 @@
+package org.ametys.runtime.plugins.core.administrator.logs;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.ModifiableTraversableSource;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggerRepository;
+
+import org.ametys.runtime.ui.Callable;
+import org.ametys.runtime.ui.StaticClientSideElement;
+
+/**
+ * Client side element for log actions
+ */
+public class LogsClientSideElement extends StaticClientSideElement
+{
+    /** The path to the application's logs folder */
+    private static final String __LOGS_BASE = "context://WEB-INF/logs/";
+    
+    /** The Excalibur source resolver */
+    private SourceResolver _sourceResolver;
+    
+    @Override
+    public void service(ServiceManager serviceManager) throws ServiceException
+    {
+        super.service(serviceManager);
+        _sourceResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE);
+    }
+    
+    /**
+     * Delete the logs at the specified locations
+     * @param files list of file ids mapped with their relative location from the logs folder
+     * @return a map
+     * @throws IOException 
+     * @throws ProcessingException 
+     */
+    @Callable
+    public Map<String, Object> deleteLogs(List<String> files) throws ProcessingException, IOException
+    {
+        Map<String, Object> result = new HashMap<>();
+        List<String> failures = new ArrayList<> ();
+        List<String> successes = new ArrayList<> ();
+        
+        if (getLogger().isInfoEnabled())
+        {
+            getLogger().info("Administrator starts a deletion of " + files.size() + " logged file");
+        }
+        
+        // Delete the selected files one by one
+        for (String location : files)
+        {
+            if (_deleteFile(location))
+            {
+                successes.add(location);
+            }
+            else
+            {
+                failures.add(location);
+            }
+        }
+        
+        if (getLogger().isInfoEnabled())
+        {
+            getLogger().info("Process terminated with following results : failure '" + failures.toString() + " successes '" + successes.toString());
+        }
+        
+        result.put("failures", failures);
+        result.put("successes", successes);
+        return result;
+    }
+    
+    /**
+     * Delete the log entries that are at least 12 days old
+     * @return a map
+     * @throws ProcessingException if an exception occurs while processing the deletion
+     */
+    @Callable
+    public Map<String, Object> purgeLogs() throws ProcessingException
+    {
+        Map<String, Object> result = new HashMap<> ();
+        
+        Calendar purgeCalendar = new GregorianCalendar();
+        purgeCalendar.add(Calendar.DAY_OF_MONTH, -12);
+        Date purgeDate = new Date(purgeCalendar.getTimeInMillis());
+
+        if (getLogger().isDebugEnabled())
+        {
+            getLogger().debug("Starting purge...");
+            getLogger().debug("Purge date is " + purgeDate);
+        }
+
+        List<String> filesList = new ArrayList<String>();
+        TraversableSource logsSources = null;
+        try
+        {
+            logsSources = (TraversableSource) _sourceResolver.resolveURI(__LOGS_BASE);
+            for (Object log : logsSources.getChildren())
+            {
+                ModifiableTraversableSource logSource = (ModifiableTraversableSource) log;
+                if (!logSource.isCollection() && logSource.getURI().endsWith(".log") && new Date(logSource.getLastModified()).before(purgeDate))
+                {
+                    String location = logSource.getURI();
+                    String name = location.substring(location.lastIndexOf('/') + 1);
+                    filesList.add(name);
+                    if (getLogger().isDebugEnabled())
+                    {
+                        getLogger().debug("Adding file to purge : " + name);
+                    }
+                }
+            }
+            
+            result.put("filesToPurge", filesList);
+            return result;
+        }
+        catch (SourceException e)
+        {
+            String message = "The purge of old log files failed";
+            getLogger().error(message, e);
+            throw new ProcessingException(message, e);
+        }
+        catch (IOException e)
+        {
+            String message = "The log directory was not found";
+            getLogger().error(message, e);
+            throw new ProcessingException(message, e);
+        }
+        finally
+        {
+            if (logsSources != null)
+            {
+                _sourceResolver.release(logsSources);
+            }
+        }  
+    }
+    
+    private boolean _deleteFile(String fileLocation) throws IOException, ProcessingException
+    {
+        if (fileLocation.indexOf("/") != -1 || fileLocation.indexOf('\\') != -1)
+        {
+            String message = "The LogsDeleteAction has been call with the forbiden parameter '" + fileLocation + "'";
+            getLogger().error(message);
+            throw new ProcessingException(message);
+        }
+        
+        ModifiableSource logsource = null;
+        try
+        {
+            if (fileLocation.endsWith(".log"))
+            {
+                logsource = (ModifiableSource) _sourceResolver.resolveURI(__LOGS_BASE + fileLocation);
+                if (getLogger().isInfoEnabled())
+                {
+                    getLogger().info("Removing log file " + logsource.getURI());
+                }
+                logsource.delete();
+                return true;
+            }
+            else if (getLogger().isWarnEnabled())
+            {
+                getLogger().warn("Ignoring this file during deletion '" + "' because it does not ends with .log");
+            }
+            return false;
+        }
+        catch (SourceException e)
+        {
+            getLogger().error("The administrator tried unsuccessfully to remove the following log file '" + (logsource != null ? logsource.getURI() : fileLocation) + "'.", e);
+            return false;
+        }
+        finally
+        {
+            if (logsource != null)
+            {
+                _sourceResolver.release(logsource);
+            }
+        }
+    }
+    
+    /**
+     * Change the log level of the selected category to the selected level
+     * @param level the selected level
+     * @param category the selected category
+     * @return a map
+     */
+    @Callable
+    public Map<String, Object> changeLogLevel(String level, String category)
+    {
+        Map<String, Object> result = new HashMap<>();
+        
+        if (getLogger().isInfoEnabled())
+        {
+            getLogger().info("Administrator change log level");
+        }
+
+        LoggerRepository loggerRepository = LogManager.getLoggerRepository();
+        
+        if (getLogger().isInfoEnabled())
+        {
+            getLogger().info("Log level changing category '" + category + "' " + level);
+        }
+
+        try
+        {
+            _changeLogLevel(loggerRepository, category, level);
+        }
+        catch (Throwable t)
+        {
+            String errorMessage = "Cannot change log level correctly : changing category '" + category + "'";
+            getLogger().error(errorMessage, t);
+            result.put("error", "error");
+            return result;
+        }
+        
+        return result;
+    }
+    
+    private void _changeLogLevel(LoggerRepository loggerRepository, String category, String mode)
+    {
+        boolean inherited = "INHERIT".equals(mode) || "INHERITFORCED".equals(mode);
+        boolean force = "FORCE".equals(mode) || "INHERITFORCED".equals(mode);
+
+        Logger logger;
+        boolean isRoot = false;
+        
+        if ("root".equals(category))
+        {
+            isRoot = true;
+            logger = loggerRepository.getRootLogger();
+        }
+        else
+        {
+            logger = loggerRepository.getLogger(category);
+        }
+    
+        if (inherited && !isRoot)
+        {
+            logger.setLevel(null);
+        }
+        
+        if (force)
+        {
+            Enumeration<Logger> e = loggerRepository.getCurrentLoggers();
+            while (e.hasMoreElements())
+            {
+                Logger l = e.nextElement();
+                if (l.getParent() == logger)
+                {
+                    _changeLogLevel(loggerRepository, l.getName(), "INHERITFORCED");
+                }
+            }
+        }
+
+        if (!inherited && !force)
+        {
+            Level level = Level.toLevel(mode);
+            logger.setLevel(level);
+        }
+    }
+}
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsDeleteAction.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsDeleteAction.java	(revision 31873)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsDeleteAction.java	(nonexistent)
@@ -1,189 +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.runtime.plugins.core.administrator.logs;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.ProcessingException;
-import org.apache.cocoon.acting.ServiceableAction;
-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.excalibur.source.ModifiableSource;
-import org.apache.excalibur.source.ModifiableTraversableSource;
-import org.apache.excalibur.source.SourceException;
-import org.apache.excalibur.source.TraversableSource;
-
-/**
- * Delete given logs
- */
-public class LogsDeleteAction extends ServiceableAction implements ThreadSafe
-{
-    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
-    {
-        StringBuffer failure = new StringBuffer(); 
-        StringBuffer done = new StringBuffer(); 
-        
-        Request request = ObjectModelHelper.getRequest(objectModel);
-
-        // Liste les fichiers
-        String[] files;
-        if ("true".equals(parameters.getParameter("purge", "false")))
-        {
-            if (getLogger().isInfoEnabled())
-            {
-                getLogger().info("Administrator starts a purge of logged file");
-            }
-            files = _purgeFiles(resolver);
-        }
-        else
-        {
-            files = request.getParameterValues("file");
-            if (getLogger().isInfoEnabled())
-            {
-                getLogger().info("Administrator starts a deletion of " + files.length + " logged file");
-            }
-        }
-        
-        // Efface les fichier listés
-        for (String file : files)
-        {
-            _deleteFile(file, resolver, failure, done);
-        }
-        
-        if (getLogger().isInfoEnabled())
-        {
-            getLogger().info("Process terminated with following results : failure '" + failure.toString() + "' and done '" + done.toString() + "'");
-        }
-
-        Map<String, String> result = new HashMap<>();
-        result.put("failure", failure.toString());
-        result.put("done", done.toString());
-        return result;
-    }
-    
-    private void _deleteFile(String file, SourceResolver resolver, StringBuffer failure, StringBuffer done) throws IOException, ProcessingException
-    {
-        if (file.indexOf("/") != -1 || file.indexOf('\\') != -1)
-        {
-            String message = "The LogsDeleteAction has been call with the forbiden parameter '" + file + "'";
-            getLogger().error(message);
-            throw new ProcessingException(message);
-        }
-        
-        ModifiableSource logsource = null;
-        try
-        {
-            if (file.endsWith(".log"))
-            {
-                logsource = (ModifiableSource) resolver.resolveURI("context://WEB-INF/logs/" + file);
-                if (getLogger().isInfoEnabled())
-                {
-                    getLogger().info("Removing log file " + logsource.getURI());
-                }
-                logsource.delete();
-                done.append('/');
-                done.append(file);
-                done.append('/');
-            }
-            else if (getLogger().isWarnEnabled())
-            {
-                getLogger().warn("Ignoring this file during deletion '" + "' because it does not ends with .log");
-            }
-        }
-        catch (SourceException e)
-        {
-            failure.append('/');
-            failure.append(file);
-            failure.append('/');
-            getLogger().error("The administrator tried unsuccessfully to remove the following log file '" + (logsource != null ? logsource.getURI() : file) + "'.", e);
-        }
-        finally
-        {
-            if (logsource != null)
-            {
-                resolver.release(logsource);
-            }
-        }
-    }
-
-    private String[] _purgeFiles(SourceResolver resolver) throws ProcessingException
-    {
-        Calendar purgeCalendar = new GregorianCalendar();
-        purgeCalendar.add(Calendar.DAY_OF_MONTH, -12);
-        Date purgeDate = new Date(purgeCalendar.getTimeInMillis());
-
-        if (getLogger().isDebugEnabled())
-        {
-            getLogger().debug("Starting purge...");
-            getLogger().debug("Purge date is " + purgeDate);
-        }
-
-        List<String> filesList = new ArrayList<>();
-        TraversableSource logsSources = null;
-        try
-        {
-            logsSources = (TraversableSource) resolver.resolveURI("context://WEB-INF/logs");
-            for (Object log : logsSources.getChildren())
-            {
-                ModifiableTraversableSource logSource = (ModifiableTraversableSource) log;
-                if (!logSource.isCollection() && logSource.getURI().endsWith(".log") && new Date(logSource.getLastModified()).before(purgeDate))
-                {
-                    String location = logSource.getURI();
-                    String name = location.substring(location.lastIndexOf('/') + 1);
-                    filesList.add(name);
-                    if (getLogger().isDebugEnabled())
-                    {
-                        getLogger().debug("Adding file to purge : " + name);
-                    }
-                }
-            }
-            
-            String[] files = new String[filesList.size()];
-            filesList.toArray(files);
-            return files;
-        }
-        catch (SourceException e)
-        {
-            String message = "The purge of old log files failed";
-            getLogger().error(message, e);
-            throw new ProcessingException(message, e);
-        }
-        catch (IOException e)
-        {
-            String message = "The log directory was not found";
-            getLogger().error(message, e);
-            throw new ProcessingException(message, e);
-        }
-        finally
-        {
-            if (logsSources != null)
-            {
-                resolver.release(logsSources);
-            }
-        }  
-    }
-}
Index: main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsGenerator.java
===================================================================
--- main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsGenerator.java	(revision 31873)
+++ main/plugin-core/src/org/ametys/runtime/plugins/core/administrator/logs/LogsGenerator.java	(working copy)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2012 Anyware Services
+ *  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.
@@ -18,10 +18,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,14 +27,9 @@
 
 import org.apache.cocoon.ProcessingException;
 import org.apache.cocoon.generation.ServiceableGenerator;
-import org.apache.cocoon.xml.AttributesImpl;
 import org.apache.cocoon.xml.XMLUtils;
 import org.apache.excalibur.source.SourceException;
 import org.apache.excalibur.source.TraversableSource;
-import org.apache.log4j.Level;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.spi.LoggerRepository;
 import org.xml.sax.SAXException;
 
 import org.ametys.runtime.util.parameter.ParameterHelper;
@@ -52,60 +44,12 @@
     public void generate() throws IOException, SAXException, ProcessingException
     {
         contentHandler.startDocument();
-        XMLUtils.startElement(contentHandler, "Logger");
-
-        XMLUtils.startElement(contentHandler, "Logs");
+        XMLUtils.startElement(contentHandler, "logs");
         _logs();
-        XMLUtils.endElement(contentHandler, "Logs");
-
-        XMLUtils.startElement(contentHandler, "LogLevels");
-        _log4jLevels();
-        XMLUtils.endElement(contentHandler, "LogLevels");
-
-        XMLUtils.endElement(contentHandler, "Logger");
+        XMLUtils.endElement(contentHandler, "logs");
         contentHandler.endDocument();
     }
     
-    private void _log4jLevels() throws SAXException
-    {
-        try
-        {
-            LoggerRepository loggerRepository = LogManager.getLoggerRepository();
-            List<Logger> loggers = new ArrayList<>();
-            Enumeration<org.apache.log4j.Logger> enumLogger = loggerRepository.getCurrentLoggers();
-            
-            while (enumLogger.hasMoreElements())
-            {
-                loggers.add(enumLogger.nextElement());
-            }
-            
-            loggers.add(loggerRepository.getRootLogger());
-            
-            Collections.sort(loggers, new LoggerComparator());
-            
-            for (Logger logger : loggers)
-            {
-                String category = logger.getName();
-                Level level = logger.getLevel();
-                
-                AttributesImpl attrs = new AttributesImpl();
-                attrs.addCDATAAttribute("category", category);
-                attrs.addCDATAAttribute("priority", level == null ? "inherit" : level.toString());
-                
-                XMLUtils.createElement(contentHandler, "logger", attrs);
-            }
-        }
-        catch (SAXException e)
-        {
-            throw e;
-        }
-        catch (Exception e) 
-        {
-             // nothing to do
-            getLogger().warn("Unable to access internal logger properties", e);
-        }
-    }
-
     private void _logs() throws IOException, SAXException
     {
         TraversableSource logsDirectorySource = (TraversableSource) resolver.resolveURI("context://WEB-INF/logs");
@@ -116,21 +60,17 @@
             
             for (String logname : logs.keySet())
             {
-                AttributesImpl logattrs = new AttributesImpl();
-                logattrs.addCDATAAttribute("name", logname);
-                XMLUtils.startElement(contentHandler, "Log", logattrs);
-                
                 List<TraversableSource> logSources = logs.get(logname);
                 for (TraversableSource logSource : logSources)
                 {
-                    XMLUtils.startElement(contentHandler, "file");
+                    XMLUtils.startElement(contentHandler, "log");
+                    XMLUtils.createElement(contentHandler, "name", logname);
                     XMLUtils.createElement(contentHandler, "location", logSource.getURI().substring(logSource.getURI().lastIndexOf('/') + 1));
                     XMLUtils.createElement(contentHandler, "lastModified", ParameterHelper.valueToString(new Date(logSource.getLastModified())));
                     XMLUtils.createElement(contentHandler, "size", Long.toString(logSource.getContentLength()));
-                    XMLUtils.endElement(contentHandler, "file");
+                    XMLUtils.endElement(contentHandler, "log");
                 }
                 
-                XMLUtils.endElement(contentHandler, "Log");
             }
         }
         finally
@@ -141,7 +81,7 @@
     
     private Map<String, List<TraversableSource>> _prepareLogs(TraversableSource logsDirectorySource) throws SourceException
     {
-        Map<String, List<TraversableSource>> logs = new HashMap<>();
+        Map<String, List<TraversableSource>> logs = new HashMap<String, List<TraversableSource>>();
         
         Collection<TraversableSource> logFiles = logsDirectorySource.getChildren();
         for (TraversableSource logSource : logFiles)
@@ -156,7 +96,7 @@
                     List<TraversableSource> underLogs = logs.get(canonicalName);
                     if (underLogs == null)
                     {
-                        underLogs = new ArrayList<>();
+                        underLogs = new ArrayList<TraversableSource>();
                         logs.put(canonicalName, underLogs);
                     }
                     
@@ -184,45 +124,4 @@
             return null;
         }
     }
-    
-    /**
-     * Comparator to compare two loggers by their name 
-     */
-    public class LoggerComparator implements Comparator<Logger>
-    {
-        public int compare(Logger o1, Logger o2)
-        {
-            String[] o1NameParts = o1.getName().split("\\.");
-            String[] o2NameParts = o2.getName().split("\\.");
-            int i = 0;
-            
-            for (; i < o1NameParts.length && i < o2NameParts.length; i++)
-            {
-                int compare = o1NameParts[i].compareTo(o2NameParts[i]);
-                
-                if (compare != 0)
-                {
-                    return compare;
-                }
-                
-                // Same category, continue
-            }
-            
-            if (i == o1NameParts.length)
-            {
-                if (i != o2NameParts.length)
-                {
-                    // o2 has a longer category
-                    return 1;
-                }
-            }
-            else
-            {
-                // o1 has a longer category
-                return -1;
-            }
-            
-            return o1.getName().compareTo(o2.getName());
-        }
-    }
 }
