From f279f2cdb6baafe132efa998646e18505df4a5e8 Mon Sep 17 00:00:00 2001
From: ribeaudc <ribeaudc>
Date: Wed, 2 Jul 2008 10:42:49 +0000
Subject: [PATCH] change: - 'FileStore' renamed to 'AbstractFileStore'. -
 'NumberStatus' renamed to 'DateStatus'. fix: - Conversion bug with
 'NumberStatus' by implementing its 'toString' method.

SVN: 6980
---
 .../filesystem/FileStoreFactory.java          | 25 +++++------
 ...{FileStore.java => AbstractFileStore.java} | 19 ++++----
 .../{NumberStatus.java => DateStatus.java}    | 43 ++++++++++++++-----
 .../datamover/filesystem/intf/IFileStore.java |  4 +-
 .../filesystem/intf/ResultStatus.java         | 29 ++++++++++---
 .../remote/CopyActivityMonitor.java           | 28 ++++++------
 .../filesystem/store/FileStoreLocal.java      | 18 ++++----
 .../filesystem/store/FileStoreRemote.java     | 21 ++++-----
 .../store/FileStoreRemoteMounted.java         | 38 ++++++++--------
 .../utils/QuietPeriodFileFilter.java          |  6 +--
 .../remote/CopyActivityMonitorTest.java       | 20 ++++-----
 .../store/FileStoreRemoteMountedTest.java     |  8 ++--
 .../filesystem/store/FileStoreRemoteTest.java |  6 ++-
 .../utils/QuietPeriodFileFilterTest.java      | 20 ++++-----
 14 files changed, 162 insertions(+), 123 deletions(-)
 rename datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/{FileStore.java => AbstractFileStore.java} (88%)
 rename datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/{NumberStatus.java => DateStatus.java} (52%)

diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/FileStoreFactory.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/FileStoreFactory.java
index a37128a4e83..35dba8c5932 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/FileStoreFactory.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/FileStoreFactory.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.datamover.filesystem;
 import java.io.File;
 
 import ch.systemsx.cisd.common.highwatermark.HostAwareFileWithHighwaterMark;
-import ch.systemsx.cisd.datamover.filesystem.intf.FileStore;
+import ch.systemsx.cisd.datamover.filesystem.intf.AbstractFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileSysOperationsFactory;
 import ch.systemsx.cisd.datamover.filesystem.store.FileStoreLocal;
@@ -27,7 +27,7 @@ import ch.systemsx.cisd.datamover.filesystem.store.FileStoreRemote;
 import ch.systemsx.cisd.datamover.filesystem.store.FileStoreRemoteMounted;
 
 /**
- * A {@link FileStore} factory.
+ * A {@link AbstractFileStore} factory.
  * 
  * @author Tomasz Pylak
  */
@@ -38,6 +38,16 @@ public final class FileStoreFactory
         // This class can not be instantiated.
     }
 
+    /**
+     * use when file store is on a remote share mounted on local host
+     */
+    private static final IFileStore createRemoteHost(final HostAwareFileWithHighwaterMark path,
+            final String kind, final IFileSysOperationsFactory factory,
+            final String findExecutableOrNull)
+    {
+        return new FileStoreRemote(path, kind, factory, findExecutableOrNull);
+    }
+
     /**
      * use when file store is on a local host.
      */
@@ -56,15 +66,6 @@ public final class FileStoreFactory
         return createLocal(new HostAwareFileWithHighwaterMark(readyToMoveDir), string, factory);
     }
 
