diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/IPathsInfoDAO.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/IPathsInfoDAO.java
index 9dd2a9c1ff3be3efd138369f28dd10baab96b9b5..3886f15f9d6005bce6a803fb53b10a83960c5555 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/IPathsInfoDAO.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/IPathsInfoDAO.java
@@ -20,11 +20,12 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
-
 import net.lemnik.eodsql.Select;
 import net.lemnik.eodsql.TransactionQuery;
 import net.lemnik.eodsql.Update;
 
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.StringArrayMapper;
+
 /**
  * Data Access Object for feeding and updating pathinfo database.
  * 
@@ -42,13 +43,13 @@ public interface IPathsInfoDAO extends TransactionQuery
             + "size_in_bytes, is_directory, last_modified) values (?{1}, ?{2}, ?{3}, ?{4}, ?{5}, ?{6}, ?{7}) returning id")
     public long createDataSetFile(long dataSetId, Long parentId, String relativePath,
             String fileName, long sizeInBytes, boolean directory, Date lastModifiedDate);
-    
+
     @Select("select registration_timestamp from last_feeding_event")
     public Date getRegistrationTimestampOfLastFeedingEvent();
-    
+
     @Update("delete from last_feeding_event")
     public void deleteLastFeedingEvent();
-    
+
     @Update("insert into last_feeding_event (registration_timestamp) values (?{1})")
     public void createLastFeedingEvent(Date registrationTimestamp);
 
@@ -57,13 +58,18 @@ public interface IPathsInfoDAO extends TransactionQuery
             + "(?{1.dataSetId}, ?{1.parentId}, ?{1.relativePath}, ?{1.fileName}, ?{1.sizeInBytes}, "
             + "?{1.checksumCRC32}, ?{1.directory}, ?{1.lastModifiedDate})", batchUpdate = true)
     public void createDataSetFiles(Collection<PathEntryDTO> filePaths);
-    
+
     @Select("select f.id, d.code as data_set_code, relative_path " +
-    		"from data_set_files as f join data_sets as d on f.dase_id = d.id " +
-    		"where checksum_crc32 is null and is_directory = 'F'")
+            "from data_set_files as f join data_sets as d on f.dase_id = d.id " +
+            "where checksum_crc32 is null and is_directory = 'F'")
     public List<PathEntryDTO> listDataSetFilesWithUnkownChecksum();
-    
+
     @Update("update data_set_files set checksum_crc32 = ?{2} where id = ?{1}")
     public void updateChecksum(long id, int checksum);
-    
+
+    @Select(sql = "select d.code as data_set_code, size_in_bytes " +
+            "from data_set_files as f join data_sets as d on f.dase_id = d.id " +
+            "where d.code = any(?{1}) and parent_id is null", parameterBindings = { StringArrayMapper.class })
+    public List<PathEntryDTO> listDataSetsSize(String[] dataSetCodes);
+
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/PathEntryDTO.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/PathEntryDTO.java
index 87cf46950dfaea6a614998f6a36be6155bf0343b..61c2f1095d0002818daf62721ed6f3149e0540eb 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/PathEntryDTO.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/path/PathEntryDTO.java
@@ -212,7 +212,7 @@ public class PathEntryDTO
         this.fileName = fileName;
     }
 
-    public long getSizeInBytes()
+    public Long getSizeInBytes()
     {
         return sizeInBytes;
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/FillUnknownDataSetSizeInOpenbisDBFromPathInfoDBMaintenanceTask.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/FillUnknownDataSetSizeInOpenbisDBFromPathInfoDBMaintenanceTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef8c02d24fa8d98926bca4c14370d6ffbe287405
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/FillUnknownDataSetSizeInOpenbisDBFromPathInfoDBMaintenanceTask.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2014 ETH Zuerich, CISD
+ *
+ * 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.systemsx.cisd.etlserver.plugins;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import net.lemnik.eodsql.QueryTool;
+
+import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.maintenance.IMaintenanceTask;
+import ch.systemsx.cisd.etlserver.path.IPathsInfoDAO;
+import ch.systemsx.cisd.etlserver.path.PathEntryDTO;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.utils.PathInfoDataSourceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
+
+/**
+ * @author pkupczyk
+ */
+public class FillUnknownDataSetSizeInOpenbisDBFromPathInfoDBMaintenanceTask implements IMaintenanceTask
+{
+
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            FillUnknownDataSetSizeInOpenbisDBFromPathInfoDBMaintenanceTask.class);
+
+    private IEncapsulatedOpenBISService service;
+
+    private IPathsInfoDAO dao;
+
+    @Override
+    public void setUp(String pluginName, Properties properties)
+    {
+        service = ServiceProvider.getOpenBISService();
+        dao = createDAO();
+    }
+
+    @Override
+    public void execute()
+    {
+        operationLog.info("Start filling.");
+
+        List<SimpleDataSetInformationDTO> dataSets = service.listPhysicalDataSetsWithUnknownSize();
+        Set<String> codes = new HashSet<String>();
+
+        for (SimpleDataSetInformationDTO dataSet : dataSets)
+        {
+            codes.add(dataSet.getDataSetCode());
+        }
+
+        operationLog.info("Found " + codes.size() + " dataset(s) with unknown size in openbis database.");
+
+        if (codes.size() > 0)
+        {
+            List<PathEntryDTO> pathInfoEntries = dao.listDataSetsSize(codes.toArray(new String[codes.size()]));
+            Map<String, Long> sizeMap = new HashMap<String, Long>();
+
+            for (PathEntryDTO pathInfoEntry : pathInfoEntries)
+            {
+                if (pathInfoEntry.getSizeInBytes() != null)
+                {
+                    sizeMap.put(pathInfoEntry.getDataSetCode(), pathInfoEntry.getSizeInBytes());
+                }
+            }
+
+            operationLog.info("Found sizes for " + sizeMap.size() + " dataset(s) in pathinfo database.");
+
+            service.updatePhysicalDataSetsSize(sizeMap);
+
+        }
+        operationLog.info("Filling finished.");
+    }
+
+    private static IPathsInfoDAO createDAO()
+    {
+        return QueryTool.getQuery(PathInfoDataSourceProvider.getDataSource(), IPathsInfoDAO.class);
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
index 6f30257d28ec33496786f0f42b2f822986672b15..17353cce39b0a36a47b90f46a3ad38e42d839558 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java
@@ -664,6 +664,21 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer
         return injectDefaultShareIdIfMissing(dataSets);
     }
 
