diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java
index ede5ae601e1850100b5e77f56382d0dc22983b42..76ba0dae6246adf2359a34a1d51770650f9183c2 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/OpenBIS.java
@@ -34,9 +34,13 @@ import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
+import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
 import org.eclipse.jetty.client.util.BytesContentProvider;
+import org.eclipse.jetty.client.util.MultiPartContentProvider;
+import org.eclipse.jetty.client.util.PathContentProvider;
+import org.eclipse.jetty.client.util.StringContentProvider;
 import org.eclipse.jetty.http.HttpMethod;
 
 import ch.ethz.sis.afsapi.api.OperationsAPI;
@@ -116,7 +120,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -1241,7 +1245,7 @@ public class OpenBIS
         return asFacadeWithTransactions.createCodes(sessionToken, prefix, entityKind, count);
     }
 
-    public void executeImport(IImportData importData, ImportOptions importOptions) {
+    public void executeImport(ImportData importData, ImportOptions importOptions) {
         asFacadeWithTransactions.executeImport(sessionToken, importData, importOptions);
     }
 
@@ -1249,6 +1253,45 @@ public class OpenBIS
         return asFacadeWithTransactions.executeExport(sessionToken, exportData, exportOptions);
     }
 
+    public String uploadToSessionWorkspace(final Path fileOrFolder)
+    {
+        if (transactionId != null)
+        {
+            throw new IllegalStateException("AS session workspace SHOULD NOT be used during transactions.");
+        }
+
+        String uploadId = UUID.randomUUID().toString() + "/" + fileOrFolder.getFileName().toString();
+
+        try
+        {
+            HttpClient httpClient = JettyHttpClientFactory.getHttpClient();
+
+            MultiPartContentProvider multiPart = new MultiPartContentProvider();
+            multiPart.addFieldPart("sessionKeysNumber", new StringContentProvider("1"), null);
+            multiPart.addFieldPart("sessionKey_0", new StringContentProvider("openbis-file-upload"), null);
+            multiPart.addFilePart("openbis-file-upload", uploadId, new PathContentProvider(fileOrFolder), null);
+            multiPart.addFieldPart("keepOriginalFileName", new StringContentProvider("True"), null);
+            multiPart.addFieldPart("sessionID", new StringContentProvider(this.sessionToken), null);
+            multiPart.close();
+
+            ContentResponse response = httpClient.newRequest(this.asURL + "/upload")
+                    .method(HttpMethod.POST)
+                    .content(multiPart)
+                    .send();
+
+            final int status = response.getStatus();
+            if (status != 200)
+            {
+                throw new IOException(response.getContentAsString());
+            }
+        } catch (final IOException | TimeoutException | InterruptedException | ExecutionException e)
+        {
+            throw new RuntimeException(e);
+        }
+
+        return uploadId;
+    }
+
     //
     // DSS Facade methods
     //
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
index bd1ec54d8cec68848cb6ffe19e7017edaf66d141..c58a8be081a0980d9a16540c824afa355a50e5fb 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
@@ -89,7 +89,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -2262,7 +2263,7 @@ public interface IApplicationServerApi extends IRpcService
      */
     public List<String> createCodes(String sessionToken, String prefix, EntityKind entityKind, int count);
 
-    public void executeImport(String sessionToken, IImportData importData, ImportOptions importOptions);
+    public ImportResult executeImport(String sessionToken, ImportData importData, ImportOptions importOptions);
 
     public ExportResult executeExport(String sessionToken, ExportData exportData, ExportOptions exportOptions);
 
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java
index 509ee42d9781903c7c0162e4a46e13957a9430aa..479452c9b9841166b7ab85d028b09e81db8bb35c 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperation.java
@@ -24,7 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperation;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
@@ -35,7 +35,7 @@ public class ImportOperation implements Serializable, IOperation
     private static final long serialVersionUID = 1L;
 
     @JsonProperty
-    private IImportData importData;
+    private ImportData importData;
 
     @JsonProperty
     private ImportOptions importOptions;
@@ -45,7 +45,7 @@ public class ImportOperation implements Serializable, IOperation
     {
     }
 
-    public ImportOperation(final IImportData importData, final ImportOptions importOptions)
+    public ImportOperation(final ImportData importData, final ImportOptions importOptions)
     {
         this.importData = importData;
         this.importOptions = importOptions;
@@ -58,13 +58,13 @@ public class ImportOperation implements Serializable, IOperation
     }
 
     @JsonIgnore
-    public IImportData getImportData()
+    public ImportData getImportData()
     {
         return importData;
     }
 
     @JsonIgnore
-    public void setImportData(final IImportData importData)
+    public void setImportData(final ImportData importData)
     {
         this.importData = importData;
     }
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java
index a28b89ee5f3c05a1fcecc0435662dd63c556abe0..54e9619942e2aff248c18b6972b54ec644c21ad2 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportOperationResult.java
@@ -19,6 +19,9 @@ package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer;
 
 import java.io.Serializable;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperationResult;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
@@ -28,12 +31,35 @@ public class ImportOperationResult implements Serializable, IOperationResult
 
     private static final long serialVersionUID = 1L;
 
+    @JsonProperty
+    private ImportResult importResult;
+
+    public ImportOperationResult()
+    {
+    }
+
+    public ImportOperationResult(final ImportResult importResult)
+    {
+        this.importResult = importResult;
+    }
+
     @Override
     public String getMessage()
     {
         return toString();
     }
 
