diff --git a/src/python/dm/aps_bss/cli/getProposalCli.py b/src/python/dm/aps_bss/cli/getProposalCli.py
index b2f215c4e7ab87b1a8395961e680f7a4c7bea34c..0f9e28712ee8ddabc3eccf42b6e7ffdc85fbb639 100755
--- a/src/python/dm/aps_bss/cli/getProposalCli.py
+++ b/src/python/dm/aps_bss/cli/getProposalCli.py
@@ -9,7 +9,7 @@ class GetProposalCli(DmCli):
         DmCli.__init__(self)
         self.addOption('', '--id', dest='proposalId', help='Proposal id.')
         self.addOption('', '--run', dest='runName', help='Run name. If not provided, current run will be used.')
-        self.addOption('', '--login-file', dest='loginFile', help='BSS login file. Login file  may also be specified via environment variable DM_BSS_LOGIN_FILE.')
+        self.addOption('', '--bss-login-file', dest='bssLoginFile', help='BSS login file. Login file  may also be specified via environment variable DM_BSS_LOGIN_FILE.')
 
     def checkArgs(self):
         if not self.options.proposalId:
@@ -19,14 +19,14 @@ class GetProposalCli(DmCli):
         self.parseArgs(usage="""
     dm-get-proposal --id=PROPOSALID
         [--run=RUNNAME]
-        [--login-file=LOGINFILE]
+        [--bss-login-file=BSSLOGINFILE]
 
 Description:
     Retrieves beamline proposal for the given id.
         """)
         self.checkArgs()
         proposalId = int(self.options.proposalId)
-        api = ApsBssApi(loginFile=self.options.loginFile)
+        api = ApsBssApi(loginFile=self.options.bssLoginFile)
         proposal = api.getBeamlineProposal(proposalId=proposalId, runName=self.options.runName)
         print proposal.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat())
 
diff --git a/src/python/dm/aps_bss/cli/listProposalsCli.py b/src/python/dm/aps_bss/cli/listProposalsCli.py
index 05b1f4301cd36ce7d4385e6d540aa0b754978325..ae5c032fb447fd059b71229f842ce2875104e65b 100755
--- a/src/python/dm/aps_bss/cli/listProposalsCli.py
+++ b/src/python/dm/aps_bss/cli/listProposalsCli.py
@@ -7,7 +7,7 @@ class ListProposalsCli(DmCli):
     def __init__(self):
         DmCli.__init__(self)
         self.addOption('', '--run', dest='runName', help='Run name. If not provided, current run will be used.')
-        self.addOption('', '--login-file', dest='loginFile', help='BSS login file. It may be provided via environment variable DM_BSS_LOGIN_FILE.')
+        self.addOption('', '--bss-login-file', dest='bssLoginFile', help='BSS login file. It may be provided via environment variable DM_BSS_LOGIN_FILE.')
 
     def checkArgs(self):
         pass
@@ -16,13 +16,13 @@ class ListProposalsCli(DmCli):
         self.parseArgs(usage="""
     dm-list-proposals 
         [--run=RUNNAME]
-        [--login-file=LOGINFILE]
+        [--bss-login-file=BSSLOGINFILE]
 
 Description:
     Retrieves list of beamline proposals for the given run.
         """)
         self.checkArgs()
-        api = ApsBssApi(loginFile=self.options.loginFile)
+        api = ApsBssApi(loginFile=self.options.bssLoginFile)
         proposals = api.listBeamlineProposals(runName=self.options.runName)
         for proposal in proposals:
             print proposal.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat())
diff --git a/src/python/dm/aps_bss/cli/listRunsCli.py b/src/python/dm/aps_bss/cli/listRunsCli.py
index 2bdcf21cfcbe831c876a3c8055dc44943efae3a9..682023092fdfaf9fb47d10a0c0b5150c78d18935 100755
--- a/src/python/dm/aps_bss/cli/listRunsCli.py
+++ b/src/python/dm/aps_bss/cli/listRunsCli.py
@@ -6,20 +6,20 @@ from dm.aps_bss.api.apsBssApi import ApsBssApi
 class ListRunsCli(DmCli):
     def __init__(self):
         DmCli.__init__(self)
-        self.addOption('', '--login-file', dest='loginFile', help='BSS login file. It may be provided via environment variable DM_BSS_LOGIN_FILE.')
+        self.addOption('', '--bss-login-file', dest='bssLoginFile', help='BSS login file. It may be provided via environment variable DM_BSS_LOGIN_FILE.')
 
     def checkArgs(self):
         pass
 
     def runCommand(self):
         self.parseArgs(usage="""
-    dm-list-runs [--login-file=LOGINFILE]
+    dm-list-runs [--bss-login-file=BSSLOGINFILE]
 
 Description:
     Retrieves list of available runs.
         """)
         self.checkArgs()
-        api = ApsBssApi(loginFile=self.options.loginFile)
+        api = ApsBssApi(loginFile=self.options.bssLoginFile)
         runs = api.listRuns()
         for run in runs:
             print run.getDisplayString(self.getDisplayKeys(), self.getDisplayFormat())
diff --git a/src/python/dm/common/cli/dmCli.py b/src/python/dm/common/cli/dmCli.py
index aeaec3086e875c04bd9f53f3970cdcd02b83dcf2..3be3e201d1920e028d5aa994ce90c0985f1eadbc 100755
--- a/src/python/dm/common/cli/dmCli.py
+++ b/src/python/dm/common/cli/dmCli.py
@@ -78,9 +78,12 @@ class DmCli(object):
         group = self.optionGroupDict.get(groupName)
         group.add_option(*args, **kwargs)
 