-    /**
-     * use when file store is on a remote share mounted on local host
-     */
-    public static final IFileStore createRemoteHost(final HostAwareFileWithHighwaterMark path,
-            final String kind, final IFileSysOperationsFactory factory, String findExecutableOrNull)
-    {
-        return new FileStoreRemote(path, kind, factory, findExecutableOrNull);
-    }
-
     /**
      * use when file store is on a remote share mounted on local host
      * 
@@ -79,7 +80,7 @@ public final class FileStoreFactory
     /**
      * Returns the most convenient <code>IFileStore</code> implementation with given <var>values</var>.
      * 
-     * @param findExecutableOrNull
+     * @param checkIntervalMillis only used if given <var>isRemote</var> is <code>true</code>.
      */
     public final static IFileStore createStore(final HostAwareFileWithHighwaterMark path,
             final String kind, final boolean isRemote, final IFileSysOperationsFactory factory,
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/AbstractFileStore.java
similarity index 88%
rename from datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java
rename to datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/AbstractFileStore.java
index dd6fcb3b7fc..94322ddb9a3 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/AbstractFileStore.java
@@ -36,7 +36,7 @@ import ch.systemsx.cisd.common.utilities.StoreItem;
  * @author Bernd Rinn
  * @author Tomasz Pylak
  */
-public abstract class FileStore implements IFileStore
+public abstract class AbstractFileStore implements IFileStore
 {
     private final HostAwareFileWithHighwaterMark hostAwareFileWithHighwaterMark;
 
@@ -44,8 +44,9 @@ public abstract class FileStore implements IFileStore
 
     protected final IFileSysOperationsFactory factory;
 
-    protected FileStore(final HostAwareFileWithHighwaterMark hostAwareFileWithHighwaterMark,
-            final String kind, final IFileSysOperationsFactory factory)
+    protected AbstractFileStore(
+            final HostAwareFileWithHighwaterMark hostAwareFileWithHighwaterMark, final String kind,
+            final IFileSysOperationsFactory factory)
     {
         assert hostAwareFileWithHighwaterMark != null;
         assert kind != null;
@@ -90,8 +91,8 @@ public abstract class FileStore implements IFileStore
     {
         final IPathCopier copier = factory.getCopier(requiresDeletionBeforeCreation);
         final String srcHostOrNull = tryGetHost();
-        final String destHostOrNull = ((FileStore) destinationDirectory).tryGetHost();
-        final File destPath = ((FileStore) destinationDirectory).getPath();
+        final String destHostOrNull = ((AbstractFileStore) destinationDirectory).tryGetHost();
+        final File destPath = ((AbstractFileStore) destinationDirectory).getPath();
         return new IStoreCopier()
             {
                 public Status copy(final StoreItem item)
@@ -128,11 +129,11 @@ public abstract class FileStore implements IFileStore
 
     public final boolean isParentDirectory(final IFileStore child)
     {
-        if (child instanceof FileStore == false)
+        if (child instanceof AbstractFileStore == false)
         {
             return false;
         }
-        final FileStore potentialChild = (FileStore) child;
+        final AbstractFileStore potentialChild = (AbstractFileStore) child;
         return StringUtils.equals(tryGetHost(), potentialChild.tryGetHost())
                 && getCanonicalPath(potentialChild.getPath()).startsWith(
                         getCanonicalPath(getPath()));
@@ -159,11 +160,11 @@ public abstract class FileStore implements IFileStore
         {
             return true;
         }
-        if (obj instanceof FileStore == false)
+        if (obj instanceof AbstractFileStore == false)
         {
             return false;
         }
-        final FileStore that = (FileStore) obj;
+        final AbstractFileStore that = (AbstractFileStore) obj;
         final EqualsBuilder equalsBuilder = new EqualsBuilder();
         equalsBuilder.append(kind, that.kind);
         equalsBuilder.append(hostAwareFileWithHighwaterMark, that.hostAwareFileWithHighwaterMark);
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/NumberStatus.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/DateStatus.java
similarity index 52%
rename from datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/NumberStatus.java
rename to datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/DateStatus.java
index 45dae51aabd..279881a1b4b 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/NumberStatus.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/DateStatus.java
@@ -16,52 +16,73 @@
 
 package ch.systemsx.cisd.datamover.filesystem.intf;
 
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+
 /**
  * A class that holds the information about the result of an operation which is a number. There is a
  * way to find out if an error occurred during operation execution, the result is unavailable then.
  * 
  * @author Tomasz Pylak
  */
-public class NumberStatus
+public final class DateStatus
 {
     private final ResultStatus<Long> result;
 
-    private NumberStatus(Long result, boolean errorOccurred, String messageOrNull)
+    private DateStatus(final Long result, final boolean errorOccurred, final String messageOrNull)
     {
         this.result = new ResultStatus<Long>(result, errorOccurred, messageOrNull);
     }
 
-    public static final NumberStatus create(long result)
+    public static final DateStatus create(final long result)
     {
-        return new NumberStatus(result, false, null);
+        return new DateStatus(result, false, null);
     }
 
-    public static final NumberStatus createError(String message)
+    public static final DateStatus createError(final String message)
     {
-        return new NumberStatus(null, true, message);
+        return new DateStatus(null, true, message);
     }
 
-    public static final NumberStatus createError()
+    public static final DateStatus createError()
     {
-        return new NumberStatus(null, true, null);
+        return new DateStatus(null, true, null);
     }
 
     /**
      * can be called only if no error occurred, otherwise it fails.
      */
-    public long getResult()
+    public final long getResult()
     {
         return result.getResult();
     }
 
     /** has operation finished with an error? */
-    public boolean isError()
+    public final boolean isError()
     {
         return result.isError();
     }
 
-    public String tryGetMessage()
+    public final String tryGetMessage()
     {
         return result.tryGetMessage();
     }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        final Long thisResult = result.getResult();
+        builder.append("result", thisResult != null ? String.format("%1$tF %1$tT", thisResult) : null);
+        builder.append("error", isError());
+        builder.append("message", tryGetMessage());
+        return builder.toString();
+    }
 }
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java
index c2b3e9a7264..9dca9a01215 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/IFileStore.java
@@ -71,7 +71,7 @@ public interface IFileStore extends ISelfTestable
      * @return The time (in milliseconds since the start of the epoch) when <var>resource</var> was
      *         last changed or error status if checking failed.
      */
-    public NumberStatus lastChanged(StoreItem item, long stopWhenFindYounger);
+    public DateStatus lastChanged(StoreItem item, long stopWhenFindYounger);
 
     /**
      * Returns the last time when there was a write access to <var>item</var>.
@@ -83,7 +83,7 @@ public interface IFileStore extends ISelfTestable
      * @return The time (in milliseconds since the start of the epoch) when <var>resource</var> was
      *         last changed or error status if checking failed.
      */
-    public NumberStatus lastChangedRelative(StoreItem item, long stopWhenFindYoungerRelative);
+    public DateStatus lastChangedRelative(StoreItem item, long stopWhenFindYoungerRelative);
 
     /**
      * List files in the scanned store. Sort in order of "oldest first".
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/ResultStatus.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/ResultStatus.java
index c1556ff33e6..9d5b827f39f 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/ResultStatus.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/ResultStatus.java
@@ -16,6 +16,10 @@
 
 package ch.systemsx.cisd.datamover.filesystem.intf;
 
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+
 /**
  * A class that holds the information about the status and the result of an operation. To be used
  * whenever a failure of an operation is signaled back via a return value rather than an exception.
@@ -37,22 +41,22 @@ public class ResultStatus<T>
         return new ResultStatus<T>(null, true, null);
     }
 
-    public static <T> ResultStatus<T> createError(String message)
+    public static <T> ResultStatus<T> createError(final String message)
     {
         return new ResultStatus<T>(null, true, message);
     }
 
-    public static <T> ResultStatus<T> createResult(T result)
+    public static <T> ResultStatus<T> createResult(final T result)
     {
         return new ResultStatus<T>(result, false, null);
     }
 
-    public static <T> ResultStatus<T> createResult(T result, String message)
+    public static <T> ResultStatus<T> createResult(final T result, final String message)
     {
         return new ResultStatus<T>(result, false, message);
     }
 
-    protected ResultStatus(T result, boolean errorOccurred, String messageOrNull)
+    protected ResultStatus(final T result, final boolean errorOccurred, final String messageOrNull)
     {
         this.result = result;
         this.errorOccurred = errorOccurred;
@@ -64,21 +68,32 @@ public class ResultStatus<T>
      * 
      * @return result of an operation
      */
-    public T getResult()
+    public final T getResult()
     {
         assert isError() == false : "Operation failed, there is no result";
         return result;
     }
 
     /** @return message associated with the result or an error if there is any */
-    public String tryGetMessage()
+    public final String tryGetMessage()
     {
         return messageOrNull;
     }
 
     /** has operation finished with an error? */
-    public boolean isError()
+    public final boolean isError()
     {
         return errorOccurred;
     }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
 }
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitor.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitor.java
index c60820cca73..c4dbc2e04bb 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitor.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitor.java
@@ -28,8 +28,8 @@ import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.ITerminable;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.datamover.filesystem.intf.BooleanStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
 import ch.systemsx.cisd.datamover.intf.ITimingParameters;
 
 /**
@@ -114,7 +114,7 @@ public class CopyActivityMonitor
     @Private
     static interface IFileStoreMonitor
     {
-        NumberStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan);
+        DateStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan);
 
         BooleanStatus exists(StoreItem item);
 
@@ -155,9 +155,9 @@ public class CopyActivityMonitor
     {
         final private long timeChecked;
 
-        final private NumberStatus timeOfLastModification;
+        final private DateStatus timeOfLastModification;
 
-        public PathCheckRecord(final long timeChecked, final NumberStatus timeLastChanged)
+        public PathCheckRecord(final long timeChecked, final DateStatus timeLastChanged)
         {
             this.timeChecked = timeChecked;
             this.timeOfLastModification = timeLastChanged;
@@ -174,7 +174,7 @@ public class CopyActivityMonitor
         /**
          * The newest last modification time found during the check.
          */
-        public NumberStatus getTimeOfLastModification()
+        public DateStatus getTimeOfLastModification()
         {
             return timeOfLastModification;
         }
@@ -184,7 +184,7 @@ public class CopyActivityMonitor
     {
         return new IFileStoreMonitor()
             {
-                public NumberStatus lastChangedRelative(StoreItem item,
+                public DateStatus lastChangedRelative(StoreItem item,
                         long stopWhenFindYoungerRelative)
                 {
                     return destinationStore.lastChangedRelative(item, stopWhenFindYoungerRelative);
@@ -320,7 +320,7 @@ public class CopyActivityMonitor
         {
             if (lastCheckOrNull == null)
             {
-                lastCheckOrNull = new PathCheckRecord(now, NumberStatus.createError());
+                lastCheckOrNull = new PathCheckRecord(now, DateStatus.createError());
                 return false;
             } else
             {
@@ -343,7 +343,7 @@ public class CopyActivityMonitor
         // modification time to the one acquired in the past.
         private boolean checkIfUnmodifiedAndSet(long now, long prevModificationTime)
         {
-            final NumberStatus newModificationTime = lastChanged(itemToBeCopied);
+            final DateStatus newModificationTime = lastChanged(itemToBeCopied);
             if (newModificationTime.isError() == false
                     && newModificationTime.getResult() != prevModificationTime)
             {
@@ -357,25 +357,23 @@ public class CopyActivityMonitor
 
         private void setFirstModificationDate(final long timeChecked)
         {
-            NumberStatus lastChanged = lastChanged(itemToBeCopied);
+            DateStatus lastChanged = lastChanged(itemToBeCopied);
             lastCheckOrNull = new PathCheckRecord(timeChecked, lastChanged);
         }
     }
 
-    private NumberStatus lastChanged(StoreItem item)
+    private DateStatus lastChanged(StoreItem item)
     {
         long stopWhenFindYoungerRelative = minusSafetyMargin(inactivityPeriodMillis);
-        final NumberStatus lastChanged =
+        final DateStatus lastChanged =
                 destinationStore.lastChangedRelative(item, stopWhenFindYoungerRelative);
         if (lastChanged.isError())
         {
             operationLog.error(lastChanged.tryGetMessage());
         } else if (operationLog.isTraceEnabled())
         {
-            String msgTemplate =
-                    "Checker reported last changed time of '%s' inside '%s' to be %3$tF %3$tT.";
-            String msg =
-                    String.format(msgTemplate, item, destinationStore, lastChanged.getResult());
+            String msgTemplate = "Checker reported last changed time of '%s' inside '%s' to be %s.";
+            String msg = String.format(msgTemplate, item, destinationStore, lastChanged);
             operationLog.trace(msg);
         }
         return lastChanged;
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
index 9a56157073d..3df9ba26dec 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
@@ -33,22 +33,22 @@ import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.FileUtilities;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.datamover.common.MarkerFile;
+import ch.systemsx.cisd.datamover.filesystem.intf.AbstractFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.BooleanStatus;
-import ch.systemsx.cisd.datamover.filesystem.intf.FileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IExtendedFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileSysOperationsFactory;
 import ch.systemsx.cisd.datamover.filesystem.intf.IPathMover;
 import ch.systemsx.cisd.datamover.filesystem.intf.IPathRemover;
 import ch.systemsx.cisd.datamover.filesystem.intf.IStoreCopier;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 
 /**
  * An {@link IFileStore} implementation for local stores.
  * 
  * @author Tomasz Pylak
  */
-public class FileStoreLocal extends FileStore implements IExtendedFileStore
+public class FileStoreLocal extends AbstractFileStore implements IExtendedFileStore
 {
     private static final Logger machineLog =
             LogFactory.getLogger(LogCategory.MACHINE, FileStoreLocal.class);
@@ -88,20 +88,20 @@ public class FileStoreLocal extends FileStore implements IExtendedFileStore
         return BooleanStatus.createFromBoolean(exists);
     }
 
-    public final NumberStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
+    public final DateStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
     {
         try
         {
             long lastChanged =
                     FileUtilities.lastChanged(getChildFile(item), true, stopWhenFindYounger);
-            return NumberStatus.create(lastChanged);
+            return DateStatus.create(lastChanged);
         } catch (UnknownLastChangedException ex)
         {
             return createLastChangedError(item, ex);
         }
     }
 
-    public final NumberStatus lastChangedRelative(final StoreItem item,
+    public final DateStatus lastChangedRelative(final StoreItem item,
             final long stopWhenFindYoungerRelative)
     {
         try
@@ -109,20 +109,20 @@ public class FileStoreLocal extends FileStore implements IExtendedFileStore
             long lastChanged =
                     FileUtilities.lastChangedRelative(getChildFile(item), true,
                             stopWhenFindYoungerRelative);
-            return NumberStatus.create(lastChanged);
+            return DateStatus.create(lastChanged);
         } catch (UnknownLastChangedException ex)
         {
             return createLastChangedError(item, ex);
         }
     }
 
-    private static NumberStatus createLastChangedError(final StoreItem item,
+    private static DateStatus createLastChangedError(final StoreItem item,
             UnknownLastChangedException ex)
     {
         String errorMsg =
                 String.format("Could not determine \"last changed time\" of %s: %s", item, ex
                         .getCause());
-        return NumberStatus.createError(errorMsg);
+        return DateStatus.createError(errorMsg);
     }
 
     public final BooleanStatus tryCheckDirectoryFullyAccessible(final long timeOutMillis)
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
index ae073beec83..eccd25b7370 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.log4j.Logger;
 
+import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
@@ -36,18 +37,18 @@ import ch.systemsx.cisd.common.process.ProcessExecutionHelper;
 import ch.systemsx.cisd.common.process.ProcessResult;
 import ch.systemsx.cisd.common.process.ProcessExecutionHelper.OutputReadingStrategy;
 import ch.systemsx.cisd.common.utilities.StoreItem;
+import ch.systemsx.cisd.datamover.filesystem.intf.AbstractFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.BooleanStatus;
-import ch.systemsx.cisd.datamover.filesystem.intf.FileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IExtendedFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileSysOperationsFactory;
 import ch.systemsx.cisd.datamover.filesystem.intf.IStoreCopier;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 
 /**
  * @author Tomasz Pylak
  */
-public class FileStoreRemote extends FileStore
+public class FileStoreRemote extends AbstractFileStore
 {
     private static final Logger operationLog =
             LogFactory.getLogger(LogCategory.OPERATION, FileStoreRemote.class);
@@ -130,7 +131,7 @@ public class FileStoreRemote extends FileStore
                 remoteFindExecutableOrNull);
     }
 
-    // exposed for tests
+    @Private
     FileStoreRemote(final HostAwareFileWithHighwaterMark hostAwareFileWithHighwaterMark,
             final String kind, final ISshCommandBuilder sshCommandBuilder,
             final IFileSysOperationsFactory factory, final String remoteFindExecutableOrNull)
@@ -229,12 +230,12 @@ public class FileStoreRemote extends FileStore
         return constructStoreCopier(destinationDirectory, requiresDeletion);
     }
 
-    public final NumberStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
+    public final DateStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
     {
         return lastChanged(item);
     }
 
-    private final NumberStatus lastChanged(final StoreItem item)
+    private final DateStatus lastChanged(final StoreItem item)
     {
         final String itemPath = StoreItem.asFile(getPath(), item).getPath();
 
@@ -248,7 +249,7 @@ public class FileStoreRemote extends FileStore
             try
             {
                 long lastChanged = Long.parseLong(resultLine) * 1000;
-                return NumberStatus.create(lastChanged);
+                return DateStatus.create(lastChanged);
             } catch (final NumberFormatException e)
             {
                 return createLastChangeError(item, "The result of " + cmd + " on remote host "
@@ -260,9 +261,9 @@ public class FileStoreRemote extends FileStore
         }
     }
 
-    private static NumberStatus createLastChangeError(StoreItem item, String errorMsg)
+    private static DateStatus createLastChangeError(StoreItem item, String errorMsg)
     {
-        return NumberStatus.createError("Cannot obtain last change time of the item " + item
+        return DateStatus.createError("Cannot obtain last change time of the item " + item
                 + ". Reason: " + errorMsg);
     }
 
@@ -281,7 +282,7 @@ public class FileStoreRemote extends FileStore
         }
     }
 
-    public final NumberStatus lastChangedRelative(final StoreItem item,
+    public final DateStatus lastChangedRelative(final StoreItem item,
             final long stopWhenFindYoungerRelative)
     {
         return lastChanged(item);
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
index 39fc4024e71..4baafe1953d 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
@@ -36,13 +36,13 @@ import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.StoreItem;
+import ch.systemsx.cisd.datamover.filesystem.intf.AbstractFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.BooleanStatus;
-import ch.systemsx.cisd.datamover.filesystem.intf.FileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IExtendedFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileSysOperationsFactory;
 import ch.systemsx.cisd.datamover.filesystem.intf.IStoreCopier;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 
 /**
  * A <code>FileStore</code> extension for remote paths mounted.
@@ -52,7 +52,7 @@ import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
  * 
  * @author Tomasz Pylak
  */
-public final class FileStoreRemoteMounted extends FileStore
+public final class FileStoreRemoteMounted extends AbstractFileStore
 {
     private static final Logger machineLog =
             LogFactory.getLogger(LogCategory.MACHINE, FileStoreRemoteMounted.class);
@@ -104,12 +104,12 @@ public final class FileStoreRemoteMounted extends FileStore
         return localImpl.exists(item);
     }
 
-    public final NumberStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
+    public final DateStatus lastChanged(final StoreItem item, final long stopWhenFindYounger)
     {
         return lastChangeInvoker.lastChangedInternal(item, stopWhenFindYounger, false);
     }
 
-    public final NumberStatus lastChangedRelative(final StoreItem item,
+    public final DateStatus lastChangedRelative(final StoreItem item,
             final long stopWhenFindYoungerRelative)
     {
         return lastChangeInvoker.lastChangedInternal(item, stopWhenFindYoungerRelative, true);
@@ -166,21 +166,21 @@ public final class FileStoreRemoteMounted extends FileStore
         }
 
         // call checking last change in a separate thread with timeout
-        public NumberStatus lastChangedInternal(StoreItem item, long stopWhenFindYoungerAge,
+        public DateStatus lastChangedInternal(StoreItem item, long stopWhenFindYoungerAge,
                 boolean isAgeRelative)
         {
-            Callable<NumberStatus> callable =
+            Callable<DateStatus> callable =
                     createLastChangedCallable(localImpl, item, stopWhenFindYoungerAge,
                             isAgeRelative);
             final ISimpleLogger simpleMachineLog = new Log4jSimpleLogger(machineLog);
-            final Future<NumberStatus> future = lastChangedExecutor.submit(callable);
-            ExecutionResult<NumberStatus> executionResult =
+            final Future<DateStatus> future = lastChangedExecutor.submit(callable);
+            ExecutionResult<DateStatus> executionResult =
                     ConcurrencyUtilities.getResult(future, lastChangedTimeoutMillis,
                             simpleMachineLog, "Check for recent paths");
-            NumberStatus result = executionResult.tryGetResult();
+            DateStatus result = executionResult.tryGetResult();
             if (result == null)
             {
-                return NumberStatus.createError(String.format(
+                return DateStatus.createError(String.format(
                         "Could not determine \"last changed time\" of %s: time out.", item));
             } else
             {
@@ -188,19 +188,19 @@ public final class FileStoreRemoteMounted extends FileStore
             }
         }
 
-        private Callable<NumberStatus> createLastChangedCallable(final IFileStore store,
+        private Callable<DateStatus> createLastChangedCallable(final IFileStore store,
                 final StoreItem item, final long stopWhenFindYoungerAge, final boolean isAgeRelative)
         {
-            return new Callable<NumberStatus>()
+            return new Callable<DateStatus>()
                 {
-                    public NumberStatus call() throws Exception
+                    public DateStatus call() throws Exception
                     {
                         if (machineLog.isTraceEnabled())
                         {
                             machineLog.trace("Starting quick check for recent paths on '" + item
                                     + "'.");
                         }
-                        final NumberStatus lastChanged;
+                        final DateStatus lastChanged;
                         if (isAgeRelative)
                         {
                             lastChanged = store.lastChangedRelative(item, stopWhenFindYoungerAge);
@@ -210,11 +210,9 @@ public final class FileStoreRemoteMounted extends FileStore
                         }
                         if (machineLog.isTraceEnabled())
                         {
-                            machineLog
-                                    .trace(String
-                                            .format(
-                                                    "Finishing quick check for recent paths on '%s', found to be %2$tF %2$tT.",
-                                                    item, lastChanged));
+                            machineLog.trace(String.format(
+                                    "Finishing quick check for recent paths on '%s': %s.", item,
+                                    lastChanged));
                         }
                         return lastChanged;
                     }
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilter.java b/datamover/source/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilter.java
index 0d04df50ad9..bdca11f031b 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilter.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilter.java
@@ -31,7 +31,7 @@ import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 import ch.systemsx.cisd.datamover.intf.ITimingParameters;
 
 /**
@@ -159,7 +159,7 @@ public class QuietPeriodFileFilter implements IStoreItemFilter
                 return false;
             }
             final long oldLastChanged = checkRecordOrNull.getTimeOfLastModification();
-            NumberStatus newStatus = fileStore.lastChanged(item, oldLastChanged);
+            DateStatus newStatus = fileStore.lastChanged(item, oldLastChanged);
             if (newStatus.isError())
             {
                 return false;
@@ -198,7 +198,7 @@ public class QuietPeriodFileFilter implements IStoreItemFilter
 
     private void saveFirstModificationTime(final StoreItem item, final long now)
     {
-        NumberStatus status = fileStore.lastChanged(item, 0L);
+        DateStatus status = fileStore.lastChanged(item, 0L);
         if (status.isError() == false)
         {
             pathMap.put(item, new PathCheckRecord(now, status.getResult()));
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
index 3f9debbf41a..44526cfc2e4 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
@@ -31,7 +31,7 @@ import ch.systemsx.cisd.common.test.StoringUncaughtExceptionHandler;
 import ch.systemsx.cisd.common.utilities.ITerminable;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.datamover.filesystem.intf.BooleanStatus;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 import ch.systemsx.cisd.datamover.filesystem.remote.CopyActivityMonitor.IFileStoreMonitor;
 import ch.systemsx.cisd.datamover.intf.ITimingParameters;
 
@@ -180,12 +180,12 @@ public class CopyActivityMonitorTest
                     return BooleanStatus.createTrue();
                 }
 
-                public NumberStatus lastChangedRelative(StoreItem item,
+                public DateStatus lastChangedRelative(StoreItem item,
                         long stopWhenFindYoungerRelative)
                 {
                     long lastChanged =
                             checker.lastChangedRelative(item, stopWhenFindYoungerRelative);
-                    return NumberStatus.create(lastChanged);
+                    return DateStatus.create(lastChanged);
                 }
 
                 @Override
@@ -347,7 +347,7 @@ public class CopyActivityMonitorTest
                     return BooleanStatus.createFalse();
                 }
 
-                public NumberStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
+                public DateStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
                 {
                     throw new UnsupportedOperationException(); // should be never called
                 }
@@ -364,10 +364,10 @@ public class CopyActivityMonitorTest
         final StoreItem dummyItem = createDummyItem();
         final IFileStoreMonitor store = new AlwaysExistsStoreMonitor(dummyItem)
             {
-                public NumberStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
+                public DateStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
                 {
                     assertEquals(dummyItem, item);
-                    return NumberStatus.createError("mock: lastChange error");
+                    return DateStatus.createError("mock: lastChange error");
                 }
             };
         checkCopyTerminated(store, dummyItem);
@@ -384,12 +384,12 @@ public class CopyActivityMonitorTest
             {
                 private boolean oddCall = true;
 
-                public NumberStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
+                public DateStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
                 {
                     assertEquals(dummyItem, item);
                     oddCall = !oddCall;
                     // error or unchanged value
-                    return oddCall ? NumberStatus.create(10) : NumberStatus
+                    return oddCall ? DateStatus.create(10) : DateStatus
                             .createError("mock: simulate error while getting last change");
                 }
             };
@@ -406,9 +406,9 @@ public class CopyActivityMonitorTest
             {
                 private int counter = 1;
 
-                public NumberStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
+                public DateStatus lastChangedRelative(StoreItem item, long stopWhenYoungerThan)
                 {
-                    return NumberStatus.create(counter++);
+                    return DateStatus.create(counter++);
                 }
             };
         checkCopyTerminationStatus(store, dummyItem, false);
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMountedTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMountedTest.java
index c2bade6247d..2e07e6510e9 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMountedTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMountedTest.java
@@ -34,7 +34,7 @@ import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 import ch.systemsx.cisd.datamover.filesystem.store.FileStoreRemoteMounted.LastChangeWrapper;
 
 /**
@@ -81,7 +81,7 @@ public class FileStoreRemoteMountedTest
                 }
             });
 
-        NumberStatus result = lastChangeWrapper.lastChangedInternal(item, age, true);
+        DateStatus result = lastChangeWrapper.lastChangedInternal(item, age, true);
         AssertJUnit.assertFalse(result.isError());
         assertFalse(lastChangedSleepAction.lastCheckInterrupted());
         context.assertIsSatisfied();
@@ -105,7 +105,7 @@ public class FileStoreRemoteMountedTest
                 }
             });
 
-        NumberStatus result = lastChangeWrapper.lastChangedInternal(item, age, false);
+        DateStatus result = lastChangeWrapper.lastChangedInternal(item, age, false);
         assertTrue(result.isError());
         assertTrue(lastChangedSleepAction.lastCheckInterrupted());
         context.assertIsSatisfied();
@@ -135,7 +135,7 @@ public class FileStoreRemoteMountedTest
                 throw new CheckedExceptionTunnel(new InterruptedException(e.getMessage()));
             }
             this.interrupted = false;
-            return NumberStatus.create(System.currentTimeMillis());
+            return DateStatus.create(System.currentTimeMillis());
         }
 
         synchronized boolean lastCheckInterrupted()
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteTest.java
index 3fd89698015..738af32cf00 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteTest.java
@@ -29,6 +29,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.highwatermark.HostAwareFileWithHighwaterMark;
 import ch.systemsx.cisd.common.logging.ISimpleLogger;
 import ch.systemsx.cisd.common.logging.LogCategory;
@@ -40,9 +41,12 @@ import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileSysOperationsFactory;
 
 /**
+ * Test cases for {@link FileStoreRemote}.
+ * 
  * @author Tomasz Pylak
  */
-public class FileStoreRemoteTest
+@Friend(toClasses = FileStoreRemote.class)
+public final class FileStoreRemoteTest
 {
     private static final File TEST_FOLDER = new File("targets/unit-test/FileStoreRemoteTest");
 
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilterTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilterTest.java
index 971d54eeddf..541650a17da 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilterTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/utils/QuietPeriodFileFilterTest.java
@@ -35,7 +35,7 @@ import ch.systemsx.cisd.common.test.LogMonitoringAppender;
 import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.common.utilities.StoreItem;
 import ch.systemsx.cisd.datamover.filesystem.intf.IFileStore;
-import ch.systemsx.cisd.datamover.filesystem.intf.NumberStatus;
+import ch.systemsx.cisd.datamover.filesystem.intf.DateStatus;
 import ch.systemsx.cisd.datamover.intf.ITimingParameters;
 
 /**
@@ -154,7 +154,7 @@ public class QuietPeriodFileFilterTest
                     one(timeProvider).getTimeInMilliseconds();
                     will(returnValue(nowMillis));
                     one(fileStore).lastChanged(ITEM, 0L);
-                    will(returnValue(NumberStatus.create(pathLastChangedMillis)));
+                    will(returnValue(DateStatus.create(pathLastChangedMillis)));
                     for (int i = 1; i <= 100; ++i)
                     {
                         one(timeProvider).getTimeInMilliseconds();
@@ -163,7 +163,7 @@ public class QuietPeriodFileFilterTest
                     // last call - will check only when last check is longer ago than the quiet
                     // period
                     one(fileStore).lastChanged(ITEM, pathLastChangedMillis);
-                    will(returnValue(NumberStatus.create(pathLastChangedMillis)));
+                    will(returnValue(DateStatus.create(pathLastChangedMillis)));
                 }
             });
         for (int i = 0; i < 100; ++i)
@@ -237,7 +237,7 @@ public class QuietPeriodFileFilterTest
         long now = 0;
         for (int i = 0; i < errorRepetitions; i++)
         {
-            prepareLastChanged(now, 0L, NumberStatus.createError());
+            prepareLastChanged(now, 0L, DateStatus.createError());
             now += QUIET_PERIOD_MILLIS;
         }
         for (int i = 0; i < errorRepetitions; i++)
@@ -245,12 +245,12 @@ public class QuietPeriodFileFilterTest
             assertNoAccept();
         }
         // first time we acquire modification time
-        NumberStatus lastChange = NumberStatus.create(0);
+        DateStatus lastChange = DateStatus.create(0);
         prepareLastChanged(now, 0L, lastChange);
         now += QUIET_PERIOD_MILLIS;
         assertNoAccept();
         // error again
-        prepareLastChanged(now, 0L, NumberStatus.createError());
+        prepareLastChanged(now, 0L, DateStatus.createError());
         now += QUIET_PERIOD_MILLIS;
         assertNoAccept();
         // second time we acquire modification time - and nothing change during the quite period, so
@@ -274,11 +274,11 @@ public class QuietPeriodFileFilterTest
     private void prepareLastChanged(final long currentTime, final long stopWhenFindYounger,
             final long lastChanged)
     {
-        prepareLastChanged(currentTime, stopWhenFindYounger, NumberStatus.create(lastChanged));
+        prepareLastChanged(currentTime, stopWhenFindYounger, DateStatus.create(lastChanged));
     }
 
     private void prepareLastChanged(final long currentTime, final long stopWhenFindYounger,
-            final NumberStatus lastChanged)
+            final DateStatus lastChanged)
     {
         context.checking(new Expectations()
             {
@@ -307,13 +307,13 @@ public class QuietPeriodFileFilterTest
                     one(timeProvider).getTimeInMilliseconds();
                     will(returnValue(nowMillis1));
                     allowing(fileStore).lastChanged(vanishingItem, 0L);
-                    will(returnValue(NumberStatus.create(pathLastChangedMillis1)));
+                    will(returnValue(DateStatus.create(pathLastChangedMillis1)));
                     // calls to get the required number of calls for clean up
                     allowing(timeProvider).getTimeInMilliseconds();
                     will(returnValue(nowMillis2));
                     allowing(fileStore).lastChanged(with(same(ITEM)),
                             with(greaterThanOrEqualTo(0L)));
-                    will(returnValue(NumberStatus.create(pathLastChangedMillis2)));
+                    will(returnValue(DateStatus.create(pathLastChangedMillis2)));
                 }
             });
         final LogMonitoringAppender appender =
-- 
GitLab