From ffcd036da49f43e36b1cb308d9df3cdf0a887a3f Mon Sep 17 00:00:00 2001
From: Juan Fuentes <juanf@ethz.ch>
Date: Tue, 28 May 2024 16:38:32 +0200
Subject: [PATCH] BIS-1059: Large file imports support

---
 .../ch/ethz/sis/openbis/generic/OpenBIS.java  |  47 +-
 .../asapi/v3/IApplicationServerApi.java       |   5 +-
 .../v3/dto/importer/ImportOperation.java      |  10 +-
 .../dto/importer/ImportOperationResult.java   |  26 ++
 .../ImportScript.java => ImportResult.java}   |  42 +-
 .../v3/dto/importer/data/IImportData.java     |  26 --
 .../{ZipImportData.java => ImportData.java}   |  22 +-
 .../v3/dto/importer/data/ImportFormat.java    |   2 +-
 .../v3/dto/importer/data/ImportValue.java     |  91 ----
 .../importer/data/UncompressedImportData.java | 113 -----
 .../generic/sharedapi/v3/dictionary.txt       |   6 +-
 .../src/v3/as/dto/importer/ImportOperation.js |   2 +-
 .../as/dto/importer/ImportOperationResult.js  |  16 +-
 .../{data/ImportScript.js => ImportResult.js} |  38 +-
 .../v3/as/dto/importer/data/IImportData.js    |  23 -
 .../data/{ZipImportData.js => ImportData.js}  |  29 +-
 .../v3/as/dto/importer/data/ImportFormat.js   |   2 +-
 .../v3/as/dto/importer/data/ImportValue.js    |  54 ---
 .../importer/data/UncompressedImportData.js   |  83 ----
 api-openbis-javascript/src/v3/openbis.js      |  28 ++
 .../dto/OpenBISJavaScriptFacade.java          |  12 +-
 .../.dynamic_property_evaluator_queue         | Bin 12 -> 0 bytes
 .../excelimport/AbstractImportTest.java       |  37 ++
 .../excelimport/ImportDatasetTypesTest.java   |  32 +-
 .../ImportExperimentTypesTest.java            |  27 +-
 .../excelimport/ImportExperimentsTest.java    | 224 +++++++---
 .../excelimport/ImportFromExcelTest.java      |  10 +-
 .../excelimport/ImportProjectsTest.java       |  43 +-
 .../excelimport/ImportPropertyTypesTest.java  |  83 ++--
 .../excelimport/ImportSampleTypesTest.java    |  71 ++-
 .../plugin/excelimport/ImportSamplesTest.java | 206 ++++++---
 .../plugin/excelimport/ImportSpacesTest.java  |  18 +-
 .../ImportVocabularyTypesTest.java            |  61 ++-
 .../plugin/excelimport/TestUtils.java         | 133 +-----
 .../test_files/experiments/update.xls         | Bin 32768 -> 7168 bytes
 .../property_types/normal_property_type.xls   | Bin 40960 -> 15360 bytes
 .../sample_types/with_dynamic_script.xls      | Bin 40960 -> 14848 bytes
 .../space_project_experiment_elsewhere.xls    | Bin 46080 -> 19968 bytes
 .../server/asapi/v3/ApplicationServerApi.java |   9 +-
 .../asapi/v3/ApplicationServerApiLogger.java  |   9 +-
 ...iPersonalAccessTokenInvocationHandler.java |   7 +-
 .../v3/executor/importer/IImportExecutor.java |   3 +-
 .../v3/executor/importer/ImportExecutor.java  | 150 +------
 .../importer/ImportOperationExecutor.java     |   5 +-
 .../helper/AbstractXLSExportHelper.java       |   3 +-
 .../xls/importer/MainImportXlsTest.java       |  89 ----
 .../server/xls/importer/XLSImport.java        | 403 +++++++++++++-----
 .../delay/DelayedExecutionDecorator.java      |  21 +-
 .../importer/helper/BasicImportHelper.java    |   5 +-
 .../helper/DatasetTypeImportHelper.java       |  15 +-
 .../helper/ExperimentImportHelper.java        |   5 +-
 .../helper/ExperimentTypeImportHelper.java    |  15 +-
 .../PropertyAssignmentImportHelper.java       |  23 +-
 .../helper/PropertyTypeImportHelper.java      |  27 +-
 .../importer/helper/SampleImportHelper.java   |   4 +-
 .../helper/SampleTypeImportHelper.java        |  21 +-
 .../importer/helper/ScriptImportHelper.java   |  57 +--
 .../helper/VocabularyImportHelper.java        |  12 +-
 .../helper/VocabularyTermImportHelper.java    |  12 +-
 .../xls/importer/utils/FileServerUtils.java   |  26 +-
 .../web/server/UploadServiceServlet.java      |   2 +-
 .../shared/ISessionWorkspaceProvider.java     |   4 +
 .../shared/SessionWorkspaceProvider.java      |  16 +
 .../asapi/v3/AbstractImportTest.java          |  33 +-
 .../systemtest/asapi/v3/AbstractTest.java     |   5 +
 .../asapi/v3/UncompressedImportTest.java      |  74 ++--
 .../systemtest/asapi/v3/ZipImportTest.java    |  70 +--
 .../v3/test_files/import/scripts/dynamic.py   |   2 +-
 .../v3/test_files/import/scripts/valid.py     |   1 +
 .../openbis-v3-api-test/html/test/common.js   |  20 +
 .../openbis-v3-api-test/html/test/dtos.js     |   7 +-
 .../html/test/openbis-execute-operations.js   |   2 +-
 .../html/test/test-import-export.ts           |  90 +---
 .../html/test/types/common.d.ts               |   1 +
 .../html/test/types/openbis.esm.d.ts          | 171 +++-----
 .../IntegrationSessionWorkspaceTest.java      |  90 ++++
 .../1/as/services/xls-import/xls-import.py    | 110 +----
 .../form/import/all/ImportAllFormFacade.js    |  34 +-
 ui-admin/src/js/services/openbis/api.js       |   4 +
 .../1/as/services/as-eln-lims-api/script.py   |  43 --
 .../eln-lims/html/js/server/ServerFacade.js   |  35 +-
 .../SampleTable/SampleTableController.js      |  22 +-
 82 files changed, 1664 insertions(+), 1715 deletions(-)
 rename api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/{data/ImportScript.java => ImportResult.java} (59%)
 delete mode 100644 api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/IImportData.java
 rename api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/{ZipImportData.java => ImportData.java} (74%)
 delete mode 100644 api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/ImportValue.java
 delete mode 100644 api-openbis-java/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/importer/data/UncompressedImportData.java
 rename api-openbis-javascript/src/v3/as/dto/importer/{data/ImportScript.js => ImportResult.js} (58%)
 delete mode 100644 api-openbis-javascript/src/v3/as/dto/importer/data/IImportData.js
 rename api-openbis-javascript/src/v3/as/dto/importer/data/{ZipImportData.js => ImportData.js} (61%)
 delete mode 100644 api-openbis-javascript/src/v3/as/dto/importer/data/ImportValue.js
 delete mode 100644 api-openbis-javascript/src/v3/as/dto/importer/data/UncompressedImportData.js
 delete mode 100644 core-plugin-openbis/.dynamic_property_evaluator_queue
 delete mode 100644 server-application-server/source/java/ch/ethz/sis/openbis/generic/server/xls/importer/MainImportXlsTest.java
 create mode 100644 server-application-server/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/test_files/import/scripts/valid.py
 create mode 100644 test-integration/sourceTest/java/ch/ethz/sis/openbis/systemtests/IntegrationSessionWorkspaceTest.java

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 ede5ae601e1..76ba0dae624 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 bd1ec54d8ce..c58a8be081a 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 509ee42d978..479452c9b98 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 a28b89ee5f3..54e9619942e 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 4307d2ff86c..29ca23329d8 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 4f47167bdca..00000000000
--- 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 d3a95e6bbd3..02137385311 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 3bd858e1271..415b5c62950 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 005b3e1059a..00000000000
--- 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 44113b16817..00000000000
--- 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 af8a6580cf7..21daba1c397 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 717aa8112bf..aeb00d41c2d 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 8644008309f..9bdfca0689c 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 64545851a62..29daa115a98 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 1289c8e8e4d..00000000000
--- 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 918cc534cd6..9786a7ef566 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 982b7ff16bf..4ffb6dd2454 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 e8bddc19ddb..00000000000
--- 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 49084d1b71c..00000000000
--- 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 f7a8d669586..a5c1a6be3fd 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 cb1cb283777..c55846a1f9f 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
GIT binary patch
literal 0
HcmV?d00001