-    def addOptionGroup(self, groupName, desc):
+    def addOptionGroup(self, groupName, desc=None, prepend=False):
         group = OptionGroup(self.parser, groupName, desc)
-        self.parser.add_option_group(group)
+	if not prepend:
+            self.parser.add_option_group(group)
+	else:
+            self.parser.option_groups.insert(0,group)
         self.optionGroupDict[groupName] = group
 
     def processArgs(self):
diff --git a/src/python/dm/common/cli/dmRestSessionCli.py b/src/python/dm/common/cli/dmRestSessionCli.py
index 2c8cfe097e2e6ea7cd43b56331cfa19e30631366..9b48e040752c1117af9364d0c99ff2ac1a262379 100755
--- a/src/python/dm/common/cli/dmRestSessionCli.py
+++ b/src/python/dm/common/cli/dmRestSessionCli.py
@@ -56,4 +56,4 @@ class DmRestSessionCli(DmRestCli):
 # Testing
 
 if __name__ == '__main__':
-        pass
+    pass
diff --git a/src/python/dm/common/constants/dmServiceConstants.py b/src/python/dm/common/constants/dmServiceConstants.py
index b74e76ee3ac4ca7fcb1ca20bc94bda4a0a2c13ab..95b987423a6f53d46ca905a4ceca4b635190378e 100755
--- a/src/python/dm/common/constants/dmServiceConstants.py
+++ b/src/python/dm/common/constants/dmServiceConstants.py
@@ -6,6 +6,6 @@ DM_SERVICE_PROTOCOL_HTTP = 'http'
 DM_SERVICE_PROTOCOL_HTTPS = 'https'
 
 DM_DAQ_MAX_RUN_TIME_IN_HOURS_KEY = 'maxRunTimeInHours'
-DM_DAQ_TARGET_DIRECTORY_KEY = 'targetDirectory'
+DM_DAQ_DEST_DIRECTORY_KEY = 'destDirectory'
 DM_DAQ_UPLOAD_DATA_DIRECTORY_ON_EXIT_KEY = 'uploadDataDirectoryOnExit'
-DM_DAQ_UPLOAD_TARGET_DIRECTORY_ON_EXIT_KEY = 'uploadTargetDirectoryOnExit'
+DM_DAQ_UPLOAD_DEST_DIRECTORY_ON_EXIT_KEY = 'uploadDestDirectoryOnExit'
diff --git a/src/python/dm/common/objects/observedFile.py b/src/python/dm/common/objects/observedFile.py
index 2ef2e31cc8bb0ac0504b9a687f64efcedae5904f..ffde9efca89516a3bf9d7aebacfc07381dcc9510 100755
--- a/src/python/dm/common/objects/observedFile.py
+++ b/src/python/dm/common/objects/observedFile.py
@@ -9,7 +9,7 @@ class ObservedFile(DmObject):
 
     DEFAULT_KEY_LIST = [ 'filePath', 'lastUpdateTime' ]
 
-    def __init__(self, dict={}, filePath=None, dataDirectory=None, experiment=None, targetDirectory=None):
+    def __init__(self, dict={}, filePath=None, dataDirectory=None, experiment=None, destDirectory=None):
         DmObject.__init__(self, dict)
         if filePath:
             self['filePath'] = filePath
@@ -18,9 +18,9 @@ class ObservedFile(DmObject):
             if filePath:
                 parseResult = urlparse.urlparse(dataDirectory)
                 self['experimentFilePath'] = os.path.relpath(filePath, parseResult.path)
-                if targetDirectory:
-                    self['targetDirectory'] = targetDirectory
-                    self['experimentFilePath'] = '%s/%s' % (targetDirectory, self['experimentFilePath'])
+                if destDirectory:
+                    self['destDirectory'] = destDirectory
+                    self['experimentFilePath'] = '%s/%s' % (destDirectory, self['experimentFilePath'])
   
         if experiment:
             self['experimentName'] = experiment.get('name')
diff --git a/src/python/dm/common/processing/plugins/fileTransferPlugin.py b/src/python/dm/common/processing/plugins/fileTransferPlugin.py
index 310962f60d727c0be35aeb53dd854816a5a69c84..a0c79eafcbf1af9170a435cdc85b5611d93af6bc 100755
--- a/src/python/dm/common/processing/plugins/fileTransferPlugin.py
+++ b/src/python/dm/common/processing/plugins/fileTransferPlugin.py
@@ -28,11 +28,11 @@ class FileTransferPlugin(FileProcessor):
     def processFile(self, fileInfo):
         filePath = fileInfo.get('filePath')
         dataDirectory = fileInfo.get('dataDirectory')
-        targetDirectory = fileInfo.get('targetDirectory')
+        destDirectory = fileInfo.get('destDirectory')
 
         storageHost = fileInfo.get('storageHost')
         storageDirectory = fileInfo.get('storageDirectory')
-        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, targetDirectory)
+        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, destDirectory)
         srcUrl = self.getSrcUrl(filePath, dataDirectory)
         self.start(src=srcUrl, dest=destUrl, templateInfo=fileInfo)
 
@@ -40,25 +40,25 @@ class FileTransferPlugin(FileProcessor):
         srcUrl = '%s/./%s' % (dataDirectory, os.path.relpath(filePath, dataDirectory))
         return srcUrl
     
