diff --git a/src/main/java/org/olat/core/_spring/mainCorecontext.xml b/src/main/java/org/olat/core/_spring/mainCorecontext.xml
index 2b4fcff8e3cc26af9a1cfa95c08c30f7d612b64c..ed73cf660499b9ccc386f17630661a1b624ecce8 100644
--- a/src/main/java/org/olat/core/_spring/mainCorecontext.xml
+++ b/src/main/java/org/olat/core/_spring/mainCorecontext.xml
@@ -29,7 +29,6 @@
 	<import resource="classpath:/org/olat/core/gui/components/form/flexible/impl/elements/richText/_spring/richTextCorecontext.xml"/> 
 	
 	<import resource="classpath:/org/olat/core/commons/services/_spring/servicesCorecontext.xml"/>
-	<import resource="classpath:/org/olat/core/commons/services/thumbnail/_spring/thumbnailserviceContext.xml"/>
 	<import resource="classpath:/org/olat/core/commons/services/webdav/_spring/webdavContext.xml"/>
 
 	<bean class="org.olat.core.gui.render.velocity.VelocityModule" depends-on="org.olat.core.helpers.Settings,coordinatorManager" init-method="init">
diff --git a/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditor.java b/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditor.java
index ff55acadc6aaeaf9c0b7aebeb55b416bf0f4b069..3f9ad215e03736ff33a91a5d936aa34e901b534d 100644
--- a/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditor.java
+++ b/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditor.java
@@ -72,6 +72,11 @@ public class FileEditor implements DocEditor {
 		return translator.translate("editor.display.name");
 	}
 
+	@Override
+	public boolean isViewOnly() {
+		return false;
+	}
+
 	@Override
 	public boolean isCollaborative() {
 		return false;
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/DocEditor.java b/src/main/java/org/olat/core/commons/services/doceditor/DocEditor.java
index 408d37d7ad3d807381bd907c338c84eccd265b5e..832776779d7a642b6537853d33730a808564ac1a 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/DocEditor.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/DocEditor.java
@@ -45,6 +45,8 @@ public interface DocEditor {
 	
 	String getDisplayName(Locale locale);
 	
+	boolean isViewOnly();
+	
 	boolean isCollaborative();
 
 	boolean isDataTransferConfirmationEnabled();
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/collabora/CollaboraEditor.java b/src/main/java/org/olat/core/commons/services/doceditor/collabora/CollaboraEditor.java
index cbea8495e409bea2d439dca01721e777ef6533f9..4d3b53362941dc11820220cf535cc0a9e4420477 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/collabora/CollaboraEditor.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/collabora/CollaboraEditor.java
@@ -72,6 +72,11 @@ public class CollaboraEditor implements DocEditor {
 		return translator.translate("editor.display.name");
 	}
 
+	@Override
+	public boolean isViewOnly() {
+		return false;
+	}
+
 	@Override
 	public boolean isCollaborative() {
 		return true;
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/collabora/manager/CollaboraServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/collabora/manager/CollaboraServiceImpl.java
index ae6cfe76b8c462338d50ead60f0ad3ddf7641b78..e1e8a593f84820b376b3a5bf97a886a0bd6f846a 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/collabora/manager/CollaboraServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/collabora/manager/CollaboraServiceImpl.java
@@ -106,6 +106,7 @@ public class CollaboraServiceImpl implements CollaboraService, GenericEventListe
 		}
 		if (updated) {
 			refreshLock(vfsLeaf);
+			vfsRepositoryService.resetThumbnails(vfsLeaf);
 		}
 		return updated;
 	}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorServiceImpl.java
index b3e82e442b5f397e4d25bbdc32ecfeb55b57a338..94d7654f28d8f87284b0da6e168afa57ad7cd273 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/manager/DocEditorServiceImpl.java
@@ -111,6 +111,7 @@ public class DocEditorServiceImpl implements DocEditorService, UserDataDeletable
 		return editors.stream()
 				.filter(editor -> !FileEditor.TYPE.equals(editor.getType()))
 				.filter(DocEditor::isEnable)
+				.filter(editor -> !editor.isViewOnly())
 				.filter(editor -> editor.isEnabledFor(identity, roles))
 				.collect(Collectors.toList());
 	}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/office365/Office365Editor.java b/src/main/java/org/olat/core/commons/services/doceditor/office365/Office365Editor.java
index 461d2c4d2017a3ada11294bd478facb3804466f2..023e00be4ee99382b682a7e21d9d55a0ea68d8d5 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/office365/Office365Editor.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/office365/Office365Editor.java
@@ -70,6 +70,11 @@ public class Office365Editor implements DocEditor {
 		return translator.translate("editor.display.name");
 	}
 
+	@Override
+	public boolean isViewOnly() {
+		return false;
+	}
+
 	@Override
 	public boolean isCollaborative() {
 		return true;
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java
index 63bcb7e9a20d883ae942fb3d2118bdfe869150dd..46c6d97470b6379e38a3490f770e9df44546fee4 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/office365/manager/Office365ServiceImpl.java
@@ -112,6 +112,7 @@ public class Office365ServiceImpl implements Office365Service, GenericEventListe
 		}
 		if (updated) {
 			refreshLock(vfsLeaf);
+			vfsRepositoryService.resetThumbnails(vfsLeaf);
 		}
 		return updated;
 	}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeConversionService.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeConversionService.java
