diff --git a/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java b/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java
index 554afe0087f39fed67ac1be4c0d673163d6d1c24..d025cd096e1e9a7f363f44d0bfad5614a0604511 100644
--- a/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java
+++ b/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java
@@ -53,6 +53,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.ims.qti.QTIResultSet;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 
 import de.bps.webservices.clients.onyxreporter.OnyxReporterConnector;
@@ -194,7 +195,7 @@ public class OnyxResultManager {
 				ScoreEvaluation sc = OnyxModule.getUserScoreEvaluationFromQtiResult(userCourseEnvironment.getCourseEnvironment().getCourseResourceableId(), node,
 						bestResultConfigured, qtiResultSet.getIdentity());
 				if(node instanceof AssessableCourseNode){
-					((AssessableCourseNode) node).updateUserScoreEvaluation(sc, userCourseEnvironment, qtiResultSet.getIdentity(), false);
+					((AssessableCourseNode) node).updateUserScoreEvaluation(sc, userCourseEnvironment, qtiResultSet.getIdentity(), false, Role.coach);
 				}
 				
 			} else {
diff --git a/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java b/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java
index 8e03bf8b5f4b17f06efb17b6a375e688f48886f2..0ffbba6e302d5ef1b03836a4f934c0787d1d14a3 100644
--- a/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java
+++ b/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java
@@ -72,6 +72,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.fileresource.FileResourceManager;
 import org.olat.ims.qti.QTIResultSet;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 
 import de.bps.onyx.plugin.OnyxModule;
@@ -569,7 +570,7 @@ public class OnyxRunController extends BasicController {
 						//now increase attempts; if an exception occurred before, this will be not reached
 						if (currentState != TestState.CANCELED) {
 							AssessmentManager am = course.getCourseEnvironment().getAssessmentManager();
-							am.incrementNodeAttempts(courseNode, student, userCourseEnv);
+							am.incrementNodeAttempts(courseNode, student, userCourseEnv, Role.user);
 						}
 					} else {
 						assessmentId = resultSet.getAssessmentID();
diff --git a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java
index 96e00d5e33b572ae874bea287d78f67247af3b49..0a2177e53a2bcc3c61456eaef23be61545ce67fb 100644
--- a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java
+++ b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java
@@ -51,6 +51,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.ims.qti.QTIResultManager;
 import org.olat.ims.qti.QTIResultSet;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 
 import de.bps.onyx.plugin.OnyxResultManager;
@@ -221,7 +222,7 @@ public class ReturnWSService {
 								}
 								ScoreEvaluation scoreEvaluation = new ScoreEvaluation(qtiResultSet.getScore(), qtiResultSet.getIsPassed(),
 										status, Boolean.TRUE, qtiResultSet.getFullyAssessed(), qtiResultSet.getAssessmentID());
-								am.saveScoreEvaluation((AssessableCourseNode)courseNode, null, assessedIdentity, scoreEvaluation, userCourseEnvironment, false);
+								am.saveScoreEvaluation((AssessableCourseNode)courseNode, null, assessedIdentity, scoreEvaluation, userCourseEnvironment, false, Role.coach);
 
 								CoreSpringFactory.getImpl(AssessmentNotificationsHandler.class).markPublisherNews(assessedIdentity, resourceId);
 							}
diff --git a/src/main/java/org/olat/course/assessment/AssessmentHelper.java b/src/main/java/org/olat/course/assessment/AssessmentHelper.java
index 6ec0b0f8d96cfc9b1600eb2b8c95c99a614fa8ed..2331d773c3147eb2356651c2f071a6c1d17f3c81 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentHelper.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentHelper.java
@@ -48,6 +48,7 @@ import org.olat.core.util.tree.TreeVisitor;
 import org.olat.core.util.tree.Visitor;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.model.AssessmentNodeData;
+import org.olat.course.assessment.model.AssessmentNodesLastModified;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.CourseNodeConfiguration;
@@ -93,6 +94,8 @@ public class AssessmentHelper {
 	public static final String KEY_TOTAL_NODES = "totalNodes";
 	public static final String KEY_ATTEMPTED_NODES = "attemptedNodes";
 	public static final String KEY_PASSED_NODES = "attemptedNodes";
+	public static final String KEY_LAST_USER_MODIFIED = "lastUserModified";
+	public static final String KEY_LAST_COACH_MODIFIED = "lastCoachModified";
 
 	/**
 	 * String to symbolize 'not available' or 'not assigned' in assessments
@@ -432,12 +435,13 @@ public class AssessmentHelper {
 	 * @return list of object arrays or null if empty
 	 */
 	public static List<AssessmentNodeData> getAssessmentNodeDataList(UserCourseEnvironment userCourseEnv,
+			AssessmentNodesLastModified lastModifications,
 			boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments) {
 		List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50);
 		ScoreAccounting scoreAccounting = userCourseEnv.getScoreAccounting();
 		scoreAccounting.evaluateAll();
 		getAssessmentNodeDataList(0, userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode(),
-				scoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data);
+				scoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, lastModifications);
 		return data;
 	}
 	
@@ -455,13 +459,14 @@ public class AssessmentHelper {
 			boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments) {
 		List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50);
 		getAssessmentNodeDataList(0, userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode(),
-				evaluatedScoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data);
+				evaluatedScoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, null);
 		return data;
 	}
 	
 	
 	public static int getAssessmentNodeDataList(int recursionLevel, CourseNode courseNode, ScoreAccounting scoreAccounting,
-			UserCourseEnvironment userCourseEnv, boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments, List<AssessmentNodeData> data) {
+			UserCourseEnvironment userCourseEnv, boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments,
+			List<AssessmentNodeData> data, AssessmentNodesLastModified lastModifications) {
 		// 1) Get list of children data using recursion of this method
 		AssessmentNodeData assessmentNodeData = new AssessmentNodeData(recursionLevel, courseNode);
 		data.add(assessmentNodeData);
@@ -470,7 +475,7 @@ public class AssessmentHelper {
 		for (int i = 0; i < courseNode.getChildCount(); i++) {
 			CourseNode child = (CourseNode) courseNode.getChildAt(i);
 			numOfChildren += getAssessmentNodeDataList(recursionLevel + 1,  child,  scoreAccounting,
-					userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data);
+					userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, lastModifications);
 		}
 		
 		// 2) Get data of this node only if
@@ -490,6 +495,14 @@ public class AssessmentHelper {
 					assessmentNodeData.setNumOfAssessmentDocs(scoreEvaluation.getNumOfAssessmentDocs());
 				}
 				assessmentNodeData.setUserVisibility(scoreEvaluation.getUserVisible());
+				assessmentNodeData.setLastModified(scoreEvaluation.getLastModified());
+				assessmentNodeData.setLastUserModified(scoreEvaluation.getLastUserModified());
+				assessmentNodeData.setLastCoachModified(scoreEvaluation.getLastCoachModified());
+				if(lastModifications != null) {
+					lastModifications.addLastModified(scoreEvaluation.getLastModified());
+					lastModifications.addLastUserModified(scoreEvaluation.getLastUserModified());
+					lastModifications.addLastCoachModified(scoreEvaluation.getLastCoachModified());
+				}
 				
 				if(!followUserVisibility || scoreEvaluation.getUserVisible() == null || scoreEvaluation.getUserVisible().booleanValue()) {
 					// details 
diff --git a/src/main/java/org/olat/course/assessment/AssessmentManager.java b/src/main/java/org/olat/course/assessment/AssessmentManager.java
index 629abda4af4590d1415e93bec7ffd271760b17fc..167b56f6adef5d4f103d09a4ef903eb9f6b2d70a 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentManager.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentManager.java
@@ -38,6 +38,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 
 /**
@@ -64,7 +65,17 @@ public interface AssessmentManager {
 	 * @param assessedIdentity The user whose score is changed
 	 * @param attempts The new attempts
 	 */
-	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts);
+	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by);
+	
+	/**
+	 * Change the last modification dates.
+	 * 
+	 * @param courseNode The course node
+	 * @param identity The identity which does the action
+	 * @param assessedIdentity The assessed identity
+	 * @param by The role of the identity which does the action.
+	 */
+	public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment, Role by);
 
 	/**
 	 * Save an assessment comment for this node for a user. If there is already a comment property available, 
@@ -111,7 +122,7 @@ public interface AssessmentManager {
 	 * @param courseNode
 	 * @param identity
 	 */
-	public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment);
+	public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment, Role by);
 	
 	/**
 	 * Increment the users attempts for this course node, but without logging (aimed at background job).
@@ -212,7 +223,8 @@ public interface AssessmentManager {
 	 */
 	
 	public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity,
