diff --git a/.hgtags b/.hgtags
index 800aedd6840643ddbcecccca6256bbc7e1b34906..59d373f6fabfe5864ea4198d76ffbc1334961cd7 100644
--- a/.hgtags
+++ b/.hgtags
@@ -173,3 +173,4 @@ bde4d49de3ec377802302debda91373537ee6dae OpenOLAT 11.0.9
 3aa428100d40cd4481df316b4feccbb6ab3414a1 OpenOLAT 11.1.2
 18b14d1153dd44d638f7362d1d02b4ebeb77d996 OpenOLAT 11.1.2
 dced52763f304b670e173b302a2bc4509e5345b8 OpenOLAT 11.2.0
+efc1aac6f9600cd8617e1c2a2b846fa833875861 OpenOLAT 11.2.1
diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java
index 7da43afab34f0a334cd2000f5b1d39954bc67932..f6708fee6aa58e5a06d05587e0a251ae957ee9b0 100644
--- a/src/main/java/org/olat/basesecurity/AuthHelper.java
+++ b/src/main/java/org/olat/basesecurity/AuthHelper.java
@@ -253,7 +253,7 @@ public class AuthHelper {
 			} else {
 				//fxdiff FXOLAT-151: add eventually the identity to the security group
 				if(!groupDao.hasRole(invitation.getBaseGroup(), identity, GroupRoles.invitee.name())) {
-					groupDao.addMembership(invitation.getBaseGroup(), identity, GroupRoles.invitee.name());
+					groupDao.addMembershipTwoWay(invitation.getBaseGroup(), identity, GroupRoles.invitee.name());
 					DBFactory.getInstance().commit();
 				}
 
diff --git a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java
index 1b9c05e1026c4707c2c02248ba2cb115b4696bd6..a0c8a5624fdcee58cb6169a00b5b8e53252889bf 100644
--- a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java
+++ b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java
@@ -80,7 +80,11 @@ public class GroupDAO {
 		return group;
 	}
 	
-	public GroupMembership addMembership(Group group, Identity identity, String role) {
+	/**
+	 * Add a membership to the group, in the set of the group too which can be
+	 * reloaded.
+	 */
+	public GroupMembership addMembershipTwoWay(Group group, Identity identity, String role) {
 		GroupMembershipImpl membership = new GroupMembershipImpl();
 		membership.setCreationDate(new Date());
 		membership.setLastModified(new Date());
@@ -98,6 +102,19 @@ public class GroupDAO {
 		return membership;
 	}
 	
+	/**
+	 * Create a membership without updating the set in the group.
+	 */
+	public void addMembershipOneWay(Group group, Identity identity, String role) {
+		GroupMembershipImpl membership = new GroupMembershipImpl();
+		membership.setCreationDate(new Date());
+		membership.setLastModified(new Date());
+		membership.setGroup(group);
+		membership.setIdentity(identity);
+		membership.setRole(role);
+		dbInstance.getCurrentEntityManager().persist(membership);
+	}
+	
 	public int removeMemberships(Group group) {
 		EntityManager em = dbInstance.getCurrentEntityManager();
 		List<GroupMembership> memberships = em.createNamedQuery("membershipsByGroup", GroupMembership.class)
diff --git a/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java b/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java
index 885616b5ab6bd0e990afbe5e618fe24b7a77c175..c9a0de90f03127399f296584cd542a9e0bce68f3 100644
--- a/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java
+++ b/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java
@@ -59,6 +59,7 @@ import org.olat.core.id.Persistable;
 	@NamedQuery(name="membershipsByGroupAndIdentity", query="select membership from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey"),
 	@NamedQuery(name="membershipsByGroupIdentityAndRole", query="select membership from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey and membership.role=:role"),
 	@NamedQuery(name="countMembersByGroup", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey"),
+	@NamedQuery(name="countMembersByGroupAndRole", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey and membership.role=:role"),
 	@NamedQuery(name="membersByGroupAndRole", query="select distinct membership.identity from bgroupmember as membership where membership.group.key=:groupKey and membership.role=:role"),
 	@NamedQuery(name="hasRoleByGroupIdentityAndRole", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey and membership.role=:role")
 })
diff --git a/src/main/java/org/olat/course/assessment/AssessmentManager.java b/src/main/java/org/olat/course/assessment/AssessmentManager.java
index 9605ad14c3f4eb4bef1127f495eb1e0db333642e..5050f2820d0c5b470a9829b9fa62d89af55979d4 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentManager.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentManager.java
@@ -163,17 +163,21 @@ public interface AssessmentManager {
 	 * @return
 	 */
 	public Date getScoreLastModifiedDate(CourseNode courseNode, Identity identity);
-	
+
 	/**
 	 * Save the users achieved ScoreEvaluation for this node. If there is already a score property available, it will be
-	 * overwritten with the new value <p>
-	 *
-	 * @param courseNode
-	 * @param identity
-	 * @param assessedIdentity
-	 * @param scoreEvaluation
+	 * overwritten with the new value.
+	 * 
+	 * @param courseNode The course element
+	 * @param identity The identity who make the changes
+	 * @param assessedIdentity The assessed identity
+	 * @param scoreEvaluation The updated score evaluation
+	 * @param userCourseEnvironment The user course env. of the assessed identity
+	 * @param incrementUserAttempts
 	 */
-	public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity, ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts);
+	
+	public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity,
+			ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts);
 	
 	/**
 	 * Provides an OLATResourceable for locking (of score/passed etc.) purposes (if doInSync is called on score/passed data)
diff --git a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
index 28d14c6ab48a3f24a660f7086df779b038b02eff..4f791e0137c4be092c68bf1aecb53514a14dabab 100644
--- a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
+++ b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
@@ -329,7 +329,7 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		}
 
 		if(course.getCourseConfig().isAutomaticCertificationEnabled()) {
-			CourseNode rootNode = userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode();
+			CourseNode rootNode = courseEnv.getRunStructure().getRootNode();
 			ScoreEvaluation rootEval = scoreAccounting.evalCourseNode((AssessableCourseNode)rootNode);
 			if(rootEval != null && rootEval.getPassed() != null && rootEval.getPassed().booleanValue()
 					&& certificatesManager.isCertificationAllowed(assessedIdentity, cgm.getCourseEntry())) {
@@ -388,7 +388,7 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		
 		AssessmentEntry nodeAssessment = assessmentService
 				.loadAssessmentEntry(identity, cgm.getCourseEntry(), courseNode.getIdent());	
-		return nodeAssessment == null ? INTEGER_ZERO : nodeAssessment.getAttempts();
+		return nodeAssessment == null || nodeAssessment.getAttempts() == null  ? INTEGER_ZERO : nodeAssessment.getAttempts();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
index 04658b2f496c9857b38bf4aa4fdd2a327944f957..453898ab2b81bd38fbb051c7e042cba454038936 100644
--- a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
@@ -559,21 +559,24 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 * @param userCourseEnv
 	 * @param assessedIdentity
 	 */
-	public void updateScoreEvaluation(UserCourseEnvironment userCourseEnv, Identity assessedIdentity) {
+	public void updateScoreEvaluation(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
 		ModuleConfiguration config = getModuleConfiguration();
 		Boolean sum = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CHECKBOX);
 		Float cutValue = (Float)config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
 		Float maxScore = (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
+		Boolean manualCorrection = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_MANUAL_CORRECTION);
 		if(cutValue != null) {
-			doUpdateAssessment(cutValue, maxScore, userCourseEnv, assessedIdentity);
-		} else if(sum != null) {
-			doUpdateAssessmentBySum(userCourseEnv, assessedIdentity);
+			doUpdateAssessment(cutValue, maxScore, identity, assessedUserCourseEnv, assessedIdentity);
+		} else if(sum != null && sum.booleanValue()) {
+			doUpdateAssessmentBySum(identity, assessedUserCourseEnv, assessedIdentity);
+		} else if(manualCorrection != null && manualCorrection.booleanValue()) {
+			doUpdateManualAssessment(maxScore, identity, assessedUserCourseEnv, assessedIdentity);
 		}
 	}
 	
-	private void doUpdateAssessment(Float cutValue, Float maxScore, UserCourseEnvironment userCourseEnv, Identity assessedIdentity) {
+	private void doUpdateAssessment(Float cutValue, Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
 		OLATResourceable courseOres = OresHelper
-				.createOLATResourceableInstance("CourseModule", userCourseEnv.getCourseEnvironment().getCourseResourceableId());
+				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
 		
 		CheckboxManager checkboxManager = CoreSpringFactory.getImpl(CheckboxManager.class);
 		float score = checkboxManager.calculateScore(assessedIdentity, courseOres, getIdent());
@@ -588,14 +591,13 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		}
 		ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), passed);
 		
-		AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
-		Identity mySelf = userCourseEnv.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, mySelf, assessedIdentity, sceval, userCourseEnv, false);
+		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false);
 	}
 	