-    def getDestUrl(self, filePath, dataDirectory, storageHost, storageDirectory, targetDirectory=None):
+    def getDestUrl(self, filePath, dataDirectory, storageHost, storageDirectory, destDirectory=None):
         if self.dest:
             destUrl = '%s/' % (self.dest)
         else:
             destUrl = '%s:%s/' % (storageHost, storageDirectory)
-        if targetDirectory:
-            destUrl = '%s/%s/' % (destUrl, targetDirectory)
+        if destDirectory:
+            destUrl = '%s/%s/' % (destUrl, destDirectory)
         return destUrl
     
     def getSrcDirUrl(self, dataDirectory):
         return '%s/' % dataDirectory
     
-    def getDestDirUrl(self, dataDirectory, storageHost, storageDirectory, targetDirectory=None):
+    def getDestDirUrl(self, dataDirectory, storageHost, storageDirectory, destDirectory=None):
         if self.dest:
             destUrl = '%s/' % (self.dest)
         else:
             destUrl = '%s:%s/' % (storageHost, storageDirectory)
-        if targetDirectory:
-            destUrl = '%s/%s/' % (destUrl, targetDirectory)
+        if destDirectory:
+            destUrl = '%s/%s/' % (destUrl, destDirectory)
         return destUrl
     
     def getFullCommand(self, src, dest, command=None):
diff --git a/src/python/dm/common/processing/plugins/gridftpFileTransferPlugin.py b/src/python/dm/common/processing/plugins/gridftpFileTransferPlugin.py
index 41957c3f0e2755e02d09e2c8e032f9920b1f0ea4..1b8544d48e2063858cb8c0b7aad0c594e98e6238 100755
--- a/src/python/dm/common/processing/plugins/gridftpFileTransferPlugin.py
+++ b/src/python/dm/common/processing/plugins/gridftpFileTransferPlugin.py
@@ -51,15 +51,15 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
             srcUrl = '%s/%s' % (self.src,filePath)
         return self.replaceSpecialCharacters(srcUrl)
     
-    def getDestUrl(self, filePath, dataDirectory, storageHost, storageDirectory, targetDirectory=None):
+    def getDestUrl(self, filePath, dataDirectory, storageHost, storageDirectory, destDirectory=None):
         (scheme, host, port, dirPath) = FtpUtility.parseFtpUrl(dataDirectory, defaultPort=self.DEFAULT_PORT)
         dirName = os.path.dirname(os.path.relpath(filePath, dirPath)).strip()
         fileName = os.path.basename(filePath)
         if self.dest:
             destUrl = '%s/%s/%s' % (self.dest, dirName, fileName)
         else:
-            if targetDirectory:
-                destUrl = 'sshftp://%s/%s/%s/%s/%s' % (storageHost, storageDirectory, targetDirectory, dirName, fileName)
+            if destDirectory:
+                destUrl = 'sshftp://%s/%s/%s/%s/%s' % (storageHost, storageDirectory, destDirectory, dirName, fileName)
             else:
                 destUrl = 'sshftp://%s/%s/%s/%s' % (storageHost, storageDirectory, dirName, fileName)
         return self.replaceSpecialCharacters(destUrl)
@@ -70,7 +70,7 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
         storageHost = uploadInfo['storageHost']
         storageDirectory = uploadInfo['storageDirectory']
         dataDirectory = uploadInfo['dataDirectory']
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
         self.logger.debug('Upload info: %s' % uploadInfo)
         # Original data directory may contain host/port
         (scheme, host, port, replacementDirPath) = FtpUtility.parseFtpUrl(dataDirectory)
@@ -78,8 +78,8 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
         self.logger.debug('Number of original files: %s' % len(filePathsDict))
         ftpUtility = SftpUtility(storageHost)
         destDirectory = storageDirectory
-        if targetDirectory:
-            destDirectory = '%s/%s/' % (destDirectory, targetDirectory)
+        if destDirectory:
+            destDirectory = '%s/%s/' % (destDirectory, destDirectory)
         storageFilePathsDict = {}
         try:
             self.logger.debug('Looking for existing files in %s' % destDirectory)
@@ -123,9 +123,9 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
         experimentName = fileInfo.get('experimentName')
         storageHost = fileInfo.get('storageHost')
         storageDirectory = fileInfo.get('storageDirectory')
-        targetDirectory = fileInfo.get('targetDirectory')
+        destDirectory = fileInfo.get('destDirectory')
 
-        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, targetDirectory)
+        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, destDirectory)
         srcUrl = self.getSrcUrl(filePath, dataDirectory)
 
         # Calculate checksum
@@ -173,13 +173,13 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
             srcUrl = '%s/%s/' % (self.src,dataDirectory)
         return srcUrl
     
-    def getDestDirUrl(self, dataDirectory, storageHost, storageDirectory, targetDirectory=None):
+    def getDestDirUrl(self, dataDirectory, storageHost, storageDirectory, destDirectory=None):
         if self.dest:
             destUrl = '%s/' % (self.dest)
         else:
             destUrl = 'sshftp://%s/%s/' % (storageHost, storageDirectory)
-        if targetDirectory:
-            destUrl = '%s/%s/' % (destUrl, targetDirectory)
+        if destDirectory:
+            destUrl = '%s/%s/' % (destUrl, destDirectory)
         return destUrl
 
     def processDirectory(self, directoryInfo):
@@ -188,9 +188,9 @@ class GridftpFileTransferPlugin(FileTransferPlugin):
         experimentName = uploadInfo.get('experimentName')
         storageHost = uploadInfo.get('storageHost')
         storageDirectory = uploadInfo.get('storageDirectory')
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
 
