diff --git a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java
index d14a9b6ff171e792d5698e28d1b351f06f0f7696..5f391a64c432dc149c0994cb0540bad0d4ddb46f 100644
--- a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java
+++ b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java
@@ -20,16 +20,25 @@
 package de.bps.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.Date;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.ValidationStatus;
 import org.olat.core.util.WebappHelper;
@@ -51,6 +60,7 @@ import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
@@ -74,7 +84,8 @@ import de.bps.olat.modules.cl.CheckpointMode;
  * @author skoeber <skoeber@bps-system.de>
  */
 public class ChecklistCourseNode extends AbstractAccessableCourseNode {
-	
+	private static final long serialVersionUID = -8978938639489414749L;
+	private static final OLog log = Tracing.createLoggerFor(ChecklistCourseNode.class);
 	private static final String TYPE = "cl";
 	public static final String CONF_COURSE_ID = "cl_course_id";
 	public static final String CONF_COURSE_NODE_ID = "cl_course_node_id";
@@ -304,16 +315,23 @@ public class ChecklistCourseNode extends AbstractAccessableCourseNode {
 	}
 	
 	@Override
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		XStream xstream = new XStream();
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		String filename = "checklist_"
+				+ StringHelper.transformDisplayNameToFileSystemName(getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+		
 		Checklist checklist = loadOrCreateChecklist(course.getCourseEnvironment().getCoursePropertyManager());
-		String exportContent = xstream.toXML(checklist);
-		String exportFilename = ExportUtil.createFileNameWithTimeStamp("checklist_"+this.getIdent(), "xml");
-		ExportUtil.writeContentToFile(exportFilename, exportContent, exportDirectory, WebappHelper.getDefaultCharset());		
-	
-  	return true;
+		String exportContent = XStreamHelper.createXStreamInstance().toXML(checklist);
+		try {
+			exportStream.putNextEntry(new ZipEntry(filename));
+			IOUtils.write(exportContent, exportStream);
+			exportStream.closeEntry();
+		} catch (IOException e) {
+			log.error("", e);
+		}
+		return true;
 	}
-	
+
 	private String getExportFilename() {
 		return "checklist_"+this.getIdent()+".xml";
 	}
diff --git a/src/main/java/de/bps/onyx/plugin/OnyxExportManager.java b/src/main/java/de/bps/onyx/plugin/OnyxExportManager.java
index 4d1f4336ba0e5abe01ce15924434175450fd9660..46066dcff9cd6a956c836eea42cbe452112a0d17 100644
--- a/src/main/java/de/bps/onyx/plugin/OnyxExportManager.java
+++ b/src/main/java/de/bps/onyx/plugin/OnyxExportManager.java
@@ -31,7 +31,10 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -112,6 +115,24 @@ public class OnyxExportManager {
 		}
 		return filename;
 	}
+	
+	public void exportResults(List<QTIResultSet> resultSets, ZipOutputStream exportStream, CourseNode currentCourseNode) {
+		final String path = createTargetFilename(currentCourseNode.getShortTitle(), "TEST");
+		for (final QTIResultSet rs : resultSets) {
+			String resultXml = getResultXml(rs.getIdentity().getName(),
+					currentCourseNode.getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE).toString(),
+					currentCourseNode.getIdent(), rs.getAssessmentID());
+
+			String filename =  path + "/" + rs.getIdentity().getName() + "_" + rs.getCreationDate() + ".xml";
+			try {
+				exportStream.putNextEntry(new ZipEntry(filename));
+				IOUtils.write(resultXml, exportStream);
+				exportStream.closeEntry();
+			} catch (IOException e) {
+				log.error("", e);
+			}
+		}
+	}
 
 	/**
 	 * Method exports the result.xmls of the given Survey in a zip file without the usernames.
diff --git a/src/main/java/org/olat/_spring/extensionContext.xml b/src/main/java/org/olat/_spring/extensionContext.xml
index b50f8cc96a9d63dae1a9a4c3a2f93e4ebb9fdacc..4015e1c541281908414843f3ba5d87a7ed9d5f1a 100644
--- a/src/main/java/org/olat/_spring/extensionContext.xml
+++ b/src/main/java/org/olat/_spring/extensionContext.xml
@@ -826,24 +826,6 @@
 			</property>		 
 			<property name="order" value="11" />
 		</bean>
-		
-		
-		<!-- Extension for SCORM Results export -->	
-		<bean class="org.olat.modules.scorm.archiver.ArchiverActionExtension" init-method="initExtensionPoints">
-			<property name="actionController">	
-				<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
-					<property name="className" value="org.olat.modules.scorm.archiver.ScormResultArchiveController"/>
-				</bean>
-			</property>
-			<property name="extensionPoints">
-				<list>	
-					<value>org.olat.course.archiver.ArchiverMainController</value>		
-				</list>
-			</property>
-			<property name="order" value="35" />
-		</bean>
-		 
-		<!-- portfolioContext.xml : property name="order" value="37" -->
 				
 	<!-- template for extension of type GenericActionExtension
 		<bean id="NAMEIToptional" class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
@@ -882,5 +864,4 @@
 			<property name="order" value="38" />
 		</bean>	 -->
 
-
 </beans>
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/components/panel/Panel.java b/src/main/java/org/olat/core/gui/components/panel/Panel.java
index 720944d0ca41e8f3f20d693c83e9e49b53574319..d2b046a39f50c3b2fd556ff53981e9f3edf67f1e 100644
--- a/src/main/java/org/olat/core/gui/components/panel/Panel.java
+++ b/src/main/java/org/olat/core/gui/components/panel/Panel.java
@@ -46,7 +46,7 @@ public class Panel extends Container {
 	private static final ComponentRenderer RENDERER = new PanelRenderer();
 
 	private Component curContent;
-	protected final List<Component> stackList = new ArrayList<Component>(3);; // allow access to extending classes
+	protected final List<Component> stackList = new ArrayList<Component>(3); // allow access to extending classes
 
 	/**
 	 * @param name
diff --git a/src/main/java/org/olat/core/util/vfs/VFSManager.java b/src/main/java/org/olat/core/util/vfs/VFSManager.java
index dcc61daebc982f441e40135fc8c1f2ea8ec83879..7fea9be18c3dd790c4ef00c6d3b0455934baf256 100644
--- a/src/main/java/org/olat/core/util/vfs/VFSManager.java
+++ b/src/main/java/org/olat/core/util/vfs/VFSManager.java
@@ -115,6 +115,14 @@ public class VFSManager extends BasicManager {
 		return false;
 	}
 	
+	public static boolean isDirectoryAndNotEmpty(VFSItem directory){
+		if(directory instanceof VFSContainer) {
+			List<VFSItem> children = ((VFSContainer)directory).getItems();
+			return !children.isEmpty();
+		}
+		return false; 
+	}
+	
 	/**
 	 * @see org.olat.core.util.vfs.VFSItem#resolveFile(java.lang.String)
 	 */
diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java
index 8036a731b2fa9b07b850587f07521ca902d2a1d5..daf48f5929550082552f1207859a64337f050a99 100644
--- a/src/main/java/org/olat/course/CourseFactory.java
+++ b/src/main/java/org/olat/course/CourseFactory.java
@@ -26,8 +26,11 @@
 package org.olat.course;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -35,7 +38,9 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.poi.util.IOUtils;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.basesecurity.Constants;
@@ -1188,87 +1193,76 @@ public class CourseFactory extends BasicManager {
 			}
 		}
 	}
-}
-
-
-
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.
-*/
+	
+	private static class NodeArchiveVisitor implements Visitor {
+		private File exportPath;
+		private Locale locale;
+		private ICourse course;
+		private String charset;
 
-class NodeArchiveVisitor implements Visitor {
-	private File exportPath;
-	private Locale locale;
-	private ICourse course;
-	private String charset;
+		/**
+		 * @param locale
+		 * @param course
+		 * @param exportPath
+		 * @param charset
+		 */
+		public NodeArchiveVisitor(Locale locale, ICourse course, File exportPath, String charset) {
+			this.locale = locale;
+			this.exportPath = exportPath;
+			//o_clusterOk by guido: save to hold reference to course inside editor
+			this.course = course;
+			this.charset = charset;
+		}
 
-	/**
-	 * @param locale
-	 * @param course
-	 * @param exportPath
-	 * @param charset
-	 */
-	public NodeArchiveVisitor(Locale locale, ICourse course, File exportPath, String charset) {
-		this.locale = locale;
-		this.exportPath = exportPath;
-		//o_clusterOk by guido: save to hold reference to course inside editor
-		this.course = course;
-		this.charset = charset;
-	}
+		/**
+		 * @see org.olat.core.util.tree.Visitor#visit(org.olat.core.util.nodes.INode)
+		 */
+		public void visit(INode node) {
+			CourseNode cn = (CourseNode) node;
 
-	/**
-	 * @see org.olat.core.util.tree.Visitor#visit(org.olat.core.util.nodes.INode)
-	 */
-	public void visit(INode node) {
-		CourseNode cn = (CourseNode) node;
-		cn.archiveNodeData(locale, course, exportPath, charset);
+			String archiveName = cn.getType() + "_"
+					+ StringHelper.transformDisplayNameToFileSystemName(cn.getShortName())
+					+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+			
+			FileOutputStream fileStream = null;
+			ZipOutputStream exportStream = null;
+			try {
+				File exportFile = new File(exportPath, archiveName);
+				fileStream = new FileOutputStream(exportFile);
+				exportStream = new ZipOutputStream(fileStream);
+				cn.archiveNodeData(locale, course, null, exportStream, charset);
+			} catch (FileNotFoundException e) {
+				log.error("", e);
+			} finally {
+				IOUtils.closeQuietly(exportStream);
+				IOUtils.closeQuietly(fileStream);
+			}
+		}
 	}
-}
-
-class NodeDeletionVisitor implements Visitor {
+	
+	private static class NodeDeletionVisitor implements Visitor {
 
-	private ICourse course;
+		private ICourse course;
 
-	/**
-	 * Constructor of the node deletion visitor
-	 * 
-	 * @param course
-	 */
-	public NodeDeletionVisitor(ICourse course) {
-		this.course = course;
-	}
+		/**
+		 * Constructor of the node deletion visitor
+		 * 
+		 * @param course
+		 */
+		public NodeDeletionVisitor(ICourse course) {
+			this.course = course;
+		}
 
-	/**
-	 * Visitor pattern to delete the course nodes
-	 * 
-	 * @see org.olat.core.util.tree.Visitor#visit(org.olat.core.util.nodes.INode)
-	 */
-	public void visit(INode node) {
-		CourseNode cNode = (CourseNode) node;
-		cNode.cleanupOnDelete(course);
+		/**
+		 * Visitor pattern to delete the course nodes
+		 * 
+		 * @see org.olat.core.util.tree.Visitor#visit(org.olat.core.util.nodes.INode)
+		 */
+		public void visit(INode node) {
+			CourseNode cNode = (CourseNode) node;
+			cNode.cleanupOnDelete(course);
+		}
 	}
-
 }
 
 /**
diff --git a/src/main/java/org/olat/course/archiver/ArchiveResource.java b/src/main/java/org/olat/course/archiver/ArchiveResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..694fecd6b4415fc82afc1f18ffe72c1a2ff41302
--- /dev/null
+++ b/src/main/java/org/olat/course/archiver/ArchiveResource.java
@@ -0,0 +1,117 @@
+/**
+ * <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.course.archiver;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Locale;
+import java.util.zip.ZipOutputStream;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.olat.core.gui.media.MediaResource;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
+import org.olat.course.nodes.CourseNode;
+import org.olat.group.BusinessGroup;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ArchiveResource implements MediaResource {
+	
+	private static final OLog log = Tracing.createLoggerFor(ArchiveResource.class);
+	
+	private final Locale locale;
+	private final String encoding = "UTF-8";
+	private final BusinessGroup group;
+	private final CourseNode courseNode;
+	private final OLATResourceable courseOres;
+	
+	public ArchiveResource(CourseNode courseNode, OLATResourceable courseOres,
+			BusinessGroup group, Locale locale) {
+		this.group = group;
+		this.locale = locale;
+		this.courseNode = courseNode;
+		this.courseOres = courseOres;
+	}
+
+	@Override
+	public String getContentType() {
+		return "application/zip";
+	}
+
+	@Override
+	public Long getSize() {
+		return null;
+	}
+
+	@Override
+	public InputStream getInputStream() {
+		return null;
+	}
+
+	@Override
+	public Long getLastModified() {
+		return null;
+	}
+
+	@Override
+	public void prepare(HttpServletResponse hres) {
+		try {
+			hres.setCharacterEncoding(encoding);
+		} catch (Exception e) {
+			log.error("", e);
+		}
+		
+		String label = courseNode.getType() + "_"
+				+ StringHelper.transformDisplayNameToFileSystemName(courseNode.getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()))
+				+ ".zip";
+		String urlEncodedLabel = StringHelper.urlEncodeISO88591(label);
+		hres.setHeader("Content-Disposition","attachment; filename=\"" + urlEncodedLabel + "\"");			
+		hres.setHeader("Content-Description", urlEncodedLabel);
+		
+		ZipOutputStream zout = null;
+		try {
+			zout = new ZipOutputStream(hres.getOutputStream());
+			zout.setLevel(9);
+			ICourse course = CourseFactory.loadCourse(courseOres);
+			courseNode.archiveNodeData(locale, course, group, zout, encoding);
+		} catch (Exception e) {
+			log.error("", e);
+		} finally {
+			IOUtils.closeQuietly(zout);
+		}
+	}
+
+	@Override
+	public void release() {
+		//
+	}
+}
diff --git a/src/main/java/org/olat/course/archiver/ArchiverMainController.java b/src/main/java/org/olat/course/archiver/ArchiverMainController.java
index 0abc8f0a98a8f89acd3c93fe59c280ae3e4edcd9..99db791db44d41db63f5112ada5985d1349443ba 100644
--- a/src/main/java/org/olat/course/archiver/ArchiverMainController.java
+++ b/src/main/java/org/olat/course/archiver/ArchiverMainController.java
@@ -51,6 +51,7 @@ import org.olat.course.ICourse;
 import org.olat.course.nodes.DialogCourseNode;
 import org.olat.course.nodes.FOCourseNode;
 import org.olat.course.nodes.ProjectBrokerCourseNode;
+import org.olat.course.nodes.ScormCourseNode;
 import org.olat.course.nodes.TACourseNode;
 import org.olat.course.nodes.WikiCourseNode;
 import org.olat.ims.qti.export.CourseQTIArchiveController;
@@ -72,6 +73,7 @@ public class ArchiverMainController extends MainLayoutBasicController {
 	private static final String CMD_FORUMS = "forums";
 	private static final String CMD_DIALOGS = "dialogs";
 	private static final String CMD_WIKIS = "wikis";
+	private static final String CMD_SCORM = "scorm";
 	
 	
 	private IArchiverCallback archiverCallback;
@@ -127,7 +129,9 @@ public class ArchiverMainController extends MainLayoutBasicController {
 			if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_CLICKED)) { // goto node in edit mode
 				TreeNode selTreeNode = menuTree.getSelectedNode();
 				Object cmd = selTreeNode.getUserObject();
-				if(cmd instanceof ActionExtension) launchExtensionController(ureq, cmd);
+				if(cmd instanceof ActionExtension) {
+					launchExtensionController(ureq, cmd);
+				}
 				else launchArchiveControllers(ureq, (String)cmd);
 			}
 		}
@@ -220,6 +224,13 @@ public class ArchiverMainController extends MainLayoutBasicController {
 			gtn.setAltText(translate("menu.wikis.alt"));
 			root.addChild(gtn);
 		}
+		if (archiverCallback.mayArchiveWikis()) {
+			gtn = new GenericTreeNode();		
+			gtn.setTitle(translate("menu.scorm"));
+			gtn.setUserObject(CMD_SCORM);
+			gtn.setAltText(translate("menu.scorm.alt"));
+			root.addChild(gtn);
+		}
 		
 		//add extension menues
 		ExtManager extm = ExtManager.getInstance();
@@ -249,40 +260,35 @@ public class ArchiverMainController extends MainLayoutBasicController {
 	private void launchArchiveControllers(UserRequest ureq, String menuCommand) {
 		if (menuCommand.equals(CMD_INDEX)) {
 			main.setContent(intro);
-		}
-		else {
+		} else {
 			removeAsListenerAndDispose(contentCtr);
 			if (menuCommand.equals(CMD_QTIRESULTS)) {
-				this.contentCtr = new CourseQTIArchiveController(ureq, getWindowControl(), ores);
+				contentCtr = new CourseQTIArchiveController(ureq, getWindowControl(), ores);
 				main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_SCOREACCOUNTING)) {
-		    this.contentCtr = new ScoreAccountingArchiveController(ureq, getWindowControl(), ores);
+			} else if (menuCommand.equals(CMD_SCOREACCOUNTING)) {
+				contentCtr = new ScoreAccountingArchiveController(ureq, getWindowControl(), ores);
 				main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_ARCHIVELOGFILES)) {
-		    this.contentCtr = new CourseLogsArchiveController(ureq, getWindowControl(), ores);
+			} else if (menuCommand.equals(CMD_ARCHIVELOGFILES)) {
+				contentCtr = new CourseLogsArchiveController(ureq, getWindowControl(), ores);
 				main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_HANDEDINTASKS)) { //TACourseNode
-		    this.contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new TACourseNode());
+			} else if (menuCommand.equals(CMD_HANDEDINTASKS)) { //TACourseNode
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new TACourseNode());
 				main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_PROJECTBROKER)) { 
-		    this.contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new ProjectBrokerCourseNode());
+			} else if (menuCommand.equals(CMD_PROJECTBROKER)) { 
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new ProjectBrokerCourseNode());
+				main.setContent(contentCtr.getInitialComponent());
+			} else if (menuCommand.equals(CMD_FORUMS)) {
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new FOCourseNode());
+				main.setContent(contentCtr.getInitialComponent());
+			} else if (menuCommand.equals(CMD_DIALOGS)) {
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new DialogCourseNode());
+				main.setContent(contentCtr.getInitialComponent());
+			} else if (menuCommand.equals(CMD_WIKIS)) {
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new WikiCourseNode());
+				main.setContent(contentCtr.getInitialComponent());
+			} else if (menuCommand.equals(CMD_SCORM)) {
+				contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new ScormCourseNode());
 				main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_FORUMS)) {
-		    this.contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new FOCourseNode());
-		    main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_DIALOGS)) {
-		    this.contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new DialogCourseNode());
-		    main.setContent(contentCtr.getInitialComponent());
-			}
-			else if (menuCommand.equals(CMD_WIKIS)) {
-		    this.contentCtr = new GenericArchiveController(ureq, getWindowControl(), ores, new WikiCourseNode());
-		    main.setContent(contentCtr.getInitialComponent());
 			}
 			listenTo(contentCtr);
 		}		
diff --git a/src/main/java/org/olat/course/archiver/ChooseGroupController.java b/src/main/java/org/olat/course/archiver/ChooseGroupController.java
new file mode 100644
index 0000000000000000000000000000000000000000..dec685e676c1e69a2fdf8d62b94a60de4d8835bf
--- /dev/null
+++ b/src/main/java/org/olat/course/archiver/ChooseGroupController.java
@@ -0,0 +1,108 @@
+/**
+ * <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.course.archiver;
+
+import java.util.List;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+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.util.StringHelper;
+import org.olat.course.nodes.CourseNode;
+import org.olat.group.BusinessGroup;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ChooseGroupController extends FormBasicController {
+	
+	private final CourseNode courseNode;
+	private final List<BusinessGroup> relatedGroups;
+	private SingleSelection selectGroupEl;
+	
+	public ChooseGroupController(UserRequest ureq, WindowControl wControl,
+			CourseNode courseNode, List<BusinessGroup> relatedGroups) {
+		super(ureq, wControl);
+		this.courseNode = courseNode;
+		this.relatedGroups = relatedGroups;
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		setFormDescription("select.group.desc");
+		
+		String[] theKeys = new String[1 + relatedGroups.size()];
+		theKeys[0] = "all";
+		String[] theValues = new String[1 + relatedGroups.size()];
+		theValues[0] = translate("select.group.all");
+		for(int i=0; i<relatedGroups.size(); i++) {
+			theKeys[i+1] = Integer.toString(i);
+			theValues[i+1] = StringHelper.escapeHtml(relatedGroups.get(i).getName());
+		}
+		selectGroupEl = uifactory.addDropdownSingleselect("select.group", formLayout, theKeys, theValues, null);
+		
+		FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator());
+		formLayout.add(buttonLayout);
+		buttonLayout.setRootForm(mainForm);
+		uifactory.addFormSubmitButton("ok", buttonLayout);
+		uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl());
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+	
+	public BusinessGroup getSelectedGroup() {
+		if(!selectGroupEl.isOneSelected() || selectGroupEl.isSelected(0)) {
+			return null;
+		}
+		String key = selectGroupEl.getSelectedKey();
+		if(StringHelper.isLong(key)) {
+			int pos = Integer.parseInt(key);
+			if(pos >= 0 && pos <relatedGroups.size()) {
+				return relatedGroups.get(pos);
+			}
+		}
+		return null;
+	}
+
+	public CourseNode getCourseNode() {
+		return courseNode;
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		fireEvent(ureq, Event.DONE_EVENT);
+	}
+
+	@Override
+	protected void formCancelled(UserRequest ureq) {
+		fireEvent(ureq, Event.CANCELLED_EVENT);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/archiver/CourseForumsArchiveController.java b/src/main/java/org/olat/course/archiver/CourseForumsArchiveController.java
deleted file mode 100644
index 51c642c0bd66c4bf6604eac8a9299485f00da85c..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/course/archiver/CourseForumsArchiveController.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.
-*/
-
-package org.olat.course.archiver;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.Component;
-import org.olat.core.gui.components.panel.Panel;
-import org.olat.core.gui.components.table.ColumnDescriptor;
-import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
-import org.olat.core.gui.components.table.DefaultColumnDescriptor;
-import org.olat.core.gui.components.table.Table;
-import org.olat.core.gui.components.table.TableController;
-import org.olat.core.gui.components.table.TableEvent;
-import org.olat.core.gui.components.table.TableGuiConfiguration;
-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;
-import org.olat.core.id.OLATResourceable;
-import org.olat.course.CourseFactory;
-import org.olat.course.ICourse;
-import org.olat.course.assessment.AssessmentHelper;
-import org.olat.course.assessment.IndentedNodeRenderer;
-import org.olat.course.assessment.NodeTableDataModel;
-import org.olat.course.nodes.CourseNode;
-import org.olat.course.nodes.FOCourseNode;
-import org.olat.user.UserManager;
-
-/**
- * @author schneider
- * Comment:  
- * Archives  the user selected forum of a course to the personal folder of this user.
- */
-public class CourseForumsArchiveController extends BasicController {
-	private static final String CMD_SELECT_NODE = "cmd.select.node";
-	
-	private Panel main;	
-	private VelocityContainer nodeChoose;
-	private NodeTableDataModel nodeTableModel;
-	private TableController nodeListCtr;
-	private FOCourseNode currentCourseNode;
-
-	private OLATResourceable ores;
-	
-	/**
-	 * Constructor for the assessment tool controller. 
-	 * @param ureq
-	 * @param wControl
-	 * @param course
-	 */
-	public CourseForumsArchiveController(UserRequest ureq, WindowControl wControl, OLATResourceable ores) {
-		super(ureq, wControl);
-		this.ores = ores;
-		main = new Panel("main");
-		nodeChoose = createVelocityContainer("fonodechoose");
-		doNodeChoose(ureq);		
-		putInitialPanel(main);
-	}
-	
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
-	 *      org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
-	 */
-	public void event(UserRequest ureq, Component source, Event event) {
-		//no interesting events
-	}
-	
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
-	 *      org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
-	 */
-	public void event(UserRequest ureq, Controller source, Event event) {
-		if (source == nodeListCtr) {
-			if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) {
-				TableEvent te = (TableEvent) event;
-				String actionid = te.getActionId();
-				if (actionid.equals(CMD_SELECT_NODE)) {
-					int rowid = te.getRowId();
-					Map nodeData = (Map) nodeTableModel.getObject(rowid);
-					ICourse course = CourseFactory.loadCourse(ores);
-					CourseNode node = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
-					this.currentCourseNode = (FOCourseNode) node;
-					// cast should be save, only ta course nodes nodes are selectable
-					boolean successfullyArchived = archiveForumNode(ureq);
-					if (successfullyArchived) {
-					  showInfo("archive.fo.successfully");	  
-					} else {
-						showWarning("archive.fo.notsuccessfully");	
-					}
-				}
-			}
-		}
-	}
-	
-	/**
-	 * 
-	 * @param ureq
-	 */
-	private void doNodeChoose(UserRequest ureq){
-	    //table configuraton
-		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
-		tableConfig.setTableEmptyMessage(translate("fonodesoverview.nonodes"));
-		tableConfig.setDownloadOffered(false);
-		tableConfig.setColumnMovingOffered(false);
-		tableConfig.setSortingEnabled(false);
-		tableConfig.setDisplayTableHeader(true);
-		tableConfig.setDisplayRowCount(false);
-		tableConfig.setPageingEnabled(false);
-		
-		removeAsListenerAndDispose(nodeListCtr);
-		nodeListCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator());
-		listenTo(nodeListCtr);
-		
-		// table columns		
-		nodeListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.node", 0, 
-				null, ureq.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, new IndentedNodeRenderer()));
-		nodeListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.action.select", 1,
-				CMD_SELECT_NODE, ureq.getLocale()));
-		
-		// get list of course node data and populate table data model
-		ICourse course = CourseFactory.loadCourse(ores);
-		CourseNode rootNode = course.getRunStructure().getRootNode();
-		List nodesTableObjectArrayList = addForumNodesAndParentsToList(0, rootNode);
-		
-		// only populate data model if data available
-		if (nodesTableObjectArrayList == null) {
-			nodeChoose.contextPut("hasForumNodes", Boolean.FALSE);
-		} else {
-		    nodeChoose.contextPut("hasForumNodes", Boolean.TRUE);
-			nodeTableModel = new NodeTableDataModel(nodesTableObjectArrayList, getTranslator());
-			nodeListCtr.setTableDataModel(nodeTableModel);
-			nodeChoose.put("fonodeTable", nodeListCtr.getInitialComponent());
-		}
-		
-		// set main content to nodechoose, do not use wrapper
-		main.setContent(nodeChoose);
-		
-	}
-	
-	/**
-	 * Recursive method that adds forum nodes and all its parents to a list
-	 * @param recursionLevel
-	 * @param courseNode
-	 * @return A list of maps containing the node data
-	 */
-	@SuppressWarnings("unchecked")
-	private List addForumNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
-		// 1) Get list of children data using recursion of this method
-		List childrenData = new ArrayList();
-		for (int i = 0; i < courseNode.getChildCount(); i++) {
-			CourseNode child = (CourseNode) courseNode.getChildAt(i);
-			List childData = addForumNodesAndParentsToList( (recursionLevel + 1),  child);
-			if (childData != null)
-				childrenData.addAll(childData);
-		}
-		
-		if (childrenData.size() > 0 || courseNode instanceof FOCourseNode) {
-			// Store node data in map. This map array serves as data model for 
-			// the tasks overview table. Leave user data empty since not used in
-			// this table. (use only node data)
-			Map nodeData = new HashMap();
-			// indent	
-			nodeData.put(AssessmentHelper.KEY_INDENT, new Integer(recursionLevel));
-			// course node data
-			nodeData.put(AssessmentHelper.KEY_TYPE, courseNode.getType());
-			nodeData.put(AssessmentHelper.KEY_TITLE_SHORT, courseNode.getShortTitle());
-			nodeData.put(AssessmentHelper.KEY_TITLE_LONG, courseNode.getLongTitle());
-			nodeData.put(AssessmentHelper.KEY_IDENTIFYER, courseNode.getIdent());
-			
-			if (courseNode instanceof FOCourseNode){
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.TRUE);
-			}
-			else {
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.FALSE);
-			}
-			
-			List nodeAndChildren = new ArrayList();
-			nodeAndChildren.add(nodeData);
-
-			nodeAndChildren.addAll(childrenData);
-			return nodeAndChildren;
-		}
-		return null;
-	}
-	
-	private boolean archiveForumNode(UserRequest ureq){
-		ICourse course = CourseFactory.loadCourse(ores);
-    File exportDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), course.getCourseTitle());
-    UserManager um = UserManager.getInstance();
-    String charset = um.getUserCharset(ureq.getIdentity());
-    return  currentCourseNode.archiveNodeData(ureq.getLocale(), course, exportDir, charset);    
-	}
-	
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
-	 */
-	protected void doDispose() {
-		//
-	}
-}
diff --git a/src/main/java/org/olat/course/archiver/GenericArchiveController.java b/src/main/java/org/olat/course/archiver/GenericArchiveController.java
index c4c091212d34de2368a4bea5fa66f995587dd749..38993f05c671b04053dc79c58bb67635c75ef49b 100644
--- a/src/main/java/org/olat/course/archiver/GenericArchiveController.java
+++ b/src/main/java/org/olat/course/archiver/GenericArchiveController.java
@@ -25,11 +25,8 @@
 
 package org.olat.course.archiver;
 
-import java.io.File;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -46,14 +43,17 @@ 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;
+import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
 import org.olat.core.id.OLATResourceable;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
-import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.IndentedNodeRenderer;
 import org.olat.course.assessment.NodeTableDataModel;
+import org.olat.course.assessment.NodeTableRow;
+import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.CourseNode;
-import org.olat.user.UserManager;
+import org.olat.course.nodes.TACourseNode;
+import org.olat.group.BusinessGroup;
 
 /**
  * @author schnider Comment: Archives the User selected wiki's to the personal
@@ -62,13 +62,15 @@ import org.olat.user.UserManager;
 public class GenericArchiveController extends BasicController {
 	
 	private static final String CMD_SELECT_NODE = "cmd.select.node";
-	private Panel main;	
-	private VelocityContainer nodeChoose;
-	private NodeTableDataModel nodeTableModel;
+	
+	private final Panel main;
 	private TableController nodeListCtr;
-	protected CourseNode currentCourseNode;
-	private CourseNode nodeType;
-	protected OLATResourceable ores;
+	private NodeTableDataModel nodeTableModel;
+	private CloseableModalController cmc;
+	private ChooseGroupController chooseGroupCtrl;
+	
+	private final CourseNode nodeType;
+	private final OLATResourceable ores;
 
 	/**
 	 * Constructor for the assessment tool controller.
@@ -82,52 +84,57 @@ public class GenericArchiveController extends BasicController {
 
 		this.ores = ores;
 		this.nodeType = nodeType;
+		
 		main = new Panel("main");
-		nodeChoose = createVelocityContainer("nodechoose");
+		VelocityContainer nodeChoose = createVelocityContainer("nodechoose");
 		nodeChoose.contextPut("nodeType",nodeType.getType());
-		doNodeChoose(ureq);		
+		doNodeChoose(ureq, nodeChoose);		
 		putInitialPanel(main);
 	}
 
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
-	 *      org.olat.core.gui.components.Component,
-	 *      org.olat.core.gui.control.Event)
-	 */
+	@Override
 	public void event(UserRequest ureq, Component source, Event event) {
 		// no interesting events
 	}
 
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
-	 *      org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
-	 */
+	@Override
 	public void event(UserRequest ureq, Controller source, Event event) {
 		if (source == nodeListCtr) {
 			if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) {
-				ICourse course = CourseFactory.loadCourse(ores);
-				TableEvent te = (TableEvent) event;
+				TableEvent te = (TableEvent)event;
 				String actionid = te.getActionId();
 				if (actionid.equals(CMD_SELECT_NODE)) {
-					int rowid = te.getRowId();
-					Map nodeData = (Map) nodeTableModel.getObject(rowid);
-					CourseNode node = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
-					this.currentCourseNode = node;
-					boolean successfullyArchived = archiveNode(ureq);		
-					if(successfullyArchived) {
-					  showInfo("archive."+nodeType.getType()+".successfully");
-					} else {
-						showWarning("archive."+nodeType.getType()+".notsuccessfully");
-					}
+					NodeTableRow nodeData = nodeTableModel.getObject(te.getRowId());
+					doSelectNode(ureq, nodeData);
 				}
 			}
+		} else if(source == chooseGroupCtrl) {
+			cmc.deactivate();
+			CourseNode courseNode = chooseGroupCtrl.getCourseNode();
+			BusinessGroup group = chooseGroupCtrl.getSelectedGroup();
+			cleanUpPopups();
+			if(Event.DONE_EVENT == event) {
+				archiveNode(ureq, courseNode, group);
+			}
+		} else if (source == cmc) {
+			cleanUpPopups();
 		}
 	}
+	
+	/**
+	 * Aggressive clean up all popup controllers
+	 */
+	protected void cleanUpPopups() {
+		removeAsListenerAndDispose(chooseGroupCtrl);
+		removeAsListenerAndDispose(cmc);
+		chooseGroupCtrl = null;
+		cmc = null;
+	}
 
 	/**
 	 * @param ureq
 	 */
-	private void doNodeChoose(UserRequest ureq) {
+	private void doNodeChoose(UserRequest ureq, VelocityContainer nodeChoose) {
 		// table configuraton
 		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
 		tableConfig.setTableEmptyMessage(translate("nodesoverview.nonodes"));
@@ -143,14 +150,14 @@ public class GenericArchiveController extends BasicController {
 		listenTo(nodeListCtr);
 		
 		// table columns
-		nodeListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.node", 0, null, ureq.getLocale(),
+		nodeListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.node", 0, null, getLocale(),
 				ColumnDescriptor.ALIGNMENT_LEFT, new IndentedNodeRenderer()));
-		nodeListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.action.select", 1, CMD_SELECT_NODE, ureq.getLocale()));
+		nodeListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.action.select", 1, CMD_SELECT_NODE, getLocale()));
 
 		// get list of course node data and populate table data model
 		ICourse course = CourseFactory.loadCourse(ores);
 		CourseNode rootNode = course.getRunStructure().getRootNode();
-		List nodesTableObjectArrayList = addNodesAndParentsToList(0, rootNode);
+		List<NodeTableRow> nodesTableObjectArrayList = addNodesAndParentsToList(0, rootNode);
 
 		// only populate data model if data available
 		if (nodesTableObjectArrayList == null) {
@@ -164,7 +171,6 @@ public class GenericArchiveController extends BasicController {
 
 		// set main content to nodechoose, do not use wrapper
 		main.setContent(nodeChoose);
-
 	}
 
 	/**
@@ -174,52 +180,62 @@ public class GenericArchiveController extends BasicController {
 	 * @param courseNode
 	 * @return A list of maps containing the node data
 	 */
-	@SuppressWarnings("unchecked")
-	private List addNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
+	private List<NodeTableRow> addNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
 		// 1) Get list of children data using recursion of this method
-		List childrenData = new ArrayList();
+		List<NodeTableRow> childrenData = new ArrayList<>();
 		for (int i = 0; i < courseNode.getChildCount(); i++) {
 			CourseNode child = (CourseNode) courseNode.getChildAt(i);
-			List childData = addNodesAndParentsToList((recursionLevel + 1), child);
-			if (childData != null) childrenData.addAll(childData);
+			List<NodeTableRow> childData = addNodesAndParentsToList((recursionLevel + 1), child);
+			if (childData != null) {
+				childrenData.addAll(childData);
+			}
 		}
 
-		String nodent = nodeType.getType();
 		if (childrenData.size() > 0 || courseNode.getType().equals(nodeType.getType())) {
 			// Store node data in map. This map array serves as data model for
 			// the tasks overview table. Leave user data empty since not used in
 			// this table. (use only node data)
-			Map nodeData = new HashMap();
-			// indent
-			nodeData.put(AssessmentHelper.KEY_INDENT, new Integer(recursionLevel));
-			// course node data
-			nodeData.put(AssessmentHelper.KEY_TYPE, courseNode.getType());
-			nodeData.put(AssessmentHelper.KEY_TITLE_SHORT, courseNode.getShortTitle());
-			nodeData.put(AssessmentHelper.KEY_TITLE_LONG, courseNode.getLongTitle());
-			nodeData.put(AssessmentHelper.KEY_IDENTIFYER, courseNode.getIdent());
-
-			if (courseNode.getType().equals(nodeType.getType())) {
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.TRUE);
-			} else {
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.FALSE);
-			}
-
-			List nodeAndChildren = new ArrayList();
+			NodeTableRow nodeData = new NodeTableRow(new Integer(recursionLevel), courseNode);
+			nodeData.setSelectable(courseNode.getType().equals(nodeType.getType()));
+			
+			List<NodeTableRow> nodeAndChildren = new ArrayList<>();
 			nodeAndChildren.add(nodeData);
-
 			nodeAndChildren.addAll(childrenData);
 			return nodeAndChildren;
 		}
 		return null;
 	}
-
-	protected boolean archiveNode(UserRequest ureq) {
+	
+	private void doSelectNode(UserRequest ureq, NodeTableRow nodeData) {
 		ICourse course = CourseFactory.loadCourse(ores);
-		File exportDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), course.getCourseTitle());
-		UserManager um = UserManager.getInstance();
-		String charset = um.getUserCharset(ureq.getIdentity());
-		boolean successfullyArchived = currentCourseNode.archiveNodeData(ureq.getLocale(), course, exportDir, charset);	
-		return successfullyArchived;
+		CourseNode node = course.getRunStructure().getNode(nodeData.getIdent());
+		//some node can limit the archive to a business group
+		if(node instanceof TACourseNode) {
+			CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager();
+			List<BusinessGroup> relatedGroups = cgm.getAllBusinessGroups();
+			if(relatedGroups.isEmpty()) {
+				archiveNode(ureq, node, null);
+			} else {
+				doSelectBusinessGroup(ureq, node, relatedGroups);
+			}
+		} else {
+			archiveNode(ureq, node, null);
+		}
+	}
+	
+	private void doSelectBusinessGroup(UserRequest ureq, CourseNode node, List<BusinessGroup> relatedGroups) {
+		chooseGroupCtrl = new ChooseGroupController(ureq, getWindowControl(), node, relatedGroups);
+		listenTo(chooseGroupCtrl);
+		cmc = new CloseableModalController(getWindowControl(), translate("close"), chooseGroupCtrl.getInitialComponent(),
+				true, translate("select.group"));
+		cmc.activate();
+		listenTo(cmc);
+	}
+
+	private void archiveNode(UserRequest ureq, CourseNode node, BusinessGroup group) {
+		ArchiveResource aResource = new ArchiveResource(node, ores, group, getLocale());
+		ureq.getDispatchResult().setResultingMediaResource(aResource);
+		showInfo("archive." + nodeType.getType() + ".successfully");
 	}
 
 	/**
@@ -228,5 +244,4 @@ public class GenericArchiveController extends BasicController {
 	protected void doDispose() {
 		//
 	}
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/archiver/ScoreAccountingArchiveController.java b/src/main/java/org/olat/course/archiver/ScoreAccountingArchiveController.java
index 4d73b384b464115ee824cc834b9135686d261f0f..295ed6f244ef1cf0430f09c6bc1ca9186dd1084e 100644
--- a/src/main/java/org/olat/course/archiver/ScoreAccountingArchiveController.java
+++ b/src/main/java/org/olat/course/archiver/ScoreAccountingArchiveController.java
@@ -34,17 +34,14 @@ 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.DefaultController;
 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.media.FileMediaResource;
 import org.olat.core.gui.media.MediaResource;
-import org.olat.core.gui.translator.PackageTranslator;
-import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.ExportUtil;
-import org.olat.core.util.Util;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.nodes.AssessableCourseNode;
@@ -56,15 +53,12 @@ import org.olat.user.UserManager;
  * Initial Date: Sep 23, 2004
  * @author gnaegi
  */
-public class ScoreAccountingArchiveController extends DefaultController {
-	private static final String PACKAGE = Util.getPackageName(ScoreAccountingArchiveController.class);
-	private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(PACKAGE);
+public class ScoreAccountingArchiveController extends BasicController {
 
 	private OLATResourceable ores;
 	private Panel myPanel;
 	private VelocityContainer myContent;
 	private VelocityContainer vcFeedback;
-	private Translator t;
 	private Link startButton, downloadButton;
 
 	/**
@@ -73,19 +67,13 @@ public class ScoreAccountingArchiveController extends DefaultController {
 	 * @param course
 	 */
 	public ScoreAccountingArchiveController(UserRequest ureq, WindowControl wControl, OLATResourceable ores) {
-		super(wControl);
+		super(ureq, wControl);
 		this.ores = ores;
 
-		this.t = new PackageTranslator(PACKAGE, ureq.getLocale());
-
-		this.myPanel = new Panel("myPanel");
-		myPanel.addListener(this);
-
-		myContent = new VelocityContainer("myContent", VELOCITY_ROOT + "/start.html", t, this);
+		myPanel = putInitialPanel(myPanel);
+		myContent = createVelocityContainer("start");
 		startButton = LinkFactory.createButtonSmall("cmd.start", myContent, this);
-		
 		myPanel.setContent(myContent);
-		setInitialComponent(myPanel);
 	}
 
 	/**
@@ -94,28 +82,7 @@ public class ScoreAccountingArchiveController extends DefaultController {
 	 */
 	public void event(UserRequest ureq, Component source, Event event) {
 		if (source == startButton) {
-			ICourse course = CourseFactory.loadCourse(ores);
-			List<Identity> users = ScoreAccountingHelper.loadUsers(course.getCourseEnvironment());
-			List<AssessableCourseNode> nodes = ScoreAccountingHelper.loadAssessableNodes(course.getCourseEnvironment());
-			
-			String result = ScoreAccountingHelper.createCourseResultsOverviewTable(users, nodes, course, ureq.getLocale());
-
-			String courseTitle = course.getCourseTitle();
-
-			String fileName = ExportUtil.createFileNameWithTimeStamp(courseTitle, "xls");
-			// location for data export
-			File exportDirectory = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), courseTitle);
-			// the user's charset
-			UserManager um = UserManager.getInstance();
-			String charset = um.getUserCharset(ureq.getIdentity());
-			
-			File downloadFile = ExportUtil.writeContentToFile(fileName, result, exportDirectory, charset);
-
-			vcFeedback = new VelocityContainer("feedback", VELOCITY_ROOT + "/feedback.html", t, this);
-			vcFeedback.contextPut("body", vcFeedback.getTranslator().translate("course.res.feedback", new String[] { fileName }));
-			downloadButton = LinkFactory.createButtonSmall("cmd.download", vcFeedback, this);
-			downloadButton.setUserObject(downloadFile);
-			myPanel.setContent(vcFeedback);
+			doStartExport();
 		} else if(source == downloadButton) {
 			File file = (File)downloadButton.getUserObject();
 			if(file != null) {
@@ -124,6 +91,31 @@ public class ScoreAccountingArchiveController extends DefaultController {
 			}
 		}
 	}
+	
+	private void doStartExport() {
+		ICourse course = CourseFactory.loadCourse(ores);
+		List<Identity> users = ScoreAccountingHelper.loadUsers(course.getCourseEnvironment());
+		List<AssessableCourseNode> nodes = ScoreAccountingHelper.loadAssessableNodes(course.getCourseEnvironment());
+		
+		String result = ScoreAccountingHelper.createCourseResultsOverviewTable(users, nodes, course, getLocale());
+
+		String courseTitle = course.getCourseTitle();
+
+		String fileName = ExportUtil.createFileNameWithTimeStamp(courseTitle, "xls");
+		// location for data export
+		File exportDirectory = CourseFactory.getOrCreateDataExportDirectory(getIdentity(), courseTitle);
+		// the user's charset
+		UserManager um = UserManager.getInstance();
+		String charset = um.getUserCharset(getIdentity());
+		
+		File downloadFile = ExportUtil.writeContentToFile(fileName, result, exportDirectory, charset);
+
+		vcFeedback = createVelocityContainer("feedback");
+		vcFeedback.contextPut("body", translate("course.res.feedback", new String[] { fileName }));
+		downloadButton = LinkFactory.createButtonSmall("cmd.download", vcFeedback, this);
+		downloadButton.setUserObject(downloadFile);
+		myPanel.setContent(vcFeedback);
+	}
 
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
diff --git a/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java b/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
index 1d652a8a439c454edba1d946ae7a7aa7b4561c6d..a42d017a5506ecfc9f6be09dc3f3d64ecf273a91 100644
--- a/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
+++ b/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
@@ -376,7 +376,6 @@ public class ScoreAccountingHelper {
 	 * @param courseEnv
 	 * @return The list of identities from this course
 	 */
-	//fxdiff VCRP-1,2: access control of resources
 	public static List<Identity> loadUsers(CourseEnvironment courseEnv) {
 		CourseGroupManager gm = courseEnv.getCourseGroupManager();
 		BaseSecurity securityManager = BaseSecurityManager.getInstance();
@@ -399,6 +398,11 @@ public class ScoreAccountingHelper {
 		return userList;
 	}
 	
+	public static List<Identity> loadUsers(BusinessGroup group) {
+		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+		return securityManager.getIdentitiesOfSecurityGroup(group.getPartipiciantGroup());
+	}
+	
 	/**
 	 * Load all nodes which are assessable
 	 * 
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ar.properties
index 08b6cf782c75acf7525ca25a89ccd2c03c96552d..43ce12308a4937a018141781e95e8c65ec50a7eb 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ar.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ar.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0645\u0642\u06
 menu.scoreaccounting.alt=\u062D\u0641\u0638 \u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0646\u0647\u0627\u0626\u064A\u0629 \u0645\u0646 \u0627\u0644\u0627\u062E\u062A\u0628\u0627\u0631\u0627\u062A \u0648\u0627\u0644\u062A\u0642\u064A\u064A\u0645\u0627\u062A \u0648\u0627\u0644\u0645\u0647\u0627\u0645
 menu.wikis=\u0627\u0644\u0648\u064A\u0643\u0649
 menu.wikis.alt=\u0623\u0631\u0634\u064A\u0641 \u0627\u0644\u0648\u064A\u0643\u0649
+menu.scorm=\u0646\u062A\u0627\u0626\u062C \u0627\u0633\u0643\u0648\u0631\u0645
+menu.scorm.alt=\u0646\u062A\u0627\u0626\u062C \u0633\u0643\u0648\u0631\u0645
 nodechoose.intro.dialog=\u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u062D\u0641\u0638 \u0645\u0644\u0641 \u0627\u0644\u062F\u062E\u0648\u0644 \u0627\u0644\u062E\u0627\u0635\u0629 \u0628\u0647\u060C \u0648\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u062D\u0648\u0627\u0631 \u0627\u0644\u0645\u062D\u0641\u0648\u0638 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649\u060C \u0642\u0633\u0645 \u0627\u0644\u062E\u0627\u0635/\u0627\u0644\u0623\u0631\u0634\u064A\u0641/[\u0627\u0633\u0645 \u0627\u0644\u0645\u0642\u0631\u0631]/\u0645\u0644\u0641 \u0627\u0644\u062D\u0648\u0627\u0631_\u0645\u0646\u062A\u062F\u0649.
 nodechoose.intro.fo=\u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0645\u0646\u062A\u062F\u0649 \u0627\u0644\u062E\u0627\u0635 \u0628\u0647\u060C \u0648\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0646\u062A\u062F\u0649 \u0627\u0644\u0645\u062D\u0641\u0648\u0638 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649\u060C \u0642\u0633\u0645 \u0627\u0644\u062E\u0627\u0635/\u0627\u0644\u0623\u0631\u0634\u064A\u0641/[\u0627\u0633\u0645 \u0627\u0644\u0645\u0642\u0631\u0631]/\u0645\u0646\u062A\u062F\u0649_\u0645\u0646\u062A\u062F\u0649.
 nodechoose.intro.projectbroker=\u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u062D\u0641\u0638 \u0645\u0648\u0627\u0636\u064A\u0639 \u0627\u0644\u062A\u0628\u0627\u062F\u0644 \u0627\u0644\u062E\u0627\u0635 \u0628\u0647\u060C \u0648\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0645\u0648\u0627\u0636\u064A\u0639 \u0627\u0644\u062A\u0628\u0627\u062F\u0644 \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649\u060C \u0642\u0633\u0645 \u0627\u0644\u062E\u0627\u0635/\u0627\u0644\u0623\u0631\u0634\u064A\u0641/[\u0627\u0633\u0645 \u0627\u0644\u0645\u0642\u0631\u0631]/\u0645\u0648\u0636\u0648\u0639 \u0627\u0644\u062A\u0628\u0627\u062F\u0644.
 nodechoose.intro.ta=\u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0645\u0647\u0627\u0645/\u0627\u0644\u062D\u0644\u0648\u0644 \u0627\u0644\u062E\u0627\u0635\u0629 \u0628\u0647\u060C \u0648\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0647\u0627\u0645/\u0627\u0644\u062D\u0644\u0648\u0644 \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649\u060C \u0642\u0633\u0645 \u0627\u0644\u062E\u0627\u0635/\u0627\u0644\u0623\u0631\u0634\u064A\u0641/[\u0627\u0633\u0645 \u0627\u0644\u0645\u0642\u0631\u0631]/\u0627\u0644\u0645\u0647\u0645\u0629_[\u0627\u0633\u0645 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631] \u0643\u0645\u0644\u0641 \u0645\u0636\u063A\u0648\u0637.
 nodechoose.intro.wiki=\u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631 \u062D\u062A\u0649 \u064A\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0648\u064A\u0643\u0649 \u0627\u0644\u062E\u0627\u0635 \u0628\u0647\u060C \u0648\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u0648\u064A\u0643\u0649 \u0627\u0644\u0645\u062D\u0641\u0648\u0638 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649\u060C \u0642\u0633\u0645 \u0627\u0644\u062E\u0627\u0635/\u0627\u0644\u0623\u0631\u0634\u064A\u0641/[\u0627\u0633\u0645 \u0627\u0644\u0645\u0642\u0631\u0631]/\u0627\u0644\u0648\u064A\u0643\u0649_[\u0627\u0644\u062A\u0627\u0631\u064A\u062E\u064D].
+nodechoose.intro.scorm=\u0641\u0649 \u0627\u0644\u062D\u0648\u0627\u0631 \u0627\u0644\u062A\u0627\u0644\u0649 \u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645 \u0627\u0644\u0630\u0649 \u064A\u062A\u0645 \u062A\u0642\u064A\u064A\u0645\u0647\u060C \u0648\u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u064A\u0647\u0627 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649.
 overview.nonodes.dialog=\u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0623\u0649 \u0645\u0644\u0641 \u062D\u0648\u0627\u0631\u0627\u062A.
 overview.nonodes.fo=\u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0623\u064A\u0629 \u0645\u0646\u062A\u062F\u064A\u0627\u062A.
 overview.nonodes.projectbroker=\u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0644\u0627 \u064A\u062A\u0636\u0645\u0646 \u0623\u0649 \u0645\u0648\u0636\u0648\u0639\u0627\u062A \u0644\u0644\u062A\u0628\u0627\u062F\u0644.
 overview.nonodes.ta=\u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0623\u064A\u0629 \u0639\u0646\u0627\u0635\u0631 \u0645\u0647\u0627\u0645.
 overview.nonodes.wiki=\u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0623\u0649 \u0648\u064A\u0643\u0649.
+overview.nonodes.scorm=\u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0639\u0644\u0649 \u0623\u0649 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645.
 projectbroker=\u062A\u0628\u0627\u062F\u0644 \u0645\u0648\u0636\u0648\u0639
 readme=\u062A\u0644\u0645\u064A\u062D\r\n\r\n\u0644\u0643\u0648\u0646\u0643 \u0645\u0633\u062A\u0641\u064A\u062F \u0645\u0646 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u0641\u0623\u0646\u062A \u0645\u0633\u0624\u0648\u0644\u0627 \u0639\u0646 \u062D\u0642\u064A\u0642\u0629 \u0623\u0646 \u0647\u0630\u0647 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0644\u0627 \u062A\u0633\u062A\u062E\u062F\u0645 \u0625\u0644\u0627 \u0639\u0644\u0649 \u0627\u0644\u0646\u062D\u0648 \u0627\u0644\u0645\u0633\u0645\u0648\u062D \u0628\u0647.\r\n\r\n\r\n- \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0634\u062E\u0635\u064A\u0629 \u0631\u0628\u0645\u0627 \u062A\u0633\u062A\u062E\u062F\u0645 \u0644\u0623\u063A\u0631\u0627\u0636 \u0627\u0644\u0628\u062D\u062B \u0648\u0627\u0644\u062A\u062F\u0631\u064A\u0633 \u0648\u0627\u0644\u062A\u0642\u064A\u064A\u0645 \u0641\u0642\u0637 \u0641\u0649 \u0645\u0627 \u064A\u062A\u0635\u0644 \u0628\u0642\u0636\u0627\u064A\u0627 \u0627\u0644\u062C\u0627\u0645\u0639\u0629.\r\n\r\n- \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0645\u062C\u0647\u0648\u0644\u0629 \u064A\u0645\u0643\u0646 \u0627\u0633\u062A\u062E\u062F\u0627\u0645\u0647\u0627 \u0641\u0649 \u0627\u0644\u0623\u063A\u0631\u0627\u0636 \u0627\u0644\u0625\u062D\u0635\u0627\u0626\u064A\u0629.\r\n\r\n- \u0642\u062F \u064A\u062A\u0645 \u062D\u0641\u0638 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0634\u062E\u0635\u064A\u0629 \u0641\u0642\u0637 \u0627\u0630\u0627 \u0643\u0627\u0646 \u0630\u0644\u0643 \u0636\u0631\u0648\u0631\u064A\u0627.\r\n\r\n- \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u063A\u064A\u0631 \u0627\u0644\u0636\u0631\u0648\u0631\u064A\u0629 \u064A\u062A\u0645 \u062D\u0630\u0641\u0647\u0627.
 showfile=\u0639\u0631\u0636 \u0645\u062C\u0644\u062F \u0627\u0644\u0623\u0631\u0634\u064A\u0641
@@ -120,4 +124,5 @@ ta=\u0645\u0647\u0627\u0645/\u062D\u0644\u0648\u0644
 table.action.select=\u0627\u062E\u062A\u064A\u0627\u0631
 table.header.node=\u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631
 tool.name=\u0623\u062F\u0627\u0629 \u0627\u0644\u0623\u0631\u0634\u064A\u0641
+scorm=SCORM
 wiki=\u0648\u064A\u0643\u0649
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_bg.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_bg.properties
index 49ab7d0f162feb449fcc31692cea28e98be1910b..d6c55d3310e44f07319657e7a918ba313494ad25 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_bg.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_bg.properties
@@ -101,3 +101,4 @@ table.action.select=\u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435
 table.header.node=\u041A\u0443\u0440\u0441\u043E\u0432 \u0435\u043B\u0435\u043C\u0435\u043D\u0442
 tool.name=\u0418\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442 \u0437\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043D\u0435
 wiki=\u0423\u0438\u043A\u0438\u0442\u0430
+scorm=SCORM
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_cs.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_cs.properties
index dc4ac5aa19f927b1fac342bea250e3dae477fffb..30c3e8901b7cd444efe885e90a5a0a0384369622 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_cs.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_cs.properties
@@ -99,4 +99,5 @@ ta=\u00DAkoly/\u0159e\u0161en\u00ED
 table.action.select=Vybrat
 table.header.node=Element kurzu
 tool.name=Z\u00E1lohovac\u00ED n\u00E1stroj
+scorm=SCORM
 wiki=Wiki
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_da.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_da.properties
index 27b66945fbea68b26f1c1b2f17af8d2e3869f52a..22e24c74827dd8d4750c686acac5a6c5eb416639 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_da.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_da.properties
@@ -76,3 +76,4 @@ menu.scoreaccounting.alt=Arkiver dine endelige resultater fra tests, vurderinger
 table.action.select=V\u00E6lg
 table.header.node=Kursuselement
 tool.name=Arkiveringsv\u00E6rkt\u00F8j
+scorm=SCORM
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_de.properties
index a350b5a0833bb7f598808ac139562a2b5500774f..8203c8d4f70a95caa61703a627aaacfd2d3a6074 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_de.properties
@@ -106,6 +106,8 @@ menu.scoreaccounting=Kursresultate
 menu.scoreaccounting.alt=Endresultate von Tests, Bewertungen und Aufgaben archivieren
 menu.wikis=Wikis
 menu.wikis.alt=Wikis archivieren
+menu.scorm=SCORM Resultate
+menu.scorm.alt=SCORM Resultate
 menu.projectbroker=Themenvergabe
 menu.projectbroker.alt=Daten der Bausteine "Themenvergabe" archivieren
 nodechoose.intro.dialog=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Dateidiskussion zu archivieren. Die archivierte Dateidiskussion finden Sie in Ihrem pers\u00F6nlichen Ordner unter private/archive/[Kursname]/Dateidiskussion_[forum_id]
@@ -113,16 +115,23 @@ nodechoose.intro.fo=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Forum zu a
 nodechoose.intro.ta=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Aufgaben/L\u00F6sungen zu archivieren. Die archivierten Aufgaben/L\u00F6sungen finden Sie in Ihrem pers\u00F6nlichem Ordner unter private/archive/[Kursname]/task_[Bausteinname] als ZIP-Datei.
 nodechoose.intro.wiki=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Wikis zu archivieren. Die archivierten Wikis finden Sie in Ihrem pers\u00F6nlichem Ordner unter private/archive/[Kursname]/Bausteinname_[Datum] als ZIP-Datei.
 nodechoose.intro.projectbroker=W\u00E4hlen Sie einen Kursbaustein aus, um dessen Themenvergabe zu archivieren. Die archivierte Themenvergabe finden Sie in Ihrem pers\u00F6nlichen Ordner unter private/archive/[Kursname]/projectbroker_[id]
+nodechoose.intro.scorm=W\u00E4hlen Sie im folgenden Dialog den SCORM Baustein aus, der ausgewertet werden soll. Die archivierten Resultate finden Sie in Ihrem pers\u00F6nlichen Ordner unter private/archive/[Kursname]/[Dateiname].
 overview.nonodes.dialog=Dieser Kurs enth\u00E4lt keine Dateidiskussionen.
 overview.nonodes.fo=Dieser Kurs enth\u00E4lt keine Foren
 overview.nonodes.ta=Dieser Kurs enth\u00E4lt keine Aufgabenkursbausteine
 overview.nonodes.wiki=Dieser Kurs enth\u00E4lt keine Wikis.
 overview.nonodes.projectbroker=Dieser Kurs enth\u00E4lt keinen Baustein "Themenvergabe".
+overview.nonodes.scorm=Dieser Kurs hat keinen SCORM Baustein.
+select.group=Gruppe ausw\u00E4hlen
+select.group.all=Alle Teilnehmer
+select.group.desc=Sie k\u00F6nnen den Download auf einem bestimmte Gruppe beschr\u00E4nken, oder nicht.
 readme=Hinweis \n \n Als Empf\u00E4nger bzw. Empf\u00E4ngerin der archivierten Daten sind Sie daf\u00FCr verantwortlich, dass die Daten nur im erlaubten Rahmen verwendet werden. \n \n \n- Personenbezogene Daten d\u00FCrfen f\u00FCr Forschung, Lehre und Evaluation verwendet werden, aber nur solange diese mit universit\u00E4ren Belangen im Zusammenhang steht. \n \n- Anonymisierte Daten k\u00F6nnen auch zu statistischen Zwecken verwendet werden. \n \n- Personenbezogene Daten d\u00FCrfen nur solange aufbewahrt werden, wie es der Zweck erfordert. \n \n- Nicht mehr ben\u00F6tigte Daten m\u00FCssen vernichtet werden.
 showfile=Archivordner anzeigen
 ta=Aufgaben/L\u00F6sungen
 table.action.select=Ausw\u00E4hlen
+table.action.download=Download
 table.header.node=Kursbaustein
 tool.name=Datenarchivierung
+scorm=SCORM
 wiki=Wikis
 projectbroker=Themenvergabe
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_el.properties
index f88911adea774803b3bfea6ce2be546b5449f9bf..dd7c84f103498155c84e99de4812e43de56ea43c 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_el.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_el.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B
 menu.scoreaccounting.alt=\u0391\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03AD\u03C4\u03B7\u03C3\u03B7 \u03C4\u03B5\u03BB\u03B9\u03BA\u03CE\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03B5\u03C3\u03BC\u03AC\u03C4\u03C9\u03BD \u03B1\u03C0\u03BF \u03C4\u03B5\u03C3\u03C4, \u03B1\u03BE\u03B9\u03BF\u03BB\u03BF\u03B3\u03AE\u03C3\u03B5\u03B9\u03C2 \u03BA\u03B1\u03B9 \u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B5\u03C2
 menu.wikis=Wikis
 menu.wikis.alt=\u0391\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03AD\u03C4\u03B7\u03C3\u03B7 Wikis
+menu.scorm=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
+menu.scorm.alt=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
 nodechoose.intro.dialog=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03AE\u03C3\u03B5\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03B4\u03B9\u03B1\u03BB\u03CC\u03B3\u03C9\u03BD. \u039F \u03B1\u03C0\u03BF\u03B8\u03B7\u03BA\u03B5\u03C5\u03BC\u03AD\u03BD\u03BF\u03C2 \u03B4\u03B9\u03AC\u03BB\u03BF\u03B3\u03BF\u03C2 \u03B2\u03C1\u03AF\u03C3\u03BA\u03B5\u03C4\u03B1\u03B9 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/\u03B4\u03B9\u03AC\u03BB\u03BF\u03B3\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD_[forum_id].
 nodechoose.intro.fo=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03AE\u03C3\u03B5\u03C4\u03B5 \u03C4\u03BF forum \u03C4\u03BF\u03C5. \u03A4\u03BF \u03B1\u03C0\u03BF\u03B8\u03B7\u03BA\u03B5\u03C5\u03BC\u03AD\u03BD\u03BF forum \u03B2\u03C1\u03AF\u03C3\u03BA\u03B5\u03C4\u03B1\u03B9 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/forum_[forum_id].
 nodechoose.intro.projectbroker=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B5\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03AE\u03C3\u03B5\u03C4\u03B5 \u03C4\u03B7\u03BD \u03B1\u03BD\u03AC\u03B8\u03B5\u03C3\u03B7 \u03B8\u03AD\u03BC\u03B1\u03C4\u03CC\u03C2 \u03C4\u03BF\u03C5. \u03A4\u03B7\u03BD \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03B7 \u03B1\u03BD\u03AC\u03B8\u03B5\u03C3\u03B7 \u03B8\u03AD\u03BC\u03B1\u03C4\u03BF\u03C2 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF\u03C4\u03B5 \u03BD\u03B1 \u03C4\u03B7 \u03B2\u03C1\u03B5\u03AF\u03C4\u03B5 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C6\u03AC\u03BA\u03B5\u03BB\u03BB\u03CC \u03C3\u03B1\u03C2, \u03C0\u03B5\u03C1\u03B9\u03BF\u03C7\u03AE private/archive/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/topic assignment_[id]
 nodechoose.intro.ta=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03AE\u03C3\u03B5\u03C4\u03B5 \u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B5\u03C2/ \u039B\u03CD\u03C3\u03B5\u03B9\u03C2 \u03C4\u03BF\u03C5. \u039F\u03B9 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03B5\u03C2 \u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B5\u03C2/ \u039B\u03CD\u03C3\u03B5\u03B9\u03C2 \u03B1\u03C0\u03BF\u03B8\u03B7\u03BA\u03B5\u03CD\u03BF\u03BD\u03C4\u03B1\u03B9 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/\u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1_[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF\u03C5 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2] \u03C9\u03C2 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF zip.
 nodechoose.intro.wiki=S\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03AE\u03C3\u03B5\u03C4\u03B5 \u03C4\u03BF Wiki. \u03A4\u03BF \u03B1\u03C0\u03BF\u03B8\u03B7\u03BA\u03B5\u03C5\u03BC\u03AD\u03BD\u03BF Wiki \u03B2\u03C1\u03AF\u03C3\u03BA\u03B5\u03C4\u03B1\u03B9 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/wiki_[\u03B7\u03BC\u03B5\u03C1\u03BF\u03BC\u03B7\u03BD\u03AF\u03B1].
+nodechoose.intro.scorm=\u03A3\u03C4\u03BF\u03BD \u03B1\u03BA\u03CC\u03BB\u03BF\u03C5\u03B8\u03BF \u03B4\u03B9\u03AC\u03BB\u03BF\u03B3\u03BF, \u03C0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B5\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM \u03C0\u03BF\u03C5 \u03B8\u03AD\u03BB\u03B5\u03C4\u03B5 \u03BD\u03B1 \u03B1\u03BE\u03B9\u03BF\u03BB\u03BF\u03B3\u03B7\u03B8\u03B5\u03AF. \u03A4\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF\u03C4\u03B5 \u03BD\u03B1 \u03C4\u03B1 \u03B2\u03C1\u03B5\u03AF\u03C4\u03B5 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF, \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5].
 overview.nonodes.dialog=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03B4\u03B9\u03B1\u03BB\u03CC\u03B3\u03BF\u03C5\u03C2 \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD.
 overview.nonodes.fo=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 forums.
 overview.nonodes.projectbroker=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03BA\u03AC\u03C0\u03BF\u03B9\u03B1 \u03B1\u03BD\u03AC\u03B8\u03B5\u03C3\u03B7 \u03B8\u03AD\u03BC\u03B1\u03C4\u03BF\u03C2.
 overview.nonodes.ta=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03B1 \u03B5\u03C1\u03B3\u03B1\u03C3\u03B9\u03CE\u03BD.
 overview.nonodes.wiki=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 Wikis.
+overview.nonodes.scorm=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B1\u03C5\u03C4\u03CC \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03BA\u03AC\u03C0\u03BF\u03B9\u03BF \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM.
 projectbroker=\u0391\u03BD\u03AC\u03B8\u03B5\u03C3\u03B7 \u03B8\u03AD\u03BC\u03B1\u03C4\u03BF\u03C2
 readme=\u03A5\u03C0\u03CC\u03B4\u03B5\u03B9\u03BE\u03B7 \n \n \u03A9\u03C2 \u03C0\u03B1\u03C1\u03B1\u03BB\u03AE\u03C0\u03C4\u03B7\u03C2 \u03C4\u03C9\u03BD \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03C9\u03BD \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03C9\u03BD \u03B5\u03AF\u03C3\u03C4\u03B5 \u03C5\u03C0\u03B5\u03CD\u03B8\u03C5\u03BD\u03BF\u03C2 \u03B3\u03B9\u03B1 \u03C4\u03B7\u03BD \u03B5\u03C0\u03B9\u03C4\u03C1\u03B5\u03C0\u03CC\u03BC\u03B5\u03BD\u03B7 \u03C7\u03C1\u03AE\u03C3\u03B7 \u03B1\u03C5\u03C4\u03CE\u03BD. \n \n \n- \u03A4\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03AC \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1 \u03BC\u03C0\u03BF\u03C1\u03BF\u03CD\u03BD \u03BD\u03B1 \u03C7\u03C1\u03B7\u03C3\u03B9\u03BC\u03BF\u03C0\u03BF\u03B9\u03BF\u03CD\u03BD\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03B3\u03B9\u03B1 \u03AD\u03C1\u03B5\u03C5\u03BD\u03B1, \u03B4\u03B9\u03B4\u03B1\u03C3\u03BA\u03B1\u03BB\u03AF\u03B1 \u03BA\u03B1\u03B9 \u03B1\u03C0\u03BF\u03C4\u03AF\u03BC\u03B7\u03C3\u03B7 \u03BC\u03CC\u03BD\u03BF \u03C3\u03B5 \u03C3\u03C7\u03AD\u03C3\u03B7 \u03BC\u03B5 \u03B8\u03AD\u03BC\u03B1\u03C4\u03B1 \u03C4\u03BF\u03C5 \u03C0\u03B1\u03BD\u03B5\u03C0\u03B9\u03C3\u03C4\u03B7\u03BC\u03AF\u03BF\u03C5. \n \n- \u03A4\u03B1 \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1 \u03B1\u03BD\u03CE\u03BD\u03C5\u03BC\u03C9\u03BD \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD \u03BC\u03C0\u03BF\u03C1\u03BF\u03CD\u03BD \u03BD\u03B1 \u03C7\u03C1\u03B7\u03C3\u03B9\u03BC\u03BF\u03C0\u03BF\u03B9\u03BF\u03CD\u03BD\u03C4\u03B1\u03B9 \u03B3\u03B9\u03B1 \u03C3\u03C4\u03B1\u03C4\u03B9\u03C3\u03C4\u03B9\u03BA\u03BF\u03CD\u03C2 \u03C3\u03BA\u03BF\u03C0\u03BF\u03CD\u03C2. \n \n- \u03A4\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03AC \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1 \u03BC\u03C0\u03BF\u03C1\u03BF\u03CD\u03BD \u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03BF\u03CD\u03BD\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03B3\u03B9\u03B1 \u03CC\u03C3\u03BF \u03B1\u03C0\u03B1\u03B9\u03C4\u03B5\u03AF\u03C4\u03B1\u03B9. \n \n- \u039C\u03B7 \u03B1\u03C0\u03B1\u03C1\u03B1\u03AF\u03C4\u03B7\u03C4\u03B1 \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1 \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03B4\u03B9\u03B1\u03B3\u03C1\u03AC\u03C6\u03BF\u03BD\u03C4\u03B1\u03B9.
 showfile=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_en.properties
index 12f57fc385e479308a177fa41aef6a035c44c60d..b83b879d03b1912dc8fe76a8eab0e5f4504bed50 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_en.properties
@@ -1,3 +1,4 @@
+
 #Mon May 16 17:10:05 CEST 2011
 archive.dialog.notsuccessfully=This file dialog could not be archived.
 archive.dialog.successfully=This file dialog has been archived in your personal folder.
@@ -108,16 +109,20 @@ menu.scoreaccounting=Course results
 menu.scoreaccounting.alt=Archive final results from tests, assessments and tasks
 menu.wikis=Wikis
 menu.wikis.alt=Archive Wikis
+menu.scorm=SCORM results
+menu.scorm.alt=SCORM results
 nodechoose.intro.dialog=Select a course element to archive its file dialog. This archived dialog can be found in your personal folder, section private/archive/[course name]/file dialog_[forum_id].
 nodechoose.intro.fo=Select a course element to archive its forum. This archived forum can be found in your personal folder, section private/archive/[course name]/forum_[forum_id].
 nodechoose.intro.projectbroker=Please select a course element to archive its topic assignment. Archived topic assignment can be found in your personal folder, section private/archive/[course's name]/topic assignment_[id]
 nodechoose.intro.ta=Select a course element in order to archive its tasks/solutions. These archived tasks/solutions are saved in your personal folder in the section private/archive/[course name]/task_[name of course element] as zip file.
 nodechoose.intro.wiki=Select a course element to archive its Wiki. This archived Wiki can be found in your personal folder, section private/archive/[course name]/wiki_[date] as zip file.
+nodechoose.intro.scorm=In the following dialog please select the SCORM element to be assessed. Archived results can be found in your personal folder, section private/archive/[course name]/[file name].
 overview.nonodes.dialog=This course does not contain any file dialogs.
 overview.nonodes.fo=This course does not contain any forums.
 overview.nonodes.projectbroker=This course does not contain any topic assignments.
 overview.nonodes.ta=This course does not contain any task elements.
 overview.nonodes.wiki=This course does not contain any Wikis.
+overview.nonodes.scorm=This course does not contain any SCORM element.
 projectbroker=Topic assignment
 readme=Directive\r\n \r\n As recipient of archived data you are responsible for the fact that these data are used only as permitted. \r\n \r\n \r\n- Personal data may be used for research, teaching, and evaluation only as far as related to university issues. \r\n \r\n- Anonymous data can also be used for statistic purposes. \r\n \r\n- Personal data may be archived only as long as necessary. \r\n \r\n- Unnecessary data have to be deleted.
 showfile=Show archive folder
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties
index a15c402a90c3662b85a0e8439f0caf3791d5f08d..e846f364e3d65dfa78b0cc5a0b5e7c30d1f0c856 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties
@@ -107,17 +107,21 @@ menu.qtiresults.alt=Archiver les donn\u00E9es des tests et des questionnaires
 menu.scoreaccounting=R\u00E9sultats des cours
 menu.scoreaccounting.alt=Archiver les r\u00E9sultats finaux des tests, des \u00E9valuations et des devoirs
 menu.wikis=Wikis
-menu.wikis.alt=Archiver Wikis 
+menu.wikis.alt=Archiver Wikis
+menu.scorm=R\u00E9sultats SCORM
+menu.scorm.alt=R\u00E9sultats SCORM
 nodechoose.intro.dialog=S\u00E9lectionnez un \u00E9l\u00E9ment de cours pour archiver ses discussions de fichiers. Les fichiers discut\u00E9s archiv\u00E9s se trouvent sous format zip dans votre dossier personnel sous private/archive/[nom_du_cours]/Dateidiskussion_[forum_id]
 nodechoose.intro.fo=S\u00E9lectionnez un \u00E9l\u00E9ment de cours pour archiver son forum. zu archivieren. Les forums archiv\u00E9s se trouvent sous format zip dans votre dossier personnel sous private/archive/[nom_du_cours]/forum_[forum_id]
 nodechoose.intro.projectbroker=S\u00E9lectionner un \u00E9l\u00E9ment de cours pour archiver son affectation des sujets. L'affectation des sujets archiv\u00E9e peut \u00EAtre trouv\u00E9e dans votre dossier personnel sous private/archive/[Kursname]/projectbroker_[id]
 nodechoose.intro.ta=S\u00E9lectionnez un \u00E9l\u00E9ment de cours pour archiver ses devoirs/solutions. Vous trouvez les devoirs/solutions achiv\u00E9es dans votre dossier personnel comme fichier zip sous private/archive/[nom_du_cours]/task_[nom de l'\u00E9l\u00E9ment].
 nodechoose.intro.wiki=S\u00E9lectionnez un \u00E9l\u00E9ment de cours pour archiver ses Wikis. Les Wikis archiv\u00E9s se trouvent sous format zip dans votre dossier personnel sous private/archive/[nom_du_cours]/Bausteinname_[date].
+nodechoose.intro.scorm=Choisir dans le dialogue suivant l'\u00E9l\u00E9ment SCORM qui doit \u00EAtre \u00E9valu\u00E9. Les r\u00E9sultats archiv\u00E9s sont d\u00E9pos\u00E9s dans votre dossier personnel sous private/archive/[nom du cours]/[nom du fichier].
 overview.nonodes.dialog=Dieser Kurs enth\u00E4lt keine Dateidiskussionen.
 overview.nonodes.fo=Dieser Kurs enth\u00E4lt keine Foren
 overview.nonodes.projectbroker=Ce cours ne contient pas d'affectation des sujets.
 overview.nonodes.ta=Dieser Kurs enth\u00E4lt keine Aufgabe-Kursbausteine
 overview.nonodes.wiki=Ce cours ne contient pas de wikis.
+overview.nonodes.scorm=Ce cours n'a pas d'\u00E9l\u00E9ment SCORM.
 projectbroker=Affectation des sujets
 readme=Attention \n \n En tant que destinataire des donn\u00E9es archiv\u00E9es, vous \u00EAtes respondable que les donn\u00E9es ne sont utilis\u00E9es que dans le cadre autoris\u00E9. \n \n \n- Les donn\u00E9es relatives au personnes peuvent \u00EAtre utilis\u00E9es pour la recherche, l'enseignement et l'\u00E9valutation, mais seulement s'ils sont li\u00E9s \u00E0 des int\u00E9r\u00EAts universitaires. \n \n- Des donn\u00E9es anonymes peuvent \u00E9galement \u00EAtre utilis\u00E9es dans des buts statistiques.\n \n- Les donn\u00E9es personnelles ne doivent \u00EAtre gard\u00E9es qu'aussi longtemps que vraiment n\u00E9cessaire.  \n \n- Les donn\u00E9es devenues superflues doivent \u00EAtre d\u00E9truites.
 showfile=Afficher dossier d'archivage
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_it.properties
index 1bb8e59a64e9e33f8c04b16c162c51af70f64deb..b8f5fee228ee34ae27f80713271da0ce08438dca 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_it.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=Risultati del corso
 menu.scoreaccounting.alt=Archiviare risultati finali di test, valutazioni e compiti
 menu.wikis=Wiki
 menu.wikis.alt=Archiviare wiki
+menu.scorm=Risultati SCORM
+menu.scorm.alt=Risultati SCORM
 nodechoose.intro.dialog=Selezioni un elemento di corso per archiviarne le discussioni documentate. Le discussioni documentate archiviate si trovano nella Sua cartella personale sotto private/archive/[nome del corso]/discussione documentata_[forum_id].
 nodechoose.intro.fo=Selezioni un elemento di corso per archiviarne il forum. Il forum archiviato si trova nella Sua cartella personale sotto private/archive/[nome del corso]/forum_[forum_id].
 nodechoose.intro.projectbroker=Selezioni un elemento di corso per archiviare l'assegnazione dei temi corrispondente. L'assegnazione dei temi archiviata si trova nella Sua cartella personale sotto private/archive/[nome del corso]/projectbroker_[id]
 nodechoose.intro.ta=Selezioni un elemento di corso per archiviarne i compiti e le soluzioni. I compiti e le soluzioni archiviati si trovano nella Sua cartella personale sotto private/archive/[nome del corso]/task_[nome dell'elemento] come file zip.
 nodechoose.intro.wiki=Selezioni un elemento di corso per archiviarne i wiki. I wiki archiviati si trovano nella Sua cartella personale sotto private/archive/[nome del corso]/nome dell'elemento_[data] come file zip.
+nodechoose.intro.scorm=Selezioni l'elemento SCORM che deve essere valutato nel dialogo seguente. I risultati archiviati si trovano nella Sua cartella personale sotto private/archive/[Nome corso]/[Nome file].
 overview.nonodes.dialog=Questo corso non contiene alcuna discussione documentata.
 overview.nonodes.fo=Questo corso non contiene alcun forum.
 overview.nonodes.projectbroker=Questo corso non contiene alcuna assegnazione dei temi.
 overview.nonodes.ta=Questo corso non contiene alcun compito.
 overview.nonodes.wiki=Questo corso non contiene alcun wiki.
+overview.nonodes.scorm=Questo corso non contiene alcun elemento SCORM.
 projectbroker=Assegnazione dei temi
 readme=Avvertenza \n \n In quanto destinataria/o dei dati archiviati, Lei \u00E8 responsabile del loro uso nel rispetto delle norme vigenti. \n \n \n- I dati personali possono essere utilizzati per la ricerca, l'insegnamento e la valutazione, ma solo in relazione ad attivit\u00E0 universitarie. \n \n- I dati anonimizzati possono essere utilizzati per statistiche. \n \n- I dati personali possono essere conservati solo per la durata necessaria alla realizzazione dello scopo cui sono destinati. \n \n- I dati caduti in disuso devono essere distrutti.
 showfile=Mostrare cartella d'archivio
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_nl_NL.properties
index 7b2b4f7ecee830cf99ff651633a5cd7a016575a2..ad5a141acfbb4776e8f2da9045a2c11fa35fc576 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_nl_NL.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_nl_NL.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=Cursus resultaten
 menu.scoreaccounting.alt=Archiveer eindresultaten van testen, beoordeling en taken
 menu.wikis=Wikis
 menu.wikis.alt=Archiveer Wikis
+menu.scorm=SCORM resultaten
+menu.scorm.alt=SCORM results
 nodechoose.intro.dialog=Selecteer een cursuselement om het te archiveren in zijn bestandsdialoog. Deze gearchiveerde dialoog kan teruggevonden worden in uw persoonlijke map, sectie private/archive/[course name]/file dialog_[forum_id].
 nodechoose.intro.fo=Selecteer een cursuselement om zijn forum te archiveren. Deze gearchiveerde forum kan teruggevonden worden in uw persoonlijke map, sectie private/archive/[course name]/forum_[forum_id].
 nodechoose.intro.projectbroker=Selecteer een cursuselement om zijn onderwerp opdracht te archiveren. Deze gearchiveerde opdracht kan teruggevonden worden in uw persoonlijke map, sectie private/archive/[course's name]/topic assignment_[id]
 nodechoose.intro.ta=Selecteer een cursuselement om zo zijn taken/oplossingen te archiveren. Deze gearchiveerde taken/oplossingen zijn opgeslagen in uw persoonlijke map in de sectie private/archive/[course name]/task_[name of course element] als een ZIP bestand.
 nodechoose.intro.wiki=Selecteer een cursuselement om zijn Wiki te archiveren. Deze gearchiveerde Wiki kan teruggevonden worden in uw persoonlijke map, sectie private/archive/[course name]/wiki_[date] als een ZIP bestand.
+nodechoose.intro.scorm=Gelieve in de volgende dialoog een SCORM element te selecteren dat moet worden beoordeeld. Gearchiveerde resultaten kunnen teruggevonden worden in uw persoonlijke map, sectie section private/archive/[cursusnaam]/[bestandsnaam].
 overview.nonodes.dialog=Deze cursus bevat geen bestandsdialogen.
 overview.nonodes.fo=Deze cursus bevat geen fora.
 overview.nonodes.projectbroker=Deze cursus bevat geen onderwerp opdrachten.
 overview.nonodes.ta=Deze cursus bevat geen opdrachtelementen.
 overview.nonodes.wiki=Deze cursus bevat geen Wiki's.
+overview.nonodes.scorm=Deze cursus bevat geen SCORM element.
 projectbroker=Onderwerp opdracht
 readme=Richtlijnen\r\n\r\n Als ontvanger van gearchiveerde data bent u er verantwoordelijk voor dat deze data alleen wordt gebruikt zoals toegestaan.\r\n\r\n\r\n- Persoonlijke data mag gebruikt worden voor onderzoek, het lesgeven en evaluatie zolang het te maken heeft met de universiteit.\r\n\r\n- Anonieme data kan ook gebruikt worden voor statistieke doeleinden.\r\n\r\n- Persoonlijke data mag enkel zolang als nodig opgeslagen worden.\r\n\r\n- Onnodige data moet verwijdert worden.
 showfile=Toon archiefmap
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pl.properties
index b61cdd0e0383439ab2cd26d17183b520f68412b0..28c2b5f1cab79401854dda455e1f660b18ffda32 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pl.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pl.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=Wyniki kursu
 menu.scoreaccounting.alt=Archiwizuj wyniki ko\u0144cowe z test\u00F3w i zada\u0144
 menu.wikis=Wiki
 menu.wikis.alt=Archiwizuj Wiki
+menu.scorm=Wyniki SCORM
+menu.scorm.alt=Wyniki SCORM
 nodechoose.intro.dialog=Wybierz element kursu, \u017Ceby zarchiwizowa\u0107 jego okno pliku. Archiwum zostanie zapisane w twoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/file dialog_[file_dialog_id].
 nodechoose.intro.fo=Wybierz element kursu, \u017Ceby zarchiwizowa\u0107 jego forum. Archiwum zostanie zapisane w twoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/forum_[forum_id].
 nodechoose.intro.projectbroker=Wybierz element kursu, \u017Ceby zarchiwizowa\u0107 przypisane zadania. Archiwum zostanie zapisane w twoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/przypisanie zadania_[id]
 nodechoose.intro.ta=Wybierz element kursu, \u017Ceby zarchiwizowa\u0107 jego zadania/rozwi\u0105zania. Archiwum zostanie zapisane w twoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/task_[nazwa elementu kursu] jako plik ZIP.
 nodechoose.intro.wiki=Wybierz element kursu by zarchiwizowa\u0107 jego wiki. To archiwum jest zapisane w Twoim prywatnym folderze w sekcji private/archive/[nazwa kursu]/wiki_[data].
+nodechoose.intro.scorm=W nast\u0119pnym oknie dialogowym wybierz element SCORM, kt\u00F3ry ma by\u0107 oceniany. Archiwum z wynikami znajdziesz w swoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/[nazwa pliku].
 overview.nonodes.dialog=Ten kurs nie zawiera elementu <b>Okno pliku</b>.
 overview.nonodes.fo=Ten kurs nie zawiera elementu\: <b>Forum</b>.
 overview.nonodes.projectbroker=Ten kurs nie posiada przypisanych zada\u0144.
 overview.nonodes.ta=Ten kurs nie zawiera elementu\: <b>Zadanie</b>.
 overview.nonodes.wiki=Kurs nie zawiera elementu <b>Wiki</b>.
+overview.nonodes.scorm=Kurs nie zawiera tre\u015Bci SCORM.
 projectbroker=Przypisanie zada\u0144
 readme=Wskaz\u00F3wka \n \n Jako odbiorca zarchiwizownych danych, jeste\u015B odpowiedzialny za nieudostepnianie ich osobom nieupowa\u017Cnionym. \n \n \n- Mo\u017Cesz ich u\u017Cywa\u0107 wy\u0142\u0105cznie w zwi\u0105zku z procesem nauki. \n \n- Dane anonimowe mog\u0105 by\u0107 \u017Ar\u00F3d\u0142em bada\u0144 statystycznych . \n \n- Dane osobowe powinny by\u0107 przechowywane jak najkr\u00F3cej. \n \n- Niepotrzebne dane musz\u0105 zosta\u0107 usuni\u0119te.
 showfile=Poka\u017C plik
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pt_BR.properties
index ad8c5d16a03852ac0c89a165156fbba842d34eba..5f6cb7ec71e29962aaa4d532fef17029e3fd6107 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_pt_BR.properties
@@ -109,16 +109,20 @@ menu.scoreaccounting=Resultados do curso
 menu.scoreaccounting.alt=Arquivar resultados finais dos testes, avalia\u00E7\u00F5es e tarefas 
 menu.wikis=Wikis
 menu.wikis.alt=Arquivar Wikis
+menu.scorm=Resultados SCORM
+menu.scorm.alt=Resultados SCORM
 nodechoose.intro.dialog=Selecionar um elemento de curso para arquivar file dialog. Este di\u00E1logo arquivado pode ser encontrado na sua pasta pessoal, se\u00E7\u00E3o confidencial/arquivo/[nomedocurso]/arquivo de di\u00E1logo_[f\u00F3rum_id].
 nodechoose.intro.fo=Selecionar um elemento de curso para arquivar f\u00F3rum. Este f\u00F3rum arquivado pode ser encontrado em sua pasta pessoal, se\u00E7\u00E3o confidencial/arquivo/[nomedocurso]/f\u00F3rum_[f\u00F3rum_id].
 nodechoose.intro.projectbroker=Por favor, selecione um elemento de curso para arquivar seu t\u00F3pico atribu\u00EDdo. T\u00F3picos atribu\u00EDdos arquivados podem ser encontrados em sua pasta pessoal, se\u00E7\u00E3o section private/archive/[course's name]/topic assignment_[id]
 nodechoose.intro.ta=Selecionar um elemento de curso para arquivar suas resolu\u00E7\u00F5es de tarefas. Estas tarefas/resolu\u00E7\u00F5es arquivadas est\u00E3o salvas em sua pasta pessoal na se\u00E7\u00E3o confidencial/arquivo/[nomedocurso]/tarefa_[nomedoelementodecurso] como arquivo zip.
 nodechoose.intro.wiki=Selecionar um elemento de curso para arquivar Wiki. Este Wiki arquivado pode ser encontrado na sua pasta pessoal, se\u00E7\u00E3o confidencial/arquivo/[nomedocurso]/wiki_[data].
+nodechoose.intro.scorm=Na janela seguinte selecione o elemento SCORM para ser avaliado. Os resultados arquivados podem ser encontrados na pasta pessoal, se\u00E7\u00E3o private/archive/[course name]/[file name].
 overview.nonodes.dialog=Este curso n\u00E3o cont\u00E9m nenhum arquivo de di\u00E1logo.
 overview.nonodes.fo=Este curso n\u00E3o cont\u00E9m nenhum f\u00F3rum.
 overview.nonodes.projectbroker=Este curso n\u00E3o cont\u00EAm quaisquer atribui\u00E7\u00F5es de t\u00F3pico.
 overview.nonodes.ta=Este curso n\u00E3o cont\u00E9m nenhum elemento de tarefa.
 overview.nonodes.wiki=Este curso n\u00E3o cont\u00E9m nenhum Wiki.
+overview.nonodes.scorm=Este curso n\u00E3o cont\u00EAm qualquer elemento SCORM.
 projectbroker=Atribui\u00E7\u00E3o de T\u00F3pico
 readme=Dica \n \n Como receptor de dados arquivados voc\u00EA \u00E9 respons\u00E1vel pelo fato de que esses dados s\u00E3o usados apenas como permitido.  \n \n \n- Dados pessoais podem ser usados para pesquisa, ensino, e avalia\u00E7\u00E3o contanto somente se relacionado \u00E0 assuntos da universidade. \n \n- Dados an\u00F4nimos podem tamb\u00E9m serem usados para finalidades de estat\u00EDstica.  \n \n- Dados pessoais devem ser arquivados somente se necess\u00E1rio. \n \n- Dados desnecess\u00E1rios tem que ser apagados.
 showfile=Exibir arquivo
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ru.properties
index bc57a78a92fba3f972a7429ef1cca0eafd8cac0f..6ead22512e5a640cc700d5cc5b65a70f2ffdf8ac 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ru.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_ru.properties
@@ -91,14 +91,18 @@ menu.scoreaccounting=\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044
 menu.scoreaccounting.alt=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043A\u043E\u043D\u0435\u0447\u043D\u044B\u0435 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u0442\u0435\u0441\u0442\u043E\u0432, \u043E\u0446\u0435\u043D\u043E\u043A \u0443\u0441\u043F\u0435\u0432\u0430\u0435\u043C\u043E\u0441\u0442\u0438 \u0438 \u0437\u0430\u0434\u0430\u043D\u0438\u0439 
 menu.wikis=\u0412\u0438\u043A\u0438
 menu.wikis.alt=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0412\u0438\u043A\u0438
+menu.scorm=SCORM \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B
+menu.scorm.alt=SCORM \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B
 nodechoose.intro.dialog=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u0443\u0440\u0441\u0430, \u0447\u0442\u043E\u0431\u044B \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u041E\u0431\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E \u043A\u0443\u0440\u0441\u0430. \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0435 \u041E\u0431\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043D\u0430\u0445\u043E\u0434\u0438\u0442\u0441\u044F \u0432 \u0412\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 \u043A\u0430\u043A zip-\u0444\u0430\u0439\u043B \u0432 \u0441\u0435\u043A\u0446\u0438\u0438 private/archive/[\u0418\u043C\u044F \u043A\u0443\u0440\u0441\u0430]/Dateidiskussion_[\u0444\u043E\u0440\u0443\u043C_id]
 nodechoose.intro.fo=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u0443\u0440\u0441\u0430, \u0447\u0442\u043E\u0431\u044B \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0424\u043E\u0440\u0443\u043C \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E \u043A\u0443\u0440\u0441\u0430. \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0424\u043E\u0440\u0443\u043C \u043D\u0430\u0445\u043E\u0434\u0438\u0442\u0441\u044F \u0432 \u0412\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 \u043A\u0430\u043A zip-\u0444\u0430\u0439\u043B \u0432 \u0441\u0435\u043A\u0446\u0438\u0438 private/archive/[\u0418\u043C\u044F \u043A\u0443\u0440\u0441\u0430]/forum_[\u0444\u043E\u0440\u0443\u043C_id]
 nodechoose.intro.ta=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u0443\u0440\u0441\u0430, \u0447\u0442\u043E\u0431\u044B \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0417\u0430\u0434\u0430\u043D\u0438\u044F/\u0420\u0435\u0448\u0435\u043D\u0438\u044F \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E \u043A\u0443\u0440\u0441\u0430. \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0417\u0430\u0434\u0430\u043D\u0438\u044F/\u0420\u0435\u0448\u0435\u043D\u0438\u044F \u043D\u0430\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u0432 \u0412\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 \u043A\u0430\u043A zip-\u0444\u0430\u0439\u043B \u0432 \u0441\u0435\u043A\u0446\u0438\u0438 private/archive/[\u0418\u043C\u044F \u043A\u0443\u0440\u0441\u0430]/task_[\u0418\u043C\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E\u0433\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430].
 nodechoose.intro.wiki=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u0443\u0440\u0441\u0430, \u0447\u0442\u043E\u0431\u044B \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0412\u0438\u043A\u0438 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E \u043A\u0443\u0440\u0441\u0430. \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0412\u0438\u043A\u0438 \u043D\u0430\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u0432 \u0412\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 \u043A\u0430\u043A zip-\u0444\u0430\u0439\u043B \u0432 \u0441\u0435\u043A\u0446\u0438\u0438  private/archive/[\u0418\u043C\u044F \u043A\u0443\u0440\u0441\u0430]/Bausteinname_[\u0418\u043C\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E\u0433\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430].
+nodechoose.intro.scorm=\u0412 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0434\u0438\u0430\u043B\u043E\u0433\u0435 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0431\u0443\u0434\u0435\u0442 \u043E\u0446\u0435\u043D\u0435\u043D. \u0410\u0440\u0445\u0438\u0432 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0439\u0442\u0438 \u0432 \u0432\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043B\u0435 private/archive/[\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u0443\u0440\u0441\u0430]/[\u0418\u043C\u044F \u0444\u0430\u0439\u043B\u0430].
 overview.nonodes.dialog=\u0423 \u044D\u0442\u043E\u0433\u043E \u043A\u0443\u0440\u0441\u0430 \u043D\u0435\u0442 \u043E\u0431\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430.
 overview.nonodes.fo=\u0423 \u044D\u0442\u043E\u0433\u043E \u043A\u0443\u0440\u0441\u0430 \u043D\u0435\u0442 \u0444\u043E\u0440\u0443\u043C\u043E\u0432
 overview.nonodes.ta=\u0423 \u044D\u0442\u043E\u0433\u043E \u043A\u0443\u0440\u0441\u0430 \u043D\u0435\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E\u0433\u043E \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430 - \u0417\u0430\u0434\u0430\u043D\u0438\u0435
 overview.nonodes.wiki=\u0423 \u044D\u0442\u043E\u0433\u043E \u043A\u0443\u0440\u0441\u0430 \u043D\u0435\u0442 \u0412\u0438\u043A\u0438.
+overview.nonodes.scorm=\u042D\u0442\u043E\u0442 \u043A\u0443\u0440\u0441 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432.
 readme=\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \n \n \u0412 \u043A\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043F\u043E\u043B\u0443\u0447\u0430\u0442\u0435\u043B\u044F \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445, \u0412\u044B \u044F\u0432\u043B\u044F\u0435\u0442\u0435\u0441\u044C \u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u043C \u0437\u0430 \u0442\u043E, \u0447\u0442\u043E\u0431\u044B \u044D\u0442\u0438 \u0434\u0430\u043D\u043D\u044B\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043B\u0438\u0441\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0432 \u0443\u0437\u0430\u043A\u043E\u043D\u0435\u043D\u043D\u044B\u0445 \u0440\u0430\u043C\u043A\u0430\u0445. \n \n \n- \u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u044B \u0432 \u043D\u0430\u0443\u0447\u043D\u044B\u0445, \u0443\u0447\u0435\u0431\u043D\u044B\u0445 \u0438 \u0430\u0442\u0442\u0435\u0441\u0442\u0430\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0446\u0435\u043B\u044F\u0445 \u0434\u043E \u0442\u0435\u0445 \u043F\u043E\u0440,  \u043F\u043E\u043A\u0430 \u044D\u0442\u043E \u043F\u043E\u0434\u043B\u0435\u0436\u0438\u0442 \u043E\u0431\u043B\u0430\u0441\u0442\u0438 \u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0441\u043A\u043E\u0433\u043E \u0443\u0441\u0442\u0430\u0432\u0430.  \n \n- \u0410\u043D\u043E\u043D\u0438\u043C\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u0442\u0430\u043A\u0436\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u044B \u0432 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u0446\u0435\u043B\u044F\u0445.  \n \n- \u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043C\u043E\u0433\u0443\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043E \u0442\u0435\u0445 \u043F\u043E\u0440, \u043F\u043E\u043A\u0430 \u043E\u043D\u0438 \u0432\u043E\u0441\u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u044B.  \n \n- \u041D\u0435\u043D\u0443\u0436\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435,  \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u0443\u043D\u0438\u0447\u0442\u043E\u0436\u0435\u043D\u044B. 
 showfile=\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0444\u0430\u0439\u043B
 ta=\u0417\u0430\u0434\u0430\u043D\u0438\u044F/\u0420\u0435\u0448\u0435\u043D\u0438\u044F
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_CN.properties
index 5f7d79ab5f1e4f3dea4b7ae860c04e6616f1428f..916325adcfdead52f8e7c4568364bb018da98b73 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_CN.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_CN.properties
@@ -103,16 +103,20 @@ menu.scoreaccounting=\u8BFE\u7A0B\u7ED3\u679C
 menu.scoreaccounting.alt=\u5BF9\u6D4B\u8BD5\u3001\u8BC4\u4F30\u548C\u4EFB\u52A1\u7684\u6700\u7EC8\u7ED3\u679C\u8FDB\u884C\u5F52\u6863
 menu.wikis=Wiki
 menu.wikis.alt=\u5F52\u6863Wikis
+menu.scorm=SCORM \u6210\u7EE9
+menu.scorm.alt=SCORM \u6210\u7EE9
 nodechoose.intro.dialog=\u9009\u62E9\u4E00\u4E2A\u8BFE\u7A0B\u5143\u7D20\u5F52\u6863\u5176\u6587\u4EF6\u8BA8\u8BBA. \u8BE5\u5F52\u6863\u5B58\u653E\u5728\u4F60\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939 private/archive/[course name]/file dialog_[forum_id]\u4E2D.
 nodechoose.intro.fo=\u9009\u62E9\u4E00\u4E2A\u8BFE\u7A0B\u5143\u7D20\u5F52\u6863\u5176\u8BBA\u575B. \u8BE5\u5F52\u6863\u5B58\u653E\u5728\u4F60\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939private/archive/[course name]/forum_[forum_id]\u4E2D. 
 nodechoose.intro.projectbroker=\u8BF7\u9009\u62E9\u4E00\u4E2A\u5B66\u7A0B\u5143\u7D20\u4EE5\u4FDD\u5B58\u5176\u9879\u76EE\u7ECF\u7EAA\u4EBA\u3002\u60A8\u80FD\u591F\u5728\u60A8\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939\u4E2D\u627E\u5230\u4FDD\u5B58\u7684\u9879\u76EE\u7ECF\u7EAA\u4EBA\uFF0C\u5B83\u4F4D\u4E8E \u4E2A\u4EBA/\u5B58\u6863/[course's name]/projectbroker_[id]
 nodechoose.intro.ta=\u9009\u62E9\u4E00\u4E2A\u8BFE\u7A0B\u5143\u7D20\u5F52\u6863\u5176tasks/solutions. \u8BE5\u5F52\u6863\u5B58\u653E\u5728\u4F60\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939n private/archive/[course name]/task_[name of course element]\u4E2D.
 nodechoose.intro.wiki=\u9009\u62E9\u4E00\u4E2A\u8BFE\u7A0B\u5143\u7D20\u5F52\u6863\u5176wiki. \u8BE5\u5F52\u6863\u5B58\u653E\u5728\u4F60\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939  private/archive/[course name]/wiki_[date] \u4E2D.
+nodechoose.intro.scorm=\u8BF7\u5728\u4EE5\u4E0B\u5BF9\u8BDD\u6846\u4E2D\u9009\u62E9\u8981\u8BC4\u4EF7\u7684SCORM\u5143\u7D20\u3002\u5B58\u50A8\u7684\u6210\u7EE9\u53EF\u4EE5\u5728\u60A8\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939\u4E2D\u627E\u5230\uFF0C\u5B83\u4F4D\u4E8E \u4E2A\u4EBA/\u5B58\u50A8/[course name]/[file name]\u3002
 overview.nonodes.dialog=\u8BE5\u8BFE\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55\u6587\u4EF6\u8BA8\u8BBA
 overview.nonodes.fo=\u8BE5\u8BFE\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55\u8BBA\u575B
 overview.nonodes.projectbroker=\u672C\u5B66\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55\u9879\u76EE\u7ECF\u7EAA\u4EBA\u3002
 overview.nonodes.ta=\u8BE5\u8BFE\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55\u4EFB\u52A1\u5143\u7D20
 overview.nonodes.wiki=\u8BE5\u8BFE\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55wiki
+overview.nonodes.scorm=\u672C\u5B66\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55SCORM\u5143\u7D20\u3002
 projectbroker=\u9879\u76EE\u7ECF\u7EAA\u4EBA
 readme=\u63D0\u793A\n\n\u4F5C\u4E3A\u4E00\u4E2A\u5F52\u6863\u6570\u636E\u7684\u63A5\u53D7\u8005\uFF0C\u4F60\u5FC5\u987B\u786E\u4FDD\u8BE5\u6570\u636E\u53EA\u6709\u5728\u88AB\u6388\u6743\u7684\u60C5\u51B5\u4E0B\u624D\u88AB\u4F7F\u7528\u3002n \n \n- \u8DDF\u5927\u5B66\u95EE\u9898\u6709\u5173\u7684\u4E2A\u4EBA\u6570\u636E\u53EF\u7528\u4E8E\u7814\u7A76\uFF0C\u6559\u5B66\u548C\u8BC4\u4F30\u3002\n \n- \u533F\u540D\u6570\u636E\u4E5F\u53EF\u7528\u4E8E\u6570\u636E\u7EDF\u8BA1\u3002n \n- \u53EA\u8981\u6709\u5FC5\u8981\uFF0C\u8FD8\u53EF\u4EE5\u5F52\u6863\u4E2A\u4EBA\u6570\u636E\u3002\n \n-  \u4E0D\u5FC5\u8981\u7684\u6570\u636E\u5FC5\u987B\u5220\u9664\u3002
 showfile=\u663E\u793A\u6587\u4EF6
diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_TW.properties
index 2b895b7e8e5ea5fd97e9d203f6a7676edf3baa01..980baa6ed6f6f4824f497cf0212b1d946a510f43 100644
--- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_TW.properties
+++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_zh_TW.properties
@@ -89,6 +89,8 @@ menu.scoreaccounting=\u8AB2\u7A0B\u7D50\u679C
 menu.scoreaccounting.alt=\u5099\u4EFD\u4F86\u81EA\u6E2C\u9A57\u3001\u8A55\u4F30\u548C\u4EFB\u52D9\u7684\u6700\u7D42\u7D50\u679C
 menu.wikis=Wikis
 menu.wikis.alt=\u5099\u4EFD Wikis
+menu.scorm=SCORM \u7D50\u679C
+menu.scorm.alt=SCORM \u7D50\u679C
 nodechoose.intro.dialog=\u9078\u64C7\u4E00\u500B\u8AB2\u7A0B\u5143\u7D20\u4F86\u5099\u4EFD\u5B83\u7684\u6A94\u6848\u5C0D\u8A71\u6846\u3002\u9019\u500B\u5099\u4EFD\u7684\u5C0D\u8A71\u6846\u53EF\u4EE5\u5728\u60A8\u7684\u500B\u4EBA\u8CC7\u6599\u593E\u4E2D\u627E\u5230\uFF0C \u5728\u8DEF\u5F91 private/archive/[course name]/file dialog_[forum_id]\u3002
 nodechoose.intro.fo=\u9078\u64C7\u4E00\u500B\u8AB2\u7A0B\u5143\u7D20\u4F86\u5099\u4EFD\u5B83\u7684\u8AD6\u58C7\u3002 \u9019\u500B\u5099\u4EFD\u7684\u8AD6\u58C7\u53EF\u4EE5\u5728\u60A8\u7684\u500B\u4EBA\u8CC7\u6599\u593E\u4E2D\u627E\u5230\uFF0C\u5728\u8DEF\u5F91 private/archive/[course name]/forum_[forum_id]\u3002
 nodechoose.intro.ta=\u9078\u64C7\u4E00\u500B\u8AB2\u7A0B\u5143\u7D20\u4EE5\u5099\u4EFD\u5B83\u7684\u4EFB\u52D9/\u89E3\u7B54\u3002\u9019\u4E9B\u5099\u4EFD\u7684\u4EFB\u52D9/\u89E3\u7B54\u662F\u5132\u5B58\u5728\u60A8\u7684\u500B\u4EBA\u8CC7\u6599\u593E\u7684 private/archive/[course name]/task_[name of course element] \u90E8\u5206\u4E0B\u7684 zip \u6A94\u3002
@@ -97,6 +99,7 @@ overview.nonodes.dialog=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u
 overview.nonodes.fo=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u4EFB\u4F55\u8AD6\u58C7\u3002
 overview.nonodes.ta=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u4EFB\u4F55\u4EFB\u52D9\u5143\u7D20\u3002
 overview.nonodes.wiki=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u4EFB\u4F55 Wikis\u3002
+overview.nonodes.scorm=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u4EFB\u4F55 SCORM \u5143\u7D20\u3002
 readme=\u63D0\u793A \n \n \u8EAB\u70BA\u5099\u4EFD\u8CC7\u6599\u7684\u6536\u4EF6\u4EBA\u60A8\u5FC5\u9808\u5C0D\u9019\u4E9B\u8CC7\u6599\u53EA\u6709\u7D93\u904E\u8A31\u53EF\u624D\u53EF\u4EE5\u4F7F\u7528\u8CA0\u8CAC\u3002 \n \n \n- \u53EA\u8981\u8DDF\u5927\u5B78\u8B70\u984C\u76F8\u95DC\uFF0C\u500B\u4EBA\u8CC7\u6599\u53EF\u4EE5\u4F5C\u70BA\u7814\u7A76\u3001\u6559\u5B78\u548C\u8A55\u4F30\u4F7F\u7528\u3002 \n \n- \u533F\u540D\u8CC7\u6599\u4E5F\u53EF\u4EE5\u7528\u4F5C\u7D71\u8A08\u76EE\u7684\u3002\n \n- \u500B\u4EBA\u8CC7\u6599\u50C5\u80FD\u5728\u9700\u8981\u6642\u5099\u4EFD\u3002\n \n- \u4E0D\u9700\u8981\u7684\u8CC7\u6599\u5FC5\u9808\u88AB\u522A\u9664\u3002
 showfile=\u986F\u793A\u6A94\u6848
 ta=\u4EFB\u52D9/\u89E3\u7B54
diff --git a/src/main/java/org/olat/course/assessment/AssessmentMainController.java b/src/main/java/org/olat/course/assessment/AssessmentMainController.java
index 8f4951e49f580ac2bf9add5763f703d4037fd3f2..6d668be6d8a39977f70bc7c5cc842cbf9289b58f 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentMainController.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentMainController.java
@@ -27,7 +27,6 @@ package org.olat.course.assessment;
 
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -99,6 +98,7 @@ import org.olat.course.nodes.CourseNodeFactory;
 import org.olat.course.nodes.ProjectBrokerCourseNode;
 import org.olat.course.nodes.STCourseNode;
 import org.olat.course.properties.CoursePropertyManager;
+import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.course.run.userview.UserCourseEnvironmentImpl;
 import org.olat.group.BusinessGroup;
@@ -208,7 +208,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 	 * @param course
 	 * @param assessmentCallback
 	 */
-	AssessmentMainController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, OLATResourceable ores, IAssessmentCallback assessmentCallback) {
+	public AssessmentMainController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, OLATResourceable ores, IAssessmentCallback assessmentCallback) {
 		super(ureq, wControl);	
 		
 		onyxModule = CoreSpringFactory.getImpl(OnyxModule.class);
@@ -518,8 +518,8 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 				if (actionid.equals(CMD_SELECT_NODE)) {
 					ICourse course = CourseFactory.loadCourse(ores);
 					int rowid = te.getRowId();
-					Map<String,Object> nodeData = (Map<String,Object>) nodeTableModel.getObject(rowid);
-					CourseNode node = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
+					NodeTableRow nodeData = nodeTableModel.getObject(rowid);
+					CourseNode node = course.getRunStructure().getNode(nodeData.getIdent());
 					this.currentCourseNode = (AssessableCourseNode) node;
 					// cast should be save, only assessable nodes are selectable
 					if((repoTutor && coachedGroups.isEmpty()) || (callback.mayAssessAllUsers() || callback.mayViewAllUsersAssessments())) {
@@ -531,8 +531,8 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 				} else if (actionid.equals(CMD_SHOW_ONYXREPORT)) {
 					int rowid = te.getRowId();
 					ICourse course = CourseFactory.loadCourse(ores);
-					Map<String, Object> nodeData = (Map<String, Object>) nodeTableModel.getObject(rowid);
-					CourseNode node = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
+					NodeTableRow nodeData = nodeTableModel.getObject(rowid);
+					CourseNode node = course.getRunStructure().getNode(nodeData.getIdent());
 					this.currentCourseNode = (AssessableCourseNode) node;
 					this.onyxReporterBackLocation = "nodeListCtr";
 					if (!showOnyxReporter(ureq)) {
@@ -807,6 +807,20 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		AssessedIdentitiesTableDataModel tdm = new AssessedIdentitiesTableDataModel(wrappedIdentities, courseNode, getLocale(), isAdministrativeUser);
 		tdm.addColumnDescriptors(userListCtr, CMD_CHOOSE_USER, mode == MODE_NODEFOCUS || mode == MODE_GROUPFOCUS || mode == MODE_USERFOCUS);
 		userListCtr.setTableDataModel(tdm);
+		
+		List<String> toolCmpNames = new ArrayList<>(3);
+		if(courseNode != null) {
+			CourseEnvironment courseEnv = course.getCourseEnvironment();
+			List<Controller> tools = courseNode.createAssessmentTools(ureq, getWindowControl(), courseEnv, group);
+			int count = 0;
+			for(Controller tool:tools) {
+				listenTo(tool);
+				String toolCmpName = "ctrl_" + (count++);
+				userChoose.put(toolCmpName, tool.getInitialComponent());
+				toolCmpNames.add(toolCmpName);
+			}
+		}
+		userChoose.contextPut("toolCmpNames", toolCmpNames);
 
 		if (mode == MODE_USERFOCUS) {
 			userChoose.contextPut("showBack", Boolean.FALSE);
@@ -890,7 +904,7 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 		
 		// get list of course node data and populate table data model 
 		CourseNode rootNode = course.getRunStructure().getRootNode();		
-		List<Map<String, Object>> nodesTableObjectArrayList = addAssessableNodesAndParentsToList(0, rootNode);
+		List<NodeTableRow> nodesTableObjectArrayList = addAssessableNodesAndParentsToList(0, rootNode);
 		
 		// only populate data model if data available
 		if (nodesTableObjectArrayList == null) {
@@ -927,12 +941,12 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 	 * @param courseNode
 	 * @return A list of maps containing the node data
 	 */
-	private List<Map<String, Object>> addAssessableNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
+	private List<NodeTableRow> addAssessableNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
 		// 1) Get list of children data using recursion of this method
-		List<Map<String, Object>> childrenData = new ArrayList<Map<String, Object>>();
+		List<NodeTableRow> childrenData = new ArrayList<>();
 		for (int i = 0; i < courseNode.getChildCount(); i++) {
 			CourseNode child = (CourseNode) courseNode.getChildAt(i);
-			List<Map<String, Object>> childData = addAssessableNodesAndParentsToList( (recursionLevel + 1),  child);
+			List<NodeTableRow> childData = addAssessableNodesAndParentsToList( (recursionLevel + 1),  child);
 			if (childData != null)
 				childrenData.addAll(childData);
 		}
@@ -942,26 +956,18 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 			// TODO:cg 04.11.2010 ProjectBroker : no assessment-tool in V1.0 , remove projectbroker completely form assessment-tool gui			// Store node data in hash map. This hash map serves as data model for 
 			// the user assessment overview table. Leave user data empty since not used in
 			// this table. (use only node data)
-			Map<String,Object> nodeData = new HashMap<String, Object>();
-			// indent
-			nodeData.put(AssessmentHelper.KEY_INDENT, new Integer(recursionLevel));
-			// course node data
-			nodeData.put(AssessmentHelper.KEY_TYPE, courseNode.getType());
-			nodeData.put(AssessmentHelper.KEY_TITLE_SHORT, courseNode.getShortTitle());
-
+			NodeTableRow nodeData = new NodeTableRow(recursionLevel, courseNode);
 			if (courseNode.getReferencedRepositoryEntry() != null) {
 				if (OnyxModule.isOnyxTest(courseNode.getReferencedRepositoryEntry().getOlatResource())) {
-					nodeData.put(KEY_IS_ONYX, Boolean.TRUE);
+					nodeData.setOnyx(true);
 					if (getAllAssessableIdentities().size() <= 0) {
-						nodeData.put(KEY_IS_ONYX, Boolean.FALSE);
+						nodeData.setOnyx(false);
 					}
 				} else {
-					nodeData.put(KEY_IS_ONYX, Boolean.FALSE);
+					nodeData.setOnyx(false);
 				}
 			}
 
-			nodeData.put(AssessmentHelper.KEY_TITLE_LONG, courseNode.getLongTitle());
-			nodeData.put(AssessmentHelper.KEY_IDENTIFYER, courseNode.getIdent());
 			
 			if (courseNode instanceof AssessableCourseNode) {
 				AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
@@ -977,37 +983,37 @@ public class AssessmentMainController extends MainLayoutBasicController implemen
 				if(assessableCourseNode.hasScoreConfigured()) {
 					if(!(courseNode instanceof STCourseNode)) {
 						Float min = assessableCourseNode.getMinScoreConfiguration();
-						nodeData.put(AssessmentHelper.KEY_MIN, min);
+						nodeData.setMinScore(min);
 						Float max = assessableCourseNode.getMaxScoreConfiguration();
-						nodeData.put(AssessmentHelper.KEY_MAX, max);
+						nodeData.setMaxScore(max);
 					}
 				}
 
 				if (assessableCourseNode.isEditableConfigured()) {
 					// Assessable course nodes are selectable when they are aditable
-					nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.TRUE);
+					nodeData.setSelectable(true);
 				} else if (courseNode instanceof STCourseNode 
 						&& (assessableCourseNode.hasScoreConfigured()
 						|| assessableCourseNode.hasPassedConfigured())) {
 					// st node is special case: selectable on node choose list as soon as it 
 					// has score or passed
-					nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.TRUE);
+					nodeData.setSelectable(true);
 				} else {
 					// assessable nodes that do not have score or passed are not selectable
 					// (e.g. a st node with no defined rule
-					nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.FALSE);
+					nodeData.setSelectable(false);
 				}
 			} else {
 				// Not assessable nodes are not selectable. (e.g. a node that 
 				// has an assessable child node but is itself not assessable)
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.FALSE);
+				nodeData.setSelectable(false);
 			}
 			// 3) Add data of this node to mast list if node assessable or children list has any data.
 			// Do only add nodes when they have any assessable element, otherwhise discard (e.g. empty course, 
 			// structure nodes without scoring rules)! When the discardEmptyNodes flag is set then only
 			// add this node when there is user data found for this node.
 			if (childrenData.size() > 0 || hasDisplayableValuesConfigured) {
-				List<Map<String, Object>> nodeAndChildren = new ArrayList<Map<String, Object>>();
+				List<NodeTableRow> nodeAndChildren = new ArrayList<>();
 				nodeAndChildren.add(nodeData);
 				// 4) Add children data list to master list
 				nodeAndChildren.addAll(childrenData);
diff --git a/src/main/java/org/olat/course/assessment/AssessmentUIFactory.java b/src/main/java/org/olat/course/assessment/AssessmentUIFactory.java
index 0c0e3f3cbca6d22e2a6b253a9fe44f43e9b0b45d..178eeead546cbec75a9e505d8e4947502b1901c4 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentUIFactory.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentUIFactory.java
@@ -24,19 +24,13 @@
 */
 package org.olat.course.assessment;
 
-import java.util.List;
-
 import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
-import org.olat.core.gui.control.generic.dtabs.Activateable2;
-import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.notifications.ContextualSubscriptionController;
 import org.olat.core.util.notifications.PublisherData;
 import org.olat.core.util.notifications.SubscriptionContext;
 import org.olat.course.ICourse;
-import org.olat.ims.qti.export.QTIArchiveWizardController;
 
 /**
  * Description:<br>
@@ -47,16 +41,6 @@ import org.olat.ims.qti.export.QTIArchiveWizardController;
  * @author patrickb
  */
 public class AssessmentUIFactory {
-
-	
-	public static Activateable2 createAssessmentMainController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, OLATResourceable ores, IAssessmentCallback assessmentCallback) {
-		return new AssessmentMainController(ureq, wControl, stackPanel, ores, assessmentCallback);
-	}
-	
-	public static Controller createQTIArchiveWizardController(boolean dummyMode, UserRequest ureq, List nodesTableObjectArrayList, ICourse course,
-			WindowControl wControl) {
-		return new QTIArchiveWizardController(dummyMode, ureq, nodesTableObjectArrayList, course, wControl);
-	}
 	
 	/**
 	 * 
diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementArchiver.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementArchiver.java
index 0f65142db52003e23e61b0fba0581f32b2128b95..d1f8a97afd70c1f0f288439ee6cc6095b8287255 100644
--- a/src/main/java/org/olat/course/assessment/EfficiencyStatementArchiver.java
+++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementArchiver.java
@@ -30,7 +30,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.olat.core.gui.translator.PackageTranslator;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.util.FileUtils;
@@ -61,10 +60,8 @@ public class EfficiencyStatementArchiver {
 	 * constructs an unitialised BusinessGroup, use setXXX for setting attributes
 	 */
 	public EfficiencyStatementArchiver() {
-		String myPackage = Util.getPackageName(this.getClass());
-		String courseNodePackage = Util.getPackageName(CourseNode.class);
-		PackageTranslator fallBackTranslator = new PackageTranslator(courseNodePackage, I18nModule.getDefaultLocale());
-		translator = new PackageTranslator(myPackage, I18nModule.getDefaultLocale(), fallBackTranslator);
+		Translator fallBackTranslator = Util.createPackageTranslator(CourseNode.class, I18nModule.getDefaultLocale());
+		translator = Util.createPackageTranslator(this.getClass(), I18nModule.getDefaultLocale(), fallBackTranslator);
 		// fallback for user properties translation
 		translator = UserManager.getInstance().getPropertyHandlerTranslator(translator);		
 		// list of user property handlers used in this archiver
@@ -75,19 +72,19 @@ public class EfficiencyStatementArchiver {
 		return instance;
 	}
 
-	public void archive(List efficiencyStatements, Identity identity, File archiveFile) {
+	public void archive(List<EfficiencyStatement> efficiencyStatements, Identity identity, File archiveFile) {
 		FileUtils.save(new File(archiveFile, EFFICIENCY_ARCHIVE_FILE), toXls(efficiencyStatements, identity), "utf-8");
 	}
 
 
-	private String toXls(List efficiencyStatements, Identity identity) {
-		StringBuffer buf = new StringBuffer();
+	private String toXls(List<EfficiencyStatement> efficiencyStatements, Identity identity) {
+		StringBuilder buf = new StringBuilder();
 		buf.append(translator.translate("efficiencystatement.title"));
 		appendIdentityIntro(buf, identity);
-		for (Iterator iter = efficiencyStatements.iterator(); iter.hasNext();) {
+		for (Iterator<EfficiencyStatement> iter = efficiencyStatements.iterator(); iter.hasNext();) {
 			buf.append(EOL);
 			buf.append(EOL);
-			EfficiencyStatement efficiencyStatement = (EfficiencyStatement) iter.next();
+			EfficiencyStatement efficiencyStatement = iter.next();
 			appendIntro(buf, efficiencyStatement);
 			buf.append(EOL);
 			appendDetailsHeader(buf);
@@ -96,7 +93,7 @@ public class EfficiencyStatementArchiver {
 		return buf.toString();
 	}
 
-	private void appendDetailsHeader(StringBuffer buf) {
+	private void appendDetailsHeader(StringBuilder buf) {
 		buf.append( translator.translate("table.header.node") );
 		buf.append(DELIMITER);
 		buf.append( translator.translate("table.header.details") );
@@ -111,9 +108,9 @@ public class EfficiencyStatementArchiver {
 		buf.append(EOL);	
 	}
 
-	private void appendDetailsTable(StringBuffer buf, EfficiencyStatement efficiencyStatement) {
-		for (Iterator iter = efficiencyStatement.getAssessmentNodes().iterator(); iter.hasNext();) {
-			Map nodeData = (Map) iter.next();
+	private void appendDetailsTable(StringBuilder buf, EfficiencyStatement efficiencyStatement) {
+		for (Iterator<Map<String,Object>> iter = efficiencyStatement.getAssessmentNodes().iterator(); iter.hasNext();) {
+			Map<String,Object> nodeData = iter.next();
 			appendValue(buf, nodeData, AssessmentHelper.KEY_TITLE_SHORT);		
 			appendValue(buf, nodeData, AssessmentHelper.KEY_TITLE_LONG);
 			appendTypeValue(buf, nodeData, AssessmentHelper.KEY_TYPE);
@@ -124,7 +121,7 @@ public class EfficiencyStatementArchiver {
 		}
 	}
 
-	private void appendTypeValue(StringBuffer buf, Map nodeData, String key_type) {
+	private void appendTypeValue(StringBuilder buf, Map<String,Object> nodeData, String key_type) {
 		Object value = nodeData.get(key_type);
 		if (value != null && (value instanceof String)) {
 			String valueString = (String)value;
@@ -139,7 +136,7 @@ public class EfficiencyStatementArchiver {
 		buf.append(DELIMITER);
 	}
 
-	private void appendIdentityIntro(StringBuffer buf, Identity identity) {
+	private void appendIdentityIntro(StringBuilder buf, Identity identity) {
 		for (UserPropertyHandler propertyHandler : userPropertyHandler) {
 			String label = translator.translate(propertyHandler.i18nColumnDescriptorLabelKey());
 			String value = propertyHandler.getUserProperty(identity.getUser(), translator.getLocale());
@@ -147,19 +144,19 @@ public class EfficiencyStatementArchiver {
 		}
 	}
 	
-	private void appendIntro(StringBuffer buf, EfficiencyStatement efficiencyStatement) {
+	private void appendIntro(StringBuilder buf, EfficiencyStatement efficiencyStatement) {
 		buf.append(EOL);
 		appendLine(buf, translator.translate("course"), efficiencyStatement.getCourseTitle() + "  (" + efficiencyStatement.getCourseRepoEntryKey().toString() +")");
 		appendLine(buf, translator.translate("date"), StringHelper.formatLocaleDateTime(efficiencyStatement.getLastUpdated(), I18nModule.getDefaultLocale()) );
 		
-		Map nodeData = (Map)efficiencyStatement.getAssessmentNodes().get(0);
+		Map<String,Object> nodeData = efficiencyStatement.getAssessmentNodes().get(0);
 		if (nodeData != null) {
 			appendLabelValueLine(buf, nodeData, translator.translate("table.header.score"), AssessmentHelper.KEY_SCORE);
 			appendLabelValueLine(buf, nodeData, translator.translate("table.header.passed"), AssessmentHelper.KEY_PASSED);
 		}
 	}
 
-	private void appendValue(StringBuffer buf, Map nodeData, String key) {
+	private void appendValue(StringBuilder buf, Map<String,Object> nodeData, String key) {
 		Object value = nodeData.get(key);
 		if (value != null) {
 			buf.append(value);		
@@ -169,22 +166,7 @@ public class EfficiencyStatementArchiver {
 		buf.append(DELIMITER);
 	}
 
-	private void appendValuePassed(StringBuffer buf, Map nodeData, String key) {
-		Object value = nodeData.get(key);
-		if (value != null && (value instanceof Boolean) ) {
-			if ( ((Boolean)value).booleanValue() ) {
-				translator.translate("form.passed.true");
-			} else {
-				translator.translate("form.passed.false");
-			}
-			buf.append(value);		
-		} else {
-			buf.append("");
-		}
-		buf.append(DELIMITER);
-	}
-
-	private void appendLabelValueLine(StringBuffer buf, Map nodeData, String label, String key) {
+	private void appendLabelValueLine(StringBuilder buf, Map<String,Object> nodeData, String label, String key) {
 		buf.append(label);
 		buf.append(DELIMITER);
 		Object value = nodeData.get(key);
@@ -196,13 +178,11 @@ public class EfficiencyStatementArchiver {
 		buf.append(EOL);
 	}
 
-	private void appendLine(StringBuffer buf, String label, String value) {
+	private void appendLine(StringBuilder buf, String label, String value) {
 		buf.append(label);
 		buf.append(DELIMITER);
 		buf.append(value);
 		buf.append(DELIMITER);
 		buf.append(EOL);
 	}
-
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java b/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java
index 9be00d20747e3f686eef4eb17307dc33acbae269..86cb08884464c6d624b76a180c33c783844cce17 100644
--- a/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java
+++ b/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java
@@ -69,18 +69,30 @@ public class IndentedNodeRenderer implements CustomCellRenderer {
 	 * @see org.olat.core.gui.components.table.CustomCellRenderer#render(org.olat.core.gui.render.StringOutput, org.olat.core.gui.render.Renderer, java.lang.Object, java.util.Locale, int, java.lang.String)
 	 */
 	public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) {
-		Map nodeData = (Map) val;
-		Integer indent = (Integer) nodeData.get(AssessmentHelper.KEY_INDENT);
-		String type = (String)  nodeData.get(AssessmentHelper.KEY_TYPE);
-
-		String cssClass = CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(type).getIconCSSClass();
-		String title = (String)  nodeData.get(AssessmentHelper.KEY_TITLE_SHORT);
-		String altText = (String)  nodeData.get(AssessmentHelper.KEY_TITLE_LONG);
+		int indent;
+		String type;
+		String title;
+		String altText;
+		if(val instanceof Map) {
+			Map nodeData = (Map) val;
+			Integer indentObj = (Integer) nodeData.get(AssessmentHelper.KEY_INDENT);
+			indent = (indentObj == null ? 0 : indentObj.intValue());
+			type = (String)nodeData.get(AssessmentHelper.KEY_TYPE);
+			title = (String)nodeData.get(AssessmentHelper.KEY_TITLE_SHORT);
+			altText = (String)nodeData.get(AssessmentHelper.KEY_TITLE_LONG);
+		} else if(val instanceof NodeTableRow) {
+			NodeTableRow row = (NodeTableRow)val;
+			indent = row.getIndent();
+			type = row.getType();
+			title = row.getShortTitle();
+			altText = row.getLongTitle();
+		} else {
+			return;
+		}
 		
-		//fxdiff VCRP-4: assessment overview with max score
+		String cssClass = CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(type).getIconCSSClass();
 		if(isIndentationEnabled()) {
-			Integer indentation = (Integer) nodeData.get(AssessmentHelper.KEY_INDENT);
-			appendIndent(sb,indentation);
+			appendIndent(sb, indent);
 		}
 		
 		sb.append("<span class=\"b_with_small_icon_left ").append(cssClass);
@@ -91,12 +103,10 @@ public class IndentedNodeRenderer implements CustomCellRenderer {
 		sb.append(StringHelper.escapeHtml(title));
 		sb.append("</span>");
 	}
-
 	
-  private void appendIndent(StringOutput sb, Integer indent) {
-  	for (int i = 0; i < indent.intValue(); i++) {
+	private void appendIndent(StringOutput sb, int indent) {
+		for (int i = 0; i < indent; i++) {
 			sb.append(INDENT);
 		}
-  }
-
-}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/assessment/NodeTableDataModel.java b/src/main/java/org/olat/course/assessment/NodeTableDataModel.java
index 3bdd52d137d7d615ae052d9c59a5c48c2d1fc851..daac695cef0293ddcb51e4a07b77b98d3591ba7f 100644
--- a/src/main/java/org/olat/course/assessment/NodeTableDataModel.java
+++ b/src/main/java/org/olat/course/assessment/NodeTableDataModel.java
@@ -26,7 +26,6 @@
 package org.olat.course.assessment;
 
 import java.util.List;
-import java.util.Map;
 
 import org.olat.core.gui.components.table.DefaultTableDataModel;
 import org.olat.core.gui.translator.Translator;
@@ -39,18 +38,16 @@ import org.olat.core.gui.translator.Translator;
  * Comment: 
  * Use the IndentedNodeRenderer to render the node element!
  */
-
-
-public class NodeTableDataModel extends DefaultTableDataModel {
-		private Translator trans;
+public class NodeTableDataModel extends DefaultTableDataModel<NodeTableRow> {
+	private final Translator trans;
 	
 		/**
 		 * Constructor for the node table
-		 * @param objects List maps containting the node data using the keys defined in AssessmentHelper
+		 * @param objects List maps containing the node data using the keys defined in AssessmentHelper
 		 * @param trans The table model translator
 		 * any node select link
 		 */
-    public NodeTableDataModel(List objects, Translator trans) {
+    public NodeTableDataModel(List<NodeTableRow> objects, Translator trans) {
         super(objects);
         this.trans = trans;
     }
@@ -58,43 +55,26 @@ public class NodeTableDataModel extends DefaultTableDataModel {
     /**
      * @see org.olat.core.gui.components.table.TableDataModel#getColumnCount()
      */
+    @Override
     public int getColumnCount() {
-    		// node, select
+    	// node, select
         return 2;
     }
 
     /**
      * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int)
      */
+    @Override
     public Object getValueAt(int row, int col) {
-    	Map nodeData = (Map) getObject(row);
+    	NodeTableRow nodeData = getObject(row);
     	switch (col) {
-				case 0:
-					// rendered using the indentedNodeRenderer
-					return nodeData;
-				case 1:
-					// selection command
-					Boolean courseNodeEditable = (Boolean) nodeData.get(AssessmentHelper.KEY_SELECTABLE);
-					if (courseNodeEditable.booleanValue()) return trans.translate("select");
-					else return null;
-				//fxdiff VCRP-4: assessment overview with max score
-				case 2:
-					//min score
-					return nodeData.get(AssessmentHelper.KEY_MIN);
-				case 3:
-					//min score
-					return nodeData.get(AssessmentHelper.KEY_MAX);
-				case 4:
-					// show OnyxReport
-					final Boolean courseNodeIsOnyx = (Boolean) nodeData.get(AssessmentMainController.KEY_IS_ONYX);
-					if (courseNodeIsOnyx != null && courseNodeIsOnyx.booleanValue()) {
-						return trans.translate("table.action.showOnyxReporter");
-					} else {
-						return "";
-					}
-				default:
-					return "error";
-			}
+			case 0: return nodeData;// rendered using the indentedNodeRenderer
+			case 1: return nodeData.isSelectable() ? trans.translate("select") : null;
+			case 2: return nodeData.getMinScore();
+			case 3: return nodeData.getMaxScore();
+			case 4: return nodeData.isOnyx() ? trans.translate("table.action.showOnyxReporter") : "";
+			default: return "error";
+		}
     }
 
     public enum Cols {
diff --git a/src/main/java/org/olat/course/assessment/NodeTableRow.java b/src/main/java/org/olat/course/assessment/NodeTableRow.java
new file mode 100644
index 0000000000000000000000000000000000000000..e684796b75faa01f932de5f865a8da18dcdf249b
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/NodeTableRow.java
@@ -0,0 +1,111 @@
+/**
+ * <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.course.assessment;
+
+import org.olat.course.nodes.CourseNode;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class NodeTableRow {
+	
+	private final int indent;
+	private final String ident;
+	private final String type;
+	private final String shortTitle;
+	private final String longTitle;
+	
+	private Float minScore;
+	private Float maxScore;
+	
+	private boolean selectable;
+	private boolean onyx = false;
+	
+	public NodeTableRow(int indent, CourseNode courseNode) {
+		this(indent, courseNode.getIdent(), courseNode.getType(), courseNode.getShortTitle(), courseNode.getLongTitle());
+	}
+
+	public NodeTableRow(int indent, String ident, String type, String shortTitle, String longTitle) {
+		this.indent = indent;
+		this.ident = ident;
+		this.type = type;
+		this.shortTitle = shortTitle;
+		this.longTitle = longTitle;
+	}
+
+	public int getIndent() {
+		return indent;
+	}
+
+	public String getIdent() {
+		return ident;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+
+	public String getShortTitle() {
+		return shortTitle;
+	}
+
+	public String getLongTitle() {
+		return longTitle;
+	}
+	
+	public Float getMinScore() {
+		return minScore;
+	}
+
+
+	public void setMinScore(Float minScore) {
+		this.minScore = minScore;
+	}
+
+
+	public Float getMaxScore() {
+		return maxScore;
+	}
+
+
+	public void setMaxScore(Float maxScore) {
+		this.maxScore = maxScore;
+	}
+
+
+	public boolean isSelectable() {
+		return selectable;
+	}
+
+	public void setSelectable(boolean selectable) {
+		this.selectable = selectable;
+	}
+
+	public boolean isOnyx() {
+		return onyx;
+	}
+
+	public void setOnyx(boolean onyx) {
+		this.onyx = onyx;
+	}
+}
diff --git a/src/main/java/org/olat/course/assessment/_content/userchoose.html b/src/main/java/org/olat/course/assessment/_content/userchoose.html
index 85d417f4086a19e01dc833b8da32cfbae9faf3ef..969f389fb23440bf4ecc549a7a8987ed2c903650 100644
--- a/src/main/java/org/olat/course/assessment/_content/userchoose.html
+++ b/src/main/java/org/olat/course/assessment/_content/userchoose.html
@@ -23,4 +23,12 @@
 <div style="clear:right">
 $r.render("userlisttable")
 </div>
+#if ($toolCmpNames)
+	<div class="b_button_group">
+	#foreach($toolCmpName in $toolCmpNames)
+		$r.render($toolCmpName)
+	#end
+	</div>
+#end
+
  
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/assessment/bulk/BulkAssessmentToolController.java b/src/main/java/org/olat/course/assessment/bulk/BulkAssessmentToolController.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c0174a1c44e9092e71d1ed2a7ee0b020bf1bc1f
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/bulk/BulkAssessmentToolController.java
@@ -0,0 +1,170 @@
+/**
+ * <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.course.assessment.bulk;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.commons.services.taskexecutor.TaskExecutorManager;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+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;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
+import org.olat.core.gui.control.generic.wizard.Step;
+import org.olat.core.gui.control.generic.wizard.StepRunnerCallback;
+import org.olat.core.gui.control.generic.wizard.StepsMainRunController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.course.assessment.manager.BulkAssessmentTask;
+import org.olat.course.assessment.model.BulkAssessmentDatas;
+import org.olat.course.assessment.model.BulkAssessmentFeedback;
+import org.olat.course.nodes.AssessableCourseNode;
+import org.olat.course.run.environment.CourseEnvironment;
+import org.olat.resource.OLATResource;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class BulkAssessmentToolController extends BasicController {
+	
+	private final Link startButton;
+	private final VelocityContainer mainVC;
+	private final AssessableCourseNode courseNode;
+
+	private DialogBoxController errorCtrl;
+	private StepsMainRunController bulkAssessmentCtrl;
+	private final TaskExecutorManager taskManager;
+	private final OLATResource courseOres;
+	
+	public BulkAssessmentToolController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, AssessableCourseNode courseNode) {
+		super(ureq, wControl);
+		this.courseNode = courseNode;
+		taskManager = CoreSpringFactory.getImpl(TaskExecutorManager.class);
+		courseOres = courseEnv.getCourseGroupManager().getCourseResource();
+		
+		mainVC = createVelocityContainer("start_button");
+		startButton = LinkFactory.createButton("bulk.wizard.title", mainVC, this);
+		putInitialPanel(mainVC);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(startButton == source) {
+			doOpen(ureq);
+		}
+	}
+	
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(bulkAssessmentCtrl == source) {
+			if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
+				getWindowControl().pop();
+				Feedback feedback = (Feedback)bulkAssessmentCtrl.getRunContext().get("feedback");
+				removeAsListenerAndDispose(bulkAssessmentCtrl);
+				bulkAssessmentCtrl = null;
+				if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
+					doBulkAssessmentSynchronous(ureq, feedback);
+				}
+			}
+		}
+		super.event(ureq, source, event);
+	}
+
+	private void doOpen(UserRequest ureq) {
+		StepRunnerCallback finish = new StepRunnerCallback() {
+			@Override
+			public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) {
+				Date scheduledDate = (Date)runContext.get("scheduledDate");
+				BulkAssessmentDatas datas = (BulkAssessmentDatas)runContext.get("datas");
+				Feedback feedback = doBulkAssessment(scheduledDate, datas);
+				runContext.put("feedback", feedback);
+				return StepsMainRunController.DONE_MODIFIED;
+			}
+		};
+		
+		Step start = new BulkAssessment_2_DatasStep(ureq, courseNode);
+		bulkAssessmentCtrl = new StepsMainRunController(ureq, getWindowControl(), start, finish, null,
+				translate("bulk.wizard.title"), "o_sel_bulk_assessment_wizard");
+		listenTo(bulkAssessmentCtrl);
+		getWindowControl().pushAsModalDialog(bulkAssessmentCtrl.getInitialComponent());
+	}
+	
+	private Feedback doBulkAssessment(Date scheduledDate, BulkAssessmentDatas datas) {
+		BulkAssessmentTask task = new BulkAssessmentTask(courseOres, courseNode, datas, getIdentity().getKey());
+		Feedback feedback;
+		if(scheduledDate == null) {
+			List<BulkAssessmentFeedback> feedbacks = task.process();
+			feedback = new Feedback(true, feedbacks);
+		} else {
+			taskManager.execute(task, getIdentity(), courseOres, courseNode.getIdent(), scheduledDate);
+			feedback = new Feedback(false, null);
+		}
+		return feedback;
+	}
+	
+	private void doBulkAssessmentSynchronous(UserRequest ureq, Feedback feedback) {
+		if(feedback.isSynchronous()) {
+			List<BulkAssessmentFeedback> feedbacks = feedback.getFeedbacks();
+			if(feedbacks.isEmpty()) {
+				showInfo("bulk.assessment.done");
+			} else {
+				String text = BulkAssessmentTask.renderFeedback(feedbacks, getTranslator());
+				List<String> buttonLabels = Collections.singletonList(translate("ok"));
+				String title = translate("bulk.assessment.error.title");
+				String translatedText = translate("bulk.assessment.error.feedback", new String[]{ text });
+				errorCtrl = activateGenericDialog(ureq, title, translatedText, buttonLabels, errorCtrl);
+			}
+		} else {
+			showInfo("bulk.assessment.enlisted");
+		}
+	}
+	
+	private static class Feedback {
+		private final boolean synchronous;
+		private final List<BulkAssessmentFeedback> feedbacks;
+		
+		public Feedback(boolean synchronous, List<BulkAssessmentFeedback> feedbacks) {
+			this.synchronous = synchronous;
+			this.feedbacks = feedbacks;
+		}
+
+		public boolean isSynchronous() {
+			return synchronous;
+		}
+
+		public List<BulkAssessmentFeedback> getFeedbacks() {
+			return feedbacks;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/course/assessment/bulk/_content/start_button.html b/src/main/java/org/olat/course/assessment/bulk/_content/start_button.html
new file mode 100644
index 0000000000000000000000000000000000000000..a80ea843e48f9cacf1fdf6aac3b527be629a79a0
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/bulk/_content/start_button.html
@@ -0,0 +1 @@
+$r.render("bulk.wizard.title")
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/editor/PublishProcess.java b/src/main/java/org/olat/course/editor/PublishProcess.java
index caa97b8f070690d1803ce9f134d40d9256af2309..58b0a75edb0550d3c9a015ff1bcc08f808af27ee 100644
--- a/src/main/java/org/olat/course/editor/PublishProcess.java
+++ b/src/main/java/org/olat/course/editor/PublishProcess.java
@@ -25,13 +25,18 @@
 package org.olat.course.editor;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.poi.util.IOUtils;
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.catalog.CatalogEntry;
 import org.olat.catalog.CatalogManager;
@@ -42,7 +47,9 @@ import org.olat.core.id.OLATResourceable;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.Formatter;
 import org.olat.core.util.ObjectCloner;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.ValidationStatus;
 import org.olat.core.util.coordinate.CoordinatorManager;
@@ -415,8 +422,7 @@ public class PublishProcess {
 					// only clean up and archive of nodes which were already in run
 					// save data, remove references
 					deleteRefs(oldCn);
-					File exportDirectory = CourseFactory.getOrCreateDataExportDirectory(identity, course.getCourseTitle());
-					oldCn.archiveNodeData(locale, course, exportDirectory, charset);
+					archiveDeletedNode(identity, cn, oldCn, locale, charset);
 					// 2) delete all user data
 					oldCn.cleanupOnDelete(course);
 				}
@@ -480,6 +486,27 @@ public class PublishProcess {
 		 */
 
 	}
+	
+	private void archiveDeletedNode(Identity identity, CourseNode cn, CourseNode oldCn, Locale locale, String charset) {
+		File exportDirectory = CourseFactory.getOrCreateDataExportDirectory(identity, course.getCourseTitle());
+		String archiveName = cn.getType() + "_"
+				+ StringHelper.transformDisplayNameToFileSystemName(cn.getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+		
+		FileOutputStream fileStream = null;
+		ZipOutputStream exportStream = null;
+		try {
+			File exportFile = new File(exportDirectory, archiveName);
+			fileStream = new FileOutputStream(exportFile);
+			exportStream = new ZipOutputStream(fileStream);
+			oldCn.archiveNodeData(locale, course, null, exportStream, charset);
+		} catch (FileNotFoundException e) {
+			log.error("", e);
+		} finally {
+			IOUtils.closeQuietly(exportStream);
+			IOUtils.closeQuietly(fileStream);
+		}
+	}
 
 	/**
 	 * Update references of a course node in the run. If the course node is new,
diff --git a/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java b/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
index 0614a067b305a4f26879a2177007727f0ca72366..8bc7d7e71ed5adfa98eca17a5e9b541636917d14 100644
--- a/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/AbstractAccessableCourseNode.java
@@ -26,9 +26,11 @@
 package org.olat.course.nodes;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.course.condition.Condition;
@@ -38,9 +40,11 @@ import org.olat.course.condition.additionalconditions.AdditionalConditionManager
 import org.olat.course.condition.interpreter.ConditionExpression;
 import org.olat.course.condition.interpreter.ConditionInterpreter;
 import org.olat.course.export.CourseEnvironmentMapper;
+import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 
 import de.bps.course.nodes.CourseNodePasswordManagerImpl;
 
@@ -181,6 +185,12 @@ public abstract class AbstractAccessableCourseNode extends GenericCourseNode {
 		//
 		return retVal;
 	}
+	
+	/** Factory method to launch course element assessment tools. limitToGroup is optional to skip he the group choose step */
+	public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, BusinessGroup limitToGroup) {
+		return Collections.emptyList();
+	}
+	
 
 	public List<AdditionalCondition> getAdditionalConditions(){
 		if(additionalConditions==null)
diff --git a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
index 5d5103163579cdc40fc62bcb2840bb60b2f2d796..c2e4b769a66d3ff669cc455a934ac6302d68868c 100644
--- a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
@@ -25,13 +25,17 @@
 
 package org.olat.course.nodes;
 
+import java.util.List;
+
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
+import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 
 
 /**
@@ -144,6 +148,12 @@ public interface AssessableCourseNode extends CourseNode {
 	 * @return a controller or null if hasDetails=false
 	 */
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, UserCourseEnvironment userCourseEnvironment);
+	
+
+	/** Factory method to launch course element assessment tools. limitToGroup is optional to skip he the group choose step */
+	public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, BusinessGroup limitToGroup);
+	
+	
 	/**
 	 * 
 	 * @param scoreEvaluation if scoreEvaluation.getScore() != null, then the score will be updated, and/or if scoreEvaluation.getPassed() != null, then 'passed' will be updated
diff --git a/src/main/java/org/olat/course/nodes/CalCourseNode.java b/src/main/java/org/olat/course/nodes/CalCourseNode.java
index 00c69118577c0776eeef27ac79d4e95ce86e4ef7..b1d660d25421eca6a1cc9b810aafbd84055fa179 100644
--- a/src/main/java/org/olat/course/nodes/CalCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CalCourseNode.java
@@ -21,7 +21,6 @@ package org.olat.course.nodes;
 
 import java.io.File;
 import java.util.List;
-import java.util.Locale;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
@@ -55,6 +54,8 @@ import org.olat.repository.RepositoryEntry;
  */
 public class CalCourseNode extends AbstractAccessableCourseNode {
 
+	private static final long serialVersionUID = -3174525063215323155L;
+	
 	public static final String TYPE = "cal";
 	public static final String EDIT_CONDITION_ID = "editarticle";
 	private Condition preConditionEdit;
@@ -178,14 +179,6 @@ public class CalCourseNode extends AbstractAccessableCourseNode {
 		return null;
 	}
 
-	/**
-	 * @see org.olat.course.nodes.GenericCourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File, java.lang.String)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-	  return true;
-	}
-
 	/**
 	 * Default set the write privileges to coaches and admin only
 	 * @return
diff --git a/src/main/java/org/olat/course/nodes/CourseNode.java b/src/main/java/org/olat/course/nodes/CourseNode.java
index 1ae15d31e46c8ebc6c1f1986f03cc432a21c2a9d..3009e3b60437a016cda817d4f2bbfa9f9e85dc65 100644
--- a/src/main/java/org/olat/course/nodes/CourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CourseNode.java
@@ -28,6 +28,7 @@ package org.olat.course.nodes;
 import java.io.File;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.core.gui.ShortName;
 import org.olat.core.gui.UserRequest;
@@ -47,6 +48,7 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.TreeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.repository.RepositoryEntry;
 
@@ -297,12 +299,12 @@ public interface CourseNode extends INode, ShortName {
 	 * 
 	 * @param locale The users locale
 	 * @param course The course
-	 * @param exportDirectory The directory where the exported files should be
+	 * @param exportStream The directory where the exported files should be
 	 *          put. This directory must exist prior to calling this method.
 	 * @param value of charset property of current user
 	 * @return true if any data to be archived was found, false otherwise.
 	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset);
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream out, String charset);
 
 	/**
 	 * Export all node user data to the given directory. This might be one file or
diff --git a/src/main/java/org/olat/course/nodes/DialogCourseNode.java b/src/main/java/org/olat/course/nodes/DialogCourseNode.java
index 490461dd740eab5d333770f1a1a2fd10ed4ecb6c..6c64051c437aeeb87585440c3d29c85a4b435e7e 100644
--- a/src/main/java/org/olat/course/nodes/DialogCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/DialogCourseNode.java
@@ -26,13 +26,10 @@
 package org.olat.course.nodes;
 
 import java.io.File;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.gui.UserRequest;
@@ -42,6 +39,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.Util;
+import org.olat.core.util.ZipUtil;
 import org.olat.core.util.notifications.NotificationsManager;
 import org.olat.core.util.notifications.SubscriptionContext;
 import org.olat.core.util.vfs.LocalFolderImpl;
@@ -64,6 +62,7 @@ import org.olat.course.nodes.dialog.DialogCourseNodeRunController;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.dialog.DialogElement;
 import org.olat.modules.dialog.DialogElementsPropertyManager;
@@ -72,6 +71,7 @@ import org.olat.modules.fo.ForumManager;
 import org.olat.modules.fo.archiver.ForumArchiveManager;
 import org.olat.modules.fo.archiver.formatters.ForumFormatter;
 import org.olat.modules.fo.archiver.formatters.ForumRTFFormatter;
+import org.olat.modules.fo.archiver.formatters.ForumStreamedRTFFormatter;
 import org.olat.repository.RepositoryEntry;
 
 /**
@@ -220,32 +220,6 @@ public class DialogCourseNode extends AbstractAccessableCourseNode {
 		
 		//delete property
 		depm.deleteProperty(course.getResourceableId(), this.getIdent());
-		
-		
-		
-	}
-
-	/**
-	 * Generic interface implementation. May be overriden by specific node's
-	 * implementation.
-	 * 
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		boolean dataFound = false;
-		DialogElementsPropertyManager depm = DialogElementsPropertyManager.getInstance();
-		DialogPropertyElements elements = depm.findDialogElements(course.getCourseEnvironment().getCoursePropertyManager(), this);
-		List<DialogElement> list = new ArrayList<DialogElement>();
-		if (elements != null) list = elements.getDialogPropertyElements();
-
-		for (Iterator<DialogElement> iter = list.iterator(); iter.hasNext();) {
-			DialogElement element = iter.next();
-			doArchiveElement(element, exportDirectory);
-			//at least one element found
-			dataFound = true;
-		}
-		return dataFound;
 	}
 
 	/**
@@ -260,8 +234,7 @@ public class DialogCourseNode extends AbstractAccessableCourseNode {
 		VFSContainer exportContainer = new LocalFolderImpl(exportDirectory);
 		
 		// append export timestamp to avoid overwriting previous export 
-		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss_SSS");
-		String exportDirName = Formatter.makeStringFilesystemSave(getShortTitle())+"_"+element.getForumKey()+"_"+formatter.format(new Date(System.currentTimeMillis()));
+		String exportDirName = Formatter.makeStringFilesystemSave(getShortTitle())+"_"+element.getForumKey()+"_"+Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
 		VFSContainer diaNodeElemExportContainer = exportContainer.createChildContainer(exportDirName);
 		// don't check quota
 		diaNodeElemExportContainer.setLocalSecurityCallback(new FullAccessCallback());
@@ -269,7 +242,43 @@ public class DialogCourseNode extends AbstractAccessableCourseNode {
 
 		ForumArchiveManager fam = ForumArchiveManager.getInstance();
 		ForumFormatter ff = new ForumRTFFormatter(diaNodeElemExportContainer, false);
-		fam.applyFormatter(ff, element.getForumKey().longValue(), null);
+		fam.applyFormatter(ff, element.getForumKey(), null);
+	}
+	
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		boolean dataFound = false;
+		List<DialogElement> list = DialogElementsPropertyManager.getInstance()
+				.findDialogElements(course.getCourseEnvironment().getCoursePropertyManager(), this)
+				.getDialogPropertyElements();
+		if(list.size() > 0) {
+			for (DialogElement element:list) {
+				doArchiveElement(element, exportStream);
+				dataFound = true;
+			}
+		}
+		return dataFound;
+	}
+	
+	/**
+	 * Archive a single dialog element with files and forum
+	 * @param element
+	 * @param exportDirectory
+	 */
+	public void doArchiveElement(DialogElement element, ZipOutputStream exportStream) {
+		// append export timestamp to avoid overwriting previous export 
+		String exportDirName = Formatter.makeStringFilesystemSave(getShortTitle())
+				+ "_" + element.getForumKey()
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+		
+		VFSContainer forumContainer = getForumContainer(element.getForumKey());
+		for(VFSItem item: forumContainer.getItems(new VFSLeafFilter())) {
+			ZipUtil.addToZip(item, exportDirName, exportStream);
+		}
+
+		ForumArchiveManager fam = ForumArchiveManager.getInstance();
+		ForumFormatter ff = new ForumStreamedRTFFormatter(exportStream, exportDirName, false);
+		fam.applyFormatter(ff, element.getForumKey(), null);
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/FOCourseNode.java b/src/main/java/org/olat/course/nodes/FOCourseNode.java
index 05992dbb5e65f41702927d4c982af0325d51b77f..ac76d8192d433c7fae38b09fb9fe3fc6bdccbd8a 100644
--- a/src/main/java/org/olat/course/nodes/FOCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/FOCourseNode.java
@@ -25,11 +25,11 @@
 
 package org.olat.course.nodes;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
@@ -49,9 +49,6 @@ import org.olat.core.util.coordinate.SyncerCallback;
 import org.olat.core.util.notifications.NotificationsManager;
 import org.olat.core.util.notifications.SubscriptionContext;
 import org.olat.core.util.resource.OresHelper;
-import org.olat.core.util.vfs.LocalFolderImpl;
-import org.olat.core.util.vfs.VFSContainer;
-import org.olat.core.util.vfs.VFSItem;
 import org.olat.course.CourseModule;
 import org.olat.course.ICourse;
 import org.olat.course.condition.Condition;
@@ -71,12 +68,13 @@ import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.ForumCallback;
 import org.olat.modules.fo.ForumManager;
 import org.olat.modules.fo.archiver.ForumArchiveManager;
-import org.olat.modules.fo.archiver.formatters.ForumRTFFormatter;
+import org.olat.modules.fo.archiver.formatters.ForumStreamedRTFFormatter;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
 import org.olat.testutils.codepoints.server.Codepoint;
@@ -352,7 +350,6 @@ public class FOCourseNode extends AbstractAccessableCourseNode {
 		return oneClickStatusCache;
 	}
 	
-	
 	/**
 	 * @see org.olat.course.nodes.CourseNode#getReferencedRepositoryEntry()
 	 */
@@ -367,41 +364,23 @@ public class FOCourseNode extends AbstractAccessableCourseNode {
 		return false;
 	}
 
-	
-	
-	/**
-	 * 
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale, org.olat.course.ICourse, java.io.File, java.lang.String)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		boolean dataFound = false;
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
 		CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
 		Property forumKeyProperty = cpm.findCourseNodeProperty(this, null, null, FORUM_KEY);
-		if(forumKeyProperty != null){			
-			Long forumKey = forumKeyProperty.getLongValue();
-			if(ForumManager.getInstance().getMessagesByForumID(forumKey).size()>0) {			
-			  String forumName = Formatter.makeStringFilesystemSave(this.getShortTitle());
-
-			  // append export timestamp to avoid overwriting previous export
-			  Date tmp = new Date(System.currentTimeMillis());
-			  java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss_SSS");
-			  forumName += "_"+formatter.format(tmp);
-			
-			  VFSContainer container = new LocalFolderImpl(exportDirectory);
-			  VFSItem vfsItem = container.resolve(forumName);
-			
-			  if (vfsItem == null || !(vfsItem instanceof VFSContainer)){
-				  vfsItem = container.createChildContainer(forumName);
-			  }
-			  container = (VFSContainer)vfsItem;
-				
-			  ForumRTFFormatter rtff = new ForumRTFFormatter(container, false);	
-			  ForumArchiveManager fam = ForumArchiveManager.getInstance();
-			  fam.applyFormatter(rtff, forumKey.longValue(), null);
-			  dataFound = true;
-			}
+		if(forumKeyProperty == null) {
+			return false;
+		}
+		Long forumKey = forumKeyProperty.getLongValue();
+		if(ForumManager.getInstance().countThreadsByForumID(forumKey) <= 0) {
+			return false;
 		}
-		return dataFound;
+		
+		String forumName = "forum_" + Formatter.makeStringFilesystemSave(getShortTitle())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+		ForumStreamedRTFFormatter rtff = new ForumStreamedRTFFormatter(exportStream, forumName, false);	
+		ForumArchiveManager.getInstance().applyFormatter(rtff, forumKey, null);
+		return true;
 	}
 
 	/**
@@ -503,7 +482,6 @@ public class FOCourseNode extends AbstractAccessableCourseNode {
 		//
 		return retVal;
 	}
-
 }
 /**
  * 
diff --git a/src/main/java/org/olat/course/nodes/GenericCourseNode.java b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
index 23f42d07f1a80bcdb96b10e52020e8ac2089f59d..c63d77c0cb4103e48aabf0e75886076421ce1432 100644
--- a/src/main/java/org/olat/course/nodes/GenericCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
@@ -29,6 +29,7 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
@@ -56,6 +57,7 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.TreeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.group.model.BGAreaReference;
 import org.olat.group.model.BusinessGroupReference;
 import org.olat.modules.ModuleConfiguration;
@@ -362,11 +364,11 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
 	 * implementation.
 	 * 
 	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
+	 *      org.olat.course.ICourse, java.util.zip.ZipOutputStream, String charset)
 	 */
-	//implemented by specialized node
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-	// nothing to do in default implementation
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		// nothing to do in default implementation
 		return true;
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
index f618de53cd6859df269cb10f230ac99993b2816d..8a3fea8b3815a1e6c4769aff7f7e57cae896b8c1 100644
--- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java
@@ -26,8 +26,10 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.gui.UserRequest;
@@ -37,6 +39,8 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.gui.translator.PackageTranslator;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
@@ -51,6 +55,7 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.ims.qti.QTIResultManager;
 import org.olat.ims.qti.QTIResultSet;
 import org.olat.ims.qti.export.QTIExportFormatter;
@@ -72,7 +77,8 @@ import de.bps.onyx.plugin.OnyxModule;
  * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>)
  */
 public class IQSELFCourseNode extends AbstractAccessableCourseNode implements SelfAssessableCourseNode, QTICourseNode {
-
+	private static final long serialVersionUID = -1929987728611139729L;
+	private static final OLog log = Tracing.createLoggerFor(IQSELFCourseNode.class);
 	private static final String PACKAGE_IQ = Util.getPackageName(IQRunController.class);
 	private static final String TYPE = "iqself";
 
@@ -205,22 +211,19 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se
 		}
 	}
 
-	/**
-	 * Override default implementation
-	 * 
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		super.archiveNodeData(locale, course, exportDirectory, charset);
-
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
 		QTIExportManager qem = QTIExportManager.getInstance();
 		String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
-		Long repKey = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, true).getKey();
+		RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, true);
 		
-  	QTIExportFormatter qef = new QTIExportFormatterCSVType2(locale,null,"\t", "\"", "\\", "\r\n", false);
-  	return qem.selectAndExportResults(qef, course.getResourceableId(), this.getShortTitle(), this.getIdent(), repKey, exportDirectory,charset, ".xls");
-  	
+		try {
+			QTIExportFormatter qef = new QTIExportFormatterCSVType2(locale, null, "\t", "\"", "\\", "\r\n", false);
+			return qem.selectAndExportResults(qef, course.getResourceableId(), getShortTitle(), getIdent(), re, exportStream, charset, ".xls");
+		} catch (IOException e) {
+			log.error("", e);
+			return false;
+		}
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
index b262e2a35f905e44b283484dcab73b364f74d080..8754323dcb178bb36cc4fd08c5db0ea45b4e8800 100644
--- a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java
@@ -26,8 +26,10 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.gui.UserRequest;
@@ -37,6 +39,8 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.gui.translator.PackageTranslator;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
@@ -51,6 +55,7 @@ import org.olat.course.repository.ImportReferencesController;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.ims.qti.QTIResultManager;
 import org.olat.ims.qti.export.QTIExportFormatter;
 import org.olat.ims.qti.export.QTIExportFormatterCSVType3;
@@ -68,6 +73,9 @@ import org.olat.repository.RepositoryManager;
  */
 public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QTICourseNode {
 
+	private static final long serialVersionUID = 1672009454920536416L;
+	private static final OLog log = Tracing.createLoggerFor(IQSURVCourseNode.class);
+
 	private static final String PACKAGE = Util.getPackageName(IQSURVCourseNode.class);
 	private static final String TYPE = "iqsurv";
 	/** category that is used to persist the node properties */
@@ -200,22 +208,19 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT
 		}
 	}
 
-	/**
-	 * Override default implementation
-	 *
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		super.archiveNodeData(locale, course, exportDirectory, charset);
-
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
 		QTIExportManager qem = QTIExportManager.getInstance();
 		String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
-		Long repKey = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, true).getKey();
+		RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, true);
 
 		QTIExportFormatter qef = new QTIExportFormatterCSVType3(locale, null,"\t", "\"", "\\", "\r\n", false);
-  	return qem.selectAndExportResults(qef, course.getResourceableId(), this.getShortTitle(), this.getIdent(), repKey, exportDirectory,charset, ".xls");
-
+		try {
+			return qem.selectAndExportResults(qef, course.getResourceableId(), getShortTitle(), getIdent(), re, exportStream, charset, ".xls");
+		} catch (IOException e) {
+			log.error("", e);
+			return false;
+		}
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
index 1ae8976bc9445d1c1d8bed32ea16cd8d94064ca6..f8c0c09fbd8b7eaf82558e033bc35ba1d89f5ee5 100644
--- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
@@ -26,8 +26,10 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.gui.UserRequest;
@@ -39,6 +41,8 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.DBRuntimeException;
 import org.olat.core.logging.KnownIssueException;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
@@ -55,19 +59,29 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.ims.qti.QTIResultManager;
+import org.olat.ims.qti.QTIResultSet;
+import org.olat.ims.qti.export.QTIExportFormatter;
+import org.olat.ims.qti.export.QTIExportFormatterCSVType1;
+import org.olat.ims.qti.export.QTIExportManager;
 import org.olat.ims.qti.process.AssessmentInstance;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryImportExport;
 import org.olat.repository.RepositoryManager;
 
+import de.bps.onyx.plugin.OnyxExportManager;
+import de.bps.onyx.plugin.OnyxModule;
+
 /**
  * Initial Date: Feb 9, 2004
  * @author Mike Stock Comment:
  * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>)
  */
 public class IQTESTCourseNode extends AbstractAccessableCourseNode implements AssessableCourseNode, QTICourseNode {
+	private static final long serialVersionUID = 5806292895738005387L;
+	private static final OLog log = Tracing.createLoggerFor(IQTESTCourseNode.class);
 	private static final String TYPE = "iqtest";
 
 	private static final int CURRENT_CONFIG_VERSION = 2;
@@ -359,21 +373,31 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements As
 		}
 	}
 
-
-	/**
-	 * Override default implementation
-	 * 
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		super.archiveNodeData(locale, course, exportDirectory, charset);
-		String repositorySoftKey = (String) getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		String repositorySoftKey = (String)getModuleConfiguration().get(IQEditController.CONFIG_KEY_REPOSITORY_SOFTKEY);
 		Long courseResourceableId = course.getResourceableId();
-		String shortTitle = this.getShortTitle();
-		String ident = this.getIdent();
-		return IQUIFactory.archive(locale, repositorySoftKey, courseResourceableId, shortTitle, ident, exportDirectory, charset);
-  
+
+		try {
+			RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftKey, true);
+			boolean onyx = OnyxModule.isOnyxTest(re.getOlatResource());
+			if (onyx) {
+				QTIResultManager qrm = QTIResultManager.getInstance();
+				List<QTIResultSet> results = qrm.getResultSets(courseResourceableId, getIdent(), re.getKey(), null);
+				if (results.size() > 0) {
+					OnyxExportManager.getInstance().exportResults(results, exportStream, this);
+				}
+				return true;
+			} else {
+				String shortTitle = getShortTitle();
+				QTIExportManager qem = QTIExportManager.getInstance();
+				QTIExportFormatter qef = new QTIExportFormatterCSVType1(locale, "\t", "\"", "\\", "\r\n", false);
+				return qem.selectAndExportResults(qef, courseResourceableId, shortTitle, getIdent(), re, exportStream, charset, ".xls");
+			}
+		} catch (IOException e) {
+			log.error("", e);
+			return false;
+		}
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/MSCourseNode.java b/src/main/java/org/olat/course/nodes/MSCourseNode.java
index c09f3184555db96a17af9aadf145211142acc638..b82ccb58411aba63906d771f63ea3f241e2f2c1b 100644
--- a/src/main/java/org/olat/course/nodes/MSCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/MSCourseNode.java
@@ -25,6 +25,7 @@
 
 package org.olat.course.nodes;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 
@@ -44,6 +45,7 @@ import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.bulk.BulkAssessmentToolController;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
@@ -53,10 +55,12 @@ import org.olat.course.nodes.ms.MSCourseNodeRunController;
 import org.olat.course.nodes.ms.MSEditFormController;
 import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.properties.PersistingCoursePropertyManager;
+import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
@@ -69,8 +73,8 @@ import org.olat.resource.OLATResource;
  * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>)
  */
 public class MSCourseNode extends AbstractAccessableCourseNode implements AssessableCourseNode {
+	private static final long serialVersionUID = -7741172700015384397L;
 	private static final String PACKAGE_MS = Util.getPackageName(MSCourseNodeRunController.class);
-
 	private static final String PACKAGE = Util.getPackageName(MSCourseNode.class);
 
 	private static final String TYPE = "ms";
@@ -430,6 +434,13 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Assess
 		throw new OLATRuntimeException(MSCourseNode.class, "Details controler not available in MS nodes", null);
 	}
 
+	@Override
+	public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, BusinessGroup limitToGroup) {
+		List<Controller> tools = new ArrayList<>(1);
+		tools.add(new BulkAssessmentToolController(ureq, wControl, courseEnv, this));
+		return tools;
+	}
+
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsListView(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
diff --git a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
index b700bc10d7a7f96ca484bbf3cf53a1f5ef85aa66..271ba7dcf76586627db9499038ccf74e4d4433a8 100644
--- a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
@@ -26,15 +26,18 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.bc.FolderConfig;
+import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.commons.services.taskexecutor.TaskExecutorManager;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
@@ -50,14 +53,19 @@ import org.olat.core.id.context.BusinessControl;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLATRuntimeException;
+import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.Formatter;
 import org.olat.core.util.Util;
-import org.olat.core.util.WebappHelper;
 import org.olat.core.util.ZipUtil;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.VFSManager;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.bulk.BulkAssessmentToolController;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
@@ -79,10 +87,12 @@ import org.olat.course.nodes.ta.ReturnboxController;
 import org.olat.course.nodes.ta.TaskController;
 import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.properties.PersistingCoursePropertyManager;
+import org.olat.course.run.environment.CourseEnvironment;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
@@ -94,7 +104,10 @@ import org.olat.resource.OLATResource;
  */
 
 public class ProjectBrokerCourseNode extends GenericCourseNode implements AssessableCourseNode {
-	
+
+	private static final long serialVersionUID = -8177448874150049173L;
+	private static final OLog log = Tracing.createLoggerFor(ProjectBrokerCourseNode.class);
+
 	private transient static final String PACKAGE_PROJECTBROKER = Util.getPackageName(ProjectListController.class);
 
 	private transient static final String PACKAGE = Util.getPackageName(ProjectBrokerCourseNode.class);
@@ -655,6 +668,14 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Assess
 		throw new AssertException("ProjectBroker does not support AssessmentTool");
 	}
 
+	/** Factory method to launch course element assessment tools. limitToGroup is optional to skip he the group choose step */
+	@Override
+	public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, BusinessGroup limitToGroup) {
+		List<Controller> tools = new ArrayList<>(1);
+		tools.add(new BulkAssessmentToolController(ureq, wControl, courseEnv, this));
+		return tools;
+	}
+
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsListView(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
@@ -692,127 +713,62 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Assess
 		ProjectBroker projectBroker = ProjectBrokerManagerFactory.getProjectBrokerManager().createAndSaveProjectBroker();
 		CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
 		ProjectBrokerManagerFactory.getProjectBrokerManager().saveProjectBrokerId(projectBroker.getKey(), cpm, this);
-		
 		return null;
 	}
-
-	/**
-	 * archives the dropbox of this task course node to the user's personal folder
-	 * under private/archive/[coursename]/dropboxes/[nodeIdent].zip
-	 * 
-	 * @param locale
-	 * @param course
-	 * @param fArchiveDirectory
-	 * @param charset
-	 */
+	
 	@Override
-	public boolean archiveNodeData(Locale locale, ICourse course, File fArchiveDirectory, String charset) {
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
 		boolean dataFound = false;
-		String dropboxPath = FolderConfig.getCanonicalRoot() + DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
-		File dropboxDir = new File(dropboxPath);
-		String returnboxPath = FolderConfig.getCanonicalRoot() + ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
-		File returnboxDir = new File(returnboxPath);
-
-		if (dropboxDir.exists() || returnboxDir.exists() ){
-			// Create Temp Dir for zipping
-			String tmpDirPath = WebappHelper.getTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath();
-			File tmpDir = new File( tmpDirPath );
-			if (!tmpDir.exists()) {
-			  tmpDir.mkdirs();
-			}
-
-			// prepare writing course results overview table
-// TODO:ch 28.01.2010 : ProjectBroker does not support assessment-tool in V1.0			
-// 			
-//			List users = ScoreAccountingHelper.loadUsers(course.getCourseEnvironment());
-//			List nodes = ScoreAccountingHelper.loadAssessableNodes(course.getCourseEnvironment());
-//			String s = ScoreAccountingHelper.createCourseResultsOverviewTable(users, nodes, course, locale);
-//	
-//			String courseTitle = course.getCourseTitle();
-//			String fileName = ExportUtil.createFileNameWithTimeStamp(courseTitle + "-score", "xls");
-//	
-//			// write course results overview table to filesystem
-//			ExportUtil.writeContentToFile(fileName, s, tmpDir, charset);
+		String dropboxPath = DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
+		OlatRootFolderImpl dropboxDir = new OlatRootFolderImpl(dropboxPath, null);
+		String returnboxPath = ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
+		OlatRootFolderImpl returnboxDir = new OlatRootFolderImpl(returnboxPath, null);
+		if (!dropboxDir.exists() && !returnboxDir.exists()) {
+			return false;
+		}
+		
+		String exportDirName = "projectbroker_" + Formatter.makeStringFilesystemSave(getShortName())
+				  + "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
 
+		try {
 			String projectBrokerTableExport = ProjectBrokerExportGenerator.createCourseResultsOverviewTable(this, course, locale);
-			String tableExportFileName = ExportUtil.createFileNameWithTimeStamp(this.getShortTitle() + "-projectbroker_overview", "xls");
-			ExportUtil.writeContentToFile(tableExportFileName, projectBrokerTableExport, tmpDir, charset);
+			String tableExportFileName = ExportUtil.createFileNameWithTimeStamp(getShortTitle() + "-projectbroker_overview", "xls");
+			exportStream.putNextEntry(new ZipEntry(exportDirName + "/" + tableExportFileName));
+			IOUtils.write(projectBrokerTableExport, exportStream);
+			exportStream.closeEntry();
+		} catch (IOException e) {
+			log.error("", e);
+		}
 
-			// prepare zipping the node directory and the course results overview table
-			Set<String> fileList = new HashSet<String>();
-			// move xls file to tmp dir
-// TODO:ch 28.01.2010 : ProjectBroker does not support assessment-tool in V1.0
-//			fileList.add(fileName);
-			fileList.add(tableExportFileName);
-
-			// copy dropboxes to tmp dir
-			if (dropboxDir.exists()) {
-				//OLAT-6426 archive only dropboxes of users that handed in at least one file -> prevent empty folders in archive
-				boolean validDropboxesfound = false; 
-				File[] themaFolderArray = dropboxDir.listFiles();
-				for(File themaFolder: themaFolderArray){
-					File[] userFolderArray = themaFolder.listFiles();
-					if(userFolderArray==null) continue;
-					for(File userFolder : userFolderArray){
-						if(FileUtils.isDirectoryAndNotEmpty(userFolder)){
-							validDropboxesfound= true;
-							File source = new File(dropboxDir+"/"+themaFolder.getName()+"/"+userFolder.getName());
-							File target = new File(tmpDirPath+"/dropboxes/"+themaFolder.getName()+"/"+userFolder.getName()) ;
-							FileUtils.copyDirContentsToDir(source, target,false, "archive projectbroker dropboxes ");
-						}
-					}
-				}
-				
-				if(validDropboxesfound){
-					// dropboxes exists, so there is something to archive
-					fileList.add("dropboxes");
-					dataFound |= true;
+		// copy dropboxes to tmp dir
+		if (dropboxDir.exists()) {
+			//OLAT-6426 archive only dropboxes of users that handed in at least one file -> prevent empty folders in archive 
+			for(VFSItem themaItem: dropboxDir.getItems()) {
+				if(!(themaItem instanceof VFSContainer)) continue;
+				List<VFSItem> userFolderArray = ((VFSContainer)themaItem).getItems();
+				for(VFSItem userFolder : userFolderArray){
+					if(!VFSManager.isDirectoryAndNotEmpty(userFolder)) continue;
+					String path  = exportDirName + "/dropboxes/" + themaItem.getName();
+					ZipUtil.addToZip(userFolder, path, exportStream);
 				}
 			}
+		}
 			
-			// copy returnboxes to tmp dir
-			if (returnboxDir.exists()) {
-				boolean validReturnboxesfound = false; 
-				File[] themaFolderArray = returnboxDir.listFiles();
-				for(File themaFolder: themaFolderArray){
-					File[] userFolderArray = themaFolder.listFiles();
-					if(userFolderArray==null) continue;
-					for(File userFolder : userFolderArray){
-						if(FileUtils.isDirectoryAndNotEmpty(userFolder)){
-							validReturnboxesfound = true;
-							File source = new File(returnboxDir+"/"+themaFolder.getName()+"/"+userFolder.getName());
-							File target = new File(tmpDirPath + "/returnboxes/"+themaFolder.getName()+"/"+userFolder.getName()) ;
-							FileUtils.copyDirContentsToDir(source , target , false, "archive projectbroker returnboxes");
-						}
-					}
-				}
-				if(validReturnboxesfound){
-					fileList.add("returnboxes");
-					//returnboxes exists, so there is something to archive
-					dataFound |= true;
+		// copy returnboxes to tmp dir
+		if (returnboxDir.exists()) {
+			for(VFSItem themaItem:returnboxDir.getItems()) {
+				if(!(themaItem instanceof VFSContainer)) continue;
+				List<VFSItem> userFolderArray = ((VFSContainer)themaItem).getItems();
+				for(VFSItem userFolder : userFolderArray){
+					if(!VFSManager.isDirectoryAndNotEmpty(userFolder)) continue;
+					String path = exportDirName + "/returnboxes/" + themaItem.getName();
+					ZipUtil.addToZip(userFolder, path, exportStream);
 				}
 			}
-			
-			if(dataFound) {
-			  String zipName = ExportUtil.createFileNameWithTimeStamp(this.getIdent(), "zip");
-
-			  java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss_SSS");
-			  String exportDirName = "projectbroker_" + this.getShortName() + "_" + formatter.format(new Date(System.currentTimeMillis()));
-			  File fDropBoxArchiveDir = new File(fArchiveDirectory, exportDirName);
-			  if (!fDropBoxArchiveDir.exists()) {
-				  fDropBoxArchiveDir.mkdir();
-			  }
-			  File archiveDir = new File(fDropBoxArchiveDir, zipName);	
-			
-			  // zip
-			  dataFound &= ZipUtil.zip(fileList, tmpDir, archiveDir, true);
-			  // Delete all temp files
-			}
-		  FileUtils.deleteDirsAndFiles( tmpDir, true, true);
-		}	
-  	return dataFound;
-	}
+		}
 
+		return dataFound;
+	}
 
 	/**
 	 * @see org.olat.course.nodes.GenericCourseNode#getConditionExpressions()
diff --git a/src/main/java/org/olat/course/nodes/ScormCourseNode.java b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
index 1c3ba6394848e40ddd299d8cd94a7ed9215c28fa..20095e7d5fce3f6594e180604a68c4301bc95c14 100644
--- a/src/main/java/org/olat/course/nodes/ScormCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
@@ -26,9 +26,14 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.Date;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
@@ -36,7 +41,12 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.iframe.DeliveryOptions;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
+import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
@@ -53,9 +63,11 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.scorm.ScormMainManager;
 import org.olat.modules.scorm.ScormPackageConfig;
+import org.olat.modules.scorm.archiver.ScormExportManager;
 import org.olat.modules.scorm.assessment.ScormResultDetailsController;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryImportExport;
@@ -66,7 +78,7 @@ import org.olat.repository.RepositoryEntryImportExport;
  * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>)
  */
 public class ScormCourseNode extends AbstractAccessableCourseNode implements AssessableCourseNode {
-
+	private static final OLog log = Tracing.createLoggerFor(ScormCourseNode.class);
 	private static final long serialVersionUID = 2970594874787761801L;
 	private static final String TYPE = "scorm";
 	private static final int CURRENT_CONFIG_VERSION = 5;
@@ -336,6 +348,24 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Ass
 		}
 	}
 
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		String fileName = "scorm_"
+				+ StringHelper.transformDisplayNameToFileSystemName(getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()))
+				+ ".xls";
+		Translator trans = Util.createPackageTranslator(ScormExportManager.class, locale);
+		String results = ScormExportManager.getInstance().getResults(course.getCourseEnvironment(), this, trans);
+		try {
+			exportStream.putNextEntry(new ZipEntry(fileName));
+			IOUtils.write(results, exportStream);
+			exportStream.closeEntry();
+		} catch (IOException e) {
+			log.error("", e);
+		}
+		return true;
+	}
+
 	/**
 	 * @see org.olat.course.nodes.CourseNode#createInstanceForCopy()
 	 */
@@ -579,6 +609,7 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Ass
 	/**
 	 * @see org.olat.course.nodes.CourseNode#cleanupOnDelete(org.olat.course.ICourse)
 	 */
+	@Override
 	public void cleanupOnDelete(ICourse course) {
 		CoursePropertyManager pm = course.getCourseEnvironment().getCoursePropertyManager();
 		// 1) Delete all properties: score, passed, log, comment, coach_comment,
@@ -591,24 +622,4 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Ass
 		// I would consider refatoring this and setting up an upgrade task that moves the
 		// folders accordingly
 	}
-
-	/**
-	 * Override default implementation
-	 * 
-	 * @see org.olat.course.nodes.CourseNode#archiveNodeData(java.util.Locale,
-	 *      org.olat.course.ICourse, java.io.File)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {	
-		return super.archiveNodeData(locale, course, exportDirectory, charset);
-		// copy all user directories containing the xml files into the export dir
-		
-		// FIXME gs
-		// we would have to work through all users
-		// of the system since data is stored under users name instead of the repo entry
-		// with many users on the system it could take quite some time and the user
-		// is waiting in a workflow
-		// see comment on cleanupOnDelete
-	}
-
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/TACourseNode.java b/src/main/java/org/olat/course/nodes/TACourseNode.java
index f2d61fedbec5797c1575aaed4c5aa68391a8f23f..4180eac948a39f90dcec5945ea178c28c1e16cab 100644
--- a/src/main/java/org/olat/course/nodes/TACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/TACourseNode.java
@@ -28,12 +28,14 @@ package org.olat.course.nodes;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.bc.FolderConfig;
 import org.olat.core.commons.modules.bc.vfs.OlatNamedContainerImpl;
@@ -54,13 +56,16 @@ import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
-import org.olat.core.util.WebappHelper;
 import org.olat.core.util.ZipUtil;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.VFSManager;
 import org.olat.course.ICourse;
 import org.olat.course.archiver.ScoreAccountingHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.bulk.BulkAssessmentToolController;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
@@ -71,6 +76,7 @@ import org.olat.course.editor.StatusDescription;
 import org.olat.course.export.CourseEnvironmentMapper;
 import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.ms.MSEditFormController;
+import org.olat.course.nodes.ta.BulkDownloadToolController;
 import org.olat.course.nodes.ta.DropboxController;
 import org.olat.course.nodes.ta.DropboxScoringViewController;
 import org.olat.course.nodes.ta.ReturnboxController;
@@ -84,6 +90,7 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
@@ -672,14 +679,25 @@ public class TACourseNode extends GenericCourseNode implements AssessableCourseN
 	 *      org.olat.core.gui.control.WindowControl,
 	 *      org.olat.course.run.userview.UserCourseEnvironment)
 	 */
+	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, UserCourseEnvironment userCourseEnvironment) {
 		// prepare file component
 		return new DropboxScoringViewController(ureq, wControl, this, userCourseEnvironment);
 	}
 
+	/** Factory method to launch course element assessment tools. limitToGroup is optional to skip he the group choose step */
+	@Override
+	public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, BusinessGroup limitToGroup) {
+		List<Controller> tools = new ArrayList<Controller>(1);
+		tools.add(new BulkAssessmentToolController(ureq, wControl, courseEnv, this));
+		tools.add(new BulkDownloadToolController(ureq, wControl, courseEnv, limitToGroup, this));
+		return tools;
+	}
+
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsListView(org.olat.course.run.userview.UserCourseEnvironment)
 	 */
+	@Override
 	public String getDetailsListView(UserCourseEnvironment userCourseEnvironment) {
 		Identity identity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
 		CoursePropertyManager propMgr = userCourseEnvironment.getCourseEnvironment().getCoursePropertyManager();
@@ -748,139 +766,89 @@ public class TACourseNode extends GenericCourseNode implements AssessableCourseN
 		return null;
 	}
 
-	/**
-	 * archives the dropbox of this task course node to the user's personal folder
-	 * under private/archive/[coursename]/dropboxes/[nodeIdent].zip
-	 * 
-	 * @param locale
-	 * @param course
-	 * @param fArchiveDirectory
-	 * @param charset
-	 */
 	@Override
-	public boolean archiveNodeData(Locale locale, ICourse course, File fArchiveDirectory, String charset) {
-	  boolean dataFound = false;
-		String dropboxPath = FolderConfig.getCanonicalRoot() + DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
-		File dropboxDir = new File(dropboxPath);
-		String solutionsPath = FolderConfig.getCanonicalRoot() + TACourseNode.getFoldernodesPathRelToFolderBase(course.getCourseEnvironment()) + "/" + this.getIdent();
-		File solutionDir = new File(solutionsPath);
-		String returnboxPath = FolderConfig.getCanonicalRoot() + ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(),this);
-		File returnboxDir = new File(returnboxPath);
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		boolean dataFound = false;
+		String dropboxPath = DropboxController.getDropboxPathRelToFolderRoot(course.getCourseEnvironment(), this);
+		OlatRootFolderImpl dropboxDir = new OlatRootFolderImpl(dropboxPath, null);
+		String solutionsPath = TACourseNode.getFoldernodesPathRelToFolderBase(course.getCourseEnvironment()) + "/" + this.getIdent();
+		OlatRootFolderImpl solutionDir = new OlatRootFolderImpl(solutionsPath, null);
+		String returnboxPath = ReturnboxController.getReturnboxPathRelToFolderRoot(course.getCourseEnvironment(), this);
+		OlatRootFolderImpl returnboxDir = new OlatRootFolderImpl(returnboxPath, null);
+		
 		Boolean hasTask = (Boolean) getModuleConfiguration().get(TACourseNode.CONF_TASK_ENABLED);
+		
+		String dirName = "task_"
+				+ StringHelper.transformDisplayNameToFileSystemName(getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
 
-		if (dropboxDir.exists() || solutionDir.exists() || returnboxDir.exists() || hasTask.booleanValue()){
-			// Create Temp Dir for zipping
-			String tmpDirPath = WebappHelper.getTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath();
-			File tmpDir = new File(tmpDirPath);
-			
-			if (!tmpDir.exists()) {
-			  tmpDir.mkdirs();
-			}
-			//we need a unique dir name
-			File newDir = FileUtils.createTempDir("tmp", "", tmpDir);
-			if(newDir!=null) {
-				tmpDir = newDir;
-				try {
-					tmpDirPath = tmpDir.getCanonicalPath();
-				} catch (IOException e) {
-					log.warn("tmpDir.getCanonicalPath() throws IOException!");
-				}
-			}	
-			
+		if (dropboxDir.exists() || solutionDir.exists() || returnboxDir.exists() || hasTask.booleanValue()){	
 			// prepare writing course results overview table
-			List<Identity> users = ScoreAccountingHelper.loadUsers(course.getCourseEnvironment());
-			List<AssessableCourseNode> nodes = new ArrayList<AssessableCourseNode>();
-			nodes.add(this);
-			String s = ScoreAccountingHelper.createCourseResultsOverviewTable(users, nodes, course, locale);
-	
+			List<Identity> users = group == null ? ScoreAccountingHelper.loadUsers(course.getCourseEnvironment())
+					: ScoreAccountingHelper.loadUsers(group);
+		
 			String courseTitle = course.getCourseTitle();
 			String fileName = ExportUtil.createFileNameWithTimeStamp(courseTitle, "xls");
-	
+			List<AssessableCourseNode> nodes = Collections.<AssessableCourseNode>singletonList(this);
+			String s = ScoreAccountingHelper.createCourseResultsOverviewTable(users, nodes, course, locale);
 			// write course results overview table to filesystem
-			ExportUtil.writeContentToFile(fileName, s, tmpDir, charset);
+			try {
+				exportStream.putNextEntry(new ZipEntry(dirName + "/" + fileName));
+				IOUtils.write(s, exportStream);
+				exportStream.closeEntry();
+			} catch (IOException e) {
+				log.error("", e);
+			}
 
-			// prepare zipping the node directory and the course results overview table
-			Set<String> fileList = new HashSet<String>();
-			// move xls file to tmp dir
-			fileList.add(fileName);
 			// copy solutions to tmp dir
 			if (solutionDir.exists()) {
-				if(FileUtils.isDirectoryAndNotEmpty(solutionDir)){
-					FileUtils.copyDirContentsToDir(solutionDir, new File(tmpDirPath + "/solutions"), false, "archive task course node solutions");
-					fileList.add("solutions");
+				for(VFSItem child:solutionDir.getItems()) {
+					dataFound = true;
+					ZipUtil.addToZip(child, dirName + "/solutions", exportStream);
 				}
 			}
+				
 			// copy dropboxes to tmp dir
 			if (dropboxDir.exists()) {
-			//OLAT-6362 archive only dropboxes of users that handed in at least one file -> prevent empty folders in archive
-				File[] dropBoxContent = dropboxDir.listFiles();
-				boolean validDropboxesfound = false;
-				for (File file : dropBoxContent) {
-					if(FileUtils.isDirectoryAndNotEmpty(file)){
-						validDropboxesfound = true;
-						FileUtils.copyDirContentsToDir(file, new File(tmpDirPath + "/dropboxes/"+file.getName()), false, "archive task course node dropboxes "+file.getName());
+				//OLAT-6362 archive only dropboxes of users that handed in at least one file -> prevent empty folders in archive
+				List<VFSItem> dropBoxContent = dropboxDir.getItems();
+				for (VFSItem file:dropBoxContent) {
+					if(VFSManager.isDirectoryAndNotEmpty(file)){
+						dataFound = true;
+						ZipUtil.addToZip(file, dirName + "/dropboxes", exportStream);
 					}
 				}
-				
-				if(validDropboxesfound){
-					// dropboxes exists and at least one is not empty, so there is something to archive
-					dataFound = true;
-					fileList.add("dropboxes");
-				}
 			}
+			
 			// copy only the choosen task to user taskfolder, loop over all users
-			String taskfolderPath = FolderConfig.getCanonicalRoot() + TACourseNode.getTaskFolderPathRelToFolderRoot(course.getCourseEnvironment(),this);
-			boolean taskFolderExist = false;
+			String taskfolderPath = TACourseNode.getTaskFolderPathRelToFolderRoot(course.getCourseEnvironment(),this);
+			OlatRootFolderImpl taskfolderDir = new OlatRootFolderImpl(taskfolderPath, null);
 			for(Identity identity:users) {
-  			// check if user already chose a task
-			  String assignedTask = TaskController.getAssignedTask(identity, course.getCourseEnvironment(), this);
-			  if (assignedTask != null) {
-			  	// copy choosen task to user folder
-					String tmpUserTaskDirPath = tmpDirPath + "/taskfolders/" + identity.getName();
-			  	FileUtils.copyFileToDir(taskfolderPath + "/" + assignedTask, tmpUserTaskDirPath );
-			  	taskFolderExist = true;
-			  }
-			}
-			if (taskFolderExist) {
-  			fileList.add("taskfolders");
+				// check if user already chose a task
+				String assignedTask = TaskController.getAssignedTask(identity, course.getCourseEnvironment(), this);
+				if (assignedTask != null) {
+					VFSItem item = taskfolderDir.resolve(assignedTask);
+					if(item != null) {
+						// copy choosen task to user folder
+						ZipUtil.addToZip(item, dirName + "/taskfolders/" + identity.getName(), exportStream);
+						dataFound = true;
+					}
+				}
 			}
-			
-			// copy returnboxes to tmp dir
+	
+			// copy returnboxes
 			if (returnboxDir.exists()) {
 				//OLAT-6362 archive only existing returnboxes -> prevent empty folders in archive
-				File[] returnBoxContent = returnboxDir.listFiles();
-				boolean validReturnboxesfound = false;
-				for (File file : returnBoxContent) {
-					if(FileUtils.isDirectoryAndNotEmpty(file)){
-						validReturnboxesfound = true;
-						FileUtils.copyDirContentsToDir(file, new File(tmpDirPath + "/returnboxes/"+file.getName()), false, "archive task course node returnboxes "+file.getName());
+				List<VFSItem> returnBoxContent = returnboxDir.getItems();
+				for (VFSItem file : returnBoxContent) {
+					if(VFSManager.isDirectoryAndNotEmpty(file)){
+						dataFound = true;
+						ZipUtil.addToZip(file, dirName + "/returnboxes", exportStream);
 					}
 				}
-				
-				if(validReturnboxesfound){
-					// returnboxes exists and at least one is not empty, so there is something to archive
-					dataFound = true;
-					fileList.add("returnboxes");
-				}
-			}
-			
-			if(dataFound) {
-				String zipName = ExportUtil.createFileNameWithTimeStamp(this.getIdent(), "zip");
-				
-			  java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss_SSS");
-			  String exportDirName = "task_" + StringHelper.transformDisplayNameToFileSystemName(this.getShortName()) + "_" + formatter.format(new Date(System.currentTimeMillis()));
-			  File fDropBoxArchiveDir = new File(fArchiveDirectory, exportDirName);
-			  if (!fDropBoxArchiveDir.exists()) {
-				  fDropBoxArchiveDir.mkdir();
-			  }
-			  File archiveDir = new File(fDropBoxArchiveDir, zipName);
-			  // zip
-			  dataFound &= ZipUtil.zip(fileList, tmpDir, archiveDir, true);
-			  // Delete all temp files
 			}
-		  FileUtils.deleteDirsAndFiles( tmpDir, true, true);
 		}	
-  	return dataFound;
+		return dataFound;
 	}
 
 	/**
diff --git a/src/main/java/org/olat/course/nodes/WikiCourseNode.java b/src/main/java/org/olat/course/nodes/WikiCourseNode.java
index d7a3d0c934e300af323ba4b8bb40bd9ec80a1789..0fa7c46970975873b0cd712450faa574e99427ab 100644
--- a/src/main/java/org/olat/course/nodes/WikiCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/WikiCourseNode.java
@@ -26,9 +26,11 @@
 package org.olat.course.nodes;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
+import java.util.zip.ZipOutputStream;
 
 import org.olat.basesecurity.BaseSecurityManager;
 import org.olat.core.gui.UserRequest;
@@ -39,15 +41,14 @@ import org.olat.core.gui.control.generic.messages.MessageUIFactory;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
+import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.notifications.NotificationsManager;
 import org.olat.core.util.notifications.SubscriptionContext;
-import org.olat.core.util.vfs.LocalFolderImpl;
 import org.olat.core.util.vfs.VFSContainer;
-import org.olat.core.util.vfs.VFSLeaf;
-import org.olat.core.util.vfs.VFSManager;
 import org.olat.course.ICourse;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionInterpreter;
@@ -61,7 +62,9 @@ import org.olat.course.repository.ImportReferencesController;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.group.BusinessGroup;
 import org.olat.modules.ModuleConfiguration;
+import org.olat.modules.wiki.Wiki;
 import org.olat.modules.wiki.WikiManager;
 import org.olat.modules.wiki.WikiToZipUtils;
 import org.olat.repository.RepositoryEntry;
@@ -74,6 +77,8 @@ import org.olat.repository.RepositoryManager;
  * @author Felix Jost
  */
 public class WikiCourseNode extends AbstractAccessableCourseNode {
+	
+	private static final OLog log = Tracing.createLoggerFor(WikiCourseNode.class);
 
 	public static final String TYPE = "wiki";
 	private Condition preConditionEdit;
@@ -223,46 +228,34 @@ public class WikiCourseNode extends AbstractAccessableCourseNode {
 			return new ImportReferencesController(ureq, wControl, this, ImportReferencesController.IMPORT_WIKI,rie);
 		}
 	}
-	
-
 
-	/**
-	 * @see org.olat.course.nodes.GenericCourseNode#archiveNodeData(java.util.Locale, org.olat.course.ICourse, java.io.File, java.lang.String)
-	 */
-	public boolean archiveNodeData(Locale locale, ICourse course, File exportDirectory, String charset) {
-		String repoRef = (String)this.getModuleConfiguration().get("reporef");
+	@Override
+	public boolean archiveNodeData(Locale locale, ICourse course, BusinessGroup group, ZipOutputStream exportStream, String charset) {
+		String repoRef = (String)getModuleConfiguration().get("reporef");
 		OLATResourceable ores = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repoRef, true).getOlatResource();
 		
-		if(WikiManager.getInstance().getOrLoadWiki(ores).getAllPagesWithContent().size()>0) {
-		  //OK, there is somthing to archive 
-		  VFSContainer exportContainer = new LocalFolderImpl(exportDirectory);
-		  VFSContainer wikiExportContainer = (VFSContainer)exportContainer.resolve(WikiManager.WIKI_RESOURCE_FOLDER_NAME);
-		  if(wikiExportContainer == null){
-			  wikiExportContainer = exportContainer.createChildContainer(WikiManager.WIKI_RESOURCE_FOLDER_NAME);
-		  }
-		  String exportDirName = getShortTitle()+"_"+Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
-		  VFSContainer destination = wikiExportContainer.createChildContainer(exportDirName);
-			if (destination==null) {
-				exportDirName = VFSManager.rename(wikiExportContainer, exportDirName);
-				destination = wikiExportContainer.createChildContainer(exportDirName);
-			}
-			if (destination==null) {
-				Tracing.logError("archiveNodeData: Could not create destination directory: wikiExportContainer="+wikiExportContainer+", exportDirName="+exportDirName, getClass());
-				return false;
-			}
-			
-		  VFSContainer container = WikiManager.getInstance().getWikiContainer(ores, WikiManager.WIKI_RESOURCE_FOLDER_NAME);
-		  if(container!=null) { //the container could be null if the wiki is an old empty one - so nothing to archive
-		    VFSContainer parent = container.getParentContainer();
-		    VFSLeaf wikiZip = WikiToZipUtils.getWikiAsZip(parent);
-		    destination.copyFrom(wikiZip);
-		  }
-		  return true;
-		}		
-	  //empty wiki, no need to archive
-  	return false;
+		Wiki wiki = WikiManager.getInstance().getOrLoadWiki(ores);
+		if(wiki.getAllPagesWithContent().isEmpty()) {
+			return false;
+		}
+		 
+		//OK, there is something to archive 
+		String currentPath = "wiki_"
+				+ StringHelper.transformDisplayNameToFileSystemName(getShortName())
+				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
+		
+		VFSContainer container = WikiManager.getInstance().getWikiContainer(ores, WikiManager.WIKI_RESOURCE_FOLDER_NAME);
+		if(container != null) { //the container could be null if the wiki is an old empty one - so nothing to archive
+		    try {
+				VFSContainer parent = container.getParentContainer();
+				WikiToZipUtils.wikiToZip(parent, currentPath, exportStream);
+			} catch (IOException e) {
+				log.error("", e);
+			} 
+		}
+		return true;
 	}
-	
+
 	public Condition getPreConditionEdit() {
 		if (preConditionEdit == null) {
 			preConditionEdit = new Condition();
diff --git a/src/main/java/org/olat/course/nodes/iq/IQControllerCreator.java b/src/main/java/org/olat/course/nodes/iq/IQControllerCreator.java
index ffd199ee9e2e5540ace50fbee0953401a6934075..67dd46c493653dccc52a962e49f07cd5a9a998ef 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQControllerCreator.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQControllerCreator.java
@@ -24,9 +24,6 @@
 */
 package org.olat.course.nodes.iq;
 
-import java.io.File;
-import java.util.Locale;
-
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
@@ -106,15 +103,4 @@ public interface IQControllerCreator {
 
 	public Controller createIQTestDetailsEditController(Long courseResourceableId, String ident, Identity identity,
 			RepositoryEntry referencedRepositoryEntry, String qmdEntryTypeAssess, UserRequest ureq, WindowControl wControl);
-	
-	/**
-	 * todo:remove to proper place
-	 * @param locale
-	 * @param course
-	 * @param exportDirectory
-	 * @param charset
-	 * @return
-	 */
-	public boolean archiveIQTestCourseNode(Locale locale, String repositorySoftkey, Long courseResourceableId, String shortTitle,  String ident, File exportDirectory, String charset);
-	
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/iq/IQControllerCreatorOlat.java b/src/main/java/org/olat/course/nodes/iq/IQControllerCreatorOlat.java
index 9503309a3afdfe6b9d6f0f26b901ea056e45fdde..f385061747c95ddfc52121e1408bd5d370217a47 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQControllerCreatorOlat.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQControllerCreatorOlat.java
@@ -24,10 +24,6 @@
 */
 package org.olat.course.nodes.iq;
 
-import java.io.File;
-import java.util.List;
-import java.util.Locale;
-
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
@@ -40,31 +36,22 @@ import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Roles;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
-import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
 import org.olat.course.groupsandrights.CourseGroupManager;
-import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.IQSELFCourseNode;
 import org.olat.course.nodes.IQSURVCourseNode;
 import org.olat.course.nodes.IQTESTCourseNode;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.ims.qti.QTI12ResultDetailsController;
-import org.olat.ims.qti.QTIResultManager;
-import org.olat.ims.qti.QTIResultSet;
-import org.olat.ims.qti.export.QTIExportFormatter;
-import org.olat.ims.qti.export.QTIExportFormatterCSVType1;
-import org.olat.ims.qti.export.QTIExportManager;
 import org.olat.ims.qti.fileresource.SurveyFileResource;
 import org.olat.ims.qti.fileresource.TestFileResource;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.iq.IQSecurityCallback;
 import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryManager;
 
 import de.bps.ims.qti.QTIResultDetailsController;
-import de.bps.onyx.plugin.OnyxExportManager;
 import de.bps.onyx.plugin.OnyxModule;
 import de.bps.onyx.plugin.run.OnyxRunController;
 
@@ -246,25 +233,4 @@ public class IQControllerCreatorOlat implements IQControllerCreator {
 			return new QTI12ResultDetailsController(ureq, wControl, courseResourceableId, ident, identity, referencedRepositoryEntry, qmdEntryTypeAssess);
 		}
 	}
-
-	@Override
-	public boolean archiveIQTestCourseNode(Locale locale, String repositorySoftkey, Long courseResourceableId, String shortTitle,  String ident, File exportDirectory, String charset) {
-		boolean onyx = OnyxModule.isOnyxTest(RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftkey, true).getOlatResource());
-		if (onyx) {
-			ICourse course = CourseFactory.loadCourse(courseResourceableId);
-			CourseNode currentCourseNode = course.getRunStructure().getNode(ident);
-			Long repKey = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftkey, true).getKey();
-			QTIResultManager qrm = QTIResultManager.getInstance();
-			List<QTIResultSet> results = qrm.getResultSets(courseResourceableId, ident, repKey, null);
-			if (results.size() > 0) {
-				OnyxExportManager.getInstance().exportResults(results, exportDirectory, currentCourseNode);
-			}
-			return true;
-		} else {
-			QTIExportManager qem = QTIExportManager.getInstance();
-			Long repKey = RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repositorySoftkey, true).getKey();
-			QTIExportFormatter qef = new QTIExportFormatterCSVType1(locale,"\t", "\"", "\\", "\r\n", false);
-			return qem.selectAndExportResults(qef, courseResourceableId, shortTitle, ident, repKey, exportDirectory,charset, ".xls");
-		}
-	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/iq/IQEditReplaceWizard.java b/src/main/java/org/olat/course/nodes/iq/IQEditReplaceWizard.java
index 4d364c5bbecea2e0abc98c7935499b31ea301ab3..22b98af4ea1b71a8ef7f5198b57528f7cc5ef860 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQEditReplaceWizard.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQEditReplaceWizard.java
@@ -194,8 +194,7 @@ public class IQEditReplaceWizard extends WizardController {
 			String charset = um.getUserCharset(ureq.getIdentity());
 			QTIExportManager qem = QTIExportManager.getInstance();
 			Long repositoryRef = results.get(0).getResultSet().getRepositoryRef();
-			QTIObjectTreeBuilder qotb = new QTIObjectTreeBuilder(repositoryRef);
-			List<QTIItemObject> qtiItemObjectList = qotb.getQTIItemObjectList();
+			List<QTIItemObject> qtiItemObjectList = new QTIObjectTreeBuilder().getQTIItemObjectList(repositoryRef);
 			QTIExportFormatter formatter = new QTIExportFormatterCSVType1(ureq.getLocale(), "\t", "\"", "\\", "\r\n", false);
 			Map<Class<?>, QTIExportItemFormatConfig> qtiItemConfigs = getQTIItemConfigs(qtiItemObjectList);
 			formatter.setMapWithExportItemConfigs(qtiItemConfigs);
diff --git a/src/main/java/org/olat/course/nodes/iq/IQUIFactory.java b/src/main/java/org/olat/course/nodes/iq/IQUIFactory.java
index 9eef41714723fcdd3ea9d5715875e9b4dc4223fd..37b9487b78fc1fbc6026daa04a3e6b43e329cbab 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQUIFactory.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQUIFactory.java
@@ -24,9 +24,6 @@
 */
 package org.olat.course.nodes.iq;
 
-import java.io.File;
-import java.util.Locale;
-
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.StackedController;
 import org.olat.core.gui.control.Controller;
@@ -106,9 +103,4 @@ public class IQUIFactory {
 		return IQUIFactory.iqControllerCreator.createIQTestDetailsEditController(courseResourceableId, ident, identity,
 				referencedRepositoryEntry, qmdEntryTypeAssess, ureq, wControl);
 	}
-
-	public static boolean archive(Locale locale, String repositorySoftkey, Long courseResourceableId, String shortTitle,  String ident, File exportDirectory, String charset){
-		return IQUIFactory.iqControllerCreator.archiveIQTestCourseNode(locale, repositorySoftkey, courseResourceableId, shortTitle, ident, exportDirectory, charset);
-	}
-	
 }
diff --git a/src/main/java/org/olat/course/nodes/ta/BulkDownloadToolController.java b/src/main/java/org/olat/course/nodes/ta/BulkDownloadToolController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e3c2172ba782849b8cd8917c97b74b2a43ecbc6
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/ta/BulkDownloadToolController.java
@@ -0,0 +1,77 @@
+/**
+ * <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.course.nodes.ta;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+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.course.archiver.ArchiveResource;
+import org.olat.course.nodes.AssessableCourseNode;
+import org.olat.course.run.environment.CourseEnvironment;
+import org.olat.group.BusinessGroup;
+import org.olat.resource.OLATResource;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class BulkDownloadToolController extends BasicController {
+	
+	private final Link downloadButton;
+
+	private final BusinessGroup group;
+	private final OLATResource courseOres;
+	private final AssessableCourseNode courseNode;
+	
+	public BulkDownloadToolController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv,
+			BusinessGroup group, AssessableCourseNode courseNode) {
+		super(ureq, wControl);
+		this.group = group;
+		this.courseNode = courseNode;
+		courseOres = courseEnv.getCourseGroupManager().getCourseResource();
+		
+		VelocityContainer mainVC = createVelocityContainer("start_button");
+		downloadButton = LinkFactory.createButton("bulk.download.title", mainVC, this);
+		putInitialPanel(mainVC);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(downloadButton == source) {
+			doDownload(ureq);
+		}
+	}
+	
+	private void doDownload(UserRequest ureq) {
+		ArchiveResource resource = new ArchiveResource(courseNode, courseOres, group, getLocale());
+		ureq.getDispatchResult().setResultingMediaResource(resource);
+	}
+}
diff --git a/src/main/java/org/olat/course/nodes/ta/_content/start_button.html b/src/main/java/org/olat/course/nodes/ta/_content/start_button.html
new file mode 100644
index 0000000000000000000000000000000000000000..dcf81d6f13e09451a370c9b1a757ca1c11213f14
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/ta/_content/start_button.html
@@ -0,0 +1 @@
+$r.render("bulk.download.title")
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/ta/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/ta/_i18n/LocalStrings_de.properties
index 53898ac56d7322127b0a83246055235eec2f7f31..8e23a5e01b053692cf902ae1345e5ddb8e18c1e8 100644
--- a/src/main/java/org/olat/course/nodes/ta/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/ta/_i18n/LocalStrings_de.properties
@@ -1,4 +1,5 @@
 #Mon Mar 02 09:54:04 CET 2009
+bulk.download.title=Return box download
 chelp.ass1=Hier bestimmen Sie, wie die Aufgaben im $\:chelp.taskfolder an die Kursteilnehmer verteilt werden.
 chelp.ass2=Sie haben die M\u00F6glichkeit, den Benutzern eine Information anzeigen zu lassen.
 chelp.ass3=Entweder sieht der Benutzer die von Ihnen zur Verf\u00FCgung gestellten Aufgaben und kann sich eine Aufgabe ausw\u00E4hlen - oder ihm wird eine der Aufgaben automatisch zugeteilt.
diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java
index 01ff99294d9ace375a12e49636290a399e99dd02..f4c885c1c49a3a3cbd80d6ecf771a53d93809015 100644
--- a/src/main/java/org/olat/course/run/RunMainController.java
+++ b/src/main/java/org/olat/course/run/RunMainController.java
@@ -88,7 +88,7 @@ import org.olat.course.ICourse;
 import org.olat.course.archiver.ArchiverMainController;
 import org.olat.course.archiver.IArchiverCallback;
 import org.olat.course.assessment.AssessmentChangedEvent;
-import org.olat.course.assessment.AssessmentUIFactory;
+import org.olat.course.assessment.AssessmentMainController;
 import org.olat.course.assessment.CoachingGroupAccessAssessmentCallback;
 import org.olat.course.assessment.EfficiencyStatementController;
 import org.olat.course.assessment.EfficiencyStatementManager;
@@ -844,20 +844,20 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 		
 		// 1) course admins and users with tool right: full access
 		if (hasCourseRight(CourseRights.RIGHT_ASSESSMENT) || isCourseAdmin) {
-			Activateable2 assessmentToolCtr = 
-				AssessmentUIFactory.createAssessmentMainController(ureq, swControl, all, course, new FullAccessAssessmentCallback(isCourseAdmin));
+			AssessmentMainController assessmentToolCtr = new AssessmentMainController(ureq, swControl, all, course,
+					new FullAccessAssessmentCallback(isCourseAdmin));
 			assessmentToolCtr.activate(ureq, null, null);
-			currentToolCtr = (Controller)assessmentToolCtr;
+			currentToolCtr = assessmentToolCtr;
 			listenTo(currentToolCtr);
 			all.pushController(translate("command.openassessment"), currentToolCtr);
 			return assessmentToolCtr;
 		}
 		// 2) users with coach right: limited access to coached groups
 		else if (isCourseCoach) {
-			Activateable2 assessmentToolCtr = AssessmentUIFactory.createAssessmentMainController(ureq, swControl, all, course,
+			AssessmentMainController assessmentToolCtr =  new AssessmentMainController(ureq, swControl, all, course,
 					new CoachingGroupAccessAssessmentCallback());
 			assessmentToolCtr.activate(ureq, null, null);
-			currentToolCtr = (Controller)assessmentToolCtr;
+			currentToolCtr = assessmentToolCtr;
 			listenTo(currentToolCtr);
 			all.pushController(translate("command.openassessment"), currentToolCtr);
 			return assessmentToolCtr;
diff --git a/src/main/java/org/olat/ims/qti/export/CourseQTIArchiveController.java b/src/main/java/org/olat/ims/qti/export/CourseQTIArchiveController.java
index 167034e09bd1eb7b45e47fa791575fd4d95f5aa5..d9623cf9dfe76ce301afe4cace36953662aece03 100644
--- a/src/main/java/org/olat/ims/qti/export/CourseQTIArchiveController.java
+++ b/src/main/java/org/olat/ims/qti/export/CourseQTIArchiveController.java
@@ -26,9 +26,7 @@
 package org.olat.ims.qti.export;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -48,9 +46,8 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle
 import org.olat.core.id.OLATResourceable;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
-import org.olat.course.assessment.AssessmentHelper;
-import org.olat.course.assessment.AssessmentUIFactory;
 import org.olat.course.assessment.IndentedNodeRenderer;
+import org.olat.course.assessment.NodeTableRow;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.IQSELFCourseNode;
 import org.olat.course.nodes.IQSURVCourseNode;
@@ -76,7 +73,7 @@ public class CourseQTIArchiveController extends BasicController {
 	private CloseableModalController cmc;
 	private OLATResourceable ores;
 	
-	private List nodesTableObjectArrayList;
+	private List<NodeTableRow> nodesTableObjectArrayList;
 	private Link startExportDummyButton;
 	private Link startExportButton;
 	
@@ -114,9 +111,9 @@ public class CourseQTIArchiveController extends BasicController {
 	public void event(UserRequest ureq, Component source, Event event) {
 		ICourse course = CourseFactory.loadCourse(ores);
 		if (source == startExportButton){
-			qawc = AssessmentUIFactory.createQTIArchiveWizardController(false, ureq, nodesTableObjectArrayList, course, getWindowControl());
+			qawc = new QTIArchiveWizardController(false, ureq, nodesTableObjectArrayList, course, getWindowControl());
 		}	else if (source == startExportDummyButton){
-			qawc = AssessmentUIFactory.createQTIArchiveWizardController(true, ureq, nodesTableObjectArrayList, course, getWindowControl());
+			qawc = new QTIArchiveWizardController(true, ureq, nodesTableObjectArrayList, course, getWindowControl());
 		}
 		listenTo(qawc);
 		cmc = new CloseableModalController(getWindowControl(), translate("close"), qawc.getInitialComponent());
@@ -140,7 +137,7 @@ public class CourseQTIArchiveController extends BasicController {
 	 * @param ureq
 	 * @return 
 	 */
-	private List doNodeChoose(UserRequest ureq){
+	private List<NodeTableRow> doNodeChoose(UserRequest ureq){
 	    //table configuraton
 		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
 		tableConfig.setTableEmptyMessage(translate("nodesoverview.nonodes"));
@@ -163,7 +160,7 @@ public class CourseQTIArchiveController extends BasicController {
 		// get list of course node data and populate table data model
 		ICourse course = CourseFactory.loadCourse(ores);
 		CourseNode rootNode = course.getRunStructure().getRootNode();
-		List objectArrayList = addQTINodesAndParentsToList(0, rootNode);
+		List<NodeTableRow> objectArrayList = addQTINodesAndParentsToList(0, rootNode);
 		
 		return objectArrayList;		
 	}
@@ -174,15 +171,15 @@ public class CourseQTIArchiveController extends BasicController {
 	 * @param courseNode
 	 * @return A list of Object[indent, courseNode, selectable]
 	 */
-	@SuppressWarnings("unchecked")
-	private List addQTINodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
+	private List<NodeTableRow> addQTINodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
 		// 1) Get list of children data using recursion of this method
-		List childrenData = new ArrayList();
+		List<NodeTableRow> childrenData = new ArrayList<>();
 		for (int i = 0; i < courseNode.getChildCount(); i++) {
 			CourseNode child = (CourseNode) courseNode.getChildAt(i);
-			List childData = addQTINodesAndParentsToList( (recursionLevel + 1),  child);
-			if (childData != null)
+			List<NodeTableRow> childData = addQTINodesAndParentsToList( (recursionLevel + 1),  child);
+			if (childData != null) {
 				childrenData.addAll(childData);
+			}
 		}
 		
 		if (childrenData.size() > 0
@@ -192,27 +189,17 @@ public class CourseQTIArchiveController extends BasicController {
 			// Store node data in hash map. This hash map serves as data model for 
 			// the tasks overview table. Leave user data empty since not used in
 			// this table. (use only node data)
-			Map nodeData = new HashMap();
-			// indent
-			nodeData.put(AssessmentHelper.KEY_INDENT, new Integer(recursionLevel));
-			// course node data
-			nodeData.put(AssessmentHelper.KEY_TYPE, courseNode.getType());
-			nodeData.put(AssessmentHelper.KEY_TITLE_SHORT, courseNode.getShortTitle());
-			nodeData.put(AssessmentHelper.KEY_TITLE_LONG, courseNode.getLongTitle());
-			nodeData.put(AssessmentHelper.KEY_IDENTIFYER, courseNode.getIdent());
-
+			NodeTableRow nodeData = new NodeTableRow(recursionLevel, courseNode);
 			if (courseNode instanceof IQTESTCourseNode
 			        || courseNode instanceof IQSELFCourseNode
 			        || courseNode instanceof IQSURVCourseNode){
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.TRUE);
-			}
-			else {
-				nodeData.put(AssessmentHelper.KEY_SELECTABLE, Boolean.FALSE);
+				nodeData.setSelectable(true);
+			} else {
+				nodeData.setSelectable(false);
 			}
 			
-			List nodeAndChildren = new ArrayList();
+			List<NodeTableRow> nodeAndChildren = new ArrayList<>();
 			nodeAndChildren.add(nodeData);
-
 			nodeAndChildren.addAll(childrenData);
 			return nodeAndChildren;
 		}
diff --git a/src/main/java/org/olat/ims/qti/export/QTIArchiveWizardController.java b/src/main/java/org/olat/ims/qti/export/QTIArchiveWizardController.java
index d1f3aa7448e04954214c55582a286bfe326d7b96..6246846ab609ad3c3feb2712d7e7060d952d5a4f 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIArchiveWizardController.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIArchiveWizardController.java
@@ -58,9 +58,9 @@ import org.olat.core.util.WebappHelper;
 import org.olat.core.util.coordinate.LockResult;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
-import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.IndentedNodeRenderer;
 import org.olat.course.assessment.NodeTableDataModel;
+import org.olat.course.assessment.NodeTableRow;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.IQSELFCourseNode;
 import org.olat.course.nodes.IQSURVCourseNode;
@@ -89,7 +89,6 @@ import de.bps.onyx.plugin.OnyxExportManager;
  */
 public class QTIArchiveWizardController extends BasicController {
 	private static final String CMD_SELECT_NODE = "cmd.select.node";
-	private static final String CMD_BACK = "back";
 	
 	private boolean dummyMode;
 	
@@ -125,8 +124,8 @@ public class QTIArchiveWizardController extends BasicController {
 	private String targetFileName;
 	private int type;
 	private Map qtiItemConfigs;
-	private List results;
-	private List qtiItemObjectList;
+	private List<QTIResult> results;
+	private List<QTIItemObject> qtiItemObjectList;
 	private Link showFileButton;
 	private Link backLinkAtOptionChoose;
 	private Link backLinkAtNoResults;
@@ -134,7 +133,7 @@ public class QTIArchiveWizardController extends BasicController {
 	private OLATResourceable ores;
 
 
-	public QTIArchiveWizardController(boolean dummyMode, UserRequest ureq, List nodesTableObjectArrayList, OLATResourceable ores, WindowControl wControl) {
+	public QTIArchiveWizardController(boolean dummyMode, UserRequest ureq, List<NodeTableRow> nodesTableObjectArrayList, OLATResourceable ores, WindowControl wControl) {
 		super(ureq, wControl);
 		this.dummyMode = dummyMode;
 		this.ores = ores;
@@ -219,9 +218,9 @@ public class QTIArchiveWizardController extends BasicController {
 				String actionid = te.getActionId();
 				if (actionid.equals(CMD_SELECT_NODE)) {
 					int rowid = te.getRowId();
-					Map nodeData = (Map) nodeTableModel.getObject(rowid);
+					NodeTableRow nodeData = nodeTableModel.getObject(rowid);
 					ICourse course = CourseFactory.loadCourse(ores);
-					this.currentCourseNode = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
+					this.currentCourseNode = course.getRunStructure().getNode(nodeData.getIdent());
 
 					boolean isOnyx = false;
 					if (currentCourseNode.getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE_QTI) != null) {
@@ -275,10 +274,9 @@ public class QTIArchiveWizardController extends BasicController {
 				    
 							QTIResultManager qrm = QTIResultManager.getInstance();
 							results = qrm.selectResults(olatResource, currentCourseNode.getIdent(), repKey, type);
-							QTIResult res0 = (QTIResult) results.get(0);
+							QTIResult res0 = results.get(0);
 							
-							QTIObjectTreeBuilder qotb = new QTIObjectTreeBuilder(new Long(res0.getResultSet().getRepositoryRef()));
-							qtiItemObjectList = qotb.getQTIItemObjectList();
+							qtiItemObjectList = new QTIObjectTreeBuilder().getQTIItemObjectList(new Long(res0.getResultSet().getRepositoryRef()));
 							
 							qtiItemConfigs = getQTIItemConfigs();
 						
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatter.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatter.java
index ab10a5e5bdca7b48f83dacd1ae61c29db5740c97..f2e2753ba3eeec65ec0280b69385e0a020ea74ae 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatter.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatter.java
@@ -34,6 +34,7 @@ import org.olat.core.gui.translator.PackageTranslator;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.util.Util;
 import org.olat.ims.qti.export.helper.IdentityAnonymizerCallback;
+import org.olat.ims.qti.export.helper.QTIItemObject;
 
 /**
  * Initial Date: May 23, 2006 <br>
@@ -45,8 +46,8 @@ public abstract class QTIExportFormatter {
 	protected StringBuilder sb;
 	protected Translator translator;
 	protected IdentityAnonymizerCallback anonymizerCallback;
-	protected List qtiItemObjectList;
-	protected Map mapWithExportItemConfigs;
+	protected List<QTIItemObject> qtiItemObjectList;
+	protected Map<Class<?>, QTIExportItemFormatConfig> mapWithExportItemConfigs;
 	
 	/**
 	 *
@@ -71,7 +72,7 @@ public abstract class QTIExportFormatter {
 	 * 
 	 * @param qtiItemObjectList
 	 */
-	public void setQTIItemObjectList(List qtiItemObjectList){
+	public void setQTIItemObjectList(List<QTIItemObject> qtiItemObjectList){
 		this.qtiItemObjectList = qtiItemObjectList;
 	}
 	
@@ -79,7 +80,7 @@ public abstract class QTIExportFormatter {
 	 * 
 	 * @param mapWithConfigs
 	 */
-	public void setMapWithExportItemConfigs(Map mapWithConfigs){
+	public void setMapWithExportItemConfigs(Map<Class<?>, QTIExportItemFormatConfig> mapWithConfigs){
 		this.mapWithExportItemConfigs = mapWithConfigs;
 	}
 	
@@ -88,7 +89,7 @@ public abstract class QTIExportFormatter {
 	 * 
 	 * @return
 	 */
-	public Map getMapWithExportItemConfigs(){
+	public Map<Class<?>, QTIExportItemFormatConfig> getMapWithExportItemConfigs(){
 		return this.mapWithExportItemConfigs;
 	}
 }
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
index 110d2d5856a7b3133bc31e855f511004e084ef87..38e590b000ac9ddf30ed7e4e511ca8be66590861 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
@@ -95,8 +95,8 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 		StringBuilder hR2 = new StringBuilder();
 		
 		int i = 1;
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject item = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject item = iter.next();
 
 			if (displayItem(qeif.getExportItemConfig(item))) {
 				hR1.append(emb);
@@ -297,8 +297,8 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 		sb.append(legend);
 		sb.append(car + car);
 		int y = 1;
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject element = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject element = iter.next();
 			
 			sb.append(element.getItemIdent());
 			sb.append(sep);
@@ -505,10 +505,10 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 	}
 
 	private void setDefaultQTIItemConfigs() {
-		Map itConfigs = new HashMap();
+		Map<Class<?>, QTIExportItemFormatConfig> itConfigs = new HashMap<>();
   	
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject item = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject item = iter.next();
 			if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)) {
 				if (itConfigs.get(QTIExportSCQItemFormatConfig.class) == null) {
 					QTIExportSCQItemFormatConfig confSCQ = new QTIExportSCQItemFormatConfig(true, false, false, false);
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType2.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType2.java
index 9295d082cc9328eb4ef2a744355b185af0a96c54..3b78ebb91f712140552f5e5402c0b452147674e7 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType2.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType2.java
@@ -481,10 +481,10 @@ public class QTIExportFormatterCSVType2 extends QTIExportFormatter {
 	}
 
 	private void setDefaultQTIItemConfigs() {
-		Map itConfigs = new HashMap();
+		Map<Class<?>, QTIExportItemFormatConfig> itConfigs = new HashMap<>();
   	
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject item = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject item = iter.next();
 			if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)) {
 				if (itConfigs.get(QTIExportSCQItemFormatConfig.class) == null) {
 					QTIExportSCQItemFormatConfig confSCQ = new QTIExportSCQItemFormatConfig(true, false, false, false);
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
index c7a8d54eec938f2008ab674f37c7854fb13dd121..53503c69490b1c82f8baaee802d5b6ed56425d5c 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
@@ -100,8 +100,8 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter{
 		StringBuilder hR2 = new StringBuilder();
 
 		int i = 1;
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject item = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject item = iter.next();
 			if(displayItem(qeif.getExportItemConfig(item))){
 				hR1.append(emb);
 				hR1.append(escape(item.getItemTitle()));
@@ -262,8 +262,8 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter{
 		sb.append(legend);
 		sb.append(car+car);
 		int y = 1;
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-			QTIItemObject element = (QTIItemObject) iter.next();
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+			QTIItemObject element = iter.next();
 			
 			sb.append(element.getItemIdent());
 			sb.append(sep);
@@ -399,11 +399,10 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter{
   	return s.replaceAll(emb, emb + emb);
   }
   
-  @SuppressWarnings("unchecked")
 	private void setDefaultQTIItemConfigs(){
-		Map itConfigs = new HashMap();
+		Map<Class<?>, QTIExportItemFormatConfig> itConfigs = new HashMap<>();
   	
-		for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+		for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
 			QTIItemObject item = (QTIItemObject) iter.next();
 			if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)){
 				if (itConfigs.get(QTIExportSCQItemFormatConfig.class) == null){
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportItemFactory.java b/src/main/java/org/olat/ims/qti/export/QTIExportItemFactory.java
index e1103eefcfe34b9c5282f34761b7f2a452827fd9..6ba8d81dc77535f5b874c9368a73bd06dfb437e7 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportItemFactory.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportItemFactory.java
@@ -38,9 +38,9 @@ import org.olat.ims.qti.export.helper.QTIItemObject;
  * @author Alexander Schneider
  */
 public class QTIExportItemFactory {
-	private Map configs;
+	private Map<Class<?>, QTIExportItemFormatConfig> configs;
 	
-	public QTIExportItemFactory(Map mapWithConfigs){
+	public QTIExportItemFactory(Map<Class<?>, QTIExportItemFormatConfig> mapWithConfigs){
 		this.configs = mapWithConfigs;
 	}
 	
@@ -48,40 +48,40 @@ public class QTIExportItemFactory {
 		QTIExportItem eItem = null;
 		if(item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)){
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportSCQItemFormatConfig) configs.get(QTIExportSCQItemFormatConfig.class));	
+			eItem.setConfig(configs.get(QTIExportSCQItemFormatConfig.class));	
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_MCQ)){ // Checkbox
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportMCQItemFormatConfig) configs.get(QTIExportMCQItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportMCQItemFormatConfig.class));
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_KPRIM)){ // Kprim
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportKPRIMItemFormatConfig) configs.get(QTIExportKPRIMItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportKPRIMItemFormatConfig.class));
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_ESSAY)){ // Area
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportEssayItemFormatConfig) configs.get(QTIExportEssayItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportEssayItemFormatConfig.class));
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_FIB)){ // Blank
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportFIBItemFormatConfig) configs.get(QTIExportFIBItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportFIBItemFormatConfig.class));
 		}
     //	if cannot find the type via the ItemParser, look for the QTIItemObject type
 		else if (item.getItemType().equals(QTIItemObject.TYPE.A)){ 
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportEssayItemFormatConfig) configs.get(QTIExportEssayItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportEssayItemFormatConfig.class));
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.R)){ 
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportSCQItemFormatConfig) configs.get(QTIExportSCQItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportSCQItemFormatConfig.class));
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.C)){
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportMCQItemFormatConfig) configs.get(QTIExportMCQItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportMCQItemFormatConfig.class));
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.B)){
 			eItem = new QTIExportItem(qtir, item);
-			eItem.setConfig((QTIExportFIBItemFormatConfig) configs.get(QTIExportFIBItemFormatConfig.class));
+			eItem.setConfig(configs.get(QTIExportFIBItemFormatConfig.class));
 		}			
 		else{
 			throw new OLATRuntimeException(null,"Can not resolve QTIItem type", null);
@@ -92,37 +92,36 @@ public class QTIExportItemFactory {
 	public QTIExportItemFormatConfig getExportItemConfig(QTIItemObject item){
 		QTIExportItemFormatConfig config = null;
 		if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)){ // Radio
-			config = (QTIExportSCQItemFormatConfig) configs.get(QTIExportSCQItemFormatConfig.class);
+			config = configs.get(QTIExportSCQItemFormatConfig.class);
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_MCQ)){ // Checkbox
-			config = (QTIExportMCQItemFormatConfig) configs.get(QTIExportMCQItemFormatConfig.class);
+			config = configs.get(QTIExportMCQItemFormatConfig.class);
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_KPRIM)){ // KPRIM
-			config = (QTIExportKPRIMItemFormatConfig) configs.get(QTIExportKPRIMItemFormatConfig.class);
+			config = configs.get(QTIExportKPRIMItemFormatConfig.class);
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_ESSAY)){ // Area
-			config = (QTIExportEssayItemFormatConfig) configs.get(QTIExportEssayItemFormatConfig.class);
+			config = configs.get(QTIExportEssayItemFormatConfig.class);
 		}
 		else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_FIB)){ // Blank
-			config = (QTIExportFIBItemFormatConfig) configs.get(QTIExportFIBItemFormatConfig.class);
+			config = configs.get(QTIExportFIBItemFormatConfig.class);
 		}
     //	if cannot find the type via the ItemParser, look for the QTIItemObject type
 		else if (item.getItemType().equals(QTIItemObject.TYPE.A)){
-			config = (QTIExportEssayItemFormatConfig) configs.get(QTIExportEssayItemFormatConfig.class);
+			config = configs.get(QTIExportEssayItemFormatConfig.class);
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.R)){
-			config = (QTIExportSCQItemFormatConfig) configs.get(QTIExportSCQItemFormatConfig.class);
+			config = configs.get(QTIExportSCQItemFormatConfig.class);
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.C)){
-			config = (QTIExportMCQItemFormatConfig) configs.get(QTIExportMCQItemFormatConfig.class);
+			config = configs.get(QTIExportMCQItemFormatConfig.class);
 		}
 		else if (item.getItemType().equals(QTIItemObject.TYPE.B)){
-			config = (QTIExportFIBItemFormatConfig) configs.get(QTIExportFIBItemFormatConfig.class);
+			config = configs.get(QTIExportFIBItemFormatConfig.class);
 		}		
 		else{
 			throw new OLATRuntimeException(null,"Can not resolve QTIItem type", null);
 		}
 		return config;
 	}
-	
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportManager.java b/src/main/java/org/olat/ims/qti/export/QTIExportManager.java
index 995993c2934421fae938d979affc023eec127f6d..e2afdcbcd8ef5d164e6356f13c2e8905c5910bf4 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportManager.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportManager.java
@@ -26,6 +26,7 @@
 package org.olat.ims.qti.export;
 
 import java.io.File;
+import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -33,7 +34,10 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.manager.BasicManager;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.Formatter;
@@ -41,6 +45,7 @@ import org.olat.ims.qti.QTIResult;
 import org.olat.ims.qti.QTIResultManager;
 import org.olat.ims.qti.export.helper.QTIItemObject;
 import org.olat.ims.qti.export.helper.QTIObjectTreeBuilder;
+import org.olat.repository.RepositoryEntry;
 
 /**
  * Description: TODO
@@ -82,17 +87,14 @@ public class QTIExportManager extends BasicManager{
 	 * should be used (only for type 2 and 3)
 	 * @return
 	 */
-	public boolean selectAndExportResults(QTIExportFormatter qef, Long olatResource, String shortTitle, String olatResourceDetail, Long repositoryRef,
-		File exportDirectory, String charset, String fileNameSuffix) {
+	public boolean selectAndExportResults(QTIExportFormatter qef, Long courseResId, String shortTitle, String olatResourceDetail,
+			Long testReKey, File exportDirectory, String charset, String fileNameSuffix) {
 		boolean resultsFoundAndExported = false;
 		QTIResultManager qrm = QTIResultManager.getInstance();
-		List<QTIResult> results = qrm.selectResults(olatResource, olatResourceDetail, repositoryRef, qef.getType());
+		List<QTIResult> results = qrm.selectResults(courseResId, olatResourceDetail, testReKey, qef.getType());
 		if(results.size() > 0){
 			QTIResult res0 = results.get(0);
-			
-			QTIObjectTreeBuilder qotb = new QTIObjectTreeBuilder(new Long(res0.getResultSet().getRepositoryRef()));
-			
-			List<QTIItemObject> qtiItemObjectList = qotb.getQTIItemObjectList();
+			List<QTIItemObject> qtiItemObjectList = new QTIObjectTreeBuilder().getQTIItemObjectList(new Long(res0.getResultSet().getRepositoryRef()));
 			qef.setQTIItemObjectList(qtiItemObjectList);
 			if (results.size() > 0) {
 				createContentOfExportFile(results,qtiItemObjectList,qef);
@@ -103,6 +105,28 @@ public class QTIExportManager extends BasicManager{
 		return resultsFoundAndExported;
 	}
 	
+	public boolean selectAndExportResults(QTIExportFormatter qef, Long courseResId, String shortTitle,
+			String olatResourceDetail, RepositoryEntry testRe, ZipOutputStream exportStream, String charset,
+			String fileNameSuffix) throws IOException {
+		boolean resultsFoundAndExported = false;
+		QTIResultManager qrm = QTIResultManager.getInstance();
+		List<QTIResult> results = qrm.selectResults(courseResId, olatResourceDetail, testRe.getKey(), qef.getType());
+		if(results.size() > 0){
+			List<QTIItemObject> qtiItemObjectList = new QTIObjectTreeBuilder().getQTIItemObjectList(testRe);
+			qef.setQTIItemObjectList(qtiItemObjectList);
+			if (results.size() > 0) {
+				createContentOfExportFile(results, qtiItemObjectList, qef);
+				String targetFileName = getFilename(shortTitle, qef, fileNameSuffix);
+				
+				exportStream.putNextEntry(new ZipEntry(targetFileName));
+				IOUtils.write(qef.getReport(), exportStream);
+				exportStream.closeEntry();
+				resultsFoundAndExported = true;
+			}			
+		}
+		return resultsFoundAndExported;
+	}
+	
 	/**
 	 * 
 	 * @param qef
@@ -114,7 +138,7 @@ public class QTIExportManager extends BasicManager{
 	 * @param fileNameSuffix
 	 * @return
 	 */
-		public String exportResults(QTIExportFormatter qef, List results, List qtiItemObjectList, String shortTitle, File exportDirectory, String charset, String fileNameSuffix) {
+		public String exportResults(QTIExportFormatter qef, List<QTIResult> results, List<QTIItemObject> qtiItemObjectList, String shortTitle, File exportDirectory, String charset, String fileNameSuffix) {
 			String targetFileName = null;
 	
 			qef.setQTIItemObjectList(qtiItemObjectList);
@@ -133,26 +157,24 @@ public class QTIExportManager extends BasicManager{
 	 * @param anonymizerCallback
 	 * @return String
 	 */
-	private void createContentOfExportFile(List qtiResults, List qtiItemObjectList, QTIExportFormatter qef) {
+	private void createContentOfExportFile(List<QTIResult> qtiResults, List<QTIItemObject> qtiItemObjectList, QTIExportFormatter qef) {
 		
 		qef.openReport();
 		
 		//formatter has information about how to format the different qti objects
-		Map mapWithConfigs = qef.getMapWithExportItemConfigs();
+		Map<Class<?>, QTIExportItemFormatConfig> mapWithConfigs = qef.getMapWithExportItemConfigs();
 		QTIExportItemFactory qeif = new QTIExportItemFactory(mapWithConfigs);
 				
 		while (qtiResults.size() > 0){
-			List assessIDresults = stripNextAssessID(qtiResults);
+			List<QTIResult> assessIDresults = stripNextAssessID(qtiResults);
 		
-			qef.openResultSet(new QTIExportSet((QTIResult)assessIDresults.get(0)));
+			qef.openResultSet(new QTIExportSet(assessIDresults.get(0)));
 			
-			for (Iterator iter = qtiItemObjectList.iterator(); iter.hasNext();) {
-				QTIItemObject element = (QTIItemObject) iter.next();
+			for (Iterator<QTIItemObject> iter = qtiItemObjectList.iterator(); iter.hasNext();) {
+				QTIItemObject element = iter.next();
 				
-				QTIResult qtir;
-				qtir = element.extractQTIResult(assessIDresults);
+				QTIResult qtir = element.extractQTIResult(assessIDresults);
 				qef.visit(qeif.getExportItem(qtir,element));
-
 			}
 			qef.closeResultSet();
 		}
@@ -164,6 +186,12 @@ public class QTIExportManager extends BasicManager{
 	 */
 	private String writeContentToFile(String shortTitle, File exportDirectory, String charset, QTIExportFormatter qef, String fileNameSuffix) {
 		// defining target filename
+		String targetFileName = getFilename(shortTitle, qef, fileNameSuffix);
+		ExportUtil.writeContentToFile(targetFileName, qef.getReport(), exportDirectory, charset);
+		return targetFileName;
+	}
+	
+	private String getFilename(String shortTitle, QTIExportFormatter qef, String fileNameSuffix) {
 		StringBuilder tf = new StringBuilder();
 		tf.append(qef.getFileNamePrefix());
 		tf.append(Formatter.makeStringFilesystemSave(shortTitle));
@@ -173,9 +201,6 @@ public class QTIExportManager extends BasicManager{
 		tf.append(timestamp);
 		tf.append(fileNameSuffix);
 		String targetFileName = tf.toString();
-
-		ExportUtil.writeContentToFile(targetFileName, qef.getReport(), exportDirectory, charset);
-		
 		return targetFileName;
 	}
 	
@@ -184,12 +209,12 @@ public class QTIExportManager extends BasicManager{
 	 * @param queryResult
 	 * @return List of results with the same assessmentid
 	 */		
-	private List stripNextAssessID(List queryResult){
-		List result = new ArrayList();
+	private List<QTIResult> stripNextAssessID(List<QTIResult> queryResult){
+		List<QTIResult> result = new ArrayList<>();
 		
 		if (queryResult.size()== 0) return result;
 		
-		QTIResult qtir = (QTIResult) queryResult.remove(0);
+		QTIResult qtir = queryResult.remove(0);
 		
 		long currentAssessmentID = qtir.getResultSet().getAssessmentID();
 		result.add(qtir);
diff --git a/src/main/java/org/olat/ims/qti/export/helper/QTIObjectTreeBuilder.java b/src/main/java/org/olat/ims/qti/export/helper/QTIObjectTreeBuilder.java
index 43dea4e0ae74775edfabd1e7902f51a30b57fb10..c590de99dc77e97e9d8e934aaca844da614241bb 100644
--- a/src/main/java/org/olat/ims/qti/export/helper/QTIObjectTreeBuilder.java
+++ b/src/main/java/org/olat/ims/qti/export/helper/QTIObjectTreeBuilder.java
@@ -33,6 +33,7 @@ import org.dom4j.Document;
 import org.dom4j.Element;
 import org.olat.ims.qti.process.ImsRepositoryResolver;
 import org.olat.ims.qti.process.Resolver;
+import org.olat.repository.RepositoryEntry;
 
 /**
  * <pre>
@@ -84,31 +85,21 @@ import org.olat.ims.qti.process.Resolver;
 
 public class QTIObjectTreeBuilder {
 
-	private Long repositoryEntryKey;
+	public List<QTIItemObject> getQTIItemObjectList(Long entryKey) {
+		Resolver resolver = new ImsRepositoryResolver(entryKey);
+		return getQTIItemObjectList(resolver);
+	}
 	
-	/**
-	 * Constructor for QTIObjectTreeBuilder
-	 * @param repositoryEntryKey
-	 * @param downloadtrans
-	 * @param type
-	 * @param anonymizerCallback
-	 */
-	public QTIObjectTreeBuilder(Long repositoryEntryKey) {
-		this.repositoryEntryKey = repositoryEntryKey;
+	public List<QTIItemObject> getQTIItemObjectList(RepositoryEntry entry) {
+		Resolver resolver = new ImsRepositoryResolver(entry);
+		return getQTIItemObjectList(resolver);
 	}
 	
-	/**
-	 * 
-	 *
-	 */
-	public List<QTIItemObject> getQTIItemObjectList() {
-		Resolver resolver = new ImsRepositoryResolver(repositoryEntryKey);
+	private final List<QTIItemObject> getQTIItemObjectList(Resolver resolver) {
 		Document doc = resolver.getQTIDocument();
 		Element root = doc.getRootElement();
 		List<Element> items = root.selectNodes("//item");
-		
 		List<QTIItemObject> itemList = new ArrayList<QTIItemObject>();
-
 		for (Iterator<Element> iter= items.iterator(); iter.hasNext();) {
 			Element el_item= iter.next();
 			if (el_item.selectNodes(".//response_lid").size() > 0){
diff --git a/src/main/java/org/olat/ims/qti/process/ImsRepositoryResolver.java b/src/main/java/org/olat/ims/qti/process/ImsRepositoryResolver.java
index e89b27210dfbf50240ba5f862c4f9e897790187e..b686d3976fada0b5e25c616a0f74b3eabe205529 100644
--- a/src/main/java/org/olat/ims/qti/process/ImsRepositoryResolver.java
+++ b/src/main/java/org/olat/ims/qti/process/ImsRepositoryResolver.java
@@ -33,6 +33,8 @@ import java.util.List;
 import org.dom4j.Document;
 import org.dom4j.Element;
 import org.olat.core.id.OLATResourceable;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.WebappHelper;
 import org.olat.core.util.vfs.LocalFileImpl;
@@ -51,6 +53,8 @@ import org.olat.resource.OLATResource;
  * @author Mike Stock Comment:
  */
 public class ImsRepositoryResolver implements Resolver {
+	
+	private static final OLog log = Tracing.createLoggerFor(ImsRepositoryResolver.class);
 
 	public static final String QTI_FILE = "qti.xml";
 	public static final String QTI_FIB_AUTOCOMPLETE_JS_FILE = "media/fibautocompl.js";
@@ -67,6 +71,13 @@ public class ImsRepositoryResolver implements Resolver {
 			init(ores);
 		}
 	}
+	
+	public ImsRepositoryResolver(RepositoryEntry entry) {
+		if (entry != null) {
+			OLATResource ores = entry.getOlatResource();
+			init(ores);
+		}
+	}
 
 	public ImsRepositoryResolver(OLATResourceable fileResource) {
 		init(fileResource);
@@ -124,28 +135,27 @@ public class ImsRepositoryResolver implements Resolver {
 			// no change log
 			return new QTIChangeLogMessage[0];
 		}
-		List items = dirChangelog.getItems();
+		List<VFSItem> items = dirChangelog.getItems();
 		// PRECONDITION: only changelog files in the changelog directory
-		QTIChangeLogMessage[] log = new QTIChangeLogMessage[items.size()];
+		QTIChangeLogMessage[] logArr = new QTIChangeLogMessage[items.size()];
 		String filName;
 		String msg;
 		int i = 0;
 		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH_mm_ss");
-		for (Iterator iter = items.iterator(); iter.hasNext();) {
+		for (Iterator<VFSItem> iter = items.iterator(); iter.hasNext();) {
 			VFSLeaf file = (VFSLeaf) iter.next();
 			filName = file.getName();
 			String[] parts = filName.split("\\.");
 			msg = FileUtils.load(file.getInputStream(), "utf-8");
 			try {
-				log[i] = new QTIChangeLogMessage(msg, parts[1].equals("all"), formatter.parse(parts[0]).getTime());
+				logArr[i] = new QTIChangeLogMessage(msg, parts[1].equals("all"), formatter.parse(parts[0]).getTime());
 				i++;
 			} catch (ParseException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
+				log.error("", e);
 			}
 		}
 
-		return log;
+		return logArr;
 	}
 
 	/**
diff --git a/src/main/java/org/olat/modules/fo/ForumController.java b/src/main/java/org/olat/modules/fo/ForumController.java
index ba685d2ca58fccafb4eb508f79c91293053ea122..6946ae486b0b59f5b18a237aefb98974826ad828 100644
--- a/src/main/java/org/olat/modules/fo/ForumController.java
+++ b/src/main/java/org/olat/modules/fo/ForumController.java
@@ -679,7 +679,7 @@ public class ForumController extends BasicController implements GenericEventList
 	private void doArchiveForum(UserRequest ureq) {
 		ForumRTFFormatter rtff = new ForumRTFFormatter(getArchiveContainer(ureq), false);
 		ForumArchiveManager fam = ForumArchiveManager.getInstance();
-		fam.applyFormatter(rtff, forum.getKey().longValue(), focallback);
+		fam.applyFormatter(rtff, forum.getKey(), focallback);
 	}
 
 	private void doArchiveThread(UserRequest ureq, Message currMsg) {
@@ -688,7 +688,7 @@ public class ForumController extends BasicController implements GenericEventList
 
 		ForumRTFFormatter rtff = new ForumRTFFormatter(getArchiveContainer(ureq), true);
 		ForumArchiveManager fam = ForumArchiveManager.getInstance();
-		fam.applyFormatterForOneThread(rtff, forum.getKey().longValue(), topMessageId.longValue());
+		fam.applyFormatterForOneThread(rtff, forum.getKey(), topMessageId);
 	}
 	
 	
diff --git a/src/main/java/org/olat/modules/fo/ForumHelper.java b/src/main/java/org/olat/modules/fo/ForumHelper.java
index 897b8a788c7f58627c7bba00caa7bc92d8102353..3690843e47810101f19c6d34e5cd57ec954de5c7 100644
--- a/src/main/java/org/olat/modules/fo/ForumHelper.java
+++ b/src/main/java/org/olat/modules/fo/ForumHelper.java
@@ -56,22 +56,8 @@ public class ForumHelper {
 	 * @return a MessageNode comparator.
 	 * @see java.util.Comparator 
 	 */
-	public static Comparator getMessageNodeComparator() {
-		return new Comparator(){
-			//puts the sticky threads first
-			public int compare(final Object o1, final Object o2) {
-				MessageNode m1 = (MessageNode)o1;
-				MessageNode m2 = (MessageNode)o2;				
-				if(m1.isSticky() && m2.isSticky()) {
-					return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
-				} else if(m1.isSticky()) {
-					return -1;
-				} else if(m2.isSticky()){
-					return 1;
-				} else {
-					return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
-				}				
-			}};
+	public static Comparator<MessageNode> getMessageNodeComparator() {
+		return new MessageNodeComparator();
 	}
 	
 	/**
@@ -171,4 +157,17 @@ public class ForumHelper {
 		}		
 	}
 	
-}
+	private static class MessageNodeComparator implements Comparator<MessageNode> {
+		public int compare(final MessageNode m1, final MessageNode m2) {			
+			if(m1.isSticky() && m2.isSticky()) {
+				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
+			} else if(m1.isSticky()) {
+				return -1;
+			} else if(m2.isSticky()){
+				return 1;
+			} else {
+				return m2.getModifiedDate().compareTo(m1.getModifiedDate()); //last first
+			}				
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/fo/ForumManager.java b/src/main/java/org/olat/modules/fo/ForumManager.java
index e40193f81924ae74fda6fc34ecb0f520faf63dec..9f95ef823b3638a5e5be60fe4b17014cd8e5c511 100644
--- a/src/main/java/org/olat/modules/fo/ForumManager.java
+++ b/src/main/java/org/olat/modules/fo/ForumManager.java
@@ -66,6 +66,8 @@ public class ForumManager extends BasicManager {
 	private static ForumManager INSTANCE;
 	@Autowired
 	private TextService txtService;
+	@Autowired
+	private DB dbInstance;
 
 	/**
 	 * [spring]
@@ -229,7 +231,7 @@ public class ForumManager extends BasicManager {
 		return messages;
 	}
 	
-	private int countMessagesByForumID(Long forum_id, boolean onlyThreads) {
+	private int countMessagesByForumID(Long forumId, boolean onlyThreads) {
 		StringBuilder query = new StringBuilder();
 		query.append("select count(msg) from ").append(MessageImpl.class.getName()).append(" as msg")
 		     .append(" where msg.forum.key=:forumId ");
@@ -237,11 +239,11 @@ public class ForumManager extends BasicManager {
 			query.append(" and msg.parent is null");
 		}
 		
-		DBQuery dbQuery = DBFactory.getInstance().createQuery(query.toString());
-		dbQuery.setLong("forumId", forum_id);
-		
-		Number totalCount = (Number)dbQuery.uniqueResult();
-		return totalCount.intValue();
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(query.toString(), Number.class)
+				.setParameter("forumId", forumId)
+				.getSingleResult()
+				.intValue();
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java b/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
index 42851f77ccd56d036930a66cd673b3b81f7c6331..650c3669498999f3af68ddf9c31809a8ac64a390 100644
--- a/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
+++ b/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
@@ -28,13 +28,11 @@ package org.olat.modules.fo.archiver;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
+import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
-import org.olat.core.manager.BasicManager;
 import org.olat.core.util.tree.TreeVisitor;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.ForumCallback;
@@ -49,10 +47,10 @@ import org.olat.modules.fo.archiver.formatters.ForumFormatter;
  * @author Alexander Schneider
  */
 
-public class ForumArchiveManager  extends BasicManager {
-	private static ForumArchiveManager instance = new ForumArchiveManager();
+public class ForumArchiveManager {
+	private static final OLog log = Tracing.createLoggerFor(ForumArchiveManager.class);
+	private static final ForumArchiveManager instance = new ForumArchiveManager();
 	
-	//TODO spring config
 	private ForumArchiveManager() {
 		// private since singleton
 	}
@@ -72,14 +70,12 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param forumCallback
 	 * @return
 	 */
-	public String applyFormatter(ForumFormatter forumFormatter, long forumId, ForumCallback forumCallback){
-		Tracing.logInfo("Archiving complete forum: "+forumId, ForumArchiveManager.class);
-		Map metaInfo = new HashMap();
-		metaInfo.put(ForumFormatter.MANDATORY_METAINFO_KEY ,new Long(forumId));
+	public String applyFormatter(ForumFormatter forumFormatter, Long forumId, ForumCallback forumCallback){
+		log.info("Archiving complete forum: " + forumId);
 		//convert forum structure to trees
-		List threadTreesList = convertToThreadTrees(forumId, forumCallback);
+		List<MessageNode> threadTreesList = convertToThreadTrees(forumId, forumCallback);
 		//format forum trees by using the formatter given by the callee
-		return formatForum(threadTreesList, forumFormatter, metaInfo);
+		return formatForum(threadTreesList, forumFormatter, forumId);
 	}
 	/**
 	 * It is assumed that if the caller of this method is allowed to see the forum thread
@@ -89,12 +85,10 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param topMessageId
 	 * @return the message thread as String formatted
 	 */
-	public String applyFormatterForOneThread(ForumFormatter forumFormatter, long forumId, long topMessageId){
-		Tracing.logInfo("Archiving forum.thread: "+forumId+"."+topMessageId, ForumArchiveManager.class);
-		Map metaInfo = new HashMap();
-		metaInfo.put(ForumFormatter.MANDATORY_METAINFO_KEY ,new Long(forumId));
+	public String applyFormatterForOneThread(ForumFormatter forumFormatter, Long forumId, Long topMessageId){
+		log.info("Archiving forum.thread: "+forumId+"."+topMessageId);
 		MessageNode topMessageNode = convertToThreadTree(topMessageId);
-		return formatThread(topMessageNode, forumFormatter, metaInfo);
+		return formatThread(topMessageNode, forumFormatter, forumId);
 	}
 
 	/**
@@ -105,16 +99,15 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param metaInfo
 	 * @return all top message nodes together with their children in a list
 	 */
-	private List convertToThreadTrees(long forumId, ForumCallback forumCallback){
-		List messages;
-		List topNodeList = new ArrayList();
+	private List<MessageNode> convertToThreadTrees(Long forumId, ForumCallback forumCallback){
+		List<MessageNode> topNodeList = new ArrayList<>();
 		ForumManager fm = ForumManager.getInstance();
-		Long l = new Long(forumId);
-		Forum f = fm.loadForum(l);
-		messages = fm.getMessagesByForum(f);
+	
+		Forum f = fm.loadForum(forumId);
+		List<Message> messages = fm.getMessagesByForum(f);
 		
-		for (Iterator iterTop = messages.iterator(); iterTop.hasNext();) {
-			Message msg = (Message) iterTop.next();
+		for (Iterator<Message> iterTop = messages.iterator(); iterTop.hasNext();) {
+			Message msg = iterTop.next();
 			if (msg.getParent() == null) {
 				iterTop.remove();
 				MessageNode topNode = new MessageNode(msg);
@@ -135,8 +128,8 @@ public class ForumArchiveManager  extends BasicManager {
    * @param topNodeList
    * @return the sorted list.
    */	
-	private List getMessagesSorted(List<Message> topNodeList) { 
-		 Comparator messageNodeComparator = ForumHelper.getMessageNodeComparator();
+	private List<MessageNode> getMessagesSorted(List<MessageNode> topNodeList) { 
+		 Comparator<MessageNode> messageNodeComparator = ForumHelper.getMessageNodeComparator();
 		 Collections.sort(topNodeList, messageNodeComparator);
 		 return topNodeList;
 	}
@@ -147,14 +140,11 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param metaInfo
 	 * @return the top message node with all its children
 	 */
-	private MessageNode convertToThreadTree(long topMessageId){
-		List messages;
+	private MessageNode convertToThreadTree(Long topMessageId){
 		MessageNode topNode = null;
-		ForumManager fm = ForumManager.getInstance();
-		Long l = new Long(topMessageId);
-		messages = fm.getThread(l);
-		for (Iterator iterTop = messages.iterator(); iterTop.hasNext();) {
-			Message msg = (Message) iterTop.next();
+		List<Message> messages = ForumManager.getInstance().getThread(topMessageId);
+		for (Iterator<Message> iterTop = messages.iterator(); iterTop.hasNext();) {
+			Message msg = iterTop.next();
 			if (msg.getParent() == null) {
 				iterTop.remove();
 				topNode = new MessageNode(msg);
@@ -164,9 +154,9 @@ public class ForumArchiveManager  extends BasicManager {
 		return topNode;
 	}
 	
-	private void addChildren(List messages, MessageNode mn){
-		for(Iterator iterMsg = messages.iterator();iterMsg.hasNext();){
-			Message msg = (Message) iterMsg.next();
+	private void addChildren(List<Message> messages, MessageNode mn){
+		for(Iterator<Message> iterMsg = messages.iterator(); iterMsg.hasNext(); ) {
+			Message msg = iterMsg.next();
 			if ((msg.getParent() != null) && (msg.getParent().getKey() == mn.getKey())){
 				MessageNode childNode = new MessageNode(msg);
 				mn.addChild(childNode);
@@ -184,12 +174,12 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param metaInfo
 	 * @return
 	 */
-	private String formatForum(List topNodeList, ForumFormatter forumFormatter, Map metaInfo){ 
-		forumFormatter.setForumMetaInformation(metaInfo);
+	private String formatForum(List<MessageNode> topNodeList, ForumFormatter forumFormatter, Long forumId) { 
+		forumFormatter.setForumKey(forumId);
 		StringBuilder formattedForum = new StringBuilder();
 		forumFormatter.openForum();
-		for (Iterator iterTop = topNodeList.iterator(); iterTop.hasNext();){
-			MessageNode mn = (MessageNode) iterTop.next();
+		for (Iterator<MessageNode> iterTop = topNodeList.iterator(); iterTop.hasNext();){
+			MessageNode mn = iterTop.next();
 			//a new top thread starts, inform formatter
 			forumFormatter.openThread();
 			TreeVisitor tv = new TreeVisitor(forumFormatter, mn, false);
@@ -207,8 +197,8 @@ public class ForumArchiveManager  extends BasicManager {
 	 * @param metaInfo
 	 * @return
 	 */
-	private String formatThread(MessageNode mn, ForumFormatter forumFormatter, Map metaInfo){
-		forumFormatter.setForumMetaInformation(metaInfo);
+	private String formatThread(MessageNode mn, ForumFormatter forumFormatter, Long forumId){
+		forumFormatter.setForumKey(forumId);
 		StringBuilder formattedThread = new StringBuilder();
 		forumFormatter.openThread();
 		TreeVisitor tv = new TreeVisitor(forumFormatter, mn, false);
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumFormatter.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumFormatter.java
index 33b7873729c2c9c4b418be3743ff9305e9bd4c43..0f4a0f5d90bb0e82bb48344c86b1a153bd2d0b2b 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumFormatter.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumFormatter.java
@@ -25,8 +25,6 @@
 
 package org.olat.modules.fo.archiver.formatters;
 
-import java.util.Map;
-
 import org.olat.core.util.nodes.INode;
 import org.olat.core.util.tree.Visitor;
 
@@ -35,12 +33,11 @@ import org.olat.core.util.tree.Visitor;
  * @author Patrick Brunner, Alexander Schneider
  */
 
-public abstract class ForumFormatter  implements Visitor{
+public abstract class ForumFormatter implements Visitor{
 	protected StringBuilder sb;
 	protected boolean isTopThread = false;
 	protected boolean filePerThread = false;
-	protected Map metaInfo;
-	public final static String MANDATORY_METAINFO_KEY ="forum.metainfo.key";
+	private Long forumKey;
 
 	/**
 	 * init string buffer
@@ -57,8 +54,8 @@ public abstract class ForumFormatter  implements Visitor{
 	 * 
 	 * @param metaInfo
 	 */
-	public void setForumMetaInformation(Map metaInfo){
-		this.metaInfo = metaInfo;
+	public void setForumKey(Long forumKey){
+		this.forumKey = forumKey;
 	}
 	/**
 	 * inform formatter that a new top thread has started, 
@@ -82,8 +79,8 @@ public abstract class ForumFormatter  implements Visitor{
 	 * @param key
 	 * @return value of key
 	 */
-	public Object getMetainfo(String key){
-		return metaInfo.get(key);
+	public Long getForumKey() {
+		return forumKey;
 	}
 	
 	/**
@@ -91,7 +88,7 @@ public abstract class ForumFormatter  implements Visitor{
 	 * @return true if every thread is saved in his own file; false if all threads are saved in one file
 	 */
 	public boolean isFilePerThread(){
-		return this.filePerThread;
+		return filePerThread;
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
index a417901801b9f709f6dcbc7425bba93405989317..29135eb118b54b490c6485214a431cb5ba9dd492 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
@@ -43,6 +43,7 @@ import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.AssertException;
+import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.WebappHelper;
@@ -64,6 +65,8 @@ import org.olat.modules.fo.MessageNode;
  */
 
 public class ForumRTFFormatter extends ForumFormatter {
+	
+	private static final OLog log = Tracing.createLoggerFor(ForumRTFFormatter.class);
 
 	private VFSContainer container;
 	private VFSItem vfsFil = null;
@@ -97,10 +100,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 		super();
 		// where to write
 		this.container = container;
-		this.filePerThread = filePerThread;		
-		//
-		/*Translator translator = new PackageTranslator(PACKAGE, locale);
-		HIDDEN_STR = translator.translate("fo_hidden");*/
+		this.filePerThread = filePerThread;
 	}
 
 	/**
@@ -115,10 +115,10 @@ public class ForumRTFFormatter extends ForumFormatter {
 				//to have a meaningful filename we create the file here
 				String filName = "Thread_" + mn.getKey().toString();
 				tempContainer = makeTempVFSContainer();			
-				this.vfsFil=tempContainer.resolve(filName + ".rtf");
+				vfsFil=tempContainer.resolve(filName + ".rtf");
 				if(vfsFil==null){
 					tempContainer.createChildLeaf(filName + ".rtf");
-					this.vfsFil=tempContainer.resolve(filName + ".rtf");
+					vfsFil=tempContainer.resolve(filName + ".rtf");
 				}
 			}
 			//important!
@@ -157,8 +157,8 @@ public class ForumRTFFormatter extends ForumFormatter {
 		}
 		sb.append(" \\par}");
 		// attachment(s)
-		OlatRootFolderImpl msgContainer = fm.getMessageContainer((Long)(getMetainfo(ForumFormatter.MANDATORY_METAINFO_KEY)), mn.getKey());
-		List attachments = msgContainer.getItems();
+		OlatRootFolderImpl msgContainer = fm.getMessageContainer(getForumKey(), mn.getKey());
+		List<VFSItem> attachments = msgContainer.getItems();
 		if (attachments != null && attachments.size() > 0){
 			VFSItem item = container.resolve("attachments");
 			if (item == null){
@@ -169,8 +169,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 			
 			sb.append("{\\pard \\f0\\fs15 Attachment(s): ");
 			boolean commaFlag = false;
-			for (Iterator iter = attachments.iterator(); iter.hasNext();) {
-				VFSItem attachment = (VFSItem) iter.next();
+			for (VFSItem attachment: attachments) {
 				if (commaFlag) sb.append(", ");
 				sb.append(attachment.getName());
 				commaFlag = true;
@@ -178,7 +177,6 @@ public class ForumRTFFormatter extends ForumFormatter {
 			sb.append("} \\line");
 		}
 		sb.append("{\\pard \\brdrb\\brdrs\\brdrw10 \\par}");
-		
 	}
 
 	/**
@@ -207,7 +205,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 			sb.append("}");
 		}
 		writeToFile(append, sb);
-		if(this.filePerThread) {
+		if(filePerThread) {
 			zipContainer(tempContainer);			
 			tempContainer.delete();	
 		}
@@ -221,7 +219,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 	public void openForum(){
 		if(!filePerThread){
 			//make one ForumFile
-			Long forumKey = (Long) metaInfo.get(ForumFormatter.MANDATORY_METAINFO_KEY);
+			Long forumKey = getForumKey();
 			String filName = forumKey.toString();
 			filName = "Threads_" + filName + ".rtf";
 			
@@ -229,7 +227,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 			this.vfsFil=tempContainer.resolve(filName);
 			if(vfsFil==null){
 				tempContainer.createChildLeaf(filName);
-				this.vfsFil=tempContainer.resolve(filName);
+				vfsFil = tempContainer.resolve(filName);
 			}
 			sb.append("{\\rtf1\\ansi\\deff0");
 			sb.append("{\\fonttbl {\\f0\\fswiss Arial;}} ");
@@ -433,7 +431,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 				container.copyFrom(imgFile);
 				fileNameList.add(file.getName());
 			} else {
-				Tracing.logError("Could not find image for forum RTF formatter::" + iconPath, ForumFormatter.class);
+				log.error("Could not find image for forum RTF formatter::" + iconPath);
 			}
 		}
 		return fileNameList;
@@ -454,7 +452,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 	 * @return the temp container.
 	 */
 	private VFSContainer makeTempVFSContainer() {		
-		Long forumKey = (Long) metaInfo.get(ForumFormatter.MANDATORY_METAINFO_KEY);
+		Long forumKey = getForumKey();
 		String dateStamp = String.valueOf(System.currentTimeMillis());
     //TODO: (LD) could this filename regarded as unique or use System.nanoTime() instead?
 		String fileName = "forum" + forumKey.toString() + "_" + dateStamp; 
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..468fce2ea050d17126637b6b7923d5e3a7fa0ecb
--- /dev/null
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
@@ -0,0 +1,419 @@
+/**
+* OLAT - Online Learning and Training<br>
+* http://www.olat.org
+* <p>
+* Licensed under the Apache License, Version 2.0 (the "License"); <br>
+* you may not use this file except in compliance with the License.<br>
+* You may obtain a copy of the License at
+* <p>
+* http://www.apache.org/licenses/LICENSE-2.0
+* <p>
+* Unless required by applicable law or agreed to in writing,<br>
+* software distributed under the License is distributed on an "AS IS" BASIS, <br>
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+* See the License for the specific language governing permissions and <br>
+* limitations under the License.
+* <p>
+* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
+* University of Zurich, Switzerland.
+* <hr>
+* <a href="http://www.openolat.org">
+* OpenOLAT - Online Learning and Training</a><br>
+* This file has been modified by the OpenOLAT community. Changes are licensed
+* under the Apache 2.0 license as the original file.
+*/
+
+package org.olat.modules.fo.archiver.formatters;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
+import org.olat.core.id.Identity;
+import org.olat.core.id.UserConstants;
+import org.olat.core.logging.AssertException;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.WebappHelper;
+import org.olat.core.util.ZipUtil;
+import org.olat.core.util.filter.FilterFactory;
+import org.olat.core.util.nodes.INode;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.modules.fo.ForumManager;
+import org.olat.modules.fo.MessageNode;
+
+/**
+ * Initial Date: Dec 19, 2013 <br>
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ * @author Patrick Brunner, Alexander Schneider
+ */
+public class ForumStreamedRTFFormatter extends ForumFormatter {
+	
+	private static final OLog log = Tracing.createLoggerFor(ForumStreamedRTFFormatter.class);
+
+	private ZipOutputStream exportStream;
+	private ForumManager fm = ForumManager.getInstance();
+	
+	final Pattern PATTERN_HTML_BOLD = Pattern.compile("<strong>(.*?)</strong>", Pattern.CASE_INSENSITIVE);
+	final Pattern PATTERN_HTML_ITALIC = Pattern.compile("<em>(.*?)</em>", Pattern.CASE_INSENSITIVE);
+	final Pattern PATTERN_HTML_BREAK = Pattern.compile("<br />", Pattern.CASE_INSENSITIVE);
+	final Pattern PATTERN_HTML_PARAGRAPH = Pattern.compile("<p>(.*?)</p>", Pattern.CASE_INSENSITIVE);
+	final Pattern PATTERN_HTML_AHREF = Pattern.compile("<a href=\"([^\"]+)\"[^>]*>(.*?)</a>", Pattern.CASE_INSENSITIVE);
+	final Pattern PATTERN_HTML_LIST = Pattern.compile("<li>(.*?)</li>", Pattern.CASE_INSENSITIVE);
+	final Pattern HTML_SPACE_PATTERN = Pattern.compile("&nbsp;");
+	
+	final Pattern PATTERN_CSS_O_FOQUOTE = Pattern.compile("<div class=\"b_quote_wrapper\">\\s*<div class=\"b_quote_author mceNonEditable\">(.*?)</div>\\s*<blockquote class=\"b_quote\">\\s*(.*?)\\s*</blockquote>\\s*</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+	final Pattern PATTERN_THREEPOINTS = Pattern.compile("&#8230;", Pattern.CASE_INSENSITIVE);
+	final String THREEPOINTS = "...";
+	
+	//TODO: (LD) translate this!
+	private String HIDDEN_STR = "VERBORGEN";
+	private final String path;
+		
+	/**
+	 * 
+	 * @param container
+	 * @param filePerThread
+	 */
+
+	public ForumStreamedRTFFormatter(ZipOutputStream exportStream, String path, boolean filePerThread) {
+		// init String Buffer in ForumFormatter
+		super();
+		// where to write
+		this.exportStream = exportStream;
+		this.filePerThread = filePerThread;
+		this.path = path;
+		addStandardImages();
+	}
+	
+	private String fileName;
+
+	/**
+	 * @see org.olat.core.util.tree.Visitor#visit(org.olat.core.util.nodes.INode)
+	 */
+	public void visit(INode node) {
+		MessageNode mn = (MessageNode)node;
+		if (isTopThread) {
+			//important!
+			fileName = "Thread_" + mn.getKey().toString() + ".rtf";
+			isTopThread = false;
+		}
+		// Message Title
+		sb.append("{\\pard \\brdrb\\brdrs\\brdrw10 \\f1\\fs30\\b ");
+		sb.append(getImageRTF(mn));
+		sb.append(getTitlePrefix(mn));
+		sb.append(mn.getTitle());
+		sb.append("\\par}");
+		// Message Body
+		sb.append("{\\pard \\f0");
+		sb.append(convertHTMLMarkupToRTF(mn.getBody()));
+		sb.append("\\par}");
+		// Message key
+		sb.append("{\\pard \\f0\\fs15 Message key: ");
+		sb.append(mn.getKey());
+		sb.append("} \\line ");
+		sb.append("{\\pard \\f0\\fs15 created: ");
+		// Creator and creation date
+		sb.append(mn.getCreator().getUser().getProperty(UserConstants.FIRSTNAME, null));
+		sb.append(", ");
+		sb.append(mn.getCreator().getUser().getProperty(UserConstants.LASTNAME, null));
+		sb.append(" ");
+		sb.append(mn.getCreationDate().toString());
+		// Modifier and modified date
+		Identity modifier = mn.getModifier();
+		if (modifier != null) {
+			sb.append(" \\line modified: ");
+			sb.append(modifier.getUser().getProperty(UserConstants.FIRSTNAME, null));
+			sb.append(", ");
+			sb.append(modifier.getUser().getProperty(UserConstants.LASTNAME,  null));
+			sb.append(" ");
+			sb.append(mn.getModifiedDate().toString());
+		}
+		sb.append(" \\par}");
+		// attachment(s)
+		OlatRootFolderImpl msgContainer = fm.getMessageContainer(getForumKey(), mn.getKey());
+		List<VFSItem> attachments = msgContainer.getItems();
+		if (attachments != null && attachments.size() > 0){
+			sb.append("{\\pard \\f0\\fs15 Attachment(s): ");
+			boolean commaFlag = false;
+			for (VFSItem attachment: attachments) {
+				if (commaFlag) sb.append(", ");
+				sb.append(attachment.getName());
+				commaFlag = true;
+				
+				ZipUtil.addToZip(attachment, path + "/attachments", exportStream);
+			}
+			sb.append("} \\line");
+		}
+		sb.append("{\\pard \\brdrb\\brdrs\\brdrw10 \\par}");
+	}
+	
+	private void addStandardImages() {
+		String[] images = new String[]{ "fo_sticky_closed", "fo_closed", "fo_sticky"};
+		try {
+			for(String image:images) {
+				String iconPath = getImagePath(image);		
+				if (iconPath != null) {
+					File file = new File(iconPath);
+					if (file.exists()) {
+						exportStream.putNextEntry(new ZipEntry(path + "/" + file.getName()));
+						FileUtils.copyFile(file, exportStream);
+						exportStream.closeEntry();
+					}
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.olat.modules.fo.archiver.formatters.ForumFormatter#openThread()
+	 */
+	public void openThread() {
+		super.openThread();
+		if(filePerThread){
+			sb.append("{\\rtf1\\ansi\\deff0");
+			sb.append("{\\fonttbl {\\f0\\fswiss Arial;}} ");
+			sb.append("\\deflang1033\\plain");
+		}
+		sb.append("{\\pard \\brdrb \\brdrs \\brdrdb \\brsp20 \\par}{\\pard\\par}");
+	}
+
+	/**
+	 * 
+	 * @see org.olat.modules.fo.archiver.formatters.ForumFormatter#getThreadResult()
+	 */
+	public StringBuilder closeThread() {
+		String footerThread = "{\\pard \\brdrb \\brdrs \\brdrw20 \\brsp20 \\par}{\\pard\\par}";
+		sb.append(footerThread);
+		if(filePerThread){
+			sb.append("}");
+			writeToFile(sb);
+			sb = new StringBuilder();
+		}
+		return sb;
+	}
+	
+	/**
+	 * 
+	 * @see org.olat.modules.fo.archiver.formatters.ForumFormatter#openForum()
+	 */
+	public void openForum(){
+		if(!filePerThread){
+			//make one ForumFile
+			Long forumKey = getForumKey();
+			fileName = "Threads_" + forumKey.toString() + ".rtf";
+			sb.append("{\\rtf1\\ansi\\deff0");
+			sb.append("{\\fonttbl {\\f0\\fswiss Arial;}} ");
+			sb.append("\\deflang1033\\plain");
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.olat.modules.fo.archiver.formatters.ForumFormatter#closeForum()
+	 */
+	public StringBuilder closeForum(){
+		if(!filePerThread){
+			String footerForum = "}";
+			sb.append(footerForum);
+			writeToFile(sb);			
+		}
+		return sb;
+	}
+	
+	/**
+	 * 
+	 * @param append
+	 * @param buff
+	 */
+	private void writeToFile(StringBuilder buff){
+		try {
+			StringBuilder out = new StringBuilder();
+			int len = buff.length();
+			for (int i = 0; i < len; i++) {
+				char c = buff.charAt(i);
+				int val = c;
+				if (val > 127) {
+					out.append("\\u").append(String.valueOf(val)).append("?");
+				} else {
+					out.append(c);
+				}
+			}
+			String encoded = out.toString();
+			exportStream.putNextEntry(new ZipEntry(path + "/" + fileName));
+			IOUtils.write(encoded, exportStream);
+			exportStream.closeEntry();
+		} catch (UnsupportedEncodingException ueEx) {
+			throw new AssertException("could not encode stream from forum export file: " + ueEx);
+		} catch (IOException e) {
+			throw new AssertException("could not write to forum export file: " + e);
+		}
+	}
+	
+	/**
+	 * 
+	 * @param originalText
+	 * @return
+	 */
+	private String convertHTMLMarkupToRTF(String originalText){
+		String htmlText = originalText;
+
+		Matcher mb = PATTERN_HTML_BOLD.matcher(htmlText);
+		StringBuffer bolds = new StringBuffer();
+		while (mb.find()) {
+			mb.appendReplacement(bolds, "{\\\\b $1} ");
+		}
+		mb.appendTail(bolds);
+		htmlText = bolds.toString();
+
+		Matcher mi = PATTERN_HTML_ITALIC.matcher(htmlText);
+		StringBuffer italics = new StringBuffer();
+		while (mi.find()) {
+			mi.appendReplacement(italics, "{\\\\i $1} ");
+		}
+		mi.appendTail(italics);
+		htmlText = italics.toString();
+		
+		Matcher mbr = PATTERN_HTML_BREAK.matcher(htmlText);
+		StringBuffer breaks = new StringBuffer();
+		while(mbr.find()){
+			mbr.appendReplacement(breaks, "\\\\line ");
+		}
+		mbr.appendTail(breaks);
+		htmlText = breaks.toString();
+		
+		Matcher mofo = PATTERN_CSS_O_FOQUOTE.matcher(htmlText);
+		StringBuffer foquotes = new StringBuffer();
+		while(mofo.find()){
+			mofo.appendReplacement(foquotes, "\\\\line {\\\\i $1} {\\\\pard $2\\\\par}");
+		}
+		mofo.appendTail(foquotes);
+		htmlText = foquotes.toString();
+		
+		Matcher mp = PATTERN_HTML_PARAGRAPH.matcher(htmlText);
+		StringBuffer paragraphs = new StringBuffer();
+		while(mp.find()){
+			mp.appendReplacement(paragraphs, "\\\\line $1 \\\\line");
+		}
+		mp.appendTail(paragraphs);
+		htmlText = paragraphs.toString();
+		
+		Matcher mahref = PATTERN_HTML_AHREF.matcher(htmlText);
+		StringBuffer ahrefs = new StringBuffer();
+		while(mahref.find()){
+			mahref.appendReplacement(ahrefs, "{\\\\field{\\\\*\\\\fldinst{HYPERLINK\"$1\"}}{\\\\fldrslt{\\\\ul $2}}}");
+		}
+		mahref.appendTail(ahrefs);
+		htmlText = ahrefs.toString();
+		
+		Matcher mli = PATTERN_HTML_LIST.matcher(htmlText);
+		StringBuffer lists = new StringBuffer();
+		while(mli.find()){
+			mli.appendReplacement(lists, "$1\\\\line ");
+		}
+		mli.appendTail(lists);
+		htmlText = lists.toString();
+		
+		Matcher mtp = PATTERN_THREEPOINTS.matcher(htmlText);
+		StringBuffer tps = new StringBuffer();
+		while (mtp.find()) {
+			mtp.appendReplacement(tps, THREEPOINTS);
+		}
+		mtp.appendTail(tps);
+		htmlText = tps.toString();
+
+		// strip all other html-fragments, because not convertable that easy
+		htmlText = FilterFactory.getHtmlTagsFilter().filter(htmlText);
+		// Remove all &nbsp;
+		Matcher tmp = HTML_SPACE_PATTERN.matcher(htmlText);
+		htmlText = tmp.replaceAll(" ");
+		htmlText = StringEscapeUtils.unescapeHtml(htmlText);
+
+		return htmlText;
+	}
+	
+	/**
+	 * 
+	 * @param messageNode
+	 * @return title prefix for hidden forum threads.
+	 */
+	private String getTitlePrefix(MessageNode messageNode) {
+		StringBuilder sb = new StringBuilder();
+		if(messageNode.isHidden()) {
+			sb.append(HIDDEN_STR);
+		} 		
+		if(sb.length()>1) {
+			sb.append(": ");
+		}
+		return sb.toString();
+	}
+	
+	/**
+	 * Gets the RTF image section for the input messageNode.
+	 * @param messageNode
+	 * @return the RTF image section for the input messageNode.
+	 */
+	private String getImageRTF(MessageNode messageNode) {			
+		StringBuilder sb = new StringBuilder();
+		for(String fileName : addImagesToVFSContainer(messageNode)) {
+			sb.append("{\\field\\fldedit{\\*\\fldinst { INCLUDEPICTURE ")
+			  .append("\"").append(fileName).append("\"")
+			  .append(" \\\\d }}{\\fldrslt {}}}");			
+		}				
+		return sb.toString();
+	}
+	
+	/**
+	 * Retrieves the appropriate images for the input messageNode, if any, 
+	 * and adds it to the input container.
+	 * 
+	 * @param messageNode
+	 * @param container
+	 * @return
+	 */
+	private List<String> addImagesToVFSContainer(MessageNode messageNode) {
+		List<String> fileNameList = new ArrayList<String>();
+		String iconPath = null;
+		if(messageNode.isClosed() && messageNode.isSticky()) {
+			iconPath = getImagePath("fo_sticky_closed");
+		} else if(messageNode.isClosed()) {
+			iconPath = getImagePath("fo_closed");			
+		} else if(messageNode.isSticky()) {
+			iconPath = getImagePath("fo_sticky");			
+		}		
+		if (iconPath != null) {
+			File file = new File(iconPath);
+			if (file.exists()) {
+				fileNameList.add(file.getName());
+			} else {
+				log.error("Could not find image for forum RTF formatter::" + iconPath);
+			}
+		}
+		return fileNameList;
+	}
+	
+	/**
+	 * TODO: LD: to clarify whether there it a better way to get the image path?
+	 * Gets the image path.
+	 * @param val
+	 * @return the path of the static icon image.
+	 */
+	private String getImagePath(Object val) { 		
+		return WebappHelper.getContextRoot() + "/static/images/forum/" + val.toString() + ".png";				
+	}
+}
diff --git a/src/main/java/org/olat/modules/scorm/archiver/ArchiverActionExtension.java b/src/main/java/org/olat/modules/scorm/archiver/ArchiverActionExtension.java
deleted file mode 100644
index 1020bef0689097b455d8bb131795aabcc12f2f3a..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/ArchiverActionExtension.java
+++ /dev/null
@@ -1,37 +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.modules.scorm.archiver;
-
-import org.olat.core.extensions.action.GenericActionExtension;
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.control.Controller;
-import org.olat.core.gui.control.WindowControl;
-import org.olat.course.ICourse;
-
-public class ArchiverActionExtension extends GenericActionExtension {
-
-	@Override
-	public Controller createController(UserRequest ureq, WindowControl wControl, Object arg) {
-		if(arg instanceof ICourse) {
-			return new ScormResultArchiveController(ureq, wControl, (ICourse)arg);
-		}
-		return super.createController(ureq, wControl, arg);
-	}
-}
diff --git a/src/main/java/org/olat/modules/scorm/archiver/ScormArchiveWizardController.java b/src/main/java/org/olat/modules/scorm/archiver/ScormArchiveWizardController.java
deleted file mode 100644
index 5f42eda06461b100ab69ed164922fbebf30c2081..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/ScormArchiveWizardController.java
+++ /dev/null
@@ -1,181 +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.modules.scorm.archiver;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.Component;
-import org.olat.core.gui.components.link.Link;
-import org.olat.core.gui.components.link.LinkFactory;
-import org.olat.core.gui.components.table.ColumnDescriptor;
-import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
-import org.olat.core.gui.components.table.DefaultColumnDescriptor;
-import org.olat.core.gui.components.table.Table;
-import org.olat.core.gui.components.table.TableController;
-import org.olat.core.gui.components.table.TableEvent;
-import org.olat.core.gui.components.table.TableGuiConfiguration;
-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;
-import org.olat.core.gui.control.generic.wizard.WizardController;
-import org.olat.core.gui.media.MediaResource;
-import org.olat.core.gui.media.MimedFileMediaResource;
-import org.olat.core.util.StringHelper;
-import org.olat.core.util.Util;
-import org.olat.course.CourseFactory;
-import org.olat.course.ICourse;
-import org.olat.course.archiver.GenericArchiveController;
-import org.olat.course.assessment.AssessmentHelper;
-import org.olat.course.assessment.IndentedNodeRenderer;
-import org.olat.course.assessment.NodeTableDataModel;
-import org.olat.course.nodes.CourseNode;
-import org.olat.course.nodes.ScormCourseNode;
-import org.olat.user.UserManager;
-
-/**
- * 
- * Description:<br>
- * A wizard to export the results of a SCORM course in a tab separated file. There is two steps:
- * select a SCORM element and then download the file. 
- * 
- * <P>
- * Initial Date:  17 août 2009 <br>
- * @author srosse
- */
-public class ScormArchiveWizardController extends BasicController {
-
-	private static final String CMD_SELECT_NODE = "cmd.select.node";
-	
-	private final Long courseId; 
-	private final NodeTableDataModel nodeTableModel;
-
-	private Link showFileButton;
-	private WizardController wc;
-	private TableController nodeListCtr;
-	private VelocityContainer finishedVC;
-	private VelocityContainer noResultsVC;
-	private Link backLinkAtNoResults;
-	
-	private String charset;
-	private File exportDir;
-	private String targetFileName;
-	
-	public ScormArchiveWizardController(UserRequest ureq, List<Map<String,Object>> nodesTableObjectArrayList, Long courseId, WindowControl wControl) {
-		super(ureq, wControl, Util.createPackageTranslator(GenericArchiveController.class, ureq.getLocale()));
-		this.courseId = courseId;
-
-    //table configuraton
-		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
-		tableConfig.setTableEmptyMessage(getTranslator().translate("nodesoverview.nonodes"));
-		tableConfig.setDownloadOffered(false);
-		tableConfig.setColumnMovingOffered(false);
-		tableConfig.setSortingEnabled(false);
-		tableConfig.setDisplayTableHeader(true);
-		tableConfig.setDisplayRowCount(false);
-		tableConfig.setPageingEnabled(false);
-		
-		nodeListCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator());
-		listenTo(nodeListCtr);
-		// table columns		
-		nodeListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.node", 0, 
-				null, ureq.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, new IndentedNodeRenderer()));
-		nodeListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.action.select", 1,
-				CMD_SELECT_NODE, ureq.getLocale()));
-		
-		nodeTableModel = new NodeTableDataModel(nodesTableObjectArrayList, getTranslator());
-		nodeListCtr.setTableDataModel(nodeTableModel);
-		
-		wc = new WizardController(ureq, wControl, 2);
-		listenTo(wc);
-		wc.setWizardTitle(getTranslator().translate("wizard.nodechoose.title"));
-		wc.setNextWizardStep(getTranslator().translate("wizard.nodechoose.howto"), nodeListCtr.getInitialComponent());
-		putInitialPanel(wc.getInitialComponent());
-	}
-
-	@Override
-	protected void doDispose() {
-		//
-	}
-
-	@Override
-	protected void event(UserRequest ureq, Component source, Event event) {
-		if (source == showFileButton){
-			File exportFile = new File(exportDir, targetFileName);
-			MediaResource resource = new MimedFileMediaResource(exportFile, "application/vnd.ms-excel; charset="+charset, true);
-			ureq.getDispatchResult().setResultingMediaResource(resource);
-			showFileButton.setDirty(false);
-		} else if (source == backLinkAtNoResults){
-			wc.setWizardTitle(getTranslator().translate("wizard.nodechoose.title"));
-			wc.setBackWizardStep(getTranslator().translate("wizard.nodechoose.howto"), nodeListCtr.getInitialComponent());
-		}
-	}
-	
-	@Override
-	public void event(UserRequest ureq, Controller source, Event event) {
-    if(source == nodeListCtr) {
-    	if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) {
-    		TableEvent tae = (TableEvent)event;
-    		
-    		Map<String,Object> nodeData = (Map<String,Object>) nodeTableModel.getObject(tae.getRowId());
-    		ICourse course = CourseFactory.loadCourse(courseId);
-				CourseNode node = course.getRunStructure().getNode((String) nodeData.get(AssessmentHelper.KEY_IDENTIFYER));
-    		if(node instanceof ScormCourseNode) {
-    			finishedVC = createVelocityContainer("finished");
-					showFileButton = LinkFactory.createButton("showfile", finishedVC, this);
-					finishedVC.contextPut("nodetitle", node.getShortTitle());
-					
-					targetFileName = doExport(ureq, (ScormCourseNode)node);
-					if(StringHelper.containsNonWhitespace(targetFileName)) {
-					  finishedVC.contextPut("filename", targetFileName);
-		    	  wc.setWizardTitle(getTranslator().translate("wizard.finished.title"));
-					  wc.setNextWizardStep(getTranslator().translate("wizard.finished.howto"), finishedVC);
-					} else { // no success
-						noResultsVC = createVelocityContainer("noresults");
-						backLinkAtNoResults = LinkFactory.createLinkBack(noResultsVC, this);
-						noResultsVC.contextPut("nodetitle", node.getShortTitle());
-						
-						wc.setWizardTitle(getTranslator().translate("wizard.finished.title"));
-						wc.setNextWizardStep(getTranslator().translate("wizard.finished.howto"), noResultsVC);						
-					}
-    		}
-    	}
-    }
-		else if (source == wc){
-			if (event == Event.CANCELLED_EVENT) {
-				fireEvent(ureq, event);
-			}
-		}
-	}
-	
-	private String doExport(UserRequest ureq, ScormCourseNode node) {
-		ICourse course = CourseFactory.loadCourse(courseId);
-		exportDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), course.getCourseTitle());
-		UserManager um = UserManager.getInstance();
-    charset = um.getUserCharset(ureq.getIdentity());
-    
-    ScormExportManager sreManager = ScormExportManager.getInstance();
-		return sreManager.exportResults(course.getCourseEnvironment(), node, getTranslator(), exportDir, charset);
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/ScormExportManager.java b/src/main/java/org/olat/modules/scorm/archiver/ScormExportManager.java
index 26a0bf4ec71d8ac18429effa1793ec850c4df3a5..0e666bda9ab6173422150447a96691a633e5bd46 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/ScormExportManager.java
+++ b/src/main/java/org/olat/modules/scorm/archiver/ScormExportManager.java
@@ -19,7 +19,6 @@
  */
 package org.olat.modules.scorm.archiver;
 
-import java.io.File;
 import java.util.List;
 
 import org.olat.core.commons.persistence.DBFactory;
@@ -28,7 +27,6 @@ import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.manager.BasicManager;
-import org.olat.core.util.ExportUtil;
 import org.olat.core.util.vfs.LocalFileImpl;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
@@ -80,18 +78,10 @@ public class ScormExportManager extends BasicManager {
 	 * @param charset
 	 * @return the name of the file, if any created or empty string otherwise
 	 */
-	public String exportResults(CourseEnvironment courseEnv, ScormCourseNode node, Translator translator, File exportDirectory, String charset) {
+	public String getResults(CourseEnvironment courseEnv, ScormCourseNode node, Translator translator) {
 		ScormExportVisitor visitor = new ScormExportFormatter(translator);
-		
-		boolean dataFound = visitScoDatas(courseEnv, node, visitor);
-
-		if(dataFound) {
-		  String content = visitor.toString();
-		  String fileName = ExportUtil.createFileNameWithTimeStamp("SCORM_" + node.getShortTitle(), "xls");
-		  ExportUtil.writeContentToFile(fileName, content, exportDirectory, charset);
-		  return fileName;
-		}
-		return "";
+		String content = visitor.toString();
+		return content;
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/modules/scorm/archiver/ScormResultArchiveController.java b/src/main/java/org/olat/modules/scorm/archiver/ScormResultArchiveController.java
deleted file mode 100644
index 9921e6b50022290a26fec5419c801d00dbef8c8e..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/ScormResultArchiveController.java
+++ /dev/null
@@ -1,183 +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.modules.scorm.archiver;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.Component;
-import org.olat.core.gui.components.link.Link;
-import org.olat.core.gui.components.link.LinkFactory;
-import org.olat.core.gui.components.table.ColumnDescriptor;
-import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
-import org.olat.core.gui.components.table.DefaultColumnDescriptor;
-import org.olat.core.gui.components.table.TableController;
-import org.olat.core.gui.components.table.TableGuiConfiguration;
-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;
-import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
-import org.olat.core.util.Util;
-import org.olat.course.CourseFactory;
-import org.olat.course.ICourse;
-import org.olat.course.archiver.GenericArchiveController;
-import org.olat.course.assessment.AssessmentHelper;
-import org.olat.course.assessment.IndentedNodeRenderer;
-import org.olat.course.nodes.CourseNode;
-import org.olat.course.nodes.ScormCourseNode;
-
-/**
- * 
- * Description:<br>
- * Main controller for the SCORM archive export. All the job is done in the wizard
- * 
- * <P>
- * Initial Date:  17 august 2009 <br>
- * @author srosse
- */
-public class ScormResultArchiveController extends BasicController {
-
-	private static final String CMD_SELECT_NODE = "cmd.select.node";
-	
-	private VelocityContainer introVC;
-	
-	private TableController nodeListCtr;
-	private ScormArchiveWizardController wizardController;
-	private CloseableModalController cmc;
-	
-	private final Long courseId;
-	
-	private List<Map<String,Object>> nodesTableObjectArrayList;
-	private final Link startExportButton;
-	
-	public ScormResultArchiveController(UserRequest ureq, WindowControl wControl, ICourse course) {
-		super(ureq, wControl, Util.createPackageTranslator(GenericArchiveController.class, ureq.getLocale()));
-		
-		courseId = course.getResourceableId();
-
-		introVC = createVelocityContainer("intro");
-		startExportButton = LinkFactory.createButtonSmall("command.start.exportwizard", introVC, this);
-		
-		nodesTableObjectArrayList = doNodeChoose(ureq);
-		
-		if (nodesTableObjectArrayList == null) {
-			introVC.contextPut("hasScormNodes", Boolean.FALSE);
-		} else {
-			introVC.contextPut("hasScormNodes", Boolean.TRUE);
-		}
-		
-		putInitialPanel(introVC);
-	}
-
-	@Override
-	protected void doDispose() {
-		// controllers autodisposed by basic controller
-	}
-
-	@Override
-	protected void event(UserRequest ureq, Component source, Event event) {
-		if (source == startExportButton){
-			
-			removeAsListenerAndDispose(wizardController);
-			wizardController = new ScormArchiveWizardController(ureq, nodesTableObjectArrayList, courseId, getWindowControl());
-			listenTo(wizardController);
-			
-			removeAsListenerAndDispose(cmc);
-			cmc = new CloseableModalController(getWindowControl(), translate("close"), wizardController.getInitialComponent());
-			listenTo(cmc);
-			
-			cmc.activate();
-		}
-	}
-	
-	@Override
-	public void event(UserRequest ureq, Controller source, Event event) {
-		if (source == wizardController){
-			if (event == Event.DONE_EVENT || event == Event.CANCELLED_EVENT) {
-				cmc.deactivate();
-			}
-		}
-	}
-
-	private List<Map<String,Object>> doNodeChoose(UserRequest ureq){
-    //table configuraton
-		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
-		tableConfig.setTableEmptyMessage(translate("nodesoverview.nonodes"));
-		tableConfig.setDownloadOffered(false);
-		tableConfig.setColumnMovingOffered(false);
-		tableConfig.setSortingEnabled(false);
-		tableConfig.setDisplayTableHeader(true);
-		tableConfig.setDisplayRowCount(false);
-		tableConfig.setPageingEnabled(false);
-		
-		removeAsListenerAndDispose(nodeListCtr);
-		nodeListCtr = new TableController(tableConfig, ureq, getWindowControl(), this.getTranslator());
-		listenTo(nodeListCtr);
-		// table columns		
-		nodeListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.node", 0, 
-				null, ureq.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, new IndentedNodeRenderer()));
-		nodeListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.action.select", 1,
-				CMD_SELECT_NODE, ureq.getLocale()));
-		
-		// get list of course node data and populate table data model
-		ICourse course = CourseFactory.loadCourse(courseId);
-		CourseNode rootNode = course.getRunStructure().getRootNode();
-		List<Map<String,Object>> objectArrayList = addScormNodesAndParentsToList(0, rootNode);
-		return objectArrayList;		
-	}
-	
-	private List<Map<String,Object>> addScormNodesAndParentsToList(int recursionLevel, CourseNode courseNode) {
-		// 1) Get list of children data using recursion of this method
-		List<Map<String,Object>> childrenData = new ArrayList<Map<String,Object>>();
-		for (int i = 0; i < courseNode.getChildCount(); i++) {
-			CourseNode child = (CourseNode) courseNode.getChildAt(i);
-			List<Map<String,Object>> childData = addScormNodesAndParentsToList( (recursionLevel + 1),  child);
-			if (childData != null) {
-				childrenData.addAll(childData);
-			}
-		}
-		
-		if (!childrenData.isEmpty() || courseNode instanceof ScormCourseNode) {
-			// Store node data in hash map. This hash map serves as data model for 
-			// the tasks overview table. Leave user data empty since not used in
-			// this table. (use only node data)
-			Map<String,Object> nodeData = new HashMap<String,Object>();
-			// indent
-			nodeData.put(AssessmentHelper.KEY_INDENT, new Integer(recursionLevel));
-			// course node data
-			nodeData.put(AssessmentHelper.KEY_TYPE, courseNode.getType());
-			nodeData.put(AssessmentHelper.KEY_TITLE_SHORT, courseNode.getShortTitle());
-			nodeData.put(AssessmentHelper.KEY_TITLE_LONG, courseNode.getLongTitle());
-			nodeData.put(AssessmentHelper.KEY_IDENTIFYER, courseNode.getIdent());
-			nodeData.put(AssessmentHelper.KEY_SELECTABLE, (courseNode instanceof ScormCourseNode) ? Boolean.TRUE : Boolean.FALSE);
-			
-			List<Map<String,Object>> nodeAndChildren = new ArrayList<Map<String,Object>>();
-			nodeAndChildren.add(nodeData);
-			nodeAndChildren.addAll(childrenData);
-			return nodeAndChildren;
-		}
-		return null;
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_content/finished.html b/src/main/java/org/olat/modules/scorm/archiver/_content/finished.html
deleted file mode 100644
index 9fcc215abe2c0552498af692abdc2727c0f77232..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/_content/finished.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<p>
-	<strong>$r.translate("wizard.nodetitle"):</strong> $nodetitle
-</p>
-<p>
-	<span class="b_with_small_icon_left b_filetype_xls">$filename</span> $r.render("showfile")
-</p>
-
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_content/intro.html b/src/main/java/org/olat/modules/scorm/archiver/_content/intro.html
deleted file mode 100644
index 5457aa0cd554497c148cc920a0fc235fdab87697..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/_content/intro.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<h4>$r.translate("wizard.intro.title")</h4>
-
-#if($hasScormNodes)
-	<p>$r.translate("wizard.intro.text")</p>
-	<ol>
-		<li>$r.translate("wizard.intro.nod")</li>
-		<li>$r.translate("wizard.intro.fin")</li>
-	</ol>
-	$r.render("command.start.exportwizard")
-#else
-	<p>
-		$r.translate("nodesoverview.nonodes")
-	</p>
-#end
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_content/noresults.html b/src/main/java/org/olat/modules/scorm/archiver/_content/noresults.html
deleted file mode 100644
index 13a129344bc464831a746c1fcefb5bc731256452..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/scorm/archiver/_content/noresults.html
+++ /dev/null
@@ -1,8 +0,0 @@
-$r.render("backLink")
-<p>
-	<strong>$r.translate("wizard.nodetitle"):</strong> $nodetitle
-</p>
-<p>
-	$r.translate("archive.noresults")
-</p>
-	
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ar.properties
index 6387a2c6e2d7b5e420366ecaa2a632e331fb96ee..587274f5821675845c763734358d33418c7386b7 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ar.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ar.properties
@@ -1,8 +1,4 @@
 #Sun Feb 21 13:44:33 CET 2010
-ScormResultArchiveController.menu.title=\u0646\u062A\u0627\u0626\u062C \u0627\u0633\u0643\u0648\u0631\u0645
-ScormResultArchiveController.menu.title.alt=\u0646\u062A\u0627\u0626\u062C \u0633\u0643\u0648\u0631\u0645
-command.start.exportwizard=\u0628\u062F\u0627\u064A\u0629 \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0627\u062A
-nodesoverview.nonodes=\u0644\u0627 \u064A\u062D\u062A\u0648\u0649 \u0647\u0630\u0627 \u0627\u0644\u0645\u0642\u0631\u0631 \u0639\u0644\u0649 \u0623\u0649 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645.
 results.header=\u0646\u062A\u0627\u0626\u062C \u0627\u0633\u0643\u0648\u0631\u0645
 results.table.foot.cr=\u0631\u062F \u0627\u0644\u0637\u0627\u0644\u0628
 results.table.footer.sr=\u0627\u062C\u0627\u0628\u0629 \u0635\u062D\u064A\u062D\u0629
@@ -13,13 +9,4 @@ results.table.header.lessonStatus=\u0627\u0644\u062D\u0627\u0644\u0629
 results.table.header.objective={0} \u0627\u0644\u062F\u0631\u062C\u0629 \u0627\u0644\u0639\u0638\u0645\u0649
 results.table.header.rawScore=\u0627\u0644\u062F\u0631\u062C\u0629 \u0627\u0644\u0646\u0647\u0627\u0626\u064A\u0629
 results.table.header.totalTime=\u0627\u0644\u0632\u0645\u0646
-results.table.header.username=\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645
-wizard.finished.howto=\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0630\u0649 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649.
-wizard.finished.title=\u062A\u0645 \u0627\u0646\u062A\u0647\u0627\u0621 \u0627\u0644\u062D\u0641\u0638
-wizard.intro.fin=\u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0630\u0649 \u064A\u062D\u062A\u0648\u0649 \u0639\u0644\u0649 \u0646\u062A\u0627\u0626\u062C\u0643 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649.
-wizard.intro.nod=\u064A\u0631\u062C\u0649 \u0627\u062E\u062A\u064A\u0627\u0631 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645.
-wizard.intro.text=\u0641\u0649 \u0627\u0644\u062D\u0648\u0627\u0631 \u0627\u0644\u062A\u0627\u0644\u0649 \u0627\u062E\u062A\u0631 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645 \u0627\u0644\u0630\u0649 \u064A\u062A\u0645 \u062A\u0642\u064A\u064A\u0645\u0647\u060C \u0648\u0627\u0644\u0646\u062A\u0627\u0626\u062C \u0627\u0644\u0645\u062D\u0641\u0648\u0638\u0629 \u064A\u0645\u0643\u0646 \u0627\u0644\u0639\u062B\u0648\u0631 \u0639\u0644\u064A\u0647\u0627 \u0641\u0649 \u0645\u062C\u0644\u062F\u0643 \u0627\u0644\u0634\u062E\u0635\u0649.
-wizard.intro.title=\u0646\u062A\u0627\u0626\u062C \u0627\u0633\u0643\u0648\u0631\u0645
-wizard.nodechoose.howto=\u064A\u0631\u062C\u0649 \u0627\u062E\u062A\u064A\u0627\u0631 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645.
-wizard.nodechoose.title=\u0627\u062E\u062A\u064A\u0627\u0631 \u0639\u0646\u0635\u0631 \u0627\u0633\u0643\u0648\u0631\u0645
-wizard.nodetitle=\u0639\u0646\u0648\u0627\u0646 \u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u0642\u0631\u0631
+results.table.header.username=\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_de.properties
index 0e3302e87724f0386aef276ad9c4a68f334649b5..90972182344074fe8f3a25beedf05c77c2a5f333 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_de.properties
@@ -1,8 +1,3 @@
-archive.noresults=F\u00FCr diesen Kursbaustein wurden noch keine Resultate gespeichert.
-ScormResultArchiveController.menu.title=SCORM Resultate
-ScormResultArchiveController.menu.title.alt=SCORM Resultate
-command.start.exportwizard=Archivierung starten
-nodesoverview.nonodes=Dieser Kurs hat keinen SCORM Baustein.
 results.header=SCORM Resultate
 results.table.foot.cr=Antwort Student
 results.table.footer.sr=Richtige Antwort
@@ -14,12 +9,3 @@ results.table.header.totalTime=Zeit
 results.table.header.interaction=Frage {0}
 results.table.header.objective=Zielpunktzahl {0}
 results.table.header.comments=Kommentar
-wizard.intro.title=SCORM Resultate
-wizard.intro.text=W\u00E4hlen Sie im folgenden Dialog den SCORM Baustein aus, der ausgewertet werden soll. Die archivierten Resultate finden Sie in Ihrem pers\u00F6nlichen Ordner unter private/archive/[Kursname]/[Dateiname].
-wizard.intro.nod=W\u00E4hlen Sie einen SCORM Baustein aus.
-wizard.intro.fin=Die Datei mit den Resultaten liegt in Ihrem pers\u00F6nlichen Ordner.
-wizard.nodechoose.howto=W\u00E4hlen Sie einen SCORM Baustein aus.
-wizard.nodechoose.title=Auswahl SCORM Baustein
-wizard.nodetitle=Titel Kursbaustein
-wizard.finished.howto=Die Datei mit den archivierten Daten finden Sie in Ihrem pers\u00F6nlichen Ordner.
-wizard.finished.title=Archivierung beendet
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_el.properties
index 1463fbd019ffc86d6df6536247b234ede269c42a..eb50e1288f38db61ddfe33cc0ba89d1b362a1fc8 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_el.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_el.properties
@@ -1,9 +1,4 @@
 #Wed Sep 15 15:25:19 CEST 2010
-ScormResultArchiveController.menu.title=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
-ScormResultArchiveController.menu.title.alt=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
-archive.noresults=\u0394\u03B5\u03BD \u03B1\u03C0\u03BF\u03B8\u03B7\u03BA\u03B5\u03CD\u03C4\u03B7\u03BA\u03B1\u03BD \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9'\u03B1\u03C5\u03C4\u03CC \u03C4\u03BF \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2.
-command.start.exportwizard=\u0388\u03BD\u03B1\u03C1\u03BE\u03B7 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03AD\u03C4\u03B7\u03C3\u03B7\u03C2
-nodesoverview.nonodes=\u03A4\u03BF \u03BC\u03AC\u03B8\u03B7\u03BC\u03B1 \u03B1\u03C5\u03C4\u03CC \u03B4\u03B5\u03BD \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03BA\u03AC\u03C0\u03BF\u03B9\u03BF \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM.
 results.header=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
 results.table.foot.cr=\u0391\u03C0\u03AC\u03BD\u03C4\u03B7\u03C3\u03B7 \u03BC\u03B1\u03B8\u03B7\u03C4\u03AE
 results.table.footer.sr=\u03A3\u03C9\u03C3\u03C4\u03AE \u03B1\u03C0\u03AC\u03BD\u03C4\u03B7\u03C3\u03B7
@@ -15,12 +10,3 @@ results.table.header.objective=\u039C\u03AD\u03B3\u03B9\u03C3\u03C4\u03B7 \u03B2
 results.table.header.rawScore=\u03A4\u03B5\u03BB\u03B9\u03BA\u03AE \u03B2\u03B1\u03B8\u03BC\u03BF\u03BB\u03BF\u03B3\u03AF\u03B1
 results.table.header.totalTime=\u038F\u03C1\u03B1
 results.table.header.username=\u038C\u03BD\u03BF\u03BC\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
-wizard.finished.howto=\u0391\u03C1\u03C7\u03B5\u03AF\u03BF \u03C0\u03BF\u03C5 \u03BD\u03B1 \u03C0\u03B5\u03C1\u03B9\u03AD\u03C7\u03B5\u03B9 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03B1 \u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B2\u03C1\u03B5\u03B8\u03B5\u03AF \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF.
-wizard.finished.title=\u0397 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03AD\u03C4\u03B7\u03C3\u03B7 \u03BF\u03BB\u03BF\u03BA\u03BB\u03B7\u03C1\u03CE\u03B8\u03B7\u03BA\u03B5
-wizard.intro.fin=\u03A4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03C0\u03BF\u03C5 \u03C0\u03B5\u03C1\u03B9\u03BB\u03B1\u03BC\u03B2\u03AC\u03BD\u03B5\u03B9 \u03C4\u03B1 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03AC \u03C3\u03B1\u03C2 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF\u03C4\u03B5 \u03BD\u03B1 \u03C4\u03BF \u03B2\u03C1\u03B5\u03AF\u03C4\u03B5 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF.
-wizard.intro.nod=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B5\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03B5\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM.
-wizard.intro.text=\u03A3\u03C4\u03BF\u03BD \u03B1\u03BA\u03CC\u03BB\u03BF\u03C5\u03B8\u03BF \u03B4\u03B9\u03AC\u03BB\u03BF\u03B3\u03BF, \u03C0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B5\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM \u03C0\u03BF\u03C5 \u03B8\u03AD\u03BB\u03B5\u03C4\u03B5 \u03BD\u03B1 \u03B1\u03BE\u03B9\u03BF\u03BB\u03BF\u03B3\u03B7\u03B8\u03B5\u03AF. \u03A4\u03B1 \u03B1\u03C1\u03C7\u03B5\u03B9\u03BF\u03B8\u03B5\u03C4\u03B7\u03BC\u03AD\u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF\u03C4\u03B5 \u03BD\u03B1 \u03C4\u03B1 \u03B2\u03C1\u03B5\u03AF\u03C4\u03B5 \u03C3\u03C4\u03BF\u03BD \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF, \u03C3\u03C4\u03BF \u03C4\u03BC\u03AE\u03BC\u03B1 \u03C0\u03C1\u03BF\u03C3\u03C9\u03C0\u03B9\u03BA\u03CC/\u03B1\u03C1\u03C7\u03B5\u03AF\u03BF/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2]/[\u03CC\u03BD\u03BF\u03BC\u03B1 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5].
-wizard.intro.title=\u0391\u03C0\u03BF\u03C4\u03B5\u03BB\u03AD\u03C3\u03BC\u03B1\u03C4\u03B1 SCORM
-wizard.nodechoose.howto=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B5\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03B5\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF SCORM.
-wizard.nodechoose.title=\u0395\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF\u03C5 SCORM
-wizard.nodetitle=\u03A4\u03AF\u03C4\u03BB\u03BF\u03C2 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF\u03C5 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_en.properties
index 63f99ce4916c42656c482a12879e5652850cfb57..44481f0e16f52822fdc4984445798b42be1a0e1e 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_en.properties
@@ -1,9 +1,4 @@
 #Fri Aug 13 17:42:53 CEST 2010
-ScormResultArchiveController.menu.title=SCORM results
-ScormResultArchiveController.menu.title.alt=SCORM results
-archive.noresults=No results saved for this course element.
-command.start.exportwizard=Start archiving
-nodesoverview.nonodes=This course does not contain any SCORM element.
 results.header=SCORM results
 results.table.foot.cr=Reply student
 results.table.footer.sr=Correct answer
@@ -15,12 +10,3 @@ results.table.header.objective=Maximum score {0}
 results.table.header.rawScore=Final score
 results.table.header.totalTime=Time
 results.table.header.username=User name
-wizard.finished.howto=A file containing archived data can be found in your personal folder.
-wizard.finished.title=Archiving finished
-wizard.intro.fin=A file containing your results can be found in your personal folder.
-wizard.intro.nod=Please select a SCORM element.
-wizard.intro.text=In the following dialog please select the SCORM element to be assessed. Archived results can be found in your personal folder, section private/archive/[course name]/[file name].
-wizard.intro.title=SCORM results
-wizard.nodechoose.howto=Please select a SCORM element.
-wizard.nodechoose.title=Selection SCORM element
-wizard.nodetitle=Title course element
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_fr.properties
index 5d11900b3ba78b9dbd05ab4d066a2bad4545c3ce..86bf44fae5068ca86ed96757fe9aa42ff7c4aa15 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_fr.properties
@@ -1,9 +1,4 @@
 #Mon Aug 23 18:45:33 CEST 2010
-ScormResultArchiveController.menu.title=R\u00E9sultats SCORM
-ScormResultArchiveController.menu.title.alt=R\u00E9sultats SCORM
-archive.noresults=Aucun r\u00E9sultat enregistr\u00E9 pour cet \u00E9l\u00E9ment de cours.
-command.start.exportwizard=D\u00E9marrer archivage
-nodesoverview.nonodes=Ce cours n'a pas d'\u00E9l\u00E9ment SCORM.
 results.header=R\u00E9sultats SCORM
 results.table.foot.cr=R\u00E9ponse \u00E9tudiant
 results.table.footer.sr=R\u00E9ponse correcte
@@ -15,12 +10,4 @@ results.table.header.objective=Nombre de points maximal {0}
 results.table.header.rawScore=R\u00E9sutat final
 results.table.header.totalTime=Temps
 results.table.header.username=Nom d'utilisateur
-wizard.finished.howto=Ce fichier avec les donn\u00E9es archiv\u00E9es peut \u00EAtre trouv\u00E9 dans votre dossier personnel.
-wizard.finished.title=Archivage termin\u00E9
-wizard.intro.fin=Le fichier avec les r\u00E9sultats est d\u00E9pos\u00E9 dans votre dossier personnel.
-wizard.intro.nod=Choisissez un \u00E9l\u00E9ment SCORM.
-wizard.intro.text=Choisir dans le dialogue suivant l'\u00E9l\u00E9ment SCORM qui doit \u00EAtre \u00E9valu\u00E9. Les r\u00E9sultats archiv\u00E9s sont d\u00E9pos\u00E9s dans votre dossier personnel sous private/archive/[nom du cours]/[nom du fichier].
-wizard.intro.title=R\u00E9sultats SCORM
-wizard.nodechoose.howto=Choisissez un \u00E9l\u00E9ment de cours SCORM
-wizard.nodechoose.title=S\u00E9lection \u00E9l\u00E9ment SCORM
-wizard.nodetitle=Titre \u00E9l\u00E9ment de cours
+
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_it.properties
index 99ccfdd95cd5e268833d2d37996446c9e606add1..62535154c85340a118718b95e93af7c1d607c4d3 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_it.properties
@@ -1,9 +1,4 @@
 #Mon Aug 16 16:18:02 CEST 2010
-ScormResultArchiveController.menu.title=Risultati SCORM
-ScormResultArchiveController.menu.title.alt=Risultati SCORM
-archive.noresults=Nessun risultato salvato per questo elemento di corso.
-command.start.exportwizard=Avviare archiviazione
-nodesoverview.nonodes=Questo corso non contiene alcun elemento SCORM.
 results.header=Risultati SCORM
 results.table.foot.cr=Risposta studente
 results.table.footer.sr=Risposta corretta
@@ -15,12 +10,3 @@ results.table.header.objective=Punteggio massimo {0}
 results.table.header.rawScore=Punteggio finale
 results.table.header.totalTime=Tempo
 results.table.header.username=Nome utente
-wizard.finished.howto=Il file con i dati archiviati si trova nella Sua cartella personale.
-wizard.finished.title=Archiviazione terminata
-wizard.intro.fin=Il file con i risultati si trova nella Sua cartella personale.
-wizard.intro.nod=Selezioni un elemento SCORM.
-wizard.intro.text=Selezioni l'elemento SCORM che deve essere valutato nel dialogo seguente. I risultati archiviati si trovano nella Sua cartella personale sotto private/archive/[Nome corso]/[Nome file].
-wizard.intro.title=Risultati SCORM
-wizard.nodechoose.howto=Selezioni un elemento SCORM.
-wizard.nodechoose.title=Selezione elemento SCORM
-wizard.nodetitle=Titolo elemento di corso
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_nl_NL.properties
index 6dee4ae208416518ef09d4f828ffe441b1d7cd21..2e8d07bac0ba8ecd8c7d73a05bfba7b22a8ea6ac 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_nl_NL.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_nl_NL.properties
@@ -1,9 +1,4 @@
 #Thu Sep 08 16:42:46 CEST 2011
-ScormResultArchiveController.menu.title=SCORM resultaten
-ScormResultArchiveController.menu.title.alt=SCORM results
-archive.noresults=Er zijn voor dit cursuselement geen resultaten opgeslagen.
-command.start.exportwizard=Start archivering
-nodesoverview.nonodes=Deze cursus bevat geen SCORM element.
 results.header=SCORM resultaten
 results.table.foot.cr=Student beantwoorden
 results.table.footer.sr=Correcte antwoord
@@ -15,12 +10,3 @@ results.table.header.objective=Maximum score {0}
 results.table.header.rawScore=Eindscore
 results.table.header.totalTime=Tijd
 results.table.header.username=Gebruikersnaam
-wizard.finished.howto=Een bestand dat gearchiveerde data bevat, kan teruggevonden worden in uw persoonlijke map.
-wizard.finished.title=Archivering be\u00EBindigd
-wizard.intro.fin=Een bestand dat uw resultaten bevat, kan teruggevonden worden in uw persoonlijke map.
-wizard.intro.nod=Gelieve een SCORM element te selecteren.
-wizard.intro.text=Gelieve in de volgende dialoog een SCORM element te selecteren dat moet worden beoordeeld. Gearchiveerde resultaten kunnen teruggevonden worden in uw persoonlijke map, sectie section private/archive/[cursusnaam]/[bestandsnaam].
-wizard.intro.title=SCORM resultaten
-wizard.nodechoose.howto=Gelieve een SCORM element te selecteren
-wizard.nodechoose.title=Selectie SCORM element
-wizard.nodetitle=Titel cursuselement
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pl.properties
index 0730d96d0123d27409dcc0b61fa80dce8348682c..44b80c66d9a970bb7c4acdb2b658c04a38f2f3ef 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pl.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pl.properties
@@ -1,9 +1,4 @@
 #Fri Sep 03 15:26:06 CEST 2010
-ScormResultArchiveController.menu.title=Wyniki SCORM
-ScormResultArchiveController.menu.title.alt=Wyniki SCORM
-archive.noresults=Brak zapisanych wynik\u00F3w dla tego elementu kursu.
-command.start.exportwizard=Rozpocznij archiwizacj\u0119
-nodesoverview.nonodes=Kurs nie zawiera tre\u015Bci SCORM.
 results.header=Wyniki SCORM
 results.table.foot.cr=Odpowiedz studentowi
 results.table.footer.sr=Prawid\u0142owa odpowied\u017A
@@ -15,12 +10,3 @@ results.table.header.objective=Wynik maksymalny {0}
 results.table.header.rawScore=Wynik ko\u0144cowy
 results.table.header.totalTime=Czas
 results.table.header.username=Nazwa u\u017Cytkownika
-wizard.finished.howto=Plik zawieraj\u0105cy zarchiwizowane dane, powinien znajdowa\u0107 si\u0119 w twoim folderze osobistym.
-wizard.finished.title=Archiwizacja uko\u0144czona
-wizard.intro.fin=Plik zawieraj\u0105cy wyniki, znajduje si\u0119 w twoim folderze osobistym.
-wizard.intro.nod=Wybierz element typu SCORM.
-wizard.intro.text=W nast\u0119pnym oknie dialogowym wybierz element SCORM, kt\u00F3ry ma by\u0107 oceniany. Archiwum z wynikami znajdziesz w swoim folderze osobistym, w sekcji private/archive/[nazwa kursu]/[nazwa pliku].
-wizard.intro.title=Wyniki SCORM
-wizard.nodechoose.howto=Wybierz element typu SCORM.
-wizard.nodechoose.title=Wyb\u00F3r elementu typu SCORM
-wizard.nodetitle=Nazwij element kursu
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pt_BR.properties
index d00e80f44599d196c74d408707533252fc1e6aa5..5e31052889a78af86da7ce69e6273ca1e3fba8f3 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_pt_BR.properties
@@ -1,9 +1,4 @@
 #Fri Sep 17 16:21:00 CEST 2010
-ScormResultArchiveController.menu.title=Resultados SCORM
-ScormResultArchiveController.menu.title.alt=Resultados SCORM
-archive.noresults=Nenhum resultado registrado para esse elemento do curso.
-command.start.exportwizard=Iniciar arquivamento
-nodesoverview.nonodes=Este curso n\u00E3o cont\u00EAm qualquer elemento SCORM.
 results.header=Resultados SCORM
 results.table.foot.cr=Responder estudante
 results.table.footer.sr=Corrigir resposta
@@ -15,12 +10,3 @@ results.table.header.objective=Pontua\u00E7\u00E3o m\u00E1xima {0}
 results.table.header.rawScore=Pontua\u00E7\u00E3o Final
 results.table.header.totalTime=Tempo
 results.table.header.username=Usu\u00E1rio
-wizard.finished.howto=Um arquivo contendo os dados arquivados podem ser encontrados em sua pasta pessoal.
-wizard.finished.title=Arquivamento finalizado
-wizard.intro.fin=Um arquivo contendo os resultados podem ser encontrados em sua pasta pessoal.
-wizard.intro.nod=Por favor selecione um elemento SCORM.
-wizard.intro.text=Na janela seguinte selecione o elemento SCORM para ser avaliado. Os resultados arquivados podem ser encontrados na pasta pessoal, se\u00E7\u00E3o private/archive/[course name]/[file name].
-wizard.intro.title=Resultados SCORM
-wizard.nodechoose.howto=Por favor selecione um elemento SCORM.
-wizard.nodechoose.title=Sele\u00E7\u00E3o elemento SCORM
-wizard.nodetitle=T\u00EDtulo do elemento de curso
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ru.properties
index f33b389df8d07c9a043ecf72ef5f15678970a938..c5594a7dab294556b73318768716862e41352db1 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ru.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_ru.properties
@@ -1,7 +1,4 @@
 #Sun Jan 24 08:19:04 CET 2010
-ScormResultArchiveController.menu.title=SCORM \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B
-command.start.exportwizard=\u0421\u0442\u0430\u0440\u0442 \u0430\u0440\u0445\u0438\u0432\u0430\u0446\u0438\u0438
-nodesoverview.nonodes=\u042D\u0442\u043E\u0442 \u043A\u0443\u0440\u0441 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432.
 results.header=SCORM \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B
 results.table.foot.cr=\u041E\u0442\u0432\u0435\u0442 \u0441\u0442\u0443\u0434\u0435\u043D\u0442\u0430
 results.table.footer.sr=\u041F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0439 \u043E\u0442\u0432\u0435\u0442
@@ -13,12 +10,3 @@ results.table.header.objective=\u041C\u0430\u043A\u0441\u0438\u043C\u0443\u043C
 results.table.header.rawScore=\u0417\u0430\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0446\u0435\u043D\u043A\u0430
 results.table.header.totalTime=\u0412\u0440\u0435\u043C\u044F
 results.table.header.username=\u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F
-wizard.finished.howto=\u0424\u0430\u0439\u043B, \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0430\u0440\u0445\u0438\u0432\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0439\u0442\u0438 \u0432 \u0432\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435.
-wizard.finished.title=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u043E\u043A\u043E\u043D\u0447\u0435\u043D\u043E
-wizard.intro.fin=\u0424\u0430\u0439\u043B, \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0430\u0448\u0438 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043D\u0430\u0445\u043E\u0434\u0438\u0442\u0441\u044F \u0432 \u0432\u0430\u0448\u0435\u0439 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435.
-wizard.intro.nod=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442.
-wizard.intro.text=\u0412 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0434\u0438\u0430\u043B\u043E\u0433\u0435 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442 \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0431\u0443\u0434\u0435\u0442 \u043E\u0446\u0435\u043D\u0435\u043D. \u0410\u0440\u0445\u0438\u0432 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u043E\u0432 \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0439\u0442\u0438 \u0432 \u0432\u0430\u0448\u0435\u0439 \u043B\u0438\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043B\u0435 private/archive/[\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u0443\u0440\u0441\u0430]/[\u0418\u043C\u044F \u0444\u0430\u0439\u043B\u0430].
-wizard.intro.title=SCORM \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B
-wizard.nodechoose.howto=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 SCORM \u044D\u043B\u0435\u043C\u0435\u043D\u0442.
-wizard.nodechoose.title=\u0412\u044B\u0431\u043E\u0440 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430 SCORM
-wizard.nodetitle=\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430 \u043A\u0443\u0440\u0441\u0430
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_CN.properties
index 3765ca9126dbd6f7832d6525d6c10869825c7411..92bf7a4d1560e850ebab66ee6de50c4fceefd419 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_CN.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_CN.properties
@@ -1,8 +1,4 @@
 #Fri Feb 12 08:07:36 CET 2010
-ScormResultArchiveController.menu.title=SCORM \u6210\u7EE9
-ScormResultArchiveController.menu.title.alt=SCORM \u6210\u7EE9
-command.start.exportwizard=\u5F00\u59CB\u5B58\u50A8
-nodesoverview.nonodes=\u672C\u5B66\u7A0B\u4E0D\u5305\u542B\u4EFB\u4F55SCORM\u5143\u7D20\u3002
 results.header=SCORM \u6210\u7EE9
 results.table.foot.cr=\u56DE\u590D\u5B66\u751F
 results.table.footer.sr=\u6B63\u786E\u7B54\u6848
@@ -13,13 +9,4 @@ results.table.header.lessonStatus=\u72B6\u6001
 results.table.header.objective=\u6700\u9AD8\u5206\u6570{0}
 results.table.header.rawScore=\u6700\u7EC8\u5F97\u5206
 results.table.header.totalTime=\u65F6\u95F4
-results.table.header.username=\u7528\u6237\u540D
-wizard.finished.howto=\u5305\u542B\u5B58\u50A8\u6570\u636E\u7684\u6587\u4EF6\u53EF\u4EE5\u5728\u60A8\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939\u4E2D\u627E\u5230\u3002
-wizard.finished.title=\u5DF2\u5B8C\u6210\u4FDD\u5B58
-wizard.intro.fin=\u5305\u542B\u60A8\u6210\u7EE9\u7684\u6587\u4EF6\u53EF\u4EE5\u5728\u60A8\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939\u4E2D\u627E\u5230\u3002
-wizard.intro.nod=\u8BF7\u9009\u62E9\u4E00\u4E2ASCORM\u5143\u7D20\u3002
-wizard.intro.text=\u8BF7\u5728\u4EE5\u4E0B\u5BF9\u8BDD\u6846\u4E2D\u9009\u62E9\u8981\u8BC4\u4EF7\u7684SCORM\u5143\u7D20\u3002\u5B58\u50A8\u7684\u6210\u7EE9\u53EF\u4EE5\u5728\u60A8\u7684\u4E2A\u4EBA\u6587\u4EF6\u5939\u4E2D\u627E\u5230\uFF0C\u5B83\u4F4D\u4E8E \u4E2A\u4EBA/\u5B58\u50A8/[course name]/[file name]\u3002
-wizard.intro.title=SCORM \u6210\u7EE9
-wizard.nodechoose.howto=\u8BF7\u9009\u62E9\u4E00\u4E2ASCORM\u5143\u7D20\u3002
-wizard.nodechoose.title=\u9009\u62E9SCORM\u5143\u7D20
-wizard.nodetitle=\u4E3A\u5B66\u7A0B\u5143\u7D20\u547D\u540D
+results.table.header.username=\u7528\u6237\u540D
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_TW.properties
index c16b2f55660726fb74075bf0c81e55d3b8f53c67..0ade1b1963d7617671dfcfc4e6d221951a8c780f 100644
--- a/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_TW.properties
+++ b/src/main/java/org/olat/modules/scorm/archiver/_i18n/LocalStrings_zh_TW.properties
@@ -1,8 +1,4 @@
 #Sun Feb 07 18:02:22 CET 2010
-ScormResultArchiveController.menu.title=SCORM \u7D50\u679C
-ScormResultArchiveController.menu.title.alt=SCORM \u7D50\u679C
-command.start.exportwizard=\u958B\u59CB\u5099\u4EFD
-nodesoverview.nonodes=\u9019\u500B\u8AB2\u7A0B\u4E26\u6C92\u6709\u5305\u542B\u4EFB\u4F55 SCORM \u5143\u7D20\u3002
 results.header=SCORM \u7D50\u679C
 results.table.foot.cr=\u56DE\u8986\u5B78\u751F
 results.table.footer.sr=\u6B63\u78BA\u7B54\u6848
@@ -14,11 +10,3 @@ results.table.header.objective=\u6700\u9AD8\u5206\u6578 {0}
 results.table.header.rawScore=\u6700\u7D42\u5206\u6578
 results.table.header.totalTime=\u6642\u9593
 results.table.header.username=\u4F7F\u7528\u8005\u540D\u7A31
-wizard.finished.howto=\u542B\u6709\u5DF2\u5099\u4EFD\u8CC7\u6599\u7684\u6A94\u6848\u53EF\u4EE5\u5728\u60A8\u7684\u500B\u4EBA\u8CC7\u6599\u593E\u4E2D\u627E\u5230\u3002
-wizard.finished.title=\u5099\u4EFD\u5B8C\u6210
-wizard.intro.fin=\u542B\u6709\u60A8\u7684\u7D50\u679C\u7684\u6A94\u6848\u53EF\u4EE5\u5728\u60A8\u7684\u500B\u4EBA\u8CC7\u6599\u593E\u4E2D\u627E\u5230\u3002
-wizard.intro.nod=\u8ACB\u9078\u64C7\u4E00\u500B SCORM \u5143\u7D20\u3002
-wizard.intro.title=SCORM \u7D50\u679C
-wizard.nodechoose.howto=\u8ACB\u9078\u64C7\u4E00\u500B SCORM \u5143\u7D20\u3002
-wizard.nodechoose.title=\u9078\u64C7 SCORM \u5143\u7D20
-wizard.nodetitle=\u6A19\u660E\u8AB2\u7A0B\u5143\u7D20
diff --git a/src/main/java/org/olat/modules/wiki/WikiToZipUtils.java b/src/main/java/org/olat/modules/wiki/WikiToZipUtils.java
index 242e77b4da8dc2c588d7a1324dca1b6709d365a1..820d12134b47a56179f732c81484a5d078dc8a5e 100644
--- a/src/main/java/org/olat/modules/wiki/WikiToZipUtils.java
+++ b/src/main/java/org/olat/modules/wiki/WikiToZipUtils.java
@@ -29,7 +29,10 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.olat.core.logging.AssertException;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.ZipUtil;
@@ -113,5 +116,23 @@ public class WikiToZipUtils {
 		ZipUtil.zip(filesTozip, rootContainer.createChildLeaf("wiki.zip"), true);
 		return (VFSLeaf)rootContainer.resolve("wiki.zip");
 	}
-
+	
+	public static void wikiToZip(VFSContainer rootContainer, String currentPath, ZipOutputStream exportStream)
+	throws IOException {
+		for (VFSItem item:rootContainer.getItems()) {
+			if (item instanceof VFSContainer) {
+				VFSContainer folder = (VFSContainer) item;
+				List<VFSItem> items = folder.getItems();
+				String overviewPage = WikiToZipUtils.createIndexPageForExport(items);
+				if(overviewPage != null){
+					exportStream.putNextEntry(new ZipEntry(currentPath + "/index.html"));
+					IOUtils.write(overviewPage, exportStream);
+					exportStream.closeEntry();
+				}
+				for(VFSItem wikiItem:items) {
+					ZipUtil.addToZip(wikiItem, currentPath, exportStream);
+				}
+			}
+		}
+	}
 }