+    @JsonIgnore
+    public ImportResult getImportResult()
+    {
+        return importResult;
+    }
+
+    public void setImportResult(final ImportResult importResult)
+    {
+        this.importResult = importResult;
+    }
+
     @Override
     public String toString()
     {
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java
similarity index 59%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java
rename to api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java
index 4307d2ff86c753ce26a9c42d1ddb1ccf3d2929cf..29ca23329d807b456294d2050e6c3027bc6fe47e 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportScript.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/ImportResult.java
@@ -14,67 +14,53 @@
  *  limitations under the License.
  */
 
-package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data;
+package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer;
 
 import java.io.Serializable;
+import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
-@JsonObject("as.dto.importer.data.ImportScript")
-public class ImportScript implements Serializable
+@JsonObject("as.dto.importer.ImportResult")
+public class ImportResult implements Serializable
 {
 
     private static final long serialVersionUID = 1L;
 
     @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private String source;
+    private List<IObjectId> objectIds;
 
     @SuppressWarnings("unused")
-    public ImportScript()
-    {
-    }
-
-    public ImportScript(final String name, final String source)
+    public ImportResult()
     {
-        this.name = name;
-        this.source = source;
     }
 
-    @JsonIgnore
-    public String getName()
-    {
-        return name;
-    }
-
-    @JsonIgnore
-    public void setName(final String name)
+    public ImportResult(final List<IObjectId> objectIds)
     {
-        this.name = name;
+        this.objectIds = objectIds;
     }
 
     @JsonIgnore
-    public String getSource()
+    public List<IObjectId> getObjectIds()
     {
-        return source;
+        return objectIds;
     }
 
     @JsonIgnore
-    public void setSource(final String source)
+    public void setObjectIds(final List<IObjectId> objectIds)
     {
-        this.source = source;
+        this.objectIds = objectIds;
     }
 
     @Override
     public String toString()
     {
-        return new ObjectToString(this).append("name", name).append("source", source).toString();
+        return new ObjectToString(this).append("objectIds", objectIds).toString();
     }
 
 }
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java
deleted file mode 100644
index 4f47167bdca1a88a117f8a56475c629b63600d91..0000000000000000000000000000000000000000
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright ETH 2023 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data;
-
-import java.io.Serializable;
-
-import ch.systemsx.cisd.base.annotation.JsonObject;
-
-@JsonObject("as.dto.importer.data.IImportData")
-public interface IImportData extends Serializable
-{
-}
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java
similarity index 74%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java
rename to api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java
index d3a95e6bbd35b02a1091889c8fd17ce38cf460ac..02137385311c6446a995290c96f66ac6d0b53f7b 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ZipImportData.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportData.java
@@ -24,8 +24,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
-@JsonObject("as.dto.importer.data.ZipImportData")
-public class ZipImportData implements Serializable, IImportData
+@JsonObject("as.dto.importer.data.ImportData")
+public class ImportData implements Serializable
 {
     private static final long serialVersionUID = 1L;
 
@@ -33,17 +33,17 @@ public class ZipImportData implements Serializable, IImportData
     private ImportFormat format;
 
     @JsonProperty
-    private byte[] file;
+    private String[] sessionWorkspaceFiles;
 
     @SuppressWarnings("unused")
-    public ZipImportData()
+    public ImportData()
     {
     }
 
-    public ZipImportData(final ImportFormat format, final byte[] file)
+    public ImportData(final ImportFormat format, final String... sessionWorkspaceFiles)
     {
         this.format = format;
-        this.file = file;
+        this.sessionWorkspaceFiles = sessionWorkspaceFiles;
     }
 
     @JsonIgnore
@@ -58,16 +58,14 @@ public class ZipImportData implements Serializable, IImportData
         this.format = format;
     }
 
-    @JsonIgnore
-    public byte[] getFile()
+    public String[] getSessionWorkspaceFiles()
     {
-        return file;
+        return sessionWorkspaceFiles;
     }
 
-    @JsonIgnore
-    public void setFile(final byte[] file)
+    public void setSessionWorkspaceFiles(String[] sessionWorkspaceFiles)
     {
-        this.file = file;
+        this.sessionWorkspaceFiles = sessionWorkspaceFiles;
     }
 
     @Override
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java
index 3bd858e12712669ecd3d96ed0ec4738bff954153..415b5c6295014dbd9efc5128f5bce07e1daf8242 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportFormat.java
@@ -22,6 +22,6 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
 public enum ImportFormat
 {
 
-    XLS
+    EXCEL
 
 }
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java
deleted file mode 100644
index 005b3e1059aef790c9dcfebe2eb0b4b205cdae86..0000000000000000000000000000000000000000
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright ETH 2023 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data;
-
-import java.io.Serializable;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
-import ch.systemsx.cisd.base.annotation.JsonObject;
-
-@JsonObject("as.dto.importer.data.ImportValue")
-public class ImportValue implements Serializable
-{
-
-    private static final long serialVersionUID = 1L;
-
-    @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private String value;
-
-    @SuppressWarnings("unused")
-    public ImportValue()
-    {
-    }
-
-    public ImportValue(final String name, final String value)
-    {
-        this.name = name;
-        this.value = value;
-    }
-
-    @JsonIgnore
-    public String getName()
-    {
-        return name;
-    }
-
-    @JsonIgnore
-    public void setName(final String name)
-    {
-        this.name = name;
-    }
-
-    @JsonIgnore
-    public String getValue()
-    {
-        return value;
-    }
-
-    @JsonIgnore
-    public void setValue(final String value)
-    {
-        this.value = value;
-    }
-
-    @Override
-    public String toString()
-    {
-        final ObjectToString builder = new ObjectToString(this).append("name", name);
-        if (value == null)
-        {
-            builder.append("value", null);
-        } else if (value.length() <= 255)
-        {
-            builder.append("value", value);
-        } else
-        {
-            builder.append("value", value.substring(0, 255) + "...");
-        }
-        return builder.toString();
-    }
-
-}
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java
deleted file mode 100644
index 44113b16817213fa7c372fa3871779ce4e91b2a8..0000000000000000000000000000000000000000
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright ETH 2023 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
-import ch.systemsx.cisd.base.annotation.JsonObject;
-
-@JsonObject("as.dto.importer.data.UncompressedImportData")
-public class UncompressedImportData implements Serializable, IImportData
-{
-    private static final long serialVersionUID = 1L;
-
-    @JsonProperty
-    private ImportFormat format;
-
-    @JsonProperty
-    private byte[] file;
-
-    @JsonProperty
-    private Collection<ImportScript> scripts;
-
-    @JsonProperty
-    private Collection<ImportValue> importValues;
-
-    @SuppressWarnings("unused")
-    public UncompressedImportData()
-    {
-    }
-
-    public UncompressedImportData(final ImportFormat format, final byte[] file, final Collection<ImportScript> scripts,
-            final Collection<ImportValue> importValues)
-    {
-        this.format = format;
-        this.file = file;
-        this.scripts = scripts;
-        this.importValues = importValues;
-    }
-
-    @JsonIgnore
-    public ImportFormat getFormat()
-    {
-        return format;
-    }
-
-    @JsonIgnore
-    public void setFormat(final ImportFormat format)
-    {
-        this.format = format;
-    }
-
-    @JsonIgnore
-    public byte[] getFile()
-    {
-        return file;
-    }
-
-    @JsonIgnore
-    public void setFile(final byte[] file)
-    {
-        this.file = file;
-    }
-
-    @JsonIgnore
-    public Collection<ImportScript> getScripts()
-    {
-        return scripts;
-    }
-
-    @JsonIgnore
-    public void setScripts(final Collection<ImportScript> scripts)
-    {
-        this.scripts = scripts;
-    }
-
-    @JsonIgnore
-    public Collection<ImportValue> getImportValues()
-    {
-        return importValues;
-    }
-
-    @JsonIgnore
-    public void setImportValues(final Collection<ImportValue> importValues)
-    {
-        this.importValues = importValues;
-    }
-
-    @Override
-    public String toString()
-    {
-        return new ObjectToString(this).append("format", format).append("scripts", scripts).toString();
-    }
-
-}
diff --git a/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
index af8a6580cf705a2d6aa1ca7516aa93231d96f283..21daba1c397710945af2d28792ee8cb41812b2c3 100644
--- a/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
+++ b/api-openbis-java/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
@@ -464,6 +464,7 @@ Event Sort Options
 Event Tech Id
 Event Type
 Event Type Search Criteria
+EXCEL
 exec
 execute Aggregation Service
 Execute Aggregation Service Operation
@@ -1282,7 +1283,6 @@ IExternalDmsId
 IFileFormatTypeId
 IGNORE_EXISTING
 IIdentifierHolder
-IImportData
 ILocatorTypeId
 ImagingDataSetConfig
 ImagingDataSetControl
@@ -1300,8 +1300,6 @@ ImportModes
 ImportOperation
 ImportOperationResult
 ImportOptions
-ImportScript
-ImportValue
 indent
 indexOf
 INSTANCE
@@ -2495,7 +2493,6 @@ UNARCHIVE_PENDING
 UnarchiveDataSetsOperation
 UnarchiveDataSetsOperationResult
 UnauthorizedObjectAccessException
-UncompressedImportData
 UNDEFINED
 UNIQUE_SUBCODES
 UNKNOWN
@@ -2903,7 +2900,6 @@ XlsTextFormat
 XLSX
 XML
 YES
-ZipImportData
 I Transaction Coordinator Api
 I Transaction Participant Api
 APPLICATION_SERVER_PARTICIPANT_ID
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js
index 717aa8112bffde1141a8bb3bf359ee5e6ce61d21..aeb00d41c2da7c72016158de687936c5779d0dc6 100644
--- a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js
+++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperation.js
@@ -46,7 +46,7 @@ define(["stjs", "as/dto/common/operation/IOperation"],
         };
       },
       {
-        importData: "IImportData",
+        importData: "ImportData",
         importOptions: "ImportOptions"
       }
     );
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js
index 8644008309f35a02da7fcdeee25354a5a1d0b28c..9bdfca0689c2e34d47404b78eee237965fee1918 100644
--- a/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js
+++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportOperationResult.js
@@ -17,7 +17,8 @@
 
 define(["stjs", "as/dto/common/operation/IOperationResult"],
   function (stjs, IOperationResult) {
-    var ImportOperationResult = function() {
+    var ImportOperationResult = function(importResult) {
+      this.importResult = importResult;
     }
 
     stjs.extend(
@@ -28,12 +29,23 @@ define(["stjs", "as/dto/common/operation/IOperationResult"],
         prototype["@type"] = "as.dto.importer.ImportOperationResult";
 
         constructor.serialVersionUID = 1;
+        prototype.importResult = null;
 
         prototype.getMessage = function() {
           return "ImportOperationResult";
         };
+
+        prototype.getImportResult = function() {
+          return this.importResult;
+        };
+
+        prototype.setImportResult = function(importResult) {
+          this.importResult = importResult;
+        };
       },
-      {}
+      {
+        importResult: "ImportResult"
+      }
     );
 
     return ImportOperationResult;
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js b/api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js
similarity index 58%
rename from api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js
rename to api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js
index 64545851a6271a2595aec39c671ec1c5858d1456..29daa115a9837ac0624ea98a7f5600e087b4b51d 100644
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportScript.js
+++ b/api-openbis-javascript/src/v3/as/dto/importer/ImportResult.js
@@ -15,40 +15,36 @@
  *
  */
 
-define(["stjs"],
-  function (stjs) {
-    var ImportScript = function() {
+define(["stjs"], function (stjs) {
+    var ImportResult = function(objectIds) {
+      this.objectIds = objectIds;
     }
 
     stjs.extend(
-      ImportScript,
+      ImportResult,
       null,
       [],
       function (constructor, prototype) {
-        prototype["@type"] = "as.dto.importer.data.ImportScript";
+        prototype["@type"] = "as.dto.importer.ImportResult";
 
         constructor.serialVersionUID = 1;
-        prototype.name = null;
-        prototype.source = null;
+        prototype.objectIds = null;
 
-        prototype.getName = function() {
-          return this.name;
+        prototype.getObjectIds = function() {
+          return this.objectIds;
         };
 
-        prototype.setName = function(name) {
-          this.name = name;
-        };
-
-        prototype.getSource = function() {
-          return this.source;
-        };
-
-        prototype.setSource = function(source) {
-          this.source = source;
+        prototype.setObjectIds = function(objectIds) {
+          this.objectIds = objectIds;
         };
       },
-      {}
+      {
+        objectIds: {
+          name: "List",
+          arguments: ["IObjectId"]
+        }
+      }
     );
 
-    return ImportScript;
+    return ImportResult;
   });
\ No newline at end of file
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js
deleted file mode 100644
index 1289c8e8e4d5fc079dc7015a826b2e4cb6f0d821..0000000000000000000000000000000000000000
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  Copyright ETH 2023 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-define(["stjs"], function (stjs) {
-  var IImportData = function () {
-  };
-  stjs.extend(IImportData, null, [], null, {});
-  return IImportData;
-});
\ No newline at end of file
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js
similarity index 61%
rename from api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js
rename to api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js
index 918cc534cd6552fff8c56e05034e0815f33aa253..9786a7ef566b7f8ed41bb4bae185b15b2d644237 100644
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/ZipImportData.js
+++ b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportData.js
@@ -15,21 +15,22 @@
  *
  */
 
-define(["stjs", "as/dto/importer/data/IImportData"],
-  function (stjs, IImportData) {
-    var ZipImportData = function() {
+define(["stjs"], function (stjs) {
+    var ImportData = function(format, sessionWorkspaceFiles) {
+      this.format = format;
+      this.sessionWorkspaceFiles = sessionWorkspaceFiles;
     }
 
     stjs.extend(
-      ZipImportData,
-      IImportData,
-      [IImportData],
+      ImportData,
+      null,
+      [],
       function (constructor, prototype) {
-        prototype["@type"] = "as.dto.importer.data.ZipImportData";
+        prototype["@type"] = "as.dto.importer.data.ImportData";
 
         constructor.serialVersionUID = 1;
         prototype.format = null;
-        prototype.file = null;
+        prototype.sessionWorkspaceFiles = null;
 
         prototype.getFormat = function() {
           return this.format;
@@ -39,19 +40,19 @@ define(["stjs", "as/dto/importer/data/IImportData"],
           this.format = format;
         };
 
-        prototype.getFile = function() {
-          return this.file;
+        prototype.getSessionWorkspaceFiles = function() {
+          return this.sessionWorkspaceFiles;
         };
 
-        prototype.setFile = function(file) {
-          this.file = file;
+        prototype.setSessionWorkspaceFiles = function(sessionWorkspaceFiles) {
+          this.sessionWorkspaceFiles = sessionWorkspaceFiles;
         };
       },
       {
         format: "ImportFormat",
-        file: "byte[]"
+        sessionWorkspaceFiles: "String[]"
       }
     );
 
-    return ZipImportData;
+    return ImportData;
   });
\ No newline at end of file
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js
index 982b7ff16bf67abb8fba38779fe10f233d4997d0..4ffb6dd245409c3c821af477395dc5f15e11b058 100644
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js
+++ b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportFormat.js
@@ -17,7 +17,7 @@
 
 define(["stjs", "as/dto/common/Enum"], function (stjs, Enum) {
   var ImportFormat = function() {
-    Enum.call(this, ["XLS"]);
+    Enum.call(this, ["EXCEL"]);
   }
 
   stjs.extend(
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js b/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js
deleted file mode 100644
index e8bddc19ddbc290d97453e38dded0705365fe526..0000000000000000000000000000000000000000
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Copyright ETH 2024 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-define(["stjs"],
-  function (stjs) {
-    var ImportValue = function() {
-    }
-
-    stjs.extend(
-      ImportValue,
-      null,
-      [],
-      function (constructor, prototype) {
-        prototype["@type"] = "as.dto.importer.data.ImportValue";
-
-        constructor.serialVersionUID = 1;
-        prototype.name = null;
-        prototype.value = null;
-
-        prototype.getName = function() {
-          return this.name;
-        };
-
-        prototype.setName = function(name) {
-          this.name = name;
-        };
-
-        prototype.getValue = function() {
-          return this.value;
-        };
-
-        prototype.setValue = function(value) {
-          this.value = value;
-        };
-      },
-      {}
-    );
-
-    return ImportValue;
-  });
\ No newline at end of file
diff --git a/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js b/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js
deleted file mode 100644
index 49084d1b71cc60392c1ff59c3a47f06f3657bcb8..0000000000000000000000000000000000000000
--- a/api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Copyright ETH 2023 Zürich, Scientific IT Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-define(["stjs", "as/dto/importer/data/IImportData"],
-  function (stjs, IImportData) {
-    var UncompressedImportData = function() {
-    }
-
-    stjs.extend(
-      UncompressedImportData,
-      IImportData,
-      [IImportData],
-      function (constructor, prototype) {
-        prototype["@type"] = "as.dto.importer.data.UncompressedImportData";
-
-        constructor.serialVersionUID = 1;
-        prototype.format = null;
-        prototype.file = null;
-        prototype.scripts = null;
-        prototype.importValues = null;
-
-        prototype.getFormat = function() {
-          return this.format;
-        };
-
-        prototype.setFormat = function(format) {
-          this.format = format;
-        };
-
-        prototype.getFile = function() {
-          return this.file;
-        };
-
-        prototype.setFile = function(file) {
-          this.file = file;
-        };
-
-        prototype.getScripts = function() {
-          return this.scripts;
-        };
-
-        prototype.setScripts = function(scripts) {
-          this.scripts = scripts;
-        };
-
-        prototype.getImportValues = function() {
-          return this.importValues;
-        };
-
-        prototype.setImportValues = function(importValues) {
-          this.importValues = importValues;
-        };
-      },
-      {
-        format: "ImportFormat",
-        file: "byte[]",
-        scripts: {
-          name: "Collection",
-          arguments: ["ImportScript"]
-        },
-        importValues: {
-          name: "Collection",
-          arguments: ["ImportValue"]
-        }
-      }
-    );
-
-    return UncompressedImportData;
-  });
\ No newline at end of file
diff --git a/api-openbis-javascript/src/v3/openbis.js b/api-openbis-javascript/src/v3/openbis.js
index f7a8d669586eb261f939331da483b19ba15f9469..a5c1a6be3fdc922f885e489e1ce466a5655f0d51 100644
--- a/api-openbis-javascript/src/v3/openbis.js
+++ b/api-openbis-javascript/src/v3/openbis.js
@@ -2728,6 +2728,34 @@ define([ 'jquery', 'util/Json', 'as/dto/datastore/search/DataStoreSearchCriteria
 			})
 		}
 
+		this.uploadToSessionWorkspace = function(file) {
+			//Building Form Data Object for Multipart File Upload
+			var formData = new FormData();
+			formData.append("sessionKeysNumber", "1");
+			formData.append("sessionKey_0", "openbis-file-upload");
+			formData.append("openbis-file-upload", file);
+			formData.append("keepOriginalFileName", "True");
+			formData.append("sessionID", this._private.sessionToken);
+
+			var dfd = jquery.Deferred();
+
+			jquery.ajax({
+				type: "POST",
+				url: "/openbis/openbis/upload",
+				contentType: false,
+				processData: false,
+				data: formData,
+				success: function() {
+					dfd.resolve();
+				},
+				error: function() {
+					dfd.reject();
+				}
+			});
+
+			return dfd.promise();
+		}
+
 		/**
 		 * =======================
 		 * OpenBIS webapp context
diff --git a/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java b/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java
index cb1cb28377795d66cf6b5f7992296c72e2738e45..c55846a1f9fde3aebeb570d293bea8779f16dd8e 100644
--- a/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java
+++ b/api-openbis-typescript/source/java/ch/ethz/sis/openbis/generic/typescript/dto/OpenBISJavaScriptFacade.java
@@ -75,7 +75,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -1322,9 +1323,9 @@ public class OpenBISJavaScriptFacade implements IApplicationServerApi
     }
 
     @TypeScriptMethod
-    @Override public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions)
+    @Override public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions)
     {
-
+        return null;
     }
 
     @TypeScriptMethod
@@ -1333,6 +1334,11 @@ public class OpenBISJavaScriptFacade implements IApplicationServerApi
         return null;
     }
 
+    @TypeScriptMethod(sessionToken = false)
+    public void uploadToSessionWorkspace(final Object file)
+    {
+    }
+
     @TypeScriptMethod(sessionToken = false)
     @Override public int getMajorVersion()
     {
diff --git a/core-plugin-openbis/.dynamic_property_evaluator_queue b/core-plugin-openbis/.dynamic_property_evaluator_queue
deleted file mode 100644
index 2e08dce276e43c677d121d627a250d1710fed824..0000000000000000000000000000000000000000
Binary files a/core-plugin-openbis/.dynamic_property_evaluator_queue and /dev/null differ
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java
index 69708ddf23d89fd553aaf7281023c434a8e05b94..42c27477f7a1f22381655cc8e63bb66905b6532e 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/AbstractImportTest.java
@@ -16,6 +16,9 @@
 package ch.ethz.sis.openbis.systemtest.plugin.excelimport;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.UUID;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
@@ -24,8 +27,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeSuite;
 
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
+import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsUtils;
 
 public class AbstractImportTest extends AbstractTransactionalTestNGSpringContextTests
@@ -41,6 +46,10 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext
 
     protected static final String PASSWORD = "password";
 
+    protected static final String VALIDATION_SCRIPT = "full/scripts/valid.py";
+
+    protected static final String DYNAMIC_SCRIPT = "full/scripts/dynamic/dynamic.py";
+
     @Autowired
     protected IApplicationServerInternalApi v3api;
 
@@ -54,6 +63,7 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext
         System.setProperty(XLS_VERSIONING_DIR, VERSIONING_JSON);
         System.setProperty(CorePluginsUtils.CORE_PLUGINS_FOLDER_KEY, "dist/core-plugins");
         System.setProperty(Constants.ENABLED_MODULES_KEY, "xls-import");
+        System.setProperty(Constants.PROJECT_SAMPLES_ENABLED_KEY, "false");
         TestInitializer.initEmptyDbNoIndex();
     }
 
@@ -71,4 +81,31 @@ public class AbstractImportTest extends AbstractTransactionalTestNGSpringContext
         v3api.logout(sessionToken);
     }
 
+    protected static String uploadToAsSessionWorkspace(final String sessionToken, final String filePath) throws IOException
+    {
+        final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider();
+        final String destination = UUID.randomUUID() + "/" + new File(filePath).getName();
+
+        sessionWorkspaceProvider.write(sessionToken, destination, new FileInputStream("sourceTest/java/" + filePath));
+
+        return destination;
+    }
+
+    protected static String[] uploadToAsSessionWorkspace(final String sessionToken, final String... filePaths) throws IOException
+    {
+        final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider();
+        final UUID uploadId = UUID.randomUUID();
+
+        final String[] destinations = new String[filePaths.length];
+        for (int i = 0; i < filePaths.length; i++)
+        {
+            destinations[i] = uploadId
+                    + (filePaths[i].toLowerCase().endsWith(".xls") || filePaths[i].toLowerCase().endsWith(".xlsx") ? "/" : "/scripts/")
+                    + new File(filePaths[i]).getName();
+            sessionWorkspaceProvider.write(sessionToken, destinations[i], new FileInputStream("sourceTest/java/" + filePaths[i]));
+        }
+
+        return destinations;
+    }
+
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java
index 1a13a1028e60b5f4765d916cbe7db1cf80f38315..bf607e4745614b3ce160f5beeade93dac21b4ba8 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportDatasetTypesTest.java
@@ -70,13 +70,16 @@ public class ImportDatasetTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA");
         List<String> propertyNames = Arrays.asList("$NAME", "NOTES");
         List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(rawData, propertyNames);
         PropertyAssignment nameProperty = propertyAssignments.get(0);
         PropertyAssignment notesProperty = propertyAssignments.get(1);
+
         // THEN
         assertEquals(rawData.getCode(), "RAW_DATA");
         assertEquals(rawData.getPropertyAssignments().size(), 2);
@@ -101,9 +104,12 @@ public class ImportDatasetTypesTest extends AbstractImportTest
     public void testDatasetTypesWithoutPropertiesTypesAreCreated() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_WITHOUT_PROPERTIES)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_WITHOUT_PROPERTIES));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA");
+
         // THEN
         assertEquals(rawData.getCode(), "RAW_DATA");
         assertEquals(rawData.getPropertyAssignments().size(), 0);
@@ -114,10 +120,13 @@ public class ImportDatasetTypesTest extends AbstractImportTest
     public void testDatasetTypesWithValidationScript() throws Exception
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(),
-                Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_WITH_VALIDATION_SCRIPT)));
+        final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, DATASET_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0]));
+
         // WHEN
         DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA");
+
         // THEN
         assertEquals(rawData.getValidationPlugin().getName().toUpperCase(), "RAW_DATA.VALID");
     }
@@ -130,15 +139,19 @@ public class ImportDatasetTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS,
-                Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_TYPES_UPDATE)));
+        final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, DATASET_TYPES_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePaths[0]));
         DataSetType rawData = TestUtils.getDatasetType(v3api, sessionToken, "RAW_DATA");
         List<String> propertyNames = Arrays.asList("$NAME", "NOTES");
         List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(rawData, propertyNames);
         PropertyAssignment nameProperty = propertyAssignments.get(0);
         PropertyAssignment notesProperty = propertyAssignments.get(1);
+
         // THEN
         // Property Assignment updates are not supported, no change here between updates.
         assertTrue(nameProperty.isMandatory());
@@ -157,10 +170,11 @@ public class ImportDatasetTypesTest extends AbstractImportTest
         assertEquals(notesProperty.getPlugin(), null);
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header should contain 'Code'.*")
     public void shouldThrowExceptionIfNoSampleCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, DATASET_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, DATASET_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java
index f8f56716ddd3b2675eab3e22e5fc357ab82c6738..843e6c02e72f27794f013002bc82bdaf7bb71bb5 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentTypesTest.java
@@ -73,13 +73,16 @@ public class ImportExperimentTypesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION");
         List<String> propertyNames = Arrays.asList("$NAME", "DEFAULT_OBJECT_TYPE");
         List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(collection, propertyNames);
         PropertyAssignment nameProperty = propertyAssignments.get(0);
         PropertyAssignment defaultObjectTypeProperty = propertyAssignments.get(1);
+
         // THEN
         assertEquals(collection.getCode(), "COLLECTION");
         assertEquals(collection.getPropertyAssignments().size(), 2);
@@ -108,15 +111,19 @@ public class ImportExperimentTypesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS,
-                Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_UPDATE)));
+        final String[] updateSessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPES_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePaths[0]));
         ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION");
         List<String> propertyNames = Arrays.asList("$NAME", "DEFAULT_OBJECT_TYPE");
         List<PropertyAssignment> propertyAssignments = TestUtils.extractAndSortPropertyAssignmentsPerGivenPropertyName(collection, propertyNames);
         PropertyAssignment nameProperty = propertyAssignments.get(0);
         PropertyAssignment defaultObjectTypeProperty = propertyAssignments.get(1);
+
         // THEN
         // Property Assignment updates are not supported, no change here between updates.
         assertTrue(nameProperty.isMandatory());
@@ -141,18 +148,22 @@ public class ImportExperimentTypesTest extends AbstractImportTest
     public void testExperimentTypesWithValidationScript() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(),
-                Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_WITH_VALIDATION_SCRIPT)));
+        final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0]));
+
         // WHEN
         ExperimentType collection = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION");
+
         // THEN
         assertEquals(collection.getValidationPlugin().getName().toUpperCase(), "COLLECTION.VALID");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Mandatory field is missing or empty: Code.*")
     public void shouldThrowExceptionIfNoSampleCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java
index 742ed9ffbe57a62a5dcde02244b8be6a1fdbc1c5..ec529f6dcff09d55c73999459e0d3e03b5583c27 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportExperimentsTest.java
@@ -96,9 +96,12 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -114,9 +117,12 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT2", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT2");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -132,12 +138,23 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -153,12 +170,22 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -166,20 +193,36 @@ public class ImportExperimentsTest extends AbstractImportTest
         assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "OBJECT_TYPE");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Experiment type COLLECTION not found.*")
     public void shouldThrowExceptionIfExperimentTypeDoesntExist() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)));
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Entity \\[/TEST_SPACE/TEST_PROJECT\\] could not be found\\..*")
     public void shouldThrowExceptionIfProjectDoesntExist() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE)));
+        // the Excel contains internally property types which can be only manipulated by the system user
+        sessionToken = v3api.loginAsSystem();
+
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_ALL_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
     }
 
     @Test
@@ -190,10 +233,17 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -209,12 +259,23 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath));
+
+        final String experimentsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentsSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -225,7 +286,8 @@ public class ImportExperimentsTest extends AbstractImportTest
     @Test(expectedExceptions = UserFailureException.class)
     public void shouldThrowExceptionIfExperimentNoCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -236,9 +298,13 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_NON_MANDATORY_PROPERTY_MISSING)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_NON_MANDATORY_PROPERTY_MISSING));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -249,7 +315,9 @@ public class ImportExperimentsTest extends AbstractImportTest
     @Test(expectedExceptions = RuntimeException.class)
     public void shouldThrowExceptionIfExperimentNoProject() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_PROJECT_ATTRIBUTE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_NO_PROJECT_ATTRIBUTE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -260,11 +328,19 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECT)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_SPACE_AND_PROJECT_ELSEWHERE)));
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectSessionWorkspaceFilePath));
+
+        final String elsewhereWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_SPACE_AND_PROJECT_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -280,10 +356,16 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_SPACE_ELSEWHERE)));
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String spaceElsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_SPACE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceElsewhereSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -299,11 +381,20 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_AND_SPACE_ELSEWHERE)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String elsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_TYPE_AND_SPACE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -314,7 +405,9 @@ public class ImportExperimentsTest extends AbstractImportTest
     @Test(expectedExceptions = UserFailureException.class)
     public void shouldThrowExceptionIfMandatoryPropertyMissing() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_MISSING)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_MISSING));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -325,9 +418,13 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_PRESENT)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_WITH_MANDATORY_PROPERTY_PRESENT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -343,9 +440,13 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -361,11 +462,17 @@ public class ImportExperimentsTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS_TYPE_ON_SERVER)));
+        final String experimentTypeSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(experimentTypeSessionWorkspaceFilePath));
+
+        final String elsewhereSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENTS_PROPERTIES_COLUMNS_AS_LABELS_TYPE_ON_SERVER));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(elsewhereSessionWorkspaceFilePath));
+
         // WHEN
         Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
         // THEN
         assertEquals(experiment.getCode(), "TEST_EXPERIMENT");
         assertEquals(experiment.getProject().getCode(), "TEST_PROJECT");
@@ -373,19 +480,26 @@ public class ImportExperimentsTest extends AbstractImportTest
         assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "OBJECT_TYPE");
     }
 
-//    @Test
-//    @DirtiesContext
-//    public void testExperimentsUpdate() throws Exception
-//    {
-//        // GIVEN
-//        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS)));
-//        // WHEN
-//        TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(), UpdateMode.UPDATE_IF_EXISTS,
-//                Paths.get(FilenameUtils.concat(FILES_DIR, EXPERIMENT_UPDATE)));
-//        Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
-//        // THEN
-//        assertEquals(experiment.getProperties().get("$NAME"), "NameUpdate");
-//        assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "DefaultObjectTypeUpdate");
-//    }
+    @Test
+    @DirtiesContext
+    public void testExperimentsUpdate() throws Exception
+    {
+        // the Excel contains internally managed property types which can be only manipulated by the system user
+        String sessionToken = v3api.loginAsSystem();
+
+        // GIVEN
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXPERIMENT_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
+        // WHEN
+        final String[] updateSessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, EXPERIMENT_UPDATE), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePaths[0]));
+        Experiment experiment = TestUtils.getExperiment(v3api, sessionToken, "TEST_EXPERIMENT", "TEST_PROJECT", "TEST_SPACE");
+
+        // THEN
+        assertEquals(experiment.getProperties().get("$NAME"), "NameUpdate");
+        assertEquals(experiment.getProperties().get("DEFAULT_OBJECT_TYPE"), "DefaultObjectTypeUpdate");
+    }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java
index 46549e079efda295eecd5a620564f51efba59ce7..758adcb28d77a380d399b824e5d849edcf571716 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportFromExcelTest.java
@@ -21,7 +21,6 @@ import static org.testng.Assert.assertNotNull;
 import java.io.IOException;
 import java.nio.file.Paths;
 
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
@@ -34,6 +33,7 @@ import org.testng.annotations.Test;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 @ContextConfiguration(locations = "classpath:applicationContext.xml")
 @Transactional(transactionManager = "transaction-manager")
@@ -53,21 +53,23 @@ public class ImportFromExcelTest extends AbstractImportTest
         FILES_DIR = f.substring(0, f.length() - ImportExperimentTypesTest.class.getSimpleName().length()) + "/test_files/";
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(?s).*Content found after a double blank row that should mark the end of a page\\..*")
     @DirtiesContext
     public void testFileWithManyBlankRowsWasParsed() throws Exception
     {
         // the Excel contains internally managed property types which can be only manipulated by the system user
         sessionToken = v3api.loginAsSystem();
 
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, WITH_BLANKS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, WITH_BLANKS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
 
         ExperimentType propertyType = TestUtils.getExperimentType(v3api, sessionToken, "COLLECTION");
         assertNotNull(propertyType); // the last line on the first sheet was read
         assertEquals(propertyType.getPropertyAssignments().size(), 2);
         assertEquals(propertyType.getPropertyAssignments().get(1).getPropertyType().getCode(), "LAST_ROW_EXP_TYPE");
 
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "LAST_SAMPLE", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "LAST_SAMPLE");
         assertNotNull(sample); // the last line on the second sheet was read
     }
 }
\ No newline at end of file
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java
index 0c827f35dd518bf89b739e9b8b597cfcc7af136c..01aa8bc54627e88ac3d4ba001632bcccb77aaac5 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportProjectsTest.java
@@ -69,9 +69,12 @@ public class ImportProjectsTest extends AbstractImportTest
     public void testProjectsAreCreated() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT");
+
         // THEN
         assertEquals(project.getCode(), "TEST_PROJECT");
         assertEquals(project.getDescription(), "TEST");
@@ -83,10 +86,14 @@ public class ImportProjectsTest extends AbstractImportTest
     public void testExistProjectIsUpdated() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
-        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_UPDATE)));
+        final String updateSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_UPDATE));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(updateSessionWorkspaceFilePath));
         Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT", "TEST_SPACE2");
+
         // THEN
         assertEquals(project.getCode(), "TEST_PROJECT");
         assertEquals(project.getDescription(), "UPDATE");
@@ -98,19 +105,23 @@ public class ImportProjectsTest extends AbstractImportTest
     public void testProjectsAreCreatedSecondProject() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT2");
+
         // THEN
         assertEquals(project.getCode(), "TEST_PROJECT2");
         assertEquals(project.getDescription(), "description of another project");
         assertEquals(project.getSpace().getCode(), "TEST_SPACE2");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Code' is missing.*")
     public void shouldThrowExceptionIfNoProjectCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -118,19 +129,23 @@ public class ImportProjectsTest extends AbstractImportTest
     public void testProjectsAreCreatedNoDescription() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_DESCRIPTION)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_DESCRIPTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT");
+
         // THEN
         assertEquals(project.getCode(), "TEST_PROJECT");
         assertEquals(project.getDescription(), null);
         assertEquals(project.getSpace().getCode(), "TEST_SPACE");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Space' is missing.*")
     public void shouldThrowExceptionIfNoProjectSpace() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_NO_SPACE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROJECTS_NO_SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -138,10 +153,16 @@ public class ImportProjectsTest extends AbstractImportTest
     public void testProjectsAreCreatedSpaceOnServer() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROJECTS_WITH_SPACES_ON_SERVER)));
+        final String spaceSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(spaceSessionWorkspaceFilePath));
+
+        final String projectsSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROJECTS_WITH_SPACES_ON_SERVER));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(projectsSessionWorkspaceFilePath));
+
         // WHEN
         Project project = TestUtils.getProject(v3api, sessionToken, "TEST_PROJECT");
+
         // THEN
         assertEquals(project.getCode(), "TEST_PROJECT");
         assertEquals(project.getDescription(), "TEST");
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java
index b7963f77f1f69bfd27dd3d963b44d5a45c7e284d..fc35b51fa4bd6757a89be8d1897184d67303dd54 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportPropertyTypesTest.java
@@ -17,6 +17,7 @@ package ch.ethz.sis.openbis.systemtest.plugin.excelimport;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
@@ -25,7 +26,6 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 
 import org.apache.commons.io.FilenameUtils;
-import org.python27.core.PyException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.annotation.Rollback;
@@ -50,6 +50,7 @@ public class ImportPropertyTypesTest extends AbstractImportTest
     private IApplicationServerInternalApi v3api;
 
     private static final String PROPERTY_TYPES_XLS = "property_types/normal_property_type.xls";
+
     private static final String PROPERTY_TYPES_WITH_PATTERN_XLS = "property_types/normal_property_type_with_pattern.xls";
 
     private static final String PROPERTY_NO_CODE = "property_types/no_code.xls";
@@ -74,7 +75,7 @@ public class ImportPropertyTypesTest extends AbstractImportTest
     public void setupClass() throws IOException
     {
         String f = ImportPropertyTypesTest.class.getName().replace(".", "/");
-        FILES_DIR = f.substring(0, f.length() - ImportPropertyTypesTest.class.getSimpleName().length()) + "/test_files/";
+        FILES_DIR = f.substring(0, f.length() - ImportPropertyTypesTest.class.getSimpleName().length()) + "test_files/";
     }
 
     @Test
@@ -85,9 +86,12 @@ public class ImportPropertyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "NOTES");
+
         // THEN
         assertEquals(notes.getCode(), "NOTES");
         assertEquals(notes.getLabel(), "Notes");
@@ -105,9 +109,13 @@ public class ImportPropertyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_WITH_PATTERN_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_WITH_PATTERN_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "PATTERN_PATTERN");
+
         // THEN
         assertEquals(notes.getCode(), "PATTERN_PATTERN");
         assertEquals(notes.getLabel(), "Pattern");
@@ -127,9 +135,12 @@ public class ImportPropertyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP");
+
         // THEN
         assertEquals(notes.getCode(), "$INTERNAL_PROP");
         assertEquals(notes.getLabel(), "Name");
@@ -144,9 +155,13 @@ public class ImportPropertyTypesTest extends AbstractImportTest
     public void testDuplicatesPropertiesAreAllowedIfTheyAreTheSame() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_DUPLICATES_SAME)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_DUPLICATES_SAME));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         PropertyType notes = TestUtils.getPropertyType(v3api, sessionToken, "NOTES");
+
         // THEN
         assertEquals(notes.getCode(), "NOTES");
         assertEquals(notes.getLabel(), "Notes");
@@ -157,76 +172,96 @@ public class ImportPropertyTypesTest extends AbstractImportTest
         assertNull(notes.getVocabulary());
     }
 
-    @Test(expectedExceptions = RuntimeException.class)
+    @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Mandatory field is missing or empty: Code.*")
     public void testPropertyTypeNoCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Property label' is missing.*")
     public void testPropertyTypeNoLabel() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_LABEL)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_LABEL));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(?s).*Ambiguous property NOTES found, it has been declared before with different attributes.*")
     public void testPropertyTypesDuplicatesAreDifferent() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_DUPLICATES_DIFFERENT)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROPERTY_DUPLICATES_DIFFERENT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = RuntimeException.class)
+    @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Vocabulary code' is missing.*")
     public void testPropertyTypeNoVocabularyCodeWhenVocabularyType() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_VOCAB_TYPE_NO_VOCABULARY_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROPERTY_VOCAB_TYPE_NO_VOCABULARY_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = RuntimeException.class)
+    @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Data type' is missing.*")
     public void testPropertyTypeNoDataType() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DATA_TYPE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DATA_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Description' is missing.*")
     public void testPropertyTypeNoDescription() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DESCRIPTION)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_NO_DESCRIPTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Entity \\[DETECTION\\] could not be found..*")
     public void testPropertyTypeVocabularyCodeToNonVocabularyType() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_NON_VOCAB_TYPE_VOCABULARY_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, PROPERTY_NON_VOCAB_TYPE_VOCABULARY_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = Exception.class)
+    @Test/*(expectedExceptions = Exception.class)*/
     @DirtiesContext
     public void deleteProjectFromDBButNotFromJSON() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)));
+        // the Excel contains internally property types which can be only manipulated by the system user
+        sessionToken = v3api.loginAsSystem();
+
+        final String sessionWorkspaceFilePath1 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFilePath1));
 
         PropertyType type = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP");
+        assertNotNull(type);
         PropertyTypeDeletionOptions deletionOptions = new PropertyTypeDeletionOptions();
         deletionOptions.setReason("test");
         v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions);
 
         // After deleting one property, the exception is not thrown.
         // Because it can be deleted by the user an DB is fine.
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)));
+        final String sessionWorkspaceFilePath2 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath2));
 
         // remove all data from DB
         type = TestUtils.getPropertyType(v3api, sessionToken, "$INTERNAL_PROP");
+        assertNotNull(type);
         deletionOptions = new PropertyTypeDeletionOptions();
         deletionOptions.setReason("test");
         v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions);
 
         type = TestUtils.getPropertyType(v3api, sessionToken, "NOTES");
+        assertNotNull(type);
         deletionOptions = new PropertyTypeDeletionOptions();
         deletionOptions.setReason("test");
         v3api.deletePropertyTypes(sessionToken, Arrays.asList(type.getPermId()), deletionOptions);
 
         // exception should be thrown because DB is empty.
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS)));
+        final String sessionWorkspaceFilePath3 = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PROPERTY_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath3));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java
index 4f37c6bd3f32276f9816aed00373bca8400f0cbe..e2a4cf0ee6a3ac9bf5a6fc3df82480b12e4f17eb 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSampleTypesTest.java
@@ -72,7 +72,7 @@ public class ImportSampleTypesTest extends AbstractImportTest
     public void setupClass() throws IOException
     {
         String f = ImportSampleTypesTest.class.getName().replace(".", "/");
-        FILES_DIR = f.substring(0, f.length() - ImportSampleTypesTest.class.getSimpleName().length()) + "/test_files/";
+        FILES_DIR = f.substring(0, f.length() - ImportSampleTypesTest.class.getSimpleName().length()) + "test_files/";
     }
 
     @Test
@@ -83,9 +83,12 @@ public class ImportSampleTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         assertFalse(antibody.isAutoGeneratedCode());
     }
@@ -98,9 +101,12 @@ public class ImportSampleTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         boolean allMandatory = antibody.getPropertyAssignments().stream().allMatch(propAssignment -> propAssignment.isMandatory() == true);
         boolean allShownInEditView =
@@ -125,9 +131,13 @@ public class ImportSampleTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS_DIFFERENT_PROPERTY_ASSIGN)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS_DIFFERENT_PROPERTY_ASSIGN));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         boolean allNotMandatory = antibody.getPropertyAssignments().stream().allMatch(propAssignment -> propAssignment.isMandatory() == false);
         boolean allNotShownInEditView =
@@ -146,9 +156,12 @@ public class ImportSampleTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         boolean namePropertyExists =
                 antibody.getPropertyAssignments().stream().anyMatch(propAssignment -> propAssignment.getPropertyType().getCode().equals("$NAME"));
@@ -171,15 +184,18 @@ public class ImportSampleTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getDynamicPluginMap(),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_DYNAMIC_SCRIPT)));
+        final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_DYNAMIC_SCRIPT), FilenameUtils.concat(FILES_DIR, DYNAMIC_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0]));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
-        Plugin dynamicScript = antibody.getPropertyAssignments().get(0).getPlugin();
+        final Plugin dynamicScript = antibody.getPropertyAssignments().get(0).getPlugin();
         assertNotNull(dynamicScript);
         assertEquals(dynamicScript.getName().toUpperCase(), "$NAME.DYNAMIC");
-        assertEquals(dynamicScript.getScript(), TestUtils.getDynamicScript());
+        assertEquals(dynamicScript.getScript(), "def calculate():\n    return 1");
         assertEquals(dynamicScript.getPluginType(), PluginType.DYNAMIC_PROPERTY);
     }
 
@@ -188,15 +204,18 @@ public class ImportSampleTypesTest extends AbstractImportTest
     public void testSampleTypesWithPropertyHavingValidationScript() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, TestUtils.getValidationPluginMap(),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VALIDATION_SCRIPT)));
+        final String[] sessionWorkspaceFilePaths = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VALIDATION_SCRIPT), FilenameUtils.concat(FILES_DIR, VALIDATION_SCRIPT));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePaths[0]));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         Plugin validationScript = antibody.getValidationPlugin();
         assertNotNull(validationScript);
         assertEquals(validationScript.getName().toUpperCase(), "ANTIBODY.VALID");
-        assertEquals(validationScript.getScript(), TestUtils.getValidationScript());
+        assertEquals(validationScript.getScript(), "def validate(entity, isNew):\n  if isNew:\n    return");
         assertEquals(validationScript.getPluginType(), PluginType.ENTITY_VALIDATION);
     }
 
@@ -205,9 +224,13 @@ public class ImportSampleTypesTest extends AbstractImportTest
     public void testSampleTypesWithVocabularyInXls() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         PropertyAssignment propertyAssignment = antibody.getPropertyAssignments().get(0);
         assertNotNull(propertyAssignment);
@@ -219,10 +242,17 @@ public class ImportSampleTypesTest extends AbstractImportTest
     public void testSampleTypesWithVocabularyOnServer() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_DETECTION)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY_ON_SERVER)));
+        final String vocabularySessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_DETECTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(vocabularySessionWorkspaceFilePath));
+
+        final String sampleTypesSessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_VOCABULARY_ON_SERVER));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sampleTypesSessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "ANTIBODY");
+
         // THEN
         PropertyAssignment propertyAssignment = antibody.getPropertyAssignments().get(0);
         assertNotNull(propertyAssignment);
@@ -234,17 +264,22 @@ public class ImportSampleTypesTest extends AbstractImportTest
     public void testSampleTypesWithAutoGeneratedCodeAttribute() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_AUTO_GENERATED_CODES)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPES_WITH_AUTO_GENERATED_CODES));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         SampleType antibody = TestUtils.getSampleType(v3api, sessionToken, "SECONDBODY");
+
         // THEN
         assertTrue(antibody.isAutoGeneratedCode());
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*")
     public void shouldThrowExceptionIfNoSampleCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java
index f92702dfa16db252c708a8ab8f0af6254aaaf19d..55567f48535513c4456921074ecd09a38dd45563 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSamplesTest.java
@@ -15,15 +15,15 @@
  */
 package ch.ethz.sis.openbis.systemtest.plugin.excelimport;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
@@ -33,15 +33,16 @@ import org.springframework.transaction.annotation.Transactional;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.Sample;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
-import static org.testng.Assert.*;
-
 @ContextConfiguration(locations = "classpath:applicationContext.xml")
 @Transactional(transactionManager = "transaction-manager")
 @Rollback