new file mode 100644
index 0000000000000000000000000000000000000000..89475b90b3bed13f4dc0d79260d883fe1980a9fe
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeConversionService.java
@@ -0,0 +1,35 @@
+/**
+ * <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.services.doceditor.onlyoffice;
+
+import org.olat.core.commons.services.thumbnail.FinalSize;
+import org.olat.core.util.vfs.VFSLeaf;
+
+/**
+ * 
+ * Initial date: 4 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public interface OnlyOfficeConversionService {
+
+	FinalSize createThumbnail(VFSLeaf file, VFSLeaf thumbnailFile, int maxWidth, int maxHeight);
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeEditor.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeEditor.java
index b4652ce105fb5fd78af2c60000408d452379e281..d7d34c023daceac891fc2fc8a7864237220f1cc9 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeEditor.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeEditor.java
@@ -58,7 +58,7 @@ public class OnlyOfficeEditor implements DocEditor {
 
 	@Override
 	public boolean isEnable() {
-		return onlyOfficeModule.isEnabled();
+		return onlyOfficeModule.isEnabled() && onlyOfficeModule.isEnabled();
 	}
 
 	@Override
@@ -72,6 +72,12 @@ public class OnlyOfficeEditor implements DocEditor {
 		return translator.translate("editor.display.name");
 	}
 
+	@Override
+	public boolean isViewOnly() {
+		Integer licenseEdit = onlyOfficeModule.getLicenseEdit();
+		return licenseEdit != null && licenseEdit.intValue() <= 0? true: false;
+	}
+
 	@Override
 	public boolean isCollaborative() {
 		return true;
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeModule.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeModule.java
index 343b0f35256be02468c4d19d6a4038c662f9e240..188c384f71014db63a35ec39d158bf6c935acde9 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeModule.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeModule.java
@@ -47,11 +47,13 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 	private static final String ONLYOFFICE_ENABLED = "onlyoffice.enabled";
 	private static final String ONLYOFFICE_BASE_URL = "onlyoffice.baseUrl";
 	private static final String ONLYOFFICE_JWT_SECRET = "onlyoffice.jwt.secret";
+	private static final String ONLYOFFICE_EDITOR_ENABLED = "onlyoffice.editor.enabled";
 	private static final String ONLYOFFICE_LICENSE_EDIT = "onlyoffice.license.edit";
 	private static final String ONLYOFFICE_DATA_TRANSER_CONFIRMATION_ENABLED = "onlyoffice.data.transfer.confirmation.enabled";
 	private static final String ONLYOFFICE_USAGE_AUTHORS = "onlyoffice.usage.authors";
 	private static final String ONLYOFFICE_USAGE_COACHES = "onlyoffice.usage.coaches";
 	private static final String ONLYOFFICE_USAGE_MANAGERS = "onlyoffice.usage.managers";
+	private static final String ONLYOFFICE_THUMBNAILS_ENABLED = "onlyoffice.thumbnails.enabled";
 	
 	@Value("${onlyoffice.enabled:false}")
 	private boolean enabled;
@@ -60,8 +62,13 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 	@Value("${onlyoffice.api.path}")
 	private String apiPath;
 	private String apiUrl;
+	@Value("${onlyoffice.conversion.path}")
+	private String conversionPath;
+	private String conversionUrl;
 	private String jwtSecret;
 	private Key jwtSignKey;
+	@Value("${onlyoffice.editor.enabled:false}")
+	private boolean editorEnabled;
 	@Value("${onlyoffice.license.edit}")
 	private Integer licenseEdit;
 	@Value("${onlyoffice.data.transfer.confirmation.enabled:false}")
@@ -72,6 +79,8 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 	private boolean usageRestrictedToCoaches;
 	@Value("${onlyoffice.usage.restricted.managers:false}")
 	private boolean usageRestrictedToManagers;
+	@Value("${onlyoffice.thumbnails.enabled:false}")
+	private boolean thumbnailsEnabled;
 	
 	@Autowired
 	private OnlyOfficeModule(CoordinatorManager coordinateManager) {
@@ -97,7 +106,7 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 		String baseUrlObj = getStringPropertyValue(ONLYOFFICE_BASE_URL, true);
 		if(StringHelper.containsNonWhitespace(baseUrlObj)) {
 			baseUrl = baseUrlObj;
-			resetApiUrl();
+			resetApiUrls();
 		}
 		
 		String jwtSecretObj = getStringPropertyValue(ONLYOFFICE_JWT_SECRET, true);
@@ -105,6 +114,11 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 			jwtSecret = jwtSecretObj;
 		}
 		
+		String editorEnabledObj = getStringPropertyValue(ONLYOFFICE_EDITOR_ENABLED, true);
+		if(StringHelper.containsNonWhitespace(editorEnabledObj)) {
+			editorEnabled = "true".equals(editorEnabledObj);
+		}
+		
 		String dataTransferConfirmationEnabledObj = getStringPropertyValue(ONLYOFFICE_DATA_TRANSER_CONFIRMATION_ENABLED, true);
 		if(StringHelper.containsNonWhitespace(dataTransferConfirmationEnabledObj)) {
 			dataTransferConfirmationEnabled = "true".equals(dataTransferConfirmationEnabledObj);
@@ -129,6 +143,11 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 		if(StringHelper.containsNonWhitespace(usageRestrictedToManagersObj)) {
 			usageRestrictedToManagers = "true".equals(usageRestrictedToManagersObj);
 		}
+		
+		String thumbnailsEnabledObj = getStringPropertyValue(ONLYOFFICE_THUMBNAILS_ENABLED, true);
+		if(StringHelper.containsNonWhitespace(thumbnailsEnabledObj)) {
+			thumbnailsEnabled = "true".equals(thumbnailsEnabledObj);
+		}
 	}
 	
 	private Integer getIntOrNull(String val) {
@@ -157,15 +176,20 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 	public void setBaseUrl(String baseUrl) {
 		this.baseUrl = baseUrl;
 		setStringProperty(ONLYOFFICE_BASE_URL, baseUrl, true);
-		resetApiUrl();
+		resetApiUrls();
 	}
 	
 	public String getApiUrl() {
 		return apiUrl;
 	}
 	
-	private void resetApiUrl() {
+	public String getConversionUrl() {
+		return conversionUrl;
+	}
+	
+	private void resetApiUrls() {
 		this.apiUrl = baseUrl + apiPath;
+		this.conversionUrl = baseUrl + conversionPath;
 	}
 	
 	public String getJwtSecret() {
@@ -188,6 +212,15 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 		}
 		return jwtSignKey;
 	}
+	
+	public boolean isEditorEnabled() {
+		return editorEnabled;
+	}
+
+	public void setEditorEnabled(boolean editorEnabled) {
+		this.editorEnabled = enabled;
+		setStringProperty(ONLYOFFICE_EDITOR_ENABLED, Boolean.toString(editorEnabled), true);
+	}
 
 	public Integer getLicenseEdit() {
 		return licenseEdit;
@@ -237,5 +270,14 @@ public class OnlyOfficeModule extends AbstractSpringModule implements ConfigOnOf
 		this.usageRestrictedToManagers = usageRestrictedToManagers;
 		setStringProperty(ONLYOFFICE_USAGE_MANAGERS, Boolean.toString(usageRestrictedToManagers), true);
 	}
+	
+	public boolean isThumbnailsEnabled() {
+		return thumbnailsEnabled;
+	}
+
+	public void setThumbnailsEnabled(boolean thumbnailsEnabled) {
+		this.thumbnailsEnabled = thumbnailsEnabled;
+		setStringProperty(ONLYOFFICE_THUMBNAILS_ENABLED, Boolean.toString(thumbnailsEnabled), true);
+	}
 
 }
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeSecurityService.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeSecurityService.java
index 90517ea2c9921a1d6baf5871e0eee50665b726c6..a8010c6a6c09470f098b01ed9571efae19c9f7da 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeSecurityService.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeSecurityService.java
@@ -19,8 +19,7 @@
  */
 package org.olat.core.commons.services.doceditor.onlyoffice;
 
-import org.olat.core.commons.services.doceditor.onlyoffice.model.DocumentImpl;
-import org.olat.core.commons.services.doceditor.onlyoffice.model.EditorConfigImpl;
+import java.util.Map;
 
 /**
  * 
@@ -51,7 +50,7 @@ public interface OnlyOfficeSecurityService {
 	 * @param editorConfig
 	 * @return jwtToken
 	 */
-	String getApiConfigToken(DocumentImpl document, EditorConfigImpl editorConfig);
+	String getApiConfigToken(Document document, EditorConfig editorConfig);
 	
 	/**
 	 * Creates the JWT token to use for download a file.
@@ -61,6 +60,7 @@ public interface OnlyOfficeSecurityService {
 	 * @return jwtToken
 	 */
 	String getFileDonwloadToken();