-	private void doUpdateAssessmentBySum(UserCourseEnvironment userCourseEnv, Identity assessedIdentity) {
+	private void doUpdateAssessmentBySum(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
 		OLATResourceable courseOres = OresHelper
-				.createOLATResourceableInstance("CourseModule", userCourseEnv.getCourseEnvironment().getCourseResourceableId());
+				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
 		
 		ModuleConfiguration config = getModuleConfiguration();
 		CheckboxManager checkboxManager = CoreSpringFactory.getImpl(CheckboxManager.class);
@@ -619,9 +621,24 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 
 		ScoreEvaluation sceval = new ScoreEvaluation(score, new Boolean(passed));
 		
-		AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
-		Identity mySelf = userCourseEnv.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, mySelf, assessedIdentity, sceval, userCourseEnv, false);
+		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false);
+	}
+	
+	private void doUpdateManualAssessment(Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
+		OLATResourceable courseOres = OresHelper
+				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
+		
+		CheckboxManager checkboxManager = CoreSpringFactory.getImpl(CheckboxManager.class);
+		float score = checkboxManager.calculateScore(assessedIdentity, courseOres, getIdent());
+		if(maxScore != null && maxScore.floatValue() < score) {
+			score = maxScore.floatValue();
+		}
+
+		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
+		ScoreEvaluation currentEval = getUserScoreEvaluation(am.getAssessmentEntry(this, assessedIdentity));
+		ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), currentEval.getPassed());
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false);
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java b/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java
index cb3c3f100d9c5713bbabede70ee84bcbf40992d6..fa630349f8ccef208d520e2f7c09431ecbc70c8e 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java
@@ -284,7 +284,7 @@ public class AssessedIdentityCheckListController extends FormBasicController {
 		}
 		checkboxManager.check(courseOres, courseNode.getIdent(), batchElements);
 		
-		courseNode.updateScoreEvaluation(assessedUserCourseEnv, assessedIdentity);
+		courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
 	}
 	
 	private void doUpdateCheck(CheckboxWrapper wrapper, boolean check) {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
index 8f730913d27f9d59a0834ae151209d53954b7a1d..b000cdfd3b6b7773ab22d5d36273cbd4c7259192 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
@@ -566,10 +566,10 @@ public class CheckListAssessmentController extends FormBasicController implement
 			DBFactory.getInstance().commit();
 			
 			ICourse course = CourseFactory.loadCourse(courseOres);
-			List<Identity> identities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
-			for(Identity identity:identities) {
-				UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				courseNode.updateScoreEvaluation(assessedUserCourseEnv, identity);
+			List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
+			for(Identity assessedIdentity:assessedIdentities) {
+				UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
+				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
 			}
 		}
 		
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
index 4c201c55d33c6ddf69d3dd84c08c6d0e7023594e..660165698cab9e0bba24b05f8e0abcafe483f5ca 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
@@ -284,7 +284,7 @@ public class CheckListRunController extends FormBasicController implements Contr
 			//make sure all results is on the database before calculating some scores
 			//manager commit already DBFactory.getInstance().commit();
 			
-			courseNode.updateScoreEvaluation(userCourseEnv, getIdentity());
+			courseNode.updateScoreEvaluation(getIdentity(), userCourseEnv, getIdentity());
 			
 			Checkbox checkbox = wrapper.getCheckbox();
 			logUpdateCheck(checkbox.getCheckboxId(), checkbox.getTitle());
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java
index fad631cc2725dfb84e1e3fe7e1b1e0802a0b15cb..208d65a756a51f298d42340326bf846696635973 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java
@@ -380,10 +380,10 @@ public class CheckboxAssessmentController extends FormBasicController {
 			DBFactory.getInstance().commit();
 			ICourse course = CourseFactory.loadCourse(courseOres);
 			
-			List<Identity> identities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
-			for(Identity identity:identities) {
-				UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				courseNode.updateScoreEvaluation(userCourseEnv, identity);
+			List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
+			for(Identity assessedIdentity:assessedIdentities) {
+				UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
+				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
 			}
 		}
 		
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_content/run.html b/src/main/java/org/olat/course/nodes/cl/ui/_content/run.html
index a9f5cb760d3dfeea8820fc9a5f81829a58eedda6..0222802b04b7393987156303590f4a0a06409587 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_content/run.html
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_content/run.html
@@ -53,7 +53,7 @@
 	</div>
 #end
 
-#if ($comment)		
+#if ($r.isNotEmpty($comment))		
 	<div class="panel panel-default o_comment">
 	  	<div class="panel-heading" data-toggle="collapse" data-target="#collapseComment">
 	  		<h4 class="panel-title">
diff --git a/src/main/java/org/olat/course/nodes/iq/IQRunController.java b/src/main/java/org/olat/course/nodes/iq/IQRunController.java
index 989f4eedc62ecf32fabd7f427bde826e83b1ffa9..7823c0f44bebc74ae63650eb58a2b0994f1a7ded 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java
@@ -610,7 +610,7 @@ public class IQRunController extends BasicController implements GenericEventList
 	    		myContent.contextPut("passed", assessmentEntry.getPassed());
 	    		StringBuilder comment = Formatter.stripTabsAndReturns(assessmentEntry.getComment());
 	    		myContent.contextPut("comment", StringHelper.xssScan(comment));
-	    		myContent.contextPut("attempts", assessmentEntry.getAttempts());
+	    		myContent.contextPut("attempts", assessmentEntry.getAttempts() == null ? 0 : assessmentEntry.getAttempts());
     		}
     	}
     	
