diff --git a/.hgtags b/.hgtags
index 867d3887798df0b9bf2e20f3e055f266aead248b..69ec33aa7ddd1831d7a87f6366139e88e93b284b 100644
--- a/.hgtags
+++ b/.hgtags
@@ -213,3 +213,4 @@ dc92e2661668e9867d401d8f929c02a6a3f92314 OpenOLAT 12.2.3
 b600dc769f2f7b69b57bdea60591488d8e27ee7d OpenOLAT 12.2.8
 93154b0f3bb64433fde186ce8d8566f71cabc9ce OpenOLAT 12.3.0
 801fa799d131e864b7fb21c42b7965a07ba8bca2 OpenOLAT 12.3.1
+de92931b87a20ec26edb2c65e3496c471bce6481 OpenOLAT 12.3.2
diff --git a/NOTICE.TXT b/NOTICE.TXT
index ae5ca1334db064dc3e93f4c56e09ce5f167932d6..939ef649f3f28ce3cae7d426053257ea75d779e9 100644
--- a/NOTICE.TXT
+++ b/NOTICE.TXT
@@ -138,6 +138,7 @@ This produce uses software based on the MIT License
 * maphilight (MIT License) [https://github.com/kemayo/maphilight]
 * iFrame Resizer (MIT License) [https://github.com/davidjbradshaw/iframe-resizer]
 * Dragula (MIT License) [https://github.com/bevacqua/dragula]
+* tabOverride (MIT License) [https://github.com/wjbryant/taboverride]
 
 -----------------------------------------------------------------------
 This product uses software based on the BSD License
diff --git a/pom.xml b/pom.xml
index ad95aa7a9c3be81852161ea16861a0970eb958b0..1cfaa766209fbc33c77d24b3ed12fd9cd81e394b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,7 +73,7 @@
 		<version.selenium>3.8.1</version.selenium>
 		<version.drone>2.5.0</version.drone>
 		<activemq.version>5.11.1</activemq.version>
-		<qtiworks.version>1.0.6</qtiworks.version>
+		<qtiworks.version>1.0.7</qtiworks.version>
 
 	    <!-- properties for testing and Q&A -->
 	    <!-- by default no tests are executed so far (April 2011). Use appropriate profiles and properties on the command line -->
@@ -1932,8 +1932,8 @@
 		<dependency>
 			<groupId>fmath</groupId>
 			<artifactId>fmath-latex-mathml</artifactId>
-			<version>0.5</version>
-			<!--  need org.jdom 1.1.3, jaxen 1.1.4 and commons-codec -->
+			<version>3.1</version>
+			<!-- need org.jdom2 2.0.6 -->
 		</dependency>
 		<dependency>
 			<groupId>jgrapht</groupId>
diff --git a/src/main/java/org/olat/admin/AdminModule.java b/src/main/java/org/olat/admin/AdminModule.java
index e04438f1aea973dae17ad0c23b53e5d501d38598..82f7767ab43b67e3ed7ee794bda01bac10e14ab7 100644
--- a/src/main/java/org/olat/admin/AdminModule.java
+++ b/src/main/java/org/olat/admin/AdminModule.java
@@ -127,12 +127,11 @@ public class AdminModule extends AbstractSpringModule {
 		PropertyManager pm = PropertyManager.getInstance();
 		Property p = pm.findProperty(null, null, null, AdminModule.SYSTEM_PROPERTY_CATEGORY, tokenPropertyName);
 		String token = (p == null ? "" : p.getStringValue());
-		if (token.matches(submittedToken)) { // limit access to token
+		if (token.equals(submittedToken)) { // limit access to token
 			return true;
-		} else {
-			log.audit("Trying to set maintenance message using a wrong token. Remote address::" + request.getRemoteAddr());
-			return false;
 		}
+		log.audit("Trying to set maintenance message using a wrong token. Remote address::" + request.getRemoteAddr());
+		return false;
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/commons/calendar/ICalServlet.java b/src/main/java/org/olat/commons/calendar/ICalServlet.java
index ad8ee92c9832b26102349b237decb762ecb0ad65..92602d87c8b7f47e3ffa61aa4978dead4fe2189e 100644
--- a/src/main/java/org/olat/commons/calendar/ICalServlet.java
+++ b/src/main/java/org/olat/commons/calendar/ICalServlet.java
@@ -90,7 +90,7 @@ public class ICalServlet extends HttpServlet {
 	private static final long serialVersionUID = -155266285395912535L;
 	private static final OLog log = Tracing.createLoggerFor(ICalServlet.class);
 	
-	private static final int TTL_HOURS = 6;
+	private static final int TTL_HOURS = 1;
 	private static final int cacheAge = 60 * 60 * TTL_HOURS;//6 Hours
 	private static final ConcurrentMap<String,VTimeZone> outlookVTimeZones = new ConcurrentHashMap<>();
 	
@@ -227,7 +227,8 @@ public class ICalServlet extends HttpServlet {
 			if(StringHelper.isLong(userName)) {
 				CalendarUserConfiguration config = calendarManager.getCalendarUserConfiguration(Long.parseLong(userName));
 				savedToken = config == null ? null : config.getToken();
-			} else {
+			} 
+			if(savedToken == null) {
 				savedToken = calendarManager.getCalendarToken(calendarType, calendarID, userName);
 			}
 			if (authToken == null || savedToken == null || !savedToken.equals(authToken)) {
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
index cb7ea9701cc395c63d4ebd21072bd3b118999171..1571da18ba74ea1907a4e207970ae8e75f3231ec 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
@@ -142,7 +142,7 @@ cal.sun=Sonntag
 cal.synchronize.personal.type.url.desc=$\:cal.synchronize.type.url.desc
 cal.synchronize.type.url=Kalender via URL importieren
 cal.synchronize.type.url.desc=Kalender via URL importieren
-cal.synchronize.type.url.error=Kalender konnte nicht synchroniziert werden
+cal.synchronize.type.url.error=Kalender konnte nicht synchronisiert werden
 cal.thisweek=Heute
 cal.thu=Donnerstag
 cal.to=Bis
@@ -153,7 +153,7 @@ cal.wed=Mittwoch
 cal.week=Woche
 cal.week.label=Woche
 calendar.admin=Kalenderkonfiguration
-calendar.admin.description=Hier k\u00F6nnen Sie den Kalender an oder abschalten.
+calendar.admin.description=Hier k\u00F6nnen Sie den Kalender ein- oder ausschalten.
 calendar.enable=Kalender einschalten
 calendar.enable.course.element=Kursbaustein einschalten
 calendar.enable.course.tool=Kurswerkzeug einschalten
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
index ec0a8664afa3acc578e64d21d506e58f08308a64..49aa56b01355093a25da8db1b0c90c8e9b5d5b0e 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
@@ -153,7 +153,7 @@ cal.wed=Wednesday
 cal.week=Week
 cal.week.label=Week
 calendar.admin=Calendar configuration
-calendar.admin.description=Enable or disable the calendar hier.
+calendar.admin.description=Enable or disable the calendar here.
 calendar.enable=Enable calendar
 calendar.enable.course.element=Enable course element
 calendar.enable.course.tool=Enable course tool
diff --git a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
index e5b3d11bd17963ae07a9f5d56a5d3d93c7c89cae..476d3e29682421e27335816d65600100ca849530 100644
--- a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
+++ b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
@@ -426,14 +426,14 @@ public class ICalFileCalendarManager implements CalendarManager, InitializingBea
 		String token = RandomStringUtils.randomAlphanumeric(6);
 		Kalendar calendar = new Kalendar(identity.getKey().toString(), CalendarManager.TYPE_USER_AGGREGATED);
 		return calendarUserConfigDao.createCalendarUserConfiguration(calendar, identity,
-				token, false, false);
+				token, true, true);
 	}
 
 	@Override
 	public CalendarUserConfiguration createCalendarConfig(Identity identity, Kalendar calendar) {
 		String token = RandomStringUtils.randomAlphanumeric(6);
 		return calendarUserConfigDao.createCalendarUserConfiguration(calendar, identity,
-				token, false, false);
+				token, true, true);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarPersonalConfigurationController.java b/src/main/java/org/olat/commons/calendar/ui/CalendarPersonalConfigurationController.java
index 4028b1766012dcfb2badda07acaaac61f3e21561..9be2244639670b3931724f662e1dcac72a5b1364 100644
--- a/src/main/java/org/olat/commons/calendar/ui/CalendarPersonalConfigurationController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/CalendarPersonalConfigurationController.java
@@ -84,6 +84,7 @@ public class CalendarPersonalConfigurationController extends FormBasicController
 	private int counter;
 	private final boolean allowImport;
 	private List<KalendarRenderWrapper> calendars;
+	private final KalendarRenderWrapper alwaysVisibleKalendar;
 	
 	@Autowired
 	private CalendarManager calendarManager;
@@ -91,10 +92,11 @@ public class CalendarPersonalConfigurationController extends FormBasicController
 	private ImportCalendarManager importCalendarManager;
 
 	public CalendarPersonalConfigurationController(UserRequest ureq, WindowControl wControl,
-			List<KalendarRenderWrapper> calendars, boolean allowImport) {
+			List<KalendarRenderWrapper> calendars, KalendarRenderWrapper alwaysVisibleKalendar, boolean allowImport) {
 		super(ureq, wControl, "configuration");
 		this.calendars = calendars;
 		this.allowImport = allowImport;
+		this.alwaysVisibleKalendar = alwaysVisibleKalendar;
 		setTranslator(Util.createPackageTranslator(CalendarManager.class, getLocale(), getTranslator()));
 		
 		initForm(ureq);
@@ -147,7 +149,12 @@ public class CalendarPersonalConfigurationController extends FormBasicController
 		row.setColorLink(colorLink);
 		
 		FormLink visibleLink = uifactory.addFormLink("vis_" + (++counter), "visible", "", null, null, Link.NONTRANSLATED);
-		enableDisableIcons(visibleLink, row.isVisible());
+		if(isAlwaysVisible(row)) {
+			enableDisableIcons(visibleLink, true);
+			visibleLink.setEnabled(false);
+		} else {
+			enableDisableIcons(visibleLink, row.isVisible());
+		}
 		visibleLink.setUserObject(row);
 		row.setVisibleLink(visibleLink);
 
@@ -167,6 +174,12 @@ public class CalendarPersonalConfigurationController extends FormBasicController
 		row.setToolsLink(toolsLink);
 	}
 	
+	private boolean isAlwaysVisible(CalendarPersonalConfigurationRow row) {
+		if(alwaysVisibleKalendar == null) return false;
+		return alwaysVisibleKalendar.getKalendar().getCalendarID().equals(row.getCalendarId())
+				&& alwaysVisibleKalendar.getKalendar().getType().equals(row.getCalendarType());
+	}
+	
 	private void enableDisableIcons(FormLink link, boolean enabled) {
 		link.setIconLeftCSS(enabled ? "o_icon o_icon_calendar_enabled" : "o_icon o_icon_calendar_disabled");
 	}
diff --git a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
index ede144f93f25d68937bd42fbb9ac6a51c92641d9..07083f73bf63151933480a209b30044a532ff5aa 100644
--- a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
@@ -179,7 +179,8 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 		formLayout.add("calendar", calendarEl);
 		calendarEl.setConfigurationEnabled(true);
 		calendarEl.setAggregatedFeedEnabled(true);
-		
+		calendarEl.setAlwaysVisibleCalendar(getCallerKalendarRenderWrapper());
+
 		if(formLayout instanceof FormLayoutContainer) {
 			FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
 			if (!isGuest && !calendarWrappers.isEmpty()) {
@@ -239,7 +240,8 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 			}
 		}
 	}
-	
+
+	@Override
 	public void setDifferentiateManagedEvent(boolean differentiate) {
 		calendarEl.setDifferentiateManagedEvents(differentiate);
 	}
@@ -501,6 +503,26 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 		eventCalloutCtr.activate();
 	}
 	
+	private KalendarRenderWrapper getCallerKalendarRenderWrapper() {
+		if(callerOres == null || calendarWrappers == null) return null;
+		
+		String callerResId = callerOres.getResourceableId().toString();
+		for(KalendarRenderWrapper calendarWrapper:calendarWrappers) {
+			String calendarType = calendarWrapper.getKalendar().getType();
+			String calendarId = calendarWrapper.getKalendar().getCalendarID();
+			if(callerResId.equals(calendarId)) {
+				if((WeeklyCalendarController.CALLER_COLLAB.equals(caller) && CalendarManager.TYPE_GROUP.equals(calendarType))
+						|| (WeeklyCalendarController.CALLER_COURSE.equals(caller) && CalendarManager.TYPE_COURSE.equals(calendarType))) {
+					return calendarWrapper;
+				}
+			} else if((WeeklyCalendarController.CALLER_PROFILE.equals(caller) || WeeklyCalendarController.CALLER_HOME.equals(caller))
+				&& CalendarManager.TYPE_USER.equals(calendarType) && calendarId.equals(callerOres.getResourceableTypeName())) {
+					return calendarWrapper;
+			}
+		}
+		return null;
+	}
+	
 	private String getCallerCalendarUrl() {
 		if(callerOres == null) return null;
 		
@@ -558,8 +580,10 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 		removeAsListenerAndDispose(cmc);
 		removeAsListenerAndDispose(configurationCtrl);
 		
+		KalendarRenderWrapper alwaysVisibleKalendar = getCallerKalendarRenderWrapper();
 		List<KalendarRenderWrapper> allCalendars = new ArrayList<>(calendarWrappers);
-		configurationCtrl = new CalendarPersonalConfigurationController(ureq, getWindowControl(), allCalendars, allowImport);
+		configurationCtrl = new CalendarPersonalConfigurationController(ureq, getWindowControl(),
+				allCalendars, alwaysVisibleKalendar, allowImport);
 		listenTo(configurationCtrl);
 		
 		String title = translate("cal.configuration.list");
diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponent.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponent.java
index 2da073f36691919292402dbe2652d4aea4ca82ec..c974812467a1bfefe30d4ae7f96c57afc191f400 100644
--- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponent.java
+++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponent.java
@@ -55,6 +55,7 @@ public class FullCalendarComponent extends AbstractComponent {
 	public static final String RECURRENCE_ID_SEP = "_xRecOOceRx_";
 	public static final String OCCURRENCE_ID_SEP = "_xOccOOccOx_";
 
+	private KalendarRenderWrapper alwaysVisibleCalendar;
 	private List<KalendarRenderWrapper> calendars = new ArrayList<>();
 	private Date currentDate;
 	private String viewName = "month";
@@ -132,6 +133,21 @@ public class FullCalendarComponent extends AbstractComponent {
 		this.differentiateManagedEvents = differentiateManagedEvents;
 	}
 
+	public KalendarRenderWrapper getAlwaysVisibleCalendar() {
+		return alwaysVisibleCalendar;
+	}
+
+	public void setAlwaysVisibleCalendar(KalendarRenderWrapper alwaysVisibleCalendar) {
+		this.alwaysVisibleCalendar = alwaysVisibleCalendar;
+	}
+	
+	public boolean isCalendarVisible(KalendarRenderWrapper calendar) {
+		return calendar.isVisible() ||
+				(alwaysVisibleCalendar != null
+					&& alwaysVisibleCalendar.getKalendar().getType().equals(calendar.getKalendar().getType())
+					&& alwaysVisibleCalendar.getKalendar().getCalendarID().equals(calendar.getKalendar().getCalendarID()));
+	}
+
 	/**
 	 * @see org.olat.core.gui.components.Component#doDispatchRequest(org.olat.core.gui.UserRequest)
 	 */
diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
index 044b13ff6b3344ab7d83fcdc3dfad311296aed59..b2b6f635246d71c648a4bb1524207f008fca9562 100644
--- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
+++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
@@ -117,7 +117,7 @@ public class FullCalendarComponentRenderer extends DefaultComponentRenderer {
 		  .append("	  eventSources:[");
 		int count = 0;
 		for(KalendarRenderWrapper calWrapper: fcC.getCalendars()) {
-			if(calWrapper.isVisible()) {
+			if(fcC.isCalendarVisible(calWrapper)) {
 				String calId = calWrapper.getKalendar().getCalendarID();
 				String color = calWrapper.getCssClass();
 				if(StringHelper.containsNonWhitespace(color) && color.startsWith("o_cal_")) {
diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarElement.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarElement.java
index d66764a7f37ff52c31e55160989d3494d3144b70..776ffbfb536228fcc82ea415afbfa1c5ae7d1934 100644
--- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarElement.java
+++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarElement.java
@@ -105,6 +105,14 @@ public class FullCalendarElement extends FormItemImpl {
 		component.addCalendar(calendarWrapper);
 	}
 	
+	public KalendarRenderWrapper getAlwaysVisibleCalendar() {
+		return component.getAlwaysVisibleCalendar();
+	}
+
+	public void setAlwaysVisibleCalendar(KalendarRenderWrapper alwaysVisibleCalendar) {
+		component.setAlwaysVisibleCalendar(alwaysVisibleCalendar);
+	}
+	
 	/**
 	 * @see org.olat.core.gui.components.form.flexible.FormItemImpl#evalFormRequest(org.olat.core.gui.UserRequest)
 	 */
diff --git a/src/main/java/org/olat/core/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/_i18n/LocalStrings_de.properties
index cf55a456f8e40fcd6ede1888a0053aea7f246cc3..c3a77774933c33868a80cc7e38b245963b45fdf6 100644
--- a/src/main/java/org/olat/core/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/core/_i18n/LocalStrings_de.properties
@@ -29,6 +29,7 @@ form.dirty.intro=Achtung! Sie haben noch ungespeicherte Formulardaten
 form.dirty.ignore=Wenn Sie die Schaltfläche <strong>$:form.dirty.button.ignore</strong> dr\u00FCcken verlassen Sie das Formular ohne zu speichern. <strong>Die enthaltenen \u00C4nderungen gehen damit verloren</strong>.
 form.dirty.back=Wenn Sie die Schaltfläche <strong>$:form.dirty.button.back</strong> dr\u00FCcken gelangen Sie zurück zum Formular und können dieses abspeichern. 
 form.error.nointeger=Ung\u00FCltige Zahl. Es muss eine Zahl eingegeben werden.
+form.error.toolong=Ihre Eingabe ist zu lang. Es sind maximal {0} Zeichen erlaubt.
 form.general.error=Es sind Eingabefehler aufgetreten. Bitte beachten Sie den Hinweis bei den Eingabefeldern.
 form.legende.mandatory=<i>Bitte f&uuml;llen Sie dieses Feld aus</i>.
 form.legende.wikiMarkup=<i>Dieses Feld erlaubt mit Wiki-Syntax formatierte Eingaben</i> </br >*<b>bold</b>*<br>_<i>italic</i>_<br>* Listen Elemente
@@ -109,6 +110,7 @@ toolbox.tools=Werkzeuge
 top=nach oben
 top.alt=Zum Anfang der Seite
 user.guest=Gast
+user.fullname.separator=;
 warn.beta.feature=Achtung\! Diese Funktion befindet sich in einer Versuchsphase. Bitte beachten Sie, dass Fehler auftreten k\u00F6nnen wenn diese Funktion verwendet wird. 
 warn.header=Achtung
 warn.notdispatched=Diese Seite wurde ver\u00E4ndert. Bitte beachten Sie allf\u00E4llige Meldungen.
diff --git a/src/main/java/org/olat/core/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/_i18n/LocalStrings_en.properties
index d3b14185c31d276101bdaaad6600be67d3b947fb..5cb8f61cc9f2a346624ae884d6f3ccd4f29407a4 100644
--- a/src/main/java/org/olat/core/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/core/_i18n/LocalStrings_en.properties
@@ -30,6 +30,7 @@ form.dirty.intro=Attention! You have not saved this form yet.
 form.dirty.ignore=By clicking <strong>$:form.dirty.button.ignore</strong> you will exit the form without saving. <strong>Changes you made on this page will be lost</strong>
 form.dirty.back=By clicking <strong>$:form.dirty.button.back</strong> you will get back to the form where you can save it. 
 form.error.nointeger=Illegal number. Please enter an integer.
+form.error.toolong=Your input is too long. A maximum of {0} characters are allowed.
 form.general.error=There are typing errors. Please consider the information next to the input fields.
 form.legende.mandatory=<i>Please fill in this field.</i>
 form.legende.wikiMarkup=<i>This field allows formatted entries using the Wiki Markup language.</i> </br >*<b>bold</b>*<br>_<i>italic</i>_<br>* List items
@@ -109,6 +110,7 @@ toolbox.tools=Tools
 top=Go to top
 top.alt=Go to top of page
 user.guest=Guest
+user.fullname.separator=/
 warn.beta.feature=Attention\! This is a beta feature. Be aware that using this feature might result in unexpected behavior.
 warn.header=Warning
 warn.notdispatched=This page has been modified. Please consider any new messages.
diff --git a/src/main/java/org/olat/core/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/_i18n/LocalStrings_fr.properties
index 03e732f3d4c9dd180b99a3b5fb562c422b33b622..e5b77dc24032f9b9ccd03ff4aad47c28f862320e 100644
--- a/src/main/java/org/olat/core/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/core/_i18n/LocalStrings_fr.properties
@@ -30,6 +30,7 @@ form.dirty.ignore=Si vous appuyez sur le bouton <strong>$\:form.dirty.button.ign
 form.dirty.intro=Attention\! Le formulaire contient encore des donn\u00E9es que vous n'avez pas enregistr\u00E9es.
 form.dirty.title=Donn\u00E9es non-enregistr\u00E9es
 form.error.nointeger=Nombre invalide. Il faut indiquer un nombre.
+form.error.toolong=Votre saisie est trop longue. Vous avez au maximum {0} caract\u00E8res \u00E0 disposition.
 form.general.error=Des erreurs de saisie sont survenues. Suivez les indications relatives aux champs, svp.
 form.legende.mandatory=<i>Veuillez remplir ce champ.</i>
 form.legende.wikiMarkup=<i>Ce champ peut \u00EAtre format\u00E9 \u00E0 l'aide des balises Wiki.</i> </br >*<b>bold</b>*<br>_<i>italic</i>_<br>* Liste d'\u00E9l\u00E9ments
@@ -109,6 +110,7 @@ toolbox.tools=Outils
 top=vers le haut
 top.alt=Vers le d\u00E9but de la page
 user.guest=invit\u00E9
+user.fullname.separator=/
 warn.beta.feature=Attention\! Cette fonction se trouve dans la phase d'essai. Veuillez noter que des erreurs peuvent appara\u00EEtre si cette fonction est utilis\u00E9e.
 warn.header=Attention
 warn.notdispatched=Cette page a \u00E9t\u00E9 modifi\u00E9e. Veuillez tenir compte d'\u00E9ventuels messages.
diff --git a/src/main/java/org/olat/core/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/core/_i18n/LocalStrings_pt_BR.properties
index d2fbb873ef3d2d5d2551295fe62aaf40c46919d9..9c849bf555eec0f6df915cbe737dda9ce6c4d380 100644
--- a/src/main/java/org/olat/core/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/core/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Tue Sep 05 19:07:58 CEST 2017
+#Wed Feb 28 13:29:33 CET 2018
 alert=Favor selecionar no m\u00EDnimo um objeto para sua a\u00E7\u00E3o.
 back=Voltar
 calendar.choose=Escolha uma data do mini calend\u00E1rio
@@ -30,6 +30,7 @@ form.dirty.ignore=Ao clicar em <strong>$\:form.dirty.button.ignore</strong>, voc
 form.dirty.intro=Aten\u00E7\u00E3o\! Voc\u00EA ainda n\u00E3o salvou este formul\u00E1rio.
 form.dirty.title=Dados do formul\u00E1rio n\u00E3o salvos
 form.error.nointeger=N\u00FAmero inv\u00E1lido. Por favor insira um n\u00FAmero inteiro.
+form.error.toolong=Sua inser\u00E7\u00E3o est\u00E1 muito longa. Um m\u00E1ximo de {0} caracteres \u00E9 permitido.
 form.general.error=Formul\u00E1rio de dados n\u00E3o \u00E9 v\u00E1lido.
 form.legende.mandatory=<i>Favor preencher este campo.</i>
 form.legende.wikiMarkup=\=<i>Este campo permite itens formatados usando a linguagem wiki markup.</i> </br >*<b>bold</b>*<br>_<i>it\u00E1lico</i>_<br>* Listar itens
diff --git a/src/main/java/org/olat/core/configuration/PersistedProperties.java b/src/main/java/org/olat/core/configuration/PersistedProperties.java
index 56f976905051f40f5afcab6f7776683aa70bc1c7..baf51868fd6a95980c0cdb289ad4769fe3547ed9 100644
--- a/src/main/java/org/olat/core/configuration/PersistedProperties.java
+++ b/src/main/java/org/olat/core/configuration/PersistedProperties.java
@@ -443,7 +443,8 @@ public class PersistedProperties extends LogDelegator implements Initializable,
 	
 	public void removeProperty(String propertyName, boolean saveConfiguration) {
 		synchronized (configuredProperties) { // make read/write save in VM
-			configuredProperties.remove(propertyName);
+			Object removedProperty = configuredProperties.remove(propertyName);
+			propertiesDirty |= removedProperty != null;
 			if (saveConfiguration) {
 				savePropertiesAndFireChangedEvent();
 			}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/DateChooser.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/DateChooser.java
index 34fcec1c4e0697affe1bd3b0f87fb05141444d1d..84fe5a43b5017a5d57885c9b97532edbe5d7755e 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/DateChooser.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/DateChooser.java
@@ -31,7 +31,7 @@ import java.util.Date;
  * @author patrickb
  *
  */
-public interface DateChooser extends TextElement{
+public interface DateChooser extends TextElement {
 
 	/**
 	 * @return the date or null if the value is not valid (parsed with
@@ -62,5 +62,16 @@ public interface DateChooser extends TextElement{
 	public void setValidDateCheck(String errorKey);
 
 	public String getExampleDateString();
+	
+	
+	public DateChooser getDefaultValue();
+	
+	/**
+	 * Set an other date chooser as default value for this
+	 * chooser.
+	 * 
+	 * @param dateChooser A date chooser
+	 */
+	public void setDefaultValue(DateChooser dateChooser);
 
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooser.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooser.java
index 96137f0044712576a2967ccc58f4da74ddd96963..b45c6b30f2d0ea7a79fb70bdac8cd76f33aad88e 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooser.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooser.java
@@ -42,8 +42,6 @@ import org.olat.core.util.ValidationStatus;
 import org.olat.core.util.ValidationStatusImpl;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for JSDateChooser
  * <P>
  * Initial Date: 19.01.2007 <br>
  * 
@@ -65,7 +63,9 @@ public class JSDateChooser extends TextElementImpl implements DateChooser {
 	private boolean dateChooserTimeEnabled;
 	private String forValidDateErrorKey;
 	private boolean checkForValidDate;
-	private int minute, hour;
+	private int minute;
+	private int hour;
+	private DateChooser defaultDateValue;
 	
 	public JSDateChooser(String name, Locale locale) {
 		this(null, name, null, locale);
@@ -111,6 +111,16 @@ public class JSDateChooser extends TextElementImpl implements DateChooser {
 		return dateComponent;
 	}
 
+	@Override
+	public DateChooser getDefaultValue() {
+		return defaultDateValue;
+	}
+
+	@Override
+	public void setDefaultValue(DateChooser dateChooser) {
+		defaultDateValue = dateChooser;
+	}
+
 	/**
 	 * @see org.olat.core.gui.components.form.flexible.elements.AbstractTextElement#validate(java.util.List)
 	 */
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserComponent.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserComponent.java
index 6f71e9076ddad1b96b7d9327d161b64bcf3ab208..43e4b1ca86da35e29b9efcab28f450eecaf67f6e 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserComponent.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserComponent.java
@@ -35,9 +35,6 @@ import org.olat.core.gui.render.ValidationResult;
 import org.olat.core.gui.translator.Translator;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for JSDateChooserComponent
- * 
  * <P>
  * Initial Date: 19.01.2007 <br>
  * 
@@ -45,7 +42,7 @@ import org.olat.core.gui.translator.Translator;
  */
 class JSDateChooserComponent extends FormBaseComponentImpl {
 	
-	private final static ComponentRenderer RENDERER = new JSDateChooserRenderer();
+	private static final ComponentRenderer RENDERER = new JSDateChooserRenderer();
 	private JSDateChooser element;
 
 	public JSDateChooserComponent(JSDateChooser element) {
@@ -104,4 +101,8 @@ class JSDateChooserComponent extends FormBaseComponentImpl {
 	public String getExampleDateString() {
 		return element.getExampleDateString();
 	}
+	
+	public JSDateChooser getFormItem() {
+		return element;
+	}
 }
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
index db6b7fe2880943afbdbeef4c786a39c7753aed05..8f6539b8378076682498e685be3510c982964ddc 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
@@ -40,8 +40,6 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.util.Util;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for JSDateChooserRenderer
  * <P>
  * Initial Date: 19.01.2007 <br>
  * 
@@ -87,7 +85,7 @@ class JSDateChooserRenderer extends DefaultComponentRenderer {
 			  .append("></i></span>")
 			  .append("</div></div>");//input-group
 			// date chooser javascript
-			sb.append("<script type=\"text/javascript\">\n /* <![CDATA[ */ \n")
+			sb.append("<script>\n /* <![CDATA[ */ \n")
 				.append("jQuery(function(){ jQuery('#").append(receiverId).append("').datepicker({\n")
 				.append("  dateFormat:'").append(format).append("',\n")
 				.append("  firstDay:1,\n")
@@ -114,11 +112,18 @@ class JSDateChooserRenderer extends DefaultComponentRenderer {
 				  .append("'").append(dateTranslator.translate("day.short.fr")).append("',")
 				  .append("'").append(dateTranslator.translate("day.short.sa")).append("'")
 				.append("],\n")
-				.append("  showOtherMonths:true,\n")
-				.append("  onSelect:function(){\n")
-				.append("    setFlexiFormDirty('").append(te.getRootForm().getDispatchFieldId()).append("');\n")
-				.append("    jQuery(this).change();\n")
-				.append("  }\n")
+				.append("  showOtherMonths:true,\n");
+			if(jsdcc.getFormItem().getDefaultValue() != null) {
+				String id = ((JSDateChooser)jsdcc.getFormItem().getDefaultValue()).getTextElementComponent().getFormDispatchId();
+				sb.append("  beforeShow:function(el, inst) {\n")
+				  .append("    var defDate = jQuery('#").append(id).append("').datepicker('getDate');\n")
+				  .append("    jQuery('#").append(receiverId).append("').datepicker('option', 'defaultDate', defDate);")
+				  .append("  },\n");
+			}
+			sb.append("  onSelect:function(){\n")
+			  .append("    setFlexiFormDirty('").append(te.getRootForm().getDispatchFieldId()).append("');\n")
+			  .append("    jQuery(this).change();\n")
+			  .append("  }\n")
 			  .append("})});")
 			  .append("\n/* ]]> */ \n</script>");
 			
diff --git a/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java b/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java
index edce7e128496f426040597fc188759280b4d6d0a..32a8b69ed9a9529d049b85d117ada618dffa8026 100644
--- a/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java
+++ b/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java
@@ -126,7 +126,7 @@ public class TabbedPane extends Container implements Activateable2 {
 	}
 	
 	public OLATResourceable getTabResource() {
-		return OresHelper.createOLATResourceableInstance("tab", new Long(selectedPane));
+		return OresHelper.createOLATResourceableInstance("tab", Long.valueOf(selectedPane));
 	}
 	
 	public void addToHistory(UserRequest ureq, WindowControl wControl) {
@@ -199,7 +199,7 @@ public class TabbedPane extends Container implements Activateable2 {
 	
 	public int indexOfTab(String displayName) {
 		for(int i=tabPanes.size(); i-->0; ) {
-			if(displayName.equals(tabPanes.get(i).getComponent())) {
+			if(displayName.equals(tabPanes.get(i).getDisplayName())) {
 				return i;
 			}
 		}
@@ -304,6 +304,7 @@ public class TabbedPane extends Container implements Activateable2 {
 	 * @deprecated
 	 * @param displayName
 	 */
+	@Deprecated
 	public void setSelectedPane(UserRequest ureq, String displayName) {
 		if (displayName == null) return;
 		int pos = indexOfTab(displayName);
@@ -417,7 +418,6 @@ public class TabbedPane extends Container implements Activateable2 {
 		
 		public void setController(Controller controller) {
 			if(controller == null) {
-				controller = null;
 				component = null;
 			} else {
 				this.controller = controller;
diff --git a/src/main/java/org/olat/core/util/IPUtils.java b/src/main/java/org/olat/core/util/IPUtils.java
index 2dab48d5936463d5ca800d9b581356d0e7ec8d85..c2b0fc76669361261b1a2a3e8ea0ecae50858e3d 100644
--- a/src/main/java/org/olat/core/util/IPUtils.java
+++ b/src/main/java/org/olat/core/util/IPUtils.java
@@ -26,7 +26,7 @@ import org.olat.core.logging.Tracing;
  * 
  * Thanks: https://gist.github.com/madan712/6651967
  * 
- * It's based of the InetAddresses clas from guava too and
+ * It's based of the InetAddresses class from guava too and
  * prevent a DNS lookup of java.net.InetAddress
  * 
  * Initial date: 18.12.2014<br>
@@ -48,6 +48,7 @@ public class IPUtils {
 	
 	public static boolean isValidRange(String ipWithMask, String address) {
 		boolean allOk = false;
+		ipWithMask = ipWithMask.trim();
 		int maskIndex = ipWithMask.indexOf('/');
 		if(maskIndex > 0) {
 			long bits = Long.parseLong(ipWithMask.substring(maskIndex + 1));
@@ -71,6 +72,9 @@ public class IPUtils {
 	 */
 	public static boolean isValidRange(String ipStart, String ipEnd, String ipToCheck) {
 		try {
+			ipStart = ipStart.trim();
+			ipEnd = ipEnd.trim();
+			ipToCheck = ipToCheck.trim();
 			long ipLo = ipToLong(textToNumericFormatV4(ipStart));
 			long ipHi = ipToLong(textToNumericFormatV4(ipEnd));
 			long ipToTest = ipToLong(textToNumericFormatV4(ipToCheck));
diff --git a/src/main/java/org/olat/core/util/openxml/OpenXMLWorkbookStyles.java b/src/main/java/org/olat/core/util/openxml/OpenXMLWorkbookStyles.java
index 4885c5906b5ac7e7b64ff7f325e917f425811589..6e9b226dcc701036ee10e5bc02ebfb1a5701ce55 100644
--- a/src/main/java/org/olat/core/util/openxml/OpenXMLWorkbookStyles.java
+++ b/src/main/java/org/olat/core/util/openxml/OpenXMLWorkbookStyles.java
@@ -48,7 +48,7 @@ public class OpenXMLWorkbookStyles {
 	private List<CellStyle> cellXfs = new ArrayList<>();
 	
 	private final Font standardFont, boldFont;
-	private final Fill noneFile, gray125Fill, correctFill;
+	private final Fill noneFile, gray125Fill, lightGrayFill, correctFill;
 	private final Border noBorder, borderRight;
 	
 	/**
@@ -62,6 +62,7 @@ public class OpenXMLWorkbookStyles {
 	private final CellStyle headerStyle;
 	private final CellStyle correctStyle;
 	private final CellStyle percentStyle;
+	private final CellStyle lightGrayStyle;
 
 	public OpenXMLWorkbookStyles() {
 		standardFont = new Font(fonts.size(), "12", "1", "Calibri", "2", "minor", FontStyle.none);
@@ -73,6 +74,8 @@ public class OpenXMLWorkbookStyles {
 		fills.add(noneFile);
 		gray125Fill = new Fill(fills.size(), "gray125");
 		fills.add(gray125Fill);
+		lightGrayFill = new Fill(fills.size(), "solid", "EFEFEFEF", "64");
+		fills.add(lightGrayFill);
 		correctFill = new Fill(fills.size(), "solid", "FFC3FFC0", "64");
 		fills.add(correctFill);
 		
@@ -97,6 +100,8 @@ public class OpenXMLWorkbookStyles {
 		cellXfs.add(correctStyle);
 		percentStyle = new CellStyle(cellXfs.size(), PERCENT_FORMAT, standardFont, noneFile, borderRight, null, "1");
 		cellXfs.add(percentStyle);
+		lightGrayStyle = new CellStyle(cellXfs.size(), "0", standardFont, lightGrayFill, borderRight, null, null);
+		cellXfs.add(lightGrayStyle);
 	}
 	
 	public CellStyle getBorderRightStyle() {
@@ -135,6 +140,10 @@ public class OpenXMLWorkbookStyles {
 		return percentStyle;
 	}
 	
+	public CellStyle getLightGrayStyle() {
+		return lightGrayStyle;
+	}
+	
 	public List<Font> getFonts() {
 		return fonts;
 	}
diff --git a/src/main/java/org/olat/course/MergedCourseContainer.java b/src/main/java/org/olat/course/MergedCourseContainer.java
index a8e3243c9837249628ce4a7b6ac244057580ea02..16541f4a15acabd3c0f97e8f352a2c0f02042966 100644
--- a/src/main/java/org/olat/course/MergedCourseContainer.java
+++ b/src/main/java/org/olat/course/MergedCourseContainer.java
@@ -35,11 +35,9 @@ import org.olat.core.util.vfs.NamedContainerImpl;
 import org.olat.core.util.vfs.Quota;
 import org.olat.core.util.vfs.QuotaManager;
 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.vfs.callbacks.ReadOnlyCallback;
 import org.olat.core.util.vfs.callbacks.VFSSecurityCallback;
-import org.olat.core.util.vfs.filters.VFSItemFilter;
 import org.olat.course.config.CourseConfig;
 import org.olat.course.nodes.BCCourseNode;
 import org.olat.course.nodes.CourseNode;
@@ -308,7 +306,7 @@ public class MergedCourseContainer extends MergeSource {
 				// , then do recursion for all children ...
 				addFoldersForAdmin(course, courseNodeContainer, child);
 				// ... but only add this container if it contains any children with at least one BC course node
-				if (courseNodeContainer.getItems().size() > 0) {
+				if (!courseNodeContainer.getItems().isEmpty()) {
 					nodesContainer.addContainer(courseNodeContainer);
 				}
 			}
@@ -325,12 +323,7 @@ public class MergedCourseContainer extends MergeSource {
 	 */
 	private String getFolderName(MergeSource nodesContainer, CourseNode bcNode, String folderName) {
 		// add node ident if multiple files have same name
-		if (nodesContainer.getItems(new VFSItemFilter() {
-			@Override
-			public boolean accept(VFSItem vfsItem) {
-				return (bcNode.getShortTitle().equals(RequestUtil.normalizeFilename(bcNode.getShortTitle())));
-			}
-		}).size() > 0) {
+		if (!nodesContainer.getItems(vfsItem -> vfsItem.getName().equals(RequestUtil.normalizeFilename(bcNode.getShortTitle()))).isEmpty()) {
 			folderName = folderName + " (" + bcNode.getIdent() + ")";
 		}
 		return folderName;
diff --git a/src/main/java/org/olat/course/archiver/FormatConfigHelper.java b/src/main/java/org/olat/course/archiver/FormatConfigHelper.java
index 02f411d782650bd4caeca1817d21901156a72d83..8f1d1e2e76bacecaa837688a5558a5452c507079 100644
--- a/src/main/java/org/olat/course/archiver/FormatConfigHelper.java
+++ b/src/main/java/org/olat/course/archiver/FormatConfigHelper.java
@@ -22,6 +22,7 @@ package org.olat.course.archiver;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.prefs.Preferences;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.nodes.ArchiveOptions;
@@ -50,8 +51,11 @@ public class FormatConfigHelper {
 			try {
 				Preferences guiPrefs = ureq.getUserSession().getGuiPreferences();
 				String formatConfigString = (String) guiPrefs.get(ExportOptionsController.class, QTI_EXPORT_ITEM_FORMAT_CONFIG);
-				Object formatObject = configXstream.fromXML(formatConfigString);
-				formatConfig = (ExportFormat) formatObject;
+				if(StringHelper.containsNonWhitespace(formatConfigString)) {
+					formatConfig = (ExportFormat)configXstream.fromXML(formatConfigString);
+				} else {
+					formatConfig = new ExportFormat(true, true, true, true, true);
+				}
 			} catch (Exception e) {
 				log.error("could not establish object from xml", e);
 				formatConfig = new ExportFormat(true, true, true, true, true);
diff --git a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java
index c6d3830c0e0e6cca7e3a7d40346d9df7fdf197a2..119fbba20d168778fa15c37f8a5619d105e91595 100644
--- a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java
+++ b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java
@@ -196,6 +196,7 @@ public class AssessmentModeEditController extends FormBasicController {
 		endEl = uifactory.addDateChooser("mode.end", assessmentMode.getEnd(), formLayout);
 		endEl.setElementCssClass("o_sel_assessment_mode_end");
 		endEl.setDateChooserTimeEnabled(true);
+		endEl.setDefaultValue(beginEl);
 		endEl.setMandatory(true);
 		endEl.setEnabled(status != Status.end);
 		
@@ -606,7 +607,7 @@ public class AssessmentModeEditController extends FormBasicController {
 
 		//update groups
 		if(groupKeys.isEmpty()) {
-			if(assessmentMode.getGroups().size() > 0) {
+			if(!assessmentMode.getGroups().isEmpty()) {
 				assessmentMode.getGroups().clear();
 			}
 		} else {
@@ -631,7 +632,7 @@ public class AssessmentModeEditController extends FormBasicController {
 		
 		//update areas
 		if(areaKeys.isEmpty()) {
-			if(assessmentMode.getAreas().size() > 0) {
+			if(!assessmentMode.getAreas().isEmpty()) {
 				assessmentMode.getAreas().clear();
 			}
 		} else {
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
index 0f90f372c2c6fe76fced3f92db6210aa3dad6e54..65ad64d781b5f279d12b85c597fbd69a3fc8808d 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
@@ -158,8 +158,8 @@ public class AssessmentIdentityListCourseTreeController extends BasicController
 		
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance("Node", new Long(courseNode.getIdent()));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
-		if(courseNode instanceof AssessableCourseNode && ((AssessableCourseNode)courseNode).isAssessedBusinessGroups()) {
-			if(courseNode instanceof GTACourseNode) {
+		if(courseNode instanceof AssessableCourseNode) {
+			if(((AssessableCourseNode)courseNode).isAssessedBusinessGroups() && courseNode instanceof GTACourseNode) {
 				CourseEnvironment courseEnv = CourseFactory.loadCourse(courseEntry).getCourseEnvironment();
 				
 				List<BusinessGroup> coachedGroups;
@@ -170,8 +170,11 @@ public class AssessmentIdentityListCourseTreeController extends BasicController
 				} else {
 					coachedGroups = assessmentCallback.getCoachedGroups();
 				}
-				currentCtrl = ((GTACourseNode)courseNode).getCoachedGroupListController(ureq, getWindowControl(), stackPanel,
+				currentCtrl = ((GTACourseNode)courseNode).getCoachedGroupListController(ureq, bwControl, stackPanel,
 						coachCourseEnv, assessmentCallback.isAdmin(), coachedGroups);
+			} else {
+				currentCtrl = ((AssessableCourseNode)courseNode).getIdentityListController(ureq, bwControl, stackPanel,
+						courseEntry, businessGroup, coachCourseEnv, toolContainer, assessmentCallback);
 			}
 		} else {
 			currentCtrl = new IdentityListCourseNodeController(ureq, bwControl, stackPanel,
diff --git a/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties
index a86eadc2dca9a8d5b243f6f49a4cd61212f74b38..b58e8ba42b9d8ba71d6e933d9fa79c793e3e1740 100644
--- a/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 13:42:54 CET 2018
+#Wed Feb 28 13:30:38 CET 2018
 command.new_db=Criar novo banco de dados
 customDb.category=Nome
 customDb.create=Criar
diff --git a/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java b/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
index 490fe21a03623737a29704c47a8835d5dcaf28dc..3fe5d4c33b011be31e005113de7d99f6e97f8570 100644
--- a/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
@@ -157,9 +157,9 @@ public abstract class AbstractAccessableCourseNode extends GenericCourseNode {
 		ArrayList<ConditionExpression> retVal;
 		List<ConditionExpression> parentsConditions = super.getConditionExpressions();
 		if (parentsConditions.size() > 0) {
-			retVal = new ArrayList<ConditionExpression>(parentsConditions);
+			retVal = new ArrayList<>(parentsConditions);
 		} else {
-			retVal = new ArrayList<ConditionExpression>();
+			retVal = new ArrayList<>();
 		}
 		//
 		String coS = getPreConditionAccess().getConditionExpression();
diff --git a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
index 744c53c390497d5c7de2416a4f026f4f1bd2581a..40a3cb6729094ab2fc34ad24fbf8c88516ced498 100644
--- a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
@@ -96,7 +96,7 @@ import org.olat.repository.RepositoryEntry;
  */
 public class CheckListCourseNode extends AbstractAccessableCourseNode implements PersistentAssessableCourseNode {
 	
-	private static final String translatorStr = Util.getPackageName(CheckListEditController.class);
+	private static final String PACKAGE_CL = Util.getPackageName(CheckListEditController.class);
 	private static final long serialVersionUID = -7460670977531082040L;
 	
 	private static final String TYPE = "checklist";
@@ -206,11 +206,16 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 */
 	@Override
 	public StatusDescription isConfigValid() {
-		if (oneClickStatusCache != null) {
+		if (oneClickStatusCache != null && oneClickStatusCache.length > 0) {
 			return oneClickStatusCache[0];
 		}
-		StatusDescription sd = StatusDescription.NOERROR;
-		return sd;
+		
+		List<StatusDescription> statusDescs = validateInternalConfiguration();
+		if(statusDescs.isEmpty()) {
+			statusDescs.add(StatusDescription.NOERROR);
+		}
+		oneClickStatusCache = StatusDescriptionHelper.sort(statusDescs);
+		return oneClickStatusCache[0];
 	}
 
 	/**
@@ -221,18 +226,56 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		oneClickStatusCache = null;
 		// only here we know which translator to take for translating condition
 		// error messages
-		List<StatusDescription> sds = isConfigValidWithTranslator(cev, translatorStr, getConditionExpressions());
+		List<StatusDescription> sds = isConfigValidWithTranslator(cev, PACKAGE_CL, getConditionExpressions());
+		if(oneClickStatusCache != null && oneClickStatusCache.length > 0) {
+			//isConfigValidWithTranslator add first
+			sds.remove(oneClickStatusCache[0]);
+		}
+		sds.addAll(validateInternalConfiguration());
 		oneClickStatusCache = StatusDescriptionHelper.sort(sds);
 		return oneClickStatusCache;
 	}
+	
+	private List<StatusDescription> validateInternalConfiguration() {
+		List<StatusDescription> sdList = new ArrayList<>(5);
+
+		ModuleConfiguration config = getModuleConfiguration();
+		
+		Boolean hasScore = (Boolean)config.get(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
+		if ((hasScore == null || hasScore.booleanValue()) &&
+				(config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN) == null || config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX) == null)) {
+			addStatusErrorDescription("error.missing.score.config", CheckListEditController.PANE_TAB_CLCONFIG, sdList);
+		}
+		
+		Boolean hasPassed = (Boolean)config.get(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
+		if (hasPassed == null || hasPassed.booleanValue()) {
+			
+			Boolean passedSum = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CHECKBOX);
+			Boolean manualCorr = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_MANUAL_CORRECTION);
+			if((manualCorr == null || !manualCorr.booleanValue()) && (passedSum == null || !passedSum.booleanValue())
+					&& config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE) == null) {
+				addStatusErrorDescription("error.missing.cutvalue.config", CheckListEditController.PANE_TAB_CLCONFIG, sdList);	
+			}
+		}
+		
+		return sdList;
+	}
+	
+	private void addStatusErrorDescription(String key, String pane, List<StatusDescription> status) {
+		String[] params = new String[] { getShortTitle() };
+		StatusDescription sd = new StatusDescription(StatusDescription.ERROR, key, key, params, PACKAGE_CL);
+		sd.setDescriptionForUnit(getIdent());
+		sd.setActivateableViewIdentifier(pane);
+		status.add(sd);
+	}
 
 	@Override
 	public List<StatusDescription> publishUpdatesExplanations(CourseEditorEnv cev) {
 		List<StatusDescription> statusDescs = new ArrayList<>();
-		StatusDescription statusDesc1 = new StatusDescription(Level.INFO, "checklist.update.assessment", null, null, translatorStr);
+		StatusDescription statusDesc1 = new StatusDescription(Level.INFO, "checklist.update.assessment", null, null, PACKAGE_CL);
 		statusDesc1.setDescriptionForUnit(getIdent());
 		statusDescs.add(statusDesc1);
-		StatusDescription statusDesc2 = new StatusDescription(Level.INFO, "checklist.update.efficiencystatements", null, null, translatorStr);
+		StatusDescription statusDesc2 = new StatusDescription(Level.INFO, "checklist.update.efficiencystatements", null, null, PACKAGE_CL);
 		statusDesc2.setDescriptionForUnit(getIdent());
 		statusDescs.add(statusDesc2);
 		return statusDescs;
@@ -268,8 +311,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 			throw new OLATRuntimeException(MSCourseNode.class, "getCutValue not defined when hasPassed set to false", null);
 		}
 		ModuleConfiguration config = getModuleConfiguration();
-		Float cut = (Float) config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-		return cut;
+		return (Float)config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
 	}
 
 	/**
@@ -281,8 +323,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 			throw new OLATRuntimeException(MSCourseNode.class, "getMaxScore not defined when hasScore set to false", null);
 		}
 		ModuleConfiguration config = getModuleConfiguration();
-		Float max = (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-		return max;
+		return (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
 	}
 
 	/**
@@ -294,8 +335,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 			throw new OLATRuntimeException(MSCourseNode.class, "getMinScore not defined when hasScore set to false", null);
 		}
 		ModuleConfiguration config = getModuleConfiguration();
-		Float min = (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-		return min;
+		return (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
 	}
 
 	/**
@@ -304,8 +344,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	@Override
 	public String getUserCoachComment(UserCourseEnvironment userCourseEnvironment) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
-		String coachCommentValue = am.getNodeCoachComment(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
-		return coachCommentValue;
+		return am.getNodeCoachComment(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
 	}
 
 	/**
@@ -314,8 +353,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	@Override
 	public String getUserLog(UserCourseEnvironment userCourseEnvironment) {
 		UserNodeAuditManager am = userCourseEnvironment.getCourseEnvironment().getAuditManager();
-		String logValue = am.getUserNodeLog(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
-		return logValue;
+		return am.getUserNodeLog(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
 	}
 
 	/**
@@ -324,8 +362,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	@Override
 	public String getUserUserComment(UserCourseEnvironment userCourseEnvironment) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
-		String userCommentValue = am.getNodeComment(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
-		return userCommentValue;
+		return am.getNodeComment(this, userCourseEnvironment.getIdentityEnvironment().getIdentity());
 	}
 	
 	@Override
@@ -696,9 +733,9 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		Boolean passed = null;
 		if(cutValue != null) {
 			boolean aboveCutValue = score >= cutValue.floatValue();
-			passed = new Boolean(aboveCutValue);
+			passed = Boolean.valueOf(aboveCutValue);
 		}
-		ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), passed);
+		ScoreEvaluation sceval = new ScoreEvaluation(Float.valueOf(score), passed);
 		
 		AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager();
 		am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by);
diff --git a/src/main/java/org/olat/course/nodes/GTACourseNode.java b/src/main/java/org/olat/course/nodes/GTACourseNode.java
index 7fdae523986ffbd1c6dfd97cc28f4c58e7d09c9e..d79c10eb3099f6205306b4cf8f7d9776282aeb6f 100644
--- a/src/main/java/org/olat/course/nodes/GTACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GTACourseNode.java
@@ -106,8 +106,8 @@ import org.olat.user.UserManager;
  */
 public class GTACourseNode extends AbstractAccessableCourseNode implements PersistentAssessableCourseNode {
 	
-	private final static OLog log = Tracing.createLoggerFor(GTACourseNode.class);
-	private final static String PACKAGE_GTA = Util.getPackageName(GTAEditController.class);
+	private static final OLog log = Tracing.createLoggerFor(GTACourseNode.class);
+	private static final String PACKAGE_GTA = Util.getPackageName(GTAEditController.class);
 
 	private static final long serialVersionUID = 1L;
 	
diff --git a/src/main/java/org/olat/course/nodes/GenericCourseNode.java b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
index c0f0ea8e819eb01531936f9cd0359b5b9af0fa52..9d417bb3af25d71cdb647c56f9f253b2ff328980 100644
--- a/src/main/java/org/olat/course/nodes/GenericCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
@@ -614,7 +614,7 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
 	 */
 	//for StatusDescription.WARNING
 	protected List<StatusDescription> isConfigValidWithTranslator(CourseEditorEnv cev, String translatorStr, List<ConditionExpression> condExprs) {
-		List<StatusDescription> condExprsStatusDescs = new ArrayList<StatusDescription>();
+		List<StatusDescription> condExprsStatusDescs = new ArrayList<>();
 		// check valid configuration without course environment
 		StatusDescription first = isConfigValid();
 		// check valid configuration within the course environment
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
index 34b6ad6fcc3d4d686bc8a77b2bedf0e0ee9af134..3ec5013fae2a7fa7b0c2cdb137ab64d73d8222df 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListConfigurationController.java
@@ -239,7 +239,7 @@ public class CheckListConfigurationController extends FormBasicController {
 
 		//due date
 		boolean closeAfterDueDate = dueDateEl.isAtLeastSelected(1);
-		config.set(CheckListCourseNode.CONFIG_KEY_CLOSE_AFTER_DUE_DATE, new Boolean(closeAfterDueDate));
+		config.set(CheckListCourseNode.CONFIG_KEY_CLOSE_AFTER_DUE_DATE, Boolean.valueOf(closeAfterDueDate));
 		Date dueDate = dueDateChooserEl.getDate();
 		if(dueDate != null) {
 			config.set(CheckListCourseNode.CONFIG_KEY_DUE_DATE, dueDate);
@@ -247,7 +247,7 @@ public class CheckListConfigurationController extends FormBasicController {
 			config.remove(CheckListCourseNode.CONFIG_KEY_DUE_DATE);
 		}
 		//score
-		Boolean sf = new Boolean(scoreGrantedEl.isSelected(0));
+		Boolean sf = Boolean.valueOf(scoreGrantedEl.isSelected(0));
 		config.set(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD, sf);
 		if (sf.booleanValue()) {
 			config.set(MSCourseNode.CONFIG_KEY_SCORE_MIN, new Float(minPointsEl.getValue()));
@@ -258,7 +258,7 @@ public class CheckListConfigurationController extends FormBasicController {
 		}
 		
 		// mandatory passed flag
-		Boolean pf = new Boolean(passedEl.isSelected(0));
+		Boolean pf = Boolean.valueOf(passedEl.isSelected(0));
 		config.set(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD, pf);
 		config.remove(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
 		config.remove(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CUTVALUE);
@@ -271,16 +271,16 @@ public class CheckListConfigurationController extends FormBasicController {
 			} else if("sum".equals(output)) {
 				config.set(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CHECKBOX, Boolean.TRUE);
 				int sumCutValue = Integer.parseInt(sumCheckboxEl.getSelectedKey());
-				config.set(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CUTVALUE, new Integer(sumCutValue));
+				config.set(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CUTVALUE, Integer.valueOf(sumCutValue));
 			} else if("coach".equals(output)) {
 				config.set(CheckListCourseNode.CONFIG_KEY_PASSED_MANUAL_CORRECTION, Boolean.TRUE);
 			}
 		}
 
 		// mandatory comment flag
-		config.set(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD, new Boolean(commentEl.isSelected(0)));
+		config.set(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD, Boolean.valueOf(commentEl.isSelected(0)));
 		// individual assessment docs
-		config.setBooleanEntry(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, new Boolean(assessmentDocsEl.isSelected(0)));
+		config.setBooleanEntry(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, assessmentDocsEl.isSelected(0));
 
 		// set info text only if something is in there
 		String iu = tipUserEl.getValue();
@@ -300,7 +300,7 @@ public class CheckListConfigurationController extends FormBasicController {
 
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
+		boolean allOk = super.validateFormLogic(ureq);
 		
 		//wizardery need title prefix and number of checklist to be defined
 		if(wizard) {
@@ -362,7 +362,7 @@ public class CheckListConfigurationController extends FormBasicController {
 			}
 		}
 		
-		return allOk & super.validateFormLogic(ureq);
+		return allOk;
 	}
 	
 	private float toFloat(String val) {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListEditController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListEditController.java
index 76b069403ee6d6abe497f767e2cfd7943bf972fc..f0f3f6fb871520aefd7754094b9b14a7211cae80 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListEditController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListEditController.java
@@ -61,7 +61,7 @@ public class CheckListEditController extends ActivateableTabbableDefaultControll
 
 	private TabbedPane myTabbedPane;
 
-	private final static String[] paneKeys = { PANE_TAB_CLCONFIG, PANE_TAB_CHECKBOX };
+	private static final String[] paneKeys = { PANE_TAB_CLCONFIG, PANE_TAB_CHECKBOX };
 
 	/**
 	 * @param cpNode
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 951a2bfd56a3bfa1d7c72358405ff7be33f4aaac..4f685c12f1617d72e90310cd6e0fd2cccf157f4f 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
@@ -38,6 +38,7 @@ 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.control.Controller;
 import org.olat.core.gui.control.ControllerEventListener;
+import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
 import org.olat.core.id.OLATResourceable;
@@ -138,7 +139,7 @@ public class CheckListRunController extends FormBasicController implements Contr
 		boolean readOnly = isReadOnly();
 		if(formLayout instanceof FormLayoutContainer) {
 			FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
-			layoutCont.contextPut("readOnly", new Boolean(readOnly));
+			layoutCont.contextPut("readOnly", Boolean.valueOf(readOnly));
 			if(dueDate != null) {
 				layoutCont.contextPut("dueDate", dueDate);
 				layoutCont.contextPut("in-due-date", isPanelOpen(ureq, "due-date", true));
@@ -290,7 +291,9 @@ public class CheckListRunController extends FormBasicController implements Contr
 			CheckboxWrapper wrapper = (CheckboxWrapper)boxEl.getUserObject();
 			if(wrapper != null) {
 				boolean checked = boxEl.isAtLeastSelected(1);
-				doCheck(ureq, wrapper, checked);
+				if(doCheck(ureq, wrapper, checked)) {
+					fireEvent(ureq, Event.CHANGED_EVENT);
+				}
 			}
 		} else if("ONCLICK".equals(event.getCommand())) {
 			String cmd = ureq.getParameter("fcid");
@@ -302,7 +305,7 @@ public class CheckListRunController extends FormBasicController implements Contr
 		super.formInnerEvent(ureq, source, event);
 	}
 	
-	private void doCheck(UserRequest ureq, CheckboxWrapper wrapper, boolean checked) {
+	private boolean doCheck(UserRequest ureq, CheckboxWrapper wrapper, boolean checked) {
 		DBCheckbox theOne;
 		if(wrapper.getDbCheckbox() == null) {
 			String uuid = wrapper.getCheckbox().getCheckboxId();
@@ -311,6 +314,7 @@ public class CheckListRunController extends FormBasicController implements Contr
 			theOne = wrapper.getDbCheckbox();
 		}
 		
+		boolean grantPoints = false;
 		if(theOne == null) {
 			//only warning because this happen in course preview
 			logWarn("A checkbox is missing: " + courseOres + " / " + courseNode.getIdent(), null);
@@ -321,17 +325,23 @@ public class CheckListRunController extends FormBasicController implements Contr
 			} else {
 				score = 0f;
 			}
-			checkboxManager.check(theOne, getIdentity(), score, new Boolean(checked));
+			if(wrapper.getCheckbox().getPoints() != null) {
+				grantPoints = true;
+			}
+			
+			checkboxManager.check(theOne, getIdentity(), score, Boolean.valueOf(checked));
 			//make sure all results is on the database before calculating some scores
-			//manager commit already DBFactory.getInstance().commit();
+			//manager commit already 
 			
 			courseNode.updateScoreEvaluation(getIdentity(), userCourseEnv, getIdentity(), Role.user);
 			
 			Checkbox checkbox = wrapper.getCheckbox();
 			logUpdateCheck(checkbox.getCheckboxId(), checkbox.getTitle());
+			
 		}
 		
 		exposeUserDataToVC(ureq, flc);
+		return grantPoints;
 	}
 	
 	private void logUpdateCheck(String checkboxId, String boxTitle) {
@@ -353,9 +363,9 @@ public class CheckListRunController extends FormBasicController implements Contr
 	private void saveOpenPanel(UserRequest ureq, String panelId, boolean newValue) {
 		Preferences guiPrefs = ureq.getUserSession().getGuiPreferences();
 		if (guiPrefs != null) {
-			guiPrefs.putAndSave(CheckListRunController.class, getOpenPanelId(panelId), new Boolean(newValue));
+			guiPrefs.putAndSave(CheckListRunController.class, getOpenPanelId(panelId), Boolean.valueOf(newValue));
 		}
-		flc.getFormItemComponent().contextPut("in-" + panelId, new Boolean(newValue));
+		flc.getFormItemComponent().contextPut("in-" + panelId, Boolean.valueOf(newValue));
 	}
 	
 	private String getOpenPanelId(String panelId) {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunForCoachController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunForCoachController.java
index 7c2fad6e7fe23e43ec3cc11fe719022143784ed2..da5aa23e4e46e6105a977928ad5b698b944ebfc3 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunForCoachController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunForCoachController.java
@@ -27,6 +27,7 @@ import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
 import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
 import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
 import org.olat.core.gui.components.velocity.VelocityContainer;
+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.gui.control.controller.BasicController;
@@ -96,6 +97,16 @@ public class CheckListRunForCoachController extends BasicController {
 		}
 	}
 
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(runController == source) {
+			if(event == Event.CHANGED_EVENT) {
+				fireEvent(ureq, event);
+			}
+		}
+		super.event(ureq, source, event);
+	}
+
 	private void doOpenRun(UserRequest ureq) {
 		if(runController == null) {
 			runController = new CheckListRunController(ureq, getWindowControl(), userCourseEnv, courseOres, courseNode);
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
index 7e1c9be78b55fb8cda5b0933b09cf73ce0c4c79d..4fd52b50f2474b39a55ee518bdb3c9a584557117 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
@@ -48,6 +48,8 @@ details=Details
 done.by=Erledigt von\:
 down=Runter
 edit.checkbox=Checkbox bearbeiten
+error.missing.score.config=Fehlende Bewertungskonfiguration\: "$\:config.points.min" or "$\:config.points.max"
+error.missing.cutvalue.config=Fehlende Bewertungskonfiguration\: "$\:config.cutvalue"
 file=Datei
 filter.all=Alle anzeigen
 form.individual.assessment.docs=$org.olat.course.nodes.ms\:form.individual.assessment.docs
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties
index 8a61a79d76e83e3976e52889e8437dd42f441fba..456b945f83c26b05d99dac8ab358832b9272a734 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties
@@ -48,6 +48,8 @@ details=Details
 done.by=Completed by\:
 down=Down
 edit.checkbox=Edit checkbox
+error.missing.score.config=Missing score configuration\: "$\:config.points.min" or "$\:config.points.max"
+error.missing.cutvalue.config=Missing score configuration\: "$\:config.cutvalue"
 file=File
 filter.all=Show all
 form.error.date=A date must be indicated.
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties
index ce13b9ffb40af650a7643cf3fcb43933eacd9dbe..3b4deb5463694f8f32e60a588e37b60ebce56882 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties
@@ -48,6 +48,8 @@ details=D\u00E9tails
 done.by=Compl\u00E9t\u00E9 par\:
 down=En bas
 edit.checkbox=Editer case \u00E0 cocher
+error.missing.score.config=Configuration d'\u00E9valuation incompl\u00E8te\: "$\:config.points.min" ou "$\:config.points.max"
+error.missing.cutvalue.config=Configuration d'\u00E9valuation incompl\u00E8te\: "$\:config.cutvalue"
 file=Fichier
 filter.all=Tout afficher
 form.error.date=La date est un champ obligatoire.
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_it.properties
index 210c111a50f9aa0bc140c4a281f1823fca4895c9..839e8b9af941ee3a82cf7de9661490a1c384051e 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_it.properties
@@ -44,6 +44,8 @@ details=Dettagli
 done.by=Completato da\:
 down=Gi\u00F9
 edit.checkbox=Modificare checkbox
+error.missing.score.config=Configurazione del punteggio mancante\: "$\:config.points.min" or "$\:config.points.max"
+error.missing.cutvalue.config=Configurazione del punteggio mancante\: "$\:config.cutvalue"
 file=File
 filter.all=Mostra tutto
 form.error.date=Indicare una data.
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_pt_BR.properties
index bad53c9536453c8d30cc1359af33160cf8622349..22c93af5becb49105c9fbe635ac23e021aa8d9e4 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_pt_BR.properties
@@ -48,6 +48,8 @@ details=Detalhes
 done.by=Completado por\:
 down=Baixar
 edit.checkbox=Editar checkbox
+error.missing.score.config=Configura\u00E7\u00E3o pontua\u00E7\u00E3o faltante\: "$\:config.points.min" or "$\:config.points.max"
+error.missing.cutvalue.config=Configura\u00E7\u00E3o pontua\u00E7\u00E3o faltante\: "$\:config.cutvalue"
 file=Arquivo
 filter.all=Mostrar tudo
 form.error.date=Uma data deve ser indicada.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_content/identity_courseelement.html b/src/main/java/org/olat/course/nodes/gta/ui/_content/identity_courseelement.html
index 780df08442b7e6f1929770de47f5c82a17a6400f..981c85aa4377513cce26d6d23602022e41ac1d6c 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_content/identity_courseelement.html
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_content/identity_courseelement.html
@@ -11,3 +11,11 @@
 	#end
 </div>
 $r.render("table")
+<div class="o_button_group">
+	#if($r.available("bulk.done"))
+		$r.render("bulk.done")
+	#end
+	#if($r.available("bulk.visible"))
+		$r.render("bulk.visible")
+	#end
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
index 076a5029320b00182806646f2a5eae48249f08c4..a2e0120dc9ef48abc55fc3840d550982480eed19 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties
@@ -315,6 +315,7 @@ uploaded.by=hochgeladen von {0}
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=Die Musterl\u00F6sung wird zum angegebenen Zeitpunkt freigegeben.
 warning.group.pick.task=Dies ist eine Gruppenaufgabe\! Die hier getroffene Auswahl ist f\u00FCr alle Mitglieder der Gruppe "{0}" g\u00FCltig\! Stellen Sie sicher, dass diese Auswahl zuvor innerhalb Ihrer Gruppe diskutiert wurde\! Nur ein Gruppenmitglied kann die Gruppenaufgabe ausw\u00E4hlen.
 warning.group.submit=Dies ist eine Gruppenaufgabe\! Das abgegebene Dokument ist f\u00FCr alle Mitglieder der Gruppe "{0}" g\u00FCltig\! Stellen Sie sicher dass diese L\u00F6sung zuvor innerhalb  Ihrer Gruppe diskutiert wurde\! Nur ein Gruppenmitglied kann eine L\u00F6sung im Namen aller Gruppenmitglieder abgeben.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
index 8ae8cc57914fc80d73a417e4894e4d90758987da..611c06fcbda6f6e9e2d2b90401b379fe91eb6828 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
@@ -315,6 +315,7 @@ uploaded.by=uploaded by {0}
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=The sample solution will be displayed at the date specified above.
 warning.group.pick.task=This is a group task\! The selection made here is valid for all members of the group "{0}"\! Make sure you discussed this selection within the group prior to selecting a task\! Only one member of the group can select the task for the group.
 warning.group.submit=This is a group task\! The submitted document is valid for all members of the group "{0}"\! Make sure you discussed this solution document prior to uploading it here\! Only one member of the group can submit a solution on behalf of all group members.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties
index 2de55d638f9c177ada7b5af5cc62b3c47af070dd..64bf1866692301809713b45225ea6004a5a8f16e 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties
@@ -97,7 +97,7 @@ error.file.invalid=$org.olat.core.commons.modules.bc\:cfile.name.notvalid
 error.max.documents=Vous ne pouvez pas d\u00E9poser plus de <b>{0}</b> documents, mais vous pouvez encore \u00E9diter ou \u00E9changer un fichier.
 error.missing.file=Le fichier d'un devoir est manquant.
 error.missing.group=Vous n'avez pas encore choisi un groupe.
-error.missing.score.config=Configuration de l'\u00E9valuation est manquante
+error.missing.score.config=Configuration d'\u00E9valuation incompl\u00E8te
 error.missing.solutions=Vous n'avez pas encore t\u00E9l\u00E9charg\u00E9 de solution.
 error.missing.tasks=Vous n'avez pas encore ajouter de devoir.
 error.no.group=Vous n'\u00EAtes inscrit dans aucun groupe.
@@ -315,6 +315,7 @@ uploaded.by=t\u00E9l\u00E9charg\u00E9 par {0}
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=Les solutions mod\u00E8les seront visible apr\u00E8s l'heure sp\u00E9cifi\u00E9e.
 warning.group.pick.task=Ceci est un devoir de groupe\! La s\u00E9lection effectu\u00E9e ici s'applique \u00E0 tous les participants du groupe "{0}"\! Assurez-vous que votre choix \u00E0 \u00E9t\u00E9 discut\u00E9 au sein de votre groupe\! Seul un participant du groupe pour choisir un devoir.
 warning.group.submit=Ceci est un devoir de groupe\! Les documents soumis le sont pour tous les participants du groupe "{0}"\! Assurez-vous que les solutions ont \u00E9t\u00E9 discut\u00E9es au sein du groupe\! Un seul membre du groupe peut soumettre la solution d\u00E9finitive.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_it.properties
index 6808ce556defcf4bec322496f5b4d1384fe2f401..cfe1bda316cb459f03a0e10b86d24125bdffe721 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_it.properties
@@ -264,6 +264,7 @@ uploaded.by=caricato da {0}
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=I modelli di soluzione saranno visibili alla data sopra indicata.
 warning.group.pick.task=Questo \u00E8 un compito di gruppo\! Le selezioni effettuate saranno valide per tutti i membri del gruppo "{0}"\! Assicurati di aver discusso questa scelta all'interno del gruppo prima di selezionare il compito\! Solo un membro del gruppo pu\u00F2 selezionare il compito per tutti.
 warning.group.submit=Questo \u00E8 un compito di gruppo\! Il documento consegnato sar\u00E0 valido per tutti i membri del gruppo "{0}"\! Assicurati di aver discusso questa soluzione all'interno del gruppo prima di consegnarla\! Solo un membro del gruppo pu\u00F2 consegnare la soluzione a nome di tutti i membri.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pl.properties
index 979cb9a62c36f4c291f7d81e10ff37ef48680595..5ee261dc0a5982dc2cb70f60abfa8a7a7f62b965 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pl.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pl.properties
@@ -258,6 +258,7 @@ uploaded.by=przes\u0142any przez {0}
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=The sample solution will be displayed at the date specified above.
 warning.group.pick.task=This is a group task\! The selection made here is valid for all members of the group "{0}"\! Make sure you discussed this selection within the group prior to selecting a task\! Only one member of the group can select the task for the group.
 warning.group.submit=This is a group task\! The submitted document is valid for all members of the group "{0}"\! Make sure you discussed this solution document prior to uploading it here\! Only one member of the group can submit a solution on behalf of all group members.
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pt_BR.properties
index 4e076c327f32d7f7d6a6da7dd1bc9e3c0918e54f..b077984244173d350c937493e8028bfa72fcae14 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_pt_BR.properties
@@ -315,6 +315,7 @@ uploaded.by=enviado por
 user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility
 user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden
 user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible
+user.visibility.visible.tooltip=$org.olat.course.assessment.ui.tool\:user.visibility.visible.tooltip
 wait.for.solutions=A solu\u00E7\u00E3o de amostra ser\u00E1 exibida na data especificada acima.
 warning.group.pick.task=Esta \u00E9 uma tarefa de grupo\! A sele\u00E7\u00E3o feita aqui \u00E9 v\u00E1lida para todos os membros do grupo "{0}"\! Certifique-se de que voc\u00EA discutiu essa sele\u00E7\u00E3o dentro do grupo antes de selecionar uma tarefa\! Apenas um membro do grupo pode selecionar a tarefa para o grupo.
 warning.group.submit=Esta \u00E9 uma tarefa de grupo\! O documento apresentado \u00E9 v\u00E1lido para todos os membros do grupo "{0}"\! Certifique-se de que voc\u00EA discutiu a solu\u00E7\u00E3o neste documento antes de envi\u00E1-lo aqui\! Apenas um membro do grupo pode apresentar uma solu\u00E7\u00E3o em nome de todos os membros do grupo.
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 b46cea2ceeb8a3e77d5ef347ef31e51dcfbbbd45..122deab3386824d5294b9cc943b7994e5b03191a 100644
--- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
@@ -668,7 +668,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 		File fUnzippedDirRoot = frm.unzipFileResource(testEntry.getOlatResource());
 		ResolvedAssessmentTest resolvedAssessmentTest = qtiService.loadAndResolveAssessmentTest(fUnzippedDirRoot, false, false);
 		AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful();
-		if(assessmentTest.getTimeLimits() != null && assessmentTest.getTimeLimits().getMaximum() != null) {
+		if(assessmentTest != null && assessmentTest.getTimeLimits() != null && assessmentTest.getTimeLimits().getMaximum() != null) {
 			return assessmentTest.getTimeLimits().getMaximum().longValue();
 		}
 		return null;
diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_pt_BR.properties
index 3077d994582820808ede74661f8ac325cd5884d0..56bf646b949c5784b79c7cabed1ae8e0125fce7c 100644
--- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 14:04:04 CET 2018
+#Wed Feb 28 13:30:52 CET 2018
 Intro.self=Clicar o bot\u00E3o "Iniciar" para executar o auto-teste.
 Intro.surv=Clicar o bot\u00E3o "Iniciar" para executar a pesquisa.
 Intro.test=Clicar o bot\u00E3o "Iniciar" para executar o teste.
@@ -187,6 +187,7 @@ time.limit.test.explain=O teste leva um m\u00E1ximo de <strong>{0}</strong>.
 tool.delete.data=Resetar todos dados
 tool.extra.time=Estender o tempo de teste
 tool.pull=Retirar teste em andamento
+validate.xml.signature=Validar recibo de teste
 warning.assessment.mode=Teste em processamento\:
 warning.assessment.mode.date={0} de {1} at\u00E9 {2}
 warning.test.with.essay=$org.olat.ims.qti.editor\:warning.test.with.essay
diff --git a/src/main/java/org/olat/course/nodes/members/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/members/_i18n/LocalStrings_pt_BR.properties
index 14d63348008fc34e4a8260f0cf328ff4656c03de..1492700ad1af1002c3114cd0d53111d2b8e35a16 100644
--- a/src/main/java/org/olat/course/nodes/members/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/nodes/members/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 14:04:06 CET 2018
+#Wed Feb 28 13:30:55 CET 2018
 add.member=Adicionar
 already.all.selected=Voc\u00EA j\u00E1 escolheu todos usu\u00E1rios
 coaches=Treinadores do Curso
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
index 2826474c3c99eb9ea75de382ec62dae5a69383b6..f0e5df3bb6504a38a9a068da5755085ecc9a88dc 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
@@ -678,20 +678,20 @@ public class BusinessGroupDAO {
 			dbq.setParameter("roles", roles);
 		}
 		if(StringHelper.containsNonWhitespace(params.getNameOrDesc())) {
-			dbq.setParameter("search", makeFuzzyQueryString(params.getNameOrDesc()));
+			dbq.setParameter("search", PersistenceHelper.makeFuzzyQueryString(params.getNameOrDesc()));
 		} else {
 			if(StringHelper.containsNonWhitespace(params.getExactName())) {
 				dbq.setParameter("exactName", params.getExactName());
 			}
 			if(StringHelper.containsNonWhitespace(params.getName())) {
-				dbq.setParameter("name", makeFuzzyQueryString(params.getName()));
+				dbq.setParameter("name", PersistenceHelper.makeFuzzyQueryString(params.getName()));
 			}
 			if(StringHelper.containsNonWhitespace(params.getDescription())) {
-				dbq.setParameter("description", makeFuzzyQueryString(params.getDescription()));
+				dbq.setParameter("description", PersistenceHelper.makeFuzzyQueryString(params.getDescription()));
 			}
 		}
 		if(StringHelper.containsNonWhitespace(params.getCourseTitle())) {
-			dbq.setParameter("displayName", makeFuzzyQueryString(params.getCourseTitle()));
+			dbq.setParameter("displayName", PersistenceHelper.makeFuzzyQueryString(params.getCourseTitle()));
 		}
 		return dbq;
 	}
@@ -967,7 +967,7 @@ public class BusinessGroupDAO {
 		
 		//owner
 		if(StringHelper.containsNonWhitespace(params.getOwnerName())) {
-			query.setParameter("owner", PersistenceHelper.makeEndFuzzyQueryString(params.getOwnerName()));
+			query.setParameter("owner", PersistenceHelper.makeFuzzyQueryString(params.getOwnerName()));
 		}
 		
 		//id
@@ -985,19 +985,19 @@ public class BusinessGroupDAO {
 		
 		//name
 		if(StringHelper.containsNonWhitespace(params.getNameOrDesc())) {
-			query.setParameter("search", PersistenceHelper.makeEndFuzzyQueryString(params.getNameOrDesc()));
+			query.setParameter("search", PersistenceHelper.makeFuzzyQueryString(params.getNameOrDesc()));
 		} else {
 			if(StringHelper.containsNonWhitespace(params.getName())) {
-				query.setParameter("name", PersistenceHelper.makeEndFuzzyQueryString(params.getName()));
+				query.setParameter("name", PersistenceHelper.makeFuzzyQueryString(params.getName()));
 			}
 			if(StringHelper.containsNonWhitespace(params.getDescription())) {
-				query.setParameter("description", PersistenceHelper.makeEndFuzzyQueryString(params.getDescription()));
+				query.setParameter("description", PersistenceHelper.makeFuzzyQueryString(params.getDescription()));
 			}
 		}
 		
 		//course title
 		if(StringHelper.containsNonWhitespace(params.getCourseTitle())) {
-			query.setParameter("displayName", PersistenceHelper.makeEndFuzzyQueryString(params.getCourseTitle()));
+			query.setParameter("displayName", PersistenceHelper.makeFuzzyQueryString(params.getCourseTitle()));
 		}
 		
 		//public group
@@ -1324,19 +1324,6 @@ public class BusinessGroupDAO {
 		return sb;
 	}
 	
-	private String makeFuzzyQueryString(String string) {
-		// By default only fuzzyfy at the end. Usually it makes no sense to do a
-		// fuzzy search with % at the beginning, but it makes the query very very
-		// slow since it can not use any index and must perform a fulltext search.
-		// User can always use * to make it a really fuzzy search query
-		string = string.replace('*', '%');
-		string = string + "%";
-		// with 'LIKE' the character '_' is a wildcard which matches exactly one character.
-		// To test for literal instances of '_', we have to escape it.
-		string = string.replace("_", "\\_");
-		return string.toLowerCase();
-	}
-	
 	private final boolean where(StringBuilder sb, boolean where) {
 		if(where) {
 			sb.append(" and ");
diff --git a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties
index 6f0a4b7d58e4a51e8cd0e3661b325f65457c7ac7..febef551b998c94750fe352a748df22546a9f817 100644
--- a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 13:32:09 CET 2018
+#Wed Feb 28 13:29:35 CET 2018
 businessgroup.contact.bodytext=<p></p>---<p>Ir imediatamente para o grupo "{0}"\: {1}</p>
 businessgroup.contact.subject=Mensagem para grupo {0}
 contact.all.coaches=Todos os treinadores (coaches) de grupo
diff --git a/src/main/java/org/olat/home/HomeCalendarController.java b/src/main/java/org/olat/home/HomeCalendarController.java
index a41fc592b3f4b0432adbe6384162e7a4e875948b..0b9b6410b74d1bd27cc2058106d99b2f38833608 100644
--- a/src/main/java/org/olat/home/HomeCalendarController.java
+++ b/src/main/java/org/olat/home/HomeCalendarController.java
@@ -38,6 +38,8 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
+import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
 import org.olat.core.util.UserSession;
@@ -58,12 +60,14 @@ public class HomeCalendarController extends BasicController implements Activatea
 		super(ureq, windowControl);
 		this.userSession = ureq.getUserSession();
 		
-		userSession.getSingleUserEventCenter().registerFor(this, ureq.getIdentity(), OresHelper.lookupType(CalendarManager.class));
-		CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, ureq.getIdentity(), OresHelper.lookupType(CalendarManager.class));
+		Identity identity = ureq.getIdentity();
+		userSession.getSingleUserEventCenter().registerFor(this, identity, OresHelper.lookupType(CalendarManager.class));
+		CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, identity, OresHelper.lookupType(CalendarManager.class));
 		
+		OLATResourceable callerOres = OresHelper.createOLATResourceableInstanceWithoutCheck(identity.getName(), identity.getKey());
 		List<KalendarRenderWrapper> calendars = homeCalendarManager.getListOfCalendarWrappers(ureq, windowControl);
 		calendarController = new WeeklyCalendarController(ureq, windowControl, calendars,
-				WeeklyCalendarController.CALLER_HOME, null, true);
+				WeeklyCalendarController.CALLER_HOME, callerOres, true);
 		listenTo(calendarController);
 
 		putInitialPanel(calendarController.getInitialComponent());
diff --git a/src/main/java/org/olat/ims/qti/resultexport/QTI12ResultsExportMediaResource.java b/src/main/java/org/olat/ims/qti/resultexport/QTI12ResultsExportMediaResource.java
index d75b0a73498236b155539ebd52cc408516166dbe..84d6790050468b5ce32073946762d9262dbd9b4f 100644
--- a/src/main/java/org/olat/ims/qti/resultexport/QTI12ResultsExportMediaResource.java
+++ b/src/main/java/org/olat/ims/qti/resultexport/QTI12ResultsExportMediaResource.java
@@ -240,8 +240,10 @@ public class QTI12ResultsExportMediaResource implements MediaResource {
 		convertToZipEntry(zout, exportFolderName + "/index.html", usersHTML);
 		
 		//Copy resource files or file trees to export file tree 
-		File sasstheme = new File(WebappHelper.getContextRealPath("/static/offline/qti"));
-		fsToZip(zout, sasstheme.toPath(), exportFolderName + "/css/offline/qti/");
+		File theme = new File(WebappHelper.getContextRealPath("/static/themes/light/theme.css"));
+		ZipUtil.addFileToZip(exportFolderName + "/css/offline/qti/theme.css", theme, zout);
+		File themeMap = new File(WebappHelper.getContextRealPath("/static/themes/light/theme.css.map"));
+		ZipUtil.addFileToZip(exportFolderName + "/css/offline/qti/theme.css.map", themeMap, zout);
 		
 		File fontawesome = new File(WebappHelper.getContextRealPath("/static/font-awesome"));
 		fsToZip(zout, fontawesome.toPath(), exportFolderName + "/css/font-awesome/");
diff --git a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
index ea3f5c7ce2a604064c40db2b1376ebf8d1f0ce26..b440cbe9603241cc322f7412a7fea45147e39c9a 100644
--- a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
+++ b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
@@ -22,6 +22,7 @@ package org.olat.ims.qti21.manager.archive;
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -117,6 +118,10 @@ import uk.ac.ed.ph.jqtiplus.node.item.interaction.SliderInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.TextEntryInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.UploadInteraction;
 import uk.ac.ed.ph.jqtiplus.node.test.AssessmentItemRef;
+import uk.ac.ed.ph.jqtiplus.node.test.AssessmentSection;
+import uk.ac.ed.ph.jqtiplus.node.test.AssessmentTest;
+import uk.ac.ed.ph.jqtiplus.node.test.SectionPart;
+import uk.ac.ed.ph.jqtiplus.node.test.TestPart;
 import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentItem;
 import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentTest;
 import uk.ac.ed.ph.jqtiplus.types.Identifier;
@@ -140,8 +145,9 @@ public class QTI21ArchiveFormat {
 	private final QTI21StatisticSearchParams searchParams;
 	private ExportFormat exportConfig;
 	
+	private int numOfSections;
 	private CourseNode courseNode;
-	private List<ItemInfos> itemInfos;
+	private List<AbstractInfos> elementInfos;
 	private final Map<String, InteractionArchive> interactionArchiveMap = new HashMap<>();
 	
 	private final QTI21Service qtiService;
@@ -332,30 +338,39 @@ public class QTI21ArchiveFormat {
 		header1Row.addCell(col++, translator.translate("archive.table.header.test"), headerStyle);
 		col += 5;
 		
-		List<ItemInfos> infos = getItemInfos();
+		List<AbstractInfos> infos = getItemInfos();
 		for(int i=0; i<infos.size(); i++) {
 			int delta = col;
-			ItemInfos item = infos.get(i);
-			if (exportConfig.isResponseCols() || exportConfig.isPointCol() || exportConfig.isTimeCols() || exportConfig.isCommentCol()) {
-				List<Interaction> interactions = item.getInteractions();
-				for(int j=0; j<interactions.size(); j++) {
-					Interaction interaction = interactions.get(j);
-					col = interactionArchiveMap.get(interaction.getQtiClassName())
-							.writeHeader1(item.getAssessmentItem(), interaction, i, j, header1Row, col, workbook);
+			AbstractInfos info = infos.get(i);
+			if(info instanceof ItemInfos) {
+				ItemInfos item = (ItemInfos)info;
+				if (exportConfig.isResponseCols() || exportConfig.isPointCol() || exportConfig.isTimeCols() || exportConfig.isCommentCol()) {
+					List<Interaction> interactions = item.getInteractions();
+					for(int j=0; j<interactions.size(); j++) {
+						Interaction interaction = interactions.get(j);
+						col = interactionArchiveMap.get(interaction.getQtiClassName())
+								.writeHeader1(item.getAssessmentItem(), interaction, i, j, header1Row, col, workbook);
+					}
+				}
+				if (!exportConfig.isResponseCols()) {
+					col -= col - delta;
+				}
+				if (exportConfig.isPointCol()) {
+					col++;
+				}
+				if (exportConfig.isCommentCol()) {
+					col++;
+				}
+				if (exportConfig.isTimeCols()) {
+					col += anonymizerCallback != null ? 1 : 2;
+				}
+			} else if(numOfSections > 1 && info instanceof SectionInfos) {
+				SectionInfos section = (SectionInfos)info;
+				if(!section.getItemInfos().isEmpty()) {
+					String sectionTitle = translator.translate("archive.table.header.section", new String[] { section.getAssessmentSection().getTitle() });
+					header1Row.addCell(col++, sectionTitle, headerStyle);
 				}
 			}
-			if (!exportConfig.isResponseCols()) {
-				col -= col - delta;
-			}
-			if (exportConfig.isPointCol()) {
-				col++;
-			}
-			if (exportConfig.isCommentCol()) {
-				col++;
-			}
-			if (exportConfig.isTimeCols()) {
-				col += anonymizerCallback != null ? 1 : 2;
-			}		
 		}
 	}
 
@@ -402,28 +417,36 @@ public class QTI21ArchiveFormat {
 		}
 		header2Row.addCell(col++, translator.translate("column.header.duration"), headerStyle);
 
-		List<ItemInfos> infos = getItemInfos();
+		List<AbstractInfos> infos = getItemInfos();
 		for(int i=0; i<infos.size(); i++) {
-			ItemInfos info = infos.get(i);
-			if (exportConfig.isResponseCols()) {
-				List<Interaction> interactions = info.getInteractions();
-				for(int j=0; j<interactions.size(); j++) {
-					Interaction interaction = interactions.get(j);
-					col = interactionArchiveMap.get(interaction.getQtiClassName())
-							.writeHeader2(info.getAssessmentItem(), interaction, i, j, header2Row, col, workbook);
+			AbstractInfos info = infos.get(i);
+			if(info instanceof ItemInfos) {
+				ItemInfos item = (ItemInfos)info;
+				if (exportConfig.isResponseCols()) {
+					List<Interaction> interactions = item.getInteractions();
+					for(int j=0; j<interactions.size(); j++) {
+						Interaction interaction = interactions.get(j);
+						col = interactionArchiveMap.get(interaction.getQtiClassName())
+								.writeHeader2(item.getAssessmentItem(), interaction, i, j, header2Row, col, workbook);
+					}
 				}
-			}
-			if (exportConfig.isPointCol()) {
-				header2Row.addCell(col++, translator.translate("item.score"), headerStyle);
-			}
-			if (exportConfig.isCommentCol()) {
-				header2Row.addCell(col++, translator.translate("item.comment"), headerStyle);
-			}
-			if (exportConfig.isTimeCols()) {
-				if (anonymizerCallback == null){
-					header2Row.addCell(col++, translator.translate("item.start"), headerStyle);
+				if (exportConfig.isPointCol()) {
+					header2Row.addCell(col++, translator.translate("item.score"), headerStyle);
+				}
+				if (exportConfig.isCommentCol()) {
+					header2Row.addCell(col++, translator.translate("item.comment"), headerStyle);
+				}
+				if (exportConfig.isTimeCols()) {
+					if (anonymizerCallback == null){
+						header2Row.addCell(col++, translator.translate("item.start"), headerStyle);
+					}
+					header2Row.addCell(col++, translator.translate("item.duration"), headerStyle);
+				}
+			} else if(numOfSections > 1 && info instanceof SectionInfos) {
+				SectionInfos section = (SectionInfos)info;
+				if(!section.getItemInfos().isEmpty()) {
+					header2Row.addCell(col++, translator.translate("archive.table.header.points"), headerStyle);
 				}
-				header2Row.addCell(col++, translator.translate("item.duration"), headerStyle);
 			}
 		}
 	}
@@ -552,74 +575,126 @@ public class QTI21ArchiveFormat {
 		}
 		dataRow.addCell(col++, toDurationInMilliseconds(testSession.getDuration()), null);
 
-		List<ItemInfos> infos = getItemInfos();
+		List<AbstractInfos> infos = getItemInfos();
 		for(int i=0; i<infos.size(); i++) {
-			ItemInfos info = infos.get(i);
-			AssessmentItemRef itemRef = info.getAssessmentItemRef();
-			String itemRefIdentifier = itemRef.getIdentifier().toString();
-			AssessmentItemSession itemSession = responses.getItemSession(itemRefIdentifier);
-			
-			if (exportConfig.isResponseCols()) {
-				List<Interaction> interactions = info.getInteractions();
-				for(int j=0; j<interactions.size(); j++) {
-					Interaction interaction = interactions.get(j);
-					AssessmentResponse response = responses
-							 .getResponse(itemRefIdentifier, interaction.getResponseIdentifier());
-					col = interactionArchiveMap.get(interaction.getQtiClassName())
-								.writeInteractionData(info.getAssessmentItem(), response, interaction, j, dataRow, col, workbook);
+			AbstractInfos info = infos.get(i);
+			if(info instanceof ItemInfos) {
+				ItemInfos item = (ItemInfos)info;
+				AssessmentItemRef itemRef = item.getAssessmentItemRef();
+				String itemRefIdentifier = itemRef.getIdentifier().toString();
+				AssessmentItemSession itemSession = responses.getItemSession(itemRefIdentifier);
+				
+				if (exportConfig.isResponseCols()) {
+					List<Interaction> interactions = item.getInteractions();
+					for(int j=0; j<interactions.size(); j++) {
+						Interaction interaction = interactions.get(j);
+						AssessmentResponse response = responses
+								 .getResponse(itemRefIdentifier, interaction.getResponseIdentifier());
+						col = interactionArchiveMap.get(interaction.getQtiClassName())
+									.writeInteractionData(item.getAssessmentItem(), response, interaction, j, dataRow, col, workbook);
+					}
 				}
-			}
 			
-			//score, start, duration
-			if (itemSession == null) {
-				if (exportConfig.isPointCol()) {
-					col++;
-				}
-				if (exportConfig.isCommentCol()) {
-					col++;
-				}
-				if (exportConfig.isTimeCols()) {
-					col += anonymizerCallback != null ? 1 : 2;
-				}
-			} else {
-				if (exportConfig.isPointCol()) {
-					if(itemSession.getManualScore() != null) {
-						dataRow.addCell(col++, itemSession.getManualScore(), null);
-					} else {
-						dataRow.addCell(col++, itemSession.getScore(), null);
+				//score, start, duration
+				if (itemSession == null) {
+					if (exportConfig.isPointCol()) {
+						col++;
+					}
+					if (exportConfig.isCommentCol()) {
+						col++;
+					}
+					if (exportConfig.isTimeCols()) {
+						col += anonymizerCallback != null ? 1 : 2;
+					}
+				} else {
+					if (exportConfig.isPointCol()) {
+						if(itemSession.getManualScore() != null) {
+							dataRow.addCell(col++, itemSession.getManualScore(), null);
+						} else {
+							dataRow.addCell(col++, itemSession.getScore(), null);
+						}
+					}
+					if (exportConfig.isCommentCol()) {
+						dataRow.addCell(col++, itemSession.getCoachComment(), null);	
+					}
+					if (exportConfig.isTimeCols()) {
+						if (anonymizerCallback == null){
+							dataRow.addCell(col++, itemSession.getCreationDate(), workbook.getStyles().getTimeStyle());
+						}
+						dataRow.addCell(col++, toDurationInMilliseconds(itemSession.getDuration()), null);
 					}
 				}
-				if (exportConfig.isCommentCol()) {
-					dataRow.addCell(col++, itemSession.getCoachComment(), null);	
-				}
-				if (exportConfig.isTimeCols()) {
-					if (anonymizerCallback == null){
-						dataRow.addCell(col++, itemSession.getCreationDate(), workbook.getStyles().getTimeStyle());
+			} else if(numOfSections > 1 && info instanceof SectionInfos) {
+				SectionInfos section = (SectionInfos)info;
+				if(!section.getItemInfos().isEmpty()) {
+					BigDecimal score = calculateSectionScore(responses, section);
+					if(score != null) {
+						dataRow.addCell(col++, score, workbook.getStyles().getLightGrayStyle());
+					} else {
+						col++;
 					}
-					dataRow.addCell(col++, toDurationInMilliseconds(itemSession.getDuration()), null);
 				}
 			}
 		}
 	}
 	
+	private BigDecimal calculateSectionScore(SessionResponses responses, SectionInfos section) {
+		BigDecimal sectionScore = BigDecimal.valueOf(0l);
+		
+		for(ItemInfos item:section.getItemInfos()) {
+			AssessmentItemRef itemRef = item.getAssessmentItemRef();
+			String itemRefIdentifier = itemRef.getIdentifier().toString();
+			AssessmentItemSession itemSession = responses.getItemSession(itemRefIdentifier);
+			if(itemSession.getManualScore() != null) {
+				sectionScore = sectionScore.add(itemSession.getManualScore());
+			} else if(itemSession.getScore() != null){
+				sectionScore = sectionScore.add(itemSession.getScore());
+			}
+		}
+		
+		return sectionScore;
+	}
+	
 	private Long toDurationInMilliseconds(Long value) {
 		if(value == null || value.longValue() == 0) return null;
 		return value.longValue() / 1000l;
 	}
 	
-	private List<ItemInfos> getItemInfos() {
-		if(itemInfos == null) {
-			itemInfos = new ArrayList<>();
-			List<AssessmentItemRef> itemRefs = resolvedAssessmentTest.getAssessmentItemRefs();
-			for(AssessmentItemRef itemRef:itemRefs) {
+	private List<AbstractInfos> getItemInfos() {
+		if(elementInfos == null) {
+			numOfSections = 0;
+			elementInfos = new ArrayList<>();
+			
+			AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractAssumingSuccessful();
+			for(TestPart part:assessmentTest.getTestParts()) {
+				for(AssessmentSection section:part.getAssessmentSections()) {
+					collectElementInfos(section);
+				}
+			}
+		}
+		return elementInfos;
+	}
+	
+	private void collectElementInfos(AssessmentSection section) {
+		numOfSections++;
+		SectionInfos sectionInfos = new SectionInfos(section);
+		elementInfos.add(sectionInfos);
+
+		List<SectionPart> parts = section.getChildAbstractParts();
+		for(SectionPart part:parts) {
+			if(part instanceof AssessmentItemRef) {
+				AssessmentItemRef itemRef = (AssessmentItemRef)part;
 				ResolvedAssessmentItem resolvedItem = resolvedAssessmentTest.getResolvedAssessmentItem(itemRef);
 				AssessmentItem item = resolvedItem.getRootNodeLookup().extractIfSuccessful();
 				if(item != null) {
-					itemInfos.add(new ItemInfos(itemRef, item, item.getItemBody().findInteractions()));
+					ItemInfos itemInfo = new ItemInfos(itemRef, item, item.getItemBody().findInteractions());
+					elementInfos.add(itemInfo);
+					sectionInfos.getItemInfos().add(itemInfo);
 				}
+			} else if(part instanceof AssessmentSection) {
+				collectElementInfos((AssessmentSection)part);
 			}
 		}
-		return itemInfos;
 	}
 	
 	private static class SessionResponses {
@@ -667,7 +742,28 @@ public class QTI21ArchiveFormat {
 		}
 	}
 	
-	private static class ItemInfos {
+	private static class AbstractInfos {
+		//
+	}
+	
+	private static class SectionInfos extends AbstractInfos {
+		private final AssessmentSection section;
+		private final List<ItemInfos> itemInfos = new ArrayList<>();
+		
+		public SectionInfos(AssessmentSection section) {
+			this.section = section;
+		}
+		
+		public AssessmentSection getAssessmentSection() {
+			return section;
+		}
+		
+		public List<ItemInfos> getItemInfos() {
+			return itemInfos;
+		}
+	}
+	
+	private static class ItemInfos extends AbstractInfos {
 		
 		private final AssessmentItemRef itemRef;
 		private final AssessmentItem assessmentItem;
diff --git a/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java b/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java
index 5278a31c438d052cacbe7df7ea426adca9cc205f..f357772544a1304340a7bd4249adf3c733975e45 100644
--- a/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java
+++ b/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java
@@ -39,7 +39,6 @@ import java.util.zip.ZipOutputStream;
 
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.io.IOUtils;
 import org.cyberneko.html.parsers.SAXParser;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.translator.Translator;
@@ -183,19 +182,16 @@ public class QTI21WordExport implements MediaResource {
 		} catch (Exception e) {
 			log.error("", e);
 		}
+		
+		AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful();
+		String label = assessmentTest.getTitle();
+		String secureLabel = StringHelper.transformDisplayNameToFileSystemName(label);
 
-		ZipOutputStream zout = null;
-		try {
-			AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful();
-			
-			String label = assessmentTest.getTitle();
-			String secureLabel = StringHelper.transformDisplayNameToFileSystemName(label);
+		String file = secureLabel + ".zip";
+		hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + StringHelper.urlEncodeUTF8(file));			
+		hres.setHeader("Content-Description", StringHelper.urlEncodeUTF8(label));
 
-			String file = secureLabel + ".zip";
-			hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + StringHelper.urlEncodeUTF8(file));			
-			hres.setHeader("Content-Description", StringHelper.urlEncodeUTF8(label));
-			
-			zout = new ZipOutputStream(hres.getOutputStream());
+		try(ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) {
 			zout.setLevel(9);
 
 			ZipEntry test = new ZipEntry(secureLabel + ".docx");
@@ -212,7 +208,6 @@ public class QTI21WordExport implements MediaResource {
 			log.error("", e);
 		} finally {
 			latch.countDown();
-			IOUtils.closeQuietly(zout);
 		}
 	}
 	
@@ -502,7 +497,10 @@ public class QTI21WordExport implements MediaResource {
 					endSimpleChoice();
 					break;
 				case "textentryinteraction":
-					//auto closing tag
+					flushText();
+					Style[] currentStyles = popStyle(tag);
+					unsetTextPreferences(currentStyles);
+					break;
 				case "extendedtextinteraction":
 					//auto closing tag
 				case "hotspotinteraction":
diff --git a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
index 39e0d5c5e22f21a084d09b608b165d1014babb02..69ec2cfba119440c5906f3bf9f4dd6cb010990ed 100644
--- a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
+++ b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
@@ -167,14 +167,12 @@ public class QTI21ResultsExportMediaResource implements MediaResource {
 		hres.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + urlEncodedLabel);
 		hres.setHeader("Content-Description", urlEncodedLabel);
 
-		try { 			
-			ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream());
+		try(ZipOutputStream zout = new ZipOutputStream(hres.getOutputStream())) {
 			zout.setLevel(9);
 			exportTestResults(zout);
 			for(RepositoryEntry testEntry:testEntries) {
 				exportExcelResults(testEntry, zout);
 			}
-			zout.close();
 		} catch (Exception e) {
 			log.error("Unknown error while assessment result resource export", e);
 		}
diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
index 4b324c4c682bfd88a8175fbc3ebcbf45eba74154..87c2db77b85dce6a0eb783561aeae9dad405d9cb 100644
--- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
@@ -1869,7 +1869,7 @@ public class AssessmentTestDisplayController extends BasicController implements
 				String[] jss = new String[] {
 						"js/jquery/ui/jquery-ui-1.11.4.custom.resize.min.js",
 						"js/jquery/qti/jquery.qtiTimer.js",
-						"js/jquery/qti/jquery.qtiAutosave.js",
+						"js/jquery/qti/jquery.qtiAutosave.js"
 				};
 				JSAndCSSComponent js = new JSAndCSSComponent("js", jss, null);
 				layoutCont.put("js", js);
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties
index b1b10aeced85c079dc5a547cd56566127a315f0f..037467d2bc4031c2bb03919823930b4114ac98d7 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties
@@ -16,8 +16,10 @@ archive.table.header.node=Kurs
 archive.table.header.node.passed=Kursbaustein bestanden
 archive.table.header.node.points=Kursbaustein Punkte
 archive.table.header.points=$\:table.header.score
+archive.table.header.section=Sektion "{0}"
 archive.table.header.test=Test
 assessment.comment.legend=Pers\u00F6nliche Notizen
+assessment.comment.legend.help=Sie k\u00F6nnen ein Kommentar hier schreiebn. Diese Notizen sind privat und werden nicht in einem Pr\u00FCfung ber\u00FCcksichtigt.
 assessment.item.mark=F\u00FCgen Sie eine private Markierung hinzu als Erinnerung um diese Frage sp\u00E4ter noch einmal anzuschauen 
 assessment.item.status.answered=Beantwortet
 assessment.item.status.finished=Erledigt
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_en.properties
index 37c984c95b360296fa722384bbf972bd39790cfc..53747311d37e3ff5270c69914e1ff1700e3610a4 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_en.properties
@@ -16,8 +16,10 @@ archive.table.header.node=Course
 archive.table.header.node.passed=Passed course element
 archive.table.header.node.points=Score course element
 archive.table.header.points=$\:table.header.score
+archive.table.header.section=Section "{0}"
 archive.table.header.test=Test
-assessment.comment.legend=Please use the following text box if you need to provide any additional information, comments or feedback during this test\:
+assessment.comment.legend=Personal notes
+assessment.comment.legend.help=Please use the following text box if you need to provide any additional information, comments or feedback during this test. This notice is private and will be taken in account for an exam.
 assessment.item.mark=Add personal marking as a reminder to review this question
 assessment.item.status.answered=Answered
 assessment.item.status.finished=Completed
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties
index 667b869142061934241807f861b99832be7e8023..7168ff94852bf2aca9900816d2e2be1df40279b0 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties
@@ -16,8 +16,10 @@ archive.table.header.node=Cours
 archive.table.header.node.passed=Element de cours r\u00E9ussi
 archive.table.header.node.points=Points \u00E9l\u00E9ment de cours
 archive.table.header.points=$\:table.header.score
+archive.table.header.section=Sektion "{0}"
 archive.table.header.test=Test
 assessment.comment.legend=Notes personelles
+assessment.comment.legend.help=Vous pouvez ajoutez un commentaire dans le champ de texte ci-dessous. Cette note est priv\u00E9e et il n'en sera pas tenu compte dans un test.
 assessment.item.mark=Ajouter un signet pour revoir cette question plus tard
 assessment.item.status.answered=R\u00E9pondu
 assessment.item.status.finished=Termin\u00E9
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_it.properties
index 89d3fdd96e0476a7ecfb7b08c80032893d8f1611..0852668b3d12b2b4a5134aa615ddd5f14652f84e 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_it.properties
@@ -6,7 +6,6 @@ admin.title=Impostazioni QTI 2.1
 anonym.not.allowed.descr=Gli utenti anonimi non possono eseguire questo test.
 anonym.not.allowed.title=Utenti anonimi
 anonym.user=Utente anonimo
-assessment.comment.legend=Nella casella di testo seguente pu\u00F2 fornire informazioni aggiuntive, commenti o feedback durante questo test\:
 assessment.item.mark=Inserire un marcatore personale come promemoria per revisionare questa domanda
 assessment.item.status.answered=Risposto
 assessment.item.status.finished=Completato
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_pt_BR.properties
index 9c612202807f21007cb3d0f28343a112acbaeeb2..aad95f61db64de358b8fcdce33553db7518092eb 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_pt_BR.properties
@@ -17,7 +17,6 @@ archive.table.header.node.passed=Elemento de curso aprovado
 archive.table.header.node.points=Pontua\u00E7\u00E3o do elemento do curso
 archive.table.header.points=$\:table.header.score
 archive.table.header.test=Teste
-assessment.comment.legend=Use a caixa de texto a seguir se voc\u00EA precisar fornecer qualquer informa\u00E7\u00E3o adicional, coment\u00E1rios ou feedback durante este teste\:
 assessment.item.mark=Adicionar marca\u00E7\u00E3o pessoal como lembrete para rever esta pergunta
 assessment.item.status.answered=Respondido
 assessment.item.status.finished=Conclu\u00EDdo
diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_zh_CN.properties
index 3d213f0378a72d9528a937d77dad5ee636d1d19b..8410840f6627e384843e340111cf3493442c51e4 100644
--- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_zh_CN.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_zh_CN.properties
@@ -6,7 +6,6 @@ admin.title=QTI 2.1 \u8BBE\u7F6E
 anonym.not.allowed.descr=\u4E0D\u5141\u8BB8\u533F\u540D\u7528\u6237\u8FDB\u884C\u672C\u6D4B\u8BD5
 anonym.not.allowed.title=\u533F\u540D\u7528\u6237
 anonym.user=\u533F\u540D\u7528\u6237
-assessment.comment.legend=\u5982\u679C\u5728\u6D4B\u8BD5\u671F\u95F4\u9700\u8981\u63D0\u4F9B\u5176\u4ED6\u4FE1\u606F\u3001\u8BC4\u8BBA\u6216\u53CD\u9988\uFF0C\u8BF7\u60A8\u4F7F\u7528\u4E0B\u9762\u7684\u6587\u672C\u6846
 assessment.item.mark=\u6DFB\u52A0\u4E2A\u4EBA\u6807\u8BB0\u4F5C\u4E3A\u63D0\u9192\u6765\u56DE\u987E\u8FD9\u4E2A\u95EE\u9898
 assessment.item.status.answered=\u5DF2\u7B54
 assessment.item.status.finished=\u5B8C\u6210
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponent.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponent.java
index f4acb20981827f32b560861687c2541ca38e4a54..a3afd1970dcc1cc89eae2a24cffb69e9c8bb13c6 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponent.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponent.java
@@ -208,10 +208,13 @@ public abstract class AssessmentObjectComponent extends AbstractComponent implem
 		jsa.addRequiredStaticJsFile("js/jquery/maphilight/jquery.maphilight.js");
 		// drawing
 		jsa.addRequiredStaticJsFile("js/jquery/openolat/jquery.paint.js");
+		//tab
+		jsa.addRequiredStaticJsFile("js/jquery/taboverride/taboverride-4.0.0.min.js");
 		
 		if(Settings.isDebuging()) {
 			// order needs dragula
 			jsa.addRequiredStaticJsFile("js/dragula/dragula.js");
+			jsa.addRequiredStaticJsFile("js/jquery/taboverride/jquery.taboverride.js");
 			// qtiAutosave and qtiTimer are loaded by the controller
 			jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.associate.js");
 			jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.choice.js");
@@ -229,6 +232,7 @@ public abstract class AssessmentObjectComponent extends AbstractComponent implem
 			jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.slider.js");
 		} else {
 			jsa.addRequiredStaticJsFile("js/dragula/dragula.min.js");
+			jsa.addRequiredStaticJsFile("js/jquery/taboverride/jquery.taboverride.min.js");
 			jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.qti.min.js");
 		}
 	}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
index 15a9b960758dbbabc8b410563e5d2fa3280fe49b..6b6db0123b85b880e93c4d51ba0bc4a1cc5faaf6 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
@@ -61,7 +61,6 @@ import java.util.List;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.context.Context;
@@ -893,6 +892,7 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 	private void renderComment(StringOutput sb, String comment, boolean disabled, Translator translator) {
 		sb.append("<fieldset class='o_candidatecomment'>")
 		  .append("<legend>").append(translator.translate("assessment.comment.legend")).append("</legend>")
+		  .append("<div class='o_item_container_help'><p><i class='o_icon o_icon_help'> </i> ").append(translator.translate("assessment.comment.legend.help")).append("</p></div>")
 		  .append("<input name='qtiworks_comment_presented' type='hidden' value='true' />")
 		  .append("<textarea name='qtiworks_comment'").append(" disabled=\"disabled\"", disabled).append(" rows='4' class='form-control'>");
 		if(StringHelper.containsNonWhitespace(comment)) {
@@ -1008,13 +1008,15 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 
 		Renderer fr = Renderer.getInstance(component, translator, ubu, new RenderResult(), renderer.getGlobalSettings());
 		AssessmentRenderer fHints = renderer.newHints(fr);
-		AssessmentObjectVelocityRenderDecorator vrdec
-			= new AssessmentObjectVelocityRenderDecorator(fHints, sb, component, resolvedAssessmentItem, itemSessionState, ubu, translator);			
-		ctx.put("r", vrdec);
-		VelocityHelper vh = VelocityHelper.getInstance();
-		vh.mergeContent(page, ctx, sb, null);
-		ctx.remove("r");
-		IOUtils.closeQuietly(vrdec);
+		try(AssessmentObjectVelocityRenderDecorator vrdec
+			= new AssessmentObjectVelocityRenderDecorator(fHints, sb, component, resolvedAssessmentItem, itemSessionState, ubu, translator)) {
+			ctx.put("r", vrdec);
+			VelocityHelper vh = VelocityHelper.getInstance();
+			vh.mergeContent(page, ctx, sb, null);
+			ctx.remove("r");
+		} catch(IOException e) {
+			log.error("", e);
+		}
 	}
 	
 	private String getInteractionTemplate(QtiNode interaction) {
@@ -1290,7 +1292,7 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 			  .append("  dispIdField:'").append(form.getDispatchFieldId()).append("',\n")
 			  .append("  dispId:'").append(component.getQtiItem().getFormDispatchId()).append("',\n")
 			  .append("  eventIdField:'").append(form.getEventFieldId()).append("'\n")
-			  .append(" });\n")
+			  .append(" }).tabOverride();\n")
 			  .append("})\n")
 			  .append(FormJSHelper.getJSEnd());
 		}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/_content/graphicGapMatchInteraction.html b/src/main/java/org/olat/ims/qti21/ui/components/_content/graphicGapMatchInteraction.html
index 1379ee19e0f1949deae0e91fa54365ca390d39c3..460754a9dda1d2edb7ec138b687614249ef4032c 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/_content/graphicGapMatchInteraction.html
+++ b/src/main/java/org/olat/ims/qti21/ui/components/_content/graphicGapMatchInteraction.html
@@ -23,7 +23,7 @@
 			$r.appendFlexiFormDirtyForClick("ac_${responseIdentifier}_$hotspot.identifier")
 		#end
 		</map>
-		<div class="o_gap_container_help">
+		<div class="o_item_container_help">
 			<p><i class="o_icon o_icon_help"> </i> $r.translate("graphic.gap.explanation")</p>
 		</div>
 		<div class="gap_container clearfix">
diff --git a/src/main/java/org/olat/modules/lecture/LectureService.java b/src/main/java/org/olat/modules/lecture/LectureService.java
index cdf7d17df82f98eb09ff8543b942d31145bc3931..14aeb0457bab194c7bb24d04b5205a50b711f597 100644
--- a/src/main/java/org/olat/modules/lecture/LectureService.java
+++ b/src/main/java/org/olat/modules/lecture/LectureService.java
@@ -503,9 +503,10 @@ public interface LectureService {
 	 * 
 	 * @param entry
 	 * @param participant
+	 * @param teacherSeparator The separator between the name of 2 teachers
 	 * @return
 	 */
-	public List<LectureBlockAndRollCall> getParticipantLectureBlocks(RepositoryEntryRef entry, IdentityRef participant);
+	public List<LectureBlockAndRollCall> getParticipantLectureBlocks(RepositoryEntryRef entry, IdentityRef participant, String teacherSeparator);
 
 	
 	/**
diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java
index 4680e95f3fa54dd260e2f74b0b04ec9dd85dbeba..e613473802453d47fb233392d56cc424b7e88bfe 100644
--- a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java
+++ b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java
@@ -322,7 +322,8 @@ public class LectureBlockRollCallDAO {
 		return query.getResultList();
 	}
 	
-	public List<LectureBlockAndRollCall> getParticipantLectureBlockAndRollCalls(RepositoryEntryRef entry, IdentityRef identity) {
+	public List<LectureBlockAndRollCall> getParticipantLectureBlockAndRollCalls(RepositoryEntryRef entry, IdentityRef identity,
+			String teacherSeaparator) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select block, call, re.displayname")
 		  .append(" from lectureblock block")
@@ -349,11 +350,11 @@ public class LectureBlockRollCallDAO {
 			blockToRollCallMap.put(block.getKey(), new LectureBlockAndRollCall(displayname, block, rollCall));
 		}
 		
-		appendCoaches(entry, blockToRollCallMap);
+		appendCoaches(entry, blockToRollCallMap, teacherSeaparator);
 		return new ArrayList<>(blockToRollCallMap.values());
 	}
 	
-	private void appendCoaches(RepositoryEntryRef entry, Map<Long,LectureBlockAndRollCall> blockToRollCallMap) {
+	private void appendCoaches(RepositoryEntryRef entry, Map<Long,LectureBlockAndRollCall> blockToRollCallMap, String teacherSeaparator) {
 		// append the coaches
 		StringBuilder sc = new StringBuilder();
 		sc.append("select block.key, coach")
@@ -378,7 +379,7 @@ public class LectureBlockRollCallDAO {
 				if(rollCall.getCoach() == null) {
 					rollCall.setCoach(fullname);
 				} else {
-					rollCall.setCoach(rollCall.getCoach() + ", " + fullname);
+					rollCall.setCoach(rollCall.getCoach() + " " + teacherSeaparator + " " + fullname);
 				}
 			}
 		}
diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
index 98a8daf5b714dc0e0db3c86f921da722ab8edb0f..c996fc9edf43b9f1b328da80666435f485bba285 100644
--- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
+++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
@@ -174,8 +174,7 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 
 	@Override
 	public RepositoryEntryLectureConfiguration updateRepositoryEntryLectureConfiguration(RepositoryEntryLectureConfiguration config) {
-		RepositoryEntryLectureConfiguration updatedConfig = lectureConfigurationDao.update(config);
-		return updatedConfig;
+		return lectureConfigurationDao.update(config);
 	}
 
 	@Override
@@ -422,6 +421,7 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 		return new ArrayList<>(participants);
 	}
 	
+	@Override
 	public List<Identity> syncParticipantSummaries(LectureBlock lectureBlock) {
 		RepositoryEntry entry = lectureBlock.getEntry();
 		Date now = new Date();
@@ -841,8 +841,9 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 	}
 
 	@Override
-	public List<LectureBlockAndRollCall> getParticipantLectureBlocks(RepositoryEntryRef entry, IdentityRef participant) {
-		return lectureBlockRollCallDao.getParticipantLectureBlockAndRollCalls(entry, participant);
+	public List<LectureBlockAndRollCall> getParticipantLectureBlocks(RepositoryEntryRef entry, IdentityRef participant,
+			String teacherSeaparator) {
+		return lectureBlockRollCallDao.getParticipantLectureBlockAndRollCalls(entry, participant, teacherSeaparator);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java b/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java
index cc7d2284b08e69ee36b9dffdd7bc375009d81f00..cc87b8ff5ffe8af9efbd1444f80667dffb49daa4 100644
--- a/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java
@@ -164,8 +164,9 @@ public class LectureListRepositoryController extends FormBasicController {
 		for(LectureBlockWithTeachers block:blocks) {
 			LectureBlock b = block.getLectureBlock();
 			StringBuilder teachers = new StringBuilder();
+			String separator = translate("user.fullname.separator");
 			for(Identity teacher:block.getTeachers()) {
-				if(teachers.length() > 0) teachers.append(", ");
+				if(teachers.length() > 0) teachers.append(" ").append(separator).append(" ");
 				teachers.append(userManager.getUserDisplayName(teacher));
 			}
 
@@ -182,7 +183,7 @@ public class LectureListRepositoryController extends FormBasicController {
 		tableModel.setObjects(rows);
 		tableEl.reset(true, true, true);
 		
-		deleteLecturesButton.setVisible(rows.size() > 0);
+		deleteLecturesButton.setVisible(!rows.isEmpty());
 	}
 	
 	@Override
@@ -314,7 +315,7 @@ public class LectureListRepositoryController extends FormBasicController {
 			}
 		}
 		
-		if(blocks.size() == 0) {
+		if(blocks.isEmpty()) {
 			showWarning("error.atleastone.lecture");
 		} else {
 			StringBuilder titles = new StringBuilder();
@@ -379,7 +380,9 @@ public class LectureListRepositoryController extends FormBasicController {
 
 	private class ToolsController extends BasicController {
 		
-		private Link deleteLink, copyLink, logLink;
+		private Link deleteLink;
+		private Link copyLink;
+		private Link logLink;
 		
 		private final LectureBlockRow row;
 		
diff --git a/src/main/java/org/olat/modules/lecture/ui/ParticipantLectureBlocksController.java b/src/main/java/org/olat/modules/lecture/ui/ParticipantLectureBlocksController.java
index 886abc2b6c17fd4774df2777895c66ab6fd4dd11..3cf7745d03acb4c962dd1f072b129486141cc9a3 100644
--- a/src/main/java/org/olat/modules/lecture/ui/ParticipantLectureBlocksController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/ParticipantLectureBlocksController.java
@@ -202,8 +202,9 @@ public class ParticipantLectureBlocksController extends FormBasicController {
 	private void loadModel() {
 		Date now = new Date();
 		Formatter formatter = Formatter.getInstance(getLocale());
-		
-		List<LectureBlockAndRollCall> rollCalls = lectureService.getParticipantLectureBlocks(entry, assessedIdentity);
+
+		String separator = translate("user.fullname.separator");
+		List<LectureBlockAndRollCall> rollCalls = lectureService.getParticipantLectureBlocks(entry, assessedIdentity, separator);
 		List<LectureBlockAuditLog> sendAppealLogs = lectureService.getAuditLog(entry, assessedIdentity, LectureBlockAuditLog.Action.sendAppeal);
 		Map<Long, Date> appealDates = new HashMap<>();
 		for(LectureBlockAuditLog sendAppealLog:sendAppealLogs) {
@@ -385,15 +386,12 @@ public class ParticipantLectureBlocksController extends FormBasicController {
 	}
 	
 	private void doPrint(UserRequest ureq) {
-		ControllerCreator printControllerCreator = new ControllerCreator() {
-			@Override
-			public Controller createController(UserRequest lureq, WindowControl lwControl) {
-				lwControl.getWindowBackOffice().getChiefController().addBodyCssClass("o_lectures_print");
-				Controller printCtrl = new ParticipantLectureBlocksController(lureq, lwControl, entry, assessedIdentity, false, false);
-				listenTo(printCtrl);
-				return printCtrl;
-			}					
-		};
+		ControllerCreator printControllerCreator = (lureq, lwControl) -> {
+			lwControl.getWindowBackOffice().getChiefController().addBodyCssClass("o_lectures_print");
+			Controller printCtrl = new ParticipantLectureBlocksController(lureq, lwControl, entry, assessedIdentity, false, false);
+			listenTo(printCtrl);
+			return printCtrl;
+		};				
 		ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createPrintPopupLayout(printControllerCreator);
 		openInNewBrowserWindow(ureq, layoutCtrlr);
 	}
diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherOverviewController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherOverviewController.java
index c9878ae05e5a468d7399cf1ca82ddddeb6cc04ca..00ceeba1adaa23d600446a1012643ca068d5cdb6 100644
--- a/src/main/java/org/olat/modules/lecture/ui/TeacherOverviewController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/TeacherOverviewController.java
@@ -89,11 +89,12 @@ public class TeacherOverviewController extends AbstractTeacherOverviewController
 			for(LectureBlockWithTeachers blockWithTeachers:blocksWithTeachers) {
 				LectureBlock block = blockWithTeachers.getLectureBlock();
 				
-				StringBuilder teachers = new StringBuilder();
+				StringBuilder teachers = new StringBuilder(32);
 				List<Identity> teacherList = blockWithTeachers.getTeachers();
-				
+
+				String separator = translate("user.fullname.separator");
 				for(Identity teacher:blockWithTeachers.getTeachers()) {
-					if(teachers.length() > 0) teachers.append(", ");
+					if(teachers.length() > 0) teachers.append(" ").append(separator).append(" ");
 					teachers.append(userManager.getUserDisplayName(teacher));
 				}
 				
diff --git a/src/main/java/org/olat/modules/portfolio/manager/PageDAO.java b/src/main/java/org/olat/modules/portfolio/manager/PageDAO.java
index b0af0a33ae9df2308bbf4142c780e4f8c6fe1488..184f437449047608541c7a394449097a29702d4f 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PageDAO.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PageDAO.java
@@ -460,11 +460,7 @@ public class PageDAO {
 				.setParameter("pageKey", page.getKey())
 				.executeUpdate();
 		
-		int evaluations = 0;
-		if(assignments > 0) {
-			// delete sessions and responses	
-			evaluations = evaluationFormSessionDao.deleteSessionForPortfolioEvaluation(body);
-		}
+		int evaluations = evaluationFormSessionDao.deleteSessionForPortfolioEvaluation(body);
 		
 		dbInstance.getCurrentEntityManager().remove(page);
 		dbInstance.getCurrentEntityManager().remove(body);
diff --git a/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java
index 6b51acfcbb8d281dfab4359eca6cf09af4bdcef7..54635978bfd939651e4408af618419f8b7b6062d 100644
--- a/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java
+++ b/src/main/java/org/olat/modules/qpool/security/ProcesslessSecurityCallback.java
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.qpool.security;
 
+import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionItemSecurityCallback;
 import org.olat.modules.qpool.QuestionItemView;
 import org.olat.modules.qpool.QuestionPoolModule;
@@ -44,6 +45,8 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback
 
 	@Autowired
 	private QuestionPoolModule qpoolModule;
+	@Autowired
+	private QPoolService qpoolService;
 	
 	@Override
 	public void setQuestionItemView(QuestionItemView itemView) {
@@ -161,7 +164,9 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback
 	@Override
 	public boolean canRemove() {
 		return  questionItemSource.isRemoveEnabled()
-				&& (admin || itemView.isAuthor());
+				|| admin
+				|| poolAdmin
+				|| itemView.isAuthor();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java b/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java
index 1469e45c69b32a6280751afd1a8ba20f5736b854..d21d0f0e77d5be6629e5b7116d6d028fbd38151e 100644
--- a/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java
+++ b/src/main/java/org/olat/modules/qpool/security/ReviewProcessSecurityCallback.java
@@ -160,8 +160,10 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba
 
 	@Override
 	public boolean canRemove() {
-		return questionItemSource.isRemoveEnabled()
-				&& (admin || itemView.isAuthor() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditStatus()));
+		return  questionItemSource.isRemoveEnabled()
+				|| admin
+				|| poolAdmin
+				|| itemView.isAuthor();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java
index a22164ff3fec433654fe333148f36f69180477c8..103c40ca91f3abfc27bda5827444ace4fe8b6007 100644
--- a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java
@@ -156,7 +156,7 @@ public class QuestionPoolMainEditorController extends BasicController implements
 	}
 	
 	private TreeNode getDelegate(TreeNode node) {
-		if (node.getDelegate() != null) {
+		if (node != null && node.getDelegate() != null) {
 			getDelegate(node.getDelegate());
 		}
 		return node;
diff --git a/src/main/java/org/olat/modules/qpool/ui/QuickViewMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/QuickViewMetadataController.java
index 0e6f21d7990915e38724618f8207d8fa8bbc25c2..d9afe6d55dba91dbc85d6809e35067271ba5f151 100644
--- a/src/main/java/org/olat/modules/qpool/ui/QuickViewMetadataController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/QuickViewMetadataController.java
@@ -59,17 +59,9 @@ public class QuickViewMetadataController extends BasicController {
 			metadataCtrl = null;
 			metadataPanel.setContent(null);
 		} else {
-			initControllers(ureq, item);
-			metadataCtrl.setItem(item, metadataSecurityCallback);
-			metadataPanel.setContent(metadataCtrl.getInitialComponent());
-		}
-	}
-	
-	private void initControllers(UserRequest ureq, QuestionItem item) {
-		if (item == null) return;
-		
-		if (metadataCtrl == null) {
+			removeAsListenerAndDispose(metadataCtrl);
 			metadataCtrl = new MetadatasController(ureq, getWindowControl(), qPoolSecurityCallback, item, metadataSecurityCallback, false);
+			metadataPanel.setContent(metadataCtrl.getInitialComponent());
 		}
 	}
 
diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
index 6146d3ab0b4b250d4a974ef15d7ef126fcd24db9..0f3ccb51ecaf2b9035ae0116d1b39a5eb02f23a9 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties
@@ -127,16 +127,16 @@ item.numbers.of={0} / {1}
 item.pooled=Frage {0} wurde zum Pool hinzugef\u00FCgt.
 item.shared=Frage {0} wurde freigegeben.
 item.type.drawing=Zeichnen
-item.type.essay=Essay
-item.type.fib=Fill-in-Blank
+item.type.essay=Freitext
+item.type.fib=L\u00FCckentext
 item.type.hotspot=Hotspot
 item.type.hottext=Hottext
-item.type.kprim=KPrim
+item.type.kprim=Kprim
 item.type.match=Matrix
+item.type.mc=Multiple Choice
 item.type.matchdraganddrop=Drag and Drop
-item.type.mc=Multiple-Choice
-item.type.numerical=Numerische Eingabe
-item.type.sc=Single-Choice
+item.type.matchtruefalse=True/false
+item.type.sc=Single Choice
 item.type.unkown=Unbekannt
 item.type.upload=Datei hochladen
 lifecycle.status=Status
diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
index f919eb670db1555e04dd958e8f553e9ed7345f7f..0004fd6fa41af67cd94fb1e3208d4e45eed74d00 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 13:13:33 CET 2018
+#Wed Feb 28 13:29:43 CET 2018
 add=+
 add.to.list=Adicionar \u00E0 lista
 admin.configuration.title=Banco de perguntas
@@ -135,6 +135,7 @@ item.type.hottext=Hottext
 item.type.kprim=KPrim
 item.type.match=Combine
 item.type.matchdraganddrop=Arraste e solte
+item.type.matchtruefalse=Verdadeiro/Falso
 item.type.mc=Escolha M\u00FAltipla
 item.type.numerical=Entrada num\u00E9rica
 item.type.sc=Escolha \u00FAnica
diff --git a/src/main/java/org/olat/modules/qpool/ui/datasource/PoolItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/PoolItemsSource.java
index 85217be35e15a29bd1f8fb3919f6e2dc488240ff..e931da62f3311b2982ad15090ff65adc95966e73 100644
--- a/src/main/java/org/olat/modules/qpool/ui/datasource/PoolItemsSource.java
+++ b/src/main/java/org/olat/modules/qpool/ui/datasource/PoolItemsSource.java
@@ -46,6 +46,10 @@ public class PoolItemsSource extends DefaultItemsSource {
 		getDefaultParams().setPoolKey(pool.getKey());
 	}
 	
+	public Pool getPool() {
+		return pool;
+	}
+
 	@Override
 	public void removeFromSource(List<QuestionItemShort> items) {
 		qpoolService.removeItemsInPool(items, pool);
diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/MetadatasController.java b/src/main/java/org/olat/modules/qpool/ui/metadata/MetadatasController.java
index af28a96ddcf7891d7a35202e7a3dc6d9081878c5..200da0240f4b007014eddf48dbbc90ca4d015644 100644
--- a/src/main/java/org/olat/modules/qpool/ui/metadata/MetadatasController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/metadata/MetadatasController.java
@@ -145,12 +145,12 @@ public class MetadatasController extends BasicController {
 		}
 	}
 	
-	public void setItem(QuestionItem item, MetadataSecurityCallback metadataScurityCallback) {
+	public void setItem(QuestionItem item, MetadataSecurityCallback metadataSecurityCallback) {
 		this.item = item;
-		generalEditCtrl.setItem(item, metadataScurityCallback);
-		questionEditCtrl.setItem(item, metadataScurityCallback);
-		rightsEditCtrl.setItem(item, metadataScurityCallback);
-		technicalEditCtrl.setItem(item, metadataScurityCallback);
+		generalEditCtrl.setItem(item, metadataSecurityCallback);
+		questionEditCtrl.setItem(item, metadataSecurityCallback);
+		rightsEditCtrl.setItem(item, metadataSecurityCallback);
+		technicalEditCtrl.setItem(item, metadataSecurityCallback);
 		if (ratingMetadataCtrl != null) {
 			ratingMetadataCtrl.setItem(item);
 		}
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/BusinessGroupTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/BusinessGroupTreeNode.java
index 1f8619c050190b6f1234d5b593c96aee43fd32c2..74cbd57e352c1f87b4badb1370cb29b7fa963fb9 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/BusinessGroupTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/BusinessGroupTreeNode.java
@@ -26,7 +26,6 @@ import org.olat.core.gui.components.tree.GenericTreeNode;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
-import org.olat.core.id.Roles;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
@@ -93,11 +92,6 @@ public class BusinessGroupTreeNode extends GenericTreeNode implements Controller
 	
 	private boolean isShareAdmin(UserRequest ureq, BusinessGroup group) {
 		Identity identity = ureq.getIdentity();
-		Roles roles = ureq.getUserSession().getRoles();
-		return roles != null &&
-				(  roles.isOLATAdmin()
-				|| roles.isPoolAdmin()
-				|| businessGroupService.isIdentityInBusinessGroup(identity, group.getKey(), true, false, null)
-				);
+		return businessGroupService.isIdentityInBusinessGroup(identity, group.getKey(), true, false, null);
 	}
 }
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
index 43e541b2360858bc1d9af5373bdd4321b21fbe2e..97f7787bc726f8e053ebb5fb999fb723e0060cda 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/FinalTreeNode.java
@@ -80,7 +80,8 @@ public class FinalTreeNode extends GenericTreeNode implements ControllerTreeNode
 					ureq.getIdentity(),
 					ureq.getUserSession().getRoles(),
 					taxonomyLevel);
-			OLATResourceable ores = OresHelper.createOLATResourceableInstance(FINAL + "_" + taxonomyLevel.getIdentifier(), taxonomyLevel.getKey());
+			String resName = FINAL + "_" + taxonomyLevel.getIdentifier();
+			OLATResourceable ores = OresHelper.createOLATResourceableInstanceWithoutCheck(resName, taxonomyLevel.getKey());
 			WindowControl swControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, null, wControl, true);
 			questionsCtrl = new QuestionsController(ureq, swControl, stackPanel, source, securityCallback,
 					FINAL + taxonomyLevel.getKey(), false);
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
index 0e481ed88fc55aff0712068f3d5f9e99ee7c1d8d..b3280eb9828a49eed4c4710ca21103a770327796 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/MyTaxonomyLevelTreeNode.java
@@ -76,7 +76,7 @@ public class MyTaxonomyLevelTreeNode extends GenericTreeNode implements Controll
 					ureq.getIdentity(),
 					ureq.getUserSession().getRoles(),
 					taxonomyLevel);
-			OLATResourceable ores = OresHelper.createOLATResourceableInstance(MY_TAX_LEVEL + "_" + taxonomyLevel.getIdentifier(), taxonomyLevel.getKey());
+			OLATResourceable ores = OresHelper.createOLATResourceableInstanceWithoutCheck(MY_TAX_LEVEL + "_" + taxonomyLevel.getIdentifier(), taxonomyLevel.getKey());
 			WindowControl swControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, null, wControl, true);
 			questionsCtrl = new QuestionsController(ureq, swControl, stackPanel, source, securityCallback,
 					MY_TAX_LEVEL + taxonomyLevel.getKey(), false);
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/PoolTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/PoolTreeNode.java
index bac68c3f8f8e500c52ffd2bc689e55060a672910..03a5d5bfec5ac784257ac1af5dc4906838f6cbfb 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/PoolTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/PoolTreeNode.java
@@ -26,7 +26,6 @@ import org.olat.core.gui.components.tree.GenericTreeNode;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
-import org.olat.core.id.Roles;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.modules.qpool.Pool;
 import org.olat.modules.qpool.QPoolSecurityCallback;
@@ -79,7 +78,7 @@ public class PoolTreeNode extends GenericTreeNode implements ControllerTreeNode
 					ureq.getIdentity(),
 					ureq.getUserSession().getRoles(),
 					pool);
-			source.setRemoveEnabled(isPoolAdmin(ureq, pool));
+			source.setRemoveEnabled(isRemoveEnabled(ureq, pool));
 			WindowControl swControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, pool, null,
 					wControl, true);
 			questionsCtrl = new QuestionsController(ureq, swControl, stackPanel, source, securityCallback,
@@ -90,15 +89,9 @@ public class PoolTreeNode extends GenericTreeNode implements ControllerTreeNode
 		return questionsCtrl;
 	}
 	
-	private boolean isPoolAdmin(UserRequest ureq, Pool pool) {
+	private boolean isRemoveEnabled(UserRequest ureq, Pool pool) {
 		Identity identity = ureq.getIdentity();
-		Roles roles = ureq.getUserSession().getRoles();
-		return roles != null &&
-				(  roles.isOLATAdmin()
-				|| roles.isPoolAdmin()
-				|| pool.isPublicPool()
-				|| qpoolService.isOwner(identity, pool)
-				);
+		return pool.isPublicPool() || qpoolService.isOwner(identity, pool);
 	}
 
 }
diff --git a/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
index 143b3ef56b253c9da5f070d9d505520c335ae4bc..7702fab5dcdd527ca6422aa3988a8e40027a3157 100644
--- a/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
+++ b/src/main/java/org/olat/modules/qpool/ui/tree/ReviewTreeNode.java
@@ -78,7 +78,8 @@ public class ReviewTreeNode extends GenericTreeNode implements ControllerTreeNod
 	@Override
 	public Controller getController(UserRequest ureq, WindowControl wControl) {
 		if (questionsCtrl == null) {
-			OLATResourceable ores = OresHelper.createOLATResourceableInstance(REVIEW + "_" + taxonomyLevel.getIdentifier(), taxonomyLevel.getKey());
+			String resName = REVIEW + "_" + taxonomyLevel.getIdentifier();
+			OLATResourceable ores = OresHelper.createOLATResourceableInstanceWithoutCheck(resName, taxonomyLevel.getKey());
 			WindowControl swControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, null, wControl, true);
 			questionsCtrl = new QuestionsController(ureq, swControl, stackPanel, source, securityCallback,
 					REVIEW + taxonomyLevel.getKey(), false);
diff --git a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
index 9724fc0e91ece7c572b8dda71299652afeffde6b..b26668a01baa1096b725f8509c30448b827cc32c 100644
--- a/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
+++ b/src/main/java/org/olat/modules/taxonomy/ui/EditTaxonomyLevelController.java
@@ -211,20 +211,11 @@ public class EditTaxonomyLevelController extends FormBasicController {
 
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
-		
-		displayNameEl.clearError();
-		if(!StringHelper.containsNonWhitespace(displayNameEl.getValue())) {
-			displayNameEl.setErrorKey("form.legende.mandatory", null);
-			allOk &= false;
-		}
-		
-		identifierEl.clearError();
-		if(!StringHelper.containsNonWhitespace(identifierEl.getValue())) {
-			identifierEl.setErrorKey("form.legende.mandatory", null);
-			allOk &= false;
-		}
+		boolean allOk = super.validateFormLogic(ureq);
 		
+		allOk &= validateTextfield(displayNameEl, 255);
+		allOk &= validateTextfield(identifierEl, 64);
+
 		sortOrderEl.clearError();
 		if(StringHelper.containsNonWhitespace(sortOrderEl.getValue())) {
 			try {
@@ -235,7 +226,22 @@ public class EditTaxonomyLevelController extends FormBasicController {
 			}
 		}
 		
-		return allOk & super.validateFormLogic(ureq);
+		return allOk;
+	}
+	
+	private boolean validateTextfield(TextElement textEl, int maxSize) {
+		boolean allOk = true;
+		
+		textEl.clearError();
+		if(!StringHelper.containsNonWhitespace(identifierEl.getValue())) {
+			identifierEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		} else if(identifierEl.getValue().length() >= maxSize) {
+			identifierEl.setErrorKey("form.error.toolong", new String[] { Integer.toString(maxSize) });
+			allOk &= false;
+		}
+		
+		return allOk;
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_pt_BR.properties
index e0596a515a64308a4f9dc0ade1afb32f85eb4321..3f33dd171ef386522032431ebea5ca42f857b461 100644
--- a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_pt_BR.properties
@@ -1,4 +1,4 @@
-#Thu Feb 08 13:32:15 CET 2018
+#Wed Feb 28 13:30:37 CET 2018
 QuestionItemImpl=Pergunta
 actions=A\u00E7\u00F5es
 add.competence.have=Adicionar "$\:have"
@@ -133,3 +133,5 @@ warning.atleastone.level=Voc\u00EA deve selecionar pelo menos um n\u00EDvel que
 warning.atleastone.level.competence=Voc\u00EA deve escolher pelo menos um n\u00EDvel.
 warning.delete.level=O n\u00EDvel n\u00E3o pode ser exclu\u00EDdo porque ainda est\u00E1 em uso.
 warning.delete.level.type=O tipo de n\u00EDvel "{0}" n\u00E3o foi exclu\u00EDdo porque ainda est\u00E1 em uso.
+warning.taxonomy.level.deleted=Esse n\u00EDvel de taxonomia n\u00E3o est\u00E1 mais dispon\u00EDvel
+warning.taxonomy.level.type.deleted=Esse tipo de n\u00EDvel n\u00E3o est\u00E1 mais dispon\u00EDvel.
diff --git a/src/main/java/org/olat/registration/RegistrationController.java b/src/main/java/org/olat/registration/RegistrationController.java
index 09d644e22932ba948cee3f7b66714cf69370a60e..1898cfe813d3f195c9946d33ad4554d063975113 100644
--- a/src/main/java/org/olat/registration/RegistrationController.java
+++ b/src/main/java/org/olat/registration/RegistrationController.java
@@ -303,7 +303,7 @@ public class RegistrationController extends BasicController implements Activatea
 				};
 
 				boolean isMailSent = false;
-				if (UserManager.getInstance().isEmailAllowed(email)) {
+				if (registrationManager.isRegistrationPending(email) || UserManager.getInstance().isEmailAllowed(email)) {
 					TemporaryKey tk = null;
 					if (userModule.isEmailUnique()) {
 						tk = registrationManager.loadTemporaryKeyByEmail(email);
diff --git a/src/main/java/org/olat/registration/RegistrationManager.java b/src/main/java/org/olat/registration/RegistrationManager.java
index 96de61bc0634baec46f81e0e92cc580351609dd2..59b5d03f620dc9972afb98348c9d4a8e32632f16 100644
--- a/src/main/java/org/olat/registration/RegistrationManager.java
+++ b/src/main/java/org/olat/registration/RegistrationManager.java
@@ -370,18 +370,21 @@ public class RegistrationManager {
 				}
 			}
 		}
-		tk = loadTemporaryKeyByAction(RegistrationManager.REGISTRATION);
-		if (tk != null) {
-			for (TemporaryKey temporaryKey : tk) {
+		return isRegistrationPending(emailAddress);
+	}
+
+	public boolean isRegistrationPending(String emailAddress) {
+		List<TemporaryKey> temporaryKeys = loadTemporaryKeyByAction(RegistrationManager.REGISTRATION);
+		if (temporaryKeys != null) {
+			for (TemporaryKey temporaryKey : temporaryKeys) {
 				if (emailAddress.equalsIgnoreCase(temporaryKey.getEmailAddress())) {
 					return true;
 				}
 			}
 		}
-		
 		return false;
 	}
-
+	
 	/**
 	 * Evaluates whether the given identity needs to accept a disclaimer before
 	 * logging in or not.
diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java
index 66ff441f538005dcb5eea1193453da59b68a9849..9497d85edad69ff33e76b63c776c16a65b8424a0 100644
--- a/src/main/java/org/olat/repository/RepositoryManager.java
+++ b/src/main/java/org/olat/repository/RepositoryManager.java
@@ -693,7 +693,7 @@ public class RepositoryManager {
 		//fetch the values
 		updatedRe.getStatistics().getLaunchCounter();
 		if(updatedRe.getLifecycle() != null) {
-			updatedRe.getLifecycle().getKey();
+			updatedRe.getLifecycle().getCreationDate();
 		}
 
 		dbInstance.commit();
@@ -710,7 +710,7 @@ public class RepositoryManager {
 		RepositoryEntry updatedRe = dbInstance.getCurrentEntityManager().merge(reloadedRe);
 		updatedRe.getStatistics().getLaunchCounter();
 		if(updatedRe.getLifecycle() != null) {
-			updatedRe.getLifecycle().getKey();
+			updatedRe.getLifecycle().getCreationDate();
 		}
 		dbInstance.commit();
 		return updatedRe;
@@ -840,7 +840,7 @@ public class RepositoryManager {
 		//fetch the values
 		updatedRe.getStatistics().getLaunchCounter();
 		if(updatedRe.getLifecycle() != null) {
-			updatedRe.getLifecycle().getKey();
+			updatedRe.getLifecycle().getCreationDate();
 		}
 
 		dbInstance.commit();
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
index 6f0095e68a4c4d5876b55f681eefd55abc59842c..da5bdf079f1f884495de2602953e4ae487436942 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
@@ -718,7 +718,9 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 	
 	protected void doDetails(UserRequest ureq) {
 		WindowControl bwControl = getSubWindowControl("Infos");
-		RepositoryEntryDetailsController ctrl = new RepositoryEntryDetailsController(ureq, addToHistory(ureq, bwControl), re, true);
+		
+		RepositoryEntry entry = loadRepositoryEntry();
+		RepositoryEntryDetailsController ctrl = new RepositoryEntryDetailsController(ureq, addToHistory(ureq, bwControl), entry, true);
 		listenTo(ctrl);
 		detailsCtrl = pushController(ureq, translate("details.header"), ctrl);
 		currentToolCtr = detailsCtrl;
diff --git a/src/main/java/org/olat/user/UserInfoMainController.java b/src/main/java/org/olat/user/UserInfoMainController.java
index e1c367cb292510d1d12467d3a937f1724915a66b..b960a8fcbb76ad597ad244b47d2ca1710ae1ea5e 100644
--- a/src/main/java/org/olat/user/UserInfoMainController.java
+++ b/src/main/java/org/olat/user/UserInfoMainController.java
@@ -343,8 +343,9 @@ public class UserInfoMainController extends MainLayoutBasicController implements
 		
 		OLATResourceable ores = OresHelper.createOLATResourceableType(CMD_CALENDAR);
 		WindowControl bwControl = addToHistory(ureq, ores, null);
+		OLATResourceable callerOres = OresHelper.createOLATResourceableInstance(chosenIdentity.getName(), chosenIdentity.getKey());
 		calendarController = new WeeklyCalendarController(ureq, bwControl, calendars,
-				WeeklyCalendarController.CALLER_PROFILE, null, false);
+				WeeklyCalendarController.CALLER_PROFILE, callerOres, false);
 		listenTo(calendarController);
 		return calendarController;
 	}
diff --git a/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java b/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java
index 5626ed039e540a15a9558c596f01ba966585eb0e..33f1e6456b0b6c14db686dfbdf2af21a147e4ea5 100644
--- a/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java
+++ b/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java
@@ -51,9 +51,8 @@ import org.olat.core.util.Util;
  */
 public class NewUsersNotificationHandler implements NotificationsHandler {
 	private static final OLog log = Tracing.createLoggerFor(NewUsersNotificationHandler.class);
-	
-	private List<Identity> identities;
 
+	@Override
 	public SubscriptionInfo createSubscriptionInfo(Subscriber subscriber, Locale locale, Date compareDate) {
 		Publisher p = subscriber.getPublisher();
 		Date latestNews = p.getLatestNewsDate();
@@ -63,12 +62,12 @@ public class NewUsersNotificationHandler implements NotificationsHandler {
 		// there could be news for me, investigate deeper
 		try {
 			if (NotificationsManager.getInstance().isPublisherValid(p) && compareDate.before(latestNews)) {
-				identities = UsersSubscriptionManager.getInstance().getNewIdentityCreated(compareDate);
+				List<Identity> identities = UsersSubscriptionManager.getInstance().getNewIdentityCreated(compareDate);
 				if (identities.isEmpty()) {
 					si = NotificationsManager.getInstance().getNoSubscriptionInfo();
 				} else {
 					translator = Util.createPackageTranslator(this.getClass(), locale);
-					si = new SubscriptionInfo(subscriber.getKey(), p.getType(), new TitleItem(getItemTitle(translator), CSSHelper.CSS_CLASS_GROUP), null);
+					si = new SubscriptionInfo(subscriber.getKey(), p.getType(), new TitleItem(getItemTitle(identities, translator), CSSHelper.CSS_CLASS_GROUP), null);
 					SubscriptionListItem subListItem;
 					for (Identity newUser : identities) {
 						String desc = translator.translate("notifications.entry", new String[] { NotificationHelper.getFormatedName(newUser) });
@@ -89,7 +88,7 @@ public class NewUsersNotificationHandler implements NotificationsHandler {
 		return si;
 	}
 
-	private String getItemTitle(Translator translator) {
+	private String getItemTitle(List<Identity> identities, Translator translator) {
 		String numOfNewUsers = Integer.toString(identities.size());
 		if (identities.size() > 1) { return translator.translate("notifications.title", new String[] { numOfNewUsers }); }
 		return translator.translate("notifications.titleOne");
diff --git a/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.js b/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.js
new file mode 100755
index 0000000000000000000000000000000000000000..57db6f1e6f36d43bb953bdeef59c4d3b07a6bd91
--- /dev/null
+++ b/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.js
@@ -0,0 +1,195 @@
+/*! jquery.taboverride v4.0.0 | https://github.com/wjbryant/jquery.taboverride
+Copyright (c) 2013 Bill Bryant | http://opensource.org/licenses/mit */
+
+/**
+ * @fileOverview Tab Override jQuery plugin
+ * @author       Bill Bryant
+ * @version      4.0.0
+ */
+
+/*global exports, require, define, jQuery, tabOverride */
+
+/**
+ * The jQuery plugin namespace
+ *
+ * @external "jQuery.fn"
+ */
+
+// Use CommonJS or AMD if available
+(function ( factory ) {
+	"use strict";
+
+	if ( typeof exports === "object" && typeof require === "function" ) {
+		// Node.js/CommonJS
+		factory( require( "jquery" ), require( "taboverride" ) );
+	} else if ( typeof define === "function" && define.amd ) {
+		// AMD - Register as an anonymous module
+		// Files must be concatenated using an AMD-aware tool such as r.js
+		define( [ "jquery", "taboverride" ], factory );
+	} else {
+		// No module format - Use global variables instead
+		factory( jQuery, tabOverride );
+	}
+}(function ( $, tabOverride ) {
+	"use strict";
+
+	var $fnTabOverride;
+
+	/**
+	 * Helper function to remove the delegated listeners. This is only used in
+	 * the removeDelegatedListeners and addDelegatedListeners functions.
+	 *
+	 * @see external:"jQuery.fn".tabOverride.utils.removeDelegatedListeners
+	 * @private
+	 */
+	function removeDelegatedListenersHelper( $container, selector ) {
+		$container.off({
+			"keydown.tabOverride": tabOverride.handlers.keydown,
+			"keypress.tabOverride": tabOverride.handlers.keypress
+		}, selector );
+	}
+
+	/**
+	 * Removes the Tab Override event listeners on the container element
+	 * using jQuery delegated events.
+	 *
+	 * Hooks: removeDelegatedListeners - passed the jQuery object for the
+	 * container element(s) and the selector string
+	 *
+	 * @param {Object} $container  the jQuery object for the container element
+	 * @param {string} selector    the selector string to use for the delegated events
+	 *
+	 * @method external:"jQuery.fn".tabOverride.utils.removeDelegatedListeners
+	 */
+	function removeDelegatedListeners( $container, selector ) {
+		tabOverride.utils.executeExtensions( "removeDelegatedListeners", [ $container, selector ] );
+		removeDelegatedListenersHelper( $container, selector );
+	}
+
+	/**
+	 * Adds the Tab Override event listeners to the container element using
+	 * jQuery delegated events.
+	 *
+	 * Hooks: addDelegatedListeners - passed the jQuery object for the
+	 * container element(s) and the selector string
+	 *
+	 * @param {Object} $container  the jQuery object for the container element
+	 * @param {string} selector    the selector string to use for the delegated events
+	 *
+	 * @method external:"jQuery.fn".tabOverride.utils.addDelegatedListeners
+	 */
+	function addDelegatedListeners( $container, selector ) {
+		tabOverride.utils.executeExtensions( "addDelegatedListeners", [ $container, selector ] );
+		removeDelegatedListenersHelper( $container, selector );
+		$container.on({
+			"keydown.tabOverride": tabOverride.handlers.keydown,
+			"keypress.tabOverride": tabOverride.handlers.keypress
+		}, selector );
+	}
+
+	/**
+	 * The tabOverride method namespace
+	 *
+	 * @namespace external:"jQuery.fn".tabOverride
+	 */
+
+	/**
+	 * Enables/disables Tab Override. If enabled, tabs (or spaces) will be
+	 * inserted in the selected textarea elements when the tab key is pressed.
+	 *
+	 * Hooks: setDelegated - fired when delegated events are used, passed the
+	 * jQuery object for the container element(s), the selector string, and a
+	 * boolean indicating whether Tab Override was enabled or disabled.
+	 *
+	 * @param  {boolean} [enable=true]  whether Tab Override should be enabled
+	 *                                  for the element(s)
+	 * @param  {string}  [selector]     the selector string for delegated events
+	 * @return {Object}                 the jQuery object
+	 *
+	 * @method external:"jQuery.fn".tabOverride(2)
+	 */
+	$fnTabOverride = $.fn.tabOverride = function ( enable, selector ) {
+
+		var enablePlugin = !arguments.length || enable,
+			isDelegated = typeof selector === "string",
+			$container;
+
+		if ( isDelegated ) {
+			$container = this;
+
+			tabOverride.utils.executeExtensions( "setDelegated", [ $container, selector, enable ] );
+
+			if ( enablePlugin ) {
+				addDelegatedListeners( $container, selector );
+			} else {
+				removeDelegatedListeners( $container, selector );
+			}
+		} else {
+			// The jQuery object acts as an array of elements, so it can be passed
+			// to tabOverride.set()
+			tabOverride.set( this, enablePlugin );
+		}
+
+		// Return the jQuery object
+		return this;
+	};
+
+	/**
+	 * Namespace for utility methods
+	 *
+	 * @namespace external:"jQuery.fn".tabOverride.utils
+	 */
+	$fnTabOverride.utils = {
+		addDelegatedListeners: addDelegatedListeners,
+		removeDelegatedListeners: removeDelegatedListeners
+	};
+
+	/**
+	 * Gets or sets the tab size for all elements that have Tab Override enabled.
+	 * 0 represents the tab character.
+	 *
+	 * @param  {number}          [size]  the tab size
+	 * @return {number|Function}         the tab size or the tabOverride function
+	 *
+	 * @method external:"jQuery.fn".tabOverride.tabSize
+	 */
+	$fnTabOverride.tabSize = tabOverride.tabSize;
+
+	/**
+	 * Gets or sets the auto indent setting. True if each line should be
+	 * automatically indented (default = false).
+	 *
+	 * @param  {boolean}          [enable]  whether auto indent should be enabled
+	 * @return {boolean|Function}           whether auto indent is enabled or the
+	 *                                      tabOverride function
+	 *
+	 * @method external:"jQuery.fn".tabOverride.autoIndent
+	 */
+	$fnTabOverride.autoIndent = tabOverride.autoIndent;
+
+	/**
+	 * Gets or sets the tab key combination.
+	 *
+	 * @param  {number}          keyCode             the key code of the key to use for tab
+	 * @param  {string[]}        [modifierKeyNames]  the modifier key names - valid names are
+	 *                                               'alt', 'ctrl', 'meta', and 'shift'
+	 * @return {string|Function}                     the current tab key combination or the
+	 *                                               tabOverride function
+	 *
+	 * @method external:"jQuery.fn".tabOverride.tabKey
+	 */
+	$fnTabOverride.tabKey = tabOverride.tabKey;
+
+	/**
+	 * Gets or sets the untab key combination.
+	 *
+	 * @param  {number}          keyCode             the key code of the key to use for untab
+	 * @param  {string[]}        [modifierKeyNames]  the modifier key names - valid names are
+	 *                                               'alt', 'ctrl', 'meta', and 'shift'
+	 * @return {string|Function}                     the current untab key combination or the
+	 *                                               tabOverride function
+	 *
+	 * @method external:"jQuery.fn".tabOverride.untabKey
+	 */
+	$fnTabOverride.untabKey = tabOverride.untabKey;
+}));
diff --git a/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.min.js b/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.min.js
new file mode 100755
index 0000000000000000000000000000000000000000..7759695eb3498bc8497741821afaf2d74c8c02a9
--- /dev/null
+++ b/src/main/webapp/static/js/jquery/taboverride/jquery.taboverride.min.js
@@ -0,0 +1,3 @@
+/*! jquery.taboverride v4.0.0 | https://github.com/wjbryant/jquery.taboverride
+Copyright (c) 2013 Bill Bryant | http://opensource.org/licenses/mit */
+!function(a){"use strict";"object"==typeof exports&&"function"==typeof require?a(require("jquery"),require("taboverride")):"function"==typeof define&&define.amd?define(["jquery","taboverride"],a):a(jQuery,tabOverride)}(function(a,b){"use strict";function c(a,c){a.off({"keydown.tabOverride":b.handlers.keydown,"keypress.tabOverride":b.handlers.keypress},c)}function d(a,d){b.utils.executeExtensions("removeDelegatedListeners",[a,d]),c(a,d)}function e(a,d){b.utils.executeExtensions("addDelegatedListeners",[a,d]),c(a,d),a.on({"keydown.tabOverride":b.handlers.keydown,"keypress.tabOverride":b.handlers.keypress},d)}var f;f=a.fn.tabOverride=function(a,c){var f,g=!arguments.length||a,h="string"==typeof c;return h?(f=this,b.utils.executeExtensions("setDelegated",[f,c,a]),g?e(f,c):d(f,c)):b.set(this,g),this},f.utils={addDelegatedListeners:e,removeDelegatedListeners:d},f.tabSize=b.tabSize,f.autoIndent=b.autoIndent,f.tabKey=b.tabKey,f.untabKey=b.untabKey});
\ No newline at end of file
diff --git a/src/main/webapp/static/js/jquery/taboverride/taboverride-4.0.0.min.js b/src/main/webapp/static/js/jquery/taboverride/taboverride-4.0.0.min.js
new file mode 100755
index 0000000000000000000000000000000000000000..debee0d54125ce9e7ed9fcdd4f48d72452da5752
--- /dev/null
+++ b/src/main/webapp/static/js/jquery/taboverride/taboverride-4.0.0.min.js
@@ -0,0 +1,4 @@
+/*! taboverride v4.0.0-dev | https://github.com/wjbryant/taboverride
+Copyright (c) 2013 Bill Bryant | http://opensource.org/licenses/mit */
+(function(e){"use strict";var t;"object"==typeof exports?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):(t=window.tabOverride={},e(t))})(function(e){"use strict";function t(e,t){var n,r,i,l=["alt","ctrl","meta","shift"],o=e.length,a=!0;for(n=0;o>n;n+=1)if(!t[e[n]]){a=!1;break}if(a)for(n=0;l.length>n;n+=1){if(i=l[n]+"Key",t[i])if(o){for(a=!1,r=0;o>r;r+=1)if(i===e[r]){a=!0;break}}else a=!1;if(!a)break}return a}function n(e,n){return e===v&&t(p,n)}function r(e,n){return e===g&&t(m,n)}function i(e,t){return function(n,r){var i,l="";if(arguments.length){if("number"==typeof n&&(e(n),t.length=0,r&&r.length))for(i=0;r.length>i;i+=1)t.push(r[i]+"Key");return this}for(i=0;t.length>i;i+=1)l+=t[i].slice(0,-3)+"+";return l+e()}}function l(e){e=e||event;var t,i,l,o,a,s,c,p,m,x,b,S,k,T,w,L,O,K,A=e.currentTarget||e.srcElement,C=e.keyCode,D="character";if((!A.nodeName||"textarea"===A.nodeName.toLowerCase())&&(C===v||C===g||13===C&&y)){if(E=!1,l=A.value,p=A.scrollTop,"number"==typeof A.selectionStart)m=A.selectionStart,x=A.selectionEnd,b=l.slice(m,x);else{if(!d.selection)return;o=d.selection.createRange(),b=o.text,a=o.duplicate(),a.moveToElementText(A),a.setEndPoint("EndToEnd",o),x=a.text.length,m=x-b.length,f>1?(s=l.slice(0,m).split(u).length-1,c=b.split(u).length-1):s=c=0}if(C===v||C===g)if(t=h,i=t.length,T=0,w=0,L=0,m!==x&&-1!==b.indexOf("\n"))if(S=0===m||"\n"===l.charAt(m-1)?m:l.lastIndexOf("\n",m-1)+1,x===l.length||"\n"===l.charAt(x)?k=x:"\n"===l.charAt(x-1)?k=x-1:(k=l.indexOf("\n",x),-1===k&&(k=l.length)),n(C,e))T=1,A.value=l.slice(0,S)+t+l.slice(S,k).replace(/\n/g,function(){return T+=1,"\n"+t})+l.slice(k),o?(o.collapse(),o.moveEnd(D,x+T*i-c-s),o.moveStart(D,m+i-s),o.select()):(A.selectionStart=m+i,A.selectionEnd=x+T*i,A.scrollTop=p);else{if(!r(C,e))return;0===l.slice(S).indexOf(t)&&(S===m?b=b.slice(i):L=i,w=i),A.value=l.slice(0,S)+l.slice(S+L,m)+b.replace(RegExp("\n"+t,"g"),function(){return T+=1,"\n"})+l.slice(x),o?(o.collapse(),o.moveEnd(D,x-w-T*i-c-s),o.moveStart(D,m-L-s),o.select()):(A.selectionStart=m-L,A.selectionEnd=x-w-T*i)}else if(n(C,e))o?(o.text=t,o.select()):(A.value=l.slice(0,m)+t+l.slice(x),A.selectionEnd=A.selectionStart=m+i,A.scrollTop=p);else{if(!r(C,e))return;0===l.slice(m-i).indexOf(t)&&(A.value=l.slice(0,m-i)+l.slice(m),o?(o.move(D,m-i-s),o.select()):(A.selectionEnd=A.selectionStart=m-i,A.scrollTop=p))}else if(y){if(0===m||"\n"===l.charAt(m-1))return E=!0,void 0;if(S=l.lastIndexOf("\n",m-1)+1,k=l.indexOf("\n",m),-1===k&&(k=l.length),O=l.slice(S,k).match(/^[ \t]*/)[0],K=O.length,S+K>m)return E=!0,void 0;o?(o.text="\n"+O,o.select()):(A.value=l.slice(0,m)+"\n"+O+l.slice(x),A.selectionEnd=A.selectionStart=m+f+K,A.scrollTop=p)}return e.preventDefault?(e.preventDefault(),void 0):(e.returnValue=!1,!1)}}function o(e){e=e||event;var t=e.keyCode;if(n(t,e)||r(t,e)||13===t&&y&&!E){if(!e.preventDefault)return e.returnValue=!1,!1;e.preventDefault()}}function a(e){function t(t){for(n=0;l>n;n+=1)t(e[n].type,e[n].handler)}var n,r,i,l=e.length;return d.addEventListener?(r=function(e){i(e),t(function(t,n){e.addEventListener(t,n,!1)})},i=function(e){t(function(t,n){e.removeEventListener(t,n,!1)})}):d.attachEvent?(r=function(e){i(e),t(function(t,n){e.attachEvent("on"+t,n)})},i=function(e){t(function(t,n){e.detachEvent("on"+t,n)})}):r=i=function(){},{add:r,remove:i}}function s(e,t){var n,r=b.length;for(n=0;r>n;n+=1)b[n](e,t)}var c,u,f,d=window.document,h="	",v=9,g=9,p=[],m=["shiftKey"],y=!0,E=!1,x=d.createElement("textarea"),b=[];c=a([{type:"keydown",handler:l},{type:"keypress",handler:o}]),e.utils={isValidModifierKeyCombo:t,createListeners:a,addListeners:c.add,removeListeners:c.remove},e.handlers={keydown:l,keypress:o},e.addExtension=function(e){return"function"==typeof e&&b.push(e),this},e.set=function(e,t){var n,r,i,l,o,a,u;if(e)for(n=2>arguments.length||t,r=e,i=r.length,"number"!=typeof i&&(r=[r],i=1),n?(l=c.add,o="true"):(l=c.remove,o=""),a=0;i>a;a+=1)u=r[a],u&&u.nodeName&&"textarea"===u.nodeName.toLowerCase()&&(s(u,n),u.setAttribute("data-taboverride-enabled",o),l(u));return this},e.tabSize=function(e){var t;if(arguments.length){if(e){if("number"==typeof e&&e>0)for(h="",t=0;e>t;t+=1)h+=" "}else h="	";return this}return"	"===h?0:h.length},e.autoIndent=function(e){return arguments.length?(y=e?!0:!1,this):y},e.tabKey=i(function(e){return arguments.length?(v=e,void 0):v},p),e.untabKey=i(function(e){return arguments.length?(g=e,void 0):g},m),x.value="\n",u=x.value,f=u.length,x=null});
+//@ sourceMappingURL=taboverride.min.js.map
\ No newline at end of file
diff --git a/src/main/webapp/static/js/jquery/taboverride/taboverride.min.js.map b/src/main/webapp/static/js/jquery/taboverride/taboverride.min.js.map
new file mode 100755
index 0000000000000000000000000000000000000000..60d76b3827ab6f54837e3f6934f48149d9829c35
--- /dev/null
+++ b/src/main/webapp/static/js/jquery/taboverride/taboverride.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["taboverride.js"],"names":["factory","mod","exports","define","amd","window","tabOverride","isValidModifierKeyCombo","modifierKeys","e","i","j","currModifierKey","modifierKeyNames","numModKeys","length","isValid","tabKeyComboPressed","keyCode","tabKey","tabModifierKeys","untabKeyComboPressed","untabKey","untabModifierKeys","createKeyComboFunction","keyFunc","keyCombo","arguments","push","this","slice","overrideKeyDown","event","tab","tabLen","text","range","tempRange","preNewlines","selNewlines","initScrollTop","selStart","selEnd","sel","startLine","endLine","numTabs","startTab","preTab","whitespace","whitespaceLen","target","currentTarget","srcElement","key","CHARACTER","nodeName","toLowerCase","autoIndent","inWhitespace","value","scrollTop","selectionStart","selectionEnd","document","selection","createRange","duplicate","moveToElementText","setEndPoint","newlineLen","split","newline","aTab","indexOf","charAt","lastIndexOf","replace","collapse","moveEnd","moveStart","select","RegExp","move","match","preventDefault","returnValue","overrideKeyPress","executeExtensions","hook","args","extensions","hooks","len","apply","createListeners","handlerList","loop","func","type","handler","remove","add","addEventListener","elem","removeEventListener","attachEvent","detachEvent","addListeners","listeners","removeListeners","textareaElem","createElement","utils","handlers","keydown","keypress","addExtension","set","elems","enable","enableFlag","elemsArr","numElems","setListeners","attrValue","setAttribute","tabSize","size"],"mappings":";;CAaC,SAAUA,GACP,YAEA,IAAIC,EAEmB,iBAAZC,SAEPF,EAAQE,SACiB,kBAAXC,SAAyBA,OAAOC,IAG9CD,QAAQ,WAAYH,IAGpBC,EAAMI,OAAOC,eACbN,EAAQC,KAEd,SAAUK,GACR,YAgCA,SAASC,GAAwBC,EAAcC,GAC3C,GAEIC,GACAC,EACAC,EAJAC,GAAoB,MAAO,OAAQ,OAAQ,SAC3CC,EAAaN,EAAaO,OAI1BC,GAAU,CAGd,KAAKN,EAAI,EAAOI,EAAJJ,EAAgBA,GAAK,EAC7B,IAAKD,EAAED,EAAaE,IAAK,CACrBM,GAAU,CACV,OAKR,GAAIA,EACA,IAAKN,EAAI,EAAGA,EAAIG,EAAiBE,OAAQL,GAAK,EAAG,CAI7C,GAHAE,EAAkBC,EAAiBH,GAAK,MAGpCD,EAAEG,GAGF,GAAIE,GAIA,IAHAE,GAAU,EAGLL,EAAI,EAAOG,EAAJH,EAAgBA,GAAK,EAC7B,GAAIC,IAAoBJ,EAAaG,GAAI,CACrCK,GAAU,CACV,YAKRA,IAAU,CAKlB,KAAKA,EACD,MAKZ,MAAOA,GAYX,QAASC,GAAmBC,EAAST,GACjC,MAAOS,KAAYC,GAAUZ,EAAwBa,EAAiBX,GAY1E,QAASY,GAAqBH,EAAST,GACnC,MAAOS,KAAYI,GAAYf,EAAwBgB,EAAmBd,GAa9E,QAASe,GAAuBC,EAASjB,GACrC,MAAO,UAAUU,EAASL,GACtB,GAAIH,GACAgB,EAAW,EAEf,IAAIC,UAAUZ,OAAQ,CAClB,GAAuB,gBAAZG,KACPO,EAAQP,GAERV,EAAaO,OAAS,EAElBF,GAAoBA,EAAiBE,QACrC,IAAKL,EAAI,EAAGA,EAAIG,EAAiBE,OAAQL,GAAK,EAC1CF,EAAaoB,KAAKf,EAAiBH,GAAK,MAKpD,OAAOmB,MAGX,IAAKnB,EAAI,EAAGA,EAAIF,EAAaO,OAAQL,GAAK,EACtCgB,GAAYlB,EAAaE,GAAGoB,MAAM,EAAG,IAAM,GAG/C,OAAOJ,GAAWD,KAY1B,QAASM,GAAgBtB,GACrBA,EAAIA,GAAKuB,KAMT,IAEIC,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAnBAC,EAAS1C,EAAE2C,eAAiB3C,EAAE4C,WAC9BC,EAAM7C,EAAES,QAmBRqC,EAAY,WAGhB,MAAKJ,EAAOK,UAA8C,aAAlCL,EAAOK,SAASC,iBAC/BH,IAAQnC,GAAUmC,IAAQhC,GAAqB,KAARgC,GAAeI,GAD/D,CAgBA,GAVAC,GAAe,EACfxB,EAAOgB,EAAOS,MAMdpB,EAAgBW,EAAOU,UAGc,gBAA1BV,GAAOW,eACdrB,EAAWU,EAAOW,eAClBpB,EAASS,EAAOY,aAChBpB,EAAMR,EAAKL,MAAMW,EAAUC,OAExB,CAAA,IAAIsB,EAASC,UAoBhB,MAnBA7B,GAAQ4B,EAASC,UAAUC,cAC3BvB,EAAMP,EAAMD,KACZE,EAAYD,EAAM+B,YAClB9B,EAAU+B,kBAAkBjB,GAC5Bd,EAAUgC,YAAY,WAAYjC,GAClCM,EAASL,EAAUF,KAAKpB,OACxB0B,EAAWC,EAASC,EAAI5B,OAMpBuD,EAAa,GACbhC,EAAcH,EAAKL,MAAM,EAAGW,GAAU8B,MAAMC,GAASzD,OAAS,EAC9DwB,EAAcI,EAAI4B,MAAMC,GAASzD,OAAS,GAE1CuB,EAAcC,EAAc,EAOpC,GAAIe,IAAQnC,GAAUmC,IAAQhC,EAU1B,GAPAW,EAAMwC,EACNvC,EAASD,EAAIlB,OACb+B,EAAU,EACVC,EAAW,EACXC,EAAS,EAGLP,IAAaC,GAAgC,KAAtBC,EAAI+B,QAAQ,MAoCnC,GA9BI9B,EAFa,IAAbH,GAAgD,OAA9BN,EAAKwC,OAAOlC,EAAW,GAE7BA,EASAN,EAAKyC,YAAY,KAAMnC,EAAW,GAAK,EAInDC,IAAWP,EAAKpB,QAAkC,OAAxBoB,EAAKwC,OAAOjC,GAEtCG,EAAUH,EACyB,OAA5BP,EAAKwC,OAAOjC,EAAS,GAG5BG,EAAUH,EAAS,GAInBG,EAAUV,EAAKuC,QAAQ,KAAMhC,GACb,KAAZG,IACAA,EAAUV,EAAKpB,SAKnBE,EAAmBqC,EAAK7C,GAExBqC,EAAU,EAGVK,EAAOS,MAAQzB,EAAKL,MAAM,EAAGc,GAAaX,EACtCE,EAAKL,MAAMc,EAAWC,GAASgC,QAAQ,MAAO,WAE1C,MADA/B,IAAW,EACJ,KAAOb,IACbE,EAAKL,MAAMe,GAGhBT,GACAA,EAAM0C,WACN1C,EAAM2C,QAAQxB,EAAWb,EAAUI,EAAUZ,EAAUK,EAAcD,GACrEF,EAAM4C,UAAUzB,EAAWd,EAAWP,EAASI,GAC/CF,EAAM6C,WAGN9B,EAAOW,eAAiBrB,EAAWP,EAEnCiB,EAAOY,aAAerB,EAAUI,EAAUZ,EAC1CiB,EAAOU,UAAYrB,OAEpB,CAAA,IAAInB,EAAqBiC,EAAK7C,GAmCjC,MAhC2C,KAAvC0B,EAAKL,MAAMc,GAAW8B,QAAQzC,KAE1BW,IAAcH,EAEdE,EAAMA,EAAIb,MAAMI,GAGhBc,EAASd,EAEba,EAAWb,GAGfiB,EAAOS,MAAQzB,EAAKL,MAAM,EAAGc,GAAaT,EAAKL,MAAMc,EAAYI,EAAQP,GACrEE,EAAIkC,QAAQ,GAAIK,QAAO,KAAOjD,EAAK,KAAM,WAErC,MADAa,IAAW,EACJ,OACNX,EAAKL,MAAMY,GAGhBN,GAEAA,EAAM0C,WACN1C,EAAM2C,QAAQxB,EAAWb,EAASK,EAAYD,EAAUZ,EAAUK,EAAcD,GAChFF,EAAM4C,UAAUzB,EAAWd,EAAWO,EAASV,GAC/CF,EAAM6C,WAGN9B,EAAOW,eAAiBrB,EAAWO,EAEnCG,EAAOY,aAAerB,EAASK,EAAYD,EAAUZ,OAS7D,IAAIjB,EAAmBqC,EAAK7C,GACpB2B,GACAA,EAAMD,KAAOF,EACbG,EAAM6C,WAEN9B,EAAOS,MAAQzB,EAAKL,MAAM,EAAGW,GAAYR,EAAME,EAAKL,MAAMY,GAC1DS,EAAOY,aAAeZ,EAAOW,eAAiBrB,EAAWP,EACzDiB,EAAOU,UAAYrB,OAEpB,CAAA,IAAInB,EAAqBiC,EAAK7C,GAkBjC,MAdmD,KAA/C0B,EAAKL,MAAMW,EAAWP,GAAQwC,QAAQzC,KACtCkB,EAAOS,MAAQzB,EAAKL,MAAM,EAAGW,EAAWP,GAAUC,EAAKL,MAAMW,GAGzDL,GAEAA,EAAM+C,KAAK5B,EAAWd,EAAWP,EAASI,GAC1CF,EAAM6C,WAEN9B,EAAOY,aAAeZ,EAAOW,eAAiBrB,EAAWP,EACzDiB,EAAOU,UAAYrB,QAOhC,IAAIkB,EAAY,CAInB,GAAiB,IAAbjB,GAAgD,OAA9BN,EAAKwC,OAAOlC,EAAW,GAIzC,YADAkB,GAAe,EAqBnB,IAhBAf,EAAYT,EAAKyC,YAAY,KAAMnC,EAAW,GAAK,EAGnDI,EAAUV,EAAKuC,QAAQ,KAAMjC,GAGb,KAAZI,IACAA,EAAUV,EAAKpB,QAInBkC,EAAad,EAAKL,MAAMc,EAAWC,GAASuC,MAAM,WAAW,GAC7DlC,EAAgBD,EAAWlC,OAIZ6B,EAAYM,EAAvBT,EAEA,YADAkB,GAAe,EAIfvB,IAEAA,EAAMD,KAAO,KAAOc,EACpBb,EAAM6C,WAGN9B,EAAOS,MAAQzB,EAAKL,MAAM,EAAGW,GAAY,KAAOQ,EAAad,EAAKL,MAAMY,GAGxES,EAAOY,aAAeZ,EAAOW,eAAiBrB,EAAW6B,EAAapB,EACtEC,EAAOU,UAAYrB,GAI3B,MAAI/B,GAAE4E,mBACF5E,GAAE4E,kBAEF5E,EAAE6E,aAAc,GACT,IAcf,QAASC,GAAiB9E,GACtBA,EAAIA,GAAKuB,KAET,IAAIsB,GAAM7C,EAAES,OAEZ,IAAID,EAAmBqC,EAAK7C,IAAMY,EAAqBiC,EAAK7C,IAC3C,KAAR6C,GAAcI,IAAeC,EAAe,CAEjD,IAAIlD,EAAE4E,eAIF,MADA5E,GAAE6E,aAAc,GACT,CAHP7E,GAAE4E,kBAgBd,QAASG,GAAkBC,EAAMC,GAC7B,GAAIhF,GACAiF,EAAaC,EAAMH,OACnBI,EAAMF,EAAW5E,MAErB,KAAKL,EAAI,EAAOmF,EAAJnF,EAASA,GAAK,EACtBiF,EAAWjF,GAAGoF,MAAM,KAAMJ,GA6BlC,QAASK,GAAgBC,GAMrB,QAASC,GAAKC,GACV,IAAKxF,EAAI,EAAOmF,EAAJnF,EAASA,GAAK,EACtBwF,EAAKF,EAAYtF,GAAGyF,KAAMH,EAAYtF,GAAG0F,SAPjD,GAAI1F,GAEA2F,EACAC,EAFAT,EAAMG,EAAYjF,MAwCtB,OA7BIiD,GAASuC,kBACTF,EAAS,SAAUG,GACfP,EAAK,SAAUE,EAAMC,GACjBI,EAAKC,oBAAoBN,EAAMC,GAAS,MAGhDE,EAAM,SAAUE,GAGZH,EAAOG,GACPP,EAAK,SAAUE,EAAMC,GACjBI,EAAKD,iBAAiBJ,EAAMC,GAAS,OAGtCpC,EAAS0C,cAEhBL,EAAS,SAAUG,GACfP,EAAK,SAAUE,EAAMC,GACjBI,EAAKG,YAAY,KAAOR,EAAMC,MAGtCE,EAAM,SAAUE,GACZH,EAAOG,GACPP,EAAK,SAAUE,EAAMC,GACjBI,EAAKE,YAAY,KAAOP,EAAMC,QAMtCE,IAAKA,EACLD,OAAQA,GAchB,QAASO,GAAaJ,GAClBhB,EAAkB,gBAAiBgB,IACnCK,EAAUP,IAAIE,GAalB,QAASM,GAAgBN,GACrBhB,EAAkB,mBAAoBgB,IACtCK,EAAUR,OAAOG,GApjBrB,GACIK,GASArC,EACAF,EAXAN,EAAW3D,OAAO2D,SAElBS,EAAO,IACPtD,EAAS,EACTG,EAAW,EACXF,KACAG,GAAqB,YACrBmC,GAAa,EACbC,GAAe,EACfoD,EAAe/C,EAASgD,cAAc,YAGtCpB,IA8iBJiB,GAAYd,IACNI,KAAM,UAAWC,QAASrE,IAC1BoE,KAAM,WAAYC,QAASb,KAIjCwB,EAAanD,MAAQ,KACrBY,EAAUuC,EAAanD,MACvBU,EAAaE,EAAQzD,OACrBgG,EAAe,KAUfzG,EAAY2G,OACRzB,kBAAmBA,EACnBjF,wBAAyBA,EACzBwF,gBAAiBA,EACjBa,aAAcA,EACdE,gBAAiBA,GAQrBxG,EAAY4G,UACRC,QAASpF,EACTqF,SAAU7B,GAadjF,EAAY+G,aAAe,SAAU5B,EAAMS,GAQvC,MAPIT,IAAwB,gBAATA,IAAqC,kBAATS,KACtCN,EAAMH,KACPG,EAAMH,OAEVG,EAAMH,GAAM7D,KAAKsE,IAGdrE,MAgBXvB,EAAYgH,IAAM,SAAUC,EAAOC,GAC/B,GAAIC,GACAC,EACAC,EACAC,EACAC,EACAnH,EACA8F,CAEJ,IAAIe,EAqBA,IApBAE,EAAa9F,UAAUZ,OAAS,GAAKyG,EAIrCE,EAAWH,EACXI,EAAWD,EAAS3G,OAEI,gBAAb4G,KACPD,GAAYA,GACZC,EAAW,GAGXF,GACAG,EAAehB,EACfiB,EAAY,SAEZD,EAAed,EACfe,EAAY,IAGXnH,EAAI,EAAOiH,EAAJjH,EAAcA,GAAK,EAC3B8F,EAAOkB,EAAShH,GACZ8F,GAAQA,EAAKhD,UAA4C,aAAhCgD,EAAKhD,SAASC,gBACvC+B,EAAkB,OAAQgB,EAAMiB,IAChCjB,EAAKsB,aAAa,2BAA4BD,GAC9CD,EAAapB,GAKzB,OAAO3E,OAUXvB,EAAYyH,QAAU,SAAUC,GAC5B,GAAItH,EAEJ,IAAIiB,UAAUZ,OAAQ,CAClB,GAAIiH,GAAwB,gBAATA,IAAqBA,EAAO,EAE3C,IADAvD,EAAO,GACF/D,EAAI,EAAOsH,EAAJtH,EAAUA,GAAK,EACvB+D,GAAQ,QAIZA,GAAO,GAEX,OAAO5C,MAGX,MAAiB,MAAT4C,EAAiB,EAAIA,EAAK1D,QAWtCT,EAAYoD,WAAa,SAAU8D,GAC/B,MAAI7F,WAAUZ,QACV2C,EAAa8D,GAAS,GAAO,EACtB3F,MAGJ6B,GAcXpD,EAAYa,OAASK,EAAuB,SAAUN,GAClD,MAAKS,WAAUZ,YAGfI,EAASD,GAFEC,GAGZC,GAaHd,EAAYgB,SAAWE,EAAuB,SAAUN,GACpD,MAAKS,WAAUZ,YAGfO,EAAWJ,GAFAI,GAGZC","file":"taboverride.min.js"}
\ No newline at end of file
diff --git a/src/main/webapp/static/themes/compiletheme.sh b/src/main/webapp/static/themes/compiletheme.sh
index f5e2330e49215a6c082d7def16476e8ae0c11d12..49b74347aded64610781a2caba0c7fb38832585e 100755
--- a/src/main/webapp/static/themes/compiletheme.sh
+++ b/src/main/webapp/static/themes/compiletheme.sh
@@ -50,7 +50,7 @@ doCompile () {
 	UPDATE=$UPDATECMD
 	if [ $1 = "."  ];
 	then
-		TARGET="light"
+		TARGET="openolat"
 	if [[ "--watch" == $UPDATECMD && ! -z $THEMES ]]; then UPDATE="--update"; fi
 	fi
 	echo "Compiling SASS: $TARGET $STYLE"
diff --git a/src/main/webapp/static/themes/light/modules/_qti21.scss b/src/main/webapp/static/themes/light/modules/_qti21.scss
index acf88255f843db3d9922e4b1155cc912d07e31ae..8b5b45f9763d071e94713df40b721e7b46710647 100644
--- a/src/main/webapp/static/themes/light/modules/_qti21.scss
+++ b/src/main/webapp/static/themes/light/modules/_qti21.scss
@@ -103,7 +103,7 @@ ul.sessionControl {
 	}
 }
 
-.o_gap_container_help, .o_items_container_help {
+.o_item_container_help, .o_items_container_help {
 	font-size: 90%;
 	font-style: italic;
 	color: $gray-light;
@@ -212,6 +212,7 @@ img.o_hotspot_responsive[usemap] {
 	textarea {
 		/* fix missing resize handle in Safe Exam Browser */
 		resize: vertical !important;
+		font-family: $font-family-monospace;
 	}
 	
 	.o_qti_essay_last_save {
@@ -222,6 +223,11 @@ img.o_hotspot_responsive[usemap] {
 	}
 }
 
+.o_qti_items .extendedTextInteraction {
+	font-family: $font-family-monospace;
+}
+
+
 #o_qti_run_title {
 	 margin: 0 15px 0.5em 15px;
 	 h3 {
@@ -1044,10 +1050,15 @@ tr.choiceinteraction {
 		font-size: 110%;
 		font-weight: bold;
 		color: $text-muted;
-		margin-bottom: $padding-small-horizontal;
+		margin-bottom: 0;
 		border-bottom: 0;
 	}
 	
+	div.o_item_container_help {
+		margin: 0;
+		padding: 0;
+	}
+	
 	textarea {
 		display: block;
 		color: $text-muted;
diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
index ae6db89764852d4a9341540027c0a8ad33e3d427..5904d1e466ee480f3bb3966645ef4770adaf409f 100644
--- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
+++ b/src/test/java/org/olat/core/commons/services/webdav/WebDAVCommandsTest.java
@@ -672,8 +672,8 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 				.path("_other").path("WebDAV%20course").path("_courseelementdata").build();
 		String publicElementXml = conn.propfind(courseElementUri, 2);
 		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Folder%20for%20all/</D:href>"));
-		Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only%20%2890600786058954%29/Readonly%20students/</D:href>"));
-		Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students%20%2890600786058958%29/Not%20for%20students/</D:href>"));
+		Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only/Readonly%20students/</D:href>"));
+		Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students/Not%20for%20students/</D:href>"));
 
 		conn.close();
 	}
@@ -704,8 +704,8 @@ public class WebDAVCommandsTest extends WebDAVTestCase {
 		String publicElementXml = conn.propfind(courseElementUri, 2);
 		//can access all 3 course nodes
 		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Folder%20for%20all/</D:href>"));
-		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only%20%2890600786058954%29/Readonly%20students/</D:href>"));
-		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students%20%2890600786058958%29/Not%20for%20students/</D:href>"));
+		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only/Readonly%20students/</D:href>"));
+		Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students/Not%20for%20students/</D:href>"));
 
 		conn.close();
 	}
diff --git a/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java b/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java
deleted file mode 100644
index d8aceea1a6b16f6f8c6710dea0086755b46a5cd3..0000000000000000000000000000000000000000
--- a/src/test/java/org/olat/core/commons/services/webdav/WebDAVExternalTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * <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.core.commons.services.webdav;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.util.EntityUtils;
-import org.junit.Test;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * This is not a real Unit Test. I use it
- * to debug some issues with a Java client
- * on external servers.
- * 
- * 
- * Initial date: 06.05.2014<br>
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- *
- */
-public class WebDAVExternalTest {
-	
-	@Test
-	public void test() 
-	throws IOException, URISyntaxException {
-		
-		WebDAVConnection conn = new WebDAVConnection("http", "kivik.frentix.com", 443);
-		conn.setCredentials("kanu", "kanu01");
-		
-		URI publicUri = conn.getBaseURI().path("webdav").path("coursefolders").path("Info").path("TP_learningmap").build();
-		String response = conn.propfind(publicUri, 1);
-		
-		URI mapUri = conn.getBaseURI().path("webdav").path("coursefolders").path("Info").path("TP_learningmap").path("mapstyles.css").build();
-		HttpGet getMap = conn.createGet(mapUri);
-		
-		HttpResponse mapResonse = conn.execute(getMap);
-		String map = EntityUtils.toString(mapResonse.getEntity());
-		System.out.println(map);
-
-		IOUtils.closeQuietly(conn);
-		parse(response);
-	}
-
-	private void parse(String response) {
-		try {
-			SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
-			InputSource in = new InputSource(new StringReader(response));
-			saxParser.parse(in, new WebDAVHandler());
-		} catch (ParserConfigurationException | SAXException | IOException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	public static class WebDAVHandler extends DefaultHandler {
-		private StringBuilder sb;
-
-		@Override
-		public void startElement(String uri, String localName, String qName, Attributes attributes)
-		throws SAXException {
-			if("D:href".equals(qName)) {
-				sb = new StringBuilder();
-			}
-		}
-
-		@Override
-		public void characters(char[] ch, int start, int length)
-		throws SAXException {
-			if(sb != null) {
-				sb.append(ch, start, length);
-			}
-		}
-
-		@Override
-		public void endElement(String uri, String localName, String qName)
-		throws SAXException {
-			if(sb != null) {
-				System.out.println(sb.toString());
-				sb = null;
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/org/olat/core/util/IPUtilsTest.java b/src/test/java/org/olat/core/util/IPUtilsTest.java
index 009111b17e997424a69ca949c7aca72a8c32c981..a74529da95987afaa1309d173e823fcc44eb36dd 100644
--- a/src/test/java/org/olat/core/util/IPUtilsTest.java
+++ b/src/test/java/org/olat/core/util/IPUtilsTest.java
@@ -41,19 +41,4 @@ public class IPUtilsTest {
 		boolean  check2 = IPUtils.isValidRange(start, end, "192.168.5.45");
 		Assert.assertFalse(check2);
 	}
-
-	@Test
-	public void checkRange_mask_31() {
-		String ipWithMask = "192.168.100.1/24";
-		
-		boolean  allowed1 = IPUtils.isValidRange(ipWithMask, "192.168.100.1");
-		Assert.assertTrue(allowed1);
-
-		boolean  notAllowed1 = IPUtils.isValidRange(ipWithMask, "192.168.99.255");
-		Assert.assertFalse(notAllowed1);
-		boolean  notAllowed2 = IPUtils.isValidRange(ipWithMask, "192.168.101.1");
-		Assert.assertFalse(notAllowed2);
-		boolean  notAllowed3 = IPUtils.isValidRange(ipWithMask, "212.34.100.0");
-		Assert.assertFalse(notAllowed3);
-	}
 }
diff --git a/src/test/java/org/olat/core/util/IPUtilsValidRangeTest.java b/src/test/java/org/olat/core/util/IPUtilsValidRangeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..feb95e8a78b77568c5e8fb7e350047548962c016
--- /dev/null
+++ b/src/test/java/org/olat/core/util/IPUtilsValidRangeTest.java
@@ -0,0 +1,69 @@
+/**
+ * <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.core.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * 
+ * Initial date: 21 févr. 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@RunWith(Parameterized.class)
+public class IPUtilsValidRangeTest {
+	
+	@Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                { "192.168.100.1/24", "192.168.100.1", Boolean.TRUE },
+                { "192.168.100.1/24", "192.168.99.255", Boolean.FALSE },
+                { "192.168.100.1/24", "192.168.101.1", Boolean.FALSE },
+                { "192.168.100.1/24", "212.34.100.0", Boolean.FALSE },
+                { "192.168.100.1/24 ", "192.168.100.1", Boolean.TRUE },
+                { "172.20.36.0/24 ", "192.168.100.1", Boolean.FALSE },
+                { "192.168.1.0/24", "192.168.100.1", Boolean.FALSE },
+                { "192.168.1.0/24", "192.168.1.1", Boolean.TRUE }
+        });
+    }
+    
+    private String ip;
+    private String ipToCheck;
+    private Boolean result;
+    
+    public IPUtilsValidRangeTest(String ip, String ipToCheck, Boolean result) {
+    		this.ip = ip;
+    		this.ipToCheck = ipToCheck;
+    		this.result = result;
+    }
+	
+	@Test
+	public void checkRange() {
+		boolean  allowed = IPUtils.isValidRange(ip, ipToCheck);
+		Assert.assertEquals(result, Boolean.valueOf(allowed));
+	}
+}
diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
index aaeea9ae542f5bc26005a48f1e8d1a535a0bcd8d..7715cddbb501b4919de7c11b1f6db43db40ac74c 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
@@ -465,26 +465,29 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		BusinessGroup group1 = businessGroupDao.createAndPersist(null, marker.toUpperCase(), "fingbg-1-desc", 0, 5, true, false, true, false, false);
 		BusinessGroup group2 = businessGroupDao.createAndPersist(null, marker + "xxx", "fingbg-2-desc", 0, 5, true, false, true, false, false);
 		BusinessGroup group3 = businessGroupDao.createAndPersist(null, "yyy" + marker.toUpperCase(), "fingbg-3-desc", 0, 5, true, false, true, false, false);
+		BusinessGroup group4 = businessGroupDao.createAndPersist(null, "yyyyZZZxxx", "fingbg-3-desc", 0, 5, true, false, true, false, false);
 		dbInstance.commitAndCloseSession();
 
 		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
 		params.setName(marker);
 		List<BusinessGroup> groups = businessGroupDao.findBusinessGroups(params, null, 0, -1);
 		Assert.assertNotNull(groups);
-		Assert.assertEquals(2, groups.size() );
+		Assert.assertEquals(3, groups.size() );
 		Assert.assertTrue(groups.contains(group1));
 		Assert.assertTrue(groups.contains(group2));
-		Assert.assertFalse(groups.contains(group3));
+		Assert.assertTrue(groups.contains(group3));
+		Assert.assertFalse(groups.contains(group4));
 
 		//check the same with the views
 		BusinessGroupQueryParams searchParams = new BusinessGroupQueryParams();
 		searchParams.setName(marker);
 		List<BusinessGroupRow> groupViews = businessGroupDao.searchBusinessGroupsWithMemberships(searchParams, identity);
 		Assert.assertNotNull(groupViews);
-		Assert.assertEquals(2, groupViews.size() );
+		Assert.assertEquals(3, groupViews.size() );
 		Assert.assertTrue(contains(groupViews, group1));
 		Assert.assertTrue(contains(groupViews, group2));
-		Assert.assertFalse(contains(groupViews, group3));
+		Assert.assertTrue(contains(groupViews, group3));
+		Assert.assertFalse(contains(groupViews, group4));
 	}
 
 	@Test
@@ -522,7 +525,7 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("bg-search-4");
 		BusinessGroup group1 = businessGroupDao.createAndPersist(null, "fingbg-1", marker.toUpperCase() + "-desc", 0, 5, true, false, true, false, false);
 		BusinessGroup group2 = businessGroupDao.createAndPersist(null, "fingbg-2", "desc-" + marker, 0, 5, true, false, true, false, false);
-		BusinessGroup group3 = businessGroupDao.createAndPersist(null, "fingbg-3", "desc-" + marker + "-desc", 0, 5, true, false, true, false, false);
+		BusinessGroup group3 = businessGroupDao.createAndPersist(null, "fingbg-3", "desc-other-one", 0, 5, true, false, true, false, false);
 		dbInstance.commitAndCloseSession();
 
 		//check find business group
@@ -530,20 +533,19 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		params.setDescription(marker);
 		List<BusinessGroup> groups = businessGroupDao.findBusinessGroups(params, null, 0, -1);
 		Assert.assertNotNull(groups);
-		Assert.assertEquals(1, groups.size() );
+		Assert.assertEquals(2, groups.size() );
 		Assert.assertTrue(groups.contains(group1));
-		Assert.assertFalse(groups.contains(group2));
+		Assert.assertTrue(groups.contains(group2));
 		Assert.assertFalse(groups.contains(group3));
 
 		//check find business group
-
 		BusinessGroupQueryParams searchParams = new BusinessGroupQueryParams();
 		searchParams.setDescription(marker);
 		List<BusinessGroupRow> groupViews = businessGroupDao.searchBusinessGroupsWithMemberships(searchParams, identity);
 		Assert.assertNotNull(groupViews);
-		Assert.assertEquals(1, groupViews.size() );
+		Assert.assertEquals(2, groupViews.size() );
 		Assert.assertTrue(contains(groupViews, group1));
-		Assert.assertFalse(contains(groupViews, group2));
+		Assert.assertTrue(contains(groupViews, group2));
 		Assert.assertFalse(contains(groupViews, group3));
 	}
 
@@ -642,10 +644,12 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsUser(marker);
 		Identity id2 = JunitTestHelper.createAndPersistIdentityAsUser("ddao-2-" + marker);
 		Identity id3 = JunitTestHelper.createAndPersistIdentityAsUser(marker + "-ddao-3");
+		Identity id4 = JunitTestHelper.createAndPersistIdentityAsUser("something-else-ddao-4");
 
 		BusinessGroup group1 = businessGroupDao.createAndPersist(id1, "fingbgown-1", "fingbgown-1-desc", 0, 5, true, false, true, false, false);
 		BusinessGroup group2 = businessGroupDao.createAndPersist(id2, "fingbgown-2", "fingbgown-2-desc", 0, 5, true, false, true, false, false);
 		BusinessGroup group3 = businessGroupDao.createAndPersist(id3, "fingbgown-3", "fingbgown-3-desc", 0, 5, true, false, true, false, false);
+		BusinessGroup group4 = businessGroupDao.createAndPersist(id4, "fingbgown-4", "fingbgown-4-desc", 0, 5, true, false, true, false, false);
 		dbInstance.commitAndCloseSession();
 
 		//check the same with the views
@@ -653,10 +657,11 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		searchParams.setOwnerName(marker);
 		List<BusinessGroupRow> groupViews = businessGroupDao.searchBusinessGroupsWithMemberships(searchParams, id1);
 		Assert.assertNotNull(groupViews);
-		Assert.assertEquals(2, groupViews.size() );
+		Assert.assertEquals(3, groupViews.size() );
 		Assert.assertTrue(contains(groupViews, group1));
-		Assert.assertFalse(contains(groupViews, group2));
+		Assert.assertTrue(contains(groupViews, group2));
 		Assert.assertTrue(contains(groupViews, group3));
+		Assert.assertFalse(contains(groupViews, group4));
 	}
 
 	@Test
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 21ea2ff6f798a6749d2dafe5fdb23cdda1493293..2a6b13d97252fee36e709d29c2ca579d6d360ed6 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -69,6 +69,7 @@ import org.junit.runners.Suite;
 	org.olat.core.util.EncoderTest.class,
 	org.olat.core.util.SimpleHtmlParserTest.class,
 	org.olat.core.util.IPUtilsTest.class,
+	org.olat.core.util.IPUtilsValidRangeTest.class,
 	org.olat.core.util.mail.EmailAddressValidatorTest.class,
 	org.olat.core.util.mail.manager.MailManagerTest.class,
 	org.olat.core.util.openxml.OpenXmlWorkbookTest.class,