-
+	
+	String getToken(Map<String, Object> claims);
 
 }
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeConversionServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeConversionServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..f87e6c1272729c64bdb27887247a3bae3e05c39a
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeConversionServiceImpl.java
@@ -0,0 +1,247 @@
+/**
+ * <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.services.doceditor.onlyoffice.manager;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.logging.log4j.Logger;
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeConversionService;
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeModule;
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeSecurityService;
+import org.olat.core.commons.services.doceditor.onlyoffice.model.ConversionParams;
+import org.olat.core.commons.services.doceditor.onlyoffice.model.ConversionResult;
+import org.olat.core.commons.services.doceditor.onlyoffice.model.Thumbnail;
+import org.olat.core.commons.services.thumbnail.FinalSize;
+import org.olat.core.dispatcher.mapper.Mapper;
+import org.olat.core.dispatcher.mapper.MapperService;
+import org.olat.core.dispatcher.mapper.manager.MapperKey;
+import org.olat.core.helpers.Settings;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.FileUtils;
+import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.core.util.vfs.VFSManager;
+import org.olat.core.util.vfs.VFSMediaMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * 
+ * Initial date: 4 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class OnlyOfficeConversionServiceImpl implements OnlyOfficeConversionService {
+	
+	private static final Logger log = Tracing.createLoggerFor(OnlyOfficeConversionServiceImpl.class);
+	
+	private static ObjectMapper objectMapper = new ObjectMapper();
+
+	@Autowired
+	private OnlyOfficeModule onlyOfficeModule;
+	@Autowired
+	private OnlyOfficeSecurityService onlyOfficeSecurityService;
+	@Autowired
+	private MapperService mapperService;
+
+	@Override
+	public FinalSize createThumbnail(VFSLeaf inputLeaf, VFSLeaf thumbnailLeaf, int maxWidth, int maxHeight) {
+		log.debug("Generate thumbnail for {}, ({})", inputLeaf.getMetaInfo().getUuid(), inputLeaf.getName());
+		
+		boolean thumbnailCreated = false;
+		
+		Mapper mapper = new VFSMediaMapper(inputLeaf);
+		MapperKey mapperKey = mapperService.register(null, mapper);
+		String url = Settings.createServerURI() + mapperKey.getUrl();
+		log.debug("Input leaf mapper url: {}", url);
+		
+		ConversionParams conversionParams = createConversionParams(inputLeaf, thumbnailLeaf, maxWidth, maxHeight, url);
+		signConversionParams(conversionParams);
+
+		try {
+			thumbnailCreated = tryCreateThumbnail(conversionParams, thumbnailLeaf);
+		} catch (Exception e) {
+			log.error("Exception when creating thumbnail for {}, ({}).", inputLeaf.getMetaInfo().getUuid(), inputLeaf.getName(), e);
+		}
+		
+		mapperService.cleanUp(Collections.singletonList(mapperKey));
+		
+		if (!thumbnailCreated) {
+			log.warn("Thumbnail generation for {}, ({}) failed.", inputLeaf.getMetaInfo().getUuid(), inputLeaf.getName());
+			return null;
+		}
+		
+		log.debug("Thumbnail generation for {}, ({}) successful.", inputLeaf.getMetaInfo().getUuid(), inputLeaf.getName());
+		return new FinalSize(maxWidth, maxWidth);
+	}
+	
+	private ConversionParams createConversionParams(VFSLeaf inputLeaf, VFSLeaf thumbnailLeaf, int maxWidth,
+			int maxHeight, String url) {
+		ConversionParams conversionParams = new ConversionParams();
+		
+		//Defines the document identifier used to unambiguously identify the document file.
+		conversionParams.setKey(inputLeaf.getMetaInfo().getUuid() + Formatter.formatDatetimeFilesystemSave(new Date()));
+		conversionParams.setUrl(url);
+		
+		String suffix = FileUtils.getFileSuffix(thumbnailLeaf.getName());
+		conversionParams.setOutputtype(suffix);
+		// Defines the converted file name.
+		conversionParams.setTitle(thumbnailLeaf.getName());
+		
+		Thumbnail thumbnail = new Thumbnail();
+		thumbnail.setAspect(1); // Keep aspect
+		thumbnail.setFirst(Boolean.TRUE); // First page only
+		thumbnail.setWidth(Integer.valueOf(maxWidth));
+		thumbnail.setHeight(Integer.valueOf(maxHeight));
+		conversionParams.setThumbnail(thumbnail);
+	
+		return conversionParams;
+	}
+	
+	private void signConversionParams(ConversionParams conversionParams) {
+		@SuppressWarnings("unchecked")
+		Map<String, Object> clainmsMap = objectMapper.convertValue(conversionParams, Map.class);
+		String token = onlyOfficeSecurityService.getToken(clainmsMap);
+		conversionParams.setToken(token);
+	}
+
+	private boolean tryCreateThumbnail(ConversionParams conversionParams, VFSLeaf thumbnailLeaf) throws JsonProcessingException {
+		boolean thumbnailCreated = false;
+		
+		ConversionResult conversionResult = sendCreateThumbnailRequest(conversionParams);
+		if (conversionResult != null) {
+			Integer error = conversionResult.getError();
+			if (error == null) {
+				if (conversionResult.getEndConvert() != null && conversionResult.getEndConvert().booleanValue()) {
+					String fileUrl = conversionResult.getFileUrl();
+					if (StringHelper.containsNonWhitespace(fileUrl)) {
+						thumbnailCreated = fetchThumbnail(thumbnailLeaf, fileUrl);
+					}
+				}
+			} else {
+				logConversionError(error);
+			}
+		}
+		
+		return thumbnailCreated;
+	}
+
+	private ConversionResult sendCreateThumbnailRequest(ConversionParams conversionParams)
+			throws JsonProcessingException {
+		HttpPost request = new HttpPost(onlyOfficeModule.getConversionUrl());
+		request.setHeader("Accept", "application/json");
+		request.addHeader("Authorization", getAutorisationHeader(conversionParams));
+		
+		StringEntity requestEntity = new StringEntity(objectMapper.writeValueAsString(conversionParams), ContentType.APPLICATION_JSON);
+		request.setEntity(requestEntity);
+
+		ConversionResult conversionResult = null;
+		try (CloseableHttpClient client = HttpClientBuilder.create().build();
+				CloseableHttpResponse response = client.execute(request)) {
+			int statusCode = response.getStatusLine().getStatusCode();
+			log.debug("Status code of create thumbnail request: {}", statusCode);
+			
+			if (statusCode == HttpStatus.SC_OK) {
+				String json = EntityUtils.toString(response.getEntity(), "UTF-8");
+				log.debug("Conversion response: {}", json);
+				conversionResult = objectMapper.readValue(json, ConversionResult.class);
+			}
+		} catch (Exception e) {
+			log.error("Create thumbnail request error.", e);
+		}
+		return conversionResult;
+	}
+	
+	private String getAutorisationHeader(ConversionParams conversionParams) {
+		Map<String, Object> payloadMap = new HashMap<>();
+		payloadMap.put("payload", conversionParams);
+		String payloadToken = onlyOfficeSecurityService.getToken(payloadMap);
+		return "Bearer " + payloadToken;
+	}
+	
+	private boolean fetchThumbnail(VFSLeaf thumbnailLeaf, String fileUrl) {
+		boolean thumbnailCreated = false;
+		
+		HttpGet downLoadRequest = new HttpGet(fileUrl);
+		try (CloseableHttpClient httpClient = HttpClients.createDefault();
+				CloseableHttpResponse httpResponse = httpClient.execute(downLoadRequest);) {
+			if (httpResponse.getStatusLine().getStatusCode() == 200) {
+				InputStream content = httpResponse.getEntity().getContent();
+				thumbnailCreated = VFSManager.copyContent(content, thumbnailLeaf);
+			} else {
+				log.warn("Get thumbnail from ONLYOFICE failed. URL: {}", fileUrl);
+			}
+		} catch (Exception e) {
+			log.error("Get thumbnail from ONLYOFICE failed. URL: {}", fileUrl, e);
+		}
+		return thumbnailCreated;
+	}
+
+	/**
+	 * See https://api.onlyoffice.com/editors/conversionapi#error
+	 *
+	 * @param error
+	 */
+	private void logConversionError(Integer error) {
+		String description;
+		switch (error.intValue()) {
+		case -1: description = "Unknown error.";
+			break;
+		case -2: description = "Conversion timeout error.";
+			break;
+		case -3: description = "Conversion error.";
+			break;
+		case -4: description = "Error while downloading the document file to be converted.";
+			break;
+		case -5: description = "Incorrect password.";
+			break;
+		case -6: description = "Error while accessing the conversion result database.";
+			break;
+		case -7: description = "Input error.";
+			break;
+		case -8: description = "Invalid token.";
+			break;
+		default:
+			description = "???.";
+			break;
+		}
+		log.warn("ONLYOFFICE conversion response error. Code {}: {}", error, description);
+	}
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeSecurityServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeSecurityServiceImpl.java
index 4e716050b29e6d687e33e3dd0cc26d63038192c9..e00df13d8ff4479f26fc72653087ff938f83f751 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeSecurityServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeSecurityServiceImpl.java
@@ -21,15 +21,16 @@ package org.olat.core.commons.services.doceditor.onlyoffice.manager;
 
 import java.io.IOException;
 import java.security.Key;
