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 fd082f51c0ba1ec63c5eb8949a402729c41e8c65..7eceddc3f671314062eeaafe9c06674676b64e8a 100644
--- a/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java
+++ b/common/source/java/ch/systemsx/cisd/common/utilities/FileUtilities.java
@@ -441,18 +441,21 @@ public final class FileUtilities
     {
         private boolean subDirectoriesOnly;
 
-        private final long stopWhenFindYounger;
+        private final long reference;
+
+        private final boolean referenceIsRelative;
 
         private long lastChanged;
 
         private boolean terminated;
 
-        LastChangedWorker(File root, boolean subDirectoriesOnly, long stopWhenFindYounger)
+        LastChangedWorker(File root, boolean subDirectoriesOnly, long reference, boolean referenceIsRelative)
         {
             assert root != null;
 
             this.subDirectoriesOnly = subDirectoriesOnly;
-            this.stopWhenFindYounger = stopWhenFindYounger;
+            this.reference = reference;
+            this.referenceIsRelative = referenceIsRelative;
             this.terminated = false;
             this.lastChanged = 0;
             updateLastChanged(root);
@@ -473,12 +476,23 @@ public final class FileUtilities
             }
             final long lastModified = path.lastModified();
             lastChanged = Math.max(lastModified, lastChanged);
-            if (stopWhenFindYounger > 0 && lastChanged >= stopWhenFindYounger)
+            if (isYoungEnough(lastChanged))
             {
                 terminated = true;
             }
         }
 
+        private boolean isYoungEnough(long currentLastChanged)
+        {
+            if (referenceIsRelative)
+            {
+                return reference > 0 && currentLastChanged >= System.currentTimeMillis() - reference;
+            } else
+            {
+                return reference > 0 && currentLastChanged >= reference;
+            }
+        }
+
         private void traverse(File path)
         {
             assert path != null;
@@ -551,7 +565,32 @@ public final class FileUtilities
      */
     public static long lastChanged(File path, boolean subDirectoriesOnly, long stopWhenFindYounger)
     {
-        return (new LastChangedWorker(path, subDirectoriesOnly, stopWhenFindYounger)).getLastChanged();
+        return (new LastChangedWorker(path, subDirectoriesOnly, stopWhenFindYounger, false)).getLastChanged();
+    }
+
+    /**
+     * Determines the time (in milliseconds since start of the epoch) when any item below <var>path</var> has last been
+     * changed in the file system.
+     * 
+     * @param path The path (file or directory) to check for last change.
+     * @param subDirectoriesOnly If <code>true</code>, only subdirectories of <var>path</var> are checked, if
+     *            <var>path</var> is a directory. If <var>path</var> is a file, this parameter is ignored. When
+     *            considering what this parameter is good for, note that the mtime of a directory is changed when an
+     *            entry in the directory changes.
+     * @param stopWhenFindYoungerRelative If &gt; 0, the recursive search for younger file will be stopped when a file
+     *            or directory is found that is as young as or younger than
+     *            <code>System.currentTimeMillis() - stopWhenYoungerRelative</code>. Supposed to be used when one
+     *            does not care about the absolute youngest entry, but only, if there are entries that are "young
+     *            enough".
+     * @return The time when any file in (or below) <var>path</var> has last been changed in the file system.
+     * @throws CheckedExceptionTunnel of an {@link IOException} if the <var>path</var> does not exist or is not
+     *             readable.
+     * @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)
+    {
+        return (new LastChangedWorker(path, subDirectoriesOnly, stopWhenFindYoungerRelative, true)).getLastChanged();
     }
 
     /**
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesLastChangedTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesLastChangedTest.java
index c2e48c09325e2695d16ef9daab3e53c79bf2b3e3..4d11ece165f3463a0082b0250a49980518fb4d60 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesLastChangedTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/FileUtilitiesLastChangedTest.java
@@ -127,5 +127,25 @@ public class FileUtilitiesLastChangedTest
         assertEquals(1000L, FileUtilities.lastChanged(dirA, false, 1000L));
         assertEquals(1000L, FileUtilities.lastChanged(dirA, true, 1000L));
     }
+    
+    @Test
+    public void testLastChangedRelative() throws IOException
+    {
+        final File dirA = new File(workingDirectory, "a-relative");
+        final long now = System.currentTimeMillis();
+        dirA.mkdir();
+        dirA.deleteOnExit();
+        final File fileB = new File(dirA, "b");
+        fileB.createNewFile();
+        fileB.deleteOnExit();
+        final long fakedModTime1 = now - 10000L;
+        final long fakedModTime2 = now - 30000L;
+        fileB.setLastModified(fakedModTime1);
+        dirA.setLastModified(fakedModTime2);
+        final long diff1 = Math.abs(fakedModTime2 - FileUtilities.lastChangedRelative(dirA, false, 31000L));
+        assertTrue("Difference to big: " + diff1 + " ms", diff1 < 1000L);
+        final long diff2 = Math.abs(fakedModTime1 - FileUtilities.lastChangedRelative(dirA, false, 11000L));
+        assertTrue("Difference to big: " + diff2 + " ms", diff2 < 1000L);
+    }
 
 }