@@ -109,9 +110,12 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.FAIL_IF_EXISTS, Paths.get(sessionWorkspaceFile));
+
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "AAA", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "AAA");
+
         // THEN
         assertEquals(sample.getCode(), "AAA");
         assertEquals(sample.getProject(), null);
@@ -127,9 +131,10 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertEquals(sample.getCode(), "VVV");
         assertEquals(sample.getProject(), null);
@@ -145,9 +150,10 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SAMPLES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "S1", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "S1");
         // THEN
         assertEquals(sample.getCode(), "S1");
         assertEquals(sample.getProject(), null);
@@ -163,10 +169,13 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)));
+        final String sessionWorkspaceFilePathForSpace = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSpace));
+        final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
     }
@@ -179,19 +188,28 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, SPACE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)));
+        final String sessionWorkspaceFilePathForSpace = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACE));
+        final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSpace),
+                Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(s?).*Entity \\[TEST_SPACE\\] could not be found. "
+                    + "Either you forgot to register it or mistyped the identifier.*")
     public void shouldThrowExceptionIfSpaceDoesntExist() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE)));
+        // the Excel contains internally property types which can be only manipulated by the system user
+        sessionToken = v3api.loginAsSystem();
+
+        final String sessionWorkspaceFilePathForSamplesSpaceElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSamplesSpaceElsewhere));
     }
 
     @Test
@@ -202,10 +220,17 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC)));
-        List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC)));
+        final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE));
+        final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForVocabularyType),
+                Paths.get(sessionWorkspaceFilePathForSampleType));
+
+        final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC));
+        List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS,
+                Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere));
         List<ISampleId> sampleIds = List.of((SampleIdentifier)ids.get(9), (SampleIdentifier)ids.get(10), (SampleIdentifier)ids.get(11));
         // WHEN
         List<Sample> samples = (List<Sample>) TestUtils.getSamplesById(v3api, sessionToken, sampleIds);
@@ -226,13 +251,22 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
+        final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE));
+        final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE));
+
         TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE)));
-        List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC)));
+                Paths.get(sessionWorkspaceFilePathForVocabularyType),
+                Paths.get(sessionWorkspaceFilePathForSampleType));
+
+        final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC));
+        List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS,
+                Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere));
         List<ISampleId> sampleIds = List.of((SampleIdentifier)ids.get(9), (SampleIdentifier)ids.get(10), (SampleIdentifier)ids.get(11));
         // WHEN
-        List<Sample> samples = (List<Sample>) TestUtils.getSamplesById(v3api, sessionToken, sampleIds);
+        List<Sample> samples = TestUtils.getSamplesById(v3api, sessionToken, sampleIds);
         Set<String> differentCyclicAssignments = new HashSet<>();
         for (Sample sample:samples) {
             differentCyclicAssignments.add((String)sample.getProperty("CYCLIC_SAMPLE_PROPERTY"));
@@ -242,7 +276,8 @@ public class ImportSamplesTest extends AbstractImportTest
         assertEquals(differentCyclicAssignments.size(), 2);
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(?s).*Property CYCLIC_SAMPLE_PROPERTY is not a sample of type ANTIBODY but of type TEST_TYPE.*")
     @DirtiesContext
     public void testSamplesAreCreatedWhenSampleTypeCyclicOnServerFixTypeWrongType() throws IOException
     {
@@ -250,10 +285,18 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
+        final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE));
+        final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE));
+
         TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE_CYCLIC_FIX_TYPE)));
-        List<IObjectId> ids = TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC_WRONG_TYPE)));
+                Paths.get(sessionWorkspaceFilePathForVocabularyType),
+                Paths.get(sessionWorkspaceFilePathForSampleType));
+
+        final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE_CYCLIC_WRONG_TYPE));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere));
     }
 
     @Test
@@ -264,12 +307,19 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
+        final String sessionWorkspaceFilePathForVocabularyType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE));
+        final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE));
         TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_TYPE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE)));
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE)));
+                Paths.get(sessionWorkspaceFilePathForVocabularyType),
+                Paths.get(sessionWorkspaceFilePathForSampleType));
+
+        final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
     }
@@ -282,11 +332,14 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE)),
-                Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE)));
+        final String sessionWorkspaceFilePathForSampleType = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLE_TYPE));
+        final String sessionWorkspaceFilePathForSampleTypeElsewhere = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SAMPLE_TYPE_ELSWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePathForSampleType),
+                Paths.get(sessionWorkspaceFilePathForSampleTypeElsewhere));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
     }
@@ -299,10 +352,10 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, CHILD_AS_IDENTIFIER)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, CHILD_AS_IDENTIFIER));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
         assertEquals(sample.getChildren().size(), 1);
@@ -319,10 +372,10 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, PARENT_AS_IDENTIFIER)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PARENT_AS_IDENTIFIER));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
         assertEquals(sample.getParents().size(), 1);
@@ -339,10 +392,10 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, CHILD_AS_DOLLARTAG)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, CHILD_AS_DOLLARTAG));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
         assertEquals(sample.getChildren().size(), 1);
@@ -359,10 +412,10 @@ public class ImportSamplesTest extends AbstractImportTest
         String sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, PARENT_AS_DOLLARTAG)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, PARENT_AS_DOLLARTAG));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "VVV", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "VVV");
         // THEN
         assertNotNull(sample);
         assertEquals(sample.getParents().size(), 1);
@@ -379,10 +432,10 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken,
-                Paths.get(FilenameUtils.concat(FILES_DIR, NON_MANDATORY_FIELD_MISSING)));
+        final String sessionWorkspaceFile = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, NON_MANDATORY_FIELD_MISSING));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFile));
         // WHEN
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "AAA", "TEST_SPACE");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "TEST_SPACE", "AAA");
         // THEN
         assertNotNull(sample);
         assertEquals(sample.getProperties().get("FOR_WHAT"), null);
@@ -396,9 +449,9 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-
-        List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING,
-                Paths.get(FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_LEVEL)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_LEVEL));
+        List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, Paths.get(sessionWorkspaceFilePath));
         String permId = result.get(result.size() - 1).toString();
 
         // WHEN
@@ -416,8 +469,9 @@ public class ImportSamplesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING,
-                Paths.get(FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_TYPE_LEVEL)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, AUTO_GENERATED_SAMPLE_TYPE_LEVEL));
+        List<IObjectId> result = TestUtils.createFrom(v3api, sessionToken, UpdateMode.IGNORE_EXISTING, Paths.get(sessionWorkspaceFilePath));
 
         String permId = result.get(result.size() - 1).toString();
         // WHEN
@@ -434,10 +488,11 @@ public class ImportSamplesTest extends AbstractImportTest
         // the Excel contains internally managed property types which can be only manipulated by the system user
         sessionToken = v3api.loginAsSystem();
 
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
 
         // test sample before update
-        Sample sample = TestUtils.getSample(v3api, sessionToken, "GENERAL_ELN_SETTINGS", "ELN_SETTINGS");
+        Sample sample = TestUtils.getSample(v3api, sessionToken, "ELN_SETTINGS", "GENERAL_ELN_SETTINGS");
         assertNotNull(sample);
         // properties are empty
         assertEquals(sample.getProperties().size(), 0);
@@ -456,11 +511,12 @@ public class ImportSamplesTest extends AbstractImportTest
         assertEquals(experiment.getProperties().containsKey("$NAME"), true);
         assertEquals(experiment.getProperties().get("$NAME"), "Default Experiment");
 
-        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS,
-                Paths.get(FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS_UPDATE)));
+        final String sessionWorkspaceFilePathForUpdate = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, GENERAL_ELN_SETTINGS_UPDATE));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePathForUpdate));
 
         // test sample after update
-        sample = TestUtils.getSample(v3api, sessionToken, "GENERAL_ELN_SETTINGS", "ELN_SETTINGS");
+        sample = TestUtils.getSample(v3api, sessionToken, "ELN_SETTINGS", "GENERAL_ELN_SETTINGS");
         assertNotNull(sample);
         // properties have been updated
         assertEquals(sample.getProperties().size(), 1);
@@ -483,16 +539,28 @@ public class ImportSamplesTest extends AbstractImportTest
         assertEquals(experiment.getProperties().get("$NAME"), "Default Experiment Updated");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(s?).*Entity \\[TEST_SPACE, /TEST_SPACE/TEST_PROJECT/TEST_EXPERIMENT\\] could not be found. "
+                    + "Either you forgot to register it or mistyped the identifier.*")
     public void shouldThrowExceptionIfSamplesSpaceProjectDoesntExist() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_PROJECT_EXPERIMENT_ELSEWHERE)));
+        // the Excel contains internally property types which can be only manipulated by the system user
+        sessionToken = v3api.loginAsSystem();
+
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, SAMPLES_SPACE_PROJECT_EXPERIMENT_ELSEWHERE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class,
+            expectedExceptionsMessageRegExp = "(s?).*Header 'name' is neither an attribute, property code or property label.*")
     public void shouldThrowExceptionIfMandatoryPropertyIsMissing() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, MANDATORY_FIELD_MISSING)));
+        // the Excel contains internally property types which can be only manipulated by the system user
+        sessionToken = v3api.loginAsSystem();
+
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, MANDATORY_FIELD_MISSING));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java
index 75fb6f688e44cb5cfcae88979eae971ef0099761..8024fecf89ea4ea66f6fb3c4adb9f5d117c7f4c9 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportSpacesTest.java
@@ -53,7 +53,7 @@ public class ImportSpacesTest extends AbstractImportTest
     public void setupClass() throws IOException
     {
         String f = ImportSpacesTest.class.getName().replace(".", "/");
-        FILES_DIR = f.substring(0, f.length() - ImportSpacesTest.class.getSimpleName().length()) + "/test_files/";
+        FILES_DIR = f.substring(0, f.length() - ImportSpacesTest.class.getSimpleName().length()) + "test_files/";
     }
 
     @Test
@@ -61,7 +61,8 @@ public class ImportSpacesTest extends AbstractImportTest
     public void testNormalSpacesAreCreated() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
         // WHEN
         Space rawData = TestUtils.getSpace(v3api, sessionToken, "TEST_SPACE");
         // THEN
@@ -74,7 +75,8 @@ public class ImportSpacesTest extends AbstractImportTest
     public void testNormalSpacesAreCreatedSecondSpace() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
         // WHEN
         Space space = TestUtils.getSpace(v3api, sessionToken, "TEST_SPACE2");
         // THEN
@@ -82,17 +84,19 @@ public class ImportSpacesTest extends AbstractImportTest
         assertEquals(space.getDescription(), "TEST desc");
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Code' is missing.*")
     public void shouldThrowExceptionIfNoSpaceCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = UserFailureException.class)
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "(?s).*Header 'Description' is missing.*")
     @DirtiesContext
     public void shouldCreateSpaceWhenNoDescription() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, SPACES_NO_DESCRIPTION)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, SPACES_NO_DESCRIPTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java
index 3b10cf00fe995b4615240409319fd99900a47dd2..707d1ab1ef31ef2f4108f5594760b5a00770df8d 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/ImportVocabularyTypesTest.java
@@ -40,7 +40,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTerm
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 @ContextConfiguration(locations = "classpath:applicationContext.xml")
 @Transactional(transactionManager = "transaction-manager")
@@ -75,7 +74,7 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     public void setupClass() throws IOException
     {
         String f = ImportVocabularyTypesTest.class.getName().replace(".", "/");
-        FILES_DIR = f.substring(0, f.length() - ImportVocabularyTypesTest.class.getSimpleName().length()) + "/test_files/";
+        FILES_DIR = f.substring(0, f.length() - ImportVocabularyTypesTest.class.getSimpleName().length()) + "test_files/";
     }
 
     @Test
@@ -86,7 +85,8 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
         // THEN
@@ -102,9 +102,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         VocabularyTerm term = detection.getTerms().get(0);
         assertEquals(term.getCode(), "HRP");
@@ -120,9 +123,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         List<Vocabulary> vocabularies = TestUtils.getAllVocabularies(v3api, sessionToken);
+
         // THEN
         assertEquals(vocabularies.size(), 3); // 2 created + 1 default
     }
@@ -135,9 +141,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
         sessionToken = v3api.loginAsSystem();
 
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_TYPES_XLS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         VocabularyTerm term = detection.getTerms().get(1);
         assertEquals(term.getCode(), "TEST_VOC");
@@ -150,24 +159,30 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     public void testVocabularyWithNoTermDescriptionShouldBeCreated() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_DESCRIPTION)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_DESCRIPTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         assertNotNull(detection);
         assertNull(detection.getTerms().get(0).getDescription());
     }
 
-    @Test(expectedExceptions = RuntimeException.class)
+    @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*")
     public void shouldThrowExceptionIfNoVocabularyCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
-    @Test(expectedExceptions = RuntimeException.class)
+    @Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "(s?).*Mandatory field is missing or empty: Code.*")
     public void shouldThrowExceptionIfNoTermCode() throws IOException
     {
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_CODE)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_CODE));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
     }
 
     @Test
@@ -175,9 +190,13 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     public void shouldNotThrowExceptionIfNoVocabularyDescription() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_DESCRIPTION)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_DESCRIPTION));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         assertNotNull(detection);
         assertNull(detection.getDescription());
@@ -188,9 +207,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     public void shouldNotThrowExceptionIfNoTermLabel() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_LABEL)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERM_LABEL));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         assertNotNull(detection);
         assertNull(detection.getTerms().get(0).getLabel());
@@ -201,9 +223,12 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     public void shouldNotThrowExceptionIfNoTerms() throws IOException
     {
         // GIVEN
-        TestUtils.createFrom(v3api, sessionToken, Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERMS)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, VOCABULARIES_NO_TERMS));
+        TestUtils.createFrom(v3api, sessionToken, Paths.get(sessionWorkspaceFilePath));
+
         // WHEN
         Vocabulary detection = TestUtils.getVocabulary(v3api, sessionToken, "DETECTION");
+
         // THEN
         assertNotNull(detection);
     }
@@ -214,7 +239,8 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
     {
         TestUtils.createVocabulary(v3api, sessionToken, "TEST_VOCABULARY_TYPE", "Test desc");
         // there should be no exceptions
-        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(FilenameUtils.concat(FILES_DIR, EXIST_VOCABULARIES)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(sessionToken, FilenameUtils.concat(FILES_DIR, EXIST_VOCABULARIES));
+        TestUtils.createFrom(v3api, sessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath));
         Vocabulary test = TestUtils.getVocabulary(v3api, sessionToken, "TEST_VOCABULARY_TYPE");
         assertNotNull(test);
     }
@@ -250,8 +276,9 @@ public class ImportVocabularyTypesTest extends AbstractImportTest
         assertEquals(beforeTerm.getDescription(), "Original Description");
         assertEquals(beforeTerm.getRegistrator().getUserId(), TEST_USER);
 
-        TestUtils.createFrom(v3api, systemSessionToken, UpdateMode.UPDATE_IF_EXISTS,
-                Paths.get(FilenameUtils.concat(FILES_DIR, VOCABULARY_WITH_TERM_TO_TAKE_OVER)));
+        final String sessionWorkspaceFilePath = uploadToAsSessionWorkspace(systemSessionToken,
+                FilenameUtils.concat(FILES_DIR, VOCABULARY_WITH_TERM_TO_TAKE_OVER));
+        TestUtils.createFrom(v3api, systemSessionToken, UpdateMode.UPDATE_IF_EXISTS, Paths.get(sessionWorkspaceFilePath));
 
         Vocabulary afterVocabulary = v3api.getVocabularies(instanceAdminSessionToken, Arrays.asList(vocabularyId), fetchOptions).get(vocabularyId);
         VocabularyTerm afterTerm = afterVocabulary.getTerms().get(0);
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java
index adbb3a91ba45a39e82ce887e9c3e615352a65525..8681e8e9cb335b9352f26fb00f78c25d6066e5f6 100644
--- a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java
+++ b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/TestUtils.java
@@ -15,23 +15,15 @@
  */
 package ch.ethz.sis.openbis.systemtest.plugin.excelimport;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
@@ -44,6 +36,11 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.Experime
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.ProjectSearchCriteria;
@@ -60,12 +57,11 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdentifier;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SamplePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleTypeSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.CustomASServiceExecutionOptions;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id.CustomASServiceCode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
@@ -73,19 +69,6 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi
 
 public class TestUtils
 {
-    private static final String TEST_XLS = "TEST-XLS";
-
-    private static final String XLS_NAME = "xls_name";
-
-    private static final String UPDATE_MODE = "update_mode";
-
-    private static final String XLS_PARAM = "xls";
-
-    public static final String CSV_PARAM = "csv";
-
-    private static final String SCRIPTS_PARAM = "scripts";
-
-    private static final String XLS_IMPORT_API = "xls-import-api";
 
     static Vocabulary getVocabulary(IApplicationServerInternalApi v3api, String sessionToken, String code)
     {
@@ -276,7 +259,7 @@ public class TestUtils
         }
     }
 
-    static Sample getSample(IApplicationServerInternalApi v3api, String sessionToken, String sampleCode, String spaceCode)
+    static Sample getSample(IApplicationServerInternalApi v3api, String sessionToken, String spaceCode, String sampleCode)
     {
         List<ISampleId> ids = new ArrayList<>();
         ids.add(new SampleIdentifier(spaceCode, null, null, sampleCode));
@@ -351,83 +334,11 @@ public class TestUtils
     static List<IObjectId> createFrom(IApplicationServerInternalApi v3api, String sessionToken, UpdateMode updateMode, Path... xls_paths)
             throws IOException
     {
-        List<byte[]> excels = new ArrayList<>();
-        for (Path xls_path : xls_paths)
-        {
-            byte[] xls = readData(xls_path);
-            excels.add(xls);
-        }
-        CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions();
-        options.withParameter(XLS_PARAM, excels);
-        options.withParameter(UPDATE_MODE, updateMode.name());
-        options.withParameter(XLS_NAME, TEST_XLS);
-        return (List<IObjectId>) v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options);
-    }
-
-    static String createFromCsv(IApplicationServerInternalApi v3api, String sessionToken, Path... csv_paths) throws IOException
-    {
-        List<byte[]> csvs = new ArrayList<>();
-        for (Path csv_path : csv_paths)
-        {
-            byte[] csv = readData(csv_path);
-            csvs.add(csv);
-        }
-        CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions();
-        options.withParameter(CSV_PARAM, csvs);
-        options.withParameter(UPDATE_MODE, UpdateMode.IGNORE_EXISTING.name());
-        options.withParameter(XLS_NAME, TEST_XLS);
-        return v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options).toString();
-    }
-
-    static String createFrom(IApplicationServerInternalApi v3api, String sessionToken, Map<String, String> scripts, Path... xls_paths)
-            throws IOException
-    {
-        return TestUtils.createFrom(v3api, sessionToken, scripts, UpdateMode.IGNORE_EXISTING, xls_paths);
-    }
-
-    static String createFrom(IApplicationServerInternalApi v3api, String sessionToken, Map<String, String> scripts, UpdateMode updateMode,
-            Path... xls_paths) throws IOException
-    {
-        List<byte[]> excels = new ArrayList<>();
-        for (Path xls_path : xls_paths)
-        {
-            byte[] xls = readData(xls_path);
-            excels.add(xls);
-        }
-        CustomASServiceExecutionOptions options = new CustomASServiceExecutionOptions();
-        options.withParameter(XLS_PARAM, excels);
-        options.withParameter(SCRIPTS_PARAM, scripts);
-        options.withParameter(UPDATE_MODE, updateMode.name());
-        options.withParameter(XLS_NAME, TEST_XLS);
-        return v3api.executeCustomASService(sessionToken, new CustomASServiceCode(XLS_IMPORT_API), options).toString();
-    }
-
-    static String getValidationScript()
-    {
-        return "def validate(entity, isNew):\n  if isNew:\n    return";
-    }
+        final String[] sessionWorkspaceFiles = Arrays.stream(xls_paths).map(Path::toString).toArray(String[]::new);
+        final ImportResult importResult = v3api.executeImport(sessionToken, new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles),
+                new ImportOptions(ImportMode.valueOf(updateMode.name())));
 
-    static String getDynamicScript()
-    {
-        return "def calculate():\n    return 1";
-    }
-
-    static Map<String, String> getValidationPluginMap()
-    {
-        String dynamicScriptString = getValidationScript();
-        Map<String, String> scriptsMap = new HashMap<>();
-        scriptsMap.put("valid.py", dynamicScriptString);
-
-        return scriptsMap;
-    }
-
-    static Map<String, String> getDynamicPluginMap()
-    {
-        String dynamicScriptString = getDynamicScript();
-        Map<String, String> scriptsMap = new HashMap<>();
-        scriptsMap.put("dynamic/dynamic.py", dynamicScriptString);
-
-        return scriptsMap;
+        return importResult.getObjectIds();
     }
 
     static VocabularyPermId createVocabulary(IApplicationServerInternalApi v3api, String sessionToken, String code, String description)
@@ -447,17 +358,6 @@ public class TestUtils
         }
     }
 
-    static String extractSamplePermIdFromResults(String result)
-    {
-        // Note this will work only if we created single sample!!
-        int indexOfSamples = result.indexOf("CreateSamplesOperationResult");
-        int permIdStart = indexOfSamples + "CreateSamplesOperationResult".length();
-        int permIdEnd = result.indexOf("]", indexOfSamples);
-        String permId = result.substring(permIdStart, permIdEnd);
-        permId = StringUtils.strip(permId, "[]");
-        return permId;
-    }
-
     static List<PropertyAssignment> extractAndSortPropertyAssignmentsPerGivenPropertyName(IEntityType rawData, List<String> propertyNames)
             throws Exception
     {
@@ -477,15 +377,4 @@ public class TestUtils
         return sortedPropertyAssignments;
     }
 
-    private static byte[] readData(Path xls_path) throws IOException
-    {
-        String path = xls_path.toString();
-        try (InputStream resourceAsStream = TestUtils.class.getClassLoader().getResourceAsStream(path))
-        {
-            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-            IOUtils.copy(resourceAsStream, byteArrayOutputStream);
-            return byteArrayOutputStream.toByteArray();
-        }
-    }
-
 }
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls
index 60bfe80c3e8fea6978f0145f164c9cb71130df34..ab24558768f2a6600fff42053a2ea52a5125cbe4 100644
Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/experiments/update.xls differ
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls
index 633a047ccafd7d2b61987293ac60eaa7c4699d17..21a24d210d4513255e21f55db657a2fcd929d162 100644
Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/property_types/normal_property_type.xls differ
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls
index 1f4512890f85a50466176aa79763c5cb03309cb4..59ad19a0a9394856024903b37ec0b635d4f5ff77 100644
Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/sample_types/with_dynamic_script.xls differ
diff --git a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls
index 2ba767a0c663d8d29d81131d1507ace8ec071198..40d3452f0b4f42da9c6cec7ebb25a5f8c673a41c 100644
Binary files a/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls and b/core-plugin-openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/plugin/excelimport/test_files/samples/space_project_experiment_elsewhere.xls differ
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
index df54c5679c00ae347859bbca0e5318e136d8713e..1d4263cd87b16fbe2ed4e4d27b644f02266d05f7 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
@@ -173,7 +173,9 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriter
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.SearchGloballyOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.SearchGloballyOperationResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -1818,9 +1820,10 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     }
 
     @Override
-    public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions)
+    public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions)
     {
-        executeOperation(sessionToken, new ImportOperation(importData, importOptions));
+        final ImportOperationResult operationResult = executeOperation(sessionToken, new ImportOperation(importData, importOptions));
+        return operationResult.getImportResult();
     }
 
     @Override
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
index b730776794ffb04fb7ffb8c6d4456c2e4bd97bc8..fbf88fbd32aaaf79c93a576e1366553af53b76e5 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
@@ -18,7 +18,6 @@ package ch.ethz.sis.openbis.generic.server.asapi.v3;
 import java.util.List;
 import java.util.Map;
 
-import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.create.AuthorizationGroupCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.delete.AuthorizationGroupDeletionOptions;
@@ -90,7 +89,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -1374,9 +1374,10 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements
     }
 
     @Override
-    public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions)
+    public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions)
     {
-        logAccess(sessionToken, "execute-import", "IImportData(%s) ImportOptions(%s)", importData, importOptions);
+        logAccess(sessionToken, "execute-import", "ImportData(%s) ImportOptions(%s)", importData, importOptions);
+        return null;
     }
 
     @Override
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java
index 1eba23cd4650c3f3bbda3dff28015498fc1281e3..fbce5f0a9ac2f6b51fddd924f836207fea1e942c 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiPersonalAccessTokenInvocationHandler.java
@@ -91,7 +91,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.externaldms.update.ExternalDmsUp
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.GlobalSearchObject;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.fetchoptions.GlobalSearchObjectFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.global.search.GlobalSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.Material;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.material.MaterialType;
@@ -1258,9 +1259,9 @@ public class ApplicationServerApiPersonalAccessTokenInvocationHandler implements
     }
 
     @Override
-    public void executeImport(final String sessionToken, final IImportData importData, final ImportOptions importOptions)
+    public ImportResult executeImport(final String sessionToken, final ImportData importData, final ImportOptions importOptions)
     {
-        invocation.proceedWithNewFirstArgument(converter.convert(sessionToken));
+        return invocation.proceedWithNewFirstArgument(converter.convert(sessionToken));
     }
 
     @Override
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java
index ae242abdc90c11999c57c0353907d98078b7b674..e90d0fca54cf7ecc12189af5f33befd28f67ab98 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/IImportExecutor.java
@@ -18,11 +18,12 @@
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
 
 public interface IImportExecutor
 {
 
-    void doImport(final IOperationContext context, final ImportOperation operation);
+    ImportResult doImport(final IOperationContext context, final ImportOperation operation);
 
 }
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java
index 51363987d1fd87e1efc9ee8d1b47da8bbeacfee3..2957d712024196b15cd1166a85a797230332fe2b 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportExecutor.java
@@ -17,23 +17,13 @@
 
 package ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
 
-import ch.ethz.sis.openbis.generic.server.xls.importer.utils.FileServerUtils;
 import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportScript;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportValue;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.UncompressedImportData;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ZipImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
