diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FormSubmit.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FormSubmit.java
index c39e191e8a8d0867aba5eda4c65c2618d37cc7bb..20d1677530d21aee11964aab9c7c53e9db207b25 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FormSubmit.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FormSubmit.java
@@ -29,6 +29,7 @@ import java.util.List;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.Window;
 import org.olat.core.gui.components.form.flexible.elements.Submit;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.logging.AssertException;
@@ -74,6 +75,10 @@ public class FormSubmit extends FormButton implements Submit{
 
 	@Override
 	public void evalFormRequest(UserRequest ureq) {
+		if(Window.NO_RESPONSE_VALUE_MARKER.equals(ureq.getParameter(Window.NO_RESPONSE_PARAMETER_MARKER))) {
+			return; // ignore background request
+		}
+
 		// no values with submit to be evaluated
 		getComponent().setDirty(true);
 	}
diff --git a/src/main/java/org/olat/core/gui/components/link/Link.java b/src/main/java/org/olat/core/gui/components/link/Link.java
index bdaf9802ba7f9aa1b26cef26c06acc4eb0d23a26..43beaa3137847a8b8d827b4f177ba390fd2cafb0 100644
--- a/src/main/java/org/olat/core/gui/components/link/Link.java
+++ b/src/main/java/org/olat/core/gui/components/link/Link.java
@@ -649,6 +649,21 @@ public class Link extends AbstractComponent {
 		active = isActive;
 		setDirty(true);
 	}
-
 	
+	@Override
+	public void setDirty(boolean dirty) {
+		super.setDirty(dirty);
+		if(flexiLink != null) {
+			// particularly important for by setDirty false
+			if(flexiLink.getExampleC() != null) {
+				flexiLink.getExampleC().setDirty(dirty);
+			}
+			if(flexiLink.getErrorC() != null) {
+				flexiLink.getErrorC().setDirty(dirty);
+			}
+			if(flexiLink.getLabelC() != null) {
+				flexiLink.getLabelC().setDirty(dirty);
+			}
+		}
+	}	
 }
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 4ce7951905ea1422d527eea3191361bf737e3e17..b0f89d4492f7a8011fabd87f3a4d61ef920dea87 100644
--- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
@@ -2080,6 +2080,10 @@ public class AssessmentTestDisplayController extends BasicController implements
 						QTIWorksAssessmentTestEvent qwate = (QTIWorksAssessmentTestEvent)event;
 						if(qwate.getEvent() == QTIWorksAssessmentTestEvent.Event.tmpResponse) {
 							processTemporaryResponse(ureq);
+							return; // only save the response
+						} else if(qwate.getEvent() == QTIWorksAssessmentTestEvent.Event.mark) {
+							fireEvent(ureq, event);
+							return; // only toggle, don't update
 						} else {
 							fireEvent(ureq, event);
 						}
@@ -2098,7 +2102,8 @@ public class AssessmentTestDisplayController extends BasicController implements
 		
 		@Override
 		protected void propagateDirtinessToContainer(FormItem fiSrc, FormEvent fe) {
-			if(!"mark".equals(fe.getCommand()) && !"rubric".equals(fe.getCommand())) {
+			if(!"mark".equals(fe.getCommand()) && !"rubric".equals(fe.getCommand())
+					&& !"tmpResponse".equals(fe.getCommand())) {
 				super.propagateDirtinessToContainer(fiSrc, fe);
 			}
 		}
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 7843582890d9532c4510754ae194b003de6def72..6ef8117c99408ab4e7c1a8738a682c0040d2b8b4 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
@@ -22,13 +22,15 @@ package org.olat.ims.qti21.ui.components;
 import static org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.valueContains;
 
 import java.net.URI;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.velocity.context.Context;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.AbstractComponent;
 import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.control.JSAndCSSAdder;
 import org.olat.core.gui.render.ValidationResult;
 import org.olat.core.gui.render.velocity.VelocityComponent;
@@ -188,16 +190,30 @@ public abstract class AssessmentObjectComponent extends AbstractComponent implem
 		return (identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.SHOW_IF_MATCH)
 				|| (!identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.HIDE_IF_MATCH);
 	}
