diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h b/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h
index 3dca5a1d70eee22f564bb142baa56f4497c187d4..2785f4d0656dac4df547cc1134495f41500b87ca 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h
@@ -1,9 +1,11 @@
 #ifndef MANTID_API_MULTIPLEFILEPROPERTY_H_
 #define MANTID_API_MULTIPLEFILEPROPERTY_H_
-    
-#include "MantidKernel/System.h"
-#include "MantidKernel/ArrayProperty.h"
 
+#include "MantidKernel/PropertyWithValue.h"
+#include "MantidKernel/System.h"
+#include "MantidKernel/MultiFileNameParser.h"
+#include <vector>
+#include <set>
 
 namespace Mantid
 {
@@ -32,33 +34,40 @@ namespace API
     File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
     Code Documentation is available at: <http://doxygen.mantidproject.org>
   */
-  class DLLExport MultipleFileProperty : public Kernel::ArrayProperty<std::string>
+  class DLLExport MultipleFileProperty : public Kernel::PropertyWithValue< std::vector< std::vector< std::string> > >
   {
   public:
-    MultipleFileProperty(const std::string & name, const std::vector<std::string> & exts = std::vector<std::string>(),
-        bool optional=false);
+    ///Constructor
+    MultipleFileProperty(const std::string & name,const std::vector<std::string> & exts = std::vector<std::string>());
 
     ~MultipleFileProperty();
 
-    ///Overridden setValue method
+    /// 'Virtual copy constructor
+    virtual MultipleFileProperty* clone() { return new MultipleFileProperty(*this); }
+
+    /// Overridden setValue method
     virtual std::string setValue(const std::string & propValue);
     /// Set a property value via a DataItem
     virtual std::string setValue(const boost::shared_ptr<Kernel::DataItem> data);
 
     /// @return the vector of suggested extensions. For use in GUIs showing files.
-    const std::set<std::string> & getExts() const
-    { return m_exts; }
+    std::set<std::string> getExts() const
+    { return std::set<std::string>(m_exts.begin(), m_exts.end()); }
+    /// @return the vector of ws names.  For use by loading algorithm to name multiple workspaces, especially summed workspaces.
+    std::vector<std::vector<unsigned int> > getRuns() const
+    { return m_parser.runs(); }
 
     // Unhide the PropertyWithValue assignment operator
-    using Kernel::ArrayProperty<std::string>::operator=;
+    using Kernel::PropertyWithValue< std::vector< std::vector< std::string> > >::operator=;
+
+    /// Return a "flattened" vector with the contents of the given vector of vectors.
+    static std::vector<std::string> flattenFileNames(const std::vector<std::vector<std::string> > & fileNames);
 
   private:
     /// Suggested extensions
-    std::set<std::string> m_exts;
-
-    /// Is the file optional?
-    bool m_optional;
-
+    std::vector<std::string> m_exts;
+    /// Parser used to parse multi-file strings.
+    Kernel::MultiFileNameParsing::Parser m_parser;
   };
 
 
diff --git a/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp b/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp
index 661cc9419c3d4206247c180e527acda24cd19422..e15620728c73e9a33e9e10ea3efe8c6653408280 100644
--- a/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp
+++ b/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp
@@ -1,10 +1,14 @@
 #include "MantidAPI/MultipleFileProperty.h"
+#include "MantidAPI/FileProperty.h"
 #include "MantidKernel/System.h"
-#include "MantidKernel/FileValidator.h"
+#include "MantidKernel/MultiFileValidator.h"
 #include "MantidKernel/Property.h"
 #include <Poco/Path.h>
 #include "MantidAPI/FileFinder.h"
 
+#include <functional>
+#include <numeric>
+
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
 
@@ -12,67 +16,105 @@ namespace Mantid
 {
 namespace API
 {
+  // Forward declaration of functor wrapped in anonymous namespace.
+  namespace
+  {
+    class AppendFullFileName
+    {
+    public:
+      AppendFullFileName(const std::vector<std::string> & exts);
+
+      std::string & operator()(std::string & result, const std::vector<std::string> & fileNames);
+      std::string & operator()(std::string & result, const std::string & fileName);
 
+    private:
+      const std::vector<std::string> & m_exts;
+    };
+  }
+  
   /** Constructor
    *
    * @param name ::          The name of the property
    * @param exts ::          The allowed/suggested extensions
    * @param optional ::      If ture, the property is optional
    */
-  MultipleFileProperty::MultipleFileProperty(const std::string & name,
-      const std::vector<std::string> & exts, bool optional)
-    : ArrayProperty<std::string>(name),
-      m_optional(optional)
-  {
-    m_exts.insert( exts.begin(), exts.end());
-  }
+  MultipleFileProperty::MultipleFileProperty(
+    const std::string & name,
+    const std::vector<std::string> & exts
+  ) : PropertyWithValue<std::vector<std::vector<std::string> > >(
+        name, 
+        std::vector<std::vector<std::string> >(), 
+        new MultiFileValidator(exts), 
+        Direction::Input),
+      m_exts(exts),
+      m_parser()
+  {}
 
-
-    
   //----------------------------------------------------------------------------------------------
   /** Destructor
    */
-  MultipleFileProperty::~MultipleFileProperty()
-  {
-  }
+  MultipleFileProperty::~MultipleFileProperty() {}
 
-  /** Set the value, the list of files, comma-separated
+  /** Set the value, with a comma- and plus-separated string of filenames
    *
-   * @param propValue :: comma-separated string of filenames
+   * @param propValue :: comma- and plus-separated string of filenames
    * @return A string indicating the outcome of the attempt to set the property. An empty string indicates success.
    */
   std::string MultipleFileProperty::setValue(const std::string & propValue)
   {
-    // Separate the files
-    std::vector<std::string> filenames;
-    toValue(propValue, filenames);
+    // No empty value is allowed.
+    if( propValue.empty())
+      return "No file(s) specified.";
+
+    std::stringstream errorMsg;
 
-    // Empty value is allowed if optional
-    if( filenames.empty())
+    try
     {
-      if (m_optional)
-        return "";
-      else
-        return "No file specified.";
+      // Parse the string into the vector of vectors of filenames.
+      m_parser.parse(propValue);
     }
-
-    std::string outValue;
-    for (size_t i=0; i<filenames.size(); i++)
+    catch(const std::runtime_error & re)
     {
-      std::string filename = filenames[i];
+      errorMsg << "Unable to parse multi file runs: \"" << re.what() << "\". ";
+    }
+
+    std::vector<std::vector<std::string> > fileNames = m_parser.fileNames();
 
-      // Adjust the filename if the path is not absolute
-      if( !Poco::Path(propValue).isAbsolute() )
+    AppendFullFileName appendFullFileName(m_exts);
+    std::string fullFileNames("");
+
+    // If we have been unable to parse multiple "run" filenames, then we try treating the string as a single file name.
+    if(fileNames.empty())
+    {
+      try
+      {
+        fullFileNames = appendFullFileName(fullFileNames, propValue);
+      }
+      catch(const std::runtime_error & re)
       {
-        filename = FileFinder::Instance().getFullPath(filename);
+        errorMsg << "Tried to find single file, but also failed: \"" << re.what() << "\".";
+        return errorMsg.str();
       }
-      // Re-build a comma-sep string
-      if (i > 0) outValue += ",";
-      outValue += filename;
     }
+    // Else, for each file name in the vector, change it into a full file name where possible,
+    // then append it onto a comma- and plus-separated string.
+    else
+    {
+      try
+      {
+        fullFileNames = std::accumulate(
+          fileNames.begin(), fileNames.end(),
+          std::string(""),
+          appendFullFileName);
+      }
+      catch(const std::runtime_error & re)
+      {
+        return re.what();
+      }
+    }  
 
-    // Now re-set the strings using the full paths found
-    return ArrayProperty<std::string>::setValue(outValue);
+    // Now re-set the value using the full paths found.
+    return PropertyWithValue<std::vector<std::vector<std::string> > >::setValue(fullFileNames);
   }
 
   /**
@@ -83,11 +125,116 @@ namespace API
   std::string MultipleFileProperty::setValue(const boost::shared_ptr<Kernel::DataItem> data )
   {
     // Implemented this method for documentation reasons. Just calls base class method.
-    return ArrayProperty<std::string>::setValue(data);
+    return PropertyWithValue<std::vector<std::vector<std::string> > >::setValue(data);
   }
 
+  /**
+   * A convenience function for the cases where we dont use the MultiFileProperty to
+   * *add* workspaces - only to list them.  It "flattens" the given vector of vectors
+   * into a single vector which is much easier to traverse.  For example:
+   *
+   * ((1), (2), (30), (31), (32), (100), (102)) becomes (1, 2, 30, 31, 32, 100, 102)
+   *
+   * Used on a vector of vectors that *has* added filenames, the following behaviour is observed:
+   *
+   * ((1), (2), (30, 31, 32), (100), (102)) becomes (1, 2, 30, 31, 32, 100, 102)
+   *
+   * @param - a vector of vectors, containing all the file names.
+   * @return a single vector containing all the file names.
+   */
+  std::vector<std::string> MultipleFileProperty::flattenFileNames(
+    const std::vector<std::vector<std::string> > & fileNames)
+  {
+    std::vector<std::string> flattenedFileNames;
+
+    std::vector<std::vector<std::string> >::const_iterator it = fileNames.begin();
+
+    for(; it != fileNames.end(); ++it)
+    {
+      flattenedFileNames.insert(
+        flattenedFileNames.end(),
+        it->begin(), it->end());
+    }
+
+    return flattenedFileNames;
+  }
+
+  //////////////////////////////////////////////////////////////////////
+  // Anonymous
+  //////////////////////////////////////////////////////////////////////
+
+  namespace
+  {
+    // Functor with overloaded function operator, for use with the "accumulate" STL algorithm.
+    // Has state to store extensions.
+    AppendFullFileName:: AppendFullFileName(const std::vector<std::string> & exts) :
+      m_exts(exts)
+    {}
+
+    /** Takes in a vector of filenames, tries to find their full path if possible, then cumulatively appends 
+      *  them to the result string.
+      *  @param result :: the cumulative result so far
+      *  @param fileNames :: the name to look for, and append to the result
+      *  @return the cumulative result, after the filenames have been appended.
+      */
+    std::string & AppendFullFileName::operator()(std::string & result, const std::vector<std::string> & fileNames)
+    {
+      // Append nothing if there are no file names to add.
+      if(fileNames.empty())
+        return result;
+
+      if(!result.empty())
+        result += ",";
+
+      AppendFullFileName appendFullFileName(m_exts);
+
+      // Change each file name into a full file name, and append each one onto a plus-separated string.
+      std::string fullFileNames;
+      fullFileNames = std::accumulate(
+        fileNames.begin(), fileNames.end(),
+        fullFileNames, 
+        appendFullFileName); // Call other overloaded operator on each filename in vector
+        
+      // Append the file names to result, and return them.
+      result += fullFileNames;
+      return result;
+    }
+
+    /** Takes in a filename, tries to find it's full path if possible, then cumulatively appends it to a result string.
+      *  @param result :: the cumulative result so far
+      *  @param fileName :: the name to look for, and append to the result
+      *  @return the cumulative result, after the filename has been appended.
+      *  @throws std::runtime_error if an individual filename could not be set to the FileProperty object
+      */
+    std::string & AppendFullFileName::operator()(std::string & result, const std::string & fileName)
+    {
+      // Append nothing if there is no file name to add.
+      if(fileName.empty())
+        return result;
 
+      if(!result.empty())
+        result += "+";
+
+      // Initialise a "slave" FileProperty object to do all the work.
+      FileProperty slaveFileProp(
+        "Slave",
+        "",
+        FileProperty::Load,
+        m_exts,
+        Direction::Input);
+
+      std::string error = slaveFileProp.setValue(fileName);
+
+      // If an error was returned then we throw it out of the functor, to be
+      // returned by MultiFileProperty.setvalue(...).
+      if(!error.empty())
+        throw std::runtime_error(error);
+
+      // Append the file name to result, and return it.
+      result += slaveFileProp();
+      return result;
+    }
+  } // anonymous namespace
 
 } // namespace Mantid
 } // namespace API
-
diff --git a/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h b/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h
index 8a77cb9c4fda2c49fcae97a5f550948400ff49d2..ed26d0aafc5e99473b7638b2ceb6e8535b4c5f0b 100644
--- a/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h
+++ b/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h
@@ -11,45 +11,27 @@
 
 using namespace Mantid;
 using namespace Mantid::API;
-using namespace Mantid::API;
 
 class MultipleFilePropertyTest : public CxxTest::TestSuite
 {
 public:
-
-  void test_empty_value_not_allowed()
-  {
-    MultipleFileProperty p("Filename");
-    TS_ASSERT_DIFFERS( p.setValue(""), "");
-  }
-
-  void test_empty_value_allowed_ifOptional()
-  {
-    MultipleFileProperty p("Filename", std::vector<std::string>(), true);
-    TS_ASSERT_EQUALS( p.setValue(""), "");
-  }
-
-  void test_getExts()
-  {
-    std::vector<std::string> exts;
-    exts.push_back(".nxs");
-    exts.push_back(".hdf");
-
-    MultipleFileProperty p("Filename", exts);
-    TS_ASSERT_EQUALS( p.getExts().size(), 2);
-    TS_ASSERT_EQUALS( p.getExts().count(".nxs"), 1);
-    TS_ASSERT_EQUALS( p.getExts().count(".hdf"), 1);
-  }
-
+  
   void test_setValue()
   {
+    // Here we try to load some files, some of them to be added together.  We should end up with a vector of vectors as follows:
+    //
+    // | [dir]MUSR00015189.nxs | [dir]MUSR00015190.nxs | [dir]MUSR00015189.nxs | [dir]MUSR00015191.nxs |
+    //                                                 | [dir]MUSR00015190.nxs |
+    //                                                 | [dir]MUSR00015191.nxs |
+
     MultipleFileProperty p("Filename");
-    p.setValue("REF_L_32035.nxs, CSP78173.raw");
-    std::vector<std::string> filenames = p();
-    TS_ASSERT_EQUALS( filenames.size(), 2);
-    TSM_ASSERT( "Files with no path are found using ConfigService paths", Poco::Path(filenames[0]).isAbsolute() );
-    TSM_ASSERT( "Files with no path are found using ConfigService paths", Poco::Path(filenames[1]).isAbsolute() );
+    p.setValue("MUSR15189:15190,15189-15191,15191.nxs");
+    std::vector<std::vector<std::string> > fileNames = p();
 
+    TS_ASSERT_EQUALS(fileNames[0].size(), 1);
+    TS_ASSERT_EQUALS(fileNames[1].size(), 1);
+    TS_ASSERT_EQUALS(fileNames[2].size(), 3);
+    TS_ASSERT_EQUALS(fileNames[3].size(), 1);
   }
 
 
diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
index 60b89e642ea91f3d7344d7885975b983dc28cc36..2d4bcd4fc3cd0b650e5945e8f335e0ea2e8789d4 100644
--- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
+++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h
@@ -72,6 +72,12 @@ namespace Mantid
       void init();
       /// Execute
       void exec();
+
+      /// Called when there is only one file to load.
+      void loadSingleFile();
+      /// Called when there are multiple files to load.
+      void loadMultipleFiles();
+
       /// Overrides the cancel() method to call m_loader->cancel()
       void cancel()const;
       /// Create the concrete instance use for the actual loading.
@@ -85,8 +91,18 @@ namespace Mantid
       /// Retrieve a pointer to the output workspace from the sub algorithm
       API::Workspace_sptr getOutputWorkspace(const std::string & propName, 
 					     const API::IDataFileChecker_sptr loader) const;
-      
 
+      /// Load a file to into a hidden workspace.
+      API::Workspace_sptr loadFileToHiddenWs(const std::string & fileName, const std::string & wsName);
+      /// Plus two workspaces together, "in place".
+      API::Workspace_sptr plusWs(API::Workspace_sptr ws1, API::Workspace_sptr ws2);
+      /// Delete a workspace with the given name.
+      void deleteWs(const std::string & wsName);
+      /// Rename a workspace with the given name.
+      void renameWs(const std::string & oldName, const std::string & newName);
+      /// Unhide the given workspace, if it is hidden.
+      void unhideWs(const std::string & wsName);
+      
     private:
       /// The base properties
       std::set<std::string> m_baseProps;
diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp
index 0466c96ee1af67123501fa7b9e9327557e49e81a..5211c29ba490da99974fbb81bbff4fc33565b87b 100644
--- a/Code/Mantid/Framework/DataHandling/src/Load.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp
@@ -33,7 +33,7 @@ Load('event_ws', Filename='INSTR_1000_event.nxs',Precount=True)
 // Includes
 //----------------------------------------------------------------------
 #include "MantidDataHandling/Load.h"
-#include "MantidAPI/FileProperty.h"
+#include "MantidAPI/MultipleFileProperty.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidKernel/ArrayProperty.h"
@@ -43,9 +43,58 @@ Load('event_ws', Filename='INSTR_1000_event.nxs',Precount=True)
 
 #include <cctype>
 #include <algorithm>
+#include <functional>
+#include <numeric>
+#include <set>
 #include "MantidAPI/IMDEventWorkspace.h"
 #include <cstdio>
 
+
+namespace
+{
+  /**
+   * Convenience function that returns true if the passed vector of vector of strings
+   * contains a single string, false if contains more than that (or zero).
+   *
+   * @param fileNames :: a vector of vectors of file name strings.
+   *
+   * @returns true if there is exactly one string, else false.
+   */
+  bool isSingleFile(const std::vector<std::vector<std::string> > & fileNames)
+  {
+    if(fileNames.size() == 1)
+    {
+      std::vector<std::vector<std::string>>::const_iterator first = fileNames.begin();
+      if(first->size() == 1)
+        return true;
+    }
+    return false;
+  }
+
+  /**
+   * Helper function that takes a vector of runs, and generates a suggested workspace name.
+   * This will likely need to be improved and may have to include instrument name, etc.
+   *
+   * @param runs :: a vector of run numbers.
+   *
+   * @returns a string containing a suggested file name based on the given run numbers.
+   */
+  std::string generateWsName(std::vector<unsigned int> runs)
+  {
+    std::string wsName("");
+
+    for(size_t i = 0; i < runs.size(); ++i)
+    {
+      if(!wsName.empty())
+        wsName += "_";
+
+      wsName += boost::lexical_cast<std::string>(runs[i]);
+    }
+
+    return wsName;
+  }
+}
+
 namespace Mantid
 {
   namespace DataHandling
@@ -88,9 +137,15 @@ namespace Mantid
       std::transform(name.begin(),name.end(),NAME.begin(),toupper);
       if( NAME == "FILENAME" )
       {
-        // Get back full path before passing to getFileLoader method.
-        IDataFileChecker_sptr loader = getFileLoader(getPropertyValue(name));
-        if( loader ) declareLoaderProperties(loader);
+        // Get back full path before passing to getFileLoader method, and also
+        // find out whether this is a multi file load.
+        std::vector<std::vector<std::string> > fileNames = getProperty("Filename");
+        // If it's a single file load, then it's fine to change loader.
+        if(isSingleFile(fileNames))
+        {
+          IDataFileChecker_sptr loader = getFileLoader(getPropertyValue(name));
+          if( loader ) declareLoaderProperties(loader);
+        }
       }
     }
 
@@ -249,9 +304,10 @@ namespace Mantid
       exts.push_back(".grp");
       exts.push_back(".nxspe");
 
-      declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts),
-        "The name of the file to read, including its full or relative\n"
-        "path. (N.B. case sensitive if running on Linux).");
+      declareProperty(new MultipleFileProperty("Filename", exts),
+        "The name of the file(s) to read, including the full or relative\n"
+        "path. (N.B. case sensitive if running on Linux). Multiple runs\n"
+        "can be loaded and added together, e.g. INST10,11+12,13.ext");
       declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace", "",Direction::Output), 
         "The name of the workspace that will be created, filled with the\n"
         "read-in data and stored in the Analysis Data Service.");