diff --git a/src/main/java/org/olat/course/site/CourseSiteContextEntryControllerCreator.java b/src/main/java/org/olat/course/site/CourseSiteContextEntryControllerCreator.java
index 74fac109c15b958fdab788fd5559e92450c87895..ce2fae5ff3ce05b30d1b25ef5583e0a7ac1a9048 100644
--- a/src/main/java/org/olat/course/site/CourseSiteContextEntryControllerCreator.java
+++ b/src/main/java/org/olat/course/site/CourseSiteContextEntryControllerCreator.java
@@ -32,6 +32,7 @@ import org.olat.core.gui.control.navigation.SiteDefinition;
 import org.olat.core.gui.control.navigation.SiteDefinitions;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.OLATResourceable;
+import org.olat.core.id.Roles;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.ContextEntryControllerCreator;
@@ -94,6 +95,13 @@ public class CourseSiteContextEntryControllerCreator extends DefaultContextEntry
 		}
 		
 		UserSession usess = ureq.getUserSession();
+		if(re.getAccess() == RepositoryEntry.DELETED) {
+			Roles roles = usess.getRoles();
+			if(!roles.isInstitutionalResourceManager() && !roles.isOLATAdmin()) {
+				return messageController(ureq, wControl, "repositoryentry.deleted");
+			}
+		}
+		
 		if(usess.isInAssessmentModeProcess() && !usess.matchLockResource(re.getOlatResource())) {
 			return null;
 		}
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
index ad1ba63e55014a6554b6b821fdde907ef7e77c8c..47134e92332a49dfb844197e0968e1c5eff1b4a5 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
@@ -141,7 +141,7 @@ public class BusinessGroupDAO {
 		Group group = groupDao.createGroup();
 		businessgroup.setBaseGroup(group);
 		if (creator != null) {
-			groupDao.addMembership(group, creator, GroupRoles.coach.name());
+			groupDao.addMembershipTwoWay(group, creator, GroupRoles.coach.name());
 		}
 
 		EntityManager em = dbInstance.getCurrentEntityManager();
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
index 5ca80d6859dedc04d5767ad2962da7150ce2eaf6..0693b16d4a5a0707b9933a448e6be64eb144d0d0 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
@@ -39,6 +39,8 @@ import org.olat.basesecurity.model.IdentityRefImpl;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.persistence.PersistenceHelper;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.course.assessment.manager.AssessmentModeDAO;
 import org.olat.group.BusinessGroup;
@@ -61,6 +63,8 @@ import org.springframework.stereotype.Service;
  */
 @Service("businessGroupRelationDao")
 public class BusinessGroupRelationDAO {
+	
+	private static final OLog log = Tracing.createLoggerFor(BusinessGroupRelationDAO.class);
 
 	@Autowired
 	private DB dbInstance;
@@ -75,9 +79,18 @@ public class BusinessGroupRelationDAO {
 		repositoryEntryRelationDao.createRelation(((BusinessGroupImpl)group).getBaseGroup(), re);
 	}
 	
-	public void addRole(Identity identity, BusinessGroupRef businessGroup, String role) {
-		Group group = getGroup(businessGroup);
-		groupDao.addMembership(group, identity, role);
+	public void addRole(Identity identity, BusinessGroup businessGroup, String role) {
+		Group group = null;
+		try {
+			group = businessGroup.getBaseGroup();
+			if(group == null) {
+				group = getGroup(businessGroup);
+			}
+		} catch(Exception e) {
+			log.warn("", e);
+			group = getGroup(businessGroup);
+		}
+		groupDao.addMembershipOneWay(group, identity, role);
 	}
 	
 	public boolean removeRole(Identity identity, BusinessGroupRef businessGroup, String role) {
@@ -195,6 +208,21 @@ public class BusinessGroupRelationDAO {
 		return count == null ? 0 : count.intValue();
 	}
 	
+	/**
+	 * Count the number of participants.
+	 * 
+	 * @param group
+	 * @return
+	 */
+	public int countEnrollment(BusinessGroup group) {
+		Number count = dbInstance.getCurrentEntityManager()
+				.createNamedQuery("countMembersByGroupAndRole", Number.class)
+				.setParameter("groupKey", group.getBaseGroup().getKey())
+				.setParameter("role", GroupRoles.participant.name())
+				.getSingleResult();
+		return count == null ? 0 : count.intValue();
+	}
+	
 	/**
 	 * Return the number of coaches with author rights.
 	 * @param group
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
index 5cef78b7fa898f45193f066841ff8a2a3ced3281..fd798171b2e4243aaabb09df9c681751ddba67c0 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
@@ -1385,11 +1385,11 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD
 				reservationDao.deleteReservation(reservation);
 			}
 		} else if (reloadedGroup.getMaxParticipants() != null) {
-			int participantsCounter = businessGroupRelationDAO.countRoles(reloadedGroup, GroupRoles.participant.name());
+			int participantsCounter = businessGroupRelationDAO.countEnrollment(reloadedGroup);
 			int reservations = reservationDao.countReservations(reloadedGroup.getResource());
 			
 			log.info("doEnroll - participantsCounter: " + participantsCounter + ", reservations: " + reservations + " maxParticipants: " + reloadedGroup.getMaxParticipants().intValue(), identity.getName());
-			if (reservation == null && (participantsCounter + reservations) >= reloadedGroup.getMaxParticipants().intValue()) {
+			if ((participantsCounter + reservations) >= reloadedGroup.getMaxParticipants().intValue()) {
 				// already full, show error and updated choose page again
 				if (reloadedGroup.getWaitingListEnabled().booleanValue()) {
 					addToWaitingList(ureqIdentity, identity, reloadedGroup, mailing, events);
diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java b/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
index e130e859b6652d0fa0e40d9a1052d3fa8eadf2c7..93e1cf36966c697150ef8941b0bf85065d45cd46 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.cyberneko.html.parsers.SAXParser;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.helpers.Settings;
@@ -631,6 +632,8 @@ public class QTI12To21Converter {
 				if(!trimmedText.startsWith("<p") && !trimmedText.startsWith("<div")) {
 					text = "<p>" + trimmedText + "</p>";
 				}	
+			} else {
+				text = StringEscapeUtils.unescapeHtml(text);
 			}
 		}
 		return text;
diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
index e39ce15e4e95ac1a45bb109f54f86d1e243052ff..4324f1ba8f8f957acc28d56dc5cd1804a5cbfb73 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
@@ -173,7 +173,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 	public Binder createNewBinder(String title, String summary, String imagePath, Identity owner) {
 		BinderImpl portfolio = binderDao.createAndPersist(title, summary, imagePath, null);
 		if(owner != null) {
-			groupDao.addMembership(portfolio.getBaseGroup(), owner, PortfolioRoles.owner.name());
+			groupDao.addMembershipTwoWay(portfolio.getBaseGroup(), owner, PortfolioRoles.owner.name());
 		}
 		return portfolio;
 	}
@@ -188,7 +188,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 	public void createAndPersistBinderTemplate(Identity owner, RepositoryEntry entry, Locale locale) {
 		BinderImpl binder = binderDao.createAndPersist(entry.getDisplayname(), entry.getDescription(), null, entry);
 		if(owner != null) {
-			groupDao.addMembership(binder.getBaseGroup(), owner, PortfolioRoles.owner.name());
+			groupDao.addMembershipTwoWay(binder.getBaseGroup(), owner, PortfolioRoles.owner.name());
 		}
 		//add section
 		Translator pt = Util.createPackageTranslator(PortfolioHomeController.class, locale);
@@ -564,7 +564,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 	public Binder assignBinder(Identity owner, BinderRef templateBinder, RepositoryEntry entry, String subIdent, Date deadline) {
 		BinderImpl reloadedTemplate = (BinderImpl)binderDao.loadByKey(templateBinder.getKey());
 		BinderImpl binder = binderDao.createCopy(reloadedTemplate, entry, subIdent);
-		groupDao.addMembership(binder.getBaseGroup(), owner, PortfolioRoles.owner.name());
+		groupDao.addMembershipTwoWay(binder.getBaseGroup(), owner, PortfolioRoles.owner.name());
 		return binder;
 	}
 
@@ -635,7 +635,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 	public void addAccessRights(PortfolioElement element, Identity identity, PortfolioRoles role) {
 		Group baseGroup = element.getBaseGroup();
 		if(!groupDao.hasRole(baseGroup, identity, role.name())) {
-			groupDao.addMembership(baseGroup, identity, role.name());
+			groupDao.addMembershipTwoWay(baseGroup, identity, role.name());
 		}
 	}
 	
@@ -647,7 +647,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 				if(change.isAdd()) {
 					if(!groupDao.hasRole(baseGroup, identity, change.getRole().name())) {
 						Group group = getGroup(change.getElement());
-						groupDao.addMembership(group, identity, change.getRole().name());
+						groupDao.addMembershipOneWay(group, identity, change.getRole().name());
 					}
 				} else {
 					if(groupDao.hasRole(baseGroup, identity, change.getRole().name())) {
@@ -839,7 +839,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 			((SectionImpl)reloadedSection).setSectionStatus(SectionStatus.inProgress);
 		}
 		Page page = pageDao.createAndPersist(title, summary, imagePath, align, editable, reloadedSection, null);
-		groupDao.addMembership(page.getBaseGroup(), owner, PortfolioRoles.owner.name());
+		groupDao.addMembershipTwoWay(page.getBaseGroup(), owner, PortfolioRoles.owner.name());
 		return page;
 	}
 
diff --git a/src/main/java/org/olat/modules/reminder/manager/ReminderDAO.java b/src/main/java/org/olat/modules/reminder/manager/ReminderDAO.java
index 905868dc0d9d5994f7676405096326a0d7f92eac..d25dcc173c99e8625def453c216cad4e36f4bd57 100644
--- a/src/main/java/org/olat/modules/reminder/manager/ReminderDAO.java
+++ b/src/main/java/org/olat/modules/reminder/manager/ReminderDAO.java
@@ -128,17 +128,18 @@ public class ReminderDAO {
 	}
 	
 	/**
-	 * Get all reminders of active repository entries.
+	 * Get all reminders of active repository entries (status must be
+	 * open and not "softly" deleted).
 	 * 
 	 * @param startDate
-	 * @return
+	 * @return A list of reminders
 	 */
 	public List<Reminder> getReminders(Date startDate) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select rem from reminder rem")
 		  .append(" inner join rem.entry entry")
 		  .append(" where (rem.startDate is null or rem.startDate<=:startDate)")
-		  .append(" and entry.statusCode=0");
+		  .append(" and entry.statusCode=0 and entry.access>").append(RepositoryEntry.DELETED);
 
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), Reminder.class)
@@ -146,6 +147,12 @@ public class ReminderDAO {
 				.getResultList();
 	}
 
+	/**
+	 * Get all reminders without restrictions.
+	 * 
+	 * @param entry
+	 * @return A list of remidners
+	 */
 	public List<Reminder> getReminders(RepositoryEntryRef entry) {
 		String q = "select rem from reminder rem inner join rem.entry entry where entry.key=:entryKey";
 		return dbInstance.getCurrentEntityManager()
diff --git a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java
index 61d160033d3df55ae53d835dc7805a7ec45fa09a..dd332c2435104114039a434737a0d328ecb5e583 100644
--- a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java
+++ b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java
@@ -225,7 +225,7 @@ public class EPPolicyManager {
 			Group secGroup = groupDao.createGroup();
 			relation = createBaseRelation(map, secGroup, EPMapPolicy.Type.user.name(), policy.getFrom(), policy.getTo());
 			for(Identity identity:policy.getIdentities()) {
-				groupDao.addMembership(secGroup, identity, GroupRoles.participant.name());
+				groupDao.addMembershipTwoWay(secGroup, identity, GroupRoles.participant.name());
 			}
 		} else {
 			EPStructureElementToGroupRelation currentPolicy = reusePolicyInSession(relation, map);
@@ -248,7 +248,7 @@ public class EPPolicyManager {
 				groupDao.removeMembership(secGroup, currentMember);
 			}
 			for(Identity newMember:newMembers) {
-				groupDao.addMembership(secGroup, newMember, GroupRoles.participant.name());
+				groupDao.addMembershipTwoWay(secGroup, newMember, GroupRoles.participant.name());
 			}
 		}
 		return relation;
diff --git a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java
index c3102bf0e1b4e4c590ed70da457ce7520e087438..6c8067aed974e808bcc7c834e8655e6eca0f1987 100755
--- a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java
+++ b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java
@@ -1829,7 +1829,7 @@ public class EPStructureManager {
 		Group group = repositoryEntyRelationDao.getDefaultGroup(entry);
 		if(group == null) {
 			group = groupDao.createGroup();
-			groupDao.addMembership(group, identity, GroupRoles.owner.name());
+			groupDao.addMembershipTwoWay(group, identity, GroupRoles.owner.name());
 		}
 		
 		EPStructureElementToGroupRelation relation = createBaseRelation(el, group);
@@ -1885,7 +1885,7 @@ public class EPStructureManager {
 		relation.setCreationDate(new Date());
 		relation.setGroup(ownerGroup);
 		relation.setStructureElement(element);
-		groupDao.addMembership(ownerGroup, author, GroupRoles.owner.name());
+		groupDao.addMembershipTwoWay(ownerGroup, author, GroupRoles.owner.name());
 		return relation;
 	}
 	
diff --git a/src/main/java/org/olat/portfolio/manager/InvitationDAO.java b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java
index c104acd26e25d091547806bdbc7e7ad23b90f794..b279768530d411721342b9f19e5fe71e6a9b0640 100644
--- a/src/main/java/org/olat/portfolio/manager/InvitationDAO.java
+++ b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java
@@ -110,7 +110,7 @@ public class InvitationDAO {
 		User user = userManager.createUser(invitation.getFirstName(), invitation.getLastName(), invitation.getMail());
 		user.getPreferences().setLanguage(locale.toString());
 		Identity invitee = securityManager.createAndPersistIdentityAndUser(tempUsername, null, user, null, null);
-		groupDao.addMembership(invitation.getBaseGroup(), invitee, GroupRoles.invitee.name());
+		groupDao.addMembershipTwoWay(invitation.getBaseGroup(), invitee, GroupRoles.invitee.name());
 		return invitee;
 	}
 	
@@ -129,7 +129,7 @@ public class InvitationDAO {
 			invitee = securityManager.createAndPersistIdentityAndUser(tempUsername, null, user, null, null, null);
 		}
 		// add invitee to the security group of that portfolio element
-		groupDao.addMembership(group, invitee, GroupRoles.invitee.name());			
+		groupDao.addMembershipTwoWay(group, invitee, GroupRoles.invitee.name());			
 		return invitee;
 	}
 	
diff --git a/src/main/java/org/olat/repository/RepositoryEntryStatus.java b/src/main/java/org/olat/repository/RepositoryEntryStatus.java
index ab875bf55247399ab9962e981daf8958bd334138..5497c5a719224ad1e645ba18c3d18bce3ab10980 100644
--- a/src/main/java/org/olat/repository/RepositoryEntryStatus.java
+++ b/src/main/java/org/olat/repository/RepositoryEntryStatus.java
@@ -35,6 +35,9 @@ package org.olat.repository;
 public class RepositoryEntryStatus {
 
 	public static final int REPOSITORY_STATUS_OPEN = 0;
+	/**
+	 * Correspond to the "freeze" status
+	 */
 	public static final int REPOSITORY_STATUS_CLOSED = 2;
 	public static final int REPOSITORY_STATUS_UNPUBLISHED = 4;
 	
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
index 7be0516accf22ac92e39827f362b91a3ba155d08..7fac13043046c3b4282e68cad0eaa5dc70060d40 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
@@ -418,6 +418,7 @@ repository.admin.leave.label=Standardeinstellung f\u00FCr neue Kurse
 repository.admin.leave.title=Verlassen von Kursen zulassen
 repository.admin.lifecycle.title=Automatische Verwaltung des Lebenszyklus
 repository.admin.title=Repository Einstellungen
+repositoryentry.deleted=Diese Ressource wurde gel\u00F6scht und ist nicht mehr verf\u00FCgbar.
 repositoryentry.not.existing=Diese Ressource ist nicht mehr verf\u00FCgbar.
 resource.editor=Editor
 resource.error.test.xml=Die Lernressource konnte nicht hinzugef\u00FCgt werden. Die qti.xml-Datei konnte nicht geparst werden.
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
index 0172982a94c71546805e9dd567a183045b307b79..a8eb6ee4f0908cf4b3fe3354eb8dd7546825386d 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties
@@ -415,6 +415,7 @@ repository.admin.leave.label=Standard setting for new courses
 repository.admin.leave.title=Allow leaving courses
 repository.admin.lifecycle.title=Automatic Life-cycle management
 repository.admin.title=Repository settings
+repositoryentry.deleted=This resource was deleted and is no longer available.
 repositoryentry.not.existing=This resource is no longer available.
 resource.editor=Editor
 resource.error.test.xml=Learning resource could not be added. The qti.xml file could not be parsed.
diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
index 85e1eccab580d6e7697f1759cf4f600aa845d441..459a6519ba81662e0c57fa59f0c0b6d57ab7c793 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
@@ -168,7 +168,7 @@ public class RepositoryEntryRelationDAO {
 	
 	public void addRole(Identity identity, RepositoryEntryRef re, String role) {
 		Group group = getDefaultGroup(re);
-		groupDao.addMembership(group, identity, role);
+		groupDao.addMembershipOneWay(group, identity, role);
 	}
 	
 	public int removeRole(IdentityRef identity, RepositoryEntryRef re, String role) {
diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
index 90f6e7600bf0a4483ae44ed859258d586e7a2a82..bfc6933b253efa78f889a1ea850f05fcb8c6276f 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
@@ -215,7 +215,7 @@ public class RepositoryServiceImpl implements RepositoryService {
 		re.setGroups(rels);
 		
 		if(initialAuthor != null) {
-			groupDao.addMembership(group, initialAuthor, GroupRoles.owner.name());
+			groupDao.addMembershipTwoWay(group, initialAuthor, GroupRoles.owner.name());
 		}
 		
 		dbInstance.getCurrentEntityManager().persist(re);
diff --git a/src/main/java/org/olat/repository/ui/author/AccessRenderer.java b/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
index 83d4f47d9c023197ae64b06b2d532688dd867ff2..1c5130e99753f20585c28961274f36d0b96d557e 100644
--- a/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
+++ b/src/main/java/org/olat/repository/ui/author/AccessRenderer.java
@@ -49,12 +49,13 @@ public class AccessRenderer implements FlexiCellRenderer {
 			int row, FlexiTableComponent source, URLBuilder ubu, Translator translator)  {
 		if(val instanceof RepositoryEntryLight) {
 			RepositoryEntryLight re = (RepositoryEntryLight)val;
-			if(re.isMembersOnly()) {
+			if(re.getAccess() == RepositoryEntry.DELETED) {
+				sb.append(translator.translate("table.header.access.deleted"));
+			} else if(re.isMembersOnly()) {
 				sb.append(translator.translate("table.header.access.membersonly")); 
 			} else {
 				switch (re.getAccess()) {
 					case RepositoryEntry.DELETED: {
-
 						sb.append(translator.translate("table.header.access.deleted"));
 						break;
 					}
diff --git a/src/main/java/org/olat/repository/ui/author/AuthorDeletedListController.java b/src/main/java/org/olat/repository/ui/author/AuthorDeletedListController.java
index f4b5717ae3f00509467f45924bb4537ec5948ae4..291fd03fe6bb05d799ffcc4ac80a05dfac7859b2 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthorDeletedListController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthorDeletedListController.java
@@ -121,6 +121,11 @@ public class AuthorDeletedListController extends AuthorListController {
 				reloadRows();
 			}
 			cleanUp();
+		} else if(dToolsCtrl == source) {
+			if(event == Event.DONE_EVENT) {
+				toolsCalloutCtrl.deactivate();
+				cleanUp();
+			}
 		}
 		super.event(ureq, source, event);
 	}
diff --git a/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java b/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java
index 7da1b5fa3b1506d5251577bce0534f35d528f050..5febf6910c3cff3ccf1f5c66fa1100ed458d3bc8 100644
--- a/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java
+++ b/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java
@@ -61,18 +61,26 @@ public class GroupDAOTest extends OlatTestCase {
 	public void createGroupMembership() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership = groupDao.addMembership(group, id, "author");
+		GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author");
 
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership);
 	}
 	
+	@Test
+	public void createGroupMembership_oneWay() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
+		Group group = groupDao.createGroup();
+		groupDao.addMembershipOneWay(group, id, "author");
+		dbInstance.commit();
+	}
+	
 	@Test
 	public void createGroupMembership_v2() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership = groupDao.addMembership(group, id, "author");
+		GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author");
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership);
@@ -86,11 +94,25 @@ public class GroupDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, members.size());
 	}
 	
+	@Test
+	public void createGroupMembership_oneWay_v2() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
+		Group group = groupDao.createGroup();
+		groupDao.addMembershipOneWay(group, id, "author");
+		dbInstance.commitAndCloseSession();
+		
+		GroupImpl loadedGroup = (GroupImpl)groupDao.loadGroup(group.getKey());
+		Assert.assertNotNull(loadedGroup);
+		Set<GroupMembership> members = loadedGroup.getMembers();
+		Assert.assertNotNull(members);
+		Assert.assertEquals(1, members.size());
+	}
+	
 	@Test
 	public void getMemberships() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership = groupDao.addMembership(group, id, "author");
+		GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author");
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership);
@@ -101,13 +123,25 @@ public class GroupDAOTest extends OlatTestCase {
 		Assert.assertNotNull(members);
 		Assert.assertEquals(1, members.size());
 	}
+	
+	@Test
+	public void getMemberships_oneWay() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-");
+		Group group = groupDao.createGroup();
+		groupDao.addMembershipOneWay(group, id, "author");
+		dbInstance.commitAndCloseSession();
+		
+		List<GroupMembership> members = groupDao.getMemberships(group, "author");
+		Assert.assertNotNull(members);
+		Assert.assertEquals(1, members.size());
+	}
 
 	@Test
 	public void hasRole() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-2-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-2b-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership = groupDao.addMembership(group, id, "author");
+		GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author");
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership);
@@ -126,7 +160,7 @@ public class GroupDAOTest extends OlatTestCase {
 	public void getMembers() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-3-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership = groupDao.addMembership(group, id, "author");
+		GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author");
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership);
@@ -143,9 +177,9 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-5-");
 		Identity id3 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-6-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot");
-		GroupMembership membership3 = groupDao.addMembership(group, id3, "copilot");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot");
+		GroupMembership membership3 = groupDao.addMembershipTwoWay(group, id3, "copilot");
 		dbInstance.commit();
 		
 		Assert.assertNotNull(membership1);
@@ -162,8 +196,8 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot");
 		Assert.assertNotNull(membership1);
 		Assert.assertNotNull(membership2);
 		dbInstance.commitAndCloseSession();
@@ -189,9 +223,9 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot");
-		GroupMembership membership2alt = groupDao.addMembership(group, id2, "commander");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot");
+		GroupMembership membership2alt = groupDao.addMembershipTwoWay(group, id2, "commander");
 		Assert.assertNotNull(membership1);
 		Assert.assertNotNull(membership2);
 		Assert.assertNotNull(membership2alt);
@@ -226,8 +260,8 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot");
 		Assert.assertNotNull(membership1);
 		Assert.assertNotNull(membership2);
 		dbInstance.commitAndCloseSession();
@@ -250,8 +284,8 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-12-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-13-");
 		Group group = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group, id2, "copilot");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "copilot");
 		Assert.assertNotNull(membership1);
 		Assert.assertNotNull(membership2);
 		dbInstance.commitAndCloseSession();
