diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/tar/Untar.java b/common/source/java/ch/systemsx/cisd/common/filesystem/tar/Untar.java
index fc30cba5863a147cb935ef7176e293496805f046..c1713ef37aa07d8f7a7965f31eda4d4bc1a271da 100644
--- a/common/source/java/ch/systemsx/cisd/common/filesystem/tar/Untar.java
+++ b/common/source/java/ch/systemsx/cisd/common/filesystem/tar/Untar.java
@@ -125,13 +125,14 @@ public class Untar implements Closeable
         }
     }
 
-    public File getEntryInLocation(TarArchiveEntry entry, final Map<String, File> locations)
+    private File getEntryInLocation(TarArchiveEntry entry, final Map<String, File> locations)
     {
         String[] parts = entry.getName().split("/", 2);
         String head = parts[0];
         String tail = parts[1];
 
-        return new File(locations.get(head), tail);
+        File parent = locations.get(head);
+        return parent == null ? null : new File(parent, tail);
     }
 
     private void extractEntry(TarArchiveEntry entry, final File entryFile, final List<TarArchiveEntry> dirEntries) throws FileNotFoundException,
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTask.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTask.java
index 4d09159f259dd3717599b232a52525a475649f5a..bb6b32680921001abc6aaa2e6cc5569c3f87e787 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTask.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTask.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.etlserver.postregistration;
 
 import java.io.File;
+import java.util.Date;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
@@ -60,6 +61,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
  */
 public class EagerShufflingTask extends AbstractPostRegistrationTaskForPhysicalDataSets
 {
+    private static final int SHARES_CACHING_TIMEOUT = 60 * 60 * 1000;
+
     @Private
     public static final String SHARE_FINDER_KEY = "share-finder";
 
@@ -176,6 +179,9 @@ public class EagerShufflingTask extends AbstractPostRegistrationTaskForPhysicalD
             return null;
         }
     }
+    
+    private List<Share> shares;
+    private Date sharesTimestamp;
 
     @Override
     public IPostRegistrationTaskExecutor createExecutor(String dataSetCode)
@@ -183,6 +189,19 @@ public class EagerShufflingTask extends AbstractPostRegistrationTaskForPhysicalD
         return new Executor(dataSetCode);
     }
 
