diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
index 18174b0e23f6c55256b79342964e13c8cbb043ba..1623beea125068c01e9bca168c1ed0d4b3bba3a2 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/FlexiTableElement.java
@@ -380,6 +380,14 @@ public interface FlexiTableElement extends FormItem {
 	 */
 	public void reset(boolean page, boolean internal, boolean reloadData);
 	
+	/**
+	 * It will reload all the data without filter. Use it with cautious as
+	 * at some place, there are minimal restrictions to the search string.
+	 * 
+	 * @param ureq
+	 */
+	public void resetSearch(UserRequest ureq);
+	
 	public void reloadData();
 
 	/**
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 71e78716a52bf90ceea9e663b2db35dad5a6f7d4..094ef037ac676593239304979bb3437c8ecce93d 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
@@ -1295,7 +1295,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 		if(StringHelper.containsNonWhitespace(search)) {
 			doSearch(ureq, FlexiTableSearchEvent.QUICK_SEARCH, search, null);
 		} else {
-			doResetSearch(ureq);
+			resetSearch(ureq);
 		}
 	}
 	
@@ -1367,7 +1367,8 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
 				search, getSelectedFilters(), getSelectedExtendedFilters(), condQueries, FormEvent.ONCLICK));
 	}
 	
-	protected void doResetSearch(UserRequest ureq) {
+	@Override
+	public void resetSearch(UserRequest ureq) {
 		conditionalQueries = null;
 		currentPage = 0;
 		if(dataSource != null) {
diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
index 37dced270d73df11f297c153d4f58aadf5afb7c9..0b8c19d7f7bc43d40e2f2661c4fc72d5da426985 100644
--- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
@@ -63,6 +63,7 @@ import org.olat.ims.qti.export.QTIExportFormatterCSVType2;
 import org.olat.ims.qti.export.QTIExportManager;
 import org.olat.ims.qti.fileresource.TestFileResource;
 import org.olat.ims.qti.process.AssessmentInstance;
+import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.iq.IQManager;
 import org.olat.modules.iq.IQSecurityCallback;
@@ -230,12 +231,15 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se
 	 */
 	@Override
 	public void cleanupOnDelete(ICourse course) {
-		// Delete all qtiresults for this node. No properties used on this node
+		// 1) Delete all qtiresults for this node. No properties used on this node
 		String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
 		RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, false);
 		if(re != null) {
 			QTIResultManager.getInstance().deleteAllResults(course.getResourceableId(), getIdent(), re.getKey());
 		}
+		// 2) Delete all assessment test sessions (QTI 2.1)
+		RepositoryEntry courseEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		CoreSpringFactory.getImpl(AssessmentTestSessionDAO.class).deleteAllUserTestSessionsByCourse(courseEntry, getIdent());
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
index d552e9434517f44fcb07beb95305eb3ce891ab66..e1f3f1128b92c42ee8c47ad06e6b35d959159a10 100644
--- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
@@ -90,6 +90,7 @@ import org.olat.ims.qti.statistics.ui.QTI12PullTestsToolController;
 import org.olat.ims.qti.statistics.ui.QTI12StatisticsToolController;
 import org.olat.ims.qti21.QTI21DeliveryOptions;
 import org.olat.ims.qti21.QTI21Service;
+import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat;
 import org.olat.ims.qti21.model.QTI21StatisticSearchParams;
 import org.olat.ims.qti21.ui.QTI21AssessmentDetailsController;
@@ -612,12 +613,15 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 		// 1) Delete all properties: score, passed, log, comment, coach_comment,
 		// attempts
 		pm.deleteNodeProperties(this, null);
-		// 2) Delete all qtiresults for this node
+		// 2) Delete all qtiresults for this node (QTI 1.2 + qtiworks)
 		String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
 		RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, false);
 		if(re != null) {
 			QTIResultManager.getInstance().deleteAllResults(course.getResourceableId(), getIdent(), re.getKey());
 		}