-	
 
 	@Override
 	public Component getComponent(String name) {
+		AssessmentObjectFormItem assessmentItem = getQtiItem();
+		if(assessmentItem != null) {
+			for(FormItem item:assessmentItem.getFormItems()) {
+				if(item.getComponent().getComponentName().equals(name)) {
+					return item.getComponent();
+				}
+			}
+		}
 		return null;
 	}
 
 	@Override
 	public Iterable<Component> getComponents() {
-		return Collections.emptyList();
+		List<Component> cmps = new ArrayList<>();
+		AssessmentObjectFormItem assessmentItem = getQtiItem();
+		if(assessmentItem != null) {
+			for(FormItem item:assessmentItem.getFormItems()) {
+				cmps.add(item.getComponent());
+			}
+		}
+		return cmps;
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectFormItem.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectFormItem.java
index b641581384c5f6ba1d095bd55c9c5ea53483f39c..c97c168b27d6690a58ecc4630841b0591cd3c269 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectFormItem.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectFormItem.java
@@ -23,6 +23,7 @@ import java.net.URI;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -63,11 +64,18 @@ public abstract class AssessmentObjectFormItem extends FormItemImpl implements F
 	
 	@Override
 	public Iterable<FormItem> getFormItems() {
-		return new ArrayList<>(components.values());
+		List<FormItem> items = new ArrayList<>(components.values());
+		if(submitButton != null) {
+			items.add(submitButton);
+		}
+		return items;
 	}
 
 	@Override
 	public FormItem getFormComponent(String name) {
+		if(submitButton != null && submitButton.getName().equals(name)) {
+			return submitButton;
+		}
 		return components.get(name);
 	}
 	
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponent.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponent.java
index 5dbb56207b0a45e28fd182dc1a312cb01d144863..22a0b033a5cdffd54c764bc566a53c431606478b 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponent.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponent.java
@@ -75,6 +75,7 @@ public class AssessmentTestComponent extends AssessmentObjectComponent  {
 		this.qtiItem = qtiItem;
 	}
 
+	@Override
 	public AssessmentTestFormItem getQtiItem() {
 		return qtiItem;
 	}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestFormItem.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestFormItem.java
index 7a4ac1505180101feddd850d0d94bd153b0896ca..de7b995760db73b039bc0111526f44c0cb38fdc3 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestFormItem.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestFormItem.java
@@ -242,7 +242,10 @@ public class AssessmentTestFormItem extends AssessmentObjectFormItem {
 			} 
 			if(event != null) {
 				getRootForm().fireFormEvent(ureq, event);
-				component.setDirty(true);
+				if(event.getEvent() != QTIWorksAssessmentTestEvent.Event.tmpResponse
+						&& event.getEvent() != QTIWorksAssessmentTestEvent.Event.mark) {
+					component.setDirty(true);
+				}
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTreeComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTreeComponentRenderer.java
index 0d87fc1abb640648f198f5d0f136f234a5da8f08..8e28e36f0a5a539f5a3d985c91914fa1dc8620bd 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTreeComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTreeComponentRenderer.java
@@ -21,6 +21,7 @@ package org.olat.ims.qti21.ui.components;
 
 import org.apache.logging.log4j.Logger;
 import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.Window;
 import org.olat.core.gui.components.form.flexible.impl.Form;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
 import org.olat.core.gui.components.form.flexible.impl.NameValuePair;
@@ -245,10 +246,14 @@ public class AssessmentTreeComponentRenderer extends AssessmentObjectComponentRe
 		
 		sb.append("<a href='javascript:;' onclick=\"")
 		  .append(FormJSHelper.getXHRNFFnCallFor(form, dispatchId, 1,
-				new NameValuePair("cid", Event.mark.name()), new NameValuePair("item", key)))
+				new NameValuePair("cid", Event.mark.name()),
+				new NameValuePair("item", key),
+				new NameValuePair(Window.NO_RESPONSE_PARAMETER_MARKER, Window.NO_RESPONSE_VALUE_MARKER)))
 		  .append("; o_toggleMark(this); return false;\" onkeydown=\"if(event.which == 13 || event.keyCode == 13) {")
 		  .append(FormJSHelper.getXHRNFFnCallFor(form, dispatchId, 1,
-					new NameValuePair("cid", Event.mark.name()), new NameValuePair("item", key)))
+					new NameValuePair("cid", Event.mark.name()),
+					new NameValuePair("item", key),
+					new NameValuePair(Window.NO_RESPONSE_PARAMETER_MARKER, Window.NO_RESPONSE_VALUE_MARKER)))
 		  .append("; o_toggleMark(this); return false; }\" ")
 		  .append(" class='o_assessmentitem_marks'><i class='o_icon ")
 		  .append("o_icon_bookmark", "o_icon_bookmark_add", mark)