+    private List<Share> getShares()
+    {
+        if (shares == null || sharesTimestamp == null 
+                || sharesTimestamp.getTime() + SHARES_CACHING_TIMEOUT < System.currentTimeMillis())
+        {
+            shares = SegmentedStoreUtils.getSharesWithDataSets(storeRoot, dataStoreCode, 
+                    FilterOptions.AVAILABLE_FOR_SHUFFLING,
+                    incomingShares, freeSpaceProvider, service, logger);
+            sharesTimestamp = new Date();
+        }
+        return shares;
+    }
+
     private final class Executor implements IPostRegistrationTaskExecutor
     {
         private final String dataSetCode;
@@ -199,17 +218,15 @@ public class EagerShufflingTask extends AbstractPostRegistrationTaskForPhysicalD
         @Override
         public ICleanupTask createCleanupTask()
         {
-            List<Share> shares =
-                    SegmentedStoreUtils.getSharesWithDataSets(storeRoot, dataStoreCode, FilterOptions.AVAILABLE_FOR_SHUFFLING,
-                            incomingShares, freeSpaceProvider, service, logger);
-            dataSet = findDataSet(shares, dataSetCode);
+            List<Share> currentShares = getShares();
+            dataSet = findDataSet(currentShares, dataSetCode);
             if (dataSet.getStatus().isAvailable() == false)
             {
                 logger.log(LogLevel.WARN, "Data set " + dataSetCode + " couldn't been shuffled because "
                         + "its archiving status is " + dataSet.getStatus());
                 return new NoCleanupTask();
             }
-            shareWithMostFreeOrNull = finder.tryToFindShare(dataSet, shares);
+            shareWithMostFreeOrNull = finder.tryToFindShare(dataSet, currentShares);
             if (shareWithMostFreeOrNull == null)
             {
                 String message = "No share found for shuffling data set " + dataSetCode + ".";
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/TarPackageManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/TarPackageManager.java
index 8207d8cbec80a4cb473f9ddc1092b06953968488..8bc177e8da32ee717a71b7cbbd6ad5b12092416b 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/TarPackageManager.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/TarPackageManager.java
@@ -55,7 +55,7 @@ public class TarPackageManager extends AbstractPackageManager
 
     private final int bufferSize;
     
-    private final ISimpleLogger ioSpeedLogger;
+    protected final ISimpleLogger logger;
 
     private Long maxQueueSize;
 
@@ -65,7 +65,7 @@ public class TarPackageManager extends AbstractPackageManager
         bufferSize = PropertyUtils.getInt(properties, BUFFER_SIZE_KEY, DEFAULT_BUFFER_SIZE);
         long maxSize = PropertyUtils.getLong(properties, MAXIMUM_QUEUE_SIZE_IN_BYTES_KEY, 5 * bufferSize);
         maxQueueSize = maxSize == 0 ? null : maxSize;
-        this.ioSpeedLogger = ioSpeedLogger;
+        this.logger = ioSpeedLogger;
     }
 
     @Override
@@ -126,7 +126,7 @@ public class TarPackageManager extends AbstractPackageManager
         if (onlyMetaData)
         {
             final ISingleDataSetPathInfoProvider pathInfoProvider 
-                    = new TarBasedPathInfoProvider(packageFile, bufferSize, ioSpeedLogger);
+                    = new TarBasedPathInfoProvider(packageFile, bufferSize, logger);
             return new PathInfoProviderBasedHierarchicalContent(pathInfoProvider, null, new IDelegatedAction()
                 {
                     @Override
@@ -135,7 +135,7 @@ public class TarPackageManager extends AbstractPackageManager
                     }
                 });
         }
-        return new TarBasedHierarchicalContent(packageFile, tempFolder, bufferSize, ioSpeedLogger);
+        return new TarBasedHierarchicalContent(packageFile, tempFolder, bufferSize, logger);
     }
 
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetArchiver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetArchiver.java
index d2f6469a2fb756fd06d7a79abf539c3fc035127a..af56d49e14684000193ff601ab5f98bc9474785c 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetArchiver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetArchiver.java
@@ -34,6 +34,7 @@ import org.apache.commons.lang.time.DateUtils;
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.collection.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.NotImplementedException;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
@@ -62,6 +63,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.ArchiverTaskContext;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IDataSetDirectoryProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IDataStoreServiceInternal;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IUnarchivingPreparation;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IncomingShareIdProvider;
@@ -544,16 +546,31 @@ public class MultiDataSetArchiver extends AbstractArchiverProcessingPlugin
     @Override
     protected DatasetProcessingStatuses doUnarchive(List<DatasetDescription> dataSets, ArchiverTaskContext context)
     {
+        DatasetProcessingStatuses result = new DatasetProcessingStatuses();
         List<String> dataSetCodes = translateToDataSetCodes(dataSets);
         Set<Long> containerIds = assertUnarchivingCapacityNotExceeded(dataSetCodes);
         assertNoAvailableDatasets(dataSetCodes);
         
         context.getUnarchivingPreparation().prepareForUnarchiving(dataSets);
 
+        IMultiDataSetFileOperationsManager operations = getFileOperations();
         for (Long containerId : containerIds)
         {
             MultiDataSetArchiverContainerDTO container = getReadonlyQuery().getContainerForId(containerId);
-            getFileOperations().restoreDataSetsFromContainerInFinalDestination(container.getPath(), dataSets);
+            Status status = operations.restoreDataSetsFromContainerInFinalDestination(container.getPath(), dataSets);
+            if (status.isError())
+            {
+                result.addResult(dataSets, status, Operation.UNARCHIVE);
+                return result;
+            }
+        }
+        
+        IHierarchicalContentProvider contentProvider = context.getHierarchicalContentProvider();
+        for (String dataSetCode : dataSetCodes)
+        {
+            IHierarchicalContent content = contentProvider.asContentWithoutModifyingAccessTimestamp(dataSetCode);
+            IHierarchicalContentNode rootNode = content.getRootNode();
+            assertFilesExists(dataSetCode, rootNode);
         }
 
         for (String dataSetCode : dataSetCodes)
@@ -561,10 +578,45 @@ public class MultiDataSetArchiver extends AbstractArchiverProcessingPlugin
             getService().notifyDatasetAccess(dataSetCode);
         }
 
