Index: main/plugin-web/plugin.xml
===================================================================
--- main/plugin-web/plugin.xml	(revision 32584)
+++ main/plugin-web/plugin.xml	(working copy)
@@ -9270,49 +9294,53 @@
                 </right>
             </extension>
             
-			<!-- <extension id="org.ametys.web.tool.user.FOUsers"
+			<extension id="org.ametys.web.FOUsers"
 					   point="org.ametys.core.ui.RibbonControlsManager"
     				   class="org.ametys.core.ui.StaticClientSideElement">
-				<action class="Ametys.ribbon.element.ui.button.OpenToolButtonController">
-					<param name="role">uitool-fo-users</param>
-					<param name="label" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_DESCRIPTION</param>
-					<param name="footer" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_FOOTER</param>
-					<param name="icon-small" file="true">img/users/fo_user_16.png</param>
-					<param name="icon-medium" file="true">img/users/fo_user_32.png</param>
-					<param name="icon-large" file="true">img/users/fo_user_48.png</param>
-				</action>
+				<class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+					<opentool-role>uitool-fo-users</opentool-role>
+					<label i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_LABEL</label>
+					<default-description i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_DESCRIPTION</default-description>
+					<footer i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_FOOTER</footer>
+					<icon-small file="true">img/users/fo_user_16.png</icon-small>
+					<icon-medium file="true">img/users/fo_user_32.png</icon-medium>
+					<icon-large file="true">img/users/fo_user_48.png</icon-large>
+				</class>
 				<css>
 					<file plugin="cms">css/users.css</file>
 				</css>
 				<right>Web_Rights_FOUsers_Handle</right>
 			</extension>
 			
-			<extension id="org.ametys.web.tool.user.FOUsersFactory"
+			<extension id="org.ametys.web.FOUsersFactory"
     				   point="org.ametys.core.ui.UIToolsFactoriesManager"
     				   class="org.ametys.core.ui.StaticClientSideElement">
-				<action class="org.ametys.web.tool.user.FOUsersToolFactory">
-					<param name="role">uitool-fo-users</param>
-					<param name="title" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_LABEL</param>
-					<param name="description" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_DESCRIPTION</param>
-					<param name="footer" i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_FOOTER</param>
-					<param name="icon-small" file="true">img/users/fo_user_16.png</param>
-					<param name="icon-medium" file="true">img/users/fo_user_32.png</param>
-					<param name="icon-large" file="true">img/users/fo_user_48.png</param>
-					<param name="default-location"></param>
-				</action>    				   
+				<class name="Ametys.tool.factory.UniqueToolFactory">
+					<role>uitool-fo-users</role>
+					<toolClass>Ametys.plugins.cms.user.UsersTool</toolClass>
+					
+					<users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+					<message-target-type>fo-user</message-target-type>
+					
+					<title i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_LABEL</title>
+					<description i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_DESCRIPTION</description>
+					<footer i18n="true">PLUGINS_WEB_UITOOL_FO_USERS_FOOTER</footer>
+					<icon-small file="true">img/users/fo_user_16.png</icon-small>
+					<icon-medium file="true">img/users/fo_user_32.png</icon-medium>
+					<icon-large file="true">img/users/fo_user_48.png</icon-large>
+					<default-location>c</default-location>
+				</class>    				   
 				<scripts>
-					<file>js/org/ametys/web/tool/user/FOUsersTool.js</file>
-					<file>js/org/ametys/web/tool/user/FOUsersToolFactory.js</file>
+					<file plugin="cms">js/Ametys/plugins/cms/user/UsersTool.js</file>
 				</scripts>
     		</extension>
     		
     		<extension id="org.ametys.web.rights.FOUserTab"
     				   point="org.ametys.core.ui.RibbonTabsManager"
     				   class="org.ametys.core.ui.StaticClientSideElement">
-				<action class="Ametys.ribbon.element.tab.TabController">
-					<param name="tool-role">^uitool-fo-users$</param>
-				</action> 
+				<class name="Ametys.ribbon.element.tab.TabController">
+					<tool-role>^uitool-fo-users$</tool-role>
+				</class> 
 				<scripts>
 					<file plugin="cms">js/org/ametys/cms/ribbon/tab/ToolTab.js</file>
 				</scripts>   	
@@ -9321,17 +9349,21 @@
     		<extension id="org.ametys.web.rights.FOUsers.add"
     				   point="org.ametys.core.ui.RibbonControlsManager"
     				   class="org.ametys.web.frontoffice.users.ModifiableFOUsersClientSideElement">