@@ -268,12 +324,27 @@ namespace Mantid
     }
 
     /** 
-    *   Executes the algorithm.
-    */
+     * Executes the algorithm.
+     */
     void Load::exec()
+    {
+      std::vector<std::vector<std::string> > fileNames = getProperty("Filename");
+      
+      if(isSingleFile(fileNames))
+      {
+        // This is essentially just the same code that was called before multiple files were supported.
+        loadSingleFile();
+      }
+      else
+      {
+        // Code that supports multiple file loading.
+        loadMultipleFiles();
+      }
+    }
+
+    void Load::loadSingleFile()
     {
       std::string loaderName = getPropertyValue("LoaderName");
-      //IDataFileChecker_sptr loader;
       if( loaderName.empty() )
       {
         m_loader = getFileLoader(getPropertyValue("Filename"));
@@ -309,6 +380,101 @@ namespace Mantid
       setOutputWorkspace(m_loader);
     }
 
+
+    void Load::loadMultipleFiles()
+    {
+      MultipleFileProperty * multiFileProp = dynamic_cast<MultipleFileProperty*>(getPointerToProperty("Filename"));
+      
+      const std::vector<std::vector<std::string> > values = getProperty("Filename");
+      const std::vector<std::vector<unsigned int> > runs = multiFileProp->getRuns();
+      std::string outputWsName = getProperty("OutputWorkspace");
+
+      std::vector<std::string> loadedWsNames;
+
+      std::vector<std::vector<std::string> >::const_iterator values_it = values.begin();
+      std::vector<std::vector<unsigned int> >::const_iterator runs_it = runs.begin();
+
+      // Cycle through the fileNames and wsNames.
+      for(; values_it != values.end(); ++values_it, ++runs_it)
+      {
+        std::vector<std::string> fileNames = *values_it;
+        std::string wsName = generateWsName(*runs_it);
+
+        // If there is only one filename, then just load it to the given wsName.
+        if(fileNames.size() == 1)
+        {
+          loadFileToHiddenWs(fileNames.at(0), wsName);
+          loadedWsNames.push_back("__" + wsName);
+        }
+        // Else there is more than one filename.  Load them all, sum them, and rename the
+        // result to the given wsName.
+        else
+        {
+          // Load all files and place the resulting workspaces in a vector.
+          std::vector<Workspace_sptr> loadedWs;
+          std::vector<std::string>::const_iterator vIt = fileNames.begin();
+
+          for(; vIt != fileNames.end(); ++vIt)
+          {
+            Workspace_sptr ws = loadFileToHiddenWs(*vIt, (*vIt) + "_temp");
+            loadedWs.push_back(ws);
+          }
+
+          // Add all workspaces together, sticking the result in sum.
+          Workspace_sptr sum;
+          for(
+            size_t i = 1; // Start at second workspace in list.
+            i < loadedWs.size(); 
+            i++)
+          {
+            Workspace_sptr firstWsToAdd;
+            // If there have been no workspaces added yet, then the first workspace to add
+            // is the first workspace in the list.
+            if(sum == Workspace_sptr())
+              firstWsToAdd = loadedWs.at(i-1);
+            // Else the first workspace to add is "sum" itself.
+            else
+              firstWsToAdd = sum;
+            
+            Workspace_sptr secondWsToAdd = loadedWs.at(i);
+            sum = plusWs(firstWsToAdd, secondWsToAdd);
+          }
+
+          // Delete all of the temporarily loaded workspaces except the first one, so that we are left only
+          // with sum at this point.
+          for(size_t i = 1; i < fileNames.size(); i++)
+          {
+            deleteWs("__" + fileNames.at(i) + "_temp");
+          }
+
+          // Rename the sum and add to the list of loaded workspace names.
+          renameWs(sum->name(), "__" + wsName);
+          loadedWsNames.push_back("__" + wsName);
+        }
+      }
+
+      // If we only have one loaded ws, set it as the output.
+      if(loadedWsNames.size() == 1)
+      {
+        renameWs(loadedWsNames.at(0), outputWsName);
+        setProperty("OutputWorkspace", AnalysisDataService::Instance().retrieve(outputWsName.c_str()));
+      }
+      // Else we have multiple loaded workspaces - group them and set the group as output.
+      else
+      {
+        Mantid::API::IAlgorithm_sptr groupingAlg = 
+          Mantid::API::AlgorithmManager::Instance().create("GroupWorkspaces", 1);
+
+        groupingAlg->setProperty("InputWorkspaces",loadedWsNames);
+        groupingAlg->setProperty("OutputWorkspace",outputWsName.c_str());
+        groupingAlg->execute();
+
+        unhideWs(outputWsName);
+
+        setProperty("OutputWorkspace", AnalysisDataService::Instance().retrieve(outputWsName.c_str()));
+      }
+    }
+
     /** 
     * Create the concrete instance use for the actual loading.
     * @param name :: The name of the loader to instantiate
@@ -449,8 +615,8 @@ namespace Mantid
     }
 
     /*
-     * Overrides the default cancel() method. Calls cancel() on the actual loader.
-     */
+    * Overrides the default cancel() method. Calls cancel() on the actual loader.
+    */
     void Load::cancel()const
     {
       if (m_loader)
@@ -459,5 +625,135 @@ namespace Mantid
       }
     }
 
