diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecorator.java b/datamover/source/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecorator.java
index 624416c4969916ff8e27dd1f75537036fb00e2af..3d7eb1077fcf97ec5570b72c0857f1caa456d5e1 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecorator.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecorator.java
@@ -20,7 +20,7 @@ import java.io.File;
 import java.io.FileFilter;
 
 import ch.systemsx.cisd.common.utilities.FileUtilities;
-import ch.systemsx.cisd.datamover.DirectoryScanningTimerTask.IPathHandler;
+import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask.IPathHandler;
 
 /**
  * A class that decorates an {@link IPathHandler} with a selective cleansing task. The files that should be removed in
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTask.java b/datamover/source/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTask.java
deleted file mode 100644
index f3cb5d14b8baa40c6b450191aabc33f052ff6cbe..0000000000000000000000000000000000000000
--- a/datamover/source/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTask.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2007 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.datamover;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TimerTask;
-
-import org.apache.log4j.Logger;
-
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.common.utilities.CollectionIO;
-import ch.systemsx.cisd.common.utilities.FileUtilities;
-import ch.systemsx.cisd.common.utilities.IFromStringConverter;
-
-/**
- * A {@link TimerTask} that scans a source directory for entries that are accepted by some {@link FileFilter} and
- * handles the accepted entries by some {@link IPathHandler}. It maintains a list of faulty paths that failed to be
- * handled OK in the past. Clearing the list will make the class to retry handling the paths.
- * <p>
- * The class should be constructed in the start-up phase and as part of the system's self-test in order to reveal
- * problems with incorrect paths timely.
- * 
- * @author Bernd Rinn
- */
-public final class DirectoryScanningTimerTask extends TimerTask
-{
-
-    public static final String FAULTY_PATH_FILENAME = ".faulty_paths";
-
-    private static final Logger operationLog =
-            LogFactory.getLogger(LogCategory.OPERATION, DirectoryScanningTimerTask.class);
-
-    private static final Logger notificationLog =
-            LogFactory.getLogger(LogCategory.NOTIFY, DirectoryScanningTimerTask.class);
-
-    private static final IFromStringConverter<File> FILE_CONVERTER = new IFromStringConverter<File>()
-        {
-            public File fromString(String value)
-            {
-                return new File(value);
-            }
-        };
-
-    private final IPathHandler handler;
-
-    private final File sourceDirectory;
-
-    private boolean errorReadingDirectory;
-
-    private final FileFilter filter;
-
-    private final Set<File> faultyPaths;
-
-    private final File faultyPathsFile;
-
-    private long faultyPathsLastChanged;
-
-    /**
-     * A handler for paths. The paths are supposed to go away when they have been handled successfully.
-     */
-    public interface IPathHandler
-    {
-        /**
-         * Handles the <var>path</var>.
-         * 
-         * @return <code>true</code> if the <var>path</var> has been handled correctly and <code>false</code>
-         *         otherwise.
-         */
-        public boolean handle(File path);
-    }
-
-    /**
-     * Creates a <var>DirectoryScanningTimerTask</var>.
-     * 
-     * @param sourceDirectory The directory to scan for entries.
-     * @param filter The file filter that picks the entries to handle.
-     * @param handler The handler that is used for treating the matching paths.
-     */
-    public DirectoryScanningTimerTask(File sourceDirectory, FileFilter filter, IPathHandler handler)
-    {
-        assert sourceDirectory != null;
-        assert filter != null;
-        assert handler != null;
-        assert FileUtilities.checkDirectoryFullyAccessible(sourceDirectory, "source") == null : FileUtilities
-                .checkDirectoryFullyAccessible(sourceDirectory, "source");
-
-        this.sourceDirectory = sourceDirectory;
-        this.filter = filter;
-        this.handler = handler;
-        this.faultyPaths = new HashSet<File>();
-        this.faultyPathsFile = new File(sourceDirectory, FAULTY_PATH_FILENAME);
-        faultyPathsFile.delete();
-    }
-
-    /**
-     * Handles all entries in {@link #sourceDirectory} that are picked by the {@link #filter} by some {@link #handler}.
-     */
-    @Override
-    public void run()
-    {
-        if (operationLog.isTraceEnabled())
-        {
-            operationLog.trace("Start scanning directory.");
-        }
-        checkForFaultyPathsFileChanged();
-        final File[] paths = listFiles();
-        if (paths == null) // Means: error reading directory listing
-        {
-            return;
-        }
-        // Sort in order of "oldest first" in order to move older items before newer items. This becomes important when
-        // doing online quality control of measurements.
-        Arrays.sort(paths, new Comparator<File>()
-            {
-                public int compare(File o1, File o2)
-                {
-                    return (int) (o1.lastModified() - o2.lastModified());
-                }
-            });
-        for (File path : paths)
-        {
-            if (faultyPathsFile.equals(path)) // Never touch the faultyPathsFile.
-            {
-                continue;
-            }
-            if (path.getName().startsWith(".is_finished_")) // Ignore any .is_finished files as created in remote mode.  
-            {
-                continue;
-            }
-            handle(path);
-        }
-        if (operationLog.isTraceEnabled())
-        {
-            operationLog.trace("Finished scanning directory.");
-        }
-    }
-
-    private void checkForFaultyPathsFileChanged()
-    {
-        if (faultyPathsFile.exists())
-        {
-            if (faultyPathsFile.lastModified() > faultyPathsLastChanged) // Handles manual manipulation.
-            {
-                faultyPaths.clear();
-                CollectionIO.readCollection(faultyPathsFile, faultyPaths, FILE_CONVERTER);
-                faultyPathsLastChanged = faultyPathsFile.lastModified();
-                if (operationLog.isInfoEnabled())
-                {
-                    operationLog.info(String.format("Reread faulty paths file (%s), new set contains %d entries",
-                            faultyPathsFile.getPath(), faultyPaths.size()));
-                }
-            }
-        } else
-        // Handles manual removal.
-        {
-            faultyPaths.clear();
-        }
-    }
-
-    private File[] listFiles()
-    {
-        File[] paths = null;
-        RuntimeException ex = null;
-        try
-        {
-            paths = sourceDirectory.listFiles(filter);
-        } catch (RuntimeException e)
-        {
-            ex = e;
-        }
-        if (paths == null)
-        {
-            if (errorReadingDirectory == false)
-            {
-                logFailureInDirectoryListing(ex);
-                errorReadingDirectory = true; // Avoid mailbox flooding.
-            }
-        } else
-        {
-            errorReadingDirectory = false;
-        }
-        return paths;
-    }
-
-    private void logFailureInDirectoryListing(RuntimeException ex)
-    {
-        if (ex == null)
-        {
-            if (sourceDirectory.isFile())
-            {
-                notificationLog.error(String
-                        .format("Failed to get listing of directory '%s' (path is file instead of directory).",
-                                sourceDirectory));
-            } else
-            {
-                notificationLog.error(String.format("Failed to get listing of directory '%s' (path not found).",
-                        sourceDirectory));
-            }
-        } else
-        {
-            notificationLog.error(String.format("Failed to get listing of directory '%s'.", sourceDirectory), ex);
-        }
-    }
-
-    private void handle(File path)
-    {
-        if (faultyPaths.contains(path))
-        { // Guard: skip faulty paths.
-            return;
-        }
-
-        final boolean handledOK = handler.handle(path);
-        if (path.exists())
-        {
-            if (handledOK)
-            {
-                operationLog.warn(String.format("Handler %s reports path '%s' be handled OK, but path still exists.",
-                        handler.getClass().getSimpleName(), path));
-            }
-            faultyPaths.add(path);
-            CollectionIO.writeIterable(faultyPathsFile, faultyPaths);
-            faultyPathsLastChanged = faultyPathsFile.lastModified();
-        }
-    }
-
-}
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/IntraFSPathMover.java b/datamover/source/java/ch/systemsx/cisd/datamover/IntraFSPathMover.java
deleted file mode 100644
index c8ccdab6c79b24ee18cf4e2af71a49d9f58a9e1d..0000000000000000000000000000000000000000
--- a/datamover/source/java/ch/systemsx/cisd/datamover/IntraFSPathMover.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2007 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.datamover;
-
-import java.io.File;
-
-import org.apache.log4j.Logger;
-
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.common.utilities.FileUtilities;
-
-/**
- * A {@link DirectoryScanningTimerTask.IPathHandler} that moves paths out of the way within one file system by calling
- * {@link File#renameTo(File)}..
- * 
- * @author Bernd Rinn
- */
-public class IntraFSPathMover implements DirectoryScanningTimerTask.IPathHandler
-{
-
-    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, IntraFSPathMover.class);
-
-    private static final Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY, IntraFSPathMover.class);
-
-    private final File destinationDirectory;
-
-    /**
-     * Creates a <var>PathMover</var>.
-     * 
-     * @param destinationDirectory The directory to move paths to.
-     */
-    public IntraFSPathMover(File destinationDirectory)
-    {
-        assert destinationDirectory != null;
-        assert FileUtilities.checkDirectoryFullyAccessible(destinationDirectory, "destination") == null : FileUtilities
-                .checkDirectoryFullyAccessible(destinationDirectory, "destination");
-
-        this.destinationDirectory = destinationDirectory;
-    }
-
-    public boolean handle(File path)
-    {
-        assert path != null;
-        assert destinationDirectory != null;
-
-        if (operationLog.isInfoEnabled())
-        {
-            operationLog
-                    .info(String.format("Moving path '%s' to '%s'", path.getPath(), destinationDirectory.getPath()));
-        }
-        boolean movedOK = path.renameTo(new File(destinationDirectory, path.getName()));
-        if (movedOK == false)
-        {
-            notificationLog.error(String.format("Moving path '%s' to directory '%s' failed.", path,
-                    destinationDirectory));
-        }
-        return movedOK;
-    }
-
-}
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/Main.java b/datamover/source/java/ch/systemsx/cisd/datamover/Main.java
index 520398fa88cd78c6eedcba69a7f0e4bfb1bfb5d9..66526cefcca0d1238d97ee2ff57bdefcdd511c2d 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/Main.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/Main.java
@@ -17,41 +17,36 @@
 package ch.systemsx.cisd.datamover;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.lang.Thread.UncaughtExceptionHandler;
 import java.util.Timer;
 
 import org.apache.log4j.Logger;
 
