diff --git a/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLockManager.java b/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLockManager.java
index c51a19b46f1ecbf93570f87dcc2c0faecffdae49..b7ca02b281ebd65574bcc344f0ee4d6da9aec2bf 100644
--- a/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLockManager.java
+++ b/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLockManager.java
@@ -65,6 +65,18 @@ public class ClusterLockManager {
 			return res.get(0);
 		}
 	}
+	
+	boolean isLocked(String asset) {
+		String sb = "select alock.key from org.olat.commons.coordinate.cluster.lock.LockImpl as alock where alock.asset=:asset";
+
+		List<Long> res = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Long.class)
+				.setParameter("asset", asset)
+				.setFirstResult(0)
+				.setMaxResults(1)
+				.getResultList();
+		return res != null && res.size() > 0 && res.get(0) != null && res.get(0).longValue() > 0;
+	}
 		
 	LockImpl createLockImpl(String asset, Identity owner) {
 		log.info("createLockImpl: "+asset+" by "+ owner);
diff --git a/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLocker.java b/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLocker.java
index a7ef668ffdc7cb89b3db5a9294be9f3838837901..0fff2897b4b2d45f41ffa01f042de2cabf145364 100644
--- a/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLocker.java
+++ b/src/main/java/org/olat/commons/coordinate/cluster/lock/ClusterLocker.java
@@ -167,13 +167,20 @@ public class ClusterLocker implements Locker, GenericEventListener {
 		}
 	}
 	
-
+	@Override
 	public boolean isLocked(OLATResourceable ores, String locksubkey) {
+		final String asset = OresHelper.createStringRepresenting(ores, locksubkey);
+		return clusterLockManager.isLocked(asset);
+	}
+
+	@Override
+	public Identity getLockedBy(OLATResourceable ores, String locksubkey) {
 		final String asset = OresHelper.createStringRepresenting(ores, locksubkey);
 		LockImpl li = clusterLockManager.findLock(asset);
-		return (li != null);
+		return li == null ? null : li.getOwner();
 	}
 