+    /**
+     * Loads a file into a *hidden* workspace.
+     *
+     * @param fileName :: file name to load.
+     * @param wsName   :: workspace name, which will be prefixed by a "__"
+     *
+     * @returns a pointer to the loaded workspace
+     */
+    API::Workspace_sptr Load::loadFileToHiddenWs(
+      const std::string & fileName, 
+      const std::string & wsName)
+    {
+      Mantid::API::IAlgorithm_sptr loadAlg = createSubAlgorithm("Load", 1);
+      // Here, as a workaround for groupworkspaces who's members have names but no
+      // accompanying entries in the ADS, we set the sub algo to not be a child ...
+      loadAlg->setChild(false);
+      // ... and now, so that the the workspaces dont appear in the window, we prefix
+      // all workspace names with "__".
+      loadAlg->setPropertyValue("Filename",fileName);
+      loadAlg->setPropertyValue("OutputWorkspace","__" + wsName);
+      loadAlg->executeAsSubAlg();
+
+      return AnalysisDataService::Instance().retrieve("__" + wsName);
+    }
+
+    /**
+     * Plus two workspaces together, "in place".
+     *
+     * @param ws1 :: The first workspace.
+     * @param ws2 :: The second workspace.
+     *
+     * @returns a pointer to the result (the first workspace).
+     */
+   API::Workspace_sptr Load::plusWs(
+      Workspace_sptr ws1,
+      Workspace_sptr ws2)
+    {
+      Mantid::API::IAlgorithm_sptr plusAlg = createSubAlgorithm("Plus", 1);
+      plusAlg->setPropertyValue("LHSWorkspace", ws1->name());
+      plusAlg->setPropertyValue("RHSWorkspace", ws2->name());
+      plusAlg->setPropertyValue("OutputWorkspace", ws1->name());
+      plusAlg->executeAsSubAlg();
+
+      return ws1;
+    }
+
+    /**
+     * Renames a workspace.
+     *
+     * @param oldName :: the old workspace name.
+     * @param newName :: the new workspace name.
+     */
+    void Load::renameWs(
+      const std::string & oldName, 
+      const std::string & newName)
+    {
+      if(oldName == newName)
+        return;
+
+      Mantid::API::IAlgorithm_sptr renameAlg = createSubAlgorithm("RenameWorkspace", 1);
+      renameAlg->setChild(false);
+      renameAlg->setPropertyValue("InputWorkspace", oldName);
+      renameAlg->setPropertyValue("OutputWorkspace", newName);
+      renameAlg->executeAsSubAlg();
+    }
+
+    /**
+     * Deletes a given workspace.  If the given workspace is a group workspace,
+     * then this function calls itself recursively for each workspace in the group.
+     *
+     * @param wsName :: the name of the workspace to delete.
+     */
+    void Load::deleteWs(const std::string & wsName)
+    {
+      Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName);
+      if(WorkspaceGroup_sptr wsGrpSptr =
+        boost::dynamic_pointer_cast<WorkspaceGroup>(ws))
+      {
+        std::vector<std::string> childWsNames = wsGrpSptr->getNames();
+        std::vector<std::string>::iterator vIt = childWsNames.begin();
+
+        for(; vIt != childWsNames.end(); ++vIt)
+        {
+          // Call this function recursively, to delete each child workspace.
+          deleteWs(*vIt);
+        }
+      }
+      else
+      {
+        Mantid::API::IAlgorithm_sptr deleteAlg = createSubAlgorithm("DeleteWorkspace", 1);
+
+        deleteAlg->setPropertyValue("Workspace", wsName);
+        deleteAlg->execute();
+      }
+    }
+
+    /**
+     * Unhides a given workspace (by removing the "__" prefix from its name if present).
+     * If the given workspace is a group workspace, then this function calls itself 
+     * recursively for each workspace in the group.
+     *
+     * @param wsName :: the name of the workspace to unhide.
+     */
+    void Load::unhideWs(const std::string & wsName)
+    {
+      std::set<std::string> adsContents1 = AnalysisDataService::Instance().getObjectNames();
+
+      Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName);
+      if(WorkspaceGroup_sptr wsGrpSptr =
+        boost::dynamic_pointer_cast<WorkspaceGroup>(ws))
+      {
+        std::vector<std::string> childWsNames = wsGrpSptr->getNames();
+        std::vector<std::string>::iterator vIt = childWsNames.begin();
+
+        for(; vIt != childWsNames.end(); ++vIt)
+        {
+          // Call this function recursively, to unhide each child workspace.
+          unhideWs(*vIt);
+        }
+      }
+      else
+      {
+        if(boost::starts_with(wsName, "__"))
+        {
+          std::string newName = wsName.substr(2, (wsName.size() - 2));
+          renameWs(wsName, newName);
+        }
+      }
+    }
+
   } // namespace DataHandling
 } // namespace Mantid