-        DatasetProcessingStatuses result = new DatasetProcessingStatuses();
         result.addResult(dataSets, Status.OK, Operation.UNARCHIVE);
         return result;
     }
+    
+    private void assertFilesExists(String dataSetCode, IHierarchicalContentNode node)
+    {
+        File file;
+        try
+        {
+            file = node.getFile();
+        } catch (UnsupportedOperationException ex)
+        {
+            throw createException(dataSetCode, node, ex);
+        }
+        if (file.exists() == false)
+        {
+            throw createException(dataSetCode, node, null);
+        }
+        if (node.isDirectory())
+        {
+            for (IHierarchicalContentNode child : node.getChildNodes())
+            {
+                assertFilesExists(dataSetCode, child);
+            }
+        }
+    }
+
+    private EnvironmentFailureException createException(String dataSetCode,
+            IHierarchicalContentNode node, Exception exOrNull)
+    {
+        String message = "Data set " + dataSetCode + ": File '" + node.getRelativePath() 
+                + "' does not exist.";
+        if (exOrNull != null)
+        {
+            return new EnvironmentFailureException(message + " (reason: " + exOrNull.getMessage() + ")", 
+                    exOrNull);
+        }
+        return new EnvironmentFailureException(message);
+    }
 
     private void assertNoAvailableDatasets(List<String> dataSetCodes)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetFileOperationsManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetFileOperationsManager.java
index 11ae86fc6c1115fe9ce6832c5c6bce46a943d775..b8274759bae5be37526dcc5b8794828826b4c07f 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetFileOperationsManager.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetFileOperationsManager.java
@@ -241,9 +241,7 @@ public class MultiDataSetFileOperationsManager extends AbstractDataSetFileOperat
         }
 
         File stageArchiveContainerFile = new File(getFinalArchive().getDestination(), containerPath);
-        packageManager.extractMultiDataSets(stageArchiveContainerFile, dataSetToLocation);
-
-        return Status.OK;
+        return packageManager.extractMultiDataSets(stageArchiveContainerFile, dataSetToLocation);
     }
 
     @Override
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetPackageManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetPackageManager.java
index d43e1c552980ae2e045203a274d6fd7baf333a28..974cddfa0c4d97a5ee65af7b1479cdcbad800561 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetPackageManager.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/MultiDataSetPackageManager.java
@@ -26,6 +26,7 @@ import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.filesystem.tar.Untar;
 import ch.systemsx.cisd.common.logging.ISimpleLogger;
+import ch.systemsx.cisd.common.logging.LogLevel;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDataSetPackager;
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.TarPackageManager;
 