-				<action class="org.ametys.ribbon.control.button.ActionButton">
-					<param name="action">org.ametys.web.tool.user.Edit.add</param>
-					<param name="label" i18n="true">plugin.cms:PLUGINS_CMS_USERS_NEW_LABEL</param>
-					<param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_USERS_NEW_DESCRIPTION</param>
-					<param name="icon-small" file="true" plugin="cms">img/users/add_16.png</param>
-					<param name="icon-medium" file="true" plugin="cms">img/users/add_32.png</param>
-					<param name="icon-large" file="true" plugin="cms">img/users/add_32.png</param>
-				</action>    				   
+				<class name="Ametys.ribbon.element.ui.ButtonController">
+					<action>Ametys.plugins.cms.user.UserActions.add</action>
+
+					<users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+                    <message-target-type>fo-user</message-target-type>
+					
+					<label i18n="true">plugin.cms:PLUGINS_CMS_USERS_NEW_LABEL</label>
+					<default-description i18n="true">plugin.cms:PLUGINS_CMS_USERS_NEW_DESCRIPTION</default-description>
+					<icon-small file="true" plugin="cms">img/users/add_16.png</icon-small>
+					<icon-medium file="true" plugin="cms">img/users/add_32.png</icon-medium>
+					<icon-large file="true" plugin="cms">img/users/add_32.png</icon-large>
+				</class>    				   
 				<scripts>
-					<file plugin="cms">js/org/ametys/cms/tool/user/Actions.js</file>
-					<file>js/org/ametys/web/tool/user/Actions.js</file>
+					<file plugin="cms">js/Ametys/plugins/cms/user/UserActions.js</file>
+					<file plugin="cms">js/Ametys/plugins/cms/user/UserActions/UserEdition.js</file>
 				</scripts>
 				<css>
 					<file plugin="cms">css/users.css</file>
@@ -9342,19 +9374,23 @@
     		<extension id="org.ametys.web.rights.FOUsers.edit"
     				   point="org.ametys.core.ui.RibbonControlsManager"
     				   class="org.ametys.web.frontoffice.users.ModifiableFOUsersClientSideElement">
-				<action class="org.ametys.ribbon.control.button.ActionSelectionButton">
-					<param name="action">org.ametys.web.tool.user.Edit.modify</param>
-					<param name="target-type">^fo-user$</param>
+				<class name="Ametys.ribbon.element.ui.ButtonController">
+					<action>Ametys.plugins.cms.user.UserActions.modify</action>
 					
-					<param name="label" i18n="true">plugin.cms:PLUGINS_CMS_USERS_MODIFY_LABEL</param>
-					<param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_USERS_MODIFY_DESCRIPTION</param>
-					<param name="icon-small" file="true" plugin="cms">img/users/modify_16.png</param>
-					<param name="icon-medium" file="true" plugin="cms">img/users/modify_32.png</param>
-					<param name="icon-large" file="true" plugin="cms">img/users/modify_32.png</param>
-				</action>    				   
+					<users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+                    <message-target-type>fo-user</message-target-type>
+					
+					<selection-target-type>^fo-user$</selection-target-type>
+					
+					<label i18n="true">plugin.cms:PLUGINS_CMS_USERS_MODIFY_LABEL</label>
+					<default-description i18n="true">plugin.cms:PLUGINS_CMS_USERS_MODIFY_DESCRIPTION</default-description>
+					<icon-small file="true" plugin="cms">img/users/modify_16.png</icon-small>
+					<icon-medium file="true" plugin="cms">img/users/modify_32.png</icon-medium>
+					<icon-large file="true" plugin="cms">img/users/modify_32.png</icon-large>
+				</class>    				   
 				<scripts>
-					<file plugin="cms">js/org/ametys/cms/tool/user/Actions.js</file>
-					<file>js/org/ametys/web/tool/user/Actions.js</file>
+					<file plugin="cms">js/Ametys/plugins/cms/user/UserActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/user/UserActions/UserEdition.js</file>
 				</scripts>
 				<css>
 					<file plugin="cms">css/users.css</file>
@@ -9365,22 +9401,26 @@
     		<extension id="org.ametys.web.rights.FOUsers.delete"
     				   point="org.ametys.core.ui.RibbonControlsManager"
     				   class="org.ametys.web.frontoffice.users.ModifiableFOUsersClientSideElement">
-				<action class="org.ametys.ribbon.control.button.ActionSelectionButton">
-					<param name="action">org.ametys.web.tool.user.Delete.act</param>
-					<param name="target-type">^fo-user$</param>
+				<class name="Ametys.ribbon.element.ui.ButtonController">
+					<action>Ametys.plugins.cms.user.UserActions.delete</action>
+					
+					<users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+                    <message-target-type>fo-user</message-target-type>
+					
+					<selection-target-type>^fo-user$</selection-target-type>
 
