diff --git a/datamover/dist/datamover.sh b/datamover/dist/datamover.sh
index 04f2c4b92bc65dc661d86b073d6f46ddd1964981..033819b08481ca4f03616073b007e37c61b877ed 100755
--- a/datamover/dist/datamover.sh
+++ b/datamover/dist/datamover.sh
@@ -1,42 +1,67 @@
 #!/bin/bash
 #
-# Control script for CISD Datamover on UNIX / Linux systems
+# Control script for CISD Datamover on Unix / Linux systems
 # -------------------------------------------------------------------------
 
 awkBin()
 {
-	# We need a awk that accepts variable assignments with '-v'
-	case `uname -s` in
-		"SunOS")
-			echo "nawk"
-			return
-			;;
-	esac
-	# default
-	echo "awk"
+  # We need a awk that accepts variable assignments with '-v'
+  case `uname -s` in
+    "SunOS")
+      echo "nawk"
+      return
+      ;;
+  esac
+  # default
+  echo "awk"
 }
 
 isPIDRunning()
 {
-	if [ "$1" = "" ]; then
-		return 1
-	fi
-	# This will have a return value of 0 on BSDish systems
-	isBSD="`ps aux > /dev/null 2>&1; echo $?`"
-	AWK=`awkBin`
-	if [ "$isBSD" = "0" ]; then
-		if [ "`ps aux | $AWK -v PID=$1 '{if ($2==PID) {print "FOUND"}}'`" = "FOUND" ]; then
-			return 0
-		else
-			return 1
-		fi
-	else
-		if [ "`ps -ef | $AWK -v PID=$1 '{if ($2==PID) {print "FOUND"}}'`" = "FOUND" ]; then
-			return 0
-		else
-			return 1
-		fi
-	fi
+  if [ "$1" = "" ]; then
+    return 1
+  fi
+  if [ "$1" = "fake" ]; then # for unit tests
+    return 0
+  fi
+  # This will have a return value of 0 on BSDish systems
+  isBSD="`ps aux > /dev/null 2>&1; echo $?`"
+  AWK=`awkBin`
+  if [ "$isBSD" = "0" ]; then
+    if [ "`ps aux | $AWK -v PID=$1 '{if ($2==PID) {print "FOUND"}}'`" = "FOUND" ]; then
+      return 0
+    else
+      return 1
+    fi
+  else
+    if [ "`ps -ef | $AWK -v PID=$1 '{if ($2==PID) {print "FOUND"}}'`" = "FOUND" ]; then
+      return 0
+    else
+      return 1
+    fi
+  fi
+}
+
+rotateLogFiles()
+{
+  logfile=$1
+  max=$2
+  if [ -z "$logfile" ]; then
+    echo "Error: rotateLogFiles: logfile argument missing"
+    return 1
+  fi
+  if [ -z "$max" ]; then
+    echo "Error: rotateLogFiles: max argument missing"
+    return 1
+  fi
+  test -f $logfile.$max && rm -f $logfile.$max
+  n=$max
+  while [ $n -gt 1 ]; do
+    nnew=$(($n-1))
+    test -f $logfile.$nnew && mv $logfile.$nnew $logfile.$n
+    n=$nnew
+  done
+  test -f $logfile && mv $logfile $logfile.1
 }
 
 #