+import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.core.commons.services.doceditor.onlyoffice.Callback;
+import org.olat.core.commons.services.doceditor.onlyoffice.Document;
+import org.olat.core.commons.services.doceditor.onlyoffice.EditorConfig;
 import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeModule;
 import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeSecurityService;
 import org.olat.core.commons.services.doceditor.onlyoffice.model.CallbackImpl;
-import org.olat.core.commons.services.doceditor.onlyoffice.model.DocumentImpl;
-import org.olat.core.commons.services.doceditor.onlyoffice.model.EditorConfigImpl;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -102,7 +103,7 @@ public class OnlyOfficeSecurityServiceImpl implements OnlyOfficeSecurityService
 	}
 
 	@Override
-	public String getApiConfigToken(DocumentImpl document, EditorConfigImpl editorConfig) {
+	public String getApiConfigToken(Document document, EditorConfig editorConfig) {
 		return Jwts.builder()
 				.claim("document", document)
 				.claim("editorConfig", editorConfig)
@@ -118,4 +119,12 @@ public class OnlyOfficeSecurityServiceImpl implements OnlyOfficeSecurityService
 				.compact();
 	}
 
+	@Override
+	public String getToken(Map<String, Object> claims) {
+		return Jwts.builder()
+				.setClaims(claims)
+				.signWith(onlyOfficeModule.getJwtSignKey())
+				.compact();
+	}
+
 }
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
index 1cf1869b04b5930f470fb94b8396deddb920b3fe..189561294bfa86d0d8611f079701f626035a2846 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
@@ -272,6 +272,7 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService {
 		if (updated) {
 			log.debug("File updated. File name: " + vfsLeaf.getName());
 			refreshLock(vfsLeaf);
+			vfsRepositoryService.resetThumbnails(vfsLeaf);
 		}
 		
 		return updated;
@@ -289,10 +290,10 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService {
 	public boolean isEditLicenseAvailable() {
 		Integer licenseEdit = onlyOfficeModule.getLicenseEdit();
 		if (licenseEdit == null) return true;
-		if (licenseEdit.intValue() == 0) return false;
+		if (licenseEdit.intValue() <= 0) return false;
 		
 		Long accessCount = documentEditorServie.getAccessCount(OnlyOfficeEditor.TYPE, Mode.EDIT);
-		return accessCount < licenseEdit.byteValue();
+		return accessCount < licenseEdit.intValue();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeThumbnailSPI.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeThumbnailSPI.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d1c6a308163f4bf1863e2bd0b048c49571b4c12
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeThumbnailSPI.java
@@ -0,0 +1,74 @@
+/**
+ * <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.services.doceditor.onlyoffice.manager;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeConversionService;
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeModule;
+import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException;
+import org.olat.core.commons.services.thumbnail.FinalSize;
+import org.olat.core.commons.services.thumbnail.ThumbnailSPI;
+import org.olat.core.util.vfs.VFSLeaf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ * Initial date: 4 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class OnlyOfficeThumbnailSPI implements ThumbnailSPI {
+
+	// https://api.onlyoffice.com/editors/conversionapi#text-matrix
+	private static final List<String> PNG_OUTPUT_EXTENSION = Arrays.asList(
+			// Text document file formats
+			"doc", "docm", "docx", "dot", "dotm", "dotx", "epub", "fodt", "html", "mht", "odt", "ott",
+			//"pdf", // PDFToThumbnail
+			"rtf", "txt",
+			// Spreadsheet file formats
+			"xps", "csv", "fods", "ods", "ots", "xls", "xlsm", "xlsx", "xlt", "xltm", "xltx",
+			// https://api.onlyoffice.com/editors/conversionapi#presentation-matrix
+			"fodp", "odp", "otp", "pot", "potm", "potx", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx");
+	
+	@Autowired
+	private OnlyOfficeModule onlyOfficeModule;
+	@Autowired
+	private OnlyOfficeConversionService onlyOfficeConversionService;
+	
+	@Override
+	public List<String> getExtensions() {
+		if (onlyOfficeModule.isEnabled() && onlyOfficeModule.isThumbnailsEnabled()) {
+			return PNG_OUTPUT_EXTENSION;
+		}
+		return Collections.emptyList();
+	}
+
+	@Override
+	public FinalSize generateThumbnail(VFSLeaf file, VFSLeaf thumbnailFile, int maxWidth, int maxHeight, boolean fill)
+			throws CannotGenerateThumbnailException {
+		return onlyOfficeConversionService.createThumbnail(file, thumbnailFile, maxWidth, maxHeight);
+	}
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionParams.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionParams.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2e64873f7d5a0113e6b0c0c2a8ef36e58eecc7c
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionParams.java
@@ -0,0 +1,97 @@
+/**
+ * <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.services.doceditor.onlyoffice.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * 
+ * Initial date: 4 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ConversionParams {
+	
+	private String filetype;
+	private String key;
+	private String outputtype;
+	private Thumbnail thumbnail;
+	private String title;
+	private String url;
+	private String token;
+	
+	public String getFiletype() {
+		return filetype;
+	}
+	
+	public void setFiletype(String filetype) {
+		this.filetype = filetype;
+	}
+	
+	public String getKey() {
+		return key;
+	}
+	
+	public void setKey(String key) {
+		this.key = key;
+	}
+	
+	public String getOutputtype() {
+		return outputtype;
+	}
+	
+	public void setOutputtype(String outputtype) {
+		this.outputtype = outputtype;
+	}
+	
+	public Thumbnail getThumbnail() {
+		return thumbnail;
+	}
+	
+	public void setThumbnail(Thumbnail thumbnail) {
+		this.thumbnail = thumbnail;
+	}
+	
+	public String getTitle() {
+		return title;
+	}
+	
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	public String getUrl() {
+		return url;
+	}
+	
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionResult.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..7677f1c66763a5347bb0c8a3b5bfbaa5788075b3
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/ConversionResult.java
@@ -0,0 +1,70 @@
+/**
+ * <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.services.doceditor.onlyoffice.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * 
+ * Initial date: 9 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ConversionResult {
+	
+	private Boolean endConvert;
+	private String fileUrl;
+	private Integer percent;
+	private Integer error;
+	
+	public Boolean getEndConvert() {
+		return endConvert;
+	}
+	
+	public void setEndConvert(Boolean endConvert) {
+		this.endConvert = endConvert;
+	}
+	
+	public String getFileUrl() {
+		return fileUrl;
+	}
+	
+	public void setFileUrl(String fileUrl) {
+		this.fileUrl = fileUrl;
+	}
+	
+	public Integer getPercent() {
+		return percent;
+	}
+	
+	public void setPercent(Integer percent) {
+		this.percent = percent;
+	}
+
+	public Integer getError() {
+		return error;
+	}
+
+	public void setError(Integer error) {
+		this.error = error;
+	}
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/Thumbnail.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/Thumbnail.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e1b73cbabed86a9fb6f51dd09674f5b7f994647
--- /dev/null
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/model/Thumbnail.java
@@ -0,0 +1,67 @@
+/**
+ * <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.services.doceditor.onlyoffice.model;
+
+/**
+ * 
+ * Initial date: 4 Sep 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class Thumbnail {
+	
+	private Integer aspect;
+	private Boolean first;
+	private Integer height;
+	private Integer width;
+	
+	public Integer getAspect() {
+		return aspect;
+	}
+	
+	public void setAspect(Integer aspect) {
+		this.aspect = aspect;
+	}
+	
+	public Boolean getFirst() {
+		return first;
+	}
+	
+	public void setFirst(Boolean first) {
+		this.first = first;
+	}
+	
+	public Integer getHeight() {
+		return height;
+	}
+	
+	public void setHeight(Integer height) {
+		this.height = height;
+	}
+	
+	public Integer getWidth() {
+		return width;
+	}
+	
+	public void setWidth(Integer width) {
+		this.width = width;
+	}
+
+}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
index 7f1733e575e8d7716ed93c1280fe3b74f3939df3..0fc9e04d4f439b9ef1a83a6929d57be90f61ebe9 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
@@ -94,7 +94,7 @@ public class OnlyOfficeWebService {
 		log.debug("ONLYOFFICE REST post callback request for File ID: " + fileId);
 		logRequestHeaders(httpHeaders);
 		
-		if (!onlyOfficeModule.isEnabled()) {
+		if (!onlyOfficeModule.isEnabled() || !onlyOfficeModule.isEditorEnabled()) {
 			return Response.serverError().status(Status.FORBIDDEN).build();
 		}
 		
@@ -223,7 +223,7 @@ public class OnlyOfficeWebService {
 		log.debug("ONLYOFFICE REST get file contents request for File ID: " + fileId);
 		logRequestHeaders(httpHeaders);
 		
-		if (!onlyOfficeModule.isEnabled()) {
+		if (!onlyOfficeModule.isEnabled() || !onlyOfficeModule.isEditorEnabled()) {
 			return Response.serverError().status(Status.FORBIDDEN).build();
 		}
 		
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeAdminController.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeAdminController.java
index eaae06d19c23a5ab0c6fc99cbca8b0ec6bc5e4bd..68a1a4d5e5243398fdb996e4a07ad8a53bd1c15a 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeAdminController.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeAdminController.java
@@ -31,10 +31,13 @@ import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeSecuritySer
 import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeService;
 import org.olat.core.commons.services.doceditor.ui.DocEditorController;
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
+import org.olat.core.gui.components.form.flexible.elements.StaticTextElement;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
 import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
@@ -59,9 +62,13 @@ public class OnlyOfficeAdminController extends FormBasicController {
 	private MultipleSelectionElement enabledEl;
 	private TextElement baseUrlEl;
 	private TextElement jwtSecretEl;
+	private MultipleSelectionElement editorEnabledEl;
+	private MultipleSelectionElement viewOnlyEl;
 	private MultipleSelectionElement dataTransferConfirmationEnabledEl;
 	private TextElement licenseEditEl;
+	private StaticTextElement licenseInUseEl;
 	private MultipleSelectionElement usageRolesEl;
+	private MultipleSelectionElement thumbnailsEnabledEl;
 
 	@Autowired
 	private OnlyOfficeModule onlyOfficeModule;
@@ -74,6 +81,7 @@ public class OnlyOfficeAdminController extends FormBasicController {
 		super(ureq, wControl);
 		setTranslator(Util.createPackageTranslator(DocEditorController.class, getLocale(), getTranslator()));
 		initForm(ureq);
+		updateUI();
 	}
 
 	@Override
@@ -81,7 +89,9 @@ public class OnlyOfficeAdminController extends FormBasicController {
 		setFormTitle("admin.title");
 		setFormDescription("admin.desc");
 		
-		enabledEl = uifactory.addCheckboxesHorizontal("admin.enabled", formLayout, ENABLED_KEYS, translateAll(getTranslator(), ENABLED_KEYS));
+		// General
+		String[] enabledValues = translateAll(getTranslator(), ENABLED_KEYS);
+		enabledEl = uifactory.addCheckboxesHorizontal("admin.enabled", formLayout, ENABLED_KEYS, enabledValues);
 		enabledEl.select(ENABLED_KEYS[0], onlyOfficeModule.isEnabled());
 		
 		String url = onlyOfficeModule.getBaseUrl();
@@ -92,19 +102,23 @@ public class OnlyOfficeAdminController extends FormBasicController {
 		jwtSecretEl = uifactory.addTextElement("admin.jwt.secret", 128, secret, formLayout);
 		jwtSecretEl.setMandatory(true);
 		
+		// Editor
+		uifactory.addSpacerElement("spacer.editor", formLayout, false);
+		
+		editorEnabledEl = uifactory.addCheckboxesHorizontal("admin.editor.enabled", formLayout, ENABLED_KEYS, enabledValues);
+		editorEnabledEl.addActionListener(FormEvent.ONCHANGE);
+		editorEnabledEl.select(ENABLED_KEYS[0], onlyOfficeModule.isEditorEnabled());
+
 		dataTransferConfirmationEnabledEl = uifactory.addCheckboxesHorizontal(
-				"admin.data.transfer.confirmation.enabled", formLayout, ENABLED_KEYS,
-				translateAll(getTranslator(), ENABLED_KEYS));
-		dataTransferConfirmationEnabledEl.select(ENABLED_KEYS[0], onlyOfficeModule.isDataTransferConfirmationEnabled());
+				"admin.data.transfer.confirmation.enabled", formLayout, ENABLED_KEYS, enabledValues);
 		
-		String licenseEdit = onlyOfficeModule.getLicenseEdit() != null
-				? onlyOfficeModule.getLicenseEdit().toString()
-				: null;
-		licenseEditEl = uifactory.addTextElement("admin.license.edit", 10, licenseEdit, formLayout);
+		viewOnlyEl = uifactory.addCheckboxesHorizontal("admin.view.only", formLayout, ENABLED_KEYS, enabledValues);
+		viewOnlyEl.setHelpTextKey("admin.view.only.help", null);
+		viewOnlyEl.addActionListener(FormEvent.ONCHANGE);
 		
-		Long editLicensesInUse = onlyOfficeService.getEditLicensesInUse();
-		editLicensesInUse = editLicensesInUse != null? editLicensesInUse: 0;
-		uifactory.addStaticTextElement("admin.license.edit.in.use", editLicensesInUse.toString(), formLayout);
+		licenseEditEl = uifactory.addTextElement("admin.license.edit", 10, "", formLayout);
+		
+		licenseInUseEl = uifactory.addStaticTextElement("admin.license.edit.in.use", "", formLayout);
 		
 		KeyValues usageRolesKV = new KeyValues();
 		usageRolesKV.add(entry(USAGE_AUTHOR, translate("admin.usage.roles.author")));
@@ -112,15 +126,74 @@ public class OnlyOfficeAdminController extends FormBasicController {
 		usageRolesKV.add(entry(USAGE_MANAGERS, translate("admin.usage.roles.managers")));
 		usageRolesEl = uifactory.addCheckboxesVertical("admin.usage.roles", formLayout, usageRolesKV.keys(), usageRolesKV.values(), 1);
 		usageRolesEl.setHelpTextKey("admin.usage.roles.help", null);
-		usageRolesEl.select(USAGE_AUTHOR, onlyOfficeModule.isUsageRestrictedToAuthors());
-		usageRolesEl.select(USAGE_COACH, onlyOfficeModule.isUsageRestrictedToCoaches());
-		usageRolesEl.select(USAGE_MANAGERS, onlyOfficeModule.isUsageRestrictedToManagers());
+		
+		// Thumbnails
+		uifactory.addSpacerElement("spacer.thumbnails", formLayout, false);
+		
+		thumbnailsEnabledEl = uifactory.addCheckboxesHorizontal("admin.thumbnails.enabled", formLayout, ENABLED_KEYS, enabledValues);
+		thumbnailsEnabledEl.select(ENABLED_KEYS[0], onlyOfficeModule.isThumbnailsEnabled());
 		
 		FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
 		formLayout.add("buttons", buttonLayout);
 		uifactory.addFormSubmitButton("save", buttonLayout);
 	}
 	
+	private void initEditorValues() {
+		dataTransferConfirmationEnabledEl.select(ENABLED_KEYS[0], onlyOfficeModule.isDataTransferConfirmationEnabled());
+		
+		Integer licenseEdit = onlyOfficeModule.getLicenseEdit();
+		boolean viewOnly = licenseEdit != null && licenseEdit.intValue() <= 0;
+		viewOnlyEl.select(ENABLED_KEYS[0], viewOnly);
+		
+		usageRolesEl.select(USAGE_AUTHOR, onlyOfficeModule.isUsageRestrictedToAuthors());
+		usageRolesEl.select(USAGE_COACH, onlyOfficeModule.isUsageRestrictedToCoaches());
+		usageRolesEl.select(USAGE_MANAGERS, onlyOfficeModule.isUsageRestrictedToManagers());
+	}
+
+	private void initLicenseValues() {
+		Integer licenseEdit = onlyOfficeModule.getLicenseEdit();
+		String licenseEditValue = licenseEdit != null && licenseEdit.intValue() > -1? licenseEdit.toString() : null;
+		licenseEditEl.setValue(licenseEditValue);
+		
+		Long editLicensesInUse = onlyOfficeService.getEditLicensesInUse();
+		editLicensesInUse = editLicensesInUse != null? editLicensesInUse: 0;
+		licenseInUseEl.setValue(editLicensesInUse.toString());
+	}
+	
+	private void updateUI() {
+		boolean editorEnabled = editorEnabledEl.isAtLeastSelected(1);
+		if (editorEnabled) {
+			initEditorValues();
+		}
+		dataTransferConfirmationEnabledEl.setVisible(editorEnabled);
+		viewOnlyEl.setVisible(editorEnabled);
+		usageRolesEl.setVisible(editorEnabled);
+		
+		updateLicenseUI();
+	}
+
+	private void updateLicenseUI() {
+		boolean editorEnabled = editorEnabledEl.isAtLeastSelected(1);
+		boolean notViewOnly = !viewOnlyEl.isAtLeastSelected(1);
+		
+		if (editorEnabled && notViewOnly) {
+			initLicenseValues();
+		}
+		
+		licenseEditEl.setVisible(editorEnabled && notViewOnly);
+		licenseInUseEl.setVisible(editorEnabled && notViewOnly);
+	}
+	
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if (source == editorEnabledEl) {
+			updateUI();
+		} else if (source == viewOnlyEl) {
+			updateLicenseUI();
+		}
+		super.formInnerEvent(ureq, source, event);
+	}
+
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
 		boolean allOk = true;
@@ -153,19 +226,31 @@ public class OnlyOfficeAdminController extends FormBasicController {
 		String jwtSecret = jwtSecretEl.getValue();
 		onlyOfficeModule.setJwtSecret(jwtSecret);
 		
-		boolean dataTransferConfirmationEnabled = dataTransferConfirmationEnabledEl.isAtLeastSelected(1);
-		onlyOfficeModule.setDataTransferConfirmationEnabled(dataTransferConfirmationEnabled);
+		boolean editorEnabled = editorEnabledEl.isAtLeastSelected(1);
+		onlyOfficeModule.setEditorEnabled(editorEnabled);
 		
-		String licenseEditValue = licenseEditEl.getValue();
-		Integer licenseEdit = StringHelper.containsNonWhitespace(licenseEditValue)
-				? Integer.valueOf(licenseEditValue)
-				: null;
-		onlyOfficeModule.setLicenseEdit(licenseEdit);
+		if (editorEnabled) {
+			boolean dataTransferConfirmationEnabled = dataTransferConfirmationEnabledEl.isAtLeastSelected(1);
+			onlyOfficeModule.setDataTransferConfirmationEnabled(dataTransferConfirmationEnabled);
+			
+			Integer licenseEdit = -1;
+			boolean viewOnly = viewOnlyEl.isAtLeastSelected(1);
+			if (!viewOnly) {
+				String licenseEditValue = licenseEditEl.getValue();
+				licenseEdit = StringHelper.containsNonWhitespace(licenseEditValue)
+						? Integer.valueOf(licenseEditValue)
+						: null;
+			}
+			onlyOfficeModule.setLicenseEdit(licenseEdit);
+			
+			Collection<String> restrictionKeys = usageRolesEl.getSelectedKeys();
+			onlyOfficeModule.setUsageRestrictedToAuthors(restrictionKeys.contains(USAGE_AUTHOR));
+			onlyOfficeModule.setUsageRestrictedToCoaches(restrictionKeys.contains(USAGE_COACH));
+			onlyOfficeModule.setUsageRestrictedToManagers(restrictionKeys.contains(USAGE_MANAGERS));
+		}
 		
-		Collection<String> restrictionKeys = usageRolesEl.getSelectedKeys();
-		onlyOfficeModule.setUsageRestrictedToAuthors(restrictionKeys.contains(USAGE_AUTHOR));
-		onlyOfficeModule.setUsageRestrictedToCoaches(restrictionKeys.contains(USAGE_COACH));
-		onlyOfficeModule.setUsageRestrictedToManagers(restrictionKeys.contains(USAGE_MANAGERS));
+		boolean thumbnailsEnabled = thumbnailsEnabledEl.isAtLeastSelected(1);
+		onlyOfficeModule.setThumbnailsEnabled(thumbnailsEnabled);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
index e7b2de05fa97be7b819c23b2761c6af9f741ba14..d4e8901e9c4d0ed497023ffaaf33da3a30b8677d 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
@@ -53,7 +53,6 @@ public class OnlyOfficeEditorController extends BasicController {
 	private static final Logger log = Tracing.createLoggerFor(OnlyOfficeEditorController.class);
 	
 	private Access access;
-	private Mode openMode;
 	private Long openVfsMetadataKey;
 	
 	@Autowired
@@ -129,7 +128,7 @@ public class OnlyOfficeEditorController extends BasicController {
 	
 	private void deleteAccess() {
 		if (access != null) {
-			log.info("Document (key={}) closed with ONLYOFFICE ({}) by {}", openVfsMetadataKey, openMode,
+			log.info("Document (key={}) closed with ONLYOFFICE ({}) by {}", openVfsMetadataKey, access.getMode(),
 					getIdentity());
 			docEditorService.deleteAccess(access);
 		}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_de.properties
index 32092792ac86118ae1c661379e4c46af609f5f89..95d485962f781789fe16abda8315b4e929d751df 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_de.properties
@@ -1,11 +1,15 @@
 admin.base.url=URL
 admin.desc=ONLYOFFICE ist eine Software zur einzelnen oder gemeinsamen Bearbeitung von Dokumenten. Es unterst\u00FCtzt alle g\u00E4ngigen Dateiformate zur Textverarbeitung, Tabellenkalkulation und Pr\u00E4sentationen. Weitere Informationen sind auf der <a href\="http\://www.onlyoffice.com/" target\=_blank>Webseite</a> von ONLYOFFICE zu finden.
+admin.editor.enabled=Dokumenteneditor
 admin.license.edit=Verf\u00FCgbare Bearbeitungslizenzen
 admin.license.edit.in.use=Aktuelle genutzte Bearbeitungslizenzen
 admin.enabled=Modul "ONLYOFFICE"
 admin.jwt.secret=Secret
 admin.jwt.secret.invalid=Das Secret ist nicht g\u00FCltig. Vermutlich ist es zu kurz. Siehe: JWA Specification (RFC 7518, Section 3.2).
 admin.title=ONLYOFFICE
+admin.thumbnails.enabled=Thumbnails
+admin.view.only=Bearbeitung nicht zulassen
+admin.view.only.help=Durch das Aktivieren dieser Option, wird ONLYOFFICE nur zur Anzeige von Dokumenten verwendet. Diese k\u00F6nnen jedoch nicht mit ONLYOFFICE bearbeitet werden.
 editor.display.name=ONLYOFFICE
 editor.warning.locked=Das Dokument wird bereits in einem anderen Editor bearbeitet und kann deshalb in ONLYOFFICE nicht bearbeitet werden.
 editor.warning.no.api.config=Dieses Dokument kann nicht angezeigt werden!
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_en.properties
index 308c424badde843cfaaaf30d4df3bcd0e8efed78..eb29a3b2413e24a67b38c8f44ca4bfd9b9c49041 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/_i18n/LocalStrings_en.properties
@@ -1,11 +1,15 @@
 admin.base.url=URL
 admin.desc=ONLYOFFICE is a software to edit documents online. It supports all major document, spreadsheet and presentation file formats. Key features are collaborative editing and excellent office file format support. Further information is available on the <a href\="https\://www.onlyoffice.com/" target\=_blank>website</a> of ONLYOFFICE
+admin.editor.enabled=Document editor
 admin.license.edit=Available edit licenses
 admin.license.edit.in.use=Edit licenses in use
 admin.enabled=Module "ONLYOFFICE"
 admin.jwt.secret=Secret
 admin.jwt.secret.invalid=The secret is not valid. Probably it is too short. See: JWA Specification (RFC 7518, Section 3.2).
 admin.title=ONLYOFFICE
+admin.thumbnails.enabled=Thumbnails
+admin.view.only=Editing suppressed
+admin.view.only.help=By activating this option, ONLYOFFICE is only used to display documents. However, they cannot be edited with ONLYOFFICE.
 editor.display.name=ONLYOFFICE
 editor.warning.locked=That document is already edited in another editor and therefore it is displayed in a read-only view.
 editor.warning.no.api.config=It is not possible to display that document!
diff --git a/src/main/java/org/olat/core/commons/services/thumbnail/_spring/thumbnailserviceContext.xml b/src/main/java/org/olat/core/commons/services/thumbnail/_spring/thumbnailserviceContext.xml
deleted file mode 100644
index cb96ce634d776c7beeac4f3e07547d34cf5e6435..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/core/commons/services/thumbnail/_spring/thumbnailserviceContext.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="
-  http://www.springframework.org/schema/beans 
-  http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-	<!-- Define commenting and rating service implementation. Remove this bean if you don't want this service to be enabled at all -->
-	<bean id="thumbnailService" class="org.olat.core.commons.services.thumbnail.impl.ThumbnailServiceImpl">	
-		<property name="thumbnailSPIes">
-			<list>
-				<bean class="org.olat.core.commons.services.thumbnail.impl.ImageToThumbnail">
-					<property name="imageHelper" ref="imageHelper"/>
-				</bean>
-				<bean class="org.olat.core.commons.services.thumbnail.impl.PDFToThumbnail">
-					<property name="imageHelper" ref="imageHelper"/>
-				</bean>
-				<ref bean="movieService"/>
-			</list>
-		</property>
-	</bean>
-	
-</beans>
diff --git a/src/main/java/org/olat/core/commons/services/thumbnail/impl/ImageToThumbnail.java b/src/main/java/org/olat/core/commons/services/thumbnail/impl/ImageToThumbnail.java
index b23b99e291057ae223df9e3f21a9a2aa4d53205f..7d2c94c18fb12c7f4755412f96a6629c801bbc82 100644
--- a/src/main/java/org/olat/core/commons/services/thumbnail/impl/ImageToThumbnail.java
+++ b/src/main/java/org/olat/core/commons/services/thumbnail/impl/ImageToThumbnail.java
@@ -23,6 +23,7 @@ package org.olat.core.commons.services.thumbnail.impl;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.annotation.PostConstruct;
 import javax.imageio.ImageIO;
 
 import org.olat.core.commons.services.image.ImageService;
@@ -30,6 +31,8 @@ import org.olat.core.commons.services.image.Size;
 import org.olat.core.commons.services.thumbnail.FinalSize;
 import org.olat.core.commons.services.thumbnail.ThumbnailSPI;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 
@@ -40,28 +43,21 @@ import org.olat.core.util.vfs.VFSLeaf;
  * Initial Date:  30 mar. 2010 <br>
  * @author srosse, stephane.rosse@frentix.com
  */
+@Service
 public class ImageToThumbnail implements ThumbnailSPI {
 	
 	private final List<String> extensions = new ArrayList<>();
 	
+	@Autowired
 	private ImageService imageHelper;
-	
-	/**
-	 * [used by Spring]
-	 * @param imageHelper
-	 */
-	public void setImageHelper(ImageService imageHelper) {
-		this.imageHelper = imageHelper;
-	}
 
-
-	public ImageToThumbnail() {
+	@PostConstruct
+	private void initExtensions() {
 		for(String imageIOSuffix : ImageIO.getWriterFileSuffixes()) {
 			extensions.add(imageIOSuffix);
 		}
 	}
 	
-	
 	@Override
 	public List<String> getExtensions() {
 		return extensions;
diff --git a/src/main/java/org/olat/core/commons/services/thumbnail/impl/PDFToThumbnail.java b/src/main/java/org/olat/core/commons/services/thumbnail/impl/PDFToThumbnail.java
index 286380428afc7da8c3ece5b7df90d0703bf79c01..5eda931f4fd9afaee7835473e91afb0b287d5285 100644
--- a/src/main/java/org/olat/core/commons/services/thumbnail/impl/PDFToThumbnail.java
+++ b/src/main/java/org/olat/core/commons/services/thumbnail/impl/PDFToThumbnail.java
@@ -29,6 +29,8 @@ import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException
 import org.olat.core.commons.services.thumbnail.FinalSize;
 import org.olat.core.commons.services.thumbnail.ThumbnailSPI;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 
@@ -38,17 +40,14 @@ import org.olat.core.util.vfs.VFSLeaf;
  * <P>
  * Initial Date:  30 mar. 2010 <br>
  * @author srosse, stephane.rosse@frentix.com
- */
+ */ @Service
 public class PDFToThumbnail implements ThumbnailSPI {
 
 	private List<String> extensions = Collections.singletonList("pdf");
 	
+	@Autowired
 	private ImageService imageHelper;
 	
-	/**
-	 * [used by Spring]
-	 * @param imageHelper
-	 */
 	public void setImageHelper(ImageService imageHelper) {
 		this.imageHelper = imageHelper;
 	}
diff --git a/src/main/java/org/olat/core/commons/services/thumbnail/impl/ThumbnailServiceImpl.java b/src/main/java/org/olat/core/commons/services/thumbnail/impl/ThumbnailServiceImpl.java
index c7fb49d06cc940d53709fb99fda46a058c514bb3..f73b227c956c1d2e286e41735f55fc492989f0d4 100644
--- a/src/main/java/org/olat/core/commons/services/thumbnail/impl/ThumbnailServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/thumbnail/impl/ThumbnailServiceImpl.java
@@ -20,7 +20,6 @@
 
 package org.olat.core.commons.services.thumbnail.impl;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException;
@@ -30,6 +29,8 @@ import org.olat.core.commons.services.thumbnail.ThumbnailService;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 
@@ -40,9 +41,11 @@ import org.olat.core.util.vfs.VFSLeaf;
  * Initial Date:  30 mar. 2010 <br>
  * @author srosse, stephane.rosse@frentix.com
  */
+@Service
 public class ThumbnailServiceImpl implements ThumbnailService {
 
-	private final List<ThumbnailSPI> thumbnailSPIes = new ArrayList<>();
+	@Autowired
+	private List<ThumbnailSPI> thumbnailSPIes;
 	
 	public ThumbnailServiceImpl() {
 		//
diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
index 6b9a7585ffa4c75526e400dbe82eb0a0b23d9a9a..359b4908879b1e338081ad8642c515a92e5b64df 100644
--- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java
@@ -696,6 +696,7 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv
 			try {
 				FinalSize finalSize = thumbnailService.generateThumbnail(file, thumbnailLeaf, maxWidth, maxHeight, fill);
 				if(finalSize == null) {
+					thumbnailLeaf.deleteSilently();
 					thumbnailLeaf = null;
 					metadata.setCannotGenerateThumbnails(Boolean.TRUE);
 					metadataDao.updateMetadata(metadata);
diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_15_3_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_15_3_0.java
new file mode 100644
index 0000000000000000000000000000000000000000..b09b1db6c83294769de6008a322ad4ba0a6bb836
--- /dev/null
+++ b/src/main/java/org/olat/upgrade/OLATUpgrade_15_3_0.java
@@ -0,0 +1,139 @@
+/**
+ * <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.upgrade;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.olat.core.commons.persistence.DB;
+import org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeModule;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.WebappHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 11 Sept 2020<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class OLATUpgrade_15_3_0 extends OLATUpgrade {
+
+	private static final Logger log = Tracing.createLoggerFor(OLATUpgrade_15_3_0.class);
+
+	private static final String VERSION = "OLAT_15.3.0";
+	private static final String MIGRATE_ONLYOFFICE_CONFIGS = "MIGRATE ONLYOFFICE CONFIGS";
+	private static final String RESET_FAILED_THUMBNAILS = "RESET FAILED THUMBNAILS";
+
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private OnlyOfficeModule onlyofficeModule;
+
+	public OLATUpgrade_15_3_0() {
+		super();
+	}
+	
+	@Override
+	public String getVersion() {
+		return VERSION;
+	}
+
+	@Override
+	public boolean doPostSystemInitUpgrade(UpgradeManager upgradeManager) {
+		UpgradeHistoryData uhd = upgradeManager.getUpgradesHistory(VERSION);
+		if (uhd == null) {
+			// has never been called, initialize
+			uhd = new UpgradeHistoryData();
+		} else if (uhd.isInstallationComplete()) {
+			return false;
+		}
+		
+		boolean allOk = true;
+		allOk &= migrateOnlyOfficeConfigs(upgradeManager, uhd);
+		allOk &= resetFailedThumbnails(upgradeManager, uhd);
+
+		uhd.setInstallationComplete(allOk);
+		upgradeManager.setUpgradesHistory(uhd, VERSION);
+		if(allOk) {
+			log.info(Tracing.M_AUDIT, "Finished OLATUpgrade_15_3_0 successfully!");
+		} else {
+			log.info(Tracing.M_AUDIT, "OLATUpgrade_15_3_0 not finished, try to restart OpenOlat!");
+		}
+		return allOk;
+	}
+
+	private boolean migrateOnlyOfficeConfigs(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
+		boolean allOk = true;
+		if (!uhd.getBooleanDataValue(MIGRATE_ONLYOFFICE_CONFIGS)) {
+			String userDataDirectory = WebappHelper.getUserDataRoot();
+			File configurationPropertiesFile = Paths.get(userDataDirectory, "system", "configuration", "org.olat.core.commons.services.doceditor.onlyoffice.OnlyOfficeModule.properties").toFile();
+			if (configurationPropertiesFile.exists()) {
+				Boolean enabled = null;
+				try (InputStream is = new FileInputStream(configurationPropertiesFile);) {
+					Properties configuredProperties = new Properties();
+					configuredProperties.load(is);
+
+					String enabledProp = configuredProperties.getProperty("onlyoffice.enabled");
+					if (StringHelper.containsNonWhitespace(enabledProp)) {
+						enabled = Boolean.valueOf(enabledProp);
+					}
+				} catch (Exception e) {
+					log.error("Error when reading / writing user properties config file from path::" + configurationPropertiesFile.getAbsolutePath(), e);
+					allOk &= false;
+				}
+				if (enabled != null && enabled.booleanValue()) {
+					onlyofficeModule.setEditorEnabled(true);
+				}
+			}
+			
+			uhd.setBooleanDataValue(MIGRATE_ONLYOFFICE_CONFIGS, allOk);
+			upgradeManager.setUpgradesHistory(uhd, VERSION);
+		}
+		return allOk;
+	}
+
+	private boolean resetFailedThumbnails(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
+		boolean allOk = true;
+		if (!uhd.getBooleanDataValue(RESET_FAILED_THUMBNAILS)) {
+			try {
+				String query = "update filemetadata metadata set metadata.cannotGenerateThumbnails = false where metadata.cannotGenerateThumbnails = true";
+				dbInstance.getCurrentEntityManager()
+						.createQuery(query)
+						.executeUpdate();
+				dbInstance.commitAndCloseSession();
+				log.info("Failed thumbnails reste.");
+			} catch (Exception e) {
+				log.error("", e);
+				allOk = false;
+			}
+			
+			uhd.setBooleanDataValue(RESET_FAILED_THUMBNAILS, allOk);
+			upgradeManager.setUpgradesHistory(uhd, VERSION);
+		}
+		return allOk;
+	}
+	
+}
diff --git a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
index cda77a77c1eb52c7f8b1aa3e2240c1d3a4803db6..d9cc738ac039c85193fee42e60bb34c3af5476ca 100644
--- a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
+++ b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml
@@ -66,6 +66,7 @@
 				<bean id="upgrade_15_2_0" class="org.olat.upgrade.OLATUpgrade_15_2_0"/>
 				<bean id="upgrade_15_2_3" class="org.olat.upgrade.OLATUpgrade_15_2_2"/>
 				<bean id="upgrade_15_2_3_re" class="org.olat.upgrade.OLATUpgrade_15_2_3"/>
+				<bean id="upgrade_15_3_0" class="org.olat.upgrade.OLATUpgrade_15_3_0"/>
 			</list>
 		</property>
 	</bean>
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 721d7943ca25bdf66b8771387270226f16c90e22..a9210072fe1fb1bf5653aa3843c96f7ddab560b6 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -1700,6 +1700,10 @@ collabora.usage.restricted.managers=false
 onlyoffice.enabled=false
 onlyoffice.baseUrl=https://onlyoffice.example.org/
 onlyoffice.api.path=web-apps/apps/api/documents/api.js
+onlyoffice.conversion.path=ConvertService.ashx
+
+## File editor
+onlyoffice.editor.enabled=false
 # Number of usable edit license.
 # You may leave the field blank to supress the licnese check.
 onlyoffice.license.edit=
@@ -1708,6 +1712,8 @@ onlyoffice.usage.restricted.authors=false
 onlyoffice.usage.restricted.coaches=false
 onlyoffice.usage.restricted.managers=false
 
+## Thumbnails
+onlyoffice.thumbnails.enabled=true
 
 ########################################
 # Options for Office 365