diff --git a/Code/Mantid/Framework/DataHandling/test/LoadTest.h b/Code/Mantid/Framework/DataHandling/test/LoadTest.h
index dc01f646c07b1ea852f019ffdc13b13ebbedb97a..eaae509040c4d21de816e3acd6994a0d5f16056e 100644
--- a/Code/Mantid/Framework/DataHandling/test/LoadTest.h
+++ b/Code/Mantid/Framework/DataHandling/test/LoadTest.h
@@ -13,6 +13,20 @@ using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 using namespace Mantid::DataHandling;
 
+namespace
+{
+  void removeGroupFromADS(WorkspaceGroup_sptr group)
+  {
+    const std::vector<std::string> wsNames = group->getNames();
+    std::vector<std::string>::const_iterator it = wsNames.begin();
+    AnalysisDataService::Instance().remove(group->name());
+    for(; it != wsNames.end(); ++it)
+    {
+      AnalysisDataService::Instance().remove(*it);
+    }
+  }
+}
+
 class LoadTest : public CxxTest::TestSuite
 {
 public:
@@ -183,7 +197,7 @@ public:
     AnalysisDataService::Instance().remove("LoadTest_Output");
   }
 
-  void test_ARGUS_NXS()
+  void _ARGUS_NXS()
   {
     Load loader;
     loader.initialize();
@@ -327,6 +341,135 @@ public:
     TS_ASSERT(ws);
     AnalysisDataService::Instance().remove("LoadTest_Output");
   }
