From 2ce9dbb44e06af96cf491906b006b3fb0dbfe340 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Fri, 24 May 2019 10:40:06 +0200
Subject: [PATCH] OO-4064: enhance user management menu with more overviews on
 roles

---
 .../admin/_i18n/LocalStrings_et_EE.properties |   1 -
 .../admin/user/UserSearchFlexiController.java |   2 +-
 .../IdentityRelationshipService.java          |   4 +
 .../basesecurity/SearchIdentityParams.java    |  55 ++--
 .../IdentityPowerSearchQueriesImpl.java       |  35 +-
 .../IdentityRelationshipServiceImpl.java      |  10 +
 .../IdentityToIdentityRelationDAO.java        |  24 ++
 .../manager/DocEditorIdentityServiceImpl.java |   2 +-
 .../olat/user/ui/admin/InfoController.java    |  10 +-
 .../ui/admin/UserAdminMainController.java     | 303 +++++++++++++-----
 .../olat/user/ui/admin/_content/infos.html    |   3 +
 .../ui/admin/_content/predefinedqueries.html  |   2 -
 .../admin/_content/systemorganisations.html   |   3 -
 .../user/ui/admin/_content/systemroles.html   |   3 -
 .../ui/admin/_i18n/LocalStrings_ar.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_bg.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_cs.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_da.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_de.properties |  46 ++-
 .../ui/admin/_i18n/LocalStrings_el.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_en.properties |  44 ++-
 .../ui/admin/_i18n/LocalStrings_es.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_fa.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_fr.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_it.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_jp.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_lt.properties |  10 +-
 .../admin/_i18n/LocalStrings_nl_NL.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_pl.properties |  10 +-
 .../admin/_i18n/LocalStrings_pt_BR.properties |  10 +-
 .../admin/_i18n/LocalStrings_pt_PT.properties |  10 +-
 .../ui/admin/_i18n/LocalStrings_ru.properties |   6 +-
 .../ui/admin/_i18n/LocalStrings_sq.properties |  10 +-
 .../admin/_i18n/LocalStrings_zh_CN.properties |   6 +-
 .../admin/_i18n/LocalStrings_zh_TW.properties |   6 +-
 .../IdentityToIdentityRelationDAOTest.java    |  30 ++
 36 files changed, 481 insertions(+), 254 deletions(-)
 create mode 100644 src/main/java/org/olat/user/ui/admin/_content/infos.html
 delete mode 100644 src/main/java/org/olat/user/ui/admin/_content/predefinedqueries.html
 delete mode 100644 src/main/java/org/olat/user/ui/admin/_content/systemorganisations.html
 delete mode 100644 src/main/java/org/olat/user/ui/admin/_content/systemroles.html

diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_et_EE.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_et_EE.properties
index 6436ce50c1c..a737e409c81 100644
--- a/src/main/java/org/olat/admin/_i18n/LocalStrings_et_EE.properties
+++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_et_EE.properties
@@ -1,7 +1,6 @@
 #Wed Jun 03 01:25:10 CEST 2009
 menu.notifications=Teated
 menu.onlinetranslation=T\u00F5lkevahend
-menu.resourceowners=Autorid ja kaasautorid
 menu.search=T\u00E4istekstiotsing
 menu.search.alt=T\u00E4istekstiotsingu administreerimine
 menu.statistics=Statistika
diff --git a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
index aa1348f2f20..e91f5069b97 100644
--- a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
+++ b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java
@@ -460,7 +460,7 @@ public class UserSearchFlexiController extends FlexiAutoCompleterController {
 				userPropertiesSearch, userPropertiesAsIntersectionSearch, null, 
 				null, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT);
 		params.setOrganisations(searchableOrganisations);
-		params.setRepositoryEntryRole(repositoryEntryRole);
+		params.setRepositoryEntryRole(repositoryEntryRole, false);
 		return identitySearchQueries.getIdentitiesByPowerSearch(params, 0, -1);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/basesecurity/IdentityRelationshipService.java b/src/main/java/org/olat/basesecurity/IdentityRelationshipService.java