-					<param name="label" i18n="true">plugin.cms:PLUGINS_CMS_USERS_DELETE_LABEL</param>
-					<param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_USERS_DELETE_DESCRIPTION</param>
-					<param name="icon-small" file="true" plugin="cms">img/users/delete_16.png</param>
-					<param name="icon-medium" file="true" plugin="cms">img/users/delete_32.png</param>
-					<param name="icon-large" file="true" plugin="cms">img/users/delete_50.png</param>
-				</action>    				   
+					<label i18n="true">plugin.cms:PLUGINS_CMS_USERS_DELETE_LABEL</label>
+					<default-description i18n="true">plugin.cms:PLUGINS_CMS_USERS_DELETE_DESCRIPTION</default-description>
+					<icon-small file="true" plugin="cms">img/users/delete_16.png</icon-small>
+					<icon-medium file="true" plugin="cms">img/users/delete_32.png</icon-medium>
+					<icon-large file="true" plugin="cms">img/users/delete_50.png</icon-large>
+				</class>    				   
 				<scripts>
-					<file plugin="cms">js/org/ametys/cms/tool/user/Actions.js</file>
-					<file>js/org/ametys/web/tool/user/Actions.js</file>
+					<file plugin="cms">js/Ametys/plugins/cms/user/UserActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/user/UserActions/UserEdition.js</file>
 				</scripts>
 				<right>Web_Rights_FOUsers_Handle</right>
-    		</extension> -->
+    		</extension>
 		</extensions>
 	</feature>
 	
@@ -9395,51 +9435,55 @@
                 </right>
             </extension>
             
-            <!-- <extension id="org.ametys.web.tool.group.FOGroups"
+            <extension id="org.ametys.web.FOGroups"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.core.ui.StaticClientSideElement">
-                <action class="Ametys.ribbon.element.ui.button.OpenToolButtonController">
-                    <param name="role">uitool-fo-groups</param>
-                    <param name="label" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_LABEL</param>
-                    <param name="default-description" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_DESCRIPTION</param>
-                    <param name="footer" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_FOOTER</param>
-                    <param name="icon-small" file="true">img/groups/fo_group_16.png</param>
-                    <param name="icon-medium" file="true">img/groups/fo_group_32.png</param>
-                    <param name="icon-large" file="true">img/groups/fo_group_48.png</param>
-                </action>
+                <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-fo-groups</opentool-role>
+                    <label i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_LABEL</label>
+                    <default-description i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_DESCRIPTION</default-description>
+                    <footer i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_FOOTER</footer>
+                    <icon-small file="true">img/groups/fo_group_16.png</icon-small>
+                    <icon-medium file="true">img/groups/fo_group_32.png</icon-medium>
+                    <icon-large file="true">img/groups/fo_group_48.png</icon-large>
+                </class>
                 <css>
                     <file plugin="cms">css/groups.css</file>
                 </css>
                 <right>Web_Rights_FOGroups_Handle</right>
             </extension>
             
-            <extension id="org.ametys.web.tool.group.FOGroupsFactory"
+            <extension id="org.ametys.web.FOGroupsFactory"
                        point="org.ametys.core.ui.UIToolsFactoriesManager"
                        class="org.ametys.core.ui.StaticClientSideElement">
-                <action class="org.ametys.web.tool.group.FOGroupsToolFactory">
-                    <param name="role">uitool-fo-groups</param>
-                    <param name="title" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_LABEL</param>
-                    <param name="description" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_DESCRIPTION</param>
-                    <param name="footer" i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_FOOTER</param>
-                    <param name="icon-small" file="true">img/groups/fo_group_16.png</param>
-                    <param name="icon-medium" file="true">img/groups/fo_group_32.png</param>
-                    <param name="icon-large" file="true">img/groups/fo_group_48.png</param>
-                    <param name="default-location"></param>
-                </action>                      
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-fo-groups</role>
+                    <toolClass>Ametys.plugins.cms.group.GroupsTool</toolClass>
+                    
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                    <user-message-target-type>fo-user</user-message-target-type>
+                    
+                    <title i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_LABEL</title>
+                    <description i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_DESCRIPTION</description>
+                    <footer i18n="true">PLUGINS_WEB_UITOOL_FO_GROUPS_FOOTER</footer>
+                    <icon-small file="true">img/groups/fo_group_16.png</icon-small>
+                    <icon-medium file="true">img/groups/fo_group_32.png</icon-medium>
+                    <icon-large file="true">img/groups/fo_group_48.png</icon-large>
+                    <default-location>c</default-location>
+                </class>                      
                 <scripts>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/GroupsTool.js</file>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/GroupsToolFactory.js</file>
-                    <file>js/org/ametys/web/tool/group/FOGroupsTool.js</file>
-                    <file>js/org/ametys/web/tool/group/FOGroupsToolFactory.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupsTool.js</file>
                 </scripts>
             </extension>
             
             <extension id="org.ametys.web.rights.FOGroupTab"
                        point="org.ametys.core.ui.RibbonTabsManager"
                        class="org.ametys.core.ui.StaticClientSideElement">
