diff --git a/src/main/java/org/olat/core/commons/controllers/resume/ResumeController.java b/src/main/java/org/olat/core/commons/controllers/resume/ResumeController.java
index ffe200243a8b6f2f584a626c36a4f4a3b5f254be..3bcb5423e38a86a68bea830231068115eacd146a 100644
--- a/src/main/java/org/olat/core/commons/controllers/resume/ResumeController.java
+++ b/src/main/java/org/olat/core/commons/controllers/resume/ResumeController.java
@@ -20,6 +20,8 @@
  */
 package org.olat.core.commons.controllers.resume;
 
+import java.util.List;
+
 import org.olat.NewControllerFactory;
 import org.olat.admin.landingpages.LandingPagesModule;
 import org.olat.admin.landingpages.model.Rules;
@@ -39,6 +41,7 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.context.BusinessControl;
 import org.olat.core.id.context.BusinessControlFactory;
+import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.HistoryManager;
 import org.olat.core.id.context.HistoryModule;
 import org.olat.core.id.context.HistoryPoint;
@@ -120,7 +123,8 @@ public class ResumeController extends FormBasicController implements SupportsAft
 			} else if ("auto".equals(resumePrefs)) {
 				HistoryPoint historyEntry = HistoryManager.getInstance().readHistoryPoint(ureq.getIdentity());
 				if(historyEntry != null && StringHelper.containsNonWhitespace(historyEntry.getBusinessPath())) {
-					BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(historyEntry.getEntries());
+					List<ContextEntry> cloneCes = BusinessControlFactory.getInstance().cloneContextEntries(historyEntry.getEntries());
+					BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(cloneCes);
 					launch(ureq, bc);
 				} else {
 					String bc = getLandingBC(ureq);
@@ -179,7 +183,8 @@ public class ResumeController extends FormBasicController implements SupportsAft
 		
 		HistoryPoint historyEntry = historyManager.readHistoryPoint(ureq.getIdentity());
 		if(historyEntry != null && StringHelper.containsNonWhitespace(historyEntry.getBusinessPath())) {
-			BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(historyEntry.getEntries());
+			List<ContextEntry> cloneCes = BusinessControlFactory.getInstance().cloneContextEntries(historyEntry.getEntries());
+			BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(cloneCes);
 			WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl());
 			try {
 				//make the resume secure. If something fail, don't generate a red screen
diff --git a/src/main/java/org/olat/core/commons/services/image/spi/ImageHelperImpl.java b/src/main/java/org/olat/core/commons/services/image/spi/ImageHelperImpl.java
index 80d34da4c078e24dc3b7e8cd50cfbab65c6cb063..08fbfbac79cbbcba75751d3708a3cec8aca3a0c7 100644
--- a/src/main/java/org/olat/core/commons/services/image/spi/ImageHelperImpl.java
+++ b/src/main/java/org/olat/core/commons/services/image/spi/ImageHelperImpl.java
@@ -247,6 +247,9 @@ public class ImageHelperImpl extends AbstractImageHelper {
 	 */
 	private ImageInputStream getInputStream(VFSLeaf leaf)
 	throws IOException {
+		if(leaf == null) {
+			return null;
+		}
 		if(leaf instanceof LocalFileImpl) {
 			LocalFileImpl file = (LocalFileImpl)leaf;
 			if(file.getBasefile() != null) {
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
index 6c39caea27a1e4d979ed857d3132ec730727703b..a369041080712df759a97d8f58e7b732a4ebfa19 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiTableElementImpl.java
@@ -394,7 +394,9 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 	public void setSortSettings(FlexiTableSortOptions options) {
 		this.sortOptions = options;
 		if(options.getDefaultOrderBy() != null) {
-			orderBy = new SortKey[]{ options.getDefaultOrderBy() };
+			SortKey defaultOrder = options.getDefaultOrderBy();
+			orderBy = new SortKey[]{ defaultOrder };
+			selectSortOption(defaultOrder.getKey(), defaultOrder.isAsc());
 		}
 	}
 
@@ -770,6 +772,11 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 			dataSource.load(null, conditionalQueries, 0, getPageSize(), orderBy);
 		}
 
+		selectSortOption(sortKey, asc);
+		component.setDirty(true);
+	}
+	
+	private void selectSortOption(String sortKey, boolean asc) {
 		if(sortOptions != null) {
 			for(FlexiTableSort sort:sortOptions.getSorts()) {
 				boolean selected = sort.getSortKey().getKey().equals(sortKey);
@@ -781,8 +788,6 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 				}
 			}
 		}
-
-		component.setDirty(true);
 	}
 	
 	private void doFilter(String filterKey) {
@@ -970,6 +975,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 					
 					if(sortKey != null) {
 						orderBy = new SortKey[]{ new SortKey(sortKey, tablePrefs.isSortDirection()) };
+						selectSortOption(sortKey, tablePrefs.isSortDirection());
 					}
 				}
 
diff --git a/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_de.properties
index ee28d32b19988ec234cf349d566bae00ddfee1f8..d75cdc3cbdd699ae4c6c7db8e76c6ae54fd33dad 100644
--- a/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_de.properties
@@ -21,7 +21,7 @@ encoding.same=Gleich wie Inhalt
 height.auto=Automatisch
 height.label=H\u00F6he Anzeigefl\u00E4che
 inherit.label=Standardwerte übernehmen
-inherit=Aus Lernressourcenverwaltung übernehmen
+inherit=Aus Layouteinstellungen der Lernressource \u00FCbernehmen
 custom=Anpassen
 glossary.need.jQuery=Glossar braucht jQuery
 automatic.need.js=Automatic braucht javascript
diff --git a/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_en.properties
index f7fc02748a7945bb1fead76b796f555b787675fb..c7faf0818746b42443eb2dff3cbdbc9a9422f6d0 100644
--- a/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/core/gui/control/generic/iframe/_i18n/LocalStrings_en.properties
@@ -21,7 +21,7 @@ automatic.need.js=Automatic needs javascript
 height.auto=Automatic
 height.label=Display height
 iframe.content=Page content within iframe
-inherit=Use from learning resource configuration
+inherit=Use from learning resource layout configuration
 inherit.label=Use standard configuration
 mode=Display mode
 mode.configured=Optimized for OpenOLAT
diff --git a/src/main/java/org/olat/core/id/context/BusinessControlFactory.java b/src/main/java/org/olat/core/id/context/BusinessControlFactory.java
index dd21774de3e57b1fa8d1670031f1e240a6915f2e..1d9129cc1ab5186139059263b42f68e753162723 100644
--- a/src/main/java/org/olat/core/id/context/BusinessControlFactory.java
+++ b/src/main/java/org/olat/core/id/context/BusinessControlFactory.java
@@ -271,7 +271,15 @@ public class BusinessControlFactory {
 		return createFromContextEntries(ces);
 	}
 
-	//fxdiff BAKS-7 Resume function
+	public List<ContextEntry> cloneContextEntries(final List<ContextEntry> ces) {
+		final List<ContextEntry> clones = new ArrayList<ContextEntry>(ces.size());
+		for(ContextEntry ce:ces) {
+			OLATResourceable clone = OresHelper.clone(ce.getOLATResourceable());
+			clones.add(new MyContextEntry(clone));
+		}
+		return clones;
+	}
+
 	public BusinessControl createFromContextEntries(final List<ContextEntry> ces) {
 		ContextEntry rootEntry = null;
 		if (ces.isEmpty() || ((rootEntry = ces.get(0))==null)) {
diff --git a/src/main/java/org/olat/course/nodes/feed/FeedPeekviewController.java b/src/main/java/org/olat/course/nodes/feed/FeedPeekviewController.java
index ff2a06bf3274206d40f4dae7448ae3d33e463c98..6291886ded82435f774b1af70d5ff70e6d5a115e 100644
--- a/src/main/java/org/olat/course/nodes/feed/FeedPeekviewController.java
+++ b/src/main/java/org/olat/course/nodes/feed/FeedPeekviewController.java
@@ -22,7 +22,6 @@ package org.olat.course.nodes.feed;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.htmlsite.OlatCmdEvent;
@@ -43,6 +42,7 @@ import org.olat.modules.webFeed.models.Item;
 import org.olat.modules.webFeed.ui.FeedUIFactory;
 import org.olat.resource.OLATResource;
 import org.olat.user.UserManager;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * <h3>Description:</h3> The feed peekview controller displays the configurable
@@ -60,6 +60,11 @@ import org.olat.user.UserManager;
 public class FeedPeekviewController extends BasicController implements Controller {
 	// the current course node id
 	private final String nodeId;
+	
+	@Autowired
+	private FeedManager feedManager;
+	@Autowired
+	private UserManager userManager;
 
 	/**
 	 * Constructor for the feed peekview controller
@@ -79,43 +84,46 @@ public class FeedPeekviewController extends BasicController implements Controlle
 			Long courseId, String nodeId, FeedUIFactory feedUIFactory, int itemsToDisplay, String wrapperCssClass) {
 		super(ureq, wControl);
 		this.nodeId = nodeId;
-		FeedManager feedManager = FeedManager.getInstance();
 		Feed feed = feedManager.getFeed(olatResource);
-		UserManager userManager = CoreSpringFactory.getImpl(UserManager.class);
 
 		VelocityContainer peekviewVC = createVelocityContainer("peekview");
-		peekviewVC.contextPut("wrapperCssClass", wrapperCssClass != null ? wrapperCssClass : "");
-		// add gui helper
-		String authorFullname = userManager.getUserDisplayName(feed.getAuthor());
-		FeedViewHelper helper = new FeedViewHelper(feed, getIdentity(), authorFullname, getTranslator(), courseId, nodeId, callback);
-		peekviewVC.contextPut("helper", helper);
-		// add items, only as many as configured
-		List<Item> allItems = feed.getFilteredItems(callback, getIdentity());
-		List<Item> items = new ArrayList<Item>();
-		for (int i = 0; i < allItems.size(); i++) {
-			if (items.size() == itemsToDisplay) {
-				break;
-			}
-			// add item itself if published
-			Item item = allItems.get(i);
-			if (item.isPublished()) {
-				items.add(item);
-				// add link to item
-				// Add link to jump to course node
-				Link nodeLink = LinkFactory.createLink("nodeLink_" + item.getGuid(), peekviewVC, this);
-				nodeLink.setCustomDisplayText(StringHelper.escapeHtml(item.getTitle()));
-				nodeLink.setIconLeftCSS("o_icon o_" + feed.getResourceableTypeName().replace(".", "-") + "_icon");
-				nodeLink.setCustomEnabledLinkCSS("o_gotoNode");
-				nodeLink.setUserObject(item.getGuid());
+		if(feed == null) {
+			peekviewVC.contextPut("items", new ArrayList<>(1));
+			peekviewVC.contextPut("errorMessage", translate("peekview.error"));
+		} else {
+			peekviewVC.contextPut("wrapperCssClass", wrapperCssClass != null ? wrapperCssClass : "");
+			// add gui helper
+			String authorFullname = userManager.getUserDisplayName(feed.getAuthor());
+			FeedViewHelper helper = new FeedViewHelper(feed, getIdentity(), authorFullname, getTranslator(), courseId, nodeId, callback);
+			peekviewVC.contextPut("helper", helper);
+			// add items, only as many as configured
+			List<Item> allItems = feed.getFilteredItems(callback, getIdentity());
+			List<Item> items = new ArrayList<Item>();
+			for (int i = 0; i < allItems.size(); i++) {
+				if (items.size() == itemsToDisplay) {
+					break;
+				}
+				// add item itself if published
+				Item item = allItems.get(i);
+				if (item.isPublished()) {
+					items.add(item);
+					// add link to item
+					// Add link to jump to course node
+					Link nodeLink = LinkFactory.createLink("nodeLink_" + item.getGuid(), peekviewVC, this);
+					nodeLink.setCustomDisplayText(StringHelper.escapeHtml(item.getTitle()));
+					nodeLink.setIconLeftCSS("o_icon o_" + feed.getResourceableTypeName().replace(".", "-") + "_icon");
+					nodeLink.setCustomEnabledLinkCSS("o_gotoNode");
+					nodeLink.setUserObject(item.getGuid());
+				}
 			}
+			peekviewVC.contextPut("items", items);
+			// Add link to show all items (go to node)
+			Link allItemsLink = LinkFactory.createLink("peekview.allItemsLink", peekviewVC, this);
+			allItemsLink.setIconRightCSS("o_icon o_icon_start");
+			allItemsLink.setCustomEnabledLinkCSS("pull-right");
+			// Add Formatter for proper date formatting
+			peekviewVC.contextPut("formatter", Formatter.getInstance(getLocale()));
 		}
-		peekviewVC.contextPut("items", items);
-		// Add link to show all items (go to node)
-		Link allItemsLink = LinkFactory.createLink("peekview.allItemsLink", peekviewVC, this);
-		allItemsLink.setIconRightCSS("o_icon o_icon_start");
-		allItemsLink.setCustomEnabledLinkCSS("pull-right");
-		// Add Formatter for proper date formatting
-		peekviewVC.contextPut("formatter", Formatter.getInstance(getLocale()));
 		putInitialPanel(peekviewVC);
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/feed/_content/peekview.html b/src/main/java/org/olat/course/nodes/feed/_content/peekview.html
index ca90c7c3c3fd0dc9ae87c433423e75ab89ffafc0..37a90fdff8b033a53f1af767bb8822613b565b6e 100644
--- a/src/main/java/org/olat/course/nodes/feed/_content/peekview.html
+++ b/src/main/java/org/olat/course/nodes/feed/_content/peekview.html
@@ -1,3 +1,6 @@
+#if($errorMessage)
+	<div class="o_error">$errorMessage</div>
+#end
 <div class="o_feed_peekview $wrapperCssClass clearfix">
 #foreach( $post in $items ) 	
 	<div class="o_item">
@@ -10,5 +13,7 @@
 		$!helper.getItemDescriptionForBrowser($post)
 	</div>
 #end
+#if($r.available("peekview.allItemsLink"))
 	$r.render("peekview.allItemsLink")
+#end
 </div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/feed/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/feed/_i18n/LocalStrings_de.properties
index a346215cc5d2013cb8822d83f7e0c67b1e90dbc7..f02641ff9b4b8b66c614b74d4dd28ca898b690db 100644
--- a/src/main/java/org/olat/course/nodes/feed/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/feed/_i18n/LocalStrings_de.properties
@@ -9,7 +9,7 @@ command.close=Vorschau schliessen
 condition.accessModerator.title=Moderieren
 condition.accessPoster.title=Lesen und Schreiben
 condition.accessReader.title=Nur Lesen
-
+peekview.error=$org.olat.modules.webFeed.ui:feed.error
 peekview.allItemsLink = Alle Ausgaben
 help.hover.feed.mo=Hilfe, um den moderierenden Zugang zu konfigurieren
 help.hover.feed.r=Hilfe, um den lesenden Zugang zu konfigurieren
diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java
index 64321d93cb6ded1d450aa7d66d0843affeb1fba9..5da6c4eddcf251724ce5d3488c55ec4d0456be52 100644
--- a/src/main/java/org/olat/course/run/CourseRuntimeController.java
+++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java
@@ -330,7 +330,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 	
 	private void initTools(Dropdown tools, ICourse course, final UserCourseEnvironmentImpl uce) {
 		// 1) administrative tools
-		if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)
+		if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach()
+				|| hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)
 				|| hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_ARCHIVING)
 				|| hasCourseRight(CourseRights.RIGHT_STATISTICS) || hasCourseRight(CourseRights.RIGHT_DB)
 				|| hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
@@ -356,7 +357,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				membersLink = LinkFactory.createToolLink("unifiedusermngt", translate("command.opensimplegroupmngt"), this, "o_icon_membersmanagement");
 				tools.addComponent(membersLink);
 			}
-			if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
+			if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
 				assessmentLink = LinkFactory.createToolLink("assessment",translate("command.openassessment"), this, "o_icon_assessment_tool");
 				tools.addComponent(assessmentLink);
 			}
@@ -371,7 +372,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				courseStatisticLink = LinkFactory.createToolLink("statistic",translate("command.openstatistic"), this, "o_icon_statistics_tool");
 				tools.addComponent(courseStatisticLink);
 			}
-			if (uce != null && (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS))) {
+			if (uce != null && (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS))) {
 				final AtomicInteger testNodes = new AtomicInteger();
 				final AtomicInteger surveyNodes = new AtomicInteger();
 				new TreeVisitor(new Visitor() {
@@ -746,7 +747,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				}	
 			} else if ("assessmentTool".equalsIgnoreCase(type)) {
 				//check the security before, the link is perhaps in the wrong hands
-				if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
+				if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
 					try {
 						Activateable2 assessmentCtrl = doAssessmentTool(ureq);
 						List<ContextEntry> subEntries;
@@ -762,7 +763,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				}
 			} else if ("TestStatistics".equalsIgnoreCase(type) || "SurveyStatistics".equalsIgnoreCase(type)) {
 				//check the security before, the link is perhaps in the wrong hands
-				if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
+				if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) {
 					try {
 						Activateable2 assessmentCtrl = null;
 						if("TestStatistics".equalsIgnoreCase(type)) {
@@ -941,7 +942,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 		OLATResourceable ores = OresHelper.createOLATResourceableType(typeName);
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
 		WindowControl swControl = addToHistory(ureq, ores, null);
-		if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) {
+		if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) {
 			removeCustomCSS(ureq);
 			UserCourseEnvironmentImpl uce = getUserCourseEnvironment();
 			StatisticCourseNodesController ctrl = new StatisticCourseNodesController(ureq, swControl, toolbarPanel, uce, types);
@@ -972,7 +973,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 			return assessmentToolCtr;
 		}
 		// 2) users with coach right: limited access to coached groups
-		if (reSecurity.isCourseCoach()) {
+		if (reSecurity.isCourseCoach() || reSecurity.isGroupCoach()) {
 			removeCustomCSS(ureq);
 			AssessmentMainController ctrl = new AssessmentMainController(ureq, swControl, toolbarPanel,
 					getOlatResourceable(), new CoachingGroupAccessAssessmentCallback());
@@ -1022,7 +1023,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 	}
 
 	private void launchChat(UserRequest ureq) {
-		boolean vip = reSecurity.isCourseCoach() || reSecurity.isEntryAdmin();
+		boolean vip = reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || reSecurity.isEntryAdmin();
 		ICourse course = CourseFactory.loadCourse(getRepositoryEntry().getOlatResource());
 		OpenInstantMessageEvent event = new OpenInstantMessageEvent(ureq, course, course.getCourseTitle(), vip);
 		ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(event, InstantMessagingService.TOWER_EVENT_ORES);
diff --git a/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java b/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java
index 74e09c085289564caab668ed823d534d503a80c1..d156d3217abde345e12c6f751266bfa01024b000 100644
--- a/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java
+++ b/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java
@@ -31,6 +31,10 @@ import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.commons.io.IOUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentType;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.SAXValidator;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.vfs.VFSLeaf;
@@ -38,7 +42,6 @@ import org.olat.ims.resources.IMSEntityResolver;
 import org.olat.search.service.document.file.utils.ShieldInputStream;
 import org.xml.sax.Attributes;
 import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
@@ -114,6 +117,30 @@ public class ItemFileResourceValidator {
 	}
 	
 	private boolean validateXml(InputStream in) {
+		boolean valid = false;
+		Document doc = readDocument(in);
+		if(doc != null) {
+			DocumentType docType = doc.getDocType();
+			if(docType == null) {
+				doc.addDocType("questestinterop", null, "ims_qtiasiv1p2p1.dtd");
+			}
+			valid = validateDocument(doc);
+		}
+		return valid;
+	}
+	
+	private Document readDocument(InputStream in) {
+		try {
+			SAXReader reader = new SAXReader();
+			reader.setEntityResolver(new IMSEntityResolver());
+			reader.setValidation(false);
+			return reader.read(in, "");
+		} catch (Exception e) {
+			return null;
+		}
+	}
+	
+	private boolean validateDocument(Document in) {
 		try {
 			SAXParserFactory factory = SAXParserFactory.newInstance();
 			factory.setValidating(true);
@@ -127,7 +154,10 @@ public class ItemFileResourceValidator {
 			reader.setEntityResolver(new IMSEntityResolver());
 			reader.setErrorHandler(errorHandler);
 			reader.setContentHandler(contentHandler);
-			reader.parse(new InputSource(in));
+
+			SAXValidator validator = new SAXValidator(reader);
+			validator.validate(in);
+			
 			return errorHandler.isValid() && contentHandler.isItem();
 		} catch (ParserConfigurationException e) {
 			return false;
@@ -176,7 +206,7 @@ public class ItemFileResourceValidator {
 			
 			if("questestinterop".equals(qName)) {
 				interop = true;
-			} else if("item".equals(localName)) {
+			} else if("item".equals(localName) || "item".equals(qName)) {
 				if(interop) {
 					item = true;
 				}
diff --git a/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
index 4f9e934a59ad62405ee22525377c9a90715aece6..6106024213e9cc9bad9dc4ad69545c1e79a83faa 100644
--- a/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
+++ b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java
@@ -636,11 +636,12 @@ class QTIImportProcessor {
 	}
 	
 	private boolean processSidecarMetadata(QuestionItemImpl item, DocInfos docInfos) {
+		InputStream metadataIn = null;
 		try {
 			Path path = docInfos.root;
-			if(path != null) {
+			if(path != null && path.getFileName() != null) {
 				Path metadata = path.resolve(path.getFileName().toString() + "_metadata.xml");
-				InputStream metadataIn = Files.newInputStream(metadata);
+				metadataIn = Files.newInputStream(metadata);
 				SAXReader reader = new SAXReader();
 		        Document document = reader.read(metadataIn);
 		        Element rootElement = document.getRootElement();
@@ -654,6 +655,8 @@ class QTIImportProcessor {
 		} catch (Exception e) {
 			log.error("", e);
 			return false;
+		} finally {
+			IOUtils.closeQuietly(metadataIn);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/modules/webFeed/_spring/webFeedContext.xml b/src/main/java/org/olat/modules/webFeed/_spring/webFeedContext.xml
index 3f2299d1c573d025271f3e1f4d18ff9bb9eeff16..50b7925f335a2ba15c929c5e5d6c6dbb113eff27 100644
--- a/src/main/java/org/olat/modules/webFeed/_spring/webFeedContext.xml
+++ b/src/main/java/org/olat/modules/webFeed/_spring/webFeedContext.xml
@@ -3,7 +3,7 @@
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="
   http://www.springframework.org/schema/beans 
-  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+  http://www.springframework.org/schema/beans/spring-beans.xsd">
 
 <bean id="feedManager" class="org.olat.modules.webFeed.managers.FeedManagerImpl">
 	<constructor-arg index="0" ref="resourceManager"/>
diff --git a/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java b/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
index a8fd512a3646109a369bc81cb2b9becbc1dee691..d4f77ba0a9e90f94d74e85133090bc9fa46f8eb8 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
+++ b/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
@@ -21,7 +21,6 @@ package org.olat.modules.webFeed.ui;
 
 import java.util.List;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.elements.FileElement;
@@ -50,6 +49,7 @@ import org.olat.modules.webFeed.models.Feed;
 import org.olat.modules.webFeed.models.Item;
 import org.olat.user.UserManager;
 import org.olat.util.logging.activity.LoggingResourceable;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * This is the main feed layout controller. It handles everything from adding
@@ -62,7 +62,6 @@ import org.olat.util.logging.activity.LoggingResourceable;
  */
 public class FeedMainController extends BasicController implements Activateable2, GenericEventListener {
 
-	private static final FeedManager feedManager = FeedManager.getInstance();
 	private Feed feed;
 	private Link editFeedButton;
 	private CloseableModalController cmc;
@@ -77,7 +76,10 @@ public class FeedMainController extends BasicController implements Activateable2
 	// needed for comparison
 	private String oldFeedUrl;
 	
-	private final UserManager userManager;
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private FeedManager feedManager;
 	
 	/**
 	 * Constructor for learning resource (not course nodes)
@@ -107,15 +109,28 @@ public class FeedMainController extends BasicController implements Activateable2
 		super(ureq, wControl);
 		this.uiFactory = uiFactory;
 		this.callback = callback;
-		userManager = CoreSpringFactory.getImpl(UserManager.class);
 		setTranslator(uiFactory.getTranslator());
 		feed = feedManager.getFeed(ores);
-		String authorFullname = userManager.getUserDisplayName(feed.getAuthor());
-		helper = new FeedViewHelper(feed, getIdentity(), authorFullname, uiFactory.getTranslator(), courseId, nodeId, callback);
-		CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, ureq.getIdentity(), feed);
-		display(ureq, wControl, displayConfig);
-		// do logging
-		ThreadLocalUserActivityLogger.log(FeedLoggingAction.FEED_READ, getClass(), LoggingResourceable.wrap(feed));
+		if(feed == null) {
+			vcMain = createVelocityContainer("feed_error");
+			vcMain.contextPut("errorMessage", translate("feed.error"));
+			putInitialPanel(vcMain);
+		} else {
+			String authorFullname = userManager.getUserDisplayName(feed.getAuthor());
+			helper = new FeedViewHelper(feed, getIdentity(), authorFullname, uiFactory.getTranslator(), courseId, nodeId, callback);
+			CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, ureq.getIdentity(), feed);
+			display(ureq, wControl, displayConfig);
+			// do logging
+			ThreadLocalUserActivityLogger.log(FeedLoggingAction.FEED_READ, getClass(), LoggingResourceable.wrap(feed));
+		}
+	}
+
+	@Override
+	protected void doDispose() {
+		feedManager.releaseLock(lock);
+		if(feed != null) {
+			CoordinatorManager.getInstance().getCoordinator().getEventBus().deregisterFor(this, feed);
+		}
 	}
 
 	/**
@@ -156,16 +171,7 @@ public class FeedMainController extends BasicController implements Activateable2
 		listenTo(itemsCtr);
 		vcMain.put("items", itemsCtr.getInitialComponent());
 
-		this.putInitialPanel(vcMain);
-	}
-
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#doDispose()
-	 */
-	@Override
-	protected void doDispose() {
-		feedManager.releaseLock(lock);
-		CoordinatorManager.getInstance().getCoordinator().getEventBus().deregisterFor(this, feed);
+		putInitialPanel(vcMain);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/modules/webFeed/ui/_content/feed_error.html b/src/main/java/org/olat/modules/webFeed/ui/_content/feed_error.html
new file mode 100644
index 0000000000000000000000000000000000000000..5ee912b6b67d579a12fe08860452d736f453d085
--- /dev/null
+++ b/src/main/java/org/olat/modules/webFeed/ui/_content/feed_error.html
@@ -0,0 +1,3 @@
+<div class="o_error">
+	$errorMessage
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/webFeed/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/webFeed/ui/_i18n/LocalStrings_de.properties
index 2af164dacdd3ee60efc472433586fb910d2eb451..7f175723acdf786ef47eb7b086d50aa8619dd9a9 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/webFeed/ui/_i18n/LocalStrings_de.properties
@@ -34,4 +34,5 @@ feed.form.minutes.error = Die Minutenangabe ist ung\u00FCltig
 feed.item.confirm.delete = Wollen Sie diesen Eintrag wirklich l\u00F6schen?
 feed.item.is.being.edited.by = Der Eintrag wird bereits von {0} bearbeitet.
 feed.is.being.edited.by = Die Beschreibung wird bereits von {0} bearbeitet.
-feed.link.more=weiterlesen
\ No newline at end of file
+feed.link.more=weiterlesen
+feed.error=Leider ist ein unerwartete Fehler aufgetretten und der Feed konnte nicht dargestellt werden.
\ No newline at end of file
diff --git a/src/main/java/org/olat/note/Note.java b/src/main/java/org/olat/note/Note.java
index f088e13c6f6316e018eb0602faab6fde848f7df2..35a43ed57e04af0d1f22a39e7800ac8b66aa53f6 100644
--- a/src/main/java/org/olat/note/Note.java
+++ b/src/main/java/org/olat/note/Note.java
@@ -37,18 +37,18 @@ import org.olat.core.id.Persistable;
  * @author Alexander Schneider
  */
 public interface Note extends CreateInfo, ModifiedInfo, Persistable {
-	public abstract Identity getOwner();
-	public abstract String getResourceTypeName();
-	public abstract Long getResourceTypeId();
-	public abstract String getSubtype();
-	public abstract String getNoteTitle();
-	public abstract String getNoteText();
+	public Identity getOwner();
+	public String getResourceTypeName();
+	public Long getResourceTypeId();
+	public String getSubtype();
+	public String getNoteTitle();
+	public String getNoteText();
 	
-	public abstract void setOwner(Identity identity);
-	public abstract void setResourceTypeName(String resourceTypeName);
-	public abstract void setResourceTypeId(Long resourceTypeId);
-	public abstract void setSubtype(String subtype);
-	public abstract void setNoteTitle(String nodeTitle);
-	public abstract void setNoteText(String noteText);
+	public void setOwner(Identity identity);
+	public void setResourceTypeName(String resourceTypeName);
+	public void setResourceTypeId(Long resourceTypeId);
+	public void setSubtype(String subtype);
+	public void setNoteTitle(String nodeTitle);
+	public void setNoteText(String noteText);
     
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/note/NoteController.java b/src/main/java/org/olat/note/NoteController.java
index 8c21bdbbb927770c59f2ffa2895209dea9a09b9b..8428ceefe7c3fe39d5de2a8a7087867eef29a077 100644
--- a/src/main/java/org/olat/note/NoteController.java
+++ b/src/main/java/org/olat/note/NoteController.java
@@ -66,7 +66,7 @@ public class NoteController extends FormBasicController implements GenericEventL
 	private FormSubmit submitButton;
 	
 	@Autowired
-	private NoteManager nm;
+	private NoteManager noteManager;
 
 	/**
 	 * @param ureq
@@ -101,7 +101,7 @@ public class NoteController extends FormBasicController implements GenericEventL
 
 	private void init(UserRequest ureq, String resourceTypeName, Long resourceTypeId, String noteTitle) {
 		Identity owner = ureq.getIdentity();
-		n = nm.loadNoteOrCreateInRAM(owner, resourceTypeName, resourceTypeId);
+		n = noteManager.loadNoteOrCreateInRAM(owner, resourceTypeName, resourceTypeId);
 		n.setNoteTitle(noteTitle);
 
 		// register for local event (for the same user), is used to dispose
@@ -138,12 +138,12 @@ public class NoteController extends FormBasicController implements GenericEventL
 	private void createOrUpdateNote(String content) {
 		n.setNoteText(content);
 		if (n.getKey() == null) {
-			nm.saveNote(n);
+			noteManager.saveNote(n);
 			Long newKey = n.getKey();
 			OLATResourceable ores = OresHelper.createOLATResourceableInstance(Note.class, newKey);
 			sec.fireEventToListenersOf(new NoteEvent(getIdentity().getKey()), ores);
 		} else {
-			nm.updateNote(n);
+			n = noteManager.updateNote(n);
 		}
 	}
 
@@ -192,9 +192,9 @@ public class NoteController extends FormBasicController implements GenericEventL
 		createOrUpdateNote(text);
 		
 		// ...and then hide the submit button, show the edit button, and make the field disabled (i.e. display-only) again.
-		this.submitButton.setVisible(false);
-		this.editButton.setVisible(true);
-		this.noteField.setEnabled(false);
+		submitButton.setVisible(false);
+		editButton.setVisible(true);
+		noteField.setEnabled(false);
 	}
 
 	/**
@@ -207,10 +207,10 @@ public class NoteController extends FormBasicController implements GenericEventL
 		// persisting: see formOK
 		
 		// If the user clicked the edit button, set the rich text input field to enabled and hide the edit button.
-		if ((source == this.editButton) && (this.editButton.isEnabled())) {
-			this.noteField.setEnabled(true);
-			this.editButton.setVisible(false);
-			this.submitButton.setVisible(true);
+		if ((source == editButton) && (editButton.isEnabled())) {
+			noteField.setEnabled(true);
+			editButton.setVisible(false);
+			submitButton.setVisible(true);
 			
 			// this is to force the redraw of the form so that the submit button gets shown:
 			flc.setDirty(true);
@@ -218,8 +218,7 @@ public class NoteController extends FormBasicController implements GenericEventL
 			// since clicking the edit button is registered as a change on the form, the submit button would get orange,
 			// so we need the following line to set the form back to unchanged since at this point, the user has not
 			// yet really changed anything.
-			this.mainForm.setDirtyMarking(false);
+			mainForm.setDirtyMarking(false);
 		}
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/note/NoteManager.java b/src/main/java/org/olat/note/NoteManager.java
index d99169878375494026367a97b09baa85e263a3aa..34034bd2f7a415070a094b401637f8791816c0eb 100644
--- a/src/main/java/org/olat/note/NoteManager.java
+++ b/src/main/java/org/olat/note/NoteManager.java
@@ -139,8 +139,13 @@ public class NoteManager implements UserDataDeletable {
 	 * @param n
 	 */
 	public Note updateNote(Note n) {
-		n.setLastModified(new Date());
-		Note mergedNote = dbInstance.getCurrentEntityManager().merge(n);
+		Note reloadedNote = dbInstance.getCurrentEntityManager()
+				.find(NoteImpl.class, n.getKey());
+		reloadedNote.setLastModified(new Date());
+		reloadedNote.setNoteTitle(n.getNoteTitle());
+		reloadedNote.setNoteText(n.getNoteText());
+		
+		Note mergedNote = dbInstance.getCurrentEntityManager().merge(reloadedNote);
 		fireBookmarkEvent(n.getOwner());
 		return mergedNote;
 	}
diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
index 3ab0efb395ef44668694259c630bb14b981841a4..6b5956aab4aef40847cc9ce679f6e6e6dcac8ae5 100644
--- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties
@@ -209,6 +209,8 @@ cif.error.description.empty=Bitte f\u00FCllen Sie das Feld "Beschreibung" aus.
 cif.error.displayname.empty=Bitte f\u00FCllen Sie das Feld "Titel der Lernressource" aus.
 cif.error.idnotint=Diese Identifikationsnummer existiert nicht.
 cif.error.resourcename.empty=Bitte f\u00FCllen Sie das Feld "Referenz" aus.
+cif.error.image=Das Titelbild könnte nicht richtig gespeichert werden.
+cif.error.movie=Der Teaser-Film könnte nicht richtig gespeichert werden.
 cif.expenditureOfWork=Zeitaufwand
 cif.externalid=Extern ID
 cif.externalref=Kennzeichen
diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
index 71b5e7ca6c4e0ff9b7ab423adff7e6f891b9ef9d..54d1efd23395b4e8622ee3045992a937f5ad16bf 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
@@ -760,8 +760,16 @@ public class AuthorListController extends FormBasicController implements Activat
 		NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
 	}
 	
-	private void launchEditDescription(UserRequest ureq, RepositoryEntryRef ref) {
-		String businessPath = "[RepositoryEntry:" + ref.getKey() + "][EditDescription:0]";
+	private void launchEditDescription(UserRequest ureq, RepositoryEntry re) {
+		RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(re);
+		if(handler != null && handler.supportsLaunch()) {
+			String businessPath = "[RepositoryEntry:" + re.getKey() + "][EditDescription:0]";
+			NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
+		}
+	}
+	
+	private void launchEditDescription(UserRequest ureq, RepositoryEntryRef re) {
+		String businessPath = "[RepositoryEntry:" + re.getKey() + "][EditDescription:0]";
 		NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
 	}
 	
diff --git a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
index 8c072a84ef7a3f3f38467d3369fc9a7e9c7945a9..df377b4c819e6bd6d7b4ccdd180d303a196318f7 100644
--- a/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
+++ b/src/main/java/org/olat/repository/ui/author/ImportRepositoryEntryController.java
@@ -199,18 +199,25 @@ public class ImportRepositoryEntryController extends FormBasicController {
 
 	private void doAnalyseUpload() {
 		File uploadedFile = uploadFileEl.getUploadFile();
-		String uploadedFilename = uploadFileEl.getUploadFileName();
-		
-		List<ResourceHandler> handlers = new ArrayList<>(3);
-		for(String type:repositoryHandlerFactory.getSupportedTypes()) {
-			RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(type);
-			ResourceEvaluation eval = handler.acceptImport(uploadedFile, uploadedFilename);
-			if(eval != null && eval.isValid()) {
-				handlers.add(new ResourceHandler(handler, eval));
+		if(uploadedFile == null) {//OO-1320
+			typeEl.setVisible(false);
+			selectType.setVisible(false);
+			uploadFileEl.reset();
+			importButton.setEnabled(false);
+		} else {
+			String uploadedFilename = uploadFileEl.getUploadFileName();
+			
+			List<ResourceHandler> handlers = new ArrayList<>(3);
+			for(String type:repositoryHandlerFactory.getSupportedTypes()) {
+				RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(type);
+				ResourceEvaluation eval = handler.acceptImport(uploadedFile, uploadedFilename);
+				if(eval != null && eval.isValid()) {
+					handlers.add(new ResourceHandler(handler, eval));
+				}
 			}
+	
+			updateResourceInfos(handlers);
 		}
-
-		updateResourceInfos(handlers);
 	}
 	
 	private void updateResourceInfos(List<ResourceHandler> handlers) {
diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
index b7772ff29107abff960b6c10f18b85f21da95907..4884adb458c0cd88abc3ddb01d189b3b56365a8b 100644
--- a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
+++ b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java
@@ -466,7 +466,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 			VFSLeaf newFile = fileUpload.moveUploadFileTo(container);//give it it's real name and extension
 			boolean ok = repositoryManager.setImage(newFile, repositoryEntry);
 			if (!ok) {
-				showError("Failed");
+				showWarning("cif.error.image");
 			} else {
 				VFSLeaf image = repositoryManager.getImage(repositoryEntry);
 				if(image instanceof  LocalFileImpl) {
@@ -481,7 +481,7 @@ public class RepositoryEditDescriptionController extends FormBasicController {
 			VFSContainer m = (VFSContainer)mediaContainer.resolve("media");
 			VFSLeaf newFile = movieUpload.moveUploadFileTo(m);
 			if (newFile == null) {
-				showError("Failed");
+				showWarning("cif.error.movie");
 			} else {
 				String filename = movieUpload.getUploadFileName();
 				String extension = FileUtils.getFileSuffix(filename);
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
index d066587d49f538a463b5db689299186af3869200..050604b9ed449abe9793b962fdee169a72d8f52b 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
@@ -239,7 +239,7 @@ public class RepositoryEntryListController extends FormBasicController
 		}
 		
 		FlexiTableSortOptions options = new FlexiTableSortOptions(sorters);
-		options.setDefaultOrderBy(new SortKey(OrderBy.automatic.name(), true));
+		options.setDefaultOrderBy(new SortKey(OrderBy.title.name(), true));
 		tableElement.setSortSettings(options);
 	}
 
diff --git a/src/test/java/org/olat/ims/qti/qpool/ItemFileResourceValidatorTest.java b/src/test/java/org/olat/ims/qti/qpool/ItemFileResourceValidatorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..77bd7cd1b0deb65f04916dbf8f187c6459f46331
--- /dev/null
+++ b/src/test/java/org/olat/ims/qti/qpool/ItemFileResourceValidatorTest.java
@@ -0,0 +1,55 @@
+package org.olat.ims.qti.qpool;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+/**
+ * 
+ * Initial date: 20.11.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ItemFileResourceValidatorTest {
+	
+	@Test
+	public void validate() throws URISyntaxException {
+		URL itemUrl = ItemFileResourceValidatorTest.class.getResource("fibi_i_001.xml");
+		Assert.assertNotNull(itemUrl);
+		File itemFile = new File(itemUrl.toURI());
+		
+		ItemFileResourceValidator validator = new ItemFileResourceValidator();
+		boolean validate = validator.validate("fibi_i_001.xml", itemFile);
+		Assert.assertTrue(validate);
+	}
+	
+	@Test
+	public void validate_missingDoctype() throws URISyntaxException {
+		URL itemUrl = ItemFileResourceValidatorTest.class.getResource("oo_item_without_doctype.xml");
+		Assert.assertNotNull(itemUrl);
+		File itemFile = new File(itemUrl.toURI());
+		
+		ItemFileResourceValidator validator = new ItemFileResourceValidator();
+		boolean validate = validator.validate("oo_item_without_doctype.xml", itemFile);
+		Assert.assertTrue(validate);
+	}
+	
+	@Test
+	public void validate_missingDoctype_invalid() throws URISyntaxException {
+		URL itemUrl = ItemFileResourceValidatorTest.class.getResource("oo_item_without_doctype_invalid.xml");
+		Assert.assertNotNull(itemUrl);
+		File itemFile = new File(itemUrl.toURI());
+		
+		ItemFileResourceValidator validator = new ItemFileResourceValidator();
+		boolean validate = validator.validate("oo_item_without_doctype_invalid.xml", itemFile);
+		Assert.assertFalse(validate);
+	}
+	
+
+
+
+}
diff --git a/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype.xml b/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3353d8f1289c5511a1fc69ed20265521c5baa905
--- /dev/null
+++ b/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype.xml
@@ -0,0 +1,49 @@
+<questestinterop>
+  <item ident="QTIEDIT:MCQ:1000002286" title="New question">
+    <presentation label="New question">
+      <material>
+        <mattext texttype="text/html"><![CDATA[New question]]></mattext>
+      </material>
+      <response_lid ident="1000002288" rcardinality="Multiple" rtiming="No">
+        <render_choice shuffle="No" minnumber="0" maxnumber="1">
+          <flow_label class="List">
+            <response_label ident="1000002291" rshuffle="Yes">
+              <material>
+                <mattext texttype="text/html"><![CDATA[New answer]]></mattext>
+              </material>
+            </response_label>
+          </flow_label>
+        </render_choice>
+      </response_lid>
+    </presentation>
+    <resprocessing>
+      <outcomes>
+        <decvar varname="SCORE" vartype="Decimal" defaultval="0" minvalue="0.0" maxvalue="1.0" cutvalue="1.0"/>
+      </outcomes>
+      <respcondition title="Mastery" continue="Yes">
+        <conditionvar>
+          <and>
+            <varequal respident="1000002288" case="Yes">1000002291</varequal>
+          </and>
+        </conditionvar>
+        <setvar varname="SCORE" action="Set">1.0</setvar>
+        <displayfeedback feedbacktype="Response" linkrefid="Mastery"/>
+      </respcondition>
+      <respcondition title="_olat_resp_feedback" continue="Yes">
+        <conditionvar>
+          <varequal respident="1000002288" case="Yes">1000002291</varequal>
+        </conditionvar>
+        <displayfeedback feedbacktype="Response" linkrefid="1000002291"/>
+      </respcondition>
+      <respcondition title="Fail" continue="Yes">
+        <conditionvar>
+          <other/>
+        </conditionvar>
+        <setvar varname="SCORE" action="Set">0</setvar>
+        <displayfeedback feedbacktype="Response" linkrefid="Fail"/>
+        <displayfeedback feedbacktype="Solution" linkrefid="Solution"/>
+        <displayfeedback feedbacktype="Hint" linkrefid="Hint"/>
+      </respcondition>
+    </resprocessing>
+  </item>
+</questestinterop>
diff --git a/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype_invalid.xml b/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype_invalid.xml
new file mode 100644
index 0000000000000000000000000000000000000000..451de66caa59d30b745bab1acd2b7228d76eacc0
--- /dev/null
+++ b/src/test/java/org/olat/ims/qti/qpool/oo_item_without_doctype_invalid.xml
@@ -0,0 +1,49 @@
+<questestinterop>
+  <itemop ident="QTIEDIT:MCQ:1000002286" title="New question">
+    <presentation label="New question">
+      <material>
+        <mattext texttype="text/html"><![CDATA[New question]]></mattext>
+      </material>
+      <response_lid ident="1000002288" rcardinality="Multiple" rtiming="No">
+        <render_choice shuffle="No" minnumber="0" maxnumber="1">
+          <flow_label class="List">
+            <response_label ident="1000002291" rshuffle="Yes">
+              <material>
+                <mattext texttype="text/html"><![CDATA[New answer]]></mattext>
+              </material>
+            </response_label>
+          </flow_label>
+        </render_choice>
+      </response_lid>
+    </presentation>
+    <resprocessing>
+      <outcomes>
+        <decvar varname="SCORE" vartype="Decimal" defaultval="0" minvalue="0.0" maxvalue="1.0" cutvalue="1.0"/>
+      </outcomes>
+      <respcondition title="Mastery" continue="Yes">
+        <conditionvar>
+          <and>
+            <varequal respident="1000002288" case="Yes">1000002291</varequal>
+          </and>
+        </conditionvar>
+        <setvar varname="SCORE" action="Set">1.0</setvar>
+        <displayfeedback feedbacktype="Response" linkrefid="Mastery"/>
+      </respcondition>
+      <respcondition title="_olat_resp_feedback" continue="Yes">
+        <conditionvar>
+          <varequal respident="1000002288" case="Yes">1000002291</varequal>
+        </conditionvar>
+        <displayfeedback feedbacktype="Response" linkrefid="1000002291"/>
+      </respcondition>
+      <respcondition title="Fail" continue="Yes">
+        <conditionvar>
+          <other/>
+        </conditionvar>
+        <setvar varname="SCORE" action="Set">0</setvar>
+        <displayfeedback feedbacktype="Response" linkrefid="Fail"/>
+        <displayfeedback feedbacktype="Solution" linkrefid="Solution"/>
+        <displayfeedback feedbacktype="Hint" linkrefid="Hint"/>
+      </respcondition>
+    </resprocessing>
+  </itemop>
+</questestinterop>
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 8019e90d1e8438a1a3154a37f29498834d9f22ce..34547efd2c3cc4b28f856cfa80ce787d5e46460d 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -144,6 +144,7 @@ import org.junit.runners.Suite;
 	org.olat.ims.qti.QTIResultManagerTest.class,
 	org.olat.ims.qti.qpool.QTIImportProcessorTest.class,
 	org.olat.ims.qti.qpool.QTIExportProcessorTest.class,
+	org.olat.ims.qti.qpool.ItemFileResourceValidatorTest.class,
 	org.olat.ims.qti.questionimport.CSVToQuestionConverterTest.class,
 	org.olat.ims.qti.statistics.manager.QTIStatisticsManagerLargeTest.class,
 	org.olat.ims.qti.statistics.manager.QTIStatisticsManagerTest.class,