-        destUrl = self.getDestDirUrl(dataDirectory, storageHost, storageDirectory, targetDirectory)
+        destUrl = self.getDestDirUrl(dataDirectory, storageHost, storageDirectory, destDirectory)
         srcUrl = self.getSrcDirUrl(dataDirectory)
 
         # Transfer directory
diff --git a/src/python/dm/common/processing/plugins/mongoDbFileCatalogPlugin.py b/src/python/dm/common/processing/plugins/mongoDbFileCatalogPlugin.py
index e7fe8d6978781500c806ec63a1cfc3f2ed78cc8a..b8801fe4dc7f2536db89d4f57c5998598b5a1642 100755
--- a/src/python/dm/common/processing/plugins/mongoDbFileCatalogPlugin.py
+++ b/src/python/dm/common/processing/plugins/mongoDbFileCatalogPlugin.py
@@ -115,12 +115,12 @@ class MongoDbFileCatalogPlugin(FileProcessor):
 
         uploadId = uploadInfo.get('id')
         dataDirectory = uploadInfo.get('dataDirectory')
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
 
         nProcessedFiles = 0
         nFiles = len(filePathsDict)
         for (filePath,filePathDict) in filePathsDict.items():
-            fileInfo = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, targetDirectory=targetDirectory)
+            fileInfo = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, destDirectory=destDirectory)
             fileInfo.update(filePathDict)
             fileInfo['daqInfo'] = daqInfo
             fileInfo['uploadId'] = uploadId
diff --git a/src/python/dm/common/processing/plugins/rsyncFileTransferPlugin.py b/src/python/dm/common/processing/plugins/rsyncFileTransferPlugin.py
index a85bfaf7165ebc20a23235ec35911427b3dd2a27..66c3806b402209a8569b951b64b2e2725a83f9f1 100755
--- a/src/python/dm/common/processing/plugins/rsyncFileTransferPlugin.py
+++ b/src/python/dm/common/processing/plugins/rsyncFileTransferPlugin.py
@@ -34,10 +34,10 @@ class RsyncFileTransferPlugin(FileTransferPlugin):
         storageDirectory = uploadInfo['storageDirectory']
         storageHost = uploadInfo['storageHost']
         dataDirectory = uploadInfo['dataDirectory']
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
         dryRunCommand = '%s %s/ %s:%s' % (self.DRY_RUN_COMMAND, dataDirectory, storageHost, storageDirectory)
-        if targetDirectory:
-            dryRunCommand = '%s/%s/' % (dryRunCommand, targetDirectory)
+        if destDirectory:
+            dryRunCommand = '%s/%s/' % (dryRunCommand, destDirectory)
 
         subprocess = DmSubprocess.getSubprocess(dryRunCommand)
         subprocess.run()
@@ -61,8 +61,8 @@ class RsyncFileTransferPlugin(FileTransferPlugin):
         experimentName = fileInfo.get('experimentName')
         storageHost = fileInfo.get('storageHost')
         storageDirectory = fileInfo.get('storageDirectory')
-        targetDirectory = fileInfo.get('targetDirectory')
-        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, targetDirectory)
+        destDirectory = fileInfo.get('destDirectory')
+        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, destDirectory)
         # Use relative path with respect to data directory as a source
         srcUrl = self.getSrcUrl(filePath, dataDirectory)
 
@@ -75,8 +75,8 @@ class RsyncFileTransferPlugin(FileTransferPlugin):
         # Transfer file
         self.logger.debug('Starting transfer: %s -> %s' % (srcUrl, destUrl))
         command = self.command
-        if targetDirectory:
-            destDirectory = '%s/%s' % (storageDirectory,targetDirectory)
+        if destDirectory:
+            destDirectory = '%s/%s' % (storageDirectory,destDirectory)
             command = self.RSYNC_WITH_MKDIR_COMMAND % destDirectory
         self.start(src=srcUrl, dest=destUrl, command=command, templateInfo=fileInfo, cwd=dataDirectory)
 
@@ -107,16 +107,16 @@ class RsyncFileTransferPlugin(FileTransferPlugin):
         experimentName = uploadInfo.get('experimentName')
         storageHost = uploadInfo.get('storageHost')
         storageDirectory = uploadInfo.get('storageDirectory')
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
 
-        destUrl = self.getDestDirUrl(dataDirectory, storageHost, storageDirectory, targetDirectory)
+        destUrl = self.getDestDirUrl(dataDirectory, storageHost, storageDirectory, destDirectory)
         srcUrl = self.getSrcDirUrl(dataDirectory)
 
         # Transfer directory
         self.logger.debug('Starting transfer: %s -> %s' % (srcUrl, destUrl))
         command = self.DIRECTORY_TRANSFER_COMMAND
-        if targetDirectory:
-            destDirectory = '%s/%s' % (storageDirectory,targetDirectory)
+        if destDirectory:
+            destDirectory = '%s/%s' % (storageDirectory,destDirectory)
             command = self.DIRECTORY_TRANSFER_WITH_MKDIR_COMMAND % destDirectory
         self.start(src=srcUrl, dest=destUrl, command=command, templateInfo=uploadInfo, cwd=dataDirectory)
 