@@ -46,110 +36,11 @@ import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 public class ImportExecutor implements IImportExecutor
 {
 
-    private static final String ZIP_PATH_SEPARATOR = "/";
-
-    private static final String SCRIPTS_FOLDER_NAME = "scripts" + ZIP_PATH_SEPARATOR;
-
-    private static final String DATA_FOLDER_NAME = "data" + ZIP_PATH_SEPARATOR;
-
-    private static final String MISCELLANEOUS_FOLDER_NAME = "miscellaneous" + ZIP_PATH_SEPARATOR;
-
-    private static final String FILE_SERVICES_FOLDER_NAME = MISCELLANEOUS_FOLDER_NAME + "file-service" + ZIP_PATH_SEPARATOR;
-
-    private static final String XLS_EXTENSION = "." + "xls";
-
-    private static final String XLSX_EXTENSION = "." + "xlsx";
-
     @Override
-    public void doImport(final IOperationContext context, final ImportOperation operation)
+    public ImportResult doImport(final IOperationContext context, final ImportOperation operation)
     {
-        final IImportData importData = operation.getImportData();
-
-        try
-        {
-            if (importData instanceof UncompressedImportData)
-            {
-                // XLS file
-
-                final UncompressedImportData uncompressedImportData = (UncompressedImportData) importData;
-
-                final Map<String, String> scripts = uncompressedImportData.getScripts() != null
-                        ? uncompressedImportData.getScripts().stream().collect(Collectors.toMap(ImportScript::getName, ImportScript::getSource))
-                        : null;
-                final Map<String, String> importValues = uncompressedImportData.getImportValues() != null
-                        ? uncompressedImportData.getImportValues().stream().collect(Collectors.toMap(ImportValue::getName, ImportValue::getValue))
-                        : null;
-                importXls(context, operation, scripts, importValues, uncompressedImportData.getFile(), null);
-            } else if (importData instanceof ZipImportData)
-            {
-                // ZIP file
-                final Map<String, String> scripts = new HashMap<>();
-                final Map<String, String> importValues = new HashMap<>();
-                byte[] xlsFileContent = null;
+        final ImportData importData = operation.getImportData();
 
-                final ZipImportData zipImportData = (ZipImportData) importData;
-                try (final ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(zipImportData.getFile())))
-                {
-                    ZipEntry entry;
-                    while ((entry = zip.getNextEntry()) != null)
-                    {
-                        final String entryName = entry.getName();
-                        if (entry.isDirectory())
-                        {
-                            if (!SCRIPTS_FOLDER_NAME.equals(entryName) && !DATA_FOLDER_NAME.equals(entryName) && !MISCELLANEOUS_FOLDER_NAME.equals(entryName))
-                            {
-                                throw UserFailureException.fromTemplate("Illegal directory '%s' is found inside the imported file.", entryName);
-                            }
-                        } else
-                        {
-                            if (!entryName.contains(ZIP_PATH_SEPARATOR) && (entryName.endsWith(XLS_EXTENSION) || entryName.endsWith(XLSX_EXTENSION)))
-                            {
-                                if (xlsFileContent == null)
-                                {
-                                    xlsFileContent = zip.readAllBytes();
-                                } else
-                                {
-                                    throw UserFailureException.fromTemplate("More than one XLS file found in the root of the imported ZIP file.");
-                                }
-                            } else if (entryName.startsWith(SCRIPTS_FOLDER_NAME))
-                            {
-                                scripts.put(entryName.substring(SCRIPTS_FOLDER_NAME.length()), new String(zip.readAllBytes()));
-                            } else if (entryName.startsWith(DATA_FOLDER_NAME))
-                            {
-                                importValues.put(entryName.substring(DATA_FOLDER_NAME.length()), new String(zip.readAllBytes()));
-                            } else
-                            {
-                                throw UserFailureException.fromTemplate(
-                                        "Entry '%s' is not allowed. Only one root XLS file is allowed and files inside the '%s' or '%s' folder",
-                                        entryName, SCRIPTS_FOLDER_NAME, DATA_FOLDER_NAME);
-                            }
-                        }
-                    }
-                }
-
-                if (xlsFileContent != null)
-                {
-                    importXls(context, operation, scripts, importValues, xlsFileContent, zipImportData.getFile());
-                } else
-                {
-                    throw UserFailureException.fromTemplate("XLS file not found in the root of the imported ZIP file.");
-                }
-
-            } else
-            {
-                throw UserFailureException.fromTemplate("Unknown instance of import data '%s'.",
-                        importData != null ? importData.getClass().getName() : null);
-            }
-        } catch (final IOException e)
-        {
-            throw UserFailureException.fromTemplate(e, "IO exception importing.");
-        }
-    }
-
-    private static void importXls(final IOperationContext context, final ImportOperation operation, final Map<String, String> scripts,
-            final Map<String, String> importValues, final byte[] xlsContent, byte[] zipImportDataOrNull)
-            throws IOException
-    {
         final IApplicationServerInternalApi applicationServerApi = CommonServiceProvider.getApplicationServerApi();
         final ImportOptions importOptions = operation.getImportOptions();
 
@@ -160,31 +51,18 @@ public class ImportExecutor implements IImportExecutor
                 .get("project-samples-enabled"));
         importerImportOptions.setAllowProjectSamples(projectSamplesEnabled);
 
-        final XLSImport xlsImport = new XLSImport(context.getSession().getSessionToken(), applicationServerApi, scripts,
-                importValues, ImportModes.valueOf(importOptions.getMode().name()), importerImportOptions, "DEFAULT");
-
-        xlsImport.importXLS(xlsContent);
-        if (zipImportDataOrNull != null)
+        try
         {
-            importZipData(zipImportDataOrNull);
-        }
-    }
-
-    public static void importZipData(byte[] zipImportDataOrNull) throws IOException
-    {
-        try (final ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(zipImportDataOrNull)))
+            final XLSImport xlsImport = new XLSImport(context.getSession().getSessionToken(), applicationServerApi,
+                    ImportModes.valueOf(importOptions.getMode().name()), importerImportOptions, importData.getSessionWorkspaceFiles(), false);
+            return new ImportResult(xlsImport.start());
+        } catch (final IOException e)
         {
-            ZipEntry entry;
-            while ((entry = zip.getNextEntry()) != null)
-            {
-                final String filePath = entry.getName();
-                if (!entry.isDirectory() && filePath.startsWith(FILE_SERVICES_FOLDER_NAME))
-                {
-                    String fileServicePath = ZIP_PATH_SEPARATOR + filePath.substring(FILE_SERVICES_FOLDER_NAME.length());
-                    byte[] fileBytes = zip.readAllBytes();
-                    FileServerUtils.write(fileServicePath, fileBytes);
-                }
-            }
+            throw UserFailureException.fromTemplate(e, "IO exception importing.");
+        } catch (final Exception e)
+        {
+            throw UserFailureException.fromTemplate(e,"Exception importing data: %s", e.getMessage());
         }
     }
+
 }
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java
index ef4032eeaa8069acad357189f88a7ad6bd389419..7702c16e50ea06f63a6466f3b7b2d19a972f337b 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/importer/ImportOperationExecutor.java
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Component;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportOperationResult;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.ImportResult;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.common.OperationExecutor;
 
@@ -41,8 +42,8 @@ public class ImportOperationExecutor extends OperationExecutor<ImportOperation,
     @Override
     protected ImportOperationResult doExecute(final IOperationContext context, final ImportOperation operation)
     {
-        executor.doImport(context, operation);
-        return new ImportOperationResult();
+        final ImportResult importResult = executor.doImport(context, operation);
+        return new ImportOperationResult(importResult);
     }
 
 }
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java
index 2e15b9a1a959b074293d744d8ba23030bf31ad4b..5d7c32c7277e67b10cbe7976b0c13c07e907f6ec 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/export/helper/AbstractXLSExportHelper.java
@@ -220,8 +220,7 @@ public abstract class AbstractXLSExportHelper<ENTITY_TYPE extends IEntityType> i
             final String filePath = matcher.group(3);
             try
             {
-                final byte[] fileContent = FileServerUtils.read(filePath);
-                imageFiles.put(filePath, fileContent);
+                imageFiles.put(filePath, FileServerUtils.readAllBytes(filePath));
             } catch (final IOException e)
             {
                 warnings.add(String.format("Could not read the file at path '%s'.", filePath));
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java
deleted file mode 100644
index 715cfae1dd0bdae8ff65e74cfb2d6ff7ced32c3b..0000000000000000000000000000000000000000
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright ETH 2022 - 2023 Zürich, Scientific IT Services
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package ch.ethz.sis.openbis.generic.server.xls.importer;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
-import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes;
-import ch.systemsx.cisd.common.filesystem.FileUtilities;
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
-import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataRegistrationHelper;
-
-public class MainImportXlsTest
-{
-    private static final Logger operationLog =
-            LogFactory.getLogger(LogCategory.OPERATION, MainImportXlsTest.class);
-
-    private static final int TIMEOUT = 10000;
-
-    private static final String URL =
-            "http://localhost:8888/openbis/openbis" + IApplicationServerApi.SERVICE_URL;
-
-    private static final File ELN_MASTER_DATA_PATH =
-            new File("../core-plugin-openbis/dist/core-plugins/eln-lims/1/as");
-
-    private static final File LIFE_SCIENCES_MASTER_DATA_PATH =
-            new File("../core-plugin-openbis/dist/core-plugins/eln-lims-life-sciences/1/as");
-
-    // used only for development!
-    public static void main(String[] args)
-    {
-        IApplicationServerApi v3 =
-                HttpInvokerUtils.createServiceStub(IApplicationServerApi.class, URL, TIMEOUT);
-        String sessionToken = v3.login("system", "a");
-
-        Map<String, String> scripts = getListScripts(ELN_MASTER_DATA_PATH.getPath());
-        ImportOptions options = new ImportOptions();
-
-        XLSImport importXls =
-                new XLSImport(sessionToken, v3, scripts, Map.of(), ImportModes.UPDATE_IF_EXISTS, options,
-                        "ELN-LIMS");
-        Collection<IObjectId> importedIds = new ArrayList<>();
-
-        File commonDataModel = new File(ELN_MASTER_DATA_PATH, "/master-data/common-data-model.xls");
-        importedIds.addAll(importXls.importXLS(FileUtilities.loadToByteArray(commonDataModel)));
-        File singleGroupDataModel =
-                new File(ELN_MASTER_DATA_PATH, "/master-data/single-group-data-model.xls");
-        importedIds.addAll(
-                importXls.importXLS(FileUtilities.loadToByteArray(singleGroupDataModel)));
-
-        Map<String, String> lifeSciencesImporterScripts =
-                getListScripts(LIFE_SCIENCES_MASTER_DATA_PATH.getPath());
-        XLSImport lifeSciencesImporter =
-                new XLSImport(sessionToken, v3, lifeSciencesImporterScripts,
-                        Map.of(), ImportModes.UPDATE_IF_EXISTS, options, "ELN-LIMS-LIFE-SCIENCES");
-        File lifeSciencesDataModel =
-                new File(LIFE_SCIENCES_MASTER_DATA_PATH, "/master-data/data-model.xls");
-        importedIds.addAll(lifeSciencesImporter.importXLS(
-                FileUtilities.loadToByteArray(lifeSciencesDataModel)));
-    }
-
-    private static Map<String, String> getListScripts(String path)
-    {
-        MasterDataRegistrationHelper helper = new MasterDataRegistrationHelper(Arrays.asList(path));
-        return helper.getAllScripts();
-    }
-}
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java
index 6340b3a5b13bee7351dd9fec47c67bc94a6589a9..64c3dc87bf60033ec122f3ba47d0377c80c09fae 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/XLSImport.java
@@ -15,12 +15,29 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.log4j.Logger;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.ethz.sis.openbis.generic.server.xls.importer.delay.DelayedExecutionDecorator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ScriptTypes;
+import ch.ethz.sis.openbis.generic.server.xls.importer.handler.ExcelParser;
 import ch.ethz.sis.openbis.generic.server.xls.importer.handler.VersionInfoHandler;
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.DatasetTypeImportHelper;
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.ExperimentImportHelper;
@@ -35,20 +52,34 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SemanticAnnotation
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SpaceImportHelper;
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.VocabularyImportHelper;
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.VocabularyTermImportHelper;
-import ch.ethz.sis.openbis.generic.server.xls.importer.handler.ExcelParser;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.DatabaseConsistencyChecker;
+import ch.ethz.sis.openbis.generic.server.xls.importer.utils.FileServerUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
-import org.apache.log4j.Logger;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider;
 
 public class XLSImport
 {
+    private static final String PATH_SEPARATOR = "/";
+
+    private static final String SCRIPTS_FOLDER_NAME = "scripts" + PATH_SEPARATOR;
+
+    private static final String DATA_FOLDER_NAME = "data" + PATH_SEPARATOR;
+
+    private static final String MISCELLANEOUS_FOLDER_NAME = "miscellaneous" + PATH_SEPARATOR;
+
+    private static final String FILE_SERVICES_FOLDER_NAME = MISCELLANEOUS_FOLDER_NAME + "file-service" + PATH_SEPARATOR;
+
+    private static final String XLS_EXTENSION = "." + "xls";
+
+    private static final String XLSX_EXTENSION = "." + "xlsx";
+
+    private static final int XLSX_DOCUMENT_LIMIT = 536870912; // 512 MB
+
+    private static final int EMBEDDED_DOCUMENT_LIMIT = 16777216; // 16 MB
+
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, XLSImport.class);
 
     private final String sessionToken;
@@ -85,8 +116,6 @@ public class XLSImport
 
     private final PropertyAssignmentImportHelper propertyAssignmentHelper;
 
-    private final ScriptImportHelper scriptHelper;
-
     private final SemanticAnnotationImportHelper semanticAnnotationImportHelper;
 
     private final DatabaseConsistencyChecker dbChecker;
@@ -95,8 +124,20 @@ public class XLSImport
 
     private final Map<String, String> importValues;
 
-    public XLSImport(String sessionToken, IApplicationServerApi api, Map<String, String> scripts, Map<String, String> importValues,
-            ImportModes mode, ImportOptions options, String xlsName)
+    private final ScriptImportHelper scriptHelper;
+
+    private final String[] sessionWorkspaceFiles;
+
+    private final byte[][] xls;
+
+    private static final String ZIP_EXTENSION = "." + "zip";
+
+    public XLSImport(String sessionToken,
+            IApplicationServerApi api,
+            ImportModes mode,
+            ImportOptions options,
+            String[] sessionWorkspaceFiles,
+            boolean shouldCheckVersionsOnDatabase) throws IOException
     {
         this.sessionToken = sessionToken;
         this.api = api;
@@ -105,8 +146,6 @@ public class XLSImport
         this.afterVersions = VersionInfoHandler.loadAllVersions(options);
         this.dbChecker = new DatabaseConsistencyChecker(this.sessionToken, this.api, this.afterVersions);
         this.delayedExecutor = new DelayedExecutionDecorator(this.sessionToken, this.api);
-        this.importValues = importValues;
-
         this.vocabularyHelper = new VocabularyImportHelper(this.delayedExecutor, mode, options, afterVersions);
         this.vocabularyTermHelper = new VocabularyTermImportHelper(this.delayedExecutor, mode, options, afterVersions);
         this.sampleTypeHelper = new SampleTypeImportHelper(this.delayedExecutor, mode, options, afterVersions);
@@ -118,122 +157,238 @@ public class XLSImport
         this.sampleHelper = new SampleImportHelper(this.delayedExecutor, mode, options);
         this.propertyHelper = new PropertyTypeImportHelper(this.delayedExecutor, mode, options, afterVersions);
         this.propertyAssignmentHelper = new PropertyAssignmentImportHelper(this.delayedExecutor, mode, options, beforeVersions);
-        this.scriptHelper = new ScriptImportHelper(this.delayedExecutor, mode, options, scripts);
         this.semanticAnnotationImportHelper = new SemanticAnnotationImportHelper(this.delayedExecutor, mode, options);
-        this.shouldCheckVersionsOnDatabase = xlsName == null || xlsName.equals("DEFAULT") == false;
-    }
+        this.shouldCheckVersionsOnDatabase = shouldCheckVersionsOnDatabase;
 
-    public List<IObjectId> importXLS(byte xls[])
-    {
-        if (shouldCheckVersionsOnDatabase)
-        {
-            this.dbChecker.checkVersionsOnDataBase();
-        }
+        // File Parsing
+        this.sessionWorkspaceFiles = sessionWorkspaceFiles;
+        final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider();
 
-        List<List<List<String>>> lines = ExcelParser.parseExcel(xls, importValues);
-        int pageNumber = 0;
-        int lineNumber;
+        final Map<String, String> scripts = new HashMap<>();
+        byte[][] xls = new byte[sessionWorkspaceFiles.length][];
+        this.importValues = new HashMap<>();
 
-        while (pageNumber < lines.size())
+        for (int i = 0; i < sessionWorkspaceFiles.length; i++)
         {
-            lineNumber = 0;
-            List<List<String>> page = lines.get(pageNumber);
-            int pageEnd = getPageEnd(page);
-            while (lineNumber < pageEnd)
+            InputStream read = sessionWorkspaceProvider.read(sessionToken, sessionWorkspaceFiles[i]);
+            if (sessionWorkspaceFiles[i].toLowerCase().endsWith(ZIP_EXTENSION))
             {
-                int blockEnd = getBlockEnd(page, lineNumber);
-                ImportTypes blockType;
-                try
+                try (final ZipInputStream zip = new ZipInputStream(read))
                 {
-                    blockType = ImportTypes.valueOf(page.get(lineNumber).get(0));
-                } catch (Exception e)
-                {
-                    throw new UserFailureException(
-                            "Exception at page " + (pageNumber + 1) + " and line " + (lineNumber + 1) + " with message: " + e.getMessage());
-                }
-                lineNumber++;
-
-                switch (blockType)
-                {
-                    case VOCABULARY_TYPE:
-                        vocabularyHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
-                        if (lineNumber + 2 != blockEnd)
+                    ZipEntry entry;
+                    while ((entry = zip.getNextEntry()) != null)
+                    {
+                        final String entryName = entry.getName();
+                        if (entry.isDirectory())
                         {
-                            vocabularyTermHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        }
-                        break;
-                    case SAMPLE_TYPE:
-                        // parse and create scripts
-                        scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
-                        // parse and create sample type
-                        sampleTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
-                        semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.SAMPLE_TYPE);
-                        // parse and assignment properties
-                        if (lineNumber + 2 != blockEnd)
+                            if (!SCRIPTS_FOLDER_NAME.equals(entryName) && !DATA_FOLDER_NAME.equals(entryName) &&
+                                    !entryName.startsWith(MISCELLANEOUS_FOLDER_NAME))
+                            {
+                                throw UserFailureException.fromTemplate("Illegal directory '%s' is found inside the imported file.", entryName);
+                            }
+                        } else
                         {
-                            scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
-                            propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
-                            propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE);
-                            semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE);
+                            if (!entryName.contains(PATH_SEPARATOR) && (entryName.endsWith(XLS_EXTENSION) || entryName.endsWith(XLSX_EXTENSION)))
+                            {
+                                validateEntrySize(entry.getSize(), XLSX_DOCUMENT_LIMIT);
+                                if (xls[i] == null)
+                                {
+                                    xls[i] = zip.readAllBytes();
+                                } else
+                                {
+                                    throw UserFailureException.fromTemplate("More than one XLS file found in the root of the imported ZIP file.");
+                                }
+                            } else if (entryName.startsWith(SCRIPTS_FOLDER_NAME))
+                            {
+                                validateEntrySize(entry.getSize(), EMBEDDED_DOCUMENT_LIMIT);
+                                scripts.put(entryName.substring(SCRIPTS_FOLDER_NAME.length()), new String(zip.readAllBytes()));
+                            } else if (entryName.startsWith(DATA_FOLDER_NAME))
+                            {
+                                validateEntrySize(entry.getSize(), EMBEDDED_DOCUMENT_LIMIT);
+                                this.importValues.put(entryName.substring(DATA_FOLDER_NAME.length()), new String(zip.readAllBytes()));
+                            } else if (!entryName.startsWith(MISCELLANEOUS_FOLDER_NAME))
+                            {
+                                throw UserFailureException.fromTemplate(
+                                        "Entry '%s' is not allowed. Only one root XLS file is allowed and files inside the '%s' or '%s' folder",
+                                        entryName, SCRIPTS_FOLDER_NAME, DATA_FOLDER_NAME);
+                            }
                         }
-                        break;
-                    case EXPERIMENT_TYPE:
-                        // parse and create scripts
-                        scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
-                        // parse and create experiment type
-                        experimentTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
-                        semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.EXPERIMENT_TYPE);
-                        // parse and assignment properties
-                        if (lineNumber + 2 != blockEnd)
+                    }
+                }
+            } else
+            {
+                final File canonicalFile = sessionWorkspaceProvider.getCanonicalFile(sessionToken, sessionWorkspaceFiles[i]);
+                validateEntrySize(canonicalFile.length(), XLSX_DOCUMENT_LIMIT);
+                xls[i] = sessionWorkspaceProvider.readAllBytes(sessionToken, sessionWorkspaceFiles[i]);
+
+                // Script folder support
+                final String scriptsFolderName = canonicalFile.getParent()
+                        + PATH_SEPARATOR + SCRIPTS_FOLDER_NAME;
+
+                final File scriptsFolder = new File(scriptsFolderName);
+                if (scriptsFolder.exists() && scriptsFolder.isDirectory())
+                {
+                    final File[] files = scriptsFolder.listFiles();
+                    if (files != null)
+                    {
+                        for (final File file : files)
                         {
-                            scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
-                            propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
-                            propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE);
-                            semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE);
+                            scripts.put(file.getName(), Files.readString(file.toPath(), StandardCharsets.UTF_8));
                         }
-                        break;
-                    case DATASET_TYPE:
-                        // parse and create scripts
-                        scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
-                        // parse and create dataset type
-                        datasetTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
-                        semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2, ImportTypes.DATASET_TYPE);
-                        // parse and assignment properties
-                        if (lineNumber + 2 != blockEnd)
+                    }
+                }
+
+                // Data folder support
+                final String dataFolderName = canonicalFile.getParent()
+                        + PATH_SEPARATOR + DATA_FOLDER_NAME;
+
+                final File dataFolder = new File(dataFolderName);
+                if (dataFolder.exists() && dataFolder.isDirectory())
+                {
+                    final File[] files = dataFolder.listFiles();
+                    if (files != null)
+                    {
+                        for (final File file : files)
                         {
-                            scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
-                            propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
-                            propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE);
-                            semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE);
+                            this.importValues.put(file.getName(), Files.readString(file.toPath(), StandardCharsets.UTF_8));
                         }
-                        break;
-                    case SPACE:
-                        spaceHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        break;
-                    case PROJECT:
-                        projectHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        break;
-                    case EXPERIMENT:
-                        experimentHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        break;
-                    case SAMPLE:
-                        sampleHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        break;
-                    case PROPERTY_TYPE:
-                        propertyHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
-                        semanticAnnotationImportHelper.importBlockForPropertyType(page, pageNumber, lineNumber, blockEnd);
-                        break;
-                    default:
-                        throw new UserFailureException("Unknown type: " + blockType);
+                    }
                 }
-                lineNumber = blockEnd + 1;
             }
-            pageNumber++;
         }
 
-        this.delayedExecutor.hasFinished();
+        this.xls = xls;
+        this.scriptHelper = new ScriptImportHelper(this.delayedExecutor, mode, options, scripts);
+    }
+
+    private static void validateEntrySize(final long size, final int limit)
+    {
+        if (size > limit)
+        {
+            throw UserFailureException.fromTemplate("Document limit exceeded: %d.", size);
+        }
+    }
 
+    public List<IObjectId> start() throws IOException
+    {
+        if (shouldCheckVersionsOnDatabase)
+        {
+            this.dbChecker.checkVersionsOnDataBase();
+        }
+
+        for (int i = 0; i < this.xls.length; i++)
+        {
+            List<List<List<String>>> lines = ExcelParser.parseExcel(this.xls[i], importValues);
+            int pageNumber = 0;
+            int lineNumber;
+
+            while (pageNumber < lines.size())
+            {
+                lineNumber = 0;
+                List<List<String>> page = lines.get(pageNumber);
+                int pageEnd = getPageEnd(page);
+                while (lineNumber < pageEnd)
+                {
+                    int blockEnd = getBlockEnd(page, lineNumber);
+                    ImportTypes blockType;
+                    try
+                    {
+                        blockType = ImportTypes.valueOf(page.get(lineNumber).get(0));
+                    } catch (Exception e)
+                    {
+                        throw new UserFailureException(
+                                "Exception at page " + (pageNumber + 1) + " and line " + (lineNumber + 1) + " with message: " + e.getMessage());
+                    }
+                    lineNumber++;
+
+                    switch (blockType)
+                    {
+                        case VOCABULARY_TYPE:
+                            vocabularyHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
+                            if (lineNumber + 2 != blockEnd)
+                            {
+                                vocabularyTermHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            }
+                            break;
+                        case SAMPLE_TYPE:
+                            // parse and create scripts
+                            scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
+                            // parse and create sample type
+                            sampleTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
+                            semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2,
+                                    ImportTypes.SAMPLE_TYPE);
+                            // parse and assignment properties
+                            if (lineNumber + 2 != blockEnd)
+                            {
+                                scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
+                                propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
+                                propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.SAMPLE_TYPE);
+                                semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd,
+                                        ImportTypes.SAMPLE_TYPE);
+                            }
+                            break;
+                        case EXPERIMENT_TYPE:
+                            // parse and create scripts
+                            scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
+                            // parse and create experiment type
+                            experimentTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
+                            semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2,
+                                    ImportTypes.EXPERIMENT_TYPE);
+                            // parse and assignment properties
+                            if (lineNumber + 2 != blockEnd)
+                            {
+                                scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
+                                propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
+                                propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.EXPERIMENT_TYPE);
+                                semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd,
+                                        ImportTypes.EXPERIMENT_TYPE);
+                            }
+                            break;
+                        case DATASET_TYPE:
+                            // parse and create scripts
+                            scriptHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2, ScriptTypes.VALIDATION_SCRIPT);
+                            // parse and create dataset type
+                            datasetTypeHelper.importBlock(page, pageNumber, lineNumber, lineNumber + 2);
+                            semanticAnnotationImportHelper.importBlockForEntityType(page, pageNumber, lineNumber, lineNumber + 2,
+                                    ImportTypes.DATASET_TYPE);
+                            // parse and assignment properties
+                            if (lineNumber + 2 != blockEnd)
+                            {
+                                scriptHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd, ScriptTypes.DYNAMIC_SCRIPT);
+                                propertyHelper.importBlock(page, pageNumber, lineNumber + 2, blockEnd);
+                                propertyAssignmentHelper.importBlock(page, pageNumber, lineNumber, blockEnd, ImportTypes.DATASET_TYPE);
+                                semanticAnnotationImportHelper.importBlockForEntityTypeProperty(page, pageNumber, lineNumber, blockEnd,
+                                        ImportTypes.DATASET_TYPE);
+                            }
+                            break;
+                        case SPACE:
+                            spaceHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            break;
+                        case PROJECT:
+                            projectHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            break;
+                        case EXPERIMENT:
+                            experimentHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            break;
+                        case SAMPLE:
+                            sampleHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            break;
+                        case PROPERTY_TYPE:
+                            propertyHelper.importBlock(page, pageNumber, lineNumber, blockEnd);
+                            semanticAnnotationImportHelper.importBlockForPropertyType(page, pageNumber, lineNumber, blockEnd);
+                            break;
+                        default:
+                            throw new UserFailureException("Unknown type: " + blockType);
+                    }
+                    lineNumber = blockEnd + 1;
+                }
+                pageNumber++;
+            }
+        }
+
+        this.delayedExecutor.hasFinished();
         VersionInfoHandler.writeAllVersions(options, afterVersions);
