diff --git a/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java b/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
index 69b65b8351a51c5489c6548d787b4e5b7df65d32..47ef44323af4456772b017ab7a93f379710fb601 100644
--- a/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
+++ b/src/main/java/org/olat/core/util/mail/manager/MailManagerImpl.java
@@ -1846,12 +1846,16 @@ public class MailManagerImpl implements MailManager, InitializingBean  {
 			logRecipients(msg, RecipientType.TO);
 			logRecipients(msg, RecipientType.BCC);
 			logRecipients(msg, RecipientType.CC);
-			log.info("Content    : {}", msg.getContent());
-			
-			//File file = new File("/HotCoffee/tmp/mail_" + CodeHelper.getForeverUniqueID() + ".msg");
-			//OutputStream os = new FileOutputStream(file);
-			//msg.writeTo(os);
-			//IOUtils.closeQuietly(os);
+			Object content = msg.getContent();
+			if(content instanceof MimeMultipart) {
+				MimeMultipart mmp = (MimeMultipart)content;
+				for(int i=0; i<mmp.getCount(); i++) {
+					if(i > 0) log.info("---------------------");
+					log.info("Content    : {}", mmp.getBodyPart(i).getContent());
+				}
+			} else {
+				log.info("Content    : {}", msg.getContent());
+			}
 		} catch (IOException e) {
 			log.error("", e);
 		}
diff --git a/src/main/java/org/olat/modules/grading/manager/GradingServiceImpl.java b/src/main/java/org/olat/modules/grading/manager/GradingServiceImpl.java
index b43e5bfdd4876f4fb76912428cd0e66eedc5cf4b..3dc42793329b359988ab20b639846ac0ed1f2dd3 100644
--- a/src/main/java/org/olat/modules/grading/manager/GradingServiceImpl.java
+++ b/src/main/java/org/olat/modules/grading/manager/GradingServiceImpl.java
@@ -67,6 +67,7 @@ import org.olat.modules.grading.GradingAssignment;
 import org.olat.modules.grading.GradingAssignmentRef;
 import org.olat.modules.grading.GradingAssignmentStatus;
 import org.olat.modules.grading.GradingModule;
+import org.olat.modules.grading.GradingNotificationType;
 import org.olat.modules.grading.GradingService;
 import org.olat.modules.grading.GradingTimeRecord;
 import org.olat.modules.grading.GradingTimeRecordRef;
@@ -614,18 +615,42 @@ public class GradingServiceImpl implements GradingService, UserDataDeletable, Re
 		return sendResult;
 	}
 	