diff --git a/src/python/dm/common/processing/plugins/rsyncWithChecksumAndDeleteFileTransferPlugin.py b/src/python/dm/common/processing/plugins/rsyncWithChecksumAndDeleteFileTransferPlugin.py
deleted file mode 100755
index 049ddf4762d03f57ca4a6ef8894fe356460f444a..0000000000000000000000000000000000000000
--- a/src/python/dm/common/processing/plugins/rsyncWithChecksumAndDeleteFileTransferPlugin.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-import os
-from dm.common.utility.loggingManager import LoggingManager
-from dm.common.utility.osUtility import OsUtility
-from dm.common.utility.fileUtility import FileUtility
-from dm.common.exceptions.fileProcessingError import FileProcessingError
-from dm.common.processing.plugins.fileTransferPlugin import FileTransferPlugin
-from dm.ds_web_service.api.dsRestApiFactory import DsRestApiFactory
-
-class RsyncWithChecksumAndDeleteFileTransferPlugin(FileTransferPlugin):
-
-    COMMAND = 'rsync -arvlPR'
-
-    def __init__(self, src=None, dest=None):
-        FileTransferPlugin.__init__(self, self.COMMAND, src, dest)
-        self.dsFileApi = DsRestApiFactory.getFileDsApi()
-        self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
-
-    def processFile(self, fileInfo):
-        filePath = fileInfo.get('filePath')
-        dataDirectory = fileInfo.get('dataDirectory')
-        experimentFilePath = fileInfo.get('experimentFilePath')
-        experimentName = fileInfo.get('experimentName')
-        storageHost = fileInfo.get('storageHost')
-        storageDirectory = fileInfo.get('storageDirectory')
-        targetDirectory = fileInfo.get('targetDirectory')
-        destUrl = self.getDestUrl(filePath, dataDirectory, storageHost, storageDirectory, targetDirectory)
-        # Use relative path with respect to data directory as a source
-        srcUrl = self.getSrcUrl(filePath, dataDirectory)
-
-        # Calculate checksum
-        FileUtility.statFile(filePath, fileInfo)
-        FileUtility.getMd5Sum(filePath, fileInfo)
-        self.logger.debug('File info before transfer: %s' % fileInfo)
-
-        # Transfer file
-        self.start(src=srcUrl, dest=destUrl, templateInfo=fileInfo, cwd=dataDirectory)
-        # Get remote checksum
-        fileInfo2 = {}
-        fileInfo2['experimentFilePath'] = experimentFilePath
-        fileInfo2['experimentName'] = experimentName
-        fileMetadata = self.dsFileApi.statFile(experimentFilePath, experimentName, fileInfo2)
-        self.logger.debug('File stat after transfer: %s' % fileMetadata)
-
-        # Verify checksum
-        if fileMetadata.get('md5Sum') != fileInfo.get('md5Sum'):
-            self.logger.error('Checksum mismatch for file: %s' % filePath)
-            raise FileProcessingError('Checksum mismatch detected for file: %s' % filePath)
-
-        # Remove file
-        self.logger.debug('Checksum test passed, deleting file %s' % filePath)
-        OsUtility.removeFile(srcUrl)
-
-#######################################################################
-# Testing.
-if __name__ == '__main__':
-    ft = RsyncWithChecksumAndDeleteFileTransferPlugin('/tmp/xyz', '/tmp/xyz2')
-    ft.start()
-    print 'StdOut: ', ft.getStdOut()
-    print 'StdErr: ', ft.getStdErr()
-    print 'Exit Status: ', ft.getExitStatus()
diff --git a/src/python/dm/daq_web_service/api/experimentDaqApi.py b/src/python/dm/daq_web_service/api/experimentDaqApi.py
index fc21edbfc5ee3991ce4d56353f8f526b56eff68b..cb68f5422f6594f5479db7d37b09597c745f00da 100755
--- a/src/python/dm/daq_web_service/api/experimentDaqApi.py
+++ b/src/python/dm/daq_web_service/api/experimentDaqApi.py
@@ -59,10 +59,10 @@ class ExperimentDaqApi(DaqRestApi):
         :param daqInfo: dictionary of optional metadata (key/value pairs) describing data acquisition; several keys have special meaning:
 
            - *processHiddenFiles* (bool): if set to True, hidden files will be processed
-           - *targetDirectory* (str): specifies directory path relative to experiment root directory where files will be stored
+           - *destDirectory* (str): specifies directory path relative to experiment root directory where files will be stored
            - *maxRunTimeInHours* (int): specifies maximum data acquisition run time in hours
            - *uploadDataDirectoryOnExit* (str): specifies URL of the data directory that should be uploaded after data acquisition completes
-           - *uploadTargetDirectoryOnExit* (str): specifies directory path relative to experiment root directory where uploaded files should be stored
+           - *uploadDestDirectoryOnExit* (str): specifies directory path relative to experiment root directory where uploaded files should be stored
            - *skipPlugins* (str): comma-separated list of plugins which should not process files
 
         :type daqInfo: dict
@@ -193,7 +193,7 @@ class ExperimentDaqApi(DaqRestApi):
 
            - *processHiddenFiles* (bool): if set to True, hidden files will be processed
            - *reprocessFiles* (bool): if set to True, files will be uploaded regardless of whether or not they already exist in storage and have not changed
-           - *targetDirectory* (str): specifies directory path relative to experiment root directory where files will be stored
+           - *destDirectory* (str): specifies directory path relative to experiment root directory where files will be stored
            - *processingMode* (str): specifies processing mode, and can be set to "files" (service plugins process individual files one at a time) or "directory" (service plugins process entire directory at once; works faster for uploads of a large number of small files)
            - *skipPlugins* (str): comma-separated list of plugins which should not process files
         :type daqInfo: dict
