diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderMapper.java b/src/main/java/org/olat/core/commons/modules/bc/FolderMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..c87bcd95c76c6c3ea7a5783ee912c4c238fac9a5
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/modules/bc/FolderMapper.java
@@ -0,0 +1,50 @@
+/**
+ * <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.core.commons.modules.bc;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.olat.core.commons.modules.bc.commands.CmdServeResource;
+import org.olat.core.dispatcher.mapper.Mapper;
+import org.olat.core.gui.media.MediaResource;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
+
+/**
+ * 
+ * Initial date: 22 août 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class FolderMapper implements Mapper {
+	
+	private final VFSContainer container;
+	
+	public FolderMapper(VFSContainer container) {
+		this.container = container;
+	}
+	
+	@Override
+	public MediaResource handle(String relPath, HttpServletRequest request) {
+		VFSItem vfsItem = container.resolve(relPath);
+		CmdServeResource cmdResource = new CmdServeResource();
+		return cmdResource.getMediaResource(relPath, vfsItem);
+	}
+}
diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java
index 5524f4886352c8de56792aca2681f29b79208991..ac0ce2b905b6ff50ce0359bb39b343339d537c02 100644
--- a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java
+++ b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java
@@ -76,7 +76,6 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.vfs.OlatRelPathImpl;
 import org.olat.core.util.vfs.Quota;
 import org.olat.core.util.vfs.VFSContainer;
-import org.olat.core.util.vfs.VFSContainerMapper;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.core.util.vfs.VFSManager;
@@ -569,13 +568,13 @@ public class FolderRunController extends BasicController implements Activateable
 				// and can not reuse the standard briefcase way of file delivering, some
 				// very old fancy code
 				// Mapper is cleaned up automatically by basic controller
-				String baseUrl = registerMapper(ureq, new VFSContainerMapper(folderComponent.getRootContainer()));
+				String baseUrl = registerMapper(ureq, new FolderMapper(folderComponent.getRootContainer()));
 				// Trigger auto-download
 				DisplayOrDownloadComponent dordc = new DisplayOrDownloadComponent("downloadcomp", baseUrl + path);
 				folderContainer.put("autoDownloadComp", dordc);
 				
-				if (path.lastIndexOf("/") > 0) {
-					String dirPath = path.substring(0, path.lastIndexOf("/"));
+				if (path.lastIndexOf('/') > 0) {
+					String dirPath = path.substring(0, path.lastIndexOf('/'));
 					if (StringHelper.containsNonWhitespace(dirPath)) {
 						folderComponent.setCurrentContainerPath(dirPath);
 					}
diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java
index cf8ec446a19fee5b0566e8cc772ffa8048bf8ce6..e770f50082ae6246be07c56392af6c4578125d48 100644
--- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java
+++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdServeResource.java
@@ -62,6 +62,7 @@ public class CmdServeResource implements FolderCommand {
 	
 	private int status = FolderCommandStatus.STATUS_SUCCESS;
 	
+	@Override
 	public Controller execute(FolderComponent folderComponent, UserRequest ureq, WindowControl wControl, Translator translator) {
 		VFSSecurityCallback inheritedSecCallback = VFSManager.findInheritedSecurityCallback(folderComponent.getCurrentContainer());
 		if (inheritedSecCallback != null && !inheritedSecCallback.canRead())
@@ -69,13 +70,28 @@ public class CmdServeResource implements FolderCommand {
 		
 		// extract file
 		String path = ureq.getModuleURI();
-		MediaResource mr = null;
 		VFSItem vfsitem = folderComponent.getRootContainer().resolve(path);
 		if(vfsitem == null) {
 			//double decoding of ++
 			vfsitem = FolderCommandHelper.tryDoubleDecoding(ureq, folderComponent);
 		}
+		MediaResource mr = getMediaResource(path, vfsitem);
+		ThreadLocalUserActivityLogger.log(FolderLoggingAction.BC_FILE_READ, getClass(), CoreLoggingResourceable.wrapBCFile(path));
+		ureq.getDispatchResult().setResultingMediaResource(mr);
+		
+		// update download counter
+		if (vfsitem instanceof MetaTagged) {
+			MetaTagged itemWithMeta = (MetaTagged) vfsitem;
+			MetaInfo meta = itemWithMeta.getMetaInfo();
+			meta.increaseDownloadCount();
+			meta.write();
+		}
 
+		return null;
+	}
+	
+	public MediaResource getMediaResource(String path, VFSItem vfsitem) {
+		MediaResource mr = null;
 		if (vfsitem == null) {
 			mr = new NotFoundMediaResource();
 		} else if(!(vfsitem instanceof VFSLeaf)) {
@@ -85,7 +101,6 @@ public class CmdServeResource implements FolderCommand {
 			VFSLeaf vfsfile = (VFSLeaf)vfsitem;
 			boolean forceDownload = FolderManager.isDownloadForcedFileType(vfsfile.getName());
 			if (path.toLowerCase().endsWith(".html") || path.toLowerCase().endsWith(".htm")) {
-				// setCurrentURI(path);
 				// set the http content-type and the encoding
 				// try to load in iso-8859-1
 				InputStream is = vfsfile.getInputStream();
@@ -166,19 +181,7 @@ public class CmdServeResource implements FolderCommand {
 				mr = vmr;
 			}
 		}
-				
-		ThreadLocalUserActivityLogger.log(FolderLoggingAction.BC_FILE_READ, getClass(), CoreLoggingResourceable.wrapBCFile(path));
-		ureq.getDispatchResult().setResultingMediaResource(mr);
-		
-		// update download counter
-		if (vfsitem instanceof MetaTagged) {
-			MetaTagged itemWithMeta = (MetaTagged) vfsitem;
-			MetaInfo meta = itemWithMeta.getMetaInfo();
-			meta.increaseDownloadCount();
-			meta.write();
-		}
-
-		return null;
+		return mr;
 	}
 
 	@Override