-                <action class="Ametys.ribbon.element.tab.TabController">
+                <class name="Ametys.ribbon.element.tab.TabController">
                     <param name="tool-role">^uitool-fo-groups$</param>
-                </action> 
+                </class> 
                 <scripts>
                     <file plugin="cms">js/org/ametys/cms/ribbon/tab/ToolTab.js</file>
                 </scripts>      
@@ -9448,17 +9492,22 @@
             <extension id="org.ametys.web.rights.fogroup.Add"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.web.frontoffice.groups.ModifiableFOGroupsClientSideElement">
-                <action class="org.ametys.ribbon.control.button.ActionButton">
-                    <param name="action">org.ametys.web.tool.group.Edit.add</param>
-                    <param name="label" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_NEW_LABEL</param>
-                    <param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_NEW_DESCRIPTION</param>
-                    <param name="icon-small" file="true" plugin="cms">img/groups/add_16.png</param>
-                    <param name="icon-medium" file="true" plugin="cms">img/groups/add_32.png</param>
-                    <param name="icon-large" file="true" plugin="cms">img/groups/add_50.png</param>
-                </action>                      
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.cms.group.GroupActions.add</action>
+                    
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                    <user-message-target-type>fo-user</user-message-target-type>
+                    
+                    <label i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_NEW_LABEL</label>
+                    <default-description i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_NEW_DESCRIPTION</default-description>
+                    <icon-small file="true" plugin="cms">img/groups/add_16.png</icon-small>
+                    <icon-medium file="true" plugin="cms">img/groups/add_32.png</icon-medium>
+                    <icon-large file="true" plugin="cms">img/groups/add_50.png</icon-large>
+                </class>                      
                 <scripts>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/Actions.js</file>
-                    <file>js/org/ametys/web/tool/group/Actions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions/GroupEdition.js</file>
                 </scripts>
                 <css>
                     <file plugin="cms">css/groups.css</file>
@@ -9469,19 +9518,23 @@
             <extension id="org.ametys.web.rights.fogroup.Modify"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.web.frontoffice.groups.ModifiableFOGroupsClientSideElement">
-                <action class="org.ametys.ribbon.control.button.ActionSelectionButton">
-                    <param name="action">org.ametys.web.tool.group.Edit.edit</param>
-                    <param name="target-type">^fo-group$</param>
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.cms.group.GroupActions.modify</action>
+                    <selection-target-type>^fo-group$</selection-target-type>
                     
-                    <param name="label" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_RENAME_LABEL</param>
-                    <param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_RENAME_DESCRIPTION</param>
-                    <param name="icon-small" file="true" plugin="cms">img/groups/rename_16.png</param>
-                    <param name="icon-medium" file="true" plugin="cms">img/groups/rename_32.png</param>
-                    <param name="icon-large" file="true" plugin="cms">img/groups/rename_50.png</param>
-                </action>                      
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                    <user-message-target-type>fo-user</user-message-target-type>
+                    
+                    <label i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_RENAME_LABEL</label>
+                    <default-description i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_RENAME_DESCRIPTION</default-description>
+                    <icon-small file="true" plugin="cms">img/groups/rename_16.png</icon-small>
+                    <icon-medium file="true" plugin="cms">img/groups/rename_32.png</icon-medium>
+                    <icon-large file="true" plugin="cms">img/groups/rename_50.png</icon-large>
+                </class>                      
                 <scripts>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/Actions.js</file>
-                    <file>js/org/ametys/web/tool/group/Actions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions/GroupEdition.js</file>
                 </scripts>
                 <css>
                     <file plugin="cms">css/groups.css</file>
@@ -9492,19 +9545,22 @@
             <extension id="org.ametys.web.rights.fogroup.Delete"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.web.frontoffice.groups.ModifiableFOGroupsClientSideElement">
-                <action class="org.ametys.ribbon.control.button.ActionSelectionButton">
-                    <param name="action">org.ametys.web.tool.group.Delete.act</param>
-                    <param name="target-type">^fo-group$</param>
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.cms.group.GroupActions.delete</action>
+                    <selection-target-type>^fo-group$</selection-target-type>
                     
-                    <param name="label" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELETE_LABEL</param>
-                    <param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELETE_DESCRIPTION</param>
-                    <param name="icon-small" file="true" plugin="cms">img/groups/delete_16.png</param>
-                    <param name="icon-medium" file="true" plugin="cms">img/groups/delete_32.png</param>
-                    <param name="icon-large" file="true" plugin="cms">img/groups/delete_50.png</param>
-                </action>                      
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                    
+                    <label i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELETE_LABEL</label>
+                    <default-description i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELETE_DESCRIPTION</default-description>
+                    <icon-small file="true" plugin="cms">img/groups/delete_16.png</icon-small>
+                    <icon-medium file="true" plugin="cms">img/groups/delete_32.png</icon-medium>
+                    <icon-large file="true" plugin="cms">img/groups/delete_50.png</icon-large>
+                </class>                      
                 <scripts>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/Actions.js</file>