diff --git a/src/python/dm/daq_web_service/cli/daqWebServiceSessionCli.py b/src/python/dm/daq_web_service/cli/daqWebServiceSessionCli.py
index e2e74172d576b65fb5480dc92654034390ae8e6f..48b090e643ed5991b2ec2ea49d3b94843065f216 100755
--- a/src/python/dm/daq_web_service/cli/daqWebServiceSessionCli.py
+++ b/src/python/dm/daq_web_service/cli/daqWebServiceSessionCli.py
@@ -8,7 +8,6 @@ from dm.common.utility.configurationManager import ConfigurationManager
 class DaqWebServiceSessionCli(DmRestSessionCli):
     """ DM DAQ web service session cli class. """
 
-    DM_FILE_SERVER_URL_ENV_VAR = 'DM_FILE_SERVER_URL'
     DEFAULT_SESSION_CACHE_FILE = OsUtility.getUserHomeDir() + '/.dm/.daq.session.cache'
 
     def __init__(self, validArgCount=0):
@@ -29,9 +28,19 @@ class DaqWebServiceSessionCli(DmRestSessionCli):
 
     def getDataDirectory(self):
         dataDirectory = self.options.dataDirectory
-        # Make sure data directory already does not have url scheme
-        if dataDirectory and dataDirectory.find('://') < 0:
-            fileServerUrl = os.environ.get(self.DM_FILE_SERVER_URL_ENV_VAR, '')
+        if not dataDirectory:
+            return None
+        if dataDirectory.find('://') < 0:
+            fileServerUrl = os.environ.get('DM_FILE_SERVER_URL')
             dataDirectory = '%s%s' % (fileServerUrl, dataDirectory)
-        return dataDirectory
+        replacementMap = os.environ.get('DM_DATA_DIRECTORY_MAP', '')
+        (scheme, host, port, dirPath) = FtpUtility.parseUrl(dataDirectory)
+        if dirPath and replacementMap:
+            # Map entries are expected to be in the form
+            # <original>|<replacement>;<original>|<replacement>;...
+            for entry in replacementMap.split(';'):
+                original = entry.split('|')[0]
+                replacement = entry.split('|')[1]
+                dirPath = dataDirectory.replace(original,replacement)
+        return FtpUtility.assembleUrl(scheme, host, port, dirPath)
 
diff --git a/src/python/dm/daq_web_service/cli/startDaqCli.py b/src/python/dm/daq_web_service/cli/startDaqCli.py
index 9124827971850c432454f662a6060b7d7032c848..00c3c991f3e1bc042a1e1675d920055d37863e7d 100755
--- a/src/python/dm/daq_web_service/cli/startDaqCli.py
+++ b/src/python/dm/daq_web_service/cli/startDaqCli.py
@@ -11,11 +11,12 @@ class StartDaqCli(DaqWebServiceSessionCli):
     def __init__(self):
         DaqWebServiceSessionCli.__init__(self, validArgCount=self.ANY_NUMBER_OF_POSITIONAL_ARGS)
         self.addOption('', '--experiment', dest='experimentName', help='Experiment name.')
-        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory. If specified string does not already contain file server URL, value of the %s environment variable will be prepended to it.' % self.DM_FILE_SERVER_URL_ENV_VAR)
-        self.addOption('', '--target-directory', dest='targetDirectory', help='Target directory relative to experiment root path.')
-        self.addOption('', '--run-time', dest='runTime', help='Maximum run time; it must be specified in hours (h) or days (d). Examples: "8h", "14d".')
+        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory URL.')
+        self.addOption('', '--dest-directory', dest='destDirectory',
+	help='Destination directory relative to experiment root path.')
+        self.addOption('', '--duration', dest='duration', help='DAQ duration; it must be specified in hours (h) or days (d). Examples: "8h", "14d".')
         self.addOption('', '--upload-data-directory-on-exit', dest='uploadDataDirectoryOnExit', help='Data directory that will be uploaded automatically after DAQ is stopped.')
-        self.addOption('', '--upload-target-directory-on-exit', dest='uploadTargetDirectoryOnExit', help='Target directory relative to experiment root path for automatic upload after DAQ is stopped. Requires upload data directory to be specified.')
+        self.addOption('', '--upload-dest-directory-on-exit', dest='uploadDestDirectoryOnExit', help='Destination directory relative to experiment root path for automatic upload after DAQ is stopped. Requires upload data directory to be specified.')
         self.addOption('', '--process-hidden', dest='processHidden', action='store_true', default=False, help='Process hidden source files.')
 
     def checkArgs(self):
@@ -27,30 +28,30 @@ class StartDaqCli(DaqWebServiceSessionCli):
     def updateDaqInfoFromOptions(self, daqInfo):
         if self.options.processHidden:
             daqInfo['processHiddenFiles'] = True
-        if self.options.runTime:
-            runTime = self.options.runTime
-            if runTime.endswith('h'):
-                daqInfo['maxRunTimeInHours'] = int(runTime[0:-1])
-            elif runTime.endswith('d'):
-                daqInfo['maxRunTimeInHours'] = int(runTime[0:-1])*self.HOURS_PER_DAY
+        if self.options.duration:
+            duration = self.options.duration
+            if duration.endswith('h'):
+                daqInfo['maxRunTimeInHours'] = int(duration[0:-1])
+            elif duration.endswith('d'):
+                daqInfo['maxRunTimeInHours'] = int(duration[0:-1])*self.HOURS_PER_DAY
             else:
                 raise InvalidRequest('Maximum run time must contain valid unit specifier: "h" for hours or "d" for days.')