-			ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts);
+			ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
+			boolean incrementUserAttempts, Role by);
 	
 	/**
 	 * 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/EfficiencyStatement.java b/src/main/java/org/olat/course/assessment/EfficiencyStatement.java
index 229030fd83d57b7e6b146a26e671ab1100d4ef7a..7003844f7a8e26fd340e758cd58937a4168de069 100644
--- a/src/main/java/org/olat/course/assessment/EfficiencyStatement.java
+++ b/src/main/java/org/olat/course/assessment/EfficiencyStatement.java
@@ -45,34 +45,62 @@ public class EfficiencyStatement {
 	private Long courseRepoEntryKey;
 	private String displayableUserInfo;
 	private long lastUpdated;
+	private long lastUserModified;
+	private long lastCoachModified;
 	
 	public long getLastUpdated() {
 		return lastUpdated;
 	}
+	
 	public void setLastUpdated(long lastUpdated) {
 		this.lastUpdated = lastUpdated;
 	}
+	
+	public long getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(long lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
+	public long getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(long lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
 	public List<Map<String,Object>> getAssessmentNodes() {
 		return assessmentNodes;
 	}
+	
 	public void setAssessmentNodes(List<Map<String,Object>> assessmentNodes) {
 		this.assessmentNodes = assessmentNodes;
 	}
+	
 	public Long getCourseRepoEntryKey() {
 		return courseRepoEntryKey;
 	}
+	
 	public void setCourseRepoEntryKey(Long courseRepoEntryKey) {
 		this.courseRepoEntryKey = courseRepoEntryKey;
 	}
+	
 	public String getCourseTitle() {
 		return courseTitle;
 	}
+	
 	public void setCourseTitle(String courseTitle) {
 		this.courseTitle = courseTitle;
 	}
+	
 	public String getDisplayableUserInfo() {
 		return displayableUserInfo;
 	}
+	
+	
 	public void setDisplayableUserInfo(String displayableUserInfo) {
 		this.displayableUserInfo = displayableUserInfo;
 	}
diff --git a/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java b/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java
index 2a9a9f53cab2918bffeb7b0d484d0f989e8b3ebc..226ba10359ce0fddacc45e3f8b96d80d18a7cb3f 100644
--- a/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java
+++ b/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java
@@ -41,6 +41,10 @@ public interface UserEfficiencyStatement {
 	
 	public Date  getLastModified();
 	
+	public Date getLastUserModified();
+	
+	public Date getLastCoachModified();
+	
 	public Date getCreationDate();
 	
 	public Long getCourseRepoKey();
diff --git a/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties
index 547238d3953c8ec999a681c123897807a6377b44..8f0cfd61c5ac2a4a3f9048e1204483411643f9cc 100644
--- a/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties
@@ -152,6 +152,8 @@ table.header.status=Status
 table.header.type=Typ
 table.header.initialLaunchDate=Erster Kursstart
 table.header.lastScoreDate=Letzte Aktualisierung
+table.header.lastUserModificationDate=Letzte Benutzer Aktualisierung
+table.header.lastCoachModificationDate=Letzte Betreuer Aktualisierung
 notifications.title=Kurs "{0}" 
 notifications.header=Neue Testresultate in Kurs "{0}"
 notifications.entry={3}: "{0}" ausgef\u00FChrt von {1} mit {2} Punkten
diff --git a/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java b/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java
index 9d74870fe85315946d6a67550dce20ced3daaeac..2a43b3170378376f70f3f0bb1ed579ec06927070 100644
--- a/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java
+++ b/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java
@@ -119,7 +119,7 @@ public class DataStepForm extends StepFormBasicController {
 			OlatRootFileImpl file = new OlatRootFileImpl(savedDatas.getDataBackupFile(), null);
 			InputStream in = file.getInputStream();
 			try {
-				dataVal = IOUtils.toString(in);
+				dataVal = IOUtils.toString(in, "UTF-8");
 			} catch (IOException e) {
 				logError("", e);
 			} finally {
@@ -238,7 +238,7 @@ public class DataStepForm extends StepFormBasicController {
 		OutputStream out = inputFile.getOutputStream(false);
 
 		try {
-			IOUtils.write(val, out);
+			IOUtils.write(val, out, "UTF-8");
 			datas.setDataBackupFile(inputFile.getRelPath());
 		} catch (IOException e) {
 			logError("", e);
diff --git a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
index 7105185a05b9d713f0827905a40266702a4fd6be..52bb19b95700db90a396bf12ba164627cf6bbc18 100644
--- a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
+++ b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
@@ -93,6 +93,7 @@ import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.user.UserManager;
 import org.olat.util.logging.activity.LoggingResourceable;
@@ -387,7 +388,7 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ
 					}
 					
 					// Update score,passed properties in db, and the user's efficiency statement
-					courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, false);
+					courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, false, Role.auto);
 				}
 			}
 			
@@ -398,7 +399,7 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ
 				ScoreEvaluation se = new ScoreEvaluation(oldScore, passed);
 				// Update score,passed properties in db, and the user's efficiency statement
 				boolean incrementAttempts = false;
-				courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, incrementAttempts);
+				courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, incrementAttempts, Role.auto);
 			}
 			
 			boolean identityHasReturnFile = false;
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 5f6b5f31b626e45ae650ca0baa064b32b0091d49..98877b30c3e9e13ce352eaea536384f6ff344bb6 100644
--- a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
+++ b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
@@ -52,6 +52,7 @@ import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentLoggingAction;
 import org.olat.course.assessment.AssessmentManager;
 import org.olat.course.assessment.model.AssessmentNodeData;
+import org.olat.course.assessment.model.AssessmentNodesLastModified;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.certificate.CertificateTemplate;
 import org.olat.course.certificate.CertificatesManager;
@@ -60,12 +61,14 @@ import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.run.environment.CourseEnvironment;
+import org.olat.course.run.scoring.AssessmentEvaluation;
 import org.olat.course.run.scoring.ScoreAccounting;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentService;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.repository.RepositoryEntry;
 import org.olat.util.logging.activity.LoggingResourceable;
@@ -138,12 +141,20 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		}
 		Float score = null;
 		Boolean passed = null;
+		Date lastUserModified = null;
+		Date lastCoachModified = null;
 		if(scoreEvaluation != null) {
 			score = scoreEvaluation.getScore();
 			passed = scoreEvaluation.getPassed();
 		}
+		if(scoreEvaluation instanceof AssessmentEvaluation) {
+			AssessmentEvaluation eval = (AssessmentEvaluation)scoreEvaluation;
+			lastCoachModified = eval.getLastCoachModified();
+			lastUserModified = eval.getLastUserModified();
+		}
 		return assessmentService
-				.createAssessmentEntry(assessedIdentity, null, cgm.getCourseEntry(), courseNode.getIdent(), referenceEntry, score, passed);
+				.createAssessmentEntry(assessedIdentity, null, cgm.getCourseEntry(), courseNode.getIdent(), referenceEntry,
+						score, passed, lastUserModified, lastCoachModified);
 	}
 
 	@Override
@@ -152,10 +163,15 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 	}
 
 	@Override
-	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts) {
+	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by) {
 		ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry());
 		
 		AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode);
+		if(by == Role.coach) {
+			nodeAssessment.setLastCoachModified(new Date());
+		} else if(by == Role.user) {
+			nodeAssessment.setLastUserModified(new Date());
+		}
 		nodeAssessment.setAttempts(attempts);
 		assessmentService.updateAssessmentEntry(nodeAssessment);
 
@@ -281,13 +297,21 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 	}
 
 	@Override
-	public void incrementNodeAttempts(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv) {
+	public void incrementNodeAttempts(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv, Role by) {
 		ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry());
 		
 		AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode);
 		int attempts = nodeAssessment.getAttempts() == null ? 1 :nodeAssessment.getAttempts().intValue() + 1;
 		nodeAssessment.setAttempts(attempts);
+		if(by == Role.coach) {
+			nodeAssessment.setLastCoachModified(new Date());
+		} else if(by == Role.user) {
+			nodeAssessment.setLastUserModified(new Date());
+		}
 		assessmentService.updateAssessmentEntry(nodeAssessment);
+		DBFactory.getInstance().commit();
+		userCourseEnv.getScoreAccounting().evaluateAll(true);
+		DBFactory.getInstance().commit();
 		if(courseNode instanceof AssessableCourseNode) {
 			// Update users efficiency statement
 			efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv);
@@ -322,10 +346,27 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(ace, course);
 	}
 	
+	@Override
+	public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv, Role by) {
+		AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode);
+		if(by == Role.coach) {
+			nodeAssessment.setLastCoachModified(new Date());
+		} else if(by == Role.user) {
+			nodeAssessment.setLastUserModified(new Date());
+		}
+		assessmentService.updateAssessmentEntry(nodeAssessment);
+		DBFactory.getInstance().commit();
+		userCourseEnv.getScoreAccounting().evaluateAll(true);
+		if(courseNode instanceof AssessableCourseNode) {
+			// Update users efficiency statement
+			efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv);
+		}
+	}
+
 	@Override
 	public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity,
 			ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnv,
-			boolean incrementUserAttempts) {
+			boolean incrementUserAttempts, Role by) {
 		final ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry());
 		final CourseEnvironment courseEnv = userCourseEnv.getCourseEnvironment();
 		
@@ -339,6 +380,11 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		if(referenceEntry != null && !referenceEntry.equals(assessmentEntry.getReferenceEntry())) {
 			assessmentEntry.setReferenceEntry(referenceEntry);
 		}
+		if(by == Role.coach) {
+			assessmentEntry.setLastCoachModified(new Date());
+		} else if(by == Role.user) {
+			assessmentEntry.setLastUserModified(new Date());
+		}
 		if(score == null) {
 			assessmentEntry.setScore(null);
 		} else {
@@ -413,9 +459,10 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		// write only when enabled for this course
 		if (courseEnv.getCourseConfig().isEfficencyStatementEnabled()) {
 			List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50);
+			AssessmentNodesLastModified lastModifications = new AssessmentNodesLastModified();
 			AssessmentHelper.getAssessmentNodeDataList(0, courseEnv.getRunStructure().getRootNode(),
-					scoreAccounting, userCourseEnv, true, true, true, data);
-			efficiencyStatementManager.updateUserEfficiencyStatement(assessedIdentity, courseEnv, data, cgm.getCourseEntry());
+					scoreAccounting, userCourseEnv, true, true, true, data, lastModifications);
+			efficiencyStatementManager.updateUserEfficiencyStatement(assessedIdentity, courseEnv, data, lastModifications, cgm.getCourseEntry());
 		}
 
 		if(course.getCourseConfig().isAutomaticCertificationEnabled()) {
diff --git a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
index b3eea997c07ed9e5650b84ed82a32ee56b71d4b8..037474f02dbe102ea3af825b6ca308f77953ce69 100644
--- a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
+++ b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
@@ -54,6 +54,7 @@ import org.olat.course.assessment.EfficiencyStatement;
 import org.olat.course.assessment.EfficiencyStatementArchiver;
 import org.olat.course.assessment.UserEfficiencyStatement;
 import org.olat.course.assessment.model.AssessmentNodeData;
+import org.olat.course.assessment.model.AssessmentNodesLastModified;
 import org.olat.course.assessment.model.UserEfficiencyStatementImpl;
 import org.olat.course.assessment.model.UserEfficiencyStatementLight;
 import org.olat.course.assessment.model.UserEfficiencyStatementStandalone;
@@ -166,15 +167,17 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 		CourseConfig cc = userCourseEnv.getCourseEnvironment().getCourseConfig();
 		// write only when enabled for this course
 		if (cc.isEfficencyStatementEnabled()) {
-			Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity();				
-			List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnv, true, true, true);
-			updateUserEfficiencyStatement(identity, userCourseEnv.getCourseEnvironment(), assessmentNodeList, repoEntry);
+			Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity();
+			AssessmentNodesLastModified lastModifications = new AssessmentNodesLastModified();
+			List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnv, lastModifications, true, true, true);
+			updateUserEfficiencyStatement(identity, userCourseEnv.getCourseEnvironment(), assessmentNodeList, lastModifications,  repoEntry);
 		}
 	}
 	
-	public void updateUserEfficiencyStatement(Identity assessedIdentity, final CourseEnvironment courseEnv, List<AssessmentNodeData> assessmentNodeList, final RepositoryEntry repoEntry) {
+	public void updateUserEfficiencyStatement(Identity assessedIdentity, final CourseEnvironment courseEnv,
+			List<AssessmentNodeData> assessmentNodeList, AssessmentNodesLastModified lastModifications, final RepositoryEntry repoEntry) {
 		List<Map<String,Object>> assessmentNodes = AssessmentHelper.assessmentNodeDataListToMap(assessmentNodeList);
-				
+			
 		EfficiencyStatement efficiencyStatement = new EfficiencyStatement();
 		efficiencyStatement.setAssessmentNodes(assessmentNodes);
 		efficiencyStatement.setCourseTitle(courseEnv.getCourseTitle());
@@ -182,6 +185,14 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 		String userInfos = userManager.getUserDisplayName(assessedIdentity);
 		efficiencyStatement.setDisplayableUserInfo(userInfos);
 		efficiencyStatement.setLastUpdated(System.currentTimeMillis());
+		if(lastModifications != null) {
+			if(lastModifications.getLastUserModified() != null) {
+				efficiencyStatement.setLastUserModified(lastModifications.getLastUserModified().getTime());
+			}
+			if(lastModifications.getLastCoachModified() != null) {
+				efficiencyStatement.setLastCoachModified(lastModifications.getLastCoachModified().getTime());
+			}
+		}
 		
 		boolean debug = log.isDebug();
 		UserEfficiencyStatementImpl efficiencyProperty = getUserEfficiencyStatementFull(repoEntry, assessedIdentity);
@@ -196,7 +207,7 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 					efficiencyProperty.setCourseRepoKey(repoEntry.getKey());
 				}
 				
-				fillEfficiencyStatement(efficiencyStatement, efficiencyProperty);
+				fillEfficiencyStatement(efficiencyStatement, lastModifications, efficiencyProperty);
 				dbInstance.getCurrentEntityManager().persist(efficiencyProperty);
 				if (debug) {
 					log.debug("creating new efficiency statement property::" + efficiencyProperty.getKey() + " for id::" + assessedIdentity.getName() + " repoEntry::" + repoEntry.getKey());
@@ -206,7 +217,7 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 				if (debug) {
 					log.debug("updating efficiency statement property::" + efficiencyProperty.getKey() + " for id::" + assessedIdentity.getName() + " repoEntry::" + repoEntry.getKey());
 				}	
-				fillEfficiencyStatement(efficiencyStatement, efficiencyProperty);
+				fillEfficiencyStatement(efficiencyStatement, lastModifications, efficiencyProperty);
 				dbInstance.getCurrentEntityManager().merge(efficiencyProperty);
 			}
 		} else {
@@ -226,7 +237,18 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(ace, courseOres);
 	}
 	
-	public void fillEfficiencyStatement(EfficiencyStatement efficiencyStatement, UserEfficiencyStatementImpl efficiencyProperty) {
+	public void fillEfficiencyStatement(EfficiencyStatement efficiencyStatement, AssessmentNodesLastModified lastModifications, UserEfficiencyStatementImpl efficiencyProperty) {
+		if(lastModifications != null) {
+			if(lastModifications.getLastUserModified() != null
+					&& (efficiencyProperty.getLastUserModified() == null || efficiencyProperty.getLastUserModified().before(lastModifications.getLastUserModified()))) {
+				efficiencyProperty.setLastUserModified(lastModifications.getLastUserModified());
+			}
+			if(lastModifications.getLastCoachModified() != null
+					&& (efficiencyProperty.getLastCoachModified() == null || efficiencyProperty.getLastCoachModified().before(lastModifications.getLastCoachModified()))) {
+				efficiencyProperty.setLastCoachModified(lastModifications.getLastCoachModified());
+			}
+		}
+		
 		List<Map<String,Object>> nodeData = efficiencyStatement.getAssessmentNodes();
 		if(!nodeData.isEmpty()) {
 			Map<String,Object> rootNode = nodeData.get(0);
@@ -264,6 +286,21 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 			
 			int passedNodes = getPassedNodes(nodeData);
 			efficiencyProperty.setPassedNodes(passedNodes);
+			
+			for(Map<String,Object> node:nodeData) {
+				Date lastUserModified = (Date)node.get(AssessmentHelper.KEY_LAST_USER_MODIFIED);
+				if(lastUserModified != null) {
+					if(efficiencyProperty.getLastUserModified() == null || efficiencyProperty.getLastUserModified().before(lastUserModified)) {
+						efficiencyProperty.setLastUserModified(lastUserModified);
+					}
+				}
+				Date lastCoachModified = (Date)node.get(AssessmentHelper.KEY_LAST_COACH_MODIFIED);
+				if(lastCoachModified != null) {
+					if(efficiencyProperty.getLastCoachModified() == null || efficiencyProperty.getLastCoachModified().before(lastCoachModified)) {
+						efficiencyProperty.setLastCoachModified(lastCoachModified);
+					}
+				}
+			}
 		}
 
 		efficiencyProperty.setLastModified(new Date());
@@ -599,6 +636,10 @@ public class EfficiencyStatementManager implements UserDataDeletable {
 				.getResultList();
 	}
 	
+	public List<Identity> findIdentitiesWithEfficiencyStatements(RepositoryEntryRef repoEntry) {
+		return findIdentitiesWithEfficiencyStatements(repoEntry.getKey());
+	}
+	
 	/**
 	 * Find all identities who have an efficiency statement for this course repository entry
 	 * @param courseRepoEntryKey
diff --git a/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java b/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java
index ef84de8e3dbe23b01f7d283d615e79b385c1d980..b05a6f58569ba8b9fa191420f60099a3c294d931 100644
--- a/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java
+++ b/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java
@@ -23,6 +23,8 @@ import static org.olat.course.assessment.AssessmentHelper.KEY_ATTEMPTS;
 import static org.olat.course.assessment.AssessmentHelper.KEY_DETAILS;
 import static org.olat.course.assessment.AssessmentHelper.KEY_IDENTIFYER;
 import static org.olat.course.assessment.AssessmentHelper.KEY_INDENT;
+import static org.olat.course.assessment.AssessmentHelper.KEY_LAST_COACH_MODIFIED;
+import static org.olat.course.assessment.AssessmentHelper.KEY_LAST_USER_MODIFIED;
 import static org.olat.course.assessment.AssessmentHelper.KEY_MAX;
 import static org.olat.course.assessment.AssessmentHelper.KEY_MIN;
 import static org.olat.course.assessment.AssessmentHelper.KEY_PASSED;
@@ -33,6 +35,7 @@ import static org.olat.course.assessment.AssessmentHelper.KEY_TITLE_LONG;
 import static org.olat.course.assessment.AssessmentHelper.KEY_TITLE_SHORT;
 import static org.olat.course.assessment.AssessmentHelper.KEY_TYPE;
 
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -72,6 +75,10 @@ public class AssessmentNodeData {
 	
 	private int numOfAssessmentDocs;
 	
+	private Date lastModified;
+	private Date lastUserModified;
+	private Date lastCoachModified;
+	
 	private boolean selectable;
 	private boolean onyx = false;
 	
@@ -215,6 +222,30 @@ public class AssessmentNodeData {
 		this.numOfAssessmentDocs = numOfAssessmentDocs;
 	}
 
+	public Date getLastModified() {
+		return lastModified;
+	}
+
+	public void setLastModified(Date lastModified) {
+		this.lastModified = lastModified;
+	}
+
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(Date lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(Date lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
 	public boolean isOnyx() {
 		return onyx;
 	}
@@ -258,6 +289,12 @@ public class AssessmentNodeData {
 		if (passed != null) {
 			nodeData.put(KEY_PASSED, passed);
 		}
+		if(lastUserModified != null) {
+			nodeData.put(KEY_LAST_USER_MODIFIED, lastUserModified);
+		}
+		if(lastCoachModified != null) {
+			nodeData.put(KEY_LAST_COACH_MODIFIED, lastCoachModified);
+		}
 		nodeData.put(KEY_SELECTABLE, selectable ? Boolean.TRUE : Boolean.FALSE);
 		return nodeData;
 	}
@@ -280,6 +317,13 @@ public class AssessmentNodeData {
 		if(nodeData.get(KEY_SELECTABLE) instanceof Boolean) {
 			selectable = ((Boolean)nodeData.get(KEY_SELECTABLE)).booleanValue();
 		}
+		if(nodeData.get(KEY_LAST_USER_MODIFIED) instanceof Date) {
+			lastUserModified = ((Date)nodeData.get(KEY_LAST_USER_MODIFIED));
+		}
+		if(nodeData.get(KEY_LAST_COACH_MODIFIED) instanceof Date) {
+			lastCoachModified = ((Date)nodeData.get(KEY_LAST_COACH_MODIFIED));
+		}
+		
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java b/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java
new file mode 100644
index 0000000000000000000000000000000000000000..159015f85a63d4f348815f16c209b6601f676b6e
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java
@@ -0,0 +1,77 @@
+/**
+ * <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.assessment.model;
+
+import java.util.Date;
+
+/**
+ * 
+ * Initial date: 14 août 2017<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class AssessmentNodesLastModified {
+	
+	private Date lastModified;
+	private Date lastUserModified;
+	private Date lastCoachModified;
+	
+	public Date getLastModified() {
+		return lastModified;
+	}
+	
+	public void addLastModified(Date date) {
+		if(date == null) return;
+		
+		if(lastModified == null) {
+			lastModified = date;
+		} else if(lastModified != null && lastModified.before(date)) {
+			lastModified = date;
+		}
+	}
+	
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+	
+	public void addLastUserModified(Date date) {
+		if(date == null) return;
+		
+		if(lastUserModified == null) {
+			lastUserModified = date;
+		} else if(lastUserModified != null && lastUserModified.before(date)) {
+			lastUserModified = date;
+		}
+	}
+	
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+	
+	public void addLastCoachModified(Date date) {
+		if(date == null) return;
+		
+		if(lastCoachModified == null) {
+			lastCoachModified = date;
+		} else if(lastCoachModified != null && lastCoachModified.before(date)) {
+			lastCoachModified = date;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
index d17e726464a5bcd4df31095373b690eab44752b2..49c302f498f529ba4a4a4d10b468fca726280fa4 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
@@ -20,6 +20,8 @@
 	<version name="version" access="field" column="version" type="int"/>
 	<property name="creationDate" column="creationdate" type="timestamp" />
 	<property name="lastModified" column="lastmodified" type="timestamp" />
+	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
+	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
 
 	<property name="score" column="score" type="float" />
 	<property name="passed" column="passed" type="boolean" />
@@ -66,6 +68,8 @@
 	<version name="version" access="field" column="version" type="int"/>
 	<property name="creationDate" column="creationdate" type="timestamp" />
 	<property name="lastModified" column="lastmodified" type="timestamp" />
+	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
+	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
 
 	<property name="score" column="score" type="float" />
 	<property name="passed" column="passed" type="boolean" />
@@ -104,6 +108,8 @@
 	<version name="version" access="field" column="version" type="int"/>
 	<property name="creationDate" column="creationdate" type="timestamp" />
 	<property name="lastModified" column="lastmodified" type="timestamp" />
+	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
+	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
 
 	<property name="score" column="score" type="float" />
 	<property name="passed" column="passed" type="boolean" />
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
index 40865dcd4786222bb6985928b5822720774beadb..2b4838673ec4864bb6e3d2dd420e147e2126469e 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
@@ -51,6 +51,12 @@ public class UserEfficiencyStatementImpl extends PersistentObject implements Use
 	private String statementXml;
 	
 	private Date lastModified;
+	private Date lastUserModified;
+	private Date lastCoachModified;
+	
+	public UserEfficiencyStatementImpl() {
+		//
+	}
 
 	@Override
 	public Date getLastModified() {
@@ -62,6 +68,22 @@ public class UserEfficiencyStatementImpl extends PersistentObject implements Use
 		this.lastModified = lastModified;
 	}
 
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(Date lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(Date lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
 	@Override
 	public Float getScore() {
 		return score;
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
index bfd22f56b16c3553103e6da2a99e4c47b8e008d6..f256aacf073ae3a4f13d09d77f9267a3def4492b 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
@@ -53,6 +53,8 @@ public class UserEfficiencyStatementLight extends PersistentObject implements Us
 	private Long archivedResourceKey;
 	
 	private Date lastModified;
+	private Date lastUserModified;
+	private Date lastCoachModified;
 
 	@Override	
 	public Date getLastModified() {
@@ -64,6 +66,22 @@ public class UserEfficiencyStatementLight extends PersistentObject implements Us
 		this.lastModified = lastModified;
 	}
 
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(Date lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(Date lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
 	@Override
 	public Float getScore() {
 		return score;
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
index 1a3d2a9c3e546d6f482a01d4d01fdb411ab0d0d9..3effbfee69654c221d02a500ff3d0c9f9bd2e0f1 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
@@ -53,6 +53,8 @@ public class UserEfficiencyStatementStandalone extends PersistentObject implemen
 	private String statementXml;
 	
 	private Date lastModified;
+	private Date lastUserModified;
+	private Date lastCoachModified;
 	
 	@Override
 	public Date getLastModified() {
@@ -64,6 +66,22 @@ public class UserEfficiencyStatementStandalone extends PersistentObject implemen
 		this.lastModified = lastModified;
 	}
 
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(Date lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(Date lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
 	@Override
 	public Float getScore() {
 		return score;
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
index d626b3fbf31eec0ab5f23521791cfb5fd6999427..f975473b8ffaa56e50ab984c6640130b1ca4979e 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
@@ -63,6 +63,7 @@ import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.run.scoring.ScoreAccounting;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.assessment.ui.event.AssessmentFormEvent;
 
@@ -315,7 +316,7 @@ public class AssessmentForm extends FormBasicController {
 			ScoreEvaluation reopenedEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(),
 					AssessmentEntryStatus.inReview, scoreEval.getUserVisible(),
 					scoreEval.getFullyAssessed(), scoreEval.getAssessmentID());
-			assessableCourseNode.updateUserScoreEvaluation(reopenedEval, assessedUserCourseEnv, getIdentity(), false);
+			assessableCourseNode.updateUserScoreEvaluation(reopenedEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 			updateStatus(reopenedEval);
 		}
 	}
@@ -337,7 +338,7 @@ public class AssessmentForm extends FormBasicController {
 		Boolean updatedPassed = null;
 
 		if (isHasAttempts() && isAttemptsDirty()) {
-			assessableCourseNode.updateUserAttempts(new Integer(getAttempts()), assessedUserCourseEnv, getIdentity());
+			assessableCourseNode.updateUserAttempts(new Integer(getAttempts()), assessedUserCourseEnv, getIdentity(), Role.coach);
 		}
 
 		if (isHasScore()) {
@@ -368,7 +369,7 @@ public class AssessmentForm extends FormBasicController {
 		} else {
 			scoreEval = new ScoreEvaluation(updatedScore, updatedPassed, null, visibility, null, null);
 		}
-		assessableCourseNode.updateUserScoreEvaluation(scoreEval, assessedUserCourseEnv, getIdentity(), false);
+		assessableCourseNode.updateUserScoreEvaluation(scoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 
 		if (isHasComment() && isUserCommentDirty()) {
 			String newComment = getUserComment().getValue();
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java
index aa51bff7267effcc204fe81297a317dc48a7c6e1..ac6eb53e4e0a10a387e37603b17bc2e5a0485236 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java
@@ -242,6 +242,10 @@ public class IdentityAssessmentOverviewController extends FormBasicController im
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.passed, new PassedCellRenderer()));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.numOfAssessmentDocs));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.status, new AssessmentStatusCellRenderer(getLocale())));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, NodeCols.lastModified));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.lastUserModified));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, NodeCols.lastCoachModified));
+		
 		if(nodesSelectable) {
 			DefaultFlexiColumnModel selectCol = new DefaultFlexiColumnModel("select", NodeCols.select.ordinal(), CMD_SELECT_NODE,
 					new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("select"), CMD_SELECT_NODE), null));
@@ -278,7 +282,7 @@ public class IdentityAssessmentOverviewController extends FormBasicController im
 		List<AssessmentNodeData> nodesTableList;
 		if (loadNodesFromCourse) {
 			// get list of course node and user data and populate table data model 	
-			nodesTableList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnvironment, followUserResultsVisibility, discardEmptyNodes, true);
+			nodesTableList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnvironment, null, followUserResultsVisibility, discardEmptyNodes, true);
 		} else {
 			// use list from efficiency statement 
 			nodesTableList = preloadedNodesList;
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java
index 64aa05045ed9a3425b61af9f5ba699c35036e366..f344f864c65604a3b68900297256dd933c9dae79 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java
@@ -109,6 +109,9 @@ public class IdentityAssessmentOverviewTableModel extends DefaultFlexiTableDataM
 				return nodeData.getNumOfAssessmentDocs();
 			}
 			case select: return nodeData.isSelectable();
+			case lastModified: return nodeData.getLastModified();
+			case lastUserModified: return nodeData.getLastUserModified();
+			case lastCoachModified: return nodeData.getLastCoachModified();
 			default: return "ERROR";
 		}
 	}
@@ -136,7 +139,10 @@ public class IdentityAssessmentOverviewTableModel extends DefaultFlexiTableDataM
 		status("table.header.status", true),
 		passed("table.header.passed", true),
 		select("table.action.select", false),
-		numOfAssessmentDocs("table.header.num.assessmentDocs", true);
+		numOfAssessmentDocs("table.header.num.assessmentDocs", true),
+		lastModified("table.header.lastScoreDate", true),
+		lastUserModified("table.header.lastUserModificationDate", true),
+		lastCoachModified("table.header.lastCoachModificationDate", true);
 		
 		private final String i18nKey;
 		private final boolean sortable;
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
index 2168f49f35903f184bbed68bba698321a5436690..d5c96424fef0f3655620cb1fbdc6a2d6f8321f3d 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
@@ -91,6 +91,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.assessment.ui.AssessedIdentityController;
 import org.olat.modules.assessment.ui.AssessedIdentityElementRow;
@@ -251,8 +252,13 @@ public class IdentityListCourseNodeController extends FormBasicController implem
 		}
 
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.assessmentStatus, new AssessmentStatusCellRenderer(getLocale())));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, select));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastScoreUpdate, select));
+		if(courseNode.getParent() == null) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, select));
+		}
+		
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastModified, select));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastUserModified, select));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastCoachModified, select));
 		
 		if(course.getCourseConfig().isCertificateEnabled()) {
 			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.certificate, new DownloadCertificateCellRenderer()));
@@ -646,7 +652,7 @@ public class IdentityListCourseNodeController extends FormBasicController implem
 			ScoreEvaluation scoreEval = assessableCourseNode.getUserScoreEvaluation(assessedUserCourseEnv);
 			ScoreEvaluation doneEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(),
 					scoreEval.getAssessmentStatus(), visibility, scoreEval.getFullyAssessed(), scoreEval.getAssessmentID());
-			assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false);
+			assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 		}
 		updateModel(ureq, null, null, null);
 	}
@@ -679,7 +685,7 @@ public class IdentityListCourseNodeController extends FormBasicController implem
 				ScoreEvaluation scoreEval = assessableCourseNode.getUserScoreEvaluation(assessedUserCourseEnv);
 				ScoreEvaluation doneEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(),
 						AssessmentEntryStatus.done, null, scoreEval.getFullyAssessed(), scoreEval.getAssessmentID());
-				assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false);
+				assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 			}
 			
 			updateModel(ureq, null, null, null);
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
index bc25f7d5ea063c511027c856468e22c807eeeee4..80cb2d4c12e8305103904c1f4450efc4af18d679 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
@@ -147,7 +147,9 @@ public class IdentityListCourseNodeTableModel extends DefaultFlexiTableDataModel
 					return certificate == null ? null : certificate.getNextRecertificationDate();
 				}
 				case initialLaunchDate: return row.getInitialCourseLaunchDate();
-				case lastScoreUpdate: return row.getLastModified();
+				case lastModified: return row.getLastModified();
+				case lastUserModified: return row.getLastUserModified();
+				case lastCoachModified: return row.getLastCoachModified();		
 			}
 		}
 		int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET;
@@ -172,7 +174,9 @@ public class IdentityListCourseNodeTableModel extends DefaultFlexiTableDataModel
 		certificate("table.header.certificate"),
 		recertification("table.header.recertification"),
 		initialLaunchDate("table.header.initialLaunchDate"),
-		lastScoreUpdate("table.header.lastScoreDate"),
+		lastModified("table.header.lastScoreDate"),
+		lastUserModified("table.header.lastUserModificationDate"),
+		lastCoachModified("table.header.lastCoachModificationDate"),
 		numOfAssessmentDocs("table.header.num.assessmentDocs");
 		
 		private final String i18nKey;
diff --git a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
index a82259ee52be5dc96ea17944ed28fea0f284a852..b9f6f16c34dfbba06075c59915b0707d6951c45d 100644
--- a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
+++ b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java
@@ -233,7 +233,14 @@ public class CertificateAndEfficiencyStatementController extends BasicController
 	private void populateAssessedIdentityInfos(UserRequest ureq, RepositoryEntry courseRepo, BusinessGroup group, boolean links) { 
 		if(efficiencyStatement != null) {
 			mainVC.contextPut("courseTitle", StringHelper.escapeHtml(efficiencyStatement.getCourseTitle()));
-			mainVC.contextPut("date", StringHelper.formatLocaleDateTime(efficiencyStatement.getLastUpdated(), ureq.getLocale()));
+			
+			long lastModified;
+			if(efficiencyStatement.getLastUserModified() > 0) {
+				lastModified = efficiencyStatement.getLastUserModified();
+			} else {
+				lastModified = efficiencyStatement.getLastUpdated();
+			}
+			mainVC.contextPut("date", StringHelper.formatLocaleDateTime(lastModified, getLocale()));
 		} else if(courseRepo != null) {
 			mainVC.contextPut("courseTitle", StringHelper.escapeHtml(courseRepo.getDisplayname()));
 		}
diff --git a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
index 96b40f918ec3871c26001549f1c06870bb65327d..cc9b95237d11ff763aec20a31268088fad021183 100644
--- a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
@@ -1,4 +1,5 @@
 /**
+
 * OLAT - Online Learning and Training<br>
 * http://www.olat.org
 * <p>
@@ -38,6 +39,7 @@ import org.olat.course.run.scoring.AssessmentEvaluation;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 
 
 /**
@@ -183,7 +185,7 @@ public interface AssessableCourseNode extends CourseNode {
 	 * @param userCourseEnvironment
 	 * @param coachingIdentity
 	 */
-	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, boolean incrementAttempts);
+	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, boolean incrementAttempts, Role doneBy);
 	/**
 	 * Updates the user comment for this node and this user. This comment is visible to the user.
 	 * @param userComment
@@ -214,14 +216,23 @@ public interface AssessableCourseNode extends CourseNode {
 	 * Increments the users attempts for this node and this user + 1. 
 	 * @param userCourseEnvironment
 	 */
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment);
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role doneBy);
 	/**
 	 * Updates the users attempts for this node and this user. 
 	 * @param userAttempts
 	 * @param userCourseEnvironment
 	 * @param coachingIdentity
 	 */
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity);
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role doneBy);
+	
+	/**
+	 * 
+	 * @param userCourseEnvironment The user course environment of the assessed identity
+	 * @param identity The identity which do the action
+	 * @param doneBy The role of the identity which do the action
+	 */
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role doneBy);
+	
 	/**
 	 * Updates the coach comment for this node and this user. This comment is not visible to the user.
 	 * @param coachComment
@@ -234,5 +245,4 @@ public interface AssessableCourseNode extends CourseNode {
 	 */
 	public boolean hasStatusConfigured();
 
