diff --git a/Code/Mantid/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py b/Code/Mantid/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
index fddcb3e36f0d54f608892d17a744acc004bcfeeb..2069d9b273826fb669b8b0e334efb4bec05f06fe 100644
--- a/Code/Mantid/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
+++ b/Code/Mantid/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
@@ -10,7 +10,7 @@ from xml.dom import minidom
 # the list of instruments this configuration is applicable to
 INELASTIC_INSTRUMENTS = ['MAPS','LET','MERLIN','MARI','HET']
 # the list of the parameters, which can be replaced if found in user files
-USER_PROPERTIES=['$instrument$', '$cycle$', '$start_date$', '$rb_folder']
+USER_PROPERTIES=['instrument', 'cycleID', 'start_date', 'rb_folder']
 
 class UserProperties(object):
     """Helper class to define & retrieve user properties
@@ -19,33 +19,37 @@ class UserProperties(object):
     def __init__(self,user_id=None):
         """ None is done for com"""
         self._user_id = str(user_id)
-        self.instrument={}
-        self.rb_dir = {}
-        self.cycle_IDlist={}
-        self.start_dates = {}
+        self._instrument={}
+        self._rb_dirs = {}
+        self._cycle_IDs={}
+        self._start_dates = {}
         self._recent_dateID=None
 
 #
     def set_user_properties(self,instrument,start_date,cycle,rb_folder):
-        """Define the information, user office provides about user. The info has the form:
+        """Define the information, user office provides about user. 
+
+           The info has the form:
            instrument -- string with full instrument name
-           date       -- experiment start date in the form YYYYMMDD
-           cycle      -- the cycle id in the form CYCLEYYYYN where N is the cycle number within the year
-           rb_folder  -- the working folder available for all users and IS participating in the experiment.
+           date       -- string with experiment start date in the form YYYYMMDD
+           cycle      -- string with the cycle id in the form CYCLEYYYYN 
+                         where N is the cycle number within the year
+           rb_folder  -- string containing the full path to working folder available 
+                        for all users and IS participating in the experiment.
         """
         self.check_input(instrument,start_date,cycle,rb_folder)
         #when user starts
         recent_date = date(int(start_date[0:4]),int(start_date[4:6]),int(start_date[6:8]))
         recent_date_id = str(recent_date)
-        self.start_dates[recent_date_id]=recent_date
+        self._start_dates[recent_date_id]=recent_date
 
         # a data which define the cycle ID e.g 2014_3 or something
-        self.cycle_IDlist[recent_date_id] = (str(cycle[5:9]),str(cycle[9:10]))
-        self.instrument[recent_date_id]   = str(instrument).upper()
-        self.rb_dir[recent_date_id]       = rb_folder
+        self._cycle_IDs[recent_date_id] = (str(cycle[5:9]),str(cycle[9:10]))
+        self._instrument[recent_date_id]   = str(instrument).upper()
+        self._rb_dirs[recent_date_id]       = rb_folder
         if self._recent_dateID:
-            max_date = self.start_dates[self._recent_dateID]
-            for date_key,a_date in self.start_dates.iteritems():
+            max_date = self._start_dates[self._recent_dateID]
+            for date_key,a_date in self._start_dates.iteritems():
                 if a_date>max_date:
                     self._recent_dateID = date_key
                     max_date = a_date
@@ -53,43 +57,59 @@ class UserProperties(object):
             self._recent_dateID = recent_date_id
 
     def replace_variables(self,data_string):
-
+        str_parts = data_string.split('$')
+        for prop in USER_PROPERTIES:
+            try:
+                ind = str_parts.index(prop)
+            except :
+                ind = None
+            if not ind is None:
+               str_parts[ind] = str(getattr(self,prop))
+        data_string = "".join(str_parts)
         return data_string        
 #
     @property
     def start_date(self):
         """Last start date"""
         if self._recent_dateID:
-            return  self.start_dates[self._recent_dateID]
+            return  self._start_dates[self._recent_dateID]
         else:
             raise RuntimeError("User's experiment date is not defined. User undefined")
-#
+ #
     @property
-    def last_instrument(self):
+    def instrument(self):
         """return instrument used in last actual experiment"""
         if self._recent_dateID:
-            return  self.instrument[self._recent_dateID]
+            return  self._instrument[self._recent_dateID]
         else:
             raise RuntimeError("User's experiment date is not defined. User undefined")
 #
     @property
-    def last_rbdir(self):
+    def rb_dir(self):
         """return rb folder used in last actual instrument"""
         if self._recent_dateID:
-            return  self.rb_dir[self._recent_dateID]
+            return  self._rb_dirs[self._recent_dateID]
         else:
             raise RuntimeError("User's experiment date is not defined. User undefined")
 #
     @property