@@ -278,14 +312,14 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-9-");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-10-");
 		Group group1 = groupDao.createGroup();
-		GroupMembership membership1 = groupDao.addMembership(group1, id1, "pilot");
-		GroupMembership membership2 = groupDao.addMembership(group1, id2, "pilot");
+		GroupMembership membership1 = groupDao.addMembershipTwoWay(group1, id1, "pilot");
+		GroupMembership membership2 = groupDao.addMembershipTwoWay(group1, id2, "pilot");
 		Assert.assertNotNull(membership1);
 		Assert.assertNotNull(membership2);
 		dbInstance.commitAndCloseSession();
 		Group group2 = groupDao.createGroup();
-		GroupMembership membership3 = groupDao.addMembership(group2, id1, "passanger");
-		GroupMembership membership4 = groupDao.addMembership(group2, id2, "passanger");
+		GroupMembership membership3 = groupDao.addMembershipTwoWay(group2, id1, "passanger");
+		GroupMembership membership4 = groupDao.addMembershipTwoWay(group2, id2, "passanger");
 		Assert.assertNotNull(membership3);
 		Assert.assertNotNull(membership4);
 		dbInstance.commitAndCloseSession();
@@ -359,7 +393,7 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-");
 		Group group = groupDao.createGroup();
 		String role = "hasGrant-role";