-	
 }
diff --git a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
index 729a0342cb83a56b3961ea98aaefcb76bd38c260..834bfa711e3b8f8baba498f1cdb0408f94d9f055 100644
--- a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
+++ b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
@@ -61,6 +61,7 @@ import org.olat.ims.lti.LTIManager;
 import org.olat.ims.lti.ui.LTIResultDetailsController;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.resource.OLATResource;
 
@@ -126,7 +127,6 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 			UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) {
 		updateModuleConfigDefaults(false);
 		
-				ModuleConfiguration config = getModuleConfiguration();
 		Controller runCtrl;
 		if(userCourseEnv.isCourseReadOnly()) {
 			Translator trans = Util.createPackageTranslator(BasicLTICourseNode.class, ureq.getLocale());
@@ -436,11 +436,11 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);
 	}
 
 	@Override
@@ -471,20 +471,27 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 	}
 
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
 	}
 
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
+	}
 
 	@Override
 	public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnvironment) {
diff --git a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
index 1b9dfde7da6e7c24f597a61f70f6fe51e6cee419..b703c36ee03ce9b7baaca193463ec1c8ca227f61 100644
--- a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
@@ -77,6 +77,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 
 /**
@@ -396,10 +397,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);
 	}
 
 	/**
@@ -456,7 +457,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		throw new OLATRuntimeException(CheckListCourseNode.class, "Attempts variable can't be updated in ST nodes", null);
 	}
 
@@ -464,9 +465,16 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		throw new OLATRuntimeException(CheckListCourseNode.class, "Attempts variable can't be updated in ST nodes", null);
 	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
+	}
 
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest,
@@ -588,22 +596,25 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 * @param userCourseEnv
 	 * @param assessedIdentity
 	 */
-	public void updateScoreEvaluation(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
+	public void updateScoreEvaluation(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) {
 		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, identity, assessedUserCourseEnv, assessedIdentity);
+			doUpdateAssessment(cutValue, maxScore, identity, assessedUserCourseEnv, assessedIdentity, by);
 		} else if(sum != null && sum.booleanValue()) {
-			doUpdateAssessmentBySum(identity, assessedUserCourseEnv, assessedIdentity);
+			doUpdateAssessmentBySum(identity, assessedUserCourseEnv, assessedIdentity, by);
 		} else if(manualCorrection != null && manualCorrection.booleanValue()) {
-			doUpdateManualAssessment(maxScore, identity, assessedUserCourseEnv, assessedIdentity);
+			doUpdateManualAssessment(maxScore, identity, assessedUserCourseEnv, assessedIdentity, by);
+		} else {
+			AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
+			am.updateLastModifications(this, assessedIdentity, assessedUserCourseEnv, by);
 		}
 	}
 	
-	private void doUpdateAssessment(Float cutValue, Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
+	private void doUpdateAssessment(Float cutValue, Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) {
 		OLATResourceable courseOres = OresHelper
 				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
 		
@@ -621,10 +632,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), passed);
 		
 		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
-		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false);
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by);
 	}
 	
-	private void doUpdateAssessmentBySum(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
+	private void doUpdateAssessmentBySum(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) {
 		OLATResourceable courseOres = OresHelper
 				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
 		
@@ -651,10 +662,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		ScoreEvaluation sceval = new ScoreEvaluation(score, new Boolean(passed));
 		
 		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
-		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false);
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by);
 	}
 	
-	private void doUpdateManualAssessment(Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) {
+	private void doUpdateManualAssessment(Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) {
 		OLATResourceable courseOres = OresHelper
 				.createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId());
 		
@@ -667,7 +678,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		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);
+		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by);
 	}
 	
 	@Override
@@ -812,7 +823,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 			ScoreEvaluation scoreEval = new ScoreEvaluation(updatedScore, updatedPassed);
 			IdentityEnvironment identityEnv = new IdentityEnvironment(assessedIdentity, null);
 			UserCourseEnvironment uce = new UserCourseEnvironmentImpl(identityEnv, course.getCourseEnvironment());
-			am.saveScoreEvaluation(this, coachIdentity, assessedIdentity, scoreEval, uce, false);
+			am.saveScoreEvaluation(this, coachIdentity, assessedIdentity, scoreEval, uce, false, Role.coach);
 		}
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/GTACourseNode.java b/src/main/java/org/olat/course/nodes/GTACourseNode.java
index e4d75eb9e96a01bd884d86da4b114849650b2087..5213e08b5eebc738960dbc1e00f9f53f86ee57af 100644
--- a/src/main/java/org/olat/course/nodes/GTACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GTACourseNode.java
@@ -91,6 +91,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.user.UserManager;
 
@@ -952,10 +953,10 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
 
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnv,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
 		Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, assessedIdentity, new ScoreEvaluation(scoreEvaluation), userCourseEnv, incrementAttempts);
+		am.saveScoreEvaluation(this, coachingIdentity, assessedIdentity, new ScoreEvaluation(scoreEvaluation), userCourseEnv, incrementAttempts, by);
 	}
 
 	@Override
@@ -986,20 +987,27 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
 	}
 
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnv) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnv, Role by) {
 		AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
 		Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, assessedIdentity, userCourseEnv);
+		am.updateLastModifications(this, assessedIdentity, userCourseEnv, by);
 	}
 
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnv, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnv, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
 			Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, assessedIdentity, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, assessedIdentity, userAttempts, by);
 		}
 	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
+	}
 
 	@Override
 	public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnv) {
diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
index 52f880d66bdd534002f411e0af0f8ccf81ae13dc..7ea094166ff01f906c28f8b7057214863e44e126 100644
--- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
@@ -77,6 +77,7 @@ import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat;
 import org.olat.ims.qti21.model.QTI21StatisticSearchParams;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQManager;
 import org.olat.modules.iq.IQSecurityCallback;
 import org.olat.repository.RepositoryEntry;
@@ -393,10 +394,10 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
 	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
index 2b1d272d404c08d020e92e14dfcdcaa7908532a7..f8bba28e13e59c963f02bdfdddb8741478ec1b45 100644
--- a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
@@ -83,6 +83,7 @@ import org.olat.ims.qti21.ui.statistics.QTI21StatisticResourceResult;
 import org.olat.ims.qti21.ui.statistics.QTI21StatisticsSecurityCallback;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQSecurityCallback;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryImportExport;
@@ -375,6 +376,7 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
 	 *          from previous node configuration version, set default to maintain
 	 *          previous behaviour
 	 */
+	@Override
 	public void updateModuleConfigDefaults(boolean isNewNode) {
 		ModuleConfiguration config = getModuleConfiguration();
 		if (isNewNode) {
@@ -400,6 +402,7 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#hasAttemptsConfigured()
 	 */
+	@Override
 	public boolean hasAttemptsConfigured() {
 		return true;
 	}
@@ -409,21 +412,21 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
 	 *      org.olat.course.run.userview.UserCourseEnvironment,
 	 *      org.olat.core.id.Identity)
 	 */
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
 	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
index cad785f0ba37b1c2827062a3da81a69dbf9f1bf0..ed1be9d6c260185cf808efec404e7efdf0521f45 100644
--- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
@@ -120,6 +120,7 @@ import org.olat.ims.qti21.ui.statistics.QTI21StatisticsToolController;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQSecurityCallback;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryImportExport;
@@ -524,11 +525,11 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
 		try {
-			am.saveScoreEvaluation(this, coachingIdentity, mySelf, scoreEvaluation, userCourseEnvironment, incrementAttempts);
+			am.saveScoreEvaluation(this, coachingIdentity, mySelf, scoreEvaluation, userCourseEnvironment, incrementAttempts, by);
 		} catch(DBRuntimeException ex) {
 			throw new KnownIssueException("DBRuntimeException - Row was updated or deleted...", 3570, ex);
 		}
@@ -791,11 +792,11 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
@@ -803,10 +804,17 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
+	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/MSCourseNode.java b/src/main/java/org/olat/course/nodes/MSCourseNode.java
index 1ae833a55b7fe787f3063474b7bea28d94ed8214..97a74ca364e46bc53eee3c0bf1ed39464ce40970 100644
--- a/src/main/java/org/olat/course/nodes/MSCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/MSCourseNode.java
@@ -66,6 +66,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
 import org.olat.resource.OLATResource;
@@ -413,10 +414,10 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);		
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);		
 	}
 
 	/**
@@ -474,7 +475,7 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		throw new OLATRuntimeException(MSCourseNode.class, "Attempts variable can't be updated in MS nodes", null);
 	}
 
@@ -482,9 +483,16 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		throw new OLATRuntimeException(MSCourseNode.class, "Attempts variable can't be updated in MS nodes", null);
 	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
+	}
 
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest,
diff --git a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
index 9ed76d2b34050a7d9dda6842e7b45a13b22916d7..b3886893015cab8e6a7db928279dc300b8fa6d26 100644
--- a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
@@ -63,6 +63,7 @@ import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.portfolio.handler.BinderTemplateResource;
 import org.olat.modules.portfolio.ui.PortfolioAssessmentDetailsController;
 import org.olat.portfolio.EPTemplateMapResource;
@@ -462,10 +463,10 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements
 
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);
 	}
 
 	@Override
@@ -496,21 +497,28 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements
 	}
 
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
 	}
 
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
+	}
+
 	@Override
 	public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnvironment) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
diff --git a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
index c97c9589e4fccbbd165a8aa091478065da0f0373..80fb43e1c22d771fd765e73ccc68de9f51643b23 100644
--- a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
@@ -113,6 +113,7 @@ import org.olat.group.model.BusinessGroupReference;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
 import org.olat.resource.OLATResource;
@@ -623,10 +624,10 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);		
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);		
 	}
 
 	/**
@@ -687,11 +688,11 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
@@ -699,10 +700,17 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
+	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
 	}
 
 	/**
@@ -943,7 +951,7 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 			String projectBrokerTableExport = ProjectBrokerExportGenerator.createCourseResultsOverviewTable(this, course, locale);
 			String tableExportFileName = ExportUtil.createFileNameWithTimeStamp(getShortTitle() + "-projectbroker_overview", "xls");
 			exportStream.putNextEntry(new ZipEntry(exportDirName + "/" + tableExportFileName));
-			IOUtils.write(projectBrokerTableExport, exportStream);
+			IOUtils.write(projectBrokerTableExport, exportStream, "UTF-8");
 			exportStream.closeEntry();
 		} catch (IOException e) {
 			log.error("", e);
diff --git a/src/main/java/org/olat/course/nodes/STCourseNode.java b/src/main/java/org/olat/course/nodes/STCourseNode.java
index 8b04afdd3d75ed4d711af09f33eb42df47329845..331a215f7eec5ba6c019154b0984006c97ebf54c 100644
--- a/src/main/java/org/olat/course/nodes/STCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/STCourseNode.java
@@ -81,6 +81,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.tree.CourseInternalLinkTreeModel;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.util.logging.activity.LoggingResourceable;
 
@@ -546,7 +547,7 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		throw new OLATRuntimeException(STCourseNode.class, "Score variable can't be updated in ST nodes", null);
 	}
 
@@ -593,7 +594,7 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		throw new OLATRuntimeException(STCourseNode.class, "Attempts variable can't be updated in ST nodes", null);
 	}
 
@@ -601,10 +602,15 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		throw new OLATRuntimeException(STCourseNode.class, "Attempts variable can't be updated in ST nodes", null);
 	}
 
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role doneBy) {
+		//do nothing
+	}
+
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest,
 	 *      org.olat.core.gui.control.WindowControl,
diff --git a/src/main/java/org/olat/course/nodes/ScormCourseNode.java b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
index 23fda397e0089c4c78a08bf29a8750ca8b1e4004..ba6840066a3b01eb436bcc3d8a5c348589cbcbea 100644
--- a/src/main/java/org/olat/course/nodes/ScormCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
@@ -65,6 +65,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.fileresource.types.ScormCPFileResource;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.scorm.ScormMainManager;
 import org.olat.modules.scorm.ScormPackageConfig;
 import org.olat.modules.scorm.archiver.ScormExportManager;
@@ -489,10 +490,10 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts);		
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by);		
 	}
 
 	/**
@@ -591,11 +592,11 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
@@ -603,10 +604,17 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
+	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java
index 5e9a0957567daed1ff49a388298835857d8b1c20..f2332b4da5f26f10804388bd33fba9c4b92dbf6c 100644
--- a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java
@@ -26,6 +26,7 @@ package org.olat.course.nodes;
 
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.assessment.Role;
 
 /**
  * 
@@ -56,6 +57,6 @@ public interface SelfAssessableCourseNode extends CourseNode {
 	 * Increments the users attempts for this node and this user + 1. 
 	 * @param userCourseEnvironment
 	 */
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment);
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by);
 	
 }
diff --git a/src/main/java/org/olat/course/nodes/TACourseNode.java b/src/main/java/org/olat/course/nodes/TACourseNode.java
index b84f5a0fe4c81b2b79abd277632c6ccb585843d3..9219eae6a9e93b72a6c902d62d001ee1d4f4bffe 100644
--- a/src/main/java/org/olat/course/nodes/TACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/TACourseNode.java
@@ -97,6 +97,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
 import org.olat.resource.OLATResource;
@@ -669,11 +670,11 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 	 */
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEval, UserCourseEnvironment userCourseEnvironment,
-			Identity coachingIdentity, boolean incrementAttempts) {
+			Identity coachingIdentity, boolean incrementAttempts, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
 		ScoreEvaluation newScoreEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(), scoreEval.getAssessmentStatus(), scoreEval.getUserVisible(), null, null);
-		am.saveScoreEvaluation(this, coachingIdentity, mySelf, newScoreEval, userCourseEnvironment, incrementAttempts);		
+		am.saveScoreEvaluation(this, coachingIdentity, mySelf, newScoreEval, userCourseEnvironment, incrementAttempts, by);		
 	}
 
 	/**
@@ -726,11 +727,11 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 	 *      org.olat.core.id.Identity)
 	 */
 	@Override
-	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) {
+	public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) {
 		if (userAttempts != null) {
 			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 			Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts);
+			am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by);
 		}
 	}
 
@@ -738,10 +739,17 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 	 * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
 	@Override
-	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) {
+	public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
 		Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity();
-		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment);
+		am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by);
+	}
+	
+	@Override
+	public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) {
+		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+		Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+		am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
index 9f216eaa9f290de0547f3b44b2f3405e162e04c5..1f70305942157562131820139941213ad8c5e6e1 100644
--- a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
+++ b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
@@ -39,6 +39,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.ims.lti.ui.OutcomeMapper;
+import org.olat.modules.assessment.Role;
 import org.olat.resource.OLATResource;
 import org.olat.util.logging.activity.LoggingResourceable;
 
@@ -101,7 +102,7 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper {
 			
 			ScoreEvaluation eval = new ScoreEvaluation(scaledScore, passed);
 			UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(course);
-			ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false);
+			ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false, Role.user);
 		}
 		
 		return super.doUpdateResult(score);
@@ -116,7 +117,7 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper {
 			Identity assessedId = getIdentity();
 			ScoreEvaluation eval = new ScoreEvaluation(0.0f, false);
 			UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(course);
-			ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false);
+			ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false, Role.user);
 		}
 
 		return super.doDeleteResult();
diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
index cc9bb39db9fcd28fd083df64ffe157c9def349e0..911c792b9f3aca14f96b74f57758e96f28a9fae1 100644
--- a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
+++ b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java
@@ -68,6 +68,7 @@ import org.olat.ims.lti.LTIManager;
 import org.olat.ims.lti.ui.PostDataMapper;
 import org.olat.ims.lti.ui.TalkBackMapper;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.properties.Property;
 import org.olat.resource.OLATResource;
 
@@ -394,7 +395,7 @@ public class LTIRunController extends BasicController {
 	@Override
 	public void event(UserRequest ureq, Component source, Event event) {
 		if(source == startButton) {
-			courseNode.incrementUserAttempts(userCourseEnv);
+			courseNode.incrementUserAttempts(userCourseEnv, Role.user);
 			openBasicLTIContent(ureq);
 		} else if (source == acceptLink) {
 			storeDataExchangeAcceptance();
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 fa630349f8ccef208d520e2f7c09431ecbc70c8e..21c13f09fb739240c4e8fa55b6c7d43ff1dc7779 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
@@ -53,6 +53,7 @@ import org.olat.course.nodes.cl.model.DBCheck;
 import org.olat.course.nodes.cl.model.DBCheckbox;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -284,7 +285,7 @@ public class AssessedIdentityCheckListController extends FormBasicController {
 		}
 		checkboxManager.check(courseOres, courseNode.getIdent(), batchElements);
 		
-		courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
+		courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach);
 	}
 	
 	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 db6a2dd96d378c5b13b1750f3b7d603531722456..c2a03d1090886de02b31c03761bbb612a8d96671 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
@@ -89,6 +89,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupMembership;
 import org.olat.group.BusinessGroupService;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
@@ -587,7 +588,7 @@ public class CheckListAssessmentController extends FormBasicController implement
 			List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
 			for(Identity assessedIdentity:assessedIdentities) {
 				UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
-				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
+				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach);
 			}
 		}
 		
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 0859355a9947deb12c6639cd51cdb5b7af1c21cb..951a2bfd56a3bfa1d7c72358405ff7be33f4aaac 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
@@ -68,6 +68,7 @@ import org.olat.course.nodes.ms.DocumentsMapper;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -324,7 +325,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(getIdentity(), userCourseEnv, getIdentity());
+			courseNode.updateScoreEvaluation(getIdentity(), userCourseEnv, getIdentity(), Role.user);
 			
 			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 940cf1297817f80ea662d19804f70c4cc9f1d55a..6464e8061583d80e844001cda6aa46a58d1f9d16 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
@@ -67,6 +67,7 @@ import org.olat.course.nodes.cl.model.CheckboxList;
 import org.olat.course.nodes.cl.ui.CheckboxAssessmentDataModel.Cols;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 
@@ -385,7 +386,7 @@ public class CheckboxAssessmentController extends FormBasicController {
 			List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate);
 			for(Identity assessedIdentity:assessedIdentities) {
 				UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
-				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity);
+				courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach);
 			}
 		}
 		
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 6eaef96a4c5b0b90f108a1cec77c5d3b7c78fe6a..eebc0e9c90591dc9da9d7e1b3de8805363d343b6 100644
--- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java
+++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java
@@ -36,6 +36,7 @@ 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;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
@@ -264,7 +265,7 @@ public interface GTAManager {
 	
 	public Task createAndPersistTask(String taskName, TaskList taskList, TaskProcess status, BusinessGroup assessedGroup, Identity assessedIdentity, GTACourseNode cNode);
 	
-	public Task nextStep(Task task, GTACourseNode cNode);
+	public Task nextStep(Task task, GTACourseNode cNode, Role by);
 	
 	
 
@@ -336,15 +337,15 @@ public interface GTAManager {
 	 */
 	public Task reviewedTask(Task task, GTACourseNode cNode);
 	
-	public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode);
+	public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode, Role by);
 	
 	public TaskDueDate updateTaskDueDate(TaskDueDate taskDueDate);
 	
-	public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs);
+	public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs, Role by);
 	
-	public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs);
+	public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs, Role by);
 	
-	public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode);
+	public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode, Role by);
 	
 	public Task allowResetTask(Task task, Identity allower, GTACourseNode cNode);
 	
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 2f6bda7f5bc1924c50af68ccf8d115282c0b39cc..d5ec967011298193ffed8b3c51387ca877a72599 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
@@ -55,6 +55,9 @@ import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSManager;
 import org.olat.core.util.xml.XStreamHelper;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.AssignmentResponse;
@@ -81,6 +84,7 @@ import org.olat.course.nodes.gta.model.TaskListImpl;
 import org.olat.course.nodes.gta.model.TaskRevisionDateImpl;
 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;
 import org.olat.group.BusinessGroupRef;
 import org.olat.group.BusinessGroupService;
@@ -90,6 +94,7 @@ import org.olat.group.manager.BusinessGroupRelationDAO;
 import org.olat.group.model.BusinessGroupRefImpl;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentService;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
@@ -923,7 +928,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 				task.setAssignmentDate(new Date());
 				dbInstance.getCurrentEntityManager().persist(task);
 				dbInstance.commit();
-				syncAssessmentEntry((TaskImpl)currentTask, cNode);
+				syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user);
 				response = new AssignmentResponse(task, Status.ok);
 			}
 		} else {
@@ -931,7 +936,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 				((TaskImpl)currentTask).setTaskStatus(TaskProcess.submit);
 			}
 			currentTask = dbInstance.getCurrentEntityManager().merge(currentTask);
-			syncAssessmentEntry((TaskImpl)currentTask, cNode);
+			syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user);
 			response = new AssignmentResponse(currentTask, Status.ok);
 		}
 		
@@ -1054,6 +1059,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 				TaskImpl task = createTask(taskName, reloadedTasks, nextStep, businessGroup, identity, cNode);
 				task.setAssignmentDate(new Date());
 				dbInstance.getCurrentEntityManager().persist(task);
+				syncAssessmentEntry(task, cNode, Role.user);
 				response = new AssignmentResponse(task, Status.ok);
 			}
 			dbInstance.commit();
@@ -1066,7 +1072,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 				}
 			}
 			currentTask = dbInstance.getCurrentEntityManager().merge(currentTask);
-			syncAssessmentEntry((TaskImpl)currentTask, cNode);
+			syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user);
 			response = new AssignmentResponse(currentTask, Status.ok);
 		}
 		return response;
@@ -1264,7 +1270,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 	}
 
 	@Override
-	public Task nextStep(Task task, GTACourseNode cNode) {
+	public Task nextStep(Task task, GTACourseNode cNode, Role by) {
 		TaskImpl taskImpl = (TaskImpl)task;
 		TaskProcess currentStep = taskImpl.getTaskStatus();
 		//cascade through the possible steps
@@ -1272,7 +1278,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		taskImpl.setTaskStatus(nextStep);
 		TaskImpl mergedTask = dbInstance.getCurrentEntityManager().merge(taskImpl);
 		dbInstance.commit();//make the thing definitiv
-		syncAssessmentEntry(mergedTask, cNode);
+		syncAssessmentEntry(mergedTask, cNode, by);
 		return mergedTask;
 	}
 	
@@ -1428,16 +1434,16 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setCollectionDate(new Date());
 		taskImpl.setCollectionNumOfDocs(numOfDocs);
-		return updateTask(task, review, cNode);
+		return updateTask(task, review, cNode, Role.coach);
 	}
 
 	@Override
