diff --git a/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/model/CourseCreationConfiguration.java b/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/model/CourseCreationConfiguration.java
index 65ba18cd64f7fd90b9903d992215abbe05bbc90c..6d6ab8c966bcae0d0684ca590f0e9e8be81b7ae5 100644
--- a/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/model/CourseCreationConfiguration.java
+++ b/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/model/CourseCreationConfiguration.java
@@ -36,9 +36,9 @@ import java.io.IOException;
 
 import org.apache.velocity.context.Context;
 import org.olat.core.commons.editor.htmleditor.WysiwygFactory;
+import org.olat.core.gui.DefaultGlobalSettings;
 import org.olat.core.gui.GlobalSettings;
 import org.olat.core.gui.components.velocity.VelocityContainer;
-import org.olat.core.gui.control.winmgr.AJAXFlags;
 import org.olat.core.gui.render.RenderResult;
 import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
@@ -365,11 +365,7 @@ public class CourseCreationConfiguration {
 		vc.contextPut("coursetitle", courseTitle);
 		
 		//prepare rendering of velocity page for the content of the single page node
-		GlobalSettings globalSettings = new GlobalSettings() {
-			public int getFontSize() { return 100;}
-			public AJAXFlags getAjaxFlags() { return new EmptyAJAXFlags();}
-			public boolean isIdDivsForced() { return false; }
-		};
+		GlobalSettings globalSettings = new DefaultGlobalSettings();
 		
 		Context context = vc.getContext();
 		Renderer fr = Renderer.getInstance(vc, translator, null, new RenderResult(), globalSettings);
@@ -385,12 +381,6 @@ public class CourseCreationConfiguration {
 			return null;
 		}
 	}
-	
-	private static class EmptyAJAXFlags extends AJAXFlags {
-		public EmptyAJAXFlags() { super(null); }
-		@Override
-		public boolean isIframePostEnabled() { return false; }
-	}
 
 	/**
 	 * @param subscriberCount The subscriberCount to set.
diff --git a/src/main/java/org/olat/collaboration/CollaborationTools.java b/src/main/java/org/olat/collaboration/CollaborationTools.java
index f2782660e2806122a08c1bc67e67504b08a71afe..9117cc6485a1ad83b0f8a2d203534ebc3619dc66 100644
--- a/src/main/java/org/olat/collaboration/CollaborationTools.java
+++ b/src/main/java/org/olat/collaboration/CollaborationTools.java
@@ -331,7 +331,7 @@ public class CollaborationTools implements Serializable {
 	}
 	
 	public Forum getForum() {
-		final ForumManager fom = ForumManager.getInstance();
+		final ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 		final NarrowedPropertyManager npm = NarrowedPropertyManager.getInstance(ores);
 		Property forumProperty = npm.findProperty(null, null, PROP_CAT_BG_COLLABTOOLS, KEY_FORUM);
 		
@@ -639,7 +639,7 @@ public class CollaborationTools implements Serializable {
 		/*
 		 * delete the forum, if existing
 		 */
-		ForumManager fom = ForumManager.getInstance();
+		ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 		Property forumKeyProperty = npm.findProperty(null, null, PROP_CAT_BG_COLLABTOOLS, KEY_FORUM);
 		if (forumKeyProperty != null) {
 			// if there was a forum, delete it
@@ -1009,7 +1009,7 @@ public class CollaborationTools implements Serializable {
 			String archiveForumName = "del_forum_" + forumKeyProperty.getLongValue();
 			VFSContainer archiveForumContainer = archiveContainer.createChildContainer(archiveForumName);
 			ForumFormatter ff = new ForumRTFFormatter(archiveForumContainer, false, I18nModule.getDefaultLocale());
-			ForumArchiveManager.getInstance().applyFormatter(ff, forumKeyProperty.getLongValue(), null);
+			CoreSpringFactory.getImpl(ForumArchiveManager.class).applyFormatter(ff, forumKeyProperty.getLongValue(), null);
 		}
 	}
 
diff --git a/src/main/java/org/olat/core/gui/DefaultGlobalSettings.java b/src/main/java/org/olat/core/gui/DefaultGlobalSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0c340647916554bc81d4e546dfedf1376e86e70
--- /dev/null
+++ b/src/main/java/org/olat/core/gui/DefaultGlobalSettings.java
@@ -0,0 +1,38 @@
+package org.olat.core.gui;
+
+import org.olat.core.gui.control.winmgr.AJAXFlags;
+
+/**
+ * 
+ * Initial date: 28 mai 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class DefaultGlobalSettings implements GlobalSettings {
+	@Override
+	public int getFontSize() {
+		return 100;
+	}
+	
+	@Override
+	public AJAXFlags getAjaxFlags() {
+		return new EmptyAJAXFlags();
+	}
+	
+	@Override
+	public boolean isIdDivsForced() {
+		return false;
+	}
+	
+	private static class EmptyAJAXFlags extends AJAXFlags {
+		
+		public EmptyAJAXFlags() {
+			super(null);
+		}
+		
+		@Override
+		public boolean isIframePostEnabled() {
+			return false;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/core/gui/control/winmgr/WindowManagerImpl.java b/src/main/java/org/olat/core/gui/control/winmgr/WindowManagerImpl.java
index 377cbdeccb7d07408f4e81aa2fca7e41ca7c79b5..f3228866ddaf5caf3a8f04aeda81dfc93e6ef17e 100644
--- a/src/main/java/org/olat/core/gui/control/winmgr/WindowManagerImpl.java
+++ b/src/main/java/org/olat/core/gui/control/winmgr/WindowManagerImpl.java
@@ -50,7 +50,7 @@ import org.olat.core.manager.BasicManager;
  */
 public class WindowManagerImpl extends BasicManager implements WindowManager {
 	
-	private List<WindowBackOfficeImpl> wbos = new ArrayList<WindowBackOfficeImpl>();
+	private List<WindowBackOfficeImpl> wbos = new ArrayList<>();
 	
 	private GlobalSettings globalSettings;
 	private boolean ajaxEnabled = false;
diff --git a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
index a74eac51a8b63d4a74b749c63bfe5c09d0b84181..bec8188c4c68fe4d0623381246810e0c0d1c74b5 100644
--- a/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
+++ b/src/main/java/org/olat/course/assessment/portfolio/EfficiencyStatementMediaHandler.java
@@ -20,10 +20,17 @@
  */
 package org.olat.course.assessment.portfolio;
 
+import java.io.File;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.util.SyntheticUserRequest;
+import org.olat.core.gui.util.WindowControlMocker;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -31,7 +38,10 @@ import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.core.util.xml.XStreamHelper;
+import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.EfficiencyStatement;
+import org.olat.course.assessment.model.AssessmentNodeData;
+import org.olat.course.assessment.ui.tool.IdentityAssessmentOverviewController;
 import org.olat.course.certificate.ui.CertificateAndEfficiencyStatementController;
 import org.olat.modules.portfolio.Media;
 import org.olat.modules.portfolio.MediaInformations;
@@ -42,6 +52,7 @@ import org.olat.modules.portfolio.handler.AbstractMediaHandler;
 import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.ui.media.StandardEditMediaController;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -141,4 +152,23 @@ public class EfficiencyStatementMediaHandler extends AbstractMediaHandler {
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new StandardEditMediaController(ureq, wControl, media);
 	}
+
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		EfficiencyStatement statement = null;
+		if(StringHelper.containsNonWhitespace(media.getContent())) {
+			try {
+				statement = (EfficiencyStatement)myXStream.fromXML(media.getContent());
+			} catch (Exception e) {
+				log.error("Cannot load efficiency statement from artefact", e);
+			}
+		}
+		if(statement != null) {
+			List<Map<String,Object>> assessmentNodes = statement.getAssessmentNodes();
+			List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.assessmentNodeDataMapToList(assessmentNodes);
+			SyntheticUserRequest ureq = new SyntheticUserRequest(media.getAuthor(), locale);
+			IdentityAssessmentOverviewController details = new IdentityAssessmentOverviewController(ureq, new WindowControlMocker(), assessmentNodeList);
+			super.exportContent(media, details.getInitialComponent(), null, mediaArchiveDirectory, locale);
+		}
+	}
 }
diff --git a/src/main/java/org/olat/course/nodes/DialogCourseNode.java b/src/main/java/org/olat/course/nodes/DialogCourseNode.java
index 60863ee013cb66b5a2cd3899e872e7c247aa4288..45a551d622696e4a5f3d18833e9a1fa26fce8e7d 100644
--- a/src/main/java/org/olat/course/nodes/DialogCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/DialogCourseNode.java
@@ -228,7 +228,7 @@ public class DialogCourseNode extends AbstractAccessableCourseNode {
 		diaNodeElemExportContainer.setLocalSecurityCallback(new FullAccessCallback());
 		diaNodeElemExportContainer.copyFrom(dialogFile);
 
-		ForumArchiveManager fam = ForumArchiveManager.getInstance();
+		ForumArchiveManager fam = CoreSpringFactory.getImpl(ForumArchiveManager.class);
 		ForumFormatter ff = new ForumRTFFormatter(diaNodeElemExportContainer, false, locale);
 		fam.applyFormatter(ff, element.getForum().getKey(), null);
 	}
@@ -264,7 +264,7 @@ public class DialogCourseNode extends AbstractAccessableCourseNode {
 			ZipUtil.addToZip(item, exportDirName, exportStream);
 		}
 
-		ForumArchiveManager fam = ForumArchiveManager.getInstance();
+		ForumArchiveManager fam = CoreSpringFactory.getImpl(ForumArchiveManager.class);
 		ForumFormatter ff = new ForumStreamedRTFFormatter(exportStream, exportDirName, false, locale);
 		fam.applyFormatter(ff, element.getForum().getKey(), null);
 	}
diff --git a/src/main/java/org/olat/course/nodes/FOCourseNode.java b/src/main/java/org/olat/course/nodes/FOCourseNode.java
index 566c6dcb7ab9c2c694b5c6160778615cfa84554c..61ddb57d90f1ba09fc62b8b4285330ee03961599 100644
--- a/src/main/java/org/olat/course/nodes/FOCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/FOCourseNode.java
@@ -440,14 +440,14 @@ public class FOCourseNode extends AbstractAccessableCourseNode {
 			return false;
 		}
 		Long forumKey = forumKeyProperty.getLongValue();
-		if(ForumManager.getInstance().countThreadsByForumID(forumKey) <= 0) {
+		if(CoreSpringFactory.getImpl(ForumManager.class).countThreadsByForumID(forumKey) <= 0) {
 			return false;
 		}
 		
 		String forumName = "forum_" + Formatter.makeStringFilesystemSave(getShortTitle())
 				+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()));
 		ForumStreamedRTFFormatter rtff = new ForumStreamedRTFFormatter(exportStream, forumName, false, locale);	
-		ForumArchiveManager.getInstance().applyFormatter(rtff, forumKey, null);
+		CoreSpringFactory.getImpl(ForumArchiveManager.class).applyFormatter(rtff, forumKey, null);
 		return true;
 	}
 