+
+  
+
+  void testList()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189,15190,15191.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    TS_ASSERT_EQUALS(output->getNumberOfEntries(),6);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_2"));
+    TS_ASSERT(ws2);
+    MatrixWorkspace_sptr ws3 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15190_1"));
+    TS_ASSERT(ws3);
+    MatrixWorkspace_sptr ws4 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15190_2"));
+    TS_ASSERT(ws4);
+    MatrixWorkspace_sptr ws5 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_1"));
+    TS_ASSERT(ws5);
+    MatrixWorkspace_sptr ws6 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_2"));
+    TS_ASSERT(ws6);
+    removeGroupFromADS(output);
+  }
+
+  void testPlus()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189+15190.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_2"));
+    removeGroupFromADS(output);
+  }
+
+  void testRange()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189:15192.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    TS_ASSERT_EQUALS(output->getNumberOfEntries(),8);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_2"));
+    TS_ASSERT(ws2);
+    MatrixWorkspace_sptr ws3 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15190_1"));
+    TS_ASSERT(ws3);
+    MatrixWorkspace_sptr ws4 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15190_2"));
+    TS_ASSERT(ws4);
+    MatrixWorkspace_sptr ws5 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_1"));
+    TS_ASSERT(ws5);
+    MatrixWorkspace_sptr ws6 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_2"));
+    TS_ASSERT(ws6);
+    MatrixWorkspace_sptr ws7 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15192_1"));
+    TS_ASSERT(ws7);
+    MatrixWorkspace_sptr ws8 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15192_2"));
+    TS_ASSERT(ws8);
+    removeGroupFromADS(output);
+  }
+
+  void testSteppedRange()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189:15192:2.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    TS_ASSERT_EQUALS(output->getNumberOfEntries(),4);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15189_2"));
+    TS_ASSERT(ws2);
+    MatrixWorkspace_sptr ws3 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_1"));
+    TS_ASSERT(ws3);
+    MatrixWorkspace_sptr ws4 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("15191_2"));
+    TS_ASSERT(ws4);
+    removeGroupFromADS(output);
+  }
+
+  void testAddedRange()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189-15192.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    TS_ASSERT_EQUALS(output->getNumberOfEntries(),2);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_2"));
+    TS_ASSERT(ws2);
+    removeGroupFromADS(output);
+  }
+
+  void testAddedSteppedRange()
+  {
+    Load loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "MUSR15189-15192:2.nxs");
+    loader.setPropertyValue("OutputWorkspace","LoadTest_Output");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+
+    WorkspaceGroup_sptr output = boost::dynamic_pointer_cast<WorkspaceGroup>(AnalysisDataService::Instance().retrieve("LoadTest_Output"));
+    TS_ASSERT(output);
+    TS_ASSERT_EQUALS(output->getNumberOfEntries(),2);
+    MatrixWorkspace_sptr ws1 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_1"));
+    TS_ASSERT(ws1);
+    MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("LoadTest_Output_2"));
+    TS_ASSERT(ws2);
+    removeGroupFromADS(output);
+  }
 };
 
 #endif /*LOADTEST_H_*/
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
index 78ceb1a510ee00c565381d3edac900abeda6f71b..9f0ee49d52240a4cb4cdb4137df67d33094d3255 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
@@ -306,10 +306,13 @@ protected:
     operator std::string ();
     /// explicit specialization for Property*()
     operator Property* ();