+    @Override
+    public List<SimpleDataSetInformationDTO> listPhysicalDataSetsWithUnknownSize() throws UserFailureException
+    {
+        List<SimpleDataSetInformationDTO> dataSets =
+                service.listPhysicalDataSetsWithUnknownSize(session.getSessionToken(),
+                        session.getDataStoreCode());
+        return injectDefaultShareIdIfMissing(dataSets);
+    }
+
+    @Override
+    public void updatePhysicalDataSetsSize(Map<String, Long> sizeMap) throws UserFailureException
+    {
+        service.updatePhysicalDataSetsSize(session.getSessionToken(), sizeMap);
+    }
+
     private List<SimpleDataSetInformationDTO> injectDefaultShareIdIfMissing(
             List<SimpleDataSetInformationDTO> dataSets)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
index 793fef241868a225a5237b35204bd5749eccd152..db800139a673648dbc3bc15dc28eccc40c4468c2 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java
@@ -280,6 +280,18 @@ public interface IEncapsulatedOpenBISService extends IEncapsulatedBasicOpenBISSe
     public List<SimpleDataSetInformationDTO> listOldestPhysicalDataSets(Date youngerThan,
             int chunkSize) throws UserFailureException;
 
+    /**
+     * Returns informations about physical data sets with unknown size that belong to the calling data store server.
+     */
+    @ManagedAuthentication
+    public List<SimpleDataSetInformationDTO> listPhysicalDataSetsWithUnknownSize() throws UserFailureException;
+
+    /**
+     * Updates sizes of the specified physical data sets (map key: data set code, map value: data set size).
+     */
+    @ManagedAuthentication
+    public void updatePhysicalDataSetsSize(Map<String, Long> sizeMap) throws UserFailureException;
+
     /** @see IServiceForDataStoreServer#listDataSets(String, String, TrackingDataSetCriteria) */
     @ManagedAuthentication
     public List<AbstractExternalData> listNewerDataSets(TrackingDataSetCriteria criteria)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
index dec4a9b597d9520ac6ec5b8f48bcbb62e27ca59d..68fd8ed8c6ab87bd19de96c574ca6c3ebb4a47be 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
@@ -1290,6 +1290,27 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         return SimpleDataSetHelper.filterAndTranslate(dataSets);
     }
 