-    def last_cycleID(self):
+    def cycleID(self):
+        """return last cycleID the user is participating"""
+        if self._recent_dateID:
+            year,num =self._cycle_IDs[self._recent_dateID]
+            return  "{0}_{1}".format(year,num)
+        else:
+            raise RuntimeError("User's experiment date is not defined. User undefined")
+    @property
+    def cycle(self):
         """return last cycle the user is participating"""
         if self._recent_dateID:
-            return  self.cycle_IDlist[self._recent_dateID]
+            return  self._cycle_IDs[self._recent_dateID]
         else:
             raise RuntimeError("User's experiment date is not defined. User undefined")
 #
     @property
-    def user_id(self):
+    def userID(self):
         return self._user_id
 
     def check_input(self,instrument,start_date,cycle,rb_folder):
@@ -255,19 +275,19 @@ class MantidConfigDirectInelastic(object):
     def _define_fullpath_to_copy(self,short_source_file=None,short_target_file=None):
         """Append full path to source and target files """
 
-        InstrName = self._user.last_instrument
+        InstrName = self._user.instrument
         rb_folder = self._user.rb_dir
         if short_source_file is None:
             short_source_file = self._sample_reduction_file(InstrName)
         if short_target_file is None:
-            CycleID = self._user.last_cycleID
+            CycleID = self._user.cycleID
             short_target_file = self._target_reduction_file(InstrName,CycleID)
 
 
         source_path = os.path.join(self._script_repo,'direct_inelastic',InstrName.upper())
-        full_source = os.path.join(source_path,source_file)
+        full_source = os.path.join(source_path,short_source_file)
 
-        full_target = os.path.join(rb_folder,target_file)
+        full_target = os.path.join(rb_folder,short_target_file)
         return full_source,full_target
 
 #
@@ -383,7 +403,7 @@ class MantidConfigDirectInelastic(object):
     def init_user(self,fedid,theUser):
         """Define settings, specific to a user"""
         #
-        for instr in theUser.instrument.values():
+        for instr in theUser._instrument.values():
             if not self.is_inelastic(instr):
                 raise RuntimeError('Instrument {0} is not among acceptable instruments'.format(instrument))
         self._user=theUser
@@ -392,14 +412,14 @@ class MantidConfigDirectInelastic(object):
         user_folder = os.path.join(self._home_path,self._fedid)
         if not os.path.exists(user_folder):
             raise RuntimeError("User with fedID {0} does not exist. Create such user folder first".format(fedid))
-        for rb_folder in theUser.rb_dir.values():
+        for rb_folder in theUser._rb_dirs.values():
             if not os.path.exists(str(rb_folder)):
                 raise RuntimeError("Experiment folder with {0} does not exist. Create such folder first".format(rb_folder))
         #
         # how to check cycle folders, they may not be available
         self._cycle_data_folder=set()
-        for date_key,folder_id in theUser.cycle_IDlist.items():
-            self._cycle_data_folder.add(self.get_data_folder_name(theUser.instrument[date_key],folder_id))
+        for date_key,folder_id in theUser._cycle_IDs.items():
+            self._cycle_data_folder.add(self.get_data_folder_name(theUser._instrument[date_key],folder_id))
         # Initialize configuration settings
         self._dynamic_configuration = copy.deepcopy(self._dynamic_options_base)
         self._init_config()
@@ -427,7 +447,7 @@ class MantidConfigDirectInelastic(object):
     def _set_default_inst(self):
         """Set up last instrument, deployed by user"""
         if self._user:
-            InstrName = self._user.last_instrument
+            InstrName = self._user.instrument
             self._dynamic_configuration.append('default.instrument={0}'.format(InstrName))
         else:
             self._dynamic_configuration.append('default.instrument={0}'.format('MARI'))
@@ -449,7 +469,7 @@ class MantidConfigDirectInelastic(object):
 
         # define and append user scripts search path
         user_path_part = copy.deepcopy(self._python_user_scripts)
-        for instr in self._user.instrument.values():
+        for instr in self._user._instrument.values():
             user_path_part.add(os.path.join('direct_inelastic',instr.upper()))
         for part in user_path_part:
             path +=';'+os.path.join(self._script_repo,part)+'/'
@@ -459,7 +479,8 @@ class MantidConfigDirectInelastic(object):
     def _set_rb_directory(self):
         """Set up default save directory, the one where data are saved by default"""
         if self._user:
-            rb_folder = self._user.last_rbdir
+            rb_folder = self._user.rb_dir
+
             self._dynamic_configuration.append('defaultsave.directory={0}'.format(rb_folder))
         else:
             raise RuntimeError("Can not define RB folder without user being defined")