-                    <file>js/org/ametys/web/tool/group/Actions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions/GroupEdition.js</file>
                 </scripts>
                 <right>Web_Rights_FOGroups_Handle</right>
             </extension>
@@ -9513,20 +9569,24 @@
             <extension id="org.ametys.web.rights.fogroup.AddUsers"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.web.frontoffice.groups.ModifiableFOGroupsClientSideElement">
-                <action class="org.ametys.ribbon.control.button.ActionSelectionButton">
-                    <param name="action">org.ametys.web.tool.group.AddUsers.act</param>
-                    <param name="target-type">^fo-group$</param>
-
-                    <param name="label" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_ADDUSERS_LABEL</param>
-                    <param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_ADDUSERS_DESCRIPTION</param>
-                    <param name="icon-small" file="true" plugin="cms">img/users/add_16.png</param>
-                    <param name="icon-medium" file="true" plugin="cms">img/users/add_32.png</param>
-                    <param name="icon-large" file="true" plugin="cms">img/users/add_50.png</param>
-                </action>                      
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.cms.group.GroupActions.addUsers</action>
+                    <selection-target-type>^fo-group$</selection-target-type>
+                    
+                    <users-manager-role>org.ametys.core.user.UsersManager.FO</users-manager-role>
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                
+                    <label i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_ADDUSERS_LABEL</label>
+                    <default-description i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_ADDUSERS_DESCRIPTION</default-description>
+                    <icon-small file="true" plugin="cms">img/users/add_16.png</icon-small>
+                    <icon-medium file="true" plugin="cms">img/users/add_32.png</icon-medium>
+                    <icon-large file="true" plugin="cms">img/users/add_50.png</icon-large>
+                </class>                      
                 <scripts>
-                    <file plugin="core">js/users/selectuser.js</file>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/Actions.js</file>
-                    <file>js/org/ametys/web/tool/group/Actions.js</file>
+                    <file plugin="core-ui">js/Ametys/helper/SelectUser.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions/GroupEdition.js</file>
                 </scripts>
                 <css>
                     <file plugin="core">css/users/selectuser.css</file>
@@ -9537,22 +9597,27 @@
             <extension id="org.ametys.web.rights.fogroup.DeleteUsers"
                        point="org.ametys.core.ui.RibbonControlsManager"
                        class="org.ametys.web.frontoffice.groups.ModifiableFOGroupsClientSideElement">
-                <action class="org.ametys.web.tool.group.FOUserFOGroupButton">
-                    <param name="action">org.ametys.web.tool.group.RemoveUsers.act</param>
-                    <param name="label" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELUSERS_LABEL</param>
-                    <param name="default-description" i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELUSERS_DESCRIPTION</param>
-                    <param name="icon-small" file="true" plugin="cms">img/users/delete_16.png</param>
-                    <param name="icon-medium" file="true" plugin="cms">img/users/delete_32.png</param>
-                    <param name="icon-large" file="true" plugin="cms">img/users/delete_50.png</param>
-                </action>                      
+                <class name="Ametys.ribbon.element.ui.ButtonController">
+                    <action>Ametys.plugins.cms.group.GroupActions.removeUsers</action>
+                    <selection-target-type>^fo-group$</selection-target-type>
+                    <selection-subtarget-type>^fo-user$</selection-subtarget-type>
+                    
+                    <groups-manager-role>org.ametys.core.group.GroupsManager.FO</groups-manager-role>
+                    <group-message-target-type>fo-group</group-message-target-type>
+                    <user-message-target-type>fo-user</user-message-target-type>
+                    
+                    <label i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELUSERS_LABEL</label>
+                    <default-description i18n="true">plugin.cms:PLUGINS_CMS_GROUPS_DELUSERS_DESCRIPTION</default-description>
+                    <icon-small file="true" plugin="cms">img/users/delete_16.png</icon-small>
+                    <icon-medium file="true" plugin="cms">img/users/delete_32.png</icon-medium>
+                    <icon-large file="true" plugin="cms">img/users/delete_50.png</icon-large>
+                </class>                      
                 <scripts>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/Actions.js</file>
-                    <file>js/org/ametys/web/tool/group/Actions.js</file>
-                    <file plugin="cms">js/org/ametys/cms/tool/group/UserGroupButton.js</file>
-                    <file>js/org/ametys/web/tool/group/FOUserFOGroupButton.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions.js</file>
+                    <file plugin="cms">js/Ametys/plugins/cms/group/GroupActions/GroupEdition.js</file>
                 </scripts>
                 <right>Web_Rights_FOGroups_Handle</right>
-            </extension>   -->                    
+            </extension>                
         </extensions>
     </feature>
     
