diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/CifexStorageProcessor.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/CifexStorageProcessor.java
index 715cce6d454317f1cfcf8445ab704004233a26ea..682edd656e486c1b62fe4dfc6b644437032144a7 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/CifexStorageProcessor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/CifexStorageProcessor.java
@@ -54,9 +54,12 @@ public class CifexStorageProcessor extends AbstractDelegatingStorageProcessor
             LogFactory.getLogger(LogCategory.NOTIFY, CifexStorageProcessor.class);
 
     public static final String KEEP_FILE_REGEX_KEY = "keep-file-regex";
+    public static final String MOVE_TO_ERROR_FOLDER_KEY = "move-to-error-folder";
 
     private final String keepFileRegex;
 
+    private final boolean moveToErrorFolder;
+    
     private File dirToRestore;
 
     private File fileToMove;
@@ -67,6 +70,7 @@ public class CifexStorageProcessor extends AbstractDelegatingStorageProcessor
     {
         super(properties);
         keepFileRegex = PropertyUtils.getProperty(properties, KEEP_FILE_REGEX_KEY);
+        moveToErrorFolder = PropertyUtils.getBoolean(properties, MOVE_TO_ERROR_FOLDER_KEY, false);
     }
 
     @Override
@@ -92,7 +96,7 @@ public class CifexStorageProcessor extends AbstractDelegatingStorageProcessor
                     dirToRestore);
         }
         super.rollback(incomingDataSetDirectory, storedDataDirectory, exception);
-        return UnstoreDataAction.DELETE;
+        return moveToErrorFolder ? UnstoreDataAction.MOVE_TO_ERROR : UnstoreDataAction.DELETE;
     }
 
     @Private
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
index c1cf70d420af36fd96ca2c6af2c6cf790ffa6d33..e123b578199c12394e0b16d8053bc7ede773a9ca 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/cifex/CifexDataSetInfoExtractor.java
@@ -22,9 +22,13 @@ import java.io.File;
 import java.util.Arrays;
 import java.util.Properties;
 
+import org.apache.log4j.Logger;
+
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
@@ -42,6 +46,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFa
  */
 public class CifexDataSetInfoExtractor implements IDataSetInfoExtractor
 {
+    private final static Logger operationLog =
+        LogFactory.getLogger(LogCategory.OPERATION, CifexDataSetInfoExtractor.class);
 
     @Private
     static final String DATA_SET_PROPERTIES_FILE_NAME_KEY =
@@ -62,6 +68,10 @@ public class CifexDataSetInfoExtractor implements IDataSetInfoExtractor
         assert incomingDataSetPath != null : "Incoming data set path can not be null.";
 
         DataSetUploadInfo info = CifexExtractorHelper.getDataSetUploadInfo(incomingDataSetPath);
+        if (operationLog.isInfoEnabled())
+        {
+            operationLog.info("Data set upload info: " + info);
+        }
         final DataSetInformation dataSetInformation = new DataSetInformation();
 
         // either sample is specified or experiment (with optional data set parents)
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/validation/DataSetValidator.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/validation/DataSetValidator.java
index 3b10f29a5b4780c8264a67f862bf1b211f6abbc0..c4ba370c9bdd9f7010916cd15ed3a9f02d42675b 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/validation/DataSetValidator.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/validation/DataSetValidator.java
@@ -24,6 +24,7 @@ import java.util.Properties;
 import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
@@ -101,7 +102,14 @@ public class DataSetValidator implements IDataSetValidator
         IDataSetValidator validator = validators.get(dataSetType.getCode());
         if (validator != null)
         {
-            validator.assertValidDataSet(dataSetType, incomingDataSetFileOrFolder);
+            try
+            {
+                validator.assertValidDataSet(dataSetType, incomingDataSetFileOrFolder);
+            } catch (Exception ex)
+            {
+                throw new UserFailureException("Data set of type '" + dataSetType.getCode()
+                        + "' is invalid: " + ex.getMessage(), ex);
+            }
             if (operationLog.isInfoEnabled())
             {
                 operationLog.info("Data set [" + incomingDataSetFileOrFolder + "] of type '"
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractFileTableReportingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractFileTableReportingPlugin.java
index 752632a855b72c45ffa3bb81a19f42d9c1f7f5a6..cbd73d334f55d0de30c8c3929b7b38c06dd24fcb 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractFileTableReportingPlugin.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractFileTableReportingPlugin.java
@@ -56,6 +56,8 @@ abstract public class AbstractFileTableReportingPlugin extends AbstractDatastore
     private static final String SEPARATOR_PROPERTY_KEY = "separator";
 
     private static final String IGNORE_COMMENTS_PROPERTY_KEY = "ignore-comments";
+    
+    private static final String IGNORE_TRAILING_EMPTY_CELLS_PROPERTY_KEY = "ignore-trailing-empty-cells";
 
     // if the line starts with this character and comments should be ignored, the line is ignored
     private static final char COMMENT = '#';
@@ -64,6 +66,8 @@ abstract public class AbstractFileTableReportingPlugin extends AbstractDatastore
 
     private final boolean ignoreComments;
 
+    private final boolean ignoreTrailingEmptyCells;
+
     protected AbstractFileTableReportingPlugin(Properties properties, File storeRoot,
             char defaultSeparator)
     {
@@ -72,6 +76,9 @@ abstract public class AbstractFileTableReportingPlugin extends AbstractDatastore
                 PropertyUtils.getChar(properties, SEPARATOR_PROPERTY_KEY, defaultSeparator);
         this.ignoreComments =
                 PropertyUtils.getBoolean(properties, IGNORE_COMMENTS_PROPERTY_KEY, true);
+        ignoreTrailingEmptyCells =
+                PropertyUtils.getBoolean(properties, IGNORE_TRAILING_EMPTY_CELLS_PROPERTY_KEY,
+                        false);
 
     }
 
@@ -143,10 +150,11 @@ abstract public class AbstractFileTableReportingPlugin extends AbstractDatastore
         return new DatasetFileLines(file, dataset, lines);
     }
 
-    protected static TableModel createTableModel(DatasetFileLines lines)
+    protected TableModel createTableModel(DatasetFileLines lines)
     {
         SimpleTableModelBuilder tableBuilder = new SimpleTableModelBuilder();
-        for (String title : lines.getHeaderTokens())
+        String[] headerTokens = lines.getHeaderTokens();
+        for (String title : headerTokens)
         {
             tableBuilder.addHeader(title);
         }
@@ -157,6 +165,18 @@ abstract public class AbstractFileTableReportingPlugin extends AbstractDatastore
             {
                 row.add(TableCellUtil.createTableCell(token));
             }
+            if (ignoreTrailingEmptyCells)
+            {
+                while (row.size() > headerTokens.length)
+                {
+                    ISerializableComparable cell = row.get(row.size() - 1);
+                    if (cell.toString().length() > 0)
+                    {
+                        break;
+                    }
+                    row.remove(row.size() - 1);
+                }
+            }
             tableBuilder.addRow(row);
         }
         return tableBuilder.getTableModel();