@@ -470,7 +491,7 @@ class MantidConfigDirectInelastic(object):
         if not self._user:
             raise RuntimeError("Can not define Data search path without user being defined")
 
-        instr_name = self._user.last_instrument
+        instr_name = self._user.instrument
         map_mask_dir  = os.path.abspath(os.path.join('{0}'.format(self._map_mask_folder),\
                                                      '{0}'.format(str.lower(instr_name))))
         # set up all data folders
@@ -479,7 +500,7 @@ class MantidConfigDirectInelastic(object):
         for folder in all_data_folders[1:]:
             data_dir +=';'+os.path.abspath('{0}'.format(folder))
 
-        all_rb_folders = self._user.rb_dir
+        all_rb_folders = self._user._rb_dirs
         for folder in all_rb_folders.values():
             data_dir+=';'+os.path.abspath('{0}'.format(folder))
 
@@ -504,9 +525,9 @@ class MantidConfigDirectInelastic(object):
         if platform.system() != 'Windows':
             os.system('chown -R {0}:{0} {1}'.format(self._fedid,config_path))
 
-        InstrName = self._user.last_instrument
-        cycleID   = self._user.last_cycleID
-        rb_folder = self._user.last_rbdir
+        InstrName = self._user.instrument
+        cycleID   = self._user.cycleID
+        rb_folder = self._user.rb_dir
         self.copy_reduction_sample(InstrName,cycleID,rb_folder)
         #
         self.make_map_mask_links(user_path)
diff --git a/Code/Mantid/scripts/test/ISISDirecInelasticConfigTest.py b/Code/Mantid/scripts/test/ISISDirecInelasticConfigTest.py
index cd0f9a26d91a65abe51d19e708c6136eb3d3e444..d1694904e291d58c6924166667d25a53e9899c04 100644
--- a/Code/Mantid/scripts/test/ISISDirecInelasticConfigTest.py
+++ b/Code/Mantid/scripts/test/ISISDirecInelasticConfigTest.py
@@ -53,7 +53,7 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
 
     def makeFakeSourceReductionFile(self,mcf,contents=None):
 
-        instr_name = mcf._user.get_last_instrument()
+        instr_name = mcf._user.instrument
 
         file_path = os.path.join(self.UserScriptRepoDir,'direct_inelastic',instr_name.upper())
         if not os.path.exists(file_path):
@@ -82,15 +82,22 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
             shutil.rmtree(self.userRootDir,ignore_errors=True)
 
     def test_UserProperties(self):
-        user = UserProperties()
+        user = UserProperties(self.userID)
 
         user.set_user_properties(self.instrument,self.start_date,self.cycle,self.rbdir)
 
         id = user._recent_dateID
-        self.assertEqual(user.instrument[id],'MERLIN')
-        self.assertEqual(user.cycle_IDlist[id],('2015','1'))
-        self.assertEqual(user.start_dates[id],datetime.date(2015,05,03))
-        self.assertEqual(user.rb_dir[id],self.rbdir)
+        self.assertEqual(user._instrument[id],'MERLIN')
+        self.assertEqual(user._cycle_IDs[id],('2015','1'))
+        self.assertEqual(user._start_dates[id],datetime.date(2015,05,03))
+        self.assertEqual(user._rb_dirs[id],self.rbdir)
+        self.assertEqual(user.userID,self.userID)
+
+        self.assertEqual(user.instrument,'MERLIN')
+        self.assertEqual(user.cycleID,'2015_1')
+        self.assertEqual(user.start_date,datetime.date(2015,05,03))
+        self.assertEqual(user.rb_dir,self.rbdir)
+
 
         self.assertRaises(RuntimeError,user.set_user_properties,'SANS2D',self.start_date,self.cycle,self.rbdir)
         self.assertRaises(RuntimeError,user.set_user_properties,'HET','201400000',self.cycle,self.rbdir)
@@ -106,9 +113,11 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         if os.path.exists(rbdir):
             shutil.rmtree(rbdir)
 
-        self.assertEqual(len(user.instrument),2)
+        self.assertEqual(len(user.instrument),6)
+        self.assertEqual(len(user._instrument),2)
+
         self.assertEqual(user._recent_dateID,id)
-        self.assertEqual(user.start_dates['2000-01-12'],datetime.date(2000,01,12))
+        self.assertEqual(user._start_dates['2000-01-12'],datetime.date(2000,01,12))
 
         targetDir = self.get_save_dir()
         rbdir = os.path.join(self.userRootDir,'RB1999666')