diff --git a/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java b/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java
index 5e4568737abe06b17f59cf557ec71ebfcc48a7b3..81f91b36bf14201c5ca3b19ac785f646fe18f1bd 100644
--- a/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java
+++ b/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java
@@ -37,6 +37,7 @@ import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.components.link.LinkFactory;
 import org.olat.core.gui.components.panel.Panel;
 import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.control.ChiefController;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
@@ -161,9 +162,6 @@ public class InstantMessagingMainController extends BasicController implements G
 		putInitialPanel(main);
 	}
 
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
-	 */
 	@Override
 	protected void doDispose() {
 		imService.unlistenChat(getIdentity(), getPrivatListenToResourceable(), this);
@@ -244,12 +242,22 @@ public class InstantMessagingMainController extends BasicController implements G
 	}
 	
 	private void updateBuddyStats() {
-		if(onlineOfflineCount != null) {
+		if(allowToUpdateBuddyStats()) {
 			BuddyStats stats = imService.getBuddyStats(getIdentity());
 			onlineOfflineCount.setCustomDisplayText(translate("im.roster.launch", new String[]{stats.getOnlineBuddies() + "", stats.getOfflineBuddies() + ""}));
 		}
 	}
 	
+	private boolean allowToUpdateBuddyStats() {
+		if(onlineOfflineCount == null) {
+			return false;
+		}
+		ChiefController chiefController = getWindowControl().getWindowBackOffice().getChiefController();
+		return (chiefController != null &&
+				(chiefController.getScreenMode() == null
+				|| !(chiefController.getScreenMode().isFullScreen() || chiefController.getScreenMode().isWishFullScreen())));
+	}
+	
 	private void loadNotifications() {
 		List<InstantMessageNotification> notifications = imService.getNotifications(getIdentity());
 		for(InstantMessageNotification notification:notifications) {
diff --git a/src/main/webapp/static/empty.html b/src/main/webapp/static/empty.html
index 42682b4746225a1fa7df6f272925245827119f42..04e79ac70a634b18b867f0405758ec088922f6d9 100644
--- a/src/main/webapp/static/empty.html
+++ b/src/main/webapp/static/empty.html
@@ -1 +1,2 @@
+<!DOCTYPE html>
 <html><body></body></html>
\ No newline at end of file
diff --git a/src/main/webapp/static/js/jquery/qti/jquery.qtiAutosave.js b/src/main/webapp/static/js/jquery/qti/jquery.qtiAutosave.js
index a86280594c14cecad373b268faeffa5f6ad5f567..9bec4353339fb59bd24d3e9a77b70b580fc235a7 100644
--- a/src/main/webapp/static/js/jquery/qti/jquery.qtiAutosave.js
+++ b/src/main/webapp/static/js/jquery/qti/jquery.qtiAutosave.js
@@ -22,6 +22,7 @@
 	    			data['tmpResponse'] =  'qtiworks_presented_' + settings.responseUniqueId;
 	    			data['qtiworks_presented_' + settings.responseUniqueId] = '1';
 	    			data['qtiworks_response_' + settings.responseUniqueId] = jQuery('#oo_' + settings.responseUniqueId).val();
+	    			data['no-response'] = 'oo-no-response';
 
 	    			var targetUrl = jQuery('#' + settings.formName).attr("action");
 	    			jQuery.ajax(targetUrl,{