@@ -60,6 +61,7 @@ public class MultiDataSetPackageManager extends TarPackageManager implements IMu
             return Status.OK;
         } catch (Exception ex)
         {
+            logger.log(LogLevel.ERROR, "Error during untaring " + packageFile, ex);
             return Status.createError(ex.toString());
         } finally
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ExperimentProjectSpaceCodeRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ExperimentProjectSpaceCodeRecord.java
index 6c244cb537d20182933e9b49440e55ba47be2c5e..581f0c90f6909eb02cdc24e5135d8bb2f27d172b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ExperimentProjectSpaceCodeRecord.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ExperimentProjectSpaceCodeRecord.java
@@ -9,6 +9,8 @@ import ch.rinn.restrictions.Private;
 @Private
 public class ExperimentProjectSpaceCodeRecord
 {
+    public long id;
+    
     public String e_code;
 
     public String e_permid;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
index f9cc0dc247ac0e308ebbee2270e15d14bc04775c..628275f4ad7e6fa2d5598e04ae324ab532a1202b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
@@ -37,6 +37,12 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 { SampleReferenceRecord.class })
 public interface ISecondaryEntityListingQuery extends BaseQuery
 {
+    public static final String SELECT_FROM_EXPERIMENTS 
+            = "select e.id as id, e.code as e_code, e.perm_id as e_permid, e.del_id as del_id, et.code as et_code, "
+            + "p.code as p_code, p.id as p_id, p.perm_id as p_perm_id, g.code as spc_code, g.dbin_id as dbin_id from experiments e "
+            + "join experiment_types et on e.exty_id=et.id join projects p on e.proj_id=p.id "
+            + "join spaces g on p.space_id=g.id";
+    
     public static final int FETCH_SIZE = 1000;
 
     //
@@ -48,12 +54,13 @@ public interface ISecondaryEntityListingQuery extends BaseQuery
      * 
      * @param experimentId The id of the experiment to get the code for.
      */
-    @Select("select e.code as e_code, e.perm_id as e_permid, e.del_id as del_id, et.code as et_code, "
-            + "p.code as p_code, p.id as p_id, p.perm_id as p_perm_id, g.code as spc_code from experiments e "
-            + "join experiment_types et on e.exty_id=et.id join projects p on e.proj_id=p.id "
-            + "join spaces g on p.space_id=g.id where e.id=?{1}")
+    @Select(SELECT_FROM_EXPERIMENTS + " where e.id=?{1}")
     public ExperimentProjectSpaceCodeRecord getExperimentAndProjectAndGroupCodeForId(
             long experimentId);
+    
+    @Select(sql = SELECT_FROM_EXPERIMENTS + " where e.id = any(?{1})", parameterBindings =
+            { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public DataIterator<ExperimentProjectSpaceCodeRecord> getExperiments(LongSet experimentIds);
 
     //
     // Samples
@@ -93,8 +100,6 @@ public interface ISecondaryEntityListingQuery extends BaseQuery
 
     /**
      * Returns all spaces of this data base instance.
-     * 
-     * @param databaseInstanceId The id of the database to get the spaces for.
      */
     @Select("select id, code from spaces")
     public Space[] getAllSpaces();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
index 8a2929c3aeedc78e8b9802e04374550c7079036a..944c8d443f89f3001f616d00c93036fe039cd0d7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
@@ -164,7 +164,18 @@ public class SecondaryEntityDAO
         }
         return result;
     }
-
+    
+    public Long2ObjectMap<Experiment> getExperiments(LongSet experimentIds)
+    {
+        Iterable<ExperimentProjectSpaceCodeRecord> experimentRecords = query.getExperiments(experimentIds);
+        Long2ObjectMap<Experiment> result = new Long2ObjectOpenHashMap<Experiment>();
+        for (ExperimentProjectSpaceCodeRecord record : experimentRecords)
+        {
+            result.put(record.id, tryCreateExperiment(record.id, record));
+        }
+        return result;
+    }
+    
     public LongSet getSampleDescendantIdsAndSelf(Long sampleId)
     {
         LongSet results = new LongOpenHashSet();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
index 0da7b1d8f037fc12b96636589050755e351f1af2..cda4425eff61b4ef5059ba57fbe8a243f93028d2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetLister.java
@@ -826,11 +826,26 @@ public class DatasetLister extends AbstractLister implements IDatasetLister
         return ids;
     }
 
+    private static LongSet extractExperimentIds(Long2ObjectMap<AbstractExternalData> datasetMap)
+    {
+        LongSet ids = new LongOpenHashSet();
+        for (AbstractExternalData dataset : datasetMap.values())
+        {
+            Experiment experiment = dataset.getExperiment();
+            if (experiment != null)
+            {
+                ids.add(experiment.getId());
+            }
+        }
+        return ids;
+    }
+    
     // assumes that the connection to experiment has been already established and experiment has the
     // id set.
     private void enrichWithExperiments(Long2ObjectMap<AbstractExternalData> datasetMap)
     {
-        Long2ObjectMap<Experiment> experimentMap = new Long2ObjectOpenHashMap<Experiment>();
+        LongSet ids = extractExperimentIds(datasetMap);
+        Long2ObjectMap<Experiment> experiments = referencedEntityDAO.getExperiments(ids);
 
         for (AbstractExternalData dataset : datasetMap.values())
         {
@@ -839,14 +854,7 @@ public class DatasetLister extends AbstractLister implements IDatasetLister
                 continue;
             }
             long experimentId = dataset.getExperiment().getId();
-            Experiment experiment = experimentMap.get(experimentId);
-            // null value is put if experiment is from different db instance
-            if (experimentMap.containsKey(experimentId) == false)
-            {
-                experiment = referencedEntityDAO.tryGetExperiment(experimentId);
-                experimentMap.put(experimentId, experiment);
-            }
-            dataset.setExperiment(experiment);
+            dataset.setExperiment(experiments.get(experimentId));
         }
     }