@@ -479,7 +479,7 @@ public class FOCourseNode extends AbstractAccessableCourseNode {
 		Property forumKeyProperty = cpm.findCourseNodeProperty(this, null, null, FORUM_KEY);
 		if (forumKeyProperty != null) {
 			Long forumKey = forumKeyProperty.getLongValue();
-			ForumManager.getInstance().deleteForum(forumKey); // delete the forum
+			CoreSpringFactory.getImpl(ForumManager.class).deleteForum(forumKey); // delete the forum
 			cpm.deleteProperty(forumKeyProperty); // delete the property
 		}
 	}
diff --git a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
index 5290ee82a3547d8c968f400dbcea77ddeda52bec..09a58c0ac3a3550d740269ff5bab1e379bfd7075 100644
--- a/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
+++ b/src/main/java/org/olat/ims/qti21/resultexport/QTI21ResultsExportMediaResource.java
@@ -44,13 +44,12 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.velocity.VelocityContext;
 import org.olat.admin.user.imp.TransientIdentity;
 import org.olat.core.CoreSpringFactory;
-import org.olat.core.gui.GlobalSettings;
+import org.olat.core.gui.DefaultGlobalSettings;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
-import org.olat.core.gui.control.winmgr.AJAXFlags;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.render.RenderResult;
 import org.olat.core.gui.render.Renderer;
@@ -340,7 +339,7 @@ public class QTI21ResultsExportMediaResource implements MediaResource {
 		mainVC.put("results", results);
 		
 		//render VelocityContainer to StringOutPut
-		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new EmptyGlobalSettings());
+		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new DefaultGlobalSettings());
 		try(StringOutput sb = new StringOutput(32000);
 				VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, mainVC, sb)) {
 			mainVC.contextPut("r", vrdec);
@@ -416,33 +415,4 @@ public class QTI21ResultsExportMediaResource implements MediaResource {
 	public void release() {
 		//
 	}
-
-	private static class EmptyAJAXFlags extends AJAXFlags {
-		
-		public EmptyAJAXFlags() {
-			super(null);
-		}
-		
-		@Override
-		public boolean isIframePostEnabled() {
-			return false;
-		}
-	}
-	
-	private static class EmptyGlobalSettings implements GlobalSettings {
-		@Override
-		public int getFontSize() {
-			return 100;
-		}
-		
-		@Override
-		public AJAXFlags getAjaxFlags() {
-			return new EmptyAJAXFlags();
-		}
-		
-		@Override
-		public boolean isIdDivsForced() {
-			return false;
-		}
-	}
 }
diff --git a/src/main/java/org/olat/modules/fo/ForumNotificationsHandler.java b/src/main/java/org/olat/modules/fo/ForumNotificationsHandler.java
index d96d83d1d5d515051b533ebdf74fde97de050fd6..c6b2bfe5f76b3d2f19d8985f0cfd7a4b37ef708c 100644
--- a/src/main/java/org/olat/modules/fo/ForumNotificationsHandler.java
+++ b/src/main/java/org/olat/modules/fo/ForumNotificationsHandler.java
@@ -96,7 +96,7 @@ public class ForumNotificationsHandler extends LogDelegator implements Notificat
 					}
 				}
 				
-				final List<Message> mInfos = ForumManager.getInstance().getNewMessageInfo(forumKey, compareDate);
+				final List<Message> mInfos = CoreSpringFactory.getImpl(ForumManager.class).getNewMessageInfo(forumKey, compareDate);
 				final Translator translator = Util.createPackageTranslator(ForumNotificationsHandler.class, locale);
 				
 				businessControlString = p.getBusinessPath() + "[Message:";
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 54843950fcce86005c6224ddc9d644ac03a0e54f..eb9e66bc092320c658d39a85655aaf6e67aff277 100644
--- a/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
+++ b/src/main/java/org/olat/modules/fo/archiver/ForumArchiveManager.java
@@ -39,26 +39,20 @@ import org.olat.modules.fo.ForumCallback;
 import org.olat.modules.fo.Message;
 import org.olat.modules.fo.archiver.formatters.ForumFormatter;
 import org.olat.modules.fo.manager.ForumManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  *          Initial Date: Nov 11, 2005 <br>
  * @author Alexander Schneider
  */