@@ -54,58 +79,58 @@ MAX_LOOPS=10
 
 getStatus()
 {
-	if [ -f $PIDFILE ]; then
-		PID=`cat $PIDFILE 2> /dev/null`
-		isPIDRunning $PID
-		if [ $? -eq 0 ]; then
-			if [ -f .MARKER_shutdown ]; then
-				STATUS=SHUTDOWN
-				return 2
-			elif [ "`ls -a1 .MARKER_*_error 2> /dev/null`" != "" ]; then
-				STATUS=ERROR
-				return 1
-			elif [ "`ls -a1 .MARKER_*_processing 2> /dev/null`" != "" ]; then
-				STATUS=PROCESSING
-			else
-				STATUS=IDLE
-			fi 
-			return 0
-		else
-			STATUS=STALE
-			return 4
-		fi
-	else
-		STATUS=DOWN
-		return 3
-	fi
+  if [ -f $PIDFILE ]; then
+    PID=`cat $PIDFILE 2> /dev/null`
+    isPIDRunning $PID
+    if [ $? -eq 0 ]; then
+      if [ -f .MARKER_shutdown ]; then
+        STATUS=SHUTDOWN
+        return 2
+      elif [ "`ls -a1 .MARKER_*_error 2> /dev/null`" != "" ]; then
+        STATUS=ERROR
+        return 1
+      elif [ "`ls -a1 .MARKER_*_processing 2> /dev/null`" != "" ]; then
+        STATUS=PROCESSING
+      else
+        STATUS=IDLE
+      fi 
+      return 0
+    else
+      STATUS=STALE
+      return 4
+    fi
+  else
+    STATUS=DOWN
+    return 3
+  fi
 }
 
 printStatus()
 {
-	PID=`cat $PIDFILE 2> /dev/null`
-	MSG_PREFIX="Datamover (pid $PID) is"
-	case "$1" in
-		ERROR)
-			echo "$MSG_PREFIX running and in error state:"
-			cat .MARKER_*_error 2> /dev/null
-			echo
-			;;
-		PROCESSING)
-			echo "$MSG_PREFIX running and in processing state"
-			;;
-		IDLE)
-			echo "$MSG_PREFIX running and in idle state"
-			;;
-		SHUTDOWN)
-			echo "$MSG_PREFIX in shutdown mode"
-			;;
-		DOWN)
-			echo "Datamover is not running"
-			;;
-		STALE)
-			echo "Datamover is dead (stale pid $PID)"
-			;;
-	esac
+  PID=`cat $PIDFILE 2> /dev/null`
+  MSG_PREFIX="Datamover (pid $PID) is"
+  case "$1" in
+    ERROR)
+      echo "$MSG_PREFIX running and in error state:"
+      cat .MARKER_*_error 2> /dev/null
+      echo
+      ;;
+    PROCESSING)
+      echo "$MSG_PREFIX running and in processing state"
+      ;;
+    IDLE)
+      echo "$MSG_PREFIX running and in idle state"
+      ;;
+    SHUTDOWN)
+      echo "$MSG_PREFIX in shutdown mode"
+      ;;
+    DOWN)
+      echo "Datamover is not running"
+      ;;
+    STALE)
+      echo "Datamover is dead (stale pid $PID)"
+      ;;
+  esac
 }
 
 #
@@ -124,16 +149,16 @@ SCRIPT=./`basename $0`
 #
 test -f $CONFFILE && source $CONFFILE
 if [ "$JAVA_HOME" != "" ]; then
-	JAVA_BIN="$JAVA_HOME/bin/java"
+  JAVA_BIN="$JAVA_HOME/bin/java"
 else
-	JAVA_BIN="java"
+  JAVA_BIN="java"
 fi
 
 command=$1
 # ensure that we ignore a possible prefix "--" for any command 
 command="${command#--*}"
 case "$command" in
-	start)
+  start)
     getStatus
     EXIT_STATUS=$?
     if [ $EXIT_STATUS -lt 3 ]; then
@@ -143,111 +168,112 @@ case "$command" in
     fi
 
     echo -n "Starting Datamover "