-	public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs) {
+	public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs, Role by) {
 		TaskProcess review = nextStep(TaskProcess.submit, cNode);
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setSubmissionDate(new Date());
 		taskImpl.setSubmissionNumOfDocs(numOfDocs);
-		return updateTask(task, review, cNode);
+		return updateTask(task, review, cNode, by);
 	}
 
 	@Override
@@ -1445,7 +1451,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setAllowResetDate(new Date());
 		taskImpl.setAllowResetIdentity(allower);
-		return updateTask(task, task.getTaskStatus(), cNode);
+		return updateTask(task, task.getTaskStatus(), cNode, Role.coach);
 	}
 	
 	@Override
@@ -1453,7 +1459,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setTaskName(null);
 		taskImpl.setAllowResetDate(null);
-		Task updatedTask = updateTask(task, TaskProcess.assignment, cNode);
+		Task updatedTask = updateTask(task, TaskProcess.assignment, cNode, Role.user);
 		
 		File submissionDir = null;
 		if(updatedTask.getBusinessGroup() != null) {
@@ -1472,17 +1478,17 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setAllowResetDate(null);
 		taskImpl.setAllowResetIdentity(null);
-		return updateTask(task, task.getTaskStatus(), cNode);
+		return updateTask(task, task.getTaskStatus(), cNode, Role.user);
 	}
 
 	@Override
-	public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs) {
+	public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs, Role by) {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setSubmissionRevisionsDate(new Date());
 		taskImpl.setSubmissionRevisionsNumOfDocs(numOfDocs);
 		//log the date
 		createAndPersistTaskRevisionDate(taskImpl, taskImpl.getRevisionLoop(), TaskProcess.correction);
-		return updateTask(taskImpl, TaskProcess.correction, cNode);
+		return updateTask(taskImpl, TaskProcess.correction, cNode, by);
 	}
 	
 	@Override
@@ -1490,16 +1496,16 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		TaskProcess solution = nextStep(TaskProcess.correction, cNode);
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setAcceptationDate(new Date());
-		return updateTask(taskImpl, solution, cNode);
+		return updateTask(taskImpl, solution, cNode, Role.coach);
 	}
 
 	@Override
-	public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode) {
+	public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode, Role by) {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setTaskStatus(newStatus);
 		syncDates(taskImpl, newStatus);
 		taskImpl = dbInstance.getCurrentEntityManager().merge(taskImpl);
-		syncAssessmentEntry(taskImpl, cNode);
+		syncAssessmentEntry(taskImpl, cNode, by);
 		
 		//update
 		OLATResource resource = taskImpl.getTaskList().getEntry().getOlatResource();
@@ -1543,14 +1549,14 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 	}
 
 	@Override
-	public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode) {
+	public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode, Role by) {
 		TaskImpl taskImpl = (TaskImpl)task;
 		taskImpl.setTaskStatus(newStatus);
 		taskImpl.setRevisionLoop(iteration);
 		taskImpl = dbInstance.getCurrentEntityManager().merge(taskImpl);
 		//log date
 		createAndPersistTaskRevisionDate(taskImpl, iteration, newStatus);
-		syncAssessmentEntry(taskImpl, cNode);
+		syncAssessmentEntry(taskImpl, cNode, by);
 		return taskImpl;
 	}
 
@@ -1572,7 +1578,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 		return assessmentStatus;
 	}
 	
-	private void syncAssessmentEntry(TaskImpl taskImpl, GTACourseNode cNode) {
+	private void syncAssessmentEntry(TaskImpl taskImpl, GTACourseNode cNode, Role by) {
 		if(taskImpl == null || taskImpl.getTaskStatus() == null || cNode == null) return;
 		
 		RepositoryEntry courseRepoEntry = taskImpl.getTaskList().getEntry();
@@ -1581,8 +1587,14 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 			//update whole group
 			assessmentService.updateAssessmentEntries(taskImpl.getBusinessGroup(), courseRepoEntry, cNode.getIdent(), null, assessmentStatus);
 		} else {
-			assessmentService.updateAssessmentEntry(taskImpl.getIdentity(), courseRepoEntry, cNode.getIdent(), null, assessmentStatus);
-		}	
+			Identity assessedIdentity = taskImpl.getIdentity();
+			assessmentService.updateAssessmentEntry(assessedIdentity, courseRepoEntry, cNode.getIdent(), null, assessmentStatus);
+			dbInstance.commit();
+
+			ICourse course = CourseFactory.loadCourse(courseRepoEntry);
+			UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
+			cNode.updateLastModifications(userCourseEnv, taskImpl.getIdentity(), by);
+		}
 	}
 
 	private TaskList loadForUpdate(TaskList tasks) {
diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
index 040523079b050d87b47dea90a1e2d72d46a987c0..d40f9536f44e9a4483220a0bbc38c411f893e319 100644
--- a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
+++ b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
@@ -65,6 +65,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.SearchBusinessGroupParams;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.manager.AssessmentEntryDAO;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryService;
@@ -666,7 +667,7 @@ class GTANotifications {
 			DueDate dueDate = gtaManager.getSubmissionDueDate(task, assessedIdentity, assessedGroup, gtaNode, re, true);
 			if(dueDate != null && dueDate.getDueDate() != null && dueDate.getDueDate().before(new Date())) {
 				int numOfDocs = getNumberOfSubmittedDocuments(assessedIdentity, assessedGroup);
-				task = gtaManager.submitTask(task, gtaNode, numOfDocs);
+				task = gtaManager.submitTask(task, gtaNode, numOfDocs, Role.auto);
 				doUpdateAttempts(assessedIdentity, assessedGroup);
 			}
 		}
@@ -721,7 +722,7 @@ class GTANotifications {
 					&& task.getRevisionsDueDate() != null
 					&& task.getRevisionsDueDate().compareTo(new Date()) < 0) {
 				//push to the next step
-				task = gtaManager.nextStep(task, gtaNode);
+				task = gtaManager.nextStep(task, gtaNode, Role.auto);
 				doUpdateAttempts(assessedIdentity, assessedGroup);
 			}
 		}
@@ -756,12 +757,12 @@ class GTANotifications {
 			List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name());
 			for(Identity identity:identities) {
 				UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				gtaNode.incrementUserAttempts(uce);
+				gtaNode.incrementUserAttempts(uce, Role.auto);
 			}
 		} else {
 			UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper
 					.createAndInitUserCourseEnvironment(assessedIdentity, course);
-			gtaNode.incrementUserAttempts(assessedUserCourseEnv);
+			gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.auto);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java
index e6b488731a4947562384b8b58dfa6704dcfaf9ca..c4d21b509731b48f773acf655232a1a6007f5b91 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java
@@ -1,3 +1,22 @@
+/**
+ * <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;
 
 import org.olat.core.gui.UserRequest;
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 6a479fe9753092cb0db7125b4e314e6ff04a351c..5f45a1b6e671dd74663f9919cf54e419ba90d1a5 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
@@ -60,6 +60,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -211,7 +212,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 		if(submit) {
 			task = stepSubmit(ureq, task);
 		} else if(task != null && task.getTaskStatus() == TaskProcess.submit) {
-			task = gtaManager.nextStep(task, gtaNode);
+			task = gtaManager.nextStep(task, gtaNode, Role.auto);
 		}
 		
 		boolean reviewAndCorrection = config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION);
@@ -219,7 +220,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 		if(reviewAndCorrection) {
 			task = stepReviewAndCorrection(ureq, task);
 		} else if(task != null && task.getTaskStatus() == TaskProcess.review) {
-			task = gtaManager.nextStep(task, gtaNode);
+			task = gtaManager.nextStep(task, gtaNode, Role.auto);
 		}
 		
 		boolean revision = config.getBooleanSafe(GTACourseNode.GTASK_REVISION_PERIOD);
@@ -227,7 +228,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 		if(reviewAndCorrection && revision) {
 			task = stepRevision(ureq, task);
 		} else if(task != null && (task.getTaskStatus() == TaskProcess.revision || task.getTaskStatus() == TaskProcess.correction)) {
-			task = gtaManager.nextStep(task, gtaNode);
+			task = gtaManager.nextStep(task, gtaNode, Role.auto);
 		}
 		
 		boolean solution = config.getBooleanSafe(GTACourseNode.GTASK_SAMPLE_SOLUTION);
@@ -235,7 +236,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 		if(solution) {
 			stepSolution(ureq, task);
 		} else if(task != null && task.getTaskStatus() == TaskProcess.solution) {
-			task = gtaManager.nextStep(task, gtaNode);
+			task = gtaManager.nextStep(task, gtaNode, Role.auto);
 		}
 		
 		boolean grading = config.getBooleanSafe(GTACourseNode.GTASK_GRADING);
@@ -243,7 +244,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 		if(grading) {
 			stepGrading(ureq, task);
 		} else if(task != null && task.getTaskStatus() == TaskProcess.grading) {
-			task = gtaManager.nextStep(task, gtaNode);
+			task = gtaManager.nextStep(task, gtaNode, Role.auto);
 		}
 		
 		mainVC.contextPut("changelogconfig", courseModule.isDisplayChangeLog());
@@ -302,7 +303,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 				if(assignedTask != null && StringHelper.containsNonWhitespace(assignedTask.getTaskName())
 						&& assignedTask.getTaskStatus() == TaskProcess.assignment && date.compareTo(new Date()) < 0) {
 					//push to the next step if the task is blocked in assignment (it's a security)
-					assignedTask = gtaManager.nextStep(assignedTask, gtaNode);
+					assignedTask = gtaManager.nextStep(assignedTask, gtaNode, Role.auto);
 				}
 			} else if(dueDate.getMessageKey() != null) {
 				mainVC.contextPut("assignmentDueDateMsg", translate(dueDate.getMessageKey(), dueDate.getMessageArg()));
@@ -363,7 +364,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 						&& date.compareTo(new Date()) < 0) {
 					//push to the next step
 					int numOfDocs = getNumberOfSubmittedDocuments();
-					assignedTask = gtaManager.submitTask(assignedTask, gtaNode, numOfDocs);
+					assignedTask = gtaManager.submitTask(assignedTask, gtaNode, numOfDocs, Role.auto);
 					doUpdateAttempts();
 				}
 			} else if(dueDate.getMessageKey() != null) {
@@ -408,7 +409,7 @@ public abstract class GTAAbstractController extends BasicController implements G
 					&& date.compareTo(new Date()) < 0) {
 				//push to the next step
 				int numOfDocs = getNumberOfRevisionDocuments(assignedTask);
-				assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs);
+				assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs, Role.auto);
 				doUpdateAttempts();
 			}
 		}
@@ -473,16 +474,17 @@ public abstract class GTAAbstractController extends BasicController implements G
 	}
 	
 	protected void doUpdateAttempts() {
+		Role by = getDoer();
 		if(businessGroupTask) {
 			List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name());
 			ICourse course = CourseFactory.loadCourse(courseEnv.getCourseGroupManager().getCourseEntry());
 			for(Identity identity:identities) {
 				UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				gtaNode.incrementUserAttempts(uce);
+				gtaNode.incrementUserAttempts(uce, by);
 			}
 		} else {
 			UserCourseEnvironment assessedUserCourseEnv = getAssessedUserCourseEnvironment();
-			gtaNode.incrementUserAttempts(assessedUserCourseEnv);
+			gtaNode.incrementUserAttempts(assessedUserCourseEnv, by);
 		}
 	}
 	
@@ -528,4 +530,6 @@ public abstract class GTAAbstractController extends BasicController implements G
 		ureq.getUserSession().getGuiPreferences()
 			.putAndSave(GTAStepPreferences.class, taskList.getKey().toString(), stepPreferences);
 	}
+	
+	protected abstract Role getDoer();
 }
\ No newline at end of file
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 3d610f840454eb462a46e1730dcc173ce047f9d1..17eb6a3076567cd053399fc2f1b266e2c842d697 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
@@ -60,6 +60,7 @@ 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;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.co.ContactFormController;
 import org.olat.resource.OLATResource;
 import org.olat.user.DisplayPortraitController;
@@ -487,7 +488,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm
 			task = gtaManager.getTask(assessedIdentity, taskList);
 		}
 		if(task != null) {
-			task = gtaManager.updateTask(task, TaskProcess.graded, gtaNode);
+			task = gtaManager.updateTask(task, TaskProcess.graded, gtaNode, Role.coach);
 			cleanUpProcess();
 			process(ureq);
 		}
@@ -502,7 +503,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm
 			task = gtaManager.getTask(assessedIdentity, taskList);
 		}
 		if(task != null && task.getTaskStatus() == TaskProcess.graded) {
-			task = gtaManager.updateTask(task, TaskProcess.grading, gtaNode);
+			task = gtaManager.updateTask(task, TaskProcess.grading, gtaNode, Role.coach);
 			cleanUpProcess();
 			process(ureq);
 		}
@@ -674,7 +675,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm
 	}
 	
 	private void doRevisions(UserRequest ureq, Task task) {
-		gtaManager.updateTask(task, TaskProcess.revision, 1, gtaNode);
+		gtaManager.updateTask(task, TaskProcess.revision, 1, gtaNode, Role.coach);
 		gtaManager.log("Review", "need revision", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 		
 		cleanUpProcess();
@@ -759,7 +760,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm
 	private void doBackToSubmission(UserRequest ureq, Task task) {
 		TaskProcess submit = gtaManager.previousStep(TaskProcess.review, gtaNode);//only submit allowed
 		if(submit == TaskProcess.submit) {
-			task = gtaManager.updateTask(task, submit, gtaNode);
+			task = gtaManager.updateTask(task, submit, gtaNode, Role.coach);
 			
 			gtaManager.log("Back to submission", "revert status of task back to submission", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 			
@@ -845,5 +846,9 @@ public class GTACoachController extends GTAAbstractController implements Assessm
 		}
 		return taskDef;
 	}
-
+	
+	@Override
+	protected Role getDoer() {
+		return Role.coach;
+	}
 }
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 7b18c1776b2e5385565ad33c5de67283e7a38469..c249466d6428afcc21b852c8061d75017b3da9a7 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
@@ -63,6 +63,7 @@ import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
+import org.olat.modules.assessment.Role;
 import org.olat.user.UserManager;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -374,7 +375,7 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im
 	}
 	
 	private void doCollect() {
-		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.correction, gtaNode);
+		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.correction, gtaNode, Role.coach);
 		gtaManager.log("Collect revision", "revision collected", assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 
 		ICourse course = CourseFactory.loadCourse(courseEnv.getCourseResourceableId());
@@ -382,10 +383,10 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im
 			List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name());
 			for(Identity identity:identities) {
 				UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				gtaNode.incrementUserAttempts(userCourseEnv);
+				gtaNode.incrementUserAttempts(userCourseEnv, Role.coach);
 			}
 		} else {
-			gtaNode.incrementUserAttempts(assessedUserCourseEnv);
+			gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.coach);
 		}
 		
 		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUBMIT_REVISION,
@@ -395,7 +396,7 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im
 	}
 	
 	private void doReturnToRevisions(Task task) {
-		assignedTask = gtaManager.updateTask(task, TaskProcess.revision, currentIteration + 1, gtaNode);
+		assignedTask = gtaManager.updateTask(task, TaskProcess.revision, currentIteration + 1, gtaNode, Role.coach);
 		gtaManager.log("Revision", "need another revision", assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
 	}
 	
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
index 597e2e4faf22c75510d11f1cc2be44091eebdd7d..0e83fbaef726e5525be575cab87c1432fcbd7012 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
@@ -72,6 +72,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -317,12 +318,12 @@ public class GTACoachedGroupGradingController extends FormBasicController {
 		if(assignedTask == null) {
 			assignedTask = gtaManager.createTask(null, taskList, TaskProcess.graded, assessedGroup, null, gtaNode);
 		} else {
-			assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode);
+			assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode, Role.coach);
 		}
 	}
 	
 	private void doReopenAssessment(UserRequest ureq) {
-		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode);
+		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode, Role.coach);
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 	
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java
index 1449359418bd2e36491436edbfcb9ec93c447160..ae4bff8a729421151398b2685098e17828894286 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java
@@ -44,6 +44,7 @@ import org.olat.course.nodes.gta.TaskProcess;
 import org.olat.course.nodes.ms.MSCourseNodeRunController;
 import org.olat.course.run.scoring.AssessmentEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.assessment.ui.event.AssessmentFormEvent;
 import org.olat.repository.RepositoryEntry;
@@ -147,7 +148,7 @@ public class GTACoachedParticipantGradingController extends BasicController {
 	}
 	
 	private void doReopenAssessment(UserRequest ureq) {
-		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode);
+		assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode, Role.coach);
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 	
@@ -164,7 +165,7 @@ public class GTACoachedParticipantGradingController extends BasicController {
 				TaskList taskList = gtaManager.createIfNotExists(courseEntry, gtaNode);
 				assignedTask = gtaManager.createTask(null, taskList, TaskProcess.graded, null, assessedIdentity, gtaNode);
 			} else {
-				assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode);
+				assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode, Role.coach);
 			}
 			fireEvent(ureq, Event.CHANGED_EVENT);
 		}
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 0326400ca2c959f6537c69bf07c15c66283dcc11..fcc500d7f4f2bc7cd1a23b02c67430ebc00ad3ac 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
@@ -69,6 +69,7 @@ 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;
+import org.olat.modules.assessment.Role;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -338,7 +339,7 @@ public class GTAParticipantController extends GTAAbstractController implements A
 	
 	private void doSubmitDocuments(UserRequest ureq, Task task) {
 		int numOfDocs = getNumberOfSubmittedDocuments();
-		task = gtaManager.submitTask(task, gtaNode, numOfDocs);
+		task = gtaManager.submitTask(task, gtaNode, numOfDocs, Role.user);
 		showInfo("run.documents.successfully.submitted");
 		
 		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUMBIT_TASK,
@@ -843,4 +844,9 @@ public class GTAParticipantController extends GTAAbstractController implements A
 		listenTo(chooserCalloutCtrl);
 		chooserCalloutCtrl.activate();
 	}
+
+	@Override
+	protected Role getDoer() {
+		return Role.user;
+	}	
 }
\ No newline at end of file
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 82b213f79af11a7d6f03bcb32c11db58c24201b6..1ba44f5b0f3d7cbb4d2bc7dd97d17d1bf19e2717 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
@@ -63,6 +63,7 @@ import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
+import org.olat.modules.assessment.Role;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -323,7 +324,7 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 		}
 		
 		int numOfDocs = submittedDocuments == null ? 0 : submittedDocuments.length;
-		assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs);
+		assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs, Role.user);
 		gtaManager.log("Revision", "revision submitted", assignedTask, getIdentity(), getIdentity(), assessedGroup, courseEnv, gtaNode);
 		
 		TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUBMIT_REVISION,
@@ -337,10 +338,10 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl
 
 			for(Identity identity:identities) {
 				UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
-				gtaNode.incrementUserAttempts(userCourseEnv);
+				gtaNode.incrementUserAttempts(userCourseEnv, Role.user);
 			}
 		} else {
-			gtaNode.incrementUserAttempts(assessedUserCourseEnv);
+			gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.user);
 		}
 	}
 }
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
index ce49553f89856e6d5a37310104862e677250450c..f46f057445557a375af94c49587dd60921f11330 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
@@ -67,6 +67,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
@@ -519,11 +520,11 @@ public class GroupAssessmentController extends FormBasicController {
 		if(applyToAllEl.isAtLeastSelected(1)) {
 			applyChangesForTheWholeGroup(rows, setAsDone, userVisible);
 		} else {
-			applyChangesForEvenryMemberGroup(rows, setAsDone, userVisible);
+			applyChangesForEveryMemberGroup(rows, setAsDone, userVisible);
 		}
 	}
 	
-	private void applyChangesForEvenryMemberGroup(List<AssessmentRow> rows, boolean setAsDone, boolean userVisible) {
+	private void applyChangesForEveryMemberGroup(List<AssessmentRow> rows, boolean setAsDone, boolean userVisible) {
 		ICourse course = CourseFactory.loadCourse(courseEnv.getCourseResourceableId());
 		
 		for(AssessmentRow row:rows) {
@@ -552,7 +553,7 @@ public class GroupAssessmentController extends FormBasicController {
 			} else {
 				newScoreEval = new ScoreEvaluation(score, passed, null, userVisible, null, null);
 			}
-			gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false);
+			gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false, Role.coach);
 			
 			if(withComment) {
 				String comment = row.getComment();
@@ -591,7 +592,7 @@ public class GroupAssessmentController extends FormBasicController {
 			} else {
 				newScoreEval = new ScoreEvaluation(score, passed, null, userVisible, null, null);
 			}
-			gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false);
+			gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false, Role.coach);
 		}
 
 		if(withComment) {
diff --git a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
index cc285dbc592c2ae88c9cd222d2c92104f111d666..b451ca60f6ce4c30e974be94e1c82360ad2a5667 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
@@ -34,6 +34,7 @@ import org.olat.core.gui.control.controller.BasicController;
 import org.olat.course.nodes.IQTESTCourseNode;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.assessment.Role;
 
 /**
  * Description: <br>
@@ -79,7 +80,7 @@ public class IQPreviewController extends BasicController {
 				boolean passed = score >= (cutValue == null ? 0 : cutValue.floatValue());
 				ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), new Boolean(passed));
 				boolean incrementUserAttempts = true;
-				cn.updateUserScoreEvaluation(sceval, userCourseEnv, ureq.getIdentity(), incrementUserAttempts);				
+				cn.updateUserScoreEvaluation(sceval, userCourseEnv, ureq.getIdentity(), incrementUserAttempts, Role.user);				
 				getWindowControl().setInfo(translate("preview.points.set"));
 			}
 		}
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 6182d38a1c2900f60a3b9c5a552590f618293e00..6a3e4c56d52cbaee9d280b389c5874225c164411 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java
@@ -92,6 +92,7 @@ import org.olat.ims.qti.process.ImsRepositoryResolver;
 import org.olat.instantMessaging.InstantMessagingService;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.iq.IQDisplayController;
 import org.olat.modules.iq.IQManager;
@@ -518,7 +519,7 @@ public class IQRunController extends BasicController implements GenericEventList
 			
 			ScoreEvaluation sceval = new ScoreEvaluation(ac.getScore(), ac.isPassed(), assessmentStatus, userVisibility, fullyAssed, ai.getAssessID());
 			AssessableCourseNode acn = (AssessableCourseNode)courseNode; // assessment nodes are assessable		
-			acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), true);
+			acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), true, Role.user);
 				
 			// Mark publisher for notifications
 			Long courseId = userCourseEnv.getCourseEnvironment().getCourseResourceableId();
@@ -534,10 +535,10 @@ public class IQRunController extends BasicController implements GenericEventList
 			// although this is not an assessable node we still use the assessment
 			// manager since this one uses caching
 			AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
-			am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv);
+			am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv, Role.user);
 		} else if(type.equals(AssessmentInstance.QMD_ENTRY_TYPE_SELF)){
 			AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
-			am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv);
+			am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv, Role.user);
 		}
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
index b6fc424ca34dff7c8fe1e857315c2c94e463f477..9e7538794fc1c06e23c0dc52c059b590859c6d14 100644
--- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
@@ -89,6 +89,7 @@ import org.olat.ims.qti21.ui.ResourcesMapper;
 import org.olat.instantMessaging.InstantMessagingService;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.repository.RepositoryEntry;
 import org.olat.user.UserManager;
@@ -727,7 +728,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 			ScoreEvaluation sceval = new ScoreEvaluation(score, pass, assessmentStatus, visibility, Boolean.TRUE, assessmentId);
 			
 			boolean increment = incrementAttempts.getAndSet(false);
-			((IQTESTCourseNode)courseNode).updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), increment);
+			((IQTESTCourseNode)courseNode).updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), increment, Role.user);
 			if(increment) {
 				ThreadLocalUserActivityLogger.log(QTI21LoggingAction.QTI_CLOSE_IN_COURSE, getClass());
 			}
@@ -736,7 +737,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 		} else if(courseNode instanceof SelfAssessableCourseNode) {
 			boolean increment = incrementAttempts.getAndSet(false);
 			if(increment) {
-				((SelfAssessableCourseNode)courseNode).incrementUserAttempts(userCourseEnv);
+				((SelfAssessableCourseNode)courseNode).incrementUserAttempts(userCourseEnv, Role.user);
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
index 868359e658a5a0c0749eb2c9f8f3f3760900f848..ba1c5bb94d4cd5d1276d3a7372b254f8e2948bad 100644
--- a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
+++ b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
@@ -63,6 +63,7 @@ import org.olat.fileresource.FileResourceManager;
 import org.olat.instantMessaging.CloseInstantMessagingEvent;
 import org.olat.instantMessaging.InstantMessagingService;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.scorm.ScormAPICallback;
 import org.olat.modules.scorm.ScormAPIandDisplayController;
 import org.olat.modules.scorm.ScormCPManifestTreeModel;
@@ -315,7 +316,7 @@ public class ScormRunController extends BasicController implements ScormAPICallb
 			//increment user attempts only once!
 			if(!config.getBooleanSafe(ScormEditController.CONFIG_ADVANCESCORE, true)
 					|| !config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) {
-				scormNode.incrementUserAttempts(userCourseEnv);
+				scormNode.incrementUserAttempts(userCourseEnv, Role.user);
 				attemptsIncremented = true;
 			}
 			
diff --git a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java
index 9c880aac7ded874f16f5c9bc801c9ce4395e974d..5bd7ee684b5dd20f25e9bc8c2b12b0da5fe46947 100644
--- a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java
@@ -64,6 +64,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.properties.Property;
 
 /**
@@ -240,19 +241,19 @@ public class ConvertToGTACourseNode {
 				UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
 				Float score = assessmentData.getScore() == null ? null : assessmentData.getScore().floatValue();
 				ScoreEvaluation scoreEval = new ScoreEvaluation(score, assessmentData.getPassed());
-				assessmentMgr.saveScoreEvaluation(gtaNode, null, assessedIdentity, scoreEval, userCourseEnv, false);
+				assessmentMgr.saveScoreEvaluation(gtaNode, null, assessedIdentity, scoreEval, userCourseEnv, false, Role.auto);
 				
 				//set graded
 				Task task = gtaManager.getTask(assessedIdentity, taskList);
 				if(task == null) {
 					gtaManager.createTask(null, taskList, TaskProcess.graded, null, assessedIdentity, gtaNode);
 				} else {
-					gtaManager.updateTask(task, TaskProcess.graded, gtaNode);
+					gtaManager.updateTask(task, TaskProcess.graded, gtaNode, Role.auto);
 				}
 			}
 			
 			if(assessmentData.getAttempts() != null) {
-				assessmentMgr.saveNodeAttempts(gtaNode, null, assessedIdentity, assessmentData.getAttempts().intValue());
+				assessmentMgr.saveNodeAttempts(gtaNode, null, assessedIdentity, assessmentData.getAttempts().intValue(), Role.auto);
 			}
 			
 			if(StringHelper.containsNonWhitespace(assessmentData.getCoachComment())) {
@@ -366,7 +367,7 @@ public class ConvertToGTACourseNode {
 		if(task == null) {
 			gtaManager.createTask(null, taskList, process, null, assessedIdentity, gtaNode);
 		} else {
-			gtaManager.updateTask(task, process, gtaNode);
+			gtaManager.updateTask(task, process, gtaNode, Role.auto);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxController.java b/src/main/java/org/olat/course/nodes/ta/DropboxController.java
index 22e7892d212ea58d922ac12278d925149bff339f..0e4e4b9794c4fa51664ff01672d2719527047f39 100644
--- a/src/main/java/org/olat/course/nodes/ta/DropboxController.java
+++ b/src/main/java/org/olat/course/nodes/ta/DropboxController.java
@@ -81,6 +81,7 @@ import org.olat.course.nodes.TACourseNode;
 import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 
 /**
  * Initial Date:  02.09.2004
@@ -361,14 +362,7 @@ public class DropboxController extends BasicController {
 		
 		// update attempts counter for this user: one file - one attempts
 		AssessableCourseNode acn = (AssessableCourseNode) node;
-		/*AssessmentEvaluation eval = acn.getUserScoreEvaluation(userCourseEnv);
-		if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) {
-			eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress);
-			acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), true);
-		} else {
-			acn.incrementUserAttempts(userCourseEnv);
-		}*/
-		acn.incrementUserAttempts(userCourseEnv);
+		acn.incrementUserAttempts(userCourseEnv, Role.user);
 				
 		// log entry for this file
 		UserNodeAuditManager am = userCourseEnv.getCourseEnvironment().getAuditManager();
diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
index a23dc5fa6b1995990bff15fd852faf6b71f21f84..fdd08ceae773a451f8937dd5e95d282e5eecfa44 100644
--- a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
+++ b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
@@ -80,6 +80,7 @@ import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.run.scoring.AssessmentEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.properties.Property;
 import org.olat.user.UserManager;
@@ -300,7 +301,7 @@ public class DropboxScoringViewController extends BasicController {
 						AssessmentEvaluation eval = acn.getUserScoreEvaluation(userCourseEnv);
 						if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) {
 							eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress);
-							acn.updateUserScoreEvaluation(eval, userCourseEnv, coach, false);
+							acn.updateUserScoreEvaluation(eval, userCourseEnv, coach, false, Role.coach);
 						}
 					}
 
@@ -339,7 +340,7 @@ public class DropboxScoringViewController extends BasicController {
 					}
 					if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) {
 						eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress);
-						acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false);
+						acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false, Role.coach);
 						fireEvent(ureq, Event.CHANGED_EVENT);
 					}
 				}
diff --git a/src/main/java/org/olat/course/nodes/ta/TaskController.java b/src/main/java/org/olat/course/nodes/ta/TaskController.java
index 994143f34ce0d395749cb7046749844207f5771c..24c4b58a902c381e21d395b3a6c42088e0b08e2e 100644
--- a/src/main/java/org/olat/course/nodes/ta/TaskController.java
+++ b/src/main/java/org/olat/course/nodes/ta/TaskController.java
@@ -66,6 +66,7 @@ import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.scoring.AssessmentEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.properties.Property;
 
@@ -352,7 +353,7 @@ public class TaskController extends BasicController {
 		AssessmentEvaluation eval = node.getUserScoreEvaluation(userCourseEnv);
 		if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) {
 			eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress);
-			node.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false);
+			node.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false, Role.user);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java b/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java
index b165328516dc155de304b12df1c393d4f2891125..3397f8f13a36c2e77b3739decc7b412d7994b789 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java
@@ -44,6 +44,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 
 /**
@@ -103,7 +104,7 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM
 	 * @see org.olat.course.assessment.AssessmentManager#saveNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.core.id.Identity, java.lang.Integer)
 	 */
 	@Override
-	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts) {
+	public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by) {
 		nodeAttempts.put(courseNode.getIdent(), attempts);
 	}
 
@@ -150,7 +151,7 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM
 	 * @see org.olat.course.assessment.AssessmentManager#incrementNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
 	 */
 	@Override
-	public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment) {
+	public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment, Role by) {
 		Integer attempts = nodeAttempts.get(courseNode.getIdent());
 		if (attempts == null) attempts = new Integer(0);
 		int iAttempts = attempts.intValue();
@@ -164,7 +165,12 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM
 	 */
 	@Override
 	public void incrementNodeAttemptsInBackground(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment) {
-		incrementNodeAttempts(courseNode, identity, userCourseEnvironment);
+		incrementNodeAttempts(courseNode, identity, userCourseEnvironment, Role.auto);
+	}
+
+	@Override
+	public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment, Role by) {
+		//
 	}
 
 	/**
@@ -263,13 +269,13 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM
 	 */
 	@Override
 	public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity, ScoreEvaluation scoreEvaluation, 
-			UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts) {
+			UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts, Role by) {
 		
 		saveNodeScore(courseNode, scoreEvaluation.getScore());
 		saveNodePassed(courseNode, scoreEvaluation.getPassed());
 		saveAssessmentID(courseNode, scoreEvaluation.getAssessmentID());
 		if(incrementUserAttempts) {
-			incrementNodeAttempts(courseNode, identity, userCourseEnvironment);
+			incrementNodeAttempts(courseNode, identity, userCourseEnvironment, by);
 		}
 	}
 
diff --git a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
index 984c19141be6559b6af67770c9a896834217f70c..ca43e06edac7b3f66bf0e7760fb0ee57b1bd8f03 100644
--- a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
+++ b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
@@ -19,6 +19,8 @@
  */
 package org.olat.course.run.scoring;
 
+import java.util.Date;
+
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
@@ -37,6 +39,11 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 	private final String comment;
 	private final String coachComment;
 	private final int numOfAssessmentDocs;
+	
+	private final Date lastModified;
+	private final Date lastUserModified;
+	private final Date lastCoachModified;
+	
 
 	public AssessmentEvaluation(Float score, Boolean passed) {
 		this(score, passed, null, null);
@@ -47,16 +54,24 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 	}
 	
 	public AssessmentEvaluation(Float score, Boolean passed, Boolean fullyAssessed, Long assessmentID) {
-		this(score, passed, null, null, null, fullyAssessed, assessmentID, null, null, -1);
+		this(score, passed, null, null, null, fullyAssessed, assessmentID, null, null, -1, null, null, null);
+	}
+	
+	public AssessmentEvaluation(Date lastModified, Date lastUserModified, Date lastCoachModified) {
+		this(null, null, null, null, null, null, null, null, null, -1, lastModified, lastUserModified, lastCoachModified);
 	}
 	
 	public AssessmentEvaluation(Float score, Boolean passed, Integer attempts, AssessmentEntryStatus assessmentStatus, Boolean userVisibility,
-			Boolean fullyAssessed, Long assessmentID, String comment, String coachComment, int numOfAssessmentDocs) {
+			Boolean fullyAssessed, Long assessmentID, String comment, String coachComment, int numOfAssessmentDocs,
+			Date lastModified, Date lastUserModified, Date lastCoachModified) {
 		super(score, passed, assessmentStatus, userVisibility, fullyAssessed, assessmentID);
 		this.attempts = attempts;
 		this.comment = comment;
 		this.coachComment = coachComment;
 		this.numOfAssessmentDocs = numOfAssessmentDocs;
+		this.lastModified = lastModified;
+		this.lastUserModified = lastUserModified;
+		this.lastCoachModified = lastCoachModified;
 	}
 	
 	/**
@@ -67,7 +82,8 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 	 */
 	public AssessmentEvaluation(AssessmentEvaluation eval, AssessmentEntryStatus assessmentStatus) {
 		this(eval.getScore(), eval.getPassed(), eval.getAttempts(), assessmentStatus, eval.getUserVisible(),
-				eval.getFullyAssessed(), eval.getAssessmentID(), eval.getComment(), eval.getCoachComment(), -1);
+				eval.getFullyAssessed(), eval.getAssessmentID(), eval.getComment(), eval.getCoachComment(), -1,
+				eval.getLastModified(), eval.getLastUserModified(), eval.getLastCoachModified());
 	}
 
 	public Integer getAttempts() {
@@ -86,6 +102,18 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 		return numOfAssessmentDocs;
 	}
 	
+	public Date getLastModified() {
+		return lastModified;
+	}
+
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
 	public static final AssessmentEvaluation toAssessmentEvalutation(AssessmentEntry entry, AssessableCourseNode node) {
 		if(entry == null) {
 			return AssessmentEvaluation.EMPTY_EVAL;
@@ -111,6 +139,7 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 			comment = entry.getComment();
 		}
 		return new AssessmentEvaluation(score, passed, attempts, entry.getAssessmentStatus(), entry.getUserVisibility(),
-				entry.getFullyAssessed(), entry.getAssessmentId(), comment, entry.getCoachComment(), entry.getNumberOfAssessmentDocuments());
+				entry.getFullyAssessed(), entry.getAssessmentId(), comment, entry.getCoachComment(), entry.getNumberOfAssessmentDocuments(),
+				entry.getLastModified(), entry.getLastUserModified(), entry.getLastCoachModified());
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
index 1d2697f1a3d892b3bbabf5819d8b9823f9f8d388..970379d59091b60ba6020a58d32bb9724fb322a9 100644
--- a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
+++ b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
@@ -177,6 +177,18 @@ public class ScoreAccounting {
 			return se;
 		}
 		
+		private void updateLastModified(CourseNode cNode, LastModifications lastModifications) {
+			AssessmentEvaluation eval = cachedScoreEvals.get(cNode);
+			if(eval != null) {
+				lastModifications.addLastUserModified(eval.getLastUserModified());
+				lastModifications.addLastCoachModified(eval.getLastCoachModified());
+			}
+			
+			for(int i=cNode.getChildCount(); i-->0; ) {
+				updateLastModified((CourseNode)cNode.getChildAt(i), lastModifications);
+			}
+		}
+		
 		/**
 		 * Recalculate the score of structure nodes.
 		 * 
@@ -196,6 +208,8 @@ public class ScoreAccounting {
 				Boolean userVisibility = entry == null ? null : entry.getUserVisibility();
 				Long assessmendId = entry == null ? null : entry.getAssessmentId();
 				int numOfAssessmentDocs = entry == null ? -1 : entry.getNumberOfAssessmentDocuments();
+				Date lastModified = entry == null ? null : entry.getLastModified();
+				
 				AssessmentEntryStatus assessmentStatus = AssessmentEntryStatus.inProgress;
 				ConditionInterpreter ci = userCourseEnvironment.getConditionInterpreter();
 				if (cNode.hasScoreConfigured() && scoreExpressionStr != null) {
@@ -221,7 +235,11 @@ public class ScoreAccounting {
 						}
 					}
 				}
-				se = new AssessmentEvaluation(score, passed, null, assessmentStatus, userVisibility, null, assessmendId, null, null, numOfAssessmentDocs);
+				
+				LastModifications lastModifications = new LastModifications();
+				updateLastModified(cNode, lastModifications);
+				se = new AssessmentEvaluation(score, passed, null, assessmentStatus, userVisibility, null, assessmendId, null, null, numOfAssessmentDocs,
+						lastModified, lastModifications.getLastUserModified(), lastModifications.getLastCoachModified());
 				
 				if(entry == null) {
 					Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
@@ -235,11 +253,49 @@ public class ScoreAccounting {
 						entry.setScore(null);
 					}
 					entry.setPassed(passed);
+					if(lastModifications.getLastCoachModified() != null
+							&& (entry.getLastCoachModified() == null || (entry.getLastCoachModified() != null && entry.getLastCoachModified().before(lastModifications.getLastCoachModified())))) {
+						entry.setLastCoachModified(lastModifications.getLastCoachModified());
+					}
+					if(lastModifications.getLastUserModified() != null
+							&& (entry.getLastUserModified() == null || (entry.getLastUserModified() != null && entry.getLastUserModified().before(lastModifications.getLastUserModified())))) {
+						entry.setLastUserModified(lastModifications.getLastUserModified());
+					}	
 					entry = userCourseEnvironment.getCourseEnvironment().getAssessmentManager().updateAssessmentEntry(entry);
 					identToEntries.put(cNode.getIdent(), entry);
 					changes = true;
 				}
 			} else {
+				//only update the last modifications dates
+				LastModifications lastModifications = new LastModifications();
+				updateLastModified(cNode, lastModifications);
+				if(entry == null) {
+					if(lastModifications.getLastCoachModified() != null || lastModifications.getLastUserModified() != null) {
+						se = new AssessmentEvaluation(new Date(), lastModifications.getLastUserModified(), lastModifications.getLastCoachModified());
+						Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+						userCourseEnvironment.getCourseEnvironment().getAssessmentManager()
+							.createAssessmentEntry(cNode, assessedIdentity, se);
+						changes = true;
+					}
+				} else {
+					boolean updated = false;
+					if(lastModifications.getLastCoachModified() != null
+							&& (entry.getLastCoachModified() == null || (entry.getLastCoachModified() != null && entry.getLastCoachModified().before(lastModifications.getLastCoachModified())))) {
+						entry.setLastCoachModified(lastModifications.getLastCoachModified());
+						updated = true;
+					}
+					if(lastModifications.getLastUserModified() != null
+							&& (entry.getLastUserModified() == null || (entry.getLastUserModified() != null && entry.getLastUserModified().before(lastModifications.getLastUserModified())))) {
+						entry.setLastUserModified(lastModifications.getLastUserModified());
+						updated = true;
+					}
+					if(updated) {
+						entry = userCourseEnvironment.getCourseEnvironment().getAssessmentManager().updateAssessmentEntry(entry);
+						identToEntries.put(cNode.getIdent(), entry);
+						changes = true;
+					}
+				}
+				
 				se = AssessmentEvaluation.EMPTY_EVAL;
 			}
 			return se;
@@ -278,6 +334,18 @@ public class ScoreAccounting {
 				same &= false;
 			}
 			
+			if((entry.getLastUserModified() == null && se.getLastUserModified() != null)
+					|| (se.getLastUserModified() != null && entry.getLastUserModified() != null
+							&& se.getLastUserModified().after(entry.getLastUserModified()))) {
+				same &= false;
+			}
+			
+			if((entry.getLastCoachModified() == null && se.getLastCoachModified() != null)
+					|| (se.getLastCoachModified() != null && entry.getLastCoachModified() != null
+							&& se.getLastCoachModified().after(entry.getLastCoachModified()))) {
+				same &= false;
+			}
+			
 			return same;
 		}
 	}
@@ -389,5 +457,31 @@ public class ScoreAccounting {
 	public boolean isError() {
 		return error;
 	}
+	
+	private static class LastModifications {
+		
+		private Date lastUserModified;
+		private Date lastCoachModified;
+		
+		public Date getLastUserModified() {
+			return lastUserModified;
+		}
+		
+		public void addLastUserModified(Date date) {
+			if(date != null && (lastUserModified == null || lastUserModified.before(date))) {
+				lastUserModified = date;
+			}
+		}
+		
+		public Date getLastCoachModified() {
+			return lastCoachModified;
+		}
+		
+		public void addLastCoachModified(Date date) {
+			if(date != null && (lastCoachModified == null || lastCoachModified.before(date))) {
+				lastCoachModified = date;
+			}
+		}
+	}
 }
 
diff --git a/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java b/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java
index da10dac2560e8cdf126279f5b1193d4366285a46..dcf627e99aa0b8142e19cd400ade5fb19d3319cb 100644
--- a/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java
+++ b/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java
@@ -65,6 +65,7 @@ import org.olat.ims.qti.process.AssessmentInstance;
 import org.olat.ims.qti.process.FilePersister;
 import org.olat.ims.qti.process.Persister;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQManager;
 import org.olat.modules.iq.IQRetrievedEvent;
 import org.olat.repository.RepositoryEntry;
@@ -262,7 +263,7 @@ public class QTI12ResultDetailsController extends BasicController {
 		Boolean passed = new Boolean(ac.isPassed());
 		ScoreEvaluation sceval = new ScoreEvaluation(score, passed, Boolean.FALSE, new Long(ai.getAssessID()));
 		UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
-		testNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true);
+		testNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true, Role.coach);
 		
 		//cleanup
 		ai.cleanUp();
diff --git a/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java b/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java
index 8a5109464d91aee8b06b5a58d0371db12a5dd397..900258218640013818ddb9509e95aea7a058668e 100644
--- a/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java
+++ b/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java
@@ -58,6 +58,7 @@ import org.olat.ims.qti.process.AssessmentInstance;
 import org.olat.ims.qti.process.FilePersister;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQManager;
 import org.olat.modules.iq.IQRetrievedEvent;
 import org.olat.user.UserManager;
@@ -216,7 +217,7 @@ public class QTI12PullTestsToolController extends BasicController implements Act
 		Boolean passed = new Boolean(ac.isPassed());
 		ScoreEvaluation sceval = new ScoreEvaluation(score, passed, Boolean.FALSE, new Long(ai.getAssessID()));
 		UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
-		courseNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true);
+		courseNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true, Role.coach);
 		
 		//cleanup
 		ai.cleanUp();
diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
index 6cbf6f56dc01a635354553e7302ac3b30945c444..b752b90a0964a392acaeabd033ddfba50a655227 100644
--- a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
@@ -77,6 +77,7 @@ import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentService;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.model.RepositoryEntrySecurity;
@@ -367,7 +368,7 @@ public class QTI21AssessmentDetailsController extends FormBasicController {
 		Float score = finalScore == null ? null : finalScore.floatValue();
 		ScoreEvaluation manualScoreEval = new ScoreEvaluation(score, scoreEval.getPassed(),
 				scoreEval.getAssessmentStatus(), null, scoreEval.getFullyAssessed(), session.getKey());
-		courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false);
+		courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 	}
 	
 	private void doUpdateEntry(AssessmentTestSession session) {
diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java
index 2353e8c1cd9223ba3595a13364b3e90270b4ab7c..99ab6726ce9bffbc021edbb810ea3ee37db2a40c 100644
--- a/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java
@@ -63,6 +63,7 @@ import org.olat.ims.qti21.QTI21Service;
 import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat;
 import org.olat.ims.qti21.model.QTI21StatisticSearchParams;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -200,7 +201,7 @@ public class QTI21ResetToolController extends BasicController {
 				ScoreEvaluation scoreEval = new ScoreEvaluation(null, null);
 				IdentityEnvironment ienv = new IdentityEnvironment(identity, studentRoles);
 				UserCourseEnvironment uce = new UserCourseEnvironmentImpl(ienv, courseEnv);
-				testCourseNode.updateUserScoreEvaluation(scoreEval, uce, getIdentity(), false);
+				testCourseNode.updateUserScoreEvaluation(scoreEval, uce, getIdentity(), false, Role.coach);
 			}
 		} else if(assessedEntry != null) {
 			archiveData(assessedEntry);
diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java
index d288a34f8f7ac2b13ca1c1d3a03b994a96e24934..4f9369b4f2568534f88db56a394cba0a7fd2204d 100644
--- a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java
@@ -40,6 +40,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.ims.qti21.AssessmentTestSession;
 import org.olat.modules.assessment.AssessmentToolOptions;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.ui.event.CompleteAssessmentTestSessionEvent;
 
 /**
@@ -138,7 +139,7 @@ public class QTI21CorrectionToolController extends BasicController {
 				Float score = finalScore == null ? null : finalScore.floatValue();
 				ScoreEvaluation manualScoreEval = new ScoreEvaluation(score, scoreEval.getPassed(),
 						scoreEval.getAssessmentStatus(), scoreEval.getUserVisible(), scoreEval.getFullyAssessed(), testSession.getKey());
-				courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false);
+				courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach);
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
index 9370b4bcf31aeb62bf091f74b5cf84f8d241bcf1..5228d513d1c4f92abb35fef5e34fd9c6ec078340 100644
--- a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
+++ b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
@@ -40,6 +40,14 @@ public interface AssessmentEntry extends AssessmentEntryLight {
 	
 	public Date getLastModified();
 	
+	public Date getLastCoachModified();
+	
+	public void setLastCoachModified(Date date);
+	
+	public Date getLastUserModified();
+	
+	public void setLastUserModified(Date date);
+	
 	public Long getAssessmentId();
 	
 	public void setAssessmentId(Long assessmentId);
diff --git a/src/main/java/org/olat/modules/assessment/AssessmentService.java b/src/main/java/org/olat/modules/assessment/AssessmentService.java
index f9b386b069adb0e516ce4b2743b69865bbb588a3..d977c118d2fdf84a0a387713c1423d850ad16f3b 100644
--- a/src/main/java/org/olat/modules/assessment/AssessmentService.java
+++ b/src/main/java/org/olat/modules/assessment/AssessmentService.java
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.assessment;
 
+import java.util.Date;
 import java.util.List;
 
 import org.olat.core.id.Identity;
@@ -46,7 +47,7 @@ public interface AssessmentService {
 	 * @return
 	 */
 	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