@@ -118,10 +127,11 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         if os.path.exists(rbdir):
             shutil.rmtree(rbdir)
 
-        self.assertEqual(len(user.instrument),3)
+        self.assertEqual(len(user._instrument),3)
         id = user._recent_dateID
         self.assertEqual(id,'2016-12-01')
-        self.assertEqual(user.instrument[id],'MERLIN')
+        self.assertEqual(user._instrument[id],'MERLIN')
+        self.assertEqual(user.instrument,'MERLIN')
 
     def test_build_config(self):
         # script verifies the presence of a folder, not its contents.
@@ -155,15 +165,15 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         self.assertTrue(os.path.exists(os.path.join(self.userRootDir,'.mantid')))
         self.assertTrue(os.path.exists(config_file))
 
-        cur_cycleID = mcf._user.get_last_cycleID()
-        instr = mcf._user.get_last_instrument()
+        cur_cycleID = mcf._user.cycleID
+        instr = mcf._user.instrument
         targ_file = mcf._target_reduction_file(instr,cur_cycleID)
 
-        reduction_file = os.path.join(mcf._user.get_last_rbdir(),targ_file)
+        reduction_file = os.path.join(mcf._user.rb_dir,targ_file)
         self.assertTrue(os.path.isfile(reduction_file))
 
         self.assertFalse(mcf.config_need_replacing(config_file))
-        start_date = user.get_start_date()
+        start_date = user.start_date
         date_in_apast=datetime.date(start_date.year,start_date.month,start_date.day-1)
         time_in_a_past = time.mktime(date_in_apast.timetuple())
         os.utime(config_file,(time_in_a_past,time_in_a_past))
@@ -215,7 +225,7 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         self.assertTrue(os.path.exists(config_file))
 
         self.assertFalse(mcf.config_need_replacing(config_file))
-        start_date = user.get_start_date()
+        start_date = user.start_date
         date_in_apast=datetime.date(start_date.year,start_date.month,start_date.day-1)
         time_in_a_past = time.mktime(date_in_apast.timetuple())
         os.utime(config_file,(time_in_a_past,time_in_a_past))
@@ -242,8 +252,8 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         # Check sample reduction file
         #
         full_rb_path = rbdir2
-        cycle_id = user1.get_last_cycleID()
-        instr = user1.get_last_instrument()
+        cycle_id = user1.cycleID
+        instr = user1.instrument
         target_file = mcf._target_reduction_file(instr,cycle_id)
         full_target_file = os.path.join(full_rb_path,target_file)
         self.assertTrue(os.path.exists(full_target_file))
@@ -267,6 +277,13 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
         if os.path.exists(user1RootDir):
             shutil.rmtree(user1RootDir,ignore_errors=True)
 
+    def test_replace_user_variables(self):
+        user = UserProperties("wkc26243")
+        user.set_user_properties(self.instrument,self.start_date,self.cycle,self.rbdir)
+
+        targ_string = user.replace_variables('$instrument$ReductionScript$cycleID$.py')
+        self.assertEqual(self.instrument+'ReductionScript2015_1.py',targ_string)
+        
 
 
 
diff --git a/Code/Mantid/scripts/test/User_files_description_test.xml b/Code/Mantid/scripts/test/User_files_description_test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b57502f7cf117fc4e60da23f5f89139934af44f8
--- /dev/null
+++ b/Code/Mantid/scripts/test/User_files_description_test.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--The file describes list of files to copy to a user's RB folder from Mantid users script repository 
+    and operations to perform with these files during copying.
+    
+    At the moment, supported operations are:
+    Copy file(s) with specified name into RB folder with name which may depend on cycle ID, instrument or other variables below.
+    On request, replace any instances of variable specified by its value.
+-->
+<user_files_description>
+  <!-- the file descriptions support the following variables defined and parsed by 
+    ISISDirectInelasticConfig.py module. $instrument$, $cycleID$ $start_date$, $rb_folder$
+    $rb_folder$ value is short rb folder path (e.g. RB1501020)  
+    not full rb folder path (/home/wkc26243/RB1501020), 
+    The values of these variables are taken from archive for current cycle and user
+  -->
+ <!--Simple file copying -->  
+  <file_to_copy file_name="Test_reduction_file1.py" copy_as="Test_reduction_file2.py"/>
+
+ <!--Advanced file copying -->    
+  <file_to_copy file_name="Test_reduction_file.py" copy_as="Test_reduction_file$cycleID$.py">
+    <replace variable  ="Test_reduction_file" by_variable="Test_reduction_file$instrument$"/>
+    <replace variable  ="AAAA" by_variable="BBB"/>  
+  </file_to_copy>
+
+</user_files_description>