+import ch.systemsx.cisd.common.Constants;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.exceptions.HighLevelException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.utilities.BuildAndEnvironmentInfo;
+import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask;
+import ch.systemsx.cisd.common.utilities.IntraFSPathMover;
+import ch.systemsx.cisd.common.utilities.NamePrefixFileFilter;
 import ch.systemsx.cisd.common.utilities.OSUtilities;
 import ch.systemsx.cisd.common.utilities.RegexFileFilter;
+import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask.IPathHandler;
 import ch.systemsx.cisd.common.utilities.RegexFileFilter.PathType;
-import ch.systemsx.cisd.datamover.DirectoryScanningTimerTask.IPathHandler;
 import ch.systemsx.cisd.datamover.rsync.RsyncCopier;
 import ch.systemsx.cisd.datamover.xcopy.XcopyCopier;
 
 /**
- * The main class of the raw data mover.
+ * The main class of the datamover.
  * 
  * @author Bernd Rinn
  */
 public class Main
 {
 
-    private static final FileFilter ALWAYS_TRUE_FILTER = new FileFilter()
-        {
-            public boolean accept(File pathname)
-            {
-                return true;
-            }
-        };
-
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, Main.class);
 
     private static final Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY, Main.class);
@@ -60,7 +55,7 @@ public class Main
         {
             public void uncaughtException(Thread t, Throwable e)
             {
-                notificationLog.error("An exception has occurred.", e);
+                notificationLog.error("An exception has occurred [thread: '" + t.getName() + "'].", e);
             }
         };
 