-
+    
     /// explicit specialization for std::vector
     template<typename T>
     operator std::vector<T> () { return pm.getValue<std::vector<T> >(prop);}
+    /// explicit specialization for std::vector
+    template<typename T>
+    operator std::vector<std::vector<T> > () { return pm.getValue<std::vector<std::vector<T> > >(prop);}
     /// explicit specialization for boost::shared_ptr
     template<typename T>
     operator boost::shared_ptr<T> () { return pm.getValue<boost::shared_ptr<T> >(prop); }
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h
index c6125b3b887e9ff7a3c2a5fb8f4b9912268a847f..f5f4b7bf4885267d5bb1584741d9a1fa1326ae11 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h
@@ -78,19 +78,19 @@ namespace Kernel
       void parse(const std::string & multiFileName);
       
       /// Return the vector of vectors of parsed file names.
-      std::vector<std::vector<unsigned int> > runs() {return m_runs;}
+      std::vector<std::vector<unsigned int> > runs() const {return m_runs;}
       /// Return the vector of vectors of parsed file names.
-      std::vector<std::vector<std::string> > fileNames() {return m_fileNames;}
+      std::vector<std::vector<std::string> > fileNames() const {return m_fileNames;}
       /// Return the parsed directory string.
-      std::string dirString() {return m_dirString;}
+      std::string dirString() const {return m_dirString;}
       /// Return the parsed instrument string.