literal 12
Rcmeyd#OO5x0|O5T0{|U20@45g

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 69708ddf23d..42c27477f7a 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 1a13a1028e6..bf607e47456 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 f8f56716ddd..843e6c02e72 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 742ed9ffbe5..ec529f6dcff 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 46549e079ef..758adcb28d7 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 0c827f35dd5..01aa8bc5462 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 b7963f77f1f..fc35b51fa4b 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 4f37c6bd3f3..e2a4cf0ee6a 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 f92702dfa16..55567f48535 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 75fb6f688e4..8024fecf89e 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 3b10cf00fe9..707d1ab1ef3 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 adbb3a91ba4..8681e8e9cb3 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
GIT binary patch
literal 7168
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
Hzb*eSXops<

literal 32768
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
bG52;?8pte-nY-5inSjL&UVk6|X$|}zLQBN=

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
GIT binary patch
literal 15360
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

literal 40960
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
I|K%L`KmM`#6aWAK

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
GIT binary patch
literal 14848
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
V|NC<DzZR!g>i@$3-~6xV|2NJy^7#M&

literal 40960
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

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
GIT binary patch
literal 19968
zcmeHP3wT_`b)MB~rPa%N*b+h*<r)mw;1Giy9wh{=<uw-3tCDPRN^4fq+FFpb>hAiX
zmLy6DX`6=TLEH4f*VHL}q<J@O(yyV!^pU15Y0@;bg(fYeZ5m1+A_Y=f!2SO@dw2GZ
zj)bB4+7CYNdhX8o=ggd$^O%{vcdRdesr}&-pX_<Wc-K`XZk{{UVCt&y81kD#y3LqP
z$P;_+)TvV;jO;7dOGpFHmiroq0c(*GNVIu9QWB{FsS&9OsTrvSX&q845?sKvBXuCH
zN7{hYiPVL322wZDnMgfIXCZAwIvc4M=~YMp5`Bm1+;aZB^7l(fg)ix@j+s0@CD<Zu
z=J8!Hi?G1yUtRE+Y6YB5&FcB$boif-=N0)*1J9=`mRIY)A&DriOPJ5L+|Q7=vHysv
zF`uZt4|ij}fpnu;;M~xknVky$udZFT51APIa1x8m)v;QvH8tigq;=-w7Qe^dueS3K
z*!oOx1$ek7JrU~zpD}mX`#JW$4)>V(jIHyKMJ~Zi^fhoL&3jl473yRCCSztz&P*Z_
za^@1uU0*=askc}T<Px!zEg{$cuC&+GLTb|7!;Y%5drkNAa<Kp9-mTIGIU3iL!hWpH
z!G5gGu?#6|k3}@S)@Vf^tJ$Krw%Odxb?Msde72C8eb}xycbg|q1&|$HCj;W>uHa9c
z9!?Y3c0B&oaJH)PzkKn#q0@lFD_^0WFA_b_{Pqg*t*hYMR>3b^1#eJs15b!?|H&;#
zmE45I1KGM%;ld9b|KyT>)~&)XINIkH#$Li-k-JgDx2)i=58K}x<xhtF_u7~KuO>Gz
zrmx&iZA&}-ydi9#TQz%0KO0wRU;2+do2R#?Rrm!DR_K$FX!Y;)zh#yFh}^9a{oGlD
zHD$@1;&<Cp+<vz&)!FZkrCR&FeyQGmZ&*s4y2;Mmw_^wTBsZeicT5}@O^@G><>2X^
z1nNwBcw%7Uz`L+mZNuljSQ5#Yi92HEF-+*#vM#@ojHYfm;1`s}Z7+kI39L4S`5mTd
znOob>fiY>`8pBpNc@hhYN%ooE$EiVVhLh+^5}V!Rcc9c~%wpm$;KN9ewtu8QwQJvC
zYV5#4b`?|C{%oO`%g=K$%}-~sr{0|{P8D(sC4gvtcX}e-KQS;e47H9H@}+EUKA6sy
zvQsP%ii^ckb`Bf#!OUcK7CqlPHj1tGOukUWd^nve&IAkDLjL&Tbf%d79*lb?8)W87
zxyk(WVvs8aQ~CLuj~vdFveUt_TxljKp<J(wj*X{=MhDZj-`Luxj+FAjVLR`ZvS?^J
zTZ9ws&&=kgGtxIZ3T*yma;6M&1q+4jq1<sOItA108rgjS-QSZM98Y7kLz#Kh&KDM;
z<nfvOu>hmZPUlL&(OmXe5!xD;f#c@}l!2j@7K2$1otny&GC^r^Axkyqr!tdAW;2CF
zD--Oy7w0o`xv4;O3z3_LQ$uNJePV218pA2CAP{&cUzoEaK;dv^E=wDw#`^cB#?a?I
zBVz}z-<z6XHeU#i&16a#_0Yb-iGjg^;q<{WC)&4`hDQ|hbJ^f1`y)NYFQWdD;fb-4
z!NK%y=MLYyx_N^whjO#CR7Gh9HmmAkke{Dj4A9}An1v~)Io`5)bJ^ln^gKN}Ffn5N
zEWMB`L1XaCaxTapvi1)B0o()QBW14~DCVh3aF=sFHxw|wZ*+8UAU%c=jUQQ9n9XGi
zkUkw0VZhAcEIG<BnhCREI}3&U^pU9&ER!0W80d#z4euM;l^%nir3$5sgW)4{li31(
z8iLAA&1Qpn3wYIGxbcaR{x=+iO8XJ&V=0CT(Nccu7P|LTcD_`w=G?2IVS~l|>=Em>
z$7ZsHtW`|8i;R<7vI`|KK$cd7d51?P(&HFne|~NbB8r3%okhg{<{O3v`$vX`(4TQk
z2O&o=m@AeLqA1;tu4IpL$AT_O{a`9HA50=Tr>7AplZ(N0?$9ChWWE#}K`a*$5SvrO
zkZMObesCO_G+Zw=Kc6qz@fCw{WU~0BE`iF3&CD%8b+jaAvd!q@_(Eoi9*yX^8KH!q
z@#*6Tqa4Qo5i5h5ycu?*$idF!W~V`56sc4Sm7#-)gX5#A{`6L3UgIdqj*g97hsjHb
z^bMowu>mUOQUvQ}Mh;bgrZSULkb-;T<WvUq{{8#6oPKL~noup6{i-y63Om$ca{#S#
zd6-IeA|X@0_*{Zl4IgI6kDj*3kDg|%0n?bZ`6Hp-t_N+H^`H6B<6jw?9KGhC#h18b
zl&|x+e3@;rx1!{}+6!%si|qYvmKT9yABNm!vA5g%`KW*R5U+1ub3s*pOQqd!U9+_+
zf5M!DC4L$$#qg<tv~98O=DOSNyXoO;!ta>bhmxdulO47(C)V@PjIlIpZR(Ptv%ChM
zr#fAE9P8iFD*jrmoF_KA@&p#y!EQ&_VU2xir=#n!9Y1=uqq$B#b(NzV(EAf@j&6jB
zs{7Z3$4Z+zTsaIEJK7|)sljxCtBuRD9b2+Sb}cn#!eS=YYKW1*W*~xb4R1ELMlg6A
z#uvqCL+lnJe25&YYkZ+UB7={_8oj#kv=tcr!<UN)Sixt#(BvX=5yQ~e>mnFkxzXHa
zv87nI9WNijHI=cjf7F#<mwNOuYS70pv8=$j@A3IC)2_hi<vw30v={eu%1456&qi1%
zfJN=W{iI))j}U#`^O0hMCxed|>phJ7^cvG=_19OnB_BchKEy|oeqZ>Ak}-!b>j%%G
z7rZzY05$Z97-kIOWa_eap<<xugF@ASqW7^*4E}b8c{AoAmUo(WpnzPQcUn;vQZ=CH
ziTB#FM*I@#hSkZ*md>omiX+!ukrhX-+djk*&NwLYQy$xP^7uHV)jsAWXD#Z%)4?HB
z92EVQ(%Fkn&@o%aQFj4l86{D=|7ozCj1Sk(`ba<PAy0HddG+Yynf4L0P_<~0o-b4a
z6n*|)?DXp)F_hL|N5ww7Q6=rD7!9nOM7urcxr`$T#A%VEbG>Vb^sd2bk+H&78qi9&
zeb6lwd&l??ioIiG2*utpCWNX7#o1S=Bq-WKs0L8<BwB{rbYq}5b=n8$<fLcF7=+@8
z7$rj0f?|9KmB3gT8A8>8VoV5?M4n}o$C<{-YqIhfDdcR5$ZN714COV!Pn^6act)#z
zpfB|(k8vbavRp=aw55~RY~?Y!$jMd7jjuT(uQ?*G*~$wl^(b#sg{lV?Mo%*=--@+U
zBCZ)0Y_;R27rB14*nXT_ZlNX8kCsS3S|a^uvHjRwsaHMj7AyI@vg8(wuiHwdM>@&t
ztmN~{E%3pl)4;lj<aH6r>#XDpD)p)*ud|Z3po|))&pUaH-A=Q$T#tJkC$BXkk2>rz
z7gjiF;fpF1<%J%_*`gJ{vPB+a#mVEE+-Y82uGbck*A|i27LnIx$9Hk1UbQ^###+s5
z%JR5oIeG0?-u7}m?%v$^+9UGXBl6m<yh|$es^zs?d6$;uG2WfL4l8d*xn4&^UPnY;
zhn2Up!byF;wnA0gufxh?8STdz#mQT5<y}^;w>~0oeMH{+h`jZ7e3w`1QQj35iu$|~
z6y?coHC&7M0JYQL5rU1-4H0=8tUUS`qjy6@-Uci0s!Cb4ybX4IEaNK3JwlJoaSp`F
z35+Xd4`%shJNI>g=DJ3j^AA^`9!tv%bS6;$gIOHyaF*+|^~m32KUnQ-31>mBBlKcv
zu?OQ}*;!awHlnQ2zNVD*judwbU638KEpmQyJ!`bDF@={q(Ez3XPK7g+zf<ANl&IQS
zu<p62>F*pl$M`!H&MiJ4XA)lqXNhVV_d*W=u+{a(o{HW!d3xIf+nr^##GVTeU#f(<
zrJmS-SzSr7=b_em4g0Lg6@F@;Ban8_uWDCHLfIUV@LW*EL*1oO67zPKdw}^n&TCQ6
z-(BuiumJ_TPHFEAz#2WdgQ)A<XUOtJce=yCe7+HdZ$Czs^mfVDLx%sW<pu>ipkQxQ
zu<ui_8x`#P73>ETjK7wv`$s#{MiS?=OqdI20a`}p1KLA!w1UhB)O{BsF^qrey$gGd
zUfioc692RS>ouCeichi!w1UVTs&EWJxAejW@ORngw%zd5YG19lEe%InqMf9rkxEM=
zRV{5W`(ZV$9a@f26Su9>W{#q@97Q`hiWYJdZR03f#Zk0}qi6}C7$-M@^8G)fV3WYA
z?Z>)P3O21^hm`gXE7**J<rM5@1-nJTW)*Bs!RBE*Kko7h-vTV?^Zg+Be7zJDtf*im
z1v{c(M-}Xtf*n_|MFsmI1^ZzIyA_!48*fsuH!F4D;$e(7`kKTsJxt<}e&u|V9_1+d
zl2EKoFOu5y9m&ySBu77y9KAzw^a;t)6C_9bQ*tkkw(#9kG$O;@1AhNNB7K0o8*$jd
zk6p*fS%qHU`c3;gik5d2ZSE*q+flT$qiA7A(YB7FRUJipI*OJQiesP+W#qJ+=$!U)
z{Irx%jOis%zCXVWnC}OChUsH`qUmF|E7&^}>_-&rM-}YH6zrW!{QkJY_bw%V?*N}a
z-k(sgcPrR?6zshU_C5u>Q^9^x!G21?ep<oauV6m|%(utSD%j5{b$?#L?ozN{P}=)|
zhcQCvSI#TxQR0>KBgxTwBuAf-96d#H^bg6=D<nr>kXWV%tR2hr2Z?2R!D>;@p3);+
zbkG+ZMK5p^?e8dB-chu<qiAhM(aw&dg&jrPI*L{mim^<4%E)O&iDlZ(@zZLKqP<*g
zT1sluK0Wri@h>9hd&mg|`=EmTl7ii>V85(jzoJC!uPS`MrbO(Az~@KouPfMx73?Dl
z_E81<n1X#=!9Jm2pH#5lP_R!a*lz;!?eSX*_GzW=XB6zW73_DE_CBj%_bAx!D%iaW
z_Bjuu_tMwI|L9?oqhCpm-XuBtkmTq&65sTfwd0%KBk@h2Su4KjKQ2b-IgX;wIEvol
zDEf(`=pl}xZ#arx;VAlpqv#2aq7Mi~4bl2Ca@t(to0fL`w6UXTU00iSmD;qX<Y+_5
z(Q=Zby(C8~$vkipIp6Q@Q?TDt;`a9yzCTdn_7B15$L;48?2i=e3kvqf3ic-o_NNMV
zzk+>H!TwCazNBDZ2IlMU&lT(|O5MLuu&*lE16KF)?rACZDm#Dwr6S|66zs1R>_G*4
zNWuO_!M>(oUstfdRs7}eJU)6p{ZD+7UMDe6Ut2ro>3I_K^tZKQp1$YehF<3=`kSNZ
zX^x_gIf~xpDEgJ7=uwWMFFA@{<S6=&P#ifuM@CM6k(j5KIDYzvqv#nS)obVzt#|^~
zs(j=(3_V2Jr(Z~p-XJ;pfaGX-$<f}Dqm?B`+lp0a(Y38Y`^v2Hurdogf>M7L_=bZ0
zy@LINg8id{eN(~yNx{CQV2>);KP%W{3idC+{8`{%73|-Xy8o_V%L?{wrM>@9uqPDk
zNd<dK!M>wl|EXY4E7*T25&z!`-!qDDJPSVGH=a|lQy#`&==8O<W&rwK7&ndhFAUWb
zea)58%N#}jauhwwQS>QC(VHAaKXMd3$Winip*RE3Yb46(D>4JnLmWSS!%_4KSDXGI
zwdn<tqwOU}i%X7nmK?1sIoecmw4}s0?YDM()0*VnXlTQ=bWVG^e$$eUq78-OQwKb5
zSz-B@g4HNkT)}D;ETLd^3RbURNnn0tHz-)6QnyLLniXuF(q5~F@%Jfp<@87`Ig0vm
z6gA^0>cmmhhNGwlM^OVp(LXtM@e+<${FCE!{2Za9I5t<CqmtSjOAow#6l+z@@?Q8E
z-rp|stVRq8<_8{M<{MkQabD(I>zHX+=38X{sxghW9_u7f`1+a-^J&Y}SH*fZ+v7`N
zHq>qpYaGV0?8B5;zHq>X|4oV%^!hSB0~j~UjeI{VX8`S)zN#~PJkwWQ&NF@cdmVp0
z-eXjk^9<ip-Wk68tJ=p|l32(ep4pTC9l>|zHs0~w;JqcI7bLv5S~V7P=dD<m=VdxP
zKAv2{vrDo=ww%vP0Bbexj9_&rZuR(h3aR=`7iG{#{I{$;9pt|~<hdMwUcl&A@bR>Z
zzq0Y<iI4FVh~F2yRa$|ap<vw##?wrGdx*vr7~bSYFuup<)n#6XJ7)m~k;E}9h#Wa+
zu`Y8p?tFjFlcj<EY{Ix$PSv-fL|Whse~!gz!7lT9+{wk$YQ2_MD4qhlrcxFM)mNcv
zL8U5G0;|ui3RMTHze3f6+FhZNco)qx03x9QRCu;2jvln4*I`)`-cyICY2tX>v$=BC
zC5{tko6W@)&UK)|b0Rz&x4CkPBMx6Y&xB_);+T5QtDKymr}o%4pX^I5#@%Z6piSzy
z7P=74GD3UIwPjhghzmKrB3wL~Ahql9mV9r8i>EgRDip^>KNij=)VZ!gwM001f+s9v
z)btp>O=Z1ArGG-zqTXPoEbNt()j@B3pDI*Cq|N3kc?o!g>nA-+#=x=h?4W3%E+Uz_
zagyt-K6nB|>hOFArPg6iaU-dN^{VBBQdx&FFDn@})P=m9<zS3=Ss&&p6P~mqUl01i
zGbfB}zF(%dvXoKHQg}Yvlyhpt8QBh(b7SOSj7SVIrX|NnmK@_(a*SHZ;a<)$LZho^
zP`!F$7%zDBM4ig&Ni*0u<2Nt6dM2P!20j;vy1M6CJ#DpDZZCZe#4v>LZ!lnoWu1g{
zJ@O0}1_|j`u9v3<Vz6!;>pw@=mgFLC%t?DUdw580C^uEe7xRZoLHhVqb~d>3@>fsr
z|KQDL?R2pV|8a>Y3SaaE{}Z7vvW4fcq33qSzv$Nw-~NGbKRq(j_Tl#?%|#b{>Oub8
zxD`p}Ib)AP(!cwVxCP>3$7%ltBu@9!NSxjmkSO8NXXS5~Fwa5vAuWBq<xzauJimGM
z@pkgomUAEce2n=EAA9_Rv5!8)F0Hs$>px}GJn+Q_?z;G_wmaXC{%?EwW8C5-JnTkb
zc5%cv1@I>n>$0!M@y+cQuK<bV+~TpEZINc4o3{S^d<p;YYXbj!Y=Gkq+u(u6ZAjaX
zZ@&be?K>{pkxr*~?Ap2g(jBkezB6^@WxFojvweH&^2@gGOs9A60_!W+OGpFX&A<O*
z{m+|2G*z4faET6v>v|l#DVSUE-?RC5Xl@bk1>8H}scfniiF4TLR3-oA3<O*;{EWz(
zImGw~`f#&=FW^r3j4{gQb-Gmt%8W6{oi*9ht+s-XKfFY;+*dFt0LRY*-@FoL+#JF9
z=kRw=__u!sa8&A$wF!|D{sv0k9-b2JmG>=W`P^Kd?)a&%kCdBAU?$4ra3TAUwSR%=
eh4tr(7cqX$|6eW3|89J}Q2kf`{hj}B`Tqm`@Jvqt

literal 46080
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
O8SK`7zy8A|@c#h*Y0<6#

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 df54c5679c0..1d4263cd87b 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 b730776794f..fbf88fbd32a 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 1eba23cd465..fbce5f0a9ac 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 ae242abdc90..e90d0fca54c 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 51363987d1f..2957d712024 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 ef4032eeaa8..7702c16e50e 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 2e15b9a1a95..5d7c32c7277 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 715cfae1dd0..00000000000
--- 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 6340b3a5b13..64c3dc87bf6 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 b67fb2fb565..6d596c17d80 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 68e38eb2b43..27692bc4fdd 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 1b0e34aba04..e7087238d59 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 1c90876232a..fea3039b97e 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 274c1a36a4b..7b816377c5b 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 a8b9c170e66..5eba0433083 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 74b87f10c9a..7f7ebd0b6d5 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 0847c18c625..1d59d9745cb 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 7597d8ba6a2..91f624ebce1 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 1c116252adf..bec20f48cd5 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 7554dec7cac..758795589b8 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 cb22b739a74..32d35170e47 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 e8f8b280404..7f461860a81 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 d845b16a11d..2c1a170dd54 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 7ed1f3ff068..736746dde6b 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 b33d92b9ccf..a66afc20af4 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 f67f997478f..21abc7ef30e 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 972d9eced25..b229afb708d 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 534803e5b09..94ebd7a52ee 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 43807a6b2b4..d2196dd938d 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 c040fa67d34..07d91dc6abd 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 00000000000..d23f9285861
--- /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 aa489331b1f..26d12018fc5 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 8d498fe2aed..64d55203476 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 8f57a107fb9..e17ce32cf2a 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 df54153e4ff..b6b7f5065f7 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 e05938aadc3..eea599e1d41 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 6add41dd7ec..7f6dc21ff7e 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 00000000000..49768482efe
--- /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 dce1366af7d..441ff4576e0 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 c1bf057f5f3..5bf59d1a984 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 d79fc89e1d3..40bd2e7e6cc 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 2ab162548ba..60ea54881c2 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 026ab63b8ea..188deda519f 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 baed5463168..c9cc4f1e290 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);
                 });
             });
         });
-- 
GitLab