index eabe7e4e009..a5f3509c97c 100644
--- a/src/main/java/org/olat/basesecurity/IdentityRelationshipService.java
+++ b/src/main/java/org/olat/basesecurity/IdentityRelationshipService.java
@@ -67,6 +67,10 @@ public interface IdentityRelationshipService {
 	
 	public void deleteRelation(IdentityToIdentityRelation relation);
 	
+	public List<Identity> getSources(RelationRole relationRole);
+	
+	public List<Identity> getTargets(RelationRole relationRole);
+	
 	/**
 	 * 
 	 * @param asSource
diff --git a/src/main/java/org/olat/basesecurity/SearchIdentityParams.java b/src/main/java/org/olat/basesecurity/SearchIdentityParams.java
index a0ce98aaaaa..c23ef9191c1 100644
--- a/src/main/java/org/olat/basesecurity/SearchIdentityParams.java
+++ b/src/main/java/org/olat/basesecurity/SearchIdentityParams.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.OrganisationRef;
+import org.olat.modules.curriculum.CurriculumRoles;
 
 /**
  * 
@@ -43,8 +44,9 @@ public class SearchIdentityParams {
 	private OrganisationRoles[] roles;
 	private OrganisationRoles[] excludedRoles;
 	private GroupRoles repositoryEntryRole;
+	private boolean repositoryEntryRoleInDefaultOnly;
 	private GroupRoles businessGroupRole;
-	private boolean authorAndCoAuthor;
+	private CurriculumRoles curriculumRole;
 	
 	private String[] authProviders;
 	private Date createdAfter;
@@ -98,11 +100,13 @@ public class SearchIdentityParams {
 		return new SearchIdentityParams(null, null, true, null, authProviders, null, null, null, null, status);
 	}
 	
-	public static SearchIdentityParams resources(GroupRoles repositoryEntryRole, GroupRoles businessGroupRole,
+	public static SearchIdentityParams resources(GroupRoles repositoryEntryRole, boolean defOnly,
+			GroupRoles businessGroupRole, CurriculumRoles curriculumRole,
 			OrganisationRoles[] roles, OrganisationRoles[] excludedRoles, Integer status) {
 		SearchIdentityParams params = new SearchIdentityParams(null, null, true, null, null, null, null, null, null, status);
-		params.setRepositoryEntryRole(repositoryEntryRole);
+		params.setRepositoryEntryRole(repositoryEntryRole, defOnly);
 		params.setBusinessGroupRole(businessGroupRole);
+		params.setCurriculumRole(curriculumRole);
 		params.setRoles(roles);
 		params.setExcludedRoles(excludedRoles);
 		return params;
@@ -122,18 +126,6 @@ public class SearchIdentityParams {
 		return params;
 	}
 	
-	/**
-	 * 
-	 * @return A set of parameters to search authors along co-authors
-	 */
-	public static SearchIdentityParams authorsAndCoAuthors() {
-		SearchIdentityParams params = new SearchIdentityParams(null, null, true, null, null, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT);
-		params.setRepositoryEntryRole(GroupRoles.owner);
-		params.setRoles(new OrganisationRoles[] { OrganisationRoles.author } );
-		params.setAuthorAndCoAuthor(true);
-		return params;
-	}
-	
 	public boolean hasOrganisationParents() {
 		return organisationParents != null && !organisationParents.isEmpty();
 	}
@@ -218,8 +210,9 @@ public class SearchIdentityParams {
 		return repositoryEntryRole;
 	}
 
-	public void setRepositoryEntryRole(GroupRoles repositoryEntryRole) {
+	public void setRepositoryEntryRole(GroupRoles repositoryEntryRole, boolean defaultOnly) {
 		this.repositoryEntryRole = repositoryEntryRole;
+		this.repositoryEntryRoleInDefaultOnly = defaultOnly;
 	}
 
 	public GroupRoles getBusinessGroupRole() {
@@ -230,6 +223,22 @@ public class SearchIdentityParams {
 		this.businessGroupRole = businessGroupRole;
 	}
 
+	public boolean isRepositoryEntryRoleInDefaultOnly() {
+		return repositoryEntryRoleInDefaultOnly;
+	}
+
+	public void setRepositoryEntryRoleInDefaultOnly(boolean repositoryEntryRoleInDefaultOnly) {
+		this.repositoryEntryRoleInDefaultOnly = repositoryEntryRoleInDefaultOnly;
+	}
+
+	public CurriculumRoles getCurriculumRole() {
+		return curriculumRole;
+	}
+
+	public void setCurriculumRole(CurriculumRoles curriculumRole) {
+		this.curriculumRole = curriculumRole;
+	}
+
 	public boolean hasAuthProviders() {
 		return authProviders != null && authProviders.length > 0;
 	}
@@ -241,20 +250,6 @@ public class SearchIdentityParams {
 	public void setAuthProviders(String[] authProviders) {
 		this.authProviders = authProviders;
 	}
-	
-	public boolean isAuthorAndCoAuthor() {
-		return authorAndCoAuthor;
-	}
-
-	/**
-	 * Set to true, this search will overwrite the
-	 * roles and repository entry role specified.
-	 * 
-	 * @param authorAndCoAuthor
-	 */
-	private void setAuthorAndCoAuthor(boolean authorAndCoAuthor) {
-		this.authorAndCoAuthor = authorAndCoAuthor;
-	}
 
 	public Boolean getManaged() {
 		return managed;
diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java b/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java
index 47af52d24db..47041b0c226 100644
--- a/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java
+++ b/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java
@@ -162,26 +162,15 @@ public class IdentityPowerSearchQueriesImpl implements IdentityPowerSearchQuerie
 				|| params.getUserLoginAfter() != null || params.getUserLoginBefore() != null
 				|| params.hasAuthProviders() || params.getManaged() != null
 				|| params.getStatus() != null || (params.getExactStatusList() != null && !params.getExactStatusList().isEmpty())
-				|| params.hasRoles() || params.hasExcludedRoles() || params.isAuthorAndCoAuthor()
-				|| params.getRepositoryEntryRole() != null || params.getBusinessGroupRole() != null
+				|| params.hasRoles() || params.hasExcludedRoles()
+				|| params.getRepositoryEntryRole() != null || params.getBusinessGroupRole() != null || params.getCurriculumRole() != null
 				|| params.hasOrganisations() || params.hasOrganisationParents()
 				|| StringHelper.containsNonWhitespace(params.getIdAndExternalIds());
 	}
 	
 	private boolean createQueryPart(SearchIdentityParams params, QueryBuilder sb, boolean needsAnd) {	
 		// authors and co-authors is essentially an OR
-		if(params.isAuthorAndCoAuthor()) {
-			needsAnd = checkAnd(sb, needsAnd);
-			sb.append(" ident.key in (select membership.identity.key from bgroupmember membership ")
-			  .append("   left join repoentrytogroup as relGroup on (relGroup.group.key=membership.group.key) ")
-			  .append("   where  membership.role in (:roles) or (relGroup.group.key is not null and membership.role=:repositoryEntryRole))");
-			if(params.hasOrganisations()) {
-				sb.append(" and ident.key in  (select orgtomember.identity.key from bgroupmember as orgtomember ")
-				  .append("  inner join organisation as org on (org.group.key=orgtomember.group.key)")
-				  .append("  where orgtomember.identity.key=ident.key and orgtomember.inheritanceModeString in ('").append(GroupMembershipInheritance.none).append("','").append(GroupMembershipInheritance.root).append("')")
-				  .append("  and org.key in (:organisationKey))");
-			}
-		} else if(params.hasRoles() && params.hasOrganisations()) {
+		if(params.hasRoles() && params.hasOrganisations()) {
 			needsAnd = checkAnd(sb, needsAnd);
 			sb.append(" exists (select orgtomember.key from bgroupmember as orgtomember ")
 			  .append("  inner join organisation as org on (org.group.key=orgtomember.group.key)")
@@ -251,12 +240,22 @@ public class IdentityPowerSearchQueriesImpl implements IdentityPowerSearchQuerie
 			  .append("  where bmember.identity.key=ident.key and  bmember.role=:businessGroupRole)");
 		}
 		
-		if(params.getRepositoryEntryRole() != null && !params.isAuthorAndCoAuthor()) {
+		if(params.getRepositoryEntryRole() != null) {
 			needsAnd = checkAnd(sb, needsAnd);
 			sb.append(" exists (select rmember.key from repoentrytogroup as relGroup")
 			  .append("  inner join relGroup.group as rGroup")
 			  .append("  inner join rGroup.members as rmember")
-			  .append("  where rmember.identity.key=ident.key and  rmember.role=:repositoryEntryRole)");
+			  .append("  where rmember.identity.key=ident.key and  rmember.role=:repositoryEntryRole")
+			  .append("  and (relGroup.defaultGroup=true)", params.isRepositoryEntryRoleInDefaultOnly())
+			  .append(" )");
+		}
+		
+		if(params.getCurriculumRole() != null) {
+			needsAnd = checkAnd(sb, needsAnd);
+			sb.append(" exists (select curEl.key from curriculumelement as curEl")
+			  .append("  inner join curEl.group as cGroup")
+			  .append("  inner join cGroup.members as cmember")
+			  .append("  where cmember.identity.key=ident.key and  cmember.role=:curriculumRole)");
 		}
 		
 		// append query for identity primary keys
@@ -516,6 +515,10 @@ public class IdentityPowerSearchQueriesImpl implements IdentityPowerSearchQuerie
 		if(params.getRepositoryEntryRole() != null) {
 			dbq.setParameter("repositoryEntryRole", params.getRepositoryEntryRole().name());
 		}
+		
+		if(params.getCurriculumRole() != null) {
+			dbq.setParameter("curriculumRole", params.getCurriculumRole().name());
+		}
 
 		// add authentication providers
 		if (params.hasAuthProviders()) {
diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityRelationshipServiceImpl.java b/src/main/java/org/olat/basesecurity/manager/IdentityRelationshipServiceImpl.java
index 2a3811c038a..d07057ee722 100644
--- a/src/main/java/org/olat/basesecurity/manager/IdentityRelationshipServiceImpl.java
+++ b/src/main/java/org/olat/basesecurity/manager/IdentityRelationshipServiceImpl.java
@@ -164,6 +164,16 @@ public class IdentityRelationshipServiceImpl implements IdentityRelationshipServ
 		return identityRelationshipDao.getRelationsAsTarget(asTarget, searchParams);
 	}
 
+	@Override
+	public List<Identity> getSources(RelationRole relationRole) {
+		return identityRelationshipDao.getSources(relationRole);
+	}
+
+	@Override
+	public List<Identity> getTargets(RelationRole relationRole) {
+		return identityRelationshipDao.getTargets(relationRole);
+	}
+
 	@Override
 	public IdentityToIdentityRelation getRelation(Long relationKey) {
 		return identityRelationshipDao.getRelation(relationKey);
diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAO.java b/src/main/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAO.java
index 125ce653f98..a541a78e329 100644
--- a/src/main/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAO.java
+++ b/src/main/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAO.java
@@ -161,6 +161,30 @@ public class IdentityToIdentityRelationDAO {
 		return query.getResultList();
 	}
 	
+	public List<Identity> getSources(RelationRole role) {
+		QueryBuilder sb = new QueryBuilder(256);
+		sb.append("select distinct identSource from identitytoidentity as identRel")
+		  .append(" inner join identRel.source as identSource")
+		  .append(" inner join fetch identSource.user as userSource")
+		  .append(" where identRel.role.key=:roleKey");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Identity.class)
+				.setParameter("roleKey", role.getKey())
+				.getResultList();
+	}
+	
+	public List<Identity> getTargets(RelationRole role) {
+		QueryBuilder sb = new QueryBuilder(256);
+		sb.append("select distinct identTarget from identitytoidentity as identRel")
+		  .append(" inner join identRel.target as identTarget")
+		  .append(" inner join fetch identTarget.user as userTarget")
+		  .append(" where identRel.role.key=:roleKey");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Identity.class)
+				.setParameter("roleKey", role.getKey())
+				.getResultList();
+	}
+	
 	public void removeRelation(IdentityToIdentityRelation relation) {
 		dbInstance.getCurrentEntityManager().remove(relation);
 	}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java
index fad7a80c216..ba3f3caf9f0 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorIdentityServiceImpl.java
@@ -79,7 +79,7 @@ public class DocEditorIdentityServiceImpl implements DocEditorIdentityService {
 	public boolean isCoach(Identity identity) {
 		SearchIdentityParams params = new SearchIdentityParams();
 		params.setIdentityKeys(Collections.singletonList(identity.getKey()));
-		params.setRepositoryEntryRole(GroupRoles.coach);
+		params.setRepositoryEntryRole(GroupRoles.coach, false);
 		List<Identity> identities = securityManager.getIdentitiesByPowerSearch(params , 0, 1);
 		return !identities.isEmpty();
 	}
diff --git a/src/main/java/org/olat/user/ui/admin/InfoController.java b/src/main/java/org/olat/user/ui/admin/InfoController.java
index 3c24113edf2..5c61bfa4a0f 100644
--- a/src/main/java/org/olat/user/ui/admin/InfoController.java
+++ b/src/main/java/org/olat/user/ui/admin/InfoController.java
@@ -21,6 +21,7 @@ package org.olat.user.ui.admin;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
@@ -31,11 +32,14 @@ import org.olat.core.gui.control.controller.BasicController;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public class InfoController extends BasicController {
+class InfoController extends BasicController {
 	
-	public InfoController(UserRequest ureq, WindowControl wControl, String template) {
+	public InfoController(UserRequest ureq, WindowControl wControl, String title, String description) {
 		super(ureq, wControl);
-		putInitialPanel(createVelocityContainer(template));
+		VelocityContainer mainVC = createVelocityContainer("infos");
+		mainVC.contextPut("title", translate(title));
+		mainVC.contextPut("description", translate(description));
+		putInitialPanel(mainVC);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java b/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java
index 57ef907da19..ae7acc63834 100644
--- a/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java
+++ b/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java
@@ -41,8 +41,10 @@ import org.olat.admin.user.delete.TabbedPaneController;
 import org.olat.admin.user.imp.UserImportController;
 import org.olat.basesecurity.BaseSecurityModule;
 import org.olat.basesecurity.GroupRoles;
+import org.olat.basesecurity.IdentityRelationshipService;
 import org.olat.basesecurity.OrganisationRoles;
 import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.RelationRole;
 import org.olat.basesecurity.SearchIdentityParams;
 import org.olat.basesecurity.events.SingleIdentityChosenEvent;
 import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
@@ -80,7 +82,13 @@ import org.olat.core.util.UserSession;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.coordinate.LockResult;
 import org.olat.core.util.resource.OresHelper;
+import org.olat.modules.curriculum.CurriculumModule;
+import org.olat.modules.curriculum.CurriculumRoles;
+import org.olat.modules.lecture.LectureModule;
+import org.olat.modules.qpool.QuestionPoolModule;
+import org.olat.modules.quality.QualityModule;
 import org.olat.user.UserManager;
+import org.olat.user.ui.role.RelationRolesAndRightsUIFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -109,9 +117,6 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 	private Controller contentCtr;
 	private UserAdminController editCtrl;
 	private UserCreateController createCtrl;
-	private UserImportController importCtrl;
-	private TabbedPaneController deleteCtrl;
-	private DirectDeleteController directDeleteCtrl;
 	private LayoutMain3ColsController columnLayoutCtr;
 
 	private final Roles identityRoles;
@@ -121,7 +126,19 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 	@Autowired
 	private UserManager userManager;
 	@Autowired
+	private QualityModule qualityModule;
+	@Autowired
+	private LectureModule lectureModule;
+	@Autowired
+	private QuestionPoolModule poolModule;
+	@Autowired
+	private CurriculumModule curriculumModule;
+	@Autowired
+	private BaseSecurityModule securityModule;
+	@Autowired
 	private OrganisationService organisationService;
+	@Autowired
+	private IdentityRelationshipService relationshipService;
 
 	/**
 	 * Constructor of the home main controller
@@ -256,7 +273,7 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		Roles roles = ureq.getUserSession().getRoles();
 		boolean canCreateOLATPassword = roles.isAdministrator() || roles.isRolesManager() || roles.isUserManager();
 
-		importCtrl = new UserImportController(ureq, getWindowControl(), canCreateOLATPassword);
+		UserImportController importCtrl = new UserImportController(ureq, getWindowControl(), canCreateOLATPassword);
 		addToHistory(ureq, importCtrl);
 		listenTo(importCtrl);
 		content.rootController(translate("menu.usersimport"), importCtrl);
@@ -270,11 +287,25 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		Object uobject = treeNode.getUserObject();
 		if (uobject instanceof GenericActionExtension) {
 			ctrl = getController(ureq, (GenericActionExtension)uobject);
+		} else if(uobject instanceof OrganisationRoles) {
+			WindowControl bwControl = addToHistory(ureq, OresHelper.createOLATResourceableType(uobject.toString()), null);
+			ctrl = createUserSearchController(ureq, bwControl, (OrganisationRoles)uobject);
+		} else if(uobject instanceof CurriculumRoles) {
+			WindowControl bwControl = addToHistory(ureq, OresHelper.createOLATResourceableType(uobject.toString()), null);
+			ctrl = createUserSearchController(ureq, bwControl, (CurriculumRoles)uobject);
 		} else if(uobject instanceof String) {
 			ctrl = getController(ureq, (String)uobject);
 		} else if(uobject instanceof Organisation) {
 			ctrl = getController(ureq, (Organisation)uobject);
+		} else if(uobject instanceof IdentityRelation) {
+			IdentityRelation rel = (IdentityRelation)uobject;
+			WindowControl bwControl = addToHistory(ureq, OresHelper.createOLATResourceableInstance("Relation", rel.getRelationRole().getKey()), null);
+			ctrl = createUserSearchController(ureq, bwControl, (IdentityRelation)uobject);
+		} else if(uobject instanceof Presentation) {
+			WindowControl bwControl = addToHistory(ureq, OresHelper.createOLATResourceableType(treeNode.getIdent()), null);
+			ctrl = createInfoController(ureq, bwControl, (Presentation)uobject);
 		}
+			
 		if(ctrl != null) {
 			listenTo(ctrl);
 			content.popUpToRootController(ureq);
@@ -288,50 +319,27 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance(uobject, 0l);
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		addToHistory(ureq, bwControl);
-		
 		switch(uobject) {
-			case "menuroles": return createInfoController(ureq, bwControl, "systemroles");
-			case "menuqueries": return createInfoController(ureq, bwControl, "predefinedqueries");
-			case "menuaccess": return createInfoController(ureq, bwControl, "systemroles");
-			case "organisations": return createInfoController(ureq, bwControl, "systemorganisations");
+			// mains
 			case "usearch":
 			case "useradmin": return createUserSearchController(ureq, bwControl);
-			case "admingroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.administrator);
-			case "sysadmingroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.sysadmin);
-			case "principalgroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.principal);
-			case "usermanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.usermanager);
-			case "rolesmanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.rolesmanager);
-			case "groupmanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.groupmanager);
-			case "learnresourcemanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.learnresourcemanager);
-			case "linemanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.linemanager);
-			case "lecturemanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.lecturemanager);
-			case "qualitymanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.qualitymanager);
-			case "curriculummanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.curriculummanager);
-			case "poolmanagergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.poolmanager);
-			case "authorgroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.author);
-			case "usergroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.user);
-			case "anonymousgroup": return createUserSearchController(ureq, bwControl, OrganisationRoles.guest);
-			case "pendinggroup": return createUserSearchController(ureq, bwControl, Identity.STATUS_PENDING);
-			case "logondeniedgroup": return createUserSearchController(ureq, bwControl, Identity.STATUS_LOGIN_DENIED);
-			case "deletedusers": return createDeletedUserController(ureq, bwControl);
-			case "created.lastweek": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.DAY_OF_MONTH, -7);
-			case "created.lastmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -1);
-			case "created.sixmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -6);
-			case "created.newUsersNotification": return new NewUsersNotificationsController(ureq, bwControl, content);
-			// repository entry owners - authors
+			// groups
+			case "groupcoach": return createUserSearchController(ureq, bwControl,
+					SearchIdentityParams.resources(null, true, GroupRoles.coach, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
+			case "groupparticipant": return createUserSearchController(ureq, bwControl,
+					SearchIdentityParams.resources(null, true, GroupRoles.participant, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
+			// resources
 			case "coauthors": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.resources(GroupRoles.owner, null, null, new OrganisationRoles[] { OrganisationRoles.author }, Identity.STATUS_VISIBLE_LIMIT));
-			// authors + repository entry owners
-			case "resourceowners": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.authorsAndCoAuthors());
+					SearchIdentityParams.resources(GroupRoles.owner, true, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
 			case "courseparticipants": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.resources(GroupRoles.participant, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
+					SearchIdentityParams.resources(GroupRoles.participant, true, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
 			case "coursecoach": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.resources(GroupRoles.coach, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
-			case "groupcoach": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.resources(null, GroupRoles.coach, null, null, Identity.STATUS_VISIBLE_LIMIT));
-			case "noauthentication": return createUserSearchController(ureq, bwControl,
-					SearchIdentityParams.authenticationProviders(new String[]{ null }, Identity.STATUS_VISIBLE_LIMIT));
+					SearchIdentityParams.resources(GroupRoles.coach, true, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT));
+			// status
+			case "pendinggroup": return createUserSearchController(ureq, bwControl, Identity.STATUS_PENDING);
+			case "logondeniedgroup": return createUserSearchController(ureq, bwControl, Identity.STATUS_LOGIN_DENIED);
+			case "deletedusers": return createDeletedUserController(ureq, bwControl);
+			// predefined queries
 			case "userswithoutgroup":
 				return createUserSearchController(ureq, bwControl, SearchIdentityParams.withBusinesGroups());
 			case "userswithoutemail":
@@ -340,6 +348,13 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 			case "usersemailduplicates":
 				List<Identity> usersEmailDuplicates = userManager.findVisibleIdentitiesWithEmailDuplicates();
 				return new UsermanagerUserSearchController(ureq, bwControl, content, usersEmailDuplicates, true, false);
+			case "noauthentication": return createUserSearchController(ureq, bwControl,
+					SearchIdentityParams.authenticationProviders(new String[]{ null }, Identity.STATUS_VISIBLE_LIMIT));
+			// time based predefined queries
+			case "created.lastweek": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.DAY_OF_MONTH, -7);
+			case "created.lastmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -1);
+			case "created.sixmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -6);
+			case "created.newUsersNotification": return new NewUsersNotificationsController(ureq, bwControl, content);
 			default: return null;		
 		}
 	}
@@ -349,8 +364,8 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		return createUserSearchController(ureq, getWindowControl(), predefinedQuery);
 	}
 	
-	private Controller createInfoController(UserRequest ureq, WindowControl bwControl, String template) {
-		return new InfoController(ureq, bwControl, template);
+	private Controller createInfoController(UserRequest ureq, WindowControl bwControl, Presentation template) {
+		return new InfoController(ureq, bwControl, template.getTitleKey(), template.getDescriptionKey());
 	}
 
 	private UsermanagerUserSearchController createUserSearchControllerAfterDate(UserRequest ureq, WindowControl bwControl, int unit, int amount) {
@@ -366,6 +381,11 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		return createUserSearchController(ureq, bwControl, predefinedQuery);
 	}
 	
+	private UsermanagerUserSearchController createUserSearchController(UserRequest ureq, WindowControl bwControl, CurriculumRoles role) {
+		SearchIdentityParams predefinedQuery = SearchIdentityParams.resources(null, true, null, role, null, null, Identity.STATUS_VISIBLE_LIMIT);
+		return createUserSearchController(ureq, bwControl, predefinedQuery);
+	}
+	
 	private UsermanagerUserSearchController createUserSearchController(UserRequest ureq, WindowControl bwControl, Integer status) {
 		SearchIdentityParams predefinedQuery = SearchIdentityParams.params(null, status);
 		return createUserSearchController(ureq, bwControl, predefinedQuery);
@@ -386,6 +406,16 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		return new UsermanagerUserSearchController(ureq, bwControl, content, predefinedQuery, true);
 	}
 	
+	private UsermanagerUserSearchController createUserSearchController(UserRequest ureq, WindowControl bwControl, IdentityRelation relation) {
+		List<Identity> identities;
+		if(relation.isContra()) {
+			identities = relationshipService.getTargets(relation.getRelationRole());
+		} else {
+			identities = relationshipService.getSources(relation.getRelationRole());
+		}
+		return new UsermanagerUserSearchController(ureq, bwControl, content, identities, true, false);
+	}
+	
 	private DeletedUsersController createDeletedUserController(UserRequest ureq, WindowControl bwControl) {
 		return new DeletedUsersController(ureq, bwControl);
 	}
@@ -406,7 +436,7 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		Controller controller = acquireDeleteUserLock(ureq);
 		if (controller == null) {
 			//success -> create new User deletion workflow
-			directDeleteCtrl = new DirectDeleteController(ureq, getWindowControl());
+			DirectDeleteController directDeleteCtrl = new DirectDeleteController(ureq, getWindowControl());
 			controller = directDeleteCtrl;
 			listenTo(controller);
 		}
@@ -424,7 +454,7 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		Controller controller = acquireDeleteUserLock(ureq);
 		if (controller == null) {
 			//success -> create new User deletion workflow
-			deleteCtrl = new TabbedPaneController(ureq, getWindowControl());
+			TabbedPaneController deleteCtrl = new TabbedPaneController(ureq, getWindowControl());
 			controller = deleteCtrl;
 			listenTo(deleteCtrl);
 		}
@@ -467,13 +497,45 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		appendNode("menu.usearch", "menu.usearch.alt", "usearch", "o_sel_useradmin_search", root);
 		
 		// Sub menu with organizations
-		GenericTreeNode organisationsNode = appendNode("menu.organisations", "menu.organisations.alt", "organisations", "o_sel_useradmin_organisations", root);
+		GenericTreeNode organisationsNode = appendNode("menu.organisations", "menu.organisations.alt",
+				new Presentation("menu.organisations", "organisations.intro"), "o_sel_useradmin_organisations", root);
 		buildTreeOrganisationSubMenu(organisationsNode);
-		// Sub menu access and rights
-		GenericTreeNode accessNode = appendNode("menu.menuaccess", "menu.menuaccess.alt", "menuaccess", "o_sel_useradmin_access", root);
-		buildTreeAccessSubMenu(accessNode);
+
+		// Sub menu organizations roles
+		GenericTreeNode organisationsRolesNode = appendNode("menu.organisations.roles", "menu.organisations.roles.alt",
+				new Presentation("menu.organisations.roles", "menu.organisations.roles.intro"), "o_sel_useradmin_organisationsroles", root);
+		buildTreeOrganisationsRoles(organisationsRolesNode);
+		// Sub menu course roles
+		GenericTreeNode resourcesRolesNode = appendNode("menu.resources.roles", "menu.resources.roles.alt",
+				new Presentation("menu.resources.roles", "menu.resources.roles.intro"), "o_sel_useradmin_resourcesroles", root);
+		buildTreeResourcesRoles(resourcesRolesNode);
+		// Sub menu groups roles
+		GenericTreeNode groupsRolesNode = appendNode("menu.groups.roles", "menu.groups.roles.alt",
+				new Presentation("menu.groups.roles", "menu.groups.roles.intro"), "o_sel_useradmin_groupsroles", root);
+		buildTreeBusinessGroupsRoles(groupsRolesNode);
+		//Sub menu curriculum roles
+		if(curriculumModule.isEnabled()) {
+			GenericTreeNode curriculumsRolesNode = appendNode("menu.curriculums.roles", "menu.curriculums.roles.alt",
+					new Presentation("menu.curriculums.roles", "menu.curriculums.roles.intro"), "o_sel_useradmin_curriculumsroles", root);
+			buildTreeCurriculumsRoles(curriculumsRolesNode);
+		}
+		// Sub menu identity to identity relations
+		if(securityModule.isRelationRoleEnabled()) {
+			List<RelationRole> roles = relationshipService.getAvailableRoles();
+			if(!roles.isEmpty()) {
+			
+				GenericTreeNode relationsNode = appendNode("menu.relations", "menu.relations.alt",
+						new Presentation("menu.relations", "menu.relations.intro"), "o_sel_useradmin_relations", root);
+				buildTreeRelationsSubMenu(relationsNode, roles);
+			}
+		}
+		// Sub menu status
+		GenericTreeNode statusNode = appendNode("menu.status", "menu.status.alt",
+				new Presentation("menu.status", "menu.status.intro"), "o_sel_useradmin_status", root);
+		buildTreeStatusSubMenu(statusNode);
 		// Sub menu queries
-		GenericTreeNode queriesNode = appendNode("menu.menuqueries", "menu.menuqueries.alt", "menuqueries", "o_sel_useradmin_menuqueries", root);
+		GenericTreeNode queriesNode = appendNode("menu.menuqueries", "menu.menuqueries.alt",
+				new Presentation("menu.menuqueries", "queries.intro"), "o_sel_useradmin_menuqueries", root);
 		buildTreeQueriesSubMenu(queriesNode);
 		buildTreeExtensionsSubMenu(ureq, queriesNode);
 		return gtm;
@@ -521,49 +583,85 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 			}
 		}
 	}
-	
-	private void buildTreeAccessSubMenu(GenericTreeNode accessNode) {
-		appendNode("menu.usergroup", "menu.usergroup.alt", "usergroup", "o_sel_useradmin_usergroup", accessNode);
-		
+
+	private void buildTreeOrganisationsRoles(GenericTreeNode accessNode) {
 		boolean isAdministrator = identityRoles.isSystemAdmin() || identityRoles.isAdministrator()
 				|| identityRoles.isPrincipal() || identityRoles.isUserManager() || identityRoles.isRolesManager();
+		// admin group and user manager group always restricted to admins
 		if (isAdministrator) {
-			appendNode("menu.authorgroup", "menu.authorgroup.alt", "authorgroup", "o_sel_useradmin_authorgroup", accessNode);
-			appendNode("menu.coauthors", "menu.coauthors.alt", "coauthors", "o_sel_useradmin_coauthors", accessNode);
-			// too slow appendNode("menu.resourceowners", "menu.resourceowners.alt", "resourceowners", "o_sel_useradmin_resourceowners", accessNode);
+			appendNode("menu.usergroup", "menu.usergroup.alt", "usergroup", "o_sel_useradmin_usergroup", accessNode);
+			
+			buildTreeNodeRole(accessNode, OrganisationRoles.author);
+			buildTreeNodeRole(accessNode, OrganisationRoles.groupmanager);
+			if(lectureModule.isEnabled()) {
+				buildTreeNodeRole(accessNode, OrganisationRoles.lecturemanager);
+			}
+			if(qualityModule.isEnabled()) {
+				buildTreeNodeRole(accessNode, OrganisationRoles.qualitymanager);
+			}
+			if(poolModule.isEnabled()) {
+				buildTreeNodeRole(accessNode, OrganisationRoles.poolmanager);
+			}
+			buildTreeNodeRole(accessNode, OrganisationRoles.usermanager);
+			buildTreeNodeRole(accessNode, OrganisationRoles.rolesmanager);
+			if(curriculumModule.isEnabled()) {
+				buildTreeNodeRole(accessNode, OrganisationRoles.curriculummanager);
+			}
+			buildTreeNodeRole(accessNode, OrganisationRoles.linemanager);
+			buildTreeNodeRole(accessNode, OrganisationRoles.principal);
+			buildTreeNodeRole(accessNode, OrganisationRoles.administrator);
+			buildTreeNodeRole(accessNode, OrganisationRoles.sysadmin);
 		}
 		
+		if (identityRoles.isRolesManager() || identityRoles.isAdministrator() || identityRoles.isSystemAdmin()) {
+			buildTreeNodeRole(accessNode, OrganisationRoles.invitee);
+		}
+	}
+	
+	private void buildTreeNodeRole(GenericTreeNode accessNode, Enum<?> role) {
+		String i18n = "menu." + role.name() + "group";
+		appendNode(i18n, i18n, role, "o_sel_useradmin_".concat(role.name()), accessNode);
+	}
+	
+	private void buildTreeResourcesRoles(GenericTreeNode accessNode) {
+		appendNode("menu.coauthors", "menu.coauthors.alt", "coauthors", "o_sel_useradmin_coauthors", accessNode);
 		appendNode("menu.coursecoach", "menu.coursecoach.alt", "coursecoach", "o_sel_useradmin_coursecoach", accessNode);
 		appendNode("menu.courseparticipants", "menu.courseparticipants.alt", "courseparticipants", "o_sel_useradmin_courseparticipants", accessNode);
+	}
 
-		if (isAdministrator) {
-			appendNode("menu.groupmanagergroup", "menu.groupmanagergroup.alt", "groupmanagergroup", "o_sel_useradmin_groupmanagergroup", accessNode);
-			appendNode("menu.groupcoach", "menu.groupcoach.alt", "groupcoach", "o_sel_useradmin_groupcoach", accessNode);
-		}
-		
-		// admin group and user manager group always restricted to admins
-		if (isAdministrator) {
-			appendNode("menu.lecturemanagergroup", "menu.lecturemanagergroup.alt", "lecturemanagergroup", "o_sel_useradmin_lecturemanagergroup", accessNode);
-			appendNode("menu.qualitymanagergroup", "menu.qualitymanagergroup.alt", "qualitymanagergroup", "o_sel_useradmin_qualitymanagergroup", accessNode);
-			appendNode("menu.poolmanagergroup", "menu.poolmanagergroup.alt", "poolmanagergroup", "o_sel_useradmin_poolmanagergroup", accessNode);
-			
-			appendNode("menu.usermanagergroup", "menu.usermanagergroup.alt", "usermanagergroup", "o_sel_useradmin_usermanagergroup", accessNode);
-			appendNode("menu.rolesmanagergroup", "menu.rolesmanagergroup.alt", "rolesmanagergroup", "o_sel_useradmin_rolesmanagergroup", accessNode);
-			appendNode("menu.learnresourcemanagergroup", "menu.learnresourcemanagergroup.alt", "learnresourcemanagergroup", "o_sel_useradmin_learnresourcemanagergroup", accessNode);
-			
-			appendNode("menu.linemanagergroup", "menu.linemanagergroup.alt", "linemanagergroup", "o_sel_useradmin_linemanagergroup", accessNode);
-			
+	private void buildTreeBusinessGroupsRoles(GenericTreeNode accessNode) {
+		appendNode("menu.groupcoach", "menu.groupcoach.alt", "groupcoach", "o_sel_useradmin_groupcoach", accessNode);
+		appendNode("menu.groupparticipant", "menu.groupparticipant.alt", "groupparticipant", "o_sel_useradmin_groupparticipant", accessNode);
+	}
 
-			appendNode("menu.principalgroup", "menu.principalgroup.alt", "principalgroup", "o_sel_useradmin_principalgroup", accessNode);
-			appendNode("menu.admingroup", "menu.admingroup.alt", "admingroup", "o_sel_useradmin_admingroup", accessNode);
-			appendNode("menu.sysadmingroup", "menu.sysadmingroup.alt", "sysadmingroup", "o_sel_useradmin_sysadmingroup", accessNode);
-		}
-		
-		if (identityRoles.isRolesManager() || identityRoles.isAdministrator() || identityRoles.isSystemAdmin()) {
-			appendNode("menu.anonymousgroup", "menu.anonymousgroup.alt", "anonymousgroup", "o_sel_useradmin_anonymousgroup", accessNode);
+	private void buildTreeCurriculumsRoles(GenericTreeNode accessNode) {
+		buildTreeNodeRole(accessNode, CurriculumRoles.curriculumowner);
+		buildTreeNodeRole(accessNode, CurriculumRoles.curriculumelementowner);
+		buildTreeNodeRole(accessNode, CurriculumRoles.mastercoach);
+		buildTreeNodeRole(accessNode, CurriculumRoles.owner);
+		buildTreeNodeRole(accessNode, CurriculumRoles.coach);
+		buildTreeNodeRole(accessNode, CurriculumRoles.participant);
+	}
+	
+	private void buildTreeRelationsSubMenu(GenericTreeNode relationsNode, List<RelationRole> roles ) {
+		for(RelationRole relationRole:roles) {
+			String relationName = RelationRolesAndRightsUIFactory
+					.getTranslatedRole(relationRole, getLocale());
+			GenericTreeNode treeNode = new GenericTreeNode();		
+			treeNode.setTitle(relationName);
+			treeNode.setUserObject(new IdentityRelation(relationRole, false));
+			relationsNode.addChild(treeNode);
+			
+			String contraRelationName = RelationRolesAndRightsUIFactory
+					.getTranslatedContraRole(relationRole, getLocale());
+			GenericTreeNode contraTreeNode = new GenericTreeNode();		
+			contraTreeNode.setTitle(contraRelationName);
+			contraTreeNode.setUserObject(new IdentityRelation(relationRole, true));
+			relationsNode.addChild(contraTreeNode);
 		}
-		
-		appendNode("menu.noauthentication", "menu.noauthentication.alt", "noauthentication", "o_sel_useradmin_noauthentication", accessNode);
+	}
+	
+	private void buildTreeStatusSubMenu(GenericTreeNode accessNode) {
 		appendNode("menu.pendinggroup", "menu.pendinggroup.alt", "pendinggroup", "o_sel_useradmin_pendinggroup", accessNode);
 		appendNode("menu.logondeniedgroup", "menu.logondeniedgroup.alt", "logondeniedgroup", "o_sel_useradmin_logondeniedgroup", accessNode);
 		appendNode("menu.deletedusers", "menu.deletedusers.alt", "deletedusers", "o_sel_useradmin_deletedusers", accessNode);
@@ -575,6 +673,7 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 			appendNode("menu.users.without.email", "menu.users.without.email.alt", "userswithoutemail", "o_sel_useradmin_userswithoutemail", queriesNode);
 			appendNode("menu.users.email.duplicate", "menu.users.email.duplicate.alt", "usersemailduplicates", "o_sel_useradmin_usersemailduplicates", queriesNode);
 		}
+		appendNode("menu.noauthentication", "menu.noauthentication.alt", "noauthentication", "o_sel_useradmin_noauthentication", queriesNode);
 		appendNode("menu.created.lastweek", "menu.created.lastweek.alt", "created.lastweek", "o_sel_useradmin_createdlastweek", queriesNode);
 		appendNode("menu.created.lastmonth", "menu.created.lastmonth.alt", "created.lastmonth", "o_sel_useradmin_createdlastmonth", queriesNode);
 		appendNode("menu.created.sixmonth", "menu.created.sixmonth.alt", "created.sixmonth", "o_sel_useradmin_createdsixmonth", queriesNode);
@@ -662,4 +761,40 @@ public class UserAdminMainController extends MainLayoutBasicController implement
 		// controllers disposed in BasicController
 		releaseDeleteUserLock();
 	}
+	
+	private static class Presentation {
+		private final String titleKey;
+		private final String descriptionKey;
+		
+		public Presentation(String titleKey, String descriptionKey) {
+			this.titleKey = titleKey;
+			this.descriptionKey = descriptionKey;
+		}
+
+		public String getTitleKey() {
+			return titleKey;
+		}
+
+		public String getDescriptionKey() {
+			return descriptionKey;
+		}
+	}
+	
+	private static class IdentityRelation {
+		private final boolean contra;
+		private final RelationRole relationRole;
+		
+		public IdentityRelation(RelationRole relationRole, boolean contra) {
+			this.contra = contra;
+			this.relationRole = relationRole;
+		}
+		
+		public boolean isContra() {
+			return contra;
+		}
+		
+		public RelationRole getRelationRole() {
+			return relationRole;
+		}
+	}
 }
diff --git a/src/main/java/org/olat/user/ui/admin/_content/infos.html b/src/main/java/org/olat/user/ui/admin/_content/infos.html
new file mode 100644
index 00000000000..a0ae7130654
--- /dev/null
+++ b/src/main/java/org/olat/user/ui/admin/_content/infos.html
@@ -0,0 +1,3 @@
+<legend>$r.contextHelpWithWrapper("User management")
+<h4>$r.escapeHtml($title)</h4></legend>
+<p>$r.xssScan($description)</p>
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/ui/admin/_content/predefinedqueries.html b/src/main/java/org/olat/user/ui/admin/_content/predefinedqueries.html
deleted file mode 100644
index 4dbea2a73c1..00000000000
--- a/src/main/java/org/olat/user/ui/admin/_content/predefinedqueries.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<h4>$r.translate("menu.menuqueries")</h4>
-$r.translate("queries.intro")
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/ui/admin/_content/systemorganisations.html b/src/main/java/org/olat/user/ui/admin/_content/systemorganisations.html
deleted file mode 100644
index eeb4909168c..00000000000
--- a/src/main/java/org/olat/user/ui/admin/_content/systemorganisations.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<legend>$r.contextHelpWithWrapper("User management")
-<h4>$r.translate("menu.organisations")</h4></legend>
-$r.translate("organisations.intro")
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/ui/admin/_content/systemroles.html b/src/main/java/org/olat/user/ui/admin/_content/systemroles.html
deleted file mode 100644
index 5a0aaf9d8c2..00000000000
--- a/src/main/java/org/olat/user/ui/admin/_content/systemroles.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<legend>$r.contextHelpWithWrapper("User management")
-<h4>$r.translate("menu.menuaccess")</h4></legend>
-$r.translate("sysroles.intro")
\ No newline at end of file
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ar.properties
index b985e2c43e9..3238acb4d24 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ar.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ar.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u0645\u0633\u062A\u062E\u062F\u0645\u064A\u0646/\u0632\u0627\u0626\u0631\u064A\u0646 \u0645\u062C\u0647\u0648\u0644\u064A\u0646
-menu.anonymousgroup.alt=\u0625\u062F\u0627\u0631\u0629 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645 (\u0627\u0644\u0632\u0627\u0626\u0631\u064A\u0646) \u0627\u0644\u0645\u062C\u0647\u0648\u0644\u064A\u0646
+menu.inviteegroup=\u0645\u0633\u062A\u062E\u062F\u0645\u064A\u0646/\u0632\u0627\u0626\u0631\u064A\u0646 \u0645\u062C\u0647\u0648\u0644\u064A\u0646
+menu.inviteegroup.alt=\u0625\u062F\u0627\u0631\u0629 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645 (\u0627\u0644\u0632\u0627\u0626\u0631\u064A\u0646) \u0627\u0644\u0645\u062C\u0647\u0648\u0644\u064A\u0646
 menu.authorgroup=\u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646
 menu.authorgroup.alt=\u0625\u062F\u0627\u0631\u0629 \u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646
 menu.coauthors=\u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646 \u0627\u0644\u0645\u0633\u0627\u0639\u062F\u064A\u0646
@@ -25,8 +25,6 @@ menu.menuqueries=\u0627\u0644\u0628\u062D\u062B \u0627\u0644\u0645\u062D\u062F\u
 menu.menuqueries.alt=\u0625\u062F\u0627\u0631\u0629 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u064A\u0646 \u0628\u0648\u0627\u0633\u0637\u0629 \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u0628\u062D\u062B \u0627\u0644\u0645\u062D\u062F\u062F\u0629 \u0645\u0633\u0628\u0642\u0627\u064B
 menu.noauthentication=\u0641\u0642\u062F\u0627\u0646 \u0627\u0644\u0645\u0635\u0627\u062F\u0642\u0629
 menu.noauthentication.alt=\u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u064A\u0646 \u0627\u0644\u0630\u064A\u0646 \u0644\u0645 \u064A\u062A\u0645 \u062A\u0633\u062C\u064A\u0644\u0647\u0645 \u0628\u0634\u0643\u0644 \u0635\u062D\u064A\u062D\u060C \u0644\u0627 \u064A\u0648\u062C\u062F \u0643\u0644\u0645\u0629 \u0645\u0631\u0648\u0631
-menu.resourceowners=\u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646 \u0648\u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646 \u0627\u0644\u0645\u0633\u0627\u0639\u062F\u064A\u0646
-menu.resourceowners.alt=\u0625\u062F\u0627\u0631\u0629 \u0643\u0644 \u0627\u0644\u0645\u0624\u0644\u0641\u064A\u0646 \u0627\u0644\u0645\u0633\u0627\u0639\u062F\u064A\u0646 \u0644\u0645\u0635\u062F\u0631 \u0627\u0644\u062A\u0639\u0644\u0645
 menu.ucreate=\u0625\u0646\u0634\u0627\u0621 \u0645\u0633\u062A\u062E\u062F\u0645
 menu.ucreate.alt=\u0625\u0646\u0634\u0640\u0627\u0621 \u0645\u0633\u062A\u062E\u062F\u0645
 menu.usearch=\u0628\u062D\u062B \u0639\u0646 \u0645\u0633\u062A\u062E\u062F\u0645
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_bg.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_bg.properties
index d8dbe2c4604..4cacf2c0f63 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_bg.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_bg.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u0410\u043D\u043E\u043D\u0438\u043C\u043D\u0438 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 / \u0433\u043E\u0441\u0442\u0438
-menu.anonymousgroup.alt=\u041C\u0435\u043D\u0430\u0436\u0438\u0440\u0430\u0439\u0442\u0435 \u0433\u0440\u0443\u043F\u0430 \u0441 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 (\u0433\u043E\u0441\u0442\u0438)
+menu.inviteegroup=\u0410\u043D\u043E\u043D\u0438\u043C\u043D\u0438 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 / \u0433\u043E\u0441\u0442\u0438
+menu.inviteegroup.alt=\u041C\u0435\u043D\u0430\u0436\u0438\u0440\u0430\u0439\u0442\u0435 \u0433\u0440\u0443\u043F\u0430 \u0441 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 (\u0433\u043E\u0441\u0442\u0438)
 menu.authorgroup=\u0410\u0432\u0442\u043E\u0440\u0438
 menu.authorgroup.alt=\u041C\u0435\u043D\u0430\u0436\u0438\u0440\u0430\u0439\u0442\u0435 \u0430\u0432\u0442\u043E\u0440\u0441\u043A\u0430 \u0433\u0440\u0443\u043F\u0430
 menu.coauthors=\u0421\u044A\u0430\u0432\u0442\u043E\u0440\u0438
@@ -23,8 +23,6 @@ menu.menuqueries=\u041F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u0
 menu.menuqueries.alt=\u041C\u0435\u043D\u0430\u0436\u0438\u0440\u0430\u0439\u0442\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B \u0441\u043F\u043E\u0440\u0435\u0434 \u0441\u043F\u0438\u0441\u044A\u0446\u0438\u0442\u0435 \u0437\u0430 \u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043E \u0442\u044A\u0440\u0441\u0435\u043D\u0435
 menu.noauthentication=\u041B\u0438\u043F\u0441\u0432\u0430\u0449\u0430 \u0430\u0432\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u044F
 menu.noauthentication.alt=\u041F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438, \u043A\u043E\u0438\u0442\u043E \u043D\u0435 \u0441\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043D\u0438 \u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E (\u043D\u044F\u043C\u0430\u0442 \u043F\u0430\u0440\u043E\u043B\u0430)
-menu.resourceowners=\u0410\u0432\u0442\u043E\u0440\u0438 \u0438 \u0441\u044A\u0430\u0432\u0442\u043E\u0440\u0438
-menu.resourceowners.alt=\u041C\u0435\u043D\u0430\u0436\u0438\u0440\u0430\u0439\u0442\u0435 \u0432\u0441\u0438\u0447\u043A\u0438 \u0441\u043E\u0431\u0441\u0442\u0432\u0435\u043D\u0438\u0446\u0438 \u043D\u0430 \u0443\u0447\u0435\u0431\u0435\u043D \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B
 menu.ucreate=\u0421\u044A\u0437\u0434\u0430\u0439\u0442\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B
 menu.ucreate.alt=\u0421\u044A\u0437\u0434\u0430\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B
 menu.usearch=\u0422\u044A\u0440\u0441\u0435\u043D\u0435 \u043D\u0430 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_cs.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_cs.properties
index 3f081b0aa8e..438c7154bbf 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_cs.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_cs.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administr\u00E1to\u0159i
-menu.admingroup.alt=Spr\u00E1va skupin administr\u00E1tor\u016F
-menu.anonymousgroup=Anonymn\u00ED u\u017Eivatel\u00E9 / hosti
-menu.anonymousgroup.alt=Spravovat anonymn\u00ED u\u017Eivatele (hosti)
+menu.administratorgroup=Administr\u00E1to\u0159i
+menu.administratorgroup.alt=Spr\u00E1va skupin administr\u00E1tor\u016F
+menu.inviteegroup=Anonymn\u00ED u\u017Eivatel\u00E9 / hosti
+menu.inviteegroup.alt=Spravovat anonymn\u00ED u\u017Eivatele (hosti)
 menu.authorgroup=Auto\u0159i
 menu.authorgroup.alt=Spr\u00E1va autorsk\u00FDch skupin
 menu.coauthors=Spoluauto\u0159i
@@ -25,8 +25,6 @@ menu.menuqueries=P\u0159eddefinovan\u00E1 vyhled\u00E1v\u00E1n\u00ED
 menu.menuqueries.alt=Spravovat seznam p\u0159eddefinovan\u00FDch vyhled\u00E1v\u00E1n\u00ED
 menu.noauthentication=Bez ov\u011B\u0159ov\u00E1n\u00ED
 menu.noauthentication.alt=U\u017Eivatel\u00E9, kte\u0159\u00ED nejsou spr\u00E1vn\u011B vytvo\u0159eni (nemaj\u00ED heslo)
-menu.resourceowners=Auto\u0159i a spoluauto\u0159i
-menu.resourceowners.alt=Spravovat v\u0161echny vlastn\u00EDky studijn\u00EDch materi\u00E1l\u016F
 menu.sysadmingroup=Administr\u00E1to\u0159i syst\u00E9mu
 menu.sysadmingroup.alt=Spr\u00E1va skupin syst\u00E9mov\u00FDch administr\u00E1tor\u016F
 menu.ucreate=Vytvo\u0159it u\u017Eivatele
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_da.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_da.properties
index d0ede9291ff..4e8f3bba3a5 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_da.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_da.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administratorer
-menu.admingroup.alt=Administrer administratorgruppen
-menu.anonymousgroup=Anonyme brugere / g\u00E6ster
-menu.anonymousgroup.alt=Administrer gruppen med anonyme brugere (g\u00E6ster)
+menu.administratorgroup=Administratorer
+menu.administratorgroup.alt=Administrer administratorgruppen
+menu.inviteegroup=Anonyme brugere / g\u00E6ster
+menu.inviteegroup.alt=Administrer gruppen med anonyme brugere (g\u00E6ster)
 menu.authorgroup=Forfattere
 menu.authorgroup.alt=Administrer forfattergruppen
 menu.coauthors=Medforfattere
@@ -25,8 +25,6 @@ menu.menuqueries=Foruddefinerede s\u00F8gninger
 menu.menuqueries.alt=Administrerer brugere ud fra foruddefinerede s\u00F8gelister
 menu.noauthentication=Mangler autentifikation
 menu.noauthentication.alt=Brugere der ikke er korrekt defineret (intet kodeord)
-menu.resourceowners=Forfattere og medforfattere
-menu.resourceowners.alt=Administrerer alle ejere af l\u00E6reressourcer
 menu.sysadmingroup=Systemadministratorer
 menu.sysadmingroup.alt=Administrer systemadministratorgruppen
 menu.ucreate=Opret bruger
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_de.properties
index e96aac4abc2..420bbce8079 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_de.properties
@@ -9,10 +9,10 @@ allow.request.delete.account.time=Benutzerkonto l\u00F6schen anfragen
 command.next=Weiter zur n\u00E4chsten Benutzer
 command.previous=Zur\u00FCck zur letzten Benutzer
 error.mail.not.valid=Der Email Adresse ist nicht g\u00FCltig.
-menu.admingroup=Administratoren
-menu.admingroup.alt=Administratoren verwalten
-menu.anonymousgroup=Anonyme Benutzer / G\u00E4ste
-menu.anonymousgroup.alt=Anonyme Benutzer (G\u00E4ste) verwalten
+menu.administratorgroup=Administratoren
+menu.administratorgroup.alt=Administratoren verwalten
+menu.inviteegroup=Anonyme Benutzer / G\u00E4ste
+menu.inviteegroup.alt=Anonyme Benutzer (G\u00E4ste) verwalten
 menu.authorgroup=Autoren
 menu.authorgroup.alt=Autoren verwalten
 menu.coauthors=Co-Autoren
@@ -29,12 +29,40 @@ menu.created.newUsersNotification=Neue Benutzer
 menu.created.newUsersNotification.alt=Neue Benutzer
 menu.created.sixmonth=Neu seit 6 Monaten
 menu.created.sixmonth.alt=Benutzer, die im letzten halben Jahr hinzugef\u00FCgt worden sind
+menu.curriculummanagergroup=$org.olat.admin.user\:role.curriculummanager
+menu.curriculummanagergroup.alt=$org.olat.admin.user\:role.curriculummanager
+menu.curriculumownergroup=Curriculumbesitzer
+menu.curriculumownergroup.alt=$\:menu.curriculumownergroup
+menu.curriculumelementownergroup=Curriculumelementbesitzer
+menu.curriculumelementownergroup.alt=$\:menu.curriculumelementownergroup
+menu.mastercoachgroup=Klassenlehrer
+menu.mastercoachgroupgroup.alt=$\:menu.mastercoachgroup
+menu.ownergroup=Kursbesitzer
+menu.ownergroupgroup.alt=$\:menu.ownergroup
+menu.coachgroup=Kursbetreuer
+menu.coachgroupgroup.alt=$\:menu.coachgroup
+menu.participantgroup=Kursteilnehmer
+menu.participantgroup.alt=$\:menu.participantgroup
+menu.status=Status
+menu.status.alt=$\:menu.status
+menu.status.intro=Unter dem Men\u00FC <i>$\:menu.status</i> finden Sie einen \u00DCberblick der Status von ihren Benutzern.
+menu.relations=Benutzerrollen
+menu.relations.alt=$\:menu.relations
+menu.relations.intro=Unter dem Men\u00FC <i>$\:menu.relations</i> finden Sie einen \u00DCberblick die Beziehungen zwischen Benutzer.
+menu.curriculums.roles=Curriculumrollen
+menu.curriculums.roles.alt=$\:menu.curriculums.roles
+menu.curriculums.roles.intro=Unter dem Men\u00FC <i>$\:menu.curriculums.roles</i> finden Sie einen \u00DCberblick der Rechte in und Zug\u00E4nge zu Curriculum.
 menu.deletedusers=Gel\u00F6schte Benutzer
 menu.deletedusers.alt=Benutzer, die in OpenOLAT gel\u00F6scht wurden
 menu.groupcoach=Gruppenbetreuer
 menu.groupcoach.alt=Gruppenbetreuer
 menu.groupmanagergroup=Gruppenverwalter
 menu.groupmanagergroup.alt=Verwalter von kurs\u00FCbergreifenden Gruppen verwalten
+menu.groupparticipant=Gruppenteilnehmer
+menu.groupparticipant.alt=$\:menu.groupparticipant
+menu.groups.roles=Gruppenrollen
+menu.groups.roles.alt=$\:menu.groups.roles
+menu.groups.roles.intro=Unter dem Men\u00FC <i>$\:menu.groups.roles</i> finden Sie einen \u00DCberblick der Rechte in und Zug\u00E4nge zu Gruppen.
 menu.learnresourcemanagergroup=$org.olat.admin.user\:role.learnresourcemanager
 menu.learnresourcemanagergroup.alt=$org.olat.admin.user\:role.learnresourcemanager
 menu.lecturemanagergroup=$org.olat.admin.user\:role.lecturemanager
@@ -51,6 +79,11 @@ menu.noauthentication=Fehlende Authentifizierung
 menu.noauthentication.alt=Benutzer, die noch nicht vollst\u00E4ndig angelegt sind (Kein Passwort)
 menu.organisations=Organisationen
 menu.organisations.alt=Organisationen
+menu.organisations.roles=Organisationsrollen
+menu.organisations.roles.alt=
+menu.organisations.roles.intro=Unter dem Men\u00FC <i>$\:menu.organisations.roles</i> finden Sie einen \u00DCberblick der Rechte in und Zug\u00E4nge zu Organisationen, die Sie verwalten k\u00F6nnen. 
+
+
 menu.pendinggroup=Ausstehende Benutzer
 menu.pendinggroup.alt=Ausstehende Benutzer
 menu.poolmanagergroup=$org.olat.admin.user\:role.poolmanager
@@ -59,8 +92,9 @@ menu.principalgroup=$org.olat.admin.user\:role.principal
 menu.principalgroup.alt=$org.olat.admin.user\:role.principal
 menu.qualitymanagergroup=$org.olat.admin.user\:role.qualitymanager
 menu.qualitymanagergroup.alt=$org.olat.admin.user\:role.qualitymanager
-menu.resourceowners=Autoren und Co-Autoren
-menu.resourceowners.alt=Besitzer von Lernressourcen verwalten
+menu.resources.roles=Kursrollen
+menu.resources.roles.alt=$\:menu.resources.roles
+menu.resources.roles.intro=Unter dem Men\u00FC <i>$\:menu.resources.roles</i> finden Sie einen \u00DCberblick der Rechte in und Zug\u00E4nge zu Kursen und Lernressourcen, <strong>ohne Verbindungen via Gruppen oder Curriculum</strong>. 
 menu.rolesmanagergroup=$org.olat.admin.user\:role.rolesmanager
 menu.rolesmanagergroup.alt=$org.olat.admin.user\:role.rolesmanager
 menu.sysadmingroup=Systemadministratoren
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_el.properties
index 0f4ddfae0cb..7c2471ec353 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_el.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_el.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u0391\u03BD\u03CE\u03BD\u03C5\u03BC\u03BF\u03B9 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B5\u03C2 / \u03B5\u03C0\u03B9\u03C3\u03BA\u03AD\u03C0\u03C4\u03B5\u03C2
-menu.anonymousgroup.alt=\u0394\u03B9\u03B1\u03C7\u03B5\u03AF\u03C1\u03B9\u03C3\u03B7 \u03BF\u03BC\u03AC\u03B4\u03B1\u03C2 \u03B1\u03BD\u03CE\u03BD\u03C5\u03BC\u03C9\u03BD \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD (\u03B5\u03C0\u03B9\u03C3\u03BA\u03AD\u03C0\u03C4\u03B5\u03C2)
+menu.inviteegroup=\u0391\u03BD\u03CE\u03BD\u03C5\u03BC\u03BF\u03B9 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B5\u03C2 / \u03B5\u03C0\u03B9\u03C3\u03BA\u03AD\u03C0\u03C4\u03B5\u03C2
+menu.inviteegroup.alt=\u0394\u03B9\u03B1\u03C7\u03B5\u03AF\u03C1\u03B9\u03C3\u03B7 \u03BF\u03BC\u03AC\u03B4\u03B1\u03C2 \u03B1\u03BD\u03CE\u03BD\u03C5\u03BC\u03C9\u03BD \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD (\u03B5\u03C0\u03B9\u03C3\u03BA\u03AD\u03C0\u03C4\u03B5\u03C2)
 menu.authorgroup=\u03A3\u03C5\u03B3\u03B3\u03C1\u03B1\u03C6\u03B5\u03AF\u03C2
 menu.authorgroup.alt=\u0394\u03B9\u03B1\u03C7\u03B5\u03AF\u03C1\u03B9\u03C3\u03B7 \u03BF\u03BC\u03AC\u03B4\u03B1\u03C2 \u03C3\u03C5\u03B3\u03B3\u03C1\u03B1\u03C6\u03AD\u03C9\u03BD
 menu.coauthors=\u0388\u03C4\u03B5\u03C1\u03BF\u03B9 \u03C3\u03C5\u03B3\u03B3\u03C1\u03B1\u03C6\u03B5\u03AF\u03C2
@@ -25,8 +25,6 @@ menu.menuqueries=\u03A0\u03C1\u03BF\u03BA\u03B1\u03B8\u03BF\u03C1\u03B9\u03C3\u0
 menu.menuqueries.alt=\u0394\u03B9\u03B1\u03C7\u03B5\u03AF\u03C1\u03B9\u03C3\u03B7 \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD \u03BC\u03B5 \u03C7\u03C1\u03AE\u03C3\u03B7 \u03C0\u03C1\u03BF\u03BA\u03B1\u03B8\u03BF\u03C1\u03B9\u03C3\u03BC\u03AD\u03BD\u03C9\u03BD \u03BB\u03B9\u03C3\u03C4\u03CE\u03BD \u03B1\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7\u03C2
 menu.noauthentication=\u0388\u03BB\u03BB\u03B5\u03B9\u03C8\u03B7 \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03AF\u03B7\u03C3\u03B7\u03C2
 menu.noauthentication.alt=\u03A7\u03C1\u03AE\u03C3\u03C4\u03B5\u03C2 \u03C0\u03BF\u03C5 \u03B4\u03B5\u03BD \u03AD\u03C7\u03BF\u03C5\u03BD \u03B5\u03B9\u03C3\u03B1\u03C7\u03B8\u03B5\u03AF \u03C3\u03C9\u03C3\u03C4\u03AC (\u03C7\u03C9\u03C1\u03AF\u03C2 \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03C0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2)
-menu.resourceowners=\u03A3\u03C5\u03B3\u03B3\u03C1\u03B1\u03C6\u03B5\u03AF\u03C2 \u03BA\u03B1\u03B9 \u03AD\u03C4\u03B1\u03B9\u03C1\u03BF\u03B9 \u03C3\u03C5\u03B3\u03B3\u03C1\u03B1\u03C6\u03B5\u03AF\u03C2
-menu.resourceowners.alt=\u0394\u03B9\u03B1\u03C7\u03B5\u03AF\u03C1\u03B9\u03C3\u03B7 \u03C4\u03C9\u03BD \u03BA\u03B1\u03C4\u03CC\u03C7\u03C9\u03BD \u03C0\u03B5\u03C1\u03B9\u03B5\u03C7\u03BF\u03BC\u03AD\u03BD\u03BF\u03C5 \u03BC\u03AC\u03B8\u03B7\u03C3\u03B7\u03C2
 menu.ucreate=\u0394\u03B7\u03BC\u03B9\u03BF\u03C5\u03C1\u03B3\u03AF\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
 menu.ucreate.alt=\u0394\u03B7\u03BC\u03B9\u03BF\u03C5\u03C1\u03B3\u03AF\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
 menu.usearch=\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_en.properties
index d47e409e60d..3c08c9e75f5 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_en.properties
@@ -9,10 +9,10 @@ allow.request.delete.account.time=Request user account deletion
 error.mail.not.valid=The E-mail addresse is not valid.
 command.next=Go to next user
 command.previous=Go to previous user
-menu.admingroup=Administrators
-menu.admingroup.alt=Manage administrator group
-menu.anonymousgroup=Anonymous users/guests
-menu.anonymousgroup.alt=Manage anonymous user group (guests)
+menu.administratorgroup=Administrators
+menu.administratorgroup.alt=Manage administrator group
+menu.inviteegroup=Anonymous users/guests
+menu.inviteegroup.alt=Manage anonymous user group (guests)
 menu.authorgroup=Authors
 menu.authorgroup.alt=Manage author group
 menu.coauthors=Co-authors
@@ -29,12 +29,40 @@ menu.created.newUsersNotification=New users
 menu.created.newUsersNotification.alt=New users
 menu.created.sixmonth=New since the last six months
 menu.created.sixmonth.alt=Users that have been created within the last six months
+menu.curriculummanagergroup=Curriculum manager
+menu.curriculummanagergroup.alt=$\:menu.curriculummanagergroup
+menu.curriculumownergroup=Curriculum owner
+menu.curriculumownergroup.alt=$\:menu.curriculumownergroup
+menu.curriculumelementownergroup=Curriculum element owner
+menu.curriculumelementownergroup.alt=$\:menu.curriculumownergroup
+menu.mastercoachgroup=Master class
+menu.mastercoachgroupgroup.alt=$\:menu.mastercoachgroup
+menu.ownergroup=Course owner
+menu.ownergroupgroup.alt=$\:menu.ownergroup
+menu.coachgroup=Course coach
+menu.coachgroupgroup.alt=$\:menu.coachgroup
+menu.participantgroup=Course particiapnt
+menu.participantgroupgroup.alt=$\:menu.participantgroup
+menu.status=Status
+menu.status.alt=$\:menu.status
+menu.status.intro=In the menu <i>$\:menu.status</i> you get an overview of the status of your users.
+menu.relations=User roles
+menu.relations.alt=$\:menu.relations
+menu.relations.intro=In the menu <i>$\:menu.relations</i> you get an overview of the relations between users.
+menu.curriculums.roles=Curriculum roles
+menu.curriculums.roles.alt=$\:menu.curriculums.roles
+menu.curriculums.roles.intro=In the menu <i>$\:menu.curriculums.roles</i> you get an overview of access and rights in curriculums.
 menu.deletedusers=Deleted users
 menu.deletedusers.alt=Users deleted in OpenOLAT
 menu.groupcoach=Group coach
 menu.groupcoach.alt=Group coach
 menu.groupmanagergroup=Group administrator
 menu.groupmanagergroup.alt=Manage group administrators course-comprehensively
+menu.groupparticipant=Group participant
+menu.groupparticipant.alt=$\:menu.groupparticipant
+menu.groups.roles=Group roles
+menu.groups.roles.alt=$\:menu.groups.roles
+menu.groups.roles.intro=In the menu <i>$\:menu.groups.roles</i> you get an overview of access and rights in groups.
 menu.learnresourcemanagergroup=$org.olat.admin.user\:role.learnresourcemanager
 menu.learnresourcemanagergroup.alt=$org.olat.admin.user\:role.learnresourcemanager
 menu.lecturemanagergroup=$org.olat.admin.user\:role.lecturemanager
@@ -51,6 +79,9 @@ menu.noauthentication=Authentication missing
 menu.noauthentication.alt=Users that are not correctly set up (no password)
 menu.organisations=Organisations
 menu.organisations.alt=Organisations
+menu.organisations.roles=Organisations roles
+menu.organisations.roles.alt=$\:menu.organisations.roles
+menu.organisations.roles.intro=In the menu <i>$\:menu.organisations.roles</i> you get an overview of access and rights in organisations you can administer.
 menu.pendinggroup=Pending users
 menu.pendinggroup.alt=Pending users
 menu.poolmanagergroup=$org.olat.admin.user\:role.poolmanager
@@ -59,8 +90,9 @@ menu.principalgroup=$org.olat.admin.user\:role.principal
 menu.principalgroup.alt=$org.olat.admin.user\:role.principal
 menu.qualitymanagergroup=$org.olat.admin.user\:role.qualitymanager
 menu.qualitymanagergroup.alt=$org.olat.admin.user\:role.qualitymanager
-menu.resourceowners=Authors and co-authors
-menu.resourceowners.alt=Manage all owners of a learning resource
+menu.resources.roles=Courses roles
+menu.resources.roles.alt=$\:menu.resources.roles
+menu.resources.roles.intro=In the menu <i>$\:menu.organisations.roles</i> you get an overview of access and rights in courses and learn resources <strong>but without the relations through groups or curriculums</strong>.
 menu.rolesmanagergroup=$org.olat.admin.user\:role.rolesmanager
 menu.rolesmanagergroup.alt=$org.olat.admin.user\:role.rolesmanager
 menu.sysadmingroup=System administrators
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_es.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_es.properties
index 068abe99b23..a1261656562 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_es.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_es.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administradores
-menu.admingroup.alt=Gestionar grupo de administradores
-menu.anonymousgroup=Usuarios/invitados an\u00F3nimos
-menu.anonymousgroup.alt=Gestionar grupo de usuarios (invitados) an\u00F3nimos
+menu.administratorgroup=Administradores
+menu.administratorgroup.alt=Gestionar grupo de administradores
+menu.inviteegroup=Usuarios/invitados an\u00F3nimos
+menu.inviteegroup.alt=Gestionar grupo de usuarios (invitados) an\u00F3nimos
 menu.authorgroup=Autores
 menu.authorgroup.alt=Gestionar grupo de autores
 menu.coauthors=Co-autores
@@ -25,8 +25,6 @@ menu.menuqueries=B\u00FAsquedas predefinidas
 menu.menuqueries.alt=Gestionar usuarios mediante listas de b\u00FAsqueda predefinidas
 menu.noauthentication=Usuarios sin autenticaci\u00F3n
 menu.noauthentication.alt=Usuarios que no han entrado correctamente (falta la contrase\u00F1a)
-menu.resourceowners=Autores y co-autores
-menu.resourceowners.alt=Gestionar a todos los usuarios que poseen recursos did\u00E1cticos
 menu.sysadmingroup=Administradores del sistema
 menu.sysadmingroup.alt=Gestionar grupo de administradores del sistema
 menu.ucreate=Crear usuario
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fa.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fa.properties
index 187d6331c93..0fe289300bd 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fa.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fa.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u06A9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0647\u0645\u0627\u0646
-menu.anonymousgroup.alt=Manage anonymous user group (guests)
+menu.inviteegroup=\u06A9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0647\u0645\u0627\u0646
+menu.inviteegroup.alt=Manage anonymous user group (guests)
 menu.authorgroup=\u0646\u0648\u06CC\u0633\u0646\u062F\u06AF\u0627\u0646
 menu.authorgroup.alt=\u0645\u062F\u06CC\u0631\u06CC\u062A \u06AF\u0631\u0648\u0647 \u0646\u0648\u06CC\u0633\u0646\u062F\u06AF\u0627\u0646
 menu.coauthors=\u0647\u0645\u06CC\u0627\u0631\u0627\u0646
@@ -21,8 +21,6 @@ menu.menuqueries=\u062C\u0633\u062A\u062C\u0648\u0647\u0627\u06CC \u0627\u0632 \
 menu.menuqueries.alt=Manage user by predefined search lists
 menu.noauthentication=\u0628\u062F\u0648\u0646 \u0627\u0639\u062A\u0628\u0627\u0631
 menu.noauthentication.alt=Users that are not correctly set up (no password)
-menu.resourceowners=\u0646\u0648\u06CC\u0633\u0646\u062F\u06AF\u0627\u0646 \u0648 \u0647\u0645\u06CC\u0627\u0631\u0627\u0646
-menu.resourceowners.alt=Manage all owners of a learning resource
 menu.ucreate=\u0627\u06CC\u062C\u0627\u062F \u06A9\u0627\u0631\u0628\u0631
 menu.ucreate.alt=\u0627\u06CC\u062C\u0627\u062F \u06A9\u0627\u0631\u0628\u0631
 menu.usearch=\u062C\u0633\u062A\u062C\u0648\u06CC \u06A9\u0627\u0631\u0628\u0631\u0627\u0646
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fr.properties
index 0698d11d562..a9099728f57 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_fr.properties
@@ -9,10 +9,10 @@ allow.request.delete.account.time=Demander \u00E0 effacer le compte utilisateur
 command.next=Aller \u00E0 l'utilisateur suivant
 command.previous=Retour \u00E0 l'utilisateur pr\u00E9c\u00E9dent
 error.mail.not.valid=L'adresse courriel n'est pas valide.
-menu.admingroup=Administrateurs
-menu.admingroup.alt=G\u00E9rer le groupe de administrateurs
-menu.anonymousgroup=Utilisateurs anonymes / Invit\u00E9(e)s
-menu.anonymousgroup.alt=Gestion du groupe des utilisateurs anonymes (invit\u00E9(e)s)
+menu.administratorgroup=Administrateurs
+menu.administratorgroup.alt=G\u00E9rer le groupe de administrateurs
+menu.inviteegroup=Utilisateurs anonymes / Invit\u00E9(e)s
+menu.inviteegroup.alt=Gestion du groupe des utilisateurs anonymes (invit\u00E9(e)s)
 menu.authorgroup=Auteurs
 menu.authorgroup.alt=G\u00E9rer le groupe des auteurs
 menu.coauthors=Co-auteurs
@@ -59,8 +59,6 @@ menu.principalgroup=$org.olat.admin.user\:role.principal
 menu.principalgroup.alt=$org.olat.admin.user\:role.principal
 menu.qualitymanagergroup=$org.olat.admin.user\:role.qualitymanager
 menu.qualitymanagergroup.alt=$org.olat.admin.user\:role.qualitymanager
-menu.resourceowners=Auteurs et co-auteurs
-menu.resourceowners.alt=G\u00E9rer tous les propri\u00E9taires d'une ressource didactique
 menu.rolesmanagergroup=$org.olat.admin.user\:role.rolesmanager
 menu.rolesmanagergroup.alt=$org.olat.admin.user\:role.rolesmanager
 menu.sysadmingroup=Administrateurs de syst\u00E8me
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_it.properties
index 11be8d5195a..8939ec7be04 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_it.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Amministratori
-menu.admingroup.alt=Gestione del gruppo di amministrazione
-menu.anonymousgroup=Utenti anonimi / Ospiti
-menu.anonymousgroup.alt=Amministrazione del gruppo degli utenti anonimi (ospiti)
+menu.administratorgroup=Amministratori
+menu.administratorgroup.alt=Gestione del gruppo di amministrazione
+menu.inviteegroup=Utenti anonimi / Ospiti
+menu.inviteegroup.alt=Amministrazione del gruppo degli utenti anonimi (ospiti)
 menu.authorgroup=Autori
 menu.authorgroup.alt=Gestione del gruppo degli autori
 menu.coauthors=Coautori
@@ -33,8 +33,6 @@ menu.menuqueries=Ricerche predefinite
 menu.menuqueries.alt=Gestione degli utenti secondo ricerche predefinite
 menu.noauthentication=Autentificazione mancante
 menu.noauthentication.alt=Utenti aggiunti in modo incompleto (password mancante)
-menu.resourceowners=Autori e coautori
-menu.resourceowners.alt=Amministrazione di tutti i proprietari di risorse didattiche
 menu.sysadmingroup=Amministratori sistema
 menu.sysadmingroup.alt=Gestione del gruppo di amministrazione del sistema
 menu.ucreate=Creare utenti
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_jp.properties
index 3c74ea32078..a0b2406e8f7 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_jp.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_jp.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u533F\u540D\u30E6\u30FC\u30B6 / \u30B2\u30B9\u30C8
-menu.anonymousgroup.alt=\u533F\u540D\u30E6\u30FC\u30B6\u30B0\u30EB\u30FC\u30D7 (\u30B2\u30B9\u30C8) \u3092\u7BA1\u7406\u3059\u308B
+menu.inviteegroup=\u533F\u540D\u30E6\u30FC\u30B6 / \u30B2\u30B9\u30C8
+menu.inviteegroup.alt=\u533F\u540D\u30E6\u30FC\u30B6\u30B0\u30EB\u30FC\u30D7 (\u30B2\u30B9\u30C8) \u3092\u7BA1\u7406\u3059\u308B
 menu.authorgroup=\u4F5C\u8005
 menu.authorgroup.alt=\u4F5C\u8005\u30B0\u30EB\u30FC\u30D7\u3092\u7BA1\u7406\u3059\u308B
 menu.coauthors=\u5171\u540C\u4F5C\u8005
@@ -25,8 +25,6 @@ menu.menuqueries=\u5B9A\u7FA9\u6E08\u307F\u691C\u7D22
 menu.menuqueries.alt=\u6240\u5B9A\u306E\u691C\u7D22\u30EA\u30B9\u30C8\u306B\u3088\u308A\u30E6\u30FC\u30B6\u3092\u7BA1\u7406\u3059\u308B
 menu.noauthentication=\u8A8D\u8A3C\u4E0D\u660E
 menu.noauthentication.alt=\u6B63\u5E38\u306B\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3055\u308C\u3066\u3044\u306A\u3044\u30E6\u30FC\u30B6 (\u30D1\u30B9\u30EF\u30FC\u30C9\u306A\u3057)
-menu.resourceowners=\u4F5C\u8005\u304A\u3088\u3073\u5171\u540C\u4F5C\u8005
-menu.resourceowners.alt=\u5B66\u7FD2\u30EA\u30BD\u30FC\u30B9\u306E\u3059\u3079\u3066\u306E\u30AA\u30FC\u30CA\u30FC\u3092\u7BA1\u7406\u3059\u308B
 menu.ucreate=\u30E6\u30FC\u30B6\u3092\u4F5C\u6210\u3059\u308B
 menu.ucreate.alt=\u30E6\u30FC\u30B6\u3092\u4F5C\u6210\u3059\u308B
 menu.usearch=\u30E6\u30FC\u30B6\u691C\u7D22
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_lt.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_lt.properties
index 64517357824..cc65f3a7594 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_lt.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_lt.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=administratoriai
-menu.admingroup.alt=Tvarkyti administravimo grup\u0119
-menu.anonymousgroup=Anoniminiai naudotojai / sve\u010Diai
-menu.anonymousgroup.alt=Valdyti anonimini\u0173 naudotoj\u0173 grup\u0119 (sve\u010Dius)
+menu.administratorgroup=administratoriai
+menu.administratorgroup.alt=Tvarkyti administravimo grup\u0119
+menu.inviteegroup=Anoniminiai naudotojai / sve\u010Diai
+menu.inviteegroup.alt=Valdyti anonimini\u0173 naudotoj\u0173 grup\u0119 (sve\u010Dius)
 menu.authorgroup=Autoriai
 menu.authorgroup.alt=Tvarkyti autori\u0173 grup\u0119
 menu.coauthors=Bendraautoriai
@@ -24,8 +24,6 @@ menu.menuqueries=I\u0161ankstin\u0117 paie\u0161ka
 menu.menuqueries.alt=Tvarkyti naudotoj\u0105 pagal i\u0161ankstinius paie\u0161kos s\u0105ra\u0161us
 menu.noauthentication=Tr\u016Bksta autentifikavimo duomen\u0173
 menu.noauthentication.alt=Netinkamai registruoti naudotojai (n\u0117ra slapta\u017Eod\u017Eio)
-menu.resourceowners=Autoriai ir bendraautoriai
-menu.resourceowners.alt=Valdyti visus mokymo resurso s\u0105vininkus
 menu.sysadmingroup=Sistemos administratoriai
 menu.sysadmingroup.alt=Tvarkyti sistemos administravimo grup\u0119
 menu.ucreate=Sukurti naudotoj\u0105
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_nl_NL.properties
index 625c39987d4..2f2dc3dd31c 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_nl_NL.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_nl_NL.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administrators
-menu.admingroup.alt=Beheer de groep administrators
-menu.anonymousgroup=Anonieme gebruikers/gasten
-menu.anonymousgroup.alt=Beheer anonieme gebruikersgroep (gasten)
+menu.administratorgroup=Administrators
+menu.administratorgroup.alt=Beheer de groep administrators
+menu.inviteegroup=Anonieme gebruikers/gasten
+menu.inviteegroup.alt=Beheer anonieme gebruikersgroep (gasten)
 menu.authorgroup=Auteurs
 menu.authorgroup.alt=Beheer auteursgroep
 menu.coauthors=Co- auteurs
@@ -27,8 +27,6 @@ menu.menuqueries=van te voren gedefinieerde zoekingen
 menu.menuqueries.alt=Beheer gebruiker bij van te voren gedefinieerde zoeklijsten
 menu.noauthentication=Machtiging ontbreekt
 menu.noauthentication.alt=Gebruikers die niet correct toegevoegd zijn (geen wachtwoord)
-menu.resourceowners=Auteurs en co-auteurs
-menu.resourceowners.alt=Beheer alle eigenaars van een leermiddel
 menu.sysadmingroup=Systeemadministrators
 menu.sysadmingroup.alt=Beheer de groep systeemadministrators
 menu.ucreate=Maak gebruiker aan
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pl.properties
index 5f7591707c1..bf508791ca6 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pl.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pl.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administratorzy
-menu.admingroup.alt=Zarz\u0105dzaj grup\u0105 administrator\u00F3w
-menu.anonymousgroup=Anonimowy u\u017Cytkownik/go\u015B\u0107
-menu.anonymousgroup.alt=Zarz\u0105dzaj grup\u0105 anonimowych u\u017Cytkownik\u00F3w (go\u015Bci)
+menu.administratorgroup=Administratorzy
+menu.administratorgroup.alt=Zarz\u0105dzaj grup\u0105 administrator\u00F3w
+menu.inviteegroup=Anonimowy u\u017Cytkownik/go\u015B\u0107
+menu.inviteegroup.alt=Zarz\u0105dzaj grup\u0105 anonimowych u\u017Cytkownik\u00F3w (go\u015Bci)
 menu.authorgroup=Autorzy
 menu.authorgroup.alt=Zarz\u0105dzaj swoj\u0105 grup\u0105 autor\u00F3w
 menu.coauthors=Wsp\u00F3\u0142autorzy
@@ -27,8 +27,6 @@ menu.menuqueries=Predefiniowane wyszukiwanie
 menu.menuqueries.alt=Zarz\u0105dzaj u\u017Cytkownikami poprzez predefiniowane listy wyszukiwa\u0144
 menu.noauthentication=Brak autoryzacji
 menu.noauthentication.alt=U\u017Cytkownicy, kt\u00F3rzy nie s\u0105 poprawnie skonfigurowani
-menu.resourceowners=Autorzy i wsp\u00F3\u0142autorzy
-menu.resourceowners.alt=Zarz\u0105dzaj w\u0142a\u015Bcicielami zasobu edukacyjnego
 menu.sysadmingroup=Administratorzy systemu
 menu.sysadmingroup.alt=Zarz\u0105dzaj grup\u0105 administrator\u00F3w systemu
 menu.ucreate=Utw\u00F3rz u\u017Cytkownika
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_BR.properties
index ad864bdb737..fbfef8d1725 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_BR.properties
@@ -9,10 +9,10 @@ allow.request.delete.account.time=Solicitar exclus\u00E3o da conta do usu\u00E1r
 command.next=Ir para o pr\u00F3ximo usu\u00E1rio
 command.previous=Ir para o usu\u00E1rio anterior
 error.mail.not.valid=O endere\u00E7o de e-mail n\u00E3o \u00E9 v\u00E1lido.
-menu.admingroup=Administradores
-menu.admingroup.alt=Gerenciar grupo de administradores
-menu.anonymousgroup=Usu\u00E1rios/convidados an\u00F4nimos
-menu.anonymousgroup.alt=Gerenciar grupo de usu\u00E1rios an\u00F4nimos (convidados)
+menu.administratorgroup=Administradores
+menu.administratorgroup.alt=Gerenciar grupo de administradores
+menu.inviteegroup=Usu\u00E1rios/convidados an\u00F4nimos
+menu.inviteegroup.alt=Gerenciar grupo de usu\u00E1rios an\u00F4nimos (convidados)
 menu.authorgroup=Autores
 menu.authorgroup.alt=Gereciar grupo de autores
 menu.coauthors=Co-autores
@@ -59,8 +59,6 @@ menu.principalgroup=$org.olat.admin.user\:role.principal
 menu.principalgroup.alt=$org.olat.admin.user\:role.principal
 menu.qualitymanagergroup=$org.olat.admin.user\:role.qualitymanager
 menu.qualitymanagergroup.alt=$org.olat.admin.user\:role.qualitymanager
-menu.resourceowners=Autores e Co-autores
-menu.resourceowners.alt=Gerenciar todos os propriet\u00E1rios de um recurso did\u00E1tico
 menu.rolesmanagergroup=$org.olat.admin.user\:role.rolesmanager
 menu.rolesmanagergroup.alt=$org.olat.admin.user\:role.rolesmanager
 menu.sysadmingroup=Administradores do sistema
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_PT.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_PT.properties
index 24cfe1867b1..2cf02e603cc 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_PT.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_pt_PT.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administradores
-menu.admingroup.alt=Gerenciar grupo de administradores
-menu.anonymousgroup=Usu\u00E1rios/convidados an\u00F4nimos
-menu.anonymousgroup.alt=Gerenciar grupo de usu\u00E1rios an\u00F4nimos (convidados)
+menu.administratorgroup=Administradores
+menu.administratorgroup.alt=Gerenciar grupo de administradores
+menu.inviteegroup=Usu\u00E1rios/convidados an\u00F4nimos
+menu.inviteegroup.alt=Gerenciar grupo de usu\u00E1rios an\u00F4nimos (convidados)
 menu.authorgroup=Autores
 menu.authorgroup.alt=Gereciar grupo de autores
 menu.coauthors=Co-autores
@@ -25,8 +25,6 @@ menu.menuqueries=Buscas predefinidas
 menu.menuqueries.alt=Gerenciar usu\u00E1rio pelas listas de buscas predefinidas
 menu.noauthentication=Falta autentica\u00E7\u00E3o
 menu.noauthentication.alt=Usu\u00E1rios que n\u00E3o est\u00E3o corretamente cadastrados (sem senha)
-menu.resourceowners=Autores e Co-autores
-menu.resourceowners.alt=Gerenciar todos os propriet\u00E1rios de um recurso did\u00E1tico
 menu.sysadmingroup=Administradores do sistema
 menu.sysadmingroup.alt=Gerenciar grupo de administradores do sistema
 menu.ucreate=Criar usu\u00E1rio
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ru.properties
index 533b8e0e26b..5beaafc62e8 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ru.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_ru.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u0410\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438 / \u0413\u043E\u0441\u0442\u0438
-menu.anonymousgroup.alt=\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0433\u0440\u0443\u043F\u043F\u044B \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 (\u0433\u043E\u0441\u0442\u0435\u0439)
+menu.inviteegroup=\u0410\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438 / \u0413\u043E\u0441\u0442\u0438
+menu.inviteegroup.alt=\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0433\u0440\u0443\u043F\u043F\u044B \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 (\u0433\u043E\u0441\u0442\u0435\u0439)
 menu.authorgroup=\u0410\u0432\u0442\u043E\u0440\u044B
 menu.authorgroup.alt=\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0433\u0440\u0443\u043F\u043F\u044B \u0430\u0432\u0442\u043E\u0440\u043E\u0432
 menu.coauthors=\u0421\u043E\u0430\u0432\u0442\u043E\u0440\u044B
@@ -24,8 +24,6 @@ menu.menuqueries=\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u
 menu.menuqueries.alt=\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E \u043F\u043E\u0438\u0441\u043A\u0430, \u0437\u0430\u0434\u0430\u043D\u043D\u043E\u0433\u043E \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 
 menu.noauthentication=\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0438
 menu.noauthentication.alt=\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438, \u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u0435 \u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u043D\u0435 \u0437\u0430\u043A\u043E\u043D\u0447\u0435\u043D\u043E (\u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043F\u0430\u0440\u043E\u043B\u044C) 
-menu.resourceowners=\u0410\u0432\u0442\u043E\u0440\u044B \u0438 \u0441\u043E\u0430\u0432\u0442\u043E\u0440\u044B
-menu.resourceowners.alt=\u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0432\u0441\u0435\u0445 \u0432\u043B\u0430\u0434\u0435\u043B\u044C\u0446\u0435\u0432 \u0443\u0447\u0435\u0431\u043D\u044B\u0445 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\u043E\u0432
 menu.ucreate=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F
 menu.ucreate.alt=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F
 menu.usearch=\u041F\u043E\u0438\u0441\u043A \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_sq.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_sq.properties
index 74211e5de9a..ee5a95ee7e6 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_sq.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_sq.properties
@@ -1,8 +1,8 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.admingroup=Administrator\u00EBt
-menu.admingroup.alt=Drejton grupin e administrator\u00EBve
-menu.anonymousgroup=Shfryt\u00EBzuesit anonim / mysafir\u00EBt
-menu.anonymousgroup.alt=Drejto grupet e shfryt\u00EBzuesve anonim (mysafir\u00EBt)
+menu.administratorgroup=Administrator\u00EBt
+menu.administratorgroup.alt=Drejton grupin e administrator\u00EBve
+menu.inviteegroup=Shfryt\u00EBzuesit anonim / mysafir\u00EBt
+menu.inviteegroup.alt=Drejto grupet e shfryt\u00EBzuesve anonim (mysafir\u00EBt)
 menu.authorgroup=Autor\u00EBt
 menu.authorgroup.alt=Drejton grupin e autor\u00EBve
 menu.coauthors=Bashk\u00EB-autor\u00EBt
@@ -25,8 +25,6 @@ menu.menuqueries=K\u00EBrkime t\u00EB paracaktuara
 menu.menuqueries.alt=Drejton shfryt\u00EBzuesit sipas listave t\u00EB k\u00EBrkimit t\u00EB paracaktuara
 menu.noauthentication=Mungon autentikimi
 menu.noauthentication.alt=Shfryt\u00EBzuesit q\u00EB nuk jan\u00EB t\u00EB krijuar me p\u00EBrpik\u00EBri (pa fjal\u00EBkalim)
-menu.resourceowners=Autor\u00EBt dhe bashk\u00EB-autor\u00EBt
-menu.resourceowners.alt=Drejto t\u00EB gjith\u00EB pronar\u00EBt e resurseve t\u00EB m\u00EBsimit
 menu.sysadmingroup=Administrator\u00EBt e sistemit
 menu.sysadmingroup.alt=Drejton grupin e administrator\u00EBve t\u00EB sistemit
 menu.ucreate=Krijo shfryt\u00EBzues
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_CN.properties
index 13b8f924d99..20127e5b318 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_CN.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_CN.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u533F\u540D\u7528\u6237/\u6E38\u5BA2
-menu.anonymousgroup.alt=\u5BF9\u533F\u540D\u7528\u6237(\u6E38\u5BA2)\u8FDB\u884C\u7BA1\u7406
+menu.inviteegroup=\u533F\u540D\u7528\u6237/\u6E38\u5BA2
+menu.inviteegroup.alt=\u5BF9\u533F\u540D\u7528\u6237(\u6E38\u5BA2)\u8FDB\u884C\u7BA1\u7406
 menu.authorgroup=\u521B\u5EFA\u4EBA
 menu.authorgroup.alt=\u5BF9\u521B\u5EFA\u4EBA\u7EC4\u8FDB\u884C\u7BA1\u7406
 menu.coauthors=\u5408\u4F5C\u8005
@@ -25,8 +25,6 @@ menu.menuqueries=\u9884\u8BBE\u641C\u7D22
 menu.menuqueries.alt=\u6839\u636E\u9884\u8BBE\u641C\u7D22\u6765\u7BA1\u7406\u7528\u6237
 menu.noauthentication=\u8BA4\u8BC1\u4FE1\u606F\u4E0D\u5B8C\u6574
 menu.noauthentication.alt=\u4FE1\u606F\u4E0D\u5B8C\u6574\u7684\u7528\u6237[\u65E0\u5BC6\u7801]
-menu.resourceowners=\u4F5C\u8005\u53CA\u5408\u4F5C\u8005
-menu.resourceowners.alt=\u5B66\u4E60\u8D44\u6E90\u6240\u6709\u8005\u7BA1\u7406
 menu.ucreate=\u521B\u5EFA\u7528\u6237
 menu.ucreate.alt=\u521B\u5EFA\u7528\u6237
 menu.usearch=\u641C\u7D22\u7528\u6237
diff --git a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_TW.properties
index 2bfdb397ba2..46b15b56331 100644
--- a/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_TW.properties
+++ b/src/main/java/org/olat/user/ui/admin/_i18n/LocalStrings_zh_TW.properties
@@ -1,6 +1,6 @@
 #Fri Mar 23 15:13:55 CET 2018
-menu.anonymousgroup=\u533F\u540D\u4F7F\u7528\u8005 / \u8A2A\u5BA2
-menu.anonymousgroup.alt=\u7BA1\u7406\u533F\u540D\u4F7F\u7528\u8005\u7FA4\u7D44(\u8A2A\u5BA2)
+menu.inviteegroup=\u533F\u540D\u4F7F\u7528\u8005 / \u8A2A\u5BA2
+menu.inviteegroup.alt=\u7BA1\u7406\u533F\u540D\u4F7F\u7528\u8005\u7FA4\u7D44(\u8A2A\u5BA2)
 menu.authorgroup=\u4F5C\u8005
 menu.authorgroup.alt=\u7BA1\u7406\u4F5C\u8005\u7FA4\u7D44
 menu.coauthors=\u5171\u540C\u4F5C\u8005
@@ -25,8 +25,6 @@ menu.menuqueries=\u9810\u5148\u5B9A\u7FA9\u7684\u641C\u5C0B
 menu.menuqueries.alt=\u4F9D\u9810\u5148\u5B9A\u7FA9\u7684\u641C\u5C0B\u4F86\u7BA1\u7406\u4F7F\u7528\u8005
 menu.noauthentication=\u672A\u8A2D\u5BC6\u78BC
 menu.noauthentication.alt=\u4E0D\u6B63\u78BA\u8A2D\u5B9A\u7684\u4F7F\u7528\u8005\uFF08\u6C92\u6709\u5BC6\u78BC\uFF09
-menu.resourceowners=\u4F5C\u8005\u548C\u53CA\u5171\u540C\u4F5C\u8005
-menu.resourceowners.alt=\u7BA1\u7406\u4E00\u500B\u5B78\u7FD2\u8CC7\u6E90\u7684\u6240\u6709\u64C1\u6709\u8005
 menu.ucreate=\u5EFA\u7ACB\u4F7F\u7528\u8005
 menu.ucreate.alt=\u5EFA\u7ACB\u4F7F\u7528\u8005
 menu.usearch=\u4F7F\u7528\u8005\u641C\u5C0B
diff --git a/src/test/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAOTest.java b/src/test/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAOTest.java
index fe33825e9ed..7bf7b72deba 100644
--- a/src/test/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAOTest.java
+++ b/src/test/java/org/olat/basesecurity/manager/IdentityToIdentityRelationDAOTest.java
@@ -221,5 +221,35 @@ public class IdentityToIdentityRelationDAOTest extends OlatTestCase {
 						idSourceRoleOtherNoRight,
 						idSourceOtherTarget);
 	}
+	
+	@Test
+	public void getSources() {
+		String role = random();
+		RelationRole relationRole = relationRoleDao.createRelationRole(role, null, null, null);
+		Identity idSource = JunitTestHelper.createAndPersistIdentityAsRndUser("id-2-id-8");
+		Identity idTarget = JunitTestHelper.createAndPersistIdentityAsRndUser("id-2-id-9");
+		IdentityToIdentityRelation relation = identityToIdentityRelationDao.createRelation(idSource, idTarget, relationRole, null, null);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(relation);
+		
+		List<Identity> targets = identityToIdentityRelationDao.getSources(relationRole);
+		assertThat(targets)
+			.containsExactly(idSource);
+	}
+	
+	@Test
+	public void getTargets() {
+		String role = random();
+		RelationRole relationRole = relationRoleDao.createRelationRole(role, null, null, null);
+		Identity idSource = JunitTestHelper.createAndPersistIdentityAsRndUser("id-2-id-8");
+		Identity idTarget = JunitTestHelper.createAndPersistIdentityAsRndUser("id-2-id-9");
+		IdentityToIdentityRelation relation = identityToIdentityRelationDao.createRelation(idSource, idTarget, relationRole, null, null);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(relation);
+		
+		List<Identity> targets = identityToIdentityRelationDao.getTargets(relationRole);
+		assertThat(targets)
+			.containsExactly(idTarget);
+	}
 
 }
-- 
GitLab