+	@Override
 	public void releaseLock(LockResult lockResult) {
 		// if the lock has not been acquired, then nothing is to be released -
 		// return silently to make cleaning up easier
diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
index 010853e76e6c47ec37cfd0475e250a32c89d4bf1..5cd91341412701e6325049686fb85b1d5b04790c 100644
--- a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
+++ b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java
@@ -182,11 +182,11 @@ public class HTMLEditorController extends FormBasicController {
 		if (fileLeaf instanceof LocalFileImpl) {
 			// Cast to LocalFile necessary because the VFSItem is missing some
 			// ID mechanism that identifies an item within the system
-			OLATResourceable lockResourceable = OresHelper.createOLATResourceableTypeWithoutCheck(fileLeaf.toString());
+			OLATResourceable lockResourceable = createLockResourceable(fileLeaf);
 			// OLAT-5066: the use of "fileName" gives users the (false) impression that the file they wish to access
 			// is already locked by someone else. Since the lock token must be smaller than 50 characters we us an 
 			// MD5 hash of the absolute file path which will always be 32 characters long and virtually unique.
-			String lockToken = Encoder.md5hash(getFileDebuggingPath(bContainer, relFilePath));
+			String lockToken = createLockToken(bContainer, relFilePath);
 			lock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockResourceable, getIdentity(), lockToken);
 			VelocityContainer vc = (VelocityContainer) flc.getComponent();
 			if (!lock.isSuccess()) {
@@ -467,6 +467,20 @@ public class HTMLEditorController extends FormBasicController {
 		htmlElement.setNewOriginalValue(content);
 		return true;
 	}
+	
+	protected static OLATResourceable createLockResourceable(VFSLeaf fileLeaf) {
+		return OresHelper.createOLATResourceableTypeWithoutCheck(fileLeaf.toString());
+	}
+	
+	/**
+	 * OLAT-5066: the use of "fileName" gives users the (false) impression that the file they wish to access
+	 * is already locked by someone else. Since the lock token must be smaller than 50 characters we us an 
+	 * MD5 hash of the absolute file path which will always be 32 characters long and virtually unique.
+	 * @return
+	 */
+	protected static String createLockToken(VFSContainer container, String relFilePath) {
+		return Encoder.md5hash(getFileDebuggingPath(container, relFilePath));
+	}
 
 	
 	/**
@@ -477,7 +491,7 @@ public class HTMLEditorController extends FormBasicController {
 	 * @param relPath
 	 * @return
 	 */
-	private String getFileDebuggingPath(VFSContainer root, String relPath) {
+	private static String getFileDebuggingPath(VFSContainer root, String relPath) {
 		String path = relPath;
 		VFSItem item = root.resolve(relPath);
 		if (item instanceof LocalFileImpl) {
diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java b/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java
index b1d319a80aae8a28d21b329f746c0401b93befea..5452e4f364c5c28ec3f97b6f36333f6383da8b1b 100644
--- a/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java
+++ b/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java
@@ -29,7 +29,9 @@ package org.olat.core.commons.editor.htmleditor;
 import org.olat.core.commons.controllers.linkchooser.CustomLinkTreeModel;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSLeaf;
 
 /**
  * Description: The WYSIWYGFactory provides a full-fledged WYSIWYG HTML editor
@@ -157,4 +159,12 @@ public class WysiwygFactory {
 		fileContent.append(HTMLEditorController.CLOSE_BODY_HTML);
 		return fileContent.toString();
 	}
+	
+	public static OLATResourceable createLockResourceable(VFSLeaf fileLeaf) {
+		return HTMLEditorController.createLockResourceable(fileLeaf);
+	}
+	
+	public static String createLockToken(VFSContainer container, String relFilePath) {
+		return HTMLEditorController.createLockToken(container, relFilePath);
+	}
 }
diff --git a/src/main/java/org/olat/core/util/coordinate/Locker.java b/src/main/java/org/olat/core/util/coordinate/Locker.java
index 9d777b3c08a8f75ff76f709896f92af9e54562b3..8b7423cae2006b39b85bfbfec261806ff7f675c4 100644
--- a/src/main/java/org/olat/core/util/coordinate/Locker.java
+++ b/src/main/java/org/olat/core/util/coordinate/Locker.java
@@ -66,6 +66,14 @@ public interface Locker {
 	 *         someone (returns true even if locked by "myself")
 	 */
 	public boolean isLocked(OLATResourceable ores, String locksubkey);
+	
+	/**
+	 * 
+	 * @param ores
+	 * @param locksubkey
+	 * @return The identity which lock the resource or null.
+	 */
+	public Identity getLockedBy(OLATResourceable ores, String locksubkey);
 		
 	
 	/**
diff --git a/src/main/java/org/olat/course/nodes/gta/GTAManager.java b/src/main/java/org/olat/course/nodes/gta/GTAManager.java
index 9c8acb2737c97cbbebdf4063004ce0962758a3bc..f7143b53f7882fd595f505610512fdee78496d04 100644
--- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java
+++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java
@@ -31,7 +31,7 @@ import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.model.Membership;
 import org.olat.course.nodes.gta.model.Solution;
 import org.olat.course.nodes.gta.model.TaskDefinition;
-import org.olat.course.nodes.gta.ui.SubmitEvent;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupRef;
diff --git a/src/main/java/org/olat/course/nodes/gta/TaskHelper.java b/src/main/java/org/olat/course/nodes/gta/TaskHelper.java
index 5b1fe6c4ac6cae4d1bad381df03785e9f1512a78..789657f66decb2b2ff6baf50f928edaf1e512e40 100644
--- a/src/main/java/org/olat/course/nodes/gta/TaskHelper.java
+++ b/src/main/java/org/olat/course/nodes/gta/TaskHelper.java
@@ -24,8 +24,16 @@ import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.Locale;
 
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.commons.editor.htmleditor.WysiwygFactory;
 import org.olat.core.gui.control.generic.iframe.DeliveryOptions;
+import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.io.SystemFileFilter;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.user.UserManager;
 
 /**
  * 
@@ -88,6 +96,36 @@ public class TaskHelper {
 		return false;
 	}
 	
-	
+	public static String getDocumentsLocked(VFSContainer documentsContainer, File[] documents) {
+		StringBuilder sb = new StringBuilder();
+		
+		boolean locked = false;
+		for(File submittedDocument:documents) {
+			VFSLeaf fileLeaf = (VFSLeaf)documentsContainer.resolve(submittedDocument.getName());
+			OLATResourceable lockResourceable = WysiwygFactory.createLockResourceable(fileLeaf);
+			String lockTocken = WysiwygFactory.createLockToken(documentsContainer, submittedDocument.getName());
+			if(CoordinatorManager.getInstance().getCoordinator().getLocker()
+				.isLocked(lockResourceable, lockTocken)) {
+
+				locked |= true;
+				Identity lockedBy = CoordinatorManager.getInstance().getCoordinator()
+						.getLocker().getLockedBy(lockResourceable, lockTocken);
+				
+				String fullname = "???";
+				if(lockedBy != null) {
+					fullname = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(lockedBy);
+				}
+				if(sb.length() > 0) {
+					sb.append(", ");
+				}
+				sb.append(fullname);
+			}
+		}
+		
+		if(locked) {
+			return sb.toString();
+		}
+		return null;
+	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
index 443f385e4c5c1c30ebd5c300e29b068f4f9262f5..683f87fb937a10f09b81a4767cc5ba7560b18826 100644
--- a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
+++ b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
@@ -64,7 +64,7 @@ import org.olat.course.nodes.gta.model.TaskDefinition;
 import org.olat.course.nodes.gta.model.TaskDefinitionList;
 import org.olat.course.nodes.gta.model.TaskImpl;
 import org.olat.course.nodes.gta.model.TaskListImpl;
-import org.olat.course.nodes.gta.ui.SubmitEvent;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupRef;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java
index 97821d45233f574e063dc3d1f1392bfe00bb90c8..b287b95de8fe5e09dbbd531b9871f56d6ae71bb4 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java
@@ -34,8 +34,12 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.coordinate.CoordinatorManager;
+import org.olat.core.util.event.GenericEventListener;
+import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
@@ -48,6 +52,7 @@ import org.olat.course.nodes.gta.GTAType;
 import org.olat.course.nodes.gta.Task;
 import org.olat.course.nodes.gta.TaskList;
 import org.olat.course.nodes.gta.TaskProcess;
+import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
@@ -64,7 +69,7 @@ import org.springframework.beans.factory.annotation.Autowired;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public abstract class GTAAbstractController extends BasicController {
+public abstract class GTAAbstractController extends BasicController implements GenericEventListener {
 	
 	protected VelocityContainer mainVC;
 
@@ -87,6 +92,8 @@ public abstract class GTAAbstractController extends BasicController {
 	
 	protected final boolean businessGroupTask;
 	
+	protected final OLATResourceable taskListEventResource;
+	
 	protected GTAStepPreferences stepPreferences;
 	
 	private ContextualSubscriptionController contextualSubscriptionCtr;
@@ -146,15 +153,34 @@ public abstract class GTAAbstractController extends BasicController {
 			stepPreferences = new GTAStepPreferences();
 		}
 		
+		taskListEventResource = OresHelper.createOLATResourceableInstance("GTaskList", taskList.getKey());
+		CoordinatorManager.getInstance().getCoordinator()
+			.getEventBus().registerFor(this, getIdentity(), taskListEventResource);
+		
 		initContainer(ureq);
 		process(ureq);
 	}
 
 	@Override
 	protected void doDispose() {
-		//
+		CoordinatorManager.getInstance().getCoordinator()
+			.getEventBus().deregisterFor(this, taskListEventResource);
+	}
+
+	@Override
+	public void event(Event event) {
+		if(event instanceof TaskMultiUserEvent) {
+			TaskMultiUserEvent ste = (TaskMultiUserEvent)event;
+			if(!getIdentity().getKey().equals(ste.getEmitterKey())
+					&& ((assessedGroup != null && assessedGroup.getKey().equals(ste.getForGroupKey()))
+							|| (assessedIdentity != null && assessedIdentity.getKey().equals(ste.getForIdentityKey())))) {
+				processEvent(ste);
+			}
+		}
 	}
 	
+	protected abstract void processEvent(TaskMultiUserEvent event);
+
 	protected abstract void initContainer(UserRequest ureq);
 	
 	protected final void process(UserRequest ureq) {
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java
index d609ff76cf3a372d5dae1b0b138d7aaf1ac38b9b..9a24736a4a72427402a6a2a136a5ac4f92a86b45 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java
@@ -37,6 +37,7 @@ import org.olat.core.id.Roles;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.GTAType;
+import org.olat.course.nodes.gta.ui.events.SelectBusinessGroupEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java
index 324842775c4b9d53871bb4ce4158bbc7af163f14..a327e916bea1072ed9b1858844061677b5d4dc5c 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java
@@ -37,6 +37,7 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle
 import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.id.Identity;
+import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.mail.ContactList;
 import org.olat.core.util.mail.ContactMessage;
 import org.olat.core.util.vfs.VFSContainer;
@@ -46,6 +47,8 @@ import org.olat.course.nodes.gta.Task;
 import org.olat.course.nodes.gta.TaskHelper;
 import org.olat.course.nodes.gta.TaskProcess;
 import org.olat.course.nodes.gta.model.TaskDefinition;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
+import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
@@ -426,6 +429,11 @@ public class GTACoachController extends GTAAbstractController {
 		}
 	}
 
+	@Override
+	protected void processEvent(TaskMultiUserEvent event) {
+		//
+	}
+
 	@Override
 	protected void event(UserRequest ureq, Component source, Event event) {
 		if(reviewedButton == source) {
@@ -600,6 +608,11 @@ public class GTACoachController extends GTAAbstractController {
 		task = gtaManager.updateTask(task, review);
 		showInfo("run.documents.successfully.submitted");
 		
+		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUMBIT_TASK,
+				assessedIdentity, assessedGroup, getIdentity());
+		CoordinatorManager.getInstance().getCoordinator().getEventBus()
+			.fireEventToListenersOf(event, taskListEventResource);
+		
 		gtaManager.log("Collect", "collect documents", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 		
 		cleanUpProcess();
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java
index faf49d23aaf29d7d97eb332e5d9750dfc32295ee..575e39e83844dc23d6037614034c2601630802d6 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java
@@ -48,6 +48,7 @@ import org.olat.course.nodes.gta.GTAType;
 import org.olat.course.nodes.gta.Task;
 import org.olat.course.nodes.gta.TaskHelper;
 import org.olat.course.nodes.gta.TaskProcess;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java
index ee787002bfa3ba50b52e4492c98dd4d78c85611a..1e2f39962bf03e181a7904e2bd85bb196888256b 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java
@@ -40,6 +40,8 @@ import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.GTAType;
+import org.olat.course.nodes.gta.ui.events.SelectBusinessGroupEvent;
+import org.olat.course.nodes.gta.ui.events.SelectIdentityEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java
index 225655517d6c4bcef2af532336960cf5dc476642..bd6d46574976fbaa6ad17500f549868b5a1a8179 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java
@@ -40,6 +40,7 @@ import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.TaskLight;
 import org.olat.course.nodes.gta.ui.CoachGroupsTableModel.CGCols;
+import org.olat.course.nodes.gta.ui.events.SelectBusinessGroupEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.repository.RepositoryEntry;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java
index 881b80389bb5cb314de8766f864cb770990f1b6b..f81ea73778c0c0a84f1fa0504d85f0e4644fcf80 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java
@@ -52,6 +52,7 @@ import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.TaskLight;
 import org.olat.course.nodes.gta.ui.CoachParticipantsTableModel.CGCols;
+import org.olat.course.nodes.gta.ui.events.SelectIdentityEvent;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java
index f6318833e78ede3c54c3911c57cd88bda3a14f34..6fc760aa88266cc1a2783f78a4a933b4f25b2c0c 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java
@@ -41,6 +41,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.io.SystemFilenameFilter;
 import org.olat.core.util.mail.MailBundle;
 import org.olat.core.util.mail.MailContext;
@@ -57,6 +58,8 @@ import org.olat.course.nodes.gta.Task;
 import org.olat.course.nodes.gta.TaskHelper;
 import org.olat.course.nodes.gta.TaskProcess;
 import org.olat.course.nodes.gta.model.TaskDefinition;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
+import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent;
 import org.olat.course.nodes.ms.MSCourseNodeRunController;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
@@ -276,26 +279,35 @@ public class GTAParticipantController extends GTAAbstractController {
 	private void doConfirmSubmit(UserRequest ureq, Task task) {
 		String title = translate("run.submit.button");
 		String text;
+		File[] submittedDocuments;
+		VFSContainer documentsContainer;
 		if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
+			documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, assessedGroup);
 			File documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedGroup);
-			File[] submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
+			submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
 			if(submittedDocuments.length == 0) {
 				text = "<div class='o_warning'>" + translate("run.submit.confirm.warning.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) }) + "</div>";
 			} else {
 				text = translate("run.submit.confirm.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) });
 			}
 		} else {
+			documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, getIdentity());
 			File documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, getIdentity());
-			File[] submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
+			submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
 			if(submittedDocuments.length == 0) {
 				text = "<div class='o_warning'>" + translate("run.submit.confirm.warning") + "</div>";
 			} else {
 				text = translate("run.submit.confirm");
 			}
 		}
-
-		confirmSubmitDialog = activateOkCancelDialog(ureq, title, text, confirmSubmitDialog);
-		confirmSubmitDialog.setUserObject(task);
+		
+		String lockedBy = TaskHelper.getDocumentsLocked(documentsContainer, submittedDocuments);
+		if(lockedBy != null) {
+			showWarning("warning.submit.documents.edited", lockedBy);
+		} else {
+			confirmSubmitDialog = activateOkCancelDialog(ureq, title, text, confirmSubmitDialog);
+			confirmSubmitDialog.setUserObject(task);
+		}
 	}
 	
 	private void doSubmitDocuments(UserRequest ureq, Task task) {
@@ -303,6 +315,11 @@ public class GTAParticipantController extends GTAAbstractController {
 		task = gtaManager.updateTask(task, review);
 		showInfo("run.documents.successfully.submitted");
 		
+		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUMBIT_TASK,
+				assessedIdentity, assessedGroup, getIdentity());
+		CoordinatorManager.getInstance().getCoordinator().getEventBus()
+			.fireEventToListenersOf(event, taskListEventResource);
+		
 		gtaManager.log("Submit", "submit documents", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 		
 		cleanUpProcess();
@@ -315,8 +332,6 @@ public class GTAParticipantController extends GTAAbstractController {
 		}
 	}
 	
-	
-	
 	private void doSubmissionEmail() {
 		String body = config.getStringValue(GTACourseNode.GTASK_SUBMISSION_TEXT);
 		if(StringHelper.containsNonWhitespace(body)) {
@@ -429,7 +444,7 @@ public class GTAParticipantController extends GTAAbstractController {
 	private void setRevisionsAndCorrections(UserRequest ureq, Task task) {
 		if(task.getRevisionLoop() > 0) {
 			revisionDocumentsCtrl = new GTAParticipantRevisionAndCorrectionsController(ureq, getWindowControl(), 
-					userCourseEnv, task, gtaNode, assessedGroup);
+					userCourseEnv, task, gtaNode, assessedGroup, taskListEventResource);
 			listenTo(revisionDocumentsCtrl);
 			mainVC.put("revisionDocs", revisionDocumentsCtrl.getInitialComponent());
 			
@@ -588,6 +603,19 @@ public class GTAParticipantController extends GTAAbstractController {
 		//
 	}
 
+	@Override
+	protected void processEvent(TaskMultiUserEvent event) {
+		if(TaskMultiUserEvent.SUMBIT_TASK.equals(event.getCommand())) {
+			if(submitDocCtrl != null) {
+				submitDocCtrl.close();
+			}
+		} else if(TaskMultiUserEvent.SUBMIT_REVISION.equals(event.getCommand())) {
+			if(revisionDocumentsCtrl != null) {
+				revisionDocumentsCtrl.close();
+			}
+		}
+	}
+
 	@Override
 	protected void event(UserRequest ureq, Component source, Event event) {
 		if(openGroupButton == source) {
@@ -635,6 +663,9 @@ public class GTAParticipantController extends GTAAbstractController {
 			if(event instanceof SubmitEvent) {
 				Task assignedTask = submitDocCtrl.getAssignedTask();
 				gtaManager.log("Submit", (SubmitEvent)event, assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
+			} else if(event == Event.DONE_EVENT) {
+				cleanUpProcess();
+				process(ureq);
 			}
 		}
 		super.event(ureq, source, event);
@@ -644,8 +675,6 @@ public class GTAParticipantController extends GTAAbstractController {
 	 * Remove all the stuff in the main velocity template, discard all controllers
 	 */
 	private void cleanUpProcess() {
-		
-		
 		if(availableTaskCtrl != null) {
 			mainVC.remove(availableTaskCtrl.getInitialComponent());
 		}
@@ -664,6 +693,7 @@ public class GTAParticipantController extends GTAAbstractController {
 		if(gradingCtrl != null) {
 			mainVC.remove(gradingCtrl.getInitialComponent());
 		}
+		
 		removeAsListenerAndDispose(availableTaskCtrl);
 		removeAsListenerAndDispose(assignedTaskCtrl);
 		removeAsListenerAndDispose(correctionsCtrl);
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java
index 06278cc82af80ce78ed2745ac4f9882a9e410a31..f39b3cb8056f018253690595c6528ca0b3a0156a 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java
@@ -36,7 +36,9 @@ import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.io.SystemFilenameFilter;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.course.CourseFactory;
@@ -49,6 +51,8 @@ import org.olat.course.nodes.gta.GTAType;
 import org.olat.course.nodes.gta.Task;
 import org.olat.course.nodes.gta.TaskHelper;
 import org.olat.course.nodes.gta.TaskProcess;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
+import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
@@ -76,6 +80,7 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 	private final BusinessGroup assessedGroup;
 	private final CourseEnvironment courseEnv;
 	private final UserCourseEnvironment assessedUserCourseEnv;
+	private final OLATResourceable taskListEventResource;
 	
 	@Autowired
 	private GTAManager gtaManager;
@@ -84,14 +89,15 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 	
 	public GTAParticipantRevisionAndCorrectionsController(UserRequest ureq, WindowControl wControl,
 			UserCourseEnvironment assessedUserCourseEnv,Task assignedTask,
-			GTACourseNode gtaNode, BusinessGroup assessedGroup) {
+			GTACourseNode gtaNode, BusinessGroup assessedGroup, OLATResourceable taskListEventResource) {
 		super(ureq, wControl);
 		this.gtaNode = gtaNode;
 		courseEnv = assessedUserCourseEnv.getCourseEnvironment();
 		this.assessedUserCourseEnv = assessedUserCourseEnv;
 		this.assignedTask = assignedTask;
 		this.assessedGroup = assessedGroup;
-		this.businessGroupTask = GTAType.group.name().equals(gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_TYPE));
+		this.taskListEventResource = taskListEventResource;
+		businessGroupTask = GTAType.group.name().equals(gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_TYPE));
 		
 		mainVC = createVelocityContainer("participant_revisions");
 		putInitialPanel(mainVC);
@@ -107,6 +113,12 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 		//
 	}
 	
+	public void close() {
+		if(uploadRevisionsCtrl != null) {
+			uploadRevisionsCtrl.close();
+		}
+	}
+	
 	private void initRevisionProcess(UserRequest ureq) {
 		List<String> revisionStepNames = new ArrayList<>();
 		mainVC.contextPut("previousRevisions", revisionStepNames);
@@ -214,6 +226,8 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 			if(event instanceof SubmitEvent) {
 				Task aTask = uploadRevisionsCtrl.getAssignedTask();
 				gtaManager.log("Revision", (SubmitEvent)event, aTask, getIdentity(), getIdentity(), assessedGroup, courseEnv, gtaNode);				
+			} else if(event == Event.DONE_EVENT) {
+				fireEvent(ureq, Event.DONE_EVENT);
 			}
 		} else if(confirmSubmitDialog == source) {
 			if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) {
@@ -241,30 +255,45 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 		int iteration = assignedTask.getRevisionLoop();
 		String title = translate("run.submit.revision.button");
 		String text;
+		File[] submittedDocuments;
+		VFSContainer documentsContainer;
 		if(GTAType.group.name().equals(gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_TYPE))) {
+			documentsContainer = gtaManager.getRevisedDocumentsContainer(courseEnv, gtaNode, iteration, assessedGroup);
 			File documentsDir = gtaManager.getRevisedDocumentsDirectory(courseEnv, gtaNode, iteration, assessedGroup);
-			File[] submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
+			submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
 			if(submittedDocuments.length == 0) {
 				text = "<div class='o_warning'>" + translate("run.submit.revision.confirm.warning.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) }) + "</div>";
 			} else {
 				text = translate("run.submit.revision.confirm.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) });
 			}
 		} else {
+			documentsContainer = gtaManager.getRevisedDocumentsContainer(courseEnv, gtaNode, iteration, getIdentity());
 			File documentsDir = gtaManager.getRevisedDocumentsDirectory(courseEnv, gtaNode, iteration, getIdentity());
-			File[] submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
+			submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
 			if(submittedDocuments.length == 0) {
 				text = "<div class='o_warning'>" + translate("run.submit.revision.confirm.warning") + "</div>";
 			} else {
 				text = translate("run.submit.revision.confirm");
 			}
 		}
-		confirmSubmitDialog = activateOkCancelDialog(ureq, title, text, confirmSubmitDialog);
+		
+		String lockedBy = TaskHelper.getDocumentsLocked(documentsContainer, submittedDocuments);
+		if(lockedBy != null) {
+			showWarning("warning.submit.documents.edited", lockedBy);
+		} else {
+			confirmSubmitDialog = activateOkCancelDialog(ureq, title, text, confirmSubmitDialog);
+		}
 	}
 	
 	private void doSubmitRevisions() {
 		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.correction);
 		gtaManager.log("Revision", "revision submitted", assignedTask, getIdentity(), getIdentity(), assessedGroup, courseEnv, gtaNode);
-
+		
+		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUBMIT_REVISION,
+				assessedGroup == null ? getIdentity() : null, assessedGroup, getIdentity());
+		CoordinatorManager.getInstance().getCoordinator().getEventBus()
+			.fireEventToListenersOf(event, taskListEventResource);
+	
 		if(businessGroupTask) {
 			List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name());
 			AssessmentManager assessmentManager = courseEnv.getAssessmentManager();
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java b/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java
index 8811ea6840d12d3b208ede56d5e983fa26532743..314c20fe8adeebfe20ae5a908f1ba693244ddf06 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/SubmitDocumentsController.java
@@ -65,6 +65,7 @@ import org.olat.core.util.vfs.VFSManager;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.Task;
+import org.olat.course.nodes.gta.ui.events.SubmitEvent;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.user.UserManager;
@@ -97,6 +98,8 @@ class SubmitDocumentsController extends FormBasicController {
 	private final ModuleConfiguration config;
 	private final SubscriptionContext subscriptionContext;
 	
+	private boolean open = true;
+	
 	@Autowired
 	private UserManager userManager;
 	@Autowired
@@ -122,12 +125,14 @@ class SubmitDocumentsController extends FormBasicController {
 	public Task getAssignedTask() {
 		return assignedTask;
 	}
-	
 
 	public boolean hasUploadDocuments() {
 		return (model.getRowCount() > 0);
 	}
-
+	
+	public void close() {
+		open = false;
+	}
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
@@ -294,11 +299,15 @@ class SubmitDocumentsController extends FormBasicController {
 	@Override
 	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
 		if(uploadDocButton == source) {
-			doOpenDocumentUpload(ureq);
+			if(checkOpen(ureq)) {
+				doOpenDocumentUpload(ureq);
+			}
 		} else if(createDocButton == source) {
-			doChooseFilename(ureq);
+			if(checkOpen(ureq)) {
+				doChooseFilename(ureq);
+			}
 		} else if(tableEl == source) {
-			if(event instanceof SelectionEvent) {
+			if(checkOpen(ureq) && event instanceof SelectionEvent) {
 				SelectionEvent se = (SelectionEvent)event;
 				SubmittedSolution row = model.getObject(se.getIndex());
 				if("delete".equals(se.getCommand())) {
@@ -316,6 +325,13 @@ class SubmitDocumentsController extends FormBasicController {
 		super.formInnerEvent(ureq, source, event);
 	}
 	
+	private boolean checkOpen(UserRequest ureq) {
+		if(open) return true;
+		showWarning("warning.tasks.submitted");
+		fireEvent(ureq, Event.DONE_EVENT);
+		return false;
+	}
+	
 	private void doView(UserRequest ureq, String filename) {
 		if(viewDocCtrl != null) return;
 		
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
index ff5b11ba2be3e9c4a66ca07b7d324c5b6d9a761d..d48d2022fc74e78678baf8d0727efbfe0adc2c55 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
@@ -260,5 +260,6 @@ warning.tasks.in.process.title=Aufgabenprozess bereits gestartet
 warning.tasks.in.process.text=Es gibt bereits Benutzer die den Aufgabenprozess gestartet haben. \u00C4nderungen an der Workflow-Konfiguration kann f\u00FCr diese Benutzer zu Problemen f\u00FChren.
 warning.tasks.in.process.delete.title=$\:warning.tasks.in.process.title
 warning.tasks.in.process.delete.text=Wollen Sie wirklich dieser Aufgabe l\u00F6schen? Es gibt bereits Benutzer die den Aufgabenprozess gestartet haben. Das kann f\u00FCr diese Benutzer zu Problemen f\u00FChren.
-
+warning.submit.documents.edited=Sie k\u00F6nnen den Aufgabe nicht abgeben, weil Dokument noch von "{0}" editiert werden.
+warning.tasks.submitted=Sie k\u00F6nnen den Aufgabe nicht mehr editieren, es wurde abgegeben.
 
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/SelectBusinessGroupEvent.java b/src/main/java/org/olat/course/nodes/gta/ui/events/SelectBusinessGroupEvent.java
similarity index 96%
rename from src/main/java/org/olat/course/nodes/gta/ui/SelectBusinessGroupEvent.java
rename to src/main/java/org/olat/course/nodes/gta/ui/events/SelectBusinessGroupEvent.java
index 515952a574d5999ded9e18932f3ef70063d0cbe8..4b2dc9b0318490d21345a1283a1e46c5f51ec919 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/SelectBusinessGroupEvent.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/events/SelectBusinessGroupEvent.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.gta.ui;
+package org.olat.course.nodes.gta.ui.events;
 
 import org.olat.core.gui.control.Event;
 import org.olat.group.BusinessGroup;
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/SelectIdentityEvent.java b/src/main/java/org/olat/course/nodes/gta/ui/events/SelectIdentityEvent.java
similarity index 96%
rename from src/main/java/org/olat/course/nodes/gta/ui/SelectIdentityEvent.java
rename to src/main/java/org/olat/course/nodes/gta/ui/events/SelectIdentityEvent.java
index 57d6da1e1fa5c95dae35c03f0ee6c0eafcbbc017..d1d35677f720a4df56ae7020b9089133809e76d2 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/SelectIdentityEvent.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/events/SelectIdentityEvent.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.gta.ui;
+package org.olat.course.nodes.gta.ui.events;
 
 import org.olat.core.gui.control.Event;
 
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/SubmitEvent.java b/src/main/java/org/olat/course/nodes/gta/ui/events/SubmitEvent.java
similarity index 97%
rename from src/main/java/org/olat/course/nodes/gta/ui/SubmitEvent.java
rename to src/main/java/org/olat/course/nodes/gta/ui/events/SubmitEvent.java
index 5072139d1d8a172506cdc7b0ad8fc056c590b57a..fdd4b7dc67e275aadbc377ed280d776a666418d3 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/SubmitEvent.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/events/SubmitEvent.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.gta.ui;
+package org.olat.course.nodes.gta.ui.events;
 
 import org.olat.core.gui.control.Event;
 
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/events/TaskMultiUserEvent.java b/src/main/java/org/olat/course/nodes/gta/ui/events/TaskMultiUserEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e14d94b1e5a891e1c2b659d1f1c8c717378b029
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/gta/ui/events/TaskMultiUserEvent.java
@@ -0,0 +1,61 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.course.nodes.gta.ui.events;
+
+import org.olat.core.id.Identity;
+import org.olat.core.util.event.MultiUserEvent;
+import org.olat.group.BusinessGroup;
+
+/**
+ * 
+ * Initial date: 31.05.2016<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class TaskMultiUserEvent extends MultiUserEvent {
+
+	private static final long serialVersionUID = 3633136669745883215L;
+	
+	public static final String SUMBIT_TASK = "submit-task";
+	public static final String SUBMIT_REVISION = "submit-revision";
+	
+	private final Long forIdentityKey;
+	private final Long forGroupKey;
+	private final Long emitterKey;
+	
+	public TaskMultiUserEvent(String cmd, Identity forIdentity, BusinessGroup forGroup, Identity emitter) {
+		super(cmd);
+		this.forGroupKey = forGroup == null ? null : forGroup.getKey();
+		this.forIdentityKey = forIdentity == null ? null : forIdentity.getKey();
+		this.emitterKey = emitter == null ? null : emitter.getKey();
+	}
+
+	public Long getForGroupKey() {
+		return forGroupKey;
+	}
+
+	public Long getForIdentityKey() {
+		return forIdentityKey;
+	}
+
+	public Long getEmitterKey() {
+		return emitterKey;
+	}
+}
diff --git a/src/test/java/org/olat/commons/coordinate/cluster/lock/LockTest.java b/src/test/java/org/olat/commons/coordinate/cluster/lock/LockTest.java
index 6b7ee934eb2c175758d678ea60bee9d5d72e1bb2..049c8f290262f8e3baed974446f931c2a64f9e4d 100644
--- a/src/test/java/org/olat/commons/coordinate/cluster/lock/LockTest.java
+++ b/src/test/java/org/olat/commons/coordinate/cluster/lock/LockTest.java
@@ -150,6 +150,10 @@ public class LockTest extends OlatTestCase {
 		LockResult res3 = cl.acquireLock(ores, ident, "abc");
 		assertTrue(res3.isSuccess());
 		dbInstance.closeSession();
+		
+		// make sure it is not locked anymore
+		boolean lo3 = cl.isLocked(ores, "abc");
+		assertTrue(lo3);
 
 		// test the admin
 		List<LockEntry> entries = cl.adminOnlyGetLockEntries();
diff --git a/src/test/java/org/olat/selenium/page/LoginPage.java b/src/test/java/org/olat/selenium/page/LoginPage.java
index e2ad4b00758251dd58086ef6eca94a27b525b9ec..8a89f4564931f26fc87c9480b8aba446210a0928 100644
--- a/src/test/java/org/olat/selenium/page/LoginPage.java
+++ b/src/test/java/org/olat/selenium/page/LoginPage.java
@@ -173,7 +173,7 @@ public class LoginPage {
 		
 		//wait until the content appears
 		By footerUserBy = By.cssSelector("#o_footer_user #o_username"); 
-		OOGraphene.waitElement(footerUserBy, 10, browser);
+		OOGraphene.waitElement(footerUserBy, 30, browser);
 		return this;
 	}
 	
diff --git a/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java b/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
index 9c69a58ac7fbdb5e2cdd179c0b4f2bffca6ccb0e..dfebe77771e60e053dffa828b8934af72d246769 100644
--- a/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
+++ b/src/test/java/org/olat/selenium/page/course/GroupTaskToCoachPage.java
@@ -176,6 +176,7 @@ public class GroupTaskToCoachPage {
 			buttons.get(0).click();
 		}
 		OOGraphene.waitBusy(browser);
+		OOGraphene.waitModalDialog(browser);
 		return this;
 	}
 	
@@ -186,6 +187,9 @@ public class GroupTaskToCoachPage {
 	 * @return
 	 */
 	public GroupTaskToCoachPage groupAssessment(Boolean passed, Float score) {
+		By groupAssessmentPopupBy = By.cssSelector(".modal-body .o_sel_course_gta_group_assessment_form");
+		OOGraphene.waitElement(groupAssessmentPopupBy, 5, browser);
+		
 		By applyToAllBy = By.cssSelector(".o_sel_course_gta_group_assessment_form .o_sel_course_gta_apply_to_all input[type='checkbox']");
 		WebElement applyToAllEl = browser.findElement(applyToAllBy);
 		OOGraphene.check(applyToAllEl, Boolean.TRUE);
diff --git a/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java b/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java
index 84913a153a67b22eaaeb371387c791d8dc2fb5a6..ac00c6e4656ab6eee4be6a52009240657a8cea58 100644
--- a/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java
+++ b/src/test/java/org/olat/selenium/page/portfolio/ArtefactWizardPage.java
@@ -107,6 +107,7 @@ public class ArtefactWizardPage {
 	 */
 	public ArtefactWizardPage tags(String... tags) {
 		By tagBy = By.cssSelector("div.o_sel_artefact_add_wizard div.bootstrap-tagsinput>input");
+		OOGraphene.waitElement(tagBy, 5, browser);
 		WebElement tagEl = browser.findElement(tagBy);
 		if(tags != null && tags.length > 0 && tags[0] != null) {
 			for(String tag:tags) {