-			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed);
+			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed, Date lastUserModified, Date lastCoachModified);
 	
 	/**
 	 * 
diff --git a/src/main/java/org/olat/modules/assessment/Role.java b/src/main/java/org/olat/modules/assessment/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7cf4ef15bbd1ddedbecf39dabe2f1b089cd2f30
--- /dev/null
+++ b/src/main/java/org/olat/modules/assessment/Role.java
@@ -0,0 +1,34 @@
+/**
+ * <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.modules.assessment;
+
+/**
+ * Say who has done the changes.
+ * 
+ * Initial date: 14 août 2017<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public enum Role {
+	coach,
+	user,
+	auto
+
+}
diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
index 9f5e28d17581aa4e3f9d29a55908e9758c663bb7..298e4564923ecadbcf3c10d5ccdbcf8958d37eb7 100644
--- a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
+++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java
@@ -68,11 +68,13 @@ public class AssessmentEntryDAO {
 	
 	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
 			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry,
-			Float score, Boolean passed) {
+			Float score, Boolean passed, Date lastUserModified, Date lastCoachModified) {
 		
 		AssessmentEntryImpl data = new AssessmentEntryImpl();
 		data.setCreationDate(new Date());
 		data.setLastModified(data.getCreationDate());
+		data.setLastUserModified(lastUserModified);
+		data.setLastCoachModified(lastCoachModified);
 		data.setIdentity(assessedIdentity);
 		data.setAnonymousIdentifier(anonymousIdentifier);
 		data.setRepositoryEntry(entry);
diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
index f9f5890f1d6411a2dc44a7305d6f11858d134252..915da459e073a8122b56350b23225b3f46c7c928 100644
--- a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
+++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java
@@ -21,6 +21,7 @@ package org.olat.modules.assessment.manager;
 
 import java.io.File;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 import org.olat.core.commons.persistence.DB;
@@ -51,8 +52,10 @@ public class AssessmentServiceImpl implements AssessmentService, UserDataDeletab
 	
 	@Override
 	public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier,
-			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed) {
-		return assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry, score, passed);
+			RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry,
+			Float score, Boolean passed, Date lastUserModified, Date lastCoachModified) {
+		return assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry,
+				score, passed, lastUserModified, lastCoachModified);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java b/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java
index ad69459e5be157e630a71b18b73598c267f14c84..85a223f96ae774f678c940a6ca984c87a646e9a5 100644
--- a/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java
+++ b/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java
@@ -74,6 +74,11 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf
 	@Temporal(TemporalType.TIMESTAMP)
 	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
 	private Date lastModified;
+	
+	@Column(name="lastcoachmodified", nullable=true, insertable=true, updatable=true)
+	private Date lastCoachModified;
+	@Column(name="lastusermodified", nullable=true, insertable=true, updatable=true)
+	private Date lastUserModified;
 
 	@Column(name="a_attemtps", nullable=true, insertable=true, updatable=true)
 	private Integer attempts;
@@ -150,6 +155,24 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf
 		this.lastModified = lastModified;
 	}
 
+	@Override
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
+
+	public void setLastCoachModified(Date lastCoachModified) {
+		this.lastCoachModified = lastCoachModified;
+	}
+
+	@Override
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+
+	public void setLastUserModified(Date lastUserModified) {
+		this.lastUserModified = lastUserModified;
+	}
+
 	@Override
 	public Integer getAttempts() {
 		return attempts;
diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java
index 603127f241ee8f3a289ea418deb131713766bbbf..133b11cb9d5843bbd083ff10889024cf2cb51be2 100644
--- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java
+++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java
@@ -43,7 +43,7 @@ public class AssessedIdentityElementRow extends UserPropertiesRow {
 	private final BigDecimal score;
 	private final Boolean passed;
 	private final Date initialCourseLaunchDate;
-	private final Date lastModified;
+	private final Date lastModified, lastUserModified, lastCoachModified;
 	private final int numOfAssessmentDocs;
 	private final AssessmentEntryStatus status;
 	
@@ -57,6 +57,8 @@ public class AssessedIdentityElementRow extends UserPropertiesRow {
 			passed = entry.getPassed();
 			userVisibility = entry.getUserVisibility();
 			lastModified = entry.getLastModified();
+			lastUserModified = entry.getLastUserModified();
+			lastCoachModified = entry.getLastCoachModified();
 			status = entry.getAssessmentStatus();
 			numOfAssessmentDocs = entry.getNumberOfAssessmentDocuments();
 		} else {
@@ -64,7 +66,7 @@ public class AssessedIdentityElementRow extends UserPropertiesRow {
 			score = null;
 			passed = null;
 			userVisibility = null;
-			lastModified = null;
+			lastModified = lastUserModified = lastCoachModified = null;
 			status = null;
 			numOfAssessmentDocs = 0;
 		}
@@ -90,6 +92,14 @@ public class AssessedIdentityElementRow extends UserPropertiesRow {
 	public Date getLastModified() {
 		return lastModified;
 	}
+	
+	public Date getLastUserModified() {
+		return lastUserModified;
+	}
+	
+	public Date getLastCoachModified() {
+		return lastCoachModified;
+	}
 
 	public int getNumOfAssessmentDocs() {
 		return numOfAssessmentDocs;
diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java
index f20d7030d75bd18ac6163ff5b58fcc56f3f08ada..9cc4aafad116dd3b3591bd4f0c30b21429db6859 100644
--- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java
+++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java
@@ -172,9 +172,10 @@ public class AssessedIdentityListController extends FormBasicController implemen
 
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.assessmentStatus, new AssessmentStatusCellRenderer(getLocale())));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, "select"));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastScoreUpdate, "select"));
-		//columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.certificate, new DownloadCertificateCellRenderer()));
-
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastModified, "select"));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastUserModified, "select"));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastCoachModified, "select"));
+		
 		usersTableModel = new AssessedIdentityListTableModel(columnsModel, element);
 		usersTableModel.setCertificateMap(new ConcurrentHashMap<>());
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", usersTableModel, 20, false, getTranslator(), formLayout);
diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java
index 2c264bb907d5a72def7e5e14c6b39cf07a9c6e44..fb80cfbef5266f1b2d968d608081e50f0ac79070 100644
--- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java
+++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java
@@ -137,7 +137,9 @@ public class AssessedIdentityListTableModel extends DefaultFlexiTableDataModel<A
 					return certificateMap.get(row.getIdentityKey());
 				}
 				case initialLaunchDate: return row.getInitialCourseLaunchDate();
-				case lastScoreUpdate: return row.getLastModified();
+				case lastModified: return row.getLastModified();
+				case lastUserModified: return row.getLastUserModified();
+				case lastCoachModified: return row.getLastCoachModified();
 			}
 		}
 		int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET;
@@ -160,7 +162,9 @@ public class AssessedIdentityListTableModel extends DefaultFlexiTableDataModel<A
 		assessmentStatus("table.header.assessmentStatus"),
 		certificate("table.header.certificate"),
 		initialLaunchDate("table.header.initialLaunchDate"),
-		lastScoreUpdate("table.header.lastScoreDate");
+		lastModified("table.header.lastScoreDate"),
+		lastUserModified("table.header.lastUserModificationDate"),
+		lastCoachModified("table.header.lastCoachModificationDate");
 		
 		private final String i18nKey;
 		
diff --git a/src/main/java/org/olat/modules/coach/ui/CourseController.java b/src/main/java/org/olat/modules/coach/ui/CourseController.java
index 0e32abda85f61be9f9599e0c39d8385730f38962..9b7f5c422945371dc2a337d2ff186a3ad7cdbb5b 100644
--- a/src/main/java/org/olat/modules/coach/ui/CourseController.java
+++ b/src/main/java/org/olat/modules/coach/ui/CourseController.java
@@ -200,7 +200,9 @@ public class CourseController extends FormBasicController implements Activateabl
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.recertification, new DateFlexiCellRenderer(getLocale())));
 			}
 		}
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified));
 		
 		model = new EfficiencyStatementEntryTableDataModel(columnsModel);
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout);
diff --git a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java
index e798b68171539a53cccc1b886ca33dd97ca50f53..dd91320d55aa50b0df42eab353ba0139a71dcc4a 100644
--- a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java
+++ b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java
@@ -119,6 +119,14 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat
 					UserEfficiencyStatement s = entry.getUserEfficencyStatement();
 					return s == null ? null : s.getLastModified();
 				}
+				case lastUserModified: {
+					UserEfficiencyStatement s = entry.getUserEfficencyStatement();
+					return s == null ? null : s.getLastUserModified();
+				}
+				case lastCoachModified: {
+					UserEfficiencyStatement s = entry.getUserEfficencyStatement();
+					return s == null ? null : s.getLastCoachModified();
+				}
 				case plannedLectures: {
 					LectureBlockStatistics statistics = getLectureBlockStatistics(entry);
 					return statistics == null ? null : statistics.getTotalPersonalPlannedLectures();
@@ -184,6 +192,8 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat
 		recertification("table.header.recertification"),
 		progress("table.header.progress"),
 		lastModification("table.header.lastScoreDate"),
+		lastUserModified("table.header.lastUserModificationDate"),
+		lastCoachModified("table.header.lastCoachModificationDate"),
 		plannedLectures("table.header.planned.lectures"),
 		attendedLectures("table.header.attended.lectures"),
 		absentLectures("table.header.absent.lectures"),
diff --git a/src/main/java/org/olat/modules/coach/ui/GroupController.java b/src/main/java/org/olat/modules/coach/ui/GroupController.java
index 8a7d81863e9d16c6b39feb3854e1c8d52b090ad3..34627732203bb1c13e05b2997e542f8185012667 100644
--- a/src/main/java/org/olat/modules/coach/ui/GroupController.java
+++ b/src/main/java/org/olat/modules/coach/ui/GroupController.java
@@ -192,7 +192,9 @@ public class GroupController extends FormBasicController implements Activateable
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.score, new ScoreCellRenderer()));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.certificate, new DownloadCertificateCellRenderer()));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.recertification, new DateFlexiCellRenderer(getLocale())));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified));
 		
 		model = new EfficiencyStatementEntryTableDataModel(columnsModel);
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout);
diff --git a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
index 1803bf62ab2cfc022376a9f54f9235d7ca1338ac..d4564cc9b1fcd82baf69cf4e8c7cece616d6209e 100644
--- a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
+++ b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java
@@ -216,7 +216,9 @@ public class StudentCoursesController extends FormBasicController implements Act
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.authorizedAbsenceLectures));
 			}
 		}
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified));
 		
 		model = new EfficiencyStatementEntryTableDataModel(columnsModel);
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout);
diff --git a/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java b/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java
index a63784518862f8e5e1aec1620f67c5e6c1425d42..a5f39cd2291bc595136a613bc6a7e18793c9a368 100644
--- a/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java
+++ b/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java
@@ -24,7 +24,6 @@ import java.util.List;
 
 import org.olat.core.gui.components.table.TableDataModel;
 import org.olat.course.assessment.UserEfficiencyStatement;
-import org.olat.modules.coach.model.EfficiencyStatementEntry;
 
 /**
  * 
@@ -94,10 +93,6 @@ public class UserEfficiencyStatementTableDataModel implements TableDataModel<Use
 	public UserEfficiencyStatement getObject(int row) {
 		return group.get(row);
 	}
-	
-	public int indexOf(EfficiencyStatementEntry obj) {
-		return group.indexOf(obj);
-	}
 
 	@Override
 	public void setObjects(List<UserEfficiencyStatement> objects) {
diff --git a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties
index 47ddc78431e1b3fb5d30f72c4a47db1ce6c5f4b0..564727e7aa63b25973e4eab268fc613fb5cb4a28 100644
--- a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties
@@ -54,6 +54,8 @@ table.header.countCourses=# Kurs
 table.header.countStudents=# Teilnehmer
 table.header.course.name=Kurs
 table.header.lastScoreDate=$org.olat.course.assessment\:table.header.lastScoreDate
+table.header.lastUserModificationDate=$org.olat.course.assessment\:table.header.lastUserModificationDate
+table.header.lastCoachModificationDate=$org.olat.course.assessment\:table.header.lastCoachModificationDate
 table.header.login=Eingeloggt
 table.header.passed=$org.olat.course.assessment\:table.header.passed
 table.header.progress=Fortschritt
diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
index 4ad46daca880590aaa052c8f92827ac40a1e760a..26300b8d25c15b6c4ca6abc1d0304788d46784e4 100644
--- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
+++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java
@@ -21,6 +21,8 @@ package org.olat.modules.portfolio;
 
 import java.util.List;
 
+import org.olat.modules.assessment.Role;
+
 /**
  * 
  * Initial date: 15.06.2016<br>
@@ -117,6 +119,9 @@ public interface BinderSecurityCallback {
 	public boolean canViewAssess(PortfolioElement element);
 	
 	public boolean canViewAssessment();
+	
+
+	public Role getRole();
  
 
 }
diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
index 62c9a07f850ee4de555742f8d61d36f8abe69f1c..d153850d5c7459c551df07f6dea1cc9fa390eb8f 100644
--- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
+++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.olat.core.CoreSpringFactory;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.portfolio.model.AccessRights;
 import org.olat.repository.model.RepositoryEntrySecurity;
 
@@ -102,7 +103,12 @@ public class BinderSecurityCallbackFactory {
 		public boolean canRestorePage(Page page) {
 			return page.getPageStatus() == PageStatus.deleted;
 		}
-		
+
+		@Override
+		public Role getRole() {
+			return Role.user;
+		}
+
 	}
 	
 	private static class BinderSecurityCallbackForDeletedBinder extends DefaultBinderSecurityCallback {
@@ -680,6 +686,11 @@ public class BinderSecurityCallbackFactory {
 			}
 			return false;
 		}
+
+		@Override
+		public Role getRole() {
+			return owner ? Role.user : Role.coach;
+		}
 	}
 	
 	private static class DefaultBinderSecurityCallback implements BinderSecurityCallback {
@@ -842,6 +853,11 @@ public class BinderSecurityCallbackFactory {
 		@Override
 		public boolean canViewAssessment() {
 			return false;
-		}	
+		}
+
+		@Override
+		public Role getRole() {
+			return Role.coach;
+		}
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/portfolio/PortfolioService.java b/src/main/java/org/olat/modules/portfolio/PortfolioService.java
index 2d2e632c2ae86f4b73618de959419c17cda46e09..09f5a4e6a1e61079916c92debda50457a4129c08 100644
--- a/src/main/java/org/olat/modules/portfolio/PortfolioService.java
+++ b/src/main/java/org/olat/modules/portfolio/PortfolioService.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import org.olat.basesecurity.IdentityRef;
 import org.olat.core.id.Identity;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.portfolio.model.AccessRightChange;
 import org.olat.modules.portfolio.model.AccessRights;
@@ -544,9 +545,11 @@ public interface PortfolioService {
 	 * Change the status of the page.
 	 * @param page
 	 * @param status
+	 * @param identity The user which does the change
+	 * @param by The role of the user which does the change
 	 * @return
 	 */