+    @Override
+    public List<SimpleDataSetInformationDTO> listPhysicalDataSetsWithUnknownSize(String sessionToken, String dataStoreCode)
+    {
+        final Session session = getSession(sessionToken);
+        final DataStorePE dataStore = loadDataStore(session, dataStoreCode);
+        final IDatasetLister datasetLister = businessObjectFactory.createDatasetLister(session);
+        final List<AbstractExternalData> dataSets =
+                datasetLister.listByDataStoreWithUnknownSize(dataStore.getId(),
+                        DATASET_FETCH_OPTIONS_FILE_DATASETS);
+        return SimpleDataSetHelper.filterAndTranslate(dataSets);
+    }
+
+    @Override
+    public void updatePhysicalDataSetsSize(String sessionToken, Map<String, Long> sizeMap)
+    {
+        assert sessionToken != null : "Unspecified session token.";
+        final Session session = getSession(sessionToken);
+        final IDataBO dataBO = businessObjectFactory.createDataBO(session);
+        dataBO.updateSizes(sizeMap);
+    }
+
     @Override
     @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER)
     public List<AbstractExternalData> listAvailableDataSets(String sessionToken,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServerLogger.java
index d5041d48e16d34b3d8c35c8976fe2ce7b08daa26..177f144b56a2e336b960bcf7c9d70bb378332e77 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServerLogger.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.server;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.EnumSet;
 import java.util.List;
@@ -415,6 +416,20 @@ public class ServiceForDataStoreServerLogger extends AbstractServerLogger implem
         return null;
     }
 