-        if self.options.targetDirectory:
-            daqInfo['targetDirectory'] = self.options.targetDirectory 
+        if self.options.destDirectory:
+            daqInfo['destDirectory'] = self.options.destDirectory 
         if self.options.uploadDataDirectoryOnExit:
             daqInfo['uploadDataDirectoryOnExit'] = self.options.uploadDataDirectoryOnExit
-        if self.options.uploadTargetDirectoryOnExit:
+        if self.options.uploadDestDirectoryOnExit:
             if not self.options.uploadDataDirectoryOnExit:
-                raise InvalidRequest('Upload target directory on exit requires that upload data directory is specified as well.')
-            daqInfo['uploadTargetDirectoryOnExit'] = self.options.uploadTargetDirectoryOnExit
+                raise InvalidRequest('Upload destination directory on exit requires that upload data directory is specified as well.')
+            daqInfo['uploadDestDirectoryOnExit'] = self.options.uploadDestDirectoryOnExit
 
     def runCommand(self):
         self.parseArgs(usage="""
     dm-start-daq --experiment=EXPERIMENTNAME --data-directory=DATADIRECTORY
-        [--run-time=RUNTIME]
-        [--target-directory=TARGETDIRECTORY]
+        [--duration=DURATION]
+        [--dest-directory=DESTDIRECTORY]
         [--upload-data-directory-on-exit=UPLOADDATADIRECTORYONEXIT]
-        [--upload-target-directory-on-exit=UPLOADTARGETDIRECTORYONEXIT]
+        [--upload-dest-directory-on-exit=UPLOADDESTDIRECTORYONEXIT]
         [--process-hidden]
         [key1:value1, key2:value2, ...]
 
diff --git a/src/python/dm/daq_web_service/cli/stopDaqCli.py b/src/python/dm/daq_web_service/cli/stopDaqCli.py
index 0c956a05c094b5d1e8d1abc1eddf158da6177c25..66d934c0a1d7ef8b2dafb629baed2e8f00e58dc6 100755
--- a/src/python/dm/daq_web_service/cli/stopDaqCli.py
+++ b/src/python/dm/daq_web_service/cli/stopDaqCli.py
@@ -8,7 +8,7 @@ class StopDaqCli(DaqWebServiceSessionCli):
     def __init__(self):
         DaqWebServiceSessionCli.__init__(self)
         self.addOption('', '--experiment', dest='experimentName', help='Experiment name.')
-        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory. If specified string does not already contain file server URL, value of the %s environment variable will be prepended to it.' % self.DM_FILE_SERVER_URL_ENV_VAR)
+        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory URL.')
 
     def checkArgs(self):
         if self.options.experimentName is None:
diff --git a/src/python/dm/daq_web_service/cli/uploadCli.py b/src/python/dm/daq_web_service/cli/uploadCli.py
index d690ed54edf431ce155b4303cd2e1e7c779dd2f9..89e0b3e6cc352cf7ebffc24c07879138516b1949 100755
--- a/src/python/dm/daq_web_service/cli/uploadCli.py
+++ b/src/python/dm/daq_web_service/cli/uploadCli.py
@@ -9,8 +9,8 @@ class UploadCli(DaqWebServiceSessionCli):
     def __init__(self):
         DaqWebServiceSessionCli.__init__(self, validArgCount=self.ANY_NUMBER_OF_POSITIONAL_ARGS)
         self.addOption('', '--experiment', dest='experimentName', help='Experiment name.')
-        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory. If specified string does not already contain file server URL, value of the %s environment variable will be prepended to it.' % self.DM_FILE_SERVER_URL_ENV_VAR)
-        self.addOption('', '--target-directory', dest='targetDirectory', help='Target directory relative to experiment root path.')
+        self.addOption('', '--data-directory', dest='dataDirectory', help='Experiment data directory URL.')
+        self.addOption('', '--dest-directory', dest='destDirectory', help='Destination directory relative to experiment root path.')
         self.addOption('', '--reprocess', dest='reprocess', action='store_true', default=False, help='Reprocess source files that are already in storage, even if they have not been modified.')
         self.addOption('', '--process-hidden', dest='processHidden', action='store_true', default=False, help='Process hidden source files.')
         self.addOption('', '--processing-mode', dest='processingMode', default=dmProcessingMode.DM_PROCESSING_MODE_FILES, help='Processing mode can be one of %s (default: %s). In the "%s" mode files are processed individually, while in the "%s" mode processing plugins work on directories (if possible).' % (dmProcessingMode.DM_ALLOWED_PROCESSING_MODE_LIST, dmProcessingMode.DM_PROCESSING_MODE_FILES, dmProcessingMode.DM_PROCESSING_MODE_FILES, dmProcessingMode.DM_PROCESSING_MODE_DIRECTORY))
@@ -33,13 +33,13 @@ class UploadCli(DaqWebServiceSessionCli):
         if self.options.skipPlugins:
             daqInfo['skipPlugins'] = self.options.skipPlugins
         daqInfo['processingMode'] = self.options.processingMode
-        if self.options.targetDirectory:
-            daqInfo['targetDirectory'] = self.options.targetDirectory
+        if self.options.destDirectory:
+            daqInfo['destDirectory'] = self.options.destDirectory
  
     def runCommand(self):
         self.parseArgs(usage="""
     dm-upload --experiment=EXPERIMENTNAME --data-directory=DATADIRECTORY
-        [--target-directory=TARGETDIRECTORY]
+        [--dest-directory=DESTDIRECTORY]
         [--reprocess]
         [--process-hidden]
         [--processing-mode=PROCESSINGMODE]
diff --git a/src/python/dm/daq_web_service/service/impl/experimentSessionControllerImpl.py b/src/python/dm/daq_web_service/service/impl/experimentSessionControllerImpl.py
index e8e60c8a03474325aaefa051deff33a821549dc6..4c9d1db6432892a9e560e46ce84602e6b0ccbc68 100755
--- a/src/python/dm/daq_web_service/service/impl/experimentSessionControllerImpl.py
+++ b/src/python/dm/daq_web_service/service/impl/experimentSessionControllerImpl.py
@@ -88,10 +88,10 @@ class ExperimentSessionControllerImpl(DmObjectManager):
             self.logger.debug('Attempting automatic upload on exit for DAQ id %s, experiment %s' % (daqId, experimentName))
             daqInfo2 = {}
             daqInfo2['originalDaqId'] = daqId
-            uploadTargetDirectoryOnExit = daqInfo.get('uploadTargetDirectoryOnExit')
-            if uploadTargetDirectoryOnExit:
-                self.logger.debug('Automatic upload on exit for DAQ id %s (experiment %s) is using target directory: %s' % (daqId, experimentName, uploadTargetDirectoryOnExit))
-                daqInfo2['targetDirectory'] = uploadTargetDirectoryOnExit
+            uploadDestDirectoryOnExit = daqInfo.get('uploadDestDirectoryOnExit')
+            if uploadDestDirectoryOnExit:
+                self.logger.debug('Automatic upload on exit for DAQ id %s (experiment %s) is using dest directory: %s' % (daqId, experimentName, uploadDestDirectoryOnExit))
+                daqInfo2['destDirectory'] = uploadDestDirectoryOnExit
        
             try:
                 uploadInfo = self.uploadFiles(experimentName, uploadDataDirectoryOnExit, daqInfo2)
@@ -176,7 +176,7 @@ class ExperimentSessionControllerImpl(DmObjectManager):
         uploadId = uploadInfo.get('id')
         self.logger.debug('Preparing upload id: %s' % uploadId)
         dataDirectory = uploadInfo.get('dataDirectory')
-        targetDirectory = uploadInfo.get('targetDirectory')
+        destDirectory = uploadInfo.get('destDirectory')
         fileProcessingManager = FileProcessingManager.getInstance()
 
         try:
@@ -223,7 +223,7 @@ class ExperimentSessionControllerImpl(DmObjectManager):
                     self.logger.debug('Upload %s has %s files waiting for upload, will not add any more for %s seconds' % (uploadId, nWaitingFiles, self.UPLOAD_CHUNK_REFRESH_IN_SECONDS))
                     time.sleep(self.UPLOAD_CHUNK_REFRESH_IN_SECONDS)
 
-                fileInfo = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, targetDirectory=targetDirectory)
+                fileInfo = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, destDirectory=destDirectory)
                 fileInfo.update(filePathDict)
                 fileInfo['daqInfo'] = daqInfo
                 fileInfo['uploadId'] = uploadId