-	public Page changePageStatus(Page page, PageStatus status);
+	public Page changePageStatus(Page page, PageStatus status, Identity identity, Role by);
 	
 	/**
 	 * Close the section
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 18de9c42d1512561ab8b263d925b9c7476a75dd8..7e5a0667a7baf211ebed69b8c77880a059ef0838 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java
@@ -61,6 +61,7 @@ import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.fileresource.FileResourceManager;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.AssessmentService;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.forms.EvaluationFormSessionStatus;
 import org.olat.modules.forms.manager.EvaluationFormSessionDAO;
@@ -1030,7 +1031,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 	}
 
 	@Override
-	public Page changePageStatus(Page page, PageStatus status) {
+	public Page changePageStatus(Page page, PageStatus status, Identity identity, Role by) {
 		PageStatus currentStatus = page.getPageStatus();
 		Page reloadedPage = pageDao.loadByKey(page.getKey());
 		((PageImpl)reloadedPage).setPageStatus(status);
@@ -1069,6 +1070,11 @@ public class PortfolioServiceImpl implements PortfolioService {
 				}
 			}
 		}
+		if(reloadedPage.getSection() != null && reloadedPage.getSection().getBinder() != null) {
+			Binder binder = reloadedPage.getSection().getBinder();
+			updateAssessmentEntryLastModification(binder, identity, by);
+		}
+		
 		return pageDao.updatePage(reloadedPage);
 	}
 	
@@ -1117,6 +1123,39 @@ public class PortfolioServiceImpl implements PortfolioService {
 		reloadedSection = binderDao.updateSection(reloadedSection);
 		return reloadedSection;
 	}
+	
+	private void updateAssessmentEntryLastModification(Binder binder, Identity doer, Role by) {
+		if(binder.getEntry() == null) return;
+
+		RepositoryEntry entry = binder.getEntry();
+		List<Identity> assessedIdentities = getMembers(binder, PortfolioRoles.owner.name());
+
+		//order status from the entry / section
+		if("CourseModule".equals(entry.getOlatResource().getResourceableTypeName())) {
+			ICourse course = CourseFactory.loadCourse(entry);
+			CourseNode courseNode = course.getRunStructure().getNode(binder.getSubIdent());
+			if(courseNode instanceof PortfolioCourseNode) {
+				PortfolioCourseNode pfNode = (PortfolioCourseNode)courseNode;
+				for(Identity assessedIdentity:assessedIdentities) {
+					UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
+					pfNode.updateLastModifications(userCourseEnv, doer, by);
+				}
+			}
+		} else {
+			OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource();
+			RepositoryEntry referenceEntry = repositoryService.loadByResourceKey(resource.getKey());
+			for(Identity assessedIdentity:assessedIdentities) {
+				AssessmentEntry assessmentEntry = assessmentService
+						.getOrCreateAssessmentEntry(assessedIdentity, null, binder.getEntry(), binder.getSubIdent(), referenceEntry);
+				if(by == Role.coach) {
+					assessmentEntry.setLastCoachModified(new Date());
+				} else if(by == Role.user) {
+					assessmentEntry.setLastUserModified(new Date());
+				}
+				assessmentService.updateAssessmentEntry(assessmentEntry);
+			}
+		}
+	}
 
 	@Override
 	public List<AssessmentSection> getAssessmentSections(BinderRef binder, Identity coach) {
@@ -1212,7 +1251,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 				PortfolioCourseNode pfNode = (PortfolioCourseNode)courseNode;
 				ScoreEvaluation scoreEval= new ScoreEvaluation(totalScore.floatValue(), totalPassed, binderStatus, true, true, binder.getKey());
 				UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course);
-				pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false);
+				pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false, Role.coach);
 			}
 		} else {
 			OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource();
@@ -1268,7 +1307,7 @@ public class PortfolioServiceImpl implements PortfolioService {
 				AssessmentEvaluation eval = pfNode.getUserScoreEvaluation(userCourseEnv);
 				
 				ScoreEvaluation scoreEval= new ScoreEvaluation(eval.getScore(), eval.getPassed(), status, true, fullyAssessed, binder.getKey());
-				pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false);
+				pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false, Role.coach);
 			}
 		} else {
 			OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource();
diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java
index 6e6327a8d2448322c378a4aff39b352a51c611da..74295bb0d76d5fa5491959bf7e1bc8c7f73bae5e 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java
@@ -397,12 +397,12 @@ public class BinderListController extends FormBasicController
 		if(binder.isChanged()) {
 			showInfo("warning.binder.synched");
 		}
-		BinderController binderCtrl = doOpenBinder(ureq, binder.getBinder());
+		BinderController selectedBinderCtrl = doOpenBinder(ureq, binder.getBinder());
 		if(row instanceof BinderRow) {
 			VFSLeaf image = portfolioService.getPosterImageLeaf(binder.getBinder());
 			((BinderRow)row).setBackgroundImage(image);
 		}
-		return binderCtrl;
+		return selectedBinderCtrl;
 	}
 	
 	protected BinderController doOpenBinder(UserRequest ureq, Binder binder) {
diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java
index 8396e02beb44eacacf2e0e22459193fba40ce586..918f95d3573457c0fa4eae74cb5a632b486b7b3d 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java
@@ -396,7 +396,7 @@ public class PageRunController extends BasicController implements TooledControll
 	}
 	
 	private void doPublish(UserRequest ureq) {
-		page = portfolioService.changePageStatus(page, PageStatus.published);
+		page = portfolioService.changePageStatus(page, PageStatus.published, getIdentity(), secCallback.getRole());
 		stackPanel.popUpToController(this);
 		loadMeta(ureq);
 		loadModel(ureq, false);
@@ -412,7 +412,7 @@ public class PageRunController extends BasicController implements TooledControll
 	}
 	
 	private void doRevision(UserRequest ureq) {
-		page = portfolioService.changePageStatus(page, PageStatus.inRevision);
+		page = portfolioService.changePageStatus(page, PageStatus.inRevision, getIdentity(), secCallback.getRole());
 		stackPanel.popUpToController(this);
 		loadMeta(ureq);
 		loadModel(ureq, false);
@@ -426,7 +426,7 @@ public class PageRunController extends BasicController implements TooledControll
 	}
 	
 	private void doClose(UserRequest ureq) {
-		page = portfolioService.changePageStatus(page, PageStatus.closed);
+		page = portfolioService.changePageStatus(page, PageStatus.closed, getIdentity(), secCallback.getRole());
 		stackPanel.popUpToController(this);
 		loadMeta(ureq);
 		loadModel(ureq, true);
@@ -440,7 +440,7 @@ public class PageRunController extends BasicController implements TooledControll
 	}
 	
 	private void doReopen(UserRequest ureq) {
-		page = portfolioService.changePageStatus(page, PageStatus.published);
+		page = portfolioService.changePageStatus(page, PageStatus.published, getIdentity(), secCallback.getRole());
 		stackPanel.popUpToController(this);
 		loadMeta(ureq);
 		loadModel(ureq, true);
diff --git a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java
index d0ed978cba332eb5caef7d2ed7e78dace59c70e2..a12e31ca98fd9ccd70106eb5656865699abbbfc8 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java
@@ -33,6 +33,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.util.StringHelper;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.portfolio.Binder;
 import org.olat.modules.portfolio.Page;
 import org.olat.modules.portfolio.PageStatus;
@@ -158,7 +159,7 @@ public class RestorePageController extends FormBasicController {
 
 	@Override
 	protected void formOK(UserRequest ureq) {
-		page = portfolioService.changePageStatus(page, PageStatus.draft);
+		page = portfolioService.changePageStatus(page, PageStatus.draft, getIdentity(), Role.user);
 
 		SectionRef selectSection = getSelectedSection();
 		if((page.getSection() == null && selectSection != null) ||
diff --git a/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java b/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java
index df215148b59a893917a1c989312af598342e0a9a..7d0e4038050fade721454e39af01feb921a23c2e 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java
@@ -54,7 +54,6 @@ public class StandardEditMediaController extends FormBasicController {
 	private TextBoxListElement categoriesEl;
 
 	private Media mediaReference;
-	private final String businessPath;
 	private Map<String,String> categories = new HashMap<>();
 	
 	@Autowired
@@ -63,7 +62,6 @@ public class StandardEditMediaController extends FormBasicController {
 	public StandardEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		super(ureq, wControl);
 		setTranslator(Util.createPackageTranslator(PortfolioHomeController.class, getLocale(), getTranslator()));
-		businessPath = media.getBusinessPath();
 		mediaReference = media;
 		
 		List<Category> categoryList = portfolioService.getCategories(media);
diff --git a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
index 6454c4021d080df9116d824e8e29d84bea50a7a9..3a41494cb6fde67267eee3e222319df64a749b79 100644
--- a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
+++ b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
@@ -55,6 +55,7 @@ import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.user.UserManager;
 
 /**
@@ -199,14 +200,14 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 				// </OLATEE-27>
 				boolean increment = !attemptsIncremented && finish;
 				ScoreEvaluation sceval = new ScoreEvaluation(new Float(0.0f), Boolean.valueOf(passed));
-				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment);
+				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user);
 				if(increment) {
 					attemptsIncremented = true;
 				}
 			} else if (!config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) {
 				boolean increment = !attemptsIncremented && finish;
 				ScoreEvaluation sceval = scormNode.getUserScoreEvaluation(userCourseEnv);
-				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment);
+				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user);
 				if(increment) {
 					attemptsIncremented = true;
 				}
@@ -214,7 +215,7 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 		} else {
 			boolean increment = !attemptsIncremented && finish;
 			ScoreEvaluation sceval = new ScoreEvaluation(new Float(0.0f), Boolean.valueOf(passed));
-			scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false);
+			scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false, Role.user);
 			if(increment) {
 				attemptsIncremented = true;
 			}
@@ -254,14 +255,14 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 				// </OLATEE-27>
 				boolean increment = !attemptsIncremented && finish;
 				ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), Boolean.valueOf(passed));
-				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment);
+				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user);
 				if(increment) {
 					attemptsIncremented = true;
 				}
 			} else if (!config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) {
 				boolean increment = !attemptsIncremented && finish;
 				ScoreEvaluation sceval = scormNode.getUserScoreEvaluation(userCourseEnv);
-				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment);
+				scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user);
 				if(increment) {
 					attemptsIncremented = true;
 				}
@@ -274,7 +275,7 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 			// </OLATEE-27>
 			boolean increment = !attemptsIncremented && finish;
 			ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), Boolean.valueOf(passed));
-			scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false);
+			scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false, Role.user);
 			if(increment) {
 				attemptsIncremented = true;
 			}
diff --git a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java
index 694ee888bb3489b39211e029b18b0915d2f21328..1fa0c11ea1a99dcb2dc711c724d3a47d7608f5c2 100755
--- a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java
+++ b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java
@@ -54,6 +54,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
 import org.olat.group.DeletableGroupData;
 import org.olat.modules.assessment.AssessmentService;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.modules.webFeed.portfolio.LiveBlogArtefactHandler;
 import org.olat.portfolio.PortfolioModule;
@@ -1148,10 +1149,10 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData
 	 * @param map
 	 */
 	public void submitMap(PortfolioStructureMap map) {
-		submitMap(map, true);
+		submitMap(map, true, Role.user);
 	}
 	
-	private void submitMap(PortfolioStructureMap map, boolean logActivity) {
+	private void submitMap(PortfolioStructureMap map, boolean logActivity, Role by) {
 		if(!(map instanceof EPStructuredMap)) return;//add an exception
 		
 		EPStructuredMap submittedMap = (EPStructuredMap)map;
@@ -1170,7 +1171,7 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData
 				ienv.setIdentity(owner);
 				UserCourseEnvironment uce = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment());
 				if(logActivity) {
-					am.incrementNodeAttempts(courseNode, owner, uce);
+					am.incrementNodeAttempts(courseNode, owner, uce, by);
 				} else {
 					am.incrementNodeAttemptsInBackground(courseNode, owner, uce);
 				}
@@ -1192,7 +1193,7 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData
 		List<PortfolioStructureMap> mapsToClose = structureManager.getOpenStructuredMapAfterDeadline();
 		int count = 0;
 		for(PortfolioStructureMap mapToClose:mapsToClose) {
-			submitMap(mapToClose, false);
+			submitMap(mapToClose, false, Role.auto);
 			if(count % 5 == 0) {
 				// this possibly takes longer than connection timeout, so do intermediatecommits.
 				dbInstance.intermediateCommit();
diff --git a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java
index 179c2290e97df3d6e8e5cac796176015e8d9838f..7f9fc07dec0d4c66d5e7ee150cbaa8d4e49ca53b 100644
--- a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java
@@ -80,6 +80,7 @@ import org.olat.ims.qti.navigator.Navigator;
 import org.olat.ims.qti.process.AssessmentFactory;
 import org.olat.ims.qti.process.AssessmentInstance;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.iq.IQManager;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
@@ -329,7 +330,7 @@ public class CourseAssessmentWebService {
 			} else {
 				AssessableCourseNode assessableNode = (AssessableCourseNode) node;
 				ScoreEvaluation scoreEval = new ScoreEvaluation(resultsVO.getScore(), Boolean.TRUE, Boolean.TRUE, new Long(nodeKey));//not directly pass this key
-				assessableNode.updateUserScoreEvaluation(scoreEval, userCourseEnvironment, requestIdentity, true);
+				assessableNode.updateUserScoreEvaluation(scoreEval, userCourseEnvironment, requestIdentity, true, Role.coach);
 			}
 
 			CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
@@ -440,7 +441,7 @@ public class CourseAssessmentWebService {
 				AssessableCourseNode acn = (AssessableCourseNode) courseNode;
 				// assessment nodes are assessable
 				boolean incrementUserAttempts = true;
-				acn.updateUserScoreEvaluation(sceval, userCourseEnv, identity, incrementUserAttempts);
+				acn.updateUserScoreEvaluation(sceval, userCourseEnv, identity, incrementUserAttempts, Role.coach);
 			} else {
 				log.error("Result set already saved");
 			}
diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java
index ce7fa7090f3e79f89ec0446f174ffe6c7f52da46..4cb4d3151e53ab4a467e774614b4516b26bfc4af 100644
--- a/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java
+++ b/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java
@@ -26,14 +26,44 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 
+import org.olat.core.commons.modules.bc.FolderConfig;
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
+import org.olat.core.id.Roles;
 import org.olat.core.util.WebappHelper;
+import org.olat.course.CorruptedCourseException;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.manager.EfficiencyStatementManager;
+import org.olat.course.assessment.model.UserEfficiencyStatementImpl;
+import org.olat.course.nodes.CourseNode;
+import org.olat.course.nodes.IQTESTCourseNode;
+import org.olat.course.nodes.MSCourseNode;
+import org.olat.course.nodes.ScormCourseNode;
+import org.olat.course.nodes.iq.IQEditController;
+import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.fileresource.types.BlogFileResource;
+import org.olat.fileresource.types.ImsQTI21Resource;
 import org.olat.fileresource.types.PodcastFileResource;
+import org.olat.ims.qti.QTIResultSet;
+import org.olat.ims.qti21.AssessmentTestSession;
+import org.olat.ims.qti21.QTI21Service;
+import org.olat.modules.assessment.AssessmentService;
+import org.olat.modules.assessment.model.AssessmentEntryImpl;
+import org.olat.modules.iq.IQManager;
 import org.olat.modules.webFeed.manager.FeedManager;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryRef;
+import org.olat.repository.RepositoryManager;
+import org.olat.repository.model.SearchRepositoryEntryParameters;
 import org.olat.resource.OLATResource;
 import org.olat.resource.OLATResourceManager;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,14 +76,27 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class OLATUpgrade_12_0_0 extends OLATUpgrade {
 
+	private static final int BATCH_SIZE = 50;
+	
 	private static final String VERSION = "OLAT_12.0.0";
 	private static final String FEED_XML_TO_DB = "FEED XML TO DB";
 	private static final String USER_PROPERTY_CONTEXT_RENAME = "USER PROPERTY CONTEXT RENAME";
+	private static final String LAST_USER_MODIFICATION = "LAST USER MODIFICATION";
 	
 	@Autowired
 	private DB dbInstance;
 	@Autowired
-	FeedManager feedManager;
+	private FeedManager feedManager;
+	@Autowired
+	private QTI21Service qtiService;
+	@Autowired
+	private IQManager iqManager;
+	@Autowired
+	private AssessmentService assessmentService;
+	@Autowired
+	private RepositoryManager repositoryManager;
+	@Autowired
+	private EfficiencyStatementManager efficiencyStatementManager;
 	
 	public OLATUpgrade_12_0_0() {
 		super();
@@ -84,6 +127,7 @@ public class OLATUpgrade_12_0_0 extends OLATUpgrade {
 		allOk &= upgradeBlogXmlToDb(upgradeManager, uhd);
 		// rename a user property context name to a more suitable name
 		allOk &= changeUserPropertyContextName(upgradeManager, uhd);
+		allOk &= upgradeLastModified(upgradeManager, uhd);
 		
 		uhd.setInstallationComplete(allOk);
 		upgradeManager.setUpgradesHistory(uhd, VERSION);
@@ -181,5 +225,176 @@ public class OLATUpgrade_12_0_0 extends OLATUpgrade {
 		}
 		return allOk;
 	}
+	
+	private boolean upgradeLastModified(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
+		boolean allOk = true;
+		if (!uhd.getBooleanDataValue(LAST_USER_MODIFICATION)) {
+			
+			int counter = 0;
+			final Roles roles = new Roles(true, true, true, true, false, true, false);
+			final SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters();
+			params.setRoles(roles);
+			params.setResourceTypes(Collections.singletonList("CourseModule"));
+			
+			List<RepositoryEntry> courses;
+			do {
+				courses = repositoryManager.genericANDQueryWithRolesRestriction(params, counter, 50, true);
+				for(RepositoryEntry course:courses) {
+					try {
+						allOk &= processCourseAssessmentLastModified(course);
+					} catch (CorruptedCourseException e) {
+						log.error("Corrupted course: " + course.getKey(), e);
+					}
+				}
+				counter += courses.size();
+				log.audit("Last modifications migration processed: " + courses.size() + ", total courses processed (" + counter + ")");
+				dbInstance.commitAndCloseSession();
+			} while(courses.size() == BATCH_SIZE);
+			
+			
+			uhd.setBooleanDataValue(LAST_USER_MODIFICATION, allOk);
+			upgradeManager.setUpgradesHistory(uhd, VERSION);
+		}
+		return allOk;
+	}
+	
+	
+	private boolean processCourseAssessmentLastModified(RepositoryEntry entry) {
+		try {
+			ICourse course = CourseFactory.loadCourse(entry);	
+			CourseNode rootNode = course.getRunStructure().getRootNode();
+			Set<Identity> changeSet = new HashSet<>();
+			processCourseNodeAssessmentLastModified(course, entry, rootNode, changeSet);
+			dbInstance.commitAndCloseSession();
+			
+			//update structure nodes and efficiency statement if any
+			Set<Identity> identitiesWithEfficiencyStatements = findIdentitiesWithEfficiencyStatements(entry);
+			for(Identity assessedIdentity:changeSet) {
+				UserCourseEnvironment userCourseEnv = AssessmentHelper
+						.createInitAndUpdateUserCourseEnvironment(assessedIdentity, course);
+				if(identitiesWithEfficiencyStatements.contains(assessedIdentity)) {
+					efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv);
+				}
+				dbInstance.commitAndCloseSession();
+			}
+		} catch(CorruptedCourseException e) {
+			log.error("Corrupted course: " + entry.getKey(), e);
+		} catch (Exception e) {
+			log.error("Unexpected error", e);
+		} finally {
+			dbInstance.commitAndCloseSession();
+		}
+		return true;
+	}
+	
+	private boolean processCourseNodeAssessmentLastModified(ICourse course, RepositoryEntry entry, CourseNode courseNode, Set<Identity> changeSet) {
+		if(courseNode instanceof IQTESTCourseNode) {
+			updateTest(entry, (IQTESTCourseNode)courseNode, changeSet);
+		} else if(courseNode instanceof MSCourseNode) {
+			updateMS(entry, courseNode, changeSet);
+		} else if(courseNode instanceof ScormCourseNode) {
+			updateScorm(course, entry, courseNode, changeSet);
+		}
+		dbInstance.commitAndCloseSession();
+
+		for(int i=courseNode.getChildCount(); i-->0; ) {
+			CourseNode child = (CourseNode)courseNode.getChildAt(i);
+			processCourseNodeAssessmentLastModified(course, entry, child, changeSet);
+		}
+		return true;
+	}
+	
+	private void updateTest(RepositoryEntry entry, IQTESTCourseNode courseNode, Set<Identity> changeSet) {
+		boolean onyx = IQEditController.CONFIG_VALUE_QTI2.equals(courseNode.getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE_QTI));
+		if (onyx) return;
+		
+		RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry();
+		OLATResource ores = testEntry.getOlatResource();
+		boolean qti21 = ImsQTI21Resource.TYPE_NAME.equals(ores.getResourceableTypeName());
 
+		List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, courseNode.getIdent());
+		for(AssessmentEntryImpl assessmentEntry:assessmentEntries) {
+			if(assessmentEntry.getLastUserModified() != null || assessmentEntry.getLastCoachModified() != null)  continue;
+
+			if(qti21) {
+				Long assessmentId = assessmentEntry.getAssessmentId();
+				if(assessmentId != null) {
+					AssessmentTestSession session = qtiService.getAssessmentTestSession(assessmentEntry.getAssessmentId());
+					if(session != null && session.getFinishTime() != null) {
+						assessmentEntry.setLastUserModified(session.getFinishTime());
+						assessmentService.updateAssessmentEntry(assessmentEntry);
+						changeSet.add(assessmentEntry.getIdentity());
+					}
+				}
+			} else {
+				long olatResource = entry.getOlatResource().getResourceableId().longValue();
+				QTIResultSet rset = iqManager.getLastResultSet(assessmentEntry.getIdentity(), olatResource, courseNode.getIdent());
+				if(rset != null && rset.getLastModified() != null ) {
+					assessmentEntry.setLastUserModified(rset.getLastModified());
+					assessmentService.updateAssessmentEntry(assessmentEntry);
+					changeSet.add(assessmentEntry.getIdentity());
+				}
+			}
+		}
+	}
+
+	private void updateMS(RepositoryEntry entry, CourseNode msNode, Set<Identity> changeSet) {
+		List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, msNode.getIdent());
+		for(AssessmentEntryImpl assessmentEntry:assessmentEntries) {
+			if(assessmentEntry.getLastCoachModified() != null) continue;
+			
+			assessmentEntry.setLastCoachModified(assessmentEntry.getLastModified());
+			assessmentService.updateAssessmentEntry(assessmentEntry);
+			changeSet.add(assessmentEntry.getIdentity());
+		}
+	}
+	
+	private void updateScorm(ICourse course, RepositoryEntry entry, CourseNode scormNode, Set<Identity> changeSet) {
+		Long courseId = course.getResourceableId();
+		String courseIdNodeId = courseId + "-" + scormNode.getIdent();
+		Calendar cal = Calendar.getInstance();
+		
+		List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, scormNode.getIdent());
+		for(AssessmentEntryImpl assessmentEntry:assessmentEntries) {
+			if(assessmentEntry.getLastUserModified() != null || assessmentEntry.getLastCoachModified() != null) continue;
+			
+			String userId = assessmentEntry.getIdentity().getName();
+			String path = FolderConfig.getCanonicalRoot() + "/scorm/" + userId + "/" + courseIdNodeId;
+			File quiz = new File(path, "thequiz.xml");
+			if(quiz.exists()) {
+				long lastModified = quiz.lastModified();
+				if(lastModified > 0) {
+					cal.setTimeInMillis(lastModified);
+					assessmentEntry.setLastUserModified(cal.getTime());
+					assessmentService.updateAssessmentEntry(assessmentEntry);
+					changeSet.add(assessmentEntry.getIdentity());
+				}
+			}
+		}
+	}
+	
+	private List<AssessmentEntryImpl> loadAssessmentEntries(RepositoryEntryRef courseEntry, String subIdent) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select data from assessmententry data")
+		  .append(" inner join fetch data.identity ident")
+		  .append(" where data.repositoryEntry.key=:courseEntryKey and data.subIdent=:subIdent")
+		  .append(" and data.lastUserModified is null and data.lastCoachModified is null");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), AssessmentEntryImpl.class)
+				.setParameter("courseEntryKey", courseEntry.getKey())
+				.setParameter("subIdent", subIdent)
+				.getResultList();
+	}
+	
+	private Set<Identity> findIdentitiesWithEfficiencyStatements(RepositoryEntryRef courseRepoEntry) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select distinct(statement.identity) from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
+		  .append(" where statement.lastUserModified is null and statement.lastCoachModified is null and statement.courseRepoKey=:repoKey");
+
+		List<Identity> identities = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Identity.class)
+				.setParameter("repoKey", courseRepoEntry.getKey())
+				.getResultList();
+		return new HashSet<>(identities);
+	}
 }
diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java
index 0584402f61706c3c384ae6ecd2efa6926b33f91c..30e7b4ff2dc318ee63ccd98dcb0d895cdb223cbe 100644
--- a/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java
+++ b/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java
@@ -173,7 +173,7 @@ public class OLATUpgrade_8_1_0 extends OLATUpgrade {
 		}
 
 		EfficiencyStatement s = (EfficiencyStatement)XStreamHelper.createXStreamInstance().fromXML(property.getTextValue());
-		efficiencyStatementManager.fillEfficiencyStatement(s, statement);
+		efficiencyStatementManager.fillEfficiencyStatement(s, null, statement);
 		statement.setLastModified(property.getLastModified());
 		
 		dbInstance.saveObject(statement);
diff --git a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql
index 1cbc01a36778b603419ba6715a07bbea0e0f5dbe..84b3cf4b96a3d6cc1e1f7dce914f5884d81dbb7c 100644
--- a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql
+++ b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql
@@ -255,4 +255,10 @@ alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_
 alter table o_info_message add column attachmentpath varchar(1024) default null;
 
 
+alter table o_as_entry add column lastcoachmodified datetime default null;
+alter table o_as_entry add column lastusermodified datetime default null;
+
+alter table o_as_eff_statement add column lastcoachmodified datetime default null;
+alter table o_as_eff_statement add column lastusermodified datetime default null;
+
 
diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql
index 4b21ab2d9dfcd27c0cbd4416209151e4320eb468..9d66eadc414e6989775b8d0569e14bf5553cdf18 100644
--- a/src/main/resources/database/mysql/setupDatabase.sql
+++ b/src/main/resources/database/mysql/setupDatabase.sql
@@ -1127,6 +1127,8 @@ create table if not exists o_as_eff_statement (
    id bigint not null,
    version mediumint unsigned not null,
    lastmodified datetime,
+   lastcoachmodified datetime,
+   lastusermodified datetime,
    creationdate datetime,
    passed bit default null,
    score float(65,30),
@@ -1161,6 +1163,8 @@ create table o_as_entry (
    id bigint not null auto_increment,
    creationdate datetime not null,
    lastmodified datetime not null,
+   lastcoachmodified datetime,
+   lastusermodified datetime,
    a_attemtps bigint default null,
    a_score float(65,30) default null,
    a_passed bit default null,
diff --git a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql
index 895acf581f141aed088961a2c4d67f6ebd68ac4c..0b060d8af1b7a04e2886884b1772a6990b4007a6 100644
--- a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql
+++ b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql
@@ -256,3 +256,13 @@ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identit
 
 alter table alter table o_info_message add attachmentpath varchar(1024) default null;
 
+
+alter table o_as_entry add lastcoachmodified date default null;
+alter table o_as_entry add lastusermodified date default null;
+
+alter table o_as_eff_statement add column lastcoachmodified date default null;
+alter table o_as_eff_statement add column lastusermodified date default null;
+
+
+
+
diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql
index 22088d9ab8d095e9f8cc9d38090ea8a70415061a..95cdca54ad97ddd38a5aec795de2fcf5b1e1e056 100644
--- a/src/main/resources/database/oracle/setupDatabase.sql
+++ b/src/main/resources/database/oracle/setupDatabase.sql
@@ -1154,6 +1154,8 @@ create table o_as_eff_statement (
    id number(20) not null,
    version number(20) not null,
    lastmodified date,
+   lastcoachmodified date,
+   lastusermodified date,
    creationdate date,
    passed number,
    score float(4),
@@ -1189,6 +1191,8 @@ create table o_as_entry (
    id number(20) GENERATED ALWAYS AS IDENTITY,
    creationdate date not null,
    lastmodified date not null,
+   lastcoachmodified date,
+   lastusermodified date,
    a_attemtps number(20) default null,
    a_score decimal default null,
    a_passed number default null,
diff --git a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql
index 7a4fd7d2fe48f7dd8e0a292abb05e803bcacc5d5..4a0d80df14799fc36f04fbc90af4b907e923731b 100644
--- a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql
+++ b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql
@@ -257,6 +257,11 @@ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identit
 alter table o_info_message add column attachmentpath varchar(1024) default null;
 
 
+alter table o_as_entry add column lastcoachmodified timestamp default null;
+alter table o_as_entry add column lastusermodified timestamp default null;
+
+alter table o_as_eff_statement add column lastcoachmodified timestamp default null;
+alter table o_as_eff_statement add column lastusermodified timestamp default null;
 
 
 
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index 723deaec2fa5b3fd220f7b6240a7e3ed23ce2ef8..34b12f8da9c67164441a8a85db8e1a015c9350d8 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -1123,6 +1123,8 @@ create table o_as_eff_statement (
    id int8 not null,
    version int4 not null,
    lastmodified timestamp,
+   lastcoachmodified timestamp,
+   lastusermodified timestamp,
    creationdate timestamp,
    passed boolean,
    score float4,
@@ -1159,6 +1161,8 @@ create table o_as_entry (
    id bigserial,
    creationdate timestamp not null,
    lastmodified timestamp not null,
+   lastcoachmodified timestamp,
+   lastusermodified timestamp,
    a_attemtps int8 default null,
    a_score decimal default null,
    a_passed bool default null,
diff --git a/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java b/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java
index 851ca4ae359d0800e3be9ef14bb26872a61e904d..bb40e0ed1874f68f85b79e33161c22bf168a1b3e 100644
--- a/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java
+++ b/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java
@@ -59,6 +59,7 @@ import org.olat.course.nodes.CourseNode;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
+import org.olat.modules.assessment.Role;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.test.JunitTestHelper;
@@ -162,7 +163,7 @@ public class AssessmentManagerTest extends OlatTestCase  {
 		UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment());
 		boolean incrementAttempts = true;
 		//assessableCourseNode.updateUserScoreEvaluation(scoreEvaluation, userCourseEnv, tutor, incrementAttempts); //alternative
-		assessmentManager.saveScoreEvaluation(assessableCourseNode, tutor, student, scoreEvaluation, userCourseEnv, incrementAttempts);
+		assessmentManager.saveScoreEvaluation(assessableCourseNode, tutor, student, scoreEvaluation, userCourseEnv, incrementAttempts, Role.coach);
 		DBFactory.getInstance().closeSession();
 		//the attempts mut have been incremented
 		//assertEquals(attempts, assessableCourseNode.getUserAttempts(userCourseEnv)); //alternative
@@ -175,7 +176,7 @@ public class AssessmentManagerTest extends OlatTestCase  {
 		//assessableCourseNode.updateUserUserComment(userComment, userCourseEnv, tutor); //alternative
     
 		attempts++;
-		assessmentManager.saveNodeAttempts(assessableCourseNode, tutor, student, attempts);
+		assessmentManager.saveNodeAttempts(assessableCourseNode, tutor, student, attempts, Role.coach);
 		assertEquals(attempts, assessmentManager.getNodeAttempts(assessableCourseNode, student));    	
 		//assessableCourseNode.updateUserAttempts(attempts, userCourseEnv, tutor); //alternative
 		        
diff --git a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
index c205043a6173e298a1f8f0b15460818d6a6b146a..5226817d9741bcb53c8e6c80026f0e625b0352a5 100644
--- a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
+++ b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java
@@ -96,10 +96,10 @@ public class AssessmentToolManagerTest extends OlatTestCase {
 		dbInstance.commitAndCloseSession();
 		
 		// some datas
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 5.0f, Boolean.TRUE);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 8.0f, Boolean.TRUE);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 9.0f, Boolean.TRUE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 5.0f, Boolean.TRUE, null, null);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 8.0f, Boolean.TRUE, null, null);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 9.0f, Boolean.TRUE, null, null);
 		assessmentEntryDao.createAssessmentEntry(null, UUID.randomUUID().toString(), entry, subIdent, refEntry);
 		dbInstance.commitAndCloseSession();
 		
diff --git a/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java b/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java
index 0b8aa3883814b890a3a71f1f1e284a9e1251b94f..899b5a35b578395071a8cf75a4f0858a8f1fad34 100644
--- a/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java
+++ b/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java
@@ -20,15 +20,24 @@
 package org.olat.course.nodes.gta.manager;
 
 import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.UUID;
 
 import org.junit.Assert;
 import org.junit.Test;
 import org.olat.basesecurity.GroupRoles;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.nodes.INode;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.AssignmentResponse;
 import org.olat.course.nodes.gta.AssignmentResponse.Status;
@@ -56,6 +65,8 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class GTAManagerTest extends OlatTestCase {
 	
+	private static final OLog log = Tracing.createLoggerFor(GTAManagerTest.class);
+	
 	@Autowired
 	private DB dbInstance;
 	@Autowired
@@ -69,8 +80,8 @@ public class GTAManagerTest extends OlatTestCase {
 	
 	@Test
 	public void createIfNotExists() {
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		Assert.assertNotNull(node.getIdent());
 		
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
@@ -100,8 +111,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void selectTask_identity() {
 		//prepare
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("solo.txt");
@@ -132,8 +143,8 @@ public class GTAManagerTest extends OlatTestCase {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2");
 		BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false);
 		dbInstance.commit();
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("bg.txt");
@@ -165,8 +176,8 @@ public class GTAManagerTest extends OlatTestCase {
 		BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false);
 		businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name());
 		dbInstance.commit();
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("bg.txt");
@@ -187,8 +198,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void isTaskAssigned() {
 		//create an individual task
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-6");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -211,8 +222,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void isTaskInProcess() {
 		//prepare
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-11");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("solo.txt");
@@ -238,8 +249,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void isTasksInProcess_yes() {
 		//prepare
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-12");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("solo.txt");
@@ -260,8 +271,8 @@ public class GTAManagerTest extends OlatTestCase {
 	@Test
 	public void isTasksInProcess_no() {
 		//prepare
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		Assert.assertNotNull(tasks);
@@ -277,8 +288,8 @@ public class GTAManagerTest extends OlatTestCase {
 		//create an individual task
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList taskList = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -301,8 +312,8 @@ public class GTAManagerTest extends OlatTestCase {
 		//create an individual task
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList taskList = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -334,8 +345,8 @@ public class GTAManagerTest extends OlatTestCase {
 		//create an individual task
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7");
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList taskList = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -401,8 +412,8 @@ public class GTAManagerTest extends OlatTestCase {
 		BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false);
 		businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name());
 		dbInstance.commit();
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("bg.txt");
@@ -442,10 +453,10 @@ public class GTAManagerTest extends OlatTestCase {
 		BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false);
 		businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name());
 		dbInstance.commit();
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re = deployGTACourse();
 		
 		//node 1
-		GTACourseNode node1 = new GTACourseNode();
+		GTACourseNode node1 = getGTACourseNode(re);
 		node1.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name());
 		TaskList tasks1 = gtaManager.createIfNotExists(re, node1);
 		File taskFile = new File("bg.txt");
@@ -499,11 +510,11 @@ public class GTAManagerTest extends OlatTestCase {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-9");
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-10");
 		dbInstance.commit();
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re = deployGTACourse();
 		repositoryEntryRelationDao.addRole(coach, re, GroupRoles.coach.name());
 		repositoryEntryRelationDao.addRole(participant, re, GroupRoles.participant.name());
 
-		GTACourseNode node = new GTACourseNode();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		File taskFile = new File("bg.txt");
@@ -542,25 +553,25 @@ public class GTAManagerTest extends OlatTestCase {
 		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-21");
 		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-22");
 		
-		RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re1 = deployGTACourse();
 		repositoryEntryRelationDao.addRole(coach, re1, GroupRoles.coach.name());
 		repositoryEntryRelationDao.addRole(participant1, re1, GroupRoles.participant.name());
 		repositoryEntryRelationDao.addRole(participant2, re1, GroupRoles.participant.name());
 		
 		//course 1
-		GTACourseNode node1 = new GTACourseNode();
+		GTACourseNode node1 = getGTACourseNode(re1);
 		node1.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks1 = gtaManager.createIfNotExists(re1, node1);
 		File taskFile = new File("bg.txt");
 		Assert.assertNotNull(tasks1);
 		dbInstance.commit();
 
-		RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re2 = deployGTACourse();
 		repositoryEntryRelationDao.addRole(coach, re2, GroupRoles.coach.name());
 		repositoryEntryRelationDao.addRole(participant1, re2, GroupRoles.participant.name());
 
 		//participant 2 course 2
-		GTACourseNode node2 = new GTACourseNode();
+		GTACourseNode node2 = getGTACourseNode(re2);
 		node2.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks2 = gtaManager.createIfNotExists(re2, node2);
 		Assert.assertNotNull(tasks2);
@@ -615,8 +626,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void createTaskRevisionDate() {
 		//prepare
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-20");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -640,8 +651,8 @@ public class GTAManagerTest extends OlatTestCase {
 	public void getTaskRevisions() {
 		//prepare
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-21");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
-		GTACourseNode node = new GTACourseNode();
+		RepositoryEntry re = deployGTACourse();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		TaskList tasks = gtaManager.createIfNotExists(re, node);
 		dbInstance.commit();
@@ -723,4 +734,31 @@ public class GTAManagerTest extends OlatTestCase {
 		String nextSlot = gtaManager.nextSlotRoundRobin(slots, usedSlots);
 		Assert.assertEquals("C", nextSlot);
 	}
+	
+	private RepositoryEntry deployGTACourse() {
+		try {
+			Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-author");
+			String displayname = "GTA-" + UUID.randomUUID();
+			
+			URL courseUrl = JunitTestHelper.class.getResource("file_resources/GTA_course.zip");
+			File courseFile = new File(courseUrl.toURI());
+			return JunitTestHelper.deployCourse(initialAuthor, displayname, courseFile);
+		} catch (URISyntaxException e) {
+			log.error("", e);
+			return null;
+		}
+	}
+	
+	private GTACourseNode getGTACourseNode(RepositoryEntry courseEntry) {
+		ICourse course = CourseFactory.loadCourse(courseEntry);
+		CourseNode rootNode = course.getRunStructure().getRootNode();
+		for(int i=rootNode.getChildCount(); i-->0; ) {
+			INode child = rootNode.getChildAt(i);
+			if(child instanceof GTACourseNode) {
+				return ((GTACourseNode)child);
+			}
+		}
+		
+		return null;
+	}
 }
diff --git a/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java b/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java
index aa88c554cad581ca7f4c88ee86224a72fda9119a..6d78418506b6aefb8390b39f6119d2bcf8ebbe91 100644
--- a/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java
+++ b/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java
@@ -20,6 +20,8 @@
 package org.olat.course.nodes.gta.rule;
 
 import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
@@ -32,9 +34,14 @@ import org.olat.basesecurity.GroupRoles;
 import org.olat.basesecurity.model.GroupMembershipImpl;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.nodes.INode;
+import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.course.assessment.model.UserCourseInfosImpl;
+import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.AssignmentResponse;
 import org.olat.course.nodes.gta.GTARelativeToDates;
@@ -66,6 +73,8 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class GTAReminderRuleTest extends OlatTestCase {
 	
+	private static final OLog log = Tracing.createLoggerFor(GTAReminderRuleTest.class);
+	
 	@Autowired
 	private DB dbInstance;
 	@Autowired
@@ -92,12 +101,12 @@ public class GTAReminderRuleTest extends OlatTestCase {
 		//prepare a course with a volatile task
 		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1");
 		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re = deployGTACourse();
 		repositoryEntryRelationDao.addRole(participant1, re, GroupRoles.participant.name());
 		repositoryEntryRelationDao.addRole(participant2, re, GroupRoles.participant.name());
 		dbInstance.commit();
 		
-		GTACourseNode node = new GTACourseNode();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		
 		Calendar cal = Calendar.getInstance();
@@ -404,12 +413,12 @@ public class GTAReminderRuleTest extends OlatTestCase {
 		//prepare a course with a volatile task
 		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1");
 		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2");
-		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false);
+		RepositoryEntry re = deployGTACourse();
 		repositoryEntryRelationDao.addRole(participant1, re, GroupRoles.participant.name());
 		repositoryEntryRelationDao.addRole(participant2, re, GroupRoles.participant.name());
 		dbInstance.commit();
 		
-		GTACourseNode node = new GTACourseNode();
+		GTACourseNode node = getGTACourseNode(re);
 		node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
 		
 		Calendar cal = Calendar.getInstance();
@@ -599,4 +608,31 @@ public class GTAReminderRuleTest extends OlatTestCase {
 		rule.setRightUnit(unit.name());
 		return rule;
 	}
+	
+	private RepositoryEntry deployGTACourse() {
+		try {
+			Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-reminder");
+			String displayname = "GTARemind-" + UUID.randomUUID();
+			
+			URL courseUrl = JunitTestHelper.class.getResource("file_resources/GTA_course.zip");
+			File courseFile = new File(courseUrl.toURI());
+			return JunitTestHelper.deployCourse(initialAuthor, displayname, courseFile);
+		} catch (URISyntaxException e) {
+			log.error("", e);
+			return null;
+		}
+	}
+	
+	private GTACourseNode getGTACourseNode(RepositoryEntry courseEntry) {
+		ICourse course = CourseFactory.loadCourse(courseEntry);
+		CourseNode rootNode = course.getRunStructure().getRootNode();
+		for(int i=rootNode.getChildCount(); i-->0; ) {
+			INode child = rootNode.getChildAt(i);
+			if(child instanceof GTACourseNode) {
+				return ((GTACourseNode)child);
+			}
+		}
+		
+		return null;
+	}
 }
diff --git a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
index 6957815923569a03be5dcc57d7b480b55436f3a1..fc20ce32f2f0710f82ccdebcb4e7102a6f2cedb6 100644
--- a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
+++ b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
@@ -174,7 +174,7 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
 		String subIdent = UUID.randomUUID().toString();
 		AssessmentEntry nodeAssessmentRef = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE);
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		AssessmentEntry resetedAssessmentRef = assessmentEntryDao
@@ -210,11 +210,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		// load with our subIdent above
@@ -239,9 +239,9 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		
 		String subIdent = UUID.randomUUID().toString();
 		assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, null, entry, 3.0f, Boolean.FALSE);
-		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
+		assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 
 		// id 1,2,3 are in the entry, but 4 is in an other entry and must not appears in the list
@@ -265,11 +265,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		// load for identity 1
@@ -321,11 +321,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		//load the assessment entries of entry
@@ -350,11 +350,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessment1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessment2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessment3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessment4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		// delete by reference
@@ -389,11 +389,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessment1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessment2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessment3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessment4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		dbInstance.commitAndCloseSession();
 		
 		// delete by reference
@@ -433,17 +433,17 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		AssessmentEntry nodeAssessmentId1 = assessmentEntryDao
 				.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry);
 		AssessmentEntry nodeAssessmentId2 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 0.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 0.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId3 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 12.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 12.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId4 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId5 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 6.0f, Boolean.TRUE);
+				.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 6.0f, Boolean.TRUE, null, null);
 		AssessmentEntry nodeAssessmentId6 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 1.0f, Boolean.FALSE);
+				.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 1.0f, Boolean.FALSE, null, null);
 		AssessmentEntry nodeAssessmentId7 = assessmentEntryDao
-				.createAssessmentEntry(assessedIdentity5, null, entry, subIdent, refEntry, 10.0f, Boolean.TRUE);
+				.createAssessmentEntry(assessedIdentity5, null, entry, subIdent, refEntry, 10.0f, Boolean.TRUE, null, null);
 		dbInstance.commitAndCloseSession();
 		// load with our subIdent above
 		List<AssessmentEntry> assessmentEntries = assessmentEntryDao
diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
index 55a6408ca7044c2b59ff9e31dfb976f1f5fbf00f..97936acfb3d47e2c3a5224d2250710636f6b3698 100644
--- a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
+++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
@@ -50,6 +50,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
 import org.olat.group.manager.BusinessGroupDAO;
 import org.olat.group.manager.BusinessGroupRelationDAO;
+import org.olat.modules.assessment.Role;
 import org.olat.modules.reminder.ReminderRule;
 import org.olat.modules.reminder.model.ReminderRuleImpl;
 import org.olat.modules.reminder.rule.CourseEnrollmentDateRuleSPI;
@@ -1059,7 +1060,7 @@ public class ReminderRuleEngineTest extends OlatTestCase {
 		ienv.setIdentity(student);
 		UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment());
 
-		course.getCourseEnvironment().getAssessmentManager().saveScoreEvaluation(testNode, tutor, student, scoreEval, userCourseEnv, true);
+		course.getCourseEnvironment().getAssessmentManager().saveScoreEvaluation(testNode, tutor, student, scoreEval, userCourseEnv, true, Role.coach);
 		dbInstance.commit();
 		
 		return testNode.getIdent();
diff --git a/src/test/java/org/olat/test/JunitTestHelper.java b/src/test/java/org/olat/test/JunitTestHelper.java
index 54119607a6fd01f0f324fa29fd6af2fda8e7966f..ee9b93f298ba7069a243d29f9239c45aefad4322 100644
--- a/src/test/java/org/olat/test/JunitTestHelper.java
+++ b/src/test/java/org/olat/test/JunitTestHelper.java
@@ -245,4 +245,26 @@ public class JunitTestHelper {
 		}
 		return re;
 	}
+	
+	/**
+	 * Deploy a course with only a single page.
+	 * @param initialAuthor
+	 * @return
+	 */
+	public static RepositoryEntry deployCourse(Identity initialAuthor, String displayname, File courseFile) {		
+		String description = "A course";
+
+		RepositoryEntry re = null;
+		try {
+			RepositoryHandler courseHandler = RepositoryHandlerFactory.getInstance()
+					.getRepositoryHandler(CourseModule.getCourseTypeName());
+			re = courseHandler.importResource(initialAuthor, null, displayname, description, true, Locale.ENGLISH, courseFile, null);
+			
+			ICourse course = CourseFactory.loadCourse(re);
+			CourseFactory.publishCourse(course, RepositoryEntry.ACC_USERS, false,  initialAuthor, Locale.ENGLISH);
+		} catch (Exception e) {
+			log.error("", e);
+		}
+		return re;
+	}
 }
diff --git a/src/test/java/org/olat/test/file_resources/GTA_course.zip b/src/test/java/org/olat/test/file_resources/GTA_course.zip
new file mode 100644
index 0000000000000000000000000000000000000000..1e1dadbfb9a55800ba8715461d2d38a86a2f6a92
Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/GTA_course.zip differ