+    @Override
+    public List<SimpleDataSetInformationDTO> listPhysicalDataSetsWithUnknownSize(String sessionToken, String dataStoreCode)
+    {
+        logAccess(Level.DEBUG, sessionToken, "listPhysicalDataSetsWithUnknownSize", "DATA_STORE(%s)", dataStoreCode);
+        return null;
+    }
+
+    @Override
+    public void updatePhysicalDataSetsSize(String sessionToken, Map<String, Long> sizeMap)
+    {
+        logAccess(Level.DEBUG, sessionToken, "updatePhysicalDataSetsSize", "CODES(%s)",
+                sizeMap != null ? CollectionUtils.abbreviate(sizeMap.keySet(), 10) : Collections.emptySet());
+    }
+
     @Override
     public List<AbstractExternalData> listAvailableDataSets(String sessionToken,
             String dataStoreCode,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
index c54ac5e329fac8d81e80623de12e8740bad6350d..5fa4905d6a72b772f180519dbba13b5787a676a1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.springframework.dao.DataAccessException;
@@ -161,7 +162,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
     public void loadDataByTechId(TechId datasetId)
     {
         String[] connections =
-            { PROPERTY_TYPES, DATA_SET_TYPE };
+        { PROPERTY_TYPES, DATA_SET_TYPE };
         data = getDataDAO().tryGetByTechId(datasetId, connections);
         if (data == null)
         {
@@ -769,6 +770,12 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         getDataDAO().updateDataSetStatuses(dataSetCodes, newStatus, newPresentInArchive);
     }
 
+    @Override
+    public void updateSizes(Map<String, Long> sizeMap)
+    {
+        getDataDAO().updateSizes(sizeMap);
+    }
+
     @Override
     public boolean compareAndSetDataSetStatus(DataSetArchivingStatus oldStatus,
             DataSetArchivingStatus newStatus, boolean newPresentInArchive)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
index 7d1469156c6a58df555d249a898c729c85ebe1fd..69136de8cf1ad79a2c8eae4876f7688476355c29 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
 import java.util.List;
+import java.util.Map;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.dataset.IDataSetId;
@@ -38,37 +39,32 @@ public interface IDataBO extends IEntityBusinessObject
 {
 
     /**
-     * Returns a data set found by the given id or null if it does not exist. Does not change the
-     * state of this object, especially the result of {@link #getData()}.
+     * Returns a data set found by the given id or null if it does not exist. Does not change the state of this object, especially the result of
+     * {@link #getData()}.
      */
     DataPE tryFindByDataSetId(final IDataSetId dataSetId);
 
     /**
-     * Returns the data item which has been created by
-     * {@link #define(NewExternalData, SamplePE, SourceType)} or null.
+     * Returns the data item which has been created by {@link #define(NewExternalData, SamplePE, SourceType)} or null.
      */
     public DataPE tryGetData();
 
     /**
-     * Returns the data item which has been created by
-     * {@link #define(NewExternalData, SamplePE, SourceType)}.
+     * Returns the data item which has been created by {@link #define(NewExternalData, SamplePE, SourceType)}.
      */
     public DataPE getData();
 
     /**
      * Defines a new external data item directly connected to a sample.
      * <p>
-     * After invocation of this method {@link IExperimentBO#save()} should be invoked to store the
-     * new external data item in the Data Access Layer.
+     * After invocation of this method {@link IExperimentBO#save()} should be invoked to store the new external data item in the Data Access Layer.
      */
     public void define(NewExternalData data, SamplePE sample, SourceType sourceType);
 
     /**
-     * Defines a new external data item not directly connected to a sample but with mandatory
-     * connection with an experiment.
+     * Defines a new external data item not directly connected to a sample but with mandatory connection with an experiment.
      * <p>
-     * After invocation of this method {@link IExperimentBO#save()} should be invoked to store the
-     * new external data item in the Data Access Layer.
+     * After invocation of this method {@link IExperimentBO#save()} should be invoked to store the new external data item in the Data Access Layer.
      */
     public void define(NewExternalData data, ExperimentPE experiment, SourceType sourceType);
 
@@ -86,18 +82,22 @@ public interface IDataBO extends IEntityBusinessObject
             boolean newPresentInArchive) throws UserFailureException;
 
     /**
-     * Set the status for the loaded data set to the given new status value if the current status
-     * equals an expected value.
+     * Updates sizes of given data sets (map key: data set code, map value: data set size).
      * 
-     * @return true if the update is successful, false if the current status is different than
-     *         <code>oldStatus</code>.
+     * @throws UserFailureException if a data set does not exist or size couldn't be set.
+     */
+    public void updateSizes(Map<String, Long> sizeMap);
+
+    /**
+     * Set the status for the loaded data set to the given new status value if the current status equals an expected value.
+     * 
+     * @return true if the update is successful, false if the current status is different than <code>oldStatus</code>.
      */
     public boolean compareAndSetDataSetStatus(DataSetArchivingStatus oldStatus,
             DataSetArchivingStatus newStatus, boolean newPresentInArchive);
 
     /**
-     * Adds chosen properties to given data set. If given property has been already defined, the
-     * value is not updated.
+     * Adds chosen properties to given data set. If given property has been already defined, the value is not updated.
      */
     public void addPropertiesToDataSet(String dataSetCode, List<NewProperty> properties);
 
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 78a093436753d3bc89c945d93984ad8c310d2f5e..d1142e75100aff60825333ab75f4f61e00c124fb 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
@@ -91,8 +91,8 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.DataStoreTranslator;
  * @author Tomasz Pylak
  */
 @Friend(toClasses =
-    { DatasetRecord.class, DatasetRelationRecord.class, DataStoreRecord.class,
-            DatasetCodeWithShareIdRecord.class, IDatasetListingQuery.class })
+{ DatasetRecord.class, DatasetRelationRecord.class, DataStoreRecord.class,
+        DatasetCodeWithShareIdRecord.class, IDatasetListingQuery.class })
 public class DatasetLister extends AbstractLister implements IDatasetLister
 {
     public static final EnumSet<DataSetFetchOption> SUPPORTED_DATASET_FETCH_OPTIONS = EnumSet.of(
@@ -490,6 +490,16 @@ public class DatasetLister extends AbstractLister implements IDatasetLister
                         dataStoreID), datasetFetchOptions));
     }
 
+    @Override
+    public List<AbstractExternalData> listByDataStoreWithUnknownSize(long dataStoreID, EnumSet<DataSetFetchOption> datasetFetchOptions)
+    {
+        checkFetchOptions(datasetFetchOptions);
+        return orderByDate(enrichDatasets(
+                handleDegenerateRegistrationTimestamp(
+                        query.getDatasetsByDataStoreIdWithUnknownSize(dataStoreID),
+                        dataStoreID), datasetFetchOptions));
+    }
+
     private Iterable<DatasetRecord> handleDegenerateRegistrationTimestamp(List<DatasetRecord> list,
             long dataStoreID)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