-		groupDao.addMembership(group, id, role);
+		groupDao.addMembershipTwoWay(group, id, role);
 		OLATResource resource = JunitTestHelper.createRandomResource();
 		groupDao.addGrant(group, role, "hasGrant-perm", resource);
 		dbInstance.commitAndCloseSession();
@@ -373,7 +407,7 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-");
 		Group group = groupDao.createGroup();
 		String role = "getPermissions-role";
-		groupDao.addMembership(group, id, role);
+		groupDao.addMembershipTwoWay(group, id, role);
 		OLATResource resource = JunitTestHelper.createRandomResource();
 		groupDao.addGrant(group, role, "getPermissions-perm", resource);
 		dbInstance.commitAndCloseSession();
@@ -389,9 +423,9 @@ public class GroupDAOTest extends OlatTestCase {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-");
 		Group group = groupDao.createGroup();
 		String role1 = "getPermissions-role-1";
-		groupDao.addMembership(group, id, role1);
+		groupDao.addMembershipTwoWay(group, id, role1);
 		String role2 = "getPermissions-role-2";
-		groupDao.addMembership(group, id, role2);
+		groupDao.addMembershipTwoWay(group, id, role2);
 		OLATResource resource = JunitTestHelper.createRandomResource();
 		groupDao.addGrant(group, role1, "getPermissions-perm-1", resource);
 		groupDao.addGrant(group, role2, "getPermissions-perm-2", resource);
@@ -408,8 +442,8 @@ public class GroupDAOTest extends OlatTestCase {
 	public void addRemoveGrant() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("addremove-1-");
 		Group group = groupDao.createGroup();
-		groupDao.addMembership(group, id, "addremove-1");
-		groupDao.addMembership(group, id, "addremove-2");
+		groupDao.addMembershipTwoWay(group, id, "addremove-1");
+		groupDao.addMembershipTwoWay(group, id, "addremove-2");
 		OLATResource resource = JunitTestHelper.createRandomResource();
 		groupDao.addGrant(group, "addremove-1", "addremove-1-perm", resource);
 		groupDao.addGrant(group, "addremove-2", "addremove-2-perm", resource);
@@ -436,8 +470,8 @@ public class GroupDAOTest extends OlatTestCase {
 	public void addRemoveGrants() {
 		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("addremove-1-");
 		Group group = groupDao.createGroup();
-		groupDao.addMembership(group, id, "addremove-1");
-		groupDao.addMembership(group, id, "addremove-2");
+		groupDao.addMembershipTwoWay(group, id, "addremove-1");
+		groupDao.addMembershipTwoWay(group, id, "addremove-2");
 		OLATResource resource = JunitTestHelper.createRandomResource();
 		groupDao.addGrant(group, "addremove-1", "addremove-1-perm", resource);
 		groupDao.addGrant(group, "addremove-1", "addremove-11-perm", resource);
diff --git a/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java b/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java
index 0bc285744fa416f59ae1febdad118144687059ae..9e46d1b9a0a3eb4178c9a427a867ae757c91500d 100644
--- a/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java
+++ b/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java
@@ -33,12 +33,14 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
+import java.util.Random;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.GroupRoles;
@@ -58,6 +60,11 @@ import org.olat.core.id.context.BusinessControl;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.logging.activity.OlatResourceableType;
+import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
+import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller;
+import org.olat.core.util.SessionInfo;
+import org.olat.core.util.UserSession;
 import org.olat.core.util.Util;
 import org.olat.course.CourseFactory;
 import org.olat.course.CourseModule;
@@ -75,6 +82,7 @@ import org.olat.resource.OLATResource;
 import org.olat.resource.OLATResourceManager;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
+import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -249,23 +257,30 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win
 	
 	@Test
 	public void testConcurrentEnrollmentWithWaitingList() {
-		List<Identity> ids = new ArrayList<Identity>(30);	
-		for(int i=0; i<30; i++) {
+		int NUM_OF_USERS = 30;
+		List<Identity> ids = new ArrayList<Identity>(NUM_OF_USERS);	
+		for(int i=0; i<NUM_OF_USERS; i++) {
 			Identity id = JunitTestHelper.createAndPersistIdentityAsUser("enroll-a-" + i + "-" + UUID.randomUUID().toString());
 			ids.add(id);
 		}
 		
 		ENCourseNode enNode = new ENCourseNode();
-		OLATResource resource = resourceManager.createOLATResourceInstance(CourseModule.class);
-		RepositoryEntry addedEntry = repositoryService.create("Ayanami", "-", "Enrollment test course 2", "A JUnit course", resource);
+		
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("enroller");
+		RepositoryEntry addedEntry = JunitTestHelper.deployBasicCourse(author);
 		CourseEnvironment cenv = CourseFactory.createCourse(addedEntry, "Test-Enroll", "Test", "Test enrollment with concurrent users").getCourseEnvironment();
 		BusinessGroup group = businessGroupService.createBusinessGroup(id1, "Enrollment", "Enroll", new Integer(1), new Integer(10), true, false, null);
 		Assert.assertNotNull(group);
 		dbInstance.commitAndCloseSession();
 
 		final CountDownLatch doneSignal = new CountDownLatch(ids.size());
+		EnrollThread[] threads = new EnrollThread[NUM_OF_USERS];
+		int t = 0;
 		for(Identity id:ids) {
-			EnrollThread thread = new EnrollThread(id, group, enNode, cenv, doneSignal);
+			threads[t++] = new EnrollThread(id, addedEntry, group, enNode, cenv, doneSignal);
+		}
+		
+		for(EnrollThread thread:threads) {
 			thread.start();
 		}
 		
@@ -275,6 +290,8 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win
 		} catch (InterruptedException e) {
 			fail("" + e.getMessage());
 		}
+		
+		dbInstance.commitAndCloseSession();
 
 		List<Identity> enrolledIds = businessGroupService.getMembers(group, GroupRoles.participant.name());
 		Assert.assertNotNull(enrolledIds);
@@ -284,17 +301,91 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win
 		Assert.assertNotNull(waitingIds);
 		Assert.assertEquals(ids.size() - 10, waitingIds.size());
 	}
+	
+	
+	@Test @Ignore
+	public void testConcurrentEnrollmentWithWaitingList_big() {
+		List<Identity> ids = new ArrayList<Identity>(100);	
+		for(int i=0; i<100; i++) {
+			Identity id = JunitTestHelper.createAndPersistIdentityAsUser("enroll-a-" + i + "-" + UUID.randomUUID().toString());
+			ids.add(id);
+		}
+		
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("enroller");
+		RepositoryEntry addedEntry = JunitTestHelper.deployBasicCourse(author);
+		
+		ENCourseNode enNode1 = new ENCourseNode();
+		ENCourseNode enNode2 = new ENCourseNode();
+		ENCourseNode enNode3 = new ENCourseNode();
+		ENCourseNode enNode4 = new ENCourseNode();
+		ENCourseNode enNode5 = new ENCourseNode();
+
+		CourseEnvironment cenv = CourseFactory.loadCourse(addedEntry).getCourseEnvironment();
+		BusinessGroup group1 = businessGroupService.createBusinessGroup(author, "Enrollment 1", "Enroll 1", new Integer(1), new Integer(8), true, true, addedEntry);
+		BusinessGroup group2 = businessGroupService.createBusinessGroup(author, "Enrollment 2", "Enroll 2", new Integer(1), new Integer(10), true, true, addedEntry);
+		BusinessGroup group3 = businessGroupService.createBusinessGroup(author, "Enrollment 3", "Enroll 3", new Integer(1), new Integer(4), true, true, addedEntry);
+		BusinessGroup group4 = businessGroupService.createBusinessGroup(author, "Enrollment 4", "Enroll 4", new Integer(1), new Integer(10), true, true, addedEntry);
+		BusinessGroup group5 = businessGroupService.createBusinessGroup(author, "Enrollment 5", "Enroll 5", new Integer(1), new Integer(9), true, true, addedEntry);
+		dbInstance.commitAndCloseSession();
+
+		EnrollThread[] threads = new EnrollThread[100];
+		
+		final CountDownLatch doneSignal = new CountDownLatch(ids.size());
+		int t = 0;
+		for(int i=0; i<30; i++) {
+			threads[t++] = new EnrollThread(ids.get(i), addedEntry, group1, enNode1, cenv, doneSignal);
+		}
+		for(int i=30; i<50; i++) {
+			threads[t++] = new EnrollThread(ids.get(i), addedEntry, group2, enNode2, cenv, doneSignal);
+		}
+		for(int i=50; i<70; i++) {
+			threads[t++] = new EnrollThread(ids.get(i), addedEntry, group3, enNode3, cenv, doneSignal);
+		}
+		for(int i=70; i<90; i++) {
+			threads[t++] = new EnrollThread(ids.get(i), addedEntry, group4, enNode4, cenv, doneSignal);
+		}
+		for(int i=90; i<100; i++) {
+			threads[t++] = new EnrollThread(ids.get(i), addedEntry, group5, enNode5, cenv, doneSignal);
+		}
+		
+		for(EnrollThread thread:threads) {
+			thread.start();
+		}
+
+		try {
+			boolean interrupt = doneSignal.await(360, TimeUnit.SECONDS);
+			assertTrue("Test takes too long (more than 10s)", interrupt);
+		} catch (InterruptedException e) {
+			fail("" + e.getMessage());
+		}
+		
+		dbInstance.commitAndCloseSession();
+
+		List<Identity> enrolled_1_Ids = businessGroupService.getMembers(group1, GroupRoles.participant.name());
+		Assert.assertEquals(8, enrolled_1_Ids.size());
+		List<Identity> enrolled_2_Ids = businessGroupService.getMembers(group2, GroupRoles.participant.name());
+		Assert.assertEquals(10, enrolled_2_Ids.size());
+		List<Identity> enrolled_3_Ids = businessGroupService.getMembers(group3, GroupRoles.participant.name());
+		Assert.assertEquals(4, enrolled_3_Ids.size());
+		List<Identity> enrolled_4_Ids = businessGroupService.getMembers(group4, GroupRoles.participant.name());
+		Assert.assertEquals(10, enrolled_4_Ids.size());
+		List<Identity> enrolled_5_Ids = businessGroupService.getMembers(group5, GroupRoles.participant.name());
+		Assert.assertEquals(9, enrolled_5_Ids.size());
+	}
 
 	private class EnrollThread extends Thread {
 		private final ENCourseNode enNode;
 		private final Identity identity;
 		private final CourseEnvironment cenv;
 		private final BusinessGroup group;
+		private final RepositoryEntry courseEntry;
 		private final CountDownLatch doneSignal;
 		
-		public EnrollThread(Identity identity, BusinessGroup group, ENCourseNode enNode, CourseEnvironment cenv, CountDownLatch doneSignal) {
+		public EnrollThread(Identity identity, RepositoryEntry courseEntry, BusinessGroup group,
+				ENCourseNode enNode, CourseEnvironment cenv, CountDownLatch doneSignal) {
 			this.enNode = enNode;
 			this.group = group;
+			this.courseEntry = courseEntry;
 			this.identity = identity;
 			this.cenv = cenv;
 			this.doneSignal = doneSignal;
@@ -303,19 +394,30 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win
 		@Override
 		public void run() {
 			try {
-				sleep(10);
+				UserSession session = new UserSession();
+				session.setIdentity(identity);
+				session.setSessionInfo(new SessionInfo(identity.getKey(), identity.getName()));
+				ThreadLocalUserActivityLoggerInstaller.initUserActivityLogger(session);
+				
 				IdentityEnvironment ienv = new IdentityEnvironment();
 				ienv.setIdentity(identity);
 				UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, cenv);
 				CoursePropertyManager coursePropertyManager = userCourseEnv.getCourseEnvironment().getCoursePropertyManager();
 				CourseGroupManager courseGroupManager = userCourseEnv.getCourseEnvironment().getCourseGroupManager();
 				
+				ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(courseEntry.getOlatResource(), OlatResourceableType.course));
+				ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(enNode));
+				ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(group));
+
+				sleep(Math.round(new Random().nextDouble() * 100l));
 				enrollmentManager.doEnroll(identity, JunitTestHelper.getUserRoles(), group, enNode, coursePropertyManager, EnrollmentManagerConcurrentTest.this /*WindowControl mock*/, testTranslator,
 						new ArrayList<Long>()/*enrollableGroupNames*/, new ArrayList<Long>()/*enrollableAreaNames*/, courseGroupManager);
-				DBFactory.getInstance().commitAndCloseSession();
+				DBFactory.getInstance().commit();
 			} catch (Exception e) {
 				log.error("", e);
 			}	finally {
+				ThreadLocalUserActivityLoggerInstaller.resetUserActivityLogger();
+				DBFactory.getInstance().commitAndCloseSession();
 				doneSignal.countDown();
 			}
 		}
diff --git a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
index 879d8c41cdf5ad7a174dd39f38d68d653b16d1e5..5a695ccd9bb4db274e2a51af87ec9cdc54ff4c37 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
@@ -93,7 +93,7 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase {
 		dbInstance.commitAndCloseSession();
 		
 		Group group = ((BusinessGroupImpl)businessGroup).getBaseGroup();
-		groupDao.addMembership(group, coach, "coach");
+		groupDao.addMembershipTwoWay(group, coach, "coach");
 		dbInstance.commitAndCloseSession();
 		
 		List<String> roles = businessGroupRelationDao.getRoles(coach, businessGroup);
@@ -582,6 +582,36 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, numOfAuthors);
 	}
 	
+	@Test
+	public void countRoles() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-" + UUID.randomUUID().toString());
+		Identity test = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth");
+		BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false);
+		businessGroupRelationDao.addRole(author, group, GroupRoles.coach.name());
+		businessGroupRelationDao.addRole(test, group, GroupRoles.coach.name());
+		dbInstance.commitAndCloseSession();
+		
+		int numOfCoachs = businessGroupRelationDao.countRoles(group, GroupRoles.coach.name());
+		Assert.assertEquals(2, numOfCoachs);
+		int numOfParticipants = businessGroupRelationDao.countRoles(group, GroupRoles.participant.name());
+		Assert.assertEquals(0, numOfParticipants);
+	}
+	
+	@Test
+	public void countEnrollment() {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-" + UUID.randomUUID().toString());
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth");
+		BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false);
+		businessGroupRelationDao.addRole(author, group, GroupRoles.coach.name());
+		businessGroupRelationDao.addRole(participant1, group, GroupRoles.participant.name());
+		businessGroupRelationDao.addRole(participant2, group, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		int numOfParticipants = businessGroupRelationDao.countEnrollment(group);
+		Assert.assertEquals(2, numOfParticipants);
+	}
+	
 	@Test
 	public void loadForUpdate() {
 		BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false);
diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderDAOTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderDAOTest.java
index 9b676a38ede5797f4677067d96b04253200c42c9..38e9d318919e5d8dd2447310b12a12b0ba756600 100644
--- a/src/test/java/org/olat/modules/reminder/manager/ReminderDAOTest.java
+++ b/src/test/java/org/olat/modules/reminder/manager/ReminderDAOTest.java
@@ -35,6 +35,7 @@ import org.olat.modules.reminder.model.ReminderImpl;
 import org.olat.modules.reminder.model.ReminderInfos;
 import org.olat.modules.reminder.model.SentReminderImpl;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryService;
 import org.olat.repository.manager.RepositoryEntryRelationDAO;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -53,6 +54,8 @@ public class ReminderDAOTest extends OlatTestCase {
 	@Autowired
 	private ReminderDAO reminderDao;
 	@Autowired
+	private RepositoryService repositoryService;
+	@Autowired
 	private RepositoryEntryRelationDAO repositoryEntryRelationDao;
 	
 	@Test
@@ -140,6 +143,34 @@ public class ReminderDAOTest extends OlatTestCase {
 		}
 		Assert.assertTrue(found);	
 	}
+
+	@Test
+	public void getReminders_repositoryEntry_softDeleted() {
+		//create and reminder and an identity
+		Identity creator = JunitTestHelper.createAndPersistIdentityAsRndUser("creator-rem-12");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		Reminder reminder = reminderDao.createReminder(entry, creator);
+		reminder.setConfiguration("<rules></rules>");
+		reminder.setDescription("Reminder - 12");
+		reminder.setEmailBody("Hello, I'm deleted");
+		Reminder savedReminder = reminderDao.save(reminder);
+		Assert.assertNotNull(savedReminder);
+		dbInstance.commitAndCloseSession();
+		
+		//check that we found the reminder
+		List<Reminder> loadedReminders = reminderDao.getReminders(new Date());
+		Assert.assertNotNull(loadedReminders);
+		Assert.assertTrue(loadedReminders.contains(savedReminder));
+		
+		// delete the resource
+		repositoryService.deleteSoftly(entry, creator, false);
+		dbInstance.commitAndCloseSession();
+		
+		// check we don't found the reminder
+		List<Reminder> reloadedReminders = reminderDao.getReminders(new Date());
+		Assert.assertNotNull(reloadedReminders);
+		Assert.assertFalse(reloadedReminders.contains(savedReminder));
+	}
 	
 	@Test
 	public void getReminders_repositoryEntry() {