+        importZipData();
         return new ArrayList<>(this.delayedExecutor.getIds());
     }
 
@@ -290,4 +445,34 @@ public class XLSImport
         }
         return true;
     }
+
+
+    private void importZipData() throws IOException
+    {
+        for (int i = 0; i < this.sessionWorkspaceFiles.length; i++)
+        {
+            if (this.sessionWorkspaceFiles[i].toLowerCase().endsWith(ZIP_EXTENSION))
+            {
+                final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider();
+                InputStream read = sessionWorkspaceProvider.read(this.sessionToken, this.sessionWorkspaceFiles[i]);
+
+                try (final ZipInputStream zip = new ZipInputStream(read))
+                {
+                    ZipEntry entry;
+                    while ((entry = zip.getNextEntry()) != null)
+                    {
+                        final String filePath = entry.getName();
+                        if (!entry.isDirectory() && filePath.startsWith(FILE_SERVICES_FOLDER_NAME))
+                        {
+                            String fileServicePath = PATH_SEPARATOR + filePath.substring(FILE_SERVICES_FOLDER_NAME.length());
+                            try (final OutputStream outputStream = FileServerUtils.newOutputStream(fileServicePath))
+                            {
+                                zip.transferTo(outputStream);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java
index b67fb2fb56570b5e595f56bebbf0c27ba54f85b4..6d596c17d8086f3a5e93c18681a0110ebfd4f4c6 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/delay/DelayedExecutionDecorator.java
@@ -15,6 +15,18 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.delay;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType;
@@ -26,7 +38,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetTypeCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetTypeUpdate;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.IEntityTypeId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
@@ -94,10 +105,6 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
-import java.io.Serializable;
-import java.util.*;
-import java.util.stream.Stream;
-
 public class DelayedExecutionDecorator
 {
     private String sessionToken;
@@ -123,7 +130,7 @@ public class DelayedExecutionDecorator
         this.v3 = v3;
         this.ids = new LinkedHashSet<>();
         this.resolvedVariables = new HashMap<>();
-        this.delayedExecutions = new HashMap<>();
+        this.delayedExecutions = new LinkedHashMap<>(); // The only reason this is a linked Hash Map is so the list of error messages is on the same order as the delayed executions are added.
         this.propertyTypeCache = new HashMap<>();
     }
 
@@ -173,7 +180,7 @@ public class DelayedExecutionDecorator
         if (!delayedExecutions.isEmpty())
         {
             List<String> errors = new ArrayList<>();
-            Set<DelayedExecution> delayedExecutionsAsList = new HashSet<>();
+            Set<DelayedExecution> delayedExecutionsAsList = new LinkedHashSet<>(); // The only reason this is a linked Hash Set is so the list of error messages is on the same order as the delayed executions are added.
             for (List<DelayedExecution> valueList : delayedExecutions.values())
             {
                 delayedExecutionsAsList.addAll(valueList);
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java
index 68e38eb2b438447d8c8fbdcb979911340a8a8b24..27692bc4fdd2e32d2b98ae7b9ea071b1178774eb 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/BasicImportHelper.java
@@ -87,7 +87,10 @@ public abstract class BasicImportHelper extends AbstractImportHelper
                         switch (mode)
                         {
                             case FAIL_IF_EXISTS:
-                                throw new UserFailureException("Mode FAIL_IF_EXISTS - Found existing " + getTypeName());
+                                if (!(this instanceof SemanticAnnotationImportHelper))
+                                {
+                                    throw new UserFailureException("Mode FAIL_IF_EXISTS - Found existing " + getTypeName());
+                                }
                             case UPDATE_IF_EXISTS:
                                 updateObject(header, page.get(lineIndex), pageIndex, lineIndex);
                                 updateVersion(header, page.get(lineIndex));
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java
index 1b0e34aba048eee4b08115d57e8631bab3c87f30..e7087238d59e7aaddfd685449c6345b28cdda3c1 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/DatasetTypeImportHelper.java
@@ -15,6 +15,9 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetTypeCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetTypeUpdate;
@@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class DatasetTypeImportHelper extends BasicImportHelper
 {
@@ -81,9 +82,15 @@ public class DatasetTypeImportHelper extends BasicImportHelper
 
     @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values)
     {
-        String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
+        String version = getValueByColumnName(header, values, Attribute.Version);
+
         if (version == null || version.isEmpty()) {
             return true;
         } else {
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java
index 1c90876232a28322f5bed4f01a1c225a1e75b8cb..fea3039b97e4375afb28885fc5092ef7c40e81aa 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentImportHelper.java
@@ -92,7 +92,7 @@ public class ExperimentImportHelper extends BasicImportHelper
 
             experimentType = new EntityTypePermId(getValueByColumnName(header, page.get(lineIndex), EXPERIMENT_TYPE_FIELD));
             if(experimentType.getPermId() == null || experimentType.getPermId().isEmpty()) {
-                throw new UserFailureException("Mandatory field missing or empty: " + EXPERIMENT_TYPE_FIELD);
+                throw new UserFailureException("Mandatory field is missing or empty: " + EXPERIMENT_TYPE_FIELD);
             }
 
             // first check that experiment type exist.
@@ -171,7 +171,6 @@ public class ExperimentImportHelper extends BasicImportHelper
     @Override protected void updateObject(Map<String, Integer> header, List<String> values, int page, int line)
     {
         String identifier = getValueByColumnName(header, values, Attribute.Identifier);
-        String project = getValueByColumnName(header, values, Attribute.Project);
 
         if (identifier == null || identifier.isEmpty())
         {
@@ -182,6 +181,8 @@ public class ExperimentImportHelper extends BasicImportHelper
         IExperimentId experimentId = new ExperimentIdentifier(identifier);
         update.setExperimentId(experimentId);
 
+        String project = getValueByColumnName(header, values, Attribute.Project);
+
         // Project is used to "MOVE", only set if present since can't be null
         if (project != null && !project.isEmpty())
         {
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java
index 274c1a36a4b2970e52e859b3228533b195bb5e07..7b816377c5b8d3c8bd41202afeb49d9dce30a11c 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ExperimentTypeImportHelper.java
@@ -15,6 +15,9 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentTypeCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions;
@@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class ExperimentTypeImportHelper extends BasicImportHelper
 {
@@ -81,9 +82,15 @@ public class ExperimentTypeImportHelper extends BasicImportHelper
 
     @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values)
     {
-        String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
+        String version = getValueByColumnName(header, values, Attribute.Version);
+
         if (version == null || version.isEmpty()) {
             return true;
         } else {
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java
index a8b9c170e663cb8e19b9128746cccc5d28c7ee47..5eba0433083b649799dd2da7a50820d3d121c5f6 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyAssignmentImportHelper.java
@@ -15,6 +15,13 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IEntityType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.update.ListUpdateValue;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
@@ -43,13 +50,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class PropertyAssignmentImportHelper extends BasicImportHelper
 {
@@ -123,9 +124,15 @@ public class PropertyAssignmentImportHelper extends BasicImportHelper
 
     @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values)
     {
-        String version = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Version);
         String code = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
+        String version = getValueByColumnName(header, values, PropertyAssignmentImportHelper.Attribute.Version);
+
         if (version == null || version.isEmpty()) {
             return true;
         } else {
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java
index 74b87f10c9abcc7a1a671f81dd722cd020fdce1f..7f7ebd0b6d554061fd49b0eef1eba56a2bc544f7 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/PropertyTypeImportHelper.java
@@ -15,6 +15,15 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_MANDATORY_TYPE;
+import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_PREFIX;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.EntityKind;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.property.DataType;
@@ -29,21 +38,13 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.delay.DelayedExecutionDec
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportModes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.handler.JSONHandler;
-import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
+import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
-import org.apache.log4j.Logger;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_MANDATORY_TYPE;
-import static ch.ethz.sis.openbis.generic.server.xls.importer.utils.PropertyTypeSearcher.SAMPLE_DATA_TYPE_PREFIX;
 
 public class PropertyTypeImportHelper extends BasicImportHelper
 {
@@ -132,8 +133,7 @@ public class PropertyTypeImportHelper extends BasicImportHelper
         }
         if (!propertyData.equals(this.propertyCache.get(code)))
         {
-            throw new UserFailureException(
-                    "Unambiguous property " + code + " found, has been declared before with different attributes.");
+            throw new UserFailureException("Ambiguous property " + code + " found, it has been declared before with different attributes.");
         }
     }
 
@@ -149,6 +149,11 @@ public class PropertyTypeImportHelper extends BasicImportHelper
         String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
         boolean isInternalNamespace = ImportUtils.isInternalNamespace(code);
         boolean isSystem = delayedExecutor.isSystem();
         boolean canUpdate = (isInternalNamespace == false) || isSystem;
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java
index 0847c18c62584723972d69a6d5b7c13c3a61cd46..1d59d9745cb3a94c2c83d5b5b7c347fb032a44bd 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleImportHelper.java
@@ -107,7 +107,7 @@ public class SampleImportHelper extends BasicImportHelper
 
             sampleType = new EntityTypePermId(getValueByColumnName(header, page.get(lineIndex), SAMPLE_TYPE_FIELD));
             if(sampleType.getPermId() == null || sampleType.getPermId().isEmpty()) {
-                throw new UserFailureException("Mandatory field missing or empty: " + SAMPLE_TYPE_FIELD);
+                throw new UserFailureException("Mandatory field is missing or empty: " + SAMPLE_TYPE_FIELD);
             }
 
             // first check that sample type exist.
@@ -268,7 +268,7 @@ public class SampleImportHelper extends BasicImportHelper
         }
 
         if (identifier == null || identifier.isEmpty()) {
-            throw new UserFailureException("'Identifier' is missing, is mandatory since is needed to select a sample to update.");
+            throw new UserFailureException("'Identifier' is missing, it is mandatory since it is needed to select a sample to update.");
         }
 
         ISampleId sampleId = ImportUtils.buildSampleIdentifier(identifier);
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java
index 7597d8ba6a2ddc6ccab2c244356a44d3b3d602e6..91f624ebce1a80442b2343af412a7d43128ed96f 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/SampleTypeImportHelper.java
@@ -15,6 +15,9 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.id.PluginPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.create.SampleTypeCreation;
@@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class SampleTypeImportHelper extends BasicImportHelper
 {
@@ -83,9 +84,15 @@ public class SampleTypeImportHelper extends BasicImportHelper
 
     @Override protected boolean isNewVersion(Map<String, Integer> header, List<String> values)
     {
-        String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
+        String version = getValueByColumnName(header, values, Attribute.Version);
+
         if (version == null || version.isEmpty()) {
             return true;
         } else {
@@ -110,6 +117,12 @@ public class SampleTypeImportHelper extends BasicImportHelper
     @Override protected boolean isObjectExist(Map<String, Integer> header, List<String> values)
     {
         String code = getValueByColumnName(header, values, Attribute.Code);
+
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
         EntityTypePermId id = new EntityTypePermId(code);
 
         return delayedExecutor.getSampleType(id, new SampleTypeFetchOptions()) != null;
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java
index 1c116252adf7e16587d9af314271bed5b19684a1..bec20f48cd5d0425d7f225554bc4695264c5d477 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/ScriptImportHelper.java
@@ -15,6 +15,10 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.PluginType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.create.PluginCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.fetchoptions.PluginFetchOptions;
@@ -27,9 +31,6 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ImportTypes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.enums.ScriptTypes;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 
-import java.util.List;
-import java.util.Map;
-
 public class ScriptImportHelper extends BasicImportHelper
 {
     private static final String OWNER_CODE = "Code";
@@ -80,36 +81,42 @@ public class ScriptImportHelper extends BasicImportHelper
     {
         String scriptPath = getValueByColumnName(header, values, scriptType.getColumnName());
 
-        if (scriptPath == null || scriptPath.isEmpty())
+        if (scriptPath != null && !scriptPath.isEmpty())
         {
-            return;
-        }
-
-        PluginCreation creation = new PluginCreation();
-        creation.setName(getScriptName(header, values));
-        creation.setScript(this.scripts.get(scriptPath));
-        switch (scriptType) {
-            case VALIDATION_SCRIPT:
-                creation.setPluginType(PluginType.ENTITY_VALIDATION);
-                break;
-            case DYNAMIC_SCRIPT:
-                creation.setPluginType(PluginType.DYNAMIC_PROPERTY);
-                break;
+            String script = this.scripts.get(new File(scriptPath).getName());
+            if (script != null)
+            {
+                PluginCreation creation = new PluginCreation();
+                creation.setName(getScriptName(header, values));
+                creation.setScript(script);
+                switch (scriptType)
+                {
+                    case VALIDATION_SCRIPT:
+                        creation.setPluginType(PluginType.ENTITY_VALIDATION);
+                        break;
+                    case DYNAMIC_SCRIPT:
+                        creation.setPluginType(PluginType.DYNAMIC_PROPERTY);
+                        break;
+                }
+                delayedExecutor.createPlugin(creation);
+            }
         }
-        delayedExecutor.createPlugin(creation);
     }
 
     @Override protected void updateObject(Map<String, Integer> header, List<String> values, int page, int line)
     {
         String scriptPath = getValueByColumnName(header, values, scriptType.getColumnName());
-        String script = this.scripts.get(scriptPath);
-        if (script != null)
+        if (scriptPath != null && !scriptPath.isEmpty())
         {
-            PluginUpdate update = new PluginUpdate();
-            PluginPermId permId = new PluginPermId(getScriptName(header, values));
-            update.setPluginId(permId);
-            update.setScript(this.scripts.get(scriptPath));
-            delayedExecutor.updatePlugin(update);
+            String script = this.scripts.get(new File(scriptPath).getName());
+            if (script != null)
+            {
+                PluginUpdate update = new PluginUpdate();
+                PluginPermId permId = new PluginPermId(getScriptName(header, values));
+                update.setPluginId(permId);
+                update.setScript(script);
+                delayedExecutor.updatePlugin(update);
+            }
         }
     }
 
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java
index 7554dec7cac9ae9c2da369664f75921719682e81..758795589b87f09ac32e7403a9c48903db57414e 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyImportHelper.java
@@ -15,6 +15,9 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
@@ -27,9 +30,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class VocabularyImportHelper extends BasicImportHelper
 {
@@ -79,6 +80,11 @@ public class VocabularyImportHelper extends BasicImportHelper
         String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
         boolean isInternalNamespace = ImportUtils.isInternalNamespace(code);
         boolean isSystem = delayedExecutor.isSystem();
         boolean canUpdate = (isInternalNamespace == false) || isSystem;
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java
index cb22b739a744704837de575ce31805d1fd00e251..32d35170e47e690fea96d69042827a7a4428178e 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/helper/VocabularyTermImportHelper.java
@@ -15,6 +15,9 @@
  */
 package ch.ethz.sis.openbis.generic.server.xls.importer.helper;
 
+import java.util.List;
+import java.util.Map;
+
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create.VocabularyTermCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyTermFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyPermId;
@@ -28,9 +31,7 @@ import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.IAttribute;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.ImportUtils;
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.VersionUtils;
-
-import java.util.List;
-import java.util.Map;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class VocabularyTermImportHelper extends BasicImportHelper
 {
@@ -92,6 +93,11 @@ public class VocabularyTermImportHelper extends BasicImportHelper
         String version = getValueByColumnName(header, values, Attribute.Version);
         String code = getValueByColumnName(header, values, Attribute.Code);
 
+        if (code == null)
+        {
+            throw new UserFailureException("Mandatory field is missing or empty: " + Attribute.Code);
+        }
+
         boolean isInternalNamespace = ImportUtils.isInternalNamespace(code) || ImportUtils.isInternalNamespace(vocabularyCode);
         boolean isSystem = delayedExecutor.isSystem();
         boolean canUpdate = (isInternalNamespace == false) || isSystem;
diff --git a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java
index e8f8b280404a50993ba94c981ba9ad3ea380e1df..7f461860a818bb2b42b3c7db6aeba328a9762448 100644
--- a/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java
+++ b/server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/utils/FileServerUtils.java
@@ -5,6 +5,8 @@ import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Set;
@@ -47,15 +49,27 @@ public class FileServerUtils
         }
     }
 
-    public static byte[] read(String filePath) throws IOException
+    public static InputStream read(String src) throws IOException
     {
-        return Files.readAllBytes(getFilePath(filePath));
+        return Files.newInputStream(getFilePath(src));
     }
 
-    public static Path write(String filePath, byte[] bytes) throws IOException
+    public static byte[] readAllBytes(final String src) throws IOException
     {
-        Path filePathAsPath = getFilePath(filePath);
-        Files.createDirectories(filePathAsPath);
-        return Files.write(filePathAsPath, bytes);
+        final Path filePathAsPath = getFilePath(src);
+        return Files.readAllBytes(filePathAsPath);
     }
+
+    public static long write(final InputStream src, final String dst) throws IOException
+    {
+        final Path filePathAsPath = getFilePath(dst);
+        return Files.copy(src, filePathAsPath);
+    }
+
+    public static OutputStream newOutputStream(String dst) throws IOException
+    {
+        final Path filePathAsPath = getFilePath(dst);
+        return Files.newOutputStream(filePathAsPath);
+    }
+
 }
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
index d845b16a11d2e9c72ebb8136315c929faf376277..2c1a170dd54b4da4937ac96064247449a1782568 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
@@ -127,7 +127,7 @@ public final class UploadServiceServlet extends AbstractController
     //
 
     @Override
-    @RequestMapping({ "/upload", "/openbis/upload" })
+    @RequestMapping({ "/upload", "/openbis/upload", "/openbis/openbis/upload" })
     protected ModelAndView handleRequestInternal(final HttpServletRequest request,
             final HttpServletResponse response) throws Exception
     {
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java
index 7ed1f3ff06893945900508ebd6ec81b50b0a753b..736746dde6b61b3183915f8dff25738e605de97c 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java
@@ -31,6 +31,8 @@ public interface ISessionWorkspaceProvider
 
     File getSessionWorkspace(String sessionToken);
 
+    File getCanonicalFile(String sessionToken, String relativePathToFile) throws IOException;
+
     void deleteSessionWorkspace(String sessionToken);
 
     void write(String sessionToken, String relativePathToFile, InputStream inputStream) throws IOException;
@@ -39,6 +41,8 @@ public interface ISessionWorkspaceProvider
 
     InputStream read(String sessionToken, String relativePathToFile) throws IOException;
 
+    byte[] readAllBytes(String sessionToken, String relativePathToFile) throws IOException;
+
     void delete(String sessionToken, String relativePathToFile) throws IOException;
 
 }
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java
index b33d92b9ccf2879974d2b713edab98b214854d7c..a66afc20af4fd2faa89a7943f10caaf19f6ae188 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java
@@ -133,6 +133,14 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider
         return sessionWorkspace;
     }
 
+    @Override
+    public File getCanonicalFile(String sessionToken, String relativePathToFile) throws IOException
+    {
+        File sessionWorkspace = getSessionWorkspace(sessionToken);
+        File targetFile = new File(sessionWorkspace, relativePathToFile);
+        return targetFile.getCanonicalFile();
+    }
+
     @Override
     public void deleteSessionWorkspace(String sessionTokenOrPAT)
     {
@@ -156,6 +164,7 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider
     public void write(String sessionToken, String relativePathToFile, InputStream inputStream) throws IOException {
         File sessionWorkspace = getSessionWorkspace(sessionToken);
         File targetFile = new File(sessionWorkspace, relativePathToFile);
+        targetFile.getParentFile().mkdirs();
         Files.copy(inputStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
     }
 
@@ -172,6 +181,13 @@ public class SessionWorkspaceProvider implements ISessionWorkspaceProvider
         return Files.newInputStream(targetFile.toPath());
     }
 
+    @Override
+    public byte[] readAllBytes(String sessionToken, String relativePathToFile) throws IOException {
+        File sessionWorkspace = getSessionWorkspace(sessionToken);
+        File targetFile = new File(sessionWorkspace, relativePathToFile);
+        return Files.readAllBytes(targetFile.toPath());
+    }
+
     @Override
     public void delete(String sessionToken, String relativePathToFile) throws IOException {
         File sessionWorkspace = getSessionWorkspace(sessionToken);
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java
index f67f997478f3a2de43f15ce8f0dec63faafb78c1..21abc7ef30e554fe6530a67bae9ae1f999f89a51 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractImportTest.java
@@ -18,13 +18,18 @@
 package ch.ethz.sis.openbis.systemtest.asapi.v3;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStream;
+import java.util.Arrays;
+import java.util.UUID;
 
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeSuite;
 
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider;
+
 public class AbstractImportTest extends AbstractTest
 {
 
@@ -59,20 +64,26 @@ public class AbstractImportTest extends AbstractTest
         v3api.logout(sessionToken);
     }
 
-    protected static byte[] getFileContent(final String fileName)
+    protected static String[] uploadToAsSessionWorkspace(final String sessionToken, final String... relativeFilePaths) throws IOException
     {
-        try (final InputStream is = AbstractImportTest.class.getResourceAsStream("test_files/import/" + fileName))
-        {
-            if (is == null)
-            {
-                throw new RuntimeException();
-            }
+        final String[] canonicalFilePaths = getFilePaths(relativeFilePaths);
+        final ISessionWorkspaceProvider sessionWorkspaceProvider = CommonServiceProvider.getSessionWorkspaceProvider();
+        final String uploadId = UUID.randomUUID().toString();
+        final String[] destinations = new String[canonicalFilePaths.length];
 
-            return is.readAllBytes();
-        } catch (final IOException e)
+        for (int i = 0; i < canonicalFilePaths.length; i++)
         {
-            throw new RuntimeException(e);
+            destinations[i] = uploadId + "/" + relativeFilePaths[i];
+            sessionWorkspaceProvider.write(sessionToken, destinations[i], new FileInputStream(canonicalFilePaths[i]));
         }
+
+        return destinations;
+    }
+
+    private static String[] getFilePaths(final String... fileNames)
+    {
+        return Arrays.stream(fileNames).map(fileName -> AbstractImportTest.class.getResource("test_files/import/" + fileName).getPath())
+                .toArray(String[]::new);
     }
 
 }
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
index 972d9eced25f0e2c51965d2301e8ff0eb246e290..b229afb708d0239dbe127639d95dfaf0dd7b3116 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java
@@ -20,6 +20,9 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.fail;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -161,6 +164,8 @@ import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.BufferedAppender;
 import ch.systemsx.cisd.common.test.AssertionUtil;
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java
index 534803e5b09b244a585a1db87c59fdd44f4bcbbf..94ebd7a52ee8d6d6973dd45965229a55d0dad5ff 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UncompressedImportTest.java
@@ -16,8 +16,8 @@
 
 package ch.ethz.sis.openbis.systemtest.asapi.v3;
 
+import static org.junit.Assert.assertNotNull;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Arrays;
@@ -25,21 +25,17 @@ import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria;
-import ch.systemsx.cisd.common.action.IDelegatedAction;
-import org.testng.annotations.Test;
-
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportScript;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportValue;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.UncompressedImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.Plugin;
@@ -55,15 +51,18 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
+import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class UncompressedImportTest extends AbstractImportTest
 {
 
     @Test
-    public void testDataImport()
+    public void testDataImport() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import.xlsx"), null, null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -85,10 +84,11 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testLargeDataImport()
+    public void testLargeDataImport() throws Exception
     {
-        final UncompressedImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_large_cell.xlsx"), null,
-                List.of(new ImportValue("value-M20.txt", new String(getFileContent("data/value-M20.txt")))));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_large_cell.xlsx", "data/value-M20.txt");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -110,9 +110,11 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testImportOptionsUpdateIfExists()
+    public void testImportOptionsUpdateIfExists() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -137,9 +139,11 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testImportOptionsIgnoreExisting()
+    public void testImportOptionsIgnoreExisting() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.IGNORE_EXISTING);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -164,21 +168,23 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*FAIL_IF_EXISTS.*")
-    public void testImportOptionsFailIfExists()
+    public void testImportOptionsFailIfExists() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.xlsx"), null, null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.FAIL_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
     }
 
     @Test
-    public void testWithValidationScript()
+    public void testWithValidationScript() throws Exception
     {
         final String name = "valid.py";
         final String source = "print 'Test validation script'";
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("validation_script.xls"),
-                List.of(new ImportScript(name, source)), null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "validation_script.xls", "scripts/" + name);
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -203,12 +209,12 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testWithDynamicScript()
+    public void testWithDynamicScript() throws Exception
     {
         final String name = "dynamic.py";
         final String source = "1+1";
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("dynamic_script.xls"),
-                List.of(new ImportScript(name, source)), null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "dynamic_script.xls", "scripts/" + name);
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles[0]);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -238,9 +244,11 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testInternalTypes_failForNormalUser()
+    public void testInternalTypes_failForNormalUser() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_internal_type.xlsx"), null, null);
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_internal_type.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         assertUserFailureException(new IDelegatedAction()
@@ -255,13 +263,15 @@ public class UncompressedImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testInternalTypes()
+    public void testInternalTypes() throws Exception
     {
-        final IImportData importData = new UncompressedImportData(ImportFormat.XLS, getFileContent("import_internal_type.xlsx"), null, null);
-        final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
-
         final String systemSessionToken = v3api.loginAsSystem();
 
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(systemSessionToken, "import_internal_type.xlsx");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
+        final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
+
         v3api.executeImport(systemSessionToken, importData, importOptions);
 
         final DataSetTypeSearchCriteria dataSetTypeSearchCriteria = new DataSetTypeSearchCriteria();
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java
index 43807a6b2b4e0fa69d8351ec9e8cec314725eb12..d2196dd938d69289bccd70265a96d1c1248067a9 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ZipImportTest.java
@@ -25,19 +25,17 @@ import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.ExperimentType;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentTypeFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentTypeSearchCriteria;
-import ch.systemsx.cisd.common.action.IDelegatedAction;
-import org.testng.annotations.Test;
-
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.IImportData;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ImportFormat;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.data.ZipImportData;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportMode;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.importer.options.ImportOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.plugin.Plugin;
@@ -53,15 +51,18 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.VocabularyTerm;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.fetchoptions.VocabularyFetchOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularySearchCriteria;
+import ch.systemsx.cisd.common.action.IDelegatedAction;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 public class ZipImportTest extends AbstractImportTest
 {
 
     @Test
-    public void testDataImport()
+    public void testDataImport() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -82,9 +83,11 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testDataImportInternalTypes_failForNormalUser()
+    public void testDataImportInternalTypes_failForNormalUser() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_internal_type.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_internal_type.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         assertUserFailureException(new IDelegatedAction()
@@ -99,13 +102,15 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testDataImportInternalTypes_systemUser()
+    public void testDataImportInternalTypes_systemUser() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_internal_type.zip"));
-        final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
-
         final String systemSessionToken = v3api.loginAsSystem();
 
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(systemSessionToken, "import_internal_type.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
+        final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
+
         v3api.executeImport(systemSessionToken, importData, importOptions);
 
         final DataSetTypeSearchCriteria dataSetTypeSearchCriteria = new DataSetTypeSearchCriteria();
@@ -130,7 +135,6 @@ public class ZipImportTest extends AbstractImportTest
         assertEquals(sampleTypeSearchResult.getTotalCount(), 1);
         assertEquals(sampleTypeSearchResult.getObjects().get(0).getDescription(), "Internal Sample Type");
 
-
         final ExperimentTypeSearchCriteria experimentTypeSearchCriteria = new ExperimentTypeSearchCriteria();
         experimentTypeSearchCriteria.withCode().thatEquals("$INTERNAL_EXPERIMENT_TYPE");
 
@@ -144,9 +148,11 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testLargeDataImport()
+    public void testLargeDataImport() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("import_large_cell.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "import_large_cell.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -168,9 +174,11 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testImportOptionsUpdateIfExists()
+    public void testImportOptionsUpdateIfExists() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -195,9 +203,11 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testImportOptionsIgnoreExisting()
+    public void testImportOptionsIgnoreExisting() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.IGNORE_EXISTING);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -222,20 +232,24 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*FAIL_IF_EXISTS.*")
-    public void testImportOptionsFailIfExists()
+    public void testImportOptionsFailIfExists() throws Exception
     {
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("existing_vocabulary.zip"));
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "existing_vocabulary.zip");
+
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.FAIL_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
     }
 
     @Test
-    public void testWithValidationScript()
+    public void testWithValidationScript() throws Exception
     {
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "validation_script.zip");
+
         final String name = "valid.py";
         final String source = "print 'Test validation script'";
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("validation_script.zip"));
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
@@ -260,11 +274,13 @@ public class ZipImportTest extends AbstractImportTest
     }
 
     @Test
-    public void testWithDynamicScript()
+    public void testWithDynamicScript() throws Exception
     {
+        final String[] sessionWorkspaceFiles = uploadToAsSessionWorkspace(sessionToken, "dynamic_script.zip");
+
         final String name = "dynamic.py";
         final String source = "1+1";
-        final IImportData importData = new ZipImportData(ImportFormat.XLS, getFileContent("dynamic_script.zip"));
+        final ImportData importData = new ImportData(ImportFormat.EXCEL, sessionWorkspaceFiles);
         final ImportOptions importOptions = new ImportOptions(ImportMode.UPDATE_IF_EXISTS);
 
         v3api.executeImport(sessionToken, importData, importOptions);
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py
index c040fa67d3452162197945543e1ca9974e202924..07d91dc6abdd2cc89ac1acf5afcdb9bc93838ee9 100644
--- a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/dynamic.py
@@ -1 +1 @@
-1+1
+1+1
\ No newline at end of file
diff --git a/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py
new file mode 100644
index 0000000000000000000000000000000000000000..d23f9285861417fe45f0016056e72c385dfc6843
--- /dev/null
+++ b/server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py
@@ -0,0 +1 @@
+print 'Test validation script'
\ No newline at end of file
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
index aa489331b1f5f1bd2ce33b7cab50f89efc4f1404..26d12018fc51c6536baa5e5f9cde3d2be6ee11de 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/common.js
@@ -1288,6 +1288,26 @@ define([ 'jquery', 'underscore'], function($, _) {
 			this.assert.ok(false, msg);
 		};
 
+		this.base64ToBlob = (b64Data, contentType='', sliceSize=512) => {
+			var byteCharacters = atob(b64Data);
+			var byteArrays = [];
+
+			for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+				  var slice = byteCharacters.slice(offset, offset + sliceSize);
+
+					var byteNumbers = new Array(slice.length);
+					for (var i = 0; i < slice.length; i++) {
+							byteNumbers[i] = slice.charCodeAt(i);
+					}
+
+					var byteArray = new Uint8Array(byteNumbers);
+					byteArrays.push(byteArray);
+			}
+
+			var blob = new Blob(byteArrays, {type: contentType});
+			return blob;
+		}
+
 	};
 
 	return Common;
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
index 8d498fe2aedd1fa482ee3462643c8a582fe7676c..64d5520347628ad2e6d49483dd02170bfbf1c82c 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/dtos.js
@@ -58,12 +58,9 @@ var fullTypes = [
 "as/dto/importer/options/ImportMode",
 "as/dto/importer/ImportOperation",
 "as/dto/importer/ImportOperationResult",
+"as/dto/importer/ImportResult",
+"as/dto/importer/data/ImportData",
 "as/dto/importer/data/ImportFormat",
-"as/dto/importer/data/ZipImportData",
-"as/dto/importer/data/UncompressedImportData",
-"as/dto/importer/data/ImportValue",
-"as/dto/importer/data/ImportScript",
-"as/dto/importer/data/IImportData",
 "as/dto/entitytype/update/IEntityTypeUpdate",
 "as/dto/entitytype/update/PropertyAssignmentListUpdateValue",
 "as/dto/entitytype/EntityKind",
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
index 8f57a107fb9f6b3bc58d7f136d2c10eecced9969..e17ce32cf2ad37119c20a223c966747f6e37dede 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/openbis-execute-operations.js
@@ -709,7 +709,7 @@ define([], function() {
 
         this.executeImport = function (importData, importOptions) {
             return this._executeOperation(new dtos.ImportOperation(importData, importOptions)).then(function (results) {
-                return results.getResults()[0]
+                return results.getResults()[0].getImportResult()
             })
         }
 
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts
index df54153e4ff10d1bec2714c024ff8ce4f57f6598..b6b7f5065f7ef3050ee11cc02e1f7dac048247ee 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-import-export.ts
@@ -15,10 +15,10 @@
  *
  */
 
-import jquery from "./types/jquery"
-import underscore from "./types/underscore"
-import common from "./types/common"
-import openbis from "./types/openbis.esm"
+import jquery from './types/jquery'
+import underscore from './types/underscore'
+import common from './types/common'
+import openbis from './types/openbis.esm'
 
 exports.default = new Promise((resolve) => {
     require(["jquery", "underscore", "openbis", "test/common", "test/openbis-execute-operations", "test/dtos"], function (
@@ -29,62 +29,7 @@ exports.default = new Promise((resolve) => {
         openbisExecuteOperations,
         dtos
     ) {
-        var fileContent =
-            "UEsDBBQACAgIAEh8FVcAAAAAAAAAAAAAAAALAAAAX3JlbHMvLnJlbHOtksFOwzAMhu97iir3Nd1ACKGmu0xIuyE0HsAkbhu1iaPEg/L2RBMSDI2" +
-            "yw45xfn/+YqXeTG4s3jAmS16JVVmJAr0mY32nxMv+cXkvNs2ifsYROEdSb0Mqco9PSvTM4UHKpHt0kEoK6PNNS9EB52PsZAA9QIdyXVV3Mv5kiOaEWeyMEnFnVqLYfwS8hE1ta" +
-            "zVuSR8cej4z4lcikyF2yEpMo3ynOLwSDWWGCnneZX25y9/vlA4ZDDBITRGXIebuyBbTt44h/ZTL6ZiYE7q55nJwYvQGzbwShDBndHtNI31ITO6fFR0zX0qLWp78y+YTUEsHCIW" +
-            "aNJruAAAAzgIAAFBLAwQUAAgICABIfBVXAAAAAAAAAAAAAAAAGgAAAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzrZFNa8MwDIbv/RVG98VJB2OMOL2MQa/9+AHGUeLQxDaS1" +
-            "rX/fi4bWwpl7NCT0Nfzvkj16jSN6ojEQwwGqqIEhcHFdgi9gf3u7eEZVs2i3uBoJY+wHxKrvBPYgBdJL1qz8zhZLmLCkDtdpMlKTqnXybqD7VEvy/JJ05wBzRVTrVsDtG4rULt" +
-            "zwv+wY9cNDl+je58wyA0JzXIekTPRUo9i4CsvMgf0bfnlPeU/Ih3YI8qvg59SNncJ1V9mHu96C28J261Qfuz8JPPyt5lFra/e3XwCUEsHCE/w+XrSAAAAJQIAAFBLAwQUAAgIC" +
-            "ABIfBVXAAAAAAAAAAAAAAAADwAAAHhsL3dvcmtib29rLnhtbI1T23LaMBB971d49A6+cCkwmAw1eJKZ3iakybNsr7GKLHmkJUA6/feuZZym0z70AaS96OzZ3ePlzbmW3jMYK7S" +
-            "KWTgMmAcq14VQ+5h9e0gHM+ZZ5KrgUiuI2QUsu1m9W560OWRaHzx6r2zMKsRm4fs2r6DmdqgbUBQptak5kmn2vm0M8MJWAFhLPwqCqV9zoViHsDD/g6HLUuSw0fmxBoUdiAHJk" +
-            "djbSjSWrZalkPDYNeTxpvnMa6KdcJkzf/VK+6vxMp4fjk1K2TErubRAjVb69CX7DjlSR1xK5hUcIZwH4z7lDwiNlEllyNk6HgWc7O94azrEW23Ei1bI5S43WsqYoTleqxFRFPm" +
-            "/Irt2UA88s73z/CRUoU8xoxVd3txP7vokCqxogdPRbNz7bkHsK4zZLJxHzEOe3beDitkkoGelMBZdEYfCqZNnoHqtRQ35bzpyO+tPT7mBupdhS5XOu4IqO50ghZ6FFZkkxmYhK" +
-            "GDuisgh9jDUbk7zFwiG8hN9VEQhbDkZKD/pgiDWhHaNvy7nam9AIieSwyAIwhYXzvjRojuvUpKa7n/JSYrMQCcgpyXmHY2I2Y/302iazKbRIFqHo0EYbieDD6PxZJBu05Qml2y" +
-            "SefqTdOVQF/RLOv4WDX0k91DuLrTbc8y25xzk2nHyKa37d9T8XhOrX1BLBwg0mo9c+wEAAHADAABQSwMEFAAICAgASHwVVwAAAAAAAAAAAAAAAA0AAAB4bC9zdHlsZXMueG1s7" +
-            "Vldb5swFH3fr7D8vkISmrYTUHWdmPYyVWsqTZr24IABq8ZGttOG/vrZmBBI231k6kYq+mJ8fM+5h4sNjuufrwsK7rCQhLMATo5cCDCLeUJYFsCbRfT2FAKpEEsQ5QwHsMISnod" +
-            "vfKkqiq9zjBXQCkwGMFeqfOc4Ms5xgeQRLzHTIykXBVK6KzJHlgKjRBpSQZ2p686dAhEGQ5+tiqhQEsR8xZS20ULANp8SDc49CKzcJU+0lY+YYYEodELfaQRCP+VsqzOHFgh9+" +
-            "QDuENUiUxMec8oFENkygFHk1n8GZqjANuwSUbIUxIApKgitLGzJORJS37bVq7PbHDuZdiQvBLFeu4LuwOhLO6DECpuxVm320lV7LrH3conrxswYQmk7Y6bQAqFfIqWwYJHugOZ" +
-            "6UZV62jG9DqxMHfeL6EygajI97hDqRuddcpHodded8xYCCUEZZ4jelAFMEZUYttAHfs82YOhTnCotLEiWm1bx0jEiSvFCX2w4JrVVbi90+hhTem0W8dd0e/euFl2njxcdqzv63" +
-            "WC8N5dWqemgsqRVxI1I/Qwt8L4O6UEXlGSswDuBV4IrHKv6HVTDoY82gSDngjxoafMAs2bNm1eWIrGB7P1CoPBafeEKWRXt6V6gcqHBtoiEJXViPSZzQdjtgkekHdZlKlsbgPL" +
-            "4FicbkzlJNLUT6azTnUq52zpN9q1T43O3UF24W6nNNDgcM9PRzDNm9l5bo5nRzGhmNDOa2ceMNxvSl9KbDMqNNyg30yG5OfvPZpzu9t1u5jv7+Pm+2/h1+th5189fWj+0Pf0/K" +
-            "tvr+iHUK5r3Z0X7/VXyims2rIlmzhiGXrHjIc2ysWCHvCyd5lPaOSDrfVZbFJjjxwB+NgfStFO25YpQRZjtOY8Jl7wo0CZ+ctwjzJ4lgG/u95Y075HmT5JWQmAWVy3npMfxfsb" +
-            "p5Trt8U6e4l1hEetn0FLOehR79Lktpu5s/3cQ/gBQSwcIAAc48d4CAACAGAAAUEsDBBQACAgIAEh8FVcAAAAAAAAAAAAAAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sv" +
-            "Vffc9o4EH6/v8Lj9+JfGIcM0GnD5Xozaelc0nbm3oQtY01kyScJCPnrbyXZxsEuydxwfUiQdle737crw+fZ+6eSOjssJOFs7gYj33UwS3lG2Gbufnu4fXflOlIhliHKGZ67Byz" +
-            "d94vfZnsuHmWBsXIgAZNzt1CquvY8mRa4RHLEK8zAk3NRIgVbsfFkJTDKzKGSeqHvT7wSEebaDNfiLTl4npMUL3m6LTFTNonAFCmALwtSySbbU/amfJlAe6Da4OlAXFpPmy8Y9" +
-            "/KVJBVc8lyNUl7W0Posp970Bc8nEf63TEEMVHdETypskpXpW1iWSDxuq3eQu4JOrQkl6mAIu4uZyf9VODmhCovPPIMh54hKDL4KbfA9Vt8q41cP/CsYGre3mHn14cUsIzAPjcw" +
-            "ROJ+7H4LrZaIjTMB3gveys3Zkwfe3gG9LkWzSGeMfgmR3hGGwKrGtjX/x/Q2nn6AXcE27jr8xNK0xCLIpAOEdzlWbUqH1PaY4VTjrnlttFYUi94dyzWmbIMM52lKlIUA5Lhr7D" +
-            "hDPXabbSSElr3SJG0yppuk6qY79E/JPxq7zzHl5nyIKTQp8v7P/Yo6fWnU779CBb01baq9+stacP2qTzuvrIRkWur0V0k9hjcJ1EFh32KL5eNXd26OO/McMBHztvHTi7roZza2" +
-            "5MTDquhPQhR8kU4XGNYqm4zgKwrjtE0zlE9Y9B3c8SsDxDONoTPUAuO30Hd5hCgcMoq4NSliC3gsEixl0VZr/ur8UVVJPsE6abqXiZQ3NzqggWYbZYFlTs0RPABM+CTOfUh3Mj" +
-            "KDbNk0Y6P5ctl5Y1wsH6kXJ5etFdb1oqJ5/+Xrjut54oF5g75sdo/0+RQotZoLvHWECbVU78baQuU2TUdxDYKPP3C4Dq8cNKOty+jmVZhBwWIJ1t/Bn3k4DhD/A1AILfzGwsAc" +
-            "saIGZiI/9iPBlxE0/IhomF50jZ5/hy7KLDLLIIGOD7GxE0ME+HsY+Pof96n/APjbIxmcmYyPiM5PpR8QvI5b9iJ/MLv7Vs4tfnV3cm93khH8/IhlmNznL7tLUJq9Sm/SAX51Q6" +
-            "0dMh6kl56glo+ji7JJX2SU97IF/Qm8g5CTLMqmvrtcQ9jrf85UgTK0qI8udAqQbSOmj1NscZd6pBeRm+yPEBXnmTCF6A1ofi85PFrywKJL2HZ7VrJ+R2BAoTI0Y9EdJLQ/rNag" +
-            "ns4LWr7mCXje7wmhMvYuD4CoI/DCahKE/hjM552rY5bU6eVuBPKuwuCfP8GM4hf50pKDRz42eqretgHIdnWIlTPWM79lDgdkKWMLgBQGS5gVn7lZcKIEICL81RenjB5b9KIhqJ" +
-            "bkDrzMd+ZuCDLzhpX5TklrBshdNXVZE6wL/2M2jJeUVweYCADvblVvTACcjeQ4dZ+qWCHks1ZpXWfb77niZFzOeZVa6wwXprGFpM1pzu+4Wg237mrn4F1BLBwh76zOXRQQAAKo" +
-            "OAABQSwMEFAAICAgASHwVVwAAAAAAAAAAAAAAABQAAAB4bC9zaGFyZWRTdHJpbmdzLnhtbI2STU/DMAyG7/yKyHeWMgmEpjRTKeM0BJo6pJ2mkJo1UvNBnE7w7wkFiRvK0fbj9" +
-            "7Uti/WHHdkZIxnvarhaVMDQad8bd6ph3z1c3gKjpFyvRu+whk8kWMsLQZRYbnVUw5BSWHFOekCraOEDulx589GqlMN44hQiqp4GxGRHvqyqG26VccC0n1zKttfAJmfeJ2x/E0u" +
-            "QgowUs8mKgtLZO6sQxjOCfHlqm7v9ttkdjt3heSN4koJ/8//1/CxZxLa+xyLwHklHE1Kp8Dx4EblVrzgWkd1m93hsitAyahYsm7KMmgXbssv/UTz/mPwCUEsHCEgvXEPsAAAAo" +
-            "QIAAFBLAwQUAAgICABIfBVXAAAAAAAAAAAAAAAAEQAAAGRvY1Byb3BzL2NvcmUueG1sfVJNT8MwDL3zK6rcu6QtGlO0dhIguDCBxCYQt5C6I9AmUeJ9/XvSbi1fEzf7vZdnO/Z" +
-            "0tmvqaAPOK6NzkowYiUBLUyq9yslycRNPSORR6FLURkNO9uDJrDibSsulcfDgjAWHCnwUjLTn0ubkDdFySr18g0b4UVDoQFbGNQJD6lbUCvkhVkBTxsa0ARSlQEFbw9gOjuRoW" +
-            "crB0q5d3RmUkkINDWj0NBkl9EuL4Bp/8kHHfFM2CvcWTkp7clDvvBqE2+12tM06aeg/oc/zu8du1Fjp9qskkGJ6bIRLBwKhjIIBP5Trmafs6npxQ4qUpSxm45iliyTjGeNp9jK" +
-            "lv963hofYuGKupDPeVBjdV5WSEC09uPbJoGjVJXjplMWw2KIjfwAhr4VercMWCtDx7WUnGaB2v7XwOA+XUCkoL/fB4wTWt9kcsf/nzGI2idNkkVzw7Jwn429z9gZdZQcb1R5kk" +
-            "XVFh7Tt2q9f30HiYaQhCTEqrOEA9+GfIy0+AVBLBwgoNK7AewEAAPACAABQSwMEFAAICAgASHwVVwAAAAAAAAAAAAAAABMAAABkb2NQcm9wcy9jdXN0b20ueG1snc6xCsIwFIX" +
-            "h3acI2dtUB5HStIs4O1T3kN62AXNvyE2LfXsjgu6Ohx8+TtM9/UOsENkRarkvKykALQ0OJy1v/aU4ScHJ4GAehKDlBiy7dtdcIwWIyQGLLCBrOacUaqXYzuANlzljLiNFb1Kec" +
-            "VI0js7CmeziAZM6VNVR2YUT+SJ8Ofnx6jX9Sw5k3+/43m8he22jfmfbF1BLBwjh1gCAlwAAAPEAAABQSwMEFAAICAgASHwVVwAAAAAAAAAAAAAAABAAAABkb2NQcm9wcy9hcHA" +
-            "ueG1snZBNa8MwDIbv+xXB9Jo4CUtWiuOyMXYqbIes7BY8W2k9/IXtlPTfz21Z2/Oki754JL1kPWuVHcAHaU2HqqJEGRhuhTS7Dn32b/kSZSEyI5iyBjp0hIDW9IF8eOvARwkhS" +
-            "wQTOrSP0a0wDnwPmoUitU3qjNZrFlPqd9iOo+TwavmkwURcl2WLYY5gBIjcXYHoQlwd4n+hwvLTfWHbH13iUdKDdopFoATfwt5GpnqpgVapfE3Is3NKchaTInQjvz28n1fgp6J" +
-            "JXi820kzz8LVsh/YxuxsY0gs/wCNuysXLJJXIa4LvYSfy9iI1rZqiTHYe+KsRfFOV/gJQSwcIRY4uEvgAAACaAQAAUEsDBBQACAgIAEh8FVcAAAAAAAAAAAAAAAATAAAAW0Nvb" +
-            "nRlbnRfVHlwZXNdLnhtbL2UTU/DMAyG7/yKKlfUZuOAEGq3Ax9HmMQ4o5C4bVjzoSQb27/H6QZMo2xMqzhFjf2+j+22zsdL1SQLcF4aXZBhNiAJaG6E1FVBnqf36RUZj87y6cq" +
-            "CTzBX+4LUIdhrSj2vQTGfGQsaI6VxigV8dBW1jM9YBfRiMLik3OgAOqQhepBRfgslmzchuVvi9ZqLcpLcrPMiqiDM2kZyFjBMY5R26hw0fo9wocVOdemmsgyVbY6vpfXnvxOsr" +
-            "nYAUsXO4n234s1Ct6QNoOYRx+2kgGTCXHhgChPoS+yEZj3300VaNhvYu3GzV2NmGSb/E3gbeRzNlKXkIAyfK5Rk3jpgwtcAAYtvz0wxqQ/wfVg14Pumt6Z/6LwVeNoew56L+PI" +
-            "/NIGaORBPweH/3fsgtr331YH6iTPW42ZwcHwRn19eVKcWjcAFuf8NfBPnPhh1cuNrm2PhyDiZDHHRCBA/2Wc5bbf06ANQSwcItuOWgmMBAADUBQAAUEsBAhQAFAAICAgASHwVV" +
-            "4WaNJruAAAAzgIAAAsAAAAAAAAAAAAAAAAAAAAAAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgASHwVV0/w+XrSAAAAJQIAABoAAAAAAAAAAAAAAAAAJwEAAHhsL19yZWxzL3dvcmt" +
-            "ib29rLnhtbC5yZWxzUEsBAhQAFAAICAgASHwVVzSaj1z7AQAAcAMAAA8AAAAAAAAAAAAAAAAAQQIAAHhsL3dvcmtib29rLnhtbFBLAQIUABQACAgIAEh8FVcABzjx3gIAAIAYA" +
-            "AANAAAAAAAAAAAAAAAAAHkEAAB4bC9zdHlsZXMueG1sUEsBAhQAFAAICAgASHwVV3vrM5dFBAAAqg4AABgAAAAAAAAAAAAAAAAAkgcAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnh" +
-            "tbFBLAQIUABQACAgIAEh8FVdIL1xD7AAAAKECAAAUAAAAAAAAAAAAAAAAAB0MAAB4bC9zaGFyZWRTdHJpbmdzLnhtbFBLAQIUABQACAgIAEh8FVcoNK7AewEAAPACAAARAAAAA" +
-            "AAAAAAAAAAAAEsNAABkb2NQcm9wcy9jb3JlLnhtbFBLAQIUABQACAgIAEh8FVfh1gCAlwAAAPEAAAATAAAAAAAAAAAAAAAAAAUPAABkb2NQcm9wcy9jdXN0b20ueG1sUEsBAhQ" +
-            "AFAAICAgASHwVV0WOLhL4AAAAmgEAABAAAAAAAAAAAAAAAAAA3Q8AAGRvY1Byb3BzL2FwcC54bWxQSwECFAAUAAgICABIfBVXtuOWgmMBAADUBQAAEwAAAAAAAAAAAAAAAAATE" +
-            "QAAW0NvbnRlbnRfVHlwZXNdLnhtbFBLBQYAAAAACgAKAIACAAC3EgAAAAA="
+      var fileContent = "UEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAAaAAAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHOtUkFqwzAQvOcVYu+17KSEUiznEgq5pukDhLy2TGxJaDdt8vuqTWgcCKEHn8TMameGYcvVcejFJ0bqvFNQZDkIdMbXnWsVfOzenl5gVc3KLfaa0xeyXSCRdhwpsMzhVUoyFgdNmQ/o0qTxcdCcYGxl0GavW5TzPF/KONaA6kZTbGoFcVMXIHangP/R9k3TGVx7cxjQ8R0LyWkXk6COLbKCX3gmiyyJgbyfYT5lBuJTj3QNccaP7BdT2n/5uCeLyNcEf1QK9/M87OJ50i6sjli/c0zHNa5kTF/CzEp5c3LVN1BLBwi+0DoZ4AAAAKkCAABQSwMEFAAICAgAi3G7WAAAAAAAAAAAAAAAAA8AAAB4bC93b3JrYm9vay54bWyNU8lu2zAQvfcrBN5tSd5qG5YDV7aQAF2COE3OlDSyWFOkQI63FP33jCgrTdEeerDJWfjmzczT4uZcSe8IxgqtIhb2A+aBynQu1C5i3x+T3pR5FrnKudQKInYBy26WHxYnbfap1nuP3isbsRKxnvu+zUqouO3rGhRFCm0qjmSanW9rAzy3JQBW0h8EwcSvuFCsRZib/8HQRSEyWOvsUIHCFsSA5EjsbSlqy5aLQkh4ahvyeF1/5RXRjrnMmL98o31vvJRn+0OdUHbECi4tUKOlPn1Lf0CG1BGXknk5RwhnwahL+QNCI2VSGXI2jicBJ/s73pgO8VYb8aIVcrnNjJYyYmgO12pEFEX2r8i2GdQjT23nPD8LletTxGhFl3f3k7s+ixxLWuBkOB11vlsQuxIjNg1nA+YhTx+aQUVsHNCzQhiLrohD4dTJEaheY1FD/ruO3M6601NuoO5l2FCl8y6nyk4nSKGjsCKVxNjMBQXMXT50iB0MtZvR/AWCofxYHxRRCBtOBoovOieIFaFd42/LudprkMiJZD8IgrDBhTN+tujOq5SkpvtfcpIiNdAKyGmJeQcjIvbz42QwiaeTQW+wCoe9MNyMe5+Go3Ev2SQJTS5ex7PkF+nKoc7pF7f8LRr6SB6g2F5ot+eIbc4ZyJXj5FNa+++o+Z0mlq9QSwcIvAhorPsBAABwAwAAUEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAATAAAAeGwvdGhlbWUvdGhlbWUxLnhtbN2VXW/bIBSG7/crEPcrcdxESRSnmpZFu6i0i3S9P8HYpgFsAW2Xfz8MTuKvqdM0aep8Ew4878uBc2Kv735IgV6YNrxUCY5uJhgxRcuUqzzB3x92HxcYGQsqBVEqluATM/hu82ENK1swyZCTK7OCBBfWVitCDHXTYG7Kiim3lpVagnWhzkmq4dXZSkGmk8mcSOAKN3r9O/oyyzhl25I+S6ZsMNFMgHWpm4JXBiMF0uX4zYPooU4Qb86pfhGs1pl6ggq9pz7/oLjnB82CzAvSY1T/GJ0fPguNXkAkeOIfTDZrcgGEHXKZfxquAdLj9C2/afAbcj0/DwCl7ijDvaMFxJO4YVtQGI7kEM+X0OVb/vGAhzhmPf/4yt8O+IWje/63V3424OlySS930oLCcD7CT6OIdXgPFYKr4+iNszN9QbJSfB3FZ7MIFocGv1Kk1T5Br2ynmVp9JOGp1DsH+OK6TlXIniqWAXXcJ81BYFRxS4sdSC5OLkWMaAHaMOuKWW8NKwYtzZY9weMz2oMybyup+TMl6SUuuXqnp7gmTtqF8mWT7YALsbcnwe6NP6QpBU93btIHHru0RVW4IfaOl5UQdUT/3IEMjyVUN0KvCZ7Hs/rqoHJvGldbN5RVmmCjcoxA5O6jQK32zVxpY7dgipCC3ylUSHLLdPN+Uu/TmfQvh2UZo/YXM9fQrQWT0dW/D5OxzA757v/s3/7BSOdvSwYf9vPM5idQSwcICEac1SMCAADXCAAAUEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAANAAAAeGwvc3R5bGVzLnhtbO1YXW+bMBR936+w/L5CEpq2E1B1mZj2MlVrKk2a9uCAAavGRrbThv762ZgQSJp9ZOqWVvTF+Piecw8X23HtX64KCu6xkISzAI5OXAgwi3lCWBbA23n09hwCqRBLEOUMB7DCEl6Gb3ypKopvcowV0ApMBjBXqnznODLOcYHkCS8x0yMpFwVSuisyR5YCo0QaUkGdsetOnQIRBkOfLYuoUBLEfMmUttFCwDafEg1OPQis3Iwn2spHzLBAFDqh7zQCoZ9yttGZQguEvnwE94hqkbEJjznlAohsEcAocus/AzNUYBs2Q5QsBDFgigpCKwtbco6E1K9t9ersNsdWpi3JK0Gs166ge2T0hR1QYonNWKs2ee6q7UvsPV/iujEzhlDazpgxtEDol0gpLFikO6B5nlelnnZMrwMrU8f9IjoTqBqNTzuEutF5F1wket1157yFQEJQxhmit2UAU0Qlhi30gT+wNRj6FKdKCwuS5aZVvHSMiFK80A9rjkltldsHnT7GlN6YRfw13by9q0VX6e6iY3VH7w3Ge/NolZoOKktaRdyI1N/QAu/rkB50RUnGCrwVeC24wrGq96AaDn20DgQ5F+RRS5sPmDVr3mxZisQGsu8LgcIr9YUrZFW0pweByrkG2yISltSJ9ZjMBWF3cx6RdliXqWxtAMrjO5ysTeYk0dROpLNKtyrlbuo0OrROjc/tQnXhbqXW0+DlmBkPZvaYOXhtDWYGM4OZwcxg5hAz3uSYfim90VG58Y7KzfiY3Fz8ZzNO9/huD/Odc7x36DF+le467/r5S+sv7Uz/j8r2uv4R6hXN+7Oi/f4qecU1Ox1qtqdmTrPPdW4vend9LQrM3VAAP5vbQtop22JJqCLM9pxdwowXBVrHj057hMleAvjmfm9J0x5p+iRpKQRmcdVyznoc72ecXq7zHu/sKd41FrH+Bi3lokex91KbYurO5mI3/AFQSwcI2kJ8YdECAAAdFgAAUEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1svVffj9o4EH6/vyLKe8lvWFZA1cJxPWlbqmPbSvdmEodY68Q528Cyf/2N7SSEhEWrCu3DLvbMeOb7vjFkMvn4nFNrj7kgrJja3sC1LVzELCHFdmr/eFx+uLMtIVGRIMoKPLWPWNgfZ39MDow/iQxjaUGCQkztTMry3nFEnOEciQErcQGelPEcSdjyrSNKjlGiD+XU8V136OSIFLbJcM/fkoOlKYnxgsW7HBfSJOGYIgnwRUZKUWd7Tt6UL+HoAFRrPC2IC+Np8nlhL19OYs4ES+UgZnkFrc9y7IzPeD5z//cyeRFQ3RPVKb9OlsdvYZkj/rQrP0DuEpTaEErkURO2ZxOd/zu3UkIl5l9ZAk1OERUYfCXa4jWWP0rtl4/sOxhqtzObONXh2SQh0A+FzOI4ndqfvPvFSEXogJ8EH0RrbYmMHZaAb0eRqNNp41+cJA+kwGCVfFcZ/2GHOaNfQAu4pm3HvxhEqw2cbDNA+IBT2aSUaLPGFMcSJ+1zq52kUGR9zDeMNgkSnKIdlQoClGO8tu8B8dQulJwUUrJSlZhjShVN24pV7N+Qfxja1gtj+TpGFETyXLe1/6aPd61Kzgd0ZDstS+VV36wNY0/KpPK6qkmahZK3ROpbWKGwLQTWPTZoPoftvTlqif90Q8DX9Eslbq/r1iz1jYFWV0qACr9IIjOFaxCMwyjw/KjRCbryBSvNwR0NRuB4gXbUpqoBzCj9gPeYwgGNqG2DEoagc4ZgNgFVhf6v9KWoFKqDVdJ4JyTLK2imRxlJElxcLKtr5ugZYMInKfSnkEfdI1DbpPE9pc9t6/lVPf9CvWB0+3pBVS+4VM+9fb2wqhdeqOfd6ftm2mh+T5FEswlnB4vrQFPVdLwppG/TcBD1EJjoK7dLw+pxA8qqnPqeCt0IOCzAup+5E2evAMIfYGqA+deBeTdH5veQeQ0yHfG5H+GfRyxMhO7wGZngGpmbMwk0Cq+FM+jgDF7BGV7DORoEN4caaiDBFdH7EeF5xLwf0W1L+Ard6F3bEvXaEnW49iOGHSbRK0yG78pk2MM56jDpR9x1mAxfYTJ67ys46kEdd8j0Izy3cwdH1R10anqjLj2n9dtbclLIValHZSuDcQrG29P4tT2NXl0LjIDNg4Fx8sIKiegc5m/MW48ReImQJO47HDNHfkV8S6Aw1QOaOxhVI1u1holGr0DoDZOgbL3L9NyndpHn3Xme6wdD33dDOJMyJi+7nGZ23ZUwMpWYr8kLPKDGoE9rPNMzbT3jVNtmqLEtlWLFdfWEHYrHDBcrYAlt5gRI6peOqV0yLjkiMIxtKIqfPhXJr4zIZky24BWjNZLGMJrNWa7eXoSaKoszURclUc9q96TmyRKzkmB9I4CdUWWpBbASkqageCGXhItTqca8SpI/96erO5uwJDHjNFyQ1hqWJqMxN+t2Mdg2r36z/wFQSwcIhMegWToEAAA+DgAAUEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAAUAAAAeGwvc2hhcmVkU3RyaW5ncy54bWyNkk9LAzEQxe9+ijB3m62CSMmmrGs9VZSyFXoqaXbsBjZ/zGSLfnvjIniTHGfmN+89hhHrTzuyC0Yy3tWwXFTA0GnfG3euYd89Xd8Do6Rcr0bvsIYvJFjLK0GUWF51VMOQUlhxTnpAq2jhA7o8effRqpTLeOYUIqqeBsRkR35TVXfcKuOAaT+5lG1vgU3OfEzY/jaWIAUZKWaTFQWls3dWIYwXBPn20jYP+22zOxy7w+tG8CQF/+H/2Wl9j0XgI5KOJqR8kSJ+DlNEbtUJxyKy2+yej00RWkbNgmUpy6hZsC27/B/F89/Ib1BLBwjRS1GV6QAAAHUCAABQSwMEFAAICAgAi3G7WAAAAAAAAAAAAAAAAAsAAABfcmVscy8ucmVsc62SwU7DMAyG73uKKvc13UAIoaa7TEi7ITQewCRuG7WJo8SD8vZEExIMjbLDjnF+f/5ipd5MbizeMCZLXolVWYkCvSZjfafEy/5xeS82zaJ+xhE4R1JvQypyj09K9MzhQcqke3SQSgro801L0QHnY+xkAD1Ah3JdVXcy/mSI5oRZ7IwScWdWoth/BLyETW1rNW5JHxx6PjPiVyKTIXbISkyjfKc4vBINZYYKed5lfbnL3++UDhkMMEhNEZch5u7IFtO3jiH9lMvpmJgTurnmcnBi9AbNvBKEMGd0e00jfUhM7p8VHTNfSotanvzL5hNQSwcIhZo0mu4AAADOAgAAUEsDBBQACAgIAItxu1gAAAAAAAAAAAAAAAARAAAAZG9jUHJvcHMvY29yZS54bWx9Uk1PwzAMvfMrqty7pCkMFG1FGgguTCAxBOIWUncLtEmUeIz9e9JuLV8TN/u9l2c79uT8o6mTd/BBWzMl2YiRBIyypTbLKXlYXKVnJAkoTSlra2BKthDIeXE0UU4o6+HOWwceNYQkGpkglJuSFaITlAa1gkaGUVSYSFbWNxJj6pfUSfUml0A5Y2PaAMpSoqStYeoGR7K3LNVg6da+7gxKRaGGBgwGmo0y+qVF8E04+KBjvikbjVsHB6U9Oag/gh6Em81mtMk7aew/o0/zm/tu1FSb9qsUkGKyb0QoDxKhTKKB2JXrmcf84nJxRQrOOEvZOGV8keUiZ4LnzxP6631ruIutL+ZaeRtshcltVWkFyUMA3z4ZFK26hKC8dhgXW3TkDyDmtTTLddxCASa9nnWSAWr3W8uA83gJlYZyto0eB7C+zWaP/T/nccpOUn66yMYi44Lzb3P2Bl1lD++6PcjiuCs6pG3XYf3yCgp3Iw1JjFFjDTu4D/8cafEJUEsHCOM3pCd7AQAA8AIAAFBLAwQUAAgICACLcbtYAAAAAAAAAAAAAAAAEAAAAGRvY1Byb3BzL2FwcC54bWydkE1PwzAMhu/8iiratU3LoExTmgmEOE2CQ5m4VSFxt6DmQ4k7df+ebBPbztgXf+mx/bLVZIZsDyFqZxtSFSXJwEqntN025LN9yxckiyisEoOz0JADRLLid+wjOA8BNcQsEWxsyA7RLymNcgdGxCK1ber0LhiBKQ1b6vpeS3h1cjRgkd6XZU1hQrAKVO4vQHImLvf4X6hy8nhf3LQHn3ictWD8IBA4o9ewdSiGVhvgVSpfEvbs/aClwKQIX+vvAO+nFfSpqJPPZ2ttx6n7WtRd/ZDdDHTphR+QSOty9jLqQeVzRm9hR/LmLDWvHosy2Wngr8boVVX+C1BLBwiawU9w+AAAAJoBAABQSwMEFAAICAgAi3G7WAAAAAAAAAAAAAAAABMAAABkb2NQcm9wcy9jdXN0b20ueG1snc6xCsIwFIXh3acI2dtUB5HStIs4O1T3kN62AXNvyE2LfXsjgu6Ohx8+TtM9/UOsENkRarkvKykALQ0OJy1v/aU4ScHJ4GAehKDlBiy7dtdcIwWIyQGLLCBrOacUaqXYzuANlzljLiNFb1KecVI0js7CmeziAZM6VNVR2YUT+SJ8Ofnx6jX9Sw5k3+/43m8he22jfmfbF1BLBwjh1gCAlwAAAPEAAABQSwMEFAAICAgAi3G7WAAAAAAAAAAAAAAAABMAAABbQ29udGVudF9UeXBlc10ueG1svVXJTsMwEL33KyJfUeKWA0IobQ8sR6hEOSNjTxLTeJHtlvbvGSdQldKFKhWXWPHMW2YysfPxUtXJApyXRg/JIOuTBDQ3QupySF6mD+k1GY96+XRlwSeYq/2QVCHYG0o9r0AxnxkLGiOFcYoFfHUltYzPWAn0st+/otzoADqkIXKQUX4HBZvXIblf4nari3CS3LZ5UWpImLW15CxgmMYo3YlzUPsDwIUWW+7SL2cZIpscX0nrL/YrWF1uCUgVK4v7uxHvFnZDmgBinrDdTgpIJsyFR6YwgS5r+hqLoR/Gzd6MmWVoKTtzeXuENyVPUzNFITkIw+cKIZm3DpjwFUBA882aKSb1Ef2AYwTtc9DZQ0NzRNCHVQ3+3OU2pH9odQPwtFm61/vTxJr/WAcq5kA8B4e/+dkbscl9yEc78P8x5Oh04oz1eBQ5OL3cb72ITi0SgQvy8LdeKyJ15/5CPFwEiFO1+dwHozrLtzS/xXs5ba6F0SdQSwcIKJkGmHMBAABFBgAAUEsBAhQAFAAICAgAi3G7WL7QOhngAAAAqQIAABoAAAAAAAAAAAAAAAAAAAAAAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQAFAAICAgAi3G7WLwIaKz7AQAAcAMAAA8AAAAAAAAAAAAAAAAAKAEAAHhsL3dvcmtib29rLnhtbFBLAQIUABQACAgIAItxu1gIRpzVIwIAANcIAAATAAAAAAAAAAAAAAAAAGADAAB4bC90aGVtZS90aGVtZTEueG1sUEsBAhQAFAAICAgAi3G7WNpCfGHRAgAAHRYAAA0AAAAAAAAAAAAAAAAAxAUAAHhsL3N0eWxlcy54bWxQSwECFAAUAAgICACLcbtYhMegWToEAAA+DgAAGAAAAAAAAAAAAAAAAADQCAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sUEsBAhQAFAAICAgAi3G7WNFLUZXpAAAAdQIAABQAAAAAAAAAAAAAAAAAUA0AAHhsL3NoYXJlZFN0cmluZ3MueG1sUEsBAhQAFAAICAgAi3G7WIWaNJruAAAAzgIAAAsAAAAAAAAAAAAAAAAAew4AAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgAi3G7WOM3pCd7AQAA8AIAABEAAAAAAAAAAAAAAAAAog8AAGRvY1Byb3BzL2NvcmUueG1sUEsBAhQAFAAICAgAi3G7WJrBT3D4AAAAmgEAABAAAAAAAAAAAAAAAAAAXBEAAGRvY1Byb3BzL2FwcC54bWxQSwECFAAUAAgICACLcbtY4dYAgJcAAADxAAAAEwAAAAAAAAAAAAAAAACSEgAAZG9jUHJvcHMvY3VzdG9tLnhtbFBLAQIUABQACAgIAItxu1gomQaYcwEAAEUGAAATAAAAAAAAAAAAAAAAAGoTAABbQ29udGVudF9UeXBlc10ueG1sUEsFBgAAAAALAAsAwQIAAB4VAAAAAA=="
 
         var executeModule = function (moduleName: string, facade: openbis.openbis, dtos: openbis.bundle) {
             QUnit.module(moduleName)
@@ -117,14 +62,23 @@ exports.default = new Promise((resolve) => {
                 var c = new common(assert, dtos)
 
                 var fAction = function (facade: openbis.openbis) {
-                    var importData = new dtos.UncompressedImportData()
-                    importData.setFormat("XLS")
-                    importData.setFile(fileContent)
-
-                    var importOptions = new dtos.ImportOptions()
-                    importOptions.setMode("UPDATE_IF_EXISTS")
-
-                    return facade.executeImport(importData, importOptions)
+                    var fileName = "model.xlsx"
+                    var data = new window.File([c.base64ToBlob(fileContent)], fileName)
+                    return facade.uploadToSessionWorkspace(data)
+                          .then(function() {
+                              c.ok("uploadToSessionWorkspace")
+                              var importData = new dtos.ImportData()
+                              importData.setFormat("EXCEL")
+                              importData.setSessionWorkspaceFiles([fileName])
+
+                              var importOptions = new dtos.ImportOptions()
+                              importOptions.setMode("UPDATE_IF_EXISTS")
+
+                              return facade.executeImport(importData, importOptions)
+                                  .then(function() {
+                                      c.ok("executeImport")
+                                  })
+                          })
                 }
 
                 var fCheck = function (facade: openbis.openbis) {
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts
index e05938aadc3c9957d0f211457fc50b2b54543e10..eea599e1d417a1a8d985ef56e9e33e6ef9b3da7d 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/common.d.ts
@@ -152,5 +152,6 @@ export namespace common {
         ok(msg?): void
         section(msg): void
         fail(msg?): void
+        base64ToBlob(b64Data: string, contentType: string='', sliceSize: number=512): Blob
     }
 }
diff --git a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts
index 6add41dd7ece762e7136c8d3a9ab1faf1be4a175..7f6dc21ff7eba597609748c9a4e96190f61edc3d 100644
--- a/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts
+++ b/test-api-openbis-javascript/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/types/openbis.esm.d.ts
@@ -11139,9 +11139,6 @@ export namespace openbis {
         getIdentifier(): ObjectIdentifier;
     }
 
-    interface IImportData extends Serializable {
-    }
-
     interface ILabelHolder {
 
         getLabel(): string;
@@ -11619,12 +11616,32 @@ export namespace openbis {
         new <T extends IObjectId>(): IdsSearchCriteria<T>;
     }
 
+    interface ImportData extends Serializable {
+
+        getFormat(): ImportFormat;
+
+        getSessionWorkspaceFiles(): string[];
+
+        setFormat(arg0: ImportFormat): void;
+
+        setSessionWorkspaceFiles(arg0: string[]): void;
+    }
+
+    /**
+     */
+    interface ImportDataConstructor {
+
+        new (): ImportData;
+
+        new (arg0: ImportFormat, arg1: string[]): ImportData;
+    }
+
     /**
      */
     interface ImportFormatObject {
         /**
          */
-        XLS: ImportFormat<> = "XLS";
+        EXCEL: ImportFormat<> = "EXCEL";
     }
 
     /**
@@ -11643,13 +11660,13 @@ export namespace openbis {
 
     interface ImportOperation extends Serializable, IOperation {
 
-        getImportData(): IImportData;
+        getImportData(): ImportData;
 
         getImportOptions(): ImportOptions;
 
         getMessage(): string;
 
-        setImportData(arg0: IImportData): void;
+        setImportData(arg0: ImportData): void;
 
         setImportOptions(arg0: ImportOptions): void;
     }
@@ -11660,12 +11677,16 @@ export namespace openbis {
 
         new (): ImportOperation;
 
-        new (arg0: IImportData, arg1: ImportOptions): ImportOperation;
+        new (arg0: ImportData, arg1: ImportOptions): ImportOperation;
     }
 
     interface ImportOperationResult extends Serializable, as_dto_common_operation_IOperationResult {
 
+        getImportResult(): ImportResult;
+
         getMessage(): string;
+
+        setImportResult(arg0: ImportResult): void;
     }
 
     /**
@@ -11673,6 +11694,8 @@ export namespace openbis {
     interface ImportOperationResultConstructor {
 
         new (): ImportOperationResult;
+
+        new (arg0: ImportResult): ImportOperationResult;
     }
 
     interface ImportOptions extends Serializable {
@@ -11691,44 +11714,20 @@ export namespace openbis {
         new (arg0: ImportMode): ImportOptions;
     }
 
-    interface ImportScript extends Serializable {
-
-        getName(): string;
-
-        getSource(): string;
-
-        setName(arg0: string): void;
-
-        setSource(arg0: string): void;
-    }
-
-    /**
-     */
-    interface ImportScriptConstructor {
-
-        new (): ImportScript;
-
-        new (arg0: string, arg1: string): ImportScript;
-    }
+    interface ImportResult extends Serializable {
 
-    interface ImportValue extends Serializable {
-
-        getName(): string;
-
-        getValue(): string;
-
-        setName(arg0: string): void;
+        getObjectIds(): IObjectId[];
 
-        setValue(arg0: string): void;
+        setObjectIds(arg0: IObjectId[]): void;
     }
 
     /**
      */
-    interface ImportValueConstructor {
+    interface ImportResultConstructor {
 
-        new (): ImportValue;
+        new (): ImportResult;
 
-        new (arg0: string, arg1: string): ImportValue;
+        new (arg0: IObjectId[]): ImportResult;
     }
 
     interface LabelSearchCriteria extends StringFieldSearchCriteria {
@@ -13851,7 +13850,7 @@ export namespace openbis {
 
         executeExport(arg1: ExportData, arg2: ExportOptions): Promise<ExportResult>;
 
-        executeImport(arg1: IImportData, arg2: ImportOptions): Promise<void>;
+        executeImport(arg1: ImportData, arg2: ImportOptions): Promise<ImportResult>;
 
         executeOperations(arg1: IOperation[], arg2: IOperationExecutionOptions): Promise<IOperationExecutionResults>;
 
@@ -14068,6 +14067,8 @@ export namespace openbis {
         updateVocabularies(arg1: VocabularyUpdate[]): Promise<void>;
 
         updateVocabularyTerms(arg1: VocabularyTermUpdate[]): Promise<void>;
+
+        uploadToSessionWorkspace(arg0: any): Promise<void>;
     }
 
     /**
@@ -23027,34 +23028,6 @@ export namespace openbis {
         new (): UnarchiveDataSetsOperationResult;
     }
 
-    interface UncompressedImportData extends Serializable, IImportData {
-
-        getFile(): string;
-
-        getFormat(): ImportFormat;
-
-        getImportValues(): ImportValue[];
-
-        getScripts(): ImportScript[];
-
-        setFile(arg0: string): void;
-
-        setFormat(arg0: ImportFormat): void;
-
-        setImportValues(arg0: ImportValue[]): void;
-
-        setScripts(arg0: ImportScript[]): void;
-    }
-
-    /**
-     */
-    interface UncompressedImportDataConstructor {
-
-        new (): UncompressedImportData;
-
-        new (arg0: ImportFormat, arg1: string, arg2: ImportScript[], arg3: ImportValue[]): UncompressedImportData;
-    }
-
     interface UnknownRelatedObjectId extends IObjectId {
 
         getRelatedObjectId(): string;
@@ -24590,26 +24563,6 @@ export namespace openbis {
         RICH: XlsTextFormat<> = "RICH";
     }
 
-    interface ZipImportData extends Serializable, IImportData {
-
-        getFile(): string;
-
-        getFormat(): ImportFormat;
-
-        setFile(arg0: string): void;
-
-        setFormat(arg0: ImportFormat): void;
-    }
-
-    /**
-     */
-    interface ZipImportDataConstructor {
-
-        new (): ZipImportData;
-
-        new (arg0: ImportFormat, arg1: string): ZipImportData;
-    }
-
     interface as_dto_common_operation_IOperationResult extends Serializable {
 
         getMessage(): string;
@@ -25182,13 +25135,13 @@ export namespace openbis {
         IdSearchCriteria: IdSearchCriteriaConstructor;
         IdentifierSearchCriteria: IdentifierSearchCriteriaConstructor;
         IdsSearchCriteria: IdsSearchCriteriaConstructor;
+        ImportData: ImportDataConstructor;
         ImportFormat: ImportFormatObject;
         ImportMode: ImportModeObject;
         ImportOperation: ImportOperationConstructor;
         ImportOperationResult: ImportOperationResultConstructor;
         ImportOptions: ImportOptionsConstructor;
-        ImportScript: ImportScriptConstructor;
-        ImportValue: ImportValueConstructor;
+        ImportResult: ImportResultConstructor;
         LabelSearchCriteria: LabelSearchCriteriaConstructor;
         LastNameSearchCriteria: LastNameSearchCriteriaConstructor;
         LinkedData: LinkedDataConstructor;
@@ -25571,7 +25524,6 @@ export namespace openbis {
         TimeZone: TimeZoneConstructor;
         UnarchiveDataSetsOperation: UnarchiveDataSetsOperationConstructor;
         UnarchiveDataSetsOperationResult: UnarchiveDataSetsOperationResultConstructor;
-        UncompressedImportData: UncompressedImportDataConstructor;
         UnknownRelatedObjectId: UnknownRelatedObjectIdConstructor;
         UnlockDataSetsOperation: UnlockDataSetsOperationConstructor;
         UnlockDataSetsOperationResult: UnlockDataSetsOperationResultConstructor;
@@ -25649,7 +25601,6 @@ export namespace openbis {
         WebAppSettingsSortOptions: WebAppSettingsSortOptionsConstructor;
         WebAppSettingsUpdateValue: WebAppSettingsUpdateValueConstructor;
         XlsTextFormat: XlsTextFormatObject;
-        ZipImportData: ZipImportDataConstructor;
         as_dto_attachment_Attachment: AttachmentConstructor;
         as_dto_attachment_create_AttachmentCreation: AttachmentCreationConstructor;
         as_dto_attachment_fetchoptions_AttachmentFetchOptions: AttachmentFetchOptionsConstructor;
@@ -26024,11 +25975,9 @@ export namespace openbis {
         as_dto_history_id_UnknownRelatedObjectId: UnknownRelatedObjectIdConstructor;
         as_dto_importer_ImportOperation: ImportOperationConstructor;
         as_dto_importer_ImportOperationResult: ImportOperationResultConstructor;
+        as_dto_importer_ImportResult: ImportResultConstructor;
+        as_dto_importer_data_ImportData: ImportDataConstructor;
         as_dto_importer_data_ImportFormat: ImportFormatObject;
-        as_dto_importer_data_ImportScript: ImportScriptConstructor;
-        as_dto_importer_data_ImportValue: ImportValueConstructor;
-        as_dto_importer_data_UncompressedImportData: UncompressedImportDataConstructor;
-        as_dto_importer_data_ZipImportData: ZipImportDataConstructor;
         as_dto_importer_options_ImportMode: ImportModeObject;
         as_dto_importer_options_ImportOptions: ImportOptionsConstructor;
         as_dto_material_Material: MaterialConstructor;
@@ -26695,7 +26644,7 @@ MATERIAL : "MATERIAL",
 SAMPLE : "SAMPLE"} as const
 
     const ImportFormat = {
-XLS : "XLS"} as const
+EXCEL : "EXCEL"} as const
 
     const ImportMode = {
 FAIL_IF_EXISTS : "FAIL_IF_EXISTS",
@@ -26979,7 +26928,7 @@ MATERIAL : "MATERIAL",
 SAMPLE : "SAMPLE"} as const
 
     const as_dto_importer_data_ImportFormat = {
-XLS : "XLS"} as const
+EXCEL : "EXCEL"} as const
 
     const as_dto_importer_options_ImportMode = {
 FAIL_IF_EXISTS : "FAIL_IF_EXISTS",
@@ -27882,15 +27831,15 @@ SAMPLE : "SAMPLE"} as const
 
     export const IdsSearchCriteria:IdsSearchCriteriaConstructor
 
+    export const ImportData:ImportDataConstructor
+
     export const ImportOperation:ImportOperationConstructor
 
     export const ImportOperationResult:ImportOperationResultConstructor
 
     export const ImportOptions:ImportOptionsConstructor
 
-    export const ImportScript:ImportScriptConstructor
-
-    export const ImportValue:ImportValueConstructor
+    export const ImportResult:ImportResultConstructor
 
     export const LabelSearchCriteria:LabelSearchCriteriaConstructor
 
@@ -28624,8 +28573,6 @@ SAMPLE : "SAMPLE"} as const
 
     export const UnarchiveDataSetsOperationResult:UnarchiveDataSetsOperationResultConstructor
 
-    export const UncompressedImportData:UncompressedImportDataConstructor
-
     export const UnknownRelatedObjectId:UnknownRelatedObjectIdConstructor
 
     export const UnlockDataSetsOperation:UnlockDataSetsOperationConstructor
@@ -28778,8 +28725,6 @@ SAMPLE : "SAMPLE"} as const
 
     export const WebAppSettingsUpdateValue:WebAppSettingsUpdateValueConstructor
 
-    export const ZipImportData:ZipImportDataConstructor
-
     export const as_dto_attachment_Attachment:AttachmentConstructor
 
     export const as_dto_attachment_create_AttachmentCreation:AttachmentCreationConstructor
@@ -29490,13 +29435,9 @@ SAMPLE : "SAMPLE"} as const
 
     export const as_dto_importer_ImportOperationResult:ImportOperationResultConstructor
 
-    export const as_dto_importer_data_ImportScript:ImportScriptConstructor
-
-    export const as_dto_importer_data_ImportValue:ImportValueConstructor
-
-    export const as_dto_importer_data_UncompressedImportData:UncompressedImportDataConstructor
+    export const as_dto_importer_ImportResult:ImportResultConstructor
 
-    export const as_dto_importer_data_ZipImportData:ZipImportDataConstructor
+    export const as_dto_importer_data_ImportData:ImportDataConstructor
 
     export const as_dto_importer_options_ImportOptions:ImportOptionsConstructor
 
@@ -31466,17 +31407,11 @@ SAMPLE : "SAMPLE"} as const
 
     type as_dto_importer_ImportOperationResult = ImportOperationResult
 
-    type as_dto_importer_data_IImportData = IImportData
+    type as_dto_importer_ImportResult = ImportResult
 
-    type as_dto_importer_data_ImportFormat = typeof as_dto_importer_data_ImportFormat[keyof typeof as_dto_importer_data_ImportFormat]
-
-    type as_dto_importer_data_ImportScript = ImportScript
-
-    type as_dto_importer_data_ImportValue = ImportValue
+    type as_dto_importer_data_ImportData = ImportData
 
-    type as_dto_importer_data_UncompressedImportData = UncompressedImportData
-
-    type as_dto_importer_data_ZipImportData = ZipImportData
+    type as_dto_importer_data_ImportFormat = typeof as_dto_importer_data_ImportFormat[keyof typeof as_dto_importer_data_ImportFormat]
 
     type as_dto_importer_options_ImportMode = typeof as_dto_importer_options_ImportMode[keyof typeof as_dto_importer_options_ImportMode]
 
diff --git a/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..49768482efe4933db4c61dd9f2eaab44133a7552
--- /dev/null
+++ b/test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java
@@ -0,0 +1,90 @@
+package ch.ethz.sis.openbis.systemtests;
+
+import static ch.ethz.sis.transaction.TransactionTestUtil.TestTransaction;
+import static ch.ethz.sis.transaction.TransactionTestUtil.assertTransactions;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.sql.DataSource;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.OpenBIS;
+import ch.ethz.sis.openbis.generic.asapi.v3.ITransactionCoordinatorApi;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.EntityTypePermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.create.ExperimentCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.fetchoptions.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.ExperimentPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.Project;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.create.ProjectCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.fetchoptions.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectIdentifier;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
+import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions;
+import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileSearchCriteria;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionConfiguration;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.TransactionCoordinatorApi;
+import ch.ethz.sis.openbis.systemtests.common.AbstractIntegrationTest;
+import ch.ethz.sis.transaction.TransactionStatus;
+
+public class IntegrationSessionWorkspaceTest extends AbstractIntegrationTest
+{
+
+    @Test
+    public void testUploadToSessionWorkspace() throws Exception
+    {
+        final OpenBIS openBIS = createOpenBIS();
+        final String sessionToken = openBIS.login(USER, PASSWORD);
+
+        final Path originalFilePath = Path.of("sourceTest/java/tests.xml");
+
+        // Testing upload
+
+        final String uploadId = openBIS.uploadToSessionWorkspace(originalFilePath);
+
+        // Verifying upload ID
+
+        assertTrue(uploadId.endsWith("tests.xml"));
+
+        // Verifying file info
+
+        final Path uploadedFilePath = Path.of(String.format("targets/sessionWorkspace/%s/tests.xml", sessionToken));
+        final File originalFile = originalFilePath.toFile();
+        final File uploadedFile = uploadedFilePath.toFile();
+
+        assertTrue(uploadedFile.exists());
+        assertEquals(uploadedFile.length(), originalFile.length());
+
+        // Verifying file content
+
+        final byte[] originalFileContent = Files.readAllBytes(originalFilePath);
+        final byte[] uploadedFileContent = Files.readAllBytes(uploadedFilePath);
+
+        assertEquals(uploadedFileContent, originalFileContent);
+
+        openBIS.logout();
+    }
+
+}
diff --git a/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py b/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py
index dce1366af7d630109fcc750585e6ee770fa84411..441ff4576e099e134ff8ce110b401fec7368bbbb 100644
--- a/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py
+++ b/ui-admin/src/core-plugins/admin/1/as/services/xls-import/xls-import.py
@@ -1,19 +1,11 @@
-import base64
-from ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl import MasterDataRegistrationHelper
 from ch.ethz.sis.openbis.generic.server.xls.importer import ImportOptions
 from ch.ethz.sis.openbis.generic.server.xls.importer import XLSImport
 from ch.ethz.sis.openbis.generic.server.xls.importer.enums import ImportModes
 from ch.systemsx.cisd.common.exceptions import UserFailureException
 from java.util import ArrayList
-from org.apache.commons.io import FileUtils
-from java.io import File
-from java.lang import Long
-from java.lang import System
-from java.nio.file import Path
-from ch.ethz.sis.openbis.generic.server.asapi.v3.executor.importer import ImportExecutor
 
-def get_update_mode(parameters):
-    update_mode = parameters.get('update_mode', 'FAIL_IF_EXISTS')
+def getMode(parameters):
+    update_mode = parameters.get('mode', 'FAIL_IF_EXISTS')
     if update_mode == "IGNORE_EXISTING":
         return ImportModes.IGNORE_EXISTING
     elif update_mode == "FAIL_IF_EXISTS":
@@ -25,20 +17,16 @@ def get_update_mode(parameters):
             str(update_mode) if update_mode else 'None'))
 
 
-def get_import_options(parameters):
+def getImportOptions(parameters):
     options = ImportOptions()
-    experiments_by_type = parameters.get('experiments_by_type', None)
-    options.setExperimentsByType(experiments_by_type)
-    spaces_by_type = parameters.get('spaces_by_type', None)
-    options.setSpacesByType(spaces_by_type)
-    definitions_only = parameters.get('definitions_only', False)
-    options.setDefinitionsOnly(definitions_only)
-    disallow_creations = parameters.get("disallow_creations", False)
-    options.setDisallowEntityCreations(disallow_creations)
-    ignore_versioning = parameters.get('ignore_versioning', False)
-    options.setIgnoreVersioning(ignore_versioning)
-    render_result = parameters.get('render_result', True)
-    options.setRenderResult(render_result)
+    allowedSampleTypes = parameters.get("allowedSampleTypes")
+
+    options.setExperimentsByType(parameters.get('experimentsByType', None))
+    options.setSpacesByType(parameters.get('spacesByType', None))
+    options.setDefinitionsOnly(False)
+    options.setDisallowEntityCreations(False)
+    options.setIgnoreVersioning(False)
+    options.setRenderResult(True)
     return options
 
 
@@ -47,82 +35,20 @@ def process(context, parameters):
     result = None
 
     if method == "import":
-        zip = parameters.get('zip', False)
-        temp = None
-        zip_bytes = None
-        if zip: # Zip mode uses xls_base64 for all multiple XLS + script files
-            zip_bytes = base64.b64decode(parameters.get('xls_base64'))
-            temp = File.createTempFile("temp", Long.toString(System.nanoTime()))
-            temp.delete()
-            temp.mkdir()
-            tempPath = temp.getAbsolutePath()
-            MasterDataRegistrationHelper.extractToDestination(zip_bytes, tempPath)
-            if (len(temp.listFiles()) == 1):
-                singleFile = temp.listFiles()[0]
-                if (singleFile.isDirectory()):
-                    temp = singleFile
-                    tempPath = singleFile.getAbsolutePath()
-            byteArrays = MasterDataRegistrationHelper.getByteArrays(Path.of(tempPath), ".xls")
-            if len(byteArrays) == 0:
-                raise UserFailureException('No .xls or .xlsx files found on the root folder of the zip file. This error could be caused by the way the zip file was generated.')
-            parameters.put('xls', byteArrays)
-            allScripts = MasterDataRegistrationHelper.getAllScripts(Path.of(tempPath))
-            parameters.put('scripts', allScripts)
-            largeValues = MasterDataRegistrationHelper.getAllLargeValues(Path.of(tempPath))
-            parameters.put('values', largeValues)
-        else:
-            # Check if xls_base64 is used for a single XLS
-            xls_base64_string = parameters.get('xls_base64', None)
-            if xls_base64_string is not None:
-                parameters.put('xls', [ base64.b64decode(xls_base64_string) ])
-        result = _import(context, parameters, zip_bytes)
-        if temp is not None:
-            FileUtils.deleteDirectory(temp)
+        result = _import(context, parameters)
     return result
 
 
-def _import(context, parameters, zip_bytes):
-    """
-        Excel import AS service.
-        For extensive documentation of usage and Excel layout,
-        please visit https://wiki-bsse.ethz.ch/display/openBISDoc/Excel+import+service
+def _import(context, parameters):
+    fileName = parameters.get("fileName")
 
-        :param context: Standard Openbis AS Service context object
-        :param parameters: Contains two elements
-            {
-                'xls' : excel byte blob,    - optional
-                'xls_base64' : base64-encoded excel byte blob - optional
-                'xls_name': identifier of excel file - mandatory
-                'zip' : True / False - optional (default: False)
-                'scripts': {                - optional
-                    file path: loaded file
-                },
-                'experiments_by_type', - optional
-                'spaces_by_type', - optional
-                'definitions_only', - optional (default: False)
-                'disallow_creations', - optional (default: False)
-                'ignore_versioning', - optional (default: False)
-                'render_result', - optional (default: True)
-                'update_mode': [IGNORE_EXISTING|FAIL_IF_EXISTS|UPDATE_IF_EXISTS] - optional, default FAIL_IF_EXISTS
-                                                                                 This only takes duplicates that are ON THE SERVER
-            }
-        :return: Openbis's execute operations result string. It should contain report on what was created.
-    """
     session_token = context.sessionToken
     api = context.applicationService
-    scripts = parameters.get('scripts', {})
-    values = parameters.get('values', {})
-    mode = get_update_mode(parameters)
-    options = get_import_options(parameters)
-    xls_name = parameters.get('xls_name', None)
+    mode = getMode(parameters)
+    options = getImportOptions(parameters)
 
-    importXls = XLSImport(session_token, api, scripts, values, mode, options, xls_name)
+    importXLS = XLSImport(session_token, api, mode, options, [fileName], False)
 
     ids = ArrayList()
-    xls_byte_arrays = parameters.get('xls', None)
-    for xls_byte_array in xls_byte_arrays:
-        ids.addAll(importXls.importXLS(xls_byte_array))
-    if zip_bytes is not None:
-        ImportExecutor.importZipData(zip_bytes)
-
+    ids.addAll(importXLS.start())
     return ids
diff --git a/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js b/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js
index c1bf057f5f3d30ef74756bb93a93b0321d6cecb0..5bf59d1a984274045fe2dc47828aecd0c0891717 100644
--- a/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js
+++ b/ui-admin/src/js/components/tools/form/import/all/ImportAllFormFacade.js
@@ -3,25 +3,19 @@ import openbis from '@src/js/services/openbis.js'
 export default class ImportAllFormFacade {
   async import(file, updateMode) {
     return new Promise((resolve, reject) => {
-      const reader = new FileReader()
-      reader.onload = () => {
-        const resultBase64 = reader.result.split(',')[1]
-        const serviceId = new openbis.CustomASServiceCode('xls-import')
-        const serviceOptions = new openbis.CustomASServiceExecutionOptions()
-        serviceOptions.withParameter('method', 'import')
-        serviceOptions.withParameter(
-          'zip',
-          file.name.toLowerCase().endsWith('.zip')
-        )
-        serviceOptions.withParameter('xls_name', 'DEFAULT')
-        serviceOptions.withParameter('xls_base64', resultBase64)
-        serviceOptions.withParameter('update_mode', updateMode)
-        openbis.executeService(serviceId, serviceOptions).then(result => {
-          resolve(result)
-        }, reject)
-      }
-      reader.onerror = reject
-      reader.readAsDataURL(file)
-    })
+      openbis.uploadToSessionWorkspace(file)
+        .then(() => {
+          const serviceId = new openbis.CustomASServiceCode('xls-import')
+          const serviceOptions = new openbis.CustomASServiceExecutionOptions()
+
+          serviceOptions.withParameter('method', 'import')
+          serviceOptions.withParameter('mode', updateMode)
+          serviceOptions.withParameter('fileName', file.name)
+
+          return openbis.executeService(serviceId, serviceOptions)
+            .then(result => resolve(result))
+            .catch(error => reject(error))
+        }, (error) => reject(error));
+    });
   }
 }
diff --git a/ui-admin/src/js/services/openbis/api.js b/ui-admin/src/js/services/openbis/api.js
index d79fc89e1d378fb298b26038aee61949f4ffe308..40bd2e7e6ccd4ead4ec0b886a1a6115020c8105a 100644
--- a/ui-admin/src/js/services/openbis/api.js
+++ b/ui-admin/src/js/services/openbis/api.js
@@ -252,6 +252,10 @@ class Facade {
     return this.promise(this.v3.evaluatePlugin(options))
   }
 
+  uploadToSessionWorkspace(file) {
+    return this.promise(this.v3.uploadToSessionWorkspace(file))
+  }
+
   executeCustomDSSService(serviceId, options) {
     return this.promise(this.v3.getDataStoreFacade().executeCustomDSSService(serviceId, options));
   }
diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py b/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py
index 2ab162548baabc0e8cdc6ee51eff4f92fc208e7e..60ea54881c25a362a82f678bf342aef2ec9942ad 100644
--- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py
+++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/services/as-eln-lims-api/script.py
@@ -2,15 +2,12 @@ import ch.systemsx.cisd.openbis.generic.server.ComponentNames as ComponentNames
 import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider as CommonServiceProvider
 import ch.ethz.sis.openbis.generic.server.xls.export.XLSExportExtendedService as XLSExportExtendedService
 import ch.systemsx.cisd.common.exceptions.UserFailureException as UserFailureException
-import base64
 import json
 import re
 import ch.ethz.sis.openbis.generic.server.xls.importer.utils.AttributeValidator as AttributeValidator
 import ch.ethz.sis.openbis.generic.server.xls.importer.helper.SampleImportHelper as SampleImportHelper
 import ch.systemsx.cisd.common.logging.LogCategory as LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory as LogFactory;
-from java.nio.file import Files
-from java.io import File
 
 isOpenBIS2020 = True;
 enableNewSearchEngine = isOpenBIS2020;
@@ -79,8 +76,6 @@ def process(context, parameters):
         result = getUserManagementMaintenanceTaskReport(context, parameters)
     elif method == "removeUserManagementMaintenanceTaskReport":
         result = removeUserManagementMaintenanceTaskReport(context, parameters)
-    elif method == "importSamples":
-        result = importSamples(context, parameters)
     elif method == "getSamplesImportTemplate":
         result = getSamplesImportTemplate(context, parameters)
     elif method == "createSpace":
@@ -343,21 +338,6 @@ def _create_cell(row, cell_index, style, value):
     cell.setCellValue(value)
     return cell_index + 1
 
-def importSamples(context, parameters):
-    sessionKey = parameters.get("sessionKey")
-    allowedSampleTypes = parameters.get("allowedSampleTypes")
-    experimentsByType = parameters.get("experimentsByType", {})
-    spacesByType = parameters.get("spacesByType", {})
-    mode = parameters.get("mode")
-    barcodeValidationInfo = json.loads(parameters.get("barcodeValidationInfo"))
-    sessionManager = CommonServiceProvider.getApplicationContext().getBean("session-manager")
-    sessionWorkspaceProvider = CommonServiceProvider.getApplicationContext().getBean("session-workspace-provider")
-    workspaceFolder = sessionWorkspaceProvider.getSessionWorkspace(context.getSessionToken())
-    uploadedFile = File(workspaceFolder, sessionKey)
-    bytes = Files.readAllBytes(uploadedFile.toPath())
-    results = importData(context, bytes, sessionKey, experimentsByType, spacesByType, mode, False)
-    return results
-
 def validateExperimentOrSpaceDefined(row_number, properties, mode, experiment, space):
     if experiment is None and space is None and not mode.startswith("UPDATE"):
         exp = properties.get("experiment")
@@ -380,29 +360,6 @@ def validateBarcode(row_number, properties, barcodeValidationInfo):
             raise UserFailureException("Error in row %s: custom barcode %s does not match "
                                        "the regular expression '%s'." % (row_number, barcode, pattern.pattern))
 
-def importData(context, bytes, file_name, experimentsByType, spacesByType, mode, definitionsOnly):
-    from ch.ethz.sis.openbis.generic.asapi.v3.dto.service.id import CustomASServiceCode
-    from ch.ethz.sis.openbis.generic.asapi.v3.dto.service import CustomASServiceExecutionOptions
-    from ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id import ExperimentIdentifier
-
-    sessionToken = context.getSessionToken()
-    api = context.getApplicationService()
-    props = CustomASServiceExecutionOptions().withParameter('xls', [bytes])
-    props.withParameter('method', 'import')
-    props.withParameter('zip', False)
-    props.withParameter('xls_name', 'DEFAULT')
-    props.withParameter('update_mode', mode)
-    props.withParameter('disallow_creations', mode == 'UPDATE_IF_EXISTS')
-    props.withParameter('render_result', False)
-    props.withParameter('ignore_versioning', True)
-    if definitionsOnly:
-        props.withParameter('definitions_only', True)
-    if experimentsByType is not None:
-        props.withParameter('experiments_by_type', experimentsByType)
-    if spacesByType is not None:
-        props.withParameter('spaces_by_type', spacesByType)
-    return api.executeCustomASService(sessionToken, CustomASServiceCode("xls-import"), props)
-
 def getUserManagementMaintenanceTaskConfig(context, parameters):
     from ch.systemsx.cisd.common.filesystem import FileUtilities
 
diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
index 026ab63b8ea644509f599c92da9ff30fcaa5c585..188deda519f031916000c14027c4a62693ab329c 100644
--- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
+++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
@@ -120,19 +120,16 @@ function ServerFacade(openbisServer) {
         });
     }
 
-    this.registerSamples = function(allowedSampleTypes, experimentsByType, spacesByType, barcodeValidationInfo, sessionKey, callback) {
-        this.customELNASAPI({
-            "method" : "importSamples",
-            "allowedSampleTypes" : allowedSampleTypes,
-            "experimentsByType" : experimentsByType,
-            "spacesByType" : spacesByType,
-            "barcodeValidationInfo" : barcodeValidationInfo,
-            "mode" : "FAIL_IF_EXISTS",
-            "sessionKey" : sessionKey
-        }, function(result) {
-            callback(result)
-        }, true);
-    }
+		this.importSamples = function(mode, sessionKey, allowedSampleTypes, experimentsByType, spacesByType, callback) {
+				this.customASService({
+					"method" : "import",
+					"mode" : mode,
+					"fileName" : sessionKey,
+					"allowedSampleTypes" : allowedSampleTypes,
+					"experimentsByType" : experimentsByType,
+					"spacesByType" : spacesByType,
+				}, callback, "xls-import", null, true);
+		}
 
     this.deleteSpace = function(code, reason, callback) {
         this.customELNASAPI({
@@ -144,18 +141,6 @@ function ServerFacade(openbisServer) {
         });
     }
 
-    this.updateSamples = function(allowedSampleTypes, barcodeValidationInfo, sessionKey, callback) {
-        this.customELNASAPI({
-            "method" : "importSamples",
-            "allowedSampleTypes" : allowedSampleTypes,
-            "barcodeValidationInfo" : barcodeValidationInfo,
-            "mode" : "UPDATE_IF_EXISTS",
-            "sessionKey" : sessionKey
-        }, function(result) {
-            callback(result)
-        }, true);
-    }
-
     this.getSamplesImportTemplate = function(allowedSampleTypes, templateType, importMode, callback) {
         this.customELNASAPI({
             "method" : "getSamplesImportTemplate",
diff --git a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js
index baed546316871ea84500080ab4d3ba51291db8e8..c9cc4f1e290e5b9e1f08cc2634018cdcdc75259d 100644
--- a/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js
+++ b/ui-eln-lims/src/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableController.js
@@ -173,13 +173,13 @@ function SampleTableController(parentController, title, experimentIdentifier, pr
         var allowSampleTypeSelection = experimentIdentifier == null;
         var batchController = new BatchController(title, "REGISTRATION", allowedSampleTypes, allowSampleTypeSelection, function(file, selectedSampleTypes) {
             Util.blockUI();
-            mainController.serverFacade.fileUpload(file, function() {
-                mainController.serverFacade.registerSamples(selectedSampleTypes, experimentsByType, spacesByType,
-                        _this.getBarcodeValidationInfo(), file.name,
-                function(result) {
+            mainController.openbisV3.uploadToSessionWorkspace(file)
+              .done(function() {
+                mainController.serverFacade.importSamples("FAIL_IF_EXISTS", file.name, selectedSampleTypes, experimentsByType, spacesByType,
+                  function(result) {
                     _this._handleResult(result, "created", experimentIdentifier);
-                });
-            });
+                  });
+              });
         });
         batchController.init();
     }
@@ -196,11 +196,11 @@ function SampleTableController(parentController, title, experimentIdentifier, pr
         var allowSampleTypeSelection = experimentIdentifier == null;
         var batchController = new BatchController(title, "UPDATE", allowedSampleTypes, allowSampleTypeSelection, function(file, selectedSampleTypes) {
             Util.blockUI();
-            mainController.serverFacade.fileUpload(file, function() {
-                mainController.serverFacade.updateSamples(selectedSampleTypes,
-                        _this.getBarcodeValidationInfo(), file.name,
-                        function(result) {
-                    _this._handleResult(result, "updated", experimentIdentifier);
+          mainController.openbisV3.uploadToSessionWorkspace(file)
+            .done(function() {
+              mainController.serverFacade.importSamples("UPDATE_IF_EXISTS", file.name, selectedSampleTypes, experimentsByType, spacesByType,
+                function(result) {
+                  _this._handleResult(result, "updated", experimentIdentifier);
                 });
             });
         });