diff --git a/src/python/dm/daq_web_service/service/impl/fileSystemObserver.py b/src/python/dm/daq_web_service/service/impl/fileSystemObserver.py
index dce1dafaf3864b68ff07888cd5dea1266142b6e1..75e71bf655afece8cbd72656c6b1c42a0edb36c9 100755
--- a/src/python/dm/daq_web_service/service/impl/fileSystemObserver.py
+++ b/src/python/dm/daq_web_service/service/impl/fileSystemObserver.py
@@ -105,9 +105,9 @@ class FileSystemObserver(threading.Thread,Singleton):
 
         daqId = daqInfo['id']
         observedFile = self.observedFileMap.get(filePath)
-        targetDirectory = daqInfo.get('targetDirectory')
+        destDirectory = daqInfo.get('destDirectory')
         if not observedFile:
-            observedFile = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, targetDirectory=targetDirectory)
+            observedFile = ObservedFile(filePath=filePath, dataDirectory=dataDirectory, experiment=experiment, destDirectory=destDirectory)
             observedFile['daqInfo'] = daqInfo.toDictWithOriginalKeys()
             observedFile['statusMonitor'] = daqInfo
             self.observedFileMap[filePath] = observedFile
diff --git a/src/python/dm/ds_web_service/cli/addExperimentCli.py b/src/python/dm/ds_web_service/cli/addExperimentCli.py
index 70c410592a5df6ea57833e49eaeab1eef1cd074d..8d4270e581c0ff2a8638142b65e9ae53bfac62e6 100755
--- a/src/python/dm/ds_web_service/cli/addExperimentCli.py
+++ b/src/python/dm/ds_web_service/cli/addExperimentCli.py
@@ -78,14 +78,19 @@ class AddExperimentCli(DsWebServiceSessionCli):
         return proposalId
 
     def getUsers(self):
+        # Return list of users and beamline managers that can access data
         users = self.options.users
         if users:
-            # Remove duplicates by converting into set
-            users = list(set(users.split(',')))
-            
+            users = users.split(',')
         else:
             users = []
-        return users
+        beamlineManagers = ConfigurationManager.getInstance().getBeamlineManagers()
+        if beamlineManagers:
+            beamlineManagers = beamlineManagers.split(',')
+        else:
+            beamlineManagers = []
+        # Remove duplicates by converting into set
+        return list(set(users+beamlineManagers))
 
     def runCommand(self):
         self.parseArgs(usage="""