diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SegmentedStoreBalancingTask.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SegmentedStoreBalancingTask.java
index 4a1b8d8bf4fa28e8e4adc5c4c6cb98e294e85359..9353a079e24f8e3f27ff9d68dc1a48fd23ea01ee 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SegmentedStoreBalancingTask.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SegmentedStoreBalancingTask.java
@@ -122,10 +122,12 @@ public class SegmentedStoreBalancingTask implements IMaintenanceTask
 
     public void execute()
     {
+        operationLog.info("Starting segmented store balancing.");
         List<Share> shares =
                 SegmentedStoreUtils.getDataSetsPerShare(storeRoot, dataStoreCode,
                         freeSpaceProvider, service, operationLogger);
         balancer.balanceStore(shares, service, operationLogger);
+        operationLog.info("Segmented store balancing finished.");
     }
 
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SimpleBalancer.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SimpleBalancer.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cae99a78d5a311904ff4127939f041bcac30665
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/SimpleBalancer.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2011 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 static ch.systemsx.cisd.common.logging.LogLevel.INFO;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.time.StopWatch;
+
+import ch.systemsx.cisd.common.logging.ISimpleLogger;
+import ch.systemsx.cisd.common.utilities.PropertyUtils;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SegmentedStoreUtils;
+import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SimpleBalancer implements ISegmentedStoreBalancer
+{
+    private static final class ShareState
+    {
+        private final Share share;
+        private long freeSpace;
+
+        ShareState(Share share)
+        {
+            this.share = share;
+            recalculateFreeSpace();
+        }
+        
+        private void recalculateFreeSpace()
+        {
+            freeSpace = share.calculateFreeSpace();
+        }
+
+        long getFreeSpace()
+        {
+            return freeSpace;
+        }
+
+        Share getShare()
+        {
+            return share;
+        }
+
+        void removeDataSet(int dataSetIndex)
+        {
+            share.getDataSetsOrderedBySize().remove(dataSetIndex);
+            recalculateFreeSpace();
+        }
+
+        void addDataSet(SimpleDataSetInformationDTO dataSet)
+        {
+            List<SimpleDataSetInformationDTO> dataSets = share.getDataSetsOrderedBySize();
+            int index = Collections.binarySearch(dataSets, dataSet, Share.DATA_SET_SIZE_COMPARATOR);
+            if (index < 0)
+            {
+                index = -index - 1;
+            }
+            dataSets.add(index, dataSet);
+            recalculateFreeSpace();
+        }
+    }
+    
+    private final long minimumFreeSpace;
+
+    public SimpleBalancer(Properties properties)
+    {
+        minimumFreeSpace =
+                FileUtils.ONE_MB
+                        * PropertyUtils.getLong(properties, "minimum-free-space-in-MB", 1024);
+    }
+    
+    public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service,
+            ISimpleLogger logger)
+    {
+        List<ShareState> shareStates = getSortedShares(shares);
+        ShareState shareWithMostFree = shareStates.get(shareStates.size() - 1);
+        List<ShareState> fullShares = getFullShares(shareStates);
+        for (ShareState fullShare : fullShares)
+        {
+            List<SimpleDataSetInformationDTO> dataSets =
+                    fullShare.getShare().getDataSetsOrderedBySize();
+            long initalFreeSpaceAboveMinimum = fullShare.getFreeSpace() - minimumFreeSpace;
+            int numberOfDataSetsToMove =
+                    getNumberOfDataSetsToMove(dataSets, initalFreeSpaceAboveMinimum);
+            if (numberOfDataSetsToMove < 0)
+            {
+                throw new IllegalStateException("Share " + fullShare.getShare().getShareId()
+                        + " has not enough free space even if it is empty.");
+            }
+            for (int i = 0; i < numberOfDataSetsToMove; i++)
+            {
+                long dataSetSize = dataSets.get(i).getDataSetSize();
+                if (shareWithMostFree.getFreeSpace() - dataSetSize > minimumFreeSpace)
+                {
+                    copy(fullShare, 0, shareWithMostFree, service, logger);
+                }
+            }
+        }
+    }
+
+    private int getNumberOfDataSetsToMove(List<SimpleDataSetInformationDTO> dataSets,
+            long initalFreeSpaceAboveMinimum)
+    {
+        long freeSpaceAboveMinimum = initalFreeSpaceAboveMinimum;
+        for (int i = 0; i < dataSets.size(); i++)
+        {
+            if (freeSpaceAboveMinimum > 0)
+            {
+                return i;
+            }
+            freeSpaceAboveMinimum += dataSets.get(i).getDataSetSize();
+        }
+        return -1;
+    }
+
+    private void copy(ShareState from, int dataSetIndex, ShareState to,
+            IEncapsulatedOpenBISService service, ISimpleLogger logger)
+    {
+        Share fromShare = from.getShare();
+        Share toShare = to.getShare();
+        SimpleDataSetInformationDTO dataSet =
+                fromShare.getDataSetsOrderedBySize().get(dataSetIndex);
+        File dataSetDirInStore = new File(fromShare.getShare(), dataSet.getDataSetLocation());
+        String commonMessage =
+                "data set " + dataSet.getDataSetCode() + " from share " + fromShare.getShareId()
+                        + " to share " + toShare.getShareId();
+        logger.log(INFO, "Move " + commonMessage + " ...");
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start();
+        SegmentedStoreUtils.moveDataSetToAnotherShare(dataSetDirInStore, toShare.getShare(),
+                service);
+        from.removeDataSet(dataSetIndex);
+        to.addDataSet(dataSet);
+        stopWatch.stop();
+        logger.log(INFO, "Moving " + commonMessage + " took " + stopWatch.toString());
+    }
+
+    private List<ShareState> getFullShares(List<ShareState> shareStates)
+    {
+        List<ShareState> fullShares = new ArrayList<ShareState>();
+        for (ShareState shareState : shareStates)
+        {
+            if (shareState.getFreeSpace() < minimumFreeSpace)
+            {
+                fullShares.add(shareState);
+            }
+        }
+        return fullShares;
+    }
+
+    private List<ShareState> getSortedShares(List<Share> shares)
+    {
+        List<ShareState> shareStates = new ArrayList<ShareState>();
+        for (Share share : shares)
+        {
+            shareStates.add(new ShareState(share));
+        }
+        Collections.sort(shareStates, new Comparator<ShareState>()
+            {
+                public int compare(ShareState o1, ShareState o2)
+                {
+                    long s1 = o1.getFreeSpace();
+                    long s2 = o2.getFreeSpace();
+                    return s1 < s2 ? -1 : (s1 > s2 ? 1 : 0);
+                }
+            });
+        return shareStates;
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/Share.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/Share.java
index 84c3783e22640947018f5fb0b376a4655909bfc6..becaf8bffab3c4b33e2d8a6ba9976ca72bdf1b33 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/Share.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/Share.java
@@ -36,6 +36,18 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
  */
 public final class Share
 {
+    public static final Comparator<SimpleDataSetInformationDTO> DATA_SET_SIZE_COMPARATOR =
+            new Comparator<SimpleDataSetInformationDTO>()
+                {
+                    public int compare(SimpleDataSetInformationDTO o1,
+                            SimpleDataSetInformationDTO o2)
+                    {
+                        long size1 = o1.getDataSetSize();
+                        long size2 = o2.getDataSetSize();
+                        return size1 < size2 ? 1 : (size1 > size2 ? -1 : 0);
+                    }
+                };
+
     private final File share;
 
     private final IFreeSpaceProvider freeSpaceProvider;
@@ -95,16 +107,7 @@ public final class Share
      */
     public List<SimpleDataSetInformationDTO> getDataSetsOrderedBySize()
     {
-        Collections.sort(dataSets, new Comparator<SimpleDataSetInformationDTO>()
-            {
-                public int compare(SimpleDataSetInformationDTO o1,
-                        SimpleDataSetInformationDTO o2)
-                {
-                    long size1 = o1.getDataSetSize();
-                    long size2 = o2.getDataSetSize();
-                    return size1 < size2 ? 1 : (size1 > size2 ? -1 : 0);
-                }
-            });
+        Collections.sort(dataSets, DATA_SET_SIZE_COMPARATOR);
         return dataSets;
     }