diff --git a/ATXCommon/Serializables/ServiceConfig.cs b/ATXCommon/Serializables/ServiceConfig.cs
index 708a6354baa702492a79df1b3e633fc754630379..367f4def51281fa8766ae245d69b5f7718c20574 100644
--- a/ATXCommon/Serializables/ServiceConfig.cs
+++ b/ATXCommon/Serializables/ServiceConfig.cs
@@ -197,6 +197,51 @@ namespace ATXCommon.Serializables
 
         #endregion
 
+        
+        #region wrappers for derived parameters
+
+        /// <summary>
+        /// The full path to the incoming directory.
+        /// </summary>
+        [XmlIgnore]
+        public string IncomingPath {
+            get { return Path.Combine(SourceDrive, IncomingDirectory); }
+        }
+
+        /// <summary>
+        /// The full path to the managed directory.
+        /// </summary>
+        [XmlIgnore]
+        public string ManagedPath {
+            get { return Path.Combine(SourceDrive, ManagedDirectory); }
+        }
+
+        /// <summary>
+        /// The full path to the processing directory.
+        /// </summary>
+        [XmlIgnore]
+        public string ProcessingPath {
+            get { return Path.Combine(ManagedPath, "PROCESSING"); }
+        }
+
+        /// <summary>
+        /// The full path to the done directory / grace location.
+        /// </summary>
+        [XmlIgnore]
+        public string DonePath {
+            get { return Path.Combine(ManagedPath, "DONE"); }
+        }
+
+        /// <summary>
+        /// The full path to the directory for unmatched user directories.
+        /// </summary>
+        [XmlIgnore]
+        public string UnmatchedPath {
+            get { return Path.Combine(ManagedPath, "UNMATCHED"); }
+        }
+
+        #endregion
+
 
         public static void Serialize(string file, ServiceConfig c) {
             // the config is never meant to be written by us, therefore:
diff --git a/AutoTx/AutoTx.cs b/AutoTx/AutoTx.cs
index e3132f6d499c296c6a9ebe45ddf65ac98a3af482..ae74397e033e9066d7e672590e62e0a0ca6ba955 100644
--- a/AutoTx/AutoTx.cs
+++ b/AutoTx/AutoTx.cs
@@ -24,12 +24,10 @@ namespace AutoTx
         private const string LogFormatDefault = @"${date:format=yyyy-MM-dd HH\:mm\:ss} [${level}] ${message}";
         // private const string LogFormatDefault = @"${date:format=yyyy-MM-dd HH\:mm\:ss} [${level}] (${logger}) ${message}"
 
-        // naming convention: variables ending with "Path" are strings, variables
-        // ending with "Dir" are DirectoryInfo objects
+        // naming convention: variables containing "Path" are strings, variables
+        // containing "Dir" are DirectoryInfo objects
         private string _pathToConfig;
         private string _pathToStatus;
-        private string _incomingPath;
-        private string _managedPath;
 
         private List<string> _transferredFiles = new List<string>();
 
@@ -210,8 +208,6 @@ namespace AutoTx
         private void LoadConfigXml() {
             try {
                 _config = ServiceConfig.Deserialize(_pathToConfig);
-                _incomingPath = Path.Combine(_config.SourceDrive, _config.IncomingDirectory);
-                _managedPath = Path.Combine(_config.SourceDrive, _config.ManagedDirectory);
                 Log.Debug("Loaded config from [{0}]", _pathToConfig);
             }
             catch (ConfigurationErrorsException ex) {
@@ -252,7 +248,7 @@ namespace AutoTx
                 SetupMailLogging();
 
             var configInvalid = false;
-            if (FsUtils.CheckSpoolingDirectories(_incomingPath, _managedPath) == false) {
+            if (FsUtils.CheckSpoolingDirectories(_config.IncomingPath, _config.ManagedPath) == false) {
                 Log.Error("ERROR checking spooling directories (incoming / managed)!");
                 configInvalid = true;
             }
@@ -557,8 +553,7 @@ namespace AutoTx
                 return;
 
             // check the "processing" location for directories:
-            var processingDir = Path.Combine(_managedPath, "PROCESSING");
-            var queued = new DirectoryInfo(processingDir).GetDirectories();
+            var queued = new DirectoryInfo(_config.ProcessingPath).GetDirectories();
             if (queued.Length == 0)
                 return;
 
@@ -592,7 +587,7 @@ namespace AutoTx
         /// </summary>
         private void CheckIncomingDirectories() {
             // iterate over all user-subdirectories:
-            foreach (var userDir in new DirectoryInfo(_incomingPath).GetDirectories()) {
+            foreach (var userDir in new DirectoryInfo(_config.IncomingPath).GetDirectories()) {
                 if (FsUtils.DirEmptyExcept(userDir, _config.MarkerFile))
                     continue;
 
@@ -670,25 +665,21 @@ namespace AutoTx
                 // first check for individual files and collect them:
                 FsUtils.CollectOrphanedFiles(userDir, _config.MarkerFile);
 
-                // the default subdir inside the managed directory, where folders will be
-                // picked up later by the actual transfer method:
-                var target = "PROCESSING";
+                // the default path where folders will be picked up by the actual transfer method:
+                var baseDir = _config.ProcessingPath;
 
                 // if the user has no directory on the destination move to UNMATCHED instead:
                 if (string.IsNullOrWhiteSpace(DestinationPath(userDir.Name))) {
                     Log.Error("Found unmatched incoming dir: {0}", userDir.Name);
-                    target = "UNMATCHED";
+                    baseDir = _config.UnmatchedPath;
                 }
                 
                 // now everything that is supposed to be transferred is in a folder,
                 // for example: D:\ATX\PROCESSING\2017-04-02__12-34-56\user00
-                var targetDir = Path.Combine(
-                    _managedPath,
-                    target,
-                    TimeUtils.Timestamp(),
-                    userDir.Name);
+                var targetDir = Path.Combine(baseDir, TimeUtils.Timestamp(), userDir.Name);
                 if (FsUtils.MoveAllSubDirs(userDir, targetDir))
                     return;
+
                 errMsg = "unable to move " + userDir.FullName;
             }
             catch (Exception ex) {
@@ -707,8 +698,7 @@ namespace AutoTx
             // CurrentTransferSrc is e.g. D:\ATX\PROCESSING\2017-04-02__12-34-56\user00
             var sourceDirectory = new DirectoryInfo(_status.CurrentTransferSrc);
             var dstPath = Path.Combine(
-                _managedPath,
-                "DONE",
+                _config.DonePath,
                 sourceDirectory.Name, // the username directory
                 TimeUtils.Timestamp());
             Log.Trace("MoveToGraceLocation: src({0}) dst({1})", sourceDirectory.FullName, dstPath);
@@ -756,7 +746,7 @@ namespace AutoTx
                 if (!remoteUserDirs.Contains(userDir))
                     continue;
 
-                FsUtils.CreateNewDirectory(Path.Combine(_incomingPath, userDir), false);
+                FsUtils.CreateNewDirectory(Path.Combine(_config.IncomingPath, userDir), false);
             }
             _lastUserDirCheck = DateTime.Now;
         }
diff --git a/AutoTx/Email.cs b/AutoTx/Email.cs
index fd22c8408fbac52ef68393697370be1d14f03c66..af291b57c128c368ec3f0074ce0fa68e588ae6d0 100644
--- a/AutoTx/Email.cs
+++ b/AutoTx/Email.cs
@@ -229,7 +229,7 @@ namespace AutoTx
         /// <returns>The summary report, empty if no expired folders exist.</returns>
         private string SendGraceLocationSummary(int threshold) {
             var report = FsUtils.GraceLocationSummary(
-                new DirectoryInfo(Path.Combine(_managedPath, "DONE")), threshold);
+                new DirectoryInfo(_config.DonePath), threshold);
             if (string.IsNullOrEmpty(report))
                 return "";