Index: main/plugin-web/resources/js/org/ametys/web/tool/group/Actions.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/group/Actions.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/group/Actions.js	(nonexistent)
@@ -1,88 +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.
- */
-
-Ext.namespace('org.ametys.web.tool.group.Edit');
-Ext.namespace('org.ametys.web.tool.group.Delete');
-Ext.namespace('org.ametys.web.tool.group.AddUsers');
-Ext.namespace('org.ametys.web.tool.group.RemoveUsers');
-
-org.ametys.web.tool.group.FOGroups = function ()
-{
-	
-}
-org.ametys.web.tool.group.FOGroups.getAdditionalParams = function (params)
-{
-	params.groupsManagerRole = "org.ametys.runtime.group.GroupsManager.FO";
-}
-
-org.ametys.web.tool.group.FOGroups.checkTarget = function (target)
-{
-	return target.getType() == "fo-group";
-}
-org.ametys.web.tool.group.FOGroups.checkUserTarget = function (target)
-{
-	return target.getType() == "fo-user";
-}
-
-org.ametys.web.tool.group.FOGroups.createMessageTarget = function (id, name)
-{
-	return org.ametys.messagebus.bus.MessageBuilder.getInstance().createTarget("fo-group", {'id': id, 'name': name});
-}
-
-
-
-
-org.ametys.web.tool.group.Edit.add = function(controlId, configuration, pluginName)
-{
-	org.ametys.cms.tool.group.Edit._groups = org.ametys.web.tool.group.FOGroups;
-	org.ametys.cms.tool.group.Edit.pluginName = "cms";
-	org.ametys.cms.tool.group.Edit._mode = 'new';
-	org.ametys.cms.tool.group.Edit.act ();
-}
-
-org.ametys.web.tool.group.Edit.edit = function(controlId, configuration, pluginName)
-{
-	org.ametys.cms.tool.group.Edit._groups = org.ametys.web.tool.group.FOGroups;
-	org.ametys.cms.tool.group.Edit.pluginName = "cms";
-	org.ametys.cms.tool.group.Edit._mode = 'edit';
-	org.ametys.cms.tool.group.Edit.act ();
-}
-
-
-org.ametys.web.tool.group.Delete.act = function ()
-{
-	org.ametys.cms.tool.group.Edit._groups = org.ametys.web.tool.group.FOGroups;
-	Ext.Msg.confirm("<i18n:text i18n:key="PLUGINS_CORE_GROUPS_HANDLE_DELETE" i18n:catalogue="plugin.core"/>", 
-			"<i18n:text i18n:key="PLUGINS_CORE_GROUPS_DELETE_CONFIRM" i18n:catalogue="plugin.core"/>", 
-			org.ametys.cms.tool.group.Delete._doAction, 
-			this
-	);
-}
-org.ametys.web.tool.group.AddUsers.act = function () 
-{
-	org.ametys.cms.tool.group.Edit._groups = org.ametys.web.tool.group.FOGroups;
-	RUNTIME_Plugin_Runtime_SelectUser.initialize('core');
-	RUNTIME_Plugin_Runtime_SelectUser.act(org.ametys.cms.tool.group.AddUsers._doAction, null, "org.ametys.runtime.user.UsersManager.FO", true);	
-}
-
-org.ametys.web.tool.group.RemoveUsers.act = function () 
-{
-	org.ametys.cms.tool.group.Edit._groups = org.ametys.web.tool.group.FOGroups;
-	Ext.Msg.confirm("<i18n:text i18n:key="PLUGINS_CMS_GROUPS_DELUSERS_LABEL" i18n:catalogue="plugin.cms"/>", 
-				"<i18n:text i18n:key="PLUGINS_CMS_GROUPS_DELUSERS_CONFIRM" i18n:catalogue="plugin.cms"/>", 
-				org.ametys.cms.tool.group.RemoveUsers._doAction, 
-				this);
-}
\ No newline at end of file
Index: main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsTool.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsTool.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsTool.js	(nonexistent)
@@ -1,50 +0,0 @@
-/*
- *  Copyright 2014 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.
- */
-
-Ext.namespace('org.ametys.web.tool.group');
-
-org.ametys.web.tool.group.FOGroupsTool = function(id, pluginName) 
-{
-	org.ametys.web.tool.group.FOGroupsTool.superclass.constructor.call(this, id, pluginName);
-};
-Ext.extend(org.ametys.web.tool.group.FOGroupsTool, org.ametys.cms.tool.group.GroupsTool, {});
-
-org.ametys.web.tool.group.FOGroupsTool.prototype._createMessageTarget = function (record)
-{
-	return org.ametys.messagebus.bus.MessageBuilder.getInstance().createTarget("fo-group", {'id': record.data.id, 'name': record.data.name});
-}
-org.ametys.web.tool.group.FOGroupsTool.prototype._createUserMessageTarget = function (record)
-{
-	return org.ametys.messagebus.bus.MessageBuilder.getInstance().createTarget("fo-user", {'login': record.data.login});
-}
-org.ametys.web.tool.group.FOGroupsTool.prototype._checkTarget = function (target)
-{
-	return target.getType() == "fo-group";
-}
-org.ametys.web.tool.group.FOGroupsTool.prototype._onBeforeLoad = function (store, options)
-{
-	org.ametys.web.tool.group.FOGroupsTool.superclass._onBeforeLoad.call(this, store, options)
-
-	options.params.siteName = context.parameters.siteName;
-	options.params.groupsManagerRole = "org.ametys.runtime.group.GroupsManager.FO";
-}
-org.ametys.web.tool.group.FOGroupsTool.prototype._onBeforeLoadUsers = function (store, options)
-{
-	org.ametys.web.tool.group.FOGroupsTool.superclass._onBeforeLoadUsers.call(this, store, options)
-	options.params.groupsManagerRole = "org.ametys.runtime.group.GroupsManager.FO";
-	options.params.usersManagerRole = "org.ametys.runtime.user.UsersManager.FO";
-	options.params.siteName = context.parameters.siteName;
-}
Index: main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsToolFactory.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsToolFactory.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/group/FOGroupsToolFactory.js	(nonexistent)
@@ -1,32 +0,0 @@
-/*
- *  Copyright 2014 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.
- */
-
-Ext.namespace('org.ametys.web.tool.group');
-
-org.ametys.web.tool.group.FOGroupsToolFactory = function(id, config, pluginName) 
-{
-	org.ametys.web.tool.group.FOGroupsToolFactory.superclass.constructor.call(this, id, config, pluginName);
-};
-
-Ext.extend(org.ametys.web.tool.group.FOGroupsToolFactory, org.ametys.uitool.tool.impl.UniqueInstanceToolFactory,
-{
-	createTool : function (id)
-	{
-		var tool = new org.ametys.web.tool.group.FOGroupsTool (id, this.getPluginName());
-		tool.setConfiguration (this._config);
-		return tool;
-	}
-});
\ No newline at end of file
Index: main/plugin-web/resources/js/org/ametys/web/tool/group/FOUserFOGroupButton.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/group/FOUserFOGroupButton.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/group/FOUserFOGroupButton.js	(nonexistent)
@@ -1,53 +0,0 @@
-/*
- *  Copyright 2014 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.
- */
-
-Ext.namespace('org.ametys.web.tool.group');
-
-org.ametys.web.tool.group.FOUserFOGroupButton = function(id, configuration, pluginName) 
-{
-	org.ametys.web.tool.group.FOUserFOGroupButton.superclass.constructor.call(this, id, configuration, pluginName);
-};
-
-Ext.extend(org.ametys.web.tool.group.FOUserFOGroupButton, org.ametys.cms.tool.group.UserGroupButton, {});
-
-org.ametys.web.tool.group.FOUserFOGroupButton.prototype._isUserGroupSelection = function(targets)
-{
-	var findGroup = false;
-	var findUser = false;
-	
-	var allTargets = [];
-	for (var i=0; i < targets.length; i++)
-	{
-		if (targets[i].getType() == "fo-group")
-		{
-			findGroup = true;
-		}
-		else if (targets[i].getType() == "fo-user")
-		{
-			findUser = true;
-		}
-		
-		if (findGroup && findUser)
-		{
-			return true;
-		}
-	}
-	return false;
-}
-
-
-
-
Index: main/plugin-web/resources/js/org/ametys/web/tool/user/Actions.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/user/Actions.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/user/Actions.js	(nonexistent)
@@ -1,64 +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.
- */
-
-Ext.namespace('org.ametys.web.tool.user.Edit');
-Ext.namespace('org.ametys.web.tool.user.Delete');
-
-org.ametys.web.tool.user.FOUsers = function ()
-{
-	
-}
-org.ametys.web.tool.user.FOUsers.getAdditionalParams = function (params)
-{
-	params.usersManagerRole = "org.ametys.runtime.user.UsersManager.FO";
-}
-
-org.ametys.web.tool.user.FOUsers.checkTarget = function (target)
-{
-	return target.getType() == "fo-user";
-}
-
-org.ametys.web.tool.user.FOUsers.createMessageTarget = function (login)
-{
-	return org.ametys.messagebus.bus.MessageBuilder.getInstance().createTarget("fo-user", {'id': login});
-}
-
-org.ametys.web.tool.user.Edit.add = function (controlId, configuration, pluginName)
-{
-	org.ametys.cms.tool.user.Edit._users = org.ametys.web.tool.user.FOUsers;
-	
-	org.ametys.cms.tool.user.Edit.pluginName = 'cms';
-	org.ametys.cms.tool.user.Edit.act ('new');
-}
-
-org.ametys.web.tool.user.Edit.modify = function(controlId, configuration, pluginName)
-{
-	org.ametys.cms.tool.user.Edit._users = org.ametys.web.tool.user.FOUsers;
-	
-	org.ametys.cms.tool.user.Edit.pluginName = 'cms';
-	org.ametys.cms.tool.user.Edit.act ('edit');
-}
-
-org.ametys.web.tool.user.Delete.act = function ()
-{
-	org.ametys.cms.tool.user.Delete._users = org.ametys.web.tool.user.FOUsers;
-	
-	Ext.Msg.confirm("<i18n:text i18n:key="PLUGINS_CORE_USERS_HANDLE_DEL_TITLE" i18n:catalogue="plugin.core"/>", 
-			"<i18n:text i18n:key="PLUGINS_CORE_USERS_HANDLE_DEL_MULTI_PROMPT" i18n:catalogue="plugin.core"/>", 
-			org.ametys.cms.tool.user.Delete._doAction, 
-			this
-	);
-}
\ No newline at end of file
Index: main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersTool.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersTool.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersTool.js	(nonexistent)
@@ -1,69 +0,0 @@
-/*
- *  Copyright 2011 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.
- */
-
-Ext.namespace('org.ametys.web.tool.user');
-
-org.ametys.web.tool.user.FOUsersTool = function(id, pluginName) 
-{
-	org.ametys.web.tool.user.FOUsersTool.superclass.constructor.call(this, id, pluginName);
-};
-
-
-Ext.extend(org.ametys.web.tool.user.FOUsersTool, org.ametys.cms.tool.user.UsersTool, {});
-
-org.ametys.web.tool.user.FOUsersTool.prototype._createMessageTarget = function (record)
-{
-	return org.ametys.messagebus.bus.MessageBuilder.getInstance().createTarget("fo-user", {'id': record.data.login});
-}
-
-org.ametys.web.tool.user.FOUsersTool.prototype._checkTarget = function (target)
-{
-	return target.getType() == "fo-user";
-}
-
-org.ametys.web.tool.user.FOUsersTool.prototype._onBeforeLoad = function (store, options)
-{
-	org.ametys.web.tool.user.FOUsersTool.superclass._onBeforeLoad.call(this, store, options)
-
-	options.params.siteName = context.parameters.siteName;
-	options.params.usersManagerRole = "org.ametys.runtime.user.UsersManager.FO";
-}
-
-org.ametys.web.tool.user.FOUsersTool.prototype._getUserInfo = function (login)
-{
-	var params = {login: login};
-	params.usersManagerRole = "org.ametys.runtime.user.UsersManager.FO";
-	
-	var serverMessage = new org.ametys.servercomm.ServerMessage("core", "/users/info", params, org.ametys.servercomm.ServerComm.PRIORITY_SYNCHRONOUS, null, this, null);
-	var nodes = org.ametys.servercomm.ServerComm.getInstance().send(serverMessage);
-
-	if (org.ametys.servercomm.ServerComm.handleBadResponse("<i18n:text i18n:key="PLUGINS_CMS_USERS_ERROR_TITLE" i18n:catalogue="plugin.cms"/>", nodes, "org.ametys.cms.tool.user.UsersTool"))
-	{
-		return null;
-	}
-	
-	var userInfo = nodes.selectSingleNode("users-info/users/user[@login='" + params['login'] + "']");
-	var lastname = userInfo.selectSingleNode('lastname');
-	var firstname = userInfo.selectSingleNode('firstname');
-	var email = userInfo.selectSingleNode('email');
-	
-	var user = {};
-	user.login = login;
-	user.lastname = lastname != null ? lastname[org.ametys.servercomm.ServerComm.xmlTextContent] : '';
-	user.firstname = firstname != null ? firstname[org.ametys.servercomm.ServerComm.xmlTextContent] : '';
-	user.email = email != null ? email[org.ametys.servercomm.ServerComm.xmlTextContent] : '';
-	return user;
-}
Index: main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersToolFactory.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersToolFactory.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/tool/user/FOUsersToolFactory.js	(nonexistent)
@@ -1,32 +0,0 @@
-/*
- *  Copyright 2011 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.
- */
-
-Ext.namespace('org.ametys.web.tool.user');
-
-org.ametys.web.tool.user.FOUsersToolFactory = function(id, config, pluginName) 
-{
-	org.ametys.web.tool.user.FOUsersToolFactory.superclass.constructor.call(this, id, config, pluginName);
-};
-
-Ext.extend(org.ametys.web.tool.user.FOUsersToolFactory, org.ametys.uitool.tool.impl.UniqueInstanceToolFactory,
-{
-	createTool : function (id)
-	{
-		var tool = new org.ametys.web.tool.user.FOUsersTool (id, this.getPluginName());
-		tool.setConfiguration (this._config);
-		return tool;
-	}
-});
\ No newline at end of file