-		shift 1
-		${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar "$@" > $STARTUPLOG 2>&1 & echo $! > $PIDFILE
-		if [ $? -eq 0 ]; then
-			# wait for initial self-test to finish
-			n=0
-			while [ $n -lt $MAX_LOOPS ]; do
-				sleep 1
-                                if [ ! -e $PIDFILE ]; then
-                                        break
-                                fi
-                                if [ -s $STARTUPLOG ]; then
-                                        PID=`cat $PIDFILE 2> /dev/null`
-                                        isPIDRunning $PID
-                                        if [ $? -ne 0 ]; then
-                                                break
-                                        fi
-                                fi
-				grep "$SUCCESS_MSG" $LOGFILE > /dev/null 2>&1
-				if [ $? -eq 0 ]; then
-					break
-				fi
-				n=$(($n+1))
-			done 
-			PID=`cat $PIDFILE 2> /dev/null`
-			isPIDRunning $PID
-			if [ $? -eq 0 ]; then
-				grep "$SUCCESS_MSG" $LOGFILE > /dev/null 2>&1
-				if [ $? -ne 0 ]; then
-					echo "(pid $PID - WARNING: SelfTest not yet finished)"
-				else
-					echo "(pid $PID)"
-				fi
-			else
-				test -e $PIDFILE && rm $PIDFILE
-				echo "FAILED"
-				echo "startup log says:"
-				cat $STARTUPLOG
-			fi
-		else
-			echo "FAILED"
-		fi
-		;;
-	stop)
-		echo -n "Stopping Datamover "
-		if [ -f $PIDFILE ]; then
-			PID=`cat $PIDFILE`
-			isPIDRunning $PID
-			if [ $? -eq 0 ]; then
-				kill $PID
-				if [ $? -eq 0 ]; then
-					echo "(pid $PID)"
-					# Shouldn't be necessary as Datamover deletes the file itself, but just to be sure
-					rm $PIDFILE 2> /dev/null
-				else
-					echo "FAILED"
-				fi
-			else
-				rm $PIDFILE
-				echo "(was dead - cleaned up pid file)"
-			fi
-		else
-			echo "(not running - nothing to do)"
-		fi
-	;;
-	shutdown)
-		touch $MARKER_SHUTDOWN_FILE
-	;;
-	status)
-		getStatus
-		EXIT_STATUS=$?
-		printStatus $STATUS
-		exit $EXIT_STATUS
-	;;
-	mstatus)
-		getStatus
-		EXIT_STATUS=$?
-		echo $STATUS
-		exit $EXIT_STATUS
-	;;
-	target)
-		if [ -f $TARGET_LOCATION_FILE ]; then
-			cat $TARGET_LOCATION_FILE
-		else
-			exit 1
-		fi
-	;;
-	recover)
-		echo "Triggering recovery cycle"
-		touch .MARKER_recovery
-	;;
-	restart)
-		$SCRIPT stop
-		$SCRIPT start
-	;;
-	help)
-		${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --help
-	;;
-	version)
-		${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --version
-	;;
-	test-notify)
-		${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --test-notify
-	;;
-	*)
-		echo $"Usage: $0 {start|stop|restart|shutdown|status|mstatus|target|recover|help|version|test-notify}"
-		exit 1
+    rotateLogFiles $LOGFILE $MAXLOGS
+    shift 1
+    ${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar "$@" > $STARTUPLOG 2>&1 & echo $! > $PIDFILE
+    if [ $? -eq 0 ]; then
+      # wait for initial self-test to finish
+      n=0
+      while [ $n -lt $MAX_LOOPS ]; do
+        sleep 1
+        if [ ! -e $PIDFILE ]; then
+          break
+        fi
+        if [ -s $STARTUPLOG ]; then
+          PID=`cat $PIDFILE 2> /dev/null`
+          isPIDRunning $PID
+          if [ $? -ne 0 ]; then
+            break
+          fi
+        fi
+        grep "$SUCCESS_MSG" $LOGFILE > /dev/null 2>&1
+        if [ $? -eq 0 ]; then
+          break
+        fi
+        n=$(($n+1))
+      done 
+      PID=`cat $PIDFILE 2> /dev/null`
+      isPIDRunning $PID
+      if [ $? -eq 0 ]; then
+        grep "$SUCCESS_MSG" $LOGFILE > /dev/null 2>&1
+        if [ $? -ne 0 ]; then
+          echo "(pid $PID - WARNING: SelfTest not yet finished)"
+        else
+          echo "(pid $PID)"
+        fi
+      else
+        test -e $PIDFILE && rm -f $PIDFILE
+        echo "FAILED"
+        echo "startup log says:"
+        cat $STARTUPLOG
+      fi
+    else
+      echo "FAILED"
+    fi
+  ;;
+  stop)
+    echo -n "Stopping Datamover "
+    if [ -f $PIDFILE ]; then
+      PID=`cat $PIDFILE 2> /dev/null`
+      isPIDRunning $PID
+      if [ $? -eq 0 ]; then
+        kill $PID
+        if [ $? -eq 0 ]; then
+          echo "(pid $PID)"
+          # Shouldn't be necessary as Datamover deletes the file itself, but just to be sure
+          test -e $PIDFILE && rm $PIDFILE
+        else
+          echo "FAILED"
+        fi
+      else
+        rm $PIDFILE
+        echo "(was dead - cleaned up pid file)"
+      fi
+    else
+      echo "(not running - nothing to do)"
+    fi
+  ;;
+  shutdown)
+    touch $MARKER_SHUTDOWN_FILE
+  ;;
+  status)
+    getStatus
+    EXIT_STATUS=$?
+    printStatus $STATUS
+    exit $EXIT_STATUS
+  ;;
+  mstatus)
+    getStatus
+    EXIT_STATUS=$?
+    echo $STATUS
+    exit $EXIT_STATUS
+  ;;
+  target)
+    if [ -f $TARGET_LOCATION_FILE ]; then
+      cat $TARGET_LOCATION_FILE
+     else
+   exit 1
+    fi
+  ;;
+  recover)
+    echo "Triggering recovery cycle"
+    touch .MARKER_recovery
+  ;;
+  restart)
+    $SCRIPT stop
+    $SCRIPT start
+  ;;
+  help)
+    ${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --help
+  ;;
+  version)
+    ${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --version
+  ;;
+  test-notify)
+    ${JAVA_BIN} ${JAVA_OPTS} -jar lib/datamover.jar --test-notify
+  ;;
+  *)
+    echo $"Usage: $0 {start|stop|restart|shutdown|status|mstatus|target|recover|help|version|test-notify}"
+    exit 1
 esac
 exit 0