+		// 3) Delete all assessment test sessions (QTI 2.1)
+		RepositoryEntry courseEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		CoreSpringFactory.getImpl(AssessmentTestSessionDAO.class).deleteAllUserTestSessionsByCourse(courseEntry, getIdent());
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java
index db3d90f9b6e02a03b9135f4717c1a176b17eaa4d..cde3cd51bc0e8d4d95c0684f9e3dc4d55db03578 100644
--- a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java
+++ b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java
@@ -422,7 +422,7 @@ public class AssessmentTestSessionDAO {
 	 * @param testEntry
 	 * @return
 	 */
-	public int deleteAllUserTestSessions(RepositoryEntryRef testEntry) {
+	public int deleteAllUserTestSessionsByTest(RepositoryEntryRef testEntry) {
 		String marksSb = "delete from qtiassessmentmarks marks where marks.testEntry.key=:testEntryKey";
 		int marks = dbInstance.getCurrentEntityManager()
 				.createQuery(marksSb)
@@ -457,4 +457,82 @@ public class AssessmentTestSessionDAO {
 				.executeUpdate();
 		return marks + itemSessions + sessions + responses;
 	}
+	
+	
+	public int deleteAllUserTestSessionsByCourse(RepositoryEntryRef entry, String subIdent) {
+		String marksSb = "delete from qtiassessmentmarks marks where marks.repositoryEntry.key=:entryKey and marks.subIdent=:subIdent";
+		int marks = dbInstance.getCurrentEntityManager()
+				.createQuery(marksSb)
+				.setParameter("entryKey", entry.getKey())
+				.setParameter("subIdent", subIdent)
+				.executeUpdate();
+		
+		StringBuilder responseSb  = new StringBuilder();
+		responseSb.append("delete from qtiassessmentresponse response where")
+		  .append("  response.assessmentItemSession.key in (")
+		  .append("   select itemSession from qtiassessmentitemsession itemSession, qtiassessmenttestsession session ")
+		  .append("   where itemSession.assessmentTestSession.key=session.key and session.repositoryEntry.key=:entryKey and session.subIdent=:subIdent")
+		  .append(" )");
+		int responses = dbInstance.getCurrentEntityManager()
+				.createQuery(responseSb.toString())
+				.setParameter("entryKey", entry.getKey())
+				.setParameter("subIdent", subIdent)
+				.executeUpdate();
+		
+		StringBuilder itemSb  = new StringBuilder();
+		itemSb.append("delete from qtiassessmentitemsession itemSession")
+		  .append(" where itemSession.assessmentTestSession.key in(")
+		  .append("  select session.key from qtiassessmenttestsession session where session.repositoryEntry.key=:entryKey and session.subIdent=:subIdent")
+		  .append(" )");
+		int itemSessions = dbInstance.getCurrentEntityManager()
+				.createQuery(itemSb.toString())
+				.setParameter("entryKey", entry.getKey())
+				.setParameter("subIdent", subIdent)
+				.executeUpdate();
+		
+		String q = "delete from qtiassessmenttestsession session where session.repositoryEntry.key=:entryKey and session.subIdent=:subIdent";
+		int sessions = dbInstance.getCurrentEntityManager()
+				.createQuery(q)
+				.setParameter("entryKey", entry.getKey())
+				.setParameter("subIdent", subIdent)
+				.executeUpdate();
+		return marks + itemSessions + sessions + responses;
+	}
+	
+	
+	public int deleteAllUserTestSessionsByCourse(RepositoryEntryRef entry) {
+		String marksSb = "delete from qtiassessmentmarks marks where marks.repositoryEntry.key=:entryKey";
+		int marks = dbInstance.getCurrentEntityManager()
+				.createQuery(marksSb)
+				.setParameter("entryKey", entry.getKey())
+				.executeUpdate();
+		
+		StringBuilder responseSb  = new StringBuilder();
+		responseSb.append("delete from qtiassessmentresponse response where")
+		  .append("  response.assessmentItemSession.key in (")
+		  .append("   select itemSession from qtiassessmentitemsession itemSession, qtiassessmenttestsession session ")
+		  .append("   where itemSession.assessmentTestSession.key=session.key and session.repositoryEntry.key=:entryKey")
+		  .append(" )");
+		int responses = dbInstance.getCurrentEntityManager()
+				.createQuery(responseSb.toString())
+				.setParameter("entryKey", entry.getKey())
+				.executeUpdate();
+		
+		StringBuilder itemSb  = new StringBuilder();
+		itemSb.append("delete from qtiassessmentitemsession itemSession")
+		  .append(" where itemSession.assessmentTestSession.key in(")
+		  .append("  select session.key from qtiassessmenttestsession session where session.repositoryEntry.key=:entryKey")
+		  .append(" )");
+		int itemSessions = dbInstance.getCurrentEntityManager()
+				.createQuery(itemSb.toString())
+				.setParameter("entryKey", entry.getKey())
+				.executeUpdate();
+		
+		String q = "delete from qtiassessmenttestsession session where session.repositoryEntry.key=:entryKey";
+		int sessions = dbInstance.getCurrentEntityManager()
+				.createQuery(q)
+				.setParameter("entryKey", entry.getKey())
+				.executeUpdate();
+		return marks + itemSessions + sessions + responses;
+	}
 }
diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java b/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java
index 18ad4a54030512718afa93bbe458c18fbdcb4354..e17a38786670f2088356b5b44b9e12d2ce244420 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java
@@ -38,7 +38,6 @@ import org.olat.core.util.FileUtils;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.ZipUtil;
 import org.olat.core.util.io.ShieldOutputStream;
-import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.ims.qti21.QTI21Service;
 import org.olat.ims.qti21.model.xml.AssessmentTestFactory;
 import org.olat.ims.qti21.model.xml.ManifestBuilder;
@@ -47,12 +46,15 @@ import org.olat.imscp.xml.manifest.ResourceType;
 import org.olat.modules.qpool.QuestionItemFull;
 import org.olat.modules.qpool.manager.QPoolFileStorage;
 
+import uk.ac.ed.ph.jqtiplus.node.content.xhtml.image.Img;
+import uk.ac.ed.ph.jqtiplus.node.content.xhtml.object.Object;
 import uk.ac.ed.ph.jqtiplus.node.item.AssessmentItem;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.Interaction;
 import uk.ac.ed.ph.jqtiplus.node.test.AssessmentSection;
 import uk.ac.ed.ph.jqtiplus.node.test.AssessmentTest;
 import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentItem;
 import uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer;
+import uk.ac.ed.ph.jqtiplus.utils.QueryUtils;
 
 /**
  * 
@@ -122,8 +124,12 @@ public class QTI21ExportProcessor {
 		//write materials
 		for(ItemMaterial material:itemAndMaterials.getMaterials()) {
 			String exportPath = material.getExportUri();
-			File leaf = new File(editorContainer, exportPath);
-			FileUtils.bcopy(leaf, editorContainer, "Export to QTI 2.1 editor");
+			File originalFile = material.getFile();
+			File exportFile = new File(editorContainer, exportPath);
+			if(!exportFile.getParentFile().exists()) {
+				exportFile.getParentFile().mkdirs();
+			}
+			FileUtils.bcopy(originalFile, exportFile, "Copy material QTI 2.1");
 		}
 		return assessmentItem;
 	}
@@ -138,11 +144,35 @@ public class QTI21ExportProcessor {
 			ResolvedAssessmentItem assessmentItem = qtiService.loadAndResolveAssessmentItem(itemFile.toURI(), resourceDirectory);
 			//enrichScore(itemEl);
 			//enrichWithMetadata(fullItem, itemEl);
-			//collectResources(itemEl, container, materials);
+			collectResources(assessmentItem.getRootNodeLookup().extractIfSuccessful(), itemFile, materials);
 			materials.addItemEl(assessmentItem);
 		}
 	}
 	
+	protected void collectResources(AssessmentItem item, File itemFile, AssessmentItemsAndResources materials) {
+		File directory = itemFile.getParentFile();
+
+		QueryUtils.search(Img.class, item).forEach((img) -> {
+			if(img.getSrc() != null) {
+				String imgPath = img.getSrc().toString();
+				File imgFile = new File(directory, imgPath);
+				if(imgFile.exists()) {
+					materials.addMaterial(new ItemMaterial(imgFile, imgPath));
+				}
+			}
+		});
+
+		QueryUtils.search(Object.class, item).forEach((object) -> {
+			if(StringHelper.containsNonWhitespace(object.getData())) {
+				String path = object.getData();
+				File objectFile = new File(directory, path);
+				if(objectFile.exists()) {
+					materials.addMaterial(new ItemMaterial(objectFile, path));
+				}
+			}
+		});
+	}
+	
 	public void enrichWithMetadata(QuestionItemFull qitem, ResolvedAssessmentItem resolvedAssessmentItem, ManifestBuilder manifestBuilder) {
 		ResourceType resource = manifestBuilder.getResourceTypeByHref(qitem.getRootFilename());
 		if(resource == null) {
@@ -331,8 +361,8 @@ public class QTI21ExportProcessor {
 
 	private static final class AssessmentItemsAndResources {
 		private final Set<String> paths = new HashSet<String>();
-		private final List<ResolvedAssessmentItem> itemEls = new ArrayList<ResolvedAssessmentItem>();
-		private final List<ItemMaterial> materials = new ArrayList<ItemMaterial>();
+		private final List<ResolvedAssessmentItem> itemEls = new ArrayList<>();
+		private final List<ItemMaterial> materials = new ArrayList<>();
 		
 		public Set<String> getPaths() {
 			return paths;
@@ -356,16 +386,16 @@ public class QTI21ExportProcessor {
 	}
 	
 	private static final class ItemMaterial {
-		private final VFSLeaf leaf;
+		private final File file;
 		private final String exportUri;
 		
-		public ItemMaterial(VFSLeaf leaf, String exportUri) {
-			this.leaf = leaf;
+		public ItemMaterial(File file, String exportUri) {
+			this.file = file;
 			this.exportUri = exportUri;
 		}
 		
-		public VFSLeaf getLeaf() {
-			return leaf;
+		public File getFile() {
+			return file;
 		}
 		
 		public String getExportUri() {
diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
index 6010b463379fb6eef1049367ab008212dfdb4be3..4f65ee540e308f88b1d76aed585079e5786815a4 100644
--- a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
+++ b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
@@ -458,7 +458,7 @@ public class QTI21AssessmentTestHandler extends FileHandler {
 	@Override
 	public boolean cleanupOnDelete(RepositoryEntry entry, OLATResourceable res) {
 		boolean clean = super.cleanupOnDelete(entry, res);
-		assessmentTestSessionDao.deleteAllUserTestSessions(entry);
+		assessmentTestSessionDao.deleteAllUserTestSessionsByTest(entry);
 		return clean;
 	}
 
diff --git a/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java b/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java
index 03cb37f6692af444c0d758df0f7e321835803735..18b08a9e9ce0ac0dfa11073f647cad32f586b27e 100644
--- a/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/AbstractItemListController.java
@@ -55,6 +55,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.OLATResourceable;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.event.EventBus;
 import org.olat.core.util.event.GenericEventListener;
 import org.olat.modules.qpool.QPoolService;
@@ -109,7 +110,6 @@ public abstract class AbstractItemListController extends FormBasicController
 		
 		extendedSearchCtrl = new ExtendedSearchController(ureq, getWindowControl(), key, mainForm);
 		extendedSearchCtrl.setEnabled(false);
-		listenTo(extendedSearchCtrl);
 		
 		initForm(ureq);
 		
@@ -167,6 +167,7 @@ public abstract class AbstractItemListController extends FormBasicController
 		itemsTable.setExtendedSearch(extendedSearchCtrl);
 		itemsTable.setColumnIndexForDragAndDropLabel(Cols.title.ordinal());
 		itemsTable.setAndLoadPersistedPreferences(ureq, "qpool-list-" + prefsKey);
+		listenTo(extendedSearchCtrl);
 		
 		VelocityContainer detailsVC = createVelocityContainer("item_list_details");
 		itemsTable.setDetailsRenderer(detailsVC, this);
@@ -225,6 +226,16 @@ public abstract class AbstractItemListController extends FormBasicController
 
 	@Override
 	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(extendedSearchCtrl == source) {
+			if(event == Event.CANCELLED_EVENT) {
+				String quickSearch = itemsTable.getQuickSearchString();
+				if(StringHelper.containsNonWhitespace(quickSearch)) {
+					itemsTable.quickSearch(ureq, quickSearch);
+				} else {
+					itemsTable.resetSearch(ureq);
+				}
+			}
+		}
 		super.event(ureq, source, event);
 	}
 
diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
index 186f83390968a4c83d72cb0485297549d60805fb..948a7ceb56af9031713d3a40b8e308f1e035627d 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
@@ -60,6 +60,7 @@ import org.olat.core.util.vfs.VFSManager;
 import org.olat.course.assessment.manager.AssessmentModeDAO;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.course.certificate.CertificatesManager;
+import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.modules.assessment.manager.AssessmentEntryDAO;
 import org.olat.modules.reminder.manager.ReminderDAO;
 import org.olat.repository.ErrorList;
@@ -136,6 +137,8 @@ public class RepositoryServiceImpl implements RepositoryService {
 	@Autowired
 	private AssessmentModeDAO assessmentModeDao;
 	@Autowired
+	private AssessmentTestSessionDAO assessmentTestSessionDao;
+	@Autowired
 	private PersistentTaskDAO persistentTaskDao;
 	@Autowired
 	private ReminderDAO reminderDao;
@@ -400,7 +403,9 @@ public class RepositoryServiceImpl implements RepositoryService {
 		// referenced resourceable a swell.
 		handler.cleanupOnDelete(entry, resource);
 		dbInstance.commit();
-		
+
+		//delete all test sessions
+		assessmentTestSessionDao.deleteAllUserTestSessionsByCourse(entry);
 		//nullify the reference
 		assessmentEntryDao.removeEntryForReferenceEntry(entry);
 		assessmentEntryDao.deleteEntryForRepositoryEntry(entry);