index 1a58ce649a9e33fb39baff09970a9b34e654808e..6ca0063c3e985b3454ea6399a459a0d80e890045 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetLister.java
@@ -26,8 +26,8 @@ import java.util.Set;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.GenericEntityPropertyRecord;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocationNode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
@@ -42,15 +42,15 @@ public interface IDatasetLister
 {
     /**
      * @return datasets connected to the experiment with the specified id
-     * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also
-     *            all descendants in dataset parent-child relationship hierarchy
+     * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also all descendants in dataset parent-child
+     *            relationship hierarchy
      */
     List<AbstractExternalData> listByExperimentTechId(TechId experimentId, boolean showOnlyDirectlyConnected);
 
     /**
      * @return datasets connected to the sample with the specified id
-     * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also
-     *            all descendants in dataset parent-child relationship hierarchy
+     * @param showOnlyDirectlyConnected whether to return only directly connected datasets, or also all descendants in dataset parent-child
+     *            relationship hierarchy
      */
     List<AbstractExternalData> listBySampleTechId(TechId sampleId, boolean showOnlyDirectlyConnected);
 
@@ -67,21 +67,20 @@ public interface IDatasetLister
     List<AbstractExternalData> listByMetaprojectId(Long metaprojectId);
 
     /**
-     * Returns a map with all parent data set IDs of specified data set IDs. The keys of the map are
-     * IDs from the argument. A value of the map contains at least one element.
+     * Returns a map with all parent data set IDs of specified data set IDs. The keys of the map are IDs from the argument. A value of the map
+     * contains at least one element.
      */
     Map<Long, Set<Long>> listParentIds(Collection<Long> dataSetIDs);
 
     /**
-     * Returns a map with all child data set IDs of specified data set IDs. The keys of the map are
-     * IDs from the argument. A value of the map contains at least one element.
+     * Returns a map with all child data set IDs of specified data set IDs. The keys of the map are IDs from the argument. A value of the map contains
+     * at least one element.
      */
     Map<Long, Set<Long>> listChildrenIds(Collection<Long> dataSetIDs);
 
     /**
-     * Returns a map with all data sets of specified samples. The sample arguments are the key into
-     * the returned map. The returned data sets contains all derived data sets (children, grand
-     * children, etc.).
+     * Returns a map with all data sets of specified samples. The sample arguments are the key into the returned map. The returned data sets contains
+     * all derived data sets (children, grand children, etc.).
      */
     Map<Sample, List<AbstractExternalData>> listAllDataSetsFor(List<Sample> samples);
 
@@ -92,8 +91,7 @@ public interface IDatasetLister
 
     /**
      * @param datasetCodes Codes of datasets.
-     * @param datasetFetchOptions The options of what datasets to fetch.
-     *            Lists all data sets with specified codes.
+     * @param datasetFetchOptions The options of what datasets to fetch. Lists all data sets with specified codes.
      */
     List<AbstractExternalData> listByDatasetCode(Collection<String> datasetCodes,
             EnumSet<DataSetFetchOption> datasetFetchOptions);
@@ -120,14 +118,18 @@ public interface IDatasetLister
             EnumSet<DataSetFetchOption> datasetFetchOptions);
 
     /**
-     * Lists the oldest <var>limit</var> physical datasets younger than <var>youngerThan</var> of
-     * the specified data store.
+     * Lists the oldest <var>limit</var> physical datasets younger than <var>youngerThan</var> of the specified data store.
      * 
      * @param datasetFetchOptions The options of what datasets to fetch.
      */
     public List<AbstractExternalData> listByDataStore(long dataStoreID, Date youngerThan, int limit,
             EnumSet<DataSetFetchOption> datasetFetchOptions);
 
