diff --git a/common/source/java/ch/systemsx/cisd/common/highwatermark/HighwaterMarkWatcher.java b/common/source/java/ch/systemsx/cisd/common/highwatermark/HighwaterMarkWatcher.java
index 51817bb31a5b87e89a6b71cb15709b35a5272eef..5e745acd21296d661de0d3ea1501684e42c49994 100644
--- a/common/source/java/ch/systemsx/cisd/common/highwatermark/HighwaterMarkWatcher.java
+++ b/common/source/java/ch/systemsx/cisd/common/highwatermark/HighwaterMarkWatcher.java
@@ -94,7 +94,7 @@ public final class HighwaterMarkWatcher implements Runnable
 
     public final static String displayKilobyteValue(final long value)
     {
-        return FileUtils.byteCountToDisplaySize(value * FileUtils.ONE_KB);
+        return FileUtilities.byteCountToDisplaySize(value * FileUtils.ONE_KB);
     }
 
     public final static boolean isBelow(final HighwaterMarkState highwaterMarkState)
@@ -199,9 +199,11 @@ public final class HighwaterMarkWatcher implements Runnable
             }
             if (operationLog.isDebugEnabled())
             {
-                operationLog.debug(String.format("Amount of available space on '%s' is: %s.",
+                operationLog.debug(String.format(
+                        "Amount of available space on '%s' is %s (high water mark: %s).",
                         state.fileWithHighwaterMark.getCanonicalPath(),
-                        displayKilobyteValue(state.freeSpace)));
+                        displayKilobyteValue(state.freeSpace),
+                        displayKilobyteValue(highwaterMarkInKb)));
             }
         } catch (final IOException ex)
         {
@@ -312,7 +314,8 @@ public final class HighwaterMarkWatcher implements Runnable
 
         static final String WARNING_LOG_FORMAT =
                 "The amount of available space (%s) on '%s' "
-                        + "is lower than the specified high water mark (%s).";
+                        + "is lower than the specified high water mark (%s). "
+                        + "Missing space is %s.";
 
         private static final Logger notificationLog =
                 LogFactory.getLogger(LogCategory.NOTIFY, NotificationLogChangeListener.class);
@@ -333,8 +336,10 @@ public final class HighwaterMarkWatcher implements Runnable
             final String freeSpaceDisplayed = displayKilobyteValue(event.getFreeSpace());
             if (event.isBelow())
             {
+                final String missingSpace =
+                        displayKilobyteValue(event.getHighwaterMark() - event.getFreeSpace());
                 notificationLog.warn(String.format(WARNING_LOG_FORMAT, freeSpaceDisplayed, path,
-                        highwaterMarkDisplayed));
+                        highwaterMarkDisplayed, missingSpace));
             } else
             {
                 notificationLog.info(String.format(INFO_LOG_FORMAT, freeSpaceDisplayed, path,
diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java b/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java
index f7c2c5f64eb1833e9eb6cde0b5b081bd2c9f8123..4dd5603e96823b37d4ccdca748b54a5b70c9effb 100644
--- a/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java
+++ b/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java
@@ -31,6 +31,8 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -39,6 +41,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.CharUtils;
@@ -92,8 +95,8 @@ public final class FileUtilities
      *            <code>sourceFile</code> will be transfered to <code>destinationFile</code>.
      * @throws EnvironmentFailureException if a {@link IOException} occured.
      */
-    public static void copyFileTo(File sourceFile, File destinationFile,
-            boolean preservesLastModifiedDate) throws CheckedExceptionTunnel
+    public static void copyFileTo(final File sourceFile, final File destinationFile,
+            final boolean preservesLastModifiedDate) throws CheckedExceptionTunnel
     {
         FileInputStream inputStream = null;
         FileOutputStream outputStream = null;
@@ -102,7 +105,7 @@ public final class FileUtilities
             inputStream = new FileInputStream(sourceFile);
             outputStream = new FileOutputStream(destinationFile);
             IOUtils.copy(inputStream, outputStream);
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new EnvironmentFailureException("Couldn't copy file '" + sourceFile + "' to '"
                     + destinationFile + "'.", ex);
@@ -114,7 +117,7 @@ public final class FileUtilities
         // In Windows last modified date can only be changed of the output stream is closed
         if (preservesLastModifiedDate)
         {
-            boolean successful = destinationFile.setLastModified(sourceFile.lastModified());
+            final boolean successful = destinationFile.setLastModified(sourceFile.lastModified());
             if (successful == false)
             {
                 throw new EnvironmentFailureException("Couldn't copy last modified date of file '"
@@ -133,7 +136,7 @@ public final class FileUtilities
      * @throws CheckedExceptionTunnel for wrapping an {@link IOException}, e.g. if the file does
      *             not exist.
      */
-    public static String loadToString(File file) throws CheckedExceptionTunnel
+    public static String loadToString(final File file) throws CheckedExceptionTunnel
     {
         assert file != null;
 
@@ -142,7 +145,7 @@ public final class FileUtilities
         {
             fileReader = new FileReader(file);
             return readString(new BufferedReader(fileReader));
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -166,7 +169,7 @@ public final class FileUtilities
         {
             fileWriter = new FileWriter(file);
             fileWriter.write(str);
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -211,7 +214,7 @@ public final class FileUtilities
         {
             fileReader = new FileReader(file);
             return readStringList(new BufferedReader(fileReader), lineFilterOrNull);
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -245,7 +248,7 @@ public final class FileUtilities
         {
             reader = tryGetBufferedReader(clazz, resource);
             return reader == null ? null : readString(reader);
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -300,7 +303,7 @@ public final class FileUtilities
         {
             reader = tryGetBufferedReader(clazz, resource);
             return reader == null ? null : readStringList(reader, lineFilterOrNull);
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -320,7 +323,7 @@ public final class FileUtilities
         try
         {
             return new BufferedReader(new FileReader(new File(url.toURI())));
-        } catch (URISyntaxException ex)
+        } catch (final URISyntaxException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         }
@@ -370,7 +373,7 @@ public final class FileUtilities
      * @return <code>null</code> if the <var>directory</var> is fully accessible and an error
      *         message describing the problem with the <var>directory</var> otherwise.
      */
-    public static String checkPathFullyAccessible(File path, String kindOfPath)
+    public static String checkPathFullyAccessible(final File path, final String kindOfPath)
     {
         assert path != null;
         assert kindOfPath != null;
@@ -385,7 +388,8 @@ public final class FileUtilities
      * @return <code>null</code> if the <var>directory</var> is fully accessible and an error
      *         message describing the problem with the <var>directory</var> otherwise.
      */
-    public static String checkDirectoryFullyAccessible(File directory, String kindOfDirectory)
+    public static String checkDirectoryFullyAccessible(final File directory,
+            final String kindOfDirectory)
     {
         assert directory != null;
         assert kindOfDirectory != null;
@@ -399,8 +403,8 @@ public final class FileUtilities
         return msg;
     }
 
-    private static String checkPathFullyAccessible(File path, String kindOfPath,
-            String directoryOrFile)
+    private static String checkPathFullyAccessible(final File path, final String kindOfPath,
+            final String directoryOrFile)
     {
         assert path != null;
         assert kindOfPath != null;
@@ -437,7 +441,7 @@ public final class FileUtilities
      * @return <code>true</code> if the path has been delete successfully, <code>false</code>
      *         otherwise.
      */
-    public static boolean deleteRecursively(File path)
+    public static boolean deleteRecursively(final File path)
     {
         assert path != null;
 
@@ -454,13 +458,13 @@ public final class FileUtilities
      * @return <code>true</code> if the path has been delete successfully, <code>false</code>
      *         otherwise.
      */
-    public static boolean deleteRecursively(File path, ISimpleLogger loggerOrNull)
+    public static boolean deleteRecursively(final File path, final ISimpleLogger loggerOrNull)
     {
         assert path != null;
 
         if (path.isDirectory())
         {
-            for (File file : path.listFiles())
+            for (final File file : path.listFiles())
             {
                 if (file.isDirectory())
                 {
@@ -496,7 +500,8 @@ public final class FileUtilities
      *            <code>null</code> if nothing should be logged.
      * @return <code>true</code> if the <var>path</var> itself has been deleted.
      */
-    public static boolean deleteRecursively(File path, FileFilter filter, ISimpleLogger logger)
+    public static boolean deleteRecursively(final File path, final FileFilter filter,
+            final ISimpleLogger logger)
     {
         assert path != null;
         assert filter != null;
@@ -508,7 +513,7 @@ public final class FileUtilities
         {
             if (path.isDirectory())
             {
-                for (File file : path.listFiles())
+                for (final File file : path.listFiles())
                 {
                     deleteRecursively(file, filter, logger);
                 }
@@ -529,8 +534,8 @@ public final class FileUtilities
 
         private boolean terminated;
 
-        LastChangedWorker(File root, boolean subDirectoriesOnly, long reference,
-                boolean referenceIsRelative)
+        LastChangedWorker(final File root, final boolean subDirectoriesOnly, final long reference,
+                final boolean referenceIsRelative)
         {
             assert root != null;
 
@@ -546,7 +551,7 @@ public final class FileUtilities
             }
         }
 
-        private void updateLastChanged(File path)
+        private void updateLastChanged(final File path)
         {
             assert path != null;
 
@@ -563,7 +568,7 @@ public final class FileUtilities
             }
         }
 
-        private boolean isYoungEnough(long currentLastChanged)
+        private boolean isYoungEnough(final long currentLastChanged)
         {
             if (referenceIsRelative)
             {
@@ -574,7 +579,7 @@ public final class FileUtilities
             }
         }
 
-        private void traverse(File path)
+        private void traverse(final File path)
         {
             assert path != null;
 
@@ -582,7 +587,7 @@ public final class FileUtilities
             {
                 return;
             }
-            for (File entry : getEntries(path))
+            for (final File entry : getEntries(path))
             {
                 updateLastChanged(entry);
                 if (terminated)
@@ -598,7 +603,7 @@ public final class FileUtilities
             }
         }
 
-        private File[] getEntries(File directory)
+        private File[] getEntries(final File directory)
         {
             assert directory != null;
 
@@ -606,7 +611,7 @@ public final class FileUtilities
             {
                 return directory.listFiles(new FileFilter()
                     {
-                        public boolean accept(File pathname)
+                        public boolean accept(final File pathname)
                         {
                             return pathname.isDirectory();
                         }
@@ -646,7 +651,8 @@ public final class FileUtilities
      * @throws CheckedExceptionTunnel of a {@link InterruptedException} if the thread that the
      *             method runs in gets interrupted.
      */
-    public static long lastChanged(File path, boolean subDirectoriesOnly, long stopWhenFindYounger)
+    public static long lastChanged(final File path, final boolean subDirectoriesOnly,
+            final long stopWhenFindYounger)
     {
         return (new LastChangedWorker(path, subDirectoriesOnly, stopWhenFindYounger, false))
                 .getLastChanged();
@@ -673,8 +679,8 @@ public final class FileUtilities
      * @throws CheckedExceptionTunnel of a {@link InterruptedException} if the thread that the
      *             method runs in gets interrupted.
      */
-    public static long lastChangedRelative(File path, boolean subDirectoriesOnly,
-            long stopWhenFindYoungerRelative)
+    public static long lastChangedRelative(final File path, final boolean subDirectoriesOnly,
+            final long stopWhenFindYoungerRelative)
     {
         return (new LastChangedWorker(path, subDirectoriesOnly, stopWhenFindYoungerRelative, true))
                 .getLastChanged();
@@ -688,7 +694,7 @@ public final class FileUtilities
      * @throws CheckedExceptionTunnel of a {@link InterruptedException} if the thread that the
      *             method runs in gets interrupted.
      */
-    public static long lastChanged(File path)
+    public static long lastChanged(final File path)
     {
         return lastChanged(path, false, 0L);
     }
@@ -704,10 +710,10 @@ public final class FileUtilities
      * @param file can not be <code>null</code>.
      * @param prefix prefix that should be removed from the file name. Can be <code>null</code>.
      */
-    public final static File removePrefixFromFileName(File file, String prefix)
+    public final static File removePrefixFromFileName(final File file, final String prefix)
     {
         assert file != null;
-        String name = file.getName();
+        final String name = file.getName();
         if (StringUtils.isEmpty(prefix))
         {
             return file;
@@ -722,7 +728,7 @@ public final class FileUtilities
     /** A <i>Java</i> pattern matching one or more digits. */
     private final static Pattern ONE_OR_MORE_DIGITS = Pattern.compile(".*(\\d+)$");
 
-    public final static File createNextNumberedFile(File path, Pattern regex)
+    public final static File createNextNumberedFile(final File path, final Pattern regex)
     {
         return createNextNumberedFile(path, regex, null);
     }
@@ -739,8 +745,8 @@ public final class FileUtilities
      *            will be used. The given <var>regex</var> must contain <code>(\\d+)</code> or
      *            <code>([0-9]+)</code>.
      */
-    public final static File createNextNumberedFile(File path, Pattern regexOrNull,
-            String defaultFileNameOrNull)
+    public final static File createNextNumberedFile(final File path, final Pattern regexOrNull,
+            final String defaultFileNameOrNull)
     {
         assert path != null;
         if (path.exists() == false)
@@ -758,7 +764,7 @@ public final class FileUtilities
             pattern = regexOrNull;
         }
 
-        String pathName = path.getName();
+        final String pathName = path.getName();
         final Matcher matcher = pattern.matcher(pathName);
         boolean found = matcher.find();
         if (found == false)
@@ -774,18 +780,18 @@ public final class FileUtilities
             return createNextNumberedFile(new File(path.getParent(), fileName), pattern,
                     defaultFileNameOrNull);
         }
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder builder = new StringBuilder();
         int nextStart = 0;
         while (found)
         {
-            String group = matcher.group(1);
+            final String group = matcher.group(1);
             final int newNumber = Integer.parseInt(group) + 1;
             builder.append(pathName.substring(nextStart, matcher.start(1))).append(newNumber);
             nextStart = matcher.end(1);
             found = matcher.find();
         }
         builder.append(pathName.substring(nextStart));
-        File newFile = new File(path.getParent(), builder.toString());
+        final File newFile = new File(path.getParent(), builder.toString());
         if (newFile.exists())
         {
             return createNextNumberedFile(newFile, pattern, defaultFileNameOrNull);
@@ -825,7 +831,7 @@ public final class FileUtilities
      * @return all files in <var>directory</var> or <code>null</code>, if <var>directory</var>
      *         does not exist or is not a directory.
      */
-    public static File[] tryListFiles(File directory, ISimpleLogger loggerOrNull)
+    public static File[] tryListFiles(final File directory, final ISimpleLogger loggerOrNull)
     {
         return tryListFiles(directory, ACCEPT_ALL_FILTER, loggerOrNull);
     }
@@ -839,14 +845,15 @@ public final class FileUtilities
      * @return all files in <var>directory</var> that match the filter, or <code>null</code>, if
      *         <var>directory</var> does not exist or is not a directory.
      */
-    public static File[] tryListFiles(File directory, FileFilter filter, ISimpleLogger loggerOrNull)
+    public static File[] tryListFiles(final File directory, final FileFilter filter,
+            final ISimpleLogger loggerOrNull)
     {
         File[] paths = null;
         RuntimeException ex = null;
         try
         {
             paths = directory.listFiles(filter);
-        } catch (RuntimeException e)
+        } catch (final RuntimeException e)
         {
             ex = e;
         }
@@ -857,13 +864,13 @@ public final class FileUtilities
         return paths;
     }
 
-    public static void sortByLastModified(File[] files)
+    public static void sortByLastModified(final File[] files)
     {
         Arrays.sort(files, FileComparator.BY_LAST_MODIFIED);
     }
 
-    private static void logFailureInDirectoryListing(RuntimeException exOrNull, File directory,
-            ISimpleLogger logger)
+    private static void logFailureInDirectoryListing(final RuntimeException exOrNull,
+            final File directory, final ISimpleLogger logger)
     {
         if (exOrNull == null)
         {
@@ -883,7 +890,7 @@ public final class FileUtilities
             }
         } else
         {
-            StringWriter exStackWriter = new StringWriter();
+            final StringWriter exStackWriter = new StringWriter();
             exOrNull.printStackTrace(new PrintWriter(exStackWriter));
             logger.log(LogLevel.ERROR, String.format(
                     "Failed to get listing of directory '%s'. Exception: %s", directory,
@@ -901,7 +908,8 @@ public final class FileUtilities
      * @throws IllegalArgumentException If the resource cannot be found in the class path.
      * @throws CheckedExceptionTunnel If an {@link IOException} occurs.
      */
-    public final static String copyResourceToTempFile(String resource, String prefix, String postfix)
+    public final static String copyResourceToTempFile(final String resource, final String prefix,
+            final String postfix)
     {
         final InputStream resourceStream = FileUtilities.class.getResourceAsStream(resource);
         if (resourceStream == null)
@@ -912,7 +920,7 @@ public final class FileUtilities
         {
             final File tempFile = File.createTempFile(prefix, postfix);
             tempFile.deleteOnExit();
-            OutputStream fileStream = new FileOutputStream(tempFile);
+            final OutputStream fileStream = new FileOutputStream(tempFile);
             try
             {
                 IOUtils.copy(resourceStream, fileStream);
@@ -921,7 +929,7 @@ public final class FileUtilities
                 IOUtils.closeQuietly(fileStream);
             }
             return tempFile.getAbsolutePath();
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             throw new CheckedExceptionTunnel(ex);
         } finally
@@ -939,13 +947,13 @@ public final class FileUtilities
      * @return The name of the temporary file, or <code>null</code>, if the resource could not be
      *         copied.
      */
-    public final static String tryCopyResourceToTempFile(String resource, String prefix,
-            String postfix)
+    public final static String tryCopyResourceToTempFile(final String resource,
+            final String prefix, final String postfix)
     {
         try
         {
             return copyResourceToTempFile(resource, prefix, postfix);
-        } catch (Exception ex)
+        } catch (final Exception ex)
         {
             return null;
         }
@@ -984,7 +992,7 @@ public final class FileUtilities
         try
         {
             return file.getCanonicalFile();
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             return new File(FilenameUtils.normalize(file.getAbsolutePath()));
         }
@@ -1002,7 +1010,7 @@ public final class FileUtilities
         try
         {
             return file.getCanonicalPath();
-        } catch (IOException ex)
+        } catch (final IOException ex)
         {
             return file.getAbsolutePath();
         }
@@ -1048,7 +1056,7 @@ public final class FileUtilities
                 t.interrupt();
             }
             return exists;
-        } catch (InterruptedException ex)
+        } catch (final InterruptedException ex)
         {
             // This is not expected to happen.
             return false;
@@ -1086,4 +1094,38 @@ public final class FileUtilities
         } while (result.exists());
         return result;
     }
+
+    private static final NumberFormat SIZE_FORMAT = new DecimalFormat("0.00");
+
+    /**
+     * Returns a human-readable version of the file size, where the input represents a specific
+     * number of bytes.
+     * <p>
+     * By comparison with {@link FileUtils#byteCountToDisplaySize(long)}, the output of this
+     * version is more exact.
+     * </p>
+     * 
+     * @param size the number of bytes
+     * @return a human-readable display value (includes units)
+     * @see FileUtils#byteCountToDisplaySize(long)
+     */
+    public final static String byteCountToDisplaySize(final long size)
+    {
+        final String displaySize;
+        if (size / FileUtils.ONE_GB > 0)
+        {
+            displaySize = SIZE_FORMAT.format(size / (float) FileUtils.ONE_GB) + " GB";
+        } else if (size / FileUtils.ONE_MB > 0)
+        {
+            displaySize = SIZE_FORMAT.format(size / (float) FileUtils.ONE_MB) + " MB";
+        } else if (size / FileUtils.ONE_KB > 0)
+        {
+            displaySize = SIZE_FORMAT.format(size / (float) FileUtils.ONE_KB) + " KB";
+        } else
+        {
+            displaySize = SIZE_FORMAT.format(size) + " bytes";
+        }
+        return displaySize;
+    }
+
 }
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesTest.java
index 1003a9b47b771a643c4e81d1441a4f5c7959db0b..6ba6516d8c81d76025ec8279f48cb28301da3cd6 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesTest.java
@@ -524,4 +524,14 @@ public final class FileUtilitiesTest extends AbstractFileSystemTestCase
         assertTrue(name.endsWith(fileSuffix));
         assertEquals(filePrefix.length() + fileSuffix.length() + 4, name.length());
     }
+
+    @Test
+    public final void testByteCountToDisplaySize()
+    {
+        assertEquals("0.00 bytes", FileUtilities.byteCountToDisplaySize(0));
+        assertEquals("1.00 bytes", FileUtilities.byteCountToDisplaySize(1));
+        assertEquals("1.00 KB", FileUtilities.byteCountToDisplaySize(1024));
+        assertEquals("1.01 KB", FileUtilities.byteCountToDisplaySize(1034));
+        assertEquals("1.00 MB", FileUtilities.byteCountToDisplaySize(1024 * 1024));
+    }
 }