diff --git a/datamover/dist/etc/datamover.conf b/datamover/dist/etc/datamover.conf
index 752a3bb80302f357c03e3c341f7c9cad0a86c8d4..ef373c25df684b6d3b2488d5b908f5a95881bc00 100644
--- a/datamover/dist/etc/datamover.conf
+++ b/datamover/dist/etc/datamover.conf
@@ -11,3 +11,8 @@
 # Options to the JRE
 #
 JAVA_OPTS=${JAVA_OPTS:=-server}
+
+#
+# Maximal number of log files to keep
+#
+MAXLOGS=5
\ No newline at end of file
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/ShellScriptTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/ShellScriptTest.java
index a7a7367b2d2b5848dcd5f12ec27f40660eacbd12..a62d59ac6fdef8398b43d0c3545b207baab130db 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/ShellScriptTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/ShellScriptTest.java
@@ -125,18 +125,20 @@ public class ShellScriptTest
     @Test
     public void testStatusIdle() throws IOException
     {
-        FileUtils.touch(PID_FILE); // empty PID file is for the shell script like a running process
+        // Convention for unit tests to get PID accepted as "running".
+        FileUtils.writeStringToFile(PID_FILE, "fake"); 
         checkStatus(0, "IDLE", false);
-        checkStatus(0, "Datamover (pid ) is running and in idle state", true);
+        checkStatus(0, "Datamover (pid fake) is running and in idle state", true);
     }
 
     @Test
     public void testStatusProcessing() throws IOException
     {
-        FileUtils.touch(PID_FILE); // empty PID file is for the shell script like a running process
+        // Convention for unit tests to get PID accepted as "running".
+        FileUtils.writeStringToFile(PID_FILE, "fake"); 
         FileUtils.touch(MARKER_FILE_INCOMING_PROCESSING);
         checkStatus(0, "PROCESSING", false);
-        checkStatus(0, "Datamover (pid ) is running and in processing state", true);
+        checkStatus(0, "Datamover (pid fake) is running and in processing state", true);
         FileUtils.touch(MARKER_FILE_OUTGOING_PROCESSING);
         checkStatus(0, "PROCESSING", false);
     }
@@ -144,10 +146,11 @@ public class ShellScriptTest
     @Test
     public void testStatusError() throws IOException
     {
-        FileUtils.touch(PID_FILE); // empty PID file is for the shell script like a running process
+        // Convention for unit tests to get PID accepted as "running".
+        FileUtils.writeStringToFile(PID_FILE, "fake"); 
         FileUtils.touch(MARKER_FILE_INCOMING_ERROR);
         checkStatus(1, "ERROR", false);
-        checkStatus(1, "Datamover (pid ) is running and in error state:", true, 2);
+        checkStatus(1, "Datamover (pid fake) is running and in error state:", true, 2);
         FileUtils.touch(MARKER_FILE_OUTGOING_ERROR);
         checkStatus(1, "ERROR", false);
     }
@@ -155,10 +158,11 @@ public class ShellScriptTest
     @Test
     public void testStatusShutdown() throws IOException
     {
-        FileUtils.touch(PID_FILE); // empty PID file is for the shell script like a running process
+        // Convention for unit tests to get PID accepted as "running".
+        FileUtils.writeStringToFile(PID_FILE, "fake"); 
         FileUtils.touch(MARKER_FILE_SHUTDOWN);
         checkStatus(2, "SHUTDOWN", false);
-        checkStatus(2, "Datamover (pid ) is in shutdown mode", true);
+        checkStatus(2, "Datamover (pid fake) is in shutdown mode", true);
         FileUtils.touch(MARKER_FILE_INCOMING_PROCESSING);
         checkStatus(2, "SHUTDOWN", false);
     }