+    /**
+     * Lists physical datasets with unknown size of the specified data store.
+     */
+    List<AbstractExternalData> listByDataStoreWithUnknownSize(long dataStoreID, EnumSet<DataSetFetchOption> datasetFetchOptions);
+
     /**
      * Lists {@link DataSetShareId}s of all data sets (even those in trash) in specified data store.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
index 53973c37e481848a45154615bc357216e2e84b76..fdbde2d471a7f0b93e9e08dd7028753a55392ff1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/IDatasetListingQuery.java
@@ -39,17 +39,16 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.LongSetMapper;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.StringArrayMapper;
 
 /**
- * A {@link TransactionQuery} interface for obtaining large sets of dataset-related entities from
- * the database.
+ * A {@link TransactionQuery} interface for obtaining large sets of dataset-related entities from the database.
  * <p>
- * This interface is intended to be used only in this package. The <code>public</code> modifier is
- * needed for creating a dynamic proxy by the EOD SQL library.
+ * This interface is intended to be used only in this package. The <code>public</code> modifier is needed for creating a dynamic proxy by the EOD SQL
+ * library.
  * 
  * @author Tomasz Pylak
  */
 @Private
 @Friend(toClasses =
-    { DataStoreRecord.class })
+{ DataStoreRecord.class })
 public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
 {
     public static final int FETCH_SIZE = 1000;
@@ -100,7 +99,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
      * Returns the directly connected datasets for the given sample ids.
      */
     @Select(sql = SELECT_ALL + " WHERE data.samp_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRecord> getDatasetsForSamples(LongSet sampleIds);
 
     /**
@@ -110,8 +109,8 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
     public DataIterator<DatasetRecord> getNewDataSets(long lastSeenDatasetId);
 
     /**
-     * Returns datasets that are newer than dataset with given id (<var>lastSeenDatasetId</var>) and
-     * are directly connected with samples of sample type with given <var>sampleTypeId</var>.
+     * Returns datasets that are newer than dataset with given id (<var>lastSeenDatasetId</var>) and are directly connected with samples of sample
+     * type with given <var>sampleTypeId</var>.
      */
     @Select(sql = SELECT_ALL
             + " WHERE data.id > ?{2} AND data.samp_id IN (SELECT id FROM samples s WHERE s.saty_id=?{1})", fetchSize = FETCH_SIZE)
@@ -119,8 +118,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             long lastSeenDatasetId);
 
     /**
-     * Returns datasets from store with given id that have status equal 'AVAILABLE' and were
-     * modified before given date.
+     * Returns datasets from store with given id that have status equal 'AVAILABLE' and were modified before given date.
      */
     @Select(sql = SELECT_ALL_EXTERNAL_DATAS
             + "    WHERE data.dast_id = ?{1} AND external_data.status = 'AVAILABLE' "
@@ -129,8 +127,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             Date lastModificationDate, boolean presentInArchive);
 
     /**
-     * Like {@link #getAvailableExtDatasRegisteredBefore(long, Date, boolean)} with additional
-     * condition for data set type id.
+     * Like {@link #getAvailableExtDatasRegisteredBefore(long, Date, boolean)} with additional condition for data set type id.
      */
     @Select(sql = SELECT_ALL_EXTERNAL_DATAS
             + "    WHERE data.dast_id = ?{1} AND external_data.status = 'AVAILABLE' "
@@ -150,15 +147,15 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
      * Returns ids of datasets directly connected to samples with given ids.
      */
     @Select(sql = "select id from data where data.samp_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<Long> getDatasetIdsForSamples(LongSet sampleIds);
 
     @Select(sql = "select * from data_set_relationships where data_id_child = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRelationRecord> listParentDataSetIds(LongSet ids);
 
     @Select(sql = "select * from data_set_relationships where data_id_parent = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRelationRecord> listChildrenDataSetIds(LongSet ids);
 
     /**
@@ -166,7 +163,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
      */
     @Select(sql = SELECT_ALL
             + "    WHERE data.id IN (SELECT data_id_child FROM data_set_relationships r WHERE r.data_id_parent = any(?{1}))", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRecord> getChildDatasetsForParents(LongSet parentDatasetIds);
 
     /**
@@ -219,11 +216,11 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
      * Returns the datasets for the given <var>entityIds</var>.
      */
     @Select(sql = SELECT_ALL + " where data.id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRecord> getDatasets(LongSet entityIds);
 
     @Select(sql = SELECT_ALL + " where data.code = any(?{1})", parameterBindings =
-        { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
+    { StringArrayMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<DatasetRecord> getDatasets(String[] datasetCodes);
 
     @Select(sql = SELECT_ALL_EXTERNAL_DATAS
@@ -246,6 +243,11 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + " order by registration_timestamp", fetchSize = FETCH_SIZE)
     public List<DatasetRecord> getDatasetsByDataStoreId(long dataStoreId, Date at);
 
+    @Select(sql = SELECT_ALL_EXTERNAL_DATAS
+            + " where data.dast_id = ?{1} and is_placeholder = false and size is null"
+            + " order by registration_timestamp", fetchSize = FETCH_SIZE)
+    public List<DatasetRecord> getDatasetsByDataStoreIdWithUnknownSize(long dataStoreID);
+
     // NOTE: we list ALL data sets (even those in trash) using data_all table here
     @Select(sql = "SELECT code, share_id FROM data_all LEFT OUTER JOIN external_data "
             + "ON data_all.id = external_data.data_id WHERE data_all.dast_id = ?{1}", fetchSize = FETCH_SIZE)
@@ -256,11 +258,11 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
      * Returns the children dataset ids of the specified datasets.
      */
     @Select(sql = "select data_id_child from data_set_relationships where data_id_parent = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<Long> getDatasetChildrenIds(LongSet sampleId);
 
     @Select(sql = "select id from data where ctnr_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<Long> getContainedDataSetIds(LongSet containerIDs);
 
     @Select(sql = "select code from data where ctnr_id = (select id from data where code = ?{1})", fetchSize = FETCH_SIZE)
@@ -280,13 +282,12 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + "      JOIN data_set_type_property_types etpt ON pr.dstpt_id=etpt.id"
             + "      LEFT OUTER JOIN scripts sc ON etpt.script_id = sc.id"
             + "     WHERE pr.value is not null AND pr.ds_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<GenericEntityPropertyRecord> getEntityPropertyGenericValues(
             LongSet entityIds);
 
     /**
-     * Returns property values for specified type code of all datasets specified by
-     * <var>entityIds</var>.
+     * Returns property values for specified type code of all datasets specified by <var>entityIds</var>.
      * 
      * @param entityIds The set of sample ids to get the property values for.
      * @param propertyTypeCode type code f properties we want to fetch
@@ -296,13 +297,12 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + "      JOIN data_set_type_property_types etpt ON pr.dstpt_id=etpt.id"
             + "      JOIN property_types pt ON etpt.prty_id=pt.id"
             + "     WHERE pr.value is not null AND pr.ds_id = any(?{1}) AND pt.code = ?{2}", parameterBindings =
-        { LongSetMapper.class, TypeMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class, TypeMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<GenericEntityPropertyRecord> getEntityPropertyGenericValues(
             LongSet entityIds, String propertyTypeCode);
 
     /**
-     * Returns all controlled vocabulary property values of all datasets specified by
-     * <var>entityIds</var>.
+     * Returns all controlled vocabulary property values of all datasets specified by <var>entityIds</var>.
      * 
      * @param entityIds The set of sample ids to get the property values for.
      */
@@ -311,7 +311,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + "      JOIN data_set_type_property_types etpt ON pr.dstpt_id=etpt.id"
             + "      JOIN controlled_vocabulary_terms cvte ON pr.cvte_id=cvte.id"
             + "     WHERE pr.cvte_id is not null AND pr.ds_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<VocabularyTermRecord> getEntityPropertyVocabularyTermValues(
             LongSet entityIds);
 
@@ -325,7 +325,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + "      JOIN data_set_type_property_types etpt ON pr.dstpt_id=etpt.id"
             + "      JOIN materials m ON pr.mate_prop_id=m.id "
             + "     WHERE pr.mate_prop_id is not null AND pr.ds_id = any(?{1})", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public DataIterator<MaterialEntityPropertyRecord> getEntityPropertyMaterialValues(
             LongSet entityIds);
 
@@ -342,7 +342,7 @@ public interface IDatasetListingQuery extends BaseQuery, IPropertyListingQuery
             + " m.private as is_private, m.creation_date as creation_date, ma.data_id as entity_id "
             + " from metaprojects m, metaproject_assignments ma, persons p "
             + " where ma.data_id = any(?{1}) and m.owner = ?{2} and m.id = ma.mepr_id and m.owner = p.id", parameterBindings =
-        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public List<MetaProjectWithEntityId> getMetaprojects(LongSet entityIds, Long userId);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java
index cce2e548b360364aeb8f44531d50ca73adedea21..beaf94c402363dc3d3efa5ef10089e489860c392 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.springframework.dao.DataAccessException;
@@ -48,8 +49,7 @@ public interface IDataDAO extends IGenericDAO<DataPE>
     public boolean hasDataSet(final SamplePE sample) throws DataAccessException;
 
     /**
-     * List the {@link DataPE} related to given <var>entities</var> of specified
-     * <var>entityKind</var>.
+     * List the {@link DataPE} related to given <var>entities</var> of specified <var>entityKind</var>.
      * 
      * @returns list of {@link DataPE}s that are related to given {@link IEntityInformationHolder}.
      */
@@ -64,8 +64,7 @@ public interface IDataDAO extends IGenericDAO<DataPE>
     public List<DataPE> listDataSets(final SamplePE sample) throws DataAccessException;
 
     /**
-     * List the {@link DataPE} for given <var>sample</var>. The datasets are fetched without the
-     * additional relationships or properties.
+     * List the {@link DataPE} for given <var>sample</var>. The datasets are fetched without the additional relationships or properties.
      * 
      * @returns list of {@link DataPE}s that are related to given {@link SamplePE}.
      */
@@ -118,6 +117,11 @@ public interface IDataDAO extends IGenericDAO<DataPE>
     public void updateDataSetStatuses(List<String> dataSetCodes, DataSetArchivingStatus status,
             boolean newPresentInArchive);
 
+    /**
+     * Updates sizes of given data sets (map key: data set code, map value: data set size).
+     */
+    public void updateSizes(Map<String, Long> sizeMap);
+
     /**
      * Persists the specified data set.
      */
@@ -159,8 +163,7 @@ public interface IDataDAO extends IGenericDAO<DataPE>
     public List<TechId> listContainedDataSets(final Collection<TechId> containerIds);
 
     /**
-     * Returs ids of contained data sets, and of datasets contained in those datasets etc. Also
-     * includes the input ids.
+     * Returs ids of contained data sets, and of datasets contained in those datasets etc. Also includes the input ids.
      */
     public List<TechId> listContainedDataSetsRecursively(final Collection<TechId> containersIds);
 
@@ -171,17 +174,14 @@ public interface IDataDAO extends IGenericDAO<DataPE>
             throws DataAccessException;
 
     /**
-     * Confirms a storage for the specified data set. It confirms the storage even if the data set
-     * is in the trash.
+     * Confirms a storage for the specified data set. It confirms the storage even if the data set is in the trash.
      * 
-     * @return Returns true if the data sets exists and the storage confirmed value has been
-     *         changed.
+     * @return Returns true if the data sets exists and the storage confirmed value has been changed.
      */
     boolean confirmStorage(String dataSetCode);
 
     /**
-     * Checks whether a data set with the specified code exists. It takes into consideration also
-     * data sets that are in the trash.
+     * Checks whether a data set with the specified code exists. It takes into consideration also data sets that are in the trash.
      * 
      * @return Returns true if the data set exists.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
index b646075da824efb101f8c3193c64c511c916c40f..6954a7c2c1e3a5edfba60edb60b38100a68978cc 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -549,6 +550,35 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple
         }
     }
 
+    @Override
+    public void updateSizes(final Map<String, Long> sizeMap)
+    {
+        final HibernateTemplate hibernateTemplate = getHibernateTemplate();
+        hibernateTemplate.execute(new HibernateCallback()
+            {
+                @Override
+                public final Object doInHibernate(final Session session)
+                        throws HibernateException, SQLException
+                {
+                    for (Map.Entry<String, Long> sizeEntry : sizeMap.entrySet())
+                    {
+                        // data sets consisting out of empty folders have a size of 0,
+                        // but we want the size of a data set to be strictly positive
+                        long positiveSize = Math.max(1, sizeEntry.getValue());
+
+                        session.createQuery(
+                                "UPDATE " + EXTERNAL_DATA_TABLE_NAME
+                                        + " SET size = :size WHERE code = :code")
+                                .setParameter("size", positiveSize)
+                                .setParameter("code", sizeEntry.getKey())
+                                .executeUpdate();
+                    }
+                    return null;
+                }
+            });
+        hibernateTemplate.flush();
+    }
+
     @Override
     public void updateDataSetStatuses(final List<String> dataSetCodes,
             final DataSetArchivingStatus status, final boolean presentInArchive)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServiceForDataStoreServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServiceForDataStoreServer.java
index 5e4febeb2b6e6d3cb697ce2f5fc947a7a82ee274..95461422b5eaac1f10abad65cb87ee5f5af4997a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServiceForDataStoreServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IServiceForDataStoreServer.java
@@ -433,6 +433,19 @@ public interface IServiceForDataStoreServer extends IServer, ISessionProvider
     public List<SimpleDataSetInformationDTO> listOldestPhysicalDataSets(final String sessionToken,
             String dataStore, Date youngerThan, int limit) throws UserFailureException;
 
+    /**
+     * Returns informations about physical data sets with unknown size that belong to the specified data store server.
+     */
+    @Transactional(readOnly = true)
+    public List<SimpleDataSetInformationDTO> listPhysicalDataSetsWithUnknownSize(String sessionToken, String dataStoreCode);
+
+    /**
+     * Updates sizes of the specified physical data sets (map key: data set code, map value: data set size).
+     */
+    @Transactional
+    @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
+    public void updatePhysicalDataSetsSize(String sessionToken, Map<String, Long> sizeMap);
+
     /**
      * List data sets deleted after specified date.
      */