-      std::string instString() {return m_instString;}
+      std::string instString() const {return m_instString;}
       /// Return the parsed underscore string.
-      std::string underscoreString() {return m_underscoreString;}
+      std::string underscoreString() const {return m_underscoreString;}
       /// Return the parsed run string.
-      std::string runString() {return m_runString;}
+      std::string runString() const {return m_runString;}
       /// Return the parsed extension string.
-      std::string extString() {return m_extString;}
+      std::string extString() const {return m_extString;}
 
     private:
       /// Clear all member variables.
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
index feb4d3d74dfc375bb91d1783c8a4ea810e76fce4..e90e62d6df30deff7fbbf5df522f0ba023793d71 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
@@ -88,6 +88,28 @@ std::string toString(const std::vector<T>& value)
   return result.str();
 }
 
+/// Specialisation for a property of type std::vector<std::vector>.
+template <typename T>
+std::string toString(const std::vector<std::vector<T> >& value)
+{
+  std::stringstream result;
+  std::size_t vsize = value.size();
+  for (std::size_t i = 0; i < vsize; ++i)
+  {
+    std::size_t innervsize = value[i].size();
+    for (std::size_t j = 0; j < innervsize; ++j)
+    {
+      result << value[i][j];
+      if (j + 1 != innervsize)
+        result << "+";
+    }
+
+    if (i + 1 != vsize)
+      result << ",";
+  }
+  return result.str();
+}
+
 // ------------- Convert strings to values
 template <typename T>
 inline void appendValue(const std::string& strvalue, std::vector<T>& value)
@@ -140,6 +162,28 @@ void toValue(const std::string& strvalue, std::vector<T>& value)
   }
 }
 