-	private MailerResult reminder(Identity recipient, RepositoryEntry entry, String subject, String body) {
+	private void notificationDaily(Identity grader, RepositoryEntry referenceEntry,
+			List<GradingAssignment> assignments, String subject, String body) {
 		
+		Set<RepositoryEntry> entries = new HashSet<>();
+		for(GradingAssignment assignment: assignments) {
+			RepositoryEntry entry = assignment.getAssessmentEntry().getRepositoryEntry();
+			entries.add(entry);
+		}
+
+		Set<CourseNode> courseNodes = new HashSet<>();
+		for(RepositoryEntry entry:entries) {
+			ICourse course = CourseFactory.loadCourse(entry);
+			Set<String> courseNodeIds = assignments.stream()
+					.filter(assignment -> entry.equals(assignment.getAssessmentEntry().getRepositoryEntry()))
+					.map(assignment -> assignment.getAssessmentEntry().getSubIdent())
+					.collect(Collectors.toSet());
+			for(String courseNodeId:courseNodeIds) {
+				CourseNode courseNode = course.getRunStructure().getNode(courseNodeId);
+				courseNodes.add(courseNode);
+			}
+		}
+
 		GraderMailTemplate template = new GraderMailTemplate(subject, body);
-		decorateGraderMailTemplate(entry, template);
+		// test and taxonomy
+		decorateGraderMailTemplate(referenceEntry, template);
+		
+		template.setEntries(new ArrayList<>(entries));
+		template.setAssessmentDate(assignments.get(0).getAssessmentDate());
+		template.setCourseNodes(new ArrayList<>(courseNodes));
 
 		MailContext context = new MailContextImpl("[CoachSite:0][Grading:0]");
 		
 		MailerResult result = new MailerResult();
-		MailBundle bundle = mailManager.makeMailBundle(context, recipient, template, null, null, result);
+		MailBundle bundle = mailManager.makeMailBundle(context, grader, template, null, null, result);
 		MailerResult sendResult = mailManager.sendMessage(bundle);
 		result.append(sendResult);
-		return sendResult;
 	}
 	
 	private GradingAssignment decorateGraderMailTemplate(GradingAssignment assignment, GraderMailTemplate template) {
@@ -653,21 +678,33 @@ public class GradingServiceImpl implements GradingService, UserDataDeletable, Re
 		if(referenceEntry == null || template == null) return;
 
 		template.setReferenceEntry(referenceEntry);
-		
+
+		StringBuilder taxonomyLevelPath = new StringBuilder();
 		List<TaxonomyLevel> levels = repositoryEntryToTaxonomyLevelDao.getTaxonomyLevels(referenceEntry);
-		String taxonomyLevels = taxonomyLevelToString(levels);
+
+		String taxonomyLevels = taxonomyLevelToString(new ArrayList<>(levels));
 		template.setTaxonomyLevel(taxonomyLevels);
 		
-		if(levels.size() == 1) {
-			TaxonomyLevel level = levels.get(0);
-			List<TaxonomyLevel> parentLine = taxonomyLevelDao.getParentLine(level, level.getTaxonomy());
-			
-			StringBuilder sb = new StringBuilder(256);
-			for(TaxonomyLevel parent:parentLine) {
-				if(sb.length() > 0) sb.append(" / ");
-				sb.append(parent.getDisplayName());
+		if(!levels.isEmpty()) {
+			for(TaxonomyLevel level:levels) {
+				List<TaxonomyLevel> parentLine = taxonomyLevelDao.getParentLine(level, level.getTaxonomy());
+				
+				StringBuilder sb = new StringBuilder(256);
+				for(TaxonomyLevel parent:parentLine) {
+					if(sb.length() > 0) sb.append(" / ");
+					sb.append(parent.getDisplayName());
+				}
+				
+				if(taxonomyLevelPath.length() > 0) {
+					taxonomyLevelPath.append(", ");
+				}
+				taxonomyLevelPath.append(sb);
 			}
 		}
+		
+		if(taxonomyLevelPath.length() > 0) {
+			template.setTaxonomyLevelPath(taxonomyLevelPath.toString());
+		}
 	}
 	
 	@Override
@@ -680,24 +717,45 @@ public class GradingServiceImpl implements GradingService, UserDataDeletable, Re
 		}	
 	}
 	
-	public void sendGraderAsssignmentsNotification(Identity grader) {
-		List<GradingAssignment> assignmentsToNotify = gradingAssignmentDao.getAssignmentsForGradersNotify(grader);
+	public void sendGraderAsssignmentNotification(GraderToIdentity grader, RepositoryEntry referenceEntry,
+			GradingAssignment assignment, RepositoryEntryGradingConfiguration config) {
+
+		GraderMailTemplate mailTemplate = new GraderMailTemplate(config.getNotificationSubject(), config.getNotificationBody());
+		decorateGraderMailTemplate(referenceEntry, mailTemplate);
 
-		List<RepositoryEntry> newReferenceEntries = assignmentsToNotify.stream()
+		MailerResult result = new MailerResult();
+		MailContext context = new MailContextImpl("[RepositoryEntry:0][Grading:0]");
+		decorateGraderMailTemplate(assignment, mailTemplate);
+		doSendEmails(context, Collections.singletonList(grader), mailTemplate, result);
+	}
+	
+	public void sendGraderAsssignmentsNotification(Identity grader) {
+		List<GradingAssignment> assignments = gradingAssignmentDao.getAssignmentsForGradersNotify(grader);
+		List<GradingAssignment> assignmentsToNotify= assignments.stream()
 				.filter(assignment -> assignment.getAssignmentNotificationDate() == null)
-				.map(GradingAssignment::getReferenceEntry)
 				.distinct().collect(Collectors.toList());
-		for(RepositoryEntry newReferenceEntry:newReferenceEntries) {
-			RepositoryEntryGradingConfiguration config = gradingConfigurationDao.getConfiguration(newReferenceEntry);
-			if(StringHelper.containsNonWhitespace(config.getNotificationBody())) {
-				reminder(grader, newReferenceEntry, config.getNotificationSubject(), config.getNotificationBody());
-			}
-		}
 		
-		Date now = new Date();
-		for(GradingAssignment assignmentToNotify:assignmentsToNotify) {
-			assignmentToNotify.setAssignmentNotificationDate(now);
-			gradingAssignmentDao.updateAssignment(assignmentToNotify);
+		if(!assignmentsToNotify.isEmpty()) {
+			List<RepositoryEntry> newReferenceEntries = assignmentsToNotify.stream()
+					.map(GradingAssignment::getReferenceEntry)
+					.distinct().collect(Collectors.toList());
+			for(RepositoryEntry newReferenceEntry:newReferenceEntries) {
+				RepositoryEntryGradingConfiguration config = gradingConfigurationDao.getConfiguration(newReferenceEntry);
+				List<GradingAssignment> refAssignmentsToNotify = assignmentsToNotify.stream()
+						.filter(assignment -> newReferenceEntry.equals(assignment.getReferenceEntry()))
+						.collect(Collectors.toList());
+				if(config.getNotificationTypeEnum() == GradingNotificationType.onceDay
+						&& StringHelper.containsNonWhitespace(config.getNotificationBody())
+						&& !refAssignmentsToNotify.isEmpty()) {
+					notificationDaily(grader, newReferenceEntry, refAssignmentsToNotify, config.getNotificationSubject(), config.getNotificationBody());
+				}
+			}
+			
+			Date now = new Date();
+			for(GradingAssignment assignmentToNotify:assignmentsToNotify) {
+				assignmentToNotify.setAssignmentNotificationDate(now);
+				gradingAssignmentDao.updateAssignment(assignmentToNotify);
+			}
 		}
 		dbInstance.commitAndCloseSession();
 	}
@@ -721,8 +779,15 @@ public class GradingServiceImpl implements GradingService, UserDataDeletable, Re
 			deadLine = CalendarUtils.addWorkingDays(new Date(), config.getGradingPeriod().intValue());
 			deadLine = CalendarUtils.endOfDay(deadLine);
 		}
-		gradingAssignmentDao.createGradingAssignment(choosedGrader, referenceEntry, assessmentEntry, new Date(), deadLine);
+		assignment = gradingAssignmentDao.createGradingAssignment(choosedGrader, referenceEntry, assessmentEntry, new Date(), deadLine);
 		dbInstance.commit();
+		
+		if(config != null && config.getNotificationTypeEnum() == GradingNotificationType.afterTestSubmission) {
+			sendGraderAsssignmentNotification(choosedGrader, referenceEntry, assignment, config);
+			assignment.setAssignmentNotificationDate(new Date());
+			gradingAssignmentDao.updateAssignment(assignment);
+			dbInstance.commit();
+		}
 	}
 	
 	protected GraderToIdentity selectGrader(RepositoryEntry referenceEntry) {
diff --git a/src/main/java/org/olat/modules/grading/ui/component/GraderMailTemplate.java b/src/main/java/org/olat/modules/grading/ui/component/GraderMailTemplate.java
index edc7d7b9ab12c256a4a3be3bc6dfccbecd6d043c..218e223c23f5f8e63bc37b2008e34569c70e4a7d 100644
--- a/src/main/java/org/olat/modules/grading/ui/component/GraderMailTemplate.java
+++ b/src/main/java/org/olat/modules/grading/ui/component/GraderMailTemplate.java
@@ -20,6 +20,7 @@
 package org.olat.modules.grading.ui.component;
 
 import java.util.Date;
+import java.util.List;
 import java.util.Locale;
 
 import org.apache.velocity.VelocityContext;
@@ -49,6 +50,9 @@ public class GraderMailTemplate extends MailTemplate {
 	private CourseNode courseNode;
 	private RepositoryEntry referenceEntry;
 	
+	private List<RepositoryEntry> entries;
+	private List<CourseNode> courseNodes;
+	
 	private String taxonomyLevel;
 	private String taxonomyLevelPath;
 	
@@ -56,13 +60,6 @@ public class GraderMailTemplate extends MailTemplate {
 		super(subject, body, null);
 	}
 	
-	private GraderMailTemplate(RepositoryEntry entry, CourseNode courseNode, RepositoryEntry referenceEntry) {
-		super(null, null, null);
-		this.entry = entry;
-		this.courseNode = courseNode;
-		this.referenceEntry = referenceEntry;
-	}
-	
 	private GraderMailTemplate(String templateName, RepositoryEntry entry, CourseNode courseNode, RepositoryEntry referenceEntry) {
 		super(null, null, null);
 		setTemplateName(templateName);
@@ -155,6 +152,14 @@ public class GraderMailTemplate extends MailTemplate {
 	public void setEntry(RepositoryEntry entry) {
 		this.entry = entry;
 	}
+	
+	public List<RepositoryEntry> getEntries() {
+		return entries;
+	}
+
+	public void setEntries(List<RepositoryEntry> entries) {
+		this.entries = entries;
+	}
 
 	public CourseNode getCourseNode() {
 		return courseNode;
@@ -164,6 +169,14 @@ public class GraderMailTemplate extends MailTemplate {
 		this.courseNode = courseNode;
 	}
 
+	public List<CourseNode> getCourseNodes() {
+		return courseNodes;
+	}
+
+	public void setCourseNodes(List<CourseNode> courseNodes) {
+		this.courseNodes = courseNodes;
+	}
+
 	public RepositoryEntry getReferenceEntry() {
 		return referenceEntry;
 	}
@@ -187,22 +200,87 @@ public class GraderMailTemplate extends MailTemplate {
 	public void setTaxonomyLevelPath(String taxonomyLevelPath) {
 		this.taxonomyLevelPath = taxonomyLevelPath;
 	}
+	
+	private void putCourseVariablesInMailContext(VelocityContext vContext, RepositoryEntry entry) {
+		String url = Settings.getServerContextPathURI() + "/url/RepositoryEntry/" + entry.getKey();
+		putVariablesInMailContext(vContext, "courseUrl", url);
+		putVariablesInMailContext(vContext, "courseName", entry.getDisplayname());
+		putVariablesInMailContext(vContext, "courseTitle", entry.getDisplayname());
+		if(StringHelper.containsNonWhitespace(entry.getExternalRef())) {
+			putVariablesInMailContext(vContext, "courseReference", entry.getExternalRef());
+		}
+	}
+	
+	private void putCourseNodeVariablesInMailContext(VelocityContext vContext, CourseNode courseNode) {
+		String title = courseNode.getLongTitle();
+		if(!StringHelper.containsNonWhitespace(title)) {
+			title = courseNode.getShortTitle();
+		}
+		putVariablesInMailContext(vContext, "courseElementTitle", title);
+		putVariablesInMailContext(vContext, "courseElementShortTitle", courseNode.getShortTitle());
+	}
+	
+	private void putCourseNodeVariablesInMailContext(VelocityContext vContext, List<CourseNode> courseNodes) {
+		StringBuilder titleSb = new StringBuilder();
+		StringBuilder shortTitleSb = new StringBuilder();
+		for(CourseNode node:courseNodes) {
+			String title = node.getLongTitle();
+			if(!StringHelper.containsNonWhitespace(title)) {
+				title = node.getShortTitle();
+			}
+			if(titleSb.length() > 0) titleSb.append(", ");
+			if(shortTitleSb.length() > 0) shortTitleSb.append(", ");
+			
+			titleSb.append(title);
+			shortTitleSb.append(node.getShortTitle());
+		}
+		
+		putVariablesInMailContext(vContext, "courseElementTitle", titleSb.toString());
+		putVariablesInMailContext(vContext, "courseElementShortTitle", shortTitleSb.toString());
+	}
+	
+	private void putCourseVariablesInMailContext(VelocityContext vContext, List<RepositoryEntry> entries) {
+		StringBuilder urlSb = new StringBuilder();
+		StringBuilder courseNameSb = new StringBuilder();
+		StringBuilder courseReferenceSb = new StringBuilder();
+		
+		for(RepositoryEntry courseEntry:entries) {
+			String url = Settings.getServerContextPathURI() + "/url/RepositoryEntry/" + courseEntry.getKey();
+			if(urlSb.length() > 0) urlSb.append(", ");
+			urlSb.append(url);
+			
+			String name = courseEntry.getDisplayname();
+			if(courseNameSb.length() > 0) courseNameSb.append(", ");
+			courseNameSb.append(name);
+			
+			if(StringHelper.containsNonWhitespace(courseEntry.getExternalRef())) {
+				if(courseReferenceSb.length() > 0) courseReferenceSb.append(", ");
+				courseReferenceSb.append(courseEntry.getExternalRef());
+			}
+		}
+
+		putVariablesInMailContext(vContext, "courseUrl", urlSb.toString());
+		putVariablesInMailContext(vContext, "courseName", courseNameSb.toString());
+		putVariablesInMailContext(vContext, "courseTitle", courseNameSb.toString());
+		putVariablesInMailContext(vContext, "courseReference", courseReferenceSb.toString());
+	}
 
 	@Override
 	public void putVariablesInMailContext(VelocityContext vContext, Identity recipient) {
 		if(entry != null) {
-			String url = Settings.getServerContextPathURI() + "/url/RepositoryEntry/" + entry.getKey();
-			putVariablesInMailContext(vContext, "courseUrl", url);
-			putVariablesInMailContext(vContext, "courseName", entry.getDisplayname());
-			putVariablesInMailContext(vContext, "courseTitle", entry.getDisplayname());
-			if(StringHelper.containsNonWhitespace(entry.getExternalRef())) {
-				putVariablesInMailContext(vContext, "courseReference", entry.getExternalRef());
-			}
+			putCourseVariablesInMailContext(vContext, entry);
+		} else if(entries != null && entries.size() == 1) {
+			putCourseVariablesInMailContext(vContext, entries.get(0));
+		} else if(entries != null && entries.size() > 1) {
+			putCourseVariablesInMailContext(vContext, entries);
 		}
 		
 		if(courseNode != null) {
-			putVariablesInMailContext(vContext, "courseElementTitle", courseNode.getLongTitle());
-			putVariablesInMailContext(vContext, "courseElementShortTitle", courseNode.getShortTitle());
+			putCourseNodeVariablesInMailContext(vContext, courseNode);
+		} else if(courseNodes != null && courseNodes.size() == 1) {
+			putCourseNodeVariablesInMailContext(vContext, courseNodes.get(0));
+		} else if(courseNodes != null && courseNodes.size() > 1) {
+			putCourseNodeVariablesInMailContext(vContext, courseNodes);
 		}
 		
 		if(referenceEntry != null) {
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
index 75d0a24bda6981ed7681aec411d138f76dabc04a..81d1249d1323d8a3e3af3fabfaabef48e27aa97c 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
@@ -84,7 +84,6 @@ import org.olat.repository.model.SingleRoleRepositoryEntrySecurity.Role;
 import org.olat.repository.ui.author.ConfirmCloseController;
 import org.olat.repository.ui.author.ConfirmDeleteSoftlyController;
 import org.olat.repository.ui.author.CopyRepositoryEntryController;
-import org.olat.repository.ui.author.RepositoryEditDescriptionController;
 import org.olat.repository.ui.author.RepositoryMembersController;
 import org.olat.repository.ui.list.LeavingEvent;
 import org.olat.repository.ui.list.RepositoryEntryDetailsController;
@@ -125,7 +124,6 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 	private RepositoryEntryDetailsController detailsCtrl;
 	private RepositoryMembersController membersEditController;
 	protected RepositoryEntrySettingsController settingsCtrl;
-	protected RepositoryEditDescriptionController descriptionCtrl2;
 	
 	private Dropdown tools;
 	private Dropdown status;
diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
deleted file mode 100644
index 1e71e98f57ee7db185e8ce5b4f94b299dda0e525..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
+++ /dev/null
@@ -1,845 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <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
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <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>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.
-*/
-
-package org.olat.repository.ui.author;
-
-import static org.olat.core.gui.components.util.KeyValues.VALUE_ASC;
-import static org.olat.core.gui.components.util.KeyValues.entry;
-
-import java.io.File;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-import org.olat.NewControllerFactory;
-import org.olat.basesecurity.OrganisationModule;
-import org.olat.basesecurity.OrganisationRoles;
-import org.olat.basesecurity.OrganisationService;
-import org.olat.basesecurity.model.OrganisationRefImpl;
-import org.olat.core.commons.services.license.LicenseModule;
-import org.olat.core.commons.services.license.LicenseService;
-import org.olat.core.commons.services.license.LicenseType;
-import org.olat.core.commons.services.license.ResourceLicense;
-import org.olat.core.commons.services.license.ui.LicenseSelectionConfig;
-import org.olat.core.commons.services.license.ui.LicenseUIFactory;
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.form.flexible.FormItem;
-import org.olat.core.gui.components.form.flexible.FormItemContainer;
-import org.olat.core.gui.components.form.flexible.elements.DateChooser;
-import org.olat.core.gui.components.form.flexible.elements.FileElement;
-import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
-import org.olat.core.gui.components.form.flexible.elements.RichTextElement;
-import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
-import org.olat.core.gui.components.form.flexible.elements.TextAreaElement;
-import org.olat.core.gui.components.form.flexible.elements.TextElement;
-import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
-import org.olat.core.gui.components.form.flexible.impl.FormEvent;
-import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
-import org.olat.core.gui.components.form.flexible.impl.elements.FileElementEvent;
-import org.olat.core.gui.components.form.flexible.impl.elements.FormSubmit;
-import org.olat.core.gui.components.util.KeyValues;
-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.id.Organisation;
-import org.olat.core.id.OrganisationNameComparator;
-import org.olat.core.id.Roles;
-import org.olat.core.util.FileUtils;
-import org.olat.core.util.StringHelper;
-import org.olat.core.util.UserSession;
-import org.olat.core.util.WebappHelper;
-import org.olat.core.util.coordinate.CoordinatorManager;
-import org.olat.core.util.event.MultiUserEvent;
-import org.olat.core.util.vfs.LocalFileImpl;
-import org.olat.core.util.vfs.LocalFolderImpl;
-import org.olat.core.util.vfs.VFSContainer;
-import org.olat.core.util.vfs.VFSLeaf;
-import org.olat.course.CourseModule;
-import org.olat.modules.taxonomy.TaxonomyLevel;
-import org.olat.modules.taxonomy.TaxonomyRef;
-import org.olat.modules.taxonomy.TaxonomyService;
-import org.olat.modules.taxonomy.model.TaxonomyRefImpl;
-import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryEntryManagedFlag;
-import org.olat.repository.RepositoryEntryToTaxonomyLevel;
-import org.olat.repository.RepositoryManager;
-import org.olat.repository.RepositoryModule;
-import org.olat.repository.RepositoryService;
-import org.olat.repository.controllers.EntryChangedEvent;
-import org.olat.repository.controllers.EntryChangedEvent.Change;
-import org.olat.repository.handlers.RepositoryHandler;
-import org.olat.repository.handlers.RepositoryHandlerFactory;
-import org.olat.repository.manager.RepositoryEntryLicenseHandler;
-import org.olat.repository.manager.RepositoryEntryLifecycleDAO;
-import org.olat.repository.model.RepositoryEntryLifecycle;
-import org.olat.resource.OLATResource;
-import org.olat.user.UserManager;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Description:<br>
- * 
- * @author Ingmar Kroll
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- * 
- */
-public class RepositoryEditDescriptionController extends FormBasicController {
-	
-	private static final Set<String> imageMimeTypes = new HashSet<>();
-	static {
-		imageMimeTypes.add("image/gif");
-		imageMimeTypes.add("image/jpg");
-		imageMimeTypes.add("image/jpeg");
-		imageMimeTypes.add("image/png");
-	}
-
-	private VFSContainer mediaContainer;
-	private RepositoryEntry repositoryEntry;
-	private final String repoEntryType;
-	private ResourceLicense license;
-	private List<Organisation> repositoryEntryOrganisations;
-	private Set<TaxonomyLevel> taxonomyLevels;
-
-	private static final int picUploadlimitKB = 5120;
-	private static final int movieUploadlimitKB = 102400;
-
-	private FileElement fileUpload, movieUpload;
-	private TextElement externalRef, displayName, authors, expenditureOfWork, language, location, licensorEl;
-	private TextAreaElement licenseFreetextEl;
-	private RichTextElement description, objectives, requirements, credits;
-	private SingleSelection dateTypesEl, publicDatesEl, licenseEl;
-	private DateChooser startDateEl, endDateEl;
-	private FormSubmit submit;
-	private MultipleSelectionElement organisationsEl;
-	private MultipleSelectionElement taxonomyLevelEl;
-	private FormLayoutContainer privateDatesCont;
-	
-	private static final String[] dateKeys = new String[]{ "none", "private", "public"};
-
-	@Autowired
-	private UserManager userManager;
-	@Autowired
-	private RepositoryService repositoryService;
-	@Autowired
-	private RepositoryManager repositoryManager;
-	@Autowired
-	private RepositoryModule repositoryModule;
-	@Autowired
-	private RepositoryEntryLifecycleDAO lifecycleDao;
-	@Autowired
-	private RepositoryHandlerFactory repositoryHandlerFactory;
-	@Autowired
-	private LicenseService licenseService;
-	@Autowired
-	private LicenseModule licenseModule;
-	@Autowired
-	private RepositoryEntryLicenseHandler licenseHandler;
-	@Autowired
-	private OrganisationModule organisationModule;
-	@Autowired
-	private OrganisationService organisationService;
-	@Autowired
-	private TaxonomyService taxonomyService;
-
-	/**
-	 * Create a repository add controller that adds the given resourceable.
-	 * 
-	 * @param ureq
-	 * @param wControl
-	 * @param sourceEntry
-	 */
-	public RepositoryEditDescriptionController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
-		super(ureq, wControl);
-		setBasePackage(RepositoryService.class);
-		this.repositoryEntry = entry;
-		repoEntryType = repositoryEntry.getOlatResource().getResourceableTypeName();
-		initForm(ureq);
-	}
-
-	/**
-	 * @return Returns the repositoryEntry.
-	 */
-	public RepositoryEntry getRepositoryEntry() {
-		return repositoryEntry;
-	}
-
-	@Override
-	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
-		UserSession usess = ureq.getUserSession();
-		setFormContextHelp("Set up info page");
-		formLayout.setElementCssClass("o_sel_edit_repositoryentry");
-
-		String id = repositoryEntry.getResourceableId() == null ? "-" : repositoryEntry.getResourceableId().toString();
-		uifactory.addStaticTextElement("cif.id", id, formLayout);
-		
-		String externalId = repositoryEntry.getExternalId();
-		if(StringHelper.containsNonWhitespace(externalId)) {
-			uifactory.addStaticTextElement("cif.externalid", externalId, formLayout);
-		}
-		
-		String extRef = repositoryEntry.getExternalRef();
-		if(StringHelper.containsNonWhitespace(repositoryEntry.getManagedFlagsString())) {
-			if(StringHelper.containsNonWhitespace(extRef)) {
-				uifactory.addStaticTextElement("cif.externalref", extRef, formLayout);
-			}
-		} else {
-			externalRef = uifactory.addTextElement("cif.externalref", "cif.externalref", 100, extRef, formLayout);
-			externalRef.setHelpText(translate("cif.externalref.hover"));
-			externalRef.setHelpUrlForManualPage("Info Page#_identification");
-			externalRef.setDisplaySize(30);
-		}
-
-		String initalAuthor = repositoryEntry.getInitialAuthor() == null ? "-" : repositoryEntry.getInitialAuthor();
-		if(repositoryEntry.getInitialAuthor() != null) {
-			initalAuthor = userManager.getUserDisplayName(initalAuthor);
-		}
-		initalAuthor = StringHelper.escapeHtml(initalAuthor);
-		uifactory.addStaticTextElement("cif.initialAuthor", initalAuthor, formLayout);
-		// Add resource type
-		String typeName = null;
-		OLATResource res = repositoryEntry.getOlatResource();
-		if (res != null) {
-			typeName = res.getResourceableTypeName();
-		}
-		
-		String typeDisplay ;
-		if (typeName != null) { // add image and typename code
-			typeDisplay = NewControllerFactory.translateResourceableTypeName(typeName, getLocale());
-		} else {
-			typeDisplay = translate("cif.type.na");
-		}
-		uifactory.addStaticTextElement("cif.type", typeDisplay, formLayout);
-		
-		uifactory.addSpacerElement("spacer1", formLayout, false);
-
-		displayName = uifactory.addTextElement("cif.displayname", "cif.displayname", 100, repositoryEntry.getDisplayname(), formLayout);
-		displayName.setDisplaySize(30);
-		displayName.setMandatory(true);
-		displayName.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.title));
-
-		authors = uifactory.addTextElement("cif.authors", "cif.authors", 255, repositoryEntry.getAuthors(), formLayout);
-		authors.setDisplaySize(60);
-		
-		if (licenseModule.isEnabled(licenseHandler)) {
-			license = licenseService.loadOrCreateLicense(res);
-
-			LicenseSelectionConfig licenseSelectionConfig = LicenseUIFactory
-					.createLicenseSelectionConfig(licenseHandler, license.getLicenseType());
-			licenseEl = uifactory.addDropdownSingleselect("cif.license", formLayout,
-					licenseSelectionConfig.getLicenseTypeKeys(),
-					licenseSelectionConfig.getLicenseTypeValues(getLocale()));
-			licenseEl.setElementCssClass("o_sel_repo_license");
-			licenseEl.setMandatory(licenseSelectionConfig.isLicenseMandatory());
-			if (licenseSelectionConfig.getSelectionLicenseTypeKey() != null) {
-				licenseEl.select(licenseSelectionConfig.getSelectionLicenseTypeKey(), true);
-			}
-			licenseEl.addActionListener(FormEvent.ONCHANGE);
-			
-			licensorEl = uifactory.addTextElement("cif.licensor", 1000, license.getLicensor(), formLayout);
-
-			String freetext = licenseService.isFreetext(license.getLicenseType()) ? license.getFreetext() : "";
-			licenseFreetextEl = uifactory.addTextAreaElement("cif.freetext", 4, 72, freetext, formLayout);
-			LicenseUIFactory.updateVisibility(licenseEl, licensorEl, licenseFreetextEl);
-		}
-		
-		String taxonomyTreeKey = repositoryModule.getTaxonomyTreeKey();
-		if(StringHelper.isLong(taxonomyTreeKey)) {
-			TaxonomyRef taxonomyRef = new TaxonomyRefImpl(Long.valueOf(taxonomyTreeKey));
-			initFormTaxonomy(formLayout, taxonomyRef);
-		}
-		
-		if(organisationModule.isEnabled()) {
-			initFormOrganisations(formLayout, usess);
-		}
-		
-		language = uifactory.addTextElement("cif.mainLanguage", "cif.mainLanguage", 16, repositoryEntry.getMainLanguage(), formLayout);
-		
-		location = uifactory.addTextElement("cif.location", "cif.location", 255, repositoryEntry.getLocation(), formLayout);
-		location.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.location));
-		
-		RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(repositoryEntry);
-		mediaContainer = handler.getMediaContainer(repositoryEntry);
-		if(mediaContainer != null && mediaContainer.getName().equals("media")) {
-			mediaContainer = mediaContainer.getParentContainer();
-			mediaContainer.setDefaultItemFilter(new MediaContainerFilter(mediaContainer));
-		}
-		
-		String desc = (repositoryEntry.getDescription() != null ? repositoryEntry.getDescription() : " ");
-		description = uifactory.addRichTextElementForStringData("cif.description", "cif.description",
-				desc, 10, -1, false, mediaContainer, null, formLayout, usess, getWindowControl());
-		description.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.description));
-		description.getEditorConfiguration().setFileBrowserUploadRelPath("media");
-
-		uifactory.addSpacerElement("spacer2", formLayout, false);
-
-		if(CourseModule.getCourseTypeName().equals(repoEntryType)) {
-			initCourse(formLayout, usess);
-		}
-		
-		boolean managed = RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.details);
-		
-		VFSLeaf img = repositoryManager.getImage(repositoryEntry);
-		fileUpload = uifactory.addFileElement(getWindowControl(), "rentry.pic", "rentry.pic", formLayout);
-		fileUpload.setExampleKey("rentry.pic.example", new String[] {RepositoryManager.PICTURE_WIDTH + "x" + (RepositoryManager.PICTURE_HEIGHT)});
-		fileUpload.setMaxUploadSizeKB(picUploadlimitKB, null, null);
-		fileUpload.setPreview(usess, true);
-		fileUpload.addActionListener(FormEvent.ONCHANGE);
-		fileUpload.setDeleteEnabled(!managed);
-		if(img instanceof LocalFileImpl) {
-			fileUpload.setPreview(usess, true);
-			fileUpload.setInitialFile(((LocalFileImpl)img).getBasefile());
-		}
-		fileUpload.setVisible(!managed);
-		fileUpload.limitToMimeType(imageMimeTypes, "cif.error.mimetype", new String[]{ imageMimeTypes.toString()} );
-
-		VFSLeaf movie = repositoryService.getIntroductionMovie(repositoryEntry);
-		movieUpload = uifactory.addFileElement(getWindowControl(), "rentry.movie", "rentry.movie", formLayout);
-		movieUpload.setExampleKey("rentry.movie.example", new String[] {"3:2"});
-		movieUpload.setMaxUploadSizeKB(movieUploadlimitKB, null, null);
-		movieUpload.setPreview(usess, true);
-		movieUpload.addActionListener(FormEvent.ONCHANGE);
-		movieUpload.setDeleteEnabled(!managed);
-		if(movie instanceof LocalFileImpl) {
-			movieUpload.setPreview(usess, true);
-			movieUpload.setInitialFile(((LocalFileImpl)movie).getBasefile());
-		}
-		movieUpload.setVisible(!managed);
-
-		FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttonContainer", getTranslator());
-		formLayout.add("buttonContainer", buttonContainer);
-		buttonContainer.setElementCssClass("o_sel_repo_save_details");
-		submit = uifactory.addFormSubmitButton("submit", buttonContainer);
-		submit.setVisible(!managed);
-		uifactory.addFormCancelButton("cancel", buttonContainer, ureq, getWindowControl());
-	}
-	
-	private void initCourse(FormItemContainer formLayout, UserSession usess) {
-		String[] dateValues = new String[] {
-				translate("cif.dates.none"),
-				translate("cif.dates.private"),
-				translate("cif.dates.public")	
-		};
-		dateTypesEl = uifactory.addRadiosVertical("cif.dates", formLayout, dateKeys, dateValues);
-		dateTypesEl.setElementCssClass("o_sel_repo_lifecycle_type");
-		if(repositoryEntry.getLifecycle() == null) {
-			dateTypesEl.select("none", true);
-		} else if(repositoryEntry.getLifecycle().isPrivateCycle()) {
-			dateTypesEl.select("private", true);
-		} else {
-			dateTypesEl.select("public", true);
-		}
-		dateTypesEl.addActionListener(FormEvent.ONCHANGE);
-
-		List<RepositoryEntryLifecycle> cycles = lifecycleDao.loadPublicLifecycle();
-		List<RepositoryEntryLifecycle> filteredCycles = new ArrayList<>();
-		//just make the upcomming and acutual running cycles or the pre-selected visible in the UI
-		LocalDateTime now = LocalDateTime.now();
-		for(RepositoryEntryLifecycle cycle:cycles) {
-			if(cycle.getValidTo() == null
-					|| now.isBefore(LocalDateTime.ofInstant(cycle.getValidTo().toInstant(), ZoneId.systemDefault()))
-					|| (repositoryEntry.getLifecycle() != null && repositoryEntry.getLifecycle().equals(cycle))) {
-				filteredCycles.add(cycle);
-			}
-		}
-		
-		String[] publicKeys = new String[filteredCycles.size()];
-		String[] publicValues = new String[filteredCycles.size()];
-		int count = 0;		
-		for(RepositoryEntryLifecycle cycle:filteredCycles) {
-				publicKeys[count] = cycle.getKey().toString();
-				
-				StringBuilder sb = new StringBuilder(32);
-				boolean labelAvailable = StringHelper.containsNonWhitespace(cycle.getLabel());
-				if(labelAvailable) {
-					sb.append(cycle.getLabel());
-				}
-				if(StringHelper.containsNonWhitespace(cycle.getSoftKey())) {
-					if(labelAvailable) sb.append(" - ");
-					sb.append(cycle.getSoftKey());
-				}
-				publicValues[count++] = sb.toString();
-		}
-		publicDatesEl = uifactory.addDropdownSingleselect("cif.public.dates", formLayout, publicKeys, publicValues, null);
-
-		String privateDatePage = velocity_root + "/cycle_dates.html";
-		privateDatesCont = FormLayoutContainer.createCustomFormLayout("private.date", getTranslator(), privateDatePage);
-		privateDatesCont.setRootForm(mainForm);
-		privateDatesCont.setLabel("cif.private.dates", null);
-		formLayout.add("private.date", privateDatesCont);
-		
-		startDateEl = uifactory.addDateChooser("date.start", "cif.date.start", null, privateDatesCont);
-		startDateEl.setElementCssClass("o_sel_repo_lifecycle_validfrom");
-		endDateEl = uifactory.addDateChooser("date.end", "cif.date.end", null, privateDatesCont);
-		endDateEl.setElementCssClass("o_sel_repo_lifecycle_validto");
-		
-		if(repositoryEntry.getLifecycle() != null) {
-			RepositoryEntryLifecycle lifecycle = repositoryEntry.getLifecycle();
-			if(lifecycle.isPrivateCycle()) {
-				startDateEl.setDate(lifecycle.getValidFrom());
-				endDateEl.setDate(lifecycle.getValidTo());
-			} else {
-				String key = lifecycle.getKey().toString();
-				for(String publicKey:publicKeys) {
-					if(key.equals(publicKey)) {
-						publicDatesEl.select(key, true);
-						break;
-					}
-				}
-			}
-		}
-
-		updateDatesVisibility();
-		uifactory.addSpacerElement("spacer3", formLayout, false);
-		
-		expenditureOfWork = uifactory.addTextElement("cif.expenditureOfWork", "cif.expenditureOfWork", 100, repositoryEntry.getExpenditureOfWork(), formLayout);
-		expenditureOfWork.setExampleKey("details.expenditureOfWork.example", null);
-
-		String obj = (repositoryEntry.getObjectives() != null ? repositoryEntry.getObjectives() : " ");
-		objectives = uifactory.addRichTextElementForStringData("cif.objectives", "cif.objectives",
-				obj, 10, -1, false, mediaContainer, null, formLayout, usess, getWindowControl());
-		objectives.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.objectives));
-		objectives.getEditorConfiguration().setFileBrowserUploadRelPath("media");
-		
-		
-		String req = (repositoryEntry.getRequirements() != null ? repositoryEntry.getRequirements() : " ");
-		requirements = uifactory.addRichTextElementForStringData("cif.requirements", "cif.requirements",
-				req, 10, -1,  false, mediaContainer, null, formLayout, usess, getWindowControl());
-		requirements.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.requirements));
-		requirements.getEditorConfiguration().setFileBrowserUploadRelPath("media");
-		requirements.setMaxLength(2000);
-		
-		String cred = (repositoryEntry.getCredits() != null ? repositoryEntry.getCredits() : " ");
-		credits = uifactory.addRichTextElementForStringData("cif.credits", "cif.credits",
-				cred, 10, -1,  false, mediaContainer, null, formLayout, usess, getWindowControl());
-		credits.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.credits));
-		credits.getEditorConfiguration().setFileBrowserUploadRelPath("media");
-		credits.setMaxLength(2000);
-		
-		uifactory.addSpacerElement("spacer4", formLayout, false);
-	}
-
-	private void initFormTaxonomy(FormItemContainer formLayout, TaxonomyRef taxonomyRef) {
-		taxonomyLevels = repositoryEntry.getTaxonomyLevels().stream()
-				.map(RepositoryEntryToTaxonomyLevel::getTaxonomyLevel)
-				.collect(Collectors.toSet());
-		List<TaxonomyLevel> allTaxonomyLevels = taxonomyService.getTaxonomyLevels(taxonomyRef);
-
-		KeyValues keyValues = new KeyValues();
-		for (TaxonomyLevel level:allTaxonomyLevels) {
-			String key = Long.toString(level.getKey());
-			ArrayList<String> names = new ArrayList<>();
-			addParentNames(names, level);
-			Collections.reverse(names);
-			String value = String.join(" / ", names);
-			keyValues.add(entry(key, value));
-		}
-		keyValues.sort(VALUE_ASC);
-	
-		taxonomyLevelEl = uifactory.addCheckboxesDropdown("taxonomyLevels", "cif.taxonomy.levels", formLayout,
-				keyValues.keys(), keyValues.values(), null, null);
-		List<TaxonomyLevel> reLevels = repositoryService.getTaxonomy(repositoryEntry);
-		for (TaxonomyLevel reLevel : reLevels) {
-			String key = reLevel.getKey().toString();
-			if (keyValues.containsKey(key)) {
-				taxonomyLevelEl.select(key, true);
-			}
-		}
-	}
-	
-	private void addParentNames(List<String> names, TaxonomyLevel level) {
-		names.add(level.getDisplayName());
-		TaxonomyLevel parent = level.getParent();
-		if (parent != null) {
-			addParentNames(names, parent);
-		}
-	}
-
-	private void initFormOrganisations(FormItemContainer formLayout, UserSession usess) {
-		Roles roles = usess.getRoles();
-		List<Organisation> organisations = organisationService.getOrganisations(getIdentity(), roles,
-				OrganisationRoles.administrator, OrganisationRoles.learnresourcemanager);
-		List<Organisation> organisationList = new ArrayList<>(organisations);
-
-		List<Organisation> reOrganisations = repositoryService.getOrganisations(repositoryEntry);
-		for(Organisation reOrganisation:reOrganisations) {
-			if(reOrganisation != null && !organisationList.contains(reOrganisation)) {
-				organisationList.add(reOrganisation);
-			}
-		}
-		
-		Collections.sort(organisationList, new OrganisationNameComparator(getLocale()));
-		
-		List<String> keyList = new ArrayList<>();
-		List<String> valueList = new ArrayList<>();
-		for(Organisation organisation:organisationList) {
-			keyList.add(organisation.getKey().toString());
-			valueList.add(organisation.getDisplayName());
-		}
-		repositoryEntryOrganisations = new ArrayList<>(reOrganisations.size());
-		organisationsEl = uifactory.addCheckboxesDropdown("organisations", "cif.organisations", formLayout,
-				keyList.toArray(new String[keyList.size()]), valueList.toArray(new String[valueList.size()]),
-				null, null);
-		organisationsEl.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.organisations));
-		for(Organisation reOrganisation:reOrganisations) {
-			if(keyList.contains(reOrganisation.getKey().toString())) {
-				organisationsEl.select(reOrganisation.getKey().toString(), true);
-			}
-		}
-	}
-
-	private void updateDatesVisibility() {
-		if(dateTypesEl.isOneSelected()) {
-			String type = dateTypesEl.getSelectedKey();
-			if("none".equals(type)) {
-				publicDatesEl.setVisible(false);
-				privateDatesCont.setVisible(false);
-			} else if("public".equals(type)) {
-				publicDatesEl.setVisible(true);
-				privateDatesCont.setVisible(false);
-			} else if("private".equals(type)) {
-				publicDatesEl.setVisible(false);
-				privateDatesCont.setVisible(true);
-			}
-		}
-	}
-
-	@Override
-	protected void doDispose() {
-		// Controllers autodisposed by basic controller
-	}
-
-	@Override
-	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = super.validateFormLogic(ureq);
-		
-		// Check for empty display name
-		if (!StringHelper.containsNonWhitespace(displayName.getValue())) {
-			displayName.setErrorKey("cif.error.displayname.empty", new String[] {});
-			allOk = false;
-		} else if (displayName.hasError()) {
-			allOk = false;
-		} else {
-			displayName.clearError();
-		}
-
-		allOk &= validateTextElement(language, 255);
-		allOk &= validateTextElement(location, 255);
-		allOk &= validateTextElement(objectives, 16000);
-		allOk &= validateTextElement(requirements, 16000);
-		allOk &= validateTextElement(credits, 16000);
-		allOk &= validateTextElement(externalRef, 58);
-		allOk &= validateTextElement(expenditureOfWork, 16000);
-		allOk &= validateTextElement(authors, 2000);
-		
-		if (publicDatesEl != null) {
-			publicDatesEl.clearError();
-			if(publicDatesEl.isEnabled() && publicDatesEl.isVisible()) {
-				if(!publicDatesEl.isOneSelected()) {
-					publicDatesEl.setErrorKey("form.legende.mandatory", null);
-					allOk &= false;
-				}	
-			}
-		}
-		
-		if (licenseEl != null) {
-			licenseEl.clearError();
-			if (LicenseUIFactory.validateLicenseTypeMandatoryButNonSelected(licenseEl)) {
-				licenseEl.setErrorKey("form.legende.mandatory", null);
-				allOk &= false;
-			}
-		}
-		
-		if (organisationsEl != null) {
-			organisationsEl.clearError();
-			if(!organisationsEl.isAtLeastSelected(1)) {
-				organisationsEl.setErrorKey("form.legende.mandatory", null);
-				allOk &= false;
-			}
-		}
-
-		return allOk;
-	}
-	
-	private boolean validateTextElement(TextElement el, int maxLength) {
-		boolean ok;
-		if(el == null) {
-			ok = true;
-		} else {
-			String val = el.getValue();
-			el.clearError();
-			if(val != null && val.length() > maxLength) {
-				el.setErrorKey("input.toolong", new String[]{ Integer.toString(maxLength) });
-				ok = false;
-			} else {
-				ok = true;
-			}
-		}
-		return ok;
-	}
-
-	@Override
-	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
-		if (source == dateTypesEl) {
-			updateDatesVisibility();
-		} else if (source == licenseEl) {
-			LicenseUIFactory.updateVisibility(licenseEl, licensorEl, licenseFreetextEl);;
-		} else if (source == fileUpload) {
-			if(FileElementEvent.DELETE.equals(event.getCommand())) {
-				fileUpload.clearError();
-				VFSLeaf img = repositoryManager.getImage(repositoryEntry);
-				if(fileUpload.getUploadFile() != null && fileUpload.getUploadFile() != fileUpload.getInitialFile()) {
-					fileUpload.reset();
-					if(img != null) {
-						fileUpload.setInitialFile(((LocalFileImpl)img).getBasefile());
-					}
-				} else if(img != null) {
-					repositoryManager.deleteImage(repositoryEntry);
-					fileUpload.setInitialFile(null);
-				}
-				flc.setDirty(true);	
-			}
-		} else if (source == movieUpload) {
-			if(FileElementEvent.DELETE.equals(event.getCommand())) {
-				movieUpload.clearError();
-				VFSLeaf movie = repositoryService.getIntroductionMovie(repositoryEntry);
-				if(movieUpload.getUploadFile() != null && movieUpload.getUploadFile() != movieUpload.getInitialFile()) {
-					movieUpload.reset();
-					if(movie != null) {
-						movieUpload.setInitialFile(((LocalFileImpl)movie).getBasefile());
-					}
-				} else if(movie != null) {
-					movie.delete();
-					movieUpload.setInitialFile(null);
-				}
-				flc.setDirty(true);
-			}
-		}
-		super.formInnerEvent(ureq, source, event);
-	}
-
-	@Override
-	protected void formOK(UserRequest ureq) {
-		if (licenseModule.isEnabled(licenseHandler)) {
-			if (licenseEl != null && licenseEl.isOneSelected()) {
-				String licenseTypeKey = licenseEl.getSelectedKey();
-				LicenseType licneseType = licenseService.loadLicenseTypeByKey(licenseTypeKey);
-				license.setLicenseType(licneseType);
-			}
-			String licensor = null;
-			String freetext = null;
-			if (licensorEl != null && licensorEl.isVisible()) {
-				licensor = StringHelper.containsNonWhitespace(licensorEl.getValue())? licensorEl.getValue(): null;
-			}
-			if (licenseFreetextEl != null && licenseFreetextEl.isVisible()) {
-				freetext = StringHelper.containsNonWhitespace(licenseFreetextEl.getValue())? licenseFreetextEl.getValue(): null;
-			}
-			license.setLicensor(licensor);
-			license.setFreetext(freetext);
-			license = licenseService.update(license);
-			licensorEl.setValue(license.getLicensor());
-			licenseFreetextEl.setValue(license.getFreetext());
-		}
-		
-		File uploadedImage = fileUpload.getUploadFile();
-		if(uploadedImage != null && uploadedImage.exists()) {
-			VFSContainer tmpHome = new LocalFolderImpl(new File(WebappHelper.getTmpDir()));
-			VFSContainer tmpContainer = tmpHome.createChildContainer(UUID.randomUUID().toString());
-			VFSLeaf newFile = fileUpload.moveUploadFileTo(tmpContainer);//give it it's real name and extension
-			boolean ok = repositoryManager.setImage(newFile, repositoryEntry);
-			if (!ok) {
-				showWarning("cif.error.image");
-			} else {
-				VFSLeaf image = repositoryManager.getImage(repositoryEntry);
-				if(image instanceof  LocalFileImpl) {
-					fileUpload.setInitialFile(((LocalFileImpl)image).getBasefile());
-				}
-			}
-			tmpContainer.deleteSilently();
-		}
-
-		File uploadedMovie = movieUpload.getUploadFile();
-		if(uploadedMovie != null && uploadedMovie.exists()) {
-			VFSContainer m = (VFSContainer)mediaContainer.resolve("media");
-			VFSLeaf newFile = movieUpload.moveUploadFileTo(m);
-			if (newFile == null) {
-				showWarning("cif.error.movie");
-			} else {
-				String filename = movieUpload.getUploadFileName();
-				String extension = FileUtils.getFileSuffix(filename);
-				newFile.rename(repositoryEntry.getKey() + "." + extension);
-			}
-		}
-
-		String displayname = displayName.getValue().trim();
-		repositoryEntry.setDisplayname(displayname);
-		
-		String mainLanguage = language.getValue();
-		if(StringHelper.containsNonWhitespace(mainLanguage)) {
-			repositoryEntry.setMainLanguage(mainLanguage);
-		} else {
-			repositoryEntry.setMainLanguage(null);
-		}
-		
-		if(dateTypesEl != null) {
-			String type = "none";
-			if(dateTypesEl.isOneSelected()) {
-				type = dateTypesEl.getSelectedKey();
-			}
-			
-			if("none".equals(type)) {
-				repositoryEntry.setLifecycle(null);
-			} else if("public".equals(type)) {
-				String key = publicDatesEl.getSelectedKey();
-				if(StringHelper.isLong(key)) {
-					Long cycleKey = Long.parseLong(key);
-					RepositoryEntryLifecycle cycle = lifecycleDao.loadById(cycleKey);
-					repositoryEntry.setLifecycle(cycle);
-				}
-			} else if("private".equals(type)) {
-				Date start = startDateEl.getDate();
-				Date end = endDateEl.getDate();
-				RepositoryEntryLifecycle cycle = repositoryEntry.getLifecycle();
-				if(cycle == null || !cycle.isPrivateCycle()) {
-					String softKey = "lf_" + repositoryEntry.getSoftkey();
-					cycle = lifecycleDao.create(displayname, softKey, true, start, end);
-				} else {
-					cycle.setValidFrom(start);
-					cycle.setValidTo(end);
-					cycle = lifecycleDao.updateLifecycle(cycle);
-				}
-				repositoryEntry.setLifecycle(cycle);
-			}
-		}
-		
-		if(externalRef != null && externalRef.isEnabled()) {
-			String ref = externalRef.getValue().trim();
-			repositoryEntry.setExternalRef(ref);
-		}
-		
-		String desc = description.getValue().trim();
-		repositoryEntry.setDescription(desc);
-		if(authors != null) {
-			String auth = authors.getValue().trim();
-			repositoryEntry.setAuthors(auth);
-		}
-		if(objectives != null) {
-			String obj = objectives.getValue().trim();
-			repositoryEntry.setObjectives(obj);
-		}
-		if(requirements != null) {
-			String req = requirements.getValue().trim();
-			repositoryEntry.setRequirements(req);
-		}
-		if(credits != null) {
-			String cred = credits.getValue().trim();
-			repositoryEntry.setCredits(cred);
-		}
-		if(expenditureOfWork != null) {
-			String exp = expenditureOfWork.getValue().trim();
-			repositoryEntry.setExpenditureOfWork(exp);
-		}
-		if(location != null) {
-			String loc = location.getValue().trim();
-			repositoryEntry.setLocation(loc);
-		}
-		
-		// Taxonomy levels
-		if (taxonomyLevelEl != null) {
-			Collection<String> selectedLevelKeys = taxonomyLevelEl.getSelectedKeys();
-			List<String> currentKeys = taxonomyLevels.stream()
-					.map(l -> l.getKey().toString())
-					.collect(Collectors.toList());
-			// add newly selected keys
-			Collection<String> addKeys = new HashSet<>(selectedLevelKeys);
-			addKeys.removeAll(currentKeys);
-			for (String addKey : addKeys) {
-				TaxonomyLevel level = taxonomyService.getTaxonomyLevel(() -> Long.valueOf(addKey));
-				taxonomyLevels.add(level);
-			}
-			// remove newly unselected keys
-			Collection<String> removeKeys = new HashSet<>(currentKeys);
-			removeKeys.removeAll(selectedLevelKeys);
-			for (String removeKey: removeKeys) {
-				taxonomyLevels.removeIf(level -> removeKey.equals(level.getKey().toString()));
-			}
-		}
-		
-		// Organisations
-		List<Organisation> organisations = null;
-		if(organisationsEl != null) {
-			organisations = new ArrayList<>(repositoryEntryOrganisations);
-
-			Set<String> organisationKeys = organisationsEl.getKeys();
-			Collection<String> selectedOrganisationKeys = organisationsEl.getSelectedKeys();
-
-			Set<String> currentOrganisationKeys = new HashSet<>();
-			for(Iterator<Organisation> it=organisations.iterator(); it.hasNext(); ) {
-				String key = it.next().getKey().toString();
-				currentOrganisationKeys.add(key);
-				if(organisationKeys.contains(key) && !selectedOrganisationKeys.contains(key)) {
-					it.remove();
-				}
-			}
-
-			for(String selectedOrganisationKey:selectedOrganisationKeys) {
-				if(!currentOrganisationKeys.contains(selectedOrganisationKey)) {
-					Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(Long.valueOf(selectedOrganisationKey)));
-					if(organisation != null) {
-						organisations.add(organisation);
-					}
-				}
-			}
-		}
-		
-		repositoryEntry = repositoryManager.setDescriptionAndName(repositoryEntry,
-				repositoryEntry.getDisplayname(), repositoryEntry.getExternalRef(), repositoryEntry.getAuthors(),
-				repositoryEntry.getDescription(), repositoryEntry.getObjectives(), repositoryEntry.getRequirements(),
-				repositoryEntry.getCredits(), repositoryEntry.getMainLanguage(), repositoryEntry.getLocation(),
-				repositoryEntry.getExpenditureOfWork(), repositoryEntry.getLifecycle(), organisations, taxonomyLevels);
-		if(repositoryEntry == null) {
-			showWarning("repositoryentry.not.existing");
-			fireEvent(ureq, Event.CLOSE_EVENT);
-		} else {
-			fireEvent(ureq, Event.CHANGED_EVENT);
-			MultiUserEvent modifiedEvent = new EntryChangedEvent(repositoryEntry, getIdentity(), Change.modifiedDescription, "authoring");
-			CoordinatorManager.getInstance().getCoordinator().getEventBus()
-				.fireEventToListenersOf(modifiedEvent, RepositoryService.REPOSITORY_EVENT_ORES);
-		}
-	}
-
-	@Override
-	protected void formCancelled(UserRequest ureq) {
-		fireEvent(ureq, Event.CANCELLED_EVENT);
-	}
-}
\ No newline at end of file