diff --git a/src/main/java/org/olat/fileresource/types/FileResource.java b/src/main/java/org/olat/fileresource/types/FileResource.java
index aecac21735826a95b2fe019b2722924161812be6..a1d3f8dbcd8b794495732f57f7297455937c9772 100644
--- a/src/main/java/org/olat/fileresource/types/FileResource.java
+++ b/src/main/java/org/olat/fileresource/types/FileResource.java
@@ -27,6 +27,8 @@ package org.olat.fileresource.types;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.FileSystem;
 import java.nio.file.FileSystems;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
@@ -34,6 +36,11 @@ import java.nio.file.Path;
 import java.nio.file.PathMatcher;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.logging.OLog;
@@ -126,6 +133,63 @@ public class FileResource implements OLATResourceable {
 		return fPath;
 	}
 	
+	public static Path getResource(File file, String filename, String fallbackEncoding)
+	throws IOException {
+		if(!StringHelper.containsNonWhitespace(filename)) {
+			filename = file.getName();
+		}
+		
+		if(!StringHelper.containsNonWhitespace(fallbackEncoding)) {
+			return getResource(file, filename);
+		}
+		
+		Path fPath = null;
+		if(file.isDirectory()) {
+			fPath = file.toPath();
+		} else if(filename != null && filename.toLowerCase().endsWith(".zip")) {
+			//perhaps find root folder and return it
+			Map<String,String> env = new HashMap<>();
+			if(isEncodingOk(file, "UTF-8")) {
+				env.put("encoding", "UTF-8");
+			} else if(isEncodingOk(file, fallbackEncoding)) {
+				env.put("encoding", fallbackEncoding);
+			}
+			
+			fPath = newFileSystem(file.toPath(), env).getPath("/");
+			RootSearcher rootSearcher = searchRootDirectory(fPath);
+			if(rootSearcher.foundRoot()) {
+				Path rootPath = rootSearcher.getRoot();
+				fPath = fPath.resolve(rootPath);
+			}
+		} else {
+			fPath = file.toPath();
+		}
+		return fPath;
+	}
+	
+	private static FileSystem newFileSystem(Path path, Map<String,String> env) throws IOException {
+		for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            try {
+                return provider.newFileSystem(path, env);
+            } catch (UnsupportedOperationException uoe) {
+            	//
+            }
+        }
+		return null;
+	}
+	
+	private static boolean isEncodingOk(File file, String encoding) {
+		boolean ok = false;
+		try(ZipFile zFile = new ZipFile(file, Charset.forName(encoding))) {
+			zFile.stream().forEach(ZipEntry::toString);
+			ok = true;
+		} catch (IOException | IllegalArgumentException e) {
+			//this is what we check
+		}
+		
+		return ok;
+	}
+	
 	protected static  RootSearcher searchRootDirectory(Path fPath)
 	throws IOException {
 		RootSearcher rootSearcher = new RootSearcher();
diff --git a/src/main/java/org/olat/ims/qti21/QTI21Module.java b/src/main/java/org/olat/ims/qti21/QTI21Module.java
index e937a4bf4d695a190fae186cf26d2fd2db20ede2..164b17e42db57bd2abc4ec8017f8f02f2c69a6a7 100644
--- a/src/main/java/org/olat/ims/qti21/QTI21Module.java
+++ b/src/main/java/org/olat/ims/qti21/QTI21Module.java
@@ -62,6 +62,8 @@ public class QTI21Module extends AbstractSpringModule {
 	private String digitalSignatureCertificatePassword;
 	@Value("${qti21.correction.workflow:anonymous}")
 	private String correctionWorkflow;
+	@Value("${qti21.import.encoding.fallback:}")
+	private String importEncodingFallback;
 	
 	@Autowired
 	public QTI21Module(CoordinatorManager coordinatorManager) {
@@ -170,6 +172,10 @@ public class QTI21Module extends AbstractSpringModule {
 		setStringProperty("qti21.digital.signature.certificate.password", digitalSignatureCertificatePassword, true);
 	}
 	
+	public String getImportEncodingFallback() {
+		return importEncodingFallback;
+	}
+
 	public enum CorrectionWorkflow {
 		anonymous,
 		named
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java
index 5573badde5d5b003ed8097f833b83d395ceac463..6b4026e32d7eff9c3a08e0e90fb932b4b6c0ec88 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java
@@ -135,8 +135,10 @@ public class AssessmentHtmlBuilder {
 		content = content.replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
 		content = content.replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
 		content = content.replace("\n   xmlns=\"http://www.imsglobal.org/xsd/imsqti_v2p1\"", "");
+		content = content.replace(" xmlns=\"http://www.imsglobal.org/xsd/imsqti_v2p1\"", "");
 		content = content.replace("xmlns=\"http://www.imsglobal.org/xsd/imsqti_v2p1\"", "");
 		content = content.replace("\n   xsi:schemaLocation=\"http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/imsqti_v2p1.xsd\"", "");
+		content = content.replace(" xsi:schemaLocation=\"http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/imsqti_v2p1.xsd\"", "");
 		content = content.replace("xsi:schemaLocation=\"http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/imsqti_v2p1.xsd\"", "");
 		return content.trim();
 	}
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/BadRessourceHelper.java b/src/main/java/org/olat/ims/qti21/model/xml/BadRessourceHelper.java
index 0d891268701cd162bc8c9acc06d08768919c59b5..cfb83252b571f72249e0d68bbe12d5af11196e4e 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/BadRessourceHelper.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/BadRessourceHelper.java
@@ -19,6 +19,8 @@
  */
 package org.olat.ims.qti21.model.xml;
 
+import java.util.List;
+
 import org.xml.sax.SAXParseException;
 
 import uk.ac.ed.ph.jqtiplus.provision.BadResourceException;
@@ -95,6 +97,13 @@ public class BadRessourceHelper {
     	        		out.append("Fatal: " + lineNumber + ":" + columnNumber + " :: " + msg + "\n");
         			}
         		}
+        		
+        		if(result.getUnsupportedSchemaNamespaces() != null) {
+        			List<String> unsupportedSchemaNamespaces = result.getUnsupportedSchemaNamespaces();
+        			for(String unsupportedSchemaNamespace : unsupportedSchemaNamespaces) {
+    	        		out.append("Error unsupported namespace: " + unsupportedSchemaNamespace + "\n");
+        			}
+        		}
         	}
         }
 	}
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java b/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java
index 64d74d99aef864da13e7e96f03a1090ee03519e4..0ebeda205e6a792363b5ba431e2481f002837fad 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java
@@ -54,7 +54,7 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 {
 	private int pLevel = -1;
 	private int liLevel = -1;
 	private int itemBodySubLevel = -1;
-	private Deque<String> skipTags = new ArrayDeque<String>();
+	private Deque<String> skipTags = new ArrayDeque<>();
 
 	private boolean envelopP = false;
 	
@@ -81,7 +81,7 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 {
 	throws SAXException {
 		try{
 			String comment = new String(ch, start, length);
-			if(comment != null && comment.contains("Onyx Editor")) {
+			if(comment.contains("Onyx Editor")) {
 				int versionIndex = comment.indexOf(VERSION_MARKER);
 				if(versionIndex > 0) {
 					int offset = VERSION_MARKER.length();
@@ -133,7 +133,7 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 {
 				writeAssessmentElement(qName, attributes);
 			} else if("mapTolResponse".equals(qName)) {
 				writeMapTo1ResponseElement(attributes);
-			}else {
+			} else {
 				if(itemBodySubLevel == 0 && !envelopP && !isBlock(qName)) {
 					xtw.writeStartElement("p");
 					envelopP = true;
@@ -212,6 +212,9 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 {
 		for(int i=0;i<numOfAttributes; i++) {
 			String attrQName = attributes.getQName(i);
 			String attrValue = attributes.getValue(i);
+			if("xsi:schemaLocation".equals(attrQName)) {
+				attrValue = attrValue.replace("http://www.w3.org/1998/Math/MathML http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd", "");
+			}
 			xtw.writeAttribute(attrQName, attrValue);
 			if("toolName".equals(attrQName)) {
 				hasToolName = true;
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/OnyxToQtiWorksHandler.java b/src/main/java/org/olat/ims/qti21/model/xml/OnyxToQtiWorksHandler.java
index ca6c0e895aea6fb4991bb49c0f55d0f1dc6aff03..950a39208c51224e85441b0530bd6ca36cc6eb1c 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/OnyxToQtiWorksHandler.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/OnyxToQtiWorksHandler.java
@@ -134,7 +134,9 @@ public class OnyxToQtiWorksHandler extends DefaultHandler2 {
 				writeImgElementAttributes(attributes);
 			} else if("customOperator".equals(qName)) {
 				writeCustomOperatorAttributes(attributes);
-			} else {
+			} else if("mapTolResponse".equals(qName)) {
+				writeMapTo1ResponseElement(attributes);
+			}  else {
 				int numOfAttributes = attributes.getLength();
 				for(int i=0;i<numOfAttributes; i++) {
 					String attrQName = attributes.getQName(i);
@@ -197,6 +199,10 @@ public class OnyxToQtiWorksHandler extends DefaultHandler2 {
 		for(int i=0;i<numOfAttributes; i++) {
 			String attrQName = attributes.getQName(i);
 			String attrValue = attributes.getValue(i);
+			if("xsi:schemaLocation".equals(attrQName)) {
+				attrValue = attrValue.replace("http://www.w3.org/1998/Math/MathML http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd", "");
+			}
+			
 			xtw.writeAttribute(attrQName, attrValue);
 			if("toolName".equals(attrQName)) {
 				hasToolName = true;
@@ -213,6 +219,19 @@ public class OnyxToQtiWorksHandler extends DefaultHandler2 {
 		}
 	}
 	
+	private void writeMapTo1ResponseElement(Attributes attributes)
+	throws XMLStreamException {
+		xtw.writeStartElement("mapResponse");
+		int numOfAttributes = attributes.getLength();
+		for(int i=0;i<numOfAttributes; i++) {
+			String attrQName = attributes.getQName(i);
+			if(!"tolerance".equals(attrQName) && !"toleranceMode".equals(attrQName) && !"xmlns".equals(attrQName)) {
+				String attrValue = attributes.getValue(i);
+				xtw.writeAttribute(attrQName, attrValue);
+			}
+		}
+	}
+	
 	/**
 	 * The customOperator accept the class attribute or the definition attribute but not
 	 * both at the same time.
@@ -268,7 +287,7 @@ public class OnyxToQtiWorksHandler extends DefaultHandler2 {
 	private boolean latexDollarOpen = false;
 	
 	private void processLatexDollar(String text)
-	throws XMLStreamException, SAXException {
+	throws XMLStreamException {
 		for(int i=100; i-->0; ) {
 		
 			int index = text.indexOf("$$");
@@ -297,7 +316,7 @@ public class OnyxToQtiWorksHandler extends DefaultHandler2 {
 	}
 	
 	private void processLatexParenthesis(String text)
-	throws XMLStreamException, SAXException {
+	throws XMLStreamException {
 		for(int i=100; i-->0; ) {
 		
 			int indexOpen = text.indexOf("\\(");
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandler.java b/src/main/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandler.java
index d742171f494395907995e2dac01ba95389ea5935..02bea0c089212d7d872d72401bb51198123feb68 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandler.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandler.java
@@ -28,6 +28,11 @@ import org.xml.sax.SAXException;
 import org.xml.sax.ext.DefaultHandler2;
 
 /**
+ * The handler search the version and the editor in a comment
+ * at the beginning of the file, in the VCARD of imsmanifest,
+ * it will react to some non-standard features like mapTolResponse or
+ * some HTML code erros like <p> in <p>.
+ * 
  * 
  * Initial date: 1 févr. 2017<br>
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
@@ -39,6 +44,7 @@ public class QTI21ExplorerHandler extends DefaultHandler2 {
 	private static final String PRODID_MARKER = "PRODID:";
 	
 	private StringBuilder collector;
+	private int pLevel = -1;
 	private final QTI21Infos infos = new QTI21Infos();
 	
 	public QTI21Infos getInfos() {
@@ -49,7 +55,7 @@ public class QTI21ExplorerHandler extends DefaultHandler2 {
 	public void comment(char[] ch, int start, int length)
 	throws SAXException {
 		String comment = new String(ch, start, length);
-		if(comment != null && comment.contains("Onyx Editor")) {
+		if(comment.contains("Onyx Editor")) {
 			infos.setEditor("Onyx Editor");
 			int versionIndex = comment.indexOf(VERSION_MARKER);
 			if(versionIndex > 0) {
@@ -73,6 +79,17 @@ public class QTI21ExplorerHandler extends DefaultHandler2 {
 			collector = new StringBuilder();
 		} else if("entity".equals(qName)) {
 			collector = new StringBuilder();
+		} else if("mapTolResponse".equals(qName)) {
+			if(!StringHelper.containsNonWhitespace(infos.getEditor())) {
+				infos.setEditor("Onyx Editor");
+				infos.setVersion("3.8.1");
+			}
+		} else if("p".equals(qName)) {
+			pLevel++;
+			if(pLevel == 1 && !StringHelper.containsNonWhitespace(infos.getEditor())) {
+				infos.setEditor("Onyx Editor");
+				infos.setVersion("3.8.1");
+			}
 		}
 	}
 	
@@ -121,6 +138,8 @@ public class QTI21ExplorerHandler extends DefaultHandler2 {
 			}
 			
 			collector = null;
+		} else if("p".equals(qName)) {
+			pLevel--;
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java b/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java
index 388a144d3efad0a5c4f20b7539679471e3b90d7d..19aa0dc79251023c19ce2d9a0f99b45c2365a19c 100644
--- a/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java
+++ b/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java
@@ -50,9 +50,9 @@ import org.olat.core.util.WebappHelper;
 import org.olat.fileresource.types.ImsQTI21Resource;
 import org.olat.fileresource.types.ImsQTI21Resource.PathResourceLocator;
 import org.olat.ims.qti21.QTI21Service;
+import org.olat.ims.qti21.model.xml.AssessmentItemChecker;
 import org.olat.ims.qti21.model.xml.BadRessourceHelper;
 import org.olat.ims.qti21.model.xml.Onyx38ToQtiWorksHandler;
-import org.olat.ims.qti21.model.xml.AssessmentItemChecker;
 import org.olat.ims.qti21.model.xml.OnyxToQtiWorksHandler;
 import org.olat.ims.qti21.model.xml.QTI21ExplorerHandler;
 import org.olat.ims.qti21.model.xml.QTI21Infos;
@@ -108,17 +108,17 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> {
 	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
     throws IOException {
 		Path relativeFile = source.relativize(file);
-        final Path destFile = Paths.get(destDir.toString(), relativeFile.toString());
-        if(filter.matches(file)) {
-        	String filename = file.getFileName().toString();
-        	if(filename.startsWith(".")) {
-        		//ignore
-        	} else if(filename != null && filename.endsWith("xml") && !filename.equals("imsmanifest.xml")) {
-        		convertXmlFile(file, destFile);
-        	} else {
-        		Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING);
-        	}
-        }
+		final Path destFile = Paths.get(destDir.toString(), relativeFile.toString());
+		if(filter.matches(file)) {
+			String filename = file.getFileName().toString();
+			if(filename.startsWith(".")) {
+				//ignore
+			} else if(filename.endsWith("xml") && !filename.equals("imsmanifest.xml")) {
+				convertXmlFile(file, destFile);
+			} else {
+				Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING);
+			}
+		}
         return FileVisitResult.CONTINUE;
 	}
  
@@ -127,7 +127,7 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> {
 	throws IOException {
 		Path relativeDir = source.relativize(dir);
         final Path dirToCreate = Paths.get(destDir.toString(), relativeDir.toString());
-        if(Files.notExists(dirToCreate)){
+        if(!dirToCreate.toFile().exists()) {
         	Files.createDirectory(dirToCreate);
         }
         return FileVisitResult.CONTINUE;
@@ -149,18 +149,12 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> {
 				fileInfos.setVersion(infos.getVersion());
 			}
 			if(onyx38Family(fileInfos)) {
-				validated = convertXmlFile(inputFile, outputFile, fileInfos.getType(), new HandlerProvider() {
-					@Override
-					public DefaultHandler2 create(XMLStreamWriter xtw) {
-						return new Onyx38ToQtiWorksHandler(xtw);
-					}
+				validated = convertXmlFile(inputFile, outputFile, fileInfos.getType(), xtw -> {
+					return new Onyx38ToQtiWorksHandler(xtw);
 				});
 			} else if(onyxWebFamily(fileInfos)) {
-				validated = convertXmlFile(inputFile, outputFile, fileInfos.getType(), new HandlerProvider() {
-					@Override
-					public DefaultHandler2 create(XMLStreamWriter xtw) {
-						return new OnyxToQtiWorksHandler(xtw, infos);
-					}
+				validated = convertXmlFile(inputFile, outputFile, fileInfos.getType(), xtw -> {
+					return new OnyxToQtiWorksHandler(xtw, infos);
 				});
 				
 				if(validated && fileInfos.getType() == InputType.assessmentItem) {
@@ -179,14 +173,14 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> {
 	
 	private boolean onyx38Family(QTI21Infos fileInfos) {
 		if(fileInfos == null || fileInfos.getEditor() == null) return false;
-		String version = infos.getVersion();
-		return "Onyx Editor".equals(infos.getEditor()) && version != null &&
+		String version = fileInfos.getVersion();
+		return "Onyx Editor".equals(fileInfos.getEditor()) && version != null &&
 				(version.startsWith("2.") || version.startsWith("3."));
 	}
 	
 	private boolean onyxWebFamily(QTI21Infos fileInfos) {
 		if(fileInfos == null || fileInfos.getEditor() == null) return false;
-		return "ONYX Editor".equals(infos.getEditor());
+		return "ONYX Editor".equals(fileInfos.getEditor());
 	}
 	
 	private QTI21Infos scanFile(Path inputFile) {
@@ -215,6 +209,9 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> {
 			
 			boolean valid = validate(tmpFile.toPath(), type, true);
 			if(valid) {
+				if(!outputFile.getParent().toFile().exists()) {
+					outputFile.getParent().toFile().mkdirs();
+				}
 				Files.copy(tmpFile.toPath(), outputFile, StandardCopyOption.REPLACE_EXISTING);
 			}
 			return valid;
diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
index 6848439425bbbfebe02c18c3d6e99ea16b1c4980..9209f9cebcc45b126fb57421928158f5eb8e4774 100644
--- a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
+++ b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java
@@ -61,6 +61,7 @@ import org.olat.fileresource.types.ResourceEvaluation;
 import org.olat.ims.qti.editor.QTIEditorPackage;
 import org.olat.ims.qti.fileresource.TestFileResource;
 import org.olat.ims.qti21.QTI21DeliveryOptions;
+import org.olat.ims.qti21.QTI21Module;
 import org.olat.ims.qti21.QTI21Service;
 import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.ims.qti21.model.IdentifierGenerator;
@@ -107,6 +108,8 @@ public class QTI21AssessmentTestHandler extends FileHandler {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private QTI21Module qtiModule;
+	@Autowired
 	private QTI21Service qtiService;
 	@Autowired
 	private RepositoryService repositoryService;
@@ -292,7 +295,8 @@ public class QTI21AssessmentTestHandler extends FileHandler {
 	
 	private boolean copyResource(File file, String filename, File targetDirectory) {
 		try {
-			Path path = FileResource.getResource(file, filename);
+			String fallbackEncoding = qtiModule.getImportEncodingFallback();
+			Path path = FileResource.getResource(file, filename, fallbackEncoding);
 			if(path == null) {
 				return false;
 			}
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index 3510aaf91fb179636f862637a52b6b45c36f9fcd..79a2cb5a8246d730f5bd97524c38131b35089e50 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -318,6 +318,9 @@ qti21.digital.signature.enabled=false
 #Path to a PFX certificate (with X509 certificate, private and public key)
 qti21.digital.signature.certificate=
 
+#Try an other encoding to open the ZIP files during import of tests
+qti21.import.encoding.fallback=
+
 ########################################################################
 # Certificates
 ########################################################################
diff --git a/src/test/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksAssessementItemsTest.java b/src/test/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksAssessementItemsTest.java
index 63618431bcb7e3fb63814fb248019f9645eb39e3..0d20f32fd360a055ccd23882faf29b2f5b46d780 100644
--- a/src/test/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksAssessementItemsTest.java
+++ b/src/test/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksAssessementItemsTest.java
@@ -85,7 +85,8 @@ public class Onyx38ToQtiWorksAssessementItemsTest {
                 { "extended-text-c-3-7.xml" },
                 { "extended-text-3-7.xml" },
                 { "text-entry-3-8.xml" },
-                { "extended-text-d-3-7.xml" }
+                { "extended-text-d-3-7.xml" },
+                { "paragraphs-rec.xml" }
         });
     }
     
diff --git a/src/test/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandlerTest.java b/src/test/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandlerTest.java
index 068bad69e69bf481f39e7f6bc9f77541232ab04e..154be025929980aac2bfb1d796566e9eed242fb4 100644
--- a/src/test/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandlerTest.java
+++ b/src/test/java/org/olat/ims/qti21/model/xml/QTI21ExplorerHandlerTest.java
@@ -57,6 +57,7 @@ public class QTI21ExplorerHandlerTest {
                 { "resources/onyx/extended-text-b-3-7.xml", "Onyx Editor", "3.7.2" },
                 { "resources/onyx/extended-text-c-3-7.xml", "Onyx Editor", "3.7.2" },
                 { "resources/onyx/extended-text-e-3-7.xml", "Onyx Editor", "3.7.2" },
+                { "resources/onyx/paragraphs-rec.xml", "Onyx Editor", "3.8.1" },
                 { "resources/onyx/imsmanifest-5-1.xml", "ONYX Editor", "5.10.3" },
                 { "resources/onyx/imsmanifest-test-5-11.xml", "ONYX Editor", "5.11.1a" },
                 { "resources/openolat/essay3c2454b4c4dbd64347ea9df54cd.xml", "OpenOLAT", "11.3a" },
diff --git a/src/test/java/org/olat/ims/qti21/model/xml/resources/onyx/paragraphs-rec.xml b/src/test/java/org/olat/ims/qti21/model/xml/resources/onyx/paragraphs-rec.xml
new file mode 100644
index 0000000000000000000000000000000000000000..693b9d153ee2e77e2634d33817d464f88cb92239
--- /dev/null
+++ b/src/test/java/org/olat/ims/qti21/model/xml/resources/onyx/paragraphs-rec.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assessmentItem
+	xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/qti/qtiv2p1/imsqti_v2p1p1.xsd http://www.w3.org/1998/Math/MathML http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd"
+	identifier="id260dc4c6-5a55-4c2c-b90b-e32f28e2f4db" title="Rechnung"
+	adaptive="false" timeDependent="false">
+	<responseDeclaration
+		identifier="id7e187f0f-409b-414e-99d2-49ba0110e62d"
+		cardinality="single" baseType="float">
+		<correctResponse>
+			<value>0.99948</value>
+		</correctResponse>
+	</responseDeclaration>
+	<outcomeDeclaration identifier="SCORE"
+		cardinality="single" baseType="float">
+		<defaultValue>
+			<value>0</value>
+		</defaultValue>
+	</outcomeDeclaration>
+	<outcomeDeclaration identifier="MAXSCORE"
+		cardinality="single" baseType="float">
+		<defaultValue>
+			<value>1</value>
+		</defaultValue>
+	</outcomeDeclaration>
+	<outcomeDeclaration identifier="FEEDBACKBASIC"
+		cardinality="single" baseType="identifier" view="testConstructor">
+		<defaultValue>
+			<value>empty</value>
+		</defaultValue>
+	</outcomeDeclaration>
+	<itemBody>
+		<p>
+			<p>
+				<p>
+					<p>
+						Do some calculation with 6
+						<sub>3</sub>
+						to make some funny result.
+					</p>
+					<p>
+						Der Normalfaktor beträgt f =  
+						<textEntryInteraction
+							responseIdentifier="id7e187f0f-409b-414e-99d2-49ba0110e62d" />
+					</p>
+				</p>
+			</p>
+		</p>
+	</itemBody>
+	<responseProcessing>
+		<responseCondition>
+			<responseIf>
+				<equal toleranceMode="absolute" tolerance="0.00005 0.00005"
+					includeLowerBound="true" includeUpperBound="true">
+					<variable
+						identifier="id7e187f0f-409b-414e-99d2-49ba0110e62d" />
+					<correct
+						identifier="id7e187f0f-409b-414e-99d2-49ba0110e62d" />
+				</equal>
+				<setOutcomeValue identifier="SCORE">
+					<sum>
+						<variable identifier="SCORE" />
+						<baseValue baseType="float">1</baseValue>
+					</sum>
+				</setOutcomeValue>
+			</responseIf>
+		</responseCondition>
+		<responseCondition>
+			<responseIf>
+				<not>
+					<isNull>
+						<variable
+							identifier="id7e187f0f-409b-414e-99d2-49ba0110e62d" />
+					</isNull>
+				</not>
+				<setOutcomeValue identifier="FEEDBACKBASIC">
+					<baseValue baseType="identifier">incorrect</baseValue>
+				</setOutcomeValue>
+			</responseIf>
+		</responseCondition>
+		<responseCondition>
+			<responseIf>
+				<and>
+					<not>
+						<match>
+							<variable identifier="FEEDBACKBASIC" />
+							<baseValue baseType="identifier">empty</baseValue>
+						</match>
+					</not>
+					<equal toleranceMode="exact">
+						<variable identifier="SCORE" />
+						<variable identifier="MAXSCORE" />
+					</equal>
+				</and>
+				<setOutcomeValue identifier="FEEDBACKBASIC">
+					<baseValue baseType="identifier">correct</baseValue>
+				</setOutcomeValue>
+			</responseIf>
+		</responseCondition>
+	</responseProcessing>
+</assessmentItem>