-
+@Service
 public class ForumArchiveManager {
+	
 	private static final OLog log = Tracing.createLoggerFor(ForumArchiveManager.class);
-	private static final ForumArchiveManager instance = new ForumArchiveManager();
 	
-	private ForumArchiveManager() {
-		// private since singleton
-	}
-	
-	/**
-	 * @return the singleton
-	 */
-	public static ForumArchiveManager getInstance() {
-		return instance;
-	}
+	@Autowired
+	private ForumManager forumManager;
 	
 	/**
 	 * If the forumCallback is null no restriction applies to the forum archiver. 
@@ -98,10 +92,9 @@ public class ForumArchiveManager {
 	 */
 	private List<MessageNode> convertToThreadTrees(Long forumId, ForumCallback forumCallback){
 		List<MessageNode> topNodeList = new ArrayList<>();
-		ForumManager fm = ForumManager.getInstance();
-	
-		Forum f = fm.loadForum(forumId);
-		List<Message> messages = fm.getMessagesByForum(f);
+
+		Forum f = forumManager.loadForum(forumId);
+		List<Message> messages = forumManager.getMessagesByForum(f);
 		
 		for (Iterator<Message> iterTop = messages.iterator(); iterTop.hasNext();) {
 			Message msg = iterTop.next();
@@ -144,7 +137,7 @@ public class ForumArchiveManager {
 	 */
 	private MessageNode convertToThreadTree(Long topMessageId){
 		MessageNode topNode = null;
-		List<Message> messages = ForumManager.getInstance().getThread(topMessageId);
+		List<Message> messages = forumManager.getThread(topMessageId);
 		for (Iterator<Message> iterTop = messages.iterator(); iterTop.hasNext();) {
 			Message msg = iterTop.next();
 			if (msg.getParent() == null) {
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumDownloadResource.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumDownloadResource.java
index 60292670b7e17e779e0dab7e157aca800c875118..4a5a9890cfcdba3632e522f8b5e2dd6d2809be8a 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumDownloadResource.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumDownloadResource.java
@@ -30,6 +30,7 @@ import java.util.zip.ZipOutputStream;
 
 import javax.servlet.http.HttpServletResponse;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.media.ServletUtil;
 import org.olat.core.logging.OLog;
@@ -146,10 +147,10 @@ public class ForumDownloadResource implements MediaResource {
 			
 			ForumOpenXMLFormatter openXmlFormatter = new ForumOpenXMLFormatter(mediaContainer, locale);
 			if(topMessageId != null) {
-				ForumArchiveManager.getInstance()
+				CoreSpringFactory.getImpl(ForumArchiveManager.class)
 					.applyFormatterForOneThread(openXmlFormatter, forum.getKey(), topMessageId);
 			} else {
-				ForumArchiveManager.getInstance()
+				CoreSpringFactory.getImpl(ForumArchiveManager.class)
 					.applyFormatter(openXmlFormatter, forum.getKey(), foCallback);
 			}
 			
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 f48c1a4eb61ab1f23c0954560aea59d550574c25..b65c09fd2480a2a2cee22f27d02e7f709b9e7843 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
@@ -40,6 +40,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringEscapeUtils;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
@@ -72,7 +73,6 @@ public class ForumRTFFormatter extends ForumFormatter {
 
 	private VFSContainer container;
 	private VFSItem vfsFil = null;
-	private ForumManager fm = ForumManager.getInstance();
 	private VFSContainer tempContainer;
 	
 	final Pattern PATTERN_HTML_BOLD = Pattern.compile("<strong>(.*?)</strong>", Pattern.CASE_INSENSITIVE);
@@ -91,6 +91,8 @@ public class ForumRTFFormatter extends ForumFormatter {
 	//TODO: (LD) translate this!
 	private String HIDDEN_STR = "VERBORGEN";
 	
+	private final ForumManager forumManager;
+	
 	/**
 	 * 
 	 * @param container
@@ -103,6 +105,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 		// where to write
 		this.container = container;
 		this.filePerThread = filePerThread;
+		forumManager = CoreSpringFactory.getImpl(ForumManager.class);
 	}
 
 	/**
@@ -167,7 +170,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 		}
 		sb.append(" \\par}");
 		// attachment(s)
-		VFSContainer msgContainer = fm.getMessageContainer(getForumKey(), mn.getKey());
+		VFSContainer msgContainer = forumManager.getMessageContainer(getForumKey(), mn.getKey());
 		List<VFSItem> attachments = msgContainer.getItems();
 		if (attachments != null && attachments.size() > 0){
 			VFSItem item = container.resolve("attachments");
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
index fd85dbb2f54ba0a54c23304cfd59b1476bc6a356..49847b8ff0c59c7ea74baf681305c9f859a879f4 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
@@ -39,6 +39,7 @@ 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.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.AssertException;
@@ -65,7 +66,6 @@ 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);
@@ -82,6 +82,8 @@ public class ForumStreamedRTFFormatter extends ForumFormatter {
 	
 	private String HIDDEN_STR = "VERBORGEN";
 	private final String path;
+	
+	private final ForumManager forumManager;
 		
 	/**
 	 * 
@@ -92,6 +94,9 @@ public class ForumStreamedRTFFormatter extends ForumFormatter {
 	public ForumStreamedRTFFormatter(ZipOutputStream exportStream, String path, boolean filePerThread, Locale locale) {
 		// init String Buffer in ForumFormatter
 		super(locale);
+		
+		forumManager = CoreSpringFactory.getImpl(ForumManager.class);
+		
 		// where to write
 		this.exportStream = exportStream;
 		this.filePerThread = filePerThread;
@@ -152,7 +157,7 @@ public class ForumStreamedRTFFormatter extends ForumFormatter {
 		}
 		sb.append(" \\par}");
 		// attachment(s)
-		VFSContainer msgContainer = fm.getMessageContainer(getForumKey(), mn.getKey());
+		VFSContainer msgContainer = forumManager.getMessageContainer(getForumKey(), mn.getKey());
 		List<VFSItem> attachments = msgContainer.getItems();
 		if (attachments != null && attachments.size() > 0){
 			sb.append("{\\pard \\f0\\fs15 Attachment(s): ");
diff --git a/src/main/java/org/olat/modules/fo/manager/ForumManager.java b/src/main/java/org/olat/modules/fo/manager/ForumManager.java
index 935aeacb113dc1c05f58ea7f69c6db2886154db4..a72e0fad8064ef32e427ac3751049be368f1611c 100644
--- a/src/main/java/org/olat/modules/fo/manager/ForumManager.java
+++ b/src/main/java/org/olat/modules/fo/manager/ForumManager.java
@@ -90,8 +90,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class ForumManager {
 	private static final OLog log = Tracing.createLoggerFor(ForumManager.class);
-	
-	private static ForumManager INSTANCE;
+
 	@Autowired
 	private DB dbInstance;
 	@Autowired
@@ -102,20 +101,6 @@ public class ForumManager {
 	private UserManager userManager;
 	@Autowired
 	private MarkingService markingService;
-
-	/**
-	 * [spring]
-	 */
-	private ForumManager() {
-		INSTANCE = this;
-	}
-
-	/**
-	 * @return the singleton
-	 */
-	public static ForumManager getInstance() {
-		return INSTANCE;
-	}
 	
 	public int countThread(Long messageKey) {
 		String query = "select count(msg) from fomessage as msg where msg.key=:messageKey or msg.threadtop.key=:messageKey";
@@ -374,6 +359,19 @@ public class ForumManager {
 				.getResultList();
 		return messages == null || messages.isEmpty() ? null : messages.get(0);
 	}
+	
+	public List<Message> getMessageByCreator(IdentityRef creator) {
+		StringBuilder query = new StringBuilder();
+		query.append("select msg from fomessage as msg")
+		     .append(" inner join msg.creator as creator")
+		     .append(" inner join fetch msg.forum as forum")
+		     .append(" where msg.creator.key=:identityKey");
+		
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(query.toString(), Message.class)
+				.setParameter("identityKey", creator.getKey())
+				.getResultList();
+	}
 
 	public boolean isPseudonymProtected(String pseudonym) {
 		StringBuilder query = new StringBuilder();
diff --git a/src/main/java/org/olat/modules/fo/manager/ForumUserDataManager.java b/src/main/java/org/olat/modules/fo/manager/ForumUserDataManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..407e206953b6c9f8128d718ad3f9e7b86e430a2f
--- /dev/null
+++ b/src/main/java/org/olat/modules/fo/manager/ForumUserDataManager.java
@@ -0,0 +1,230 @@
+/**
+ * <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.fo.manager;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.gui.DefaultGlobalSettings;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.render.EmptyURLBuilder;
+import org.olat.core.gui.render.RenderResult;
+import org.olat.core.gui.render.Renderer;
+import org.olat.core.gui.render.StringOutput;
+import org.olat.core.gui.render.velocity.VelocityRenderDecorator;
+import org.olat.core.gui.translator.Translator;
+import org.olat.core.id.Identity;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.id.context.BusinessControlFactory;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.FileUtils;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.Util;
+import org.olat.core.util.io.SystemFileFilter;
+import org.olat.core.util.resource.OresHelper;
+import org.olat.group.BusinessGroup;
+import org.olat.group.BusinessGroupService;
+import org.olat.modules.fo.Forum;
+import org.olat.modules.fo.ForumModule;
+import org.olat.modules.fo.Message;
+import org.olat.modules.wiki.WikiManager;
+import org.olat.properties.Property;
+import org.olat.properties.PropertyManager;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryManager;
+import org.olat.user.UserDataExportable;
+import org.olat.user.manager.ManifestBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ * Initial date: 28 mai 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class ForumUserDataManager implements UserDataExportable {
+	
+	private static final OLog log = Tracing.createLoggerFor(ForumUserDataManager.class);
+
+	public static final String FORUM_KEY = "forumKey";// course and group
+	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private ForumManager forumManager;
+	@Autowired
+	private PropertyManager propertyManager;
+	@Autowired
+	private RepositoryManager repositoryManager;
+	@Autowired
+	private BusinessGroupService businessGroupService;
+
+	@Override
+	public String getExporterID() {
+		return "forums";
+	}
+
+	@Override
+	public void export(Identity identity, ManifestBuilder manifest, File archiveDirectory, Locale locale) {
+		List<Message> messages = forumManager.getMessageByCreator(identity);
+		dbInstance.commitAndCloseSession();
+		if(messages.isEmpty()) return;
+
+
+		File forumArchive = new File(archiveDirectory, "Forums");
+		forumArchive.mkdir();
+		Map<Long,Property> properties = loadMappingProperties();
+		Map<Long, Location> locations = new HashMap<>();
+		Translator translator = Util.createPackageTranslator(ForumModule.class, locale);
+		int count = 1;
+		for(Message message:messages) {
+			String name = count++ + "_" + StringHelper.transformDisplayNameToFileSystemName(message.getTitle());
+
+			Forum forum = message.getForum();
+			Location location = locations.computeIfAbsent(forum.getKey(), forumKey -> resolveLocation(forumKey, properties));
+			
+			List<File> attachments;
+			File msgContainer = forumManager.getMessageDirectory(forum.getKey(), message.getKey(), false);
+			if(msgContainer != null && msgContainer.exists()) {
+				File[] attachmentArr = msgContainer.listFiles(new SystemFileFilter(true, false));
+				attachments = Arrays.asList(attachmentArr);
+				if(!attachments.isEmpty()) {
+					File messageAttachementDir = new File(forumArchive, name);
+					messageAttachementDir.mkdir();
+					for(File attachment:attachments) {
+						FileUtils.copyFileToDir(attachment, messageAttachementDir, "Copy forum message attachments");
+					}
+				}
+			} else {
+				attachments = Collections.emptyList();
+			}
+			
+			File messageFile = new File(forumArchive, name + ".html");
+			try(OutputStream out = new FileOutputStream(messageFile)) {
+				String content = renderForumMessage(location, message, attachments, translator);
+				out.write(content.getBytes("UTF-8"));
+				out.flush();
+			} catch(IOException e) {
+				log.error("", e);
+			}
+		}
+
+	}
+	
+	private Location resolveLocation(Long forumKey, Map<Long,Property> properties) {
+		Property property = properties.get(forumKey);
+		String name = null;
+		String businessPath = null;
+		if(property != null) {
+			if("CourseModule".equals(property.getResourceTypeName())) {
+				OLATResourceable resourceable = OresHelper.createOLATResourceableInstance(property.getResourceTypeName(), property.getResourceTypeId());
+				RepositoryEntry entry = repositoryManager.lookupRepositoryEntry(resourceable, false);
+				if(entry != null) {
+					name = entry.getDisplayname();
+					businessPath = "[RepositoryEntry:" + entry.getKey() + "]";
+					String nodeId = extractNodeId(property);
+					if(nodeId != null) {
+						businessPath += "[CourseNode:" + nodeId + "]";
+					}
+				}	
+			} else if("BusinessGroup".equals(property.getResourceTypeName())) {
+				BusinessGroup businessGroup = businessGroupService.loadBusinessGroup(property.getResourceTypeId());
+				if(businessGroup != null) {
+					name = businessGroup.getName();
+					businessPath += "[BusinessGroup:" + businessGroup.getKey() + "]";
+				}
+			}
+		}
+		
+		String url = businessPath == null ? null : BusinessControlFactory.getInstance().getURLFromBusinessPathString(businessPath);
+		return new Location(name, url);
+	}
+	
+	private String extractNodeId(Property property) {
+		if(property.getCategory() != null) {
+			String category = property.getCategory();
+			int index = category.indexOf("::");
+			if(index > 0 && index + 2 < category.length()) {
+				return category.substring(index + 2, category.length());
+			}
+		}	
+		return null;
+	}
+	
+	private Map<Long,Property> loadMappingProperties() {
+		Map<Long,Property> propertyMap = new HashMap<>();
+		List<Property> properties = propertyManager.listProperties(null, null, null, null, null, FORUM_KEY);
+		for(Property property:properties) {
+			propertyMap.put(property.getLongValue(), property);
+		}
+		
+		List<Property> wikiProperties = propertyManager.listProperties(null, null, null, null, null, WikiManager.FORUM_KEY);
+		for(Property property:wikiProperties) {
+			propertyMap.put(property.getLongValue(), property);
+		}
+		return propertyMap;
+	}
+
+	
+	private String renderForumMessage(Location location, Message message, List<File> attachments, Translator translator) {
+		StringOutput sb = new StringOutput(10000);
+		String pagePath = Util.getPackageVelocityRoot(ForumUserDataManager.class) + "/export_message.html";
+		VelocityContainer component = new VelocityContainer("html", pagePath, translator, null);
+		component.contextPut("message", message);
+		component.contextPut("attachments", attachments);
+		component.contextPut("location", location);
+		
+		Renderer renderer = Renderer.getInstance(component, translator, new EmptyURLBuilder(), new RenderResult(), new DefaultGlobalSettings());
+		VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, component, sb);
+		component.contextPut("r", vrdec);
+		renderer.render(sb, component, null);
+		return sb.toString();
+	}
+	
+	public static class Location {
+		private final String name;
+		private final String url;
+		
+		public Location(String name, String url) {
+			this.name = name;
+			this.url = url;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public String getUrl() {
+			return url;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/modules/fo/manager/_content/export_message.html b/src/main/java/org/olat/modules/fo/manager/_content/export_message.html
new file mode 100644
index 0000000000000000000000000000000000000000..19a0a32db7b37f2ae27e16f27e5be435d8d14f3e
--- /dev/null
+++ b/src/main/java/org/olat/modules/fo/manager/_content/export_message.html
@@ -0,0 +1,36 @@
+<html>
+	<head>
+		<title>$r.escapeHtml($message.title)</title>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	</head>
+	<body>
+		<div class="o_forum_message_header clearfix">
+			<h4 class="o_forum_message_title">$r.escapeHtml($message.title)</h4>
+			<div class="o_date">
+				$r.translate("msg.creationdate") $r.formatDateAndTime($message.creationDate)
+			</div>
+			#if($r.isNotEmpty($location.url))
+			<div class="o_path">
+				<a href="$location.url">$location.name <small>$location.url</small></a>
+			</div>
+			#end
+		</div>
+		<div class="o_forum_message_body o_user_content_block">
+			<div class="clearfix o_scrollblock">$r.formatLatexFormulas($message.body)</div>
+		</div>
+		
+		#if($r.isNotEmpty($attachments))
+		<div class="o_forum_message_attachments">
+			<h5>$r.translate("attachments"):</h5>
+			<ul class="list-inline">
+			#foreach($attachment in $attachments)
+				#set($fname = $attachment.getName())
+				<li class="o_attachment">
+					<a href="${message.forum.key}_${message.key}/${fname}" target="_blank"><span class="o_filename">$r.escapeHtml($fname)</span></a>		
+				</li>
+			#end 
+			</ul>
+		</div>
+		#end
+	</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/fo/portfolio/ForumArtefactHandler.java b/src/main/java/org/olat/modules/fo/portfolio/ForumArtefactHandler.java
index 6850fbf8ce22c4ca6e8bf650af35868366a48ab0..14f713116ee53be91d364b4017e035409024081d 100755
--- a/src/main/java/org/olat/modules/fo/portfolio/ForumArtefactHandler.java
+++ b/src/main/java/org/olat/modules/fo/portfolio/ForumArtefactHandler.java
@@ -21,6 +21,7 @@ package org.olat.modules.fo.portfolio;
 
 import java.util.List;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
@@ -51,7 +52,7 @@ public class ForumArtefactHandler extends EPAbstractHandler<ForumArtefact> {
 		super.prefillArtefactAccordingToSource(artefact, source);
 		if (source instanceof OLATResourceable){
 			OLATResourceable ores = (OLATResourceable) source;
-			ForumManager fMgr = ForumManager.getInstance();
+			ForumManager fMgr = CoreSpringFactory.getImpl(ForumManager.class);
 			Message fm = fMgr.loadMessage(ores.getResourceableId());
 			String thread = fm.getThreadtop() != null ? fm.getThreadtop().getTitle() + " - " : "";
 			artefact.setTitle(thread + fm.getTitle());
diff --git a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
index ef47808a23cf8cb58310dd8e8607776d8edd63f9..5c068e2d629f0c54bb15a7de8e36c4bb31eabfbc 100644
--- a/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
+++ b/src/main/java/org/olat/modules/fo/portfolio/ForumMediaHandler.java
@@ -21,7 +21,10 @@
 package org.olat.modules.fo.portfolio;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
@@ -30,6 +33,8 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.io.SystemFileFilter;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
@@ -51,6 +56,7 @@ import org.olat.modules.portfolio.manager.PortfolioFileStorage;
 import org.olat.modules.portfolio.ui.media.StandardEditMediaController;
 import org.olat.portfolio.manager.EPFrontendManager;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -170,4 +176,17 @@ public class ForumMediaHandler extends AbstractMediaHandler {
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new StandardEditMediaController(ureq, wControl, media);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		List<File> attachments = new ArrayList<>();
+		if(StringHelper.containsNonWhitespace(media.getStoragePath())) {
+			File mediaDir = fileStorage.getMediaDirectory(media);
+			if(mediaDir != null && mediaDir.exists()) {
+				File[] attachmentArr = mediaDir.listFiles(new SystemFileFilter(true, false));
+				attachments = Arrays.asList(attachmentArr);
+			}
+		}
+		super.exportContent(media, null, attachments, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/fo/restapi/ForumCourseNodeWebService.java b/src/main/java/org/olat/modules/fo/restapi/ForumCourseNodeWebService.java
index 34d5202c0b1f3242976a2b90ab0de1281aa2f014..cf11317ed7526fe2e6fcc924b3e0ce49a264cd14 100644
--- a/src/main/java/org/olat/modules/fo/restapi/ForumCourseNodeWebService.java
+++ b/src/main/java/org/olat/modules/fo/restapi/ForumCourseNodeWebService.java
@@ -53,6 +53,7 @@ import javax.ws.rs.core.Response.Status;
 
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.services.notifications.NotificationsManager;
 import org.olat.core.commons.services.notifications.Subscriber;
 import org.olat.core.gui.UserRequest;
@@ -388,7 +389,7 @@ public class ForumCourseNodeWebService extends AbstractCourseNodeWebService {
 		CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
 		Property forumKeyProp = cpm.findCourseNodeProperty(courseNode, null, null, FOCourseNode.FORUM_KEY);
 		Forum forum = null;
-		ForumManager fom = ForumManager.getInstance();
+		ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 		if(forumKeyProp!=null) {
       // Forum does already exist, load forum with key from properties
 		  Long forumKey = forumKeyProp.getLongValue();
@@ -455,7 +456,7 @@ public class ForumCourseNodeWebService extends AbstractCourseNodeWebService {
 		@Override
 		public void configure(ICourse course, CourseNode newNode, ModuleConfiguration moduleConfig) {
 			// create the forum
-			ForumManager fom = ForumManager.getInstance();
+			ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 			CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
 			Forum forum = fom.addAForum();
 			Long forumKey = forum.getKey();
diff --git a/src/main/java/org/olat/modules/fo/restapi/ForumImportWebService.java b/src/main/java/org/olat/modules/fo/restapi/ForumImportWebService.java
index d15989eed7a3109ffb464b356b846076a40d5fb6..e042b1b776502d0dcf90128b01b6b798a36ba62f 100644
--- a/src/main/java/org/olat/modules/fo/restapi/ForumImportWebService.java
+++ b/src/main/java/org/olat/modules/fo/restapi/ForumImportWebService.java
@@ -27,6 +27,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.manager.ForumManager;
 
@@ -65,7 +66,7 @@ public class ForumImportWebService {
 	 */
 	@Path("{forumKey}")
 	public ForumWebService getForumWebservice(@PathParam("forumKey") Long forumKey) {
-		ForumManager fom = ForumManager.getInstance();
+		ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 		Forum forum = fom.loadForum(forumKey);
 		return new ForumWebService(forum);
 	}
diff --git a/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java b/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java
index 484c84d8e149dd66fa4f7a02e15940a0d408bcbf..d621a1535b79152b404f6343472a0a9486a129b6 100644
--- a/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java
+++ b/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java
@@ -60,6 +60,7 @@ import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -100,10 +101,11 @@ public class ForumWebService {
 	}
 	
 	private final Forum forum;
-	private final ForumManager fom = ForumManager.getInstance();
+	private final ForumManager fom;
 	
 	public ForumWebService(Forum forum) {
 		this.forum = forum;
+		fom = CoreSpringFactory.getImpl(ForumManager.class);
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/modules/portfolio/MediaHandler.java b/src/main/java/org/olat/modules/portfolio/MediaHandler.java
index 8f6f4c9569f34b08755c7d71ff06677a2fc3f6e4..32200a10842d4bc380e371a0446b3bd9f2cfbf2b 100644
--- a/src/main/java/org/olat/modules/portfolio/MediaHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/MediaHandler.java
@@ -20,6 +20,9 @@
  */
 package org.olat.modules.portfolio;
 
+import java.io.File;
+import java.util.Locale;
+
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
@@ -27,6 +30,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 
 /**
  * 
@@ -57,5 +61,15 @@ public interface MediaHandler {
 	public Controller getMediaController(UserRequest ureq, WindowControl wControl, Media media, MediaRenderingHints hints);
 	
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media);
+	
+	/**
+	 * Export the user data.
+	 * 
+	 * @param identity The identity
+	 * @param manifest A manifest for all the files added to the archive
+	 * @param archiveDirectory The directory where the files can be safely saved.
+	 * @param locale The language
+	 */
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale);
 
 }
diff --git a/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java b/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java
index 382328b871439baa5f34a447b0fa1aded8e03ffe..cee0e8ab9ed618fbea99b4f7817462e60fb857ef 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/AbstractMediaHandler.java
@@ -19,9 +19,32 @@
  */
 package org.olat.modules.portfolio.handler;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Locale;
+
+import org.olat.core.gui.DefaultGlobalSettings;
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.render.EmptyURLBuilder;
+import org.olat.core.gui.render.RenderResult;
+import org.olat.core.gui.render.Renderer;
+import org.olat.core.gui.render.StringOutput;
+import org.olat.core.gui.render.velocity.VelocityRenderDecorator;
+import org.olat.core.gui.translator.Translator;
+import org.olat.core.gui.util.SyntheticUserRequest;
+import org.olat.core.gui.util.WindowControlMocker;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.FileUtils;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.Util;
 import org.olat.modules.portfolio.Media;
 import org.olat.modules.portfolio.MediaHandler;
 import org.olat.modules.portfolio.MediaInformations;
@@ -29,6 +52,8 @@ import org.olat.modules.portfolio.MediaLight;
 import org.olat.modules.portfolio.MediaRenderingHints;
 import org.olat.modules.portfolio.model.MediaPart;
 import org.olat.modules.portfolio.model.StandardMediaRenderingHints;
+import org.olat.modules.portfolio.ui.MediaCenterController;
+import org.olat.modules.portfolio.ui.MediaMetadataController;
 import org.olat.modules.portfolio.ui.editor.PageElement;
 import org.olat.modules.portfolio.ui.editor.PageElementHandler;
 import org.olat.modules.portfolio.ui.editor.PageElementRenderingHints;
@@ -43,6 +68,8 @@ import org.olat.modules.portfolio.ui.editor.PageRunElement;
  */
 public abstract class AbstractMediaHandler implements MediaHandler, PageElementHandler {
 	
+	private static final OLog log = Tracing.createLoggerFor(AbstractMediaHandler.class);
+	
 	private final String type;
 	
 	public AbstractMediaHandler(String type) {
@@ -83,6 +110,64 @@ public abstract class AbstractMediaHandler implements MediaHandler, PageElementH
 		return null;
 	}
 
+	/**
+	 * A utility method to export media with content or a content component. The
+	 * attached files are added to the output as a list of links.
+	 * 
+	 * 
+	 * @param media The media to export
+	 * @param contentCmp Optional, if not present with simply print the content of the media
+	 * @param attachments Optional, a list of document to be attached to the media
+	 * @param mediaArchiveDirectory The directory where all the medias are exported
+	 * @param locale The language
+	 */
+	protected void exportContent(Media media, Component contentCmp, List<File> attachments, File mediaArchiveDirectory, Locale locale) {
+		String title = StringHelper.transformDisplayNameToFileSystemName(media.getTitle());
+		File mediaFile = new File(mediaArchiveDirectory, media.getKey() + "_" + title + ".html");
+		try(OutputStream out = new FileOutputStream(mediaFile)) {
+			String content = exportContent(media, contentCmp, attachments, locale);
+			out.write(content.getBytes("UTF-8"));
+			out.flush();
+		} catch(IOException e) {
+			log.error("", e);
+		}
+		
+		if(attachments != null && !attachments.isEmpty()) {
+			File attachmentsDir = new File(mediaArchiveDirectory, media.getKey().toString());
+			attachmentsDir.mkdir();
+			for(File attachment:attachments) {
+				FileUtils.copyFileToDir(attachment, attachmentsDir, false, "Copy media artfacts");
+			}
+		}
+	}
+
+	private String exportContent(Media media, Component contentCmp, List<File> attachments, Locale locale) {
+		StringOutput sb = new StringOutput(10000);
+		Translator translator = Util.createPackageTranslator(MediaCenterController.class, locale);
+		String pagePath = Util.getPackageVelocityRoot(AbstractMediaHandler.class) + "/export_content.html";
+		VelocityContainer component = new VelocityContainer("html", pagePath, translator, null);
+		component.contextPut("media", media);
+		if(contentCmp != null) {
+			component.put("contentCmp", contentCmp);
+		} else {
+			component.contextPut("content", media.getContent());
+		}
+		component.contextPut("attachments", attachments);
+		
+		SyntheticUserRequest ureq = new SyntheticUserRequest(null, locale);
+		MediaMetadataController metadata = new MediaMetadataController(ureq, new WindowControlMocker(), media);
+		component.put("metadata", metadata.getInitialComponent());
+		
+		Renderer renderer = Renderer.getInstance(component, translator, new EmptyURLBuilder(), new RenderResult(), new DefaultGlobalSettings());
+		try(VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, component, sb)) {
+			component.contextPut("r", vrdec);
+			renderer.render(sb, component, null);
+		} catch(IOException e) {
+			log.error("", e);
+		}
+		return sb.toString();
+	}
+
 	public final class Informations implements MediaInformations {
 		
 		private final String title;
diff --git a/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java b/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java
index 34915d42b7a6d41f542a24b0a5d581b1e453396e..ddc214ddab2f3ecde0649a7ae88fd8a51f8d76b8 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/CitationHandler.java
@@ -19,6 +19,9 @@
  */
 package org.olat.modules.portfolio.handler;
 
+import java.io.File;
+import java.util.Locale;
+
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
@@ -37,6 +40,7 @@ import org.olat.modules.portfolio.ui.editor.PageElementAddController;
 import org.olat.modules.portfolio.ui.media.CitationMediaController;
 import org.olat.modules.portfolio.ui.media.CollectCitationMediaController;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -106,4 +110,9 @@ public class CitationHandler extends AbstractMediaHandler implements Interactive
 	public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) {
 		return new CollectCitationMediaController(ureq, wControl);
 	}
+
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		super.exportContent(media, null, null, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
index b34adbd5d7323d80570fd41d4a75a48e5c875037..35542bea2c056cc18555dfd47cbb886d90be0c07 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/FileHandler.java
@@ -20,6 +20,9 @@
 package org.olat.modules.portfolio.handler;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
 
 import org.olat.core.commons.modules.bc.meta.MetaInfo;
 import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged;
@@ -51,6 +54,7 @@ import org.olat.modules.portfolio.ui.media.UploadMedia;
 import org.olat.portfolio.manager.EPFrontendManager;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
 import org.olat.portfolio.model.artefacts.FileArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -198,4 +202,14 @@ public class FileHandler extends AbstractMediaHandler implements InteractiveAddP
 	public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) {
 		return new CollectFileMediaController(ureq, wControl);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		List<File> files = new ArrayList<>();
+		if(StringHelper.containsNonWhitespace(media.getStoragePath()) && StringHelper.containsNonWhitespace(media.getRootFilename())) {
+			File mediaDir = fileStorage.getMediaDirectory(media);
+			files.add(new File(mediaDir, media.getRootFilename()));
+		}
+		super.exportContent(media, null, files, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
index 242f8b146ec6d81b73de968d431faaf12824c622..d1153c681544ec8727557b6eafb702a7d014d067 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/ImageHandler.java
@@ -20,7 +20,10 @@
 package org.olat.modules.portfolio.handler;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 
 import org.olat.core.commons.modules.bc.meta.MetaInfo;
@@ -50,6 +53,7 @@ import org.olat.modules.portfolio.ui.media.CollectImageMediaController;
 import org.olat.modules.portfolio.ui.media.ImageMediaController;
 import org.olat.modules.portfolio.ui.media.UploadMedia;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -176,4 +180,12 @@ public class ImageHandler extends AbstractMediaHandler implements InteractiveAdd
 	public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) {
 		return new CollectImageMediaController(ureq, wControl);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		List<File> images = new ArrayList<>();
+		File mediaDir = fileStorage.getMediaDirectory(media);
+		images.add(new File(mediaDir, media.getRootFilename()));
+		super.exportContent(media, null, images, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
index 4905cea59761c9ad754b89b01a3202975d34f620..9f4608b6889dfec5a2d4024950c1fff4348144bf 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/TextHandler.java
@@ -19,6 +19,9 @@
  */
 package org.olat.modules.portfolio.handler;
 
+import java.io.File;
+import java.util.Locale;
+
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
@@ -37,6 +40,7 @@ import org.olat.modules.portfolio.ui.media.CollectTextMediaController;
 import org.olat.modules.portfolio.ui.media.TextMediaController;
 import org.olat.portfolio.manager.EPFrontendManager;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -117,6 +121,11 @@ public class TextHandler extends AbstractMediaHandler {
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new CollectTextMediaController(ureq, wControl, media);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		super.exportContent(media, null, null, mediaArchiveDirectory, locale);
+	}
 
 	/*@Override
 	public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) {
diff --git a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java
index 39a4b58bf78790251d086928f74eecd1d9cd1d84..dff7b8d01c46921ae08e03b8c2378713ca00d829 100644
--- a/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java
+++ b/src/main/java/org/olat/modules/portfolio/handler/VideoHandler.java
@@ -20,7 +20,10 @@
 package org.olat.modules.portfolio.handler;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 
 import org.olat.core.commons.modules.bc.meta.MetaInfo;
@@ -50,6 +53,7 @@ import org.olat.modules.portfolio.ui.media.CollectVideoMediaController;
 import org.olat.modules.portfolio.ui.media.UploadMedia;
 import org.olat.modules.portfolio.ui.media.VideoMediaController;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -173,4 +177,12 @@ public class VideoHandler extends AbstractMediaHandler implements InteractiveAdd
 	public PageElementAddController getAddPageElementController(UserRequest ureq, WindowControl wControl) {
 		return new CollectVideoMediaController(ureq, wControl);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		List<File> videos = new ArrayList<>();
+		File mediaDir = fileStorage.getMediaDirectory(media);
+		videos.add(new File(mediaDir, media.getRootFilename()));
+		super.exportContent(media, null, videos, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html b/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html
new file mode 100644
index 0000000000000000000000000000000000000000..00ba3ddcb97ef481a9804adf3484acd5e14ead50
--- /dev/null
+++ b/src/main/java/org/olat/modules/portfolio/handler/_content/export_content.html
@@ -0,0 +1,33 @@
+<html>
+	<head>
+		<title>$r.escapeHtml($media.title)</title>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	</head>
+	<body>
+		<fieldset>
+			<legend>$r.translate("metadata.title")</legend>
+			$r.render("metadata")
+		</fieldset>
+		<fieldset>
+			<legend>$r.translate("content.title")</legend>
+			#if($r.available("contentCmp"))
+			<div>$r.render("contentCmp")</div>
+			#else
+			<div>$media.content</div>
+			#end
+			#if($r.isNotEmpty($attachments))
+			<div class="o_attachments">
+				<h5>$r.translate("attachments"):</h5>
+				<ul class="list-inline">
+				#foreach($attachment in $attachments)
+					#set($fname = $attachment.getName())
+					<li class="o_attachment">
+						<a href="${media.key}/${fname}" target="_blank"><span class="o_filename">$r.escapeHtml($fname)</span></a>		
+					</li>
+				#end 
+				</ul>
+			</div>
+			#end
+		</fieldset>
+	</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java
index 845c4fc286bc7c1e31a4f50dbb20043bf28253ed..77930423ffca5ede45022228d3ea5fa6fab5daf5 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioFileStorage.java
@@ -149,6 +149,10 @@ public class PortfolioFileStorage implements InitializingBean {
 		return null;
 	}
 	
+	public File getMediaDirectory(MediaLight media) {
+		return new File(FolderConfig.getCanonicalRoot(), media.getStoragePath());
+	}
+	
 	public VFSContainer getMediaContainer(MediaLight media) {
 		return new OlatRootFolderImpl("/" + media.getStoragePath(), null);
 	}
diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java
index 9e533458874b307f627aaf96b3f7d5bed6de9405..5e36df4bb2c036c1b3f77d120d89cef0f96e0281 100644
--- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java
+++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioUserDataManager.java
@@ -21,6 +21,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.DeletableGroupData;
 import org.olat.modules.portfolio.Binder;
 import org.olat.modules.portfolio.Media;
+import org.olat.modules.portfolio.MediaHandler;
 import org.olat.modules.portfolio.PortfolioRoles;
 import org.olat.modules.portfolio.PortfolioService;
 import org.olat.modules.portfolio.model.BinderImpl;
@@ -111,10 +112,29 @@ public class PortfolioUserDataManager implements DeletableGroupData, UserDataDel
 	@Override
 	public void export(Identity identity, ManifestBuilder manifest, File archiveDirectory, Locale locale) {
 		File portfolioArchive = new File(archiveDirectory, "Portfolios");
-		portfolioArchive.mkdirs();
+		portfolioArchive.mkdir();
+		exportBinders(identity, portfolioArchive, locale);
+		exportMedias(identity, manifest, portfolioArchive, locale);
+	}
+	
+	private void exportMedias(Identity identity, ManifestBuilder manifest, File portfolioArchive, Locale locale) {
+		File mediasArchive = new File(portfolioArchive, "Media");
+		mediasArchive.mkdir();
+		
+		List<Media> medias = mediaDao.load(identity);
+		dbInstance.commitAndCloseSession();
+		for(Media media:medias) {
+			MediaHandler handler = portfolioService.getMediaHandler(media.getType());
+			handler.export(media, manifest, mediasArchive, locale);
+		}
+	}
+	
+	private void exportBinders(Identity identity, File portfolioArchive, Locale locale) {
+		File bindersArchive = new File(portfolioArchive, "Binders");
+		bindersArchive.mkdir();
 		List<Binder> binders = binderDao.getOwnedBinders(identity);
 		for(Binder binder:binders) {
-			exportBinder(binder, identity, portfolioArchive, locale);
+			exportBinder(binder, identity, bindersArchive, locale);
 		}
 	}
 	
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
index 8f7634c770b8c1c245a518bfddefc3a10a99ec99..802a952a5c9a6df5bd47838842bc596fa54c62bd 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties
@@ -58,6 +58,7 @@ assignment.type=Typ
 assignment.type.document=Dokument
 assignment.type.essay=Freitext
 assignment.type.form=Fragebogen
+attachments=Dokumenten
 attachments.error.file.exists=Diese Datei existiert bereits und kann nicht erneut hochgeladen werden.
 attachments.upload.successful=Die Datei {0} wurde erfolgreich hochgeladen. Bei Bedarf k\u00F6nnen noch weitere Dateien angeh\u00E4ngt werden.
 author=Autor
@@ -95,6 +96,7 @@ compare.evaluations=Auswertung
 confirmation=Best\u00E4tigung
 confirm.close.page=Wollen Sie diesen Eintrag abschliessen? Der Eintrag wird f\u00FCr den Lernenden anschliessend als abgeschlossen angezeigt.
 confirm.close.page.other.coaches=Die folgende Personen haben auch Zugriff auf diesen Eintrag:
+content.title=Inhalt
 create.binder=Mappe erstellen
 create.empty.binder=Leere Mappe erstellen
 create.empty.binder.from.course=Mappe f\u00FCr Portfolioaufgabe aus Kurs erstellen
@@ -222,6 +224,7 @@ meta.page.assignment=Hier ist eine Aufgabe.
 meta.page.assignment.type=Typ
 meta.section.assignments=<strong>Aufgabe</strong> in diesem Bereich
 meta.section.categories=<strong>Kategorien</strong> in diesem Bereich
+metadata.title=Metadaten
 mf.creator=Autor
 mf.edition=Auflage
 mf.editor=Verlag
diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
index 285340b6eefe4a8b9c351152b3b54aa457449647..410a41eaf058c61a862363733e74a3897a1c9a0a 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties
@@ -58,6 +58,7 @@ assignment.type=Type
 assignment.type.document=Document
 assignment.type.essay=Essay
 assignment.type.form=Survey
+attachments=Documents
 attachments.error.file.exists=This file already exists and can therefore not be uploaded again.
 attachments.upload.successful=File {0} successfully uploaded. Other files can still be attached if needed.
 author=Author
@@ -95,6 +96,7 @@ compare.evaluations=Evaluation
 confirm.close.page=Do you really want to close this entry? The entry will be marked as closed for the trainee.
 confirm.close.page.other.coaches=The following persons also have access to this entry\:
 confirmation=Confirmation
+content.title=Content
 create.binder=Create binder
 create.empty.binder=New empty binder
 create.empty.binder.from.course=New binder from course portfolio task
@@ -222,6 +224,7 @@ meta.page.assignment=This is an assignment
 meta.page.assignment.type=Type
 meta.section.assignments=<strong>Assignments</strong> in this section
 meta.section.categories=<strong>Categories</strong> in this section
+metadata.title=Metadata
 mf.creator=Author
 mf.edition=Edition
 mf.editor=Editor
diff --git a/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsCPResource.java b/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsCPResource.java
index 9ff9848763fbbce32dec3c065b3b86668fc99e9a..292664baa77dfe5cabcffb1eec495c7b6e5d3bd6 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsCPResource.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsCPResource.java
@@ -47,12 +47,11 @@ import org.olat.core.commons.services.commentAndRating.ui.UserCommentsController
 import org.olat.core.dispatcher.DispatcherModule;
 import org.olat.core.dispatcher.mapper.Mapper;
 import org.olat.core.dispatcher.mapper.MapperService;
-import org.olat.core.gui.GlobalSettings;
+import org.olat.core.gui.DefaultGlobalSettings;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.WindowControl;
-import org.olat.core.gui.control.winmgr.AJAXFlags;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.render.RenderResult;
 import org.olat.core.gui.render.Renderer;
@@ -375,7 +374,7 @@ public class ExportBinderAsCPResource implements MediaResource {
 	private String renderVelocityContainer(VelocityContainer mainVC) {
 		StringOutput sb = new StringOutput(32000);
 		URLBuilder ubu = new URLBuilder("auth", "1", "0");
-		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new EmptyGlobalSettings());
+		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new DefaultGlobalSettings());
 		VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, mainVC, sb);
 		mainVC.contextPut("r", vrdec);
 		renderer.render(sb, mainVC, null);
@@ -535,35 +534,6 @@ public class ExportBinderAsCPResource implements MediaResource {
 		}
 	}
 	
-	private static class EmptyGlobalSettings implements GlobalSettings {
-		@Override
-		public int getFontSize() {
-			return 100;
-		}
-		
-		@Override
-		public AJAXFlags getAjaxFlags() {
-			return new EmptyAJAXFlags();
-		}
-		
-		@Override
-		public boolean isIdDivsForced() {
-			return false;
-		}
-	};
-	
-	private static class EmptyAJAXFlags extends AJAXFlags {
-		
-		public EmptyAJAXFlags() {
-			super(null);
-		}
-		
-		@Override
-		public boolean isIframePostEnabled() {
-			return false;
-		}
-	}
-	
 	private class PortfolioPageProvider implements PageProvider {
 		
 		private final List<PageElementHandler> handlers = new ArrayList<>();
diff --git a/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsPDFResource.java b/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsPDFResource.java
index 6ab3ff44b91823ce9f0b0ef9139618aae607ed78..46af8f17b1b85a5f42cf8ee4023837e611ceb669 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsPDFResource.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/export/ExportBinderAsPDFResource.java
@@ -40,12 +40,11 @@ import org.olat.core.CoreSpringFactory;
 import org.olat.core.dispatcher.DispatcherModule;
 import org.olat.core.dispatcher.mapper.Mapper;
 import org.olat.core.dispatcher.mapper.MapperService;
-import org.olat.core.gui.GlobalSettings;
+import org.olat.core.gui.DefaultGlobalSettings;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.WindowControl;
-import org.olat.core.gui.control.winmgr.AJAXFlags;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.render.RenderResult;
 import org.olat.core.gui.render.Renderer;
@@ -225,7 +224,7 @@ public class ExportBinderAsPDFResource implements MediaResource {
 		
 		StringOutput sb = new StringOutput(32000);
 		URLBuilder ubu = new URLBuilder("auth", "1", "0");
-		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new EmptyGlobalSettings());
+		Renderer renderer = Renderer.getInstance(mainVC, translator, ubu, new RenderResult(), new DefaultGlobalSettings());
 		VelocityRenderDecorator vrdec = new VelocityRenderDecorator(renderer, mainVC, sb);
 		mainVC.contextPut("r", vrdec);
 		renderer.render(sb, mainVC, null);
@@ -369,33 +368,4 @@ public class ExportBinderAsPDFResource implements MediaResource {
 			return cleanedSrc;
 		}
 	}
-	
-	private static class EmptyGlobalSettings implements GlobalSettings {
-		@Override
-		public int getFontSize() {
-			return 100;
-		}
-		
-		@Override
-		public AJAXFlags getAjaxFlags() {
-			return new EmptyAJAXFlags();
-		}
-		
-		@Override
-		public boolean isIdDivsForced() {
-			return false;
-		}
-	};
-	
-	private static class EmptyAJAXFlags extends AJAXFlags {
-		
-		public EmptyAJAXFlags() {
-			super(null);
-		}
-		
-		@Override
-		public boolean isIframePostEnabled() {
-			return false;
-		}
-	}
 }
diff --git a/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java b/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java
index 818cf51486458c978734bb22977ea1090adcd1e7..256626beb33d2ebe13bf311cf548584a0a75c9a8 100644
--- a/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java
+++ b/src/main/java/org/olat/modules/portfolio/ui/wizard/CollectArtefactController.java
@@ -128,8 +128,12 @@ public class CollectArtefactController extends FormBasicController {
 			//TODO
 		}
 
-		List<String> updatedCategories = categoriesEl.getValueList();
-		portfolioService.updateCategories(mediaReference, updatedCategories);
+		if(mediaReference != null) {
+			List<String> updatedCategories = categoriesEl.getValueList();
+			portfolioService.updateCategories(mediaReference, updatedCategories);
+		} else {
+			showError("ERROR");
+		}
 		
 		fireEvent(ureq, Event.DONE_EVENT);
 	}
diff --git a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
index 10d1a8983219d2cdc8945c97a29042af00121493..be3c2b7fbb9ed18094acb343ab89435055a1f95b 100644
--- a/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
+++ b/src/main/java/org/olat/modules/webFeed/portfolio/BlogEntryMediaHandler.java
@@ -20,6 +20,10 @@
 package org.olat.modules.webFeed.portfolio;
 
 import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
 
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
@@ -27,6 +31,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
+import org.olat.core.util.io.SystemFileFilter;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.core.util.vfs.VFSManager;
@@ -44,6 +49,7 @@ import org.olat.modules.webFeed.Item;
 import org.olat.modules.webFeed.manager.FeedManager;
 import org.olat.portfolio.manager.EPFrontendManager;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -148,4 +154,12 @@ public class BlogEntryMediaHandler extends AbstractMediaHandler {
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new StandardEditMediaController(ureq, wControl, media);
 	}
+	
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		File mediaDir = fileStorage.getMediaDirectory(media);
+		File[] files = mediaDir.listFiles(new SystemFileFilter(true, false));
+		List<File> attachments = files == null ? Collections.emptyList() : Arrays.asList(files);
+		super.exportContent(media, null, attachments, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/modules/wiki/WikiMainController.java b/src/main/java/org/olat/modules/wiki/WikiMainController.java
index a05e18921bc352cd4fe1e5eed89c995387f261c9..9c1fbff17bbedad2c4ab4b7aeb1d80419b3538d6 100644
--- a/src/main/java/org/olat/modules/wiki/WikiMainController.java
+++ b/src/main/java/org/olat/modules/wiki/WikiMainController.java
@@ -189,6 +189,8 @@ public class WikiMainController extends BasicController implements CloneableCont
 	private WikiMediaHandler wikiMediaHandler;
 	@Autowired
 	private PortfolioV2Module portfolioModule;
+	@Autowired
+	private ForumManager forumManager;
 
 	public WikiMainController(UserRequest ureq, WindowControl wControl, OLATResourceable ores,
 			WikiSecurityCallback securityCallback, String initialPageName) {
@@ -672,10 +674,10 @@ public class WikiMainController extends BasicController implements CloneableCont
 			 **********************************************************************/
 			Forum forum = null;
 			if (page.getForumKey() > 0) {
-				forum = ForumManager.getInstance().loadForum(Long.valueOf(page.getForumKey()));
+				forum = forumManager.loadForum(Long.valueOf(page.getForumKey()));
 			}
 			if (forum == null) {
-				forum = ForumManager.getInstance().addAForum();
+				forum = forumManager.addAForum();
 				page.setForumKey(forum.getKey().longValue());
 				WikiManager.getInstance().updateWikiPageProperties(ores, page);
 			}
diff --git a/src/main/java/org/olat/modules/wiki/WikiPageChangeOrCreateNotificationHandler.java b/src/main/java/org/olat/modules/wiki/WikiPageChangeOrCreateNotificationHandler.java
index 5083eba944717883e6e5cec7d1fa80df09e3d8e4..2642172fea7c29c57cd38269e154213c50c2287f 100644
--- a/src/main/java/org/olat/modules/wiki/WikiPageChangeOrCreateNotificationHandler.java
+++ b/src/main/java/org/olat/modules/wiki/WikiPageChangeOrCreateNotificationHandler.java
@@ -171,7 +171,7 @@ public class WikiPageChangeOrCreateNotificationHandler implements NotificationsH
 					}
 					
 					long forumKey = element.getForumKey();
-					List<Message> mInfos = ForumManager.getInstance().getNewMessageInfo(forumKey, compareDate);
+					List<Message> mInfos = CoreSpringFactory.getImpl(ForumManager.class).getNewMessageInfo(forumKey, compareDate);
 					
 					for (Message mInfo : mInfos) {
 						String messageTitle = mInfo.getTitle();
diff --git a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
index b2cdead0e0b48b14565fd202177e8d4bd373bfb2..b0ec4c86ae89ee95addbdc06e6fb54024b09e5b5 100644
--- a/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
+++ b/src/main/java/org/olat/modules/wiki/portfolio/WikiMediaHandler.java
@@ -21,6 +21,9 @@
  */
 package org.olat.modules.wiki.portfolio;
 
+import java.io.File;
+import java.util.Locale;
+
 import org.olat.core.commons.services.image.Size;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
@@ -39,6 +42,7 @@ import org.olat.modules.portfolio.manager.MediaDAO;
 import org.olat.modules.portfolio.ui.media.StandardEditMediaController;
 import org.olat.modules.wiki.WikiPage;
 import org.olat.portfolio.model.artefacts.AbstractArtefact;
+import org.olat.user.manager.ManifestBuilder;
 import org.olat.util.logging.activity.LoggingResourceable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -124,4 +128,9 @@ public class WikiMediaHandler extends AbstractMediaHandler {
 	public Controller getEditMediaController(UserRequest ureq, WindowControl wControl, Media media) {
 		return new StandardEditMediaController(ureq, wControl, media);
 	}
+
+	@Override
+	public void export(Media media, ManifestBuilder manifest, File mediaArchiveDirectory, Locale locale) {
+		super.exportContent(media, null, null, mediaArchiveDirectory, locale);
+	}
 }
diff --git a/src/main/java/org/olat/search/service/indexer/ForumIndexer.java b/src/main/java/org/olat/search/service/indexer/ForumIndexer.java
index 47b6c1b25e146b35431772a777c76acc6882f4fe..bacc1bd6ebddf47d8fc0646a4e9ef1d40665cc08 100644
--- a/src/main/java/org/olat/search/service/indexer/ForumIndexer.java
+++ b/src/main/java/org/olat/search/service/indexer/ForumIndexer.java
@@ -30,6 +30,7 @@ import java.io.IOException;
 import java.util.List;
 
 import org.apache.lucene.document.Document;
+import org.olat.core.CoreSpringFactory;
 import org.olat.modules.fo.Forum;
 import org.olat.modules.fo.Message;
 import org.olat.modules.fo.manager.ForumManager;
@@ -48,7 +49,7 @@ public abstract class ForumIndexer extends AbstractHierarchicalIndexer {
 			return;
 		}
 		// loop over all messages of a forum
-		List<Message> messages = ForumManager.getInstance().getMessagesByForum(forum);
+		List<Message> messages = CoreSpringFactory.getImpl(ForumManager.class).getMessagesByForum(forum);
 		for(Message message : messages) {
 			SearchResourceContext searchResourceContext = new SearchResourceContext(parentResourceContext);
 			searchResourceContext.setBusinessControlFor(message);
diff --git a/src/main/java/org/olat/search/service/indexer/group/GroupForumIndexer.java b/src/main/java/org/olat/search/service/indexer/group/GroupForumIndexer.java
index def85f66783bcde0414b2f83918aefc8efe1b651..a048dc415c7e4884f5700c73dbad78555498de92 100644
--- a/src/main/java/org/olat/search/service/indexer/group/GroupForumIndexer.java
+++ b/src/main/java/org/olat/search/service/indexer/group/GroupForumIndexer.java
@@ -29,6 +29,7 @@ package org.olat.search.service.indexer.group;
 import java.io.IOException;
 
 import org.olat.collaboration.CollaborationTools;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
 import org.olat.core.id.context.BusinessControl;
@@ -71,7 +72,7 @@ public class GroupForumIndexer extends ForumIndexer{
 		BusinessGroup businessGroup = (BusinessGroup)businessObj;
 		
 		NarrowedPropertyManager npm = NarrowedPropertyManager.getInstance(businessGroup);
-		ForumManager fom = ForumManager.getInstance();
+		ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 
 		Property forumKeyProperty = npm.findProperty(null, null, CollaborationTools.PROP_CAT_BG_COLLABTOOLS, CollaborationTools.KEY_FORUM);
 		// Check if forum-property exist
@@ -100,7 +101,7 @@ public class GroupForumIndexer extends ForumIndexer{
 	public boolean checkAccess(ContextEntry contextEntry, BusinessControl businessControl, Identity identity, Roles roles) {
 		ContextEntry ce = businessControl.popLauncherContextEntry();
 		Long resourceableId = ce.getOLATResourceable().getResourceableId();
-		Message message = ForumManager.getInstance().loadMessage(resourceableId);
+		Message message = CoreSpringFactory.getImpl(ForumManager.class).loadMessage(resourceableId);
 		if(message == null)  return false;
 
 		Message threadtop = message.getThreadtop();
diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java
index 841148f613c8debd9d521f56465c51f32563761f..71a18f2e022d4d6e261648d536f78f75a9f29034 100644
--- a/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java
+++ b/src/main/java/org/olat/search/service/indexer/repository/course/DialogCourseNodeIndexer.java
@@ -128,7 +128,7 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod
 
 	private void doIndexAllMessages(SearchResourceContext parentResourceContext, Forum forum, OlatFullIndexer indexWriter) throws IOException,InterruptedException {
 		// loop over all messages of a forum
-		List<Message> messages = ForumManager.getInstance().getMessagesByForum(forum);
+		List<Message> messages = CoreSpringFactory.getImpl(ForumManager.class).getMessagesByForum(forum);
 		for(Message message:messages){
 			SearchResourceContext searchResourceContext = new SearchResourceContext(parentResourceContext);
 			searchResourceContext.setBusinessControlFor(message);
@@ -158,7 +158,7 @@ public class DialogCourseNodeIndexer extends DefaultIndexer implements CourseNod
 		} else if (ores.getResourceableTypeName().equals(OresHelper.calculateTypeName(Message.class))) {
 			// it is message => check message access
 			Long resourceableId = ores.getResourceableId();
-			Message message = ForumManager.getInstance().loadMessage(resourceableId);
+			Message message = CoreSpringFactory.getImpl(ForumManager.class).loadMessage(resourceableId);
 			Message threadtop = message.getThreadtop();
 			if(threadtop==null) {
 				threadtop = message;
diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java
index 5e22112801d3347666868cc6e69dea498f1a7fa0..b79f30529b8b1ddc8e2925d205e79c684b1c40ae 100644
--- a/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java
+++ b/src/main/java/org/olat/search/service/indexer/repository/course/FOCourseNodeIndexer.java
@@ -28,6 +28,7 @@ package org.olat.search.service.indexer.repository.course;
 import java.io.IOException;
 
 import org.apache.lucene.document.Document;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
 import org.olat.core.id.context.BusinessControl;
@@ -86,7 +87,7 @@ public class FOCourseNodeIndexer extends ForumIndexer implements CourseNodeIndex
 		}
 		
 		Long resourceableId = ce.getOLATResourceable().getResourceableId();
-		Message message = ForumManager.getInstance().loadMessage(resourceableId);
+		Message message = CoreSpringFactory.getImpl(ForumManager.class).loadMessage(resourceableId);
 		if(message != null) {
 			Message threadtop = message.getThreadtop();
 			if(threadtop == null) {
@@ -112,7 +113,7 @@ public class FOCourseNodeIndexer extends ForumIndexer implements CourseNodeIndex
 	 */
 	private void doIndexForum(SearchResourceContext parentResourceContext, ICourse course, CourseNode courseNode, OlatFullIndexer indexWriter) throws IOException,InterruptedException  {
 		if (log.isDebug()) log.debug("Index Course Forum...");
-		ForumManager fom = ForumManager.getInstance();
+		ForumManager fom = CoreSpringFactory.getImpl(ForumManager.class);
 		CoursePropertyManager cpm = course.getCourseEnvironment().getCoursePropertyManager();
 
 		Property forumKeyProperty = cpm.findCourseNodeProperty(courseNode, null, null, FOCourseNode.FORUM_KEY);
diff --git a/src/main/java/org/olat/user/manager/UserDataExportTask.java b/src/main/java/org/olat/user/manager/UserDataExportTask.java
index 0bdc9e8e4490b9042fdf6614baebf9ca56e668e4..e72860883080806ca778beff7c017a323b62ea83 100644
--- a/src/main/java/org/olat/user/manager/UserDataExportTask.java
+++ b/src/main/java/org/olat/user/manager/UserDataExportTask.java
@@ -20,6 +20,7 @@
 package org.olat.user.manager;
 
 import org.olat.core.CoreSpringFactory;
+import org.olat.core.commons.services.taskexecutor.LongRunnable;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.user.UserDataExportService;
@@ -30,7 +31,7 @@ import org.olat.user.UserDataExportService;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public class UserDataExportTask implements /* Long */ Runnable {
+public class UserDataExportTask implements LongRunnable {
 
 	private static final long serialVersionUID = 6931074116105090545L;
 
diff --git a/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties
index e28608c4d073688e65fb7559c15599ed39559a8e..54789b0ca66ae672eda538f475899e67156879b1 100644
--- a/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_de.properties
@@ -7,8 +7,6 @@ chat=Chat
 disclaimer=Nutzungsbedigung
 display.portrait=Profilbild
 download.data=Dateien herunterladen
-dx=dr
-dy=dr
 efficiency.statements=Leistungnachweise
 export.options=Export Elemente
 export.start=Start export
@@ -20,6 +18,7 @@ export.user.data.processing=Der Export ist gerade bearbeitet.
 export.user.data.ready=Der Benutzer kann den Export mit dem folgenden Link herunterladen. Sie k\u00F6nnen auch ein en neuen Export erfordern.
 export.user.data.ready.subject=Export von "{0}" ist fertig
 export.user.data.ready.text=<p>Export von "{0}" ist fertig. Es konnte unter <a href\="{1}">{1}</a> heruntergeladen werden</p>
+forums=Foren
 group.memberships=Zugeh\u00F6rigkeit zu Gruppen
 mail=Mail
 notes=Pers\u00F6nliche Notizen
diff --git a/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_en.properties
index 860f801c21b97f0131e4ed29c3b6044139f603a5..6236b054fd31aa7d67bf1b3fd4e6940e253e72f9 100644
--- a/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/user/ui/data/_i18n/LocalStrings_en.properties
@@ -13,6 +13,7 @@ efficiency.statements=Evidences of achievement
 export.options=Export elements
 export.start=Start export
 export.url=Link to the data
+forums=Forums
 group.memberships=Membership to groups
 mail=Emails
 notes=Notes
diff --git a/src/main/java/org/olat/util/logging/activity/LoggingResourceable.java b/src/main/java/org/olat/util/logging/activity/LoggingResourceable.java
index 2663cad2f67ebfe1f14049b82e48971e3d924fe0..b8139b7090cd6586d9aed3458d6737d0ba1893c0 100644
--- a/src/main/java/org/olat/util/logging/activity/LoggingResourceable.java
+++ b/src/main/java/org/olat/util/logging/activity/LoggingResourceable.java
@@ -29,6 +29,7 @@ package org.olat.util.logging.activity;
 import java.io.UnsupportedEncodingException;
 
 import org.olat.commons.calendar.model.Kalendar;
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.context.ContextEntry;
@@ -447,7 +448,7 @@ public class LoggingResourceable implements ILoggingResourceable {
 	 * @return a LoggingResourceable wrapping the given Forum
 	 */
 	public static LoggingResourceable wrap(Forum forum) {
-		final String name = ForumManager.getInstance().getForumNameForLogging(forum);
+		final String name = CoreSpringFactory.getImpl(ForumManager.class).getForumNameForLogging(forum);
 		return new LoggingResourceable(forum, OlatResourceableType.forum, forum.getResourceableTypeName(),
 				String.valueOf(forum.getResourceableId()), name, false);
 	}
diff --git a/src/test/java/org/olat/restapi/ForumTest.java b/src/test/java/org/olat/restapi/ForumTest.java
index 6e75f8528afd33025a7c62b40bcf7bcf0b116542..6b73bb8538dc6e65f81ebdcb52b353a8d0447b56 100644
--- a/src/test/java/org/olat/restapi/ForumTest.java
+++ b/src/test/java/org/olat/restapi/ForumTest.java
@@ -216,8 +216,7 @@ public class ForumTest extends OlatJerseyTestCase {
 		
 		//really saved?
 		boolean saved = false;
-		ForumManager fm = ForumManager.getInstance();
-		List<Message> allMessages = fm.getMessagesByForum(forum);
+		List<Message> allMessages = forumManager.getMessagesByForum(forum);
 		for(Message message:allMessages) {
 			if(message.getKey().equals(thread.getKey())) {
 				saved = true;
@@ -249,8 +248,7 @@ public class ForumTest extends OlatJerseyTestCase {
 		
 		//really saved?
 		boolean saved = false;
-		ForumManager fm = ForumManager.getInstance();
-		List<Message> allMessages = fm.getMessagesByForum(forum);
+		List<Message> allMessages = forumManager.getMessagesByForum(forum);
 		for(Message msg:allMessages) {
 			if(msg.getKey().equals(message.getKey())) {
 				saved = true;
@@ -326,8 +324,7 @@ public class ForumTest extends OlatJerseyTestCase {
 		assertEquals(200, attachResponse.getStatusLine().getStatusCode());
 		
 		//check if the file exists
-		ForumManager fm = ForumManager.getInstance();
-		VFSContainer container = fm.getMessageContainer(message.getForumKey(), message.getKey());
+		VFSContainer container = forumManager.getMessageContainer(message.getForumKey(), message.getKey());
 		VFSItem uploadedFile = container.resolve("portrait.jpg");
 		assertNotNull(uploadedFile);
 		assertTrue(uploadedFile instanceof VFSLeaf);
@@ -374,8 +371,7 @@ public class ForumTest extends OlatJerseyTestCase {
 		assertEquals(200, attachCode.getStatusLine().getStatusCode());
 		
 		//check if the file exists
-		ForumManager fm = ForumManager.getInstance();
-		VFSContainer container = fm.getMessageContainer(message.getForumKey(), message.getKey());
+		VFSContainer container = forumManager.getMessageContainer(message.getForumKey(), message.getKey());
 		VFSItem uploadedFile = container.resolve("portrait64.jpg");
 		assertNotNull(uploadedFile);
 		assertTrue(uploadedFile instanceof VFSLeaf);
@@ -439,9 +435,8 @@ public class ForumTest extends OlatJerseyTestCase {
 		}
 		
 		
-		//check if the file exists
-		ForumManager fm = ForumManager.getInstance();
-		VFSContainer container = fm.getMessageContainer(message.getForumKey(), message.getKey());
+		//check if the file existsforumManager
+		VFSContainer container = forumManager.getMessageContainer(message.getForumKey(), message.getKey());
 		VFSItem uploadedFile = container.resolve("portrait64.jpg");
 		assertNotNull(uploadedFile);
 		assertTrue(uploadedFile instanceof VFSLeaf);
@@ -493,8 +488,7 @@ public class ForumTest extends OlatJerseyTestCase {
 		assertEquals(200, attachCode.getStatusLine().getStatusCode());
 		
 		//check if the file exists
-		ForumManager fm = ForumManager.getInstance();
-		VFSContainer container = fm.getMessageContainer(message.getForumKey(), message.getKey());
+		VFSContainer container = forumManager.getMessageContainer(message.getForumKey(), message.getKey());
 		VFSItem uploadedFile = container.resolve("portrait64vo.jpg");
 		assertNotNull(uploadedFile);
 		assertTrue(uploadedFile instanceof VFSLeaf);
diff --git a/src/test/java/org/olat/restapi/GroupMgmtTest.java b/src/test/java/org/olat/restapi/GroupMgmtTest.java
index 127845d0cbdfbab05205a413448ac7eebb34fb88..1785a2e00e7427d104598e7225c100046c7ce141 100644
--- a/src/test/java/org/olat/restapi/GroupMgmtTest.java
+++ b/src/test/java/org/olat/restapi/GroupMgmtTest.java
@@ -61,7 +61,6 @@ import org.olat.basesecurity.OrganisationService;
 import org.olat.collaboration.CollaborationTools;
 import org.olat.collaboration.CollaborationToolsFactory;
 import org.olat.core.commons.persistence.DB;
-import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Organisation;
@@ -112,6 +111,8 @@ public class GroupMgmtTest extends OlatJerseyTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private ForumManager forumManager;
+	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
 	private OrganisationService organisationService;
@@ -174,7 +175,7 @@ public class GroupMgmtTest extends OlatJerseyTestCase {
 		// groups
 		g3 = businessGroupService.createBusinessGroup(null, "rest-g3", null, -1, -1, false, false, c2);
 		g4 = businessGroupService.createBusinessGroup(null, "rest-g4", null, -1, -1, false, false, c2);
-		DBFactory.getInstance().commit();
+		dbInstance.commit();
 		// members
 		businessGroupRelationDao.addRole(owner1, g3, GroupRoles.participant.name());
 		businessGroupRelationDao.addRole(owner2, g4, GroupRoles.participant.name());
@@ -194,42 +195,41 @@ public class GroupMgmtTest extends OlatJerseyTestCase {
 		CollaborationTools collabTools2 = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g2);
 		collabTools2.setToolEnabled(CollaborationTools.TOOL_FORUM, true);
     
-		DBFactory.getInstance().closeSession(); // simulate user clicks
+		dbInstance.closeSession(); // simulate user clicks
     
 		//4) fill forum for g1
 		NarrowedPropertyManager npm = NarrowedPropertyManager.getInstance(g1);
 		Property forumKeyProperty = npm.findProperty(null, null, CollaborationTools.PROP_CAT_BG_COLLABTOOLS, CollaborationTools.KEY_FORUM);
-		ForumManager fm = ForumManager.getInstance();
-		Forum forum = fm.loadForum(forumKeyProperty.getLongValue());
+		Forum forum = forumManager.loadForum(forumKeyProperty.getLongValue());
 		
-		m1 = fm.createMessage(forum, owner1, false);
+		m1 = forumManager.createMessage(forum, owner1, false);
 		m1.setTitle("Thread-1");
 		m1.setBody("Body of Thread-1");
-		fm.addTopMessage(m1);
+		forumManager.addTopMessage(m1);
 		
-		m2 = fm.createMessage(forum, owner2, false);
+		m2 = forumManager.createMessage(forum, owner2, false);
 		m2.setTitle("Thread-2");
 		m2.setBody("Body of Thread-2");
-		fm.addTopMessage(m2);
+		forumManager.addTopMessage(m2);
 		
-		DBFactory.getInstance().intermediateCommit();
+		dbInstance.intermediateCommit();
 		
-		m3 = fm.createMessage(forum, owner3, false);
+		m3 = forumManager.createMessage(forum, owner3, false);
 		m3.setTitle("Message-1.1");
 		m3.setBody("Body of Message-1.1");
-		fm.replyToMessage(m3, m1);
+		forumManager.replyToMessage(m3, m1);
 		
-		m4 = fm.createMessage(forum, part1, false);
+		m4 = forumManager.createMessage(forum, part1, false);
 		m4.setTitle("Message-1.1.1");
 		m4.setBody("Body of Message-1.1.1");
-		fm.replyToMessage(m4, m3);
+		forumManager.replyToMessage(m4, m3);
 		
-		m5 = fm.createMessage(forum, part2, false);
+		m5 = forumManager.createMessage(forum, part2, false);
 		m5.setTitle("Message-1.2");
 		m5.setBody("Body of Message-1.2");
-		fm.replyToMessage(m5, m1);
+		forumManager.replyToMessage(m5, m1);
 
-		DBFactory.getInstance().intermediateCommit();
+		dbInstance.intermediateCommit();
 	}
 	
 	@After
diff --git a/src/test/java/org/olat/restapi/NotificationsTest.java b/src/test/java/org/olat/restapi/NotificationsTest.java
index 4c9ae94d17b3526fb6b71d72ac425424838126fb..c0ee6d208d62fb967eeaa74141b910297ba0dc74 100644
--- a/src/test/java/org/olat/restapi/NotificationsTest.java
+++ b/src/test/java/org/olat/restapi/NotificationsTest.java
@@ -111,6 +111,8 @@ public class NotificationsTest extends OlatJerseyTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private ForumManager forumManager;
+	@Autowired
 	private OrganisationService organisationService;
 	@Autowired
 	private BusinessGroupService businessGroupService;
@@ -142,7 +144,7 @@ public class NotificationsTest extends OlatJerseyTestCase {
 			}
 			
 			//create a forum
-			forum = ForumManager.getInstance().addAForum();
+			forum = forumManager.addAForum();
 			Message m1 = createMessage(userSubscriberId, forum);
 			Assert.assertNotNull(m1);
 			
@@ -511,11 +513,10 @@ public class NotificationsTest extends OlatJerseyTestCase {
 	}
 	
 	private Message createMessage(Identity id, Forum fo) {
-		ForumManager fm = ForumManager.getInstance();
-		Message m1 = fm.createMessage(fo, id, false);
+		Message m1 = forumManager.createMessage(fo, id, false);
 		m1.setTitle("Thread-1");
 		m1.setBody("Body of Thread-1");
-		fm.addTopMessage(m1);
+		forumManager.addTopMessage(m1);
 		return m1;
 	}
 	
diff --git a/src/test/java/org/olat/restapi/UserMgmtTest.java b/src/test/java/org/olat/restapi/UserMgmtTest.java
index dafd34b8418621d60a6ef114335d27fc29654c0e..dbee180a08b1ef487e3badc9f4f462b7d46ffacc 100644
--- a/src/test/java/org/olat/restapi/UserMgmtTest.java
+++ b/src/test/java/org/olat/restapi/UserMgmtTest.java
@@ -143,6 +143,8 @@ public class UserMgmtTest extends OlatJerseyTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private ForumManager forumManager;
+	@Autowired
 	private BusinessGroupRelationDAO businessGroupRelationDao;
 	@Autowired
 	private BusinessGroupService businessGroupService;
@@ -222,10 +224,10 @@ public class UserMgmtTest extends OlatJerseyTestCase {
 		CollaborationTools g1CTSMngr = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(g1);
 		g1CTSMngr.setToolEnabled(CollaborationTools.TOOL_FORUM, true);
 		Forum g1Forum = g1CTSMngr.getForum();//create the forum
-		Message m1 = ForumManager.getInstance().createMessage(g1Forum, id1, false);
+		Message m1 = forumManager.createMessage(g1Forum, id1, false);
 		m1.setTitle("Thread-1");
 		m1.setBody("Body of Thread-1");
-		ForumManager.getInstance().addTopMessage(m1);
+		forumManager.addTopMessage(m1);
 		
 		dbInstance.commitAndCloseSession();
 		
@@ -258,10 +260,10 @@ public class UserMgmtTest extends OlatJerseyTestCase {
 					if(demoForumNode == null) {
 						demoForumNode = (FOCourseNode)node;
 						Forum courseForum = demoForumNode.loadOrCreateForum(demoCourse.getCourseEnvironment());
-						Message message1 = ForumManager.getInstance().createMessage(courseForum, id1, false);
+						Message message1 = forumManager.createMessage(courseForum, id1, false);
 						message1.setTitle("Thread-1");
 						message1.setBody("Body of Thread-1");
-						ForumManager.getInstance().addTopMessage(message1);
+						forumManager.addTopMessage(message1);
 					}	
 				} else if (node instanceof BCCourseNode) {
 					if(demoBCCourseNode == null) {