@@ -72,7 +67,7 @@ public class Main
 
     private static void printInitialLogMessage(final Parameters parameters)
     {
-        operationLog.info("Data mover is starting up.");
+        operationLog.info("datamover is starting up.");
         for (String line : BuildAndEnvironmentInfo.INSTANCE.getEnvironmentInfo())
         {
             operationLog.info(line);
@@ -90,7 +85,8 @@ public class Main
         } else if (OSUtilities.isWindows())
         {
             return new XcopyCopier(OSUtilities.findExecutable("xcopy"), requiresDeletionBeforeCreation);
-        } else {
+        } else
+        {
             throw new ConfigurationFailureException("Unable to find a copy engine.");
         }
     }
@@ -192,7 +188,8 @@ public class Main
         final IPathHandler remoteMover =
                 new RemotePathMover(remoteDataDirectory, remoteHost, monitor, operations, parameters);
         final DirectoryScanningTimerTask remoteMovingTask =
-                new DirectoryScanningTimerTask(localTemporaryDirectory, ALWAYS_TRUE_FILTER, remoteMover);
+                new DirectoryScanningTimerTask(localTemporaryDirectory,
+                        new NamePrefixFileFilter(Constants.IS_FINISHED_PREFIX, false), remoteMover);
         final RegexFileFilter cleansingFilter = new RegexFileFilter();
         if (parameters.getCleansingRegex() != null)
         {
@@ -224,7 +221,7 @@ public class Main
         final Parameters parameters = new Parameters(args);
         printInitialLogMessage(parameters);
         startupServer(parameters);
-        operationLog.info("Data mover ready and waiting for data.");
+        operationLog.info("datamover ready and waiting for data.");
     }
 
 }
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/RemotePathMover.java b/datamover/source/java/ch/systemsx/cisd/datamover/RemotePathMover.java
index 3a34def44fc9d4fa6c12f046b96e3479ce7f77b0..d08cbde57ea76b116216653a8a2c1b45d525f7f1 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/RemotePathMover.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/RemotePathMover.java
@@ -20,10 +20,13 @@ import java.io.File;
 import java.io.IOException;
 
 import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.Constants;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask;
 import ch.systemsx.cisd.common.utilities.FileUtilities;
 
 /**
@@ -191,7 +194,7 @@ public final class RemotePathMover implements DirectoryScanningTimerTask.IPathHa
 
     private boolean markAsFinishedLocal(File path)
     {
-        final File markFile = new File(destinationDirectory, ".is_finished_" + path.getName());
+        final File markFile = new File(destinationDirectory, Constants.IS_FINISHED_PREFIX + path.getName());
         try
         {
             markFile.createNewFile();
@@ -210,7 +213,7 @@ public final class RemotePathMover implements DirectoryScanningTimerTask.IPathHa
 
     private boolean markAsFinishedRemote(File path)
     {
-        final File markFile = new File(path.getParent(), ".is_finished_" + path.getName());
+        final File markFile = new File(path.getParent(), Constants.IS_FINISHED_PREFIX + path.getName());
         try
         {
             markFile.createNewFile();
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecoratorTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecoratorTest.java
index 39ad89ffdb91a2ca5b46e1fdea2ac1d8d18644e1..38f53b85b3a7c7712830a51477dae06e404e4e2e 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecoratorTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CleansingPathHandlerDecoratorTest.java
@@ -26,8 +26,8 @@ import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.utilities.FileUtilities;
+import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask.IPathHandler;
 
-import ch.systemsx.cisd.datamover.DirectoryScanningTimerTask.IPathHandler;
 
 /**
  * Test cases for the {@link CleansingPathHandlerDecorator}.
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CopyActivityMonitorTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CopyActivityMonitorTest.java
index 88b32adb2492903d99a62275743b412f3d153b39..9d12d92040fe59d1414be1983e69c0056dc025a2 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CopyActivityMonitorTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/CopyActivityMonitorTest.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.logging.LogMonitoringAppender;
 import ch.systemsx.cisd.common.utilities.ITerminable;
+import ch.systemsx.cisd.common.utilities.StoringUncaughtExceptionHandler;
 
 /**
  * Test cases for the {@link CopyActivityMonitor} class.
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTaskTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTaskTest.java
deleted file mode 100644
index f0c46e18fa7ca21fe7c9880002174db73bf0dbb1..0000000000000000000000000000000000000000
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/DirectoryScanningTimerTaskTest.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright 2007 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.datamover;
-
-import static org.testng.AssertJUnit.assertEquals;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogInitializer;
-import ch.systemsx.cisd.common.logging.LogMonitoringAppender;
-import ch.systemsx.cisd.common.utilities.CollectionIO;
-import ch.systemsx.cisd.common.utilities.FileUtilities;
-import ch.systemsx.cisd.datamover.DirectoryScanningTimerTask.IPathHandler;
-
-/**
- * Test cases for the {@link DirectoryScanningTimerTask}.
- * 
- * @author Bernd Rinn
- */
-public class DirectoryScanningTimerTaskTest
-{
-
-    private static final File unitTestRootDirectory = new File("targets" + File.separator + "unit-test-wd");
-
-    private static final File workingDirectory = new File(unitTestRootDirectory, "DirectoryScanningTimerTaskTest");
-
-    private final StoringUncaughtExceptionHandler exceptionHandler = new StoringUncaughtExceptionHandler();
-
-    private final static FileFilter ALWAYS_FALSE_FILE_FILTER = new FileFilter()
-        {
-            public boolean accept(File pathname)
-            {
-                return false;
-            }
-        };
-
-    private final static FileFilter ALWAYS_TRUE_FILE_FILTER = new FileFilter()
-        {
-            public boolean accept(File pathname)
-            {
-                return true;
-            }
-        };
-
-    private final static String EXCEPTION_THROWING_FILE_FILTER_MESSAGE = "Exception throwing file filter does its job.";
-
-    private final static FileFilter EXCEPTION_THROWING_FILE_FILTER = new FileFilter()
-        {
-            public boolean accept(File pathname)
-            {
-                throw new RuntimeException(EXCEPTION_THROWING_FILE_FILTER_MESSAGE);
-            }
-        };
-
-    private final MockPathHandler mockPathHandler = new MockPathHandler();
-
-    /**
-     * A mock implementation that stores the handled paths.
-     */
-    public static class MockPathHandler implements IPathHandler
-    {
-
-        final List<File> handledPaths = new ArrayList<File>();
-
-        public void clear()
-        {
-            handledPaths.clear();
-        }
-
-        public boolean handle(File path)
-        {
-            handledPaths.add(path);
-            path.delete();
-            return true;
-        }
-
-    }
-
-    @BeforeClass
-    public void init()
-    {
-        LogInitializer.init();
-        unitTestRootDirectory.mkdirs();
-        assert unitTestRootDirectory.isDirectory();
-        Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
-    }
-
-    @BeforeMethod
-    public void setUp()
-    {
-        FileUtilities.deleteRecursively(workingDirectory);
-        workingDirectory.mkdirs();
-        workingDirectory.deleteOnExit();
-        mockPathHandler.clear();
-    }
-
-    @AfterMethod
-    public void checkException()
-    {
-        exceptionHandler.checkAndRethrowException();
-    }
-
-    @Test(expectedExceptions =
-        { AssertionError.class })
-    public void testFailedConstructionNonExistent()
-    {
-        final File nonExistentFile = new File(unitTestRootDirectory, "non-existent");
-        nonExistentFile.delete();
-        new DirectoryScanningTimerTask(nonExistentFile, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-    }
-
-    @Test(expectedExceptions =
-        { AssertionError.class })
-    public void testFailedConstructionFileInsteadOfDirectory() throws IOException
-    {
-        final File file = new File(unitTestRootDirectory, "existent_file");
-        file.delete();
-        file.deleteOnExit();
-        file.createNewFile();
-        new DirectoryScanningTimerTask(file, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-    }
-
-    @Test(groups =
-        { "requires_unix" }, expectedExceptions =
-        { AssertionError.class })
-    public void testFailedConstructionReadOnly() throws IOException, InterruptedException
-    {
-        final File readOnlyDirectory = new File(unitTestRootDirectory, "read_only_directory");
-        readOnlyDirectory.delete();
-        readOnlyDirectory.mkdir();
-        readOnlyDirectory.deleteOnExit();
-        if (readOnlyDirectory.setReadOnly() == false)
-        {
-            // Can't use assert here since we expect an AssertationError
-            throw new IllegalStateException();
-        }
-
-        try
-        {
-            // Here we should get an AssertationError
-            new DirectoryScanningTimerTask(readOnlyDirectory, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        } finally
-        {
-            // Unfortunately, with JDK 5 there is no portable way to set a file or directory read/write, once
-            // it has been set read-only, thus this test 'requires_unix' for the time being.
-            Runtime.getRuntime().exec(String.format("/bin/chmod u+w %s", readOnlyDirectory.getPath())).waitFor();
-            if (readOnlyDirectory.canWrite() == false)
-            {
-                // Can't use assert here since we expect an AssertationError
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    @Test
-    public void testFaultyPathsDeletion()
-    {
-        final File faultyPaths = new File(workingDirectory, DirectoryScanningTimerTask.FAULTY_PATH_FILENAME);
-        CollectionIO.writeIterable(faultyPaths, Collections.singleton("some_path"));
-        new DirectoryScanningTimerTask(workingDirectory, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        assert faultyPaths.length() == 0;
-    }
-
-    @Test
-    public void testProcessOK() throws IOException
-    {
-        final File someFile = new File(workingDirectory, "some_file");
-        someFile.createNewFile();
-        someFile.deleteOnExit();
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(workingDirectory, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        assertEquals(0, mockPathHandler.handledPaths.size());
-        scanner.run();
-        assertEquals(1, mockPathHandler.handledPaths.size());
-        assertEquals(someFile, mockPathHandler.handledPaths.get(0));
-    }
-
-    @Test
-    public void testFileFilterUsed() throws IOException
-    {
-        final File someFile = new File(workingDirectory, "some_file");
-        someFile.createNewFile();
-        someFile.deleteOnExit();
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(workingDirectory, ALWAYS_FALSE_FILE_FILTER, mockPathHandler);
-        assertEquals(0, mockPathHandler.handledPaths.size());
-        scanner.run();
-        assertEquals(0, mockPathHandler.handledPaths.size());
-    }
-
-    @Test
-    public void testManipulateFaultyPaths() throws IOException
-    {
-        final File faultyPaths = new File(workingDirectory, DirectoryScanningTimerTask.FAULTY_PATH_FILENAME);
-        final File someFile = new File(workingDirectory, "some_file");
-        someFile.createNewFile();
-        someFile.deleteOnExit();
-        assert someFile.exists();
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(workingDirectory, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        CollectionIO.writeIterable(faultyPaths, Collections.singleton(someFile));
-        scanner.run();
-        assertEquals(0, mockPathHandler.handledPaths.size());
-    }
-
-    @Test
-    public void testFaultyPaths() throws IOException
-    {
-        final File faultyPaths = new File(workingDirectory, DirectoryScanningTimerTask.FAULTY_PATH_FILENAME);
-        final File someFile = new File(workingDirectory, "some_file");
-        final MockPathHandler myPathHandler = new MockPathHandler()
-            {
-                boolean firstTime = true;
-
-                @Override
-                public boolean handle(File path)
-                {
-                    if (firstTime)
-                    {
-                        firstTime = false;
-                        return false;
-                    }
-                    return super.handle(path);
-                }
-            };
-        someFile.createNewFile();
-        assert someFile.exists();
-        someFile.deleteOnExit();
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(workingDirectory, ALWAYS_TRUE_FILE_FILTER, myPathHandler);
-
-        // See whether faulty_paths settings works.
-        scanner.run();
-        assertEquals(0, mockPathHandler.handledPaths.size());
-        List<String> faulty = CollectionIO.readList(faultyPaths);
-        assertEquals(1, faulty.size());
-        assertEquals(someFile.getPath(), faulty.get(0));
-        // See whether fault_paths resetting works.
-        assert faultyPaths.delete();
-        myPathHandler.clear(); // Isn't necessary, just for expressing intention.
-        // See whether faulty_paths settings works.
-        scanner.run();
-        assertEquals(1, myPathHandler.handledPaths.size());
-        assertEquals(someFile, myPathHandler.handledPaths.get(0));
-    }
-
-    @Test
-    public void testPathOrder() throws IOException
-    {
-        final File dir = new File(workingDirectory, "testPathOrder");
-        final File f1 = new File(dir, "1");
-        final File f2 = new File(dir, "2");
-        final File f3 = new File(dir, "3");
-        final File f4 = new File(dir, "4");
-        final long now = System.currentTimeMillis();
-        dir.mkdir();
-        dir.deleteOnExit();
-        f1.createNewFile();
-        f1.deleteOnExit();
-        f2.createNewFile();
-        f2.deleteOnExit();
-        f3.createNewFile();
-        f3.deleteOnExit();
-        f4.createNewFile();
-        f4.deleteOnExit();
-        // Order should be: 2, 4, 3, 1
-        f2.setLastModified(now - 10000);
-        f4.setLastModified(now - 5000);
-        f3.setLastModified(now - 1000);
-        f1.setLastModified(now);
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(dir, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        scanner.run();
-        assertEquals(f2, mockPathHandler.handledPaths.get(0));
-        assertEquals(f4, mockPathHandler.handledPaths.get(1));
-        assertEquals(f3, mockPathHandler.handledPaths.get(2));
-        assertEquals(f1, mockPathHandler.handledPaths.get(3));
-        assertEquals(4, mockPathHandler.handledPaths.size());
-    }
-
-    @Test
-    public void testMissingDirectory()
-    {
-        final File dir = new File(workingDirectory, "testMissingDirectory");
-        dir.mkdir();
-        LogMonitoringAppender appender =
-                LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "Failed to get listing of directory");
-        // The directory needs to exist when the scanner is created, otherwise the self-test will fail.
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(dir, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        dir.delete();
-        assert dir.exists() == false;
-        scanner.run();
-        assert appender.hasLogHappened();
-        LogMonitoringAppender.removeAppender(appender);
-    }
-
-    @Test
-    public void testDirectoryIsFile() throws IOException
-    {
-        final File dir = new File(workingDirectory, "testMissingDirectory");
-        dir.mkdir();
-        LogMonitoringAppender appender =
-                LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "Failed to get listing of directory");
-        // The directory needs to exist when the scanner is created, otherwise the self-test will fail.
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(dir, ALWAYS_TRUE_FILE_FILTER, mockPathHandler);
-        dir.delete();
-        dir.createNewFile();
-        dir.deleteOnExit();
-        assert dir.isFile();
-        scanner.run();
-        assert appender.hasLogHappened();
-        dir.delete();
-        LogMonitoringAppender.removeAppender(appender);
-    }
-
-    @Test
-    public void testFailingFileFilter() throws IOException
-    {
-        final File dir = new File(workingDirectory, "testMissingDirectory");
-        dir.mkdir();
-        dir.deleteOnExit();
-        final File file = new File(dir, "some.file");
-        file.createNewFile();
-        file.deleteOnExit();
-        LogMonitoringAppender appender1 =
-                LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "Failed to get listing of directory");
-        LogMonitoringAppender appender2 =
-                LogMonitoringAppender.addAppender(LogCategory.NOTIFY, EXCEPTION_THROWING_FILE_FILTER_MESSAGE);
-        // The directory needs to exist when the scanner is created, otherwise the self-test will fail.
-        final DirectoryScanningTimerTask scanner =
-                new DirectoryScanningTimerTask(dir, EXCEPTION_THROWING_FILE_FILTER, mockPathHandler);
-        scanner.run();
-        assert appender1.hasLogHappened();
-        assert appender2.hasLogHappened();
-        file.delete();
-        dir.delete();
-        LogMonitoringAppender.removeAppender(appender1);
-        LogMonitoringAppender.removeAppender(appender2);
-    }
-
-}
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/StoringUncaughtExceptionHandler.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/StoringUncaughtExceptionHandler.java
deleted file mode 100644
index 12d05082396c48b579a7d0366dde3360acd3c82b..0000000000000000000000000000000000000000
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/StoringUncaughtExceptionHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2007 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.datamover;
-
-import java.lang.Thread.UncaughtExceptionHandler;
-
-/**
- * An exception handler that stores the first occurring exception for later investigation. Needs to be activated by
- * 
- * <pre>
- * StoringUncaughtExceptionHandler exceptionHandler = new StoringUncaughtExceptionHandler();
- * Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
- * </pre>
- * 
- * @author Bernd Rinn
- */
-public class StoringUncaughtExceptionHandler implements UncaughtExceptionHandler
-{
-
-    private Throwable throwable;
-
-    private String threadName;
-
-    public void uncaughtException(Thread t, Throwable e)
-    {
-        if (throwable == null) // Only store the first throwable
-        {
-            throwable = e;
-            threadName = t.getName();
-        }
-    }
-
-    /** Resets the handler. Any stored exception will be lost. */
-    public void reset()
-    {
-        throwable = null;
-        threadName = null;
-    }
-
-    /**
-     * @return <code>true</code> if an exception or error has occurred, <code>false</code> otherwise.
-     */
-    public boolean hasExceptionOccurred()
-    {
-        return (throwable != null);
-    }
-
-    /**
-     * @return The throwable, if any has been occurred, or <code>null</code> otherwise.
-     */
-    public Throwable getThrowable()
-    {
-        return throwable;
-    }
-
-    /**
-     * @return The name of the thread where the exception or error has occurred, or <code>null</code>, if no
-     *         exception or error has occurred.
-     */
-    public String getThreadName()
-    {
-        return threadName;
-    }
-
-    /**
-     * Checks whether an exception or error has occurred and, if yes, throws a new {@link RuntimeException} with the
-     * caught exception as cause in the current thread.
-     */
-    public void checkAndRethrowException()
-    {
-        if (hasExceptionOccurred())
-        {
-            throw new RuntimeException(String.format("An exception occurred in thread %s.", getThreadName()),
-                    getThrowable());
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/rsync/RsyncCopierTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/rsync/RsyncCopierTest.java
index dddfaeb4034bf9ba5e75624456e8cc7c673de595..1d423b7209731c5467da8fd2e19c5110744f0411 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/rsync/RsyncCopierTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/rsync/RsyncCopierTest.java
@@ -30,7 +30,7 @@ import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.utilities.CollectionIO;
-import ch.systemsx.cisd.datamover.StoringUncaughtExceptionHandler;
+import ch.systemsx.cisd.common.utilities.StoringUncaughtExceptionHandler;
 
 /**
  * Test cases for the {@link RsyncCopier} class.