+template <typename T>
+void toValue(const std::string& strvalue, std::vector<std::vector<T> >& value)
+{
+  // Split up comma-separated properties
+  typedef Poco::StringTokenizer tokenizer;
+  tokenizer tokens(strvalue, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+
+  value.clear();
+  value.reserve(tokens.count());
+
+  for (tokenizer::Iterator oIt = tokens.begin(); oIt != tokens.end(); ++oIt)
+  {
+    tokenizer values(*oIt, "+", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+    std::vector<T> vect;
+
+    for (tokenizer::Iterator iIt = values.begin(); iIt != values.end(); ++iIt)
+      vect.push_back(boost::lexical_cast<T>(*iIt));
+
+    value.push_back(vect);
+  }
+}
+
 /// Macro for the vector<int> specializations
 #define PROPERTYWITHVALUE_TOVALUE(type) \
   template <> \
diff --git a/Code/Mantid/Framework/Kernel/src/ArrayProperty.cpp b/Code/Mantid/Framework/Kernel/src/ArrayProperty.cpp
index 783434bca3d60c0ad3df3aca68d8812224ebb1dc..9c2a5625b4b02016b387d8d2c1637b8cc7f7dcfc 100644
--- a/Code/Mantid/Framework/Kernel/src/ArrayProperty.cpp
+++ b/Code/Mantid/Framework/Kernel/src/ArrayProperty.cpp
@@ -16,6 +16,8 @@ template DLLExport class ArrayProperty<size_t>;
 template DLLExport class ArrayProperty<double>;
 template DLLExport class ArrayProperty<std::string>;
 
+template DLLExport class ArrayProperty<std::vector<std::string> >;
+
 /// @endcond
 
 } // namespace Kernel
diff --git a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp
index 50fa4e642cbeea24698e8440758649589f181311..dade2e8585894e8d2270c910b65e7d886c019604 100644
--- a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp
+++ b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp
@@ -23,6 +23,7 @@ DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<int64_t>);
 DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<uint64_t>);
 DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<double>);
 DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::string>);
+DEFINE_IPROPERTYMANAGER_GETVALUE(std::vector<std::vector<std::string> >);
 
 namespace Mantid
 {
diff --git a/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp b/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp
index 668fe0af7fe2bef524f4b7a8669c40a80af0dac7..735c351657b1c0d68ab392d406a0febedd7709cb 100644
--- a/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp
+++ b/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp
@@ -208,7 +208,7 @@ namespace Kernel
       // Get the directory, if there is one.
       size_t lastSeparator = m_multiFileName.find_last_of("/\\");
       if(lastSeparator != std::string::npos)
-        m_dirString = m_multiFileName.substr(0, lastSeparator);
+        m_dirString = m_multiFileName.substr(0, lastSeparator + 1);
 
       // Slice off the directory and extension.
       std::string base = m_multiFileName.substr(
diff --git a/Code/Mantid/Framework/Kernel/src/Property.cpp b/Code/Mantid/Framework/Kernel/src/Property.cpp
index dd97321951cca3bae3fa14a233e0040cbae847a1..0ec0609c5e245f69ad669a4777aed1030506a6bc 100644
--- a/Code/Mantid/Framework/Kernel/src/Property.cpp
+++ b/Code/Mantid/Framework/Kernel/src/Property.cpp
@@ -247,6 +247,7 @@ std::string getUnmangledTypeName(const std::type_info& type)
     typestrings.insert(make_pair(typeid(std::vector<int>).name(), string("int list")));
     typestrings.insert(make_pair(typeid(std::vector<int64_t>).name(), string("int list")));
     typestrings.insert(make_pair(typeid(std::vector<double>).name(), string("dbl list")));
+    typestrings.insert(make_pair(typeid(std::vector<std::vector<string> >).name(), string("list of str lists")));
 
     //Workspaces
     typestrings.insert(make_pair(typeid(boost::shared_ptr<Workspace>).name(), 
diff --git a/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp b/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp
index e8db6c92cafe1d8dd9f287d4b12fe13c9a0a492d..8924b53481a81ff85312832dbebd2895e19eb9fd 100644
--- a/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp
+++ b/Code/Mantid/Framework/Kernel/src/PropertyWithValue.cpp
@@ -23,6 +23,8 @@ namespace Mantid
     template DLLExport class PropertyWithValue<std::vector<int32_t> >;
     template DLLExport class PropertyWithValue<std::vector<uint64_t> >;
     template DLLExport class PropertyWithValue<std::vector<int64_t> >;
+
+    template DLLExport class PropertyWithValue<std::vector<std::vector<std::string> > >;
     /// @endcond
 
   } // namespace Kernel
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp
index 2add40e13ba64af72da40c38667d17dd1a2717d8..cb40d94a230d647350f0ee17be0598fe710414d4 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp
@@ -632,7 +632,8 @@ namespace MDAlgorithms
    */
   void MergeMDFiles::exec()
   {
-    m_filenames = getProperty("Filenames");
+    MultipleFileProperty * multiFileProp = dynamic_cast<MultipleFileProperty*>(getPointerToProperty("Filenames"));
+    m_filenames = MultipleFileProperty::flattenFileNames(multiFileProp->operator()());
     if (m_filenames.size() == 0)
       throw std::invalid_argument("Must specify at least one filename.");
     std::string firstFile = m_filenames[0];
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
index f60db5cf9c27e4b676d7e22a107f6f66b57068dc..2e6c24b745c3a515abb5b1eb1230bdc70a8b6380 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
@@ -41,7 +41,7 @@ public:
   void do_test_exec(std::string OutputFilename)
   {
     // Create a bunch of input files
-    std::vector<std::string> filenames;
+    std::vector<std::vector<std::string> > filenames;
     std::vector<MDEventWorkspace3Lean::sptr> inWorkspaces;
     for (size_t i=0; i<3; i++)
     {
@@ -49,7 +49,7 @@ public:
       mess << "MergeMDFilesTestInput" << i;
       MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true);
       inWorkspaces.push_back(ws);
-      filenames.push_back(ws->getBoxController()->getFilename());
+      filenames.push_back(std::vector<std::string>(1,ws->getBoxController()->getFilename()));
     }
 
     // Name of the output workspace.