diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/RecordingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/RecordingService.java
index d1f2eb9d56ae8de33024686ae088f57bafda5e8a..04345dc132ab03393495b179d52297da9aabc019 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/RecordingService.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/RecordingService.java
@@ -70,11 +70,11 @@ public class RecordingService {
 
     public void processMakePresentationDownloadableMsg(MakePresentationDownloadableMsg msg) {
         try {
-            Util.makePresentationDownloadable(presentationBaseDir, msg.meetingId, msg.presId, msg.downloadable);
+            File presDir = Util.getPresentationDir(presentationBaseDir, msg.meetingId, msg.presId);
+            Util.makePresentationDownloadable(presDir, msg.presId, msg.downloadable);
         } catch (IOException e) {
             log.error("Failed to make presentation downloadable: {}", e);
         }
-
     }
 
     public File getDownloadablePresentationFile(String meetingId, String presId, String presFilename) {
@@ -89,7 +89,7 @@ public class RecordingService {
 
         String presFilenameExt = FilenameUtils.getExtension(presFilename);
         File presDir = Util.getPresentationDir(presentationBaseDir, meetingId, presId);
-        File downloadMarker = Util.getPresFileDownloadMarker(presentationBaseDir, meetingId, presId);
+        File downloadMarker = Util.getPresFileDownloadMarker(presDir, presId);
         if (presDir != null && downloadMarker != null && downloadMarker.exists()) {
             String safePresFilename = presId.concat(".").concat(presFilenameExt);
             File presFile = new File(presDir.getAbsolutePath() + File.separatorChar + safePresFilename);
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/Util.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/Util.java
index 9b8d3e5c70b336e4eae691dfa099e112fa660715..c0c272ebad9360b05834ea7246f0ceb78428b9e1 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/api/Util.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/Util.java
@@ -12,7 +12,8 @@ public final class Util {
 
 	private static final Pattern MEETING_ID_PATTERN = Pattern.compile("^[a-z0-9-]+$");
 	private static final Pattern PRES_ID_PATTERN = Pattern.compile("^[a-z0-9-]+$");
-	private static final Pattern PRES_FILE_ID_PATTERN = Pattern.compile("^[a-z0-9-]+.[a-zA-Z]{3,4}$");
+	// see https://www.baeldung.com/java-regexp-escape-char#1-escaping-using-backslash
+	private static final Pattern PRES_FILE_ID_PATTERN = Pattern.compile("^[a-z0-9-]+\\.[a-zA-Z]{3,4}$");
 
 	private Util() {
 		throw new IllegalStateException("Utility class");
@@ -102,23 +103,20 @@ public final class Util {
 		return path;
 	}
 
-	public static File getPresFileDownloadMarker(String presBaseDir, String meetingId, String presId) {
-		File presDir = Util.getPresentationDir(presBaseDir, meetingId, presId);
-
-		if (presDir != null) {
+	public static File getPresFileDownloadMarker(File presBaseDir, String presId) {
+		if (presBaseDir != null) {
 			String downloadMarker = presId.concat(".downloadable");
-			return new File(presDir.getAbsolutePath() + File.separatorChar + downloadMarker);
+			return new File(presBaseDir.getAbsolutePath() + File.separatorChar + downloadMarker);
 		}
 		return null;
 	}
 
 	public static void makePresentationDownloadable(
-		String presBaseDir,
-		String meetingId,
+		File presFileDir,
 		String presId,
 		boolean downloadable
 	) throws IOException {
-		File downloadMarker = Util.getPresFileDownloadMarker(presBaseDir, meetingId, presId);
+		File downloadMarker = Util.getPresFileDownloadMarker(presFileDir, presId);
 		if (downloadable) {
 			if (downloadMarker != null && ! downloadMarker.exists()) {
 				downloadMarker.createNewFile();
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java
index 24e0c5f6c77c115f80298c0955e4bf9561824844..e9e7d3b489b337e0e3538c60a69454bf42d9481e 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java
@@ -19,18 +19,16 @@
 
 package org.bigbluebutton.presentation;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
-
 import org.bigbluebutton.api2.IBbbWebApiGWApp;
 import org.bigbluebutton.presentation.imp.*;
-import org.bigbluebutton.presentation.messages.DocPageConversionStarted;
 import org.bigbluebutton.presentation.messages.DocConversionRequestReceived;
-import org.bigbluebutton.presentation.messages.DocPageCountExceeded;
-import org.bigbluebutton.presentation.messages.DocPageCountFailed;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
+import org.bigbluebutton.api.Util;
 import com.google.gson.Gson;
 
 public class DocumentConversionServiceImp implements DocumentConversionService {
@@ -43,7 +41,6 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
   private PresentationFileProcessor presentationFileProcessor;
 
   public void processDocument(UploadedPresentation pres) {
-
     if (pres.isUploadFailed()) {
       // We should send a message to the client in the future.
       // ralam may 1, 2020
@@ -52,10 +49,13 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
       return;
     }
 
-    SupportedDocumentFilter sdf = new SupportedDocumentFilter(gw);
-
     sendDocConversionRequestReceived(pres);
 
+    processDocumentStart(pres);
+  }
+
+  public void processDocumentStart(UploadedPresentation pres) {
+    SupportedDocumentFilter sdf = new SupportedDocumentFilter(gw);
     if (sdf.isSupported(pres)) {
       String fileType = pres.getFileType();
 
@@ -67,7 +67,7 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
           // Successfully converted to pdf. Call the process again, this time it
           // should be handled by
           // the PDF conversion service.
-          processDocument(pres);
+          processDocumentStart(pres);
         } else {
           // Send notification that office to pdf conversion failed.
           // The cause should have been set by the previous step.
@@ -75,26 +75,10 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
           ocsf.sendProgress(pres);
         }
       } else if (SupportedFileTypes.isPdfFile(fileType)) {
-          presentationFileProcessor.process(pres);
+        presentationFileProcessor.process(pres);
       } else if (SupportedFileTypes.isImageFile(fileType)) {
-          presentationFileProcessor.process(pres);
+        presentationFileProcessor.process(pres);
       } else {
-          Map<String, Object> logData = new HashMap<String, Object>();
-          logData = new HashMap<String, Object>();
-          logData.put("podId", pres.getPodId());
-          logData.put("meetingId", pres.getMeetingId());
-          logData.put("presId", pres.getId());
-          logData.put("filename", pres.getName());
-          logData.put("current", pres.isCurrent());
-          logData.put("logCode", "supported_file_not_handled");
-          logData.put("message", "Supported file not handled.");
-
-          Gson gson = new Gson();
-          String logStr = gson.toJson(logData);
-          log.warn(" --analytics-- data={}", logStr);
-      }
-
-    } else {
         Map<String, Object> logData = new HashMap<String, Object>();
         logData = new HashMap<String, Object>();
         logData.put("podId", pres.getPodId());
@@ -102,29 +86,44 @@ public class DocumentConversionServiceImp implements DocumentConversionService {
         logData.put("presId", pres.getId());
         logData.put("filename", pres.getName());
         logData.put("current", pres.isCurrent());
-        logData.put("logCode", "unsupported_file_format");
-        logData.put("message", "Unsupported file format");
+        logData.put("logCode", "supported_file_not_handled");
+        logData.put("message", "Supported file not handled.");
 
         Gson gson = new Gson();
         String logStr = gson.toJson(logData);
-        log.error(" --analytics-- data={}", logStr);
-
-        logData.clear();
-
-        logData.put("podId", pres.getPodId());
-        logData.put("meetingId", pres.getMeetingId());
-        logData.put("presId", pres.getId());
-        logData.put("filename", pres.getName());
-        logData.put("current", pres.isCurrent());
-        logData.put("logCode", "presentation_conversion_end");
-        logData.put("message", "End presentation conversion.");
-
-        logStr = gson.toJson(logData);
-        log.info(" --analytics-- data={}", logStr);
+        log.warn(" --analytics-- data={}", logStr);
+      }
 
-        notifier.sendConversionCompletedMessage(pres);
+    } else {
+      Map<String, Object> logData = new HashMap<String, Object>();
+      logData = new HashMap<String, Object>();
+      logData.put("podId", pres.getPodId());
+      logData.put("meetingId", pres.getMeetingId());
+      logData.put("presId", pres.getId());
+      logData.put("filename", pres.getName());
+      logData.put("current", pres.isCurrent());
+      logData.put("logCode", "unsupported_file_format");
+      logData.put("message", "Unsupported file format");
+
+      Gson gson = new Gson();
+      String logStr = gson.toJson(logData);
+      log.error(" --analytics-- data={}", logStr);
+
+      logData.clear();
+
+      logData.put("podId", pres.getPodId());
+      logData.put("meetingId", pres.getMeetingId());
+      logData.put("presId", pres.getId());
+      logData.put("filename", pres.getName());
+      logData.put("current", pres.isCurrent());
+      logData.put("logCode", "presentation_conversion_end");
+      logData.put("message", "End presentation conversion.");
+
+      logStr = gson.toJson(logData);
+      log.info(" --analytics-- data={}", logStr);
+
+      notifier.sendConversionCompletedMessage(pres);
     }
-
   }
 
   private void sendDocConversionRequestReceived(UploadedPresentation pres) {
diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PresentationFileProcessor.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PresentationFileProcessor.java
index b36288b5513e6746d2bfb4a2d3bfce16c0b30c7c..8cd63229441b361838fe30d952980eb90b96190e 100755
--- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PresentationFileProcessor.java
+++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PresentationFileProcessor.java
@@ -56,16 +56,7 @@ public class PresentationFileProcessor {
 
     public synchronized void process(UploadedPresentation pres) {
         if (pres.isDownloadable()) {
-            try {
-                Util.makePresentationDownloadable(
-                  pres.getUploadedFile().getParent(),
-                  pres.getMeetingId(),
-                  pres.getId(),
-                  pres.isDownloadable()
-                );
-            } catch (IOException e) {
-                log.error("Failed to make presentation downloadable: {}", e);
-            }
+            processMakePresentationDownloadableMsg(pres);
         }
 
         Runnable messageProcessor = new Runnable() {
@@ -76,6 +67,15 @@ public class PresentationFileProcessor {
         executor.submit(messageProcessor);
     }
 
+    private void processMakePresentationDownloadableMsg(UploadedPresentation pres) {
+        try {
+            File presentationFileDir = pres.getUploadedFile().getParentFile();
+            Util.makePresentationDownloadable(presentationFileDir, pres.getId(), pres.isDownloadable());
+        } catch (IOException e) {
+            log.error("Failed to make presentation downloadable: {}", e);
+        }
+    }
+
     private void processUploadedPresentation(UploadedPresentation pres) {
         if (SupportedFileTypes.isPdfFile(pres.getFileType())) {
             determineNumberOfPages(pres);