diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7aaeb52cb7b4455307d18c9daac9fc71bcf099f..fe419689dc47026419b2fece92e86a4dc5c9df33 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -203,12 +203,13 @@ if ( MSVC )
   add_definitions ( -DQWT_DLL )
 endif ()
 
+add_custom_target ( AllTests )
+add_dependencies( AllTests FrameworkTests )
 if ( ENABLE_MANTIDPLOT OR ENABLE_WORKBENCH )
   add_custom_target ( GUITests )
   add_dependencies ( check GUITests )
   # Collect all tests together
-  add_custom_target ( AllTests )
-  add_dependencies ( AllTests FrameworkTests GUITests )
+  add_dependencies ( AllTests GUITests )
   add_subdirectory ( qt )
 endif()
 
@@ -311,7 +312,7 @@ if ( ENABLE_CPACK )
                                        "sip >= 4.18,"
                                        "python-six,python-ipython >= 1.1.0,python-ipython-notebook,PyYAML,"
                                        "python-requests,"
-                                       "scipy,"
+                                       "scipy,python2-scikit-image,"
                                        "hdf,hdf5,jsoncpp >= 0.7.0" )
       if (ENABLE_MANTIDPLOT)
         set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},qt4 >= 4.2,PyQt4,qwtplot3d-qt4" )
@@ -394,6 +395,7 @@ if ( ENABLE_CPACK )
                                            "python3-six,"
                                            "python3-matplotlib,"
                                            "python3-scipy,"
+                                           "python3-skimage,"
                                            "python3-pycifrw (>= 4.2.1),"
                                            "python3-yaml,"
                                            "python3-qtawesome,"
@@ -413,6 +415,7 @@ if ( ENABLE_CPACK )
                                            "python-six,"
                                            "python-matplotlib,"
                                            "python-scipy,"
+                                           "python-skimage,"
                                            "python-pycifrw (>= 4.2.1),"
                                            "python-yaml,"
                                            "python-qtawesome,"
diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h
index 37c4df0ab86e57e1c2c58dda569702dae656609a..22c0052248afc5cbd5ed379f1b10cba6354d6ac6 100644
--- a/Framework/API/inc/MantidAPI/Algorithm.h
+++ b/Framework/API/inc/MantidAPI/Algorithm.h
@@ -441,15 +441,17 @@ private:
 
   // --------------------- Private Members -----------------------------------
   /// Poco::ActiveMethod used to implement asynchronous execution.
-  Poco::ActiveMethod<bool, Poco::Void, Algorithm,
-                     Poco::ActiveStarter<Algorithm>> *m_executeAsync;
+  std::unique_ptr<Poco::ActiveMethod<bool, Poco::Void, Algorithm,
+                                     Poco::ActiveStarter<Algorithm>>>
+      m_executeAsync;
 
   /// Sends notifications to observers. Observers can subscribe to
   /// notificationCenter
   /// using Poco::NotificationCenter::addObserver(...);
-  mutable Poco::NotificationCenter *m_notificationCenter;
+  mutable std::unique_ptr<Poco::NotificationCenter> m_notificationCenter;
   /// Child algorithm progress observer
-  mutable Poco::NObserver<Algorithm, ProgressNotification> *m_progressObserver;
+  mutable std::unique_ptr<Poco::NObserver<Algorithm, ProgressNotification>>
+      m_progressObserver;
 
   bool m_isInitialized;         ///< Algorithm has been initialized flag
   bool m_isExecuted;            ///< Algorithm is executed flag
diff --git a/Framework/API/inc/MantidAPI/AnalysisDataServiceObserver.h b/Framework/API/inc/MantidAPI/AnalysisDataServiceObserver.h
index f07a2aadb9a70d25dc84ffe3eedd5c1c4b400339..3445102cf040df86b47bd80f70a6ef12da118b8d 100644
--- a/Framework/API/inc/MantidAPI/AnalysisDataServiceObserver.h
+++ b/Framework/API/inc/MantidAPI/AnalysisDataServiceObserver.h
@@ -1,6 +1,6 @@
 // Mantid Repository : https://github.com/mantidproject/mantid
 //
-// Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory UKRI,
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
diff --git a/Framework/API/inc/MantidAPI/IEventList.h b/Framework/API/inc/MantidAPI/IEventList.h
index 5e699f6b5109af5ab99adf11a6a0bd7c93f68a65..f58454a32197ea77cb6a9da449fc683024a2db45 100644
--- a/Framework/API/inc/MantidAPI/IEventList.h
+++ b/Framework/API/inc/MantidAPI/IEventList.h
@@ -77,6 +77,8 @@ public:
   virtual void addPulsetime(const double seconds) = 0;
   /// Mask a given TOF range
   virtual void maskTof(const double tofMin, const double tofMax) = 0;
+  /// Mask the events by the condition vector
+  virtual void maskCondition(const std::vector<bool> &mask) = 0;
   /// Return the list of TOF values
   virtual std::vector<double> getTofs() const = 0;
   /// Return the list of TOF values
diff --git a/Framework/API/inc/MantidAPI/IFunction.h b/Framework/API/inc/MantidAPI/IFunction.h
index 31fd0923a40fa9fa5f782c5843328fb762cf5194..976f91742f0fe916dbc03cd3e358ba972699e7c3 100644
--- a/Framework/API/inc/MantidAPI/IFunction.h
+++ b/Framework/API/inc/MantidAPI/IFunction.h
@@ -534,9 +534,9 @@ public:
   bool isParallel() const { return m_isParallel; }
 
   /// Set a function handler
-  void setHandler(FunctionHandler *handler);
+  void setHandler(std::unique_ptr<FunctionHandler> handler);
   /// Return the handler
-  FunctionHandler *getHandler() const { return m_handler; }
+  FunctionHandler *getHandler() const { return m_handler.get(); }
 
   /// Describe parameter status in relation to fitting:
   /// Active: Fit varies such parameter directly.
@@ -597,7 +597,7 @@ protected:
   bool m_isParallel;
 
   /// Pointer to a function handler
-  FunctionHandler *m_handler;
+  std::unique_ptr<FunctionHandler> m_handler;
 
   /// Pointer to the progress handler
   boost::shared_ptr<Kernel::ProgressBase> m_progReporter;
diff --git a/Framework/API/inc/MantidAPI/Sample.h b/Framework/API/inc/MantidAPI/Sample.h
index af2a5f6199aab87a5a27f987efcf5a9d05b36598..08a7f5c4f16c799346355b2fd32770a070b124e1 100644
--- a/Framework/API/inc/MantidAPI/Sample.h
+++ b/Framework/API/inc/MantidAPI/Sample.h
@@ -69,7 +69,7 @@ public:
   /// Get a reference to the sample's environment
   const Geometry::SampleEnvironment &getEnvironment() const;
   /// Set the environment used to contain the sample
-  void setEnvironment(Geometry::SampleEnvironment *env);
+  void setEnvironment(std::unique_ptr<Geometry::SampleEnvironment> env);
   //@}
 
   /** @name Access the sample's lattice structure and orientation */
@@ -127,7 +127,7 @@ private:
   /// An owned pointer to the SampleEnvironment object
   boost::shared_ptr<Geometry::SampleEnvironment> m_environment;
   /// Pointer to the OrientedLattice of the sample, NULL if not set.
-  Geometry::OrientedLattice *m_lattice;
+  std::unique_ptr<Geometry::OrientedLattice> m_lattice;
 
   /// CrystalStructure of the sample
   std::unique_ptr<Geometry::CrystalStructure> m_crystalStructure;
diff --git a/Framework/API/src/Algorithm.cpp b/Framework/API/src/Algorithm.cpp
index 7bf4718f14e411bddaa53c2fe382185b037c1d88..4878e93e52e6e49b706cfe8fbf7906fc0995b7e8 100644
--- a/Framework/API/src/Algorithm.cpp
+++ b/Framework/API/src/Algorithm.cpp
@@ -107,11 +107,7 @@ Algorithm::Algorithm()
       m_communicator(Kernel::make_unique<Parallel::Communicator>()) {}
 
 /// Virtual destructor
-Algorithm::~Algorithm() {
-  delete m_notificationCenter;
-  delete m_executeAsync;
-  delete m_progressObserver;
-}
+Algorithm::~Algorithm() {}
 
 //=============================================================================================
 //================================== Simple Getters/Setters
@@ -573,6 +569,7 @@ bool Algorithm::execute() {
   // Invoke exec() method of derived class and catch all uncaught exceptions
   try {
     try {
+      setExecuted(false);
       if (!isChild()) {
         m_running = true;
       }
@@ -1652,8 +1649,9 @@ private:
  * Asynchronous execution
  */
 Poco::ActiveResult<bool> Algorithm::executeAsync() {
-  m_executeAsync = new Poco::ActiveMethod<bool, Poco::Void, Algorithm>(
-      this, &Algorithm::executeAsyncImpl);
+  m_executeAsync =
+      std::make_unique<Poco::ActiveMethod<bool, Poco::Void, Algorithm>>(
+          this, &Algorithm::executeAsyncImpl);
   return (*m_executeAsync)(Poco::Void());
 }
 
@@ -1672,7 +1670,7 @@ bool Algorithm::executeAsyncImpl(const Poco::Void &) {
  */
 Poco::NotificationCenter &Algorithm::notificationCenter() const {
   if (!m_notificationCenter)
-    m_notificationCenter = new Poco::NotificationCenter;
+    m_notificationCenter = std::make_unique<Poco::NotificationCenter>();
   return *m_notificationCenter;
 }
 
@@ -1692,9 +1690,10 @@ void Algorithm::handleChildProgressNotification(
  */
 const Poco::AbstractObserver &Algorithm::progressObserver() const {
   if (!m_progressObserver)
-    m_progressObserver = new Poco::NObserver<Algorithm, ProgressNotification>(
-        *const_cast<Algorithm *>(this),
-        &Algorithm::handleChildProgressNotification);
+    m_progressObserver =
+        std::make_unique<Poco::NObserver<Algorithm, ProgressNotification>>(
+            *const_cast<Algorithm *>(this),
+            &Algorithm::handleChildProgressNotification);
 
   return *m_progressObserver;
 }
diff --git a/Framework/API/src/AnalysisDataServiceObserver.cpp b/Framework/API/src/AnalysisDataServiceObserver.cpp
index 7dffb883ac6c6c49fec0467d9040b8a255300443..3dde21ea6cd5c35a5078da9bdd62c61cb7dee6c7 100644
--- a/Framework/API/src/AnalysisDataServiceObserver.cpp
+++ b/Framework/API/src/AnalysisDataServiceObserver.cpp
@@ -1,12 +1,27 @@
 // Mantid Repository : https://github.com/mantidproject/mantid
 //
-// Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory UKRI,
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 
 #include "MantidAPI/AnalysisDataServiceObserver.h"
 
+namespace {
+template <typename Observer>
+void modifyObserver(const bool turnOn, bool &isObserving, Observer &observer) {
+  if (turnOn && !isObserving) {
+    AnalysisDataService::Instance().notificationCenter.addObserver(observer);
+  } else if (!turnOn && isObserving) {
+    AnalysisDataService::Instance().notificationCenter.removeObserver(observer);
+  }
+  isObserving = turnOn;
+}
+} // namespace
+
+namespace Mantid {
+namespace API {
+
 AnalysisDataServiceObserver::AnalysisDataServiceObserver()
     : m_addObserver(*this, &AnalysisDataServiceObserver::_addHandle),
       m_replaceObserver(*this, &AnalysisDataServiceObserver::_replaceHandle),
@@ -31,8 +46,8 @@ AnalysisDataServiceObserver::~AnalysisDataServiceObserver() {
 /**
  * @brief Function will turn on/off all observers for the ADS
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True, then if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeAll(bool turnOn) {
   this->observeAdd(turnOn);
@@ -46,147 +61,91 @@ void AnalysisDataServiceObserver::observeAll(bool turnOn) {
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a workspace is
- * added to it.
+ * @brief Function will add/remove the observer to the ADS for when a workspace
+ * is added to it.
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeAdd(bool turnOn) {
-  if (turnOn && !m_observingAdd) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_addObserver);
-  } else if (!turnOn && m_observingAdd) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_addObserver);
-  }
-  m_observingAdd = turnOn;
+  modifyObserver(turnOn, m_observingAdd, m_addObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a workspace is
- * replaced
+ * @brief Function will add/remove the observer to the ADS for when a workspace
+ * is replaced
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeReplace(bool turnOn) {
-  if (turnOn && !m_observingReplace) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_replaceObserver);
-  } else if (!turnOn && m_observingReplace) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_replaceObserver);
-  }
-  m_observingReplace = turnOn;
+  modifyObserver(turnOn, m_observingReplace, m_replaceObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a workspace is
- * deleted.
+ * @brief Function will add/remove the observer to the ADS for when a workspace
+ * is deleted.
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeDelete(bool turnOn) {
-  if (turnOn && !m_observingDelete) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_deleteObserver);
-  } else if (!turnOn && m_observingDelete) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_deleteObserver);
-  }
-  m_observingDelete = turnOn;
+  modifyObserver(turnOn, m_observingDelete, m_deleteObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if the ADS is
+ * @brief Function will add/remove the observer to the ADS for when the ADS is
  * cleared.
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeClear(bool turnOn) {
-  if (turnOn && !m_observingClear) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_clearObserver);
-  } else if (!turnOn && m_observingClear) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_clearObserver);
-  }
-  m_observingClear = turnOn;
+  modifyObserver(turnOn, m_observingClear, m_clearObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a workspace is
- * renamed
+ * @brief Function will add/remove the observer to the ADS for when a workspace
+ * is renamed
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeRename(bool turnOn) {
-  if (turnOn && !m_observingRename) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_renameObserver);
-  } else if (!turnOn && m_observingRename) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_renameObserver);
-  }
-  m_observingRename = turnOn;
+  modifyObserver(turnOn, m_observingRename, m_renameObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a group is
+ * @brief Function will add/remove the observer to the ADS for when a group is
  * added/created in the ADS
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeGroup(bool turnOn) {
-  if (turnOn && !m_observingGroup) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_groupObserver);
-  } else if (!turnOn && m_observingGroup) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_groupObserver);
-  }
-  m_observingGroup = turnOn;
+  modifyObserver(turnOn, m_observingGroup, m_groupObserver);
 }
 
 /**
- * @brief Function will add/remove the observer to the ADS for if a group is
+ * @brief Function will add/remove the observer to the ADS for when a group is
  * removed/delete from the ADS
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeUnGroup(bool turnOn) {
-  if (turnOn && !m_observingUnGroup) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_unGroupObserver);
-  } else if (!turnOn && m_observingUnGroup) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_unGroupObserver);
-  }
-  m_observingUnGroup = turnOn;
+  modifyObserver(turnOn, m_observingUnGroup, m_unGroupObserver);
 }
 
 /**
  * @brief Function will add/remove the observer to the ADS for if a workspace is
  * added to a group or removed.
  *
- * @param turnOn bool; if this is True then if not already present the observer
- * will be added else removed if it's false.
+ * @param turnOn bool; if this is True then, if not already present, the
+ * observer will be added else removed if it's false.
  */
 void AnalysisDataServiceObserver::observeGroupUpdate(bool turnOn) {
-  if (turnOn && !m_observingGroupUpdate) {
-    AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_groupUpdatedObserver);
-  } else if (!turnOn && m_observingGroupUpdate) {
-    AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_groupUpdatedObserver);
-  }
-  m_observingGroupUpdate = turnOn;
+  modifyObserver(turnOn, m_observingGroupUpdate, m_groupUpdatedObserver);
 }
 
 // ------------------------------------------------------------
@@ -350,4 +309,7 @@ void AnalysisDataServiceObserver::_groupUpdateHandle(
         &pNf) {
   this->anyChangeHandle();
   this->groupUpdateHandle(pNf->objectName(), pNf->object());
-}
\ No newline at end of file
+}
+
+} // namespace API
+} // namespace Mantid
\ No newline at end of file
diff --git a/Framework/API/src/IFunction.cpp b/Framework/API/src/IFunction.cpp
index 74d02c7dc04146465946f9a4ab9e30a1aaf6efbc..887c0892f8798c17846f127ad097b0db14e823d4 100644
--- a/Framework/API/src/IFunction.cpp
+++ b/Framework/API/src/IFunction.cpp
@@ -66,13 +66,7 @@ struct TieNode {
 /**
  * Destructor
  */
-IFunction::~IFunction() {
-  m_attrs.clear();
-  if (m_handler) {
-    delete m_handler;
-    m_handler = nullptr;
-  }
-}
+IFunction::~IFunction() { m_attrs.clear(); }
 
 /**
  * Virtual copy constructor
@@ -558,8 +552,8 @@ std::vector<std::string> IFunction::getParameterNames() const {
 /** Set a function handler
  * @param handler :: A new handler
  */
-void IFunction::setHandler(FunctionHandler *handler) {
-  m_handler = handler;
+void IFunction::setHandler(std::unique_ptr<FunctionHandler> handler) {
+  m_handler = std::move(handler);
   if (handler && handler->function().get() != this) {
     throw std::runtime_error("Function handler points to a different function");
   }
diff --git a/Framework/API/src/Sample.cpp b/Framework/API/src/Sample.cpp
index fa1078cd5c8c9eb1701fdc166edf502ea669856f..aefb03a631a09f14f9f584b19ec19c9f2c6089de 100644
--- a/Framework/API/src/Sample.cpp
+++ b/Framework/API/src/Sample.cpp
@@ -48,16 +48,16 @@ Sample::Sample(const Sample &copy)
       m_geom_id(copy.m_geom_id), m_thick(copy.m_thick), m_height(copy.m_height),
       m_width(copy.m_width) {
   if (copy.m_lattice)
-    m_lattice = new OrientedLattice(copy.getOrientedLattice());
+    m_lattice = std::make_unique<OrientedLattice>(copy.getOrientedLattice());
 
   if (copy.hasCrystalStructure()) {
-    m_crystalStructure.reset(
-        new Geometry::CrystalStructure(copy.getCrystalStructure()));
+    m_crystalStructure = std::make_unique<Geometry::CrystalStructure>(
+        copy.getCrystalStructure());
   }
 }
 
 /// Destructor
-Sample::~Sample() { delete m_lattice; }
+Sample::~Sample() = default;
 
 /** Assignment operator
  * @param rhs :: const reference to the sample object
@@ -75,12 +75,10 @@ Sample &Sample::operator=(const Sample &rhs) {
   m_thick = rhs.m_thick;
   m_height = rhs.m_height;
   m_width = rhs.m_width;
-  if (m_lattice != nullptr)
-    delete m_lattice;
   if (rhs.m_lattice)
-    m_lattice = new OrientedLattice(rhs.getOrientedLattice());
+    m_lattice = std::make_unique<OrientedLattice>(rhs.getOrientedLattice());
   else
-    m_lattice = nullptr;
+    m_lattice.reset(nullptr);
 
   m_crystalStructure.reset();
   if (rhs.hasCrystalStructure()) {
@@ -146,8 +144,8 @@ const SampleEnvironment &Sample::getEnvironment() const {
  * @param env :: A pointer to a created sample environment. This takes
  * ownership of the object.
  */
-void Sample::setEnvironment(SampleEnvironment *env) {
-  m_environment = boost::shared_ptr<SampleEnvironment>(env);
+void Sample::setEnvironment(std::unique_ptr<SampleEnvironment> env) {
+  m_environment = boost::shared_ptr<SampleEnvironment>(std::move(env));
 }
 
 /** Return a const reference to the OrientedLattice of this sample
@@ -179,13 +177,10 @@ OrientedLattice &Sample::getOrientedLattice() {
  * @param latt :: A pointer to a OrientedLattice.
  */
 void Sample::setOrientedLattice(OrientedLattice *latt) {
-  if (m_lattice != nullptr) {
-    delete m_lattice;
-  }
   if (latt != nullptr)
-    m_lattice = new OrientedLattice(*latt);
+    m_lattice = std::make_unique<OrientedLattice>(*latt);
   else
-    m_lattice = nullptr;
+    m_lattice.reset(nullptr);
 }
 
 /** @return true if the sample has an OrientedLattice  */
@@ -394,7 +389,7 @@ int Sample::loadNexus(::NeXus::File *file, const std::string &group) {
     int num_oriented_lattice;
     file->readData("num_oriented_lattice", num_oriented_lattice);
     if (num_oriented_lattice > 0) {
-      m_lattice = new OrientedLattice;
+      m_lattice = std::make_unique<OrientedLattice>();
       m_lattice->loadNexus(file, "oriented_lattice");
     }
   }
@@ -418,8 +413,7 @@ int Sample::loadNexus(::NeXus::File *file, const std::string &group) {
  */
 void Sample::clearOrientedLattice() {
   if (m_lattice) {
-    delete m_lattice;
-    m_lattice = nullptr;
+    m_lattice.reset(nullptr);
   }
 }
 } // namespace API
diff --git a/Framework/API/src/WorkspaceFactory.cpp b/Framework/API/src/WorkspaceFactory.cpp
index 30dedbc1fe13fbb5d4707218919d8824470e3bbd..bc8b78456c8f83a02e5d0dc056e1052220827107 100644
--- a/Framework/API/src/WorkspaceFactory.cpp
+++ b/Framework/API/src/WorkspaceFactory.cpp
@@ -5,6 +5,7 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -127,21 +128,26 @@ void WorkspaceFactoryImpl::initializeFromParent(
 
   // deal with axis
   for (size_t i = 0; i < parent.m_axes.size(); ++i) {
-    const size_t newAxisLength = child.getAxis(i)->length();
-    const size_t oldAxisLength = parent.getAxis(i)->length();
-
-    if (!differentSize || newAxisLength == oldAxisLength) {
-      // Need to delete the existing axis created in init above
-      delete child.m_axes[i];
+    if (parent.m_axes[i]->isSpectra()) {
+      // By default the child already has a spectra axis which
+      // does not need to get cloned from the parent.
+      continue;
+    }
+    const bool isBinEdge =
+        dynamic_cast<const BinEdgeAxis *const>(parent.m_axes[i]) != nullptr;
+    const size_t newAxisLength =
+        child.m_axes[i]->length() + (isBinEdge ? 1 : 0);
+    const size_t oldAxisLength = parent.m_axes[i]->length();
+
+    // Need to delete the existing axis created in init above
+    delete child.m_axes[i];
+    child.m_axes[i] = nullptr;
+    if (newAxisLength == oldAxisLength) {
       // Now set to a copy of the parent workspace's axis
       child.m_axes[i] = parent.m_axes[i]->clone(&child);
     } else {
-      if (!parent.getAxis(i)->isSpectra()) // WHY???
-      {
-        delete child.m_axes[i];
-        // Call the 'different length' clone variant
-        child.m_axes[i] = parent.m_axes[i]->clone(newAxisLength, &child);
-      }
+      // Call the 'different length' clone variant
+      child.m_axes[i] = parent.m_axes[i]->clone(newAxisLength, &child);
     }
   }
 }
diff --git a/Framework/API/test/FakeAlgorithms.h b/Framework/API/test/FakeAlgorithms.h
index a48b0abd2442a3d49b9d3d5a402d497837f7dfef..5c875ae8a8bec350412248a8aa01e0b267f01db1 100644
--- a/Framework/API/test/FakeAlgorithms.h
+++ b/Framework/API/test/FakeAlgorithms.h
@@ -68,12 +68,10 @@ public:
     declareProperty("prop1", "value");
     declareProperty("prop2", 1);
     declareProperty("prop3", 10.5);
-    std::vector<double> binning;
-    binning.push_back(1.0);
-    binning.push_back(0.1);
-    binning.push_back(2.0);
+    std::vector<double> binning{1.0, 0.1, 2.0};
     declareProperty(Mantid::Kernel::make_unique<ArrayProperty<double>>(
-        "Binning", binning, boost::make_shared<RebinParamsValidator>()));
+        "Binning", std::move(binning),
+        boost::make_shared<RebinParamsValidator>()));
   }
   void exec() override {}
 };
diff --git a/Framework/API/test/SampleTest.h b/Framework/API/test/SampleTest.h
index 6b73e2df9e74b9dfb165eff2f23df170d0f0fb50..65fa08fdf43e672636b745199fd1fe90ed29d78c 100644
--- a/Framework/API/test/SampleTest.h
+++ b/Framework/API/test/SampleTest.h
@@ -62,15 +62,14 @@ public:
   test_That_An_Environment_Can_Be_Set_And_The_Same_Environment_Is_Returned() {
     Sample sample;
     const std::string envName("TestKit");
-    SampleEnvironment *kit =
-        new SampleEnvironment(envName, boost::make_shared<const Container>(""));
+    auto kit = std::make_unique<SampleEnvironment>(
+        envName, boost::make_shared<const Container>(""));
     kit->add(boost::make_shared<const CSGObject>());
 
-    TS_ASSERT_THROWS_NOTHING(sample.setEnvironment(kit));
+    TS_ASSERT_THROWS_NOTHING(sample.setEnvironment(std::move(kit)));
 
     const SampleEnvironment &sampleKit = sample.getEnvironment();
     // Test that this references the correct object
-    TS_ASSERT_EQUALS(&sampleKit, kit);
     TS_ASSERT_EQUALS(sampleKit.name(), envName);
     TS_ASSERT_EQUALS(sampleKit.nelements(), 2);
   }
diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index 833a810433fb12e2128ee3a379f310da5dfd9749..b25448dccdee91276b4fe8a0377ef79f5f96b8c2 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -701,6 +701,7 @@ set ( TEST_FILES
 	AppendSpectraTest.h
 	ApplyCalibrationTest.h
 	ApplyDetailedBalanceTest.h
+	ApplyFloodWorkspaceTest.h
 	ApplyTransmissionCorrectionTest.h
 	AverageLogDataTest.h
 	Bin2DPowderDiffractionTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
index f6142bb49c5dbddf979a6f94cfdf5303a2a23f1c..74198235cb60dc8293acca81e86fa32879b796fe 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
@@ -43,7 +43,6 @@ class ConversionFactors;
 class DLLExport AlignDetectors : public API::Algorithm {
 public:
   AlignDetectors();
-  ~AlignDetectors() override;
 
   /// Algorithms name for identification. @see Algorithm::name
   const std::string name() const override;
@@ -83,9 +82,6 @@ private:
 
   /// number of spectra in input workspace
   int64_t m_numberOfSpectra;
-
-  /// Map of conversion factors for TOF to d-Spacing conversion
-  std::map<detid_t, double> *tofToDmap;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
index 2f4c5017c4bcc4b04319a87d189e3e2df5fdccf8..16b3392f45c303a2504dcb688b80f617cb5be066 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
@@ -14,6 +14,7 @@
 #include "MantidAPI/Workspace_fwd.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidHistogramData/Histogram.h"
 #include "MantidKernel/System.h"
 
 namespace Mantid {
@@ -102,41 +103,29 @@ protected:
   /** Carries out the binary operation on a single spectrum, with another
    *spectrum as the right-hand operand.
    *
-   *  @param lhsX :: The X values, made available if required.
-   *  @param lhsY :: The vector of lhs data values
-   *  @param lhsE :: The vector of lhs error values
-   *  @param rhsY :: The vector of rhs data values
-   *  @param rhsE :: The vector of rhs error values
-   *  @param YOut :: The vector to hold the data values resulting from the
-   *operation
-   *  @param EOut :: The vector to hold the error values resulting from the
-   *operation
+   *  @param lhs :: Lhs histogram data
+   *  @param rhs :: Rhs histogram data
+   *  @param YOut :: Data values resulting from the operation
+   *  @param EOut :: Drror values resulting from the operation
    */
-  virtual void performBinaryOperation(const MantidVec &lhsX,
-                                      const MantidVec &lhsY,
-                                      const MantidVec &lhsE,
-                                      const MantidVec &rhsY,
-                                      const MantidVec &rhsE, MantidVec &YOut,
-                                      MantidVec &EOut) = 0;
+  virtual void performBinaryOperation(const HistogramData::Histogram &lhs,
+                                      const HistogramData::Histogram &rhs,
+                                      HistogramData::HistogramY &YOut,
+                                      HistogramData::HistogramE &EOut) = 0;
 
   /** Carries out the binary operation when the right hand operand is a single
    *number.
    *
-   *  @param lhsX :: The X values, made available if required.
-   *  @param lhsY :: The vector of lhs data values
-   *  @param lhsE :: The vector of lhs error values
+   *  @param lhs :: Lhs histogram data
    *  @param rhsY :: The rhs data value
-   *  @param rhsE :: The rhs error value
-   *  @param YOut :: The vector to hold the data values resulting from the
-   *operation
-   *  @param EOut :: The vector to hold the error values resulting from the
-   *operation
+   *  @param rhsE :: The lhs data value
+   *  @param YOut :: Data values resulting from the operation
+   *  @param EOut :: Error values resulting from the operation
    */
-  virtual void performBinaryOperation(const MantidVec &lhsX,
-                                      const MantidVec &lhsY,
-                                      const MantidVec &lhsE, const double rhsY,
-                                      const double rhsE, MantidVec &YOut,
-                                      MantidVec &EOut) = 0;
+  virtual void performBinaryOperation(const HistogramData::Histogram &lhs,
+                                      const double rhsY, const double rhsE,
+                                      HistogramData::HistogramY &YOut,
+                                      HistogramData::HistogramE &EOut) = 0;
 
   // ===================================== EVENT LIST BINARY OPERATIONS
   // ==========================================
@@ -155,9 +144,9 @@ protected:
    * with another (histogrammed) spectrum as the right-hand operand.
    *
    *  @param lhs :: Reference to the EventList that will be modified in place.
-   *  @param rhsX :: The vector of rhs X bin boundaries
-   *  @param rhsY :: The vector of rhs data values
-   *  @param rhsE :: The vector of rhs error values
+   *  @param rhsX :: Rhs X bin boundaries
+   *  @param rhsY :: Rhs data values
+   *  @param rhsE :: Rhs error values
    */
   virtual void performEventBinaryOperation(DataObjects::EventList &lhs,
                                            const MantidVec &rhsX,
@@ -193,9 +182,9 @@ protected:
   /** Only overridden by operations that affect the properties of the run (e.g.
    * Plus
    *  where the proton currents (charges) are added). Otherwise it does nothing.
-   *  @param lhs :: one of the workspaces to operate on
-   *  @param rhs :: the other workspace
-   *  @param ans :: the output workspace
+   *  @param lhs :: One of the workspaces to operate on
+   *  @param rhs :: The other workspace
+   *  @param ans :: The output workspace
    */
 
   virtual void operateOnRun(const API::Run &lhs, const API::Run &rhs,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CommutativeBinaryOperation.h b/Framework/Algorithms/inc/MantidAlgorithms/CommutativeBinaryOperation.h
index dde6b296101fef4a24f54d93f0e0e4bc08befc4a..c8922438d213c734706587389d97bfb888156a5c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CommutativeBinaryOperation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CommutativeBinaryOperation.h
@@ -4,12 +4,9 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_ALGORITHM_COMMUTATIVEBINARYOPERATION_H_
-#define MANTID_ALGORITHM_COMMUTATIVEBINARYOPERATION_H_
+#ifndef MANTID_ALGORITHMS_COMMUTATIVEBINARYOPERATION_H_
+#define MANTID_ALGORITHMS_COMMUTATIVEBINARYOPERATION_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/BinaryOperation.h"
 
 namespace Mantid {
@@ -38,4 +35,4 @@ protected:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /*MANTID_ALGORITHM_COMMUTATIVEBINARYOPERATION_H_*/
+#endif /*MANTID_ALGORITHMS_COMMUTATIVEBINARYOPERATION_H_*/
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
index 5167bf138567b65c59992785e2a3fa4176231824..d64feb5626b2834783008dcd5c043cca59d01ddf 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
@@ -24,7 +24,6 @@ namespace Algorithms {
 class DLLExport CreateSampleWorkspace : public API::Algorithm {
 public:
   CreateSampleWorkspace();
-  ~CreateSampleWorkspace() override;
 
   const std::string name() const override;
   int version() const override;
@@ -72,7 +71,7 @@ private:
   void addChopperParameters(API::MatrixWorkspace_sptr &ws);
 
   /// A pointer to the random number generator
-  Kernel::PseudoRandomNumberGenerator *m_randGen;
+  std::unique_ptr<Kernel::PseudoRandomNumberGenerator> m_randGen;
   std::map<std::string, std::string> m_preDefinedFunctionmap;
 };
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
index add31a64e015df48de3887db6b2c2346c5e7d2b2..82ac1ef4bec2508e5a0d12f2d0084ae52a59718b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
@@ -4,12 +4,9 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_ALGORITHM_DIVIDE_H_
-#define MANTID_ALGORITHM_DIVIDE_H_
+#ifndef MANTID_ALGORITHMS_DIVIDE_H_
+#define MANTID_ALGORITHMS_DIVIDE_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/BinaryOperation.h"
 
 namespace Mantid {
@@ -21,8 +18,8 @@ the init() & exec()  methods.
 
 Required Properties:
 <UL>
-<LI> InputWorkspace1 - The name of the workspace </LI>
-<LI> InputWorkspace2 - The name of the workspace </LI>
+<LI> LHSWorkspace - The name of the workspace </LI>
+<LI> RHSWorkspace - The name of the workspace </LI>
 <LI> OutputWorkspace - The name of the workspace in which to store the division
 data </LI>
 </UL>
@@ -50,14 +47,14 @@ private:
   void init() override;
   void exec() override;
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
   void setOutputUnits(const API::MatrixWorkspace_const_sptr lhs,
                       const API::MatrixWorkspace_const_sptr rhs,
                       API::MatrixWorkspace_sptr out) override;
@@ -86,4 +83,4 @@ private:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /*MANTID_ALGORITHM_DIVIDE_H_*/
+#endif /*MANTID_ALGORITHMS_DIVIDE_H_*/
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
index afff45a5ade87e7796f77664d18b0f3c7186261c..14e02be2b9d2a1b6c141e46a90c51375a6c7b82d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
@@ -50,8 +50,7 @@ class DLLExport He3TubeEfficiency : public API::Algorithm {
 public:
   /// Default constructor
   He3TubeEfficiency();
-  /// Virtual destructor
-  ~He3TubeEfficiency() override;
+
   /// Algorithm's name for identification overriding a virtual method
   const std::string name() const override { return "He3TubeEfficiency"; }
   /// Summary of algorithms purpose
@@ -118,7 +117,7 @@ private:
   /// The spectra numbers that were skipped
   std::vector<specnum_t> m_spectraSkipped;
   /// Algorithm progress keeper
-  API::Progress *m_progress;
+  std::unique_ptr<API::Progress> m_progress;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
index b2d6f754f7754a7f1496544acf5a7e39e09a85c0..bb7b0fb8df8f63f736293cdbdd43a841143331da 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
@@ -4,12 +4,8 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_ALGORITHM_MINUS_H_
-#define MANTID_ALGORITHM_MINUS_H_
-
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
+#ifndef MANTID_ALGORITHMS_MINUS_H_
+#define MANTID_ALGORITHMS_MINUS_H_
 #include "MantidAlgorithms/BinaryOperation.h"
 
 namespace Mantid {
@@ -21,8 +17,8 @@ the init() & exec() methods.
 
 Required Properties:
 <UL>
-<LI> InputWorkspace1 - The name of the workspace </LI>
-<LI> InputWorkspace2 - The name of the workspace </LI>
+<LI> LSHWorkspace - The name of the workspace </LI>
+<LI> RHSWorkspace - The name of the workspace </LI>
 <LI> OutputWorkspace - The name of the workspace in which to store the
 difference data </LI>
 </UL>
@@ -50,14 +46,14 @@ public:
 
 private:
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
   void performEventBinaryOperation(DataObjects::EventList &lhs,
                                    const DataObjects::EventList &rhs) override;
   void performEventBinaryOperation(DataObjects::EventList &lhs,
@@ -81,4 +77,4 @@ private:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /*MANTID_ALGORITHM_MINUS_H_*/
+#endif /*MANTID_ALGORITHMS_MINUS_H_*/
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
index e869ecfbd6384e86aa47f32ab7044a3dd22319f5..33d5949fc4d5ec508fc63802fe9d78bd92f0f420 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
@@ -4,12 +4,9 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_ALGORITHM_MULTIPLY_H_
-#define MANTID_ALGORITHM_MULTIPLY_H_
+#ifndef MANTID_ALGORITHMS_MULTIPLY_H_
+#define MANTID_ALGORITHMS_MULTIPLY_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/CommutativeBinaryOperation.h"
 
 namespace Mantid {
@@ -21,8 +18,8 @@ the init()&+ exec()  methods.
 
 Required Properties:
 <UL>
-<LI> InputWorkspace1 - The name of the workspace </LI>
-<LI> InputWorkspace2 - The name of the workspace </LI>
+<LI> LHSWorkspace - The name of the workspace </LI>
+<LI> RHSWorkspace - The name of the workspace </LI>
 <LI> OutputWorkspace - The name of the workspace in which to store the product
 data </LI>
 </UL>
@@ -48,14 +45,14 @@ public:
 
 private:
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
 
   void setOutputUnits(const API::MatrixWorkspace_const_sptr lhs,
                       const API::MatrixWorkspace_const_sptr rhs,
@@ -81,4 +78,4 @@ private:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /*MANTID_ALGORITHM_MULTIPLY_H_*/
+#endif /*MANTID_ALGORITHMS_MULTIPLY_H_*/
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
index b3e65b75fcb1a7a7b6a64d0a8e986a75ca422675..db9ec2f07900ddd1e5e5b4dcfa9abb08d6c580f6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
@@ -4,12 +4,10 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_ALGORITHM_PLUS_H_
-#define MANTID_ALGORITHM_PLUS_H_
+#ifndef MANTID_ALGORITHMS_PLUS_H_
+#define MANTID_ALGORITHMS_PLUS_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
+#include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAPI/Run.h"
 #include "MantidAlgorithms/CommutativeBinaryOperation.h"
 #include "MantidDataObjects/EventWorkspace.h"
@@ -17,14 +15,14 @@
 namespace Mantid {
 namespace Algorithms {
 /**
-Plus performs the difference of two input workspaces.
+Plus performs the addition of two input workspaces.
 It inherits from the Algorithm class, and overrides
 the init() & exec() methods.
 
 Required Properties:
 <UL>
-<LI> InputWorkspace1 - The name of the workspace </LI>
-<LI> InputWorkspace2 - The name of the workspace </LI>
+<LI> LHSWorkspace - The name of the workspace </LI>
+<LI> RHSWorkspace - The name of the workspace </LI>
 <LI> OutputWorkspace - The name of the workspace in which to store the added
 data </LI>
 </UL>
@@ -50,14 +48,14 @@ public:
 
 private:
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
   void performEventBinaryOperation(DataObjects::EventList &lhs,
                                    const DataObjects::EventList &rhs) override;
   void performEventBinaryOperation(DataObjects::EventList &lhs,
@@ -85,4 +83,4 @@ private:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /*MANTID_ALGORITHM_PLUS_H_*/
+#endif /*MANTID_ALGORITHMS_PLUS_H_*/
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PoissonErrors.h b/Framework/Algorithms/inc/MantidAlgorithms/PoissonErrors.h
index 9f10e2b7cb285d3e8071c0927cb4c05eb805cc5b..547b6bdfe3c14b21b06e5b8e48355443214a3058 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PoissonErrors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PoissonErrors.h
@@ -7,9 +7,6 @@
 #ifndef MANTID_ALGORITHMS_POISSONERRORS_H_
 #define MANTID_ALGORITHMS_POISSONERRORS_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/BinaryOperation.h"
 
 namespace Mantid {
@@ -52,14 +49,14 @@ public:
 
 private:
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
   std::string checkSizeCompatibility(
       const API::MatrixWorkspace_const_sptr lhs,
       const API::MatrixWorkspace_const_sptr rhs) const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
index 45b9511f791c6e485e76463c789d9ad3a032ce5c..22dd73f60eb9fbfa4994bc3a02f50362edd04972 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
@@ -35,8 +35,7 @@ class DLLExport ScaleX : public API::Algorithm {
 public:
   /// Default constructor
   ScaleX();
-  /// Destructor
-  ~ScaleX() override;
+
   /// Algorithm's name for identification overriding a virtual method
   const std::string name() const override { return "ScaleX"; }
   /// Summary of algorithms purpose
@@ -70,7 +69,7 @@ private:
                         const size_t index);
 
   /// The progress reporting object
-  API::Progress *m_progress;
+  std::unique_ptr<API::Progress> m_progress;
 
   /// Scaling factor
   double m_algFactor;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/TimeAtSampleStrategy.h b/Framework/Algorithms/inc/MantidAlgorithms/TimeAtSampleStrategy.h
index 8a7063175b1f847acaa8b21321db3512b7227f60..e315b2d241c4cf9eeff0b8535867fcfb07084560 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/TimeAtSampleStrategy.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/TimeAtSampleStrategy.h
@@ -13,7 +13,7 @@ namespace Mantid {
 namespace Algorithms {
 
 /**
- * @brief The Correction struct
+ * @brief The Correction struct to be applied as factor * TOF + offset
  * offset:: TOF offset in unit of TOF
  * factor:  TOF correction factor to multiply with
  */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
index 3ba36ad90d40ce873ce88ae39d5af1f1029a3552..acce27c3238856e933639d12e5b4a561a980757f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
@@ -7,10 +7,8 @@
 #ifndef MANTID_ALGORITHMS_WEIGHTEDMEAN_H_
 #define MANTID_ALGORITHMS_WEIGHTEDMEAN_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidAlgorithms/BinaryOperation.h"
+#include "MantidAlgorithms/CommutativeBinaryOperation.h"
+#include "MantidHistogramData/Histogram.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -27,7 +25,7 @@ namespace Algorithms {
     @author Robert Dalgliesh, ISIS, RAL
     @date 12/1/2010
  */
-class DLLExport WeightedMean : public BinaryOperation {
+class DLLExport WeightedMean : public CommutativeBinaryOperation {
 public:
   const std::string name() const override { return "WeightedMean"; }
   /// Summary of algorithms purpose
@@ -42,14 +40,14 @@ public:
 
 private:
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override;
   bool
   checkCompatibility(const API::MatrixWorkspace_const_sptr lhs,
                      const API::MatrixWorkspace_const_sptr rhs) const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WorkspaceJoiners.h b/Framework/Algorithms/inc/MantidAlgorithms/WorkspaceJoiners.h
index fe4f8745c31ff546f7c57b42cdc0af18c0c943fd..69e3144e512141320a4c8c420df85f8bec19310a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/WorkspaceJoiners.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/WorkspaceJoiners.h
@@ -25,7 +25,6 @@ namespace Algorithms {
 class DLLExport WorkspaceJoiners : public API::Algorithm {
 public:
   WorkspaceJoiners();
-  ~WorkspaceJoiners() override;
 
   const std::string category() const override;
 
@@ -51,7 +50,7 @@ protected:
                                   const API::MatrixWorkspace &ws2,
                                   API::MatrixWorkspace &output) = 0;
 
-  API::Progress *m_progress; ///< Progress reporting object
+  std::unique_ptr<API::Progress> m_progress; ///< Progress reporting object
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/src/AbsorptionCorrection.cpp b/Framework/Algorithms/src/AbsorptionCorrection.cpp
index f74a8aa03e12675626433206ca857c168a8c8cd1..7ab980db4e194b3611df72ea56565b3b61e036cf 100644
--- a/Framework/Algorithms/src/AbsorptionCorrection.cpp
+++ b/Framework/Algorithms/src/AbsorptionCorrection.cpp
@@ -138,6 +138,11 @@ void AbsorptionCorrection::exec() {
 
   // Calculate the cached values of L1 and element volumes.
   initialiseCachedDistances();
+  if (m_L1s.empty()) {
+    throw std::runtime_error(
+        "Failed to define any initial scattering gauge volume for geometry");
+  }
+
   // If sample not at origin, shift cached positions.
   const auto &spectrumInfo = m_inputWS->spectrumInfo();
   const V3D samplePos = spectrumInfo.samplePosition();
diff --git a/Framework/Algorithms/src/AddPeak.cpp b/Framework/Algorithms/src/AddPeak.cpp
index c497c06dff57379cf0e9e3c7cd2489cb086c72ca..116bb58502d32d3127ade2711a0cfa5456dcb311 100644
--- a/Framework/Algorithms/src/AddPeak.cpp
+++ b/Framework/Algorithms/src/AddPeak.cpp
@@ -117,8 +117,8 @@ void AddPeak::exec() {
   Qy *= knorm;
   Qz *= knorm;
 
-  Mantid::Geometry::IPeak *peak =
-      peaksWS->createPeak(Mantid::Kernel::V3D(Qx, Qy, Qz), l2);
+  auto peak = std::unique_ptr<Mantid::Geometry::IPeak>(
+      peaksWS->createPeak(Mantid::Kernel::V3D(Qx, Qy, Qz), l2));
   peak->setDetectorID(detID);
   peak->setGoniometerMatrix(runWS->run().getGoniometer().getR());
   peak->setBinCount(count);
@@ -128,7 +128,6 @@ void AddPeak::exec() {
     peak->setSigmaIntensity(std::sqrt(height));
 
   peaksWS->addPeak(*peak);
-  delete peak;
   // peaksWS->modified();
 }
 
diff --git a/Framework/Algorithms/src/AlignDetectors.cpp b/Framework/Algorithms/src/AlignDetectors.cpp
index 0503c00533f2a31c5527ebef60c271c6cd5dcb75..8e766661918dc5da3d65ed72bee09863e129a97c 100644
--- a/Framework/Algorithms/src/AlignDetectors.cpp
+++ b/Framework/Algorithms/src/AlignDetectors.cpp
@@ -111,12 +111,7 @@ const std::string AlignDetectors::summary() const {
 }
 
 /// (Empty) Constructor
-AlignDetectors::AlignDetectors() : m_numberOfSpectra(0) {
-  this->tofToDmap = nullptr;
-}
-
-/// Destructor
-AlignDetectors::~AlignDetectors() { delete this->tofToDmap; }
+AlignDetectors::AlignDetectors() : m_numberOfSpectra(0) {}
 
 void AlignDetectors::init() {
   auto wsValidator = boost::make_shared<CompositeValidator>();
diff --git a/Framework/Algorithms/src/ApplyFloodWorkspace.cpp b/Framework/Algorithms/src/ApplyFloodWorkspace.cpp
index 29dc640d720ebc18f39c5019814d568106d025da..cd2294d7d2aad6fc6ad20e89ad5a257179efee4b 100644
--- a/Framework/Algorithms/src/ApplyFloodWorkspace.cpp
+++ b/Framework/Algorithms/src/ApplyFloodWorkspace.cpp
@@ -5,10 +5,15 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidAlgorithms/ApplyFloodWorkspace.h"
+#include "MantidAPI/Axis.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAlgorithms/BinaryOperation.h"
+#include "MantidKernel/Unit.h"
 
 using namespace Mantid::Kernel;
+using namespace Mantid::Algorithms;
 using namespace Mantid::API;
 
 namespace {
@@ -30,6 +35,31 @@ void correctEvents(MatrixWorkspace *ws) {
     }
   }
 }
+
+/// Make sure that the returned flood workspace match the input workspace
+/// in number and order of the spectra.
+MatrixWorkspace_sptr makeEqualSizes(const MatrixWorkspace_sptr &input,
+                                    const MatrixWorkspace_sptr &flood) {
+  auto newFlood =
+      WorkspaceFactory::Instance().create(flood, input->getNumberHistograms());
+  auto const table = BinaryOperation::buildBinaryOperationTable(input, flood);
+  const ISpectrum *missingSpectrum = nullptr;
+  for (size_t i = 0; i < table->size(); ++i) {
+    auto const j = (*table)[i];
+    if (j < 0) {
+      if (missingSpectrum) {
+        newFlood->getSpectrum(i).copyDataFrom(*missingSpectrum);
+      } else {
+        newFlood->dataY(i).assign(flood->blocksize(), 1.0);
+        newFlood->dataE(i).assign(flood->blocksize(), 0.0);
+        missingSpectrum = &newFlood->getSpectrum(i);
+      }
+    } else {
+      newFlood->getSpectrum(i).copyDataFrom(flood->getSpectrum(j));
+    }
+  }
+  return newFlood;
+}
 } // namespace
 
 namespace Mantid {
@@ -74,6 +104,33 @@ void ApplyFloodWorkspace::init() {
 void ApplyFloodWorkspace::exec() {
   MatrixWorkspace_sptr input = getProperty(Prop::INPUT_WORKSPACE);
   MatrixWorkspace_sptr flood = getProperty(Prop::FLOOD_WORKSPACE);
+
+  if (input->size() != flood->size()) {
+    flood = makeEqualSizes(input, flood);
+  }
+
+  auto const inputXUnitId = input->getAxis(0)->unit()->unitID();
+  bool const doConvertUnits =
+      flood->getAxis(0)->unit()->unitID() != inputXUnitId;
+  bool const doRebin = flood->blocksize() > 1;
+
+  if (doRebin) {
+    if (doConvertUnits) {
+      auto convert = createChildAlgorithm("ConvertUnits", 0, 1);
+      convert->setProperty("InputWorkspace", flood);
+      convert->setProperty("Target", inputXUnitId);
+      convert->setProperty("OutputWorkspace", "dummy");
+      convert->execute();
+      flood = convert->getProperty("OutputWorkspace");
+    }
+    auto rebin = createChildAlgorithm("RebinToWorkspace", 0, 1);
+    rebin->setProperty("WorkspaceToRebin", flood);
+    rebin->setProperty("WorkspaceToMatch", input);
+    rebin->setProperty("OutputWorkspace", "dummy");
+    rebin->execute();
+    flood = rebin->getProperty("OutputWorkspace");
+  }
+
   auto divide = createChildAlgorithm("Divide", 0, 1);
   divide->setProperty("LHSWorkspace", input);
   divide->setProperty("RHSWorkspace", flood);
diff --git a/Framework/Algorithms/src/BinaryOperation.cpp b/Framework/Algorithms/src/BinaryOperation.cpp
index 191489bbd26b914b5f4c862ba0b0c294bbdab885..902e34b4527d478d1c5ef83185221e5bb9b6c74f 100644
--- a/Framework/Algorithms/src/BinaryOperation.cpp
+++ b/Framework/Algorithms/src/BinaryOperation.cpp
@@ -234,14 +234,6 @@ void BinaryOperation::exec() {
     //   (b) it has been, but it's not the correct dimensions
     if ((m_out != m_lhs && m_out != m_rhs) ||
         (m_out == m_rhs && (m_lhs->size() > m_rhs->size()))) {
-      // Make sure to delete anything that might be in the output name.
-      // Removed ahead of 2.0 release to avoid problems detailed in trac #4630.
-      // Hopefully temporary (see #4635).
-      //          if
-      //          (AnalysisDataService::Instance().doesExist(getPropertyValue(outputPropName()
-      //          )))
-      //            AnalysisDataService::Instance().remove(getPropertyValue(outputPropName()
-      //            ));
       m_out = WorkspaceFactory::Instance().create(m_lhs);
     }
   }
@@ -464,8 +456,8 @@ void BinaryOperation::doSingleValue() {
   // single value was masked
 
   // Pull out the single value and its error
-  const double rhsY = m_rhs->readY(0)[0];
-  const double rhsE = m_rhs->readE(0)[0];
+  const double rhsY = m_rhs->y(0)[0];
+  const double rhsE = m_rhs->e(0)[0];
 
   // Now loop over the spectra of the left hand side calling the virtual
   // function
@@ -476,7 +468,7 @@ void BinaryOperation::doSingleValue() {
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
-      m_out->setX(i, m_lhs->refX(i));
+      m_out->setSharedX(i, m_lhs->sharedX(i));
       performEventBinaryOperation(m_eout->getSpectrum(i), rhsY, rhsE);
       m_progress->report(this->name());
       PARALLEL_END_INTERUPT_REGION
@@ -487,15 +479,14 @@ void BinaryOperation::doSingleValue() {
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
-      m_out->setX(i, m_lhs->refX(i));
+      m_out->setSharedX(i, m_lhs->sharedX(i));
       // Get reference to output vectors here to break any sharing outside the
       // function call below
       // where the order of argument evaluation is not guaranteed (if it's L->R
       // there would be a data race)
-      MantidVec &outY = m_out->dataY(i);
-      MantidVec &outE = m_out->dataE(i);
-      performBinaryOperation(m_lhs->readX(i), m_lhs->readY(i), m_lhs->readE(i),
-                             rhsY, rhsE, outY, outE);
+      HistogramData::HistogramY &outY = m_out->mutableY(i);
+      HistogramData::HistogramE &outE = m_out->mutableE(i);
+      performBinaryOperation(m_lhs->histogram(i), rhsY, rhsE, outY, outE);
       m_progress->report(this->name());
       PARALLEL_END_INTERUPT_REGION
     }
@@ -523,10 +514,8 @@ void BinaryOperation::doSingleColumn() {
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
-      const double rhsY = m_rhs->readY(i)[0];
-      const double rhsE = m_rhs->readE(i)[0];
-
-      // m_out->setX(i, m_lhs->refX(i)); //unnecessary - that was copied before.
+      const double rhsY = m_rhs->y(i)[0];
+      const double rhsE = m_rhs->e(i)[0];
       if (propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
                                outSpectrumInfo)) {
         performEventBinaryOperation(m_eout->getSpectrum(i), rhsY, rhsE);
@@ -540,20 +529,19 @@ void BinaryOperation::doSingleColumn() {
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
-      const double rhsY = m_rhs->readY(i)[0];
-      const double rhsE = m_rhs->readE(i)[0];
+      const double rhsY = m_rhs->y(i)[0];
+      const double rhsE = m_rhs->e(i)[0];
 
-      m_out->setX(i, m_lhs->refX(i));
+      m_out->setSharedX(i, m_lhs->sharedX(i));
       if (propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
                                outSpectrumInfo)) {
         // Get reference to output vectors here to break any sharing outside the
         // function call below
         // where the order of argument evaluation is not guaranteed (if it's
         // L->R there would be a data race)
-        MantidVec &outY = m_out->dataY(i);
-        MantidVec &outE = m_out->dataE(i);
-        performBinaryOperation(m_lhs->readX(i), m_lhs->readY(i),
-                               m_lhs->readE(i), rhsY, rhsE, outY, outE);
+        HistogramData::HistogramY &outY = m_out->mutableY(i);
+        HistogramData::HistogramE &outE = m_out->mutableE(i);
+        performBinaryOperation(m_lhs->histogram(i), rhsY, rhsE, outY, outE);
       }
       m_progress->report(this->name());
       PARALLEL_END_INTERUPT_REGION
@@ -586,9 +574,6 @@ void BinaryOperation::doSingleSpectrum() {
       PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
       for (int64_t i = 0; i < numHists; ++i) {
         PARALLEL_START_INTERUPT_REGION
-        // m_out->setX(i,m_lhs->refX(i)); //unnecessary - that was copied
-        // before.
-
         // Perform the operation on the event list on the output (== lhs)
         performEventBinaryOperation(m_eout->getSpectrum(i), rhs_spectrum);
         m_progress->report(this->name());
@@ -609,8 +594,6 @@ void BinaryOperation::doSingleSpectrum() {
       PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
       for (int64_t i = 0; i < numHists; ++i) {
         PARALLEL_START_INTERUPT_REGION
-        // m_out->setX(i,m_lhs->refX(i)); //unnecessary - that was copied
-        // before.
         // Perform the operation on the event list on the output (== lhs)
         performEventBinaryOperation(m_eout->getSpectrum(i), rhsX, rhsY, rhsE);
         m_progress->report(this->name());
@@ -625,8 +608,7 @@ void BinaryOperation::doSingleSpectrum() {
     //  will be used instead)
 
     // Pull m_out the m_rhs spectrum
-    const MantidVec &rhsY = m_rhs->readY(0);
-    const MantidVec &rhsE = m_rhs->readE(0);
+    const auto rhs = m_rhs->histogram(0);
 
     // Now loop over the spectra of the left hand side calling the virtual
     // function
@@ -635,15 +617,14 @@ void BinaryOperation::doSingleSpectrum() {
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
-      m_out->setX(i, m_lhs->refX(i));
+      m_out->setSharedX(i, m_lhs->sharedX(i));
       // Get reference to output vectors here to break any sharing outside the
       // function call below
       // where the order of argument evaluation is not guaranteed (if it's L->R
       // there would be a data race)
-      MantidVec &outY = m_out->dataY(i);
-      MantidVec &outE = m_out->dataE(i);
-      performBinaryOperation(m_lhs->readX(i), m_lhs->readY(i), m_lhs->readE(i),
-                             rhsY, rhsE, outY, outE);
+      HistogramData::HistogramY &outY = m_out->mutableY(i);
+      HistogramData::HistogramE &outE = m_out->mutableE(i);
+      performBinaryOperation(m_lhs->histogram(i), rhs, outY, outE);
       m_progress->report(this->name());
       PARALLEL_END_INTERUPT_REGION
     }
@@ -756,7 +737,7 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
     for (int64_t i = 0; i < numHists; ++i) {
       PARALLEL_START_INTERUPT_REGION
       m_progress->report(this->name());
-      m_out->setX(i, m_lhs->refX(i));
+      m_out->setSharedX(i, m_lhs->sharedX(i));
       int64_t rhs_wi = i;
       if (mismatchedSpectra && table) {
         rhs_wi = (*table)[i];
@@ -773,11 +754,10 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
       // function call below
       // where the order of argument evaluation is not guaranteed (if it's L->R
       // there would be a data race)
-      MantidVec &outY = m_out->dataY(i);
-      MantidVec &outE = m_out->dataE(i);
-      performBinaryOperation(m_lhs->readX(i), m_lhs->readY(i), m_lhs->readE(i),
-                             m_rhs->readY(rhs_wi), m_rhs->readE(rhs_wi), outY,
-                             outE);
+      HistogramData::HistogramY &outY = m_out->mutableY(i);
+      HistogramData::HistogramE &outE = m_out->mutableE(i);
+      performBinaryOperation(m_lhs->histogram(i), m_rhs->histogram(rhs_wi),
+                             outY, outE);
 
       // Free up memory on the RHS if that is possible
       if (m_ClearRHSWorkspace)
@@ -840,9 +820,9 @@ void BinaryOperation::performEventBinaryOperation(
  * with another (histogrammed) spectrum as the right-hand operand.
  *
  *  @param lhs :: Reference to the EventList that will be modified in place.
- *  @param rhsX :: The vector of rhs X bin boundaries
- *  @param rhsY :: The vector of rhs data values
- *  @param rhsE :: The vector of rhs error values
+ *  @param rhsX :: Rhs X bin boundaries
+ *  @param rhsY :: Rhs data values
+ *  @param rhsE :: Rhs error values
  */
 void BinaryOperation::performEventBinaryOperation(DataObjects::EventList &lhs,
                                                   const MantidVec &rhsX,
diff --git a/Framework/Algorithms/src/CommutativeBinaryOperation.cpp b/Framework/Algorithms/src/CommutativeBinaryOperation.cpp
index be9f18e7f0ea104b1ed164c5ef63f48178f755f2..b20f75726bb2b49652a8957aeafb7c9348ec940c 100644
--- a/Framework/Algorithms/src/CommutativeBinaryOperation.cpp
+++ b/Framework/Algorithms/src/CommutativeBinaryOperation.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/CommutativeBinaryOperation.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/CopySample.cpp b/Framework/Algorithms/src/CopySample.cpp
index 4734956da4217b72ba5bfc4d699649439b75f8fd..0d6777320c526f976c23ed6b2595f7cc91207cac 100644
--- a/Framework/Algorithms/src/CopySample.cpp
+++ b/Framework/Algorithms/src/CopySample.cpp
@@ -167,8 +167,10 @@ void CopySample::copyParameters(Sample &from, Sample &to, bool nameFlag,
                                 bool orientationOnlyFlag) {
   if (nameFlag)
     to.setName(from.getName());
-  if (environmentFlag)
-    to.setEnvironment(new SampleEnvironment(from.getEnvironment()));
+  if (environmentFlag) {
+    to.setEnvironment(
+        std::make_unique<SampleEnvironment>(from.getEnvironment()));
+  }
   if (shapeFlag) {
     Material rhsMaterial;
     if (materialFlag) {
diff --git a/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Framework/Algorithms/src/CreateSampleWorkspace.cpp
index 39b8e554d034c8b9f2132c2a120417bbd8058a40..7981e567b731d26b2c5b7bbf060f9668a85de7a4 100644
--- a/Framework/Algorithms/src/CreateSampleWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateSampleWorkspace.cpp
@@ -50,10 +50,6 @@ DECLARE_ALGORITHM(CreateSampleWorkspace)
  */
 CreateSampleWorkspace::CreateSampleWorkspace() : m_randGen(nullptr) {}
 
-/** Destructor
- */
-CreateSampleWorkspace::~CreateSampleWorkspace() { delete m_randGen; }
-
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string CreateSampleWorkspace::name() const {
   return "CreateSampleWorkspace";
@@ -225,7 +221,7 @@ void CreateSampleWorkspace::exec() {
     if (isRandom) {
       seedValue = static_cast<int>(std::time(nullptr));
     }
-    m_randGen = new Kernel::MersenneTwister(seedValue);
+    m_randGen = std::make_unique<Kernel::MersenneTwister>(seedValue);
   }
 
   int numPixels = numBanks * bankPixelWidth * bankPixelWidth;
diff --git a/Framework/Algorithms/src/DeadTimeCorrection.cpp b/Framework/Algorithms/src/DeadTimeCorrection.cpp
index 0cf516d4e419424eb297dc29c0e9dbce7ab5c3f5..be36d351377269cca6ed4a6df12b82dab53df8d4 100644
--- a/Framework/Algorithms/src/DeadTimeCorrection.cpp
+++ b/Framework/Algorithms/src/DeadTimeCorrection.cpp
@@ -84,6 +84,12 @@ void DeadTimeCorrection::exec() {
     integrator->setPropertyValue("OutputWorkspace", "unused");
     integrator->executeAsChildAlg();
     integrated = integrator->getProperty("OutputWorkspace");
+    // after integration we end up with one bin
+    // however the bin edges might vary, which does not matter, we just need to
+    // group the counts, hence we need to do this before we can group the pixels
+    for (size_t index = 1; index < integrated->getNumberHistograms(); ++index) {
+      integrated->setSharedX(index, integrated->sharedX(0));
+    }
   }
   const std::string groupingPattern = getProperty("GroupingPattern");
   MatrixWorkspace_sptr grouped = integrated;
diff --git a/Framework/Algorithms/src/Divide.cpp b/Framework/Algorithms/src/Divide.cpp
index bd6387ef2b35a7d6d2f4eb0bb0b8adbdf81dc431..5393477f442f2c18a22f70348f2907f88819968c 100644
--- a/Framework/Algorithms/src/Divide.cpp
+++ b/Framework/Algorithms/src/Divide.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/Divide.h"
 
 using namespace Mantid::API;
@@ -32,20 +29,16 @@ void Divide::exec() {
   BinaryOperation::exec();
 }
 
-void Divide::performBinaryOperation(const MantidVec &lhsX,
-                                    const MantidVec &lhsY,
-                                    const MantidVec &lhsE,
-                                    const MantidVec &rhsY,
-                                    const MantidVec &rhsE, MantidVec &YOut,
-                                    MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-
-  const int bins = static_cast<int>(lhsE.size());
+void Divide::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                    const HistogramData::Histogram &rhs,
+                                    HistogramData::HistogramY &YOut,
+                                    HistogramData::HistogramE &EOut) {
+  const int bins = static_cast<int>(lhs.e().size());
 
   for (int j = 0; j < bins; ++j) {
     // Get references to the input Y's
-    const double leftY = lhsY[j];
-    const double rightY = rhsY[j];
+    const double leftY = lhs.y()[j];
+    const double rightY = rhs.y()[j];
 
     //  error dividing two uncorrelated numbers, re-arrange so that you don't
     //  get infinity if leftY==0 (when rightY=0 the Y value and the result will
@@ -54,23 +47,19 @@ void Divide::performBinaryOperation(const MantidVec &lhsX,
     // (Sa c/a)2 + (Sb c/b)2 = (Sc)2
     // = (Sa 1/b)2 + (Sb (a/b2))2
     // (Sc)2 = (1/b)2( (Sa)2 + (Sb a/b)2 )
-    EOut[j] =
-        sqrt(pow(lhsE[j], 2) + pow(leftY * rhsE[j] / rightY, 2)) / fabs(rightY);
+    EOut[j] = sqrt(pow(lhs.e()[j], 2) + pow(leftY * rhs.e()[j] / rightY, 2)) /
+              fabs(rightY);
 
     // Copy the result last in case one of the input workspaces is also any
     // output
     YOut[j] = leftY / rightY;
-    ;
   }
 }
 
-void Divide::performBinaryOperation(const MantidVec &lhsX,
-                                    const MantidVec &lhsY,
-                                    const MantidVec &lhsE, const double rhsY,
-                                    const double rhsE, MantidVec &YOut,
-                                    MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-
+void Divide::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                    const double rhsY, const double rhsE,
+                                    HistogramData::HistogramY &YOut,
+                                    HistogramData::HistogramE &EOut) {
   if (rhsY == 0 && m_warnOnZeroDivide)
     g_log.warning() << "Division by zero: the RHS is a single-valued vector "
                        "with value zero."
@@ -78,13 +67,13 @@ void Divide::performBinaryOperation(const MantidVec &lhsX,
 
   // Do the right-hand part of the error calculation just once
   const double rhsFactor = pow(rhsE / rhsY, 2);
-  const int bins = static_cast<int>(lhsE.size());
+  const int bins = static_cast<int>(lhs.e().size());
   for (int j = 0; j < bins; ++j) {
     // Get reference to input Y
-    const double leftY = lhsY[j];
+    const double leftY = lhs.y()[j];
 
     // see comment in the function above for the error formula
-    EOut[j] = sqrt(pow(lhsE[j], 2) + pow(leftY, 2) * rhsFactor) / fabs(rhsY);
+    EOut[j] = sqrt(pow(lhs.e()[j], 2) + pow(leftY, 2) * rhsFactor) / fabs(rhsY);
     // Copy the result last in case one of the input workspaces is also any
     // output
     YOut[j] = leftY / rhsY;
diff --git a/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp b/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp
index 0eb81698799bca38656fea038dc051be42f3b234..547b114354f5ad75b87d18a8911645aa800da3dd 100644
--- a/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp
+++ b/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp
@@ -81,9 +81,8 @@ void EstimateResolutionDiffraction::init() {
   auto positiveDeltaTOF = boost::make_shared<BoundedValidator<double>>();
   positiveDeltaTOF->setLower(0.);
   positiveDeltaTOF->setLowerExclusive(true);
-  declareProperty(
-      "DeltaTOF", 0., positiveDeltaTOF,
-      "DeltaT as the resolution of TOF with unit microsecond (10^-6m).");
+  declareProperty("DeltaTOF", 0., positiveDeltaTOF,
+                  "DeltaT as the resolution of TOF with unit microsecond");
 
   auto positiveWavelength = boost::make_shared<BoundedValidator<double>>();
   positiveWavelength->setLower(0.);
diff --git a/Framework/Algorithms/src/ExtractSpectra2.cpp b/Framework/Algorithms/src/ExtractSpectra2.cpp
index c5b3dbfcabf98bf1fc4c1ca0a708aa45b92bbe65..3480c2ddc5214b269b11cc08d93a93e930f52ffb 100644
--- a/Framework/Algorithms/src/ExtractSpectra2.cpp
+++ b/Framework/Algorithms/src/ExtractSpectra2.cpp
@@ -6,6 +6,7 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidAlgorithms/ExtractSpectra2.h"
 #include "MantidAPI/Algorithm.tcc"
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidDataObjects/EventWorkspace.h"
@@ -68,12 +69,15 @@ void ExtractSpectra2::exec() {
   Axis *inAxis1(nullptr);
   TextAxis *outTxtAxis(nullptr);
   NumericAxis *outNumAxis(nullptr);
+  bool isBinEdgeAxis(false);
   if (inputWS->axes() > 1) {
     inAxis1 = inputWS->getAxis(1);
     auto outAxis1 = outputWS->getAxis(1);
     outTxtAxis = dynamic_cast<TextAxis *>(outAxis1);
-    if (!outTxtAxis)
+    if (!outTxtAxis) {
       outNumAxis = dynamic_cast<NumericAxis *>(outAxis1);
+      isBinEdgeAxis = dynamic_cast<BinEdgeAxis *>(inAxis1) != nullptr;
+    }
   }
 
   Progress prog(this, 0.0, 1.0, indexSet.size());
@@ -96,6 +100,17 @@ void ExtractSpectra2::exec() {
     prog.report();
   }
 
+  if (isBinEdgeAxis) {
+    if (!indexSet.isContiguous()) {
+      throw std::invalid_argument("Cannot extract non-contiguous set of "
+                                  "spectra when the vertical axis has bin "
+                                  "edges.");
+    }
+    const auto outIndex = indexSet.size();
+    const auto inIndex = indexSet[indexSet.size() - 1] + 1;
+    outNumAxis->setValue(outIndex, inAxis1->operator()(inIndex));
+  }
+
   setProperty("OutputWorkspace", std::move(outputWS));
 }
 
diff --git a/Framework/Algorithms/src/FilterEvents.cpp b/Framework/Algorithms/src/FilterEvents.cpp
index 08ddd95a774fcf0c3f92ab95d3bcb54c6d5dd29b..ac90660c91d569f68e47b33444cb655d0288965f 100644
--- a/Framework/Algorithms/src/FilterEvents.cpp
+++ b/Framework/Algorithms/src/FilterEvents.cpp
@@ -65,7 +65,7 @@ FilterEvents::FilterEvents()
       m_filterByPulseTime(false), m_informationWS(), m_hasInfoWS(),
       m_progress(0.), m_outputWSNameBase(), m_toGroupWS(false),
       m_vecSplitterTime(), m_vecSplitterGroup(), m_splitSampleLogs(false),
-      m_useDBSpectrum(false), m_dbWSIndex(-1), m_tofCorrType(),
+      m_useDBSpectrum(false), m_dbWSIndex(-1), m_tofCorrType(NoneCorrect),
       m_specSkipType(), m_vecSkip(), m_isSplittersRelativeTime(false),
       m_filterStartTime(0), m_runStartTime(0) {}
 
@@ -81,7 +81,9 @@ void FilterEvents::init() {
                   "An input SpilltersWorskpace for filtering");
 
   declareProperty("OutputWorkspaceBaseName", "OutputWorkspace",
-                  "The base name to use for the output workspace");
+                  "The base name to use for the output workspace. The output "
+                  "workspace names are a combination of this and the index in "
+                  "splitter.");
 
   declareProperty(
       Kernel::make_unique<WorkspaceProperty<TableWorkspace>>(
@@ -184,15 +186,22 @@ std::map<std::string, std::string> FilterEvents::validateInputs() {
   std::map<std::string, std::string> result;
 
   // check the splitters workspace for special behavior
-  API::Workspace_const_sptr wksp = this->getProperty(SPLITER_PROP_NAME);
+  API::Workspace_const_sptr splitter = this->getProperty(SPLITER_PROP_NAME);
   // SplittersWorkspace is a special type that needs no further checking
-  if (!bool(boost::dynamic_pointer_cast<const SplittersWorkspace>(wksp))) {
-    const auto table = boost::dynamic_pointer_cast<const TableWorkspace>(wksp);
+  if (bool(boost::dynamic_pointer_cast<const SplittersWorkspace>(splitter))) {
+    if (boost::dynamic_pointer_cast<const SplittersWorkspace>(splitter)
+            ->rowCount() == 0)
+      result[SPLITER_PROP_NAME] = "SplittersWorkspace must have rows defined";
+  } else {
+    const auto table =
+        boost::dynamic_pointer_cast<const TableWorkspace>(splitter);
     const auto matrix =
-        boost::dynamic_pointer_cast<const MatrixWorkspace>(wksp);
+        boost::dynamic_pointer_cast<const MatrixWorkspace>(splitter);
     if (bool(table)) {
       if (table->columnCount() != 3)
         result[SPLITER_PROP_NAME] = "TableWorkspace must have 3 columns";
+      else if (table->rowCount() == 0)
+        result[SPLITER_PROP_NAME] = "TableWorkspace must have rows defined";
     } else if (bool(matrix)) {
       if (matrix->getNumberHistograms() == 1) {
         if (!matrix->isHistogramData())
@@ -206,6 +215,30 @@ std::map<std::string, std::string> FilterEvents::validateInputs() {
     }
   }
 
+  const string correctiontype = getPropertyValue("CorrectionToSample");
+  if (correctiontype == "Direct") {
+    double ei = getProperty("IncidentEnergy");
+    if (isEmpty(ei)) {
+      EventWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace");
+      if (!inputWS->run().hasProperty("Ei")) {
+        const string msg(
+            "InputWorkspace does not have Ei. Must specify IncidentEnergy");
+        result["CorrectionToSample"] = msg;
+        result["IncidentEnergy"] = msg;
+      }
+    }
+  } else if (correctiontype == "Customized") {
+    TableWorkspace_const_sptr correctionWS =
+        getProperty("DetectorTOFCorrectionWorkspace");
+    if (!correctionWS) {
+      const string msg(
+          "Must specify correction workspace with CorrectionToSample=Custom");
+      result["CorrectionToSample"] = msg;
+      result["DetectorTOFCorrectionWorkspace"] = msg;
+    }
+  }
+  // "None" and "Elastic" and "Indirect" don't require extra information
+
   return result;
 }
 
@@ -221,9 +254,9 @@ void FilterEvents::exec() {
   // Parse splitters
   m_progress = 0.0;
   progress(m_progress, "Processing SplittersWorkspace.");
-  if (m_useSplittersWorkspace)
+  if (m_useSplittersWorkspace) // SplittersWorkspace the class in nanoseconds
     processSplittersWorkspace();
-  else if (m_useArbTableSplitters)
+  else if (m_useArbTableSplitters) // TableWorkspace in seconds
     processTableSplittersWorkspace();
   else
     processMatrixSplitterWorkspace();
@@ -437,14 +470,6 @@ void FilterEvents::processAlgorithmProperties() {
     throw runtime_error("Impossible situation!");
   }
 
-  if (m_tofCorrType == CustomizedCorrect) {
-    // Customized correciton
-    m_detCorrectWorkspace = getProperty("DetectorTOFCorrectionWorkspace");
-    if (!m_detCorrectWorkspace)
-      throw runtime_error("In case of customized TOF correction, correction "
-                          "workspace must be given!");
-  }
-
   // Spectrum skip
   string skipappr = getPropertyValue("SpectrumWithoutDetector");
   if (skipappr == "Skip")
@@ -951,6 +976,14 @@ void FilterEvents::processMatrixSplitterWorkspace() {
   return;
 }
 
+namespace {
+// offset_ns - an offset from the GPS epoch
+int64_t timeInSecondsToNanoseconds(const int64_t offset_ns,
+                                   const double time_sec) {
+  return offset_ns + static_cast<int64_t>(time_sec * 1.E9);
+}
+} // anonymous namespace
+
 //----------------------------------------------------------------------------------------------
 /** process the input splitters given by a TableWorkspace
  * The method will transfer the start/stop time to "m_vecSplitterTime"
@@ -959,8 +992,6 @@ void FilterEvents::processMatrixSplitterWorkspace() {
  *"m_wsGroupIndexTargetMap".
  * Also, "m_maxTargetIndex" is set up to record the highest target group/index,
  * i.e., max value of m_vecSplitterGroup
- *
- * @brief FilterEvents::processTableSplittersWorkspace
  */
 void FilterEvents::processTableSplittersWorkspace() {
   // check input workspace's validity
@@ -986,27 +1017,26 @@ void FilterEvents::processTableSplittersWorkspace() {
   size_t num_rows = m_splitterTableWorkspace->rowCount();
   for (size_t irow = 0; irow < num_rows; ++irow) {
     // get start and stop time in second
-    double start_time = m_splitterTableWorkspace->cell_cast<double>(irow, 0);
-    double stop_time = m_splitterTableWorkspace->cell_cast<double>(irow, 1);
-    std::string target = m_splitterTableWorkspace->cell<std::string>(irow, 2);
-
-    int64_t start_64 =
-        filter_shift_time + static_cast<int64_t>(start_time * 1.E9);
-    int64_t stop_64 =
-        filter_shift_time + static_cast<int64_t>(stop_time * 1.E9);
+    const auto start_time = timeInSecondsToNanoseconds(
+        filter_shift_time,
+        m_splitterTableWorkspace->cell_cast<double>(irow, 0));
+    const auto stop_time = timeInSecondsToNanoseconds(
+        filter_shift_time,
+        m_splitterTableWorkspace->cell_cast<double>(irow, 1));
+    const auto target = m_splitterTableWorkspace->cell<std::string>(irow, 2);
 
     if (m_vecSplitterTime.empty()) {
       // first splitter: push the start time to vector
-      m_vecSplitterTime.push_back(start_64);
-    } else if (start_64 - m_vecSplitterTime.back() > TOLERANCE) {
+      m_vecSplitterTime.push_back(start_time);
+    } else if (start_time - m_vecSplitterTime.back() > TOLERANCE) {
       // the start time is way behind previous splitter's stop time
       // create a new splitter and set the time interval in the middle to target
       // -1
-      m_vecSplitterTime.push_back(start_64);
+      m_vecSplitterTime.push_back(start_time);
       // NOTE: use index = 0 for un-defined slot
       m_vecSplitterGroup.push_back(UNDEFINED_SPLITTING_TARGET);
       found_undefined_splitter = true;
-    } else if (abs(start_64 - m_vecSplitterTime.back()) < TOLERANCE) {
+    } else if (abs(start_time - m_vecSplitterTime.back()) < TOLERANCE) {
       // new splitter's start time is same (within tolerance) as the stop time
       // of the previous
       ;
@@ -1017,21 +1047,12 @@ void FilterEvents::processTableSplittersWorkspace() {
     }
 
     // convert string-target to integer target
-    bool addnew = false;
     int int_target(-1);
-    if (m_targetIndexMap.empty()) {
-      addnew = true;
-    } else {
-      std::map<std::string, int>::iterator mapiter =
-          m_targetIndexMap.find(target);
-      if (mapiter == m_targetIndexMap.end())
-        addnew = true;
-      else
-        int_target = mapiter->second;
-    }
+    const auto &mapiter = m_targetIndexMap.find(target);
 
-    // add a new ordered-integer-target
-    if (addnew) {
+    if (mapiter != m_targetIndexMap.end()) {
+      int_target = mapiter->second;
+    } else {
       // target is not in map
       int_target = max_target_index;
       m_targetIndexMap.insert(std::pair<std::string, int>(target, int_target));
@@ -1041,7 +1062,7 @@ void FilterEvents::processTableSplittersWorkspace() {
     }
 
     // add start time, stop time and 'target
-    m_vecSplitterTime.push_back(stop_64);
+    m_vecSplitterTime.push_back(stop_time);
     m_vecSplitterGroup.push_back(int_target);
   } // END-FOR (irow)
 
@@ -1413,16 +1434,16 @@ TimeAtSampleStrategy *FilterEvents::setupElasticTOFCorrection() const {
 TimeAtSampleStrategy *FilterEvents::setupDirectTOFCorrection() const {
 
   // Get incident energy Ei
-  double ei = 0.;
-  if (m_eventWS->run().hasProperty("Ei")) {
-    Kernel::Property *eiprop = m_eventWS->run().getProperty("Ei");
-    ei = boost::lexical_cast<double>(eiprop->value());
-    g_log.debug() << "Using stored Ei value " << ei << "\n";
-  } else {
-    ei = getProperty("IncidentEnergy");
-    if (isEmpty(ei))
+  double ei = getProperty("IncidentEnergy");
+  if (isEmpty(ei)) {
+    if (m_eventWS->run().hasProperty("Ei")) {
+      ei = m_eventWS->run().getLogAsSingleValue("Ei");
+      g_log.debug() << "Using stored Ei value " << ei << "\n";
+    } else {
       throw std::invalid_argument(
           "No Ei value has been set or stored within the run information.");
+    }
+  } else {
     g_log.debug() << "Using user-input Ei value " << ei << "\n";
   }
 
@@ -1442,6 +1463,7 @@ TimeAtSampleStrategy *FilterEvents::setupIndirectTOFCorrection() const {
  */
 void FilterEvents::setupCustomizedTOFCorrection() {
   // Check input workspace
+  m_detCorrectWorkspace = getProperty("DetectorTOFCorrectionWorkspace");
   vector<string> colnames = m_detCorrectWorkspace->getColumnNames();
   bool hasshift = false;
   if (colnames.size() < 2)
diff --git a/Framework/Algorithms/src/He3TubeEfficiency.cpp b/Framework/Algorithms/src/He3TubeEfficiency.cpp
index f547ba828d687cdfcd3fd946bf8d274d1aa16e70..1cbbf3a9a238c034d8668ef0867a0f3b62d3bbf7 100644
--- a/Framework/Algorithms/src/He3TubeEfficiency.cpp
+++ b/Framework/Algorithms/src/He3TubeEfficiency.cpp
@@ -47,13 +47,6 @@ He3TubeEfficiency::He3TubeEfficiency()
   m_shapeCache.clear();
 }
 
-/// Destructor
-He3TubeEfficiency::~He3TubeEfficiency() {
-  if (m_progress) {
-    delete m_progress;
-  }
-}
-
 /**
  * Declare algorithm properties
  */
@@ -125,7 +118,7 @@ void He3TubeEfficiency::exec() {
   }
 
   std::size_t numHists = m_inputWS->getNumberHistograms();
-  m_progress = new API::Progress(this, 0.0, 1.0, numHists);
+  m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, numHists);
   const auto &spectrumInfo = m_inputWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS))
@@ -425,7 +418,7 @@ void He3TubeEfficiency::execEvent() {
 
   std::size_t numHistograms = m_outputWS->getNumberHistograms();
   auto &spectrumInfo = m_outputWS->mutableSpectrumInfo();
-  m_progress = new API::Progress(this, 0.0, 1.0, numHistograms);
+  m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, numHistograms);
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*m_outputWS))
   for (int i = 0; i < static_cast<int>(numHistograms); ++i) {
diff --git a/Framework/Algorithms/src/MergeRuns.cpp b/Framework/Algorithms/src/MergeRuns.cpp
index f85859c49131787b2aac6c6957716a086be80611..4c3d1183a4d3e5c5198a32b6693190503089bdd4 100644
--- a/Framework/Algorithms/src/MergeRuns.cpp
+++ b/Framework/Algorithms/src/MergeRuns.cpp
@@ -729,14 +729,17 @@ std::vector<SpectrumDefinition> MergeRuns::buildScanIntervals(
     const DetectorInfo &addeeDetInfo, const DetectorInfo &newOutDetInfo) {
   std::vector<SpectrumDefinition> newAddeeSpecDefs(addeeSpecDefs.size());
 
+  auto addeeScanIntervals = addeeDetInfo.scanIntervals();
+  auto newOutScanIntervals = newOutDetInfo.scanIntervals();
+
   PARALLEL_FOR_NO_WSP_CHECK()
   for (int64_t i = 0; i < int64_t(addeeSpecDefs.size()); ++i) {
     for (auto &index : addeeSpecDefs[i]) {
       SpectrumDefinition newSpecDef;
       for (size_t time_index = 0; time_index < newOutDetInfo.scanCount();
            time_index++) {
-        if (addeeDetInfo.scanIntervals()[index.second] ==
-            newOutDetInfo.scanIntervals()[time_index]) {
+        if (addeeScanIntervals[index.second] ==
+            newOutScanIntervals[time_index]) {
           newSpecDef.add(index.first, time_index);
         }
       }
diff --git a/Framework/Algorithms/src/Minus.cpp b/Framework/Algorithms/src/Minus.cpp
index 2ea763c5a1b13a6d87e1abfe48d9d15adbd02293..5d8accfc4ffa1d1f7058fa391f9ae6a7d26fc3e6 100644
--- a/Framework/Algorithms/src/Minus.cpp
+++ b/Framework/Algorithms/src/Minus.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/Minus.h"
 #include "MantidKernel/VectorHelper.h"
 
@@ -20,30 +17,28 @@ DECLARE_ALGORITHM(Minus)
 
 const std::string Minus::alias() const { return "Subtract"; }
 
-void Minus::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                                   const MantidVec &lhsE, const MantidVec &rhsY,
-                                   const MantidVec &rhsE, MantidVec &YOut,
-                                   MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-  std::transform(lhsY.begin(), lhsY.end(), rhsY.begin(), YOut.begin(),
+void Minus::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                   const HistogramData::Histogram &rhs,
+                                   HistogramData::HistogramY &YOut,
+                                   HistogramData::HistogramE &EOut) {
+  std::transform(lhs.y().begin(), lhs.y().end(), rhs.y().begin(), YOut.begin(),
                  std::minus<double>());
-  std::transform(lhsE.begin(), lhsE.end(), rhsE.begin(), EOut.begin(),
+  std::transform(lhs.e().begin(), lhs.e().end(), rhs.e().begin(), EOut.begin(),
                  VectorHelper::SumGaussError<double>());
 }
 
-void Minus::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                                   const MantidVec &lhsE, const double rhsY,
-                                   const double rhsE, MantidVec &YOut,
-                                   MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-  std::transform(lhsY.begin(), lhsY.end(), YOut.begin(),
+void Minus::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                   const double rhsY, const double rhsE,
+                                   HistogramData::HistogramY &YOut,
+                                   HistogramData::HistogramE &EOut) {
+  std::transform(lhs.y().begin(), lhs.y().end(), YOut.begin(),
                  std::bind2nd(std::minus<double>(), rhsY));
   // Only do E if non-zero, otherwise just copy
   if (rhsE != 0)
-    std::transform(lhsE.begin(), lhsE.end(), EOut.begin(),
+    std::transform(lhs.e().begin(), lhs.e().end(), EOut.begin(),
                    std::bind2nd(VectorHelper::SumGaussError<double>(), rhsE));
   else
-    EOut = lhsE;
+    EOut = lhs.e();
 }
 
 // ===================================== EVENT LIST BINARY OPERATIONS
diff --git a/Framework/Algorithms/src/Multiply.cpp b/Framework/Algorithms/src/Multiply.cpp
index bddcfcbb2bfe6ca2576437708d3200aa6ae53909..83bc720760c45e84931a616593b3e8803041f3d7 100644
--- a/Framework/Algorithms/src/Multiply.cpp
+++ b/Framework/Algorithms/src/Multiply.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-// Includes
-//----------------------------------------------------------------------
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/Multiply.h"
 
 using namespace Mantid::API;
@@ -19,25 +16,22 @@ namespace Algorithms {
 // Register the class into the algorithm factory
 DECLARE_ALGORITHM(Multiply)
 
-void Multiply::performBinaryOperation(const MantidVec &lhsX,
-                                      const MantidVec &lhsY,
-                                      const MantidVec &lhsE,
-                                      const MantidVec &rhsY,
-                                      const MantidVec &rhsE, MantidVec &YOut,
-                                      MantidVec &EOut) {
-  UNUSED_ARG(lhsX);
-  const size_t bins = lhsE.size();
+void Multiply::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                      const HistogramData::Histogram &rhs,
+                                      HistogramData::HistogramY &YOut,
+                                      HistogramData::HistogramE &EOut) {
+  const size_t bins = lhs.e().size();
   for (size_t j = 0; j < bins; ++j) {
     // Get references to the input Y's
-    const double leftY = lhsY[j];
-    const double rightY = rhsY[j];
+    const double leftY = lhs.y()[j];
+    const double rightY = rhs.y()[j];
 
     // error multiplying two uncorrelated numbers, re-arrange so that you don't
     // get infinity if leftY or rightY == 0
     // (Sa/a)2 + (Sb/b)2 = (Sc/c)2
     // (Sc)2 = (Sa c/a)2 + (Sb c/b)2
     //       = (Sa b)2 + (Sb a)2
-    EOut[j] = sqrt(pow(lhsE[j] * rightY, 2) + pow(rhsE[j] * leftY, 2));
+    EOut[j] = sqrt(pow(lhs.e()[j] * rightY, 2) + pow(rhs.e()[j] * leftY, 2));
 
     // Copy the result last in case one of the input workspaces is also any
     // output
@@ -45,19 +39,17 @@ void Multiply::performBinaryOperation(const MantidVec &lhsX,
   }
 }
 
-void Multiply::performBinaryOperation(const MantidVec &lhsX,
-                                      const MantidVec &lhsY,
-                                      const MantidVec &lhsE, const double rhsY,
-                                      const double rhsE, MantidVec &YOut,
-                                      MantidVec &EOut) {
-  UNUSED_ARG(lhsX);
-  const size_t bins = lhsE.size();
+void Multiply::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                      const double rhsY, const double rhsE,
+                                      HistogramData::HistogramY &YOut,
+                                      HistogramData::HistogramE &EOut) {
+  const size_t bins = lhs.e().size();
   for (size_t j = 0; j < bins; ++j) {
     // Get reference to input Y
-    const double leftY = lhsY[j];
+    const double leftY = lhs.y()[j];
 
     // see comment in the function above for the error formula
-    EOut[j] = sqrt(pow(lhsE[j] * rhsY, 2) + pow(rhsE * leftY, 2));
+    EOut[j] = sqrt(pow(lhs.e()[j] * rhsY, 2) + pow(rhsE * leftY, 2));
 
     // Copy the result last in case one of the input workspaces is also any
     // output
diff --git a/Framework/Algorithms/src/PDDetermineCharacterizations.cpp b/Framework/Algorithms/src/PDDetermineCharacterizations.cpp
index 736723e624b2926eb19011228ec7719c1edfefe9..43853dd8466c886d96565316dbc7d0e2e1670774 100644
--- a/Framework/Algorithms/src/PDDetermineCharacterizations.cpp
+++ b/Framework/Algorithms/src/PDDetermineCharacterizations.cpp
@@ -153,13 +153,13 @@ void PDDetermineCharacterizations::init() {
   std::vector<std::string> defaultFrequencyNames{"SpeedRequest1", "Speed1",
                                                  "frequency", "skf1.speed"};
   declareProperty(Kernel::make_unique<Kernel::ArrayProperty<std::string>>(
-                      FREQ_PROP_NAME, defaultFrequencyNames),
+                      FREQ_PROP_NAME, std::move(defaultFrequencyNames)),
                   "Candidate log names for frequency");
 
   std::vector<std::string> defaultWavelengthNames{"LambdaRequest", "lambda",
                                                   "skf12.lambda"};
   declareProperty(Kernel::make_unique<Kernel::ArrayProperty<std::string>>(
-                      WL_PROP_NAME, defaultWavelengthNames),
+                      WL_PROP_NAME, std::move(defaultWavelengthNames)),
                   "Candidate log names for wave length");
 }
 
diff --git a/Framework/Algorithms/src/Plus.cpp b/Framework/Algorithms/src/Plus.cpp
index bb9b8caf37dd17863a0c87a2b27cad672a635eac..b0683314e6d3b2a2d24b54271812c26c9b83ad86 100644
--- a/Framework/Algorithms/src/Plus.cpp
+++ b/Framework/Algorithms/src/Plus.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/Plus.h"
 #include "MantidKernel/VectorHelper.h"
 
@@ -22,31 +19,29 @@ DECLARE_ALGORITHM(Plus)
 // ===================================== HISTOGRAM BINARY OPERATIONS
 // ==========================================
 //---------------------------------------------------------------------------------------------
-void Plus::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                                  const MantidVec &lhsE, const MantidVec &rhsY,
-                                  const MantidVec &rhsE, MantidVec &YOut,
-                                  MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-  std::transform(lhsY.begin(), lhsY.end(), rhsY.begin(), YOut.begin(),
+void Plus::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                  const HistogramData::Histogram &rhs,
+                                  HistogramData::HistogramY &YOut,
+                                  HistogramData::HistogramE &EOut) {
+  std::transform(lhs.y().begin(), lhs.y().end(), rhs.y().begin(), YOut.begin(),
                  std::plus<double>());
-  std::transform(lhsE.begin(), lhsE.end(), rhsE.begin(), EOut.begin(),
+  std::transform(lhs.e().begin(), lhs.e().end(), rhs.e().begin(), EOut.begin(),
                  VectorHelper::SumGaussError<double>());
 }
 
 //---------------------------------------------------------------------------------------------
-void Plus::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                                  const MantidVec &lhsE, const double rhsY,
-                                  const double rhsE, MantidVec &YOut,
-                                  MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-  std::transform(lhsY.begin(), lhsY.end(), YOut.begin(),
+void Plus::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                  const double rhsY, const double rhsE,
+                                  HistogramData::HistogramY &YOut,
+                                  HistogramData::HistogramE &EOut) {
+  std::transform(lhs.y().begin(), lhs.y().end(), YOut.begin(),
                  std::bind2nd(std::plus<double>(), rhsY));
   // Only do E if non-zero, otherwise just copy
   if (rhsE != 0)
-    std::transform(lhsE.begin(), lhsE.end(), EOut.begin(),
+    std::transform(lhs.e().begin(), lhs.e().end(), EOut.begin(),
                    std::bind2nd(VectorHelper::SumGaussError<double>(), rhsE));
   else
-    EOut = lhsE;
+    EOut = lhs.e();
 }
 
 // ===================================== EVENT LIST BINARY OPERATIONS
diff --git a/Framework/Algorithms/src/PoissonErrors.cpp b/Framework/Algorithms/src/PoissonErrors.cpp
index 53f9fc3c68d871a74fcc1dfe93d7e971f36ee764..e306efc0f1de1ea17433f9c9473f7864fb605a29 100644
--- a/Framework/Algorithms/src/PoissonErrors.cpp
+++ b/Framework/Algorithms/src/PoissonErrors.cpp
@@ -4,9 +4,6 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/PoissonErrors.h"
 
 using namespace Mantid::API;
@@ -37,39 +34,33 @@ std::string PoissonErrors::checkSizeCompatibility(
   }
 }
 
-void PoissonErrors::performBinaryOperation(const MantidVec &lhsX,
-                                           const MantidVec &lhsY,
-                                           const MantidVec &lhsE,
-                                           const MantidVec &rhsY,
-                                           const MantidVec &rhsE,
-                                           MantidVec &YOut, MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
+void PoissonErrors::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                           const HistogramData::Histogram &rhs,
+                                           HistogramData::HistogramY &YOut,
+                                           HistogramData::HistogramE &EOut) {
   // Just copy over the lhs data
-  YOut = lhsY;
+  YOut = lhs.y();
   // Now make the fractional error the same as it was on the rhs
-  const int bins = static_cast<int>(lhsE.size());
+  const int bins = static_cast<int>(lhs.e().size());
   for (int j = 0; j < bins; ++j) {
-    if (rhsY[j] != 0.0)
-      EOut[j] = rhsE[j] / rhsY[j] * lhsY[j];
+    if (rhs.y()[j] != 0.0)
+      EOut[j] = rhs.e()[j] / rhs.y()[j] * lhs.y()[j];
     else
       EOut[j] = 0.0;
   }
 }
 
-void PoissonErrors::performBinaryOperation(const MantidVec &lhsX,
-                                           const MantidVec &lhsY,
-                                           const MantidVec &lhsE,
+void PoissonErrors::performBinaryOperation(const HistogramData::Histogram &lhs,
                                            const double rhsY, const double rhsE,
-                                           MantidVec &YOut, MantidVec &EOut) {
-  (void)lhsE;
-  (void)lhsX; // Avoid compiler warning
+                                           HistogramData::HistogramY &YOut,
+                                           HistogramData::HistogramE &EOut) {
 
-  assert(lhsX.size() == 1);
+  assert(lhs.x().size() == 1);
   // If we get here we've got two single column workspaces so it's easy.
-  YOut[0] = lhsY[0];
+  YOut[0] = lhs.y()[0];
 
   if (rhsY != 0.0)
-    EOut[0] = rhsE / rhsY * lhsY[0];
+    EOut[0] = rhsE / rhsY * lhs.y()[0];
   else
     EOut[0] = 0.0;
 }
diff --git a/Framework/Algorithms/src/RadiusSum.cpp b/Framework/Algorithms/src/RadiusSum.cpp
index d5a8d883bc55bb61dcd778a7aa6629e9c738a1c9..a01ae49d45de5232e73780f14734c7a70a0a4577 100644
--- a/Framework/Algorithms/src/RadiusSum.cpp
+++ b/Framework/Algorithms/src/RadiusSum.cpp
@@ -57,22 +57,23 @@ void RadiusSum::init() {
   auto twoOrThreeElements =
       boost::make_shared<ArrayLengthValidator<double>>(2, 3);
   std::vector<double> myInput(3, 0);
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
-                      "Centre", myInput, twoOrThreeElements),
-                  "Coordinate of the centre of the ring");
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("Centre", std::move(myInput),
+                                                 std::move(twoOrThreeElements)),
+      "Coordinate of the centre of the ring");
 
   auto nonNegative = boost::make_shared<BoundedValidator<double>>();
   nonNegative->setLower(0);
-  declareProperty("MinRadius", 0.0, nonNegative,
+  declareProperty("MinRadius", 0.0, nonNegative->clone(),
                   "Length of the inner ring. Default=0");
-  declareProperty(
-      make_unique<PropertyWithValue<double>>(
-          "MaxRadius", std::numeric_limits<double>::max(), nonNegative),
-      "Length of the outer ring. Default=ImageSize.");
+  declareProperty(make_unique<PropertyWithValue<double>>(
+                      "MaxRadius", std::numeric_limits<double>::max(),
+                      std::move(nonNegative)),
+                  "Length of the outer ring. Default=ImageSize.");
 
   auto nonNegativeInt = boost::make_shared<BoundedValidator<int>>();
   nonNegativeInt->setLower(1);
-  declareProperty("NumBins", 100, nonNegativeInt,
+  declareProperty("NumBins", 100, std::move(nonNegativeInt),
                   "Number of slice bins for the output. Default=100");
 
   const char *normBy = "NormalizeByRadius";
diff --git a/Framework/Algorithms/src/Rebin2D.cpp b/Framework/Algorithms/src/Rebin2D.cpp
index 0a7a2375689c01f4a5b16da5aa595f37eaa0956b..b4d04b679e475e80e1d7d6ee19521c7e12a3982d 100644
--- a/Framework/Algorithms/src/Rebin2D.cpp
+++ b/Framework/Algorithms/src/Rebin2D.cpp
@@ -112,10 +112,11 @@ void Rebin2D::exec() {
   auto inputHasFA = boost::dynamic_pointer_cast<const RebinnedOutput>(inputWS);
   // For MatrixWorkspace, only UseFractionalArea=False makes sense.
   if (useFractionalArea && !inputHasFA) {
-    g_log.warning("Fractional area tracking requires the input workspace to "
-                  "contain calculated bin fractions from a parallelpiped rebin "
-                  "like SofQW. Continuing without fractional area tracking");
-    useFractionalArea = false;
+    g_log.warning(
+        "Fractional area tracking was requested but input workspace does "
+        "not have calculated bin fractions. Assuming bins are exact "
+        "(fractions are unity). The results may not be accurate if this "
+        "workspace was previously rebinned.");
   }
   // For RebinnedOutput, should always use useFractionalArea to get the
   // correct signal and errors (so that weights of input ws is accounted for).
diff --git a/Framework/Algorithms/src/RingProfile.cpp b/Framework/Algorithms/src/RingProfile.cpp
index 2a3ac1624c4f82c176d2083cf3491b1f73e2e89e..990c54ac9cbe9355ac5d17b2d95adf5c05d9898f 100644
--- a/Framework/Algorithms/src/RingProfile.cpp
+++ b/Framework/Algorithms/src/RingProfile.cpp
@@ -56,20 +56,20 @@ void RingProfile::init() {
       boost::make_shared<Kernel::ArrayLengthValidator<double>>(2, 3);
   std::vector<double> myInput(3, 0);
   declareProperty(Kernel::make_unique<Kernel::ArrayProperty<double>>(
-                      "Centre", myInput, twoOrThree),
+                      "Centre", std::move(myInput), std::move(twoOrThree)),
                   "Coordinate of the centre of the ring");
   auto nonNegative = boost::make_shared<Kernel::BoundedValidator<double>>();
   nonNegative->setLower(0);
 
-  declareProperty<double>("MinRadius", 0, nonNegative,
+  declareProperty<double>("MinRadius", 0, nonNegative->clone(),
                           "Radius of the inner ring(m)");
-  declareProperty(
-      Kernel::make_unique<Kernel::PropertyWithValue<double>>(
-          "MaxRadius", std::numeric_limits<double>::max(), nonNegative),
-      "Radius of the outer ring(m)");
+  declareProperty(Kernel::make_unique<Kernel::PropertyWithValue<double>>(
+                      "MaxRadius", std::numeric_limits<double>::max(),
+                      std::move(nonNegative)),
+                  "Radius of the outer ring(m)");
   auto nonNegativeInt = boost::make_shared<Kernel::BoundedValidator<int>>();
   nonNegativeInt->setLower(1);
-  declareProperty<int>("NumBins", 100, nonNegativeInt,
+  declareProperty<int>("NumBins", 100, std::move(nonNegativeInt),
                        "Number of slice bins for the output");
   auto degreesLimits = boost::make_shared<Kernel::BoundedValidator<double>>();
   degreesLimits->setLower(-360);
diff --git a/Framework/Algorithms/src/ScaleX.cpp b/Framework/Algorithms/src/ScaleX.cpp
index d9d21e2c34e8e630303e79b0ed63eafe565409df..49db28dfa97bf663bf74e2df4f2604cc26a46c85 100644
--- a/Framework/Algorithms/src/ScaleX.cpp
+++ b/Framework/Algorithms/src/ScaleX.cpp
@@ -35,11 +35,6 @@ ScaleX::ScaleX()
     : API::Algorithm(), m_progress(nullptr), m_algFactor(1.0), m_parname(),
       m_combine(false), m_binOp(), m_wi_min(-1), m_wi_max(-1) {}
 
-/**
- * Destructor
- */
-ScaleX::~ScaleX() { delete m_progress; }
-
 /**
  * Initialisation method. Declares properties to be used in algorithm.
  */
@@ -99,7 +94,7 @@ void ScaleX::exec() {
   API::MatrixWorkspace_sptr outputW = createOutputWS(inputW);
   // Get number of histograms
   int histnumber = static_cast<int>(inputW->getNumberHistograms());
-  m_progress = new API::Progress(this, 0.0, 1.0, histnumber + 1);
+  m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, histnumber + 1);
   m_progress->report("Scaling X");
   m_wi_min = 0;
   m_wi_max = histnumber - 1;
diff --git a/Framework/Algorithms/src/SmoothData.cpp b/Framework/Algorithms/src/SmoothData.cpp
index b6d48808a50fb8c9144e5470aba35846fac40e8a..45d1433d13e3b7f9f30a176033486aef931e6687 100644
--- a/Framework/Algorithms/src/SmoothData.cpp
+++ b/Framework/Algorithms/src/SmoothData.cpp
@@ -28,14 +28,13 @@ void SmoothData::init() {
       make_unique<WorkspaceProperty<>>("OutputWorkspace", "",
                                        Direction::Output),
       "The name of the workspace to be created as the output of the algorithm");
-  std::vector<int> npts0;
-  npts0.push_back(3);
+  std::vector<int> npts0{3};
   auto min = boost::make_shared<Kernel::ArrayBoundedValidator<int>>();
   min->setLower(3);
   // The number of points to use in the smoothing.
   declareProperty(
-      Kernel::make_unique<ArrayProperty<int>>("NPoints", npts0, min,
-                                              Direction::Input),
+      Kernel::make_unique<ArrayProperty<int>>("NPoints", std::move(npts0),
+                                              std::move(min), Direction::Input),
       "The number of points to average over (minimum 3). If an even number is\n"
       "given, it will be incremented by 1 to make it odd (default value 3)");
   declareProperty(
diff --git a/Framework/Algorithms/src/TimeAtSampleStrategyDirect.cpp b/Framework/Algorithms/src/TimeAtSampleStrategyDirect.cpp
index d19f8d97dbdb83cf9ebd93f3f31e28ff68ed11b5..ff68180e289c0344bcfa0e579285584d928dc058 100644
--- a/Framework/Algorithms/src/TimeAtSampleStrategyDirect.cpp
+++ b/Framework/Algorithms/src/TimeAtSampleStrategyDirect.cpp
@@ -30,14 +30,17 @@ TimeAtSampleStrategyDirect::TimeAtSampleStrategyDirect(
     MatrixWorkspace_const_sptr ws, double ei)
     : m_constShift(0) {
 
+  // A constant among all spectra
+  constexpr double TWO_MEV_OVER_MASS =
+      2. * PhysicalConstants::meV / PhysicalConstants::NeutronMass;
+
   // Get L1
-  V3D samplepos = ws->getInstrument()->getSample()->getPos();
-  V3D sourcepos = ws->getInstrument()->getSource()->getPos();
+  const auto &samplepos = ws->getInstrument()->getSample()->getPos();
+  const auto &sourcepos = ws->getInstrument()->getSource()->getPos();
   double l1 = samplepos.distance(sourcepos);
 
   // Calculate constant (to all spectra) shift
-  m_constShift = l1 / std::sqrt(ei * 2. * PhysicalConstants::meV /
-                                PhysicalConstants::NeutronMass);
+  m_constShift = l1 / std::sqrt(ei * TWO_MEV_OVER_MASS);
 }
 
 /**
@@ -51,6 +54,5 @@ Correction Mantid::Algorithms::TimeAtSampleStrategyDirect::calculate(
   // required.
   return Correction(0, m_constShift);
 }
-
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/TimeAtSampleStrategyElastic.cpp b/Framework/Algorithms/src/TimeAtSampleStrategyElastic.cpp
index a005257641b379c67f78750f4eb2a81294865d39..0d7f3732da2714fad7fdfa8d2384bc47f39736ef 100644
--- a/Framework/Algorithms/src/TimeAtSampleStrategyElastic.cpp
+++ b/Framework/Algorithms/src/TimeAtSampleStrategyElastic.cpp
@@ -33,22 +33,20 @@ TimeAtSampleStrategyElastic::TimeAtSampleStrategyElastic(
  */
 Correction
 TimeAtSampleStrategyElastic::calculate(const size_t &workspace_index) const {
-  Correction retvalue(0, 0);
 
   // Calculate TOF ratio
   const double L1s = m_spectrumInfo.l1();
+  double scale;
   if (m_spectrumInfo.isMonitor(workspace_index)) {
     double L1m =
         m_beamDir.scalar_prod(m_spectrumInfo.sourcePosition() -
                               m_spectrumInfo.position(workspace_index));
-    retvalue.factor = std::abs(L1s / L1m);
+    scale = std::abs(L1s / L1m);
   } else {
-    retvalue.factor = L1s / (L1s + m_spectrumInfo.l2(workspace_index));
+    scale = L1s / (L1s + m_spectrumInfo.l2(workspace_index));
   }
 
-  retvalue.offset = 0;
-
-  return retvalue;
+  return Correction(0., scale);
 }
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/src/TimeAtSampleStrategyIndirect.cpp b/Framework/Algorithms/src/TimeAtSampleStrategyIndirect.cpp
index 8ca7195c0dc16f41e5f0b9d8e0ca395929272d58..ee30d23235f1ac4557f91b60c7611ac3f7204628 100644
--- a/Framework/Algorithms/src/TimeAtSampleStrategyIndirect.cpp
+++ b/Framework/Algorithms/src/TimeAtSampleStrategyIndirect.cpp
@@ -36,44 +36,50 @@ Correction
 TimeAtSampleStrategyIndirect::calculate(const size_t &workspace_index) const {
 
   // A constant among all spectra
-  double twomev_d_mass =
+  constexpr double TWO_MEV_OVER_MASS =
       2. * PhysicalConstants::meV / PhysicalConstants::NeutronMass;
 
-  // Get the parameter map
-  const ParameterMap &pmap = m_ws->constInstrumentParameters();
-
-  double shift;
   const IDetector *det = &m_spectrumInfo.detector(workspace_index);
-  if (!m_spectrumInfo.isMonitor(workspace_index)) {
-    // Get E_fix
-    double efix = 0.;
-    try {
-      Parameter_sptr par = pmap.getRecursive(det, "Efixed");
-      if (par) {
-        efix = par->value<double>();
-      }
-    } catch (std::runtime_error &) {
-      // Throws if a DetectorGroup, use single provided value
-      std::stringstream errmsg;
-      errmsg << "Inelastic instrument detector " << det->getID()
-             << " of spectrum " << workspace_index << " does not have EFixed ";
-      throw std::runtime_error(errmsg.str());
-    }
-
-    double l2 = m_spectrumInfo.l2(workspace_index);
-    shift = -1. * l2 / sqrt(efix * twomev_d_mass);
+  if (m_spectrumInfo.isMonitor(workspace_index)) {
+    // use the same math as TimeAtSampleStrategyElastic
+    const double L1s = m_spectrumInfo.l1();
+    const auto &beamDir =
+        m_ws->getInstrument()->getReferenceFrame()->vecPointingAlongBeam();
+    const double L1m =
+        beamDir.scalar_prod(m_spectrumInfo.sourcePosition() -
+                            m_spectrumInfo.position(workspace_index));
+    const double scale = std::abs(L1s / L1m);
+    return Correction(0., scale);
+  }
 
-  } else {
-    std::stringstream errormsg;
-    errormsg << "Workspace index " << workspace_index << " is a monitor. ";
-    throw std::invalid_argument(errormsg.str());
+  // Get E_fix
+  double efix{0.};
+  try {
+    // Get the parameter map
+    const ParameterMap &pmap = m_ws->constInstrumentParameters();
+    Parameter_sptr par = pmap.getRecursive(det, "Efixed");
+    if (par) {
+      efix = par->value<double>();
+    }
+  } catch (std::runtime_error &) {
+    // Throws if a DetectorGroup, use single provided value
+    std::stringstream errmsg;
+    errmsg << "Inelastic instrument detector " << det->getID()
+           << " of spectrum " << workspace_index << " does not have EFixed ";
+    throw std::runtime_error(errmsg.str());
+  }
+  if (efix <= 0.) {
+    std::stringstream errmsg;
+    errmsg << "Inelastic instrument detector " << det->getID()
+           << " of spectrum " << workspace_index << " does not have EFixed ";
+    throw std::runtime_error(errmsg.str());
   }
 
-  Correction retvalue(0, 0);
-  retvalue.factor = 1.0;
-  retvalue.offset = shift;
+  const double l2 = m_spectrumInfo.l2(workspace_index);
+  const double shift = -1. * l2 / sqrt(efix * TWO_MEV_OVER_MASS);
 
-  return retvalue;
+  // 1.0 * tof + shift
+  return Correction(shift, 1.0);
 }
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/src/WeightedMean.cpp b/Framework/Algorithms/src/WeightedMean.cpp
index f45a333417f0ca2ebbdb7dc6b59bf84742f7706d..8e9cbda86f37ddb4320fecfbc3ede8c834592cc1 100644
--- a/Framework/Algorithms/src/WeightedMean.cpp
+++ b/Framework/Algorithms/src/WeightedMean.cpp
@@ -49,28 +49,25 @@ std::string WeightedMean::checkSizeCompatibility(
   }
 }
 
-void WeightedMean::performBinaryOperation(const MantidVec &lhsX,
-                                          const MantidVec &lhsY,
-                                          const MantidVec &lhsE,
-                                          const MantidVec &rhsY,
-                                          const MantidVec &rhsE,
-                                          MantidVec &YOut, MantidVec &EOut) {
-  (void)lhsX; // Avoid compiler warning
-  const size_t bins = lhsY.size();
+void WeightedMean::performBinaryOperation(const HistogramData::Histogram &lhs,
+                                          const HistogramData::Histogram &rhs,
+                                          HistogramData::HistogramY &YOut,
+                                          HistogramData::HistogramE &EOut) {
+  const size_t bins = lhs.size();
   for (size_t j = 0; j < bins; ++j) {
-    if (lhsE[j] > 0.0 && rhsE[j] > 0.0) {
-      const double err1 = lhsE[j] * lhsE[j];
-      const double err2 = rhsE[j] * rhsE[j];
-      YOut[j] = (lhsY[j] / err1) + (rhsY[j] / err2);
+    if (lhs.e()[j] > 0.0 && rhs.e()[j] > 0.0) {
+      const double err1 = lhs.e()[j] * lhs.e()[j];
+      const double err2 = rhs.e()[j] * rhs.e()[j];
+      YOut[j] = (lhs.y()[j] / err1) + (rhs.y()[j] / err2);
       EOut[j] = (err1 * err2) / (err1 + err2);
       YOut[j] *= EOut[j];
       EOut[j] = sqrt(EOut[j]);
-    } else if (lhsE[j] > 0.0 && rhsE[j] <= 0.0) {
-      YOut[j] = lhsY[j];
-      EOut[j] = lhsE[j];
-    } else if (lhsE[j] <= 0.0 && rhsE[j] > 0.0) {
-      YOut[j] = rhsY[j];
-      EOut[j] = rhsE[j];
+    } else if (lhs.e()[j] > 0.0 && rhs.e()[j] <= 0.0) {
+      YOut[j] = lhs.y()[j];
+      EOut[j] = lhs.e()[j];
+    } else if (lhs.e()[j] <= 0.0 && rhs.e()[j] > 0.0) {
+      YOut[j] = rhs.y()[j];
+      EOut[j] = rhs.e()[j];
     } else {
       YOut[j] = 0.0;
       EOut[j] = 0.0;
@@ -78,25 +75,23 @@ void WeightedMean::performBinaryOperation(const MantidVec &lhsX,
   }
 }
 
-void WeightedMean::performBinaryOperation(const MantidVec &lhsX,
-                                          const MantidVec &lhsY,
-                                          const MantidVec &lhsE,
+void WeightedMean::performBinaryOperation(const HistogramData::Histogram &lhs,
                                           const double rhsY, const double rhsE,
-                                          MantidVec &YOut, MantidVec &EOut) {
-  UNUSED_ARG(lhsX);
-  assert(lhsX.size() == 1);
+                                          HistogramData::HistogramY &YOut,
+                                          HistogramData::HistogramE &EOut) {
+  assert(lhs.size() == 1);
   // If we get here we've got two single column workspaces so it's easy.
-  if (lhsE[0] > 0.0 && rhsE > 0.0) {
-    const double err1 = lhsE[0] * lhsE[0];
+  if (lhs.e()[0] > 0.0 && rhsE > 0.0) {
+    const double err1 = lhs.e()[0] * lhs.e()[0];
     const double err2 = rhsE * rhsE;
-    YOut[0] = (lhsY[0] / err1) + (rhsY / err2);
+    YOut[0] = (lhs.y()[0] / err1) + (rhsY / err2);
     EOut[0] = (err1 * err2) / (err1 + err2);
     YOut[0] *= EOut[0];
     EOut[0] = sqrt(EOut[0]);
-  } else if (lhsE[0] > 0.0 && rhsE <= 0.0) {
-    YOut[0] = lhsY[0];
-    EOut[0] = lhsE[0];
-  } else if (lhsE[0] <= 0.0 && rhsE > 0.0) {
+  } else if (lhs.e()[0] > 0.0 && rhsE <= 0.0) {
+    YOut[0] = lhs.y()[0];
+    EOut[0] = lhs.e()[0];
+  } else if (lhs.e()[0] <= 0.0 && rhsE > 0.0) {
     YOut[0] = rhsY;
     EOut[0] = rhsE;
   } else {
diff --git a/Framework/Algorithms/src/WorkspaceJoiners.cpp b/Framework/Algorithms/src/WorkspaceJoiners.cpp
index 5f8ae044a5c27d58d8733cc735ec28ad06efeb9d..375a72b239e424f672491706a3a6a592f22911df 100644
--- a/Framework/Algorithms/src/WorkspaceJoiners.cpp
+++ b/Framework/Algorithms/src/WorkspaceJoiners.cpp
@@ -25,10 +25,6 @@ using namespace DataObjects;
  */
 WorkspaceJoiners::WorkspaceJoiners() : Algorithm(), m_progress(nullptr) {}
 
-/** Destructor
- */
-WorkspaceJoiners::~WorkspaceJoiners() { delete m_progress; }
-
 /// Algorithm's category for identification. @see Algorithm::category
 const std::string WorkspaceJoiners::category() const {
   return "Transforms\\Merging";
@@ -53,7 +49,7 @@ MatrixWorkspace_sptr WorkspaceJoiners::execWS2D(const MatrixWorkspace &ws1,
   auto XValues = ws1.refX(0);
 
   // Initialize the progress reporting object
-  m_progress = new API::Progress(this, 0.0, 1.0, totalHists);
+  m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, totalHists);
 
   // Loop over the input workspaces in turn copying the data into the output one
   const int64_t &nhist1 = ws1.getNumberHistograms();
@@ -134,7 +130,7 @@ WorkspaceJoiners::execEvent(const DataObjects::EventWorkspace &eventWs1,
       create<EventWorkspace>(eventWs1, totalHists, eventWs1.binEdges(0));
 
   // Initialize the progress reporting object
-  m_progress = new API::Progress(this, 0.0, 1.0, totalHists);
+  m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, totalHists);
 
   const int64_t &nhist1 = eventWs1.getNumberHistograms();
   for (int64_t i = 0; i < nhist1; ++i) {
diff --git a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
index deada58ef8d4a1fd94bb0bda8d58247e3dcd6745..526810f1f8eab18b138b65faaed92417e0db168c 100644
--- a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
+++ b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
@@ -127,8 +127,7 @@ public:
     TS_ASSERT(cyl.isExecuted());
 
     // Using the output of the CylinderAbsorption algorithm is convenient
-    // because
-    // it adds the sample object to the workspace
+    // because it adds the sample object to the workspace
     TS_ASSERT_THROWS_NOTHING(atten2.setPropertyValue("InputWorkspace", cylWS));
     std::string outputWS("factors");
     TS_ASSERT_THROWS_NOTHING(
@@ -199,6 +198,55 @@ public:
     Mantid::API::AnalysisDataService::Instance().remove("gauge");
   }
 
+  void testTinyVolume() {
+    if (!atten.isInitialized())
+      atten.initialize();
+
+    // Create a small test workspace
+    MatrixWorkspace_sptr testWS =
+        WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(1, 10);
+    // Needs to have units of wavelength
+    testWS->getAxis(0)->unit() =
+        Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
+
+    Mantid::Algorithms::FlatPlateAbsorption flat;
+    flat.initialize();
+    TS_ASSERT_THROWS_NOTHING(
+        flat.setProperty<MatrixWorkspace_sptr>("InputWorkspace", testWS));
+    std::string flatWS("flat");
+    TS_ASSERT_THROWS_NOTHING(flat.setPropertyValue("OutputWorkspace", flatWS));
+    TS_ASSERT_THROWS_NOTHING(
+        flat.setPropertyValue("AttenuationXSection", "5.08"));
+    TS_ASSERT_THROWS_NOTHING(
+        flat.setPropertyValue("ScatteringXSection", "5.1"));
+    TS_ASSERT_THROWS_NOTHING(
+        flat.setPropertyValue("SampleNumberDensity", "0.07192"));
+    TS_ASSERT_THROWS_NOTHING(flat.setPropertyValue("SampleHeight", "2.3"));
+    TS_ASSERT_THROWS_NOTHING(flat.setPropertyValue("SampleWidth", "1.8"));
+    // too thin to work in any shapes gauge volume creation
+    TS_ASSERT_THROWS_NOTHING(flat.setPropertyValue("SampleThickness", ".1"));
+    TS_ASSERT_THROWS_NOTHING(flat.execute());
+    TS_ASSERT(flat.isExecuted());
+
+    // Using the output of the FlatPlateAbsorption algorithm is convenient
+    // because it adds the sample object to the workspace
+    TS_ASSERT_THROWS_NOTHING(atten.setPropertyValue("InputWorkspace", flatWS));
+    std::string outputWS("factors");
+    TS_ASSERT_THROWS_NOTHING(
+        atten.setPropertyValue("OutputWorkspace", outputWS));
+    TS_ASSERT_THROWS_NOTHING(
+        atten.setPropertyValue("AttenuationXSection", "5.08"));
+    TS_ASSERT_THROWS_NOTHING(
+        atten.setPropertyValue("ScatteringXSection", "5.1"));
+    TS_ASSERT_THROWS_NOTHING(
+        atten.setPropertyValue("SampleNumberDensity", "0.07192"));
+    atten.setRethrows(true); // needed for the next check to work
+    TS_ASSERT_THROWS(atten.execute(), std::runtime_error);
+    TS_ASSERT(!atten.isExecuted());
+
+    Mantid::API::AnalysisDataService::Instance().remove(flatWS);
+  }
+
 private:
   Mantid::Algorithms::AnyShapeAbsorption atten;
 };
diff --git a/Framework/Algorithms/test/ApplyDetailedBalanceTest.h b/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
index 85a614793ff1369db1f8b0ef8867e9aed08decea..9ef20ae48ddf9aa9804bca230c2f37575703c2bf 100644
--- a/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
+++ b/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
@@ -89,7 +89,7 @@ public:
         alg.setPropertyValue("OutputWorkspace", outputWSname));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Temperature", "x"));
     TS_ASSERT_THROWS_NOTHING(alg.execute());
-    TS_ASSERT(alg.isExecuted());
+    TS_ASSERT(!alg.isExecuted());
     Workspace2D_sptr outws;
     TS_ASSERT_THROWS_ANYTHING(
         outws = AnalysisDataService::Instance().retrieveWS<Workspace2D>(
diff --git a/Framework/Algorithms/test/ApplyFloodWorkspaceTest.h b/Framework/Algorithms/test/ApplyFloodWorkspaceTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1afb6154fa151d0ad08b1a37673f4f7b50c1e7a5
--- /dev/null
+++ b/Framework/Algorithms/test/ApplyFloodWorkspaceTest.h
@@ -0,0 +1,96 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_ALGORITHMS_APPLYFLOODWORKSPACETEST_H_
+#define MANTID_ALGORITHMS_APPLYFLOODWORKSPACETEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/ApplyFloodWorkspace.h"
+
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/Axis.h"
+#include "MantidAlgorithms/ConvertUnits.h"
+#include "MantidKernel/Unit.h"
+#include "MantidTestHelpers/ReflectometryHelper.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
+using namespace Mantid::Algorithms;
+using namespace Mantid::API;
+using namespace Mantid::Kernel;
+using namespace WorkspaceCreationHelper;
+
+class ApplyFloodWorkspaceTest : public CxxTest::TestSuite {
+public:
+  void test_flood_same_x_units() {
+    auto inputWS =
+        create2DWorkspaceWithReflectometryInstrumentMultiDetector(0, 0.1);
+    auto flood = createFloodWorkspace(inputWS->getInstrument());
+
+    ApplyFloodWorkspace alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setProperty("InputWorkspace", inputWS);
+    alg.setProperty("FloodWorkspace", flood);
+    alg.setProperty("OutputWorkspace", "dummy");
+    alg.execute();
+    MatrixWorkspace_sptr out = alg.getProperty("OutputWorkspace");
+    TS_ASSERT_DELTA(out->y(0)[0], 2.8571428575, 1e-9);
+    TS_ASSERT_DELTA(out->y(1)[0], 2.0, 1e-9);
+    TS_ASSERT_DELTA(out->y(2)[0], 2.5, 1e-9);
+    TS_ASSERT_DELTA(out->y(3)[0], 2.2222222222, 1e-9);
+    AnalysisDataService::Instance().clear();
+  }
+
+  void test_flood_different_x_units() {
+    auto inputWS =
+        create2DWorkspaceWithReflectometryInstrumentMultiDetector(0, 0.1);
+    auto flood = createFloodWorkspace(inputWS->getInstrument(), "Wavelength");
+
+    ApplyFloodWorkspace alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setProperty("InputWorkspace", inputWS);
+    alg.setProperty("FloodWorkspace", flood);
+    alg.setProperty("OutputWorkspace", "dummy");
+    alg.execute();
+    MatrixWorkspace_sptr out = alg.getProperty("OutputWorkspace");
+    TS_ASSERT_DELTA(out->y(0)[0], 2.8571428575, 1e-9);
+    TS_ASSERT_DELTA(out->y(1)[0], 2.0, 1e-9);
+    TS_ASSERT_DELTA(out->y(2)[0], 2.5, 1e-9);
+    TS_ASSERT_DELTA(out->y(3)[0], 2.2222222222, 1e-9);
+    AnalysisDataService::Instance().clear();
+  }
+
+private:
+  MatrixWorkspace_sptr
+  createFloodWorkspace(Mantid::Geometry::Instrument_const_sptr instrument,
+                       std::string const &xUnit = "TOF") {
+    MatrixWorkspace_sptr flood = create2DWorkspace(4, 1);
+    flood->mutableY(0)[0] = 0.7;
+    flood->mutableY(1)[0] = 1.0;
+    flood->mutableY(2)[0] = 0.8;
+    flood->mutableY(3)[0] = 0.9;
+    flood->setInstrument(instrument);
+    for (size_t i = 0; i < flood->getNumberHistograms(); ++i) {
+      flood->getSpectrum(i).setDetectorID(Mantid::detid_t(i + 1));
+    }
+    flood->getAxis(0)->setUnit("TOF");
+    if (xUnit != "TOF") {
+      ConvertUnits convert;
+      convert.initialize();
+      convert.setChild(true);
+      convert.setProperty("InputWorkspace", flood);
+      convert.setProperty("Target", xUnit);
+      convert.setProperty("OutputWorkspace", "dummy");
+      convert.execute();
+      flood = convert.getProperty("OutputWorkspace");
+    }
+    return flood;
+  }
+};
+
+#endif /* MANTID_ALGORITHMS_APPLYFLOODWORKSPACETEST_H_ */
diff --git a/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h b/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
index e15b90bf4584ae49611b465164c8cd6006f0e9ba..440ab8b199a4a0f5d909c5b0a75fbbd6b498fd17 100644
--- a/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
+++ b/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
@@ -45,8 +45,9 @@ public:
     mover.setPropertyValue("ComponentName", "detector1");
     // X = (16-192.0/2.0+0.5)*5.15/1000.0 = -0.409425
     // Y = (95-192.0/2.0+0.5)*5.15/1000.0 = -0.002575
-    mover.setPropertyValue("X", "0.409425");
+    mover.setPropertyValue("X", "0.009425");
     mover.setPropertyValue("Y", "0.002575");
+    mover.setPropertyValue("Z", "-0.8114");
     mover.execute();
 
     Mantid::Algorithms::ApplyTransmissionCorrection correction;
diff --git a/Framework/Algorithms/test/BinaryOperationTest.h b/Framework/Algorithms/test/BinaryOperationTest.h
index e5b6dbe3566fa37ec766e8bdb95e383bcae71dd6..8b54ea141d9cf26b29a02c548e5f4fe2e3df6754 100644
--- a/Framework/Algorithms/test/BinaryOperationTest.h
+++ b/Framework/Algorithms/test/BinaryOperationTest.h
@@ -55,17 +55,13 @@ private:
   // Unhide base class method to avoid Intel compiler warning
   using BinaryOperation::checkSizeCompatibility;
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const Mantid::MantidVec &,
-                              const Mantid::MantidVec &,
-                              const Mantid::MantidVec &,
-                              const Mantid::MantidVec &,
-                              const Mantid::MantidVec &, Mantid::MantidVec &,
-                              Mantid::MantidVec &) override {}
-  void performBinaryOperation(const Mantid::MantidVec &,
-                              const Mantid::MantidVec &,
-                              const Mantid::MantidVec &, const double,
-                              const double, Mantid::MantidVec &,
-                              Mantid::MantidVec &) override {}
+  void performBinaryOperation(const HistogramData::Histogram &,
+                              const HistogramData::Histogram &,
+                              HistogramData::HistogramY &,
+                              HistogramData::HistogramE &) override {}
+  void performBinaryOperation(const HistogramData::Histogram &, const double,
+                              const double, HistogramData::HistogramY &,
+                              HistogramData::HistogramE &) override {}
 };
 
 namespace {
diff --git a/Framework/Algorithms/test/CommutativeBinaryOperationTest.h b/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
index 0376141d9e80352045bdec6406d52c5a2445835e..200e1a23ff7aa847e398f1b01e6c702729123ed8 100644
--- a/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
+++ b/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
@@ -47,25 +47,20 @@ private:
   // Unhide base class method to avoid Intel compiler warning
   using BinaryOperation::checkSizeCompatibility;
   // Overridden BinaryOperation methods
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const MantidVec &rhsY,
-                              const MantidVec &rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override {
-    UNUSED_ARG(lhsX);
-    UNUSED_ARG(lhsY);
-    UNUSED_ARG(lhsE);
-    UNUSED_ARG(rhsY);
-    UNUSED_ARG(rhsE);
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const HistogramData::Histogram &rhs,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override {
+    UNUSED_ARG(lhs);
+    UNUSED_ARG(rhs);
     UNUSED_ARG(YOut);
     UNUSED_ARG(EOut);
   }
-  void performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY,
-                              const MantidVec &lhsE, const double rhsY,
-                              const double rhsE, MantidVec &YOut,
-                              MantidVec &EOut) override {
-    UNUSED_ARG(lhsX);
-    UNUSED_ARG(lhsY);
-    UNUSED_ARG(lhsE);
+  void performBinaryOperation(const HistogramData::Histogram &lhs,
+                              const double rhsY, const double rhsE,
+                              HistogramData::HistogramY &YOut,
+                              HistogramData::HistogramE &EOut) override {
+    UNUSED_ARG(lhs);
     UNUSED_ARG(rhsY);
     UNUSED_ARG(rhsE);
     UNUSED_ARG(YOut);
diff --git a/Framework/Algorithms/test/CopySampleTest.h b/Framework/Algorithms/test/CopySampleTest.h
index 715e35c6b3418f760d211aba31b4506be985ea48..d24adb45a31177f39c4edd261099db9e3738bf73 100644
--- a/Framework/Algorithms/test/CopySampleTest.h
+++ b/Framework/Algorithms/test/CopySampleTest.h
@@ -47,10 +47,10 @@ public:
     const std::string envName("TestKit");
     auto canShape = ComponentCreationHelper::cappedCylinderXML(
         0.5, 1.5, V3D(0.0, 0.0, 0.0), V3D(0., 1.0, 0.), "tube");
-    SampleEnvironment *kit = new SampleEnvironment(
+    auto kit = std::make_unique<SampleEnvironment>(
         envName,
         boost::make_shared<Container>(ShapeFactory().createShape(canShape)));
-    sample.setEnvironment(kit);
+    sample.setEnvironment(std::move(kit));
     OrientedLattice *latt = new OrientedLattice(1.0, 2.0, 3.0, 90, 90, 90);
     sample.setOrientedLattice(latt);
     delete latt;
diff --git a/Framework/Algorithms/test/ExtractFFTSpectrumTest.h b/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
index a21bc0765b21cf739186bb1e9dddaaf2d2067b9d..66bdd6e3f52d989873d12543ae047035c38b6e71 100644
--- a/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
+++ b/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
@@ -87,7 +87,7 @@ public:
     TS_ASSERT_EQUALS(inputWS->blocksize(), outputWS->blocksize());
 
     // Units ( Axis 1 should be the same, Axis 0 should be "Time/ns"
-    TS_ASSERT_EQUALS(inputWS->getAxis(1)->unit(), outputWS->getAxis(1)->unit());
+    TS_ASSERT(*inputWS->getAxis(1)->unit() == *outputWS->getAxis(1)->unit());
     TS_ASSERT_EQUALS(outputWS->getAxis(0)->unit()->caption(), "Time");
     TS_ASSERT_EQUALS(outputWS->getAxis(0)->unit()->label(), "ns");
   }
diff --git a/Framework/Algorithms/test/ExtractSpectra2Test.h b/Framework/Algorithms/test/ExtractSpectra2Test.h
index 818c857e42a70e36a878b0431a391e83cc51bf1b..b8b05a3220598cd725efbba7fea3f3a9373ee3cd 100644
--- a/Framework/Algorithms/test/ExtractSpectra2Test.h
+++ b/Framework/Algorithms/test/ExtractSpectra2Test.h
@@ -10,6 +10,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAlgorithms/ExtractSpectra2.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
@@ -125,6 +126,51 @@ public:
   }
 
   void test_parallel() { ParallelTestHelpers::runParallel(run_parallel); }
+
+  void test_BinEdgeAxis() {
+    auto input = createWorkspace();
+    BinEdgeAxis *axis = new BinEdgeAxis(input->getNumberHistograms() + 1);
+    for (size_t i = 0; i < axis->length(); ++i) {
+      axis->setValue(i, -2. + static_cast<double>(i));
+    }
+    input->replaceAxis(1, axis);
+    ExtractSpectra2 alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setRethrows(true);
+    alg.setProperty("InputWorkspace", std::move(input));
+    alg.setProperty("InputWorkspaceIndexSet", "1-3");
+    alg.setProperty("OutputWorkspace", "out");
+    alg.execute();
+    MatrixWorkspace_sptr out = alg.getProperty("OutputWorkspace");
+    auto outAxis = out->getAxis(1);
+    TS_ASSERT_DIFFERS(dynamic_cast<BinEdgeAxis *>(outAxis), nullptr)
+    TS_ASSERT_EQUALS(outAxis->length(), 4)
+    TS_ASSERT_EQUALS((*outAxis)(0), -1.)
+    TS_ASSERT_EQUALS((*outAxis)(1), 0.)
+    TS_ASSERT_EQUALS((*outAxis)(2), 1.)
+    TS_ASSERT_EQUALS((*outAxis)(3), 2.)
+  }
+
+  void test_BinEdgeAxis_fails_with_non_contiguous_indices() {
+    auto input = createWorkspace();
+    BinEdgeAxis *axis = new BinEdgeAxis(input->getNumberHistograms() + 1);
+    for (size_t i = 0; i < axis->length(); ++i) {
+      axis->setValue(i, -2. + static_cast<double>(i));
+    }
+    input->replaceAxis(1, axis);
+    ExtractSpectra2 alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setRethrows(true);
+    alg.setProperty("InputWorkspace", std::move(input));
+    alg.setProperty("InputWorkspaceIndexSet", "1,3");
+    alg.setProperty("OutputWorkspace", "out");
+    TS_ASSERT_THROWS_EQUALS(
+        alg.execute(), const std::invalid_argument &e, e.what(),
+        std::string("Cannot extract non-contiguous set of spectra when the "
+                    "vertical axis has bin edges."))
+  }
 };
 
 #endif /* MANTID_ALGORITHMS_EXTRACTSPECTRA2TEST_H_ */
diff --git a/Framework/Algorithms/test/IndirectFitDataCreationHelperTest.h b/Framework/Algorithms/test/IndirectFitDataCreationHelperTest.h
index d110ed764ef2b88f621fe0a397ba83f9936f73c2..60fa576cdbaaa8094d8f3ed38e5e822b79fa1cf9 100644
--- a/Framework/Algorithms/test/IndirectFitDataCreationHelperTest.h
+++ b/Framework/Algorithms/test/IndirectFitDataCreationHelperTest.h
@@ -12,6 +12,10 @@ using namespace Mantid::IndirectFitDataCreationHelper;
 
 namespace {
 
+std::vector<std::string> getTextAxisLabels() {
+  return {"f0.Width", "f1.Width", "f2.EISF"};
+}
+
 void storeWorkspaceInADS(std::string const &workspaceName,
                          MatrixWorkspace_sptr workspace) {
   SetUpADSWithWorkspace ads(workspaceName, workspace);
@@ -63,6 +67,12 @@ public:
 
   void tearDown() override { AnalysisDataService::Instance().clear(); }
 
+  void test_that_the_constant_variables_have_the_values_expected() {
+    TS_ASSERT_EQUALS(START_X_COLUMN, 2);
+    TS_ASSERT_EQUALS(END_X_COLUMN, 3);
+    TS_ASSERT_EQUALS(EXCLUDE_REGION_COLUMN, 4);
+  }
+
   void
   test_that_createWorkspace_returns_a_workspace_with_the_number_of_spectra_specified() {
     auto const workspace = createWorkspace(10);
@@ -77,6 +87,31 @@ public:
     TS_ASSERT_EQUALS(workspace->getNumberHistograms(), 6);
   }
 
+  void
+  test_that_createWorkspaceWithTextAxis_returns_a_workspace_with_the_number_of_spectra_specified() {
+    auto const workspace = createWorkspaceWithTextAxis(3, getTextAxisLabels());
+    TS_ASSERT(workspace);
+    TS_ASSERT_EQUALS(workspace->getNumberHistograms(), 3);
+  }
+
+  void
+  test_that_createWorkspaceWithTextAxis_returns_a_workspace_with_the_text_axis_labels_specified() {
+    auto const labels = getTextAxisLabels();
+    auto const workspace = createWorkspaceWithTextAxis(3, labels);
+
+    auto const yAxis = workspace->getAxis(1);
+
+    for (auto index = 0u; index < workspace->getNumberHistograms(); ++index)
+      TS_ASSERT_EQUALS(yAxis->label(index), labels[index]);
+  }
+
+  void
+  test_that_createWorkspaceWithTextAxis_throws_when_the_number_of_spectra_is_not_equal_to_the_number_of_labels() {
+    auto const labels = std::vector<std::string>({"f0.Width", "f1.EISF"});
+    TS_ASSERT_THROWS(createWorkspaceWithTextAxis(6, labels),
+                     std::runtime_error);
+  }
+
   void
   test_that_setWorkspaceEFixed_does_not_throw_when_setting_EFixed_values() {
     auto workspace = createInstrumentWorkspace(6, 5);
diff --git a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
index b43a162c130c33a6ba6f84a06cddfe2f3ea35a1b..3e6db57c1ef7e59dee5cc0c7f9c59d15516fd0a7 100644
--- a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
+++ b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
@@ -65,8 +65,8 @@ void addSample(Mantid::API::MatrixWorkspace_sptr ws,
     canShape->setMaterial(Material(
         "CanMaterial", PhysicalConstants::getNeutronAtom(26, 0), 0.01));
     auto can = boost::make_shared<Container>(canShape);
-    SampleEnvironment *env = new SampleEnvironment("can", can);
-    ws->mutableSample().setEnvironment(env);
+    ws->mutableSample().setEnvironment(
+        std::make_unique<SampleEnvironment>("can", can));
   } else if (environment == Environment::UserBeamSize) {
     auto inst = ws->getInstrument();
     auto &pmap = ws->instrumentParameters();
diff --git a/Framework/Algorithms/test/MonteCarloTesting.h b/Framework/Algorithms/test/MonteCarloTesting.h
index 5d2b3f860bcedfca9a392f7563e18821aa6e791e..4877acb2b9d95a614bf59b9f15faf6ad325ebf1d 100644
--- a/Framework/Algorithms/test/MonteCarloTesting.h
+++ b/Framework/Algorithms/test/MonteCarloTesting.h
@@ -14,9 +14,7 @@
 #include "MantidKernel/Material.h"
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 #include "MantidKernel/WarningSuppressions.h"
-#include "MantidKernel/make_unique.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
-
 #include <boost/make_shared.hpp>
 #include <gmock/gmock.h>
 
@@ -105,7 +103,7 @@ inline Mantid::API::Sample createSamplePlusContainer() {
   }
   auto can = boost::make_shared<Container>(canShape);
   auto environment =
-      Mantid::Kernel::make_unique<SampleEnvironment>("Annulus Container", can);
+      std::make_unique<SampleEnvironment>("Annulus Container", can);
   // Sample volume
   auto sampleCell = ComponentCreationHelper::createCappedCylinder(
       innerRadius, height, centre, upAxis, "sample");
@@ -118,7 +116,7 @@ inline Mantid::API::Sample createSamplePlusContainer() {
   // Sample object
   Sample testSample;
   testSample.setShape(sampleCell);
-  testSample.setEnvironment(environment.release());
+  testSample.setEnvironment(std::move(environment));
   return testSample;
 }
 
diff --git a/Framework/Algorithms/test/MultiplyDivideTest.in.h b/Framework/Algorithms/test/MultiplyDivideTest.in.h
index d8939989e9d40619b0845c3b94a6937ceae37954..a1d3b0f6c620b3163bdd132ccd07d06cec57f7d0 100644
--- a/Framework/Algorithms/test/MultiplyDivideTest.in.h
+++ b/Framework/Algorithms/test/MultiplyDivideTest.in.h
@@ -15,7 +15,6 @@
 #include "MantidAlgorithms/Divide.h"
 #include "MantidAlgorithms/Multiply.h"
 #include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
@@ -97,19 +96,19 @@ public:
     if (DO_DIVIDE)
     {
       a /= 5;
-      TS_ASSERT_EQUALS(a->readY(0)[0], 0.6)
+      TS_ASSERT_EQUALS(a->y(0)[0], 0.6)
       TS_ASSERT_EQUALS(a,b);
       a /= c;
-      TS_ASSERT_EQUALS(a->readY(0)[0], 0.3);
+      TS_ASSERT_EQUALS(a->y(0)[0], 0.3);
       TS_ASSERT_EQUALS(a,b);
     }
     else
     {
       a *= 5;
-      TS_ASSERT_EQUALS(a->readY(0)[0],15.0)
+      TS_ASSERT_EQUALS(a->y(0)[0],15.0)
       TS_ASSERT_EQUALS(a,b);
       a *= c;
-      TS_ASSERT_EQUALS(a->readY(0)[0],30.0);
+      TS_ASSERT_EQUALS(a->y(0)[0],30.0);
       TS_ASSERT_EQUALS(a,b);
     }
   }
@@ -158,6 +157,31 @@ public:
     }
   }
 
+  void test_2D_denominator_with_fewer_spectra()
+  {
+    if(DO_DIVIDE)
+    {
+    int nHist = 5,nBins=5;
+    MatrixWorkspace_sptr numerator  = WorkspaceCreationHelper::create2DWorkspace123(nHist,nBins);
+    MatrixWorkspace_sptr denominator = WorkspaceCreationHelper::create2DWorkspace123(nHist-1, nBins); // Cropped
+    Divide alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setProperty("LHSWorkspace", numerator);
+    alg.setProperty("RHSWorkspace", denominator);
+    alg.setPropertyValue("OutputWorkspace", "dummy");
+    alg.setProperty("AllowDifferentNumberSpectra", true);
+    alg.execute();
+    MatrixWorkspace_sptr outWS = alg.getProperty("OutputWorkspace");
+    TS_ASSERT_EQUALS(outWS->getNumberHistograms(), nHist);
+    TS_ASSERT_EQUALS(outWS->y(0)[0], 1.0);
+    TS_ASSERT_EQUALS(outWS->y(1)[0], 1.0);
+    TS_ASSERT_EQUALS(outWS->y(2)[0], 1.0);
+    TS_ASSERT_EQUALS(outWS->y(3)[0], 1.0);
+    TS_ASSERT_EQUALS(outWS->y(4)[0], 0.0);
+    }
+  }
+
   void test_2D_1DColumn()
   {
     for (int inplace=0; inplace<2; inplace++)
@@ -208,9 +232,9 @@ public:
       work_out3 = value/work_in2;
       // checkData won't work on this one, do a few checks here
       TS_ASSERT_EQUALS( work_out3->size(), work_in2->size() );
-      TS_ASSERT_EQUALS( work_out3->readX(1), work_in2->readX(1) );
-      TS_ASSERT_DELTA( work_out3->readY(2)[6], 0.6,  0.0001 );
-      TS_ASSERT_DELTA( work_out3->readE(3)[4], 0.48, 0.0001 );
+      TS_ASSERT_EQUALS( work_out3->x(1), work_in2->x(1) );
+      TS_ASSERT_DELTA( work_out3->y(2)[6], 0.6,  0.0001 );
+      TS_ASSERT_DELTA( work_out3->e(3)[4], 0.48, 0.0001 );
     }
     else
     {
@@ -596,13 +620,13 @@ public:
     MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createGroupedEventWorkspace(lhs, 10, 1.0);
     if (lhs2D)
       work_in1 = EventWorkspaceHelpers::convertEventTo2D(work_in1);
-    TS_ASSERT_DELTA( work_in1->readE(0)[0], sqrt( double(lhs_grouping*1.0) ), 1e-5);
+    TS_ASSERT_DELTA( work_in1->e(0)[0], sqrt( double(lhs_grouping*1.0) ), 1e-5);
 
     // Grouped workspace will have rhs_grouping events in each bin (also).
     MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createGroupedEventWorkspace(rhs, 10, 1.0);
     if (rhs2D)
       work_in2 = EventWorkspaceHelpers::convertEventTo2D(work_in2);
-    TS_ASSERT_DELTA( work_in2->readE(0)[0], sqrt( double(rhs_grouping*1.0) ), 1e-5);
+    TS_ASSERT_DELTA( work_in2->e(0)[0], sqrt( double(rhs_grouping*1.0) ), 1e-5);
 
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, !lhs2D, divideValue, divideError, true);
@@ -675,7 +699,7 @@ public:
     else
       mess << "2D";
     mess << "(" << ws->getNumberHistograms() << " spectra," << ws->blocksize() << " bins,";
-    mess << "Y[0][0] = " << ws->readY(0)[0] << ")";
+    mess << "Y[0][0] = " << ws->y(0)[0] << ")";
     return mess.str();
   }
 
@@ -852,10 +876,10 @@ public:
       bool breakOut=false;
       std::string  dummy;
       for (size_t wi=0; wi < work_out1->getNumberHistograms(); wi++) {
-        const auto &xIn = work_in1->readX(wi);
-        const auto &xOut = work_out1->readX(wi);
-        const auto &yOut = work_out1->readY(wi);
-        const auto &eOut = work_out1->readE(wi);
+        const auto &xIn = work_in1->x(wi);
+        const auto &xOut = work_out1->x(wi);
+        const auto &yOut = work_out1->y(wi);
+        const auto &eOut = work_out1->e(wi);
         for (size_t i=0; i < yOut.size(); i++) {
           //std::ostringstream mess;
           //mess << message << ", evaluated at wi " << wi << ", i " << i;
@@ -887,16 +911,16 @@ public:
 //      return true;
 //    if (ws2Index/work_in2->blocksize() >= work_in2->getNumberHistograms())
 //      return true;
-    double sig1 = work_in1->readY(i/work_in1->blocksize())[i%work_in1->blocksize()];
-    double sig2 = work_in2->readY(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
-    double sig3 = work_out1->readY(i/work_in1->blocksize())[i%work_in1->blocksize()];
+    double sig1 = work_in1->y(i/work_in1->blocksize())[i%work_in1->blocksize()];
+    double sig2 = work_in2->y(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
+    double sig3 = work_out1->y(i/work_in1->blocksize())[i%work_in1->blocksize()];
 
-    TS_ASSERT_DELTA(work_in1->readX(i/work_in1->blocksize())[i%work_in1->blocksize()],
-        work_out1->readX(i/work_in1->blocksize())[i%work_in1->blocksize()], 0.0001);
+    TS_ASSERT_DELTA(work_in1->x(i/work_in1->blocksize())[i%work_in1->blocksize()],
+        work_out1->x(i/work_in1->blocksize())[i%work_in1->blocksize()], 0.0001);
 
-    double err1 = work_in1->readE(i/work_in1->blocksize())[i%work_in1->blocksize()];
-    double err2 = work_in2->readE(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
-    double err3 = work_out1->readE(i/work_in1->blocksize())[i%work_in1->blocksize()];
+    double err1 = work_in1->e(i/work_in1->blocksize())[i%work_in1->blocksize()];
+    double err2 = work_in2->e(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
+    double err3 = work_out1->e(i/work_in1->blocksize())[i%work_in1->blocksize()];
 
     double expectValue, expectError;
     //Compute the expectation
@@ -978,7 +1002,7 @@ public:
       else
       {
         TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
-        double yValue = output->readY(i)[0];
+        double yValue = output->y(i)[0];
         TS_ASSERT_EQUALS(yValue, yValue );
         TS_ASSERT( !std::isinf(yValue) );
       }
diff --git a/Framework/Algorithms/test/PlusMinusTest.in.h b/Framework/Algorithms/test/PlusMinusTest.in.h
index 6e337f3c1a2226e6a7dea87f36a11f8d5c3f765e..fc1c9b517105cf1f089f1d47dc2a9147f68264e7 100644
--- a/Framework/Algorithms/test/PlusMinusTest.in.h
+++ b/Framework/Algorithms/test/PlusMinusTest.in.h
@@ -15,7 +15,6 @@
 #include "MantidAlgorithms/Plus.h"
 #include "MantidAlgorithms/Rebin.h"
 #include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
@@ -94,19 +93,19 @@ public:
     if (DO_PLUS)
     {
       a += 5;
-      TS_ASSERT_EQUALS(a->readY(0)[0],7);
+      TS_ASSERT_EQUALS(a->y(0)[0],7);
       TS_ASSERT_EQUALS(a,b);
       a += c;
-      TS_ASSERT_EQUALS(a->readY(0)[0],9);
+      TS_ASSERT_EQUALS(a->y(0)[0],9);
       TS_ASSERT_EQUALS(a,b);
     }
     else
     {
       a -= 5;
-      TS_ASSERT_EQUALS(a->readY(0)[0],-3);
+      TS_ASSERT_EQUALS(a->y(0)[0],-3);
       TS_ASSERT_EQUALS(a,b);
       a -= c;
-      TS_ASSERT_EQUALS(a->readY(0)[0],-5);
+      TS_ASSERT_EQUALS(a->y(0)[0],-5);
       TS_ASSERT_EQUALS(a,b);
     }
   }
@@ -269,7 +268,7 @@ public:
       MatrixWorkspace_sptr work_out3 = value-work_in2;
       // checkData won't work on this one, do a few checks here
       TS_ASSERT_EQUALS( work_out3->size(), work_in2->size() );
-      TS_ASSERT_EQUALS( work_out3->readX(1), work_in2->readX(1) );
+      TS_ASSERT_EQUALS( work_out3->x(1), work_in2->x(1) );
       TS_ASSERT_EQUALS( work_out3->y(2)[6], 3.0 );
       TS_ASSERT_EQUALS( work_out3->e(3)[4], 4.0 );
     }
@@ -619,7 +618,7 @@ public:
     else
       mess << "2D";
     mess << "(" << ws->getNumberHistograms() << " spectra," << ws->blocksize() << " bins,";
-    mess << "Y[0][0] = " << ws->readY(0)[0] << ")";
+    mess << "Y[0][0] = " << ws->y(0)[0] << ")";
     return mess.str();
   }
 
@@ -725,7 +724,7 @@ public:
         TSM_ASSERT( message, ews_out);
         // The # of events is equal to the sum of the original amount
         TSM_ASSERT_EQUALS( message, ews_out->getNumberEvents(), numEvents1 + numEvents2 );
-        std::cout << ews_out->readY(0)[0] << " after adding (Y\n";
+        std::cout << ews_out->y(0)[0] << " after adding (Y\n";
       }
       else
       {
@@ -889,16 +888,16 @@ public:
     const size_t work_in1_blksize = work_in1->blocksize();
     const size_t work_in2_blksize = work_in2->blocksize();
 
-    const double sig1 = work_in1->readY(i/work_in1_blksize)[i%work_in1_blksize];
-    const double sig2 = work_in2->readY(ws2Index/work_in2_blksize)[ws2Index%work_in2_blksize];
-    const double sig3 = work_out1->readY(i/work_in1_blksize)[i%work_in1_blksize];
+    const double sig1 = work_in1->y(i/work_in1_blksize)[i%work_in1_blksize];
+    const double sig2 = work_in2->y(ws2Index/work_in2_blksize)[ws2Index%work_in2_blksize];
+    const double sig3 = work_out1->y(i/work_in1_blksize)[i%work_in1_blksize];
 
-    TS_ASSERT_DELTA(work_in1->readX(i/work_in1_blksize)[i%work_in1_blksize],
-        work_out1->readX(i/work_in1_blksize)[i%work_in1_blksize], 0.0001);
+    TS_ASSERT_DELTA(work_in1->x(i/work_in1_blksize)[i%work_in1_blksize],
+        work_out1->x(i/work_in1_blksize)[i%work_in1_blksize], 0.0001);
 
-    const double err1 = work_in1->readE(i/work_in1_blksize)[i%work_in1_blksize];
-    const double err2 = work_in2->readE(ws2Index/work_in2_blksize)[ws2Index%work_in2_blksize];
-    const double err3 = work_out1->readE(i/work_in1_blksize)[i%work_in1_blksize];
+    const double err1 = work_in1->e(i/work_in1_blksize)[i%work_in1_blksize];
+    const double err2 = work_in2->e(ws2Index/work_in2_blksize)[ws2Index%work_in2_blksize];
+    const double err3 = work_out1->e(i/work_in1_blksize)[i%work_in1_blksize];
 
     double expectValue;
     //Compute the expectation
diff --git a/Framework/Algorithms/test/PoissonErrorsTest.h b/Framework/Algorithms/test/PoissonErrorsTest.h
index cd8e2311e24963bb7a60a5fcf54ac3e4eafca4d8..2c4612eedef63017dcca8ff80cb8540c33d945b5 100644
--- a/Framework/Algorithms/test/PoissonErrorsTest.h
+++ b/Framework/Algorithms/test/PoissonErrorsTest.h
@@ -32,9 +32,7 @@ public:
   PoissonErrorsTest() {
     inputProp1 = "InputWorkspace";
     inputProp2 = "CountsWorkspace";
-    ;
     outputProp = "OutputWorkspace";
-    ;
   }
 
   void testInit() {
@@ -276,26 +274,26 @@ private:
                      size_t ws2Index) {
     // printf("I=%d\tws2Index=%d\n",i,ws2Index);
     double sig1 =
-        work_in1->dataY(i / work_in1->blocksize())[i % work_in1->blocksize()];
-    double sig2 = work_in2->dataY(
+        work_in1->y(i / work_in1->blocksize())[i % work_in1->blocksize()];
+    double sig2 = work_in2->y(
         ws2Index / work_in2->blocksize())[ws2Index % work_in2->blocksize()];
-    double sig2e = work_in2->dataE(
+    double sig2e = work_in2->e(
         ws2Index / work_in2->blocksize())[ws2Index % work_in2->blocksize()];
     double sig3 =
-        work_out1->dataY(i / work_in1->blocksize())[i % work_in1->blocksize()];
+        work_out1->y(i / work_in1->blocksize())[i % work_in1->blocksize()];
     TS_ASSERT_DELTA(
-        work_in1->dataX(i / work_in1->blocksize())[i % work_in1->blocksize()],
-        work_out1->dataX(i / work_in1->blocksize())[i % work_in1->blocksize()],
+        work_in1->x(i / work_in1->blocksize())[i % work_in1->blocksize()],
+        work_out1->x(i / work_in1->blocksize())[i % work_in1->blocksize()],
         0.0001);
     TS_ASSERT_DELTA(sig1, sig3, 0.0001);
     // double err1 =
-    // work_in1->dataE(i/work_in1->blocksize())[i%work_in1->blocksize()];
+    // work_in1->e(i/work_in1->blocksize())[i%work_in1->blocksize()];
     // double err2 =
-    // work_in2->dataE(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
+    // work_in2->e(ws2Index/work_in2->blocksize())[ws2Index%work_in2->blocksize()];
     double err3((sig2e / sig2) * sig3);
     TS_ASSERT_DELTA(
         err3,
-        work_out1->dataE(i / work_in1->blocksize())[i % work_in1->blocksize()],
+        work_out1->e(i / work_in1->blocksize())[i % work_in1->blocksize()],
         0.0001);
   }
 
diff --git a/Framework/Algorithms/test/Q1DWeightedTest.h b/Framework/Algorithms/test/Q1DWeightedTest.h
index 540bfbad442b079e735ca086fecb244e8f362002..12a449a5bfb10205829b80e5d48146e9ff2557b2 100644
--- a/Framework/Algorithms/test/Q1DWeightedTest.h
+++ b/Framework/Algorithms/test/Q1DWeightedTest.h
@@ -287,8 +287,13 @@ private:
     // located at N_pixel / 2 + 0.5
     // X = (16-192.0/2.0+0.5)*5.15/1000.0 = -0.409425
     // Y = (95-192.0/2.0+0.5)*5.15/1000.0 = -0.002575
-    mover.setPropertyValue("X", "0.409425");
+    // mover.setPropertyValue("X", "0.409425");
+    // mover.setPropertyValue("Y", "0.002575");
+
+    mover.setPropertyValue("X", "0.009425");
     mover.setPropertyValue("Y", "0.002575");
+    mover.setPropertyValue("Z", "-0.8114");
+
     mover.execute();
   }
 
diff --git a/Framework/Algorithms/test/Rebin2DTest.h b/Framework/Algorithms/test/Rebin2DTest.h
index b4bcddb1deaeafa3a74331a36bcb1e499f12ed68..0216510bf56597b97fafa14780c2751e121ec15d 100644
--- a/Framework/Algorithms/test/Rebin2DTest.h
+++ b/Framework/Algorithms/test/Rebin2DTest.h
@@ -64,7 +64,8 @@ MatrixWorkspace_sptr makeInputWS(const bool distribution,
 
 MatrixWorkspace_sptr runAlgorithm(MatrixWorkspace_sptr inputWS,
                                   const std::string &axis1Params,
-                                  const std::string &axis2Params) {
+                                  const std::string &axis2Params,
+                                  const bool UseFractionalArea = false) {
   // Name of the output workspace.
   std::string outWSName("Rebin2DTest_OutputWS");
 
@@ -75,6 +76,8 @@ MatrixWorkspace_sptr runAlgorithm(MatrixWorkspace_sptr inputWS,
   TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", outWSName));
   TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Axis1Binning", axis1Params));
   TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Axis2Binning", axis2Params));
+  TS_ASSERT_THROWS_NOTHING(
+      alg.setProperty("UseFractionalArea", UseFractionalArea));
   TS_ASSERT_THROWS_NOTHING(alg.execute(););
   TS_ASSERT(alg.isExecuted());
 
@@ -155,6 +158,32 @@ public:
     }
   }
 
+  void test_BothAxes_FractionalArea() {
+    MatrixWorkspace_sptr inputWS =
+        makeInputWS(false, false, false); // 10 histograms, 10 bins
+    MatrixWorkspace_sptr outputWS =
+        runAlgorithm(inputWS, "5.,1.8,15", "-0.5,2.5,9.5", true);
+    TS_ASSERT_EQUALS(outputWS->id(), "RebinnedOutput");
+    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 4);
+    TS_ASSERT_EQUALS(outputWS->blocksize(), 6);
+
+    const double epsilon(1e-08);
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      const auto &y = outputWS->y(i);
+      const auto &e = outputWS->e(i);
+      const size_t numBins = y.size();
+      for (size_t j = 0; j < numBins; ++j) {
+        TS_ASSERT_DELTA(y[j], 2, epsilon);
+        if (j < 5) {
+          TS_ASSERT_DELTA(e[j], 2. / 3., epsilon);
+        } else {
+          // Last bin
+          TS_ASSERT_DELTA(e[j], sqrt(0.8), epsilon);
+        }
+      }
+    }
+  }
+
 private:
   void checkData(MatrixWorkspace_const_sptr outputWS, const size_t nxvalues,
                  const size_t nhist, const bool dist, const bool onAxis1,
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h b/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
index 0bbc3a825b77bef0bd7a9140cf7e139077d10186..9671292cdfa4aa391f423b2c887623254c83dcb6 100644
--- a/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
+++ b/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
@@ -12,6 +12,7 @@
 #include "MantidAlgorithms/ReflectometryReductionOneAuto2.h"
 
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -1346,7 +1347,7 @@ public:
   void test_flood_correction() {
     auto inputWS =
         create2DWorkspaceWithReflectometryInstrumentMultiDetector(0, 0.1);
-    auto flood = createFloodWorkspace();
+    auto flood = createFloodWorkspace(inputWS->getInstrument());
 
     // Correct by rotating detectors around the sample
     ReflectometryReductionOneAuto2 alg;
@@ -1377,7 +1378,7 @@ public:
       auto &y = transWS->mutableY(i);
       y.assign(y.size(), 10.0 * double(i + 1));
     }
-    auto flood = createFloodWorkspace();
+    auto flood = createFloodWorkspace(inputWS->getInstrument());
 
     ReflectometryReductionOneAuto2 alg;
     alg.initialize();
@@ -1409,7 +1410,7 @@ public:
     group->addWorkspace(inputWS1);
     group->addWorkspace(inputWS2);
     AnalysisDataService::Instance().addOrReplace("input", group);
-    auto flood = createFloodWorkspace();
+    auto flood = createFloodWorkspace(inputWS1->getInstrument());
 
     // Correct by rotating detectors around the sample
     ReflectometryReductionOneAuto2 alg;
@@ -1438,11 +1439,13 @@ public:
   }
 
   void test_flood_correction_polarization_correction() {
-
     std::string const name = "input";
     prepareInputGroup(name, "Fredrikze");
     applyPolarizationEfficiencies(name);
-    auto flood = createFloodWorkspace(257);
+    auto const inputWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name +
+                                                                    "_1");
+    auto flood = createFloodWorkspace(inputWS->getInstrument(), 257);
 
     ReflectometryReductionOneAuto2 alg;
     alg.initialize();
@@ -1470,6 +1473,7 @@ public:
     TS_ASSERT_DELTA(out3->y(0)[0], 70.0, 0.003);
     auto out4 = boost::dynamic_pointer_cast<MatrixWorkspace>(out->getItem(3));
     TS_ASSERT_DELTA(out4->y(0)[0], 60.0, 0.003);
+
     AnalysisDataService::Instance().clear();
   }
 
@@ -1477,7 +1481,10 @@ public:
 
     std::string const name = "input";
     prepareInputGroup(name, "Flood");
-    auto flood = createFloodWorkspace(257);
+    auto const inputWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name +
+                                                                    "_1");
+    auto flood = createFloodWorkspace(inputWS->getInstrument(), 257);
 
     ReflectometryReductionOneAuto2 alg;
     alg.initialize();
@@ -1511,7 +1518,6 @@ public:
 
     std::string const name = "input";
     prepareInputGroup(name, "No_Flood");
-    auto flood = createFloodWorkspace(257);
 
     ReflectometryReductionOneAuto2 alg;
     alg.initialize();
@@ -1534,7 +1540,10 @@ public:
   }
 
 private:
-  MatrixWorkspace_sptr createFloodWorkspace(size_t n = 4) {
+  MatrixWorkspace_sptr
+  createFloodWorkspace(Mantid::Geometry::Instrument_const_sptr instrument,
+                       size_t n = 4) {
+    size_t detid = 1;
     auto flood = create2DWorkspace(int(n), 1);
     if (n == 4) {
       flood->mutableY(0)[0] = 0.7;
@@ -1545,7 +1554,13 @@ private:
       for (size_t i = 0; i < n; ++i) {
         flood->mutableY(i)[0] = double(i) * 0.01;
       }
+      detid = 1000;
+    }
+    flood->setInstrument(instrument);
+    for (size_t i = 0; i < flood->getNumberHistograms(); ++i) {
+      flood->getSpectrum(i).setDetectorID(Mantid::detid_t(i + detid));
     }
+    flood->getAxis(0)->setUnit("TOF");
     return flood;
   }
 };
diff --git a/Framework/Algorithms/test/TimeAtSampleStrategyDirectTest.h b/Framework/Algorithms/test/TimeAtSampleStrategyDirectTest.h
index d997c8ce86fa7453bf48671048560d6ed0e2a5ae..471e9d4d9f7d4270f06b33ee788d46ba30a353ef 100644
--- a/Framework/Algorithms/test/TimeAtSampleStrategyDirectTest.h
+++ b/Framework/Algorithms/test/TimeAtSampleStrategyDirectTest.h
@@ -57,7 +57,7 @@ public:
     double expectedShift = L1 / std::sqrt(ei * 2. * PhysicalConstants::meV /
                                           PhysicalConstants::NeutronMass);
 
-    TSM_ASSERT_EQUALS("L1 / (L1 + L2)", expectedShift, shift);
+    TSM_ASSERT_DELTA("L1 / (L1 + L2)", expectedShift, shift, 0.0000001);
   }
 };
 
diff --git a/Framework/Algorithms/test/TimeAtSampleStrategyIndirectTest.h b/Framework/Algorithms/test/TimeAtSampleStrategyIndirectTest.h
index 4430eb35a1fd7b2a2d5e70c31456ebb5e40e5cfc..f6e5b2b972b628b58f1f7ff3ac17a744e5c9fed2 100644
--- a/Framework/Algorithms/test/TimeAtSampleStrategyIndirectTest.h
+++ b/Framework/Algorithms/test/TimeAtSampleStrategyIndirectTest.h
@@ -8,6 +8,8 @@
 #define MANTID_ALGORITHMS_TIMEATSAMPLESTRATEGYINDIRECTTEST_H_
 
 #include "MantidAlgorithms/TimeAtSampleStrategyIndirect.h"
+#include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cxxtest/TestSuite.h>
 
@@ -28,9 +30,27 @@ public:
     auto ws = WorkspaceCreationHelper::
         create2DWorkspaceWithReflectometryInstrument(); // workspace has
                                                         // monitors
+
+    const size_t monitorIndex = 1; // monitor workspace index.
+    const auto &instrument = ws->getInstrument();
+    auto sample = instrument->getSample();
+    auto source = instrument->getSource();
+
+    const auto &beamDir =
+        instrument->getReferenceFrame()->vecPointingAlongBeam();
+
+    auto monitor = ws->getDetector(monitorIndex);
+
+    const double L1 = source->getPos().distance(sample->getPos());
+
     TimeAtSampleStrategyIndirect strategy(ws);
-    TS_ASSERT_THROWS(strategy.calculate(1 /*monitor index*/),
-                     std::invalid_argument &);
+    const auto correction = strategy.calculate(monitorIndex);
+
+    TSM_ASSERT_EQUALS("L1/L1m",
+                      std::abs(L1 / beamDir.scalar_prod(source->getPos() -
+                                                        monitor->getPos())),
+                      correction.factor);
+    TS_ASSERT_EQUALS(0., correction.offset);
   }
 };
 
diff --git a/Framework/Algorithms/test/WeightedMeanTest.h b/Framework/Algorithms/test/WeightedMeanTest.h
index 1d16ee8685f6118212d285c982617e70d15c08ee..6da20eff43c4189e1c1f31bd4cd727831be96176 100644
--- a/Framework/Algorithms/test/WeightedMeanTest.h
+++ b/Framework/Algorithms/test/WeightedMeanTest.h
@@ -63,19 +63,19 @@ public:
         result = boost::dynamic_pointer_cast<MatrixWorkspace>(
             AnalysisDataService::Instance().retrieve("result")))
     // Check bin boundaries are the same
-    TS_ASSERT_EQUALS(in2->readX(0), result->readX(0))
+    TS_ASSERT_EQUALS(in2->x(0), result->x(0))
     // Pick a bin where both entries are non-zero
-    TS_ASSERT_DELTA(result->readY(0)[1176], 21983.40535, 0.00001)
-    TS_ASSERT_DELTA(result->readE(0)[1176], 104.841321, 0.000001)
+    TS_ASSERT_DELTA(result->y(0)[1176], 21983.40535, 0.00001)
+    TS_ASSERT_DELTA(result->e(0)[1176], 104.841321, 0.000001)
     // Now one where first is zero
-    TS_ASSERT_EQUALS(result->readY(0)[2], 2.0)
-    TS_ASSERT_EQUALS(result->readE(0)[2], M_SQRT2)
+    TS_ASSERT_EQUALS(result->y(0)[2], 2.0)
+    TS_ASSERT_EQUALS(result->e(0)[2], M_SQRT2)
     // And one where second is zero
-    TS_ASSERT_EQUALS(result->readY(0)[113], 97.0)
-    TS_ASSERT_EQUALS(result->readE(0)[113], std::sqrt(97.0))
+    TS_ASSERT_EQUALS(result->y(0)[113], 97.0)
+    TS_ASSERT_EQUALS(result->e(0)[113], std::sqrt(97.0))
     // Finally one where both are zero
-    TS_ASSERT_EQUALS(result->readY(0)[4989], 0.0)
-    TS_ASSERT_EQUALS(result->readE(0)[4989], 0.0)
+    TS_ASSERT_EQUALS(result->y(0)[4989], 0.0)
+    TS_ASSERT_EQUALS(result->e(0)[4989], 0.0)
 
     AnalysisDataService::Instance().remove("first");
     AnalysisDataService::Instance().remove("second");
diff --git a/Framework/Catalog/CMakeLists.txt b/Framework/Catalog/CMakeLists.txt
index 5c868b025d761f4ae0cc83f06af6d4e3c0b4989e..3eee38799cfa141ec7fc64fac16ecab716da2c39 100644
--- a/Framework/Catalog/CMakeLists.txt
+++ b/Framework/Catalog/CMakeLists.txt
@@ -41,7 +41,7 @@ set_target_properties ( Catalog PROPERTIES OUTPUT_NAME MantidCatalog
 )
 
 if (OSX_VERSION VERSION_GREATER 10.8)
-  set_target_properties(Catalog PROPERTIES INSTALL_RPATH "@loader_path/../Contents/MacOS")
+  set_target_properties(Catalog PROPERTIES INSTALL_RPATH "@loader_path/../MacOS")
 elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
   set_target_properties(Catalog PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}")
 endif ()
@@ -60,4 +60,4 @@ add_subdirectory ( test )
 # Installation settings
 ###########################################################################
 
-install ( TARGETS Catalog ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PLUGINS_DIR} )
+install ( TARGETS Catalog ${SYSTEM_PACKAGE_TARGET} DESTINATION ${LIB_DIR} )
diff --git a/Framework/Crystal/CMakeLists.txt b/Framework/Crystal/CMakeLists.txt
index 5d22c05bcba5270d7eeb3d18781b1a238c2cdcb9..29285d0473cd843c661dcad4d2adb6f367a46289 100644
--- a/Framework/Crystal/CMakeLists.txt
+++ b/Framework/Crystal/CMakeLists.txt
@@ -58,6 +58,7 @@ set ( SRC_FILES
 	src/SaveLauenorm.cpp
 	src/SelectCellOfType.cpp
 	src/SelectCellWithForm.cpp
+	src/SetCrystalLocation.cpp
 	src/SetGoniometer.cpp
 	src/SetSpecialCoordinates.cpp
 	src/SetUB.cpp
@@ -132,6 +133,7 @@ set ( INC_FILES
 	inc/MantidCrystal/SaveLauenorm.h
 	inc/MantidCrystal/SelectCellOfType.h
 	inc/MantidCrystal/SelectCellWithForm.h
+	inc/MantidCrystal/SetCrystalLocation.h
 	inc/MantidCrystal/SetGoniometer.h
 	inc/MantidCrystal/SetSpecialCoordinates.h
 	inc/MantidCrystal/SetUB.h
@@ -199,6 +201,7 @@ set ( TEST_FILES
 	SaveLauenormTest.h
 	SelectCellOfTypeTest.h
 	SelectCellWithFormTest.h
+    SetCrystalLocationTest.h
 	SetGoniometerTest.h
 	SetSpecialCoordinatesTest.h
 	SetUBTest.h
diff --git a/Framework/Crystal/inc/MantidCrystal/SetCrystalLocation.h b/Framework/Crystal/inc/MantidCrystal/SetCrystalLocation.h
new file mode 100644
index 0000000000000000000000000000000000000000..4eb14a9af3877b98b603812d486431af32dd93fc
--- /dev/null
+++ b/Framework/Crystal/inc/MantidCrystal/SetCrystalLocation.h
@@ -0,0 +1,57 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+/*
+ * SetCrystalLocation.h
+ *
+ *  Created on: Dec 12, 2018
+ *      Author: Brendan Sullivan
+ */
+
+#ifndef SETCRYSTALLOCATION_H_
+#define SETCRYSTALLOCATION_H_
+
+#include "MantidAPI/Algorithm.h"
+#include "MantidKernel/System.h"
+
+namespace Mantid {
+namespace Crystal {
+
+/** SetCrystalLocation
+
+Description:
+This algorithm provides a convenient interface to sets the
+sample position of an events workspace.
+@author Brendan Sullivan, SNS,ORNL
+@date Dec 20 2018
+*/
+class DLLExport SetCrystalLocation : public API::Algorithm {
+public:
+  const std::string name() const override { return "SetCrystalLocation"; };
+  /// Summary of algorithms purpose
+  const std::string summary() const override {
+    return "This algorithm sets the sample location of the "
+           "input event workspace.";
+  }
+  const std::vector<std::string> seeAlso() const override {
+    return {"OptimizeCrystalPlacement"};
+  }
+
+  int version() const override { return 1; };
+
+  const std::string category() const override {
+    return "Crystal\\Corrections";
+  };
+
+private:
+  void init() override;
+
+  void exec() override;
+};
+} // namespace Crystal
+} // namespace Mantid
+
+#endif /* SETCRYSTALLOCATION_H_ */
diff --git a/Framework/Crystal/src/IndexSXPeaks.cpp b/Framework/Crystal/src/IndexSXPeaks.cpp
index cdd087c0740b17e098122fc2d81088a9d5e549eb..da346697dce9fdeed5d431ad14420fd7dfbfee2d 100644
--- a/Framework/Crystal/src/IndexSXPeaks.cpp
+++ b/Framework/Crystal/src/IndexSXPeaks.cpp
@@ -41,28 +41,31 @@ void IndexSXPeaks::init() {
       "Input Peaks Workspace");
 
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "a", -1.0, mustBePositive, Direction::Input),
+                      "a", -1.0, mustBePositive->clone(), Direction::Input),
                   "Lattice parameter a");
 
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "b", -1.0, mustBePositive, Direction::Input),
+                      "b", -1.0, mustBePositive->clone(), Direction::Input),
                   "Lattice parameter b");
 
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "c", -1.0, mustBePositive, Direction::Input),
+                      "c", -1.0, std::move(mustBePositive), Direction::Input),
                   "Lattice parameter c");
 
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "alpha", -1.0, reasonable_angle, Direction::Input),
-                  "Lattice parameter alpha");
+  declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "alpha", -1.0, reasonable_angle->clone(), Direction::Input),
+      "Lattice parameter alpha");
 
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "beta", -1.0, reasonable_angle, Direction::Input),
-                  "Lattice parameter beta");
+  declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "beta", -1.0, reasonable_angle->clone(), Direction::Input),
+      "Lattice parameter beta");
 
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "gamma", -1.0, reasonable_angle, Direction::Input),
-                  "Lattice parameter gamma");
+  declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "gamma", -1.0, std::move(reasonable_angle), Direction::Input),
+      "Lattice parameter gamma");
 
   declareProperty(make_unique<ArrayProperty<int>>("PeakIndices"),
                   "Index of the peaks in the table workspace to be used. If no "
@@ -79,11 +82,11 @@ void IndexSXPeaks::init() {
   extents[3] = range;
   extents[4] = -range;
   extents[5] = range;
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<int>>("SearchExtents", extents),
-      "A comma separated list of min, max for each of H, K and L,\n"
-      "Specifies the search extents applied for H K L values "
-      "associated with the peaks.");
+  declareProperty(Kernel::make_unique<ArrayProperty<int>>("SearchExtents",
+                                                          std::move(extents)),
+                  "A comma separated list of min, max for each of H, K and L,\n"
+                  "Specifies the search extents applied for H K L values "
+                  "associated with the peaks.");
 }
 
 /**
diff --git a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
index b5f8e8e5c3f3ad2d14c54e26370d8db146d718c4..257a0f8129e8008bd1ec51ca64da3e15582f888d 100644
--- a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
+++ b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
@@ -118,10 +118,10 @@ void OptimizeCrystalPlacement::init() {
   declareProperty("MaxAngularChange", 5.0,
                   "Max offset in degrees from current settings(def=5)");
 
-  declareProperty("MaxIndexingError", .25,
+  declareProperty("MaxIndexingError", 0.15,
                   "Use only peaks whose fractional "
                   "hkl values are below this "
-                  "tolerance(def=.25)");
+                  "tolerance(def=0.15)");
 
   declareProperty("MaxHKLPeaks2Use", -1.0,
                   "If less than 0 all peaks are used, "
@@ -449,8 +449,9 @@ void OptimizeCrystalPlacement::exec() {
   UBinv.Invert();
   UBinv /= (2 * M_PI);
   for (int i = 0; i < outPeaks->getNumberPeaks(); ++i) {
-
-    int RunNum = outPeaks->getPeak(i).getRunNumber();
+    auto peak = outPeaks->getPeak(i);
+    peak.setSamplePos(peak.getSamplePos() + newSampPos);
+    int RunNum = peak.getRunNumber();
     std::string RunNumStr = std::to_string(RunNum);
     Matrix<double> GonMatrix;
     if (RunNum == prevRunNum ||
@@ -472,12 +473,12 @@ void OptimizeCrystalPlacement::exec() {
       GonMatrix = GonTilt * uniGonio.getR();
       MapRunNum2GonMat[RunNum] = GonMatrix;
     } else {
-      GonMatrix = GonTilt * outPeaks->getPeak(i).getGoniometerMatrix();
+      GonMatrix = GonTilt * peak.getGoniometerMatrix();
       MapRunNum2GonMat[RunNum] = GonMatrix;
     }
 
-    outPeaks->getPeak(i).setGoniometerMatrix(GonMatrix);
-    V3D hkl = UBinv * outPeaks->getPeak(i).getQSampleFrame();
+    peak.setGoniometerMatrix(GonMatrix);
+    V3D hkl = UBinv * peak.getQSampleFrame();
     if (Geometry::IndexingUtils::ValidIndex(hkl, HKLintOffsetMax))
       nIndexed++;
 
diff --git a/Framework/Crystal/src/PeakHKLErrors.cpp b/Framework/Crystal/src/PeakHKLErrors.cpp
index 059fd6191aeaf743624341ffcede102cbe88ce0c..3edfe24e37f5f5fc0a06130cca41282b3975c7ae 100644
--- a/Framework/Crystal/src/PeakHKLErrors.cpp
+++ b/Framework/Crystal/src/PeakHKLErrors.cpp
@@ -208,7 +208,7 @@ PeakHKLErrors::getNewInstrument(PeaksWorkspace_sptr Peaks) const {
   } else // catch(... )
   {
     auto P1 = boost::make_shared<Geometry::Instrument>(
-        instSave->baseInstrument(), pmap);
+        instSave->baseInstrument(), instSave->makeLegacyParameterMap());
     instChange = P1;
   }
 
@@ -394,6 +394,10 @@ void PeakHKLErrors::function1D(double *out, const double *xValues,
     } else {
       peak.setGoniometerMatrix(GonRot * peak.getGoniometerMatrix());
     }
+    V3D sampOffsets(getParameter("SampleXOffset"),
+                    getParameter("SampleYOffset"),
+                    getParameter("SampleZOffset"));
+    peak.setSamplePos(peak.getSamplePos() + sampOffsets);
 
     V3D hkl = UBinv * peak.getQSampleFrame();
 
@@ -513,6 +517,10 @@ void PeakHKLErrors::functionDeriv1D(Jacobian *out, const double *xValues,
       chiParamNum = phiParamNum = omegaParamNum = nParams() + 10;
       peak.setGoniometerMatrix(GonRot * peak.getGoniometerMatrix());
     }
+    V3D sampOffsets(getParameter("SampleXOffset"),
+                    getParameter("SampleYOffset"),
+                    getParameter("SampleZOffset"));
+    peak.setSamplePos(peak.getSamplePos() + sampOffsets);
     // NOTE:Use getQLabFrame except for below.
     // For parameters the getGoniometerMatrix should remove GonRot, for derivs
     // wrt GonRot*, wrt chi*,phi*,etc.
diff --git a/Framework/Crystal/src/PeaksInRegion.cpp b/Framework/Crystal/src/PeaksInRegion.cpp
index ec40a6a5820e68c7ab9292cf66112c5362bc69e1..3e20d5c899fbde05b34b51739d23d4daa4e0c248 100644
--- a/Framework/Crystal/src/PeaksInRegion.cpp
+++ b/Framework/Crystal/src/PeaksInRegion.cpp
@@ -48,8 +48,8 @@ void PeaksInRegion::init() {
   extents[0] = -50;
   extents[1] = +50;
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Extents", extents,
-                                                 mandatoryExtents),
+      Kernel::make_unique<ArrayProperty<double>>("Extents", std::move(extents),
+                                                 std::move(mandatoryExtents)),
       "A comma separated list of min, max for each dimension,\n"
       "specifying the extents of each dimension. Optional, default +-50 in "
       "each dimension.");
diff --git a/Framework/Crystal/src/PeaksOnSurface.cpp b/Framework/Crystal/src/PeaksOnSurface.cpp
index cd7d78f1e614885d9231274ce431cf4b33562d3e..769b96e5a140b89558a05057c242097cb4afa80e 100644
--- a/Framework/Crystal/src/PeaksOnSurface.cpp
+++ b/Framework/Crystal/src/PeaksOnSurface.cpp
@@ -43,31 +43,33 @@ void PeaksOnSurface::init() {
   auto manditoryExtents = boost::make_shared<
       Mantid::Kernel::MandatoryValidator<std::vector<double>>>();
 
-  std::vector<double> vertexDefault;
-
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
-                      "Vertex1", vertexDefault, manditoryExtents->clone()),
-                  "A comma separated list of cartesian coordinates for the "
-                  "lower left vertex of the surface. Values to be specified in "
-                  "the CoordinateFrame choosen.");
-
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
-                      "Vertex2", vertexDefault, manditoryExtents->clone()),
-                  "A comma separated list of cartesian coordinates for the "
-                  "upper left vertex of the surface. Values to be specified in "
-                  "the CoordinateFrame choosen.");
-
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
-                      "Vertex3", vertexDefault, manditoryExtents->clone()),
-                  "A comma separated list of cartesian coordinates for the "
-                  "upper right vertex of the surface. Values to be specified "
-                  "in the CoordinateFrame choosen.");
-
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
-                      "Vertex4", vertexDefault, manditoryExtents->clone()),
-                  "A comma separated list of cartesian coordinates for the "
-                  "lower right vertex of the surface. Values to be specified "
-                  "in the CoordinateFrame choosen.");
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>(
+          "Vertex1", std::vector<double>(), manditoryExtents->clone()),
+      "A comma separated list of cartesian coordinates for the "
+      "lower left vertex of the surface. Values to be specified in "
+      "the CoordinateFrame choosen.");
+
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>(
+          "Vertex2", std::vector<double>(), manditoryExtents->clone()),
+      "A comma separated list of cartesian coordinates for the "
+      "upper left vertex of the surface. Values to be specified in "
+      "the CoordinateFrame choosen.");
+
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>(
+          "Vertex3", std::vector<double>(), manditoryExtents->clone()),
+      "A comma separated list of cartesian coordinates for the "
+      "upper right vertex of the surface. Values to be specified "
+      "in the CoordinateFrame choosen.");
+
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>(
+          "Vertex4", std::vector<double>(), std::move(manditoryExtents)),
+      "A comma separated list of cartesian coordinates for the "
+      "lower right vertex of the surface. Values to be specified "
+      "in the CoordinateFrame choosen.");
 }
 
 void PeaksOnSurface::validateExtentsInput() const {
diff --git a/Framework/Crystal/src/SetCrystalLocation.cpp b/Framework/Crystal/src/SetCrystalLocation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86568da261d89f048a44c31d9cf0e326feb065fb
--- /dev/null
+++ b/Framework/Crystal/src/SetCrystalLocation.cpp
@@ -0,0 +1,80 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+/*
+ *
+ * SetCrystalLocation.cpp
+ *
+ *  Created on: Dec 12, 2018
+ *      Author: Brendan Sullivan
+ */
+#include "MantidCrystal/SetCrystalLocation.h"
+
+#include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/Run.h"
+#include "MantidAPI/Sample.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidCrystal/CalibrationHelpers.h"
+#include "MantidCrystal/PeakHKLErrors.h"
+#include "MantidCrystal/SCDCalibratePanels.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidGeometry/Crystal/IPeak.h"
+#include "MantidGeometry/Crystal/IndexingUtils.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/EnabledWhenProperty.h"
+
+#include <cstdarg>
+
+using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Kernel;
+using Mantid::Geometry::IndexingUtils;
+using Mantid::Geometry::Instrument_const_sptr;
+using namespace Mantid::Geometry;
+
+namespace Mantid {
+
+namespace Crystal {
+
+DECLARE_ALGORITHM(SetCrystalLocation)
+
+void SetCrystalLocation::init() {
+  declareProperty(make_unique<WorkspaceProperty<EventWorkspace>>(
+                      "InputWorkspace", "", Direction::Input),
+                  "Original event workspace");
+  declareProperty(make_unique<WorkspaceProperty<EventWorkspace>>(
+                      "OutputWorkspace", "", Direction::Output),
+                  "Output event workspace with a modified sample position");
+  declareProperty("NewX", 0.0, "New Absolute X position of crystal.");
+  declareProperty("NewY", 0.0, "New Absolute Y position of crystal.");
+  declareProperty("NewZ", 0.0, "New Absolute Z position of crystal.");
+}
+
+// simple algorithm that changes the sample position of the input
+// event workspace.
+void SetCrystalLocation::exec() {
+  EventWorkspace_sptr events = getProperty("InputWorkspace");
+  EventWorkspace_sptr outEvents = getProperty("OutputWorkspace");
+  const double newX = getProperty("NewX");
+  const double newY = getProperty("NewY");
+  const double newZ = getProperty("NewZ");
+  V3D newSamplePos = V3D(newX, newY, newZ);
+  if (events != outEvents) {
+    outEvents = events->clone();
+  }
+
+  auto &componentInfo = outEvents->mutableComponentInfo();
+  CalibrationHelpers::adjustUpSampleAndSourcePositions(
+      componentInfo.l1(), newSamplePos, componentInfo);
+
+  setProperty("OutputWorkspace", outEvents);
+} // exec
+
+} // namespace Crystal
+
+} // namespace Mantid
diff --git a/Framework/Crystal/src/SetUB.cpp b/Framework/Crystal/src/SetUB.cpp
index 0c91e298eeae8de05b546a0e31d992c38748145d..eca4e8ced021b775bdde4afb7bdc1ba42ec1cb32 100644
--- a/Framework/Crystal/src/SetUB.cpp
+++ b/Framework/Crystal/src/SetUB.cpp
@@ -49,33 +49,40 @@ void SetUB::init() {
   this->declareProperty(make_unique<WorkspaceProperty<Workspace>>(
                             "Workspace", "", Direction::InOut),
                         "An input workspace.");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "a", 1.0, mustBePositive, Direction::Input),
-                        "Lattice parameter a");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "b", 1.0, mustBePositive, Direction::Input),
-                        "Lattice parameter b");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "c", 1.0, mustBePositive, Direction::Input),
-                        "Lattice parameter c");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "alpha", 90.0, reasonableAngle, Direction::Input),
-                        "Lattice parameter alpha (degrees)");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "beta", 90.0, reasonableAngle, Direction::Input),
-                        "Lattice parameter beta (degrees)");
-  this->declareProperty(make_unique<PropertyWithValue<double>>(
-                            "gamma", 90.0, reasonableAngle, Direction::Input),
-                        "Lattice parameter gamma(degrees) ");
   this->declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("u", u0, mustBe3D),
-      "Vector along k_i, when goniometer is at 0");
+      make_unique<PropertyWithValue<double>>("a", 1.0, mustBePositive->clone(),
+                                             Direction::Input),
+      "Lattice parameter a");
   this->declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("v", v0, mustBe3D),
-      "In plane vector perpendicular to k_i, when goniometer is at 0");
+      make_unique<PropertyWithValue<double>>("b", 1.0, mustBePositive->clone(),
+                                             Direction::Input),
+      "Lattice parameter b");
+  this->declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "c", 1.0, std::move(mustBePositive), Direction::Input),
+      "Lattice parameter c");
+  this->declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "alpha", 90.0, reasonableAngle->clone(), Direction::Input),
+      "Lattice parameter alpha (degrees)");
   this->declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("UB", zeroes, threeVthree),
-      "UB Matrix");
+      make_unique<PropertyWithValue<double>>(
+          "beta", 90.0, reasonableAngle->clone(), Direction::Input),
+      "Lattice parameter beta (degrees)");
+  this->declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "gamma", 90.0, std::move(reasonableAngle), Direction::Input),
+      "Lattice parameter gamma(degrees) ");
+  this->declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                            "u", std::move(u0), mustBe3D->clone()),
+                        "Vector along k_i, when goniometer is at 0");
+  this->declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("v", std::move(v0),
+                                                 std::move(mustBe3D)),
+      "In plane vector perpendicular to k_i, when goniometer is at 0");
+  this->declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                            "UB", std::move(zeroes), threeVthree),
+                        "UB Matrix");
   this->declareProperty(make_unique<PropertyWithValue<int>>(
                             "MDSampleNumber", EMPTY_INT(), Direction::Input),
                         "For an MD workspace, the sample number to wich to "
diff --git a/Framework/Crystal/src/TransformHKL.cpp b/Framework/Crystal/src/TransformHKL.cpp
index 2c910fd309e239a153fda26ca302e9b78d3c2ef4..20ecdabbe916d5fc711e859d920abc1bee32d782 100644
--- a/Framework/Crystal/src/TransformHKL.cpp
+++ b/Framework/Crystal/src/TransformHKL.cpp
@@ -41,8 +41,8 @@ void TransformHKL::init() {
   mustBePositive->setLower(0.0);
 
   this->declareProperty(
-      make_unique<PropertyWithValue<double>>("Tolerance", 0.15, mustBePositive,
-                                             Direction::Input),
+      make_unique<PropertyWithValue<double>>(
+          "Tolerance", 0.15, std::move(mustBePositive), Direction::Input),
       "Indexing Tolerance (0.15)");
 
   std::vector<double> identity_matrix(9, 0.0);
@@ -53,8 +53,8 @@ void TransformHKL::init() {
   auto threeBythree = boost::make_shared<ArrayLengthValidator<double> >(9);
   // clang-format on
   this->declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("HKLTransform",
-                                                 identity_matrix, threeBythree),
+      Kernel::make_unique<ArrayProperty<double>>(
+          "HKLTransform", std::move(identity_matrix), std::move(threeBythree)),
       "Specify 3x3 HKL transform matrix as a comma separated list of 9 "
       "numbers");
 
diff --git a/Framework/Crystal/test/LoadIsawPeaksTest.h b/Framework/Crystal/test/LoadIsawPeaksTest.h
index 6d771ddd96898a73188482ccb8aea73116499867..63841ee630d5458da174c42a039c5ff2b044b0c7 100644
--- a/Framework/Crystal/test/LoadIsawPeaksTest.h
+++ b/Framework/Crystal/test/LoadIsawPeaksTest.h
@@ -139,6 +139,47 @@ public:
     TS_ASSERT_EQUALS(G.getAxis(1).name, "chi");
     TS_ASSERT_EQUALS(G.getAxis(0).name, "omega");
   }
+
+  /* Test for the calibrated geometry */
+  void test_exec_calibrated() {
+    LoadIsawPeaks alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+    alg.setPropertyValue("Filename", "calibrated.peaks");
+    alg.setPropertyValue("OutputWorkspace", "calibrated");
+
+    TS_ASSERT(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    PeaksWorkspace_sptr ws;
+    TS_ASSERT_THROWS_NOTHING(
+        ws = boost::dynamic_pointer_cast<PeaksWorkspace>(
+            AnalysisDataService::Instance().retrieve("calibrated")));
+    TS_ASSERT(ws);
+    if (!ws)
+      return;
+    TS_ASSERT_EQUALS(ws->getNumberPeaks(), 14);
+
+    Peak p = ws->getPeaks()[0];
+    TS_ASSERT_EQUALS(p.getRunNumber(), 71907)
+    TS_ASSERT_DELTA(p.getH(), 0, 1e-4);
+    TS_ASSERT_DELTA(p.getK(), 0, 1e-4);
+    TS_ASSERT_DELTA(p.getL(), 0, 1e-4);
+    TS_ASSERT_EQUALS(p.getBankName(), "bank22");
+    TS_ASSERT_DELTA(p.getCol(), 5, 1e-4);
+    TS_ASSERT_DELTA(p.getRow(), 154, 1e-4);
+    TS_ASSERT_DELTA(p.getIntensity(), 0, 0.01);
+    TS_ASSERT_DELTA(p.getSigmaIntensity(), 0, 0.01);
+    TS_ASSERT_DELTA(p.getBinCount(), 8, 53);
+    TS_ASSERT_DELTA(p.getWavelength(), 0.893676, 0.001);
+    TS_ASSERT_DELTA(p.getL1(), 20.0, 1e-3);
+    TS_ASSERT_DELTA(p.getL2(), 2.51, 1e-3);
+    TS_ASSERT_DELTA(p.getTOF(), 5085.05, 0.1); // channel number is about TOF
+
+    TS_ASSERT_DELTA(p.getDSpacing(), 2.0360, 0.001);
+    TS_ASSERT_DELTA(ws->getPeaks()[1].getDSpacing(), 2.3261, 0.001);
+    TS_ASSERT_DELTA(ws->getPeaks()[2].getDSpacing(), 2.3329, 0.001);
+  }
 };
 
 #endif /* MANTID_CRYSTAL_LOADPEAKSFILETEST_H_ */
diff --git a/Framework/Crystal/test/OptimizeCrystalPlacementTest.h b/Framework/Crystal/test/OptimizeCrystalPlacementTest.h
index 4a17be0b0bad8265a7b8b5f0c349136a8b2982d7..f76e3532a14fc36e05b612f956ab3416224ed03c 100644
--- a/Framework/Crystal/test/OptimizeCrystalPlacementTest.h
+++ b/Framework/Crystal/test/OptimizeCrystalPlacementTest.h
@@ -187,9 +187,10 @@ public:
 
   void test_SamplePosition() {
     auto modPeaksNoFix = calculateBasicPlacement();
-    const auto &peak = modPeaksNoFix->getPeak(0);
+    auto peak = modPeaksNoFix->getPeak(0);
     auto inst = peak.getInstrument();
     const V3D sampPos(.0003, -.00025, .00015);
+    peak.setSamplePos(sampPos);
 
     auto pmap = inst->getParameterMap();
     auto sample = inst->getSample();
@@ -208,9 +209,9 @@ public:
         modPeaksNoFix, {{"KeepGoniometerFixedfor", "5637, 5638"},
                         {"AdjustSampleOffsets", "1"}});
     const auto table = resultsSamplePos.second;
-    TS_ASSERT_DELTA(table->Double(0, 1), 0, .0004);
-    TS_ASSERT_DELTA(table->Double(1, 1), 0, .00024);
-    TS_ASSERT_DELTA(table->Double(2, 1), 0, .0003);
+    TS_ASSERT_DELTA(table->Double(0, 1), 0, 0.0000773);
+    TS_ASSERT_DELTA(table->Double(1, 1), 0, 0.00004575);
+    TS_ASSERT_DELTA(table->Double(2, 1), 0, 0.00006745);
   }
 
 private:
diff --git a/Framework/Crystal/test/SCDCalibratePanelsTest.h b/Framework/Crystal/test/SCDCalibratePanelsTest.h
index 92e273852585beceef3a4017f997ee1c78ff2595..f1b53e34d72d53391a738125dc7a256cf3c9c6fb 100644
--- a/Framework/Crystal/test/SCDCalibratePanelsTest.h
+++ b/Framework/Crystal/test/SCDCalibratePanelsTest.h
@@ -64,7 +64,7 @@ public:
     TS_ASSERT_DELTA(0.0, results->cell<double>(3, 1), 1.2);
     TS_ASSERT_DELTA(0.0, results->cell<double>(4, 1), 1.1);
     TS_ASSERT_DELTA(0.1133, results->cell<double>(5, 1), 0.36);
-    TS_ASSERT_DELTA(1.0024, results->cell<double>(6, 1), 5e-3);
+    TS_ASSERT_DELTA(0.9953, results->cell<double>(6, 1), 1e-2);
     TS_ASSERT_DELTA(0.9986, results->cell<double>(7, 1), 1e-2);
     TS_ASSERT_DELTA(0.2710, results->cell<double>(9, 1), 0.2);
     ITableWorkspace_sptr resultsL1 =
diff --git a/Framework/Crystal/test/SetCrystalLocationTest.h b/Framework/Crystal/test/SetCrystalLocationTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..109be075372f7c53ba5b8bf19c090d9e81b60306
--- /dev/null
+++ b/Framework/Crystal/test/SetCrystalLocationTest.h
@@ -0,0 +1,112 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef SETCRYSTALLOCATIONTEST_H_
+#define SETCRYSTALLOCATIONTEST_H_
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidCrystal/LoadIsawUB.h"
+#include "MantidCrystal/SetCrystalLocation.h"
+#include "MantidCrystal/ShowPeakHKLOffsets.h"
+#include "MantidDataHandling/Load.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include <cxxtest/TestSuite.h>
+
+using Mantid::DataHandling::Load;
+using namespace Mantid::DataObjects;
+using Mantid::Crystal::LoadIsawUB;
+using Mantid::Crystal::SetCrystalLocation;
+using Mantid::Crystal::ShowPeakHKLOffsets;
+using Mantid::DataObjects::TableWorkspace;
+using Mantid::Kernel::V3D;
+using namespace Mantid::API;
+
+class SetCrystalLocationTest : public CxxTest::TestSuite {
+public:
+  void test_algo() {
+    std::string WSName = "events";
+    std::string file_name = "BSS_11841_event.nxs";
+    Load loader;
+    TS_ASSERT_THROWS_NOTHING(loader.initialize());
+    TS_ASSERT(loader.isInitialized());
+    loader.setPropertyValue("OutputWorkspace", WSName);
+    loader.setPropertyValue("Filename", file_name);
+    TS_ASSERT(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+
+    auto workspace = AnalysisDataService::Instance().retrieve(WSName);
+    EventWorkspace_sptr events =
+        boost::dynamic_pointer_cast<EventWorkspace>(workspace);
+    TS_ASSERT(events);
+    auto inst = events->getInstrument();
+    TS_ASSERT(inst);
+    auto sample = inst->getSample();
+    TS_ASSERT(sample);
+
+    SetCrystalLocation algo;
+    TS_ASSERT_THROWS_NOTHING(algo.initialize());
+    TS_ASSERT(algo.isInitialized());
+    algo.setProperty("InputWorkspace", WSName);
+    algo.setProperty("OutputWorkspace", WSName);
+    algo.setProperty("NewX", 1.0);
+    algo.setProperty("NewY", -0.30);
+    algo.setProperty("NewZ", 10.0);
+
+    // Check the sample is at the origin by default
+    V3D sampPos0 = sample->getPos();
+    TS_ASSERT_DELTA(sampPos0.X(), 0.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos0.Y(), 0.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos0.Z(), 0.0, 1.e-3);
+
+    // Move the sample to (1.0, -0.3, 10.0)
+    TS_ASSERT(algo.execute());
+    TS_ASSERT(algo.isExecuted());
+
+    // Check that the sample moved
+    V3D sampPos1 = sample->getPos();
+    TS_ASSERT_DELTA(sampPos1.X(), 1.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos1.Y(), -0.30, 1.e-3);
+    TS_ASSERT_DELTA(sampPos1.Z(), 10.0, 1.e-3);
+
+    // Try it on a separate workspace
+    SetCrystalLocation algo2;
+    TS_ASSERT_THROWS_NOTHING(algo2.initialize());
+    TS_ASSERT(algo2.isInitialized());
+    algo2.setProperty("InputWorkspace", WSName);
+    algo2.setProperty("OutputWorkspace", "events_new");
+    algo2.setProperty("NewX", 2.0);
+    algo2.setProperty("NewY", 4.0);
+    algo2.setProperty("NewZ", 0.0);
+    TS_ASSERT(algo2.execute());
+    TS_ASSERT(algo2.isExecuted());
+
+    // Check that the original is unchanged.  "Events" should be at
+    // the same sampPos1 = (1.0, -0.3, 10.0)
+    V3D sampPos2 = sample->getPos();
+    TS_ASSERT_DELTA(sampPos2.X(), 1.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos2.Y(), -0.30, 1.e-3);
+    TS_ASSERT_DELTA(sampPos2.Z(), 10.0, 1.e-3);
+
+    // Get pointers to the new workspace
+    auto workspace_new = AnalysisDataService::Instance().retrieve("events_new");
+    EventWorkspace_sptr events_new =
+        boost::dynamic_pointer_cast<EventWorkspace>(workspace_new);
+    TS_ASSERT(events_new)
+    auto inst_new = events_new->getInstrument();
+    TS_ASSERT(inst_new);
+    auto sample_new = inst_new->getSample();
+    TS_ASSERT(sample_new);
+
+    // the new workspace should be at (2.,4.,0.,)
+    V3D sampPos3 = sample_new->getPos();
+    TS_ASSERT_DELTA(sampPos3.X(), 2.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos3.Y(), 4.0, 1.e-3);
+    TS_ASSERT_DELTA(sampPos3.Z(), 0.0, 1.e-3);
+  }
+};
+
+#endif /* SETCRYSTALLOCATIONTEST_H_ */
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMinimizer.h
index 0eb61f9101610dbfdbc940e2814ceed65a745b94..693118aacc9d76f6dcd31846a975767770fab373 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMinimizer.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/LevenbergMarquardtMinimizer.h
@@ -47,7 +47,7 @@ private:
   int hasConverged();
 
   /// GSL data container
-  GSL_FitData *m_data;
+  std::unique_ptr<GSL_FitData> m_data;
 
   /// GSL minimizer container
   gsl_multifit_function_fdf gslContainer;
diff --git a/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMinimizer.cpp
index c70d8e809d71eff8f2ef3fcea483cd43c3c053e7..8685dc4ce45ddf8d489c38e8700515c574f0e008 100644
--- a/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMinimizer.cpp
+++ b/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMinimizer.cpp
@@ -60,7 +60,7 @@ void LevenbergMarquardtMinimizer::initialize(
       boost::dynamic_pointer_cast<CostFunctions::CostFuncLeastSquares>(
           costFunction);
   if (leastSquares) {
-    m_data = new GSL_FitData(leastSquares);
+    m_data = std::make_unique<GSL_FitData>(leastSquares);
   } else {
     throw std::runtime_error("LevenbergMarquardt can only be used with Least "
                              "squares cost function.");
@@ -73,9 +73,10 @@ void LevenbergMarquardtMinimizer::initialize(
   gslContainer.f = &gsl_f;
   gslContainer.df = &gsl_df;
   gslContainer.fdf = &gsl_fdf;
+
   gslContainer.n = m_data->n;
   gslContainer.p = m_data->p;
-  gslContainer.params = m_data;
+  gslContainer.params = m_data.get();
 
   // setup GSL solver
   m_gslSolver = gsl_multifit_fdfsolver_alloc(T, m_data->n, m_data->p);
@@ -92,9 +93,6 @@ void LevenbergMarquardtMinimizer::initialize(
 }
 
 LevenbergMarquardtMinimizer::~LevenbergMarquardtMinimizer() {
-  if (m_data) {
-    delete m_data;
-  }
   if (m_gslSolver) {
     gsl_multifit_fdfsolver_free(m_gslSolver);
   }
diff --git a/Framework/DataHandling/CMakeLists.txt b/Framework/DataHandling/CMakeLists.txt
index 3482694e01f61bd9f5e999c17576ceb7151c330d..a6cdcea3329d4be683578b3447602372de23ae1f 100644
--- a/Framework/DataHandling/CMakeLists.txt
+++ b/Framework/DataHandling/CMakeLists.txt
@@ -65,7 +65,7 @@
 	src/LoadILLIndirect2.cpp
 	src/LoadILLPolarizationFactors.cpp
 	src/LoadILLReflectometry.cpp
-	src/LoadILLSANS.cpp
+    	src/LoadILLSANS.cpp
 	src/LoadILLTOF2.cpp
 	src/LoadISISNexus2.cpp
 	src/LoadISISPolarizationEfficiencies.cpp
@@ -108,6 +108,7 @@
 	src/LoadRawHelper.cpp
 	src/LoadRawSpectrum0.cpp
 	src/LoadSampleShape.cpp
+	src/LoadSampleEnvironment.cpp
 	src/LoadSESANS.cpp
 	src/LoadSINQFocus.cpp
 	src/LoadSNSspec.cpp
@@ -141,7 +142,6 @@
 	src/RenameLog.cpp
 	src/RotateInstrumentComponent.cpp
 	src/RotateSource.cpp
-	src/SNSDataArchive.cpp
 	src/SaveANSTOAscii.cpp
 	src/SaveAscii.cpp
 	src/SaveAscii2.cpp
@@ -164,7 +164,7 @@
 	src/SaveILLCosmosAscii.cpp
 	src/SaveISISNexus.cpp
 	src/SaveIsawDetCal.cpp
-	src/SaveMask.cpp
+  src/SaveMask.cpp
 	src/SaveNISTDAT.cpp
 	src/SaveNXSPE.cpp
 	src/SaveNXTomo.cpp
@@ -177,7 +177,7 @@
 	src/SavePHX.cpp
 	src/SaveParameterFile.cpp
 	src/SaveRKH.cpp
-	src/SaveReflectometryAscii.cpp
+  src/SaveReflectometryAscii.cpp
 	src/SaveReflCustomAscii.cpp
 	src/SaveReflThreeColumnAscii.cpp
 	src/SaveSESANS.cpp
@@ -301,6 +301,7 @@ set ( INC_FILES
 	inc/MantidDataHandling/LoadRawHelper.h
 	inc/MantidDataHandling/LoadRawSpectrum0.h
 	inc/MantidDataHandling/LoadSampleShape.h
+	inc/MantidDataHandling/LoadSampleEnvironment.h
 	inc/MantidDataHandling/LoadSESANS.h
 	inc/MantidDataHandling/LoadSINQFocus.h
 	inc/MantidDataHandling/LoadSNSspec.h
@@ -335,7 +336,6 @@ set ( INC_FILES
 	inc/MantidDataHandling/RenameLog.h
 	inc/MantidDataHandling/RotateInstrumentComponent.h
 	inc/MantidDataHandling/RotateSource.h
-	inc/MantidDataHandling/SNSDataArchive.h
 	inc/MantidDataHandling/SaveANSTOAscii.h
 	inc/MantidDataHandling/SaveAscii.h
 	inc/MantidDataHandling/SaveAscii2.h
@@ -371,7 +371,7 @@ set ( INC_FILES
 	inc/MantidDataHandling/SavePHX.h
 	inc/MantidDataHandling/SaveParameterFile.h
 	inc/MantidDataHandling/SaveRKH.h
-	inc/MantidDataHandling/SaveReflectometryAscii.h
+  inc/MantidDataHandling/SaveReflectometryAscii.h
 	inc/MantidDataHandling/SaveReflCustomAscii.h
 	inc/MantidDataHandling/SaveReflThreeColumnAscii.h
 	inc/MantidDataHandling/SaveSESANS.h
@@ -486,7 +486,9 @@ set ( TEST_FILES
 	LoadRawBin0Test.h
 	LoadRawSaveNxsLoadNxsTest.h
 	LoadRawSpectrum0Test.h
+	LoadStlTest.h
 	LoadSampleShapeTest.h
+	LoadSampleEnvironmentTest.h
 	LoadSESANSTest.h
 	LoadSINQFocusTest.h
 	LoadSNSspecTest.h
@@ -518,7 +520,6 @@ set ( TEST_FILES
 	RenameLogTest.h
 	RotateInstrumentComponentTest.h
 	RotateSourceTest.h
-	SNSDataArchiveTest.h
 	SaveANSTOAsciiTest.h
 	SaveAscii2Test.h
 	SaveAsciiTest.h
@@ -552,7 +553,7 @@ set ( TEST_FILES
 	SavePHXTest.h
 	SaveParameterFileTest.h
 	SaveRKHTest.h
-	SaveReflectometryAsciiTest.h
+  SaveReflectometryAsciiTest.h
 	SaveReflCustomAsciiTest.h
 	SaveReflThreeColumnAsciiTest.h
 	SaveSESANSTest.h
diff --git a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
index c37df542799ba051db2b1d5a2e9954c1a6df4892..3cf2c9c3e29552becbc0b28ebe09364aa02fb911 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
@@ -35,7 +35,8 @@ public:
   /// Algorithm's version
   int version() const override { return (1); }
   const std::vector<std::string> seeAlso() const override {
-    return {"AbsorptionCorrection", "SetSampleMaterial", "CopySample"};
+    return {"SetSample", "AbsorptionCorrection", "SetSampleMaterial",
+            "CopySample"};
   }
   /// Algorithm's category for identification
   const std::string category() const override { return "Sample;"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOEventFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOEventFile.h
index 549a68d77d87e2501fed72631df30b1f1a8c82b6..006e80d7f7502ebd4579a180165e7fb0e85e8e10 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOEventFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOEventFile.h
@@ -91,11 +91,11 @@ void ReadEventFile(IReader &loader, IEventHandler &handler, IProgress &progress,
                    int32_t def_clock_scale, bool use_tx_chopper) {
   // read file headers (base header then packed-format header)
   EventFileHeader_Base hdr_base;
-  if (!loader.read(reinterpret_cast<int8_t *>(&hdr_base), sizeof(hdr_base)))
+  if (!loader.read(reinterpret_cast<char *>(&hdr_base), sizeof(hdr_base)))
     throw std::runtime_error("unable to load EventFileHeader-Base");
 
   EventFileHeader_Packed hdr_packed;
-  if (!loader.read(reinterpret_cast<int8_t *>(&hdr_packed), sizeof(hdr_packed)))
+  if (!loader.read(reinterpret_cast<char *>(&hdr_packed), sizeof(hdr_packed)))
     throw std::runtime_error("unable to load EventFileHeader-Packed");
 
   if (hdr_base.magic_number != EVENTFILEHEADER_BASE_MAGIC_NUMBER)
@@ -185,7 +185,7 @@ void ReadEventFile(IReader &loader, IEventHandler &handler, IProgress &progress,
 
     // read next byte
     uint8_t ch;
-    if (!loader.read(reinterpret_cast<int8_t *>(&ch), 1))
+    if (!loader.read(reinterpret_cast<char *>(&ch), 1))
       break;
 
     int32_t nbits_ch_used = 0; // no bits used initially, 8 to go
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAsciiStl.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAsciiStl.h
index 9559fe2e6f7a74f7b71c77f9d2bc35b2869e1a3e..efe155be8575641942f7c85380f9405542fe8ffe 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadAsciiStl.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAsciiStl.h
@@ -1,17 +1,31 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef MANTID_DATAHANDLING_LOADASCIISTL_H_
 #define MANTID_DATAHANDLING_LOADASCIISTL_H_
 #include "MantidDataHandling/LoadStl.h"
-#include "MantidGeometry/Objects/MeshObject.h"
-#include "MantidKernel/V3D.h"
-#include <fstream>
+#include <iosfwd>
 namespace Mantid {
+
+namespace Kernel {
+class V3D;
+}
+
+namespace Geometry {
+class MeshObject;
+}
 namespace DataHandling {
 
 class DLLExport LoadAsciiStl : LoadStl {
 public:
   LoadAsciiStl(std::string filename) : LoadStl(filename) {}
+  LoadAsciiStl(std::string filename, ReadMaterial::MaterialParameters params)
+      : LoadStl(filename, params) {}
   std::unique_ptr<Geometry::MeshObject> readStl() override;
-  bool isAsciiSTL();
+  static bool isAsciiSTL(std::string filename);
 
 private:
   int m_lineNumber = 0;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadBinaryStl.h b/Framework/DataHandling/inc/MantidDataHandling/LoadBinaryStl.h
index e141f4c63d9c925b06c935dfc5aad15e633824a7..61d61b1b25402027102bd980ce5f689d8dcfcac9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadBinaryStl.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadBinaryStl.h
@@ -1,10 +1,21 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef MANTID_DATAHANDLING_LOADBINARYSTL_H_
 #define MANTID_DATAHANDLING_LOADBINARYSTL_H_
 #include "MantidDataHandling/LoadStl.h"
-#include "MantidGeometry/Objects/MeshObject.h"
-#include "MantidKernel/BinaryStreamReader.h"
 
 namespace Mantid {
+namespace Kernel {
+class BinaryStreamReader;
+}
+
+namespace Geometry {
+class MeshObject;
+}
 namespace DataHandling {
 
 class DLLExport LoadBinaryStl : LoadStl {
@@ -14,12 +25,13 @@ public:
   static constexpr uint32_t TRIANGLE_COUNT_DATA_SIZE = 4;
   static constexpr uint32_t VECTOR_DATA_SIZE = 12;
   LoadBinaryStl(std::string filename) : LoadStl(filename) {}
+  LoadBinaryStl(std::string filename, ReadMaterial::MaterialParameters params)
+      : LoadStl(filename, params) {}
   std::unique_ptr<Geometry::MeshObject> readStl() override;
-  bool isBinarySTL();
+  static bool isBinarySTL(std::string filename);
 
 private:
-  uint32_t getNumberTriangles(Kernel::BinaryStreamReader);
-  void readTriangle(Kernel::BinaryStreamReader);
+  void readTriangle(Kernel::BinaryStreamReader, uint32_t &vertexCount);
 };
 
 } // namespace DataHandling
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEMU.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEMU.h
index 829ac8d3fd84ce7c27ee7d9bde58324982297b9f..d74c777d737a099e26a9fcbf17fb9e8de4dedb84 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadEMU.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEMU.h
@@ -20,24 +20,6 @@ using ANSTO::EventVector_pt;
 
 /*
 Loads an ANSTO EMU event file and stores it in an event workspace.
-LoadEMU is an algorithm and as such inherits  from the Algorithm class,
-via DataHandlingCommand, and overrides the init() & exec() methods.
-
-Required Properties:
-<UL>
-<LI> Filename - Name of and path to the input event file</LI>
-<LI> OutputWorkspace - Name of the workspace which stores the data</LI>
-</UL>
-
-Optional Properties:
-<UL>
-<LI> Mask - The input filename of the mask data</LI>
-<LI> SelectDetectorTubes - Range of detector tubes to be loaded</LI>
-<LI> OverrideDopplerPhase - Override the Doppler phase (degrees)</LI>
-<LI> FilterByTimeStart - Only include events after the start time</LI>
-<LI> FilterByTimeStop - Only include events before the stop time</LI>
-<LI> LoadAsRawDopplerTime - Save event time relative the Doppler</LI>
-</UL>
 
 @author Geish Miladinovic (ANSTO)
 
@@ -63,42 +45,32 @@ File change history is stored at: <https://github.com/mantidproject/mantid>.
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 
-class DLLExport LoadEMU : public API::IFileLoader<Kernel::FileDescriptor> {
+template <typename FD> class LoadEMU : public API::IFileLoader<FD> {
 
-public:
-  // description
-  int version() const override { return 1; }
-  const std::vector<std::string> seeAlso() const override {
-    return {"Load", "LoadQKK"};
-  }
-  const std::string name() const override { return "LoadEMU"; }
-  const std::string category() const override { return "DataHandling\\ANSTO"; }
-  const std::string summary() const override {
-    return "Loads an EMU data file into a workspace.";
-  }
-
-  // returns a confidence value that this algorithm can load a specified file
-  int confidence(Kernel::FileDescriptor &descriptor) const override;
+protected:
+  using Base = API::IFileLoader<FD>;
 
-private:
-  // initialisation
-  void init() override;
+  // detailed init and exec code
+  void init(bool hdfLoader);
+  void exec(const std::string &hdfFile, const std::string &eventFile);
 
-  // execution
-  void exec() override;
-
-  // region of intreset
-  static std::vector<bool> createRoiVector(const std::string &seltubes,
-                                           const std::string &maskfile);
+private:
+  using Base::exec;
+  using Base::init;
+  // region of intereset
+  std::vector<bool> createRoiVector(const std::string &seltubes,
+                                    const std::string &maskfile);
 
+protected:
   // load parameters from input file
-  void loadParameters(ANSTO::Tar::File &tarFile, API::LogManager &logm);
+  void loadParameters(const std::string &hdfFile, API::LogManager &logm);
+  void loadEnvironParameters(const std::string &hdfFile, API::LogManager &logm);
 
   // load the instrument definition and instrument parameters
   void loadInstrument();
 
   // create workspace
-  void createWorkspace(ANSTO::Tar::File &tarFile);
+  void createWorkspace(const std::string &title);
 
   // dynamically update the neutronic position
   void loadDetectorL2Values();
@@ -107,28 +79,110 @@ private:
   // load and log the Doppler parameters
   void loadDopplerParameters(API::LogManager &logm);
 
+  // calibrate doppler phase
+  void calibrateDopplerPhase(const std::vector<size_t> &eventCounts,
+                             const std::vector<EventVector_pt> &eventVectors);
+  void dopplerTimeToTOF(std::vector<EventVector_pt> &eventVectors,
+                        double &minTOF, double &maxTOF);
+
   // prepare event storage
   void prepareEventStorage(ANSTO::ProgressTracker &prog,
-                           std::vector<size_t> &eventCounts,
+                           const std::vector<size_t> &eventCounts,
                            std::vector<EventVector_pt> &eventVectors);
 
   // set up the detector masks
   void setupDetectorMasks(std::vector<bool> &roi);
 
-  // binary file access
-  template <class EventProcessor>
-  static void loadEvents(API::Progress &prog, const char *progMsg,
-                         ANSTO::Tar::File &tarFile,
-                         EventProcessor &eventProcessor);
-
   // shared member variables
   DataObjects::EventWorkspace_sptr m_localWorkspace;
   std::vector<double> m_detectorL2;
+  int32_t m_datasetIndex;
+  std::string m_startRun;
 
   // Doppler characteristics
   double m_dopplerAmpl;
   double m_dopplerFreq;
   double m_dopplerPhase;
+  int32_t m_dopplerRun;
+  bool m_calibrateDoppler;
+};
+
+// Implemented the two classes explicitly rather than through specialization as
+// the instantiation and linking did not behave consistently across platforms.
+
+extern template class LoadEMU<Kernel::FileDescriptor>;
+extern template class LoadEMU<Kernel::NexusDescriptor>;
+
+/** LoadEMUTar : Loads a merged ANSTO EMU Hdf and event file into a workspace.
+
+Required Properties:
+<UL>
+<LI> Filename - Name of and path to the input event file</LI>
+<LI> OutputWorkspace - Name of the workspace which stores the data</LI>
+</UL>
+
+Optional Properties:
+<UL>
+<LI> Mask - The input filename of the mask data</LI>
+<LI> SelectDetectorTubes - Range of detector tubes to be loaded</LI>
+<LI> OverrideDopplerFrequency - Override the Doppler frequency (Hz)</LI>
+<LI> OverrideDopplerPhase - Override the Doppler phase (degrees)</LI>
+<LI> CalibrateDopplerPhase - Calibrate the Doppler phase prior to TOF</LI>
+<LI> LoadAsRawDopplerTime - Save event time relative the Doppler</LI>
+<LI> FilterByTimeStart - Only include events after the start time</LI>
+<LI> FilterByTimeStop - Only include events before the stop time</LI>
+</UL>
+
+*/
+class DLLExport LoadEMUTar : public LoadEMU<Kernel::FileDescriptor> {
+public:
+  int version() const override;
+  const std::vector<std::string> seeAlso() const override;
+  const std::string category() const override;
+  const std::string name() const override;
+  const std::string summary() const override;
+  int confidence(Kernel::FileDescriptor &descriptor) const override;
+
+private:
+  void exec() override;
+  void init() override;
+};
+
+/** LoadEMUHdf : Loads an ANSTO EMU Hdf and linked event file into a workspace.
+
+Required Properties:
+<UL>
+<LI> Filename - Name of and path to the input event file</LI>
+<LI> OutputWorkspace - Name of the workspace which stores the data</LI>
+</UL>
+
+Optional Properties:
+<UL>
+<LI> Mask - The input filename of the mask data</LI>
+<LI> SelectDetectorTubes - Range of detector tubes to be loaded</LI>
+<LI> OverrideDopplerFrequency - Override the Doppler frequency (Hz)</LI>
+<LI> OverrideDopplerPhase - Override the Doppler phase (degrees)</LI>
+<LI> CalibrateDopplerPhase - Calibrate the Doppler phase prior to TOF</LI>
+<LI> LoadAsRawDopplerTime - Save event time relative the Doppler</LI>
+<LI> FilterByTimeStart - Only include events after the start time</LI>
+<LI> FilterByTimeStop - Only include events before the stop time</LI>
+<LI> PathToBinaryEventFile - Rel or abs path to event file linked to hdf</LI>
+<LI> SelectDataset - Select the linked event dataset</LI>
+</UL>
+
+*/
+class DLLExport LoadEMUHdf : public LoadEMU<Kernel::NexusDescriptor> {
+public:
+  int version() const override;
+  const std::vector<std::string> seeAlso() const override;
+  const std::string category() const override;
+  const std::string name() const override;
+  const std::string summary() const override;
+  int confidence(Kernel::NexusDescriptor &descriptor) const override;
+
+private:
+  void exec() override;
+  void init() override;
 };
 
 } // namespace DataHandling
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleEnvironment.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleEnvironment.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca19c4d87309f43976180b9f60f5325fddbae6b5
--- /dev/null
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleEnvironment.h
@@ -0,0 +1,62 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef DATAHANDLING_LOAD_ENVIRONMENT_H_
+#define DATAHANDLING_LOAD_ENVIRONMENT_H_
+
+#include "MantidAPI/Algorithm.h"
+
+namespace Mantid {
+namespace Geometry {
+class MeshObject;
+}
+namespace DataHandling {
+/**  Load Environment into the sample of a workspace, either replacing the
+   current environment, or replacing it, you may also set the material
+
+     The following file types are supported
+
+       STL file with suffix .stl
+ */
+
+class DLLExport LoadSampleEnvironment : public Mantid::API::Algorithm {
+public:
+  /// Algorithm's name for identification overriding a virtual method
+  const std::string name() const override { return "LoadSampleEnvironment"; };
+  /// Summary of algorithms purpose
+  const std::string summary() const override {
+    return "The algorithm loads an Environment into the instrument of a "
+           "workspace "
+           "at the sample.";
+  }
+
+  /// Algorithm's version for identification overriding a virtual method
+  int version() const override { return 1; };
+  /// Related algorithms
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateSampleEnvironment", "CopySample", "SetSampleMaterial",
+            "LoadSampleShape"};
+  }
+  /// Algorithm's category for identification overriding a virtual method
+  const std::string category() const override {
+    return "DataHandling\\Instrument";
+  }
+  boost::shared_ptr<Geometry::MeshObject>
+  translate(boost::shared_ptr<Geometry::MeshObject> environmentMesh);
+  boost::shared_ptr<Geometry::MeshObject>
+  rotate(boost::shared_ptr<Geometry::MeshObject> environmentMesh);
+  std::map<std::string, std::string> validateInputs() override;
+
+private:
+  // Implement abstract Algorithm methods
+  void init() override;
+  void exec() override;
+};
+
+} // end namespace DataHandling
+} // namespace Mantid
+
+#endif /* DATAHANDLING_LOAD_ENVIRONMENT_H_ */
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleShape.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleShape.h
index f30ebe1176d5e4b724ce8f614dc61d7e77cc8484..225902df063bec8a329e275e84f5c614092026f2 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleShape.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleShape.h
@@ -36,7 +36,8 @@ public:
   int version() const override { return 1; };
   /// Related algorithms
   const std::vector<std::string> seeAlso() const override {
-    return {"CreateSampleShape", "CopySample", "SetSampleMaterial"};
+    return {"CreateSampleShape", "CopySample", "SetSampleMaterial",
+            "LoadSampleEnvironment"};
   }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
index b63eca9b51c0a16efc9e3db5eaa7d037c3de731a..b649529eb8ab43188e119a4f57d96a0f0a5f925b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
@@ -112,9 +112,8 @@ private:
   void addRunProperty(const std::string &name, const T &value,
                       const std::string &units = "");
   void setBeamTrapRunProperty(std::map<std::string, std::string> &metadata);
-  void moveDetector(double, double);
-  double detectorDistance(std::map<std::string, std::string> &metadata);
-  double detectorTranslation(std::map<std::string, std::string> &metadata);
+  void detectorDistance(std::map<std::string, std::string> &metadata);
+  void detectorTranslation(std::map<std::string, std::string> &metadata);
   void setMetadataAsRunProperties(std::map<std::string, std::string> &metadata);
   void rotateDetector(const double &);
   void setTimes();
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadStl.h b/Framework/DataHandling/inc/MantidDataHandling/LoadStl.h
index ee78eafd159ea53cce6432611fb80e1bd1ede4e1..13813bcbb8c34d8713a1f8a6963b059d9e4cbc23 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadStl.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadStl.h
@@ -1,24 +1,65 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef MANTID_DATAHANDLING_LOADSTL_H_
 #define MANTID_DATAHANDLING_LOADSTL_H_
-#include "MantidGeometry/Objects/MeshObject.h"
-#include <MantidKernel/V3D.h>
-
+#include "MantidDataHandling/ReadMaterial.h"
+#include "MantidKernel/Logger.h"
+#include "MantidKernel/V3D.h"
+#include <boost/functional/hash.hpp>
+#include <functional>
+#include <unordered_set>
+namespace {
+Mantid::Kernel::Logger g_logstl("LoadStl");
+}
 namespace Mantid {
+
+namespace Geometry {
+class MeshObject;
+}
 namespace DataHandling {
 
+struct HashV3DPair {
+  size_t operator()(const std::pair<Kernel::V3D, uint32_t> &v) const {
+    size_t seed = std::hash<double>{}(v.first.X());
+    boost::hash_combine(seed, v.first.Y());
+    boost::hash_combine(seed, v.first.Z());
+    return seed;
+  }
+};
+
+struct V3DTrueComparator {
+  bool operator()(const std::pair<Kernel::V3D, uint32_t> &v1,
+                  const std::pair<Kernel::V3D, uint32_t> &v2) const {
+    const Kernel::V3D diff = v1.first - v2.first;
+    const double nanoMetre = 1e-9;
+    return diff.norm() < nanoMetre;
+  }
+};
+
 class DLLExport LoadStl {
 public:
-  LoadStl(std::string filename) : m_filename(filename) {}
+  LoadStl(std::string filename) : m_filename(filename), m_setMaterial(false) {}
+  LoadStl(std::string filename, ReadMaterial::MaterialParameters params)
+      : m_filename(filename), m_setMaterial(true), m_params(params) {}
   virtual std::unique_ptr<Geometry::MeshObject> readStl() = 0;
 
 protected:
-  uint16_t addSTLVertex(Kernel::V3D &vertex);
-  bool areEqualVertices(Kernel::V3D const &v1, Kernel::V3D const &v2);
-  std::string m_filename;
-  std::vector<uint16_t> m_triangle;
+  bool areEqualVertices(Kernel::V3D const &v1, Kernel::V3D const &v2) const;
+  void changeToVector();
+  const std::string m_filename;
+  bool m_setMaterial;
+  ReadMaterial::MaterialParameters m_params;
+  std::vector<uint32_t> m_triangle;
   std::vector<Kernel::V3D> m_verticies;
+  std::unordered_set<std::pair<Kernel::V3D, uint32_t>, HashV3DPair,
+                     V3DTrueComparator>
+      vertexSet;
 };
 
 } // namespace DataHandling
 } // namespace Mantid
-#endif /* MANTID_DATAHANDLING_LOADSTL_H_ */
\ No newline at end of file
+#endif /* MANTID_DATAHANDLING_LOADSTL_H_ */
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h b/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h
deleted file mode 100644
index d31f5a113f1e2058b035b5c9ed659863e8ba12cf..0000000000000000000000000000000000000000
--- a/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchive.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#ifndef MANTID_DATAHANDLING_SNSDATAARCHIVE_H_
-#define MANTID_DATAHANDLING_SNSDATAARCHIVE_H_
-
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidAPI/IArchiveSearch.h"
-#include "MantidKernel/System.h"
-
-#include <string>
-
-namespace Mantid {
-namespace DataHandling {
-/**
- This class is for searching the SNS data archive
- @date 02/22/2012
- */
-
-class DLLExport SNSDataArchive : public API::IArchiveSearch {
-public:
-  /// Find the archive location of a set of files.
-  std::string
-  getArchivePath(const std::set<std::string> &filenames,
-                 const std::vector<std::string> &exts) const override;
-};
-} // namespace DataHandling
-} // namespace Mantid
-
-#endif /* MANTID_DATAHANDLING_SNSDATAARCHIVE_H_ */
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveReflectometryAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveReflectometryAscii.h
index a1eb06a653d65dba3fc990603fb4b2b6912d2d22..c5c8d71206f9f34cb0e2a69220455b124eee631e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveReflectometryAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveReflectometryAscii.h
@@ -60,10 +60,13 @@ private:
   bool writeString(bool write, std::string s);
   /// Print a string value to file
   void outputval(std::string val);
-  /// Retrieve sample log information
-  std::string sampleInfo(const std::string &logName);
+  /// Retrieve sample log value
+  std::string sampleLogValue(const std::string &logName);
+  /// Retrieve sample log unit
+  std::string sampleLogUnit(const std::string &logName);
   /// Write one header line
-  void writeInfo(const std::string logName, const std::string logValue = "");
+  void writeInfo(const std::string logName,
+                 const std::string logNameFixed = "");
   /// Write header
   void header();
   /// Determine the separator
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
index 2303dfda7c29f50625634ed61f55ff68117c353d..dfe9085670a3f70d350b9acec87b8077cc9d504b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
@@ -26,7 +26,7 @@ public:
   const std::string name() const override final;
   int version() const override final;
   const std::vector<std::string> seeAlso() const override {
-    return {"SetSampleMaterial", "CopySample", "SetBeam"};
+    return {"SetSampleMaterial", "CreateSampleShape", "CopySample", "SetBeam"};
   }
   const std::string category() const override final;
   const std::string summary() const override final;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h b/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h
index 1cc15c249f081ca52abee07f08a2024a144b8fb6..f9b7bdff274be9297edec06a1f649bfb6d291e2e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h
@@ -33,7 +33,7 @@ public:
   /// Algorithm's version
   int version() const override;
   const std::vector<std::string> seeAlso() const override {
-    return {"AbsorptionCorrection", "CreateSampleShape",
+    return {"SetSample", "AbsorptionCorrection", "CreateSampleShape",
             "CalculateSampleTransmission"};
   }
   /// Algorithm's category for identification
diff --git a/Framework/DataHandling/src/LoadAsciiStl.cpp b/Framework/DataHandling/src/LoadAsciiStl.cpp
index 9e3e22f3ccef2bbb5f4f9111813915750f94c078..5ccb388d749c457546003c1a7ba24ab5caa76b50 100644
--- a/Framework/DataHandling/src/LoadAsciiStl.cpp
+++ b/Framework/DataHandling/src/LoadAsciiStl.cpp
@@ -1,4 +1,11 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidDataHandling/LoadAsciiStl.h"
+#include "MantidGeometry/Objects/MeshObject.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/make_unique.h"
 #include <boost/algorithm/string.hpp>
@@ -8,8 +15,12 @@
 namespace Mantid {
 namespace DataHandling {
 
-bool LoadAsciiStl::isAsciiSTL() {
-  std::ifstream file(m_filename.c_str());
+bool LoadAsciiStl::isAsciiSTL(std::string filename) {
+  std::ifstream file(filename.c_str());
+  if (!file) {
+    // if the file cannot be read then it is not a valid asciiStl File
+    return false;
+  }
   std::string line;
   getline(file, line);
   boost::trim(line);
@@ -22,20 +33,43 @@ std::unique_ptr<Geometry::MeshObject> LoadAsciiStl::readStl() {
   getline(file, line);
   m_lineNumber++;
   Kernel::V3D t1, t2, t3;
+  uint32_t vertexCount = 0;
   while (readSTLTriangle(file, t1, t2, t3)) {
     // Add triangle if all 3 vertices are distinct
     if (!areEqualVertices(t1, t2) && !areEqualVertices(t1, t3) &&
         !areEqualVertices(t2, t3)) {
-      m_triangle.emplace_back(addSTLVertex(t1));
-      m_triangle.emplace_back(addSTLVertex(t2));
-      m_triangle.emplace_back(addSTLVertex(t3));
+      auto vertexPair = std::pair<Kernel::V3D, uint32_t>(t1, vertexCount);
+      auto emplacementResult = vertexSet.insert(vertexPair);
+      if (emplacementResult.second) {
+        vertexCount++;
+      }
+      m_triangle.emplace_back(emplacementResult.first->second);
+      vertexPair = std::pair<Kernel::V3D, uint32_t>(t2, vertexCount);
+      emplacementResult = vertexSet.insert(vertexPair);
+      if (emplacementResult.second) {
+        vertexCount++;
+      }
+      m_triangle.emplace_back(emplacementResult.first->second);
+      vertexPair = std::pair<Kernel::V3D, uint32_t>(t3, vertexCount);
+      emplacementResult = vertexSet.insert(vertexPair);
+      if (emplacementResult.second) {
+        vertexCount++;
+      }
+      m_triangle.emplace_back(emplacementResult.first->second);
     }
   }
-  // Use efficient constructor of MeshObject
-  std::unique_ptr<Geometry::MeshObject> retVal =
-      Kernel::make_unique<Geometry::MeshObject>(std::move(m_triangle),
-                                                std::move(m_verticies),
-                                                Mantid::Kernel::Material());
+  changeToVector();
+  Mantid::Kernel::Material material;
+  if (m_setMaterial) {
+    g_logstl.information("Setting Material");
+    ReadMaterial reader;
+    reader.setMaterialParameters(m_params);
+    material = *(reader.buildMaterial());
+  } else {
+    material = Mantid::Kernel::Material();
+  }
+  auto retVal = std::make_unique<Geometry::MeshObject>(
+      std::move(m_triangle), std::move(m_verticies), material);
   return retVal;
 }
 
diff --git a/Framework/DataHandling/src/LoadBinaryStl.cpp b/Framework/DataHandling/src/LoadBinaryStl.cpp
index 36992f6f12b4764422d47b6a2a112510b385619c..4620d354d52ba3ad711e23c349c98975b12a3eab 100644
--- a/Framework/DataHandling/src/LoadBinaryStl.cpp
+++ b/Framework/DataHandling/src/LoadBinaryStl.cpp
@@ -1,12 +1,41 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidDataHandling/LoadBinaryStl.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidKernel/BinaryStreamReader.h"
+#include "MantidKernel/MultiThreaded.h"
 #include <Poco/File.h>
+#include <boost/functional/hash.hpp>
+#include <boost/make_shared.hpp>
+#include <chrono>
 #include <fstream>
-
+#include <string>
+#include <vector>
 namespace Mantid {
 namespace DataHandling {
 
-bool LoadBinaryStl::isBinarySTL() {
-  Poco::File stlFile = Poco::File(m_filename);
+namespace {
+uint32_t getNumberTriangles(Kernel::BinaryStreamReader streamReader,
+                            const int header) {
+  uint32_t numberTrianglesLong;
+  // skip header
+  streamReader.moveStreamToPosition(header);
+  // Read the number of triangles
+  streamReader >> numberTrianglesLong;
+  return numberTrianglesLong;
+}
+} // namespace
+
+bool LoadBinaryStl::isBinarySTL(std::string filename) {
+  Poco::File stlFile = Poco::File(filename);
+  if (!stlFile.exists()) {
+    // if the file cannot be read then it is not a valid binary Stl File
+    return false;
+  }
   auto fileSize = stlFile.getSize();
   if (fileSize < HEADER_SIZE + TRIANGLE_COUNT_DATA_SIZE) {
     // File is smaller than header plus number of triangles, cannot be binary
@@ -14,9 +43,9 @@ bool LoadBinaryStl::isBinarySTL() {
     return false;
   }
   uint32_t numberTrianglesLong;
-  std::ifstream myFile(m_filename.c_str(), std::ios::in | std::ios::binary);
+  std::ifstream myFile(filename.c_str(), std::ios::in | std::ios::binary);
   Kernel::BinaryStreamReader streamReader = Kernel::BinaryStreamReader(myFile);
-  numberTrianglesLong = getNumberTriangles(streamReader);
+  numberTrianglesLong = getNumberTriangles(streamReader, HEADER_SIZE);
   myFile.close();
   if (!(fileSize == (HEADER_SIZE + TRIANGLE_COUNT_DATA_SIZE +
                      (numberTrianglesLong * TRIANGLE_DATA_SIZE)))) {
@@ -28,40 +57,48 @@ bool LoadBinaryStl::isBinarySTL() {
   return true;
 }
 
-uint32_t
-LoadBinaryStl::getNumberTriangles(Kernel::BinaryStreamReader streamReader) {
-  uint32_t numberTrianglesLong;
-  // skip header
-  streamReader.moveStreamToPosition(HEADER_SIZE);
-  // Read the number of triangles
-  streamReader >> numberTrianglesLong;
-  return numberTrianglesLong;
-}
-
 std::unique_ptr<Geometry::MeshObject> LoadBinaryStl::readStl() {
   std::ifstream myFile(m_filename.c_str(), std::ios::in | std::ios::binary);
 
   Kernel::BinaryStreamReader streamReader = Kernel::BinaryStreamReader(myFile);
-  const auto numberTrianglesLong = getNumberTriangles(streamReader);
+  const auto numberTrianglesLong =
+      getNumberTriangles(streamReader, HEADER_SIZE);
   uint32_t nextToRead =
       HEADER_SIZE + TRIANGLE_COUNT_DATA_SIZE + VECTOR_DATA_SIZE;
   // now read in all the triangles
-
+  m_triangle.reserve(3 * numberTrianglesLong);
+  m_verticies.reserve(3 * numberTrianglesLong);
+  g_logstl.debug("Began reading " + std::to_string(numberTrianglesLong) +
+                 " triangles.");
+  uint32_t vertexCount = 0;
   for (uint32_t i = 0; i < numberTrianglesLong; i++) {
+
     // find next triangle, skipping the normal and attribute
     streamReader.moveStreamToPosition(nextToRead);
-    readTriangle(streamReader);
+    readTriangle(streamReader, vertexCount);
     nextToRead += TRIANGLE_DATA_SIZE;
   }
+  changeToVector();
+  m_verticies.shrink_to_fit();
+  m_triangle.shrink_to_fit();
+  g_logstl.debug("Read All");
   myFile.close();
-  std::unique_ptr<Geometry::MeshObject> retVal =
-      std::unique_ptr<Geometry::MeshObject>(new Geometry::MeshObject(
-          std::move(m_triangle), std::move(m_verticies),
-          Mantid::Kernel::Material()));
+  Mantid::Kernel::Material material;
+  if (m_setMaterial) {
+    g_logstl.information("Setting Material");
+    ReadMaterial reader;
+    reader.setMaterialParameters(m_params);
+    material = *(reader.buildMaterial());
+  } else {
+    material = Mantid::Kernel::Material();
+  }
+  auto retVal = std::make_unique<Geometry::MeshObject>(
+      std::move(m_triangle), std::move(m_verticies), material);
   return retVal;
 }
 
-void LoadBinaryStl::readTriangle(Kernel::BinaryStreamReader streamReader) {
+void LoadBinaryStl::readTriangle(Kernel::BinaryStreamReader streamReader,
+                                 uint32_t &vertexCount) {
   // read in the verticies
   for (int i = 0; i < 3; i++) {
     float xVal;
@@ -71,8 +108,14 @@ void LoadBinaryStl::readTriangle(Kernel::BinaryStreamReader streamReader) {
     streamReader >> yVal;
     streamReader >> zVal;
     Kernel::V3D vec = Kernel::V3D(double(xVal), double(yVal), double(zVal));
-    // add index of new vertex to triangle
-    m_triangle.push_back(addSTLVertex(vec));
+    auto vertexPair = std::pair<Kernel::V3D, uint32_t>(vec, vertexCount);
+    auto emplacementResult = vertexSet.insert(vertexPair);
+    // check if the value was new to the map and increase the value to assign to
+    // the next if so
+    if (emplacementResult.second) {
+      vertexCount++;
+    }
+    m_triangle.emplace_back(emplacementResult.first->second);
   }
 }
 
diff --git a/Framework/DataHandling/src/LoadDiffCal.cpp b/Framework/DataHandling/src/LoadDiffCal.cpp
index 9c3e3ed525154cad64e496a2fe03935f0871d082..a0a61cfd7d6326433b6e1ff299e123a114a81e6d 100644
--- a/Framework/DataHandling/src/LoadDiffCal.cpp
+++ b/Framework/DataHandling/src/LoadDiffCal.cpp
@@ -18,6 +18,7 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/Diffraction.h"
+#include "MantidKernel/Exception.h"
 #include "MantidKernel/OptionalBool.h"
 
 #include <H5Cpp.h>
@@ -36,6 +37,7 @@ using Mantid::DataObjects::GroupingWorkspace_sptr;
 using Mantid::DataObjects::MaskWorkspace_sptr;
 using Mantid::DataObjects::Workspace2D;
 using Mantid::Kernel::Direction;
+using Mantid::Kernel::Exception::FileError;
 using Mantid::Kernel::PropertyWithValue;
 
 using namespace H5;
@@ -397,8 +399,13 @@ void LoadDiffCal::exec() {
   }
 
   // read in everything from the file
-  H5File file(m_filename, H5F_ACC_RDONLY);
   H5::Exception::dontPrint();
+  H5File file;
+  try {
+    file = H5File(m_filename, H5F_ACC_RDONLY);
+  } catch (FileIException &) {
+    throw FileError("Failed to open file using HDF5", m_filename);
+  }
   getInstrument(file);
 
   Progress progress(this, 0.1, 0.4, 8);
@@ -412,7 +419,8 @@ void LoadDiffCal::exec() {
 #else
     e.printError(stderr);
 #endif
-    throw std::runtime_error("Did not find group \"/calibration\"");
+    file.close();
+    throw FileError("Did not find group \"/calibration\"", m_filename);
   }
 
   progress.report("Reading detid");
diff --git a/Framework/DataHandling/src/LoadEMU.cpp b/Framework/DataHandling/src/LoadEMU.cpp
index 3fe201297385a994454244fee3b9a6a3f9c3599f..6d25324d26c274818b130f09e18ebab925575a98 100644
--- a/Framework/DataHandling/src/LoadEMU.cpp
+++ b/Framework/DataHandling/src/LoadEMU.cpp
@@ -18,27 +18,30 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidNexus/NexusClasses.h"
 
+#include <boost/filesystem.hpp>
 #include <boost/math/special_functions/round.hpp>
+#include <boost/math/tools/minima.hpp>
 
 #include <Poco/AutoPtr.h>
 #include <Poco/TemporaryFile.h>
 #include <Poco/Util/PropertyFileConfiguration.h>
 
-#include <math.h>
+#include <algorithm>
+#include <cmath>
+#include <cstdio>
+#include <fstream>
 
 namespace Mantid {
 namespace DataHandling {
 
-using namespace Kernel;
-
 namespace {
 
 // number of physical detectors
 constexpr size_t HORIZONTAL_TUBES = 16;
 constexpr size_t VERTICAL_TUBES = 35;
-constexpr size_t DETECTORS = HORIZONTAL_TUBES + VERTICAL_TUBES;
+constexpr size_t DETECTOR_TUBES = HORIZONTAL_TUBES + VERTICAL_TUBES;
 // analysed and direct detectors
-constexpr size_t HISTO_BINS_X = DETECTORS * 2;
+constexpr size_t HISTO_BINS_X = DETECTOR_TUBES * 2;
 constexpr size_t HISTO_BINS_Y = 1024;
 constexpr size_t HISTO_BINS_Y_DENUMERATOR = 16;
 constexpr size_t PIXELS_PER_TUBE = HISTO_BINS_Y / HISTO_BINS_Y_DENUMERATOR;
@@ -55,24 +58,41 @@ constexpr size_t Progress_Total =
 constexpr char FilenameStr[] = "Filename";
 constexpr char MaskStr[] = "Mask";
 constexpr char SelectDetectorTubesStr[] = "SelectDetectorTubes";
+constexpr char SelectDatasetStr[] = "SelectDataset";
+constexpr char OverrideDopplerFreqStr[] = "OverrideDopplerFrequency";
 constexpr char OverrideDopplerPhaseStr[] = "OverrideDopplerPhase";
 constexpr char FilterByTimeStartStr[] = "FilterByTimeStart";
 constexpr char FilterByTimeStopStr[] = "FilterByTimeStop";
 constexpr char RawDopplerTimeStr[] = "LoadAsRawDopplerTime";
+constexpr char CalibrateDopplerPhaseStr[] = "CalibrateDopplerPhase";
+constexpr char PathToBinaryStr[] = "BinaryEventPath";
 
 // Common pairing of limits
 using TimeLimits = std::pair<double, double>;
 
+template <typename Type>
+void AddSinglePointTimeSeriesProperty(API::LogManager &logManager,
+                                      const std::string &time,
+                                      const std::string &name,
+                                      const Type value) {
+  // create time series property and add single value
+  auto p = new Kernel::TimeSeriesProperty<Type>(name);
+  p->addValue(time, value);
+
+  // add to log manager
+  logManager.addProperty(p);
+}
+
 // Utility functions for loading values with defaults
 // Single value properties only support int, double, string and bool
 template <typename Type>
 Type GetNeXusValue(NeXus::NXEntry &entry, const std::string &path,
-                   const Type &defval) {
+                   const Type &defval, int32_t index) {
   try {
     NeXus::NXDataSetTyped<Type> dataSet = entry.openNXDataSet<Type>(path);
     dataSet.load();
 
-    return *dataSet();
+    return dataSet()[index];
   } catch (std::runtime_error &) {
     return defval;
   }
@@ -80,12 +100,12 @@ Type GetNeXusValue(NeXus::NXEntry &entry, const std::string &path,
 // string and double are special cases
 template <>
 double GetNeXusValue<double>(NeXus::NXEntry &entry, const std::string &path,
-                             const double &defval) {
+                             const double &defval, int32_t index) {
   try {
     NeXus::NXDataSetTyped<float> dataSet = entry.openNXDataSet<float>(path);
     dataSet.load();
 
-    return *dataSet();
+    return dataSet()[index];
   } catch (std::runtime_error &) {
     return defval;
   }
@@ -93,7 +113,7 @@ double GetNeXusValue<double>(NeXus::NXEntry &entry, const std::string &path,
 template <>
 std::string GetNeXusValue<std::string>(NeXus::NXEntry &entry,
                                        const std::string &path,
-                                       const std::string &defval) {
+                                       const std::string &defval, int32_t) {
 
   try {
     NeXus::NXChar dataSet = entry.openNXChar(path);
@@ -108,22 +128,36 @@ std::string GetNeXusValue<std::string>(NeXus::NXEntry &entry,
 template <typename T>
 void MapNeXusToProperty(NeXus::NXEntry &entry, const std::string &path,
                         const T &defval, API::LogManager &logManager,
-                        const std::string &name, const T &factor) {
+                        const std::string &name, const T &factor,
+                        int32_t index) {
 
-  T value = GetNeXusValue<T>(entry, path, defval);
+  T value = GetNeXusValue<T>(entry, path, defval, index);
   logManager.addProperty<T>(name, value * factor);
 }
 
 // sting is a special case
 template <>
-void MapNeXusToProperty<std::string>(
-    NeXus::NXEntry &entry, const std::string &path, const std::string &defval,
-    API::LogManager &logManager, const std::string &name, const std::string &) {
-
-  std::string value = GetNeXusValue<std::string>(entry, path, defval);
+void MapNeXusToProperty<std::string>(NeXus::NXEntry &entry,
+                                     const std::string &path,
+                                     const std::string &defval,
+                                     API::LogManager &logManager,
+                                     const std::string &name,
+                                     const std::string &, int32_t index) {
+
+  std::string value = GetNeXusValue<std::string>(entry, path, defval, index);
   logManager.addProperty<std::string>(name, value);
 }
 
+template <typename T>
+void MapNeXusToSeries(NeXus::NXEntry &entry, const std::string &path,
+                      const T &defval, API::LogManager &logManager,
+                      const std::string &time, const std::string &name,
+                      const T &factor, int32_t index) {
+
+  T value = GetNeXusValue<T>(entry, path, defval, index);
+  AddSinglePointTimeSeriesProperty<T>(logManager, time, name, value * factor);
+}
+
 // map the comma separated range of indexes to the vector via a lambda function
 // throws an exception if it is outside the vector range
 //
@@ -189,13 +223,15 @@ double invert(double y, const F &f, double x0 = 0.0, const double eps = 1e-16) {
 // the detectors is not constant so it needs to store the distance for each
 // Note that observation time and TOF are in usec
 //
+using TofData = std::tuple<double, double>;
+
 class ConvertTOF {
   const double m_w;
   const double m_phi;
   const double m_L0;
   const double m_v2;
   const double m_A;
-  std::vector<double> m_L2;
+  const std::vector<double> &m_L2;
 
   inline double L1(double t) const { return m_L0 + m_A * sin(m_w * t + m_phi); }
 
@@ -209,7 +245,7 @@ public:
       : m_w(2 * M_PI * freq), m_phi(M_PI * phase / 180.0), m_L0(L1), m_v2(v2),
         m_A(Amp), m_L2(L2) {}
 
-  double directTOF(size_t detID, double tobs) const {
+  TofData directTOF(size_t detID, double tobs) const {
 
     // observation time and tof are in usec
     auto tn = [=](double t) { return t + (L1(t) + m_L2[detID]) / v1(t); };
@@ -217,12 +253,12 @@ public:
     double tsec = tobs * 1.0e-6;
     double t0 = tsec - (m_L0 + m_L2[detID]) / m_v2;
     double tinv = invert(tsec, tn, t0);
-    double tof = m_L0 / v1(tinv) + m_L2[detID] / m_v2;
+    double tof = (m_L0 + m_L2[detID]) / v1(tinv);
 
-    return tof * 1.0e6;
+    return TofData(tinv * 1.0e6, tof * 1.0e6);
   }
 
-  double analysedTOF(size_t detID, double tobs) const {
+  TofData analysedTOF(size_t detID, double tobs) const {
     // observation time and tof are in usec
     auto tn = [=](double t) { return t + L1(t) / v1(t) + m_L2[detID] / m_v2; };
 
@@ -231,8 +267,69 @@ public:
     double t = invert(tsec, tn, t0);
     double tof = m_L0 / v1(t) + m_L2[detID] / m_v2;
 
-    return tof * 1.0e6;
+    return TofData(t * 1.0e6, tof * 1.0e6);
+  }
+};
+
+// calculate mean of a subset of the vector
+double maskedMean(const std::vector<double> &vec,
+                  const std::vector<bool> &mask) {
+  if (vec.size() == 0 || vec.size() != mask.size())
+    throw std::runtime_error("masked mean of empty or mismatched vectors");
+  double sum = 0.0;
+  size_t count = 0;
+  for (size_t i = 0; i != vec.size(); i++) {
+    if (!mask[i])
+      continue;
+    sum += vec[i];
+    count++;
   }
+  if (count == 0)
+    throw std::runtime_error("mean of empty vector");
+  return sum / static_cast<double>(count);
+}
+
+// calculate stdev fro a subset of the vector
+double maskedStdev(const std::vector<double> &vec,
+                   const std::vector<bool> &mask) {
+
+  auto avg = maskedMean(vec, mask);
+  size_t count = 0;
+  double sum = 0.0;
+  for (size_t i = 0; i != vec.size(); i++) {
+    if (!mask[i])
+      continue;
+    sum += (vec[i] - avg) * (vec[i] - avg);
+    count++;
+  }
+  return std::sqrt(sum / static_cast<double>(count));
+}
+
+// Simple reader that is compatible with the ASNTO event file loader
+class FileLoader {
+  std::ifstream _ifs;
+  size_t _size;
+
+public:
+  explicit FileLoader(const char *filename)
+      : _ifs(filename, std::ios::binary | std::ios::in) {
+    if (!_ifs.is_open() || _ifs.fail())
+      throw std::runtime_error("unable to open file");
+
+    _ifs.seekg(0, _ifs.end);
+    _size = _ifs.tellg();
+    _ifs.seekg(0, _ifs.beg);
+  }
+
+  bool read(char *s, std::streamsize n) {
+    return static_cast<bool>(_ifs.read(s, n));
+  }
+
+  size_t size() { return _size; }
+
+  size_t position() { return _ifs.tellg(); }
+
+  size_t selected_position() { return _ifs.tellg(); }
 };
 
 } // anonymous namespace
@@ -298,6 +395,13 @@ public:
     // length test in seconds
     return m_framePeriod * static_cast<double>(m_frames) * 1.0e-6;
   }
+
+  inline int64_t frameStart() const {
+    // returns time in nanoseconds from start of test
+    auto start = m_framePeriod * static_cast<double>(m_frames);
+    return static_cast<int64_t>(start * 1.0e3);
+  }
+
   void addEvent(size_t x, size_t p, double tdop, double taux) {
 
     // check if in time boundaries
@@ -308,7 +412,7 @@ public:
     auto y = static_cast<size_t>(p / HISTO_BINS_Y_DENUMERATOR);
 
     // determine detector id and check limits
-    if (x >= DETECTORS || y >= m_stride)
+    if (x >= DETECTOR_TUBES || y >= m_stride)
       return;
 
     // map the raw detector index to the physical model
@@ -318,7 +422,7 @@ public:
     // longer background chopper rate
     double ptaux = fmod(taux, m_gatePeriod);
     if (ptaux >= m_directTaux.first && ptaux <= m_directTaux.second)
-      xid = xid + DETECTORS;
+      xid = xid + DETECTOR_TUBES;
     else if (!(ptaux >= m_analysedTaux.first && ptaux <= m_analysedTaux.second))
       return;
 
@@ -366,22 +470,34 @@ protected:
   const ConvertTOF &m_convertTOF;
   double m_tofMin;
   double m_tofMax;
+  int64_t m_startTime;
   bool m_saveAsTOF;
 
   void addEventImpl(size_t id, size_t x, size_t, double tobs) override {
 
-    // convert observation time to tof
+    // get the absolute time for the start of the frame
+    auto offset = m_startTime + frameStart();
+
+    // convert observation time to tof and set the pulse time
+    // relative to the start of the doppler cycle
     double tof = tobs;
-    if (m_saveAsTOF)
-      tof = x < DETECTORS ? m_convertTOF.analysedTOF(id, tobs)
-                          : m_convertTOF.directTOF(id, tobs);
+
+    if (m_saveAsTOF) {
+      double pulse;
+      if (x < DETECTOR_TUBES)
+        std::tie(pulse, tof) = m_convertTOF.analysedTOF(id, tobs);
+      else
+        std::tie(pulse, tof) = m_convertTOF.directTOF(id, tobs);
+      offset += static_cast<int64_t>(pulse * 1e3);
+    }
 
     if (m_tofMin > tof)
       m_tofMin = tof;
     if (m_tofMax < tof)
       m_tofMax = tof;
 
-    m_eventVectors[id]->push_back(tof);
+    auto ev = Types::Event::TofEvent(tof, Types::Core::DateAndTime(offset));
+    m_eventVectors[id]->push_back(ev);
   }
 
 public:
@@ -390,109 +506,114 @@ public:
                 const double framePeriod, const double gatePeriod,
                 const TimeLimits &timeBoundary, const TimeLimits &directLimits,
                 const TimeLimits &analysedLimits, ConvertTOF &convert,
-                std::vector<EventVector_pt> &eventVectors, bool saveAsTOF)
+                std::vector<EventVector_pt> &eventVectors, int64_t startTime,
+                bool saveAsTOF)
       : EventProcessor(roi, mapIndex, stride, framePeriod, gatePeriod,
                        timeBoundary, directLimits, analysedLimits),
         m_eventVectors(eventVectors), m_convertTOF(convert),
         m_tofMin(std::numeric_limits<double>::max()),
-        m_tofMax(std::numeric_limits<double>::min()), m_saveAsTOF(saveAsTOF) {}
+        m_tofMax(std::numeric_limits<double>::min()), m_startTime(startTime),
+        m_saveAsTOF(saveAsTOF) {}
 
   double tofMin() const { return m_tofMin <= m_tofMax ? m_tofMin : 0.0; }
   double tofMax() const { return m_tofMin <= m_tofMax ? m_tofMax : 0.0; }
 };
-} // namespace EMU
 
-// register the algorithm into the AlgorithmFactory
-DECLARE_FILELOADER_ALGORITHM(LoadEMU)
+template <typename EP>
+void loadEvents(API::Progress &prog, const char *progMsg,
+                const std::string &eventFile, EP &eventProcessor) {
 
-/**
- * Return the confidence value that this algorithm can load the file
- * @param descriptor A descriptor for the file
- * @returns An integer specifying the confidence level. 0 indicates it will not
- * be used
- */
-int LoadEMU::confidence(Kernel::FileDescriptor &descriptor) const {
-  if (descriptor.extension() != ".tar")
-    return 0;
+  using namespace ANSTO;
 
-  ANSTO::Tar::File file(descriptor.filename());
-  if (!file.good())
-    return 0;
+  prog.doReport(progMsg);
 
-  size_t hdfFiles = 0;
-  size_t binFiles = 0;
-  const std::vector<std::string> &subFiles = file.files();
-  for (const auto &subFile : subFiles) {
-    auto len = subFile.length();
-    if ((len > 4) &&
-        (subFile.find_first_of("\\/", 0, 2) == std::string::npos)) {
-      if ((subFile.rfind(".hdf") == len - 4) &&
-          (subFile.compare(0, 3, "EMU") == 0))
-        hdfFiles++;
-      else if (subFile.rfind(".bin") == len - 4)
-        binFiles++;
-    }
-  }
+  FileLoader loader(eventFile.c_str());
 
-  return (hdfFiles == 1) && (binFiles == 1) ? 50 : 0;
+  // for progress notifications
+  ANSTO::ProgressTracker progTracker(prog, progMsg, loader.size(),
+                                     Progress_LoadBinFile);
+
+  ReadEventFile(loader, eventProcessor, progTracker, 100, false);
 }
 
-/**
- * Initialise the algorithm. Declare properties which can be set before
- * execution (input) and
- * read from after the execution (output).
- */
-void LoadEMU::init() {
+} // namespace EMU
+
+/// Declares the properties for the two loader variants. Adds the path option
+/// to the binary file and dataset set index if it is the \p hdfLoader.
+template <typename FD> void LoadEMU<FD>::init(bool hdfLoader) {
+
   // Specify file extensions which can be associated with a specific file.
   std::vector<std::string> exts;
 
   // Declare the Filename algorithm property. Mandatory. Sets the path to the
   // file to load.
   exts.clear();
-  exts.emplace_back(".tar");
-  declareProperty(Kernel::make_unique<API::FileProperty>(
-                      FilenameStr, "", API::FileProperty::Load, exts),
-                  "The input filename of the stored data");
+  if (hdfLoader)
+    exts.emplace_back(".hdf");
+  else
+    exts.emplace_back(".tar");
+  Base::declareProperty(Kernel::make_unique<API::FileProperty>(
+                            FilenameStr, "", API::FileProperty::Load, exts),
+                        "The input filename of the stored data");
+
+  if (hdfLoader) {
+    Base::declareProperty(
+        PathToBinaryStr, "",
+        "Relative or absolute path to the compressed binary\n"
+        "event file linked to the HDF file, eg /storage/data/");
+  }
 
   // mask
   exts.clear();
   exts.emplace_back(".xml");
-  declareProperty(Kernel::make_unique<API::FileProperty>(
-                      MaskStr, "", API::FileProperty::OptionalLoad, exts),
-                  "The input filename of the mask data");
+  Base::declareProperty(Kernel::make_unique<API::FileProperty>(
+                            MaskStr, "", API::FileProperty::OptionalLoad, exts),
+                        "The input filename of the mask data");
 
-  declareProperty(SelectDetectorTubesStr, "",
-                  "Comma separated range of detectors tubes to be loaded,\n"
-                  "  e.g. 16,19-45,47");
+  Base::declareProperty(
+      SelectDetectorTubesStr, "",
+      "Comma separated range of detectors tubes to be loaded,\n"
+      "  eg 16,19-45,47");
 
-  declareProperty(
+  Base::declareProperty(
       Kernel::make_unique<API::WorkspaceProperty<API::IEventWorkspace>>(
           "OutputWorkspace", "", Kernel::Direction::Output));
 
-  declareProperty(OverrideDopplerPhaseStr, EMPTY_DBL(),
-                  "Override the Doppler phase, in degrees.");
+  if (hdfLoader) {
+    Base::declareProperty(SelectDatasetStr, 0,
+                          "Select the index for the dataset to be loaded.");
+  }
 
-  declareProperty(RawDopplerTimeStr, false,
-                  "Import file as observed time relative the Doppler "
-                  "drive, in microsecs.");
+  Base::declareProperty(OverrideDopplerFreqStr, EMPTY_DBL(),
+                        "Override the Doppler frequency, in Hertz.");
 
-  declareProperty(FilterByTimeStartStr, 0.0,
-                  "Only include events after the provided start time, in "
-                  "seconds (relative to the start of the run).");
+  Base::declareProperty(OverrideDopplerPhaseStr, EMPTY_DBL(),
+                        "Override the Doppler phase, in degrees.");
 
-  declareProperty(FilterByTimeStopStr, EMPTY_DBL(),
-                  "Only include events before the provided stop time, in "
-                  "seconds (relative to the start of the run).");
+  Base::declareProperty(CalibrateDopplerPhaseStr, false,
+                        "Calibrate the Doppler phase prior to TOF conversion,\n"
+                        "ignored if imported as Doppler time or phase entered");
+
+  Base::declareProperty(RawDopplerTimeStr, false,
+                        "Import file as observed time relative the Doppler\n"
+                        "drive, in microsecs.");
+
+  Base::declareProperty(FilterByTimeStartStr, 0.0,
+                        "Only include events after the provided start time, in "
+                        "seconds (relative to the start of the run).");
+
+  Base::declareProperty(FilterByTimeStopStr, EMPTY_DBL(),
+                        "Only include events before the provided stop time, in "
+                        "seconds (relative to the start of the run).");
 
   std::string grpOptional = "Filters";
-  setPropertyGroup(FilterByTimeStartStr, grpOptional);
-  setPropertyGroup(FilterByTimeStopStr, grpOptional);
+  Base::setPropertyGroup(FilterByTimeStartStr, grpOptional);
+  Base::setPropertyGroup(FilterByTimeStopStr, grpOptional);
 }
 
-/**
- * Creates an event workspace and sets the title.
- */
-void LoadEMU::createWorkspace(ANSTO::Tar::File &tarFile) {
+/// Creates an event workspace and sets the \p title.
+template <typename FD>
+void LoadEMU<FD>::createWorkspace(const std::string &title) {
 
   // Create the workspace
   m_localWorkspace = boost::make_shared<DataObjects::EventWorkspace>();
@@ -504,58 +625,53 @@ void LoadEMU::createWorkspace(ANSTO::Tar::File &tarFile) {
   m_localWorkspace->setYUnit("Counts");
 
   // set title
-  const std::vector<std::string> &subFiles = tarFile.files();
-  for (const auto &subFile : subFiles)
-    if (subFile.compare(0, 3, "EMU") == 0) {
-      std::string title = subFile;
-
-      if (title.rfind(".hdf") == title.length() - 4)
-        title.resize(title.length() - 4);
-
-      if (title.rfind(".nx") == title.length() - 3)
-        title.resize(title.length() - 3);
-
-      m_localWorkspace->setTitle(title);
-      break;
-    }
+  m_localWorkspace->setTitle(title);
 }
 
-/**
- * Execute the algorithm. The steps involved are:
- *   Get the instrument properties and load options
- *   Create the workspace
- *   Load the instrument from the IDF
- *   Reposition the relevant neutronic values for model based on the parameters
- *   Load the data values and convert to TOF
- *   Setting up the masks
- */
-void LoadEMU::exec() {
+/// Execute the algorithm using the \p hdfFile and \p eventFile.
+/// The steps involved are:
+///   Create the workspace
+///   Get the instrument properties and load options
+///   Load the instrument from the IDF
+///   Reposition the relevant neutronic values for model based on the parameters
+///   Load the data values and convert to TOF
+///   Setting up the masks
+template <typename FD>
+void LoadEMU<FD>::exec(const std::string &hdfFile,
+                       const std::string &eventFile) {
+
+  namespace fs = boost::filesystem;
 
   // Create workspace
   // ----------------
-  std::string filename = getPropertyValue(FilenameStr);
-  ANSTO::Tar::File tarFile(filename);
-  if (!tarFile.good())
-    throw std::invalid_argument("invalid EMU file");
-  createWorkspace(tarFile);
+  fs::path p = hdfFile;
+  for (; !p.extension().empty();)
+    p = p.stem();
+  std::string title = p.generic_string();
+  createWorkspace(title);
   API::LogManager &logManager = m_localWorkspace->mutableRun();
   API::Progress prog(this, 0.0, 1.0, Progress_Total);
 
   // Load instrument and workspace properties
   // ----------------------------------------
-  loadParameters(tarFile, logManager);
+  logManager.addProperty(SelectDatasetStr, m_datasetIndex);
+  loadParameters(hdfFile, logManager);
   prog.doReport("creating instrument");
   loadInstrument();
 
-  // Get the region of interest and filters
+  // Get the region of interest and filters and save to log
   //
-  std::string maskfile = getPropertyValue(MaskStr);
-  std::string seltubes = getPropertyValue(SelectDetectorTubesStr);
+  std::string maskfile = Base::getPropertyValue(MaskStr);
+  std::string seltubes = Base::getPropertyValue(SelectDetectorTubesStr);
+  logManager.addProperty(SelectDetectorTubesStr, seltubes);
+  logManager.addProperty(MaskStr, maskfile);
+
   std::vector<bool> roi = createRoiVector(seltubes, maskfile);
-  double timeMaxBoundary = getProperty(FilterByTimeStopStr);
-  if (isEmpty(timeMaxBoundary))
+  double timeMaxBoundary = Base::getProperty(FilterByTimeStopStr);
+  if (Base::isEmpty(timeMaxBoundary))
     timeMaxBoundary = std::numeric_limits<double>::infinity();
-  TimeLimits timeBoundary(getProperty(FilterByTimeStartStr), timeMaxBoundary);
+  TimeLimits timeBoundary(Base::getProperty(FilterByTimeStartStr),
+                          timeMaxBoundary);
 
   // lambda to simplify loading instrument parameters
   auto instr = m_localWorkspace->getInstrument();
@@ -568,14 +684,14 @@ void LoadEMU::exec() {
   // sequence starting from 0
   //
   double sampleAnalyser = iparam("SampleAnalyser");
-  auto endID = static_cast<detid_t>(DETECTORS * PIXELS_PER_TUBE);
+  auto endID = static_cast<detid_t>(DETECTOR_TUBES * PIXELS_PER_TUBE);
   for (detid_t detID = 0; detID < endID; detID++)
     updateNeutronicPostions(detID, sampleAnalyser);
 
   // get the detector map from raw input to a physical detector
   //
   std::string dmapStr = instr->getParameterAsString("DetectorMap");
-  std::vector<size_t> detMapIndex = std::vector<size_t>(DETECTORS, 0);
+  std::vector<size_t> detMapIndex = std::vector<size_t>(DETECTOR_TUBES, 0);
   mapRangeToIndex(dmapStr, detMapIndex, [](size_t n) { return n; });
 
   // Collect the L2 distances, Doppler characteristics and
@@ -587,12 +703,8 @@ void LoadEMU::exec() {
   double framePeriod =
       1.0e6 / m_dopplerFreq; // period and max direct as microsec
   double sourceSample = iparam("SourceSample");
-  ConvertTOF convertTOF(m_dopplerAmpl, m_dopplerFreq, m_dopplerPhase,
-                        sourceSample, v2, m_detectorL2);
-
-  Types::Core::DateAndTime start_time(
-      logManager.getPropertyValueAsType<std::string>("StartTime"));
-  std::string time_str = start_time.toISO8601String();
+  ConvertTOF convertTOF(m_dopplerAmpl * m_dopplerRun, m_dopplerFreq,
+                        m_dopplerPhase, sourceSample, v2, m_detectorL2);
 
   // Load the events file
   // --------------------
@@ -614,48 +726,76 @@ void LoadEMU::exec() {
                             1000.0 * iparam("AnalysedTauxMax"));
 
   // fabs because the value can be negative
-  double gatePeriod = 1.0e6 / fabs(logManager.getPropertyValueAsType<double>(
-                                  "GraphiteChopperFrequency"));
+  double gatePeriod =
+      1.0e6 /
+      fabs(logManager.getTimeSeriesProperty<double>("GraphiteChopperFrequency")
+               ->firstValue());
 
   // count total events per pixel and reserve necessary memory
   EMU::EventCounter eventCounter(roi, detMapIndex, PIXELS_PER_TUBE, framePeriod,
                                  gatePeriod, timeBoundary, directLimits,
                                  analysedLimits, eventCounts);
-  loadEvents(prog, "loading neutron counts", tarFile, eventCounter);
+  EMU::loadEvents(prog, "loading neutron counts", eventFile, eventCounter);
   ANSTO::ProgressTracker progTracker(prog, "creating neutron event lists",
                                      numberHistograms, Progress_ReserveMemory);
   prepareEventStorage(progTracker, eventCounts, eventVectors);
 
-  // now perfrom the actual event collection and TOF convert if necessary
-  bool saveAsTOF = !getProperty(RawDopplerTimeStr);
-  EMU::EventAssigner eventAssigner(
-      roi, detMapIndex, PIXELS_PER_TUBE, framePeriod, gatePeriod, timeBoundary,
-      directLimits, analysedLimits, convertTOF, eventVectors, saveAsTOF);
-  loadEvents(prog, "loading neutron events (TOF)", tarFile, eventAssigner);
+  // now perform the actual event collection and TOF convert if necessary
+  // if a phase calibration is required then load it as raw doppler time
+  // perform the calibration and then convert to TOF
+  Types::Core::DateAndTime startTime(m_startRun);
+  auto start_nanosec = startTime.totalNanoseconds();
+  bool saveAsTOF = !Base::getProperty(RawDopplerTimeStr);
+  bool loadAsTOF = !m_calibrateDoppler && saveAsTOF;
+  EMU::EventAssigner eventAssigner(roi, detMapIndex, PIXELS_PER_TUBE,
+                                   framePeriod, gatePeriod, timeBoundary,
+                                   directLimits, analysedLimits, convertTOF,
+                                   eventVectors, start_nanosec, loadAsTOF);
+  EMU::loadEvents(prog, "loading neutron events (TOF)", eventFile,
+                  eventAssigner);
+
+  // perform a calibration and then TOF conversion if necessary
+  // and update the tof limits
+  auto minTOF = eventAssigner.tofMin();
+  auto maxTOF = eventAssigner.tofMax();
+  if (m_calibrateDoppler) {
+    calibrateDopplerPhase(eventCounts, eventVectors);
+    if (saveAsTOF) {
+      dopplerTimeToTOF(eventVectors, minTOF, maxTOF);
+    }
+  }
+  AddSinglePointTimeSeriesProperty<double>(logManager, m_startRun,
+                                           "DopplerPhase", m_dopplerPhase);
 
   // just to make sure the bins hold it all and setup the detector masks
   m_localWorkspace->setAllX(
-      HistogramData::BinEdges{std::max(0.0, floor(eventAssigner.tofMin())),
-                              eventAssigner.tofMax() + 1});
+      HistogramData::BinEdges{std::max(0.0, floor(minTOF)), maxTOF + 1});
   setupDetectorMasks(roi);
 
   // set log values
   auto frame_count = static_cast<int>(eventCounter.numFrames());
+  AddSinglePointTimeSeriesProperty<int>(logManager, m_startRun, "frame_count",
+                                        frame_count);
 
+  std::string filename = Base::getPropertyValue(FilenameStr);
   logManager.addProperty("filename", filename);
-  logManager.addProperty("frame_count", frame_count);
 
   Types::Core::time_duration duration = boost::posix_time::microseconds(
       static_cast<boost::int64_t>(eventCounter.duration() * 1.0e6));
-  Types::Core::DateAndTime end_time(start_time + duration);
-  logManager.addProperty("start_time", start_time.toISO8601String());
-  logManager.addProperty("end_time", end_time.toISO8601String());
+  Types::Core::DateAndTime endTime(startTime + duration);
+  logManager.addProperty("start_time", startTime.toISO8601String());
+  logManager.addProperty("end_time", endTime.toISO8601String());
+  logManager.addProperty<double>("dur", eventCounter.duration());
+
+  // Finally add the time-series parameter explicitly
+  loadEnvironParameters(hdfFile, logManager);
 
-  setProperty("OutputWorkspace", m_localWorkspace);
+  Base::setProperty("OutputWorkspace", m_localWorkspace);
 }
 
-// set up the detector masks
-void LoadEMU::setupDetectorMasks(std::vector<bool> &roi) {
+/// Set up the detector masks to the region of interest \p roi.
+template <typename FD>
+void LoadEMU<FD>::setupDetectorMasks(std::vector<bool> &roi) {
 
   // count total number of masked bins
   size_t maskedBins = 0;
@@ -672,17 +812,20 @@ void LoadEMU::setupDetectorMasks(std::vector<bool> &roi) {
       if (!roi[i])
         maskIndexList[maskIndex++] = i;
 
-    API::IAlgorithm_sptr maskingAlg = createChildAlgorithm("MaskDetectors");
+    API::IAlgorithm_sptr maskingAlg =
+        Base::createChildAlgorithm("MaskDetectors");
     maskingAlg->setProperty("Workspace", m_localWorkspace);
     maskingAlg->setProperty("WorkspaceIndexList", maskIndexList);
     maskingAlg->executeAsChildAlg();
   }
 }
 
-// prepare the event storage
-void LoadEMU::prepareEventStorage(ANSTO::ProgressTracker &progTracker,
-                                  std::vector<size_t> &eventCounts,
-                                  std::vector<EventVector_pt> &eventVectors) {
+/// Allocate space for the event storage in \p eventVectors after the
+/// \p eventCounts have been determined.
+template <typename FD>
+void LoadEMU<FD>::prepareEventStorage(
+    ANSTO::ProgressTracker &progTracker, const std::vector<size_t> &eventCounts,
+    std::vector<EventVector_pt> &eventVectors) {
 
   size_t numberHistograms = eventCounts.size();
   for (size_t i = 0; i != numberHistograms; ++i) {
@@ -701,14 +844,30 @@ void LoadEMU::prepareEventStorage(ANSTO::ProgressTracker &progTracker,
   progTracker.complete();
 }
 
-// get and log the Doppler parameters
-void LoadEMU::loadDopplerParameters(API::LogManager &logm) {
+/// Get the Doppler parameters and record to the log manager, \p logm.
+template <typename FD>
+void LoadEMU<FD>::loadDopplerParameters(API::LogManager &logm) {
 
   auto instr = m_localWorkspace->getInstrument();
-  m_dopplerFreq = logm.getPropertyValueAsType<double>("DopplerFrequency");
-  m_dopplerAmpl = logm.getPropertyValueAsType<double>("DopplerAmplitude");
-  m_dopplerPhase = getProperty(OverrideDopplerPhaseStr);
-  if (isEmpty(m_dopplerPhase)) {
+
+  // use nominal frequency based on amp and velocity unless overridden
+  m_dopplerAmpl =
+      logm.getTimeSeriesProperty<double>("DopplerAmplitude")->firstValue();
+  m_dopplerRun =
+      logm.getTimeSeriesProperty<int32_t>("DopplerRun")->firstValue();
+  m_dopplerFreq = Base::getProperty(OverrideDopplerFreqStr);
+  if (Base::isEmpty(m_dopplerFreq)) {
+    auto doppVel =
+        logm.getTimeSeriesProperty<double>("DopplerVelocity")->firstValue();
+    m_dopplerFreq = 0.5 * doppVel / (M_PI * m_dopplerAmpl);
+  }
+  AddSinglePointTimeSeriesProperty<double>(logm, m_startRun, "DopplerFrequency",
+                                           m_dopplerFreq);
+
+  m_dopplerPhase = Base::getProperty(OverrideDopplerPhaseStr);
+  m_calibrateDoppler = Base::getProperty(CalibrateDopplerPhaseStr) &&
+                       Base::isEmpty(m_dopplerPhase);
+  if (Base::isEmpty(m_dopplerPhase)) {
     // sinusoidal motion crossing a threshold with a delay
     double doppThreshold =
         instr->getNumberParameter("DopplerReferenceThreshold")[0];
@@ -717,11 +876,135 @@ void LoadEMU::loadDopplerParameters(API::LogManager &logm) {
         180.0 - asin(0.001 * doppThreshold / m_dopplerAmpl) * 180.0 / M_PI +
         doppDelay * m_dopplerFreq;
   }
-  logm.addProperty<double>("DopplerPhase", m_dopplerPhase);
+
+  // problem adding 'bool' to log
+  int32_t calPhase = (m_calibrateDoppler ? 1 : 0);
+  logm.addProperty("CalibratePhase", calPhase);
+}
+
+/// Calibrate the doppler phase based on the analysed events using
+/// the \p eventCounts and \p eventVectors.
+template <typename FD>
+void LoadEMU<FD>::calibrateDopplerPhase(
+    const std::vector<size_t> &eventCounts,
+    const std::vector<EventVector_pt> &eventVectors) {
+
+  // get the doppler parameters
+  auto instr = m_localWorkspace->getInstrument();
+  double v2 = instr->getNumberParameter("AnalysedV2")[0];
+  double l1 = instr->getNumberParameter("SourceSample")[0];
+
+  // get the number of analysed events and initial doppler time
+  auto startID = static_cast<size_t>(HORIZONTAL_TUBES * PIXELS_PER_TUBE);
+  auto endID = static_cast<size_t>(DETECTOR_TUBES * PIXELS_PER_TUBE);
+  size_t numEvents = 0;
+  for (size_t i = startID; i < endID; i++)
+    numEvents += eventCounts[i];
+  if (numEvents == 0)
+    throw std::runtime_error("no analysed events for phase calibration");
+  std::vector<double> nVel(numEvents);
+  std::vector<size_t> nMap(numEvents);
+  std::vector<bool> nCnd(numEvents);
+  constexpr size_t NHIST = 100;
+  std::vector<int> histogram(NHIST + 1, 0);
+
+  // define the cost function to optimize phase
+  auto costFn = [&, this](double phase) {
+    ConvertTOF convTOF(m_dopplerAmpl * m_dopplerRun, m_dopplerFreq, phase, l1,
+                       v2, m_detectorL2);
+
+    // convert each analysed event to source velocity
+    size_t ix = 0;
+    double tof, pulse;
+    for (size_t i = startID; i < endID; i++) {
+      for (auto const &x : *eventVectors[i]) {
+        std::tie(pulse, tof) = convTOF.analysedTOF(i, x.tof());
+        auto tof1 = 1e-6 * tof - m_detectorL2[i] / v2;
+        nVel[ix++] = l1 / tof1;
+      }
+    }
+
+    // now histogram the data and create the map from velocity to hist
+    auto ixlim = std::minmax_element(nVel.begin(), nVel.end());
+    auto vmin = nVel[ixlim.first - nVel.begin()];
+    auto vmax = nVel[ixlim.second - nVel.begin()];
+    int maxHist = 0;
+    std::fill(histogram.begin(), histogram.end(), 0);
+    auto delta = (vmax - vmin) / NHIST;
+    for (size_t i = 0; i < numEvents; i++) {
+      auto v = nVel[i];
+      auto j = static_cast<size_t>(std::floor((v - vmin) / delta));
+      histogram[j]++;
+      if (histogram[j] > maxHist)
+        maxHist = histogram[j];
+      nMap[i] = j;
+    }
+
+    // determine the points above the 25% threshold
+    int minLevel = static_cast<int>(maxHist / 4);
+    for (size_t i = 0; i < numEvents; i++) {
+      nCnd[i] = (histogram[nMap[i]] >= minLevel ? true : false);
+    }
+
+    // calculate the standard deviation for the points above the threshold
+    auto cost = maskedStdev(nVel, nCnd);
+    return cost;
+  };
+
+  // call the optimizer and update the doppler phase value
+  // limit the optimization to 30 iterations
+  int bits = std::numeric_limits<double>::digits;
+  boost::uintmax_t itn = 30;
+  using boost::math::tools::brent_find_minima;
+  auto minPhase = m_dopplerPhase - 5.0;
+  auto maxPhase = m_dopplerPhase + 5.0;
+  auto r = brent_find_minima(costFn, minPhase, maxPhase, bits, itn);
+  m_dopplerPhase = r.first;
+}
+
+/// Convert the doppler time to TOF for all the events in \p eventVectors and
+/// time of flight range as \p minTOF and \p maxTOF.
+template <typename FD>
+void LoadEMU<FD>::dopplerTimeToTOF(std::vector<EventVector_pt> &eventVectors,
+                                   double &minTOF, double &maxTOF) {
+
+  // get the doppler parameters and initialise TOD converter
+  auto instr = m_localWorkspace->getInstrument();
+  double v2 = instr->getNumberParameter("AnalysedV2")[0];
+  double l1 = instr->getNumberParameter("SourceSample")[0];
+  ConvertTOF convTOF(m_dopplerAmpl * m_dopplerRun, m_dopplerFreq,
+                     m_dopplerPhase, l1, v2, m_detectorL2);
+
+  // run through all the events noting that analysed event are in
+  // the bottom half of the detector ids
+  auto start = true;
+  auto directID = static_cast<size_t>(DETECTOR_TUBES * PIXELS_PER_TUBE);
+  for (size_t id = 0; id < eventVectors.size(); id++) {
+    for (auto &x : *eventVectors[id]) {
+      double tof, pulse;
+      if (id < directID)
+        std::tie(pulse, tof) = convTOF.analysedTOF(id, x.tof());
+      else
+        std::tie(pulse, tof) = convTOF.directTOF(id, x.tof());
+
+      // update the pulse time and tof
+      int64_t pulseTime = x.pulseTime().totalNanoseconds();
+      pulseTime += static_cast<int64_t>(pulse * 1000);
+      x = Types::Event::TofEvent(tof, Types::Core::DateAndTime(pulseTime));
+
+      if (start) {
+        minTOF = maxTOF = x.tof();
+        start = false;
+      } else {
+        minTOF = std::min(minTOF, x.tof());
+        maxTOF = std::max(maxTOF, x.tof());
+      }
+    }
+  }
 }
 
-// Recovers the L2 neutronic distance for each detector.
-void LoadEMU::loadDetectorL2Values() {
+/// Recovers the L2 neutronic distance for each detector.
+template <typename FD> void LoadEMU<FD>::loadDetectorL2Values() {
 
   m_detectorL2 = std::vector<double>(HISTOGRAMS);
   const auto &detectorInfo = m_localWorkspace->detectorInfo();
@@ -733,15 +1016,11 @@ void LoadEMU::loadDetectorL2Values() {
   }
 }
 
-// update the neutronic positins
-void LoadEMU::updateNeutronicPostions(detid_t detID, double sampleAnalyser) {
-
-  // get the instrument
-
-  // get the list of indirect horizontal detectors
-
-  // for each detector get the current position and scale
-  // the detectors
+/// Update the neutronic position for the \p detID using the distance
+/// from the source and the sample to analyser distance, \p sampleAnalyser.
+template <typename FD>
+void LoadEMU<FD>::updateNeutronicPostions(detid_t detID,
+                                          double sampleAnalyser) {
 
   Geometry::Instrument_const_sptr instrument =
       m_localWorkspace->getInstrument();
@@ -763,10 +1042,11 @@ void LoadEMU::updateNeutronicPostions(detid_t detID, double sampleAnalyser) {
   }
 }
 
-// region of interest is defined by the selected detectors and the mask
-//
-std::vector<bool> LoadEMU::createRoiVector(const std::string &selected,
-                                           const std::string &maskfile) {
+/// Region of interest is defined by the \p selected detectors and the
+/// \p maskfile.
+template <typename FD>
+std::vector<bool> LoadEMU<FD>::createRoiVector(const std::string &selected,
+                                               const std::string &maskfile) {
 
   std::vector<bool> result(HISTOGRAMS, true);
 
@@ -804,87 +1084,89 @@ std::vector<bool> LoadEMU::createRoiVector(const std::string &selected,
   return result;
 }
 
-// load parameters from input file
-void LoadEMU::loadParameters(ANSTO::Tar::File &tarFile, API::LogManager &logm) {
-
-  // extract log and hdf file
-  const std::vector<std::string> &files = tarFile.files();
-  auto file_it =
-      std::find_if(files.cbegin(), files.cend(), [](const std::string &file) {
-        return file.rfind(".hdf") == file.length() - 4;
-      });
-  if (file_it != files.end()) {
-    tarFile.select(file_it->c_str());
-    // extract hdf file into tmp file
-    Poco::TemporaryFile hdfFile;
-    boost::shared_ptr<FILE> handle(fopen(hdfFile.path().c_str(), "wb"), fclose);
-    if (handle) {
-      // copy content
-      char buffer[4096];
-      size_t bytesRead;
-      while (0 != (bytesRead = tarFile.read(buffer, sizeof(buffer))))
-        fwrite(buffer, bytesRead, 1, handle.get());
-      handle.reset();
-
-      NeXus::NXRoot root(hdfFile.path());
-      NeXus::NXEntry entry = root.openFirstEntry();
-
-      MapNeXusToProperty<std::string>(entry, "sample/name", "unknown", logm,
-                                      "SampleName", "");
-      MapNeXusToProperty<std::string>(entry, "sample/description", "unknown",
-                                      logm, "SampleDescription", "");
-      MapNeXusToProperty<std::string>(
-          entry, "start_time", "2000-01-01T00:00:00", logm, "StartTime", "");
-
-      MapNeXusToProperty<double>(entry, "instrument/doppler/ctrl/amplitude",
-                                 75.0, logm, "DopplerAmplitude", 0.001);
-      double speedToFreq =
-          0.5 / (M_PI * m_localWorkspace->run().getPropertyValueAsType<double>(
-                            "DopplerAmplitude"));
-      MapNeXusToProperty<double>(entry, "instrument/doppler/ctrl/velocity", 4.7,
-                                 logm, "DopplerFrequency", speedToFreq);
-
-      MapNeXusToProperty<double>(entry, "instrument/chpr/background/actspeed",
-                                 1272.8, logm, "BackgroundChopperFrequency",
-                                 1.0 / 60);
-      MapNeXusToProperty<double>(entry, "instrument/chpr/graphite/actspeed",
-                                 2545.6, logm, "GraphiteChopperFrequency",
-                                 1.0 / 60);
-      MapNeXusToProperty<double>(entry, "instrument/hztubegap", 0.02, logm,
-                                 "HorizontalTubesGap", 1.0);
-      MapNeXusToProperty<int32_t>(entry, "monitor/bm1_counts", 0, logm,
-                                  "MonitorCounts", 1);
-
-      // temp fix for source position when loading IDF
-      MapNeXusToProperty<double>(entry, "instrument/doppler/tosource", 2.035,
-                                 logm, "SourceSample", 1.0);
-    }
+/// Load parameters from input \p hdfFile and save to the log manager, \p logm.
+template <typename FD>
+void LoadEMU<FD>::loadParameters(const std::string &hdfFile,
+                                 API::LogManager &logm) {
+
+  NeXus::NXRoot root(hdfFile);
+  NeXus::NXEntry entry = root.openFirstEntry();
+
+  MapNeXusToProperty<std::string>(entry, "sample/name", "unknown", logm,
+                                  "SampleName", "", 0);
+  MapNeXusToProperty<std::string>(entry, "sample/description", "unknown", logm,
+                                  "SampleDescription", "", 0);
+
+  // if dataset index > 0 need to add an offset to the start time
+  Types::Core::DateAndTime startTime(GetNeXusValue<std::string>(
+      entry, "start_time", "2000-01-01T00:00:00", 0));
+  if (m_datasetIndex > 0) {
+    auto baseTime =
+        GetNeXusValue<int32_t>(entry, "instrument/detector/start_time", 0, 0);
+    auto nthTime = GetNeXusValue<int32_t>(
+        entry, "instrument/detector/start_time", 0, m_datasetIndex);
+
+    Types::Core::time_duration duration = boost::posix_time::microseconds(
+        static_cast<boost::int64_t>((nthTime - baseTime) * 1.0e6));
+    Types::Core::DateAndTime startDataset(startTime + duration);
+    m_startRun = startDataset.toISO8601String();
+  } else {
+    m_startRun = startTime.toISO8601String();
   }
 
-  // patching
-  file_it = std::find(files.cbegin(), files.cend(), "History.log");
-  if (file_it != files.cend()) {
-    tarFile.select(file_it->c_str());
-    std::string logContent;
-    logContent.resize(tarFile.selected_size());
-    tarFile.read(&logContent[0], logContent.size());
-    std::istringstream data(logContent);
-    Poco::AutoPtr<Poco::Util::PropertyFileConfiguration> conf(
-        new Poco::Util::PropertyFileConfiguration(data));
-
-    if (conf->hasProperty("SampleName")) {
-      std::string name = conf->getString("SampleName");
-      logm.addProperty("SampleName", name);
-    }
+  MapNeXusToSeries<double>(entry, "instrument/doppler/ctrl/amplitude", 75.0,
+                           logm, m_startRun, "DopplerAmplitude", 0.001,
+                           m_datasetIndex);
+  MapNeXusToSeries<double>(entry, "instrument/doppler/ctrl/velocity", 4.7, logm,
+                           m_startRun, "DopplerVelocity", 1, m_datasetIndex);
+  MapNeXusToSeries<int>(entry, "instrument/doppler/ctrl/run_cmd", 1, logm,
+                        m_startRun, "DopplerRun", 1, m_datasetIndex);
+
+  MapNeXusToSeries<double>(entry, "instrument/chpr/background/actspeed", 1272.8,
+                           logm, m_startRun, "BackgroundChopperFrequency",
+                           1.0 / 60, 0);
+  MapNeXusToSeries<double>(entry, "instrument/chpr/graphite/actspeed", 2545.6,
+                           logm, m_startRun, "GraphiteChopperFrequency",
+                           1.0 / 60, 0);
+  // hz tube gap or equivalent to be added later - reverts to default
+  MapNeXusToSeries<double>(entry, "instrument/hztubegap", 0.02, logm,
+                           m_startRun, "horizontal_tubes_gap", 1.0, 0);
+  MapNeXusToSeries<int32_t>(entry, "monitor/bm1_counts", 0, logm, m_startRun,
+                            "MonitorCounts", 1, m_datasetIndex);
+
+  // fix for source position when loading IDF
+  MapNeXusToProperty<double>(entry, "instrument/doppler/tosource", 2.035, logm,
+                             "SourceSample", 1.0, 0);
+}
+
+/// Load the environment variables from the \p hdfFile and save as
+/// time series to the log manager, \p logm.
+template <typename FD>
+void LoadEMU<FD>::loadEnvironParameters(const std::string &hdfFile,
+                                        API::LogManager &logm) {
+
+  NeXus::NXRoot root(hdfFile);
+  NeXus::NXEntry entry = root.openFirstEntry();
+  auto time_str = logm.getPropertyValueAsType<std::string>("end_time");
+
+  // load the environment variables for the dataset loaded
+  std::vector<std::string> tags = {"P01PS03", "P01PSP03", "T01S00",  "T01S05",
+                                   "T01S06",  "T01SP00",  "T01SP06", "T02S00",
+                                   "T02S04",  "T02S05",   "T02S06",  "T02SP00",
+                                   "T02SP06"};
+
+  for (const auto &tag : tags) {
+    MapNeXusToSeries<double>(entry, "data/" + tag, 0.0, logm, time_str,
+                             "env_" + tag, 1.0, m_datasetIndex);
   }
 }
 
-// load the instrument definition and instrument parameters
-void LoadEMU::loadInstrument() {
+/// Load the instrument definition.
+template <typename FD> void LoadEMU<FD>::loadInstrument() {
 
   // loads the IDF and parameter file
   API::IAlgorithm_sptr loadInstrumentAlg =
-      createChildAlgorithm("LoadInstrument");
+      Base::createChildAlgorithm("LoadInstrument");
   loadInstrumentAlg->setProperty("Workspace", m_localWorkspace);
   loadInstrumentAlg->setPropertyValue("InstrumentName", "EMUau");
   loadInstrumentAlg->setProperty("RewriteSpectraMap",
@@ -892,31 +1174,218 @@ void LoadEMU::loadInstrument() {
   loadInstrumentAlg->executeAsChildAlg();
 }
 
-// read counts/events from binary file
-template <class EventProcessor>
-void LoadEMU::loadEvents(API::Progress &prog, const char *progMsg,
-                         ANSTO::Tar::File &tarFile,
-                         EventProcessor &eventProcessor) {
+//--------- explicit template instantiation -----------
 
-  using namespace ANSTO;
+// Instantiate base class for LoadEMU's
+template class LoadEMU<Kernel::FileDescriptor>;
+template class LoadEMU<Kernel::NexusDescriptor>;
 
-  prog.doReport(progMsg);
+// -------- EMU Hdf loader -----------------------
+
+/// Algorithm's version for identification. @see Algorithm::version
+int LoadEMUHdf::version() const { return 1; }
+
+/// Similar algorithms. @see Algorithm::seeAlso
+const std::vector<std::string> LoadEMUHdf::seeAlso() const {
+  return {"Load", "LoadQKK"};
+}
+/// Algorithm's category for identification. @see Algorithm::category
+const std::string LoadEMUHdf::category() const { return "DataHandling\\ANSTO"; }
+
+/// Algorithms name for identification. @see Algorithm::name
+const std::string LoadEMUHdf::name() const { return "LoadEMUHdf"; }
+
+/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+const std::string LoadEMUHdf::summary() const {
+  return "Loads an EMU Hdf and linked event file into a workspace.";
+}
+
+/// Return the confidence as an integer value that this algorithm can
+/// load the file \p descriptor.
+int LoadEMUHdf::confidence(Kernel::NexusDescriptor &descriptor) const {
+  if (descriptor.extension() != ".hdf")
+    return 0;
+
+  if (descriptor.pathExists("/entry1/site_name") &&
+      descriptor.pathExists("/entry1/instrument/doppler/ctrl/velocity") &&
+      descriptor.pathExists("/entry1/instrument/doppler/ctrl/amplitude") &&
+      descriptor.pathExists("/entry1/instrument/detector/daq_dirname") &&
+      descriptor.pathExists("/entry1/instrument/detector/dataset_number") &&
+      descriptor.pathExists("/entry1/data/hmm_total_t_ds0") &&
+      descriptor.pathExists("/entry1/data/hmm_total_t_ds1") &&
+      descriptor.pathExists("/entry1/data/hmm_total_xt_ds0") &&
+      descriptor.pathExists("/entry1/data/hmm_total_xt_ds1")) {
+    return 80;
+  } else {
+    return 0;
+  }
+}
+
+/// Initialise the algorithm and declare the properties for the
+/// nexus descriptor.
+void LoadEMUHdf::init() { LoadEMU<Kernel::NexusDescriptor>::init(true); }
+
+/// Execute the algorithm. Establishes the filepath to the event file
+/// from the HDF link and the path provided and invokes the common
+// exec() function that works with the two files.
+void LoadEMUHdf::exec() {
+
+  namespace fs = boost::filesystem;
 
-  // select bin file
-  int64_t fileSize = 0;
+  // Open the hdf file and find the dirname and dataset number
+  std::string hdfFile = Base::getPropertyValue(FilenameStr);
+  std::string evtPath = Base::getPropertyValue(PathToBinaryStr);
+  if (evtPath.empty())
+    evtPath = "./";
+
+  // if relative ./ or ../ then append to the directory for the hdf file
+  if (evtPath.rfind("./") == 0 || evtPath.rfind("../") == 0) {
+    fs::path hp = hdfFile;
+    evtPath = fs::canonical(evtPath, hp.parent_path()).generic_string();
+  }
+
+  // dataset index to be loaded
+  m_datasetIndex = Base::getProperty(SelectDatasetStr);
+
+  // if path provided build the file path
+  if (fs::is_directory(evtPath)) {
+    NeXus::NXRoot root(hdfFile);
+    NeXus::NXEntry entry = root.openFirstEntry();
+    auto eventDir = GetNeXusValue<std::string>(
+        entry, "instrument/detector/daq_dirname", "./", 0);
+    auto dataset = GetNeXusValue<int32_t>(
+        entry, "instrument/detector/dataset_number", 0, m_datasetIndex);
+
+    // build the path to the event file as if a relative or absolute
+    // path is passed:
+    //   'relpath/[daq_dirname]/DATASET_[n]/EOS.bin' or the
+    char buffer[255] = {};
+    snprintf(buffer, sizeof(buffer), "%s/DATASET_%d/EOS.bin", eventDir.c_str(),
+             dataset);
+    fs::path path = evtPath;
+    path /= buffer;
+    path = fs::absolute(path);
+    evtPath = path.generic_string();
+  }
+
+  // finally check that the event file exists
+  if (!fs::is_regular_file(evtPath)) {
+    std::string msg = "Check path, cannot open binary event file: " + evtPath;
+    throw std::runtime_error(msg);
+  }
+
+  LoadEMU<Kernel::NexusDescriptor>::exec(hdfFile, evtPath);
+}
+
+// -------- EMU Tar loader -----------------------
+
+/// Algorithm's version for identification. @see Algorithm::version
+int LoadEMUTar::version() const { return 1; }
+
+/// Similar algorithms. @see Algorithm::seeAlso
+const std::vector<std::string> LoadEMUTar::seeAlso() const {
+  return {"Load", "LoadQKK"};
+}
+/// Algorithm's category for identification. @see Algorithm::category
+const std::string LoadEMUTar::category() const { return "DataHandling\\ANSTO"; }
+
+/// Algorithms name for identification. @see Algorithm::name
+const std::string LoadEMUTar::name() const { return "LoadEMU"; }
+
+/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+const std::string LoadEMUTar::summary() const {
+  return "Loads an EMU tar file, containing the Hdf and event file, into a "
+         "workspace.";
+}
+
+/// Return the confidence as an integer value that this algorithm can
+/// load the file \p descriptor.
+int LoadEMUTar::confidence(Kernel::FileDescriptor &descriptor) const {
+  if (descriptor.extension() != ".tar")
+    return 0;
+
+  ANSTO::Tar::File file(descriptor.filename());
+  if (!file.good())
+    return 0;
+
+  size_t hdfFiles = 0;
+  size_t binFiles = 0;
+  const std::vector<std::string> &subFiles = file.files();
+  for (const auto &subFile : subFiles) {
+    auto len = subFile.length();
+    if ((len > 4) &&
+        (subFile.find_first_of("\\/", 0, 2) == std::string::npos)) {
+      if ((subFile.rfind(".hdf") == len - 4) &&
+          (subFile.compare(0, 3, "EMU") == 0))
+        hdfFiles++;
+      else if (subFile.rfind(".bin") == len - 4)
+        binFiles++;
+    }
+  }
+
+  return (hdfFiles == 1) && (binFiles == 1) ? 50 : 0;
+}
+
+/// Initialise the algorithm and declare the standard properties for the
+/// general file descriptor.
+void LoadEMUTar::init() { LoadEMU<Kernel::FileDescriptor>::init(false); }
+
+/// Execute the algorithm. Extracts the hdf and event file from the tar
+/// and invokes the invokes the common exec() function that works with
+/// the two files.
+void LoadEMUTar::exec() {
+
+  // Opens the tar and extracts the hdf and event data to temporary files
+  std::string filename = Base::getPropertyValue(FilenameStr);
+  ANSTO::Tar::File tarFile(filename);
+  if (!tarFile.good())
+    throw std::invalid_argument("invalid EMU tar file");
+
+  // dataset selection not supported in tar version - order is not guaranteed
+  m_datasetIndex = 0;
+
+  // lambda functions to find the first file of extension and to extract
+  // the file
   const std::vector<std::string> &files = tarFile.files();
-  for (const auto &file : files)
-    if (file.rfind(".bin") == file.length() - 4) {
-      tarFile.select(file.c_str());
-      fileSize = tarFile.selected_size();
-      break;
+  auto selectFile = [&](const std::string &ext) {
+    auto itf = std::find_if(files.cbegin(), files.cend(),
+                            [&ext](const std::string &file) {
+                              return file.rfind(ext) == file.length() - 4;
+                            });
+    if (itf == files.end())
+      throw std::runtime_error("missing tar file data");
+    else
+      tarFile.select(itf->c_str());
+  };
+  auto extractFile = [&](Poco::TemporaryFile &tfile) {
+    boost::shared_ptr<FILE> handle(fopen(tfile.path().c_str(), "wb"), fclose);
+    if (handle) {
+      // copy content
+      char buffer[4096];
+      size_t bytesRead;
+      while (0 != (bytesRead = tarFile.read(buffer, sizeof(buffer))))
+        fwrite(buffer, bytesRead, 1, handle.get());
+      handle.reset();
     }
+  };
 
-  // for progress notifications
-  ANSTO::ProgressTracker progTracker(prog, progMsg, fileSize,
-                                     Progress_LoadBinFile);
+  // extract hdf file into tmp file
+  selectFile(".hdf");
+  Poco::TemporaryFile hdfFile;
+  extractFile(hdfFile);
 
-  ReadEventFile(tarFile, eventProcessor, progTracker, 100, false);
+  // extract the event file
+  selectFile(".bin");
+  Poco::TemporaryFile eventFile;
+  extractFile(eventFile);
+
+  // call the common loader
+  LoadEMU<Kernel::FileDescriptor>::exec(hdfFile.path(), eventFile.path());
 }
+
+// register the algorithms into the AlgorithmFactory
+DECLARE_FILELOADER_ALGORITHM(LoadEMUTar)
+DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadEMUHdf)
+
 } // namespace DataHandling
-} // namespace Mantid
\ No newline at end of file
+} // namespace Mantid
diff --git a/Framework/DataHandling/src/LoadIsawDetCal.cpp b/Framework/DataHandling/src/LoadIsawDetCal.cpp
index 70fc5025f7b38809d3b6710f51e8d995f3ddbedf..196f4fb6b43592f42f0605381ed4865143fdf89c 100644
--- a/Framework/DataHandling/src/LoadIsawDetCal.cpp
+++ b/Framework/DataHandling/src/LoadIsawDetCal.cpp
@@ -50,17 +50,17 @@ void LoadIsawDetCal::init() {
                       boost::make_shared<InstrumentValidator>()),
                   "The workspace containing the geometry to be calibrated.");
 
-  const auto exts = std::vector<std::string>({".DetCal"});
+  const auto exts =
+      std::vector<std::string>({".DetCal", ".detcal", ".peaks", ".integrate"});
   declareProperty(
       Kernel::make_unique<API::MultipleFileProperty>("Filename", exts),
       "The input filename of the ISAW DetCal file (Two files "
       "allowed for SNAP) ");
 
-  declareProperty(
-      Kernel::make_unique<API::FileProperty>(
-          "Filename2", "", API::FileProperty::OptionalLoad, ".DetCal"),
-      "The input filename of the second ISAW DetCal file (West "
-      "banks for SNAP) ");
+  declareProperty(Kernel::make_unique<API::FileProperty>(
+                      "Filename2", "", API::FileProperty::OptionalLoad, exts),
+                  "The input filename of the second ISAW DetCal file (West "
+                  "banks for SNAP) ");
 
   declareProperty("TimeOffset", 0.0, "Time Offset", Direction::Output);
 }
diff --git a/Framework/DataHandling/src/LoadNexusLogs.cpp b/Framework/DataHandling/src/LoadNexusLogs.cpp
index 3bcdc76be3eafd14617bff2361d56560fb3906a9..7cea29bc3762d9254b7226a761c64ca8159389ca 100644
--- a/Framework/DataHandling/src/LoadNexusLogs.cpp
+++ b/Framework/DataHandling/src/LoadNexusLogs.cpp
@@ -473,8 +473,8 @@ void LoadNexusLogs::loadNPeriods(
     API::Run &run = workspace->mutableRun();
     const std::string protonChargeByPeriodLabel = "proton_charge_by_period";
     if (!run.hasProperty(protonChargeByPeriodLabel)) {
-      run.addProperty(new ArrayProperty<double>(protonChargeByPeriodLabel,
-                                                protonChargeByPeriod));
+      run.addProperty(new ArrayProperty<double>(
+          protonChargeByPeriodLabel, std::move(protonChargeByPeriod)));
     }
     file.closeGroup();
   } catch (::NeXus::Exception &) {
diff --git a/Framework/DataHandling/src/LoadNexusMonitors2.cpp b/Framework/DataHandling/src/LoadNexusMonitors2.cpp
index c7170e43299e8ffaa40369047ac9abd008b66472..24eb8df7bcf3299cb5d16678c0b04e3cc4dbc72e 100644
--- a/Framework/DataHandling/src/LoadNexusMonitors2.cpp
+++ b/Framework/DataHandling/src/LoadNexusMonitors2.cpp
@@ -426,18 +426,16 @@ void LoadNexusMonitors2::runLoadLogs(const std::string filename,
  **/
 bool LoadNexusMonitors2::canOpenAsNeXus(const std::string &fname) {
   bool res = true;
-  ::NeXus::File *f = nullptr;
+  std::unique_ptr<::NeXus::File> filePointer;
   try {
-    f = new ::NeXus::File(fname);
-    if (f)
-      f->getEntries();
+    filePointer = std::make_unique<::NeXus::File>(fname);
+    if (filePointer)
+      filePointer->getEntries();
   } catch (::NeXus::Exception &e) {
     g_log.error() << "Failed to open as a NeXus file: '" << fname
                   << "', error description: " << e.what() << '\n';
     res = false;
   }
-  if (f)
-    delete f;
   return res;
 }
 
diff --git a/Framework/DataHandling/src/LoadSampleEnvironment.cpp b/Framework/DataHandling/src/LoadSampleEnvironment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a0fd6bf8e247eab190a32ddd7ca3bc51e5caea76
--- /dev/null
+++ b/Framework/DataHandling/src/LoadSampleEnvironment.cpp
@@ -0,0 +1,324 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "MantidDataHandling/LoadSampleEnvironment.h"
+#include "MantidDataHandling/LoadAsciiStl.h"
+#include "MantidDataHandling/LoadBinaryStl.h"
+#include "MantidDataHandling/ReadMaterial.h"
+#include "MantidGeometry/Instrument/Container.h"
+#include "MantidGeometry/Instrument/SampleEnvironment.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+
+#include "MantidAPI/FileProperty.h"
+#include "MantidAPI/InstrumentValidator.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/Sample.h"
+
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/EnabledWhenProperty.h"
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/MandatoryValidator.h"
+
+#include <Poco/File.h>
+#include <boost/algorithm/string.hpp>
+#include <cmath>
+#include <fstream>
+
+namespace Mantid {
+namespace DataHandling {
+
+// Register the algorithm into the algorithm factory
+DECLARE_ALGORITHM(LoadSampleEnvironment)
+
+using namespace Kernel;
+using namespace API;
+using namespace Geometry;
+
+void LoadSampleEnvironment::init() {
+  auto wsValidator = boost::make_shared<API::InstrumentValidator>();
+  ;
+
+  // input workspace
+  declareProperty(make_unique<WorkspaceProperty<>>(
+                      "InputWorkspace", "", Direction::Input, wsValidator),
+                  "The name of the workspace containing the instrument to add "
+                  "the Environment");
+
+  // Environment file
+  const std::vector<std::string> extensions{".stl"};
+  declareProperty(
+      make_unique<FileProperty>("Filename", "", FileProperty::Load, extensions),
+      "The path name of the file containing the Environment");
+
+  // Output workspace
+  declareProperty(make_unique<WorkspaceProperty<>>("OutputWorkspace", "",
+                                                   Direction::Output),
+                  "The name of the workspace that will contain the loaded "
+                  "Environment of the sample");
+
+  // Environment Name
+  declareProperty("EnvironmentName", "Environment");
+
+  // New Can or Add
+  declareProperty("Add", false);
+
+  // Vector to translate mesh
+  declareProperty(
+      make_unique<ArrayProperty<double>>("TranslationVector", "0,0,0"),
+      "Vector by which to translate the loaded environment");
+
+  // Matrix to rotate mesh
+  declareProperty(make_unique<ArrayProperty<double>>(
+                      "RotationMatrix", "1.0,0.0,0.0,0.0,1.0,0.0,1.0,0.0,0.0"),
+                  "Rotation Matrix in format x1,x2,x3,y1,y2,y3,z1,z2,z3");
+
+  declareProperty("SetMaterial", false);
+
+  // properties for SetMaterial
+
+  declareProperty("ChemicalFormula", "",
+                  "The chemical formula, see examples in documentation");
+
+  declareProperty("AtomicNumber", 0, "The atomic number");
+  declareProperty("MassNumber", 0,
+                  "Mass number if ion (use 0 for default mass sensity)");
+  auto mustBePositive = boost::make_shared<BoundedValidator<double>>();
+  mustBePositive->setLower(0.0);
+  declareProperty("SampleNumberDensity", EMPTY_DBL(), mustBePositive,
+                  "This number density of the sample in number of "
+                  "atoms per cubic angstrom will be used instead of "
+                  "calculated");
+  declareProperty("ZParameter", EMPTY_DBL(), mustBePositive,
+                  "Number of formula units in unit cell");
+  declareProperty("UnitCellVolume", EMPTY_DBL(), mustBePositive,
+                  "Unit cell volume in Angstoms^3. Will be calculated from the "
+                  "OrientedLattice if not supplied.");
+  declareProperty("CoherentXSection", EMPTY_DBL(), mustBePositive,
+                  "Optional:  This coherent cross-section for the sample "
+                  "material in barns will be used instead of tabulated");
+  declareProperty("IncoherentXSection", EMPTY_DBL(), mustBePositive,
+                  "Optional:  This incoherent cross-section for the sample "
+                  "material in barns will be used instead of tabulated");
+  declareProperty("AttenuationXSection", EMPTY_DBL(), mustBePositive,
+                  "Optional:  This absorption cross-section for the sample "
+                  "material in barns will be used instead of tabulated");
+  declareProperty("ScatteringXSection", EMPTY_DBL(), mustBePositive,
+                  "Optional:  This total scattering cross-section (coherent + "
+                  "incoherent) for the sample material in barns will be used "
+                  "instead of tabulated");
+  declareProperty("SampleMassDensity", EMPTY_DBL(), mustBePositive,
+                  "Measured mass density in g/cubic cm of the sample "
+                  "to be used to calculate the number density.");
+
+  // Perform Group Associations.
+  std::string formulaGrp("By Formula or Atomic Number");
+  setPropertyGroup("ChemicalFormula", formulaGrp);
+  setPropertyGroup("AtomicNumber", formulaGrp);
+  setPropertyGroup("MassNumber", formulaGrp);
+  setPropertySettings("ChemicalFormula", make_unique<EnabledWhenProperty>(
+                                             "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("AtomicNumber", make_unique<EnabledWhenProperty>(
+                                          "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("MassNumber", make_unique<EnabledWhenProperty>(
+                                        "SetMaterial", IS_NOT_DEFAULT));
+
+  std::string densityGrp("Sample Density");
+  setPropertyGroup("SampleNumberDensity", densityGrp);
+  setPropertyGroup("ZParameter", densityGrp);
+  setPropertyGroup("UnitCellVolume", densityGrp);
+  setPropertyGroup("SampleMassDensity", densityGrp);
+  setPropertySettings(
+      "SampleNumberDensity",
+      make_unique<EnabledWhenProperty>("SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("ZParameter", make_unique<EnabledWhenProperty>(
+                                        "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("UnitCellVolume", make_unique<EnabledWhenProperty>(
+                                            "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("SampleMassDensity", make_unique<EnabledWhenProperty>(
+                                               "SetMaterial", IS_NOT_DEFAULT));
+
+  std::string specificValuesGrp("Override Cross Section Values");
+  setPropertyGroup("CoherentXSection", specificValuesGrp);
+  setPropertyGroup("IncoherentXSection", specificValuesGrp);
+  setPropertyGroup("AttenuationXSection", specificValuesGrp);
+  setPropertyGroup("ScatteringXSection", specificValuesGrp);
+  setPropertySettings("CoherentXSection", make_unique<EnabledWhenProperty>(
+                                              "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("IncoherentXSection", make_unique<EnabledWhenProperty>(
+                                                "SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings(
+      "AttenuationXSection",
+      make_unique<EnabledWhenProperty>("SetMaterial", IS_NOT_DEFAULT));
+  setPropertySettings("ScatteringXSection", make_unique<EnabledWhenProperty>(
+                                                "SetMaterial", IS_NOT_DEFAULT));
+}
+
+std::map<std::string, std::string> LoadSampleEnvironment::validateInputs() {
+  std::map<std::string, std::string> result;
+  if (getProperty("SetMaterial")) {
+    ReadMaterial::MaterialParameters params;
+    params.chemicalSymbol = getPropertyValue("ChemicalFormula");
+    params.atomicNumber = getProperty("AtomicNumber");
+    params.massNumber = getProperty("MassNumber");
+    params.sampleNumberDensity = getProperty("SampleNumberDensity");
+    params.zParameter = getProperty("ZParameter");
+    params.unitCellVolume = getProperty("UnitCellVolume");
+    params.sampleMassDensity = getProperty("SampleMassDensity");
+    result = ReadMaterial::validateInputs(params);
+  }
+  return result;
+}
+
+void LoadSampleEnvironment::exec() {
+
+  MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
+  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
+
+  if (inputWS != outputWS) {
+    outputWS = inputWS->clone();
+  }
+
+  const std::string filename = getProperty("Filename");
+  const std::ifstream file(filename.c_str());
+  if (!file) {
+    g_log.error("Unable to open file: " + filename);
+    throw Exception::FileError("Unable to open file: ", filename);
+  }
+
+  boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+
+  std::unique_ptr<LoadAsciiStl> asciiStlReader = nullptr;
+  std::unique_ptr<LoadBinaryStl> binaryStlReader = nullptr;
+
+  if (getProperty("SetMaterial")) {
+    ReadMaterial::MaterialParameters params;
+    params.chemicalSymbol = getPropertyValue("ChemicalFormula");
+    params.atomicNumber = getProperty("AtomicNumber");
+    params.massNumber = getProperty("MassNumber");
+    params.sampleNumberDensity = getProperty("SampleNumberDensity");
+    params.zParameter = getProperty("ZParameter");
+    params.unitCellVolume = getProperty("UnitCellVolume");
+    params.sampleMassDensity = getProperty("SampleMassDensity");
+    params.coherentXSection = getProperty("CoherentXSection");
+    params.incoherentXSection = getProperty("IncoherentXSection");
+    params.attenuationXSection = getProperty("AttenuationXSection");
+    params.scatteringXSection = getProperty("ScatteringXSection");
+    binaryStlReader = std::make_unique<LoadBinaryStl>(filename, params);
+    asciiStlReader = std::make_unique<LoadAsciiStl>(filename, params);
+  } else {
+    binaryStlReader = std::make_unique<LoadBinaryStl>(filename);
+    asciiStlReader = std::make_unique<LoadAsciiStl>(filename);
+  }
+
+  if (binaryStlReader->isBinarySTL(filename)) {
+    environmentMesh = binaryStlReader->readStl();
+  } else if (asciiStlReader->isAsciiSTL(filename)) {
+    environmentMesh = asciiStlReader->readStl();
+  } else {
+    throw Kernel::Exception::ParseError(
+        "Could not read file, did not match either STL Format", filename, 0);
+  }
+  environmentMesh = translate(environmentMesh);
+  environmentMesh = rotate(environmentMesh);
+
+  std::string name = getProperty("EnvironmentName");
+  const bool add = getProperty("Add");
+  Sample &sample = outputWS->mutableSample();
+  std::unique_ptr<Geometry::SampleEnvironment> environment = nullptr;
+  if (add) {
+    environment =
+        std::make_unique<Geometry::SampleEnvironment>(sample.getEnvironment());
+    environment->add(environmentMesh);
+  } else {
+    auto can = boost::make_shared<Container>(environmentMesh);
+    environment = std::make_unique<Geometry::SampleEnvironment>(name, can);
+  }
+  // Put Environment into sample.
+
+  std::string debugString =
+      "Environment has: " + std::to_string(environment->nelements()) +
+      " elements.";
+
+  sample.setEnvironment(std::move(environment));
+
+  auto translatedVertices = environmentMesh->getVertices();
+  if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
+    int i = 0;
+    for (double vertex : translatedVertices) {
+      i++;
+      g_log.debug(std::to_string(vertex));
+      if (i % 3 == 0) {
+        g_log.debug("\n");
+      }
+    }
+  }
+  // get the material name and number density for debug
+  const auto outMaterial =
+      outputWS->sample().getEnvironment().container()->material();
+  debugString += "\n"
+                 "Environment Material: " +
+                 outMaterial.name();
+  debugString += "\n"
+                 "Environment Material Number Density: " +
+                 std::to_string(outMaterial.numberDensity());
+  // Set output workspace
+  setProperty("OutputWorkspace", outputWS);
+  g_log.debug(debugString);
+}
+
+/**
+ * translates the environment by a provided matrix
+ * @param environmentMesh The environment to translate
+ * @returns a shared pointer to the newly translated environment
+ */
+boost::shared_ptr<MeshObject> LoadSampleEnvironment::translate(
+    boost::shared_ptr<MeshObject> environmentMesh) {
+  const std::vector<double> translationVector =
+      getProperty("TranslationVector");
+  std::vector<double> checkVector = std::vector<double>(3, 0.0);
+  if (translationVector != checkVector) {
+    if (translationVector.size() != 3) {
+      throw std::invalid_argument(
+          "Invalid Translation vector, must have exactly 3 dimensions");
+    }
+    Kernel::V3D translate = Kernel::V3D(
+        translationVector[0], translationVector[1], translationVector[2]);
+    environmentMesh->translate(translate);
+  }
+  return environmentMesh;
+}
+
+/**
+ * Rotates the environment by a provided matrix
+ * @param environmentMesh The environment to rotate
+ * @returns a shared pointer to the newly rotated environment
+ */
+boost::shared_ptr<MeshObject>
+LoadSampleEnvironment::rotate(boost::shared_ptr<MeshObject> environmentMesh) {
+  const std::vector<double> rotationMatrix = getProperty("RotationMatrix");
+  double valueList[] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0};
+  std::vector<double> checkVector1 =
+      std::vector<double>(std::begin(valueList), std::end(valueList));
+  if (rotationMatrix != checkVector1) {
+    if (rotationMatrix.size() != 9) {
+
+      throw std::invalid_argument(
+          "Invalid Rotation Matrix, must have exactly 9 values, not: " +
+          std::to_string(rotationMatrix.size()));
+    }
+    Kernel::Matrix<double> rotation = Kernel::Matrix<double>(rotationMatrix);
+    double determinant = rotation.determinant();
+    if (!(std::abs(determinant) == 1.0)) {
+      throw std::invalid_argument("Invalid Rotation Matrix");
+    }
+    environmentMesh->rotate(rotation);
+  }
+  return environmentMesh;
+}
+
+} // namespace DataHandling
+} // namespace Mantid
diff --git a/Framework/DataHandling/src/LoadSampleShape.cpp b/Framework/DataHandling/src/LoadSampleShape.cpp
index 22e65d1143578a80915523edd6b7995e951fc400..76ed9e02aa13d56a095b4266412d50636a8a0791 100644
--- a/Framework/DataHandling/src/LoadSampleShape.cpp
+++ b/Framework/DataHandling/src/LoadSampleShape.cpp
@@ -50,10 +50,10 @@ bool getOFFline(std::ifstream &file, std::string &line) {
   return true;
 }
 
-void readOFFVertices(std::ifstream &file, uint16_t nVertices,
+void readOFFVertices(std::ifstream &file, uint32_t nVertices,
                      std::vector<V3D> &vertices) {
   std::string line;
-  for (uint16_t i = 0; i < nVertices; i++) {
+  for (uint32_t i = 0; i < nVertices; i++) {
     if (getOFFline(file, line)) {
       std::vector<std::string> tokens;
       boost::split(tokens, line, boost::is_any_of(" "),
@@ -72,12 +72,12 @@ void readOFFVertices(std::ifstream &file, uint16_t nVertices,
   }
 }
 
-void readOFFTriangles(std::ifstream &file, uint16_t nTriangles,
-                      std::vector<uint16_t> &triangleIndices) {
+void readOFFTriangles(std::ifstream &file, uint32_t nTriangles,
+                      std::vector<uint32_t> &triangleIndices) {
   std::string line;
-  uint16_t t1, t2, t3;
+  uint32_t t1, t2, t3;
   size_t nFaceVertices;
-  for (uint16_t i = 0; i < nTriangles; i++) {
+  for (uint32_t i = 0; i < nTriangles; i++) {
     if (getOFFline(file, line)) {
       std::vector<std::string> tokens;
       boost::split(tokens, line, boost::is_any_of(" "),
@@ -85,9 +85,9 @@ void readOFFTriangles(std::ifstream &file, uint16_t nTriangles,
       if (tokens.size() >= 4) {
         nFaceVertices = boost::lexical_cast<size_t>(tokens[0]);
         if (nFaceVertices == 3) {
-          t1 = boost::lexical_cast<uint16_t>(tokens[1]);
-          t2 = boost::lexical_cast<uint16_t>(tokens[2]);
-          t3 = boost::lexical_cast<uint16_t>(tokens[3]);
+          t1 = boost::lexical_cast<uint32_t>(tokens[1]);
+          t2 = boost::lexical_cast<uint32_t>(tokens[2]);
+          t3 = boost::lexical_cast<uint32_t>(tokens[3]);
         } else {
           throw std::runtime_error("OFF face is not a triangle.");
         }
@@ -105,10 +105,10 @@ void readOFFTriangles(std::ifstream &file, uint16_t nTriangles,
 }
 
 std::unique_ptr<MeshObject> readOFFMeshObject(std::ifstream &file) {
-  std::vector<uint16_t> triangleIndices;
+  std::vector<uint32_t> triangleIndices;
   std::vector<V3D> vertices;
-  uint16_t nVertices;
-  uint16_t nTriangles;
+  uint32_t nVertices;
+  uint32_t nTriangles;
 
   std::string line;
   // Get number of vetrtices and faces
@@ -117,8 +117,8 @@ std::unique_ptr<MeshObject> readOFFMeshObject(std::ifstream &file) {
     boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on);
     if (tokens.size() == 3) {
       try {
-        nVertices = boost::lexical_cast<uint16_t>(tokens[0]);
-        nTriangles = boost::lexical_cast<uint16_t>(tokens[1]);
+        nVertices = boost::lexical_cast<uint32_t>(tokens[0]);
+        nTriangles = boost::lexical_cast<uint32_t>(tokens[1]);
       } catch (...) {
         throw std::runtime_error("Error in reading numbers of OFF vertices and "
                                  "triangles, which may be too large");
@@ -188,14 +188,14 @@ void LoadSampleShape::exec() {
     outputWS = inputWS->clone();
   }
 
-  std::string filename = getProperty("Filename");
+  const std::string filename = getProperty("Filename");
   std::ifstream file(filename.c_str());
   if (!file) {
     g_log.error("Unable to open file: " + filename);
     throw Exception::FileError("Unable to open file: ", filename);
   }
 
-  std::string filetype = filename.substr(filename.size() - 3);
+  const std::string filetype = filename.substr(filename.size() - 3);
 
   boost::shared_ptr<MeshObject> shape = nullptr;
   if (filetype == "off") {
@@ -203,10 +203,10 @@ void LoadSampleShape::exec() {
   } else /* stl */ {
     auto asciiStlReader = LoadAsciiStl(filename);
     auto binaryStlReader = LoadBinaryStl(filename);
-    if (asciiStlReader.isAsciiSTL()) {
-      shape = asciiStlReader.readStl();
-    } else if (binaryStlReader.isBinarySTL()) {
+    if (binaryStlReader.isBinarySTL(filename)) {
       shape = binaryStlReader.readStl();
+    } else if (asciiStlReader.isAsciiSTL(filename)) {
+      shape = asciiStlReader.readStl();
     } else {
       throw Kernel::Exception::ParseError(
           "Could not read file, did not match either STL Format", filename, 0);
diff --git a/Framework/DataHandling/src/LoadSpice2D.cpp b/Framework/DataHandling/src/LoadSpice2D.cpp
index 1aa83d4cd442ca4c8fbf01d6c03cd72c0e0ffa18..e6262d3bef0350a26b6037cbfadf6a3c3965697a 100644
--- a/Framework/DataHandling/src/LoadSpice2D.cpp
+++ b/Framework/DataHandling/src/LoadSpice2D.cpp
@@ -192,7 +192,6 @@ void LoadSpice2D::exec() {
 
   // run load instrument
   std::string instrument = metadata["Header/Instrument"];
-  runLoadInstrument(instrument, m_workspace);
 
   // ugly hack for Biosans wing detector:
   // it tests if there is metadata tagged with the wing detector
@@ -201,15 +200,11 @@ void LoadSpice2D::exec() {
     double angle = boost::lexical_cast<double>(
         metadata["Motor_Positions/det_west_wing_rot"]);
     rotateDetector(-angle);
-    // To make the property is set and the detector rotates!
-    runLoadInstrument(instrument, m_workspace);
   }
-
   // sample_detector_distances
-  double detector_distance = detectorDistance(metadata);
-  double detector_tranlation = detectorTranslation(metadata);
-  moveDetector(detector_distance, detector_tranlation);
-
+  detectorDistance(metadata);
+  detectorTranslation(metadata);
+  runLoadInstrument(instrument, m_workspace);
   setProperty("OutputWorkspace", m_workspace);
 }
 
@@ -272,7 +267,7 @@ void LoadSpice2D::setInputPropertiesAsMemberProperties() {
 }
 
 /**
- * Gets the wavelenght and wavelength spread from the  metadata
+ * Gets the wavelength and wavelength spread from the  metadata
  * and sets them as class attributes
  */
 void LoadSpice2D::setWavelength(std::map<std::string, std::string> &metadata) {
@@ -329,7 +324,7 @@ std::vector<int> LoadSpice2D::getData(const std::string &dataXpath = "//Data") {
 
     // Horrible hack:
     // Some old files had a: //Data/DetectorWing with dimensions:
-    // 16 x 256 = 4096. This must be igored as it is not in the IDF.
+    // 16 x 256 = 4096. This must be ignored as it is not in the IDF.
     if (detectorXpath.find("DetectorWing") != std::string::npos &&
         dims.first * dims.second <= 4096)
       break;
@@ -572,10 +567,10 @@ void LoadSpice2D::setMetadataAsRunProperties(
  * the file
  * Last Changes:
  * If SDD tag is available in the metadata set that as sample detector distance
- * @return : sample_detector_distance
+ * Puts a numeric series in the log with the value of sample_detector_distance
  */
-double
-LoadSpice2D::detectorDistance(std::map<std::string, std::string> &metadata) {
+void LoadSpice2D::detectorDistance(
+    std::map<std::string, std::string> &metadata) {
 
   double sample_detector_distance = 0, sample_detector_distance_offset = 0,
          sample_si_window_distance = 0;
@@ -583,17 +578,14 @@ LoadSpice2D::detectorDistance(std::map<std::string, std::string> &metadata) {
   // check if it's the new format
   if (metadata.find("Motor_Positions/sample_det_dist") != metadata.end()) {
     // Old Format
-
     from_string<double>(sample_detector_distance,
                         metadata["Motor_Positions/sample_det_dist"], std::dec);
     sample_detector_distance *= 1000.0;
     addRunProperty<double>("sample-detector-distance", sample_detector_distance,
                            "mm");
-
     sample_detector_distance_offset =
         addRunProperty<double>(metadata, "Header/tank_internal_offset",
                                "sample-detector-distance-offset", "mm");
-
     sample_si_window_distance = addRunProperty<double>(
         metadata, "Header/sample_to_flange", "sample-si-window-distance", "mm");
 
@@ -602,12 +594,9 @@ LoadSpice2D::detectorDistance(std::map<std::string, std::string> &metadata) {
     from_string<double>(sample_detector_distance,
                         metadata["Motor_Positions/flange_det_dist"], std::dec);
     sample_detector_distance *= 1000.0;
-
     addRunProperty<double>("sample-detector-distance-offset", 0, "mm");
-
     addRunProperty<double>("sample-detector-distance", sample_detector_distance,
                            "mm");
-
     sample_si_window_distance = addRunProperty<double>(
         metadata, "Header/sample_to_flange", "sample-si-window-distance", "mm");
   }
@@ -637,58 +626,35 @@ LoadSpice2D::detectorDistance(std::map<std::string, std::string> &metadata) {
   addRunProperty<double>("total-sample-detector-distance",
                          total_sample_detector_distance, "mm");
 
+  // Add to the log!
+  API::Run &runDetails = m_workspace->mutableRun();
+  auto *p = new Mantid::Kernel::TimeSeriesProperty<double>("sdd");
+  p->addValue(DateAndTime::getCurrentTime(), total_sample_detector_distance);
+  runDetails.addLogData(p);
+
   // Store sample-detector distance
   declareProperty("SampleDetectorDistance", sample_detector_distance,
                   Kernel::Direction::Output);
-
-  return sample_detector_distance;
 }
-
-double
-LoadSpice2D::detectorTranslation(std::map<std::string, std::string> &metadata) {
+/**
+ * Puts a numeric series in the log with the value of detector translation
+ */
+void LoadSpice2D::detectorTranslation(
+    std::map<std::string, std::string> &metadata) {
 
   // detectorTranslations
   double detectorTranslation = 0;
   from_string<double>(detectorTranslation,
                       metadata["Motor_Positions/detector_trans"], std::dec);
-  detectorTranslation /= 1000.0; // mm to meters conversion
-
-  g_log.debug() << "Detector Translation = " << detectorTranslation
-                << " meters." << '\n';
-  return detectorTranslation;
-}
-
-/**
- * Places the detector at the right sample_detector_distance
- */
-void LoadSpice2D::moveDetector(double sample_detector_distance,
-                               double translation_distance) {
-  // Some tests fail if the detector is moved here.
-  // TODO: Move the detector here and not the SANSLoad
-  UNUSED_ARG(translation_distance);
-
-  // Move the detector to the right position
-  API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");
-
-  // Finding the name of the detector object.
-  std::string detID =
-      m_workspace->getInstrument()->getStringParameter("detector-name")[0];
+  // Add to the log!
+  API::Run &runDetails = m_workspace->mutableRun();
+  auto *p =
+      new Mantid::Kernel::TimeSeriesProperty<double>("detector-translation");
+  p->addValue(DateAndTime::getCurrentTime(), detectorTranslation);
+  runDetails.addLogData(p);
 
-  g_log.information("Moving " + detID);
-  try {
-    mover->setProperty<API::MatrixWorkspace_sptr>("Workspace", m_workspace);
-    mover->setProperty("ComponentName", detID);
-    mover->setProperty("Z", sample_detector_distance / 1000.0);
-    // mover->setProperty("X", -translation_distance);
-    mover->execute();
-  } catch (std::invalid_argument &e) {
-    g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm");
-    g_log.error(e.what());
-  } catch (std::runtime_error &e) {
-    g_log.error(
-        "Unable to successfully run MoveInstrumentComponent Child Algorithm");
-    g_log.error(e.what());
-  }
+  g_log.debug() << "Detector Translation = " << detectorTranslation << " mm."
+                << '\n';
 }
 
 /** Run the Child Algorithm LoadInstrument (as for LoadRaw)
diff --git a/Framework/DataHandling/src/LoadSpiceAscii.cpp b/Framework/DataHandling/src/LoadSpiceAscii.cpp
index 49bd27872db34b8473cd039fa6d08af14e415508..8e125c4701e66a091b22ece472cc216e9584779b 100644
--- a/Framework/DataHandling/src/LoadSpiceAscii.cpp
+++ b/Framework/DataHandling/src/LoadSpiceAscii.cpp
@@ -128,7 +128,7 @@ void LoadSpiceAscii::init() {
   defaultlogformat[2] = "time";
   defaultlogformat[3] = "HH:MM:SS AM";
   declareProperty(Kernel::make_unique<ArrayProperty<std::string>>(
-                      "DateAndTimeLog", defaultlogformat),
+                      "DateAndTimeLog", std::move(defaultlogformat)),
                   "Name and format for date and time");
 
   // Output
diff --git a/Framework/DataHandling/src/LoadStl.cpp b/Framework/DataHandling/src/LoadStl.cpp
index f075134197b34dd2ddb9bf35d9c8efa0b6406271..8d33bc0325c25a3e3ff3510ba50251744758156d 100644
--- a/Framework/DataHandling/src/LoadStl.cpp
+++ b/Framework/DataHandling/src/LoadStl.cpp
@@ -1,27 +1,30 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidDataHandling/LoadStl.h"
+#include "MantidKernel/V3D.h"
 #include <Poco/File.h>
 
+#include <functional>
+
 namespace Mantid {
 namespace DataHandling {
 
-// Adds vertex to list if distinct and returns index to vertex added or equal
-uint16_t LoadStl::addSTLVertex(Kernel::V3D &vertex) {
-  for (uint16_t i = 0; i < m_verticies.size(); ++i) {
-    if (areEqualVertices(vertex, m_verticies[i])) {
-      return i;
-    }
-  }
-  m_verticies.emplace_back(vertex);
-  uint16_t index = static_cast<uint16_t>(m_verticies.size() - 1);
-  if (index != m_verticies.size() - 1) {
-    throw std::runtime_error("Too many vertices in solid");
-  }
-  return index;
+bool LoadStl::areEqualVertices(Kernel::V3D const &v1,
+                               Kernel::V3D const &v2) const {
+  const Kernel::V3D diff = v1 - v2;
+  const double nanoMetre = 1e-9;
+  return diff.norm() < nanoMetre; // This is 1 nanometre for a unit of a metre.
 }
 
-bool LoadStl::areEqualVertices(Kernel::V3D const &v1, Kernel::V3D const &v2) {
-  Kernel::V3D diff = v1 - v2;
-  return diff.norm() < 1e-9; // This is 1 nanometre for a unit of a metre.
+void LoadStl::changeToVector() {
+  m_verticies.resize(vertexSet.size());
+  for (auto const &mapValue : vertexSet) {
+    m_verticies[mapValue.second] = mapValue.first;
+  }
 }
 } // namespace DataHandling
 } // namespace Mantid
\ No newline at end of file
diff --git a/Framework/DataHandling/src/ORNLDataArchive.cpp b/Framework/DataHandling/src/ORNLDataArchive.cpp
index c3ec9081bb3543a801f757d18aa4862aaccaca5f..8eadaf1ceb8c66824fe8cc32caae83c2f9a787cb 100644
--- a/Framework/DataHandling/src/ORNLDataArchive.cpp
+++ b/Framework/DataHandling/src/ORNLDataArchive.cpp
@@ -48,6 +48,7 @@ namespace Mantid {
 namespace DataHandling {
 
 DECLARE_ARCHIVESEARCH(ORNLDataArchive, ORNLDataSearch)
+DECLARE_ARCHIVESEARCH(ORNLDataArchive, SNSDataSearch)
 
 /**
  * ****************
diff --git a/Framework/DataHandling/src/SNSDataArchive.cpp b/Framework/DataHandling/src/SNSDataArchive.cpp
deleted file mode 100644
index af276e1d0bed47629c23c5f54701eb371428fb7f..0000000000000000000000000000000000000000
--- a/Framework/DataHandling/src/SNSDataArchive.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include <sstream>
-
-#include "MantidAPI/ArchiveSearchFactory.h"
-#include "MantidDataHandling/SNSDataArchive.h"
-#include "MantidKernel/Exception.h"
-#include "MantidKernel/InternetHelper.h"
-#include "MantidKernel/Logger.h"
-
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-
-#include <Poco/AutoPtr.h>
-#include <Poco/DOM/DOMParser.h>
-#include <Poco/DOM/Document.h>
-#include <Poco/DOM/Element.h>
-#include <Poco/DOM/NodeList.h>
-#include <Poco/SAX/InputSource.h>
-
-namespace Mantid {
-namespace DataHandling {
-namespace {
-// Get a reference to the logger
-Kernel::Logger g_log("SNSDataArchive");
-/// Base url for restful web survice
-const std::string
-    BASE_URL("http://icat.sns.gov:2080/icat-rest-ws/datafile/filename/");
-} // namespace
-
-DECLARE_ARCHIVESEARCH(SNSDataArchive, SNSDataSearch)
-
-/**
- * @param filenames : List of files to search
- * @param exts : List of extensions to check against
- * @return list of archive locations
- */
-std::string
-SNSDataArchive::getArchivePath(const std::set<std::string> &filenames,
-                               const std::vector<std::string> &exts) const {
-  g_log.debug() << "getArchivePath([ ";
-  for (const auto &iter : filenames)
-    g_log.debug() << iter << " ";
-  g_log.information() << "], [ ";
-  for (const auto &iter : exts)
-    g_log.debug() << iter << " ";
-  g_log.debug() << "])\n";
-
-  auto iter = filenames.cbegin();
-  std::string filename = *iter;
-
-  // ICAT4 web service take upper case filename such as HYSA_2662
-  std::transform(filename.begin(), filename.end(), filename.begin(), toupper);
-
-  for (const auto &ext : exts) {
-    g_log.debug() << ext << ";";
-  }
-  g_log.debug() << "\n";
-
-  const std::string URL(BASE_URL + filename);
-  g_log.debug() << "URL: " << URL << "\n";
-
-  Kernel::InternetHelper inetHelper;
-  std::ostringstream rs;
-
-  int status = inetHelper.sendRequest(URL, rs);
-
-  // Create a DOM document from the response.
-  Poco::XML::DOMParser parser;
-  std::istringstream istrsource(rs.str());
-  Poco::XML::InputSource source(istrsource);
-  Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parse(&source);
-
-  std::vector<std::string> locations;
-
-  // Everything went fine, return the XML document.
-  // Otherwise look for an error message in the XML document.
-  if (status == Kernel::InternetHelper::HTTP_OK) {
-    std::string location;
-    Poco::AutoPtr<Poco::XML::NodeList> pList =
-        pDoc->getElementsByTagName("location");
-    for (unsigned long i = 0; i < pList->length(); i++) {
-      location = pList->item(i)->innerText();
-      g_log.debug() << "location: " << location << "\n";
-      locations.push_back(location);
-    }
-  }
-
-  for (const auto &ext : exts) {
-    std::string datafile = filename + ext;
-    std::vector<std::string>::const_iterator iter = locations.begin();
-    for (; iter != locations.end(); ++iter) {
-      if (boost::algorithm::ends_with((*iter), datafile)) {
-        return *iter;
-      } // end if
-    }   // end for iter
-
-  } // end for ext
-  return "";
-}
-
-} // namespace DataHandling
-} // namespace Mantid
diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp
index 08cc93a5ebdc934eed6f3bab9d54fa4919f45ffb..c60683ad0363c072ac35bb3c6b83616467122efb 100644
--- a/Framework/DataHandling/src/SaveGSS.cpp
+++ b/Framework/DataHandling/src/SaveGSS.cpp
@@ -201,7 +201,8 @@ void SaveGSS::init() {
   std::vector<int> default_precision(3, 9);
   declareProperty(
       Kernel::make_unique<Kernel::ArrayProperty<int>>(
-          "SLOGXYEPrecision", default_precision, precision_validator),
+          "SLOGXYEPrecision", std::move(default_precision),
+          std::move(precision_validator)),
       "Enter 3 integers as the precisions of output X, Y and E for SLOG data "
       "only."
       "Default is (9, 9, 9) if it is left empty.  Otherwise it is not "
diff --git a/Framework/DataHandling/src/SaveReflectometryAscii.cpp b/Framework/DataHandling/src/SaveReflectometryAscii.cpp
index 5ac34fa092d39490de6fb70aa97f9c7b405c485b..a39dbeacc6da5cafb6134e0e504a8c1ab0797716 100644
--- a/Framework/DataHandling/src/SaveReflectometryAscii.cpp
+++ b/Framework/DataHandling/src/SaveReflectometryAscii.cpp
@@ -37,10 +37,6 @@ using namespace API;
 // Register the algorithm into the algorithm factory
 DECLARE_ALGORITHM(SaveReflectometryAscii)
 
-auto visibleWhenFileExtension(const std::string s) {
-  return make_unique<VisibleWhenProperty>("FileExtension", IS_EQUAL_TO, s);
-}
-
 /// Initialise the algorithm
 void SaveReflectometryAscii::init() {
   declareProperty(
@@ -53,28 +49,31 @@ void SaveReflectometryAscii::init() {
   declareProperty("FileExtension", ".mft",
                   boost::make_shared<StringListValidator>(extension),
                   "Choose the file extension according to the file format.");
-  auto mft = visibleWhenFileExtension(".mft");
-  auto cus = visibleWhenFileExtension("custom");
-  auto vis1 =
-      make_unique<VisibleWhenProperty>(std::move(mft), std::move(cus), OR);
-  auto vis2 = visibleWhenFileExtension("custom");
-  auto vis3 = visibleWhenFileExtension("custom");
-  auto vis4 = visibleWhenFileExtension("custom");
+  auto mft =
+      make_unique<VisibleWhenProperty>("FileExtension", IS_EQUAL_TO, "mft");
+  auto cus =
+      make_unique<VisibleWhenProperty>("FileExtension", IS_EQUAL_TO, "custom");
   declareProperty(make_unique<ArrayProperty<std::string>>("LogList"),
                   "List of logs to write to file.");
-  setPropertySettings("LogList", std::move(vis1));
+  setPropertySettings("LogList", make_unique<VisibleWhenProperty>(
+                                     std::move(mft), std::move(cus), OR));
   declareProperty("WriteHeader", false, "Whether to write header lines.");
-  setPropertySettings("WriteHeader", std::move(vis2));
+  setPropertySettings(
+      "WriteHeader",
+      make_unique<VisibleWhenProperty>("FileExtension", IS_EQUAL_TO, "custom"));
   std::vector<std::string> separator = {"comma", "space", "tab"};
   declareProperty(
       "WriteResolution", true,
       "Whether to compute resolution values and write them as fourth "
       "data column.");
-  setPropertySettings("WriteResolution", std::move(vis3));
+  setPropertySettings(
+      "WriteResolution",
+      make_unique<VisibleWhenProperty>("FileExtension", IS_EQUAL_TO, "custom"));
   declareProperty("Separator", "tab",
                   boost::make_shared<StringListValidator>(separator),
                   "The separator used for splitting data columns.");
-  setPropertySettings("Separator", std::move(vis4));
+  setPropertySettings("Separator", make_unique<VisibleWhenProperty>(
+                                       "FileExtension", IS_EQUAL_TO, "custom"));
 }
 
 /// Input validation for single MatrixWorkspace
@@ -177,58 +176,72 @@ void SaveReflectometryAscii::outputval(std::string val) {
   m_file << std::setw(28) << val;
 }
 
-/// Retrieve sample log information
-std::string SaveReflectometryAscii::sampleInfo(const std::string &logName) {
+/// Retrieve sample log value
+std::string SaveReflectometryAscii::sampleLogValue(const std::string &logName) {
   auto run = m_ws->run();
   try {
     return boost::lexical_cast<std::string>(run.getLogData(logName)->value());
   } catch (Exception::NotFoundError &) {
+    return "Not defined";
   }
-  return "Not defined";
 }
 
-/// Write one header line
+/// Retrieve sample log unit
+std::string SaveReflectometryAscii::sampleLogUnit(const std::string &logName) {
+  auto run = m_ws->run();
+  try {
+    return " " +
+           boost::lexical_cast<std::string>(run.getLogData(logName)->units());
+  } catch (Exception::NotFoundError &) {
+    return "";
+  }
+}
+
+/** Write one header line
+ *  @param logName :: the name of a SampleLog entry to get its value from
+ *  @param logNameFixed :: the name of the SampleLog entry defined by the header
+ */
 void SaveReflectometryAscii::writeInfo(const std::string logName,
-                                       const std::string logValue) {
-  if (!logValue.empty())
-    m_file << logName << " : " << sampleInfo(logValue) << '\n';
-  else
-    m_file << logName << " : " << sampleInfo(logName) << '\n';
+                                       const std::string logNameFixed) {
+  const std::string logValue = sampleLogValue(logName);
+  const std::string logUnit = sampleLogUnit(logName);
+  if (!logNameFixed.empty()) {
+    // The logName corresponds to an existing header line of given name
+    m_file << logNameFixed;
+  } else {
+    // The user provided a log name which is not part of the defined header
+    m_file << logName;
+  }
+  m_file << " : " << logValue << logUnit << '\n';
 }
 
 /// Write header lines
 void SaveReflectometryAscii::header() {
   m_file << std::setfill(' ');
   m_file << "MFT\n";
-  std::map<std::string, std::string> logs;
-  logs["Instrument"] = "instrument.name";
-  logs["User-local contact"] = "user.namelocalcontact";
-  logs["Title"] = "title";
-  logs["Subtitle"] = "";
-  logs["Start date + time"] = "start_time";
-  logs["End date + time"] = "end_time";
-  logs["Theta 1 + dir + ref numbers"] = "";
-  logs["Theta 2 + dir + ref numbers"] = "";
-  logs["Theta 3 + dir + ref numbers"] = "";
-  writeInfo("Instrument", "instrument.name");
-  writeInfo("User-local contact", "user.namelocalcontact");
-  writeInfo("Title", "title");
-  writeInfo("Subtitle", "");
-  writeInfo("Start date + time", "start_time");
-  writeInfo("End date + time", "end_time");
-  writeInfo("Theta 1 + dir + ref numbers", "");
-  writeInfo("Theta 2 + dir + ref numbers", "");
-  writeInfo("Theta 3 + dir + ref numbers", "");
+  std::vector<std::string> logs{"instrument.name", "user.namelocalcontact",
+                                "title", "start_time", "end_time"};
+  writeInfo("instrument.name", "Instrument");
+  writeInfo("user.namelocalcontact", "User-local contact");
+  writeInfo("title", "Title");
+  writeInfo("", "Subtitle");
+  writeInfo("start_time", "Start date + time");
+  writeInfo("end_time", "End date + time");
+  writeInfo("", "Theta 1 + dir + ref numbers");
+  writeInfo("", "Theta 2 + dir + ref numbers");
+  writeInfo("", "Theta 3 + dir + ref numbers");
   const std::vector<std::string> logList = getProperty("LogList");
-  int nlogs = 0;
+  int nLogs = 0;
   for (const auto &log : logList) {
-    if (logs.find(log) == logs.end()) {
+    if (find(logs.cbegin(), logs.cend(), log) ==
+        logs.end()) { // do not repeat a log
       writeInfo(log);
-      ++nlogs;
+      ++nLogs;
     }
   }
-  for (auto i = nlogs + 1; i < 10; ++i)
-    writeInfo("Parameter ");
+  // Write "Parameter : Not defined" 9 times minus the number of new user logs
+  for (auto i = nLogs; i < 9; ++i)
+    writeInfo("", "Parameter ");
   m_file << "Number of file format : "
          << "40\n";
   m_file << "Number of data points : " << m_ws->y(0).size() << '\n';
diff --git a/Framework/DataHandling/src/SetSample.cpp b/Framework/DataHandling/src/SetSample.cpp
index f2c00b40591fdfeac199585f4774e59a8cf188a7..29f4074a4a3e77cbc2b53768537367de43d59404 100644
--- a/Framework/DataHandling/src/SetSample.cpp
+++ b/Framework/DataHandling/src/SetSample.cpp
@@ -11,6 +11,7 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidGeometry/Instrument/SampleEnvironment.h"
 #include "MantidGeometry/Instrument/SampleEnvironmentFactory.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
@@ -303,8 +304,7 @@ const Geometry::SampleEnvironment *SetSample::setSampleEnvironment(
   SampleEnvironmentFactory factory(std::move(finder));
   auto sampleEnviron =
       factory.create(facilityName, instrumentName, envName, canName);
-  workspace->mutableSample().setEnvironment(sampleEnviron.release());
-
+  workspace->mutableSample().setEnvironment(std::move(sampleEnviron));
   return &(workspace->sample().getEnvironment());
 }
 
diff --git a/Framework/DataHandling/test/CompressEventsTest.h b/Framework/DataHandling/test/CompressEventsTest.h
index f3a7b711f854c9333a988f70e36488ba037df57e..64c8568bfb1b09baf39cf1612b9474936a7c9d93 100644
--- a/Framework/DataHandling/test/CompressEventsTest.h
+++ b/Framework/DataHandling/test/CompressEventsTest.h
@@ -12,6 +12,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidDataHandling/CompressEvents.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidKernel/Unit.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using Mantid::MantidVecPtr;
@@ -113,8 +114,8 @@ public:
     TS_ASSERT_DELTA(output->readY(0)[1], 2.0, 1e-5);
     TS_ASSERT_DELTA(output->readE(0)[1], M_SQRT2, 1e-5);
     TS_ASSERT_EQUALS(output->YUnit(), input->YUnit());
-    TS_ASSERT_EQUALS(output->getAxis(0)->unit(), input->getAxis(0)->unit());
-    TS_ASSERT_EQUALS(output->getAxis(1)->unit(), input->getAxis(1)->unit());
+    TS_ASSERT(*output->getAxis(0)->unit() == *input->getAxis(0)->unit());
+    TS_ASSERT(*output->getAxis(1)->unit() == *input->getAxis(1)->unit());
   }
 
   // WEIGHTED_NOTIME tests
diff --git a/Framework/DataHandling/test/LoadAsciiStlTest.h b/Framework/DataHandling/test/LoadAsciiStlTest.h
index 19d67dd4ce207a4de0432575937eb05fe23fb80c..64f6c29fead36eb448d8848d51f4da5e99d30ee9 100644
--- a/Framework/DataHandling/test/LoadAsciiStlTest.h
+++ b/Framework/DataHandling/test/LoadAsciiStlTest.h
@@ -1,3 +1,9 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef LOAD_ASCIISTL_TEST_H_
 #define LOAD_ASCIISTL_TEST_H_
 
@@ -17,7 +23,6 @@ public:
   static LoadAsciiStlTest *createSuite() { return new LoadAsciiStlTest(); }
   static void destroySuite(LoadAsciiStlTest *suite) { delete suite; }
 
-  void testInit() {}
   void test_cube() {
     std::string path = FileFinder::Instance().getFullPath("cube.stl");
     auto Loader = LoadAsciiStl(path);
@@ -67,13 +72,13 @@ public:
   void test_return_false_on_binary_stl() {
     std::string path = FileFinder::Instance().getFullPath("cubeBin.stl");
     auto Loader = LoadAsciiStl(path);
-    TS_ASSERT(!(Loader.isAsciiSTL()));
+    TS_ASSERT(!(Loader.isAsciiSTL(path)));
   }
 
   void test_return_false_on_invalid_solid() {
     std::string path = FileFinder::Instance().getFullPath("invalid_solid.stl");
     auto Loader = LoadAsciiStl(path);
-    TS_ASSERT(!(Loader.isAsciiSTL()));
+    TS_ASSERT(!(Loader.isAsciiSTL(path)));
   }
 };
 
diff --git a/Framework/DataHandling/test/LoadBinaryStlTest.h b/Framework/DataHandling/test/LoadBinaryStlTest.h
index fd5c3e33cf86ec75a9eb7928a7791002b889eb01..7a0ef1cc073d6d10b187fe5c9a0e6e1821606519 100644
--- a/Framework/DataHandling/test/LoadBinaryStlTest.h
+++ b/Framework/DataHandling/test/LoadBinaryStlTest.h
@@ -1,3 +1,9 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef LOAD_BINARYSTL_TEST_H_
 #define LOAD_BINARYSTL_TEST_H_
 #include "MantidAPI/FileFinder.h"
@@ -48,7 +54,7 @@ public:
     std::string path =
         FileFinder::Instance().getFullPath("invalid_vertexBin.stl");
     auto loader = LoadBinaryStl(path);
-    TS_ASSERT(!(loader.isBinarySTL()));
+    TS_ASSERT(!(loader.isBinarySTL(path)));
   }
   // check that isBinaryStl returns false if the file contains an incomplete
   // triangle
@@ -56,14 +62,20 @@ public:
     std::string path =
         FileFinder::Instance().getFullPath("invalid_triangleBin.stl");
     auto loader = LoadBinaryStl(path);
-    TS_ASSERT(!(loader.isBinarySTL()));
+    TS_ASSERT(!(loader.isBinarySTL(path)));
   }
 
   void test_fail_ascii_stl() {
     std::string path = FileFinder::Instance().getFullPath("cube.stl");
     auto loader = LoadBinaryStl(path);
-    TS_ASSERT(!(loader.isBinarySTL()));
+    TS_ASSERT(!(loader.isBinarySTL(path)));
   }
-};
 
+  void test_loading_large_stl() {
+    std::string path = FileFinder::Instance().getFullPath("SI-4200-610.stl");
+    auto loader = LoadBinaryStl(path);
+    auto LargeFile = loader.readStl();
+    assert_shape_matches(LargeFile, 174388, 424694, 21218, 1);
+  }
+};
 #endif /* LOAD_BINARYSTL_TEST_H_ */
\ No newline at end of file
diff --git a/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h b/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
index 3df375aa8c0de8a7676a81a10b80c47372bd3a06..915aefc77d284bd554b9c7510978b9215f175844 100644
--- a/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
+++ b/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
@@ -372,8 +372,8 @@ public:
     TS_ASSERT(load.setProperty("InputFile", file.getFileName()));
     TS_ASSERT(load.setProperty("OutputWorkspace", ws));
 
-    std::string errorMsg =
-        "Bad number of spectra list in " + file.getFileName() + " on line 4";
+    std::string errorMsg = "Bad number of spectra list in \"" +
+                           file.getFileName() + "\" on line 4";
 
     TS_ASSERT_THROWS_EQUALS(load.execute(), const Exception::ParseError &e,
                             e.what(), errorMsg);
@@ -398,8 +398,9 @@ public:
     TS_ASSERT(load.setProperty("InputFile", file.getFileName()));
     TS_ASSERT(load.setProperty("OutputWorkspace", ws));
 
-    std::string errorMsg = "Premature end of file, expecting spectra list in " +
-                           file.getFileName() + " on line 4";
+    std::string errorMsg =
+        "Premature end of file, expecting spectra list in \"" +
+        file.getFileName() + "\" on line 4";
 
     TS_ASSERT_THROWS_EQUALS(load.execute(), const Exception::ParseError &e,
                             e.what(), errorMsg);
@@ -426,8 +427,8 @@ public:
     TS_ASSERT(load.setProperty("OutputWorkspace", ws));
 
     std::string errorMsg =
-        "Expected a single int for the number of group spectra in " +
-        file.getFileName() + " on line 3";
+        "Expected a single int for the number of group spectra in \"" +
+        file.getFileName() + "\" on line 3";
 
     TS_ASSERT_THROWS_EQUALS(load.execute(), const Exception::ParseError &e,
                             e.what(), errorMsg);
diff --git a/Framework/DataHandling/test/LoadEMUauTest.h b/Framework/DataHandling/test/LoadEMUauTest.h
index 4c9dffc97264f2a5f941523bbdfe05a4565c8d2b..e446176af3657fd2dc764e5d1497e14f57e0bc2b 100644
--- a/Framework/DataHandling/test/LoadEMUauTest.h
+++ b/Framework/DataHandling/test/LoadEMUauTest.h
@@ -15,6 +15,12 @@
 #include <Poco/Path.h>
 #include <Poco/TemporaryFile.h>
 
+#ifdef _MSC_VER
+// Disable warning on 'no suitable definition ..' as the extern
+// does not clear the warning. No issue linking.
+#pragma warning(disable : 4661)
+#endif
+
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
 using namespace Mantid::DataHandling;
@@ -23,14 +29,14 @@ using namespace Mantid::DataObjects;
 class LoadEMUauTest : public CxxTest::TestSuite {
 public:
   void test_load_emu_algorithm_init() {
-    LoadEMU algToBeTested;
+    LoadEMUTar algToBeTested;
 
     TS_ASSERT_THROWS_NOTHING(algToBeTested.initialize());
     TS_ASSERT(algToBeTested.isInitialized());
   }
 
   void test_load_emu_algorithm() {
-    LoadEMU algToBeTested;
+    LoadEMUTar algToBeTested;
 
     if (!algToBeTested.isInitialized())
       algToBeTested.initialize();
@@ -72,7 +78,8 @@ public:
 
     // test some data properties
     auto logpm = [&run](std::string tag) {
-      return run.getPropertyValueAsType<double>(tag);
+      return dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty(tag))
+          ->firstValue();
     };
     TS_ASSERT_DELTA(logpm("DopplerFrequency"), 9.974, 1.0e-3);
     TS_ASSERT_DELTA(logpm("DopplerAmplitude"), 0.075, 1.0e-4);
@@ -87,4 +94,4 @@ public:
   }
 };
 
-#endif /*LoadEMUTEST_H_*/
\ No newline at end of file
+#endif /*LoadEMUTEST_H_*/
diff --git a/Framework/DataHandling/test/LoadILLDiffractionTest.h b/Framework/DataHandling/test/LoadILLDiffractionTest.h
index 3e076c3edc90a8fb50822252b185a9b676f64f3d..e9d2127006f444d86589a1f4158bb43ef3b8bada 100644
--- a/Framework/DataHandling/test/LoadILLDiffractionTest.h
+++ b/Framework/DataHandling/test/LoadILLDiffractionTest.h
@@ -15,6 +15,7 @@
 #include "MantidDataHandling/LoadILLDiffraction.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidKernel/FacilityInfo.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
@@ -32,7 +33,22 @@ public:
   void setUp() override {
     ConfigService::Instance().appendDataSearchSubDir("ILL/D20/");
     ConfigService::Instance().appendDataSearchSubDir("ILL/D2B/");
+
+    m_oldFacility = ConfigService::Instance().getFacility().name();
     ConfigService::Instance().setFacility("ILL");
+
+    m_oldInstrument = ConfigService::Instance().getInstrument().name();
+    ConfigService::Instance().setString("default.instrument", "");
+  }
+
+  void tearDown() override {
+    if (!m_oldFacility.empty()) {
+      ConfigService::Instance().setFacility(m_oldFacility);
+    }
+    if (!m_oldInstrument.empty()) {
+      ConfigService::Instance().setString("default.instrument",
+                                          m_oldInstrument);
+    }
   }
 
   void test_Init() {
@@ -400,6 +416,8 @@ public:
 
 private:
   const double RAD_2_DEG = 180.0 / M_PI;
+  std::string m_oldFacility;
+  std::string m_oldInstrument;
 };
 
 #endif /* MANTID_DATAHANDLING_LOADILLDIFFRACTIONTEST_H_ */
diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h
index 017c36b6653da182ed84bf5a534a07f9ca12bb82..7522db4caa6125999ad0e382ed123655b4462aad 100644
--- a/Framework/DataHandling/test/LoadInstrumentTest.h
+++ b/Framework/DataHandling/test/LoadInstrumentTest.h
@@ -665,7 +665,7 @@ public:
         instLoader.execute(), Kernel::Exception::FileError & e,
         std::string(e.what()),
         "Either the InstrumentName or Filename property of LoadInstrument "
-        "must be specified to load an instrument in ");
+        "must be specified to load an instrument in \"\"");
     TS_ASSERT(!instLoader.isExecuted());
     TS_ASSERT_EQUALS(instLoader.getPropertyValue("Filename"), "");
   }
diff --git a/Framework/DataHandling/test/LoadSampleEnvironmentTest.h b/Framework/DataHandling/test/LoadSampleEnvironmentTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..718ddd7bf5e2da10445a21687e63cc95dcde142d
--- /dev/null
+++ b/Framework/DataHandling/test/LoadSampleEnvironmentTest.h
@@ -0,0 +1,142 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef LOAD_ENVIRONMENTEST_H_
+#define LOAD_ENVIRONMENTEST_H_
+
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/FileFinder.h"
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/Sample.h"
+#include "MantidDataHandling/LoadBinaryStl.h"
+#include "MantidDataHandling/LoadInstrument.h"
+#include "MantidDataHandling/LoadSampleEnvironment.h"
+#include "MantidGeometry/Instrument/SampleEnvironment.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include <cxxtest/TestSuite.h>
+
+using namespace Mantid;
+using namespace Mantid::API;
+using namespace Mantid::DataHandling;
+using namespace Mantid::Geometry;
+
+class LoadSampleEnvironmentTest : public CxxTest::TestSuite {
+public:
+  static LoadSampleEnvironmentTest *createSuite() {
+    return new LoadSampleEnvironmentTest();
+  }
+  static void destroySuite(LoadSampleEnvironmentTest *suite) { delete suite; }
+
+  void testInit() {
+
+    LoadSampleEnvironment alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+
+    TSM_ASSERT_EQUALS("should be 19 properties here", 19,
+                      (size_t)(alg.getProperties().size()));
+  }
+
+  void testTranslate() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    alg.setProperty("TranslationVector", "5,5,15");
+    boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+    environmentMesh = loadCube();
+    alg.translate(environmentMesh);
+    auto translatedVertices = environmentMesh->getVertices();
+    double arrayToMatch[] = {0,  0, 0,  10, 10, 0,  10, 0,  0,  0, 10, 0,
+                             10, 0, 30, 10, 10, 30, 0,  10, 30, 0, 0,  30};
+    std::vector<double> vectorToMatch =
+        std::vector<double>(std::begin(arrayToMatch), std::end(arrayToMatch));
+    TS_ASSERT(translatedVertices == vectorToMatch);
+  }
+
+  void testTranslateFailWrongSize() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    alg.setProperty("TranslationVector", "-1,0,1,0,0,0,0,1");
+    boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+    environmentMesh = loadCube();
+    TS_ASSERT_THROWS(alg.translate(environmentMesh), std::invalid_argument &);
+  }
+
+  void testRotate() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    alg.setProperty("RotationMatrix", "0,-1,0,1,0,0,0,0,1");
+    boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+    environmentMesh = loadCube();
+    alg.rotate(environmentMesh);
+    auto rotatedVertices = environmentMesh->getVertices();
+    double arrayToMatch[] = {5, -5, -15, -5, 5, -15, 5,  5,  -15, -5, -5, -15,
+                             5, 5,  15,  -5, 5, 15,  -5, -5, 15,  5,  -5, 15};
+    std::vector<double> vectorToMatch =
+        std::vector<double>(std::begin(arrayToMatch), std::end(arrayToMatch));
+    TS_ASSERT(rotatedVertices == vectorToMatch);
+  }
+
+  void testRotateFailWrongSize() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    alg.setProperty("RotationMatrix", "-1,0,1,0,0,0,0,1");
+    boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+    environmentMesh = loadCube();
+    TS_ASSERT_THROWS(alg.rotate(environmentMesh), std::invalid_argument);
+  }
+
+  void testRotateFailInvalidMatrix() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    alg.setProperty("RotationMatrix", "6,1,1,4,-2,5,2,8,7");
+    boost::shared_ptr<MeshObject> environmentMesh = nullptr;
+    environmentMesh = loadCube();
+    TS_ASSERT_THROWS(alg.rotate(environmentMesh), std::invalid_argument);
+  }
+
+  void testSetMaterial() {
+    LoadSampleEnvironment alg;
+    alg.initialize();
+    std::string path = FileFinder::Instance().getFullPath("cubeBin.stl");
+    alg.setProperty("Filename", path);
+    alg.setPropertyValue("EnvironmentName", "testName");
+    alg.setProperty("SetMaterial", true);
+    alg.setProperty("AtomicNumber", 1);
+    alg.setProperty("MassNumber", 1);
+    alg.setProperty("SampleNumberDensity", 1.0);
+    const int nvectors(2), nbins(10);
+    MatrixWorkspace_sptr inputWS =
+        WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(nvectors,
+                                                                     nbins);
+    alg.setChild(true);
+    alg.setProperty("InputWorkspace", inputWS);
+    alg.setPropertyValue("OutputWorkspace", "outputWorkspace");
+    alg.execute();
+    TS_ASSERT(alg.isExecuted());
+    MatrixWorkspace_sptr ws = alg.getProperty("OutputWorkspace");
+    const auto &sample(ws->sample());
+    const Geometry::SampleEnvironment environment = sample.getEnvironment();
+    const auto can = environment.container();
+    const auto material = can->material();
+    TSM_ASSERT_EQUALS(("expected elements"), environment.nelements(), 1);
+    TS_ASSERT(can->hasValidShape());
+    TS_ASSERT_EQUALS(environment.name(), "testName");
+    TS_ASSERT_EQUALS(material.numberDensity(), 1);
+    TS_ASSERT_EQUALS(material.name(), "");
+  }
+
+private:
+  // load a cube into a meshobject
+  std::unique_ptr<MeshObject> loadCube() {
+    std::string path = FileFinder::Instance().getFullPath("cubeBin.stl");
+    auto loader = LoadBinaryStl(path);
+    auto cube = loader.readStl();
+    return cube;
+  }
+};
+
+#endif /* LOAD_ENVIRONMENTTEST_H_ */
\ No newline at end of file
diff --git a/Framework/DataHandling/test/LoadSpice2dTest.h b/Framework/DataHandling/test/LoadSpice2dTest.h
index 91c6ada8ea7dd1cd5b05d455096a5559837bbdaf..335a83770bc98a20b30b18bb6ff041fc2f5fa5c2 100644
--- a/Framework/DataHandling/test/LoadSpice2dTest.h
+++ b/Framework/DataHandling/test/LoadSpice2dTest.h
@@ -173,7 +173,7 @@ public:
     TS_ASSERT_EQUALS(*np, 4);
 
     // Check detector position
-    prop = ws2d->run().getProperty("sample-detector-distance");
+    prop = ws2d->run().getProperty("total-sample-detector-distance");
     Mantid::Kernel::PropertyWithValue<double> *tsdd =
         dynamic_cast<Mantid::Kernel::PropertyWithValue<double> *>(prop);
     TS_ASSERT_EQUALS(i->getComponentByName("detector1")->getPos().Z(),
diff --git a/Framework/DataHandling/test/LoadStlTest.h b/Framework/DataHandling/test/LoadStlTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3752f7b48c77015d6e6225391fb6e10377e8746
--- /dev/null
+++ b/Framework/DataHandling/test/LoadStlTest.h
@@ -0,0 +1,75 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef LOAD_STL_TEST_H_
+#define LOAD_STL_TEST_H_
+#include "MantidDataHandling/LoadStl.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidKernel/V3D.h"
+#include <cxxtest/TestSuite.h>
+#include <functional>
+using namespace Mantid;
+using namespace Mantid::DataHandling;
+using namespace Mantid::Geometry;
+using namespace Mantid::Kernel;
+
+class LoadStlTest : public CxxTest::TestSuite {
+public:
+  static LoadStlTest *createSuite() { return new LoadStlTest(); }
+  static void destroySuite(LoadStlTest *suite) { delete suite; }
+
+  void test_same_V3D_hash_equal() {
+    V3D vertex1 = V3D(0, 0, 0);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex1, 1);
+    TS_ASSERT_EQUALS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+  }
+
+  void test_V3D_same_val_hash_equal() {
+    V3D vertex1 = V3D(0, 0, 0);
+    V3D vertex2 = V3D(0, 0, 0);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex2, 1);
+    TS_ASSERT_EQUALS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+  }
+
+  void test_dif_first_val() {
+    V3D vertex1 = V3D(0, 0, 0);
+    V3D vertex2 = V3D(1, 0, 0);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex2, 1);
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+  }
+
+  void test_dif_second_val() {
+    V3D vertex1 = V3D(0, 0, 0);
+    V3D vertex2 = V3D(0, 1, 0);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex2, 1);
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+  }
+
+  void test_dif_third_val() {
+    V3D vertex1 = V3D(0, 0, 0);
+    V3D vertex2 = V3D(0, 0, 1);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex2, 1);
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+  }
+
+  void test_order_matters() {
+    V3D vertex1 = V3D(1, 0, 0);
+    V3D vertex2 = V3D(0, 1, 0);
+    V3D vertex3 = V3D(0, 0, 1);
+    auto pair1 = std::pair<V3D, uint32_t>(vertex1, 0);
+    auto pair2 = std::pair<V3D, uint32_t>(vertex2, 1);
+    auto pair3 = std::pair<V3D, uint32_t>(vertex3, 2);
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair1), HashV3DPair{}(pair2));
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair2), HashV3DPair{}(pair3));
+    TS_ASSERT_DIFFERS(HashV3DPair{}(pair1), HashV3DPair{}(pair3));
+  }
+};
+#endif /* LOAD_STL_TEST_H_ */
\ No newline at end of file
diff --git a/Framework/DataHandling/test/ReadMaterialTest.h b/Framework/DataHandling/test/ReadMaterialTest.h
index 59a1109bf431ea2ad543c02c70ef8d0bbb92400e..2f7158665844d8c141e91dcbccbced4fbd646166 100644
--- a/Framework/DataHandling/test/ReadMaterialTest.h
+++ b/Framework/DataHandling/test/ReadMaterialTest.h
@@ -34,7 +34,7 @@ public:
   }
 
   void testSuccessfullValidateInputsAtomicNumber() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -64,7 +64,7 @@ public:
   }
 
   void testFailureValidateInputsNoMaterial() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 0;
       setMaterial.massNumber = 0;
@@ -78,7 +78,7 @@ public:
   }
 
   void testSuccessfullValidateInputsSampleNumber() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -93,7 +93,7 @@ public:
   }
 
   void testSuccessfullValidateInputsZParam() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -109,7 +109,7 @@ public:
   }
 
   void testSuccessfullValidateInputsSampleMass() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -124,7 +124,7 @@ public:
   }
 
   void testFailureValidateInputsSampleNumberAndZParam() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -142,7 +142,7 @@ public:
   }
 
   void testFailureValidateInputsZParamWithSampleMass() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -160,7 +160,7 @@ public:
   }
 
   void testFailureValidateInputsZParamWithoutUnitCell() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -176,7 +176,7 @@ public:
   }
 
   void testFailureValidateInputsSampleNumWithSampleMass() {
-    const ReadMaterial::MaterialParameters params = [this]() -> auto {
+    const ReadMaterial::MaterialParameters params = []() -> auto {
       ReadMaterial::MaterialParameters setMaterial;
       setMaterial.atomicNumber = 1;
       setMaterial.massNumber = 1;
@@ -290,4 +290,4 @@ private:
                      materialFormula[0].multiplicity);
     TS_ASSERT_EQUALS(checkFormula.size(), materialFormula.size())
   }
-};
\ No newline at end of file
+};
diff --git a/Framework/DataHandling/test/SNSDataArchiveTest.h b/Framework/DataHandling/test/SNSDataArchiveTest.h
deleted file mode 100644
index 3d8d7d588b44351e168cbd82760b51852ebcf6e4..0000000000000000000000000000000000000000
--- a/Framework/DataHandling/test/SNSDataArchiveTest.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Mantid Repository : https://github.com/mantidproject/mantid
-//
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
-//     NScD Oak Ridge National Laboratory, European Spallation Source
-//     & Institut Laue - Langevin
-// SPDX - License - Identifier: GPL - 3.0 +
-#ifndef SNSDATAARCHIVETEST_H_
-#define SNSDATAARCHIVETEST_H_
-
-#include <cxxtest/TestSuite.h>
-
-#include "MantidAPI/ArchiveSearchFactory.h"
-#include "MantidDataHandling/SNSDataArchive.h"
-
-using namespace Mantid::DataHandling;
-using namespace Mantid::API;
-
-class SNSDataArchiveTest : public CxxTest::TestSuite {
-public:
-  void xtestSearch() {
-    SNSDataArchive arch;
-
-    // PG3 Test case
-    std::set<std::string> filename;
-    filename.insert("PG3_7390");
-    std::vector<std::string> extension =
-        std::vector<std::string>(1, "_event.nxs");
-    std::string path = arch.getArchivePath(filename, extension);
-    TS_ASSERT_EQUALS(path,
-                     "/SNS/PG3/IPTS-2767/0/7390/NeXus/PG3_7390_histo.nxs");
-
-    // BSS Test case
-    filename.clear();
-    filename.insert("BSS_18339");
-    path = arch.getArchivePath(filename, extension);
-    TS_ASSERT_EQUALS(path,
-                     "/SNS/BSS/IPTS-6817/0/18339/NeXus/BSS_18339_event.nxs");
-
-    // HYSA Test case
-    filename.clear();
-    filename.insert("HYSA_2411");
-    extension = std::vector<std::string>(1, ".nxs.h5");
-    path = arch.getArchivePath(filename, extension);
-    TS_ASSERT_EQUALS(path, "/SNS/HYSA/IPTS-8004/nexus/HYSA_2411.nxs.h5");
-
-    // Test a non-existent file
-    filename.clear();
-    filename.insert("mybeamline_666");
-    extension = std::vector<std::string>(1, ".nxs");
-    path = arch.getArchivePath(filename, extension);
-    TS_ASSERT(path.empty());
-  }
-
-  void testFactory() {
-    boost::shared_ptr<IArchiveSearch> arch =
-        ArchiveSearchFactory::Instance().create("SNSDataSearch");
-    TS_ASSERT(arch);
-  }
-};
-
-#endif /*SNSDATAARCHIVETEST_H_*/
diff --git a/Framework/DataHandling/test/SaveReflectometryAsciiTest.h b/Framework/DataHandling/test/SaveReflectometryAsciiTest.h
index a9fe3094977ceb651288855b284b6e42e8a56746..dc62981c1c8ca4b788b18be801d58b18950537b6 100644
--- a/Framework/DataHandling/test/SaveReflectometryAsciiTest.h
+++ b/Framework/DataHandling/test/SaveReflectometryAsciiTest.h
@@ -344,7 +344,7 @@ public:
     TS_ASSERT_EQUALS(line, "Number of data points : 2")
   }
 
-  void test_defined_log() {
+  void test_user_log() {
     const auto &x1 = Mantid::HistogramData::Points({0.33, 0.34});
     const auto &y1 = Mantid::HistogramData::Counts({3., 6.6});
     Mantid::HistogramData::Histogram histogram(x1, y1);
@@ -353,6 +353,10 @@ public:
     Mantid::Kernel::PropertyWithValue<int> *a =
         new Mantid::Kernel::PropertyWithValue<int>("a", 5);
     ws->mutableRun().addLogData(a);
+    Mantid::Kernel::PropertyWithValue<double> *b =
+        new Mantid::Kernel::PropertyWithValue<double>("b", 3.4382);
+    ws->mutableRun().addLogData(b);
+    ws->mutableRun().getProperty("b")->setUnits("MyUnit");
     auto outputFileHandle = Poco::TemporaryFile();
     const std::string file = outputFileHandle.path();
     SaveReflectometryAscii alg;
@@ -360,8 +364,7 @@ public:
     alg.setRethrows(true);
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", ws))
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("Filename", file))
-    TS_ASSERT_THROWS_NOTHING(
-        alg.setProperty("LogList", std::vector<std::string>{"a"}))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LogList", "a, b"))
     TS_ASSERT_THROWS_NOTHING(alg.execute())
     TS_ASSERT(alg.isExecuted())
     std::string filename = alg.getPropertyValue("Filename");
@@ -389,7 +392,71 @@ public:
     std::getline(in, line);
     TS_ASSERT_EQUALS(line, "Theta 3 + dir + ref numbers : Not defined")
     std::getline(in, line);
-    TS_ASSERT_EQUALS(line, "a : 5")
+    TS_ASSERT_EQUALS(line, "a : 5 ")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "b : 3.4382000000000001 MyUnit")
+    for (int i = 0; i < 7; ++i) {
+      std::getline(in, line);
+      TS_ASSERT_EQUALS(line, "Parameter  : Not defined")
+    }
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Number of file format : 40")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Number of data points : 2")
+  }
+
+  void test_user_log_overrides_fixed_log() {
+    const auto &x1 = Mantid::HistogramData::Points({0.33, 0.34});
+    const auto &y1 = Mantid::HistogramData::Counts({3., 6.6});
+    Mantid::HistogramData::Histogram histogram(x1, y1);
+    auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();
+    ws->initialize(1, histogram);
+    // User wants to add the Instrument name header line
+    Mantid::Kernel::PropertyWithValue<std::string> *a =
+        new Mantid::Kernel::PropertyWithValue<std::string>("Instrument", "ABC");
+    ws->mutableRun().addLogData(a);
+    // The workspace has an entry already for the instrument name
+    Mantid::Kernel::PropertyWithValue<std::string> *b =
+        new Mantid::Kernel::PropertyWithValue<std::string>("instrument.name",
+                                                           "DEF");
+    ws->mutableRun().addLogData(b);
+    auto outputFileHandle = Poco::TemporaryFile();
+    const std::string file = outputFileHandle.path();
+    SaveReflectometryAscii alg;
+    alg.initialize();
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", ws))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Filename", file))
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setProperty("LogList", "Instrument, instrument.name"))
+    TS_ASSERT_THROWS_NOTHING(alg.execute())
+    TS_ASSERT(alg.isExecuted())
+    std::string filename = alg.getPropertyValue("Filename");
+    TS_ASSERT(Poco::File(filename.append(".mft")).exists())
+    std::ifstream in(filename);
+    std::string line;
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "MFT")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Instrument : DEF ")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "User-local contact : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Title : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Subtitle : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Start date + time : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "End date + time : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 1 + dir + ref numbers : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 2 + dir + ref numbers : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 3 + dir + ref numbers : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Instrument : ABC ")
     for (int i = 0; i < 8; ++i) {
       std::getline(in, line);
       TS_ASSERT_EQUALS(line, "Parameter  : Not defined")
@@ -400,6 +467,60 @@ public:
     TS_ASSERT_EQUALS(line, "Number of data points : 2")
   }
 
+  void test_automatic_log_filling() {
+    const auto &x1 = Mantid::HistogramData::Points({0.33, 0.34});
+    const auto &y1 = Mantid::HistogramData::Counts({3., 6.6});
+    Mantid::HistogramData::Histogram histogram(x1, y1);
+    auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();
+    ws->initialize(1, histogram);
+    // Should use this instrument name
+    Mantid::Kernel::PropertyWithValue<std::string> *a =
+        new Mantid::Kernel::PropertyWithValue<std::string>("instrument.name",
+                                                           "DEF");
+    ws->mutableRun().addLogData(a);
+    auto outputFileHandle = Poco::TemporaryFile();
+    const std::string file = outputFileHandle.path();
+    SaveReflectometryAscii alg;
+    alg.initialize();
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", ws))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Filename", file))
+    TS_ASSERT_THROWS_NOTHING(alg.execute())
+    TS_ASSERT(alg.isExecuted())
+    std::string filename = alg.getPropertyValue("Filename");
+    TS_ASSERT(Poco::File(filename.append(".mft")).exists())
+    std::ifstream in(filename);
+    std::string line;
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "MFT")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Instrument : DEF ")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "User-local contact : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Title : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Subtitle : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Start date + time : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "End date + time : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 1 + dir + ref numbers : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 2 + dir + ref numbers : Not defined")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Theta 3 + dir + ref numbers : Not defined")
+    for (int i = 0; i < 9; ++i) {
+      std::getline(in, line);
+      TS_ASSERT_EQUALS(line, "Parameter  : Not defined")
+    }
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Number of file format : 40")
+    std::getline(in, line);
+    TS_ASSERT_EQUALS(line, "Number of data points : 2")
+  }
+
   void test_group_workspaces() {
     const auto &x1 = Mantid::HistogramData::Points({4.36, 6.32});
     const auto &y1 = Mantid::HistogramData::Counts({4., 7.6});
diff --git a/Framework/DataHandling/test/SetSampleTest.h b/Framework/DataHandling/test/SetSampleTest.h
index 008dd450fc0e9bc2caa353c035bfa2074c9e598b..4de78a6110eb5e0eb5e8b8ae593e9b72b3a7b68e 100644
--- a/Framework/DataHandling/test/SetSampleTest.h
+++ b/Framework/DataHandling/test/SetSampleTest.h
@@ -520,8 +520,9 @@ private:
     props->declareProperty(
         Mantid::Kernel::make_unique<DoubleProperty>("Thick", 0.1), "");
     std::vector<double> center{1, 0, 0};
-    props->declareProperty(
-        Mantid::Kernel::make_unique<DoubleArrayProperty>("Center", center), "");
+    props->declareProperty(Mantid::Kernel::make_unique<DoubleArrayProperty>(
+                               "Center", std::move(center)),
+                           "");
     if (angle != 0.0) {
       props->declareProperty(
           Mantid::Kernel::make_unique<DoubleProperty>("Angle", angle), "");
@@ -543,8 +544,9 @@ private:
     props->declareProperty(
         Mantid::Kernel::make_unique<DoubleProperty>("Radius", 5), "");
     std::vector<double> center{0, 0, 1};
-    props->declareProperty(
-        Mantid::Kernel::make_unique<DoubleArrayProperty>("Center", center), "");
+    props->declareProperty(Mantid::Kernel::make_unique<DoubleArrayProperty>(
+                               "Center", std::move(center)),
+                           "");
 
     return props;
   }
@@ -566,8 +568,9 @@ private:
     props->declareProperty(
         Mantid::Kernel::make_unique<DoubleProperty>("OuterRadius", 4), "");
     std::vector<double> center{0, 0, 1};
-    props->declareProperty(
-        Mantid::Kernel::make_unique<DoubleArrayProperty>("Center", center), "");
+    props->declareProperty(Mantid::Kernel::make_unique<DoubleArrayProperty>(
+                               "Center", std::move(center)),
+                           "");
 
     return props;
   }
diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventList.h b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
index 22e967eaa2547d3e80c3523cc10a13fe1aa1713d..b987dcf74cbfa19781ba3d73f1f9a9e31f428a1b 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/EventList.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
@@ -244,6 +244,7 @@ public:
   void addPulsetime(const double seconds) override;
 
   void maskTof(const double tofMin, const double tofMax) override;
+  void maskCondition(const std::vector<bool> &mask) override;
 
   void getTofs(std::vector<double> &tofs) const override;
   double getTofMin() const override;
@@ -456,6 +457,10 @@ private:
   static std::size_t maskTofHelper(std::vector<T> &events, const double tofMin,
                                    const double tofMax);
   template <class T>
+  static std::size_t maskConditionHelper(std::vector<T> &events,
+                                         const std::vector<bool> &mask);
+
+  template <class T>
   static void getTofsHelper(const std::vector<T> &events,
                             std::vector<double> &tofs);
   template <class T>
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
index 1455b821bc1866612083ea4daaf0687992da07f2..e13c043b9f47e70ec88fe986a7d1a206e2282e8f 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
@@ -140,7 +140,7 @@ protected:
   uint64_t m_max;
 
   /// Implicit function to limit volume searched
-  Mantid::Geometry::MDImplicitFunction *m_function;
+  std::unique_ptr<Mantid::Geometry::MDImplicitFunction> m_function;
 
   /// Number of dimensions
   size_t m_nd;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
index 39d9aec99c26b65409f77754d669928edd6a39ca..30a0ef9c4b6118c39ea949fc2b4a6ae28339fc67 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
@@ -110,6 +110,8 @@ public:
   void setBankName(std::string m_bankName);
   void setHKL(double H, double K, double L) override;
   void setHKL(const Mantid::Kernel::V3D &HKL) override;
+  void setSamplePos(double samX, double samY, double samZ) override;
+  void setSamplePos(const Mantid::Kernel::V3D &XYZ) override;
   void resetHKL();
 
   Mantid::Kernel::V3D getQLabFrame() const override;
@@ -160,6 +162,7 @@ public:
   int getPeakNumber() const override;
 
   virtual Mantid::Kernel::V3D getDetPos() const override;
+  virtual Mantid::Kernel::V3D getSamplePos() const override;
   double getL1() const override;
   double getL2() const override;
 
diff --git a/Framework/DataObjects/src/EventList.cpp b/Framework/DataObjects/src/EventList.cpp
index 4cef5659ab23fc3ba8aacda5f0d6379534b8362d..1a11e7f60fd3ea938ce813dd3a44af86e5b400ae 100644
--- a/Framework/DataObjects/src/EventList.cpp
+++ b/Framework/DataObjects/src/EventList.cpp
@@ -2695,6 +2695,75 @@ void EventList::maskTof(const double tofMin, const double tofMax) {
     this->clear(false);
 }
 
+// --------------------------------------------------------------------------
+/** Mask out events by the condition vector.
+ * Events are removed from the list.
+ * @param events :: reference to a vector of events to change.
+ * @param mask :: condition vector
+ * @returns The number of events deleted.
+ */
+template <class T>
+std::size_t EventList::maskConditionHelper(std::vector<T> &events,
+                                           const std::vector<bool> &mask) {
+
+  // runs through the two synchronized vectors and delete elements
+  // for condition false
+  auto itm = std::find(mask.begin(), mask.end(), false);
+  auto first = events.begin() + (itm - mask.begin());
+
+  if (itm != mask.end()) {
+    for (auto ite = first; ++ite != events.end() && ++itm != mask.end();) {
+      if (*itm != false) {
+        *first++ = std::move(*ite);
+      }
+    }
+  }
+
+  auto n = events.end() - first;
+  if (n != 0)
+    events.erase(first, events.end());
+
+  return n;
+}
+
+// --------------------------------------------------------------------------
+/**
+ * Mask out events by the condition vector.
+ * Events are removed from the list.
+ * @param mask :: condition vector
+ */
+void EventList::maskCondition(const std::vector<bool> &mask) {
+
+  // mask size must match the number of events
+  if (this->getNumberEvents() != mask.size())
+    throw std::runtime_error("EventList::maskTof: tofMax must be > tofMin");
+
+  // don't do anything with an emply list
+  if (this->getNumberEvents() == 0)
+    return;
+
+  // Convert the list
+  size_t numOrig = 0;
+  size_t numDel = 0;
+  switch (eventType) {
+  case TOF:
+    numOrig = this->events.size();
+    numDel = this->maskConditionHelper(this->events, mask);
+    break;
+  case WEIGHTED:
+    numOrig = this->weightedEvents.size();
+    numDel = this->maskConditionHelper(this->weightedEvents, mask);
+    break;
+  case WEIGHTED_NOTIME:
+    numOrig = this->weightedEventsNoTime.size();
+    numDel = this->maskConditionHelper(this->weightedEventsNoTime, mask);
+    break;
+  }
+
+  if (numDel >= numOrig)
+    this->clear(false);
+}
+
 // --------------------------------------------------------------------------
 /** Get the m_tof member of all events in a list
  *
diff --git a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
index bb6280ec1429c66c737dceec01f2fd7f9fc9152a..6e0e88ac766730f2abc6edd6e412506f1a48bf1a 100644
--- a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
@@ -168,7 +168,7 @@ void MDHistoWorkspaceIterator::init(
 
   m_begin = beginPos;
   m_pos = m_begin;
-  m_function = function;
+  m_function.reset(function);
 
   m_max = endPos;
   if (m_max > m_ws->getNPoints())
@@ -249,12 +249,7 @@ MDHistoWorkspaceIterator::~MDHistoWorkspaceIterator() {
   delete[] m_index;
   delete[] m_indexMax;
   delete[] m_indexMaker;
-
-  if (m_function)
-    delete m_function;
-  m_function = nullptr;
 }
-
 //----------------------------------------------------------------------------------------------
 /** @return the number of points to be iterated on */
 size_t MDHistoWorkspaceIterator::getDataSize() const {
diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp
index d498a4142936962325d4672c7b4587ba10b28299..8dc87b49aadf191b43ba3561a19550cc2d23fd42 100644
--- a/Framework/DataObjects/src/Peak.cpp
+++ b/Framework/DataObjects/src/Peak.cpp
@@ -811,6 +811,27 @@ void Peak::setHKL(const Mantid::Kernel::V3D &HKL) {
   m_L = HKL.Z();
 }
 
+/** Set sample position
+ *
+ * @ doubles x,y,z-> samplePos(x), samplePos(y), samplePos(z)
+ */
+void Peak::setSamplePos(double samX, double samY, double samZ) {
+
+  this->samplePos[0] = samX;
+  this->samplePos[1] = samY;
+  this->samplePos[2] = samZ;
+}
+
+/** Set sample position
+ *
+ * @param XYZ :: vector x,y,z-> samplePos(x), samplePos(y), samplePos(z)
+ */
+void Peak::setSamplePos(const Mantid::Kernel::V3D &XYZ) {
+
+  this->samplePos[0] = XYZ[0];
+  this->samplePos[1] = XYZ[1];
+  this->samplePos[2] = XYZ[2];
+}
 //----------------------------------------------------------------------------------------------
 /** Return the # of counts in the bin at its peak*/
 double Peak::getBinCount() const { return m_binCount; }
@@ -923,6 +944,10 @@ void Peak::setPeakNumber(int m_peakNumber) {
 /** Return the detector position vector */
 Mantid::Kernel::V3D Peak::getDetPos() const { return detPos; }
 
+// -------------------------------------------------------------------------------------
+/** Return the sample position vector */
+Mantid::Kernel::V3D Peak::getSamplePos() const { return samplePos; }
+
 // -------------------------------------------------------------------------------------
 /** Return the L1 flight path length (source to sample), in meters. */
 double Peak::getL1() const { return (samplePos - sourcePos).norm(); }
diff --git a/Framework/DataObjects/test/EventListTest.h b/Framework/DataObjects/test/EventListTest.h
index d29c5ac56fd25c3840b04d0f3d2fa771159ee64a..4b99079d07dfad0b5a3be51c95101bb147c6bc3b 100644
--- a/Framework/DataObjects/test/EventListTest.h
+++ b/Framework/DataObjects/test/EventListTest.h
@@ -1314,6 +1314,41 @@ public:
     }
   }
 
+  //-----------------------------------------------------------------------------------------------
+  void test_maskCondition_allTypes() {
+    // Go through each possible EventType as the input
+    for (int this_type = 0; this_type < 3; this_type++) {
+      this->fake_uniform_data();
+      el.switchTo(static_cast<EventType>(this_type));
+
+      // tof steps of 5 microseconds, starting at 100 ns, up to 20 msec
+      // How many events did we make?
+      TS_ASSERT_EQUALS(el.getNumberEvents(), 2 * MAX_TOF / BIN_DELTA);
+
+      // Mask out 5-10 milliseconds
+      auto nlen = el.getNumberEvents();
+      std::vector<bool> mask(nlen, true);
+
+      // first check no removal
+      el.maskCondition(mask);
+      TS_ASSERT_EQUALS(el.getNumberEvents(), 2 * MAX_TOF / BIN_DELTA);
+
+      double min = MAX_TOF * 0.25;
+      double max = MAX_TOF * 0.5;
+      for (size_t i = 0; i < nlen; i++) {
+        if ((el.getEvent(i).tof() >= min) && (el.getEvent(i).tof() <= max)) {
+          mask[i] = false;
+        }
+      }
+      el.maskCondition(mask);
+      for (std::size_t i = 0; i < el.getNumberEvents(); i++) {
+        // No tofs in that range
+        TS_ASSERT((el.getEvent(i).tof() < min) || (el.getEvent(i).tof() > max));
+      }
+      TS_ASSERT_EQUALS(el.getNumberEvents(), 0.75 * 2 * MAX_TOF / BIN_DELTA);
+    }
+  }
+
   //-----------------------------------------------------------------------------------------------
   void test_getTofs_and_setTofs() {
     // Go through each possible EventType as the input
diff --git a/Framework/DataObjects/test/PeakTest.h b/Framework/DataObjects/test/PeakTest.h
index ff5211b6efc3f8412a5341aa23295c51d9574907..8dc69662462f5fae0aa29db5403251d716860e7e 100644
--- a/Framework/DataObjects/test/PeakTest.h
+++ b/Framework/DataObjects/test/PeakTest.h
@@ -236,6 +236,14 @@ public:
     TS_ASSERT_EQUALS(p.getHKL(), V3D(1.0, 2.0, 3.0));
   }
 
+  void test_samplePos() {
+    Peak p(inst, 10000, 2.0);
+    p.setSamplePos(1.0, 1.0, 1.0);
+    TS_ASSERT_EQUALS(p.getSamplePos(), V3D(1.0, 1.0, 1.0));
+    p.setSamplePos(V3D(2.0, 2.0, 2.0));
+    TS_ASSERT_EQUALS(p.getSamplePos(), V3D(2.0, 2.0, 2.0));
+  }
+
   void test_getBank_and_row() {
     Peak p(inst, 10000, 2.0);
     TS_ASSERT_EQUALS(p.getBankName(), "bank1")
diff --git a/Framework/DataObjects/test/WorkspaceCreationTest.h b/Framework/DataObjects/test/WorkspaceCreationTest.h
index 82eee10415802f66fd473500d74251905831c32f..a7fe8b94993a82c5df0908200f969f18960ede5f 100644
--- a/Framework/DataObjects/test/WorkspaceCreationTest.h
+++ b/Framework/DataObjects/test/WorkspaceCreationTest.h
@@ -9,6 +9,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/Run.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/SpecialWorkspace2D.h"
@@ -419,6 +420,30 @@ public:
     check_zeroed_data(*ws);
   }
 
+  void test_create_parent_numeric_vertical_axis() {
+    constexpr size_t parentNhist{3};
+    const auto parent = create<Workspace2D>(parentNhist, Histogram(Points{1}));
+    NumericAxis *parentAxis = new NumericAxis({-1.5, -0.5, 2.3});
+    parent->replaceAxis(1, parentAxis);
+    constexpr size_t nhist{2};
+    const auto ws = create<Workspace2D>(*parent, nhist, parent->histogram(0));
+    auto axis = ws->getAxis(1);
+    TS_ASSERT_DIFFERS(dynamic_cast<NumericAxis *>(axis), nullptr)
+    TS_ASSERT_EQUALS(axis->length(), nhist);
+  }
+
+  void test_create_parent_bin_edge_vertical_axis() {
+    constexpr size_t parentNhist{3};
+    const auto parent = create<Workspace2D>(parentNhist, Histogram(Points{1}));
+    BinEdgeAxis *parentAxis = new BinEdgeAxis({-1.5, -0.5, 2.3, 3.4});
+    parent->replaceAxis(1, parentAxis);
+    constexpr size_t nhist{2};
+    const auto ws = create<Workspace2D>(*parent, nhist, parent->histogram(0));
+    auto axis = ws->getAxis(1);
+    TS_ASSERT_DIFFERS(dynamic_cast<BinEdgeAxis *>(axis), nullptr)
+    TS_ASSERT_EQUALS(axis->length(), nhist + 1);
+  }
+
   void test_create_drop_events() {
     auto eventWS = create<EventWorkspace>(1, Histogram(BinEdges(3)));
     auto ws = create<HistoWorkspace>(*eventWS);
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
index 1d15fe3bbf791d2c2fa279f1fb09533e4a4e0997..6a50101841cbc07f241a0ff7e5ec394cf8dae3a4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
@@ -50,6 +50,9 @@ public:
   virtual void setL(double m_L) = 0;
   virtual void setHKL(double H, double K, double L) = 0;
   virtual void setHKL(const Mantid::Kernel::V3D &HKL) = 0;
+  virtual void setSamplePos(double samX, double samY, double samZ) = 0;
+  virtual void setSamplePos(const Mantid::Kernel::V3D &XYZ) = 0;
+  virtual Mantid::Kernel::V3D getSamplePos() const = 0;
   virtual Mantid::Kernel::V3D getDetectorPosition() const = 0;
   virtual Mantid::Kernel::V3D getDetectorPositionNoCheck() const = 0;
 
diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
index 1a79d17461c56005f4545b933c2371682e215c65..08a188ede6cb35b7174cc9ba7f12f7f3d921a591 100644
--- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
+++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
@@ -90,7 +90,7 @@ public:
   virtual const Kernel::Material material() const = 0;
 
   /// Gets the GeometryHandler
-  GeometryHandler *Handle() const { return handle; }
+  GeometryHandler *Handle() const { return handle.get(); }
 
 protected:
   /// Reset the current geometry handler
@@ -98,7 +98,7 @@ protected:
 
 private:
   /// Geometry Handle for rendering
-  GeometryHandler *handle;
+  std::unique_ptr<GeometryHandler> handle;
 
   friend class GeometryHandler;
 };
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
index e57513c99a6b416cb0b54d95c7f3918de92c122e..10c8e4b98167c0396d9501207719e39306c4d08f 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
@@ -43,17 +43,17 @@ class vtkGeometryCacheWriter;
 
 Mesh Object of Triangles assumed to form one or more
 non-intersecting closed surfaces enclosing separate volumes.
-The number of vertices is limited to 2^16 based on index type. For 2D Meshes see
+The number of vertices is limited to 2^32 based on index type. For 2D Meshes see
 Mesh2DObject
 */
 class MANTID_GEOMETRY_DLL MeshObject : public IObject {
 public:
   /// Constructor
-  MeshObject(const std::vector<uint16_t> &faces,
+  MeshObject(const std::vector<uint32_t> &faces,
              const std::vector<Kernel::V3D> &vertices,
-             const Kernel::Material &material);
+             const Kernel::Material material);
   /// Constructor
-  MeshObject(std::vector<uint16_t> &&faces, std::vector<Kernel::V3D> &&vertices,
+  MeshObject(std::vector<uint32_t> &&faces, std::vector<Kernel::V3D> &&vertices,
              const Kernel::Material &&material);
 
   /// Copy constructor
@@ -133,6 +133,8 @@ public:
   size_t numberOfTriangles() const;
   std::vector<uint32_t> getTriangles() const;
 
+  void rotate(const Kernel::Matrix<double> &);
+  void translate(Kernel::V3D);
   void updateGeometryHandler();
 
 private:
@@ -170,7 +172,7 @@ private:
 
   /// Contents
   /// Triangles are specified by indices into a list of vertices.
-  std::vector<uint16_t> m_triangles;
+  std::vector<uint32_t> m_triangles;
   std::vector<Kernel::V3D> m_vertices;
   /// material composition
   Kernel::Material m_material;
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
index e1374a0994ef078cf2cd89ffd6b57955104d92fc..19392be677a0cd0e64ea9ad754bf845637a985f4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject2D.h
@@ -31,11 +31,11 @@ class GeometryHandler;
 class MANTID_GEOMETRY_DLL MeshObject2D : public IObject {
 public:
   /// Constructor
-  MeshObject2D(const std::vector<uint16_t> &faces,
+  MeshObject2D(const std::vector<uint32_t> &faces,
                const std::vector<Kernel::V3D> &vertices,
                const Kernel::Material &material);
   /// Constructor
-  MeshObject2D(std::vector<uint16_t> &&faces,
+  MeshObject2D(std::vector<uint32_t> &&faces,
                std::vector<Kernel::V3D> &&vertices,
                const Kernel::Material &&material);
 
@@ -97,7 +97,7 @@ private:
   void initialize();
   /// Triangles are specified by indices into a list of vertices. Offset is
   /// always 3.
-  std::vector<uint16_t> m_triangles;
+  std::vector<uint32_t> m_triangles;
   /// Vertices
   std::vector<Kernel::V3D> m_vertices;
   /// Material composition
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObjectCommon.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObjectCommon.h
index f0d61427f5005cd2238f1f61de82f1d933c40544..fc87882568479c93da6ed57b5adf1beeaa5d5e11 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObjectCommon.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObjectCommon.h
@@ -47,8 +47,6 @@ rayIntersectsTriangle(const Kernel::V3D &start, const Kernel::V3D &direction,
                       int &entryExit);
 
 MANTID_GEOMETRY_DLL void checkVertexLimit(size_t nVertices);
-MANTID_GEOMETRY_DLL std::vector<uint32_t>
-getTriangles_uint32(const std::vector<uint16_t> &input);
 MANTID_GEOMETRY_DLL const BoundingBox &
 getBoundingBox(const std::vector<Kernel::V3D> &vertices, BoundingBox &cacheBB);
 MANTID_GEOMETRY_DLL void
diff --git a/Framework/Geometry/src/IObjComponent.cpp b/Framework/Geometry/src/IObjComponent.cpp
index c07c94c7979b2f57f61a8b2e43a0e447927cc881..6787cf01eecc17718af1b6abe4ee502c8edbfa02 100644
--- a/Framework/Geometry/src/IObjComponent.cpp
+++ b/Framework/Geometry/src/IObjComponent.cpp
@@ -13,21 +13,20 @@
 namespace Mantid {
 namespace Geometry {
 
-IObjComponent::IObjComponent() { handle = new GeometryHandler(this); }
+IObjComponent::IObjComponent() {
+  handle = std::make_unique<GeometryHandler>(this);
+}
 
 /** Constructor, specifying the GeometryHandler (renderer engine)
  * for this IObjComponent.
  */
 IObjComponent::IObjComponent(GeometryHandler *the_handler) {
-  handle = the_handler;
+  handle.reset(the_handler);
 }
 
 // Looking to get rid of the first of these constructors in due course (and
 // probably add others)
-IObjComponent::~IObjComponent() {
-  if (handle != nullptr)
-    delete handle;
-}
+IObjComponent::~IObjComponent() = default;
 
 /**
  * Set the geometry handler for IObjComponent
@@ -37,7 +36,7 @@ IObjComponent::~IObjComponent() {
 void IObjComponent::setGeometryHandler(GeometryHandler *h) {
   if (h == nullptr)
     return;
-  this->handle = h;
+  this->handle.reset(h);
 }
 
 /**
@@ -45,7 +44,7 @@ void IObjComponent::setGeometryHandler(GeometryHandler *h) {
  */
 IObjComponent::IObjComponent(const IObjComponent &) {
   // Copy constructor just creates new handle. Copies nothing.
-  handle = new GeometryHandler(this);
+  handle = std::make_unique<GeometryHandler>(this);
 }
 
 /**
@@ -56,7 +55,7 @@ IObjComponent::IObjComponent(const IObjComponent &) {
 IObjComponent &IObjComponent::operator=(const IObjComponent &rhs) {
   if (&rhs != this) {
     // Assignment operator copies nothing. Just creates new handle.
-    handle = new GeometryHandler(this);
+    handle = std::make_unique<GeometryHandler>(this);
   }
   return *this;
 }
diff --git a/Framework/Geometry/src/Objects/MeshObject.cpp b/Framework/Geometry/src/Objects/MeshObject.cpp
index 138d52abb8586dce88200038361f645e188ed342..71d9468fdd3b829d77cca2df441823f1adddfb30 100644
--- a/Framework/Geometry/src/Objects/MeshObject.cpp
+++ b/Framework/Geometry/src/Objects/MeshObject.cpp
@@ -20,16 +20,16 @@
 namespace Mantid {
 namespace Geometry {
 
-MeshObject::MeshObject(const std::vector<uint16_t> &faces,
+MeshObject::MeshObject(const std::vector<uint32_t> &faces,
                        const std::vector<Kernel::V3D> &vertices,
-                       const Kernel::Material &material)
+                       const Kernel::Material material)
     : m_boundingBox(), m_id("MeshObject"), m_triangles(faces),
       m_vertices(vertices), m_material(material) {
 
   initialize();
 }
 
-MeshObject::MeshObject(std::vector<uint16_t> &&faces,
+MeshObject::MeshObject(std::vector<uint32_t> &&faces,
                        std::vector<Kernel::V3D> &&vertices,
                        const Kernel::Material &&material)
     : m_boundingBox(), m_id("MeshObject"), m_triangles(std::move(faces)),
@@ -473,6 +473,18 @@ boost::shared_ptr<GeometryHandler> MeshObject::getGeometryHandler() const {
   return m_handler;
 }
 
+void MeshObject::rotate(const Kernel::Matrix<double> &rotationMatrix) {
+  for (Kernel::V3D &vertex : m_vertices) {
+    vertex.rotate(rotationMatrix);
+  }
+}
+
+void MeshObject::translate(Kernel::V3D translationVector) {
+  for (Kernel::V3D &vertex : m_vertices) {
+    vertex = vertex + translationVector;
+  }
+}
+
 /**
  * Updates the geometry handler if needed
  */
@@ -488,9 +500,7 @@ size_t MeshObject::numberOfTriangles() const { return m_triangles.size() / 3; }
 /**
  * get faces
  */
-std::vector<uint32_t> MeshObject::getTriangles() const {
-  return MeshObjectCommon::getTriangles_uint32(m_triangles);
-}
+std::vector<uint32_t> MeshObject::getTriangles() const { return m_triangles; }
 
 /**
  * get number of points
diff --git a/Framework/Geometry/src/Objects/MeshObject2D.cpp b/Framework/Geometry/src/Objects/MeshObject2D.cpp
index b0d255cd02812758c6388b53df919bfdd14fafc1..d77a22f8d82c6975c813ae26f30a53c6031daf16 100644
--- a/Framework/Geometry/src/Objects/MeshObject2D.cpp
+++ b/Framework/Geometry/src/Objects/MeshObject2D.cpp
@@ -59,10 +59,9 @@ bool allCoplanar(const std::vector<Kernel::V3D> &vertices,
   const auto nz = normal[2];
   const auto k = nx * v0.X() + ny * v0.Y() + nz * v0.Z();
   const auto denom = normal.norm();
-  const static double tolerance =
-      1e-9; // Fixed Tolerance. Too expensive to calculate
-            // based on machine uncertaintly for each
-            // vertex.
+  const static double tolerance = 1e-9; // Fixed Tolerance. Too expensive to
+                                        // calculate based on machine
+                                        // uncertaintly for each vertex.
 
   for (const auto &vertex : vertices) {
     auto d = (nx * vertex.X() + ny * vertex.Y() + nz * vertex.Z() - k) / denom;
@@ -108,7 +107,7 @@ namespace {
  * @param vertex3 :: Third vertex of triangle
  * @returns true if the specified triangle exists
  */
-bool getTriangle(const size_t index, const std::vector<uint16_t> &triangles,
+bool getTriangle(const size_t index, const std::vector<uint32_t> &triangles,
                  const std::vector<Kernel::V3D> &vertices, Kernel::V3D &vertex1,
                  Kernel::V3D &vertex2, Kernel::V3D &vertex3) {
   bool triangleExists = index < triangles.size() / 3;
@@ -146,7 +145,7 @@ bool MeshObject2D::pointsCoplanar(const std::vector<Kernel::V3D> &vertices) {
 /**
  * Constructor
  */
-MeshObject2D::MeshObject2D(const std::vector<uint16_t> &faces,
+MeshObject2D::MeshObject2D(const std::vector<uint32_t> &faces,
                            const std::vector<Kernel::V3D> &vertices,
                            const Kernel::Material &material)
     : m_triangles(faces), m_vertices(vertices), m_material(material) {
@@ -156,7 +155,7 @@ MeshObject2D::MeshObject2D(const std::vector<uint16_t> &faces,
 /**
  * Move constructor
  */
-MeshObject2D::MeshObject2D(std::vector<uint16_t> &&faces,
+MeshObject2D::MeshObject2D(std::vector<uint32_t> &&faces,
                            std::vector<Kernel::V3D> &&vertices,
                            const Kernel::Material &&material)
     : m_triangles(std::move(faces)), m_vertices(std::move(vertices)),
@@ -207,10 +206,11 @@ bool MeshObject2D::isValid(const Kernel::V3D &point) const {
 
   static const double tolerance = 1e-9;
   if (distanceToPlane(point) < tolerance) {
-    for (size_t i = 0; i < m_vertices.size(); i += 3) {
+    for (size_t i = 0; i < m_triangles.size(); i += 3) {
 
-      if (MeshObjectCommon::isOnTriangle(point, m_vertices[i],
-                                         m_vertices[i + 1], m_vertices[i + 2]))
+      if (MeshObjectCommon::isOnTriangle(point, m_vertices[m_triangles[i]],
+                                         m_vertices[m_triangles[i + 1]],
+                                         m_vertices[m_triangles[i + 2]]))
         return true;
     }
   }
@@ -393,10 +393,7 @@ std::vector<double> MeshObject2D::getVertices() const {
   return MeshObjectCommon::getVertices(m_vertices);
 }
 
-std::vector<uint32_t> MeshObject2D::getTriangles() const {
-
-  return MeshObjectCommon::getTriangles_uint32(m_triangles);
-}
+std::vector<uint32_t> MeshObject2D::getTriangles() const { return m_triangles; }
 
 void MeshObject2D::GetObjectGeom(detail::ShapeInfo::GeometryShape &,
                                  std::vector<Kernel::V3D> &, double &,
diff --git a/Framework/Geometry/src/Objects/MeshObjectCommon.cpp b/Framework/Geometry/src/Objects/MeshObjectCommon.cpp
index 368cff0fa3426ede810b886b5d82b8d42062666f..4b1e80dae712c2ad77757ba02f170f0ad4676faa 100644
--- a/Framework/Geometry/src/Objects/MeshObjectCommon.cpp
+++ b/Framework/Geometry/src/Objects/MeshObjectCommon.cpp
@@ -190,30 +190,13 @@ bool rayIntersectsTriangle(const Kernel::V3D &start,
 }
 
 void checkVertexLimit(size_t nVertices) {
-  if (nVertices > std::numeric_limits<uint16_t>::max()) {
+  if (nVertices >= std::numeric_limits<uint32_t>::max()) {
     throw std::invalid_argument(
         "Too many vertices (" + std::to_string(nVertices) +
-        "). MeshObject cannot have more than 65535 vertices.");
+        "). MeshObject cannot have more than 2^32 vertices.");
   }
 }
 
-/**
- * Converts triangle indices from unit16 to unit32
- * @param input
- * @return indices as unit32 vector
- */
-std::vector<uint32_t> getTriangles_uint32(const std::vector<uint16_t> &input) {
-  std::vector<uint32_t> faces;
-  size_t nFaceCorners = input.size();
-  if (nFaceCorners > 0) {
-    faces.resize(static_cast<std::size_t>(nFaceCorners));
-    for (size_t i = 0; i < nFaceCorners; ++i) {
-      faces[i] = static_cast<int>(input[i]);
-    }
-  }
-  return faces;
-}
-
 /**
  * Takes input vertices and calculates bounding box. Returns the bounding box.
  *
diff --git a/Framework/Geometry/test/MeshObject2DTest.h b/Framework/Geometry/test/MeshObject2DTest.h
index 7d0f1a2e79b0eb6a83b060929baf37a40e4bde67..3309a6da1a2d87dbaf6f6ff73a96853b1f642871 100644
--- a/Framework/Geometry/test/MeshObject2DTest.h
+++ b/Framework/Geometry/test/MeshObject2DTest.h
@@ -30,14 +30,14 @@ MeshObject2D makeSimpleTriangleMesh() {
   vertices.emplace_back(V3D(-1, 0, 0));
   vertices.emplace_back(V3D(1, 0, 0));
   vertices.emplace_back(V3D(0, 1, 0));
-  std::vector<uint16_t> triangles;
+  std::vector<uint32_t> triangles;
   triangles.insert(triangles.end(), {0, 1, 2});
   return MeshObject2D(triangles, vertices, Mantid::Kernel::Material());
 }
 MeshObject2D makeTrapezoidMesh(const V3D &a, const V3D &b, const V3D &c,
                                const V3D &d) {
   std::vector<V3D> vertices{a, b, c, d};
-  std::vector<uint16_t> triangles;
+  std::vector<uint32_t> triangles;
   triangles.insert(triangles.end(), {0, 1, 2});
   triangles.insert(triangles.end(), {2, 3, 0});
   return MeshObject2D(triangles, vertices, Mantid::Kernel::Material());
@@ -108,7 +108,7 @@ public:
     vertices.emplace_back(V3D(0, 0, 0));
     vertices.emplace_back(V3D(1, 0, 0));
 
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(),
                      {0, 1, 1}); // invalid, but doesn't matter for this test
 
@@ -131,7 +131,7 @@ public:
     vertices.emplace_back(V3D(1, 0, 0));
     vertices.emplace_back(V3D(2, 0, 0));
 
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {0, 1, 2});
 
     // Test constructor taking lvalue references
@@ -155,7 +155,7 @@ public:
     vertices.emplace_back(V3D(1, 1, 0));
     vertices.emplace_back(V3D(1, 0, 1));
 
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {0, 1, 2});
 
     // Test constructor taking lvalue references
@@ -176,9 +176,9 @@ public:
     vertices.emplace_back(V3D(-1, 0, 0));
     vertices.emplace_back(V3D(1, 0, 0));
     vertices.emplace_back(V3D(0, 1, 0));
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {0, 1, 2});
-
+#
     MeshObject2D mesh(triangles, vertices, Mantid::Kernel::Material());
     TS_ASSERT(mesh.hasValidShape());
     TS_ASSERT_EQUALS(mesh.volume(), 0);
@@ -224,7 +224,7 @@ public:
         V3D{-halfSideLength, halfSideLength, observerDistance},
         V3D{halfSideLength, halfSideLength, observerDistance},
         V3D{halfSideLength, -halfSideLength, observerDistance}};
-    std::vector<uint16_t> triangles{2, 1, 0, 0, 3, 2};
+    std::vector<uint32_t> triangles{2, 1, 0, 0, 3, 2};
     MeshObject2D mesh(triangles, vertices, Mantid::Kernel::Material{});
     double solidAngle = mesh.solidAngle(V3D{0, 0, 0});
     TS_ASSERT_DELTA(solidAngle, expected, 1e-3);
@@ -249,7 +249,7 @@ public:
         V3D{-halfSideLength, halfSideLength, observerDistance},
         V3D{halfSideLength, halfSideLength, observerDistance},
         V3D{halfSideLength, -halfSideLength, observerDistance}};
-    std::vector<uint16_t> triangles{2, 1, 0, 0, 3, 2};
+    std::vector<uint32_t> triangles{2, 1, 0, 0, 3, 2};
     // Scaling square uniformly (and reducing distance to origin by same
     // factor), yields same angular area 4pi/6
     V3D scaleFactor{0.5, 0.5, 0.5};
diff --git a/Framework/Geometry/test/MeshObjectCommonTest.h b/Framework/Geometry/test/MeshObjectCommonTest.h
index 6799b51410a03c67d7dd6798c74bd4fc360067d1..128f661a04526d2241ba5be85019b2597c04e9c9 100644
--- a/Framework/Geometry/test/MeshObjectCommonTest.h
+++ b/Framework/Geometry/test/MeshObjectCommonTest.h
@@ -2,6 +2,7 @@
 #define MANTID_GEOMETRY_MESHOBJECTCOMMONTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include <limits>
 
 #include "MantidGeometry/Objects/MeshObjectCommon.h"
 #include "MantidKernel/V3D.h"
@@ -118,6 +119,12 @@ public:
     TS_ASSERT(
         !MeshObjectCommon::isOnTriangle(p3 + V3D(0, 0.0001, 0), p1, p2, p3));
   }
+
+  void testTooManyVertices() {
+    TS_ASSERT_THROWS(MeshObjectCommon::checkVertexLimit(
+                         std::numeric_limits<uint32_t>::max()),
+                     std::invalid_argument &);
+  }
 };
 
 #endif /* MANTID_GEOMETRY_MESHOBJECTCOMMONTEST_H_ */
diff --git a/Framework/Geometry/test/MeshObjectTest.h b/Framework/Geometry/test/MeshObjectTest.h
index 3d1d8d7351919b4be687ee51f33e313275bc506f..fe76d899a4f50eabc9b16a7c6b2a9f0f48486168 100644
--- a/Framework/Geometry/test/MeshObjectTest.h
+++ b/Framework/Geometry/test/MeshObjectTest.h
@@ -7,9 +7,9 @@
 #ifndef MANTID_TESTMESHOBJECT__
 #define MANTID_TESTMESHOBJECT__
 
-#include "MantidGeometry/Objects/MeshObject.h"
-
 #include "MantidGeometry/Math/Algebra.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidGeometry/Objects/MeshObjectCommon.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidGeometry/Objects/Track.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
@@ -74,7 +74,7 @@ std::unique_ptr<MeshObject> createCube(const double size, const V3D &centre) {
   vertices.emplace_back(centre + V3D(max, min, min));
   vertices.emplace_back(centre + V3D(min, min, min));
 
-  std::vector<uint16_t> triangles;
+  std::vector<uint32_t> triangles;
   // top face of cube - z max
   triangles.insert(triangles.end(), {0, 1, 2});
   triangles.insert(triangles.end(), {2, 1, 3});
@@ -124,7 +124,7 @@ std::unique_ptr<MeshObject> createOctahedron() {
   vertices.emplace_back(V3D(0, -u, 0));
   vertices.emplace_back(V3D(0, 0, -u));
 
-  std::vector<uint16_t> triangles;
+  std::vector<uint32_t> triangles;
   // +++ face
   triangles.insert(triangles.end(), {0, 1, 2});
   //++- face
@@ -168,7 +168,7 @@ std::unique_ptr<MeshObject> createLShape() {
   vertices.emplace_back(V3D(1, 2, 1));
   vertices.emplace_back(V3D(0, 2, 1));
 
-  std::vector<uint16_t> triangles;
+  std::vector<uint32_t> triangles;
   // z min
   triangles.insert(triangles.end(), {0, 5, 1});
   triangles.insert(triangles.end(), {1, 3, 2});
@@ -214,7 +214,7 @@ public:
     vertices.emplace_back(V3D(0, 1, 0));
     vertices.emplace_back(V3D(0, 0, 1));
 
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {1, 2, 3});
     triangles.insert(triangles.end(), {2, 1, 0});
     triangles.insert(triangles.end(), {3, 0, 1});
@@ -235,13 +235,6 @@ public:
     TS_ASSERT(cloned);
   }
 
-  void testTooManyVertices() {
-    auto tooManyVertices = std::vector<V3D>(70000);
-    auto triangles = std::vector<uint16_t>(1000);
-    TS_ASSERT_THROWS_ANYTHING(
-        MeshObject(triangles, tooManyVertices, Mantid::Kernel::Material()));
-  }
-
   void testMaterial() {
     using Mantid::Kernel::Material;
     std::vector<V3D> vertices;
@@ -250,7 +243,7 @@ public:
     vertices.emplace_back(V3D(0, 1, 0));
     vertices.emplace_back(V3D(0, 0, 1));
 
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {1, 2, 3});
     triangles.insert(triangles.end(), {2, 1, 0});
     triangles.insert(triangles.end(), {3, 0, 1});
@@ -963,6 +956,40 @@ public:
     TS_ASSERT_THROWS_NOTHING(geom_obj->getTriangles());
     TS_ASSERT_THROWS_NOTHING(geom_obj->getVertices());
   }
+
+  void testRotation()
+  /* Test Rotating a mesh */
+  {
+    auto lShape = createLShape();
+    const double valueList[] = {0, -1, 0, 1, 0, 0, 0, 0, 1};
+    const std::vector<double> rotationMatrix =
+        std::vector<double>(std::begin(valueList), std::end(valueList));
+    const Kernel::Matrix<double> rotation =
+        Kernel::Matrix<double>(rotationMatrix);
+
+    const double checkList[] = {0,  0, 0, 0,  2, 0, -1, 2, 0, -1, 1, 0,
+                                -2, 1, 0, -2, 0, 0, 0,  0, 1, 0,  2, 1,
+                                -1, 2, 1, -1, 1, 1, -2, 1, 1, -2, 0, 1};
+    auto checkVector =
+        std::vector<double>(std::begin(checkList), std::end(checkList));
+
+    TS_ASSERT_THROWS_NOTHING(lShape->rotate(rotation));
+    auto rotated = lShape->getVertices();
+    TS_ASSERT_DELTA(rotated, checkVector, 1e-8);
+  }
+  void testTranslation()
+  /* Test Translating a mesh */
+  {
+    auto octahedron = createOctahedron();
+    V3D translation = V3D(1, 2, 3);
+    const double checkList[] = {2, 2, 3, 1, 3, 3, 1, 2, 4,
+                                0, 2, 3, 1, 1, 3, 1, 2, 2};
+    auto checkVector =
+        std::vector<double>(std::begin(checkList), std::end(checkList));
+    TS_ASSERT_THROWS_NOTHING(octahedron->translate(translation));
+    auto moved = octahedron->getVertices();
+    TS_ASSERT_DELTA(moved, checkVector, 1e-8);
+  }
 };
 
 // -----------------------------------------------------------------------------
@@ -982,6 +1009,22 @@ public:
         smallCube(createCube(0.2)) {
     testPoints = create_test_points();
     testRays = create_test_rays();
+    translation = create_translation_vector();
+    rotation = create_rotation_matrix();
+  }
+
+  void test_rotate(const Kernel::Matrix<double> &) {
+    const size_t number(10000);
+    for (size_t i = 0; i < number; ++i) {
+      octahedron->rotate(rotation);
+    }
+  }
+
+  void test_translate(Kernel::V3D) {
+    const size_t number(10000);
+    for (size_t i = 0; i < number; ++i) {
+      octahedron->translate(translation);
+    }
   }
 
   void test_isOnSide() {
@@ -1121,6 +1164,19 @@ public:
     return output;
   }
 
+  V3D create_translation_vector() {
+    V3D translate = Kernel::V3D(5, 5, 15);
+    return translate;
+  }
+
+  Kernel::Matrix<double> create_rotation_matrix() {
+    double valueList[] = {0, -1, 0, 1, 0, 0, 0, 0, 1};
+    const std::vector<double> rotationMatrix =
+        std::vector<double>(std::begin(valueList), std::end(valueList));
+    Kernel::Matrix<double> rotation = Kernel::Matrix<double>(rotationMatrix);
+    return rotation;
+  }
+
 private:
   Mantid::Kernel::MersenneTwister rng;
   std::unique_ptr<MeshObject> octahedron;
@@ -1128,6 +1184,8 @@ private:
   std::unique_ptr<MeshObject> smallCube;
   std::vector<V3D> testPoints;
   std::vector<Track> testRays;
+  V3D translation;
+  Kernel::Matrix<double> rotation;
 };
 
 #endif // MANTID_TESTMESHOBJECT__
diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h
index 2d489ef0c9112c499ada8bab332227e43f080f64..cc3728edbbf44ff265ff7c1257a8e84306e28e68 100644
--- a/Framework/Geometry/test/MockObjects.h
+++ b/Framework/Geometry/test/MockObjects.h
@@ -81,11 +81,14 @@ public:
   MOCK_CONST_METHOD0(getK, double());
   MOCK_CONST_METHOD0(getL, double());
   MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D());
+  MOCK_CONST_METHOD0(getSamplePos, Mantid::Kernel::V3D());
   MOCK_METHOD1(setH, void(double m_H));
   MOCK_METHOD1(setK, void(double m_K));
   MOCK_METHOD1(setL, void(double m_L));
   MOCK_METHOD3(setHKL, void(double H, double K, double L));
   MOCK_METHOD1(setHKL, void(const Mantid::Kernel::V3D &HKL));
+  MOCK_METHOD3(setSamplePos, void(double samX, double samY, double samZ));
+  MOCK_METHOD1(setSamplePos, void(const Mantid::Kernel::V3D &XYZ));
   MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
   MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
   MOCK_METHOD0(findDetector, bool());
diff --git a/Framework/ICat/src/ICat3/ICat3Helper.cpp b/Framework/ICat/src/ICat3/ICat3Helper.cpp
index 70fcd3a91ef39f0723ace3d6bd772c3ddeb75efc..200cea75df2fd73c83e517555e30bb7bbb9f65f3 100644
--- a/Framework/ICat/src/ICat3/ICat3Helper.cpp
+++ b/Framework/ICat/src/ICat3/ICat3Helper.cpp
@@ -190,18 +190,15 @@ void CICatHelper::saveInvestigationIncludesResponse(
         savetoTableWorkspace((*datafile_citr)->location, t);
 
         // File creation Time.
-        std::string *creationtime = nullptr;
-        if ((*datafile_citr)->datafileCreateTime != nullptr) {
-          time_t crtime = *(*datafile_citr)->datafileCreateTime;
-          char temp[25];
-          strftime(temp, 25, "%Y-%b-%d %H:%M:%S", localtime(&crtime));
-          std::string ftime(temp);
-          creationtime = new std::string;
-          creationtime->assign(ftime);
+        if ((*datafile_citr)->datafileCreateTime) {
+          const static std::string format("%Y-%b-%d %H:%M:%S");
+          std::string creationTime;
+          creationTime.resize(format.size());
+          const time_t crtime = *(*datafile_citr)->datafileCreateTime;
+          strftime(const_cast<char *>(creationTime.data()), creationTime.size(),
+                   format.data(), localtime(&crtime));
+          savetoTableWorkspace(creationTime.data(), t);
         }
-        savetoTableWorkspace(creationtime, t);
-        if (creationtime)
-          delete creationtime;
 
         //
         savetoTableWorkspace((*datafile_citr)->id, t);
@@ -385,8 +382,8 @@ void CICatHelper::doMyDataSearch(API::ITableWorkspace_sptr &ws_sptr) {
   std::string sessionID = m_session->getSessionId();
   request.sessionId = &sessionID;
   // investigation include
-  boost::shared_ptr<ns1__investigationInclude> invstInculde_sptr(
-      new ns1__investigationInclude);
+  boost::shared_ptr<ns1__investigationInclude> invstInculde_sptr =
+      boost::make_shared<ns1__investigationInclude>();
   request.investigationInclude = invstInculde_sptr.get();
   *request.investigationInclude =
       ns1__investigationInclude__INVESTIGATORS_USCORESHIFTS_USCOREAND_USCORESAMPLES;
diff --git a/Framework/Indexing/inc/MantidIndexing/IndexSet.h b/Framework/Indexing/inc/MantidIndexing/IndexSet.h
index dfb3c25774aa69eeff63db6be74df21ebbca5295..ed50cbb1229484d106900bd8f78fb414a784ce2e 100644
--- a/Framework/Indexing/inc/MantidIndexing/IndexSet.h
+++ b/Framework/Indexing/inc/MantidIndexing/IndexSet.h
@@ -91,6 +91,8 @@ public:
     return m_indices[index];
   }
 
+  bool isContiguous() const noexcept;
+
 protected:
   ~IndexSet() = default;
 
@@ -139,6 +141,20 @@ IndexSet<T>::IndexSet(const std::vector<size_t> &indices, size_t fullRange)
   m_size = m_indices.size();
 }
 
+/**
+ * Check if the index range is contiguous and in ascending order.
+ */
+template <class T> bool IndexSet<T>::isContiguous() const noexcept {
+  if (!m_isRange || m_indices.size() > 1) {
+    for (size_t i = 0; i < m_indices.size() - 1; ++i) {
+      if (m_indices[i] + 1 != m_indices[i + 1]) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 } // namespace detail
 } // namespace Indexing
 } // namespace Mantid
diff --git a/Framework/Indexing/test/IndexSetTest.h b/Framework/Indexing/test/IndexSetTest.h
index 916f4429dd1990f9e9c9f9eccc7666c94cb2126b..7108f6770e5cbcda0bf5ca9ff08a792546440161 100644
--- a/Framework/Indexing/test/IndexSetTest.h
+++ b/Framework/Indexing/test/IndexSetTest.h
@@ -137,6 +137,17 @@ public:
     TS_ASSERT_THROWS_NOTHING(--it2);
     TS_ASSERT_EQUALS(*it2, 0);
   }
+
+  void test_isContiguous() {
+    const IndexSetTester empty{};
+    TS_ASSERT(empty.isContiguous())
+    const IndexSetTester range(3);
+    TS_ASSERT(range.isContiguous())
+    const IndexSetTester manualRange({3, 4, 5}, 6);
+    TS_ASSERT(manualRange.isContiguous())
+    IndexSetTester nonContiguous({2, 1, 3}, 4);
+    TS_ASSERT(!nonContiguous.isContiguous())
+  }
 };
 
 #endif /* MANTID_INDEXING_INDEXSETTEST_H_ */
diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt
index eef665587c030544d673251947cd966ffc7b1d77..02ba8ed36e241aebaae702f3b054e909ed1eb85a 100644
--- a/Framework/Kernel/CMakeLists.txt
+++ b/Framework/Kernel/CMakeLists.txt
@@ -607,7 +607,7 @@ configure_file ( ../Properties/Mantid.properties.template
 if(MSVC)
   file(GENERATE
      OUTPUT
-     ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/Mantid.properties
+     ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/$<CONFIG>/Mantid.properties
      INPUT
      ${CMAKE_CURRENT_BINARY_DIR}/Mantid.properties.config
   )
diff --git a/Framework/Kernel/inc/MantidKernel/ArrayProperty.h b/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
index a9864990368bcdcc65bdfbef2c0ef90266ed10ec..17da6e6dd462cbec32944e2f600bc7f1ffeaa770 100644
--- a/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
@@ -29,14 +29,14 @@ namespace Kernel {
 template <typename T>
 class DLLExport ArrayProperty : public PropertyWithValue<std::vector<T>> {
 public:
-  ArrayProperty(const std::string &name, const std::vector<T> &vec,
+  ArrayProperty(std::string name, std::vector<T> vec,
                 IValidator_sptr validator = IValidator_sptr(new NullValidator),
                 const unsigned int direction = Direction::Input);
-  ArrayProperty(const std::string &name, IValidator_sptr validator,
+  ArrayProperty(std::string name, IValidator_sptr validator,
                 const unsigned int direction = Direction::Input);
-  ArrayProperty(const std::string &name,
+  ArrayProperty(std::string name,
                 const unsigned int direction = Direction::Input);
-  ArrayProperty(const std::string &name, const std::string &values,
+  ArrayProperty(std::string name, const std::string &values,
                 IValidator_sptr validator = IValidator_sptr(new NullValidator),
                 const unsigned int direction = Direction::Input);
 
diff --git a/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Framework/Kernel/inc/MantidKernel/ConfigService.h
index 2530996bee636dc0a6b8b0204024b1bce49abd0c..7f220c2e7a874780c2abbf39206cf7a4c8026742 100644
--- a/Framework/Kernel/inc/MantidKernel/ConfigService.h
+++ b/Framework/Kernel/inc/MantidKernel/ConfigService.h
@@ -16,6 +16,7 @@
 #include <boost/optional/optional.hpp>
 
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -288,9 +289,9 @@ private:
   // Forward declaration of inner class
   template <class T> class WrappedObject;
   /// the POCO file config object
-  WrappedObject<Poco::Util::PropertyFileConfiguration> *m_pConf;
+  std::unique_ptr<WrappedObject<Poco::Util::PropertyFileConfiguration>> m_pConf;
   /// the POCO system Config Object
-  WrappedObject<Poco::Util::SystemConfiguration> *m_pSysConfig;
+  std::unique_ptr<WrappedObject<Poco::Util::SystemConfiguration>> m_pSysConfig;
 
   /// A set of property keys that have been changed
   mutable std::set<std::string> m_changed_keys;
diff --git a/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Framework/Kernel/inc/MantidKernel/InternetHelper.h
index 2447b3c1c11a950a57c88ad45c13b2c5fdf1f3dd..9b15a860223b79c4da8c66be9aadff3653c5c788 100644
--- a/Framework/Kernel/inc/MantidKernel/InternetHelper.h
+++ b/Framework/Kernel/inc/MantidKernel/InternetHelper.h
@@ -12,6 +12,7 @@
 
 #include <ios>
 #include <map>
+#include <memory>
 #include <string>
 
 namespace Poco {
@@ -157,8 +158,8 @@ protected:
   std::string m_contentType;
   std::string m_body;
   StringToStringMap m_headers;
-  Poco::Net::HTTPRequest *m_request;
-  Poco::Net::HTTPResponse *m_response;
+  std::unique_ptr<Poco::Net::HTTPRequest> m_request;
+  std::unique_ptr<Poco::Net::HTTPResponse> m_response;
 };
 
 } // namespace Kernel
diff --git a/Framework/Kernel/inc/MantidKernel/Property.h b/Framework/Kernel/inc/MantidKernel/Property.h
index 5e7e3cb1630ec94e7a958fdf7e2d68afc7b5929c..85cd4f0f43ecfabf4cc14bd7a3e99be2d5dbf4eb 100644
--- a/Framework/Kernel/inc/MantidKernel/Property.h
+++ b/Framework/Kernel/inc/MantidKernel/Property.h
@@ -196,8 +196,8 @@ public:
 
 protected:
   /// Constructor
-  Property(const std::string &name, const std::type_info &type,
-           const unsigned int direction = Direction::Input);
+  Property(std::string name, const std::type_info &type,
+           unsigned int direction = Direction::Input);
   /// Copy constructor
   Property(const Property &right);
   /// The name of the property
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
index d5907ce819cfe44dc2e053a8473ced31bd0bf11b..7de94ff751e6b75f6afff76ef3d325dc74b73040 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
@@ -38,13 +38,13 @@ namespace Kernel {
 template <typename TYPE> class DLLExport PropertyWithValue : public Property {
 public:
   PropertyWithValue(
-      const std::string &name, const TYPE &defaultValue,
+      std::string name, TYPE defaultValue,
       IValidator_sptr validator = IValidator_sptr(new NullValidator),
       const unsigned int direction = Direction::Input);
-  PropertyWithValue(const std::string &name, const TYPE &defaultValue,
+  PropertyWithValue(std::string name, TYPE defaultValue,
                     const unsigned int direction);
-  PropertyWithValue(const std::string &name, const TYPE &defaultValue,
-                    const std::string defaultValueStr,
+  PropertyWithValue(std::string name, TYPE defaultValue,
+                    const std::string &defaultValueStr,
                     IValidator_sptr validator, const unsigned int direction);
   PropertyWithValue(const PropertyWithValue &right);
   PropertyWithValue<TYPE> *clone() const override;
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
index a4c0e34392a751b18dd838294ed9ae2743721dbe..da008842b9f38c99b288f02b5317bdac62ef083d 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
@@ -39,12 +39,12 @@ namespace Kernel {
  * or Direction::InOut (Input & Output) property
  */
 template <typename TYPE>
-PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
-                                           const TYPE &defaultValue,
+PropertyWithValue<TYPE>::PropertyWithValue(std::string name,
+                                           TYPE defaultValue,
                                            IValidator_sptr validator,
-                                           const unsigned int direction)
-    : Property(name, typeid(TYPE), direction), m_value(defaultValue),
-      m_initialValue(defaultValue), m_validator(validator) {}
+                                           unsigned int direction)
+    : Property(std::move(name), typeid(TYPE), direction), m_value(defaultValue),
+      m_initialValue(std::move(defaultValue)), m_validator(std::move(validator)) {}
 
 /** Constructor
  *  @param name :: The name to assign to the property
@@ -53,11 +53,11 @@ PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
  * or Direction::InOut (Input & Output) property
  */
 template <typename TYPE>
-PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
-                                           const TYPE &defaultValue,
-                                           const unsigned int direction)
-    : Property(name, typeid(TYPE), direction), m_value(defaultValue),
-      m_initialValue(defaultValue),
+PropertyWithValue<TYPE>::PropertyWithValue(std::string name,
+                                           TYPE defaultValue,
+                                           unsigned int direction)
+    : Property(std::move(name), typeid(TYPE), direction), m_value(defaultValue),
+      m_initialValue(std::move(defaultValue)),
       m_validator(boost::make_shared<NullValidator>()) {}
 
 /*
@@ -75,15 +75,15 @@ PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
   * or Direction::InOut (Input & Output) property
   */
 template <typename TYPE>
-PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
-                                           const TYPE &defaultValue,
-                                           const std::string defaultValueStr,
+PropertyWithValue<TYPE>::PropertyWithValue(std::string name,
+                                           TYPE defaultValue,
+                                           const std::string &defaultValueStr,
                                            IValidator_sptr validator,
-                                           const unsigned int direction)
-    : Property(name, typeid(TYPE), direction),
+                                           unsigned int direction)
+    : Property(std::move(name), typeid(TYPE), direction),
       m_value(extractToValueVector<TYPE>(defaultValueStr)),
-      m_initialValue(extractToValueVector<TYPE>(defaultValueStr)),
-      m_validator(validator) {
+      m_initialValue(m_value),
+      m_validator(std::move(validator)) {
   UNUSED_ARG(defaultValue);
 }
 
diff --git a/Framework/Kernel/inc/MantidKernel/ThreadPool.h b/Framework/Kernel/inc/MantidKernel/ThreadPool.h
index 6825b7ece64609a41952cc57bcd13d21048a6a59..7dd51777ba32c6b7018779de810b51ada5727160 100644
--- a/Framework/Kernel/inc/MantidKernel/ThreadPool.h
+++ b/Framework/Kernel/inc/MantidKernel/ThreadPool.h
@@ -54,19 +54,19 @@ protected:
   size_t m_numThreads;
 
   /// The ThreadScheduler instance taking care of task scheduling
-  ThreadScheduler *m_scheduler;
+  std::unique_ptr<ThreadScheduler> m_scheduler;
 
   /// Vector with all the threads that are started
-  std::vector<Poco::Thread *> m_threads;
+  std::vector<std::unique_ptr<Poco::Thread>> m_threads;
 
   /// Vector of the POCO-required classes to actually run in a thread.
-  std::vector<ThreadPoolRunnable *> m_runnables;
+  std::vector<std::unique_ptr<ThreadPoolRunnable>> m_runnables;
 
   /// Have the threads started?
   bool m_started;
 
   /// Progress reporter
-  ProgressBase *m_prog;
+  std::unique_ptr<ProgressBase> m_prog;
 
 private:
   // prohibit default copy constructor as it does not work
diff --git a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
index b089666b7e5527272d6e4524161007c3dee88e62..06e3571330fbe3a9fb62750f1cbf35885147d4b7 100644
--- a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
@@ -35,7 +35,10 @@ CatalogConfigService *makeCatalogConfigServiceAdapter(
     Adapter(const T &adaptee, const std::string key)
         : m_adaptee(adaptee), m_key(key) {}
     OptionalPath preferredMountPoint() const override {
-      return m_adaptee.getString(m_key);
+      auto const mountPoint = m_adaptee.getString(m_key);
+      if (!mountPoint.empty())
+        return OptionalPath(mountPoint);
+      return OptionalPath(boost::none);
     }
   };
   return new Adapter(adaptee, key);
diff --git a/Framework/Kernel/src/ANN/bd_tree.h b/Framework/Kernel/src/ANN/bd_tree.h
index 7670c06383cf326770f93958e6866df18f8733dc..10ba69c5a0b904de4bc474c8ff53a63b223e08ea 100644
--- a/Framework/Kernel/src/ANN/bd_tree.h
+++ b/Framework/Kernel/src/ANN/bd_tree.h
@@ -78,12 +78,11 @@ public:
 
   ~ANNbd_shrink() override // destructor
   {
-    if (child[ANN_IN] != nullptr && child[ANN_IN] != KD_TRIVIAL)
+    if (child[ANN_IN] != KD_TRIVIAL)
       delete child[ANN_IN];
-    if (child[ANN_OUT] != nullptr && child[ANN_OUT] != KD_TRIVIAL)
+    if (child[ANN_OUT] != KD_TRIVIAL)
       delete child[ANN_OUT];
-    if (bnds != nullptr)
-      delete[] bnds; // delete bounds
+    delete[] bnds; // delete bounds
   }
 
   void getStats(                                // get tree statistics
diff --git a/Framework/Kernel/src/ArrayProperty.cpp b/Framework/Kernel/src/ArrayProperty.cpp
index 57df5d46ff79824e15087258bdb6c8160c979277..936dc6cc5b0a15d6f893b52c675275251c6a0491 100644
--- a/Framework/Kernel/src/ArrayProperty.cpp
+++ b/Framework/Kernel/src/ArrayProperty.cpp
@@ -18,11 +18,11 @@ namespace Kernel {
  *  @param direction :: The direction (Input/Output/InOut) of this property
  */
 template <typename T>
-ArrayProperty<T>::ArrayProperty(const std::string &name,
-                                const std::vector<T> &vec,
+ArrayProperty<T>::ArrayProperty(std::string name, std::vector<T> vec,
                                 IValidator_sptr validator,
                                 const unsigned int direction)
-    : PropertyWithValue<std::vector<T>>(name, vec, validator, direction) {}
+    : PropertyWithValue<std::vector<T>>(std::move(name), std::move(vec),
+                                        std::move(validator), direction) {}
 
 /** Constructor
  *  Will lead to the property having a default-constructed (i.e. empty) vector
@@ -33,11 +33,10 @@ ArrayProperty<T>::ArrayProperty(const std::string &name,
  */
 
 template <typename T>
-ArrayProperty<T>::ArrayProperty(const std::string &name,
-                                IValidator_sptr validator,
+ArrayProperty<T>::ArrayProperty(std::string name, IValidator_sptr validator,
                                 const unsigned int direction)
-    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), validator,
-                                        direction) {}
+    : PropertyWithValue<std::vector<T>>(std::move(name), std::vector<T>(),
+                                        std::move(validator), direction) {}
 
 /** Constructor that's useful for output properties or inputs with an empty
  * default and no validator.
@@ -47,9 +46,8 @@ ArrayProperty<T>::ArrayProperty(const std::string &name,
  *  @param direction :: The direction (Input/Output/InOut) of this property
  */
 template <typename T>
-ArrayProperty<T>::ArrayProperty(const std::string &name,
-                                const unsigned int direction)
-    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(),
+ArrayProperty<T>::ArrayProperty(std::string name, const unsigned int direction)
+    : PropertyWithValue<std::vector<T>>(std::move(name), std::vector<T>(),
                                         IValidator_sptr(new NullValidator),
                                         direction) {}
 
@@ -69,12 +67,12 @@ ArrayProperty<T>::ArrayProperty(const std::string &name,
  * the array type
  */
 template <typename T>
-ArrayProperty<T>::ArrayProperty(const std::string &name,
-                                const std::string &values,
+ArrayProperty<T>::ArrayProperty(std::string name, const std::string &values,
                                 IValidator_sptr validator,
                                 const unsigned int direction)
-    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), values,
-                                        validator, direction) {}
+    : PropertyWithValue<std::vector<T>>(std::move(name), std::vector<T>(),
+                                        values, std::move(validator),
+                                        direction) {}
 
 /// 'Virtual copy constructor'
 template <typename T> ArrayProperty<T> *ArrayProperty<T>::clone() const {
diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp
index 5951d5dc97d495d4e5559c6e24724b6a420d7015..152ddb1f0272e87791ec67a2a17c1e5a8a9855ce 100644
--- a/Framework/Kernel/src/ConfigService.cpp
+++ b/Framework/Kernel/src/ConfigService.cpp
@@ -169,7 +169,8 @@ ConfigServiceImpl::ConfigServiceImpl()
       m_DataSearchDirs(), m_UserSearchDirs(), m_InstrumentDirs(),
       m_instr_prefixes(), m_proxyInfo(), m_isProxySet(false) {
   // getting at system details
-  m_pSysConfig = new WrappedObject<Poco::Util::SystemConfiguration>;
+  m_pSysConfig =
+      std::make_unique<WrappedObject<Poco::Util::SystemConfiguration>>();
   m_pConf = nullptr;
 
   // Register StdChannel with Poco
@@ -280,8 +281,6 @@ ConfigServiceImpl::ConfigServiceImpl()
 ConfigServiceImpl::~ConfigServiceImpl() {
   // std::cerr << "ConfigService destroyed.\n";
   Kernel::Logger::shutdown();
-  delete m_pSysConfig;
-  delete m_pConf; // potential double delete???
   clearFacilities();
 }
 
@@ -387,7 +386,7 @@ std::string checkForBadConfigOptions(const std::string &filename,
  */
 void ConfigServiceImpl::loadConfig(const std::string &filename,
                                    const bool append) {
-  delete m_pConf;
+
   if (!append) {
     // remove the previous property string
     m_PropertyString = "";
@@ -428,7 +427,9 @@ void ConfigServiceImpl::loadConfig(const std::string &filename,
 
   // use the cached property string to initialise the POCO property file
   std::istringstream istr(m_PropertyString);
-  m_pConf = new WrappedObject<Poco::Util::PropertyFileConfiguration>(istr);
+  m_pConf =
+      std::make_unique<WrappedObject<Poco::Util::PropertyFileConfiguration>>(
+          istr);
 }
 
 /**
@@ -462,7 +463,7 @@ void ConfigServiceImpl::configureLogging() {
   try {
     // Configure the logging framework
     Poco::Util::LoggingConfigurator configurator;
-    configurator.configure(m_pConf);
+    configurator.configure(m_pConf.get());
   } catch (std::exception &e) {
     std::cerr << "Trouble configuring the logging framework " << e.what()
               << '\n';
diff --git a/Framework/Kernel/src/Exception.cpp b/Framework/Kernel/src/Exception.cpp
index 6d6f56528af921bdb6e7cdbc58362858607a91cc..5919ced3d8c3c19fcb85063ba4c85793b09606cf 100644
--- a/Framework/Kernel/src/Exception.cpp
+++ b/Framework/Kernel/src/Exception.cpp
@@ -19,7 +19,8 @@ namespace Exception {
 */
 FileError::FileError(const std::string &Desc, const std::string &FName)
     : std::runtime_error(Desc), fileName(FName) {
-  outMessage = std::string(std::runtime_error::what()) + " in " + fileName;
+  outMessage =
+      std::string(std::runtime_error::what()) + " in \"" + fileName + "\"";
 }
 
 /// Copy constructor
diff --git a/Framework/Kernel/src/ICatalogInfo.cpp b/Framework/Kernel/src/ICatalogInfo.cpp
index 80f76c830d5e388bfd0f50de9aedddec9020457d..c8de68e8b0b4fe5703f1fc3c4af15fbaef28e33f 100644
--- a/Framework/Kernel/src/ICatalogInfo.cpp
+++ b/Framework/Kernel/src/ICatalogInfo.cpp
@@ -25,7 +25,7 @@ std::string ICatalogInfo::transformArchivePath(const std::string &path) const {
     ret = replacePrefix(path, linuxPrefix(), windowsPrefix());
     ret = replaceAllOccurences(ret, "/", "\\");
   } else {
-    ret = path;
+    ret = replacePrefix(path, catalogPrefix(), windowsPrefix());
   }
 #endif
   return ret;
diff --git a/Framework/Kernel/src/InternetHelper.cpp b/Framework/Kernel/src/InternetHelper.cpp
index 55d54fd383593e99fa1bb6694fe55bc5f31c8fbf..c71a1583afeae5f0f5ff88ecb34d752ea8221dbb 100644
--- a/Framework/Kernel/src/InternetHelper.cpp
+++ b/Framework/Kernel/src/InternetHelper.cpp
@@ -108,14 +108,7 @@ InternetHelper::InternetHelper(const Kernel::ProxyInfo &proxy)
 //----------------------------------------------------------------------------------------------
 /** Destructor
  */
-InternetHelper::~InternetHelper() {
-  if (m_request != nullptr) {
-    delete m_request;
-  }
-  if (m_response != nullptr) {
-    delete m_response;
-  }
-}
+InternetHelper::~InternetHelper() = default;
 
 void InternetHelper::setupProxyOnSession(HTTPClientSession &session,
                                          const std::string &proxyUrl) {
@@ -127,17 +120,9 @@ void InternetHelper::setupProxyOnSession(HTTPClientSession &session,
 }
 
 void InternetHelper::createRequest(Poco::URI &uri) {
-  if (m_request != nullptr) {
-    delete m_request;
-  }
-  if (m_response != nullptr) {
-    delete m_response;
-  }
-
-  m_request =
-      new HTTPRequest(m_method, uri.getPathAndQuery(), HTTPMessage::HTTP_1_1);
-
-  m_response = new HTTPResponse();
+  m_request = std::make_unique<HTTPRequest>(m_method, uri.getPathAndQuery(),
+                                            HTTPMessage::HTTP_1_1);
+  m_response = std::make_unique<HTTPResponse>();
   if (!m_contentType.empty()) {
     m_request->setContentType(m_contentType);
   }
diff --git a/Framework/Kernel/src/Property.cpp b/Framework/Kernel/src/Property.cpp
index c222fb1bf1e2327620c89bba8b5b6deafde4830d..c8c02da9eb8411266d011d41c9544e63174c68a7 100644
--- a/Framework/Kernel/src/Property.cpp
+++ b/Framework/Kernel/src/Property.cpp
@@ -25,9 +25,9 @@ namespace Kernel {
  *  @param direction :: Whether this is a Direction::Input, Direction::Output or
  * Direction::InOut (Input & Output) property
  */
-Property::Property(const std::string &name, const std::type_info &type,
+Property::Property(std::string name, const std::type_info &type,
                    const unsigned int direction)
-    : m_name(name), m_documentation(""), m_typeinfo(&type),
+    : m_name(std::move(name)), m_documentation(""), m_typeinfo(&type),
       m_direction(direction), m_units(""), m_group(""), m_remember(true),
       m_autotrim(true) {
   // Make sure a random int hasn't been passed in for the direction
diff --git a/Framework/Kernel/src/PropertyNexus.cpp b/Framework/Kernel/src/PropertyNexus.cpp
index bf03367765f1d0713d12a63663dab0db4dfb3d13..ed908626f791792db450649010c2265a6f1598d2 100644
--- a/Framework/Kernel/src/PropertyNexus.cpp
+++ b/Framework/Kernel/src/PropertyNexus.cpp
@@ -57,7 +57,8 @@ makeProperty(::NeXus::File *file, const std::string &name,
       return Mantid::Kernel::make_unique<PropertyWithValue<NumT>>(name,
                                                                   values[0]);
     } else {
-      return Mantid::Kernel::make_unique<ArrayProperty<NumT>>(name, values);
+      return Mantid::Kernel::make_unique<ArrayProperty<NumT>>(
+          name, std::move(values));
     }
   } else {
     auto prop = Mantid::Kernel::make_unique<TimeSeriesProperty<NumT>>(name);
diff --git a/Framework/Kernel/src/ThreadPool.cpp b/Framework/Kernel/src/ThreadPool.cpp
index c84e988f2d0d1c001d16fa43122e2981fb8c8890..f381b9f7f3b35934a9ae73ac078cf98d99eaee45 100644
--- a/Framework/Kernel/src/ThreadPool.cpp
+++ b/Framework/Kernel/src/ThreadPool.cpp
@@ -43,7 +43,8 @@ namespace Kernel {
  */
 ThreadPool::ThreadPool(ThreadScheduler *scheduler, size_t numThreads,
                        ProgressBase *prog)
-    : m_scheduler(scheduler), m_started(false), m_prog(prog) {
+    : m_scheduler(std::unique_ptr<ThreadScheduler>(scheduler)),
+      m_started(false), m_prog(std::unique_ptr<ProgressBase>(prog)) {
   if (!m_scheduler)
     throw std::invalid_argument(
         "NULL ThreadScheduler passed to ThreadPool constructor.");
@@ -59,12 +60,7 @@ ThreadPool::ThreadPool(ThreadScheduler *scheduler, size_t numThreads,
 //--------------------------------------------------------------------------------
 /** Destructor. Deletes the ThreadScheduler.
  */
-ThreadPool::~ThreadPool() {
-  if (m_scheduler)
-    delete m_scheduler;
-  if (m_prog)
-    delete m_prog;
-}
+ThreadPool::~ThreadPool() = default;
 
 //--------------------------------------------------------------------------------
 /** Return the number of physical cores available on the system.
@@ -102,13 +98,6 @@ size_t ThreadPool::getNumPhysicalCores() {
 void ThreadPool::start(double waitSec) {
   if (m_started)
     throw std::runtime_error("Threads have already started.");
-
-  // Delete any old threads (they should NOT be running!)
-  for (auto &thread : m_threads)
-    delete thread;
-  for (auto &runnable : m_runnables)
-    delete runnable;
-
   // Now, launch that many threads and let them wait for new tasks.
   m_threads.clear();
   m_runnables.clear();
@@ -117,14 +106,13 @@ void ThreadPool::start(double waitSec) {
     std::ostringstream name;
     name << "Thread" << i;
     // Create the thread
-    Poco::Thread *thread = new Poco::Thread(name.str());
-    m_threads.push_back(thread);
-
+    auto thread = std::make_unique<Poco::Thread>(name.str());
     // Make the runnable object and run it
-    auto runnable = new ThreadPoolRunnable(i, m_scheduler, m_prog, waitSec);
-    m_runnables.push_back(runnable);
-
+    auto runnable = std::make_unique<ThreadPoolRunnable>(i, m_scheduler.get(),
+                                                         m_prog.get(), waitSec);
     thread->start(*runnable);
+    m_threads.push_back(std::move(thread));
+    m_runnables.push_back(std::move(runnable));
   }
   // Yep, all the threads are running.
   m_started = true;
@@ -184,15 +172,12 @@ void ThreadPool::joinAll() {
   // Sequentially join all the threads.
   for (auto &thread : m_threads) {
     thread->join();
-    delete thread;
   }
 
   // Clear the vectors (the threads are deleted now).
   m_threads.clear();
 
   // Get rid of the runnables too
-  for (auto &runnable : m_runnables)
-    delete runnable;
   m_runnables.clear();
 
   // This will make threads restart
diff --git a/Framework/Kernel/test/ArrayPropertyTest.h b/Framework/Kernel/test/ArrayPropertyTest.h
index 63fadc8763c6df5c87f3d3bff612486db4636fcb..bc71cc0b8c8948467bef9a501e1435cbe06b98f2 100644
--- a/Framework/Kernel/test/ArrayPropertyTest.h
+++ b/Framework/Kernel/test/ArrayPropertyTest.h
@@ -47,17 +47,17 @@ public:
     TS_ASSERT(sProp->operator()().empty())
 
     std::vector<int> i(5, 2);
-    ArrayProperty<int> ip("ip", i);
+    ArrayProperty<int> ip("ip", std::move(i));
     TS_ASSERT_EQUALS(ip.operator()().size(), 5)
     TS_ASSERT_EQUALS(ip.operator()()[3], 2)
 
     std::vector<double> d(4, 6.66);
-    ArrayProperty<double> dp("dp", d);
+    ArrayProperty<double> dp("dp", std::move(d));
     TS_ASSERT_EQUALS(dp.operator()().size(), 4)
     TS_ASSERT_EQUALS(dp.operator()()[1], 6.66)
 
     std::vector<std::string> s(3, "yyy");
-    ArrayProperty<std::string> sp("sp", s);
+    ArrayProperty<std::string> sp("sp", std::move(s));
     TS_ASSERT_EQUALS(sp.operator()().size(), 3)
     TS_ASSERT(!sp.operator()()[2].compare("yyy"))
   }
@@ -77,7 +77,8 @@ public:
     // should only be the size of the
     // parent vector that is counted.
     std::vector<std::vector<int>> input{{10}};
-    Property *b = new ArrayProperty<std::vector<int>>("vec_property", input);
+    Property *b =
+        new ArrayProperty<std::vector<int>>("vec_property", std::move(input));
     TS_ASSERT_EQUALS(1, b->size());
     delete b;
   }
@@ -185,15 +186,15 @@ public:
 
   void testValue() {
     std::vector<int> i(3, 3);
-    ArrayProperty<int> ip("ip", i);
+    ArrayProperty<int> ip("ip", std::move(i));
     TS_ASSERT(!ip.value().compare("3,3,3"))
 
     std::vector<double> d(4, 1.23);
-    ArrayProperty<double> dp("dp", d);
+    ArrayProperty<double> dp("dp", std::move(d));
     TS_ASSERT(!dp.value().compare("1.23,1.23,1.23,1.23"))
 
     std::vector<std::string> s(2, "yyy");
-    ArrayProperty<std::string> sp("sp", s);
+    ArrayProperty<std::string> sp("sp", std::move(s));
     TS_ASSERT(!sp.value().compare("yyy,yyy"))
   }
 
diff --git a/Framework/Kernel/test/CatalogInfoTest.h b/Framework/Kernel/test/CatalogInfoTest.h
index a810c073531fe249a04322ec8fc7cba0b7740d5b..436a65425dfe3e4db5bd55e03a4203476e4f749a 100644
--- a/Framework/Kernel/test/CatalogInfoTest.h
+++ b/Framework/Kernel/test/CatalogInfoTest.h
@@ -75,7 +75,9 @@ public:
         "regex=\"\\\\\\\\isis\\\\inst\\$\\\\Instruments\\$\"></"
         "prefix>" // Same regex from facilities.xml, lots of "\"
                   // character escaping.
-        "<windows replacement=\"\"></windows>"
+        "<windows "
+        "replacement=\"\\\\\\\\isis\\.cclrc\\.ac\\.uk\\\\inst\\$"
+        "\\\\Instruments\\$\"></windows>"
         "<linux replacement=\"/archive\"></linux>"
         "<mac replacement=\"/archive\"></mac>"
         "</filelocation>"
@@ -92,10 +94,9 @@ public:
     std::string macPrefixPath =
         "/archive/NDXSANDALS/Instrument/data/cycle_05_3/ALF06716.LOG";
     std::string winPrefixPath =
-        R"(\NDXSANDALS\Instrument\data\cycle_05_3\ALF06716.LOG)";
-    std::string winDefaultPath = "\\\\isis\\inst$\\Instruments$"
-                                 "\\NDXSANDALS\\Instrument\\data\\cycle_05_"
-                                 "3\\ALF06716.LOG";
+        R"(\\isis.cclrc.ac.uk\inst$\Instruments$\NDXSANDALS\Instrument\data\cycle_05_3\ALF06716.LOG)";
+    std::string winDefaultPath =
+        R"(\\isis\inst$\Instruments$\NDXSANDALS\Instrument\data\cycle_05_3\ALF06716.LOG)";
 
     // Perform the transformation of each path prior to assertions for
     // re-usability of code.
@@ -115,7 +116,7 @@ public:
     TS_ASSERT_EQUALS(macPrefixPath, transformWin);
     TS_ASSERT_EQUALS(macPrefixPath, transformLin);
 #elif _WIN32
-    TS_ASSERT_EQUALS(winDefaultPath, transformWin);
+    TS_ASSERT_EQUALS(winPrefixPath, transformWin);
     TS_ASSERT_EQUALS(winPrefixPath, transformMac);
     TS_ASSERT_EQUALS(winPrefixPath, transformLin);
 #endif
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
index b0b741f84c299154067f9f8278fb7515099f5cce..f5028d7a5ebdb6b8a89c7346e9403b31f5050862 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
@@ -116,7 +116,7 @@ private:
   /// same ion
   std::string m_MagIonName;
   /// Owned pointer to magnetic form factor cache
-  PhysicalConstants::MagneticFormFactorTable *m_formFactorTable;
+  std::unique_ptr<PhysicalConstants::MagneticFormFactorTable> m_formFactorTable;
 };
 
 /// boost::shared_ptr typedef
diff --git a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
index 51ee2c64cfcb4ad502238ffd0d27c173140a6f6f..e31b1bb38fb3390552e84131bfe0e27bb8a86e71 100644
--- a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
@@ -41,7 +41,7 @@ void BoxControllerSettingsAlgorithm::initBoxControllerProps(
     valueVec.push_back(boost::lexical_cast<int>(value));
 
   declareProperty(
-      Kernel::make_unique<ArrayProperty<int>>("SplitInto", valueVec),
+      Kernel::make_unique<ArrayProperty<int>>("SplitInto", std::move(valueVec)),
       "A comma separated list of into how many sub-grid elements each "
       "dimension should split; "
       "or just one to split into the same number for all dimensions. Default " +
diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
index 5e794895af496f3e91319754d38c841d2e0d2706..2646753f573e21a3552844d6f831609829ef9d9d 100644
--- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
+++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
@@ -120,21 +120,21 @@ void CalculateCoverageDGS::init() {
   Q1[0] = 1.;
   Q2[1] = 1.;
   Q3[2] = 1.;
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Q1Basis", Q1, mustBe3D),
-      "Q1 projection direction in the x,y,z format. Q1, Q2, Q3 "
-      "must not be coplanar");
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Q2Basis", Q2, mustBe3D),
-      "Q2 projection direction in the x,y,z format. Q1, Q2, Q3 "
-      "must not be coplanar");
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Q3Basis", Q3, mustBe3D),
-      "Q3 projection direction in the x,y,z format. Q1, Q2, Q3 "
-      "must not be coplanar");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                      "Q1Basis", std::move(Q1), mustBe3D->clone()),
+                  "Q1 projection direction in the x,y,z format. Q1, Q2, Q3 "
+                  "must not be coplanar");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                      "Q2Basis", std::move(Q2), mustBe3D->clone()),
+                  "Q2 projection direction in the x,y,z format. Q1, Q2, Q3 "
+                  "must not be coplanar");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                      "Q3Basis", std::move(Q3), std::move(mustBe3D)),
+                  "Q3 projection direction in the x,y,z format. Q1, Q2, Q3 "
+                  "must not be coplanar");
   declareProperty(
       make_unique<PropertyWithValue<double>>("IncidentEnergy", EMPTY_DBL(),
-                                             mustBePositive,
+                                             std::move(mustBePositive),
                                              Mantid::Kernel::Direction::Input),
       "Incident energy. If set, will override Ei in the input workspace");
 
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
index 8331e8f1cfa9e93d82dbd1dbe4e8725fbcb272b8..9f9cad714a5edf78d829712f6d9d3ae2a4ac077a 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
@@ -123,7 +123,7 @@ void ConvertToDiffractionMDWorkspace::init() {
 
   std::vector<double> extents{-50, +50};
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Extents", extents),
+      Kernel::make_unique<ArrayProperty<double>>("Extents", std::move(extents)),
       "A comma separated list of min, max for each dimension,\n"
       "specifying the extents of each dimension. Optional, default "
       "+-50 in each dimension.");
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp
index e9b438ef627785daff7fdab17304cfc5f18c9aff..6bf69fa6e533bd81ede150e67d95a9730548f2ea 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace2.cpp
@@ -43,7 +43,7 @@ void ConvertToDiffractionMDWorkspace2::init() {
 
   std::vector<double> extents = {-50.0, 50.0};
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Extents", extents),
+      Kernel::make_unique<ArrayProperty<double>>("Extents", std::move(extents)),
       "A comma separated list of min, max for each dimension,\n"
       "specifying the extents of each dimension. Optional, default "
       "+- 50 in each dimension.");
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace3.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace3.cpp
index bf36b4bd90416f7d4b328470259e1b64443f268b..b1e2a5b568fd2155caa91d13f5cdef4827e0f1aa 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace3.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace3.cpp
@@ -43,7 +43,7 @@ void ConvertToDiffractionMDWorkspace3::init() {
 
   std::vector<double> extents;
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Extents", extents),
+      Kernel::make_unique<ArrayProperty<double>>("Extents", std::move(extents)),
       "A comma separated list of min, max for each dimension,\n"
       "specifying the extents of each dimension. Optional, default "
       "will use ConvertToMDMinMaxLocal to calculate extents for each "
diff --git a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
index b122780b0bd1d2a773920ef69c5682b677894ed9..2ade110ebe53da3403a839740697c840b43b9f5c 100644
--- a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
@@ -236,7 +236,7 @@ void ConvertToReflectometryQ::init() {
 
   std::vector<double> extents{-50, +50, -50, +50};
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Extents", extents),
+      Kernel::make_unique<ArrayProperty<double>>("Extents", std::move(extents)),
       "A comma separated list of min, max for each dimension. "
       "Takes four values in the form dim_0_min, dim_0_max, "
       "dim_1_min, dim_1_max,\n"
diff --git a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp
index 684bdd9ac6289b3fc8b11d3ee8ce50e44497a63b..42125b531cb01c05cf0fbcf54d8fd076e5160b5d 100644
--- a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp
+++ b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp
@@ -156,23 +156,25 @@ void LoadDNSSCD::init() {
   v0[2] = 1.;
 
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "a", 1.0, mustBePositive, Direction::Input),
+                      "a", 1.0, mustBePositive->clone(), Direction::Input),
                   "Lattice parameter a in Angstrom");
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "b", 1.0, mustBePositive, Direction::Input),
+                      "b", 1.0, mustBePositive->clone(), Direction::Input),
                   "Lattice parameter b in Angstrom");
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "c", 1.0, mustBePositive, Direction::Input),
+                      "c", 1.0, std::move(mustBePositive), Direction::Input),
                   "Lattice parameter c in Angstrom");
+  declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "alpha", 90.0, reasonableAngle->clone(), Direction::Input),
+      "Angle between b and c in degrees");
   declareProperty(make_unique<PropertyWithValue<double>>(
-                      "alpha", 90.0, reasonableAngle, Direction::Input),
-                  "Angle between b and c in degrees");
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "beta", 90.0, reasonableAngle, Direction::Input),
+                      "beta", 90.0, reasonableAngle->clone(), Direction::Input),
                   "Angle between a and c in degrees");
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "gamma", 90.0, reasonableAngle, Direction::Input),
-                  "Angle between a and b in degrees");
+  declareProperty(
+      make_unique<PropertyWithValue<double>>(
+          "gamma", 90.0, std::move(reasonableAngle), Direction::Input),
+      "Angle between a and b in degrees");
 
   declareProperty(make_unique<PropertyWithValue<double>>(
                       "OmegaOffset", 0.0,
@@ -181,21 +183,23 @@ void LoadDNSSCD::init() {
                   "Angle in degrees between (HKL1) and the beam axis"
                   "if the goniometer is at zero.");
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("HKL1", u0, mustBe3D),
+      Kernel::make_unique<ArrayProperty<double>>("HKL1", std::move(u0),
+                                                 mustBe3D->clone()),
       "Indices of the vector in reciprocal space in the horizontal plane at "
       "angle Omegaoffset, "
       "if the goniometer is at zero.");
 
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("HKL2", v0, mustBe3D),
+      Kernel::make_unique<ArrayProperty<double>>("HKL2", std::move(v0),
+                                                 std::move(mustBe3D)),
       "Indices of a second vector in reciprocal space in the horizontal plane "
       "not parallel to HKL1");
 
   std::vector<double> ttl(2, 0);
   ttl[1] = 180.0;
   declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("TwoThetaLimits", ttl,
-                                                 mustBe2D),
+      Kernel::make_unique<ArrayProperty<double>>(
+          "TwoThetaLimits", std::move(ttl), std::move(mustBe2D)),
       "Range (min, max) of scattering angles (2theta, in degrees) to consider. "
       "Everything out of this range will be cut.");
 
@@ -212,15 +216,16 @@ void LoadDNSSCD::init() {
 
   auto mustBeIntPositive = boost::make_shared<BoundedValidator<int>>();
   mustBeIntPositive->setLower(0);
-  declareProperty(make_unique<PropertyWithValue<int>>(
-                      "ElasticChannel", 0, mustBeIntPositive, Direction::Input),
-                  "Elastic channel number. Only for TOF data.");
+  declareProperty(
+      make_unique<PropertyWithValue<int>>(
+          "ElasticChannel", 0, std::move(mustBeIntPositive), Direction::Input),
+      "Elastic channel number. Only for TOF data.");
 
   auto mustBeNegative = boost::make_shared<BoundedValidator<double>>();
   mustBeNegative->setUpper(0.0);
   declareProperty(
-      make_unique<PropertyWithValue<double>>("DeltaEmin", -10.0, mustBeNegative,
-                                             Direction::Input),
+      make_unique<PropertyWithValue<double>>(
+          "DeltaEmin", -10.0, std::move(mustBeNegative), Direction::Input),
       "Minimal energy transfer to consider. Should be <=0. Only for TOF data.");
 }
 
diff --git a/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp b/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp
index ee9b018c843b557512d5552a3f26e30ba58dc047..6d18dd22a19b5a0afb7467b71ca22b047ed1f4bd 100644
--- a/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp
+++ b/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp
@@ -44,7 +44,7 @@ ForegroundModel::ForegroundModel(const API::IFunction &fittingFunction)
 
 /**
  */
-ForegroundModel::~ForegroundModel() { delete m_formFactorTable; }
+ForegroundModel::~ForegroundModel() = default;
 
 /**
  * Set a reference to the convolved fitting function. Required as we need a
@@ -135,16 +135,14 @@ const API::IFunction &ForegroundModel::functionUnderMinimization() const {
 void ForegroundModel::setFormFactorIon(const std::string &ionType) {
   // "0" indicates off
   if (ionType == "0") {
-    delete m_formFactorTable;
-    m_formFactorTable = nullptr;
+    m_formFactorTable.reset(nullptr);
   } else {
     using namespace PhysicalConstants;
     if (m_MagIonName != ionType) {
       if (m_formFactorTable) {
-        delete m_formFactorTable;
       }
-      m_formFactorTable = new MagneticFormFactorTable(FORM_FACTOR_TABLE_LENGTH,
-                                                      getMagneticIon(ionType));
+      m_formFactorTable = std::make_unique<MagneticFormFactorTable>(
+          FORM_FACTOR_TABLE_LENGTH, getMagneticIon(ionType));
       m_MagIonName = ionType;
     }
   }
diff --git a/Framework/MDAlgorithms/src/TransformMD.cpp b/Framework/MDAlgorithms/src/TransformMD.cpp
index 11f31283fec721607c4c230510df4510b319ce8a..a7ce8ad0decd9d3ac51339b5b8d6ea9ca3239ac1 100644
--- a/Framework/MDAlgorithms/src/TransformMD.cpp
+++ b/Framework/MDAlgorithms/src/TransformMD.cpp
@@ -48,16 +48,16 @@ void TransformMD::init() {
                   "Any input MDWorkspace.");
 
   std::vector<double> defaultScaling(1, 1.0);
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Scaling", defaultScaling),
-      "Scaling value multiplying each coordinate. Default "
-      "1.\nEither a single value or a list for each dimension.");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                      "Scaling", std::move(defaultScaling)),
+                  "Scaling value multiplying each coordinate. Default "
+                  "1.\nEither a single value or a list for each dimension.");
 
   std::vector<double> defaultOffset(1, 0.0);
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>("Offset", defaultOffset),
-      "Offset value to add to each coordinate. Default 0.\nEither "
-      "a single value or a list for each dimension.");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>(
+                      "Offset", std::move(defaultOffset)),
+                  "Offset value to add to each coordinate. Default 0.\nEither "
+                  "a single value or a list for each dimension.");
 
   declareProperty(make_unique<WorkspaceProperty<IMDWorkspace>>(
                       "OutputWorkspace", "", Direction::Output),
diff --git a/Framework/MDAlgorithms/test/CreateMDFitWorkspaceTest.h b/Framework/MDAlgorithms/test/CreateMDFitWorkspaceTest.h
index d38da7a6f6e03c90283efe11c3ea6d18a7b05792..0b4a0dc47232830a3645bf716e38312bf7986741 100644
--- a/Framework/MDAlgorithms/test/CreateMDFitWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/CreateMDFitWorkspaceTest.h
@@ -30,15 +30,12 @@ public:
     maker.execute();
     TS_ASSERT(maker.isExecuted());
 
-    IFitFunction *fun = FunctionFactory::Instance().createInitialized(
-        "name=UserFunctionMD,Formula=h*exp(-a*(x-c)^2),Workspace="
-        "CreateMDFitWorkspaceTest_ws");
+    std::unique_ptr<IFitFunction> fun = std::unique_ptr<IFitFunction>(
+        FunctionFactory::Instance().createInitialized(
+            "name=UserFunctionMD,Formula=h*exp(-a*(x-c)^2),Workspace="
+            "CreateMDFitWorkspaceTest_ws"));
     TS_ASSERT(fun);
     TS_ASSERT(fun->getWorkspace());
-
-    if (fun) {
-      delete fun;
-    }
   }
 };
 
diff --git a/Framework/MDAlgorithms/test/MDWSTransfTest.h b/Framework/MDAlgorithms/test/MDWSTransfTest.h
index bc9ab71e5e0409dd69e8bd17fd2246b90006b038..c7f67afb682f29a9a85dec2fff4049ba441074bd 100644
--- a/Framework/MDAlgorithms/test/MDWSTransfTest.h
+++ b/Framework/MDAlgorithms/test/MDWSTransfTest.h
@@ -37,7 +37,7 @@ public:
 
 class MDWSTransfTest : public CxxTest::TestSuite {
   Mantid::API::MatrixWorkspace_sptr ws2D;
-  Geometry::OrientedLattice *pLattice;
+  std::unique_ptr<Geometry::OrientedLattice> pLattice;
   // this is permutation matrix which transforms Mantid coordinate system (beam
   // along Z-axis)
   // to Horace coordinate system (beam along X-axis);
@@ -73,7 +73,7 @@ public:
     TS_ASSERT_EQUALS(CnvrtToMD::SampleFrame,
                      Transf.findTargetFrame(TargWSDescription));
 
-    spws->mutableSample().setOrientedLattice(pLattice);
+    spws->mutableSample().setOrientedLattice(pLattice.get());
     TS_ASSERT_EQUALS(CnvrtToMD::HKLFrame,
                      Transf.findTargetFrame(TargWSDescription));
   }
@@ -100,7 +100,7 @@ public:
                                              CnvrtToMD::SampleFrame,
                                              CnvrtToMD::HKLScale),
                       std::invalid_argument);
-    spws->mutableSample().setOrientedLattice(pLattice);
+    spws->mutableSample().setOrientedLattice(pLattice.get());
 
     WorkspaceCreationHelper::setGoniometer(spws, 20, 0, 0);
 
@@ -148,11 +148,9 @@ public:
     std::vector<double> minVal(4, -3), maxVal(4, 3);
     TWS.setMinMax(minVal, maxVal);
 
-    if (pLattice)
-      delete pLattice;
-    pLattice =
-        new Geometry::OrientedLattice(5 * M_PI, M_PI, 2 * M_PI, 90., 90., 90.);
-    ws2D->mutableSample().setOrientedLattice(pLattice);
+    pLattice = std::make_unique<Geometry::OrientedLattice>(
+        5 * M_PI, M_PI, 2 * M_PI, 90., 90., 90.);
+    ws2D->mutableSample().setOrientedLattice(pLattice.get());
     TWS.buildFromMatrixWS(ws2D, "Q3D", "Direct");
 
     std::vector<double> u(3, 0);
@@ -410,8 +408,8 @@ public:
     // add workspace energy
     ws2D->mutableRun().addProperty("Ei", 13., "meV", true);
 
-    pLattice = new Geometry::OrientedLattice(3, 3, 2, 90, 90, 90);
-    ws2D->mutableSample().setOrientedLattice(pLattice);
+    pLattice = std::make_unique<Geometry::OrientedLattice>(3, 3, 2, 90, 90, 90);
+    ws2D->mutableSample().setOrientedLattice(pLattice.get());
 
     // S_mantid*k_mantid = S_hor*k_hor; -- both Mantid and Horace produce the
     // same kind of crystal frame
diff --git a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
index afb04234b1bdad0362784638f42edbd0d6075276..50c8bfe60c78b8a25a2f8952046a10c1f3eab787 100644
--- a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
+++ b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
@@ -205,9 +205,9 @@ public:
     // Create some input data. Signal values as two offset sine waves.
     using VecDouble = std::vector<double>;
     VecDouble s1, s2, e1, e2, x;
-    double theta_shift = 0.4;
+    const double theta_shift = 0.4;
     for (size_t i = 0; i < 40; ++i) {
-      double theta = 0.02 * double(i) * M_PI;
+      const double theta = 0.02 * double(i) * M_PI;
       s1.push_back(std::sin(theta));
       e1.push_back(std::sin(theta));
       s2.push_back(std::sin(theta + theta_shift));
diff --git a/Framework/Muon/src/AlphaCalc.cpp b/Framework/Muon/src/AlphaCalc.cpp
index f44558a9bd5e0ce5da5b0413c51e59d2d48a1946..388007287b508f19bf353a2ef8160f91cd10666e 100644
--- a/Framework/Muon/src/AlphaCalc.cpp
+++ b/Framework/Muon/src/AlphaCalc.cpp
@@ -32,13 +32,13 @@ void AlphaCalc::init() {
                   "Name of the input workspace");
 
   std::vector<int> forwardDefault{1};
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<int>>("ForwardSpectra", forwardDefault),
-      "The spectra numbers of the forward group (default to 1)");
+  declareProperty(Kernel::make_unique<ArrayProperty<int>>(
+                      "ForwardSpectra", std::move(forwardDefault)),
+                  "The spectra numbers of the forward group (default to 1)");
 
   std::vector<int> backwardDefault{2};
-  declareProperty(Kernel::make_unique<ArrayProperty<int>>("BackwardSpectra",
-                                                          backwardDefault),
+  declareProperty(Kernel::make_unique<ArrayProperty<int>>(
+                      "BackwardSpectra", std::move(backwardDefault)),
                   "The spectra numbers of the backward group (default to 2)");
 
   declareProperty("FirstGoodValue", EMPTY_DBL(),
diff --git a/Framework/Muon/src/EstimateMuonAsymmetryFromCounts.cpp b/Framework/Muon/src/EstimateMuonAsymmetryFromCounts.cpp
index 138d69f8464cf80a18e8521bf487873da6c98531..aee33457b2058a34eabd68194196910781ce37fc 100644
--- a/Framework/Muon/src/EstimateMuonAsymmetryFromCounts.cpp
+++ b/Framework/Muon/src/EstimateMuonAsymmetryFromCounts.cpp
@@ -59,7 +59,8 @@ void EstimateMuonAsymmetryFromCounts::init() {
 
   std::vector<int> empty;
   declareProperty(
-      Kernel::make_unique<Kernel::ArrayProperty<int>>("Spectra", empty),
+      Kernel::make_unique<Kernel::ArrayProperty<int>>("Spectra",
+                                                      std::move(empty)),
       "The workspace indices to remove the exponential decay from.");
   declareProperty(
       "StartX", 0.1,
diff --git a/Framework/Muon/src/MuonGroupingAsymmetry.cpp b/Framework/Muon/src/MuonGroupingAsymmetry.cpp
index e100808b0b0454192a63c6c762b20ddc3d1dca19..4cff242bbcb3a057864b7d66572d12b5c03332d7 100644
--- a/Framework/Muon/src/MuonGroupingAsymmetry.cpp
+++ b/Framework/Muon/src/MuonGroupingAsymmetry.cpp
@@ -138,8 +138,8 @@ DECLARE_ALGORITHM(MuonGroupingAsymmetry)
 
 void MuonGroupingAsymmetry::init() {
   const std::string emptyString("");
-  const std::vector<int> defaultGrouping = {1};
-  const std::vector<int> defaultPeriods = {1};
+  std::vector<int> defaultGrouping = {1};
+  std::vector<int> defaultPeriods = {1};
 
   declareProperty(
       Mantid::Kernel::make_unique<WorkspaceProperty<WorkspaceGroup>>(
@@ -160,7 +160,7 @@ void MuonGroupingAsymmetry::init() {
                   Direction::Input);
 
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "Grouping", defaultGrouping,
+                      "Grouping", std::move(defaultGrouping),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "The grouping of detectors, comma separated list of detector "
                   "IDs or hyphenated ranges of IDs.");
@@ -181,7 +181,7 @@ void MuonGroupingAsymmetry::init() {
                   Direction::Input);
 
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "SummedPeriods", defaultPeriods,
+                      "SummedPeriods", std::move(defaultPeriods),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "A list of periods to sum in multiperiod data.");
   declareProperty(
diff --git a/Framework/Muon/src/MuonGroupingCounts.cpp b/Framework/Muon/src/MuonGroupingCounts.cpp
index 103e0234b434eb8e49a210a8e1d82ab4658f0278..70a5301d96615bb73f6555fc744c8fafde9aef30 100644
--- a/Framework/Muon/src/MuonGroupingCounts.cpp
+++ b/Framework/Muon/src/MuonGroupingCounts.cpp
@@ -88,13 +88,13 @@ void MuonGroupingCounts::init() {
                   "alphanumeric character.",
                   Direction::Input);
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "Grouping", defaultGrouping,
+                      "Grouping", std::move(defaultGrouping),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "The grouping of detectors, comma separated list of detector "
                   "IDs or hyphenated ranges of IDs.");
 
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "SummedPeriods", defaultGrouping,
+                      "SummedPeriods", std::vector<int>(1, 1),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "A list of periods to sum in multiperiod data.");
   declareProperty(
diff --git a/Framework/Muon/src/MuonPairingAsymmetry.cpp b/Framework/Muon/src/MuonPairingAsymmetry.cpp
index 1c52c2a2d88980001f5f744813dc1da44806047d..ad53d15b4965066ac31de6a669823f84fd10fa76 100644
--- a/Framework/Muon/src/MuonPairingAsymmetry.cpp
+++ b/Framework/Muon/src/MuonPairingAsymmetry.cpp
@@ -105,8 +105,8 @@ DECLARE_ALGORITHM(MuonPairingAsymmetry)
 
 void MuonPairingAsymmetry::init() {
   std::string emptyString("");
-  const std::vector<int> defaultGrouping1 = {1};
-  const std::vector<int> defaultGrouping2 = {2};
+  std::vector<int> defaultGrouping1 = {1};
+  std::vector<int> defaultGrouping2 = {2};
 
   declareProperty(
       Mantid::Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
@@ -158,12 +158,12 @@ void MuonPairingAsymmetry::init() {
                       make_unique<Kernel::EnabledWhenProperty>(
                           "SpecifyGroupsManually", Kernel::IS_EQUAL_TO, "1"));
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "Group1", defaultGrouping1,
+                      "Group1", std::move(defaultGrouping1),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "The grouping of detectors, comma separated list of detector "
                   "IDs or hyphenated ranges of IDs.");
   declareProperty(make_unique<ArrayProperty<int>>(
-                      "Group2", defaultGrouping2,
+                      "Group2", std::move(defaultGrouping2),
                       IValidator_sptr(new NullValidator), Direction::Input),
                   "The grouping of detectors, comma separated list of detector "
                   "IDs or hyphenated ranges of IDs.");
diff --git a/Framework/Muon/src/RemoveExpDecay.cpp b/Framework/Muon/src/RemoveExpDecay.cpp
index 6c8ad115843cc741716c986519e20995437c9d88..d50ead7a44687c8d685183aeeefd675e69375c02 100644
--- a/Framework/Muon/src/RemoveExpDecay.cpp
+++ b/Framework/Muon/src/RemoveExpDecay.cpp
@@ -49,7 +49,8 @@ void MuonRemoveExpDecay::init() {
                   "The name of the output 2D workspace.");
   std::vector<int> empty;
   declareProperty(
-      Kernel::make_unique<Kernel::ArrayProperty<int>>("Spectra", empty),
+      Kernel::make_unique<Kernel::ArrayProperty<int>>("Spectra",
+                                                      std::move(empty)),
       "The workspace indices to remove the exponential decay from.");
 }
 
diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusShapeFactory.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusShapeFactory.h
index b584d3c123355685e5226c717e5133e4912be6d1..485a544591c145a3113a548998e03e7c936d7c38 100644
--- a/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusShapeFactory.h
+++ b/Framework/NexusGeometry/inc/MantidNexusGeometry/NexusShapeFactory.h
@@ -35,19 +35,19 @@ createCylinder(const Eigen::Matrix<double, 3, 3> &pointsDef);
 
 /// Creates a triangular mesh shape based on ready triangulated polygons
 DLLExport std::unique_ptr<const Geometry::IObject>
-createMesh(std::vector<uint16_t> &&triangularFaces,
+createMesh(std::vector<uint32_t> &&triangularFaces,
            std::vector<Mantid::Kernel::V3D> &&vertices);
 
 /// Creates a triangular mesh shape based on OFF (Object File Format) polygon
 /// inputs https://en.wikipedia.org/wiki/OFF_(file_format)
 DLLExport std::unique_ptr<const Geometry::IObject>
-createFromOFFMesh(const std::vector<uint16_t> &faceIndices,
-                  const std::vector<uint16_t> &windingOrder,
+createFromOFFMesh(const std::vector<uint32_t> &faceIndices,
+                  const std::vector<uint32_t> &windingOrder,
                   const std::vector<float> &nexusVertices);
 
 DLLExport std::unique_ptr<const Geometry::IObject>
-createFromOFFMesh(const std::vector<uint16_t> &faceIndices,
-                  const std::vector<uint16_t> &windingOrder,
+createFromOFFMesh(const std::vector<uint32_t> &faceIndices,
+                  const std::vector<uint32_t> &windingOrder,
                   const std::vector<Eigen::Vector3d> &nexusVertices);
 } // namespace NexusShapeFactory
 } // namespace NexusGeometry
diff --git a/Framework/NexusGeometry/src/NexusGeometryParser.cpp b/Framework/NexusGeometry/src/NexusGeometryParser.cpp
index b74b36c21134a5f8b412e097b9494d4feec3c143..a216c31ed7c685200ecec4fa67cb30ae84d04a5a 100644
--- a/Framework/NexusGeometry/src/NexusGeometryParser.cpp
+++ b/Framework/NexusGeometry/src/NexusGeometryParser.cpp
@@ -477,28 +477,28 @@ parseNexusCylinder(const Group &shapeGroup) {
 // Parse OFF (mesh) nexus geometry
 boost::shared_ptr<const Geometry::IObject>
 parseNexusMesh(const Group &shapeGroup) {
-  const std::vector<uint16_t> faceIndices = convertVector<int32_t, uint16_t>(
+  const std::vector<uint32_t> faceIndices = convertVector<int32_t, uint32_t>(
       get1DDataset<int32_t>("faces", shapeGroup));
-  const std::vector<uint16_t> windingOrder = convertVector<int32_t, uint16_t>(
+  const std::vector<uint32_t> windingOrder = convertVector<int32_t, uint32_t>(
       get1DDataset<int32_t>("winding_order", shapeGroup));
   const auto vertices = get1DDataset<float>("vertices", shapeGroup);
   return NexusShapeFactory::createFromOFFMesh(faceIndices, windingOrder,
                                               vertices);
 }
 
-void extractFacesAndIDs(const std::vector<uint16_t> &detFaces,
-                        const std::vector<uint16_t> &windingOrder,
+void extractFacesAndIDs(const std::vector<uint32_t> &detFaces,
+                        const std::vector<uint32_t> &windingOrder,
                         const std::vector<float> &vertices,
                         const std::unordered_map<int, uint32_t> &detIdToIndex,
                         const size_t vertsPerFace,
                         std::vector<std::vector<Eigen::Vector3d>> &detFaceVerts,
-                        std::vector<std::vector<uint16_t>> &detFaceIndices,
-                        std::vector<std::vector<uint16_t>> &detWindingOrder,
+                        std::vector<std::vector<uint32_t>> &detFaceIndices,
+                        std::vector<std::vector<uint32_t>> &detWindingOrder,
                         std::vector<int32_t> &detIds) {
   const size_t vertStride = 3;
   size_t detFaceIndex = 1;
   std::fill(detFaceIndices.begin(), detFaceIndices.end(),
-            std::vector<uint16_t>(1, 0));
+            std::vector<uint32_t>(1, 0));
   for (size_t i = 0; i < windingOrder.size(); i += vertsPerFace) {
     auto detFaceId = detFaces[detFaceIndex];
     // Id -> Index
@@ -511,27 +511,27 @@ void extractFacesAndIDs(const std::vector<uint16_t> &detFaces,
     for (size_t v = 0; v < vertsPerFace; ++v) {
       const auto vi = windingOrder[i + v] * vertStride;
       detVerts.emplace_back(vertices[vi], vertices[vi + 1], vertices[vi + 2]);
-      detWinding.push_back(static_cast<uint16_t>(detWinding.size()));
+      detWinding.push_back(static_cast<uint32_t>(detWinding.size()));
     }
     // Index -> Id
     detIds[detIndex] = detFaceId;
-    detIndices.push_back(static_cast<uint16_t>(detVerts.size()));
+    detIndices.push_back(static_cast<uint32_t>(detVerts.size()));
     // Detector faces is 2N detectors
     detFaceIndex += 2;
   }
 }
 
 void parseNexusMeshAndAddDetectors(
-    const std::vector<uint16_t> &detFaces,
-    const std::vector<uint16_t> &faceIndices,
-    const std::vector<uint16_t> &windingOrder,
+    const std::vector<uint32_t> &detFaces,
+    const std::vector<uint32_t> &faceIndices,
+    const std::vector<uint32_t> &windingOrder,
     const std::vector<float> &vertices, const size_t numDets,
     const std::unordered_map<int, uint32_t> &detIdToIndex,
     const std::string &name, InstrumentBuilder &builder) {
   auto vertsPerFace = windingOrder.size() / faceIndices.size();
   std::vector<std::vector<Eigen::Vector3d>> detFaceVerts(numDets);
-  std::vector<std::vector<uint16_t>> detFaceIndices(numDets);
-  std::vector<std::vector<uint16_t>> detWindingOrder(numDets);
+  std::vector<std::vector<uint32_t>> detFaceIndices(numDets);
+  std::vector<std::vector<uint32_t>> detWindingOrder(numDets);
   std::vector<int> detIds(numDets);
 
   extractFacesAndIDs(detFaces, windingOrder, vertices, detIdToIndex,
@@ -563,11 +563,11 @@ void parseAndAddBank(const Group &shapeGroup, InstrumentBuilder &builder,
                      const std::string &bankName) {
   // Load mapping between detector IDs and faces, winding order of vertices for
   // faces, and face corner vertices.
-  const std::vector<uint16_t> detFaces = convertVector<int32_t, uint16_t>(
+  const std::vector<uint32_t> detFaces = convertVector<int32_t, uint32_t>(
       get1DDataset<int32_t>("detector_faces", shapeGroup));
-  const std::vector<uint16_t> faceIndices = convertVector<int32_t, uint16_t>(
+  const std::vector<uint32_t> faceIndices = convertVector<int32_t, uint32_t>(
       get1DDataset<int32_t>("faces", shapeGroup));
-  const std::vector<uint16_t> windingOrder = convertVector<int32_t, uint16_t>(
+  const std::vector<uint32_t> windingOrder = convertVector<int32_t, uint32_t>(
       get1DDataset<int32_t>("winding_order", shapeGroup));
   const auto vertices = get1DDataset<float>("vertices", shapeGroup);
 
diff --git a/Framework/NexusGeometry/src/NexusShapeFactory.cpp b/Framework/NexusGeometry/src/NexusShapeFactory.cpp
index 911b6ddd9e1f33f84827f020cd73a85482bbd204..d498c295eea39730421eba12151e5e88a58d6561 100644
--- a/Framework/NexusGeometry/src/NexusShapeFactory.cpp
+++ b/Framework/NexusGeometry/src/NexusShapeFactory.cpp
@@ -47,8 +47,8 @@ std::unique_ptr<const Geometry::IObject> createCylinderShape(
   return std::unique_ptr<const Geometry::IObject>(shape.release());
 }
 
-void createTrianglesFromPolygon(const std::vector<uint16_t> &windingOrder,
-                                std::vector<uint16_t> &triangularFaces,
+void createTrianglesFromPolygon(const std::vector<uint32_t> &windingOrder,
+                                std::vector<uint32_t> &triangularFaces,
                                 int &startOfFace, int &endOfFace) {
   int polygonOrder = endOfFace - startOfFace;
   auto first = windingOrder.begin() + startOfFace;
@@ -63,16 +63,16 @@ void createTrianglesFromPolygon(const std::vector<uint16_t> &windingOrder,
   startOfFace = endOfFace; // start of the next face
 }
 
-std::vector<uint16_t>
-createTriangularFaces(const std::vector<uint16_t> &faceIndices,
-                      const std::vector<uint16_t> &windingOrder) {
+std::vector<uint32_t>
+createTriangularFaces(const std::vector<uint32_t> &faceIndices,
+                      const std::vector<uint32_t> &windingOrder) {
 
   // Elements 0 to 2 are the indices of the vertices vector corresponding to the
   // vertices of the first triangle.
   // Elements 3 to 5 are for the second triangle, and so on.
   // The order of the vertices is the winding order of the triangle, determining
   // the face normal by right-hand rule
-  std::vector<uint16_t> triangularFaces;
+  std::vector<uint32_t> triangularFaces;
 
   int startOfFace = 0;
   int endOfFace = 0;
@@ -156,10 +156,10 @@ createCylinder(const Eigen::Matrix<double, 3, 3> &pointsDef) {
 }
 
 std::unique_ptr<const Geometry::IObject>
-createFromOFFMesh(const std::vector<uint16_t> &faceIndices,
-                  const std::vector<uint16_t> &windingOrder,
+createFromOFFMesh(const std::vector<uint32_t> &faceIndices,
+                  const std::vector<uint32_t> &windingOrder,
                   const std::vector<float> &nexusVertices) {
-  std::vector<uint16_t> triangularFaces =
+  std::vector<uint32_t> triangularFaces =
       createTriangularFaces(faceIndices, windingOrder);
 
   std::vector<Mantid::Kernel::V3D> vertices;
@@ -190,10 +190,10 @@ toVectorV3D(const std::vector<Eigen::Vector3d> &nexusVertices) {
 }
 
 std::unique_ptr<const Geometry::IObject>
-createFromOFFMesh(const std::vector<uint16_t> &faceIndices,
-                  const std::vector<uint16_t> &windingOrder,
+createFromOFFMesh(const std::vector<uint32_t> &faceIndices,
+                  const std::vector<uint32_t> &windingOrder,
                   const std::vector<Eigen::Vector3d> &nexusVertices) {
-  std::vector<uint16_t> triangularFaces =
+  std::vector<uint32_t> triangularFaces =
       createTriangularFaces(faceIndices, windingOrder);
 
   return NexusShapeFactory::createMesh(std::move(triangularFaces),
@@ -201,7 +201,7 @@ createFromOFFMesh(const std::vector<uint16_t> &faceIndices,
 }
 
 std::unique_ptr<const Geometry::IObject>
-createMesh(std::vector<uint16_t> &&triangularFaces,
+createMesh(std::vector<uint32_t> &&triangularFaces,
            std::vector<Mantid::Kernel::V3D> &&vertices) {
 
   if (Geometry::MeshObject2D::pointsCoplanar(vertices))
diff --git a/Framework/NexusGeometry/test/NexusShapeFactoryTest.h b/Framework/NexusGeometry/test/NexusShapeFactoryTest.h
index ea7c353e905243261d1fa69094cf2f8ca734312e..d392974f3de761836d91b2b318064e9c51dd99e1 100644
--- a/Framework/NexusGeometry/test/NexusShapeFactoryTest.h
+++ b/Framework/NexusGeometry/test/NexusShapeFactoryTest.h
@@ -29,7 +29,7 @@ public:
     vertices.emplace_back(V3D(-1, 0, 0));
     vertices.emplace_back(V3D(1, 0, 0));
     vertices.emplace_back(V3D(0, 1, 0));
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {0, 1, 2});
 
     auto obj = createMesh(std::move(triangles), std::move(vertices));
@@ -46,7 +46,7 @@ public:
     vertices.emplace_back(V3D(1, 0, 0));
     vertices.emplace_back(V3D(0, 1, 0));
     vertices.emplace_back(V3D(0, 1, 1));
-    std::vector<uint16_t> triangles;
+    std::vector<uint32_t> triangles;
     triangles.insert(triangles.end(), {0, 1, 2, 1, 3, 2, 3, 0, 2});
 
     auto obj = createMesh(std::move(triangles), std::move(vertices));
@@ -59,8 +59,8 @@ public:
 class NexusShapeFactoryTestPerformance : public CxxTest::TestSuite {
 private:
   std::vector<Eigen::Vector3d> m_vertices;
-  std::vector<uint16_t> m_facesIndices;
-  std::vector<uint16_t> m_windingOrder;
+  std::vector<uint32_t> m_facesIndices;
+  std::vector<uint32_t> m_windingOrder;
 
   template <typename T>
   void appendTo(std::vector<T> &destination, unsigned int value) {
@@ -79,7 +79,7 @@ public:
 
   NexusShapeFactoryTestPerformance() {
     // Make inputs. Repeated squares
-    for (uint16_t i = 0; i < 10000; ++i) {
+    for (uint32_t i = 0; i < 10000; ++i) {
       m_vertices.emplace_back(Eigen::Vector3d(0 + i, 1, 0));
       m_vertices.emplace_back(Eigen::Vector3d(0 + i, 1, 0));
       /*
@@ -89,13 +89,13 @@ public:
        *     x           x     x
        */
 
-      appendTo<uint16_t>(m_facesIndices, (i * 4));
-      appendTo<uint16_t>(m_facesIndices, ((i + 1) * 4));
+      appendTo<uint32_t>(m_facesIndices, (i * 4));
+      appendTo<uint32_t>(m_facesIndices, ((i + 1) * 4));
       if (i % 2 != 0) {
-        appendTo<uint16_t>(m_windingOrder, (i * 2));
-        appendTo<uint16_t>(m_windingOrder, (i * 2 + 1));
-        appendTo<uint16_t>(m_windingOrder, (i * 2 + 2));
-        appendTo<uint16_t>(m_windingOrder, (i * 2 + 3));
+        appendTo<uint32_t>(m_windingOrder, (i * 2));
+        appendTo<uint32_t>(m_windingOrder, (i * 2 + 1));
+        appendTo<uint32_t>(m_windingOrder, (i * 2 + 2));
+        appendTo<uint32_t>(m_windingOrder, (i * 2 + 3));
       }
     }
   }
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/AnalysisDataServiceObserverAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/AnalysisDataServiceObserverAdapter.h
index ff96d44dc8f5706627964ee49c7be9896aaca28d..e466b745c4f9606e38252b1a4ab1ce82f88a21c5 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/api/AnalysisDataServiceObserverAdapter.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/AnalysisDataServiceObserverAdapter.h
@@ -1,6 +1,6 @@
 // Mantid Repository : https://github.com/mantidproject/mantid
 //
-// Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory UKRI,
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h
index 1d071c910d2a07af8ea75e902bdc52e83205770e..d626f3e6de81a4ed8c3d9cf19b277e4f56f2b371 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/NDArrayToVector.h
@@ -26,7 +26,7 @@ template <typename DestElementType> struct DLLExport NDArrayToVector {
   /// Constructor
   NDArrayToVector(const NDArray &value);
   /// Create a new vector from the contents of the array
-  const TypedVector operator()();
+  TypedVector operator()();
   /// Fill the container with data from the array
   void copyTo(TypedVector &dest) const;
 
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PySequenceToVector.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PySequenceToVector.h
index 2a3127f2e49c7d45fa5e895c00e94bbd4eff4f4f..c70b5fabb7a80e37a1fe803a5c255e0bfd0c47ef 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PySequenceToVector.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/PySequenceToVector.h
@@ -62,7 +62,7 @@ template <typename DestElementType> struct DLLExport PySequenceToVector {
    * @return A std::vector<ElementType> containing the values
    * from the Python sequence
    */
-  inline const TypedVector operator()() {
+  inline TypedVector operator()() {
     TypedVector cvector(srcSize());
     copyTo(cvector);
     return cvector;
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserver.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserver.cpp
index e19291316cf7fdb49e8051c87770d0e101aff580..8eb4ba7041187fd01d6973fd7a17ef62acdacad6 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserver.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserver.cpp
@@ -1,6 +1,6 @@
 // Mantid Repository : https://github.com/mantidproject/mantid
 //
-// Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory UKRI,
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserverAdapter.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserverAdapter.cpp
index d610d38daced038a523c373f20cfd35b5deecffe..32e33c85472ef41ed0e592ec1a5252933f42b4b8 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserverAdapter.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataServiceObserverAdapter.cpp
@@ -1,6 +1,6 @@
 // Mantid Repository : https://github.com/mantidproject/mantid
 //
-// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+// Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
index 006e403de8002742763e91368ad0af6ac4eed4d9..c66f1ead66d595a1fa4be7003ce5080e6066d77e 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
@@ -5,6 +5,7 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "MantidAPI/IEventList.h"
+#include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h"
 #include "MantidPythonInterface/kernel/GetPointer.h"
 #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
 #include <boost/python/class.hpp>
@@ -18,11 +19,16 @@ using Mantid::API::TOF;
 using Mantid::API::WEIGHTED;
 using Mantid::API::WEIGHTED_NOTIME;
 
-namespace Policies = Mantid::PythonInterface::Policies;
+using namespace Mantid::PythonInterface;
 using namespace boost::python;
 
 GET_POINTER_SPECIALIZATION(IEventList)
 
+namespace {
+void maskCondition(IEventList &self, const NDArray &data) {
+  self.maskCondition(Converters::NDArrayToVector<bool>(data)());
+}
+} // namespace
 /// return_value_policy for copied numpy array
 using return_clone_numpy = return_value_policy<Policies::VectorToNumpy>;
 
@@ -67,6 +73,8 @@ void export_IEventList() {
       .def("maskTof", &IEventList::maskTof, args("self", "tofMin", "tofMax"),
            "Mask out events that have a tof between tofMin and tofMax "
            "(inclusively)")
+      .def("maskCondition", &maskCondition, args("self", "mask"),
+           "Mask out events by the condition vector")
       .def("getTofs",
            (std::vector<double>(IEventList::*)(void) const) &
                IEventList::getTofs,
@@ -84,6 +92,10 @@ void export_IEventList() {
            "Get a vector of the weights of the events")
       .def("getPulseTimes", &IEventList::getPulseTimes, args("self"),
            "Get a vector of the pulse times of the events")
+      .def("getPulseTimeMax", &IEventList::getPulseTimeMax, args("self"),
+           "The maximum pulse time for the list of the events.")
+      .def("getPulseTimeMin", &IEventList::getPulseTimeMin, args("self"),
+           "The minimum pulse time for the list of the events.")
       .def("getTofMin", &IEventList::getTofMin, args("self"),
            "The minimum tof value for the list of the events.")
       .def("getTofMax", &IEventList::getTofMax, args("self"),
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
index 291268be925844004be324f06627aa6881c14c69..411660fd56c4323b3b7462b3b81dcde1725b86a6 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
@@ -45,6 +45,12 @@ void export_IEventWorkspace() {
       .def("getTofMax", &IEventWorkspace::getTofMax, args("self"),
            "Returns the maximum TOF value (in microseconds) held by the "
            ":class:`~mantid.api.Workspace`")
+      .def("getPulseTimeMin", &IEventWorkspace::getPulseTimeMin, args("self"),
+           "Returns the minimum pulse time held by the "
+           ":class:`~mantid.api.Workspace`")
+      .def("getPulseTimeMax", &IEventWorkspace::getPulseTimeMax, args("self"),
+           "Returns the maximum pulse time held by the "
+           ":class:`~mantid.api.Workspace`")
       .def("getEventList", &deprecatedGetEventList,
            return_internal_reference<>(), args("self", "workspace_index"),
            "Return the :class:`~mantid.api.IEventList` managing the events at "
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
index a159b756332a3034e33af9c448993a0526673a5e..a68b1f2ac0f0d12848fca94b5c5c756619ce0c57 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
@@ -87,9 +87,21 @@ void export_IPeak() {
       .def("getL", &IPeak::getL, arg("self"), "Get the L index of the peak")
       .def("getHKL", &IPeak::getHKL, arg("self"),
            "Get HKL as a :class:`~mantid.kernel.V3D` object")
+      .def("getSamplePos", &IPeak::getSamplePos, arg("self"),
+           "Get the cached samplePos as a :class:`~mantid.kernel.V3D` object")
       .def("setHKL", (void (IPeak::*)(double, double, double)) & IPeak::setHKL,
            (arg("self"), arg("h"), arg("k"), arg("l")),
            "Set the HKL values of this peak")
+      .def("setSamplePos",
+           (void (IPeak::*)(double, double, double)) & IPeak::setSamplePos,
+           (arg("self"), arg("samX"), arg("samY"), arg("samZ")),
+           "Set the samplePos value of this peak.  It does not set the "
+           "instrument sample position.")
+      .def("setSamplePos",
+           (void (IPeak::*)(const Mantid::Kernel::V3D &)) & IPeak::setSamplePos,
+           (arg("self"), arg("newPos")),
+           "Set the samplePos value of this peak.  It does not set the "
+           "instrument sample position.")
       .def("setH", &IPeak::setH, (arg("self"), arg("h")),
            "Get the H index of the peak")
       .def("setK", &IPeak::setK, (arg("self"), arg("k")),
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
index d1a9f270e68717e259c0964afd9f10fea8b747ca..99108d3813d9b43bd8ddf16e715ce13bbfbfa7eb 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
@@ -12,6 +12,7 @@
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidKernel/V3D.h"
 #include "MantidPythonInterface/core/NDArray.h"
+#include "MantidPythonInterface/core/VersionCompat.h"
 #include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h"
 #include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h"
 #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"
@@ -26,6 +27,7 @@
 #include <boost/python/dict.hpp>
 #include <boost/python/list.hpp>
 #include <boost/python/make_constructor.hpp>
+
 #include <cstring>
 #include <vector>
 
@@ -296,6 +298,27 @@ PyObject *row(ITableWorkspace &self, int row) {
   return result;
 }
 
+/**
+ * Return the C++ types for all columns
+ * @param self A reference to the TableWorkspace python object that we were
+ * called on
+ */
+PyObject *columnTypes(ITableWorkspace &self) {
+  int numCols = static_cast<int>(self.columnCount());
+
+  PyObject *list = PyList_New(numCols);
+
+  for (int col = 0; col < numCols; col++) {
+    Mantid::API::Column_const_sptr column = self.getColumn(col);
+    const std::type_info &typeID = column->get_type_info();
+    if (PyList_SetItem(list, col, FROM_CSTRING(typeID.name()))) {
+      throw std::runtime_error("Error while building list");
+    }
+  }
+
+  return list;
+}
+
 /**
  * Adds a new row in the table, where the items are given in a dictionary
  * object mapping {column name:value}. It must contain a key-value entry for
@@ -629,6 +652,9 @@ void export_ITableWorkspace() {
       .def("row", &row, (arg("self"), arg("row")),
            "Return all values of a specific row as a dict.")
 
+      .def("columnTypes", &columnTypes, arg("self"),
+           "Return the types of the columns as a list")
+
       // FromSequence must come first since it takes an object parameter
       // Otherwise, FromDict will never be called as object accepts anything
       .def("addRow", &addRowFromSequence, (arg("self"), arg("row_items_seq")),
diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
index 67488005468f85a1a6438d793229ddab2e76a047..cd9d46cbfb819ff862b48e21d2940e22cc89cd4d 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
@@ -133,7 +133,7 @@ NDArrayToVector<DestElementType>::NDArrayToVector(const NDArray &value)
  * @return A vector of the DestElementType created from the numpy array
  */
 template <typename DestElementType>
-const typename NDArrayToVector<DestElementType>::TypedVector
+typename NDArrayToVector<DestElementType>::TypedVector
 NDArrayToVector<DestElementType>::operator()() {
   std::vector<DestElementType> cvector(
       PyArray_SIZE((PyArrayObject *)m_arr.ptr()));
diff --git a/Framework/PythonInterface/mantid/plots/__init__.py b/Framework/PythonInterface/mantid/plots/__init__.py
index 587e8e38603f6d9a489e144f90767570c68fae4f..e4a8c380c9f8c81017f312270dbc7b4cad1bfa55 100644
--- a/Framework/PythonInterface/mantid/plots/__init__.py
+++ b/Framework/PythonInterface/mantid/plots/__init__.py
@@ -50,18 +50,18 @@ def plot_decorator(func):
             # Fill out kwargs with the values of args
             for index, arg in enumerate(args):
                 if index is 0:
-                    kwargs["workspaces"] = arg.name()
+                    kwargs["workspaces"] = args[0].name()
                 if index is 1:
-                    kwargs["spectrum_nums"] = arg
+                    kwargs["spectrum_nums"] = args[1]
                 if index is 2:
-                    kwargs["wksp_indices"] = arg
+                    kwargs["wksp_indices"] = args[2]
                 if index is 3:
-                    kwargs["errors"] = arg
+                    kwargs["errors"] = args[3]
                 if index is 4:
-                    kwargs["overplot"] = arg
+                    kwargs["overplot"] = arg[4]
                 # ignore 5 as no need to save the fig object
                 if index is 6:
-                    kwargs["plot_kwargs"] = arg
+                    kwargs["plot_kwargs"] = arg[6]
             if hasattr(self, "creation_args"):
                 self.creation_args.append(kwargs)
             else:
diff --git a/Framework/PythonInterface/mantid/plots/plotfunctions.py b/Framework/PythonInterface/mantid/plots/plotfunctions.py
index c40055055227a3912569c8d758414bea2cf4b77e..234177f46fd0e267b0b8559d68d409a6cbe30cb2 100644
--- a/Framework/PythonInterface/mantid/plots/plotfunctions.py
+++ b/Framework/PythonInterface/mantid/plots/plotfunctions.py
@@ -10,6 +10,7 @@
 from __future__ import (absolute_import, division, print_function)
 
 import numpy
+from skimage.transform import resize
 import mantid.kernel
 import mantid.api
 from mantid.plots.helperfunctions import *
@@ -374,10 +375,74 @@ def pcolormesh(axes, workspace, *args, **kwargs):
             return _pcolorpieces(axes, workspace, distribution, *args, **kwargs)
         else:
             (x, y, z) = get_matrix_2d_data(workspace, distribution, histogram2D=True)
-
     return axes.pcolormesh(x, y, z, *args, **kwargs)
 
 
+def _skimage_version():
+    import skimage
+    from distutils.version import LooseVersion
+    return LooseVersion(skimage.__version__) >= LooseVersion('1.4.0')
+
+
+class ScalingAxesImage(mimage.AxesImage):
+    def __init__(self, ax,
+                 cmap=None,
+                 norm=None,
+                 interpolation=None,
+                 origin=None,
+                 extent=None,
+                 filternorm=1,
+                 filterrad=4.0,
+                 resample=False,
+                 **kwargs):
+        self.dx = None
+        self.dy = None
+        self.unsampled_data = None
+        super(ScalingAxesImage, self).__init__(
+            ax,
+            cmap=cmap,
+            norm=norm,
+            interpolation=interpolation,
+            origin=origin,
+            extent=extent,
+            filternorm=filternorm,
+            filterrad=filterrad,
+            resample=resample,
+            **kwargs)
+
+    def set_data(self, A):
+        dims = A.shape
+        max_dims = (3840,2160) # 4K resolution
+        if dims[0] > max_dims[0] or dims[1] > max_dims[1]:
+            new_dims = numpy.minimum(dims, max_dims)
+            if(_skimage_version()):
+                self.unsampled_data = resize(A, new_dims, mode='constant', cval=numpy.nan, anti_aliasing=True)
+            else:
+                self.unsampled_data = resize(A, new_dims, mode='constant', cval=numpy.nan)
+        else:
+            self.unsampled_data = A
+        super(ScalingAxesImage, self).set_data(A)
+
+    def draw(self, renderer):
+        ax = self.axes
+        # might not be calculated before first call
+        we = ax.get_window_extent()
+        dx = round(we.x1 - we.x0)
+        dy = round(we.y1 - we.y0)
+        #decide if we should downsample
+        dims = self.unsampled_data.shape
+        if dx != self.dx or dy != self.dy:
+            if dims[0] > dx or dims[1] > dy:
+                new_dims = numpy.minimum(dims,[dx,dy])
+                if(_skimage_version()):
+                    sampled_data = resize(self.unsampled_data, new_dims, mode='constant', cval=numpy.nan, anti_aliasing=True)
+                else:
+                    sampled_data = resize(self.unsampled_data, new_dims, mode='constant', cval=numpy.nan)
+                self.dx = dx
+                self.dy = dy
+                super(ScalingAxesImage, self).set_data(sampled_data)
+        return super(ScalingAxesImage,self).draw(renderer)
+
 def _imshow(axes, z, cmap=None, norm=None, aspect=None,
             interpolation=None, alpha=None, vmin=None, vmax=None,
             origin=None, extent=None, shape=None, filternorm=1,
@@ -393,10 +458,9 @@ def _imshow(axes, z, cmap=None, norm=None, aspect=None,
     if aspect is None:
         aspect = matplotlib.rcParams['image.aspect']
     axes.set_aspect(aspect)
-    im = mimage.AxesImage(axes, cmap, norm, interpolation, origin, extent,
+    im = ScalingAxesImage(axes, cmap, norm, interpolation, origin, extent,
                           filternorm=filternorm, filterrad=filterrad,
                           resample=resample, **kwargs)
-
     im.set_data(z)
     im.set_alpha(alpha)
     if im.get_clip_path() is None:
diff --git a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
index 718e5a7e6cddc3bc9805f95bb20351c94c9e21c8..7c8f94638e9dfef1616fbe56abc3debef280794d 100644
--- a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
+++ b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
@@ -9,9 +9,9 @@ from __future__ import (absolute_import, division, print_function)
 from mantid.api import mtd, AlgorithmFactory, DistributedDataProcessorAlgorithm, ITableWorkspaceProperty, \
     MatrixWorkspaceProperty, MultipleFileProperty, PropertyMode
 from mantid.kernel import ConfigService, Direction
-from mantid.simpleapi import AlignAndFocusPowder, CompressEvents, ConvertUnits, CreateCacheFilename, \
-    DeleteWorkspace, DetermineChunking, Divide, EditInstrumentGeometry, FilterBadPulses, Load, \
-    LoadNexusProcessed, PDDetermineCharacterizations, Plus, RenameWorkspace, SaveNexusProcessed
+from mantid.simpleapi import AlignAndFocusPowder, CompressEvents, ConvertUnits, CopyLogs, CreateCacheFilename, \
+    DeleteWorkspace, DetermineChunking, Divide, EditInstrumentGeometry, FilterBadPulses, LoadNexusProcessed, \
+    PDDetermineCharacterizations, Plus, RemoveLogs, RenameWorkspace, SaveNexusProcessed
 import os
 
 EXTENSIONS_NXS = ["_event.nxs", ".nxs.h5"]
@@ -19,7 +19,7 @@ PROPS_FOR_INSTR = ["PrimaryFlightPath", "SpectrumIDs", "L2", "Polar", "Azimuthal
 CAL_FILE, GROUP_FILE = "CalFileName", "GroupFilename"
 CAL_WKSP, GRP_WKSP, MASK_WKSP = "CalibrationWorkspace", "GroupingWorkspace", "MaskWorkspace"
 PROPS_FOR_ALIGN = [CAL_FILE, GROUP_FILE,
-                   GRP_WKSP,CAL_WKSP, "OffsetsWorkspace",
+                   GRP_WKSP, CAL_WKSP, "OffsetsWorkspace",
                    MASK_WKSP, "MaskBinTable",
                    "Params", "ResampleX", "Dspacing", "DMin", "DMax",
                    "TMin", "TMax", "PreserveEvents",
@@ -63,7 +63,7 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
         return "Diffraction\\Reduction"
 
     def seeAlso(self):
-        return [ "AlignAndFocusPowder" ]
+        return ["AlignAndFocusPowder"]
 
     def name(self):
         return "AlignAndFocusPowderFromFiles"
@@ -124,11 +124,28 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
                 linearizedRuns.append(item)
         return linearizedRuns
 
+    def __createLoader(self, filename, wkspname, progstart=None, progstop=None):
+        # load a chunk - this is a bit crazy long because we need to get an output property from `Load` when it
+        # is run and the algorithm history doesn't exist until the parent algorithm (this) has finished
+        if progstart is None or progstop is None:
+            loader = self.createChildAlgorithm(self.__loaderName)
+        else:
+            loader = self.createChildAlgorithm(self.__loaderName,
+                                               startProgress=progstart, endProgress=progstop)
+        loader.setAlwaysStoreInADS(True)
+        loader.setLogging(True)
+        loader.initialize()
+        loader.setPropertyValue('Filename', filename)
+        loader.setPropertyValue('OutputWorkspace', wkspname)
+        return loader
+
     def __getAlignAndFocusArgs(self):
         args = {}
         for name in PROPS_FOR_ALIGN:
             prop = self.getProperty(name)
-            if name == 'PreserveEvents' or not prop.isDefault:
+            name_list = ['PreserveEvents', 'CompressTolerance',
+                         'CompressWallClockTolerance', 'CompressStartTime']
+            if name in name_list or not prop.isDefault:
                 if 'Workspace' in name:
                     args[name] = prop.valueAsStr
                 else:
@@ -159,18 +176,25 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
             if key not in self.kwargs:
                 self.kwargs[key] = instr + ext
 
-    def __determineCharacterizations(self, filename, wkspname, loadFile):
+    def __determineCharacterizations(self, filename, wkspname):
         useCharac = bool(self.charac is not None)
+        loadFile = not mtd.doesExist(wkspname)
 
         # input workspace is only needed to find a row in the characterizations table
         tempname = None
         if loadFile:
             if useCharac:
                 tempname = '__%s_temp' % wkspname
-                Load(Filename=filename, OutputWorkspace=tempname,
-                     MetaDataOnly=True)
+                # set the loader for this file
+                loader = self.__createLoader(filename, tempname)
+                loader.setProperty('MetaDataOnly', True)  # this is only supported by LoadEventNexus
+                loader.execute()
+
+                # get the underlying loader name if we used the generic one
+                if self.__loaderName == 'Load':
+                    self.__loaderName = loader.getPropertyValue('LoaderName')
         else:
-            tempname = wkspname # assume it is already loaded
+            tempname = wkspname  # assume it is already loaded
 
         # put together argument list
         args = dict(ReductionProperties=self.getProperty('ReductionProperties').valueAsStr)
@@ -179,7 +203,7 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
             if not prop.isDefault:
                 args[name] = prop.value
         if tempname is not None:
-            args['InputWorkspace']=tempname
+            args['InputWorkspace'] = tempname
         if useCharac:
             args['Characterizations'] = self.charac
 
@@ -209,12 +233,13 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
 
     def __processFile(self, filename, wkspname, unfocusname, file_prog_start, determineCharacterizations):
         chunks = determineChunking(filename, self.chunkSize)
-        numSteps = 6 # for better progress reporting - 6 steps per chunk
+        numSteps = 6  # for better progress reporting - 6 steps per chunk
         if unfocusname != '':
-            numSteps = 7 # one more for accumulating the unfocused workspace
+            numSteps = 7  # one more for accumulating the unfocused workspace
         self.log().information('Processing \'{}\' in {:d} chunks'.format(filename, len(chunks)))
         prog_per_chunk_step = self.prog_per_file * 1./(numSteps*float(len(chunks)))
         unfocusname_chunk = ''
+        canSkipLoadingLogs = False
 
         # inner loop is over chunks
         for (j, chunk) in enumerate(chunks):
@@ -223,11 +248,30 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
             if unfocusname != '':  # only create unfocus chunk if needed
                 unfocusname_chunk = '{}_c{:d}'.format(unfocusname, j)
 
-            Load(Filename=filename, OutputWorkspace=chunkname,
-                 startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step,
-                 **chunk)
-            if determineCharacterizations:
-                self.__determineCharacterizations(filename, chunkname, False) # updates instance variable
+            # load a chunk - this is a bit crazy long because we need to get an output property from `Load` when it
+            # is run and the algorithm history doesn't exist until the parent algorithm (this) has finished
+            loader = self.__createLoader(filename, chunkname,
+                                         progstart=prog_start, progstop=prog_start + prog_per_chunk_step)
+            if canSkipLoadingLogs:
+                loader.setProperty('LoadLogs', False)
+            for key, value in chunk.items():
+                if isinstance(value, str):
+                    loader.setPropertyValue(key, value)
+                else:
+                    loader.setProperty(key, value)
+            loader.execute()
+
+            # copy the necessary logs onto the workspace
+            if canSkipLoadingLogs:
+                CopyLogs(InputWorkspace=wkspname, OutputWorkspace=chunkname, MergeStrategy='WipeExisting')
+
+            # get the underlying loader name if we used the generic one
+            if self.__loaderName == 'Load':
+                self.__loaderName = loader.getPropertyValue('LoaderName')
+            canSkipLoadingLogs = self.__loaderName == 'LoadEventNexus'
+
+            if determineCharacterizations and j == 0:
+                self.__determineCharacterizations(filename, chunkname)  # updates instance variable
                 determineCharacterizations = False
 
             prog_start += prog_per_chunk_step
@@ -250,7 +294,7 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
             AlignAndFocusPowder(InputWorkspace=chunkname, OutputWorkspace=chunkname, UnfocussedWorkspace=unfocusname_chunk,
                                 startProgress=prog_start, endProgress=prog_start+2.*prog_per_chunk_step,
                                 **self.kwargs)
-            prog_start += 2.*prog_per_chunk_step # AlignAndFocusPowder counts for two steps
+            prog_start += 2. * prog_per_chunk_step  # AlignAndFocusPowder counts for two steps
 
             if j == 0:
                 self.__updateAlignAndFocusArgs(chunkname)
@@ -258,19 +302,24 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
                 if unfocusname != '':
                     RenameWorkspace(InputWorkspace=unfocusname_chunk, OutputWorkspace=unfocusname)
             else:
+                RemoveLogs(Workspace=chunkname)  # accumulation has them already
                 Plus(LHSWorkspace=wkspname, RHSWorkspace=chunkname, OutputWorkspace=wkspname,
                      ClearRHSWorkspace=self.kwargs['PreserveEvents'],
                      startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step)
                 DeleteWorkspace(Workspace=chunkname)
 
                 if unfocusname != '':
+                    RemoveLogs(Workspace=unfocusname_chunk)  # accumulation has them already
                     Plus(LHSWorkspace=unfocusname, RHSWorkspace=unfocusname_chunk, OutputWorkspace=unfocusname,
                          ClearRHSWorkspace=self.kwargs['PreserveEvents'],
                          startProgress=prog_start, endProgress=prog_start + prog_per_chunk_step)
                     DeleteWorkspace(Workspace=unfocusname_chunk)
 
-                if self.kwargs['PreserveEvents']:
-                    CompressEvents(InputWorkspace=wkspname, OutputWorkspace=wkspname)
+                if self.kwargs['PreserveEvents'] and self.kwargs['CompressTolerance'] > 0.:
+                    CompressEvents(InputWorkspace=wkspname, OutputWorkspace=wkspname,
+                                   WallClockTolerance=self.kwargs['CompressWallClockTolerance'],
+                                   Tolerance=self.kwargs['CompressTolerance'],
+                                   StartTime=self.kwargs['CompressStartTime'])
         # end of inner loop
 
     def PyExec(self):
@@ -296,7 +345,7 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
         else:
             self.log().warning('CacheDir is not specified - functionality disabled')
 
-        self.prog_per_file = 1./float(len(filenames)) # for better progress reporting
+        self.prog_per_file = 1./float(len(filenames))  # for better progress reporting
 
         # these are also passed into the child-algorithms
         self.kwargs = self.__getAlignAndFocusArgs()
@@ -306,14 +355,14 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
             # default name is based off of filename
             wkspname = os.path.split(filename)[-1].split('.')[0]
 
+            self.__loaderName = 'Load'  # reset to generic load with each file
             if useCaching:
-                self.__determineCharacterizations(filename,
-                                                  wkspname, True) # updates instance variable
+                self.__determineCharacterizations(filename, wkspname)  # updates instance variable
                 cachefile = self.__getCacheName(wkspname)
             else:
                 cachefile = None
 
-            wkspname += '_f%d' % i # add file number to be unique
+            wkspname += '_f%d' % i  # add file number to be unique
 
             # if the unfocussed data is requested, don't read it from disk
             # because of the extra complication of the unfocussed workspace
@@ -330,7 +379,7 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
                 if editinstrargs:
                     EditInstrumentGeometry(Workspace=wkspname, **editinstrargs)
             else:
-                self.__processFile(filename, wkspname, unfocusname_file, self.prog_per_file*float(i), not useCaching)
+                self.__processFile(filename, wkspname, unfocusname_file, self.prog_per_file * float(i), not useCaching)
 
                 # write out the cachefile for the main reduced data independent of whether
                 # the unfocussed workspace was requested
@@ -353,8 +402,11 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
                          ClearRHSWorkspace=self.kwargs['PreserveEvents'])
                     DeleteWorkspace(Workspace=unfocusname_file)
 
-                if self.kwargs['PreserveEvents']:
-                    CompressEvents(InputWorkspace=finalname, OutputWorkspace=finalname)
+                if self.kwargs['PreserveEvents'] and self.kwargs['CompressTolerance'] > 0.:
+                    CompressEvents(InputWorkspace=finalname, OutputWorkspace=finalname,
+                                   WallClockTolerance=self.kwargs['CompressWallClockTolerance'],
+                                   Tolerance=self.kwargs['CompressTolerance'],
+                                   StartTime=self.kwargs['CompressStartTime'])
                     # not compressing unfocussed workspace because it is in d-spacing
                     # and is likely to be from a different part of the instrument
 
diff --git a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
index 046b6cc654857d1f88f0a0d49589ff1dde1030b8..b3eb99ada058fb1d5ae6918a5e41d6793babc726 100644
--- a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
@@ -536,7 +536,8 @@ class SNSPowderReduction(DistributedDataProcessorAlgorithm):
                                               OutputWorkspace=self._charTable)
         # export the characterizations table
         charTable = results[0]
-        self.declareProperty(ITableWorkspaceProperty("CharacterizationsTable", self._charTable, Direction.Output))
+        if not self.existsProperty("CharacterizationsTable"):
+            self.declareProperty(ITableWorkspaceProperty("CharacterizationsTable", self._charTable, Direction.Output))
         self.setProperty("CharacterizationsTable", charTable)
 
         # get the focus positions from the properties
@@ -972,7 +973,8 @@ class SNSPowderReduction(DistributedDataProcessorAlgorithm):
                 self.log().warning(str(e))
 
             propertyName = "OutputWorkspace%s" % str(output_wksp_list[split_index])
-            self.declareProperty(WorkspaceProperty(propertyName, str(output_wksp_list[split_index]), Direction.Output))
+            if not self.existsProperty(propertyName):
+                self.declareProperty(WorkspaceProperty(propertyName, str(output_wksp_list[split_index]), Direction.Output))
             self.setProperty(propertyName, output_wksp_list[split_index])
             self._save(output_wksp_list[split_index], self._info, False, True)
             self.log().information("Done focussing data of %d." % (split_index))
diff --git a/Framework/PythonInterface/plugins/algorithms/StatisticsOfTableWorkspace.py b/Framework/PythonInterface/plugins/algorithms/StatisticsOfTableWorkspace.py
index f148fc24d9f8bac466243921ecbedbf96d11223f..6b9d25ad702e0473b2a9902914f87772647b6371 100644
--- a/Framework/PythonInterface/plugins/algorithms/StatisticsOfTableWorkspace.py
+++ b/Framework/PythonInterface/plugins/algorithms/StatisticsOfTableWorkspace.py
@@ -4,30 +4,33 @@
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
-#pylint: disable=no-init
+# pylint: disable=no-init
 
 from __future__ import (absolute_import, division, print_function)
-from mantid.api import PythonAlgorithm, AlgorithmFactory, ITableWorkspaceProperty
-from mantid.kernel import Direction, Stats
-import mantid.simpleapi as ms
-from mantid import mtd, logger
-import numpy as np
+
 import collections
+
+import numpy as np
 from six import iteritems
 
+import mantid.simpleapi as ms
+from mantid import logger, mtd
+from mantid.api import AlgorithmFactory, ITableWorkspaceProperty, PythonAlgorithm
+from mantid.kernel import Direction, IntArrayBoundedValidator, IntArrayProperty, Stats
+
 
 def _stats_to_dict(stats):
     """
-    Converts a Statstics object to an ordered dictionary.
+    Converts a Statistics object to an ordered dictionary.
     @param stats Statistics object to convertToWaterfall
     @return Dictionary of statistics
     """
     stat_dict = collections.OrderedDict()
-    stat_dict['standard_deviation'] = stats.standard_deviation
-    stat_dict['maximum'] = stats.maximum
-    stat_dict['minimum'] = stats.minimum
-    stat_dict['mean'] = stats.mean
-    stat_dict['median'] = stats.median
+    stat_dict['StandardDev'] = stats.standard_deviation
+    stat_dict['Maximum'] = stats.maximum
+    stat_dict['Minimum'] = stats.minimum
+    stat_dict['Mean'] = stats.mean
+    stat_dict['Median'] = stats.median
     return stat_dict
 
 
@@ -42,38 +45,55 @@ class StatisticsOfTableWorkspace(PythonAlgorithm):
     def PyInit(self):
         self.declareProperty(ITableWorkspaceProperty('InputWorkspace', '', Direction.Input),
                              doc='Input table workspace.')
+        validator = IntArrayBoundedValidator()
+        validator.setLower(0)
+        self.declareProperty(
+            IntArrayProperty('ColumnIndices', values=[], direction=Direction.Input, validator=validator),
+            'Comma separated list of column indices for which statistics will be separated')
         self.declareProperty(ITableWorkspaceProperty('OutputWorkspace', '', Direction.Output),
-                             doc='Output workspace contatining column statitics.')
+                             doc='Output workspace containing column statistics.')
 
     def PyExec(self):
         in_ws = mtd[self.getPropertyValue('InputWorkspace')]
+        indices_list = self.getPropertyValue('ColumnIndices')
         out_ws_name = self.getPropertyValue('OutputWorkspace')
+        column_names = in_ws.getColumnNames()
+
+        # If column indices are not provided, then default to _ALL_ columns
+        if len(indices_list) > 0:
+            indices_list = [int(x) for x in indices_list.split(',')]
+        else:
+            indices_list = range(len(column_names))
 
         out_ws = ms.CreateEmptyTableWorkspace(OutputWorkspace=out_ws_name)
 
-        out_ws.addColumn('str', 'statistic')
+        out_ws.addColumn('str', 'Statistic')
 
         stats = collections.OrderedDict([
-            ('standard_deviation', collections.OrderedDict()),
-            ('minimum', collections.OrderedDict()),
-            ('median', collections.OrderedDict()),
-            ('maximum', collections.OrderedDict()),
-            ('mean', collections.OrderedDict()),
+            ('StandardDev', collections.OrderedDict()),
+            ('Minimum', collections.OrderedDict()),
+            ('Median', collections.OrderedDict()),
+            ('Maximum', collections.OrderedDict()),
+            ('Mean', collections.OrderedDict()),
         ])
 
-        for name in in_ws.getColumnNames():
+        for index in indices_list:
+            column_name = column_names[index]
             try:
-                col_stats = _stats_to_dict(Stats.getStatistics(np.array([float(v) for v in in_ws.column(name)])))
-                for statname in stats:
-                    stats[statname][name] = col_stats[statname]
-                out_ws.addColumn('float', name)
-            except ValueError:
-                logger.notice('Column \'%s\' is not numerical, skipping' % name)
-
-        for name, stat in iteritems(stats):
-            stat1 = collections.OrderedDict(stat)
-            stat1['statistic'] = name
-            out_ws.addRow(stat1)
+                column_data = np.array([float(v) for v in in_ws.column(index)])
+                col_stats = _stats_to_dict(Stats.getStatistics(column_data))
+                for stat_name in stats:
+                    stats[stat_name][column_name] = col_stats[stat_name]
+                out_ws.addColumn('float', column_name)
+            except RuntimeError:
+                logger.notice('Column \'%s\' is not numerical, skipping' % column_name)
+            except:
+                logger.notice('Column \'%s\' is not numerical, skipping' % column_name)
+
+        for index, stat_name in iteritems(stats):
+            stat = collections.OrderedDict(stat_name)
+            stat['Statistic'] = index
+            out_ws.addRow(stat)
 
         self.setProperty('OutputWorkspace', out_ws)
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegration.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegration.py
index be085623bb3a07a3c385503f81e052892896c777..3110cd70f5985a6fb94cbe5579fba62c9d605476 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegration.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegration.py
@@ -35,7 +35,7 @@ class SANSILLIntegration(PythonAlgorithm):
 
     def validateInputs(self):
         issues = dict()
-        if self.getProperty('ResolutionBasedBinning').value and self.getPropertyValue('CalculateResolution') == 'None':
+        if self.getPropertyValue('DefaultQBinning') == 'ResolutionBased' and self.getPropertyValue('CalculateResolution') == 'None':
             issues['CalculateResolution'] = 'Please choose a resolution calculation method if resolution based binning is requested.'
         if not isinstance(self.getProperty('InputWorkspace').value, MatrixWorkspace):
             issues['InputWorkspace'] = 'The input must be a MatrixWorkspace'
@@ -82,15 +82,21 @@ class SANSILLIntegration(PythonAlgorithm):
                              validator=StringListValidator(['MildnerCarpenter', 'None']),
                              doc='Choose to calculate the Q resolution.')
 
-        self.declareProperty('ResolutionBasedBinning', False, 'Whether or not to use default binning based on 2*sigma of resolution.')
-        self.setPropertySettings('ResolutionBasedBinning',
-                                 EnabledWhenProperty('CalculateResolution', PropertyCriterion.IsNotEqualTo, 'None'))
-
         output_iq = EnabledWhenProperty('OutputType', PropertyCriterion.IsEqualTo, 'I(Q)')
         output_iphiq = EnabledWhenProperty('OutputType', PropertyCriterion.IsEqualTo, 'I(Phi,Q)')
         output_iqxy = EnabledWhenProperty('OutputType', PropertyCriterion.IsEqualTo, 'I(Qx,Qy)')
 
-        self.declareProperty(FloatArrayProperty('OutputBinning'), doc='The Q binning of the output')
+        self.declareProperty(name='DefaultQBinning', defaultValue='PixelSizeBased',
+                             validator=StringListValidator(['PixelSizeBased', 'ResolutionBased']),
+                             doc='Choose how to calculate the default Q binning.')
+        self.setPropertySettings('DefaultQBinning', EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))
+
+        self.declareProperty(name='BinningFactor', defaultValue=1.,
+                             validator=FloatBoundedValidator(lower=0.),
+                             doc='Specify a multiplicative factor for default Q binning (pixel or resolution based).')
+        self.setPropertySettings('BinningFactor', EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))
+
+        self.declareProperty(FloatArrayProperty('OutputBinning'), doc='The manual Q binning of the output')
         self.setPropertySettings('OutputBinning', EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))
 
         self.declareProperty('NPixelDivision', 1, IntBoundedValidator(lower=1), 'Number of subpixels to split the pixel (NxN)')
@@ -119,6 +125,8 @@ class SANSILLIntegration(PythonAlgorithm):
         self.declareProperty(name='AsymmetricWedges', defaultValue=False, doc='Whether to have asymmetric wedges.')
         self.setPropertySettings('AsymmetricWedges', iq_with_wedges)
 
+        self.setPropertyGroup('DefaultQBinning', 'I(Q) Options')
+        self.setPropertyGroup('BinningFactor', 'I(Q) Options')
         self.setPropertyGroup('OutputBinning', 'I(Q) Options')
         self.setPropertyGroup('NPixelDivision', 'I(Q) Options')
         self.setPropertyGroup('NumberOfWedges', 'I(Q) Options')
@@ -154,7 +162,7 @@ class SANSILLIntegration(PythonAlgorithm):
             self._integrate_iqxy()
         self.setProperty('OutputWorkspace', self._output_ws)
 
-    def _get_iq_binning(self, q_min, q_max, pixel_height, wavelength, l2):
+    def _get_iq_binning(self, q_min, q_max, pixel_size, wavelength, l2, binning_factor):
         """
         Returns the OutputBinning string to be used in Q1DWeighted
         """
@@ -163,23 +171,23 @@ class SANSILLIntegration(PythonAlgorithm):
                              'Given qmin={0:.2f}, qmax={0:.2f}.'.format(q_min, q_max))
         q_binning = []
         binning = self.getProperty('OutputBinning').value
-        use_resolution = self.getProperty('ResolutionBasedBinning').value
+        strategy = self.getPropertyValue('DefaultQBinning')
         if len(binning) == 0:
-            if use_resolution:
-                q_binning = self._mildner_carpenter_q_binning(q_min, q_max)
+            if strategy == 'ResolutionBased':
+                q_binning = self._mildner_carpenter_q_binning(q_min, q_max, binning_factor)
             else:
                 if wavelength != 0:
-                    q_binning = self._pixel_q_binning(q_min, q_max, pixel_height, wavelength, l2)
+                    q_binning = self._pixel_q_binning(q_min, q_max, pixel_size * binning_factor, wavelength, l2)
                 else:
                     q_binning = self._tof_default_q_binning(q_min, q_max)
         elif len(binning) == 1:
             q_binning = [q_min, binning[0], q_max]
         elif len(binning) == 2:
-            if use_resolution:
-                q_binning = self._mildner_carpenter_q_binning(binning[0], binning[1])
+            if strategy == 'ResolutionBased':
+                q_binning = self._mildner_carpenter_q_binning(binning[0], binning[1], binning_factor)
             else:
                 if wavelength != 0:
-                    q_binning = self._pixel_q_binning(binning[0], binning[1], pixel_height, wavelength, l2)
+                    q_binning = self._pixel_q_binning(binning[0], binning[1], pixel_size * binning_factor, wavelength, l2)
                 else:
                     q_binning = self._tof_default_q_binning(binning[0], binning[1])
         else:
@@ -192,15 +200,16 @@ class SANSILLIntegration(PythonAlgorithm):
         """
         return [q_min, -0.2, q_max]
 
-    def _pixel_q_binning(self, q_min, q_max, pixel_height, wavelength, l2):
+    def _pixel_q_binning(self, q_min, q_max, pixel_size, wavelength, l2):
         """
-        Returns q binning based on the height of a single pixel within the range of q_min and q_max
+        Returns q binning based on the size of a single pixel within the range of q_min and q_max
+        Size is the largest size, i.e. max(height, width)
         """
         bins = []
         q = 0.
         pixels = 1
         while (q < q_max):
-            two_theta = np.arctan(pixel_height * pixels / l2)
+            two_theta = np.arctan(pixel_size * pixels / l2)
             q = 4 * np.pi * np.sin(two_theta / 2) / wavelength
             bins.append(q)
             pixels += 1
@@ -212,14 +221,14 @@ class SANSILLIntegration(PythonAlgorithm):
         q_binning[1::2] = q_bin_widths
         return q_binning
 
-    def _mildner_carpenter_q_binning(self, qmin, qmax):
+    def _mildner_carpenter_q_binning(self, qmin, qmax, factor):
         """
-        Returns q binning such that at each q, bin width is almost 2*sigma
+        Returns q binning such that at each q, bin width is almost factor*sigma
         """
         q = qmin
         result = [qmin]
         while q < qmax:
-            bin_width = 2 * self._deltaQ(q)
+            bin_width = factor * self._deltaQ(q)
             result.append(bin_width)
             q += bin_width
             result.append(q)
@@ -288,11 +297,14 @@ class SANSILLIntegration(PythonAlgorithm):
         q_max = run.getLogData('qmax').value
         self.log().information('Using qmin={0:.2f}, qmax={1:.2f}'.format(q_min, q_max))
         pixel_height = run.getLogData('pixel_height').value
+        pixel_width = run.getLogData('pixel_width').value
+        pixel_size = pixel_height if pixel_height >= pixel_width else pixel_width
+        binning_factor = self.getProperty('BinningFactor').value
         wavelength = 0. # for TOF mode there is no wavelength
         if run.hasProperty('wavelength'):
             wavelength = run.getLogData('wavelength').value
         l2 = run.getLogData('l2').value
-        q_binning = self._get_iq_binning(q_min, q_max, pixel_height, wavelength, l2)
+        q_binning = self._get_iq_binning(q_min, q_max, pixel_size, wavelength, l2, binning_factor)
         n_wedges = self.getProperty('NumberOfWedges').value
         pixel_division = self.getProperty('NPixelDivision').value
         if self._output_type == 'I(Q)':
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
index 370270d2de7a0278fae694d164a022bada207f57..2997a4e34e9b687b6ecf228e392a51bdea7fe3c5 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
@@ -197,11 +197,30 @@ class SANSILLReduction(PythonAlgorithm):
                 duration = mtd[ws].getRun().getLogData('timer').value
                 if duration != 0.:
                     Scale(InputWorkspace=ws, Factor=1./duration, OutputWorkspace=ws)
+                    self._dead_time_correction(ws)
                 else:
                     raise RuntimeError('Unable to normalise to time; duration found is 0 seconds.')
             else:
                 raise RuntimeError('Normalise to timer requested, but timer information is not available.')
 
+    def _dead_time_correction(self, ws):
+        """
+            Performs the dead time correction
+            @param ws : the input workspace
+        """
+
+        instrument = mtd[ws].getInstrument()
+        if instrument.hasParameter('tau'):
+            tau = instrument.getNumberParameter('tau')[0]
+            if instrument.hasParameter('grouping'):
+                pattern = instrument.getStringParameter('grouping')[0]
+                DeadTimeCorrection(InputWorkspace=ws, Tau=tau, GroupingPattern=pattern, OutputWorkspace=ws)
+            else:
+                self.log().warning('No grouping available in IPF, dead time correction will be performed pixel-wise.')
+                DeadTimeCorrection(InputWorkspace=ws, Tau=tau, OutputWorkspace=ws)
+        else:
+            self.log().information('No tau available in IPF, skipping dead time correction.')
+
     def _process_beam(self, ws):
         """
             Calculates the beam center's x,y coordinates, and the beam flux
@@ -248,25 +267,13 @@ class SANSILLReduction(PythonAlgorithm):
     def _check_processed_flag(ws, value):
         return ws.getRun().getLogData('ProcessedAs').value == value
 
-    @staticmethod
-    def _parallax_correction(ws):
-        formula = ws.getInstrument().getStringParameter('parallax_old')[0]
-        l2 = ws.getRun().getLogData('L2').value
-        n_spectra = ws.getNumberHistograms()
-        p = np.empty(n_spectra)
-        for i in range(n_spectra):
-            d = ws.getDetector(i).getPos()
-            p[i] = np.arctan(d[0]/l2)
-        parallax_ws = ws.getName() + '_parallax'
-        parallax_ws = CreateWorkspace(NSpec=n_spectra, DataY=eval(formula), DataX=ws.extractX(), ParentWorkspace=ws, StoreInADS=False)
-        Divide(LHSWorkspace=ws, RHSWorkspace=parallax_ws, OutputWorkspace=ws.getName())
-
     def PyExec(self): # noqa: C901
         process = self.getPropertyValue('ProcessAs')
         ws = '__' + self.getPropertyValue('OutputWorkspace')
         LoadAndMerge(Filename=self.getPropertyValue('Run').replace(',','+'), LoaderName='LoadILLSANS', OutputWorkspace=ws)
         self._normalise(ws)
         ExtractMonitors(InputWorkspace=ws, DetectorWorkspace=ws)
+        instrument = mtd[ws].getInstrument().getName()
         if process in ['Beam', 'Transmission', 'Container', 'Reference', 'Sample']:
             absorber_ws = self.getProperty('AbsorberInputWorkspace').value
             if absorber_ws:
@@ -342,10 +349,14 @@ class SANSILLReduction(PythonAlgorithm):
                         thickness = self.getProperty('SampleThickness').value
                         NormaliseByThickness(InputWorkspace=ws, OutputWorkspace=ws, SampleThickness=thickness)
                         # parallax (gondola) effect
-                        if mtd[ws].getInstrument().hasParameter('parallax_old'):
-                            # for the moment it's only D22 that has this
+                        if instrument in ['D22', 'D22lr', 'D33']:
                             self.log().information('Performing parallax correction')
-                            self._parallax_correction(mtd[ws])
+                            if instrument == 'D33':
+                                components = ['back_detector', 'front_detector_top', 'front_detector_bottom',
+                                              'front_detector_left', 'front_detector_right']
+                            else:
+                                components = ['detector']
+                            ParallaxCorrection(InputWorkspace=ws, OutputWorkspace=ws, ComponentNames=components)
                         if process == 'Reference':
                             sensitivity_out = self.getPropertyValue('SensitivityOutputWorkspace')
                             if sensitivity_out:
@@ -386,7 +397,7 @@ class SANSILLReduction(PythonAlgorithm):
                                 ReplaceSpecialValues(InputWorkspace=ws, OutputWorkspace=ws,
                                                      NaNValue=0., NaNError=0., InfinityValue=0., InfinityError=0.)
         if process != 'Transmission':
-            if mtd[ws].getInstrument().getName() == 'D33':
+            if instrument == 'D33':
                 CalculateDynamicRange(Workspace=ws, ComponentNames=['back_detector', 'front_detector'])
             else:
                 CalculateDynamicRange(Workspace=ws)
diff --git a/Framework/PythonInterface/test/python/mantid/api/AnalysisDataServiceObserverTest.py b/Framework/PythonInterface/test/python/mantid/api/AnalysisDataServiceObserverTest.py
index d78bc85ca65a05f10182228a4ba7dab12009dab5..2a7cba7cf4bd18ed4128ec0d0eede570249863db 100644
--- a/Framework/PythonInterface/test/python/mantid/api/AnalysisDataServiceObserverTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/AnalysisDataServiceObserverTest.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -14,9 +14,11 @@ import sys
 from mantid.api import AnalysisDataService as ADS, AnalysisDataServiceObserver
 from mantid.simpleapi import CreateSampleWorkspace, RenameWorkspace, GroupWorkspaces, UnGroupWorkspace, DeleteWorkspace
 
-if sys.version_info.major == 3:
+if sys.version_info.major >= 3:
+    # Python 3 and above
     from unittest import mock
 else:
+    # Python 2
     import mock
 
 
diff --git a/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py b/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py
index 60a87c5952b554916862134d9f0ba69430a2253f..c6b1420f8da23e1a754b0eccd512757f1317f829 100644
--- a/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py
+++ b/Framework/PythonInterface/test/python/mantid/dataobjects/EventListTest.py
@@ -61,5 +61,15 @@ class EventListTest(unittest.TestCase):
 
         self.assertEquals(left.integrate(-1.,31., True), -10.)
 
+    def test_mask_condition(self):
+        evl = self.createRandomEventList(20)
+
+        tof = evl.getTofs()
+        mask = (tof < 10)
+        evl.maskCondition(mask)
+
+        self.assertEquals(evl.getNumberEvents(), 10)
+        self.assertEquals(evl.getTofMax(), float(9.0))
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/ComputeIncoherentDOSTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/ComputeIncoherentDOSTest.py
index 8bd3f00ec267ec02b2479ed3c32da07e05694ced..dd7e674690d94a0de3332843cefa1076e16c1186 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/ComputeIncoherentDOSTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/ComputeIncoherentDOSTest.py
@@ -245,8 +245,8 @@ class ComputeIncoherentDOSTest(unittest.TestCase):
         g1 = self.compute(qs[0:2], energyBins)
         g2 = self.compute(qs[1:3], energyBins)
         g3 = self.compute(qs[2:4], energyBins)
-        g = g1 + g2 + g3
-        gE = np.sqrt(g1**2 + g2**2 + g3**2)
+        g = (g1 + g2 + g3) / 3
+        gE = np.sqrt(g1**2 + g2**2 + g3**2) / 3
         np.testing.assert_equal(dos_Xs, energyBins)
         for i in range(len(dos_Ys)):
             self.assertAlmostEquals(dos_Ys[i], g[i])
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/StatisticsOfTableWorkspaceTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/StatisticsOfTableWorkspaceTest.py
index 4c7aca53c6fa3ac7dbdf420dd880076d8a175668..417f35cb590dc7c7f168c8d7800a00094f164fbd 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/StatisticsOfTableWorkspaceTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/StatisticsOfTableWorkspaceTest.py
@@ -34,14 +34,13 @@ class StatisticsOfTableWorkspaceTest(unittest.TestCase):
         self.assertEqual(stats.rowCount(), 5)
         self.assertEqual(stats.columnCount(), 3)
 
-        stat_col = stats.column('statistic')
-
-        self.assertAlmostEqual(stats.column('a')[stat_col.index('standard_deviation')], 1.11803400517)
-        self.assertAlmostEqual(stats.column('a')[stat_col.index('minimum')], 1.0)
-        self.assertAlmostEqual(stats.column('a')[stat_col.index('median')], 2.5)
-        self.assertAlmostEqual(stats.column('a')[stat_col.index('maximum')], 4.0)
-        self.assertAlmostEqual(stats.column('a')[stat_col.index('mean')], 2.5)
+        stat_col = stats.column('Statistic')
 
+        self.assertAlmostEqual(stats.column('a')[stat_col.index('StandardDev')], 1.11803400517)
+        self.assertAlmostEqual(stats.column('a')[stat_col.index('Minimum')], 1.0)
+        self.assertAlmostEqual(stats.column('a')[stat_col.index('Median')], 2.5)
+        self.assertAlmostEqual(stats.column('a')[stat_col.index('Maximum')], 4.0)
+        self.assertAlmostEqual(stats.column('a')[stat_col.index('Mean')], 2.5)
 
     def test_invalid_types(self):
         """
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
index b1b9176f59136f8a73e1ad022c4d3fd9526ab3fb..97657fbb32d36a20d8b569e15341e1fbb74a61a2 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectDataTest.py
@@ -51,7 +51,7 @@ class DirectILLCollectDataTest(unittest.TestCase):
         self.assertEquals(outWS.getNumberHistograms(), inWS.getNumberHistograms() - 1)
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[1:, :] - self._BKG_LEVEL)
+        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :] - self._BKG_LEVEL)
 
     def testBackgroundOutput(self):
         outWSName = 'outWS'
@@ -90,10 +90,10 @@ class DirectILLCollectDataTest(unittest.TestCase):
         inWS = mtd[self._TEST_WS_NAME]
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[1:, :] / duration)
+        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :] / duration)
         es = outWS.extractE()
         originalEs = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs[1:, :] / duration)
+        numpy.testing.assert_almost_equal(es, originalEs[:-1, :] / duration)
 
     def testRawWorkspaceOutput(self):
         outWSName = 'outWS'
@@ -112,10 +112,10 @@ class DirectILLCollectDataTest(unittest.TestCase):
         rawWS = mtd[rawWSName]
         ys = rawWS.extractY()
         originalYS = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYS[1:, :])
+        numpy.testing.assert_almost_equal(ys, originalYS[:-1, :])
         es = rawWS.extractE()
         originalES = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalES[1:, :])
+        numpy.testing.assert_almost_equal(es, originalES[:-1, :])
         xs = rawWS.extractX()
         outXS = outWS.extractX()
         numpy.testing.assert_almost_equal(xs, outXS)
@@ -144,13 +144,13 @@ class DirectILLCollectDataTest(unittest.TestCase):
         self.assertEquals(outWS.getNumberHistograms(), inWS.getNumberHistograms() - 1)
         xs = outWS.extractX()
         originalXs = inWS.extractX()
-        numpy.testing.assert_almost_equal(xs, originalXs[1:, :])
+        numpy.testing.assert_almost_equal(xs, originalXs[:-1, :])
         ys = outWS.extractY()
         originalYs = inWS.extractY()
-        numpy.testing.assert_almost_equal(ys, originalYs[1:, :])
+        numpy.testing.assert_almost_equal(ys, originalYs[:-1, :])
         es = outWS.extractE()
         originalEs = inWS.extractE()
-        numpy.testing.assert_almost_equal(es, originalEs[1:, :])
+        numpy.testing.assert_almost_equal(es, originalEs[:-1, :])
 
     def testOutputIncidentEnergyWorkspaceWhenEnergyCalibrationIsOff(self):
         outWSName = 'outWS'
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
index 9c4a7e95e8206a8886b54a30da949a3cabf6321f..448b6cece72188990206d129e1c7f3d70437bb88 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
@@ -10,7 +10,6 @@ import collections
 from mantid.api import mtd
 import numpy
 import numpy.testing
-from scipy import constants
 from testhelpers import illhelpers, run_algorithm
 import unittest
 
@@ -175,7 +174,7 @@ class DirectILLReductionTest(unittest.TestCase):
 
 def _groupingTestDetectors(ws):
     """Mask detectors for detector grouping tests."""
-    indexBegin = 63106  # Detector at L2 and at 2theta = 40.6.
+    indexBegin = 63105  # Detector at L2 and at 2theta = 40.6.
     kwargs = {
         'Workspace': ws,
         'StartWorkspaceIndex': 0,
@@ -183,20 +182,18 @@ def _groupingTestDetectors(ws):
         'child': True
     }
     run_algorithm('MaskDetectors', **kwargs)
-    referenceDetector = ws.getDetector(indexBegin)
-    reference2Theta1 = ws.detectorTwoTheta(referenceDetector)
-    referenceDetector = ws.getDetector(indexBegin + 256)
-    reference2Theta2 = ws.detectorTwoTheta(referenceDetector)
+    spectrumInfo = ws.spectrumInfo()
+    reference2Theta1 = spectrumInfo.twoTheta(indexBegin)
+    reference2Theta2 = spectrumInfo.twoTheta(indexBegin + 256)
     mask = list()
     tolerance = numpy.deg2rad(0.01)
     for i in range(indexBegin + 1, indexBegin + 10000):
-        det = ws.getDetector(i)
-        twoTheta = ws.detectorTwoTheta(det)
+        twoTheta = spectrumInfo.twoTheta(i)
         if abs(reference2Theta1 - twoTheta) >= tolerance and abs(reference2Theta2 - twoTheta) >= tolerance:
             mask.append(i)
     kwargs = {
         'Workspace': ws,
-        'DetectorList': mask,
+        'WorkspaceIndexList': mask,
         'child': True
     }
     run_algorithm('MaskDetectors', **kwargs)
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegrationTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegrationTest.py
index 77778febed1b00609e81d8c473da0cf3e2aeb681..f2852f69b342a46635e41dc4a749af3ad6f638f6 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegrationTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLIntegrationTest.py
@@ -90,9 +90,9 @@ class SANSILLIntegrationTest(unittest.TestCase):
         self.assertTrue(mtd['iq'].hasDx(0))
 
     def test_resolution_binning(self):
-        SANSILLIntegration(InputWorkspace='sample', OutputWorkspace='iq', ResolutionBasedBinning=True)
+        SANSILLIntegration(InputWorkspace='sample', OutputWorkspace='iq', DefaultQBinning='ResolutionBased')
         self._check_output(mtd['iq'])
-        self.assertEquals(mtd['iq'].blocksize(), 6)
+        self.assertEquals(mtd['iq'].blocksize(), 12)
         self.assertTrue(mtd['iq'].hasDx(0))
 
     def test_tof(self):
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
index bd57282a196484dc3acb93ba1c8e4981bfae5f88..4ed5b6f23cf949d1a140a613fafbb9f4c1cf385e 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
@@ -37,8 +37,8 @@ class SANSILLReductionTest(unittest.TestCase):
         run = mtd['Db'].getRun()
         self.assertAlmostEqual(run.getLogData('BeamCenterX').value, -0.0048, delta=1e-4)
         self.assertAlmostEqual(run.getLogData('BeamCenterY').value, -0.0027, delta=1e-4)
-        self.assertAlmostEqual(run.getLogData('BeamFluxValue').value, 6618939, delta=1)
-        self.assertAlmostEqual(run.getLogData('BeamFluxError').value, 8554, delta=1)
+        self.assertAlmostEqual(run.getLogData('BeamFluxValue').value, 6628249, delta=1)
+        self.assertAlmostEqual(run.getLogData('BeamFluxError').value, 8566, delta=1)
 
     def test_transmission(self):
         SANSILLReduction(Run='010414', ProcessAs='Beam', OutputWorkspace='Db')
@@ -79,7 +79,7 @@ class SANSILLReductionTest(unittest.TestCase):
         run = mtd['beam'].getRun()
         self.assertAlmostEqual(run.getLogData('BeamCenterX').value, -0.0025, delta=1e-4)
         self.assertAlmostEqual(run.getLogData('BeamCenterY').value, 0.0009, delta=1e-4)
-        self.assertAlmostEqual(run.getLogData('BeamFluxValue').value, 33698, delta=1)
+        self.assertAlmostEqual(run.getLogData('BeamFluxValue').value, 33963, delta=1)
         self.assertAlmostEqual(run.getLogData('BeamFluxError').value, 16, delta=1)
 
     def test_transmission_tof(self):
diff --git a/Framework/PythonInterface/test/testhelpers/illhelpers.py b/Framework/PythonInterface/test/testhelpers/illhelpers.py
index 34c6b39d6436ffa4b615e2025de7e665f9e32d2e..690a2a4d9a238c23a50829039a8de478557036f7 100644
--- a/Framework/PythonInterface/test/testhelpers/illhelpers.py
+++ b/Framework/PythonInterface/test/testhelpers/illhelpers.py
@@ -94,14 +94,13 @@ def _fillTemplateTOFWorkspace(templateWS, bkgLevel):
     xs = numpy.empty(nHistograms*(nBins+1))
     ys = numpy.empty(nHistograms*nBins)
     es = numpy.empty(nHistograms*nBins)
+    spectrumInfo = templateWS.spectrumInfo()
     instrument = templateWS.getInstrument()
-    sample = instrument.getSample()
-    l1 = sample.getDistance(instrument.getSource())
+    l1 = spectrumInfo.l1()
     l2 = float(instrument.getStringParameter('l2')[0])
     tofElastic = UnitConversion.run('Energy', 'TOF', E_i, l1, l2, 0.0, DeltaEModeType.Direct, 0.0)
     tofBegin = tofElastic - elasticIndex * binWidth
-    monitor = instrument.getDetector(0)
-    monitorSampleDistance = sample.getDistance(monitor)
+    monitorSampleDistance = 0.5
     tofElasticMonitor = tofBegin + monitorElasticIndex * binWidth
     tofMonitorDetector = UnitConversion.run('Energy', 'TOF', E_i, monitorSampleDistance, l2, 0.0,
                                             DeltaEModeType.Direct, 0.0)
@@ -121,11 +120,11 @@ def _fillTemplateTOFWorkspace(templateWS, bkgLevel):
             ys[yIndexOffset+binIndex] = y
             es[yIndexOffset+binIndex] = numpy.sqrt(y)
 
-    fillBins(0, tofElasticMonitor, 1623 * elasticPeakHeight, bkgMonitor)
-    for histogramIndex in range(1, nHistograms):
-        trueL2 = sample.getDistance(templateWS.getDetector(histogramIndex))
+    for histogramIndex in range(0, nHistograms - 1):
+        trueL2 = spectrumInfo.l2(histogramIndex)
         trueTOF = UnitConversion.run('Energy', 'TOF', E_i, l1, trueL2, 0.0, DeltaEModeType.Direct, 0.0)
         fillBins(histogramIndex, trueTOF, elasticPeakHeight, bkgLevel)
+    fillBins(nHistograms - 1, tofElasticMonitor, 1623 * elasticPeakHeight, bkgMonitor)
     kwargs = {
         'DataX': xs,
         'DataY': ys,
@@ -180,7 +179,7 @@ def _fillTemplateTOFWorkspace(templateWS, bkgLevel):
         'Workspace': ws,
         'ParameterName': 'default-incident-monitor-spectrum',
         'ParameterType': 'Number',
-        'Value': '1',
+        'Value': str(98305),
         'child': True
     }
     run_algorithm('SetInstrumentParameter', **kwargs)
@@ -325,6 +324,7 @@ def default_test_detectors(ws):
     kwargs = {
         'Workspace': ws,
         'StartWorkspaceIndex': 512,
+        'EndWorkspaceIndex': ws.getNumberHistograms() - 2,
         'child': True
     }
     run_algorithm('MaskDetectors', **kwargs)
diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
index d1dc13d5fd0d2bb1b903e1373bcc48f0087cc704..e20648c266cbe986498223c78626a3419af024b6 100644
--- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
+++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
@@ -7,12 +7,12 @@
 #ifndef MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPER_H
 #define MANTID_REMOTEJOBMANAGERS_MANTIDWEBSERVICEAPIHELPER_H
 
+#include "MantidKernel/DllConfig.h"
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
-#include "MantidKernel/DllConfig.h"
-
 #include <Poco/Net/HTTPResponse.h>
 
 namespace Poco {
@@ -111,10 +111,10 @@ private:
   static std::vector<Poco::Net::HTTPCookie> g_cookies;
   Poco::Net::NameValueCollection getCookies() const;
 
-  mutable Poco::Net::HTTPClientSession
-      *m_session; // Pointer to session object for all our HTTP requests
-                  // (Has to be a pointer because we allocate and delete
-                  // it multiple times)
+  mutable std::unique_ptr<Poco::Net::HTTPClientSession>
+      m_session; // Pointer to session object for all our HTTP requests
+                 // (Has to be a pointer because we allocate and delete
+                 // it multiple times)
   Poco::Net::HTTPResponse
       m_response; // Response object for all of our HTTP requests
 
diff --git a/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp b/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
index 37c3d23e2b9ad8b61ac1f794cbdcf60cd9b8a921..bce4eddc99267699855fa375b6ddb81e1d7b20cc 100644
--- a/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
+++ b/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
@@ -39,7 +39,7 @@ MantidWebServiceAPIHelper::MantidWebServiceAPIHelper()
   m_serviceBaseUrl = "https://fermi.ornl.gov/MantidRemote";
 }
 
-MantidWebServiceAPIHelper::~MantidWebServiceAPIHelper() { delete m_session; }
+MantidWebServiceAPIHelper::~MantidWebServiceAPIHelper() = default;
 
 std::istream &MantidWebServiceAPIHelper::httpGet(
     const std::string &path, const std::string &query_str,
@@ -186,10 +186,7 @@ void MantidWebServiceAPIHelper::initHTTPRequest(Poco::Net::HTTPRequest &req,
                                                 std::string extraPath,
                                                 std::string queryString) const {
   // Set up the session object
-  if (m_session) {
-    delete m_session;
-    m_session = nullptr;
-  }
+  m_session.reset();
 
   if (Poco::URI(m_serviceBaseUrl).getScheme() == "https") {
     // Create an HTTPS session
@@ -200,15 +197,15 @@ void MantidWebServiceAPIHelper::initHTTPRequest(Poco::Net::HTTPRequest &req,
         new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
                                Poco::Net::Context::VERIFY_NONE, 9, false,
                                "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
-    m_session = new Poco::Net::HTTPSClientSession(
+    m_session = std::make_unique<Poco::Net::HTTPSClientSession>(
         Poco::URI(m_serviceBaseUrl).getHost(),
         Poco::URI(m_serviceBaseUrl).getPort(), context);
   } else {
     // Create a regular HTTP client session.  (NOTE: Using unencrypted HTTP is a
     // really bad idea! We'll be sending passwords in the clear!)
-    m_session =
-        new Poco::Net::HTTPClientSession(Poco::URI(m_serviceBaseUrl).getHost(),
-                                         Poco::URI(m_serviceBaseUrl).getPort());
+    m_session = std::make_unique<Poco::Net::HTTPClientSession>(
+        Poco::URI(m_serviceBaseUrl).getHost(),
+        Poco::URI(m_serviceBaseUrl).getPort());
   }
 
   Poco::URI uri(m_serviceBaseUrl);
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/IndirectFitDataCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/IndirectFitDataCreationHelper.h
index ddce2d0ed52e0a33a216d7d83559289e143d6262..581c1f7f3d131c201f7916b552509ff0116db932 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/IndirectFitDataCreationHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/IndirectFitDataCreationHelper.h
@@ -1,8 +1,15 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
 #ifndef MANTID_INDIRECTFITDATACREATIONHELPER_H_
 #define MANTID_INDIRECTFITDATACREATIONHELPER_H_
 
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/TextAxis.h"
 #include "MantidHistogramData/BinEdges.h"
 
 #include <string>
@@ -13,12 +20,23 @@
 
 namespace Mantid {
 namespace IndirectFitDataCreationHelper {
+/// Commonly used constant variables
+int const START_X_COLUMN(2);
+int const END_X_COLUMN(3);
+int const EXCLUDE_REGION_COLUMN(4);
 
 /// Functions used in the creation of workspaces
 Mantid::API::MatrixWorkspace_sptr createWorkspace(int const &numberOfSpectra);
 Mantid::API::MatrixWorkspace_sptr createInstrumentWorkspace(int const &xLength,
                                                             int const &yLength);
 Mantid::API::MatrixWorkspace_sptr
+createWorkspaceWithTextAxis(int const &numberOfSpectra,
+                            std::vector<std::string> const &labels);
+
+Mantid::API::TextAxis *getTextAxis(int const &numberOfSpectra,
+                                   std::vector<std::string> const &labels);
+
+Mantid::API::MatrixWorkspace_sptr
 setWorkspaceEFixed(Mantid::API::MatrixWorkspace_sptr workspace,
                    int const &xLength);
 Mantid::API::MatrixWorkspace_sptr
diff --git a/Framework/TestHelpers/src/IndirectFitDataCreationHelper.cpp b/Framework/TestHelpers/src/IndirectFitDataCreationHelper.cpp
index 83082b0c41ef340802cfdb8591cfd883832370ba..3aab288df166664217dfde39b323d81169fe7c2d 100644
--- a/Framework/TestHelpers/src/IndirectFitDataCreationHelper.cpp
+++ b/Framework/TestHelpers/src/IndirectFitDataCreationHelper.cpp
@@ -15,6 +15,26 @@ MatrixWorkspace_sptr createInstrumentWorkspace(int const &xLength,
       xLength, yLength - 1, false, false, true, "testInst");
 }
 
+MatrixWorkspace_sptr
+createWorkspaceWithTextAxis(int const &numberOfSpectra,
+                            std::vector<std::string> const &labels) {
+  if (static_cast<std::size_t>(numberOfSpectra) == labels.size()) {
+    auto workspace = createWorkspace(numberOfSpectra);
+    workspace->replaceAxis(1, getTextAxis(numberOfSpectra, labels));
+    return workspace;
+  } else
+    throw std::runtime_error(
+        "The number of spectra is not equal to the number of labels");
+}
+
+TextAxis *getTextAxis(int const &numberOfSpectra,
+                      std::vector<std::string> const &labels) {
+  auto axis = new TextAxis(numberOfSpectra);
+  for (auto index = 0; index < numberOfSpectra; ++index)
+    axis->setLabel(index, labels[index]);
+  return axis;
+}
+
 MatrixWorkspace_sptr setWorkspaceEFixed(MatrixWorkspace_sptr workspace,
                                         int const &xLength) {
   for (int i = 0; i < xLength; ++i)
diff --git a/Framework/WorkflowAlgorithms/CMakeLists.txt b/Framework/WorkflowAlgorithms/CMakeLists.txt
index 49c85f2b98968c7dc872893dcf93ee590ee5714c..26b72344fe602df0a9e24add8d656996bbcaebf9 100644
--- a/Framework/WorkflowAlgorithms/CMakeLists.txt
+++ b/Framework/WorkflowAlgorithms/CMakeLists.txt
@@ -86,6 +86,7 @@ set ( INC_FILES
 )
 
 set ( TEST_FILES
+	AlignAndFocusPowderTest.h
 	ExtractQENSMembersTest.h
 	IMuonAsymmetryCalculatorTest.h
 	LoadEventAndCompressTest.h
diff --git a/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp b/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
index 412a6ec4cff4b07a311af7e4e55dd5e01c807cc2..bf042d3b297507fb62334dcf9b9fbe2be7b3f7e3 100644
--- a/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
+++ b/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
@@ -271,8 +271,12 @@ void AlignAndFocusPowder::exec() {
   m_inputW = getProperty("InputWorkspace");
   m_inputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_inputW);
   m_instName = m_inputW->getInstrument()->getName();
-  m_instName =
-      Kernel::ConfigService::Instance().getInstrument(m_instName).shortName();
+  try {
+    m_instName =
+        Kernel::ConfigService::Instance().getInstrument(m_instName).shortName();
+  } catch (Exception::NotFoundError &) {
+    ; // not noteworthy
+  }
   std::string calFilename = getPropertyValue("CalFileName");
   std::string groupFilename = getPropertyValue("GroupFilename");
   m_calibrationWS = getProperty("CalibrationWorkspace");
@@ -379,7 +383,7 @@ void AlignAndFocusPowder::exec() {
   } else {
     // workspace2D
     if (m_outputW != m_inputW) {
-      m_outputW = WorkspaceFactory::Instance().create(m_inputW);
+      m_outputW = m_inputW->clone();
     }
   }
 
@@ -720,7 +724,6 @@ void AlignAndFocusPowder::exec() {
     API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents");
     compressAlg->setProperty("InputWorkspace", m_outputEW);
     compressAlg->setProperty("OutputWorkspace", m_outputEW);
-    compressAlg->setProperty("OutputWorkspace", m_outputEW);
     compressAlg->setProperty("Tolerance", tolerance);
     if (!isEmpty(wallClockTolerance)) {
       compressAlg->setProperty("WallClockTolerance", wallClockTolerance);
@@ -776,6 +779,13 @@ AlignAndFocusPowder::diffractionFocus(API::MatrixWorkspace_sptr ws) {
     return ws;
   }
 
+  if (m_maskWS) {
+    API::IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors");
+    maskAlg->setProperty("Workspace", m_groupWS);
+    maskAlg->setProperty("MaskedWorkspace", m_maskWS);
+    maskAlg->executeAsChildAlg();
+  }
+
   g_log.information() << "running DiffractionFocussing started at "
                       << Types::Core::DateAndTime::getCurrentTime() << "\n";
 
diff --git a/Framework/WorkflowAlgorithms/test/AlignAndFocusPowderTest.h b/Framework/WorkflowAlgorithms/test/AlignAndFocusPowderTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..15c4eb136223823e8008ef5df90b33594c7548e7
--- /dev/null
+++ b/Framework/WorkflowAlgorithms/test/AlignAndFocusPowderTest.h
@@ -0,0 +1,820 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef ALIGNANDFOCUSPOWDERTEST_H_
+#define ALIGNANDFOCUSPOWDERTEST_H_
+
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAPI/Axis.h"
+#include "MantidAlgorithms/AddSampleLog.h"
+#include "MantidAlgorithms/AddTimeSeriesLog.h"
+#include "MantidAlgorithms/ConvertUnits.h"
+#include "MantidAlgorithms/CreateGroupingWorkspace.h"
+#include "MantidAlgorithms/CreateSampleWorkspace.h"
+#include "MantidAlgorithms/ResampleX.h"
+#include "MantidDataHandling/LoadDiffCal.h"
+#include "MantidDataHandling/LoadNexus.h"
+#include "MantidDataHandling/MaskDetectors.h"
+#include "MantidDataHandling/MoveInstrumentComponent.h"
+#include "MantidDataHandling/RotateInstrumentComponent.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/GroupingWorkspace.h"
+#include "MantidWorkflowAlgorithms/AlignAndFocusPowder.h"
+
+using namespace Mantid::API;
+using namespace Mantid::Algorithms;
+using namespace Mantid::DataHandling;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Kernel;
+using namespace Mantid::WorkflowAlgorithms;
+
+class AlignAndFocusPowderTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static AlignAndFocusPowderTest *createSuite() {
+    return new AlignAndFocusPowderTest();
+  }
+  static void destroySuite(AlignAndFocusPowderTest *suite) { delete suite; }
+
+  /* Test AlignAndFocusPowder basics */
+  void testTheBasics() {
+    AlignAndFocusPowder align_and_focus;
+    TS_ASSERT_EQUALS(align_and_focus.name(), "AlignAndFocusPowder");
+    TS_ASSERT_EQUALS(align_and_focus.version(), 1);
+  }
+
+  void testInit() {
+    AlignAndFocusPowder align_and_focus;
+    TS_ASSERT_THROWS_NOTHING(align_and_focus.initialize());
+    TS_ASSERT(align_and_focus.isInitialized());
+  }
+
+  void testException() {
+    AlignAndFocusPowder align_and_focus;
+    align_and_focus.initialize();
+    TS_ASSERT_THROWS(align_and_focus.execute(), std::runtime_error);
+  }
+
+  /* Test AlignAndFocusPowder for HRP38692 raw data */
+  void testHRP38692_useCalfile() { doTestHRP38692(true, false, false, false); }
+
+  void testHRP38692_useCalfile_useGroupfile() {
+    doTestHRP38692(true, false, true, false);
+  }
+
+  void testHRP38692_useCalfile_useGroupWorkspace() {
+    doTestHRP38692(true, false, false, true);
+  }
+
+  void testHRP38692_useCalWorkspace_useGroupfile() {
+    doTestHRP38692(false, true, true, false);
+  }
+
+  void testHRP38692_useCalWorkspace_useGroupWorkspace() {
+    doTestHRP38692(false, true, false, true);
+  }
+
+  /* Test AlignAndFocusPowder for Event Workspace*/
+  void testEventWksp_preserveEvents() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[80], 1609.2800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[80], 20);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 587);
+  }
+
+  void testEventWksp_preserveEvents_useGroupAll() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = true;
+    m_useResamplex = true;
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3791, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[423], 2702);
+    TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.8272, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[970], 149165);
+  }
+
+  void testEventWksp_doNotPreserveEvents() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = false;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[80], 1609.2800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[80], 20);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 587);
+  }
+
+  void testEventWksp_doNotPreserveEvents_useGroupAll() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = false;
+    m_useGroupAll = true;
+    m_useResamplex = true;
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3791, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->y(0)[423], 2419.5680, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.8272, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->y(0)[970], 148503.3853, 0.0001);
+  }
+
+  void testEventWksp_rebin_preserveEvents() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = false;
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Test the input
+    TS_ASSERT_DELTA(m_inWS->x(0)[170], 1628.3764, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[170], 48);
+    TS_ASSERT_DELTA(m_inWS->x(0)[391], 14681.7696, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[391], 2540);
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[1693], 1629.3502, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[1693], 6);
+    TS_ASSERT_DELTA(m_outWS->x(0)[3895], 14718.1436, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[3895], 612);
+  }
+
+  void testEventWksp_preserveEvents_dmin_dmax() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_dmin = createArgForNumberHistograms(0.5, m_inWS);
+    m_dmax = createArgForNumberHistograms(1.5, m_inWS);
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_dmin = "0";
+    m_dmax = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[116], 3270.3908, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[116], 37);
+    TS_ASSERT_DELTA(m_outWS->x(0)[732], 6540.7817, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[732], 25);
+  }
+
+  void testEventWksp_preserveEvents_tmin_tmax() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_tmin = "2000.0";
+    m_tmax = "10000.0";
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_tmin = "0";
+    m_tmax = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[149], 3270.7563, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[149], 51);
+    TS_ASSERT_DELTA(m_outWS->x(0)[982], 9814.5378, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[982], 138);
+  }
+
+  void testEventWksp_preserveEvents_lambdamin_lambdamax() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_lambdamin = "0.5";
+    m_lambdamax = "3.0";
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_lambdamin = "0";
+    m_lambdamax = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 105);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 290);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 0);
+  }
+
+  void testEventWksp_preserveEvents_maskbins() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_maskBinTableWS = createMaskBinTable();
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_maskBinTableWS = nullptr;
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 105);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 290);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 0);
+  }
+
+  void testEventWksp_preserveEvents_noCompressTolerance() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_compressTolerance = "0.0";
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_compressTolerance = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 105);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 290);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 587);
+  }
+
+  void testEventWksp_preserveEvents_highCompressTolerance() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_compressTolerance = "5.0";
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_compressTolerance = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 96);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 427);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 672);
+  }
+
+  void testEventWksp_preserveEvents_compressWallClockTolerance() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_compressWallClockTolerance = "50.0";
+    addPulseTimesForLogs();
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_compressWallClockTolerance = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 105);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 290);
+    TS_ASSERT_DELTA(m_outWS->x(0)[880], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[880], 587);
+  }
+
+  void testEventWksp_preserveEvents_removePromptPulse() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    m_removePromptPulse = true;
+    addFrequencyForLogs();
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_removePromptPulse = false;
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 105);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 0);
+  }
+
+  void testEventWksp_preserveEvents_compressStartTime() {
+    // Setup the event workspace
+    setUp_EventWorkspace();
+
+    // Set the inputs for doTestEventWksp
+    m_preserveEvents = true;
+    m_useGroupAll = false;
+    m_useResamplex = true;
+    // require both inside AlignAndFocusPowder
+    m_compressStartTime =
+        "2010-01-01T00:20:00"; // start time is "2010-01-01T00:00:00"
+    m_compressWallClockTolerance =
+        "50.0"; // require both inside AlignAndFocusPowder
+
+    // Run the main test function
+    doTestEventWksp();
+
+    // Reset inputs to default values
+    m_compressStartTime = "0";
+    m_compressWallClockTolerance = "0";
+
+    // Test the input
+    docheckEventInputWksp();
+
+    // Test the output
+    TS_ASSERT_DELTA(m_outWS->x(0)[181], 3262.2460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[181], 72);
+    TS_ASSERT_DELTA(m_outWS->x(0)[581], 9808.6460, 0.0001);
+    TS_ASSERT_EQUALS(m_outWS->y(0)[581], 197);
+  }
+
+  /** Setup for testing HRPD NeXus data */
+  void setUp_HRP38692() {
+
+    LoadNexus loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "HRP38692a.nxs");
+    loader.setPropertyValue("OutputWorkspace", m_inputWS);
+    loader.execute();
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+  }
+
+  void doTestHRP38692(bool useCalfile, bool useCalWksp, bool useGroupfile,
+                      bool useGroupWksp) {
+
+    setUp_HRP38692();
+
+    AlignAndFocusPowder align_and_focus;
+    align_and_focus.initialize();
+
+    align_and_focus.setPropertyValue("InputWorkspace", m_inputWS);
+    align_and_focus.setPropertyValue("OutputWorkspace", m_outputWS);
+    align_and_focus.setProperty("ResampleX", 1000);
+    align_and_focus.setProperty("Dspacing", false);
+
+    TS_ASSERT_THROWS_NOTHING(align_and_focus.execute());
+    TS_ASSERT(align_and_focus.isExecuted());
+
+    std::string calfilename("hrpd_new_072_01.cal");
+    if (useCalfile)
+      align_and_focus.setPropertyValue("CalFilename", calfilename);
+    else if (useCalWksp) {
+      loadDiffCal(calfilename, false, true, true);
+      align_and_focus.setPropertyValue("GroupingWorkspace",
+                                       m_loadDiffWSName + "_group");
+      align_and_focus.setPropertyValue("CalibrationWorkspace",
+                                       m_loadDiffWSName + "_cal");
+      align_and_focus.setPropertyValue("MaskWorkspace",
+                                       m_loadDiffWSName + "_mask");
+    }
+
+    if (useGroupfile)
+      align_and_focus.setPropertyValue("GroupFilename", calfilename);
+    else if (useGroupWksp) {
+      loadDiffCal(calfilename, true, false, true);
+      align_and_focus.setPropertyValue("MaskWorkspace",
+                                       m_loadDiffWSName + "_mask");
+      align_and_focus.setPropertyValue("GroupingWorkspace",
+                                       m_loadDiffWSName + "_group");
+    }
+
+    TS_ASSERT_THROWS_NOTHING(align_and_focus.execute());
+    TS_ASSERT(align_and_focus.isExecuted());
+
+    m_inWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_inputWS);
+    m_outWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_outputWS);
+
+    TS_ASSERT_EQUALS(m_inWS->size(), 263857);
+    TS_ASSERT_EQUALS(m_inWS->blocksize(), 23987);
+
+    TS_ASSERT_EQUALS(m_outWS->getAxis(0)->unit()->unitID(), "TOF");
+    TS_ASSERT_EQUALS(m_outWS->size(), 1000);
+    TS_ASSERT_EQUALS(m_outWS->blocksize(), m_outWS->size());
+    TS_ASSERT_EQUALS(m_outWS->getNumberHistograms(), 1);
+
+    // Maximum of peak near TOF approx. equal to 22,000 (micro-seconds)
+    TS_ASSERT_DELTA(m_outWS->x(0)[333], 21990.0502, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->y(0)[333], 770.2515, 0.0001);
+
+    // Maximum of peak near TOF approx. equal to 25,800 (micro-seconds)
+    TS_ASSERT_DELTA(m_outWS->x(0)[398], 25750.3113, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->y(0)[398], 1522.3778, 0.0001);
+
+    // Maximum of peak near TOF approx. equal to 42,000 (micro-seconds)
+    TS_ASSERT_DELTA(m_outWS->x(0)[600], 42056.6091, 0.0001);
+    TS_ASSERT_DELTA(m_outWS->y(0)[600], 7283.29652, 0.0001);
+  }
+
+  /* Setup for event data */
+
+  void setUp_EventWorkspace() {
+    m_inputWS = "eventWS";
+
+    CreateSampleWorkspace createSampleAlg;
+    createSampleAlg.initialize();
+    createSampleAlg.setPropertyValue("WorkspaceType", "Event");
+    createSampleAlg.setPropertyValue("Function", "Powder Diffraction");
+    createSampleAlg.setProperty("XMin", m_xmin); // first frame
+    createSampleAlg.setProperty("XMax", m_xmax);
+    createSampleAlg.setProperty("BinWidth", 1.0);
+    createSampleAlg.setProperty("NumBanks", m_numBanks); // detIds = [100,200)
+    createSampleAlg.setProperty("BankPixelWidth", m_numPixels);
+    createSampleAlg.setProperty("NumEvents", m_numEvents);
+    createSampleAlg.setPropertyValue("OutputWorkspace", m_inputWS);
+    createSampleAlg.execute();
+
+    for (int i = 1; i <= m_numBanks; i++) {
+      std::string bank = "bank" + std::to_string(i);
+      RotateInstrumentComponent rotateInstr;
+      rotateInstr.initialize();
+      rotateInstr.setPropertyValue("Workspace", m_inputWS);
+      rotateInstr.setPropertyValue("ComponentName", bank);
+      rotateInstr.setProperty("Y", 1.);
+      rotateInstr.setProperty("Angle", 90.);
+      rotateInstr.execute();
+
+      MoveInstrumentComponent moveInstr;
+      moveInstr.initialize();
+      moveInstr.setPropertyValue("Workspace", m_inputWS);
+      moveInstr.setPropertyValue("ComponentName", bank);
+      moveInstr.setProperty("X", 5.);
+      moveInstr.setProperty("Y", -.1);
+      moveInstr.setProperty("Z", .1);
+      moveInstr.setProperty("RelativePosition", false);
+      moveInstr.execute();
+    }
+  }
+
+  void docheckEventInputWksp() {
+    TS_ASSERT_DELTA(m_inWS->x(0)[8], 1609.2800, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[8], 97);
+    TS_ASSERT_DELTA(m_inWS->x(0)[18], 3245.8800, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[18], 237);
+    TS_ASSERT_DELTA(m_inWS->x(0)[38], 6519.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[38], 199);
+    TS_ASSERT_DELTA(m_inWS->x(0)[58], 9792.2800, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[58], 772);
+    TS_ASSERT_DELTA(m_inWS->x(0)[88], 14702.0800, 0.0001);
+    TS_ASSERT_EQUALS(m_inWS->y(0)[88], 2162);
+  }
+
+  void doTestEventWksp() {
+    // Bin events using either ResampleX or Rebin
+    int inputHistoBins{100};
+    int numHistoBins{1000};
+    std::string input_params{"-0.01"};
+    std::string params{"-0.001"};
+    if (m_useResamplex) {
+      resamplex(inputHistoBins);
+    } else {
+      rebin(params);
+      m_inWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
+          m_inputWS);
+      numHistoBins = int(m_inWS->blocksize());
+
+      rebin(input_params);
+      m_inWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
+          m_inputWS);
+      inputHistoBins = int(m_inWS->blocksize());
+    }
+
+    // Initialize AlignAndFocusPowder
+    AlignAndFocusPowder align_and_focus;
+    align_and_focus.initialize();
+    align_and_focus.setPropertyValue("InputWorkspace", m_inputWS);
+    align_and_focus.setPropertyValue("OutputWorkspace", m_outputWS);
+    align_and_focus.setProperty("Dspacing", false);
+    align_and_focus.setProperty("PreserveEvents", m_preserveEvents);
+
+    // Use a Mask TableWorkspace created from createMaskBinTable
+    if (m_maskBinTableWS)
+      align_and_focus.setProperty("MaskBinTable", m_maskBinTableWS);
+
+    // Compress tolerance for events
+    if (m_compressTolerance != "0")
+      align_and_focus.setProperty("CompressTolerance", m_compressTolerance);
+
+    // Compression for the wall clock time; controls whether all pulses are
+    // compressed together
+    if (m_compressWallClockTolerance != "0")
+      align_and_focus.setProperty("CompressWallClockTolerance",
+                                  m_compressWallClockTolerance);
+
+    // Filtering for the start wall clock time; cuts off events before start
+    // time
+    if (m_compressStartTime != "0")
+      align_and_focus.setProperty("CompressStartTime", m_compressStartTime);
+
+    // Remove prompt pulse; will cutoff last 6 long-TOF peaks (freq is 200 Hz)
+    if (m_removePromptPulse)
+      align_and_focus.setProperty("RemovePromptPulseWidth", 1e4);
+
+    // Setup the binning type
+    if (m_useResamplex) {
+      align_and_focus.setProperty("ResampleX", numHistoBins);
+    } else {
+      align_and_focus.setProperty("Params", params);
+    }
+
+    // Crop each histogram using dSpacing
+    if (m_dmin != "0") {
+      align_and_focus.setProperty("Dspacing", true);
+      align_and_focus.setPropertyValue("DMin", m_dmin);
+    }
+    if (m_dmax != "0") {
+      align_and_focus.setProperty("Dspacing", true);
+      align_and_focus.setPropertyValue("DMax", m_dmax);
+    }
+
+    // Crop entire workspace by TOF
+    if (m_tmin != "0")
+      align_and_focus.setPropertyValue("TMin", m_tmin);
+    if (m_tmax != "0")
+      align_and_focus.setPropertyValue("TMax", m_tmax);
+
+    // Crop entire workspace by Wavelength
+    if (m_lambdamin != "0")
+      align_and_focus.setPropertyValue("CropWavelengthMin", m_lambdamin);
+    if (m_lambdamax != "0")
+      align_and_focus.setPropertyValue("CropWavelengthMax", m_lambdamax);
+
+    int numGroups{m_numBanks * m_numPixels * m_numPixels};
+    if (m_useGroupAll) {
+      groupAllBanks(m_inputWS);
+      auto group_wksp =
+          AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
+              m_groupWS);
+      align_and_focus.setProperty("GroupingWorkspace", group_wksp->getName());
+      numGroups = (int)group_wksp->blocksize();
+    }
+
+    TS_ASSERT_THROWS_NOTHING(align_and_focus.execute());
+    TS_ASSERT(align_and_focus.isExecuted());
+
+    m_inWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_inputWS);
+    m_outWS =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_outputWS);
+
+    TS_ASSERT_EQUALS(m_inWS->size(),
+                     m_numBanks * m_numPixels * m_numPixels * inputHistoBins);
+    TS_ASSERT_EQUALS(m_inWS->blocksize(), inputHistoBins);
+
+    TS_ASSERT_EQUALS(m_outWS->getAxis(0)->unit()->unitID(), "TOF");
+    TS_ASSERT_EQUALS(m_outWS->size(), numGroups * numHistoBins);
+    TS_ASSERT_EQUALS(m_outWS->blocksize(), numHistoBins);
+    TS_ASSERT_EQUALS(m_outWS->getNumberHistograms(), numGroups);
+  }
+
+  /* Utility functions */
+  void loadDiffCal(std::string calfilename, bool group, bool cal, bool mask) {
+    LoadDiffCal loadDiffAlg;
+    loadDiffAlg.initialize();
+    loadDiffAlg.setPropertyValue("Filename", calfilename);
+    loadDiffAlg.setPropertyValue("InstrumentName", "HRPD");
+    loadDiffAlg.setProperty("MakeGroupingWorkspace", group);
+    loadDiffAlg.setProperty("MakeCalWorkspace", cal);
+    loadDiffAlg.setProperty("MakeMaskWorkspace", mask);
+    loadDiffAlg.setPropertyValue("WorkspaceName", m_loadDiffWSName);
+    loadDiffAlg.execute();
+  }
+
+  void groupAllBanks(std::string m_inputWS) {
+    CreateGroupingWorkspace groupAlg;
+    groupAlg.initialize();
+    groupAlg.setPropertyValue("InputWorkspace", m_inputWS);
+    groupAlg.setPropertyValue("GroupDetectorsBy", "All");
+    groupAlg.setPropertyValue("OutputWorkspace", m_groupWS);
+    groupAlg.execute();
+  }
+
+  void rebin(std::string params, bool preserveEvents = true) {
+    Rebin rebin;
+    rebin.initialize();
+    rebin.setPropertyValue("InputWorkspace", m_inputWS);
+    rebin.setPropertyValue("OutputWorkspace", m_inputWS);
+    rebin.setPropertyValue("Params", params);
+    rebin.setProperty("PreserveEvents", preserveEvents);
+    rebin.execute();
+    rebin.isExecuted();
+  }
+
+  void resamplex(int numHistoBins, bool preserveEvents = true) {
+    ResampleX resamplexAlg;
+    resamplexAlg.initialize();
+    resamplexAlg.setPropertyValue("InputWorkspace", m_inputWS);
+    resamplexAlg.setPropertyValue("OutputWorkspace", m_inputWS);
+    resamplexAlg.setProperty("NumberBins", numHistoBins);
+    resamplexAlg.setProperty("PreserveEvents", preserveEvents);
+    resamplexAlg.execute();
+  }
+
+  std::string createArgForNumberHistograms(double val, MatrixWorkspace_sptr ws,
+                                           std::string delimiter = ",") {
+    std::vector<std::string> vec;
+    for (size_t i = 0; i < ws->getNumberHistograms(); i++)
+      vec.push_back(boost::lexical_cast<std::string>(val));
+    std::string joined = boost::algorithm::join(vec, delimiter + " ");
+    return joined;
+  }
+
+  ITableWorkspace_sptr createMaskBinTable() {
+    m_maskBinTableWS = WorkspaceFactory::Instance().createTable();
+    m_maskBinTableWS->addColumn("str", "SpectraList");
+    m_maskBinTableWS->addColumn("double", "XMin");
+    m_maskBinTableWS->addColumn("double", "XMax");
+    TableRow row1 = m_maskBinTableWS->appendRow();
+    row1 << "" << 0.0 << 2000.0;
+    TableRow row2 = m_maskBinTableWS->appendRow();
+    row2 << "" << 10000.0 << m_xmax + 1000.0;
+    return m_maskBinTableWS;
+  }
+
+  void addPulseTimesForLogs() {
+    AddTimeSeriesLog logAlg;
+    std::string time, minute;
+    std::string prefix{"2010-01-01T00:"};
+    for (int i = 0; i < 60; i++) {
+      minute =
+          std::string(2 - std::to_string(i).length(), '0') + std::to_string(i);
+      time = prefix + minute + "00";
+      logAlg.initialize();
+      logAlg.setPropertyValue("Workspace", m_inputWS);
+      logAlg.setPropertyValue("Name", "proton_charge");
+      logAlg.setPropertyValue("Time", time);
+      logAlg.setPropertyValue("Value", "100");
+    }
+    logAlg.execute();
+  }
+
+  void addFrequencyForLogs() {
+    AddSampleLog freqAlg;
+    freqAlg.initialize();
+    freqAlg.setPropertyValue("LogName", "Frequency");
+    freqAlg.setPropertyValue("LogText", "200.0");
+    freqAlg.setPropertyValue("LogUnit", "Hz");
+    freqAlg.setPropertyValue("LogType", "Number Series");
+    freqAlg.setPropertyValue("NumberType", "Double");
+    freqAlg.setPropertyValue("Workspace", m_inputWS);
+    freqAlg.execute();
+  }
+
+private:
+  std::string m_inputWS{"nexusWS"};
+  std::string m_outputWS{"align_and_focused"};
+  MatrixWorkspace_sptr m_inWS;
+  MatrixWorkspace_sptr m_outWS;
+  ITableWorkspace_sptr m_maskBinTableWS;
+
+  std::string m_loadDiffWSName{"AlignAndFocusPowderTest_diff"};
+  std::string m_groupWS{"AlignAndFocusPowderTest_groupWS"};
+  std::string m_maskBinTableWSName{"AlignAndFocusPowderTest_maskBinTable"};
+
+  int m_numEvents{10000};
+  int m_numBanks{1};
+  int m_numPixels{12};
+  double m_xmin{300.0};
+  double m_xmax{16666.0};
+
+  std::string m_dmin{"0"};
+  std::string m_dmax{"0"};
+  std::string m_tmin{"0"};
+  std::string m_tmax{"0"};
+  std::string m_lambdamin{"0"};
+  std::string m_lambdamax{"0"};
+  std::string m_compressTolerance{"0"};
+  std::string m_compressWallClockTolerance{"0"};
+  std::string m_compressStartTime{"0"};
+  bool m_removePromptPulse{false};
+  bool m_preserveEvents{true};
+  bool m_useGroupAll{true};
+  bool m_useResamplex{true};
+};
+
+#endif /*ALIGNANDFOCUSPOWDERTEST_H_*/
diff --git a/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h b/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
index 9b3acdc7d144664e5bc749e19e5b37ee786f7bbb..2909e940538586410753704c12982c871852eaf4 100644
--- a/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
+++ b/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
@@ -45,8 +45,13 @@ public:
     mover.setPropertyValue("ComponentName", "detector1");
     // X = (16-192.0/2.0)*5.15/1000.0 = -0.412
     // Y = (95-192.0/2.0)*5.15/1000.0 = -0.00515
-    mover.setPropertyValue("X", "0.412");
-    mover.setPropertyValue("Y", "0.00515");
+    // mover.setPropertyValue("X", "0.412");
+    // mover.setPropertyValue("Y", "0.00515");
+
+    mover.setPropertyValue("X", "0.009425");
+    mover.setPropertyValue("Y", "0.002575");
+    mover.setPropertyValue("Z", "-0.8114");
+
     mover.execute();
 
     if (!correction.isInitialized())
diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in
index 2b7ffea2dc202a6f9363aaae9275fa890c8df5c3..c59b0561d220a28f391aa48bbd081b648b6db44a 100755
--- a/MantidPlot/make_package.rb.in
+++ b/MantidPlot/make_package.rb.in
@@ -339,7 +339,8 @@ system_python_extras = "/System/Library/Frameworks/Python.framework/Versions/2.7
 pip_site_packages = "/Library/Python/2.7/site-packages"
 directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports", "qtawesome", "qtpy",
                "certifi","tornado","markupsafe","matplotlib","mpl_toolkits", "jinja2","jsonschema","functools32",
-               "ptyprocess","CifFile","yaml","requests"]
+               "ptyprocess","CifFile","yaml","requests","networkx","PIL","dateutil","pytz",
+               "pywt","skimage"]
 directories.each do |directory|
   module_dir = "#{pip_site_packages}/#{directory}"
   if !File.exist?(module_dir)
@@ -397,7 +398,7 @@ h5py_patterns.each do |pattern|
   end
 end
 
-files = ["gnureadline.so","cycler.py","readline.py","pyparsing.py","mistune.py"]
+files = ["gnureadline.so","cycler.py","readline.py","pyparsing.py","mistune.py","decorator.py","kiwisolver.so","subprocess32.py"]
 files.each do |file|
   copyFile("#{pip_site_packages}/#{file}")
 end
diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp
index 4cb0fbb82362fa6d70866ae5f4ac133cb17402be..e52f2fbc8010174d8349784e20da5955dc164808 100644
--- a/MantidPlot/src/ApplicationWindow.cpp
+++ b/MantidPlot/src/ApplicationWindow.cpp
@@ -11647,7 +11647,11 @@ void ApplicationWindow::patchPaletteForLinux(QPalette &palette) const {
 
 bool ApplicationWindow::isUnityDesktop() const {
   return QString::fromLocal8Bit(qgetenv("XDG_SESSION_DESKTOP")) == "Unity" ||
-         QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")) == "Unity";
+         QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")) == "Unity" ||
+         QString::fromLocal8Bit(qgetenv("XDG_SESSION_DESKTOP")) ==
+             "ubuntu:GNOME" ||
+         QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")) ==
+             "ubuntu:GNOME";
 }
 
 void ApplicationWindow::setAppColors(const QColor &wc, const QColor &pc,
diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp
index e969a22b4632c3d20efc890826e53e79405f1e7e..e08d3d805207ac09dc9ea0703ebfdce58357a4f8 100644
--- a/MantidPlot/src/Graph.cpp
+++ b/MantidPlot/src/Graph.cpp
@@ -244,8 +244,7 @@ MultiLayer *Graph::multiLayer() {
 
 void Graph::deselectMarker() {
   selectedMarker = -1;
-  if (d_markers_selector)
-    delete d_markers_selector;
+  delete d_markers_selector;
 
   emit enableTextEditor(nullptr);
 
@@ -4564,8 +4563,7 @@ void Graph::setActiveTool(PlotToolInterface *tool) {
     return;
   }
 
-  if (d_active_tool)
-    delete d_active_tool;
+  delete d_active_tool;
 
   d_active_tool = tool;
 }
@@ -4577,21 +4575,17 @@ void Graph::disableTools() {
   if (drawLineActive())
     drawLine(false);
 
-  if (d_active_tool)
-    delete d_active_tool;
+  delete d_active_tool;
   d_active_tool = nullptr;
 
-  if (d_range_selector)
-    delete d_range_selector;
+  delete d_range_selector;
   d_range_selector = nullptr;
 }
 
 bool Graph::enableRangeSelectors(const QObject *status_target,
                                  const char *status_slot) {
-  if (d_range_selector) {
-    delete d_range_selector;
-    d_range_selector = nullptr;
-  }
+  delete d_range_selector;
+  d_range_selector = nullptr;
   d_range_selector = new RangeSelectorTool(this, status_target, status_slot);
   setActiveTool(d_range_selector);
   connect(d_range_selector, SIGNAL(changed()), this,
@@ -4848,14 +4842,10 @@ bool Graph::validCurvesDataSize() {
 
 Graph::~Graph() {
   setActiveTool(nullptr);
-  if (d_range_selector)
-    delete d_range_selector;
-  if (d_peak_fit_tool)
-    delete d_peak_fit_tool;
-  if (d_magnifier)
-    delete d_magnifier;
-  if (d_panner)
-    delete d_panner;
+  delete d_range_selector;
+  delete d_peak_fit_tool;
+  delete d_magnifier;
+  delete d_panner;
   delete titlePicker;
   delete scalePicker;
   delete cp;
@@ -5361,10 +5351,8 @@ void Graph::changeIntensity(bool bIntensityChanged) {
  * @param on :: boolean parameter to switch on zooming
  */
 void Graph::enablePanningMagnifier(bool on) {
-  if (d_magnifier)
-    delete d_magnifier;
-  if (d_panner)
-    delete d_panner;
+  delete d_magnifier;
+  delete d_panner;
 
   QwtPlotCanvas *cnvs = d_plot->canvas(); // canvas();
   if (on) {
@@ -5400,8 +5388,7 @@ bool Graph::isFixedAspectRatioEnabled() {
  */
 void Graph::enableFixedAspectRatio(bool on) {
 #if QWT_VERSION >= 0x050200
-  if (d_rescaler)
-    delete d_rescaler;
+  delete d_rescaler;
 
   QwtPlotCanvas *cnvs = d_plot->canvas();
   if (on) {
diff --git a/Testing/Data/SystemTest/INTER/INTERReductionTestRuns.nxs.md5 b/Testing/Data/SystemTest/INTER/INTERReductionTestRuns.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..fb8487afde95e4fc24b4adb384d6ab610e85c35c
--- /dev/null
+++ b/Testing/Data/SystemTest/INTER/INTERReductionTestRuns.nxs.md5
@@ -0,0 +1 @@
+e50c38cd8fb906ab71f1e6e93911d988
diff --git a/Testing/Data/SystemTest/WISH/input/11_4/WISH00019612.raw.md5 b/Testing/Data/SystemTest/WISH/input/11_4/WISH00019612.raw.md5
new file mode 100644
index 0000000000000000000000000000000000000000..8a7b42a5047089aa0a64a5840ec0637d3154f3b8
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/11_4/WISH00019612.raw.md5
@@ -0,0 +1 @@
+81e9d09c17c274f9c79252cdd73c0491
diff --git a/Testing/Data/SystemTest/WISH/input/11_4/WISH00019618.raw.md5 b/Testing/Data/SystemTest/WISH/input/11_4/WISH00019618.raw.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1ca467917012ab64944245f925797eb060e96760
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/11_4/WISH00019618.raw.md5
@@ -0,0 +1 @@
+9b8888478637a478d9563fe7060a8881
diff --git a/Testing/Data/SystemTest/WISH/input/18_1/WISH00040503.raw.md5 b/Testing/Data/SystemTest/WISH/input/18_1/WISH00040503.raw.md5
new file mode 100644
index 0000000000000000000000000000000000000000..0d713758f24e30dbad440464a19c2127999b52a6
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/18_1/WISH00040503.raw.md5
@@ -0,0 +1 @@
+4fdb9e8db88934f2acb4d4dd900da0b1
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_10_3_noends_10to10.cal.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_10_3_noends_10to10.cal.md5
deleted file mode 100644
index 5c1b0c2e9dbdf35d782f2ff7e4d764d22c85ebb2..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_10_3_noends_10to10.cal.md5
+++ /dev/null
@@ -1 +0,0 @@
-055d17177f5593f65066a35d61a7db2c
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_15_4_noends_10to10_dodgytube_removed_feb2016.cal.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_15_4_noends_10to10_dodgytube_removed_feb2016.cal.md5
new file mode 100644
index 0000000000000000000000000000000000000000..57f6caec5e3c1e74b278ecebf54fee192483bb30
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/Cal/WISH_cycle_15_4_noends_10to10_dodgytube_removed_feb2016.cal.md5
@@ -0,0 +1 @@
+98d61de6108b0298c12f7339e5729a4c
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-10foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-10foc.nxs.md5
deleted file mode 100644
index 2db9ed15d7d29be90bf84538d333b56998b8136d..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-10foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-a6bb6c3c8413e25f2e55189476b0205f
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-1foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-1foc.nxs.md5
deleted file mode 100644
index 4292e9aa75eead93017c148a86a72d99577dfeb7..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-1foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-a3a3932fb3429932d5c4eb5ad6dd50db
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-2foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-2foc.nxs.md5
deleted file mode 100644
index 30de28390184d73e4db13ceedf56f569aa64ff6f..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-2foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-265af81599660d239a7643a999222d95
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-3foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-3foc.nxs.md5
deleted file mode 100644
index 9952fc37b622e3add2cb71bb43e276547fd7a610..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-3foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-dfa2b3fee890f6530ea1071c3910f293
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-4foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-4foc.nxs.md5
deleted file mode 100644
index e71c1d7d48170eb881c647fec5b30f2290656418..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-4foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-3bc719616f727879c2be9e57433a3fe6
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-5foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-5foc.nxs.md5
deleted file mode 100644
index 9ce1643b3bad368f02ee197863e606cd4f4ecac3..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-5foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-37c393acc606b627ff7f8712f4b0c27b
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-6foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-6foc.nxs.md5
deleted file mode 100644
index 308fa0541c339912432e0e2340eb474f6ad76a75..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-6foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-81a2766ecb6e31db395ba84e495adc52
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-7foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-7foc.nxs.md5
deleted file mode 100644
index 950aa568e3c5d4f73d542a3fa841a8e5314c0f4b..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-7foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-158392b86a834dd39c27fba9dcc7a006
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-8foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-8foc.nxs.md5
deleted file mode 100644
index f82dc507147ec666a9f5f32d92af6a3fa7f1e69c..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-8foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-ffbb89ea154b576d3e96f899c297ad88
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-9foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-9foc.nxs.md5
deleted file mode 100644
index d3baa82f99f9e540df5dd206bc652e1ae6b3184c..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/WISHvana41865-9foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-decc7353a7dc895fdfe7f298a046c6ea
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-5foc-SF-S.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-5foc-SF-S.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..a08dc42650091a1b60ee5eb2e10a71333b196f42
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-5foc-SF-S.nxs.md5
@@ -0,0 +1 @@
+71831f8efeb8be3e0f5d3caa2e9eca89
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-6foc-SF-S.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-6foc-SF-S.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..a08dc42650091a1b60ee5eb2e10a71333b196f42
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst19618-6foc-SF-S.nxs.md5
@@ -0,0 +1 @@
+71831f8efeb8be3e0f5d3caa2e9eca89
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-10foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-10foc.nxs.md5
deleted file mode 100644
index e5364e50ed20ca7892db65932dc1ff1cbb97e28c..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-10foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-9b3f366c3f0597cdaf74c77fa3fd1c27
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-1foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-1foc.nxs.md5
deleted file mode 100644
index 8e9185681b28a6d1850f9c8a1df7409633a1ac85..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-1foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-f529a4e600134d3d116e65c33a078817
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-2foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-2foc.nxs.md5
deleted file mode 100644
index 696f25ffc7f85ce24a8c42102fd78c2c91574e7f..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-2foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-74ff004da8309bc26c251c69e24106a5
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-3foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-3foc.nxs.md5
deleted file mode 100644
index ab8659ea511243cf9014f57876cbb9ef3a3e20a5..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-3foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-e3ff38a26c672fde75b1ed7de99d19a6
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-4foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-4foc.nxs.md5
deleted file mode 100644
index cd6d92a8f2051698a16a7a624de63ad78dee8fa2..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-4foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-678059385510dc8d1e45b9565f2b7208
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-5foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-5foc.nxs.md5
deleted file mode 100644
index 53913d47efa9909651c730101ffd763236c2e406..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-5foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-a8f292edf6640bbb7c2eac34ff44f9bd
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-6foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-6foc.nxs.md5
deleted file mode 100644
index ae70766609d29061035e23a7df1311b3f2df3ef2..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-6foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-61fad722828e1620be2be59b6eddc66b
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-7foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-7foc.nxs.md5
deleted file mode 100644
index 7d6e36d5a90f551233842ec5379c2aabe28fd8ed..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-7foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-f45ee059905b380093748835d9cd90d0
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-8foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-8foc.nxs.md5
deleted file mode 100644
index cfbc1794ee484359353490ecb0446f1f676d1bcc..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-8foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-f7f9eb1001e7e7260b067f9ba901d949
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-9foc.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-9foc.nxs.md5
deleted file mode 100644
index 4eae207a8b259d775b5dc762f3be0b4b4650138a..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/Cal/emptyinst38581-9foc.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-3d8675ca48aa242e3c5a02b1f85624ae
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/vana19612-5foc-SF-SS.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/vana19612-5foc-SF-SS.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..cf5800e7b756d10574b57b78fe76ed36fb4b8518
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/Cal/vana19612-5foc-SF-SS.nxs.md5
@@ -0,0 +1 @@
+e8fea832144b67b4911cd00e5abb27e8
diff --git a/Testing/Data/SystemTest/WISH/input/Cal/vana19612-6foc-SF-SS.nxs.md5 b/Testing/Data/SystemTest/WISH/input/Cal/vana19612-6foc-SF-SS.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..d81d1572114947b481305f83bb2e5d71ae0aaf0b
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH/input/Cal/vana19612-6foc-SF-SS.nxs.md5
@@ -0,0 +1 @@
+dafd63eef31cf573fcf643614ce5808d
diff --git a/Testing/Data/SystemTest/WISH/input/WISH00041870.nxs.md5 b/Testing/Data/SystemTest/WISH/input/WISH00041870.nxs.md5
deleted file mode 100644
index cf41a2b053048fc0c247daf42e65c2d92fb5498b..0000000000000000000000000000000000000000
--- a/Testing/Data/SystemTest/WISH/input/WISH00041870.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-b8ce8bb291d797f10fcc53b1faebd284
diff --git a/Testing/Data/UnitTest/REFL_flood_cor_test.nxs.md5 b/Testing/Data/UnitTest/REFL_flood_cor_test.nxs.md5
index 10b140c8397b0104834495678f6a4642c8548fd0..0dd4a86b5636a177dff67122fb9ff9a7a8959b4c 100644
--- a/Testing/Data/UnitTest/REFL_flood_cor_test.nxs.md5
+++ b/Testing/Data/UnitTest/REFL_flood_cor_test.nxs.md5
@@ -1 +1 @@
-ea6c6ca01b66fc8e24934104cdc1c47d
+fbd34ac5030a36b26ca424b819613c38
diff --git a/Testing/Data/UnitTest/SI-4200-610.stl.md5 b/Testing/Data/UnitTest/SI-4200-610.stl.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5993cad31adf12304b2936cf03d0d0f2617f288b
--- /dev/null
+++ b/Testing/Data/UnitTest/SI-4200-610.stl.md5
@@ -0,0 +1 @@
+af483b9877fd265539a2a0df6c4b5513
diff --git a/Testing/Data/UnitTest/calibrated.peaks.md5 b/Testing/Data/UnitTest/calibrated.peaks.md5
new file mode 100644
index 0000000000000000000000000000000000000000..15c9141d44d4534a56f7cf5bcb18438d4a7f3545
--- /dev/null
+++ b/Testing/Data/UnitTest/calibrated.peaks.md5
@@ -0,0 +1 @@
+baeef5e84e6c12ef0e8ad19d9e05fffb
diff --git a/Testing/PerformanceTests/make_report.py b/Testing/PerformanceTests/make_report.py
index 99332b10bba0ceeb96ad9beb051ae99c90ad50e4..8c766e84b23dbce0b678bdf616037b00d7ba65a9 100755
--- a/Testing/PerformanceTests/make_report.py
+++ b/Testing/PerformanceTests/make_report.py
@@ -64,14 +64,18 @@ if __name__ == "__main__":
                         default=["./MantidSystemTests.db"],
                         help='Required: Path to the SQL database file(s).')
 
+    parser.add_argument('--plotting', dest='plotting',
+                        default="plotly",
+                        help='Plotting toolkit to generate the plots. Options=["plotly", "matplotlib"]')
+
     args = parser.parse_args()
 
-    # Import the manager definition
-    try:
+    if args.plotting == 'plotly':
         import analysis
-    except:
-        # plotly not available, use matplotlib fallback
+    elif args.plotting == 'matplotlib':
         import analysis_mpl as analysis
+    else:
+        raise RuntimeError("Unknown plotting toolkit '{}'".format(args.plotting))
 
     import sqlresults
 
diff --git a/Testing/SystemTests/lib/systemtests/systemtesting.py b/Testing/SystemTests/lib/systemtests/systemtesting.py
index 9d5035b6b79929641f8cb416af28dadc454eba6a..024eed7e1b8cc39ec43c09acd93f2570a2d43c09 100644
--- a/Testing/SystemTests/lib/systemtests/systemtesting.py
+++ b/Testing/SystemTests/lib/systemtests/systemtesting.py
@@ -12,6 +12,12 @@ or by importing them into MantidPlot.
 File change history is stored at: <https://github.com/mantidproject/systemtests>.
 """
 from __future__ import (absolute_import, division, print_function)
+# == for testing conda build of mantid-framework ==========
+import os
+if os.environ.get('MANTID_FRAMEWORK_CONDA_SYSTEMTEST'):
+    # conda build of mantid-framework sometimes require importing matplotlib before mantid
+    import matplotlib
+# =========================================================
 from six import PY3
 import datetime
 import difflib
@@ -22,7 +28,6 @@ from mantid.api import FrameworkManager
 from mantid.kernel import config, MemoryStats
 from mantid.simpleapi import AlgorithmManager, Load, SaveNexus
 import numpy
-import os
 import platform
 import re
 import shutil
diff --git a/Testing/SystemTests/scripts/InstallerTests.py b/Testing/SystemTests/scripts/InstallerTests.py
index 5a75afbc1bf8fd36401b278ec55b1baca3156e25..1e4a1547f3b0a21fc0c59e6f309ef141a1afaf7d 100644
--- a/Testing/SystemTests/scripts/InstallerTests.py
+++ b/Testing/SystemTests/scripts/InstallerTests.py
@@ -33,7 +33,7 @@ parser.add_argument('--archivesearch', dest='archivesearch', action='store_true'
 parser.add_argument('--exclude-in-pull-requests', dest="exclude_in_pr_builds",action="store_true",
                     help="Skip tests that are not run in pull request builds")
 log_levels = ['error', 'warning', 'notice', 'information', 'debug']
-parser.add_argument('-l', dest='log_level', metavar='level', default='notice',
+parser.add_argument('-l', dest='log_level', metavar='level', default='information',
                     choices=log_levels, help='Log level '+str(log_levels))
 options = parser.parse_args()
 
@@ -54,32 +54,35 @@ if options.doInstall:
     log("Installing package '%s'" % installer.mantidInstaller)
     try:
         installer.install()
-        log("Application path " + installer.mantidPlotPath)
+        log("Application path: %r" % installer.mantidPlotPath)
         installer.no_uninstall = False
     except Exception as err:
         scriptfailure("Installing failed. "+str(err))
 else:
     installer.no_uninstall = True
 
-try:
-    # Keep hold of the version that was run
-    version = run(installer.mantidPlotPath + ' -v')
-    version_tested = open(os.path.join(output_dir,'version_tested.log'),'w')
-    if version and len(version) > 0:
-        version_tested.write(version)
-    version_tested.close()
-except Exception as err:
-    scriptfailure('Version test failed: '+str(err), installer)
+# conda mantid-framework does not have mantid plot. skip these
+if not os.environ.get('MANTID_FRAMEWORK_CONDA_SYSTEMTEST'):
+    try:
+        # Keep hold of the version that was run
+        version = run(installer.mantidPlotPath + ' -v')
+        version_tested = open(os.path.join(output_dir,'version_tested.log'),'w')
+        if version and len(version) > 0:
+            version_tested.write(version)
+        version_tested.close()
+    except Exception as err:
+        scriptfailure('Version test failed: '+str(err), installer)
+
+    try:
+        # Now get the revision number/git commit ID (remove the leading 'g' that isn't part of it)
+        revision = run(installer.mantidPlotPath + ' -r').lstrip('g')
+        revision_tested = open(os.path.join(output_dir, 'revision_tested.log'), 'w')
+        if revision and len(version) > 0:
+            revision_tested.write(revision)
+        revision_tested.close()
+    except Exception as err:
+        scriptfailure('Revision test failed: '+str(err), installer)
 
-try:
-    # Now get the revision number/git commit ID (remove the leading 'g' that isn't part of it)
-    revision = run(installer.mantidPlotPath + ' -r').lstrip('g')
-    revision_tested = open(os.path.join(output_dir, 'revision_tested.log'), 'w')
-    if revision and len(version) > 0:
-        revision_tested.write(revision)
-    revision_tested.close()
-except Exception as err:
-    scriptfailure('Revision test failed: '+str(err), installer)
 
 log("Running system tests. Log files are: '%s' and '%s'" % (testRunLogPath,testRunErrPath))
 try:
diff --git a/Testing/SystemTests/scripts/install_conda_mantid.sh b/Testing/SystemTests/scripts/install_conda_mantid.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3c7c974e248c26a883f9a5550c1639b9302a0782
--- /dev/null
+++ b/Testing/SystemTests/scripts/install_conda_mantid.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# * install miniconda2 in $HOME/jenkins-systemtests-opt/miniconda2
+# * create env "mantid"
+# * install mantid-framework from "jenkins" channel
+
+wget --no-verbose http://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh
+
+unset PYTHONPATH
+CONDA_PREFIX=$HOME/jenkins-systemtests-opt/miniconda2
+bash miniconda.sh -b -p $CONDA_PREFIX
+export PATH=$CONDA_PREFIX/bin:$PATH
+conda config --add channels conda-forge
+conda config --add channels mantid
+conda config --set always_yes true
+
+## anaconda client
+conda install -n root --yes --quiet anaconda-client
+
+## upload conda pkg to mantid jenkins channel
+anaconda -t $ANACONDA_ACCESS_KEY upload -l jenkins --force $1
+
+## Establish mantid environment
+conda create --yes --quiet --name mantid python=2.7.14
+## install
+source activate mantid
+pwd
+which conda
+
+conda env list
+cat ~/.condarc
+conda remove mantid-framework
+conda search mantid-framework
+conda install --yes -c mantid/label/jenkins mantid-framework
+conda list
+which python
+python -c "import numpy"
+python -c "import matplotlib; import mantid"
diff --git a/Testing/SystemTests/scripts/mantidinstaller.py b/Testing/SystemTests/scripts/mantidinstaller.py
index eaf746dc9c567316eca48f861a2c4d4b604a0f4d..708c1ce8374a0fe148e0a463f2d5173b21a66a58 100644
--- a/Testing/SystemTests/scripts/mantidinstaller.py
+++ b/Testing/SystemTests/scripts/mantidinstaller.py
@@ -75,6 +75,11 @@ def get_installer(package_dir, do_install=True):
         @param package_dir :: The directory to search for packages
         @param do_install :: True if installation is to be performed
     """
+    # == for testing conda build of mantid-framework ==========
+    import os
+    if os.environ.get('MANTID_FRAMEWORK_CONDA_SYSTEMTEST'):
+        return CondaInstaller(package_dir, do_install)
+    # =========================================================
     system = platform.system()
     if system == 'Windows':
         return NSISInstaller(package_dir, do_install)
@@ -295,6 +300,33 @@ class DMGInstaller(MantidInstaller):
     def do_uninstall(self):
         run('sudo rm -fr /Applications/MantidPlot.app/')
 
+
+class CondaInstaller(MantidInstaller):
+
+    python_args = "" # not mantidpython. just normal python
+
+    def __init__(self, package_dir, do_install=True):
+        filepattern = "mantid-framework*.tar.bz2"
+        MantidInstaller.__init__(self, package_dir, filepattern, do_install)
+        package = os.path.basename(self.mantidInstaller)
+        self.conda_prefix = os.path.expanduser('~/jenkins-systemtests-opt/miniconda2')
+        self.conda_mantid_env_prefix = install_prefix = os.path.join(self.conda_prefix, 'envs', 'mantid')
+        self.mantidPlotPath = None # conda mantid-framework does not include mantidplot
+        self.python_cmd = install_prefix + '/bin/python'
+
+    def do_install(self):
+        """Uses gdebi to run the install
+        """
+        thisdir = os.path.dirname(__file__)
+        script = os.path.join(thisdir, 'install_conda_mantid.sh')
+        run('%s %s' % (script, self.mantidInstaller))
+
+    def do_uninstall(self):
+        """Removes the debian package
+        """
+        # run('rm -rf %s' % self.conda_mantid_env_prefix)
+
+
 #-------------------------------------------------------------------------------
 # Main
 #-------------------------------------------------------------------------------
diff --git a/Testing/SystemTests/tests/analysis/GUIStartupTest.py b/Testing/SystemTests/tests/analysis/GUIStartupTest.py
index 8b0eea635a971f9a447d6b01ceebb6820cf165df..fb2e24e8e261ae735fc3448106a7fb60825b56cf 100644
--- a/Testing/SystemTests/tests/analysis/GUIStartupTest.py
+++ b/Testing/SystemTests/tests/analysis/GUIStartupTest.py
@@ -58,7 +58,7 @@ class GUIStartupTest(systemtesting.MantidSystemTest):
         # good startup
         p = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
         out, err = p.communicate()
-        self.assertEquals(out, b'Hello Mantid\n')
+        self.assertTrue(b'Hello Mantid\n' in out)
 
         # failing script
         with open(self.script, 'a') as f:
diff --git a/Testing/SystemTests/tests/analysis/INTERReductionTest.py b/Testing/SystemTests/tests/analysis/INTERReductionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..344bcd61d7e7c08e7d58a2516a76760023f8618f
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/INTERReductionTest.py
@@ -0,0 +1,350 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+"""
+System Test for ISIS Reflectometry reduction
+Adapted from scripts provided by Max Skoda.
+"""
+from __future__ import (print_function)
+import systemtesting
+from mantid.simpleapi import *
+from mantid import ConfigService
+
+
+class INTERReductionTest(systemtesting.MantidSystemTest):
+    '''
+    Mantid Test Script for INTER:
+
+    Tests:
+    1. Event data time-slicing
+    2. "Quickref" - used when the autoreduction unwantedly sums runs together.
+    3. Scripted fitting of reduced data for NRW
+    4. Linear detector reduction
+    '''
+    # Note: you may find the regenerate functions useful.
+
+    event_run_numbers = [45222]
+    run_numbers = [45222, 45223, 45224, 44984, 44985, 44990, 44991]
+    first_transmission_run_names = ['45226', '44988', '44986']
+    second_transmission_run_names = ['45227', '44989', '44987']
+    transmission_workspace_names = ['TRANS', 'TRANS_SM', 'TRANS_NoSM']
+    runs_file = 'INTERReductionTestRuns.nxs'
+    runs_workspace = 'Runs'
+    reference_result_file = 'INTERReductionResult.nxs'
+    result_workspace = 'Result'
+    expected_fit_params={
+        'Name': ['Theta', 'ScaleFactor', 'AirSLD', 'BulkSLD', 'Roughness', 'BackGround', 'Resolution',
+                 'SLD_Layer0', 'd_Layer0', 'Rough_Layer0', 'Cost function value'],
+        'Value': [2.2999999999999998, 1, 0, 0, 0, 7.9488100000033575e-06, 5, 8.2865399998548345e-07,
+                  31.315399998680391, 0, 0.90910656437440196],
+        'Error': [0, 0, 0, 0, 0, 1.1949723340559929e-07, 0, 2.2338118077681473e-08, 0.9921668942754267, 0, 0]}
+    expected_fit_covariance={
+        'Name': ['BackGround', 'SLD_Layer0', 'd_Layer0'],
+        'BackGround':[100, -64.519943050096259, 60.825620358818924],
+        'SLD_Layer0':[-64.519943050096032, 100, -96.330851077988683],
+        'd_Layer0': [60.825555558936458, -96.33084065170361, 100]}
+
+    def __init__(self):
+        super(INTERReductionTest, self).__init__()
+        self.tolerance = 1e-6
+
+    def requiredFiles(self):
+        return [self.reference_result_file, self.runs_file]
+
+    def validate(self):
+        return (self.result_workspace, self.reference_result_file)
+
+    def runTest(self):
+        setupInstrument()
+        Load(self.runs_file, OutputWorkspace=self.runs_workspace)
+        workspaces_to_exclude_from_result = AnalysisDataService.Instance().getObjectNames()
+        createTransmissionWorkspaces(self.first_transmission_run_names,
+                                     self.second_transmission_run_names,
+                                     self.transmission_workspace_names)
+
+        testEventDataTimeSlicing(self.event_run_numbers)
+        testReductionOfThreeAngleFringedSolidLiquidExample([45222, 45223, 45224])
+        testReductionOfTwoAngleAirLiquidExample([44984, 44985])
+        testFittingOfReducedData(44990, 44991, self.expected_fit_params, self.expected_fit_covariance)
+
+        removeWorkspaces(workspaces_to_exclude_from_result)
+        GroupWorkspaces(InputWorkspaces=AnalysisDataService.Instance().getObjectNames(),
+                        OutputWorkspace=self.result_workspace)
+        mtd[self.result_workspace].sortByName()
+
+    @staticmethod
+    def regenerateRunsFile():
+        setupInstrument()
+        regenerateRunsFile(INTERReductionTest.first_transmission_run_names +
+                           INTERReductionTest.second_transmission_run_names,
+                           INTERReductionTest.run_numbers,
+                           INTERReductionTest.event_run_numbers)
+
+    @staticmethod
+    def regenerateReferenceFileByReducing():
+        setupInstrument()
+        test = INTERReductionTest()
+        test.runTest()
+        SaveNexus(InputWorkspace=INTERReductionTest.result_workspace,
+                  Filename=INTERReductionTest.reference_result_file)
+
+    @staticmethod
+    def regenerateReferenceFileFromDirectory(reference_file_directory):
+        setupInstrument()
+        regenerateReferenceFile(reference_file_directory, INTERReductionTest.reference_result_file)
+
+
+def setupInstrument():
+    configI = ConfigService.Instance()
+    configI.setString("default.instrument", "INTER")
+    configI.setString("default.facility", "ISIS")
+
+
+def removeWorkspaces(to_remove):
+    for workspace_name in to_remove:
+        AnalysisDataService.Instance().remove(workspace_name)
+
+
+def workspaceName(file_path):
+    return os.path.splitext(os.path.basename(file_path))[0]
+
+
+def regenerateReferenceFile(reference_file_directory, output_filename):
+    '''Generate the reference file from a given folder of output workspaces'''
+    files = os.listdir(reference_file_directory)
+    workspace_names = []
+    for file in files:
+        workspace_name = WorkspaceName(file)
+        Load(file, OutputWorkspace=workspace_name)
+        workspace_names.append(workspace_name)
+
+    output_workspace_name = 'Output'
+    GroupWorkspaces(InputWorkspaces=workspace_names, OutputWorkspace=output_workspace_name)
+    mtd[output_workspace_name].sortByName()
+    SaveNexus(InputWorkspace=output_workspace_name, Filename=output_filename)
+
+
+def regenerateRunsFile(transmission_run_names, run_numbers, event_run_numbers):
+    '''Generate the test input file from a range of run numbers and transmission runs.'''
+    # Load transmission runs
+    for run in transmission_run_names:
+        Load('{}.raw'.format(run), OutputWorkspace=run)
+    # Load raw run files
+    run_names = [str(run_number)+'.raw' for run_number in run_numbers]
+    for run_name in run_names:
+        Load(run_name, OutputWorkspace=run_name)
+    # Load event workspaces
+    event_run_names = [str(event_run_number) for event_run_number in event_run_numbers]
+    for event_run_name in event_run_names:
+        LoadEventNexus(event_run_name, OutputWorkspace=event_run_name, LoadMonitors=True)
+    event_monitor_names = [str(run_number)+'_monitors' for run_number in event_run_numbers]
+    # Group and save
+    GroupWorkspaces(InputWorkspaces=run_names + transmission_run_names + event_run_names +
+                    event_monitor_names,
+                    OutputWorkspace='Input')
+    SaveNexus(InputWorkspace='Input', Filename='INTERReductionTestRuns.nxs')
+
+
+def createTransmissionWorkspaces(runs1, runs2, output_names):
+    '''Create a transmission workspace for each pair of input runs with the given output names'''
+    for run1, run2, name in zip(runs1, runs2, output_names):
+        CreateTransmissionWorkspaceAuto(
+            FirstTransmissionRun=run1,
+            SecondTransmissionRun=run2,
+            OutputWorkspace=name,
+            StartOverlap=10,
+            EndOverlap=12)
+        # Delete debug workspaces
+        DeleteWorkspace('TRANS_LAM_'+run1)
+        DeleteWorkspace('TRANS_LAM_'+run2)
+
+
+def eventRef(run_number, angle, start=0, stop=0, DB='TRANS'):
+    '''Perform reflectometry reduction on a slice of the given run for the given
+    start/stop times'''
+    # Filter the input workspace by the given start/stop time (or end time
+    # if stop time is not given)
+    run_name=str(run_number)
+    run_workspace=mtd[run_name]
+    if stop==0:
+        stoptime=run_workspace.getRun().getLogData('duration').value
+    else:
+        stoptime=stop
+    filter_ws_name=run_name+'_filter'
+    FilterByTime(InputWorkspace=run_name, OutputWorkspace=filter_ws_name, StartTime=start, StopTime=stoptime)
+    # Calculate the fraction of proton charge in this slice
+    filter_workspace=mtd[filter_ws_name]
+    slice_proton_charge = filter_workspace.getRun().getLogData('gd_prtn_chrg').value
+    total_proton_charge = run_workspace.getRun().getLogData('gd_prtn_chrg').value
+    fraction = slice_proton_charge/total_proton_charge
+    duration = filter_workspace.getRun().getLogData('duration').value
+    print('Fraction:', fraction)
+    print('Slice:', slice_proton_charge)
+    print('Duration:', duration)
+    # Scale monitors by proton charge and add them to the slice workspace
+    Scale(InputWorkspace=run_name+'_monitors', Factor=fraction, OutputWorkspace='mon_slice')
+    Rebin(InputWorkspace='mon_slice', OutputWorkspace='mon_rebin', Params='0, 100, 100000', PreserveEvents=False)
+    slice_name = str(run_number) + '_' + str(start) + '_' + str(stop)
+    Rebin(InputWorkspace=filter_ws_name, OutputWorkspace=slice_name, Params='0, 100, 100000', PreserveEvents=False)
+    AppendSpectra(InputWorkspace1='mon_rebin', InputWorkspace2=slice_name,
+                  OutputWorkspace=slice_name, MergeLogs=False)
+    # Reduce this slice
+    ReflectometryReductionOneAuto(InputWorkspace=slice_name, FirstTransmissionRun=DB,
+                                  OutputWorkspaceBinned=slice_name+'_ref_binned',
+                                  OutputWorkspace=slice_name+'_ref',
+                                  OutputWorkspaceWavelength=slice_name+'_lam', Debug=True)
+    # Delete interim workspaces
+    DeleteWorkspace(slice_name+'_lam')
+    DeleteWorkspace(slice_name)
+    DeleteWorkspace(slice_name+'_ref')
+    DeleteWorkspace('mon_slice')
+    DeleteWorkspace('mon_rebin')
+
+
+def stitchedWorkspaceName(run1_number, run2_number):
+    '''Gets the name of the stitched workspace based on the two input workspace names'''
+    run1_name=str(run1_number)
+    run2_name=str(run2_number)
+    run2_short_name=run2_name[-2:]
+    return run1_name+'_'+run2_short_name
+
+
+def quickRef(run_numbers=[], trans_workspace_names=[], angles=[]):
+    '''Perform reflectometry reduction on each input run, and stitch the
+    reduced workspaces together'''
+    reduced_runs=''
+    for run_index in range(len(run_numbers)):
+        # Set up the reduction properties
+        run_name=str(run_numbers[run_index])
+        properties = {'InputWorkspace': run_name+'.raw',
+                      'FirstTransmissionRun': str(trans_workspace_names[run_index]),
+                      'OutputWorkspaceBinned': run_name+'_IvsQ_binned',
+                      'OutputWorkspace': run_name+'_IvsQ',
+                      'OutputWorkspaceWavelength': run_name+'_IvsLam',
+                      'Debug':True}
+        # Set ThetaIn if the angles are given
+        if angles:
+            theta=angles[run_index]
+            properties['ThetaIn']=theta
+            # Special case to set WavelengthMin for a specific angle
+            if theta == 0.8:
+                properties['WavelengthMin']=2.6
+        # Do the reduction
+        ReflectometryReductionOneAuto(**properties)
+        reduced_runs=reduced_runs+run_name+'_IvsQ_binned'
+        if run_index < len(run_numbers)-1:
+            reduced_runs=reduced_runs+','
+    # Stitch the results
+    first_run_name=str(run_numbers[0])
+    dqq = NRCalculateSlitResolution(Workspace=first_run_name+'_IvsQ')
+    stitched_name=stitchedWorkspaceName(run_numbers[0], run_numbers[-1])
+    Stitch1DMany(InputWorkspaces=reduced_runs, OutputWorkspace=stitched_name, Params='-'+str(dqq), ScaleRHSWorkspace=1)
+
+
+def twoAngleFit(workspace_name, scalefactor, expected_fit_params, expected_fit_covariance):
+    '''Perform a fit on the given workspace and compare to the given results'''
+    # Scale and fit
+    Scale(InputWorkspace=workspace_name, OutputWorkspace=workspace_name+'_scaled', Factor=(1.0/scalefactor))
+    function_name='name=ReflectivityMulf, nlayer=1, Theta=2.3, ScaleFactor=1, AirSLD=0, BulkSLD=0, Roughness=0, BackGround=6.8e-06,'\
+        'Resolution=5.0, SLD_Layer0=1.0e-6, d_Layer0=20.0, Rough_Layer0=0.0, constraints=(0<SLD_Layer0, 0<d_Layer0),'\
+        'ties=(Theta=2.3, AirSLD=0, BulkSLD=0, Resolution=5.0, ScaleFactor=1.0, Roughness=0, Rough_Layer0=0)'
+    Fit(Function=function_name,
+        InputWorkspace=workspace_name+'_scaled', IgnoreInvalidData='1',
+        Output=workspace_name+'_fit', OutputCompositeMembers='1', ConvolveMembers='1')
+    # Get output tables
+    params_table=mtd[workspace_name+'_fit_Parameters']
+    covariance_table=mtd[workspace_name+'_fit_NormalisedCovarianceMatrix']
+    # Print output info
+    sld=round(params_table.cell(7, 1), 9)
+    thick=round(params_table.cell(8, 1), 2)
+    dNb=sld*thick
+    print('dNb ', dNb)
+    print('SLD ', sld)
+    print('Thick ', thick)
+    print('-----------')
+    # Annoyingly, fitting/gsl seems unstable across different platforms so the results don't match
+    # accurately. To get around this remove the offending workspaces from the reference and check
+    # manually here instead with a more generous tolerance. This isn't ideal but should be enough.
+    tolerance=1e-2
+    compareFitResults(params_table.toDict(), expected_fit_params, tolerance)
+    compareFitResults(covariance_table.toDict(), expected_fit_covariance, tolerance)
+    removeWorkspaces([workspace_name+'_fit_Parameters', workspace_name+'_fit_NormalisedCovarianceMatrix'])
+
+
+def compareFitResults(results_dict, reference_dict, tolerance):
+    '''Compare the fit results to the reference. The output table workspaces from the fit
+    should be converted to dicts before calling this function'''
+    for key in reference_dict:
+        if key == 'Name':
+            continue
+
+        if key not in results_dict:
+            raise ValueError("The column {0} was not found in the fit output table".format(key))
+
+        reference_values = reference_dict[key]
+        values_fitted = results_dict[key]
+        if len(values_fitted) != len(reference_values):
+            raise ValueError("The values fitted and the reference values must be provided as lists (with the same "
+                             "number of elements).\nGot actual (length {0}) vs reference (length {1}):\n{2}\n{3}".
+                             format(len(values_fitted), len(reference_values), values_fitted, reference_values))
+
+        for index, (value, expected) in enumerate(zip(values_fitted, reference_values)):
+            if abs(value - expected) > tolerance:
+                logger.error("For the parameter with index {0}, the value found '{1}' differs from "
+                             "reference '{2}' by more than required tolerance '{3}'".
+                             format(index, value, expected, tolerance))
+                logger.error("These were the values found:         {0}".
+                             format(values_fitted))
+                raise RuntimeError("Some results were not as accurate as expected. Please check the log "
+                                   "messages for details")
+
+
+def generateTimeSlices(run_number):
+    '''Generate 60 second time slices of the given run, and perform reflectometry
+    reduction on each slice'''
+    for slice_index in range(5):
+        start=slice_index*60
+        stop=(slice_index+1)*60
+        eventRef(run_number, 0.5, start, stop, DB='TRANS')
+
+
+def testEventDataTimeSlicing(event_run_numbers):
+    for run_number in event_run_numbers:
+        generateTimeSlices(run_number)
+
+
+def testReductionOfThreeAngleFringedSolidLiquidExample(run_numbers):
+    quickRef(run_numbers,['TRANS','TRANS','TRANS'])
+
+
+def testReductionOfTwoAngleAirLiquidExample(run_numbers):
+    quickRef(run_numbers,['TRANS_SM','TRANS_noSM'], angles=[0.8, 2.3])
+
+
+def testFittingOfReducedData(run1_number, run2_number, expected_fit_params, expected_fit_covariance):
+    #D2O run:
+    CloneWorkspace(InputWorkspace='44984_85', OutputWorkspace='D2O_IvsQ_binned')
+    #fit d2o to get scalefactor
+    function_name='name=ReflectivityMulf, nlayer=0, Theta=2.3, ScaleFactor=1.0, AirSLD=0, BulkSLD=6.35e-6, Roughness=2.5,'\
+        'BackGround=3.0776e-06, Resolution=5.0, ties=(Theta=2.3, AirSLD=0, BulkSLD=6.35e-6, Resolution=5.0, Roughness=2.5)'
+    Fit(Function=function_name,
+        InputWorkspace='D2O_IvsQ_binned', IgnoreInvalidData='1', Minimizer='Simplex', Output='D2O_fit',
+        OutputCompositeMembers='1', ConvolveMembers='1', StartX='0.0015', EndX='0.3359')
+    scalefactor=round(mtd['D2O_fit_Parameters'].cell(1, 1), 3)
+    #Create reduced workspace for test:
+    quickRef([run1_number, run2_number],['TRANS_SM','TRANS_noSM'], angles=[0.8, 2.3])
+    #Test fitting of the result:
+    print('run ', str(run1_number))
+    stitched_name=stitchedWorkspaceName(run1_number, run2_number)
+    twoAngleFit(stitched_name, scalefactor, expected_fit_params, expected_fit_covariance)
+
+
+# If you want to re-run the test and save the result as a reference...
+#   INTERReductionTest.regenerateReferenceFileByReducing()
+
+# or
+# If you have workspaces in a folder to use as a reference...
+#   INTERReductionTest.regenerateReferenceFileFromDirectory("Path/To/Folder")
diff --git a/Testing/SystemTests/tests/analysis/ISIS_WISHPowderReductionTest.py b/Testing/SystemTests/tests/analysis/ISIS_WISHPowderReductionTest.py
index ad9bf484c4add564a0beef9d0349ed4516b950cc..5a4013f52160d35ecd41333b4ad81cb64d352f72 100644
--- a/Testing/SystemTests/tests/analysis/ISIS_WISHPowderReductionTest.py
+++ b/Testing/SystemTests/tests/analysis/ISIS_WISHPowderReductionTest.py
@@ -1,5 +1,5 @@
 from systemtesting import MantidSystemTest
-from wish.reduce import Wish_Run
+from wish.reduce import Wish
 
 from mantid import config
 import mantid.simpleapi as mantid
@@ -18,7 +18,6 @@ output_folder_name = "output"
 # Relative to input folder
 calibration_folder_name = "Cal"
 
-
 # Generate paths for the tests
 # This implies DIRS[0] is the system test data folder
 working_dir = os.path.join(DIRS[0], working_folder_name)
@@ -27,42 +26,106 @@ input_dir = os.path.join(working_dir, input_folder_name)
 output_dir = os.path.join(working_dir, output_folder_name)
 
 calibration_dir = os.path.join(input_dir, calibration_folder_name)
+# just test 5 and 6 to save time as process is the same for all other pairs
+panels = [5, 6]
+linked_panels = {
+    1: 10,
+    2: 9,
+    3: 8,
+    4: 7,
+    5: 6
+}
 
 
 class WISHPowderReductionTest(MantidSystemTest):
     # still missing required files check with ./systemtest -R PowderReduction --showskipped
     def requiredFiles(self):
-        input_files = ["WISHvana41865-1foc.nxs", "WISHvana41865-2foc.nxs", "WISHvana41865-3foc.nxs",
-                       "WISHvana41865-4foc.nxs", "WISHvana41865-5foc.nxs", "WISHvana41865-6foc.nxs",
-                       "WISHvana41865-7foc.nxs", "WISHvana41865-8foc.nxs", "WISHvana41865-9foc.nxs",
-                       "WISHvana41865-10foc.nxs", "emptyinst38581-1foc.nxs", "emptyinst38581-2foc.nxs",
-                       "emptyinst38581-3foc.nxs", "emptyinst38581-4foc.nxs", "emptyinst38581-5foc.nxs",
-                       "emptyinst38581-6foc.nxs", "emptyinst38581-7foc.nxs", "emptyinst38581-8foc.nxs",
-                       "emptyinst38581-9foc.nxs", "emptyinst38581-10foc.nxs"]
+        input_files = ["vana19612-{}foc-SF-SS.nxs".format(panel) for panel in panels]
+
+        input_files = [os.path.join(calibration_dir, files) for files in input_files]
+        return input_files
+
+    def cleanup(self):
+        if os.path.isdir(output_dir):
+            shutil.rmtree(output_dir)
+
+    def runTest(self):
+        os.makedirs(output_dir)
+        wish_test = Wish(calibration_dir, output_dir, True, input_dir + "/", False)
+        runs = [40503]
+
+        wish_test.reduce(runs, panels)
+        self.clearWorkspaces()
+
+    def validate(self):
+        validation_files = []
+        for panel in [x for x in panels if x < 6]:
+            validation_files = validation_files + \
+                               ["w40503-{0}_{1}foc".format(panel, linked_panels.get(panel)),
+                                "WISH40503-{0}_{1}no_absorb_raw.nxs".format(panel, linked_panels.get(panel))]
+        return validation_files
+
+    def clearWorkspaces(self):
+        deletews = ["w40503-{}foc".format(panel) for panel in panels]
+        for ws in deletews:
+            mantid.DeleteWorkspace(ws)
+            mantid.DeleteWorkspace(ws + "-d")
+
+
+class WISHPowderReductionNoAbsorptionTest(MantidSystemTest):
+    # still missing required files check with ./systemtest -R PowderReduction --showskipped
+    def requiredFiles(self):
+        input_files = ["vana19612-{}foc-SF-SS.nxs".format(panel) for panel in panels]
 
         input_files = [os.path.join(calibration_dir, files) for files in input_files]
         return input_files
 
     def cleanup(self):
-        shutil.rmtree(output_dir)
+        if os.path.isdir(output_dir):
+            shutil.rmtree(output_dir)
 
     def runTest(self):
         os.makedirs(output_dir)
-        Wish_Run("__main__", calibration_dir+"/", input_dir, output_dir, True)
+        wish_test = Wish(calibration_dir, output_dir, True, input_dir + "/")
+        runs = [40503]
+
+        wish_test.reduce(runs, panels)
         self.clearWorkspaces()
 
     def validate(self):
-        return "w41870-2_9foc", "WISH41870-2_9raw.nxs", \
-               "w41870-3_8foc", "WISH41870-3_8raw.nxs", \
-               "w41870-4_7foc", "WISH41870-4_7raw.nxs", \
-               "w41870-5_6foc", "WISH41870-5_6raw.nxs"
+        validation_files = []
+        for panel in [x for x in panels if x < 6]:
+            validation_files = validation_files + ["w40503-{0}_{1}foc".format(panel, linked_panels.get(panel)),
+                                                   "WISH40503-{0}_{1}raw.nxs".format(panel, linked_panels.get(panel))]
+        return validation_files
 
     def clearWorkspaces(self):
-        deletews = ["w41870-" + str(i) + "foc" for i in range(1, 11)]
+        deletews = ["w40503-{}foc".format(panel) for panel in panels]
         for ws in deletews:
             mantid.DeleteWorkspace(ws)
             mantid.DeleteWorkspace(ws + "-d")
 
-    # Skip test when on builds as extremely slow, run only as reversion test for wish script
-    def skipTests(self):
-        return True
+
+class WISHPowderReductionCreateVanadiumTest(MantidSystemTest):
+    # still missing required files check with ./systemtest -R PowderReduction --showskipped
+    def requiredFiles(self):
+        input_files = ["emptyinst19618-{}foc-SF-S.nxs".format(panel) for panel in panels]
+
+        input_files = [os.path.join(calibration_dir, files) for files in input_files]
+        return input_files
+
+    def cleanup(self):
+        if os.path.isdir(output_dir):
+            shutil.rmtree(output_dir)
+
+    def runTest(self):
+        os.makedirs(output_dir)
+        wish_test = Wish(calibration_dir, output_dir, True, input_dir + "/")
+        wish_test.create_vanadium_run(19612, 19618, panels)
+
+    def validate(self):
+        validation_files = []
+        for panel in [x for x in panels if x < 6]:
+            validation_files = validation_files + ["w19612-{}foc".format(panel),
+                                                   "vana19612-{}foc-SF-SS.nxs".format(panel)]
+        return validation_files
diff --git a/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5
index 870024467e73790d3cf578ce13fa1e900a33ca4a..a9857f36b9e5022067e49ec3004d659683329c33 100644
--- a/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5
@@ -1 +1 @@
-d2185756bd31c3fce4bee9f4dc0bc441
+5019e21091a7b56a76b92b9f98cc59ec
diff --git a/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5
index 8bd1cff7ee995f771198fd4e5a5b861457a4292f..863af15f45b1492b2ffafa6f756b6fe7d7d0c84d 100644
--- a/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5
@@ -1 +1 @@
-a1a495cd3351cd56ed06c7c7844817bb
+c23e62c08f2ced8496ce229b071be418
diff --git a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D11_IQ.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D11_IQ.nxs.md5
index 4d2acc2a39e875d03476fcb8aa0443774a6f970c..ceff9e31105eb5aac787f30b510dc0f9226d0cf4 100644
--- a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D11_IQ.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D11_IQ.nxs.md5
@@ -1 +1 @@
-45be2c31ed771f9bc50268f7e1a0f755
+b561ae0e1bcfd40bdda11f845b00cd02
diff --git a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D22_IQ.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D22_IQ.nxs.md5
index f6ad8af25e5a082892310f95a8a23b9266e51405..9b9864c9701825dff8af9947d79db796e98035a7 100644
--- a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D22_IQ.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D22_IQ.nxs.md5
@@ -1 +1 @@
-573e21a48ed9fae7ccdd4f0f83482980
+adca8c3ce4cb74468844a6030549fea8
diff --git a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_IQ.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_IQ.nxs.md5
index be4c69a63b7f0e3672b8d74d5e85ab47106504b1..04ff98f98d4e9c521e05b262d837d3472ae72116 100644
--- a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_IQ.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_IQ.nxs.md5
@@ -1 +1 @@
-07cce51ce42dac9e658d0aa7d94cbe25
+7e457178571d9dee467383faeed27e1f
diff --git a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_LTOF_IQ.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_LTOF_IQ.nxs.md5
index e49ecdf4aff45a0558e0d05cbdec893623a0acd6..61e09f1b8318e07497d0dbfbb9edbcc9320b1c7b 100644
--- a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_LTOF_IQ.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_LTOF_IQ.nxs.md5
@@ -1 +1 @@
-d940d5e6b48541cf4a7369092d1978bd
+53d72419283c9a9edc80b728c0d4dca0
diff --git a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_VTOF_IQ.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_VTOF_IQ.nxs.md5
index f45e7bcb26511f2f4027c0bc5323012241c076c8..4dd21ff3a0ee55e49f27df2d5733091c27b0e46a 100644
--- a/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_VTOF_IQ.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ILL_SANS_D33_VTOF_IQ.nxs.md5
@@ -1 +1 @@
-6c31e8fbbfd4f7d60ae8ddf63a9542a8
+6117c10d5619528f3a1d8ed8361ecc82
diff --git a/Testing/SystemTests/tests/analysis/reference/INTERReductionResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/INTERReductionResult.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5f41c56df50a11a4ef26603a8ccf123c2eaea1fb
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/INTERReductionResult.nxs.md5
@@ -0,0 +1 @@
+9260c7683da0460fc24c791c6e02a079
diff --git a/Testing/SystemTests/tests/analysis/reference/PG3_9829_sum_reference.gsa.md5 b/Testing/SystemTests/tests/analysis/reference/PG3_9829_sum_reference.gsa.md5
index d5ea4e051aa8223bae162d5464e41160bf20dfca..e3db4c237afddfb25a0e78a62f185f1803b3d35a 100644
--- a/Testing/SystemTests/tests/analysis/reference/PG3_9829_sum_reference.gsa.md5
+++ b/Testing/SystemTests/tests/analysis/reference/PG3_9829_sum_reference.gsa.md5
@@ -1 +1 @@
-13f233609f78d30c6cbdb228a8c1b1b3
+0a6f1170aa0baca89f766337fe50b687
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6no_absorb_raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6no_absorb_raw.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..48be88f06db245a22550ac088d1dd566857297d0
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6no_absorb_raw.nxs.md5
@@ -0,0 +1 @@
+6d48e72de164d0bea0d2f33d954ae1ef
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6raw.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..f011cfd731f0c5ff2394a70957d4b34a01dcb1a0
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/WISH40503-5_6raw.nxs.md5
@@ -0,0 +1 @@
+c9c36283bd351afc7296b81594b64f05
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH41870-1_10raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH41870-1_10raw.nxs.md5
deleted file mode 100644
index b35e98a748bf0a0efcf682c585fc529e532261af..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/WISH41870-1_10raw.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-62b46e6a09c66c34fd65cca545783c2b
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH41870-2_9raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH41870-2_9raw.nxs.md5
deleted file mode 100644
index 43cfcbfd6a2f5c2e0ee978a832c3d5d92ef43a96..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/WISH41870-2_9raw.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-75b95e5e550ab45932c92525f7285209
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH41870-3_8raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH41870-3_8raw.nxs.md5
deleted file mode 100644
index fe1f174409616056aff2fba331dd6bcd0461d3d0..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/WISH41870-3_8raw.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-cb91390e3ed1428eda044c75c776afb6
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH41870-4_7raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH41870-4_7raw.nxs.md5
deleted file mode 100644
index 0045522dc678b8ef92214b190692de4eca889013..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/WISH41870-4_7raw.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-31d0b9bea9965eae70fbf0d2c93ab6f1
diff --git a/Testing/SystemTests/tests/analysis/reference/WISH41870-5_6raw.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/WISH41870-5_6raw.nxs.md5
deleted file mode 100644
index 42fa6b456e67c67dd9320478c976822b1d640d53..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/WISH41870-5_6raw.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-c4515cceb5b4d58f0bcfded962d2a189
diff --git a/Testing/SystemTests/tests/analysis/reference/vana19612-5foc-SF-SS.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/vana19612-5foc-SF-SS.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..cf5800e7b756d10574b57b78fe76ed36fb4b8518
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/vana19612-5foc-SF-SS.nxs.md5
@@ -0,0 +1 @@
+e8fea832144b67b4911cd00e5abb27e8
diff --git a/Testing/SystemTests/tests/analysis/reference/vana19612-6foc-SF-SS.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/vana19612-6foc-SF-SS.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..d81d1572114947b481305f83bb2e5d71ae0aaf0b
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/vana19612-6foc-SF-SS.nxs.md5
@@ -0,0 +1 @@
+dafd63eef31cf573fcf643614ce5808d
diff --git a/buildconfig/CMake/Bootstrap.cmake b/buildconfig/CMake/Bootstrap.cmake
index 543205f5a54480fa23e1d8547bbb11d81da3f07b..7f0d1195b812d95221c2476e424def5ed590183c 100644
--- a/buildconfig/CMake/Bootstrap.cmake
+++ b/buildconfig/CMake/Bootstrap.cmake
@@ -10,7 +10,7 @@ if( MSVC )
   include ( ExternalProject )
   set( EXTERNAL_ROOT ${PROJECT_SOURCE_DIR}/external CACHE PATH "Location to clone third party dependencies to" )
   set( THIRD_PARTY_GIT_URL "https://github.com/mantidproject/thirdparty-msvc2015.git" )
-  set ( THIRD_PARTY_GIT_SHA1 cee87b544761b0311dd3664f9dbbd2f11e0a780a )
+  set ( THIRD_PARTY_GIT_SHA1 22bf373a4055d85b6793a34f6c823719d482a229 )
   set ( THIRD_PARTY_DIR ${EXTERNAL_ROOT}/src/ThirdParty )
   # Generates a script to do the clone/update in tmp
   set ( _project_name ThirdParty )
@@ -74,6 +74,7 @@ if( MSVC )
 
   # Set variables to help CMake find components
   set ( CMAKE_INCLUDE_PATH "${THIRD_PARTY_DIR}/include" )
+  include_directories ( ${THIRD_PARTY_DIR}/include )
   set ( CMAKE_LIBRARY_PATH "${THIRD_PARTY_DIR}/lib" )
   set ( CMAKE_PREFIX_PATH "${THIRD_PARTY_DIR};${THIRD_PARTY_DIR}/lib/qt4" )
   set ( BOOST_INCLUDEDIR "${CMAKE_INCLUDE_PATH}" )
diff --git a/buildconfig/CMake/FindPyUnitTest.cmake b/buildconfig/CMake/FindPyUnitTest.cmake
index 5ac987e2e6291f92d6adc0e70198daeafd859e0e..20725240b3ff1abab4c30d6d6a92e710db61e006 100644
--- a/buildconfig/CMake/FindPyUnitTest.cmake
+++ b/buildconfig/CMake/FindPyUnitTest.cmake
@@ -24,7 +24,13 @@ function ( PYUNITTEST_ADD_TEST _test_src_dir _testname_prefix )
   if ( WIN32 )
     set ( _test_runner ${_test_runner}.bat )
   endif ()
-  set ( _test_runner_module ${CMAKE_SOURCE_DIR}/Framework/PythonInterface/test/testhelpers/testrunner.py )
+
+  if ( NOT PYUNITTEST_RUNNER )
+    set ( _test_runner_module ${CMAKE_SOURCE_DIR}/Framework/PythonInterface/test/testhelpers/testrunner.py )
+  else ()
+    set ( _test_runner_module ${PYUNITTEST_RUNNER} )
+  endif()
+
 
   # Environment
   if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
diff --git a/buildconfig/CMake/MSVCSetup.cmake b/buildconfig/CMake/MSVCSetup.cmake
index 97012c783ed55ac4e24df008212b14eab8b3f3cd..d6944bde37b86424cc5a3d43665a9584f4fcd2c0 100644
--- a/buildconfig/CMake/MSVCSetup.cmake
+++ b/buildconfig/CMake/MSVCSetup.cmake
@@ -89,7 +89,7 @@ set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin )
 # Configure IDE/commandline startup scripts
 ###########################################################################
 set ( WINDOWS_BUILDCONFIG ${PROJECT_SOURCE_DIR}/buildconfig/windows )
-configure_file ( ${WINDOWS_BUILDCONFIG}/buildenv.bat.in ${PROJECT_BINARY_DIR}/buildenv.bat @ONLY )
+configure_file ( ${WINDOWS_BUILDCONFIG}/thirdpartypaths.bat.in ${PROJECT_BINARY_DIR}/thirdpartypaths.bat @ONLY )
 
 if ( MSVC_VERSION LESS 1911 )
     get_filename_component ( MSVC_VAR_LOCATION "$ENV{VS140COMNTOOLS}/../../VC/" ABSOLUTE)
@@ -101,13 +101,6 @@ else ()
     set ( MSVC_IDE_LOCATION "${MSVC_IDE_LOCATION}/Common7/IDE")
 endif()
 
-if ( ${CMAKE_SYSTEM_VERSION} MATCHES "^8" )
-  set ( SDK_VERSION ${CMAKE_SYSTEM_VERSION} )
-else ()
-  # append patch version to get SDK version
-  set ( SDK_VERSION ${CMAKE_SYSTEM_VERSION}.0 )
-endif ()
-
 configure_file ( ${WINDOWS_BUILDCONFIG}/command-prompt.bat.in ${PROJECT_BINARY_DIR}/command-prompt.bat @ONLY )
 # The IDE may not be installed as we could be just using the build tools
 if ( EXISTS ${MSVC_IDE_LOCATION}/devenv.exe )
@@ -120,7 +113,7 @@ configure_file ( ${WINDOWS_BUILDCONFIG}/pycharm.bat.in ${PROJECT_BINARY_DIR}/pyc
 ###########################################################################
 set ( PACKAGING_DIR ${PROJECT_SOURCE_DIR}/buildconfig/CMake/Packaging )
 # build version
-set ( MANTIDPYTHON_PREAMBLE "call %~dp0..\\..\\buildenv.bat\nset PATH=%_BIN_DIR%;%_BIN_DIR%\\PVPlugins\\PVPlugins;%PATH%" )
+set ( MANTIDPYTHON_PREAMBLE "call %~dp0..\\..\\thirdpartypaths.bat\nset PATH=%_BIN_DIR%;%_BIN_DIR%\\PVPlugins\\PVPlugins;%PATH%" )
 
 if ( MAKE_VATES )
   set ( PARAVIEW_PYTHON_PATHS ";${ParaView_DIR}/bin/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>;${ParaView_DIR}/lib/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>;${ParaView_DIR}/lib/site-packages;${ParaView_DIR}/lib/site-packages/vtk" )
diff --git a/buildconfig/CMake/Packaging/launch_mantidplot.sh.in b/buildconfig/CMake/Packaging/launch_mantidplot.sh.in
index 0ba17b9ad15420e63018f7fd27d534876159d876..daae071f08fdd71b6fc44acf1905e0ead3506c0c 100644
--- a/buildconfig/CMake/Packaging/launch_mantidplot.sh.in
+++ b/buildconfig/CMake/Packaging/launch_mantidplot.sh.in
@@ -18,4 +18,4 @@ INSTALLDIR=$(dirname $INSTALLDIR) # root install directory
 # Launch
 LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \
     TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \
-    @WRAPPER_PREFIX@$VGLRUN $GDB $INSTALLDIR/bin/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@
+    @WRAPPER_PREFIX@$VGLRUN $GDB $INSTALLDIR/bin/@MANTIDPLOT_EXEC@ "$@"@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@
diff --git a/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in b/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in
index 476e533daac4a1a18b2615862db746548e937faf..ffe62a59252757c331116a79f06f5638f6b9c5a2 100644
--- a/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in
+++ b/buildconfig/CMake/Packaging/launch_mantidworkbench.sh.in
@@ -24,4 +24,4 @@ fi
 LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \
     TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \
     PYTHONPATH=${LOCAL_PYTHONPATH} \
-    @WRAPPER_PREFIX@$VGLRUN $GDB @PYTHON_EXECUTABLE@ $INSTALLDIR/bin/@MANTIDWORKBENCH_EXEC@ $*@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@
+    @WRAPPER_PREFIX@$VGLRUN $GDB @PYTHON_EXECUTABLE@ $INSTALLDIR/bin/@MANTIDWORKBENCH_EXEC@ "$@"@WRAPPER_POSTFIX@ || @PYTHON_EXECUTABLE@ @SCRIPTSDIR@/@ERROR_CMD@
diff --git a/buildconfig/CMake/Packaging/mantidpython.in b/buildconfig/CMake/Packaging/mantidpython.in
index c96304ffa464f047d88ec95a74f6dde1d20230bd..99011c8f4eacf221ff3b661e8b94e9d61df61c6c 100755
--- a/buildconfig/CMake/Packaging/mantidpython.in
+++ b/buildconfig/CMake/Packaging/mantidpython.in
@@ -34,18 +34,19 @@ fi
 
 if [ -n "$1" ] && [ "$1" = "--classic" ]; then
     shift
-    set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ $*@WRAPPER_POSTFIX@
+    set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ "$@"@WRAPPER_POSTFIX@
 elif [ -n "$1" ] && [ -n "$2" ] && [ "$1" = "-n" ]; then
     ranks=$2
     shift 2
-    set -- mpirun -n $ranks @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ $*@WRAPPER_POSTFIX@
+    set -- mpirun -n $ranks @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ "$@"@WRAPPER_POSTFIX@
 else
     IPYTHON_STARTUP="import IPython;IPython.start_ipython()"
-    set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ -c "${IPYTHON_STARTUP}" $*@WRAPPER_POSTFIX@
+    set -- @WRAPPER_PREFIX@@PYTHON_EXECUTABLE@ -c "${IPYTHON_STARTUP}" "$@"@WRAPPER_POSTFIX@
 fi
 
 LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \
     TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=${TCM_REPORT} \
+    @MTD_PATH_DEFINITION@ \
     PYTHONPATH=${LOCAL_PYTHONPATH} \
     QT_API=${LOCAL_QT_API} \
     LD_LIBRARY_PATH=${LOCAL_LDPATH} \
diff --git a/buildconfig/Jenkins/buildscript b/buildconfig/Jenkins/buildscript
index 2bdc3fb258f0a12518c68ad58f82da60eb3ac3a9..145830fb7135f6b3b574e07f478bac5d86bc47e0 100755
--- a/buildconfig/Jenkins/buildscript
+++ b/buildconfig/Jenkins/buildscript
@@ -363,6 +363,16 @@ fi
 # Prevent race conditions when creating the user config directory
 userconfig_dir=$HOME/.mantid
 rm -fr $userconfig_dir
+# Remove GUI qsettings files
+if [[ ${ON_MACOS} == true ]] ; then
+  rm -f $HOME/Library/Preferences/com.mantid.MantidPlot.plist
+  rm -f $HOME/Library/Preferences/org.mantidproject.MantidPlot.plist
+  rm -f "$HOME/Library/Saved Application State/org.mantidproject.MantidPlot.savedState/windows.plist"
+else
+  rm -f ~/.config/Mantid/MantidPlot.conf
+fi
+rm -f ~/.config/mantidproject/mantidworkbench.ini
+
 mkdir -p $userconfig_dir
 # use a fixed number of openmp threads to avoid overloading the system
 userprops_file=$userconfig_dir/Mantid.user.properties
diff --git a/buildconfig/Jenkins/buildscript.bat b/buildconfig/Jenkins/buildscript.bat
index 0b92d738eea761a53f4c9bc63b368e01ad069230..402a0db2907f86067cc4be73b1fc70a85aff3231 100755
--- a/buildconfig/Jenkins/buildscript.bat
+++ b/buildconfig/Jenkins/buildscript.bat
@@ -13,23 +13,27 @@ setlocal enableextensions enabledelayedexpansion
 call cmake.exe --version
 echo %sha1%
 
-:: Find the grep tool for later
-for /f "delims=" %%I in ('where git') do @set GIT_EXE_DIR=%%~dpI
-set GIT_ROOT_DIR=%GIT_EXE_DIR:~0,-4%
-set GREP_EXE=%GIT_ROOT_DIR%\usr\bin\grep.exe
-
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Environment setup
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Source the VS setup script
-set VS_VERSION=14
-:: 8.1 is backwards compatible with Windows 7. It allows us to target Windows 7
-:: when building on newer versions of Windows. This value must be supplied
-:: externally and cannot be supplied in the cmake configuration
-set SDK_VERSION=8.1
-call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" amd64 %SDK_VERSION%
-set UseEnv=true
-set CM_GENERATOR=Visual Studio 14 2015 Win64
+:: Set cmake generator
+call %~dp0cmakegenerator.bat
+
+:: Find grep
+for /f "delims=" %%I in ('where git') do (
+  @set _grep_exe=%%~dpI..\usr\bin\grep.exe
+  @echo Checking for grep at: !_grep_exe!
+  if EXIST "!_grep_exe!" (
+    goto :endfor
+  ) else (
+    @set _grep_exe=""
+  )
+)
+:endfor
+if !_grep_exe! == "" (
+  @echo Unable to find grep.exe
+  exit /b 1
+)
+@echo Using grep: !_grep_exe!
+
+:: ParaView version
 set PARAVIEW_DIR=%PARAVIEW_DIR%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@@ -93,7 +97,19 @@ if not "%JOB_NAME%" == "%JOB_NAME:debug=%" (
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 set BUILD_DIR_REL=build
 set BUILD_DIR=%WORKSPACE%\%BUILD_DIR_REL%
-call %~dp0setupcompiler.bat %BUILD_DIR%
+
+if EXIST %BUILD_DIR%\CMakeCache.txt (
+  call "%_grep_exe%" CMAKE_GENERATOR:INTERNAL %BUILD_DIR%\CMakeCache.txt > %BUILD_DIR%\cmake_generator.log
+  call "%_grep_exe%" -q "%CM_GENERATOR%" %BUILD_DIR%\cmake_generator.log
+  if ERRORLEVEL 1 (
+    set CLEANBUILD=yes
+    echo Previous build used a different compiler. Performing a clean build.
+  ) else (
+    set CLEANBUILD=no
+    echo Previous build used the same compiler. No need to clean.
+  )
+)
+
 
 if "!CLEANBUILD!" == "yes" (
   echo Removing build directory for a clean build
@@ -165,15 +181,17 @@ if not "%JOB_NAME%"=="%JOB_NAME:debug=%" (
   set VATES_OPT_VAL=ON
 )
 
-call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERSION% -DCONSOLE=OFF -DENABLE_CPACK=ON -DMAKE_VATES=%VATES_OPT_VAL% -DParaView_DIR=%PARAVIEW_DIR% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DENABLE_WORKBENCH=ON -DPACKAGE_WORKBENCH=ON -DUSE_PRECOMPILED_HEADERS=ON %PACKAGE_OPTS% ..
+call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERS% -DCONSOLE=OFF -DENABLE_CPACK=ON -DMAKE_VATES=%VATES_OPT_VAL% -DParaView_DIR=%PARAVIEW_DIR% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DENABLE_WORKBENCH=ON -DPACKAGE_WORKBENCH=ON -DUSE_PRECOMPILED_HEADERS=ON %PACKAGE_OPTS% ..
 
 if ERRORLEVEL 1 exit /B %ERRORLEVEL%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Build step
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-call %BUILD_DIR%\buildenv.bat
-msbuild /nologo /m:%BUILD_THREADS% /nr:false /p:Configuration=%BUILD_CONFIG% Mantid.sln
+call %BUILD_DIR%\thirdpartypaths.bat
+cmake --build . -- /nologo /m:%BUILD_THREADS% /verbosity:minimal /p:Configuration=%BUILD_CONFIG%
+if ERRORLEVEL 1 exit /B %ERRORLEVEL%
+cmake --build . --target AllTests -- /nologo /m:%BUILD_THREADS% /verbosity:minimal /p:Configuration=%BUILD_CONFIG%
 if ERRORLEVEL 1 exit /B %ERRORLEVEL%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@@ -183,9 +201,10 @@ if ERRORLEVEL 1 exit /B %ERRORLEVEL%
 :: This prevents race conditions when creating the user config directory
 set USERPROPS=bin\%BUILD_CONFIG%\Mantid.user.properties
 del %USERPROPS%
-set CONFIGDIR=%APPDATA%\mantidproject\mantid
+set CONFIGDIR=%APPDATA%\mantidproject
 rmdir /S /Q %CONFIGDIR%
-mkdir %CONFIGDIR%
+:: Create the directory to avoid any race conditions
+mkdir %CONFIGDIR%\mantid
 :: use a fixed number of openmp threads to avoid overloading the system
 echo MultiThreaded.MaxCores=2 > %USERPROPS%
 
@@ -210,7 +229,7 @@ echo Note: not running doc-test target as it currently takes too long
 
 if "%BUILDPKG%" == "yes" (
   :: Build offline documentation
-  msbuild /nologo /nr:false /p:Configuration=%BUILD_CONFIG% docs/docs-qthelp.vcxproj
+  cmake --build . --target docs-qthelp -- /p:Configuration=%BUILD_CONFIG%  /verbosity:minimal
   :: Ignore errors as the exit code of msbuild is wrong here.
   :: It always marks the build as a failure even though MantidPlot exits correctly
   echo Building package
diff --git a/buildconfig/Jenkins/cmakegenerator.bat b/buildconfig/Jenkins/cmakegenerator.bat
new file mode 100755
index 0000000000000000000000000000000000000000..2a5ae661628e9c87355869121bb43632b6f26422
--- /dev/null
+++ b/buildconfig/Jenkins/cmakegenerator.bat
@@ -0,0 +1,7 @@
+@echo off
+
+:: SDK 8.1 is backwards compatible with Windows 7. It allows us to target Windows 7
+:: when building on newer versions of Windows. This value must be supplied
+:: externally and cannot be supplied in the cmake configuration
+set SDK_VERS=8.1
+set CM_GENERATOR=Visual Studio 15 2017 Win64
diff --git a/buildconfig/Jenkins/setupcompiler.bat b/buildconfig/Jenkins/setupcompiler.bat
deleted file mode 100755
index d3846f2ecfadcf63a28a9acbf56b7e37e9749c7e..0000000000000000000000000000000000000000
--- a/buildconfig/Jenkins/setupcompiler.bat
+++ /dev/null
@@ -1,49 +0,0 @@
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Set up the compiler to use with the mantid build
-:: The first argument is the location of the build dir.
-::
-:: On exit the CM_GENERATOR variable will be set appropriately.
-:: If the previous compiler does not match this then the
-:: CLEANBUILD flag is also set to yes
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-:: Find grep
-for /f "delims=" %%I in ('where git') do (
-set _git_root_dir=%_git_root_dir:~0,-4%
-  @set _grep_exe=%%~dpI..\usr\bin\grep.exe
-set _grep_exe=%_git_root_dir%\usr\bin\grep.exe
-  @echo Checking for grep at: !_grep_exe!
-  if EXIST "!_grep_exe!" (
-    goto :endfor
-  ) else (
-    @set _grep_exe=""
-  )
-)
-:endfor
-if !_grep_exe! == "" (
-  @echo Unable to find grep.exe
-  exit /b 1
-)
-@echo Using grep: !_grep_exe!
-
-:: 8.1 is backwards compatible with Windows 7. It allows us to target Windows 7
-:: when building on newer versions of Windows. This value must be supplied
-:: externally and cannot be supplied in the cmake configuration
-set _sdk_version=8.1
-set _vs_version=14
-call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" amd64 %_sdk_version%
-set CM_GENERATOR=Visual Studio %_vs_version% 2015 Win64
-
-set _builddir=%1
-echo %_builddir%
-if EXIST %_builddir%\CMakeCache.txt (
-  call "%_grep_exe%" CMAKE_LINKER:FILEPATH %_builddir%\CMakeCache.txt > %_builddir%\compiler_version.log
-  call "%_grep_exe%" %_vs_version% %_builddir%\compiler_version.log
-  if ERRORLEVEL 1 (
-    set CLEANBUILD=yes
-    echo Previous build used a different compiler. Performing a clean build
-  ) else (
-    set CLEANBUILD=no
-    echo Previous build used the same compiler. No need to clean
-  )
-)
diff --git a/buildconfig/Jenkins/systemtests b/buildconfig/Jenkins/systemtests
index fe04694e0c2436bc9593f4188a4afb29beae0213..4fdda64ac74231a227b5113648b9b31eb2ff2496 100755
--- a/buildconfig/Jenkins/systemtests
+++ b/buildconfig/Jenkins/systemtests
@@ -50,6 +50,11 @@ fi
 [ -d $WORKSPACE/build ] || mkdir $WORKSPACE/build
 cd $WORKSPACE/build
 
+# Remove (possibly) stale files
+#   build/ExternalData/**: data files will change over time and removing
+#                          the links helps keep it fresh
+rm -rf $WORKSPACE/build/ExternalData
+
 ###############################################################################
 # CMake configuration if it has not already been configured.
 # We use the special flag that only creates the targets for the data
@@ -69,10 +74,22 @@ ${CMAKE_EXE} --build . -- SystemTestData
 ###############################################################################
 # Run the tests
 ###############################################################################
-# Remove any Mantid.user.properties file
-userprops=~/.mantid/Mantid.user.properties
-rm -f $userprops
+# Remove any user settings
+userconfig_dir=$HOME/.mantid
+rm -fr $userconfig_dir
+# Remove GUI qsettings files
+if [[ ${ON_MACOS} == true ]] ; then
+  rm -f $HOME/Library/Preferences/com.mantid.MantidPlot.plist
+  rm -f $HOME/Library/Preferences/org.mantidproject.MantidPlot.plist
+  rm -f "$HOME/Library/Saved Application State/org.mantidproject.MantidPlot.savedState/windows.plist"
+else
+  rm -f ~/.config/Mantid/MantidPlot.conf
+fi
+rm -f ~/.config/mantidproject/mantidworkbench.ini
+
 # Turn off any auto updating on startup
+mkdir -p $userconfig_dir
+userprops=$userconfig_dir/Mantid.user.properties
 echo "UpdateInstrumentDefinitions.OnStartup = 0" > $userprops
 echo "usagereports.enabled = 0" >> $userprops
 echo "CheckMantidVersion.OnStartup = 0" >> $userprops
diff --git a/buildconfig/Jenkins/systemtests.bat b/buildconfig/Jenkins/systemtests.bat
index dec043b732225a2cae65508bd312008c1fc7a1f2..1034ccc99c090427eb684375e04a07417871121b 100755
--- a/buildconfig/Jenkins/systemtests.bat
+++ b/buildconfig/Jenkins/systemtests.bat
@@ -4,28 +4,18 @@ setlocal enableextensions enabledelayedexpansion
 ::
 :: Notes:
 ::
-:: WORKSPACE, JOB_NAME & NODE_LABEL are environment variables that 
+:: WORKSPACE, JOB_NAME & NODE_LABEL are environment variables that
 :: are set by Jenkins. The last one corresponds to any labels set on a slave.
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Print out the versions of things we are using
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-call cmake --version 
+call cmake --version
 echo %sha1%
 
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Environment setup
-:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Source the VS setup script
-set VS_VERSION=14
-:: 8.1 is backwards compatible with Windows 7. It allows us to target Windows 7
-:: when building on newer versions of Windows. This value must be supplied
-:: externally and cannot be supplied in the cmake configuration
-set SDK_VERSION=8.1
-call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" amd64 %SDK_VERSION%
-set UseEnv=true
-set CM_GENERATOR=Visual Studio 14 2015 Win64
+:: CMake generator
+call %~dp0cmakegenerator.bat
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Set up the location for local object store outside of the build and source
@@ -44,37 +34,53 @@ if NOT DEFINED MANTID_DATA_STORE (
 md %WORKSPACE%\build
 cd %WORKSPACE%\build
 
+:: Remove (possibly) stale files
+::   build/ExternalData/**: data files will change over time and removing
+::                          the links helps keep it fresh
+rmdir /S /Q %WORKSPACE%\build\ExternalData
+
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: CMake configuration if it has not already been configured.
 :: We use the special flag that only creates the targets for the data
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 if not EXIST %WORKSPACE%\build\CMakeCache.txt (
-  call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERSION% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DDATA_TARGETS_ONLY=ON ..
+  call cmake.exe -G "%CM_GENERATOR%" -DCMAKE_SYSTEM_VERSION=%SDK_VERS% -DMANTID_DATA_STORE=!MANTID_DATA_STORE! -DDATA_TARGETS_ONLY=ON ..
   if ERRORLEVEL 1 exit /b %ERRORLEVEL%
 ) else (
   :: This ensures that any new data files are picked up by the cmake globbing
-  call cmake .
+  call cmake.exe .
   if ERRORLEVEL 1 exit /b %ERRORLEVEL%
 )
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Build step
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-msbuild /nologo /nr:false /p:Configuration=Release StandardTestData.vcxproj
+call cmake.exe --build . --target StandardTestData -- /nologo /p:Configuration=Release /verbosity:minimal
 if ERRORLEVEL 1 exit /b %ERRORLEVEL%
-msbuild /nologo /nr:false /p:Configuration=Release SystemTestData.vcxproj
+call cmake.exe --build . --target SystemTestData -- /nologo /p:Configuration=Release /verbosity:minimal
 if ERRORLEVEL 1 exit /b %ERRORLEVEL%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Run the tests
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Remove any Mantid.user.properties file
-set USERPROPS=C:\MantidInstall\bin\Mantid.user.properties
-del /Q %USERPROPS%
+set USERPROPS_RELEASE=C:\MantidInstall\bin\Mantid.user.properties
+set USERPROPS_NIGHTLY=C:\MantidNightlyInstall\bin\Mantid.user.properties
+del /Q %USERPROPS_RELEASE% %USERPROPS_NIGHTLY%
+:: Remove user settings
+set CONFIGDIR=%APPDATA%\mantidproject
+rmdir /S /Q %CONFIGDIR%
+:: Create the directory to avoid any race conditions
+mkdir %CONFIGDIR%\mantid
+
 :: Turn off any auto updating on startup
-echo UpdateInstrumentDefinitions.OnStartup = 0 > %USERPROPS%
-echo usagereports.enabled = 0 >> %USERPROPS%
-echo CheckMantidVersion.OnStartup = 0 >> %USERPROPS%
+echo UpdateInstrumentDefinitions.OnStartup = 0 > %USERPROPS_RELEASE%
+echo usagereports.enabled = 0 >> %USERPROPS_RELEASE%
+echo CheckMantidVersion.OnStartup = 0 >> %USERPROPS_RELEASE%
+:: Nightly
+echo UpdateInstrumentDefinitions.OnStartup = 0 > %USERPROPS_NIGHTLY%
+echo usagereports.enabled = 0 >> %USERPROPS_NIGHTLY%
+echo CheckMantidVersion.OnStartup = 0 >> %USERPROPS_NIGHTLY%
 
 :: Run
 set PKGDIR=%WORKSPACE%\build
diff --git a/buildconfig/dev-packages/deb/mantid-developer/ns-control b/buildconfig/dev-packages/deb/mantid-developer/ns-control
index 17e368037f314e125891a7452384966a43399a26..d76d5108475a21b03ed5368a91d6087a578d5b8d 100644
--- a/buildconfig/dev-packages/deb/mantid-developer/ns-control
+++ b/buildconfig/dev-packages/deb/mantid-developer/ns-control
@@ -3,7 +3,7 @@ Priority: optional
 Standards-Version: 3.9.2
 
 Package: mantid-developer
-Version: 1.3.8
+Version: 1.3.9
 Maintainer: Mantid Project <mantid-tech@mantidproject.org>
 Priority: optional
 Architecture: all
@@ -41,6 +41,7 @@ Depends: git,
   python-setuptools,
   python-numpy,
   python-scipy,
+  python-skimage,
   python-qt4-dev,
   python-qt4-dbg,
   pyqt5-dev,
@@ -70,6 +71,7 @@ Depends: git,
   python3-qtawesome,
   python3-numpy,
   python3-scipy,
+  python3-skimage,
   python3-sphinx,
   python3-sphinx-bootstrap-theme,
   python3-dateutil,
diff --git a/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec b/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec
index 8bd9deb669356ad23c7362d683f007fb2b21c973..b37c7c737f4df37686e358bd881ec50565dafd47 100644
--- a/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec
+++ b/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec
@@ -5,7 +5,7 @@
 %endif
 
 Name:           mantid-developer
-Version:        1.29
+Version:        1.30
 Release:        1%{?dist}
 Summary:        Meta Package to install dependencies for Mantid Development
 
@@ -64,6 +64,7 @@ Requires: qwtplot3d-qt4-devel
 Requires: redhat-lsb
 Requires: rpmdevtools
 Requires: scipy
+Requires: python2-scikit-image
 Requires: sip-devel
 Requires: tbb
 Requires: tbb-devel
@@ -96,6 +97,7 @@ Requires: python3-QtPy
 %{?fedora:Requires: python3-QtAwesome}
 Requires: python3-numpy
 Requires: python3-scipy
+Requires: python3-scikit-image
 Requires: python3-sphinx
 Requires: python3-sphinx-bootstrap-theme
 Requires: python3-dateutil
diff --git a/buildconfig/windows/command-prompt.bat.in b/buildconfig/windows/command-prompt.bat.in
index bbe0e8b1b4cf0573096deb270d6afa1f7d1b2240..ebfbff4028b2fc5813499f0577cd02adde47ec8a 100644
--- a/buildconfig/windows/command-prompt.bat.in
+++ b/buildconfig/windows/command-prompt.bat.in
@@ -3,9 +3,8 @@
 :: Sets up the environment configured for Mantid by CMake and
 :: starts the appropriate version of Visual Studio
 
-:: Assume the buildenv.bat script exists and is in the same directory
-call %~dp0buildenv.bat
+call %~dp0thirdpartypaths.bat
 set VCVARS=@MSVC_VAR_LOCATION@
 set UseEnv=true
 :: Start command line
-%COMSPEC% /k ""%VCVARS%\vcvarsall.bat"" amd64 @SDK_VERSION@
+%COMSPEC% /k ""%VCVARS%\vcvarsall.bat"" amd64
diff --git a/buildconfig/windows/pycharm.bat.in b/buildconfig/windows/pycharm.bat.in
index 7343cba8a6066caf555907858cfd49d8f6f783a8..b05e6cc720ea50ce282c93f65ec3747e7ef0197a 100644
--- a/buildconfig/windows/pycharm.bat.in
+++ b/buildconfig/windows/pycharm.bat.in
@@ -1,9 +1,5 @@
 @echo OFF
-
-call %~dp0buildenv.bat
-
-setlocal ENABLEEXTENSIONS
-setlocal enabledelayedexpansion
+setlocal enableextensions enabledelayedexpansion
 
 set KEY_NAME="HKCR\Applications\pycharm.exe\shell\open\command"
 
@@ -16,7 +12,8 @@ if defined ValueValue (
     :: Strip "" and %1
     set ValueValue=!ValueValue:"=!
     set ValueValue=!ValueValue: %%1=!
+    call %~dp0thirdpartypaths.bat
     start "" "!ValueValue!"
 ) else (
     @echo %KEY_NAME% not found.
-)
\ No newline at end of file
+)
diff --git a/buildconfig/windows/buildenv.bat.in b/buildconfig/windows/thirdpartypaths.bat.in
similarity index 100%
rename from buildconfig/windows/buildenv.bat.in
rename to buildconfig/windows/thirdpartypaths.bat.in
diff --git a/buildconfig/windows/visual-studio.bat.in b/buildconfig/windows/visual-studio.bat.in
index 7d6cbae1ca0b073f80748c5ac35297d92116aca2..f86e7efa23fc4c8b59665c52e7277f530fa44d40 100755
--- a/buildconfig/windows/visual-studio.bat.in
+++ b/buildconfig/windows/visual-studio.bat.in
@@ -3,8 +3,7 @@
 :: Sets up the environment configured for Mantid by CMake and
 :: starts the appropriate version of Visual Studio
 
-:: Assume the buildenv.bat script exists and is in the same directory
-call %~dp0buildenv.bat
+call %~dp0thirdpartypaths.bat
 set MSVC_IDE=@MSVC_IDE_LOCATION@
 :: Start IDE
 start "" "%MSVC_IDE%/devenv.exe" Mantid.sln
diff --git a/dev-docs/source/BuildingWithCMake.rst b/dev-docs/source/BuildingWithCMake.rst
index fc688834120288a4c7bb0ba7ff2b753140e26061..db172345699e75bb2e0eb6e5b23ed91e4e469ac9 100644
--- a/dev-docs/source/BuildingWithCMake.rst
+++ b/dev-docs/source/BuildingWithCMake.rst
@@ -70,14 +70,18 @@ From the CMake gui
 ------------------
 
 * The cmake gui is available from, e.g., the Windows Program menu or the command line executable ``cmake-gui``.
-* Start it and click the "Browse Source" button to point to ``/path/to/Mantid``, or to ``/path/to/Mantid/Framework`` if you only want a build of the Framework (typically not recommended, but possible nonetheless).
+* Start it and click the "Browse Source" button to point to ``/path/to/Mantid``.
 * Click "Browse Build" and point to the directory you want to build into - it's recommended that you create a new directory for this (see above), though it can be the same as the source directory.
 * Click "Configure" down near the bottom of the window.
-* A new window will appear asking which 'Generator' you want to use. Choose one and click OK (N.B. VS2010 = Visual Studio 10, and note that you should append Win64 to this for a 64 bit build).
+* A new window will appear asking which 'Generator' you want to use.
+
+  * Linux/Mac developers should choose ``Ninja``
+  * Windows developers should choose ``Visual Studio 15 2017 Win64`` (the Win64 is very important)
+
 * Wait a while....
 * You will be presented with a list of options in red that can in principle be changed. You probably don't want to change anything, except perhaps checking "MAKE_VATES" if you want to build that.
 * Click "Configure" again and wait....
-* Finally, click "Generate". This will create the build files, e.g. there will be a Mantid.sln in the directory you selected as your build directory.
+* Finally, click "Generate". This will create the build files, e.g. there will be a ``Mantid.sln`` in the directory you selected as your build directory.
 
 Data Files Location
 -------------------
diff --git a/dev-docs/source/GettingStarted.rst b/dev-docs/source/GettingStarted.rst
index c95315f976d284df09864fa7ca540f213ebe10b6..3de44933d1cae47783b84404415a839c0b4833cc 100644
--- a/dev-docs/source/GettingStarted.rst
+++ b/dev-docs/source/GettingStarted.rst
@@ -18,22 +18,22 @@ Windows
 
 Install the following:
 
-* `Visual Studio 2015 Community Edition <https://go.microsoft.com/fwlink/?LinkId=532606&clcid=0x409>`_. If you are at RAL then
-  ask for the location of the locally-cached offline version.
+* `Visual Studio 2017 Community Edition <https://visualstudio.microsoft.com/downloads/>`_.
 
-  * Select a custom install and include at minimum:
+  * When asked about installation workloads choose ``Desktop development with C++``
+  * Under the "Installation details" section verify that the following are checked:
+
+    * ``Windows 8.1 SDK and UCRT SDK``
+    * The latest Windows 10 SDK
 
-    * Programming Languages -> Visual C++
-    * Universal Windows App Development Kits -> Tools and Windows 10 SDK
-    * Windows 8.1 and Windows Phone 8.0/8.1 Tools -> Tools and Windows SDKs
 
 * `Git <https://git-scm.com/>`_.
 
   * install the latest version and ensure that Git LFS is checked to be included
   * when the install has completed create a directory for storage of the LFS objects, e.g. ``C:\GitLFSStorage``
   * open up Git Bash and run ``git config --global lfs.storage C:/GitLFSStorage``
- 
-* `CMake <https://cmake.org/download/>`_
+
+* `CMake <https://cmake.org/download/>`_ >= 3.7
 * `MiKTeX <https://miktex.org/download>`_. Installation instructions are  `available here <https://miktex.org/howto/install-miktex>`_. Once installed:
 
   * open the MikTeX console from the start menu
@@ -67,7 +67,7 @@ Red Hat/Cent OS/Fedora
   # Enable the mantid repo from copr
   yum copr enable mantid/mantid
 
-  # Install dependencies 
+  # Install dependencies
   yum install mantid-developer
 
 Ubuntu
diff --git a/dev-docs/source/JenkinsConfiguration.rst b/dev-docs/source/JenkinsConfiguration.rst
index ddc5cb2573651aaedc76896ae0f086df7564e2cd..6695beb8daac9c733eb645c64371e1dd07913b6b 100644
--- a/dev-docs/source/JenkinsConfiguration.rst
+++ b/dev-docs/source/JenkinsConfiguration.rst
@@ -43,8 +43,9 @@ Set up a local ``builder`` account that will be used by the slave.
 Install the :ref:`required prerequisites <GettingStarted>` for the relevant OS.
 
 .. note::
-   For Windows the `Command line Visual C++ build tools <http://landinghub.visualstudio.com/visual-cpp-build-tools>`__
-   may be used in place of a full Visual Studio install from version 2017 onwards (the 2015 tools contain a broken `vcvarsall.bat`).
+   For Windows the `Command line Visual C++ build tools <https://visualstudio.microsoft.com/downloads/>`__
+   may be used in place of a full Visual Studio install from version 2017 onwards (the 2015 tools contain a broken `vcvarsall.bat`). The same
+   options should be used as for the full install.
 
 Windows
 -------
diff --git a/dev-docs/source/Python3.rst b/dev-docs/source/Python3.rst
index 55fc190b999744cd6a0383b834c8ba4689323200..85915a6d2ad75e2d9e1a1055742578ff3d79f80b 100644
--- a/dev-docs/source/Python3.rst
+++ b/dev-docs/source/Python3.rst
@@ -12,28 +12,12 @@ migration strategy for Mantid.
 Building Against Python 3
 #########################
 
-This is currently only possible on a Linux system with a pre-installed version of python 3. You need
-to install some additional packages as shown below:
-
-.. code-block:: sh
-
-   apt-get install python3-sip-dev python3-pyqt4  python3-numpy  python3-scipy  python3-sphinx \
-     python3-sphinx-bootstrap-theme  python3-dateutil python3-matplotlib ipython3-qtconsole \
-     python3-h5py python3-yaml
-
-or on fedora, with slightly different package names
-
-.. code-block:: sh
-
-   dnf install python3-sip-devel python3-PyQt4-devel python3-numpy python3-scipy python3-sphinx \
-     python3-sphinx-theme-bootstrap python3-dateutil python3-matplotlib python3-ipython-gui \
-     boost-python3-devel python3-h5py python3-yaml
-
-then set ``-DPYTHON_EXECUTABLE=/usr/bin/python3`` when running cmake before building.
+This is currently only possible on a Linux system with a pre-installed version of python 3 and you will need to have
+the latest version of the `mantid-developer` package installed. Once installed run cmake as standard but with the additional option ``-DPYTHON_EXECUTABLE=/usr/bin/python3``. Please note that
+reconfiguring an existing Python 2 build is not supported - a build in a fresh build directory is required.
 
 .. warning::
-   If any of these packages are installed via pip, this could cause conflicts.
-   Install as described here only.
+   Do not install python packages via ``pip``. Install packages only from the system repositories.
 
 Supporting Python 2 and 3
 #########################
diff --git a/dev-docs/source/RunningTheUnitTests.rst b/dev-docs/source/RunningTheUnitTests.rst
index fb93f74bca9bdb8def74fe9394435d0bd73f291d..1a34eb1dfa9f85afe61506506cc2b0bc34297a62 100644
--- a/dev-docs/source/RunningTheUnitTests.rst
+++ b/dev-docs/source/RunningTheUnitTests.rst
@@ -86,22 +86,27 @@ Starting in your build folder (e.g. Mantid/Code/debug):
    .. code-block:: sh
 
       ctest -j8 -R KernelTest
-      bin/KernelTest
+      ./bin/KernelTest
 
 -  Running a specific test class.
 
    .. code-block:: sh
 
       ctest -R MyTestClassName
-      bin/KernelTest MyTestClassName
+      ./bin/KernelTest MyTestClassName
 
--  Running a specific test.
+-  Running a specific test from a CxxTest test class (not possible via CTest).
 
    .. code-block:: sh
 
-      bin/KernelTest MyTestClassName MySingleTestName``
+      ./bin/KernelTest MyTestClassName MySingleTestName
 
-   -  Not possible with ctest.
+- Running a specific test from a Python ``unittest`` test class (not possible
+  via CTest).
+
+  .. code-block:: sh
+
+     ./bin/mantidpython /path/to/src/Framework/PythonInterface/test/python/plugins/algorithms/MeanTest.py MeanTest.test_mean
 
 Running Unit Tests With Visual Studio and ctest
 ###############################################
diff --git a/dev-docs/source/Standards/AdditionalPythonCode.rst b/dev-docs/source/Standards/AdditionalPythonCode.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c984cbf5fb52ff05cdf0992f8df932fb98398776
--- /dev/null
+++ b/dev-docs/source/Standards/AdditionalPythonCode.rst
@@ -0,0 +1,57 @@
+.. _AdditionalPythonCode:
+
+======================
+Additional Python code
+======================
+
+.. contents::
+  :local:
+
+Overview
+########
+
+Python code that is not part of 'core' Mantid, e.g. is not an algorithm, not
+related to the Python exports (``mantid.*`` modules) nor an integral part of
+``workbench`` should go to either the ``scripts`` directory or ``qt``
+directory.
+
+``scripts`` is a place to put non-GUI modules and scripts such as pure Python 
+reduction frameworks or technique specific plotting modules which are 
+desirable to be included in an official release. The code in ``scripts`` can 
+be included in the automatic unit testing machinery making it possible to 
+avoid breakages due to changes in Mantid's core parts. Although some reduction 
+interface code lives in ``scripts``, adding more GUI related code there is 
+discouraged. 
+
+Python interfaces should go to the ``qt`` directory.
+
+The ``scripts`` directory
+#########################
+
+Python code should be written as proper `modules 
+<https://docs.python.org/3/tutorial/modules.html>`_. For example, the code of 
+a module called ``spam`` should go into ``scripts/spam`` and contain a file 
+named ``__init__.py`` at minimum. Then the module can be imported into Mantid 
+simply by ``import spam``.
+
+Documentation
+-------------
+
+Documentation can be added to Mantid's Python API docs in ``docs/source/api`` 
+and linked to ``docs/source/api/index.rst``. Note, that it is possible to 
+import Python's docstrings in ``.rst`` files using directives such as ``.. 
+automodule::`` or ``.. autoclass::``, see `here 
+<http://www.sphinx-doc.org/es/stable/ext/autodoc.html>`_.
+
+Unit testing
+------------
+
+Unit tests for each module should be added to ``scripts/test/modulename``. The 
+tests follow the :ref:`standard Mantid unit testing practices 
+<UnitTestGoodPractice>`.
+
+The ``qt`` directory
+####################
+
+There are no official rules for ``qt`` yet. Follow the structure of already
+existing code there.
diff --git a/dev-docs/source/Standards/index.rst b/dev-docs/source/Standards/index.rst
index 20709a3f984ff07e6e82d93b1a044750509481ac..55bf344979fc1c54fa4f06e0e559bf37e9d6d0b9 100644
--- a/dev-docs/source/Standards/index.rst
+++ b/dev-docs/source/Standards/index.rst
@@ -42,3 +42,4 @@ Guidelines
    :maxdepth: 1
 
    Libraries
+   AdditionalPythonCode
diff --git a/dev-docs/source/Testing/IndirectInelastic/IndirectInelasticAcceptanceTests.rst b/dev-docs/source/Testing/IndirectInelastic/IndirectInelasticAcceptanceTests.rst
index 3871e7e6832560c73df40965418ecf1b774c027e..cd985643dd1c227a548ed9e9059df2589b889d4d 100644
--- a/dev-docs/source/Testing/IndirectInelastic/IndirectInelasticAcceptanceTests.rst
+++ b/dev-docs/source/Testing/IndirectInelastic/IndirectInelasticAcceptanceTests.rst
@@ -92,7 +92,7 @@ Data analysis Elwin
 #. Click ``Run``
 #. This should result in three new workspaces again, this time with file ranges as their name
 #. In the main GUI right-click on ``irs26174-26176_graphite002_red_elwin_eq2`` and choose ``Plot Spectrum``, choose ``Plot All``
-#. This should plot two lines of :math:`A^{-2}` vs :math:`Q`
+#. This should plot two lines of A^2 vs Q
 #. Right-click on the ``irs26176_graphite002_elwin_eq`` workspace and ``Save Nexus``; save to a location of your choice; you will use this file in the next test
 
 Data analysis MSD
@@ -193,5 +193,3 @@ Data analysis I(Q, T) Fit
 #. Select Lifetime from the ``Plot Output`` drop-down
 #. Click ``Plot Result`` this should open a new plot with the lifetimes plotted
   
-
-
diff --git a/dev-docs/source/Testing/MuonInterface/MuonTesting.rst b/dev-docs/source/Testing/MuonInterface/MuonTesting.rst
index 79f9b9fda0156c3b04e17b86a6be5930ce0a00c1..5748a7db2e23c98bdb4013c658861a05931e5ce5 100644
--- a/dev-docs/source/Testing/MuonInterface/MuonTesting.rst
+++ b/dev-docs/source/Testing/MuonInterface/MuonTesting.rst
@@ -55,8 +55,8 @@ Ionic Diffusion test
 -  In the ``Results Table`` workspace
 
    -  Expected values (similar to within 50%) ..
-   -  f0.A0: 0.18235938124844153
-   -  f1.Asym: 0.0050597127151507
+   -  f0.A0: -0.083439833711330152
+   -  f1.Asym: 0.19125607982528858
    -  f1:Delta: 0.3301445010124604
    -  f1:Nu: 0.8574644977974730220884
 
@@ -67,11 +67,6 @@ Ionic Diffusion test
    -  Right-click each workspace
    -  Choose ``Plot spectrum``
    -  Choose ``1D plot`` and click ``Plot All``
-   -  The results should look like the image below:
-
-.. figure:: ../../images/CuResult.jpg
-   :alt: CuResult.png
-
 
 Possible problems
 ^^^^^^^^^^^^^^^^^
diff --git a/dev-docs/source/Testing/VSI/VSITesting.rst b/dev-docs/source/Testing/VSI/VSITesting.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2063beb03abe647bf09e81c4e022901bc258c68c
--- /dev/null
+++ b/dev-docs/source/Testing/VSI/VSITesting.rst
@@ -0,0 +1,61 @@
+.. _vsi_testing:
+
+VSI Testing
+=============
+
+.. contents::
+   :local:
+
+
+*Preparation*
+
+- Get the scripts from the Mantid repository `this directory <https://github.com/mantidproject/mantid/tree/master/scripts/Vates>`_.
+- Make sure that you have the Mantid system test data. You can do this by building a SystemTestData target of Mantid.
+- Put the system test data directory in your Mantid user directories
+
+
+**Time required 20-30 minutes**
+
+--------------
+
+#. Load the script SXD_NaCl.py in MantidPlot. Run it.
+#. This should load a workspace called QLab. Right-click this workspace and choose 'Show Vates simple interface'.
+#. This should open the VSI window. Like the picture below. Check that all tabs are present.
+
+.. figure:: ../../images/vsi.png
+   :alt: alternate text
+   :align: right
+   
+#. Click the various tabs making sure that the interface does not crash. 
+#. Make sure all tabs have a tool tip when you hover over them.
+#. Go into three slice mode (the star shaped tab at the top).
+#. Play with the maximum and minimum parameters at the top of the plot, make sure the colours change in the plot.
+#. Hover on each of the upper two plots and the lower left plot. While hovering over a plot use the roll bar (or equivalent), the slices in the other plots should update. The lower right plot should show all three slices. Check that the text on the plots is legible and updates appropriately.
+#. Switch to multi-slice view (just to the left of three slice view).
+
+   #. In the properties tab (left of the plot) select the Display menu.
+   #.  Choose all options for Representation, make sure they work.
+   #. Change the Styling and Lighting sliders, make sure the picture updates.
+   #. Next to Data Axes Grid click edit, this should open a new dialog of settings for the plot.
+   #. Change some of the properties in this dialog and click apply, the plot should update accordingly.
+   #. Make sure that the sliders for the plot work. These are the triangles on the scales above and to the left of the plot. Slide them and move through the plot.
+   #. On the slider scale Shift+Right-click should add another slice
+   #. Select the View menu.
+   #. Turn on/off the orientation axes visibility, check that the little axes icon on the plot turns on and off.
+   #. Check and uncheck the parallel camera box, make sure the view switches between perspective on and off.
+
+#. Switch to standard view (left of multi-slice)
+
+   #. In the Rebin drop-down (above the plot) select Fast Rebin and click Slice - a new MDScaleWorkspace should appear in the list
+   #. In the Properties tab select Properties and change the X/Y/Z scaling factors, click Apply. The plot should distort accordingly. 
+   #. In the properties tab click Delete and the plot alterations should be removed from the plot.
+   #. Repeat the previous three steps for the different Rebin options.  
+
+#. Close the VSI interface and then reopen as before. You are now in scatter plot mode.
+
+   #. Under Properties, change the Number of Points and Top Percentile settings and see that the plot changes.
+   #. Drag the peaks_qLab workspace from the main GUI onto VSI. This should show the peak position in the plot as points.
+   #. Drag the peaks_qLab_integrated workspace from the main GUI onto VSI. This should show the peak positions in the plot as spheres.
+
+#. Close the VSI GUI.
+
diff --git a/dev-docs/source/Testing/index.rst b/dev-docs/source/Testing/index.rst
index 8b5446cd991f14a97fe028c5f40199b194155336..679a911759d4e1d92204f3127a8ff49acc8a798d 100644
--- a/dev-docs/source/Testing/index.rst
+++ b/dev-docs/source/Testing/index.rst
@@ -24,4 +24,5 @@ creation is outlined in :ref:`issue_tracking`.
    IndirectInelastic/IndirectInelasticAcceptanceTests
    ErrorReporter-ProjectRecovery/ErrorReporterTesting
    ErrorReporter-ProjectRecovery/ProjectRecoveryTesting
+   VSI/VSITesting
 
diff --git a/dev-docs/source/images/vsi.png b/dev-docs/source/images/vsi.png
new file mode 100644
index 0000000000000000000000000000000000000000..28685e6c7c23cca0890ccb37de18b9d17dbbd182
Binary files /dev/null and b/dev-docs/source/images/vsi.png differ
diff --git a/docs/source/algorithms/AbsorptionCorrection-v1.rst b/docs/source/algorithms/AbsorptionCorrection-v1.rst
index 7cce5394108f305c9f80272d802b9ffcd95dbf1d..472811bea3ffdda3404c9fdd91e9da4f0d664562 100644
--- a/docs/source/algorithms/AbsorptionCorrection-v1.rst
+++ b/docs/source/algorithms/AbsorptionCorrection-v1.rst
@@ -112,3 +112,4 @@ Output:
 .. categories::
 
 .. sourcelink::
+   :filename: AnyShapeAbsorption
diff --git a/docs/source/algorithms/CreateSampleShape-v1.rst b/docs/source/algorithms/CreateSampleShape-v1.rst
index d4de5dbd5bf095c3e6a624a6dbf0607e8d0ed7b9..e533f43f24fd21c2c7582cf01b0f6b7b1b074e08 100644
--- a/docs/source/algorithms/CreateSampleShape-v1.rst
+++ b/docs/source/algorithms/CreateSampleShape-v1.rst
@@ -13,10 +13,12 @@ Creates a shape object that defines the sample and sets the sample for
 the given workspace. Shapes are defined using XML descriptions that can
 be found :ref:`here <HowToDefineGeometricShape>`.
 
+.. note:: It is recommended that you use :ref:`SetSample <algm-SetSample>` instead.
+
 Usage
 -----
 
-**Example - A Sphere**  
+**Example - A Sphere**
 
 .. testcode:: Sphere
 
@@ -28,7 +30,7 @@ Usage
       </sphere>'''
     CreateSampleShape(ws,shape_xml)
 
-**Example - A ball with a cylinder carved out of the middle**  
+**Example - A ball with a cylinder carved out of the middle**
 
 .. testcode:: BallwithHole
 
diff --git a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
index df4b51d778d521b95eec4d79cd343f2aab5524c2..4072fc364b89a7e4e982bf53fac9147b2bace63b 100644
--- a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
+++ b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
@@ -47,7 +47,7 @@ functions where ``_tof`` is the time-of-flight term, ``_length`` is
 the path length term, and ``_angle`` is the angular term. Note that
 the total resolution is these terms added in quadriture.
 
-Note that :math:`\frac{\Delta d}{d} = \frac{\Delta Q}{Q}`.
+Note that :math:`\frac{\Delta d}{d} = \frac{\Delta Q}{Q}`. When fitting peaks in time-of-flight the resolution is :math:`\frac{\Delta T}{T} = \frac{\Delta d}{d}`.
 
 Factor Sheet
 ------------
diff --git a/docs/source/algorithms/FilterByLogValue-v1.rst b/docs/source/algorithms/FilterByLogValue-v1.rst
index 6579b1d95d58e25908e113772d61d9159450c7be..8e5a6508db1fb9a3ba1b8d49c74049e1ddaf3614 100644
--- a/docs/source/algorithms/FilterByLogValue-v1.rst
+++ b/docs/source/algorithms/FilterByLogValue-v1.rst
@@ -38,6 +38,11 @@ will be included also. If a log has a single point in time, then that
 log value is assumed to be constant for all time and if it falls within
 the range, then all events will be kept.
 
+.. warning::
+
+   :ref:`FilterByLogValue <algm-FilterByLogValue>` is not suitable for
+   fast log filtering.
+
 PulseFilter (e.g. for Veto Pulses)
 ##################################
 
@@ -63,7 +68,7 @@ rejected. For example, this call will filter out veto pulses:
 .. testsetup:: VetoPulseTime
 
    ws=CreateSampleWorkspace("Event")
-   AddTimeSeriesLog(ws, Name="veto_pulse_time", Time="2010-01-01T00:00:00", Value=1) 
+   AddTimeSeriesLog(ws, Name="veto_pulse_time", Time="2010-01-01T00:00:00", Value=1)
    AddTimeSeriesLog(ws, Name="veto_pulse_time", Time="2010-01-01T00:10:00", Value=0)
    AddTimeSeriesLog(ws, Name="veto_pulse_time", Time="2010-01-01T00:20:00", Value=1)
    AddTimeSeriesLog(ws, Name="veto_pulse_time", Time="2010-01-01T00:30:00", Value=0)
@@ -77,20 +82,20 @@ rejected. For example, this call will filter out veto pulses:
 Comparing with other event filtering algorithms
 ###############################################
 
-Wiki page :ref:`EventFiltering` has a detailed
-introduction on event filtering in MantidPlot.
+The :ref:`EventFiltering` page has a detailed introduction on event
+filtering in mantid.
 
 
 Usage
 -----
 
-**Example - Filtering by a simple time series Log**  
+**Example - Filtering by a simple time series Log**
 
 .. testcode:: FilterByLogValue
 
    ws = CreateSampleWorkspace("Event",BankPixelWidth=1)
 
-   AddTimeSeriesLog(ws, Name="proton_charge", Time="2010-01-01T00:00:00", Value=100) 
+   AddTimeSeriesLog(ws, Name="proton_charge", Time="2010-01-01T00:00:00", Value=100)
    AddTimeSeriesLog(ws, Name="proton_charge", Time="2010-01-01T00:10:00", Value=100)
    AddTimeSeriesLog(ws, Name="proton_charge", Time="2010-01-01T00:20:00", Value=100)
    AddTimeSeriesLog(ws, Name="proton_charge", Time="2010-01-01T00:30:00", Value=100)
diff --git a/docs/source/algorithms/FilterEvents-v1.rst b/docs/source/algorithms/FilterEvents-v1.rst
index b45de531098b1640271f410a12797f88f29a7f4a..7063dcb65b05b1757d3ea993b6613e7474117a38 100644
--- a/docs/source/algorithms/FilterEvents-v1.rst
+++ b/docs/source/algorithms/FilterEvents-v1.rst
@@ -9,147 +9,120 @@
 Description
 -----------
 
-This algorithm filters events from an :ref:`EventWorkspace` to one or
-multiple :ref:`EventWorkspaces <EventWorkspace>` according to an input
-:ref:`SplittersWorkspace` containing a series of splitters (i.e.,
-:ref:`splitting intervals <SplittingInterval>`).
-
-Inputs
-######
-
-FilterEvents takes 2 mandatory input Workspaces and 1 optional
-Workspace.  One of mandatory workspace is the :ref:`EventWorkspace`
-where the events are filtered from.  The other mandatory workspace is
-workspace containing splitters.  It can be a MatrixWorkspace, a TableWorkspace or
-a :ref:`SplittersWorkspace <SplittersWorkspace>`.
-
-The optional workspace is a :ref:`TableWorkspace <Table Workspaces>`
-for information of splitters.
-
-Workspace containing splitters
-==============================
-
-This algorithm accepts three types of workspace that contains event splitters.
-- TableWorkspace: a general TableWorkspace with at three columns
-- MatrixWorkspace: a 1-spectrum MatrixWorkspace
-- SplittersWorkspace: an extended TableWorkspace with restrict definition on start and stop time.
-
-Event splitter
-++++++++++++++
-
-An event splitter contains three items, start time, stop time and splitting target (index).
-All the events belonged to the same splitting target will be saved to a same output EventWorkspace.
-
-Unit of input splitters
-+++++++++++++++++++++++
-
-- MatrixWorkspace:  the unit must be second.
-- TableWorkspace: the unit must be second.
-- SplittersWorkspace: by the definition of SplittersWorkspace, the unit has to be nanosecond.
-
-
-How to generate input workspace containing splitters
-++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-There are two ways to generate
-
-Algorithm :ref:`GenerateEventsFilter <algm-GenerateEventsFilter>`
-creates both the :ref:`SplittersWorkspace <SplittersWorkspace>` and
-splitter information workspace.
-
-
-Splitters in relative time or absolute time
-+++++++++++++++++++++++++++++++++++++++++++
-
-As the SplittersWorkspace is in format of :ref:`MatrixWorkspace
-<MatrixWorkspace>`, its time, i.e., the value in X vector, can be
-relative time.
-
-Property ``RelativeTime`` flags that the splitters' time is relative.
-Property ``FilterStartTime`` specifies the starting time of the filter.
-Or the shift of time of the splitters.
-If it is not specified, then the algorithm will search for sample log ``run_start``.
-
-Outputs
-#######
-
-The output will be one or multiple workspaces according to the number of
-index in splitters. The output workspace name is the combination of
-parameter OutputWorkspaceBaseName and the index in splitter.
-
-Calibration File
-################
-
-The calibration, or say correction, from the detector to sample must be
-consider in fast log. Thus a calibration file is required. The math is
-
-``TOF_calibrated = TOF_raw * correction(detector ID).``
-
-The calibration is in column data format.
-
-A reasonable approximation of the correction is
-
-``correction(detector_ID) = L1/(L1+L2(detector_ID))``
+This algorithm filters events from a single :ref:`EventWorkspace` to
+one or multiple :ref:`EventWorkspaces <EventWorkspace>` according to
+the ``SplittersWorkspace`` property. The :ref:`EventFiltering` concept
+page has a detailed introduction to event filtering.
+
+Specifying the splitting strategy
+---------------------------------
+
+The ``SplittersWorkspace`` describes much of the information for
+splitting the ``InputWorkspace`` into the various output
+workspaces. It can have one of three types
+
++--------------------------------------------------------------+-------------+----------+
+| workspace class                                              | units       | rel/abs  |
++==============================================================+=============+==========+
+| :ref:`MatrixWorkspace <MatrixWorkspace>`                     | seconds     | either   |
++--------------------------------------------------------------+-------------+----------+
+| :class:`SplittersWorkspace <mantid.api.ISplittersWorkspace>` | nanoseconds | absolute |
++--------------------------------------------------------------+-------------+----------+
+| :ref:`TableWorkspace <Table Workspaces>`                     | seconds     | either   |
++--------------------------------------------------------------+-------------+----------+
+
+Whether the values in :ref:`MatrixWorkspace <MatrixWorkspace>` and
+:ref:`TableWorkspace <Table Workspaces>` is treated as relative or
+absolute time is dependent on the value of ``RelativeTime``. In the
+case of ``RelativeTime=True``, the time is relative to the start of
+the run (in the ``ws.run()['run_start']``) or, if specified, the
+``FilterStartTime``. In the case of ``RelativeTime=False``, the times
+are relative to the :class:`GPS epoch <mantid.kernel.DateAndTime>`.
+
+Both :ref:`TableWorkspace <Table Workspaces>` and
+:class:`SplittersWorkspace <mantid.api.ISplittersWorkspace>` have 3
+colums, ``start``, ``stop``, and ``target`` which should be a float,
+float, and string. The :ref:`event filtering <EventFiltering>` concept
+page has details on creating the :ref:`TableWorkspace <Table
+Workspaces>` by hand.
+
+If the ``SplittersWorkspace`` is a :ref:`MatrixWorkspace
+<MatrixWorkspace>`, it must have a single spectrum with the x-value is
+the time boundaries and the y-value is the workspace group index.
+
+The optional ``InformationWorkspace`` is a :ref:`TableWorkspace <Table
+Workspaces>` for information of splitters.
 
 Unfiltered Events
-#################
+-----------------
 
 Some events are not inside any splitters. They are put to a workspace
-name ended with '\_unfiltered'.
-
-If input property 'OutputWorkspaceIndexedFrom1' is set to True, then
-this workspace shall not be outputted.
+name ended with ``_unfiltered``. If
+``OutputWorkspaceIndexedFrom1=True``, then this workspace will not be
+created.
 
 Using FilterEvents with fast-changing logs
-##########################################
+------------------------------------------
+
+There are a few parameters to consider when the log filtering is
+expected to produce a large splitter table. An example of such a case
+would be a data file for which the events need to be split according
+to a log with two or more states changing in the kHz range. To reduce
+the filtering time, one may do the following:
+
+- Make sure the ``SplitterWorkspace`` input is a :ref:`MatrixWorkspace
+  <MatrixWorkspace>`. Such a workspace can be produced by using the
+  ``FastLog = True`` option when calling :ref:`GenerateEventsFilter
+  <algm-GenerateEventsFilter>`.
+- Choose the logs to split. Filtering the logs can take a substantial
+  amount of time. To save time, you may want to split only the logs
+  you will need for analysis. To do so, set ``ExcludeSpecifiedLogs =
+  False`` and list the logs you need in
+  ``TimeSeriesPropertyLogs``. For example, if we only need to know the
+  accumulated proton charge for each filtered workspace, we would set
+  ``TimeSeriesPropertyLogs = proton_charge``.
+
+Correcting time neutron was at the sample
+#########################################
+
+When filtering fast logs, the time to filter by is the time that the
+neutron was at the sample. This can be specified using the
+``CorrectionToSample`` parameter. Either the user specifies the
+correction parameter for every pixel, or one is calculated. The
+correction parameters are applied as
+
+.. math::
+
+   TOF_{sample} = TOF_{detector} * scale[detectorID] + shift[detectorID]
+
+and stored in the ``OutputTOFCorrectionWorkspace``.
+
+* ``CorrectionToSample="None"`` applies no correction
+* ``CorrectionToSample="Elastic"`` applies :math:`shift = 0` with
+  :math:`scale = L1/(L1+L2)` for detectors and :math:`scale = L1/L_{monitor}`
+  for monitors
+* ``CorrectionToSample="Direct"`` applies :math:`scale = 0` and
+  :math:`shift = L1 / \sqrt{2 E_{fix} / m_n}`.  The value supplied in
+  ``IncidentEnergy`` will override the value found in the workspace's
+  value of ``Ei``.
+* ``CorrectionToSample="Indirect"`` applies :math:`scale = 1` and
+  :math:`shift = -1 * L2 / \sqrt{2 E_{fix} / m_n}` for detectors. For
+  monitors, uses the same corrections as ``Elastic``.
+
+* ``CorrectionToSample="Customized"`` applies the correction supplied
+  in the ``DetectorTOFCorrectionWorkspace``.
 
-There are a few parameters to consider when the log filtering is expected to produce a large
-splitter table. An example of such a case would be a data file for which the events need to be split
-according to a log with two or more states changing in the kHz range. To reduce the filtering time,
-one may do the following:
-
-- Make sure the ``SplitterWorkspace`` input is a :ref:`MatrixWorkspace <MatrixWorkspace>`. Such a workspace can be produced by using the ``FastLog = True`` option when calling :ref:`GenerateEventsFilter <algm-GenerateEventsFilter>`.
-- Choose the logs to split. Filtering the logs can take a substantial amount of time. To save time, you may want to split only the logs you will need for analysis. To do so, set ``ExcludeSpecifiedLogs = False`` and list the logs you need in ``TimeSeriesPropertyLogs``. For example, if we only need to know the accumulated proton charge for each filtered workspace, we would set ``TimeSeriesPropertyLogs = proton_charge``.
 
 Difference from FilterByLogValue
-################################
-
-In FilterByLogValue(), EventList.splitByTime() is used.
-
-In FilterEvents, if FilterByPulse is selected true,
-EventList.SplitByTime is called; otherwise, EventList.SplitByFullTime()
-is called instead.
-
-The difference between splitByTime and splitByFullTime is that
-splitByTime filters events by pulse time, and splitByFullTime considers
-both pulse time and TOF.
-
-Therefore, FilterByLogValue is not suitable for fast log filtering.
-
-Comparing with other event filtering algorithms
-###############################################
-
-Wiki page :ref:`EventFiltering` has a detailed introduction on event
-filtering in MantidPlot.
-
-
-Developer's Note
-----------------
-
-Splitters given by TableWorkspace
-#################################
-
-- The ``start/stop time`` is converted to ``m_vecSplitterTime``.
-- The splitting target (in string) is mapped to a set of continuous integers that are stored in ``m_vecSplitterGroup``.
-  - The mapping will be recorded in ``m_targetIndexMap`` and ``m_wsGroupIndexTargetMap``.
-  - Class variable ``m_maxTargetIndex`` is set up to record the highest target group/index,i.e., the max value of ``m_vecSplitterGroup``.
-
-
-Undefined splitting target
-##########################
-
-Indexed as ``0`` in m_vecSplitterGroup.
-
+--------------------------------
+
+In :ref:`FilterByLogValue <algm-FilterByLogValue>`,
+``EventList.splitByTime()`` is used. In FilterEvents, it only uses
+this when ``FilterByPulse=True``. Otherwise,
+``EventList.splitByFullTime()`` is used. The difference between
+``splitByTime`` and ``splitByFullTime`` is that ``splitByTime``
+filters events by pulse time, and ``splitByFullTime`` considers both
+pulse time and TOF.
 
 Usage
 -----
diff --git a/docs/source/algorithms/LoadSampleEnvironment-v1.rst b/docs/source/algorithms/LoadSampleEnvironment-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..74d6ba9237259bcc08de7989201f2fcd5884a06e
--- /dev/null
+++ b/docs/source/algorithms/LoadSampleEnvironment-v1.rst
@@ -0,0 +1,25 @@
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+Loads an environment into the sample of a workspace, either replacing the current environment, or adding to it. you may also set a material for the environment to be loaded, this follows the same inputs as :ref:`algm-SetSampleMaterial`.
+
+The following types of input file are supported:
+
+* ``*.stl`` stereolithography `https://en.wikipedia.org/wiki/STL_(file_format) <https://en.wikipedia.org/wiki/STL_(file_format)>`_
+  This is a file format consisting of a list of faces specified by their vertex coordinates.
+  The file may be in ASCII or Binary format, and all the faces must be triangular. 
+  The normals are ignored, but the vertices must be in the order required by the standard 
+  (counter-clockwise when viewed from outside).
+
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
index d4527d6fdbfba4fe4c41c28e33c416768f54787e..7b48ff9752ce23a87403270148a40a1d299a2b02 100644
--- a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
+++ b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
@@ -54,16 +54,16 @@ Usage
 .. testcode:: ExOptimizeCrystalPlacement
 
     ws=LoadIsawPeaks("TOPAZ_3007.peaks")
-    LoadIsawUB(ws,"ls5637.mat")
+    LoadIsawUB(ws,"TOPAZ_3007.mat")
     wsd = OptimizeCrystalPlacement(ws)
-    (wsPeakOut,fitInfoTable,chi2overDoF,nPeaks,nParams,nIndexed,covrianceInfoTable) = OptimizeCrystalPlacement(ws)
+    (wsPeakOut,fitInfoTable,chi2overDoF,nPeaks,nParams,nIndexed,covrianceInfoTable) = OptimizeCrystalPlacement(ws,AdjustSampleOffsets=True)
     print("Chi2: {:.4f}".format(chi2overDoF))
 
 Output:
 
 .. testoutput:: ExOptimizeCrystalPlacement
 
-    Chi2: 0.0203
+    Chi2: 0.0003
 
 .. categories::
 
diff --git a/docs/source/algorithms/Rebin2D-v1.rst b/docs/source/algorithms/Rebin2D-v1.rst
index dda2cdb3205dd0beb75d97adf3cdb69925504170..f27fe831c1129d565a547a23d069e14b9854a33d 100644
--- a/docs/source/algorithms/Rebin2D-v1.rst
+++ b/docs/source/algorithms/Rebin2D-v1.rst
@@ -24,6 +24,12 @@ where :math:`F_i = A^{\mathrm{overlap}}_i / A^{\mathrm{old}}_i` is the
 ratio of the overlap area of the new and old bin over the area of the
 old bin.
 
+If the input workspace is not of type: **RebinnedOutput**, and the
+`UseFractionalArea` option is set to `True`, the algorithm
+will assume that the input fraction is unity. This is correct if this
+workspace has not been previously rebinned, but will give incorrect
+error (standard deviation) estimates if it has been rebinned.
+
 Requirements
 ------------
 
diff --git a/docs/source/algorithms/SaveReflectometryAscii-v1.rst b/docs/source/algorithms/SaveReflectometryAscii-v1.rst
index e3409a6f1f724c87c9f93b7cc4d2631b435df277..86cdf54a3b94bbe718801bff40aad332e446d208 100644
--- a/docs/source/algorithms/SaveReflectometryAscii-v1.rst
+++ b/docs/source/algorithms/SaveReflectometryAscii-v1.rst
@@ -17,6 +17,7 @@ In case of histogrammed input data, the resulting file will contain the bin cent
 It is especially useful for saving reflectometry reduction data.
 A file can be loaded back into Mantid by :ref:`algm-LoadAscii`, which will not have an instrument defined and `Sample Logs` are missing.
 This algorithm writes data in scientific exponential notation (E-notation) of double-precision.
+Please note that `SampleLog` entries are not case sensitive, editing fields `Title` and `title` both edit the field `title`.
 
 Computation of resolution values
 --------------------------------
@@ -34,6 +35,7 @@ The file contains minimum 21 header lines each separating its name and value by
 The header lines contain the following information: `Instrument`, `User-local contact`, `Title`, `Subtitle`, `Start date + time`, `End date + time`, `Theta 1 + dir + ref numbers`, `Theta 2 + dir + ref numbers`, `Theta 3 + dir + ref numbers`, (foreseen potentially added angle(s),) followed by 9 user defined parameter lines, followed by potentially added user defined parameter lines, `Number of file format`, `Number of data points`.
 The version of the file format is set randomly to the high value 40 in order to exceed all ILL Cosmos versions.
 For the ILL instruments D17 and FIGARO, obligatory header lines will be automatically filled by using the workspaces `Sample Logs` information which can be modified as shown in the `Usage`_.
+The algorithm seeks to add the values for the following SampleLog entries: `instrument.name`, `user.namelocalcontact`, `title`, `start_time` and `end_time` which correspond to the header lines of names `Instrument`, `User-local contact`, `Title`, `Start date + time`, `End date + time`, respectively.
 The options `WriteHeader`, `WriteResolution` and `Separator` do not have any effect and are not visible in the user interface.
 
 TXT File Format
@@ -80,14 +82,14 @@ Usage
     file = os.path.join(os.path.expanduser("~"), "ws")
 
     # Add Sample Log entries
-    # Add a Title entry which will be automatically used
-    AddSampleLog(Workspace=ws, LogName='Title', LogText='MyTest', LogType='String')
+    # Add a Title entry:
+    AddSampleLog(Workspace=ws, LogName='title', LogText='MyTest', LogType='String')
     # Add an entry called d as a Parameter (then, only eight not defined parameter lines remain):
     AddSampleLog(Workspace=ws, LogName='d', LogText='0.3', LogType='Number', LogUnit='mm', NumberType='Double')
 
-    # Save with mft extension and using the option LogList: Title will be added to a required header line and d will be additionally added
+    # Save with mft extension and using the option LogList: title will be added to a required header line and d will be additionally added
     # to the first parameter field.
-    SaveReflectometryAscii(InputWorkspace=ws, Filename=file, LogList=['Title', 'd'])
+    SaveReflectometryAscii(InputWorkspace=ws, Filename=file, LogList=['title', 'd'])
 
     if os.path.exists(file + ".mft"):
       myFile = open((file + ".mft"), 'r')
@@ -106,7 +108,7 @@ Usage
    Theta 1 + dir + ref numbers : Not defined
    Theta 2 + dir + ref numbers : Not defined
    Theta 3 + dir + ref numbers : Not defined
-   d : 0.29999999999999999
+   d : 0.29999999999999999 mm
    Parameter  : Not defined
    Parameter  : Not defined
    Parameter  : Not defined
diff --git a/docs/source/algorithms/SetCrystalLocation-v1.rst b/docs/source/algorithms/SetCrystalLocation-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..114fb8d9e3297278a3e242ce56eaf29bd0867a1b
--- /dev/null
+++ b/docs/source/algorithms/SetCrystalLocation-v1.rst
@@ -0,0 +1,36 @@
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm changes the sample location for an events workspace.  If the InputWorkspace and OutputWorkspace are the same, the position is simply changed.  If the InputWorkspace and OutputWorkspace are different, the InputWorkspace is cloned then the clone's position is changed.  The former is faster, especially for large workspaces. 
+
+Usage
+-----
+
+**Example:**
+
+.. testcode:: ExSetCrystalLocation
+
+  events = Load('BSS_11841_event.nxs')
+  sample = mtd['events'].getInstrument().getSample()
+  print('Sample position before SetCrystalLocation: {}'.format(sample.getPos()))
+  SetCrystalLocation(InputWorkspace=events, OutputWorkspace=events, NewX=0.1, NewY=0.1, NewZ=0.1)
+  print('Sample position after SetCrystalLocation: {}'.format(sample.getPos()))
+
+Output:
+
+.. testoutput:: ExSetCrystalLocation
+
+  Sample position before SetCrystalLocation: [0,0,0]
+  Sample position after SetCrystalLocation: [0.1,0.1,0.1]
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/SetSample-v1.rst b/docs/source/algorithms/SetSample-v1.rst
index ca36b085e2965ba238a672e63cf0ce0eeb73bf61..b30e5b18137c4c23dbe00de3b0664345e84114e4 100644
--- a/docs/source/algorithms/SetSample-v1.rst
+++ b/docs/source/algorithms/SetSample-v1.rst
@@ -22,6 +22,10 @@ The 3 arguments to this algorithm ``Environment``, ``Geometry`` and
 dictionaries specifying multiple parameters that relate to the
 respective argument.
 
+.. note:: Contrary to the :ref:`xml forms of defining the geometry
+          <HowToDefineGeometricShape>` which are in metres,
+          :py:obj:`dict` versions are in centimetres.
+
 Environment
 ###########
 
diff --git a/docs/source/algorithms/SetSampleMaterial-v1.rst b/docs/source/algorithms/SetSampleMaterial-v1.rst
index af4760a9cb00987720ecc38ef96cf7fc48686085..3e1cd2a577659918740ec76aa51bde791ddc3ecc 100644
--- a/docs/source/algorithms/SetSampleMaterial-v1.rst
+++ b/docs/source/algorithms/SetSampleMaterial-v1.rst
@@ -10,109 +10,17 @@ Description
 -----------
 
 Sets the neutrons information in the sample. You can either enter
-details about the chemical formula or atomic number, or you can provide
-specific values for the attenuation and scattering cross sections and
-the sample number density. If you decide to provide specific values you
-must give values for all three (attenuation and scattering cross
-sections and the sample number density), and any formula information
-will be ignored. If you miss any of the three specific values then the
-other will be ignored.
-
-Neutron scattering lengths and cross sections of the elements and their
-isotopes have been taken from
-`NIST <http://www.ncnr.nist.gov/resources/n-lengths/list.html>`__.
-
-Chemical Composition with Examples
-##################################
-- ``H2 O`` - Isotopically averaged Hydrogen
-- ``(H2)2 O`` - Heavy water
-- ``D2 O`` - Another way to specify heavy water
-
-Enter a composition as a molecular formula of elements or isotopes.
-For example, basic elements might be ``H``, ``Fe`` or ``Si``, etc.
-A molecular formula of elements might be ``H4-N2-C3``, which
-corresponds to a molecule with 4 Hydrogen atoms, 2 Nitrogen atoms and
-3 Carbon atoms.  Each element in a molecular formula is followed by
-the number of the atoms for that element, specified **without a hyphen**,
-because each element is separated from other elements using a hyphen.
-
-The number of atoms can be integer or float, but must start with a
-digit, e.g. 0.6 is fine but .6 is not. This can be used to set elemental ratios
-within a chemical composition. For example 95.1% Vanadium 4.9% Niobium can be
-expressed as ``V0.951 Nb0.049``. *Warning: Using this representation will
-calculate all properties except for SampleNumberDensity which must be
-set manually if required*
-
-Isotopes may also be included in a :py:obj:`material
-<mantid.kernel.Material>` composition, and can be specified alone (as
-in ``Li7``), or in a molecular formula (as in ``(Li7)2-C-H4-N-Cl6``).
-Note, however, that No Spaces or Hyphens are allowed in an isotope
-symbol specification. Also Note that for isotopes specified in a
-molecular expression, the isotope must be enclosed by parenthesis,
-except for two special cases, ``D`` and ``T``, which stand for ``H2``
-and ``H3``, respectively.
-
-Cross Section Calculations
-##########################
-
-Each of the cross sections (:math:`\sigma`) are calculated according to
-
-.. math:: \sigma = \frac{1}{N_{atoms}}\sum_{i}\sigma_{i}n_{i}
-
-where :math:`N_{atoms} = \sum_{i}n_{i}`. A concrete example for the total
-cross section of ``D2 O``
-
-.. math:: \sigma = \frac{1}{2+1}\left( 7.64*2 + 4.232*1\right) = 6.504\ barns
-
-Number Density
-##############
-
-The number density is defined as
-
-.. math:: \rho_n = \frac{N_{atoms}ZParameter}{UnitCellVolume}
-
-It can can be generated in one of three ways:
-
-1. Specifying it directly with ``SampleNumberDensity``.
-2. Specifying the ``ZParameter`` and the ``UnitCellVolume`` (or letting
-   the algorithm calculate it from the OrientedLattice on the
-   ``InputWorkspace``).
-3. Specifying the mass density. In this case the number density is calculated as
-
-.. math:: \rho_n = \frac{N_{atoms} \rho_m N_A}{M_r}
-
-where :math:`\rho_m` is the mass density, :math:`N_A` is the Avogadro constant, and :math:`M_r` the relative molecular mass.
-
-Linear Absorption Coefficients
-##############################
-
-.. math:: \mu_s = \rho_n \frac{1}{N_{atoms}}\sum_{i}s_{i}n_{i} \text{ units of 1/cm}
-.. math:: s = \sigma_{total scattering}
-.. math:: \mu_a = \rho_n \frac{1}{N_{atoms}}\sum_{i}a_{i}n_{i} \text{ units of 1/cm}
-.. math:: a = \sigma_{absorption} (\lambda=1.8)
-
-A detailed version of this is found in [2].
-
-Normalized Laue
-###############
-
-The low-:math:`Q` limit of :math:`S(Q)` is :math:`-L` where :math:`L` is called the normalized Laue term
-
-.. math:: bAverage = <b_{coh}> = \frac{1}{N_{atoms}}\sum_{i}b_{coh,i}
-.. math:: bSquaredAverage = <b_{tot}^2> = \frac{1}{N_{atoms}}\sum_{i}b_{tot,i}^2
-.. math:: L = \frac{<b_{tot}^2>-<b_{coh}>^2}{<b_{coh}>^2}
-
-References
-----------
-
-The data used in this algorithm comes from the following paper.
-
-#. Varley F. Sears, *Neutron scattering lengths and cross sections*, Neutron News **3:3** (1992) 26
-   `doi: 10.1080/10448639208218770 <http://dx.doi.org/10.1080/10448639208218770>`_
-#. J. A. K. Howard, O. Johnson, A. J. Schultz and A. M. Stringer, *Determination of the neutron
-   absorption cross section for hydrogen as a function of wavelength with a pulsed neutron
-   source*, J. Appl. Cryst. (1987). 20, 120-122
-   `doi: 10.1107/S0021889887087028 <http://dx.doi.org/10.1107/S0021889887087028>`_
+details about the chemical formula or atomic number, or you can
+provide specific values for the attenuation and scattering cross
+sections and the sample number density. If you decide to provide
+specific values you must give values for all three (attenuation and
+scattering cross sections and the sample number density), and any
+formula information will be ignored. If you miss any of the three
+specific values then the other will be ignored. For details of how the
+various quantities are calculated, refer to the :ref:`Materials`
+concept page.
+
+.. note:: It is recommended that you use :ref:`SetSample <algm-SetSample>` instead.
 
 .. categories::
 
diff --git a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
index c53256425cb77e93e359f54406064e57e344bf98..70c3c34a4b1ffca081795ca28bc76386a78e7217 100644
--- a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
+++ b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
@@ -30,7 +30,7 @@ Usage
     stats = StatisticsOfTableWorkspace(ws)
 
     for idx in range(stats.rowCount()):
-        stat_name = stats.column('statistic')[idx]
+        stat_name = stats.column('Statistic')[idx]
         stat_value = stats.column('a')[idx]
         print('%s of column \'a\' is %.3f' % (stat_name, stat_value))
 
@@ -38,11 +38,11 @@ Output:
 
 .. testoutput:: ExStatisticsOfTableWorkspace
 
-    standard_deviation of column 'a' is 1.118
-    minimum of column 'a' is 1.000
-    median of column 'a' is 2.500
-    maximum of column 'a' is 4.000
-    mean of column 'a' is 2.500
+    StandardDev of column 'a' is 1.118
+    Minimum of column 'a' is 1.000
+    Median of column 'a' is 2.500
+    Maximum of column 'a' is 4.000
+    Mean of column 'a' is 2.500
 
 .. categories::
 
diff --git a/docs/source/algorithms/WeightedMean-v1.rst b/docs/source/algorithms/WeightedMean-v1.rst
index ac5a7caa55b9c8472a7d4ab487c2b0e9d82d344e..c67687674c0048643817a118eefe939bbdad9201 100644
--- a/docs/source/algorithms/WeightedMean-v1.rst
+++ b/docs/source/algorithms/WeightedMean-v1.rst
@@ -9,9 +9,17 @@
 Description
 -----------
 
-The algorithm calculates the weighted mean of two workspaces. This is useful when working with distributions rather than histograms, particularly when counting statistics are poor and it is possible that the value of one data set is statistically insignificant but differs greatly from the other. In such a case simply calculating the average of the two data sets would produce a spurious result. This algorithm will eventually be modified to take a list of workspaces as an input.
+The algorithm calculates the weighted mean of two workspaces. This is useful when working with distributions rather than histograms, particularly when counting statistics are poor and it is possible that the value of one data set is statistically insignificant but differs greatly from the other. In such a case simply calculating the average of the two data sets would produce a spurious result.
+If each input workspace and the standard deviation are labelled :math:`w_i` and :math:`sigma_i`, respectively, and there
+are *N* workspaces then the weighted mean is computed as:
 
-:math:`y=\frac{\sum\frac{x_i}{\sigma^{2}_i}}{\sum\frac{1}{\sigma^{2}_i}}`
+.. math::
+
+   m = \frac{\sum_{i=0}^{N-1}\frac{w_i}{\sigma^{2}_i}}{\sum_{i=0}^{N-1}\frac{1}{\sigma^{2}_i}}
+
+where *m* is the output workspace. The *x* values are copied from the first input workspace.
+
+The input workspaces must be compatible with respect to size, units, and whether they are distributions or not.
 
 Usage
 -----
diff --git a/docs/source/concepts/EventFiltering.rst b/docs/source/concepts/EventFiltering.rst
index d86f072e1dbd1578c81e99ca95cd0bd21b04c47a..c77137bbefa98cf7fbd1e2437740ac4bec866820 100644
--- a/docs/source/concepts/EventFiltering.rst
+++ b/docs/source/concepts/EventFiltering.rst
@@ -7,86 +7,117 @@ Event Filtering
 .. contents::
    :local:
 
-In MantidPlot, there are a few algorithms working with event
-filtering.  These algorithms are :ref:`algm-FilterByTime`,
-:ref:`algm-FilterByLogValue`, :ref:`algm-FilterEvents`, and
-:ref:`algm-GenerateEventsFilter`.
+In mantid, there are a variety of ways to filter events that are in an
+:ref:`EventWorkspace`. They are :ref:`FilterByTime
+<algm-FilterByTime>` and :ref:`FilterByLogValue
+<algm-FilterByLogValue>` which will create a filter and apply it in a
+single step. The other way to filter events is to use
+:ref:`FilterEvents <algm-FilterEvents>` which allows for a variety of
+workspaces to specify how an :ref:`EventWorkspace` is split. This
+document focuses on how the create these workspaces and will largely
+ignore :ref:`FilterByTime <algm-FilterByTime>` and
+:ref:`FilterByLogValue <algm-FilterByLogValue>`.
 
 How to generate event filters
 =============================
 
-Generating filters explicitly
------------------------------
-
-:ref:`algm-FilterEvents` reads and parses a
-:class:`mantid.api.ISplittersWorkspace` object to generate a list of
-:ref:`SplittingIntervals <SplittingInterval>`, which are used to split
-neutron events to specified output workspaces according to the times
-that they arrive detectors.
-
-There can be two approaches to create a
-:class:`mantid.api.ISplittersWorkspace`.
-
-* :ref:`algm-GenerateEventsFilter` generate event filters by either by
-  time or log value.  The output filters are stored in a
-  :ref:`SplittersWorkspace`, which is taken as an input property of
-  :ref:`algm-FilterEvents`.
-
-* Users can create a :class:`mantid.api.ISplittersWorkspace` from scrach from Python
-  script, because :class:`mantid.api.ISplittersWorkspace` inherits from
-  :ref:`TableWorkspace <Table Workspaces>`.
-
-Generating inexplicit filters
------------------------------
-
-:ref:`algm-FilterByTime` and :ref:`algm-FilterByLogValue` generate event filters during execution.
-
-* :ref:`algm-FilterByTime` generates a set of :ref:`SplittingInterval`
-  according to user-specified setup for time splicing;
-
-* :ref:`algm-FilterByLogValue` generates a set of
-  :ref:`SplittingInterval` according to the value of a specific sample
-  log.
-
-:ref:`algm-GenerateEventsFilter` and :ref:`algm-FilterEvents` vs :ref:`algm-FilterByTime` and :ref:`algm-FilterByLogValue`
---------------------------------------------------------------------------------------------------------------------------
-
-* If :ref:`algm-GenerateEventsFilter` and :ref:`algm-FilterEvents` are
-  set up correctly, they can have the same functionality as
-  :ref:`algm-FilterByTime` and :ref:`algm-FilterByLogValue`.
-
-* :ref:`algm-FilterEvents` is able to filter neutron events by either
-  their pulse times or their absolute times.  An neutron event's
-  absolute time is the summation of its pulse time and TOF.
-
-* :ref:`algm-FilterByLogValue` and :ref:`algm-FilterByTime` can only
-  split neutron events by their pulse time.
-
-Types of events filters
-=======================
-
-Filtering by :ref:`SplittingInterval`
--------------------------------------
-
-:ref:`SplittingInterval` is an individual class to indicate an
-independent time splitter.  Any event can be filtered by a
-:ref:`SplittingInterval` object.
-
-:ref:`SplittersWorkspace` is a :ref:`TableWorkspace <Table
-Workspaces>` that stors a set of :ref:`SplittingInterval`.
-
-Filtering by duplicate entries/booleans
----------------------------------------
-
-Duplicate entries in a :ref:`TimeSeriesProperty` and boolean type of
-:ref:`TimeSeriesProperty` are used in MantidPlot too to serve as time
-splitters.
-
-These two are applied in the MantidPlot log viewing functionality and
-unfortunately intrudes into :ref:`TimeSeriesProperty`.
-
-As time splitters are better to be isolated from logs, which are
-recorded in :ref:`TimeSeriesProperty`, it is not
-recommended to set up event filters by this approach.
+Implicit filters
+----------------
+
+:ref:`algm-FilterByTime` and :ref:`algm-FilterByLogValue` internally
+generate event filters during execution that are not exposed to the
+user. These algorithms can only split the neutron events by pulse
+time and do not provide the equivalent of a ``FastLog=True`` option.
+
+Explicit filters
+----------------
+
+:ref:`algm-FilterEvents` takes either a :class:`SplittersWorkspace
+<mantid.api.ISplittersWorkspace>`, :ref:`TableWorkspace <Table
+Workspaces>`, or :ref:`MatrixWorkspace <MatrixWorkspace>` as the
+``SplittersWorkspace``. The events are split into output workspaces
+according to the times that they arrive detectors.
+
+:ref:`GenerateEventsFilter <algm-GenerateEventsFilter>` will create a
+:class:`SplittersWorkspace <mantid.api.ISplittersWorkspace>` based on
+its various options. This result can be supplied as the
+``SplittersWorkspace`` input property of ref:`algm-FilterEvents`. It
+will also generate an ``InformationWorkspace`` which can be passed
+along to :ref:`GenerateEventsFilter <algm-GenerateEventsFilter>`.
+Depending on the parameters in :ref:`GenerateEventsFilter
+<algm-GenerateEventsFilter>`, the events will be filtered based on
+their pulse times or their absolute times.  An neutron event's
+absolute time is the summation of its pulse time and TOF.
+
+Custom event filters
+====================
+
+Sometimes one wants to filter events based on arbitrary conditions. In
+this case, one needs to go beyond what existing algorithms can do. For
+this, one must generate their own splitters workspace. The workspace
+is generally 3 columns, with the first two being start and stop times
+and the third being the workspace index to put the events into. For
+filtering with time relative to the start of the run, the first two
+columns are ``float``. To specify the times as absolute, in the case
+of filtering files that will be summed together, the first two columns
+should be ``int64``. For both of the examples below, the filter
+workspaces are created using the following function:
+
+.. code-block:: python
+
+   def create_table_workspace(table_ws_name, column_def_list):
+      CreateEmptyTableWorkspace(OutputWorkspace=table_ws_name)
+      table_ws = mtd[table_ws_name]
+      for col_tup in column_def_list:
+          data_type = col_tup[0]
+          col_name = col_tup[1]
+          table_ws.addColumn(data_type, col_name)
+
+      return table_ws
+
+Relative time
+-------------
+
+The easiest way to generate a custom event filter is to make one
+relative to the start time of the run or relative to a specified
+epoch. As the times in the table are seconds, a table can be created
+and used
+
+.. code-block:: python
+
+   filter_rel = create_table_workspace('custom_relative', [('float', 'start'), ('float', 'stop'), ('str', 'target')])
+   filter_rel.addRow((0,9500, '0'))
+   filter_rel.addRow((9500,19000, '1'))
+   FilterEvents(InputWorkspace='ws', SplitterWorkspace=filter_rel,
+                GroupWorkspaces=True, OutputWorkspaceBaseName='relative', RelativeTime=True)
+
+This will generate an event filter relative to the start of the
+run. Specifying the ``FilterStartTime`` in :ref:`FilterEvents
+<algm-FilterEvents>`, one can specify a different time that filtering
+will be relative to.
+
+Absolute time
+-------------
+
+If instead a custom filter is to be created with absolute time, the
+time must be processed somewhat to go into the table workspace. Much of the
+
+.. code-block:: python
+
+   abs_times = [datetime64('2014-12-12T09:11:22.538096666'), datetime64('2014-12-12T11:45:00'), datetime64('2014-12-12T14:14:00')]
+   # convert to time relative to GPS epoch
+   abs_times = [time - datetime64('1990-01-01T00:00') for time in abs_times]
+   # convert to number of seconds
+   abs_times = [float(time / timedelta64(1, 's')) for time in abs_times]
+
+   filter_abs = create_table_workspace('custom_absolute', [('float', 'start'), ('float', 'stop'), ('str', 'target')])
+   filter_abs.addRow((abs_times[0], abs_times[1], '0'))
+   filter_abs.addRow((abs_times[1], abs_times[2], '1'))
+   FilterEvents(InputWorkspace='PG3_21638', SplitterWorkspace=filter_abs,
+                GroupWorkspaces=True, OutputWorkspaceBaseName='absolute', RelativeTime=False)
+
+Be warned that specifying ``RelativeTime=True`` with a table full of
+absolute times will almost certainly generate output workspaces
+without any events in them.
 
 .. categories:: Concepts
diff --git a/docs/source/concepts/FitFunctionsInPython.rst b/docs/source/concepts/FitFunctionsInPython.rst
index af1f53d3fe63fb4bd48b2e6daa661137673f10b7..6ba7ef2b30e8bff89806910a1582ded4f996ceca 100644
--- a/docs/source/concepts/FitFunctionsInPython.rst
+++ b/docs/source/concepts/FitFunctionsInPython.rst
@@ -204,6 +204,21 @@ Also one can put parameters into the function when evaluating.
 
 This enables one to fit the functions with ``scipy.optimize.curve_fit``.  
 
+Errors
+------
+
+The errors assoicated with a given parameter can be accessed using the ``getError`` method.
+``getError`` takes either the parameter name or index as input. For example to get the error
+on ``A1`` in the above polynomial, the code is:
+
+.. code:: python
+
+    # Find the parameter error by index
+    error_A1 = p.getError(1)
+    # Find the parameter error by name
+    error_A1 = p.getError('A1')
+
+
 Plotting
 --------
 Functions may be plotted by calling the ``plot`` method of the function.
diff --git a/docs/source/concepts/Materials.rst b/docs/source/concepts/Materials.rst
new file mode 100644
index 0000000000000000000000000000000000000000..58ea2cfc42990d5049bbee41878eefaca8816426
--- /dev/null
+++ b/docs/source/concepts/Materials.rst
@@ -0,0 +1,104 @@
+.. _Materials:
+
+Materials
+=========
+
+.. contents::
+
+Neutron scattering lengths and cross sections of the elements and their
+isotopes have been taken from
+`NIST <http://www.ncnr.nist.gov/resources/n-lengths/list.html>`__.
+
+Chemical Composition with Examples
+##################################
+- ``H2 O`` - Isotopically averaged Hydrogen
+- ``(H2)2 O`` - Heavy water
+- ``D2 O`` - Another way to specify heavy water
+
+Enter a composition as a molecular formula of elements or isotopes.
+For example, basic elements might be ``H``, ``Fe`` or ``Si``, etc.
+A molecular formula of elements might be ``H4-N2-C3``, which
+corresponds to a molecule with 4 Hydrogen atoms, 2 Nitrogen atoms and
+3 Carbon atoms.  Each element in a molecular formula is followed by
+the number of the atoms for that element, specified **without a hyphen**,
+because each element is separated from other elements using a hyphen.
+
+The number of atoms can be integer or float, but must start with a
+digit, e.g. 0.6 is fine but .6 is not. This can be used to set elemental ratios
+within a chemical composition. For example 95.1% Vanadium 4.9% Niobium can be
+expressed as ``V0.951 Nb0.049``. *Warning: Using this representation will
+calculate all properties except for SampleNumberDensity which must be
+set manually if required*
+
+Isotopes may also be included in a :py:obj:`material
+<mantid.kernel.Material>` composition, and can be specified alone (as
+in ``(Li7)``), or in a molecular formula (as in ``(Li7)2-C-H4-N-Cl6``).
+Note, however, that No Spaces or Hyphens are allowed in an isotope
+symbol specification. Also Note that for isotopes specified in a
+molecular expression, the isotope must be enclosed by parenthesis,
+except for two special cases, ``D`` and ``T``, which stand for ``H2``
+and ``H3``, respectively.
+
+Cross Section Calculations
+##########################
+
+Each of the cross sections (:math:`\sigma`) are calculated according to
+
+.. math:: \sigma = \frac{1}{N_{atoms}}\sum_{i}\sigma_{i}n_{i}
+
+where :math:`N_{atoms} = \sum_{i}n_{i}`. A concrete example for the total
+cross section of ``D2 O``
+
+.. math:: \sigma = \frac{1}{2+1}\left( 7.64*2 + 4.232*1\right) = 6.504\ barns
+
+Number Density
+##############
+
+The number density is defined as
+
+.. math:: \rho_n = \frac{N_{atoms}ZParameter}{UnitCellVolume}
+
+It can can be generated in one of three ways:
+
+1. Specifying it directly with ``SampleNumberDensity``.
+2. Specifying the ``ZParameter`` and the ``UnitCellVolume`` (or letting
+   the algorithm calculate it from the OrientedLattice on the
+   ``InputWorkspace``).
+3. Specifying the mass density. In this case the number density is calculated as
+
+.. math:: \rho_n = \frac{N_{atoms} \rho_m N_A}{M_r}
+
+where :math:`\rho_m` is the mass density, :math:`N_A` is the Avogadro constant, and :math:`M_r` the relative molecular mass.
+
+Linear Absorption Coefficients
+##############################
+
+.. math:: \mu_s = \rho_n \frac{1}{N_{atoms}}\sum_{i}s_{i}n_{i} \text{ units of 1/cm}
+.. math:: s = \sigma_{total scattering}
+.. math:: \mu_a = \rho_n \frac{1}{N_{atoms}}\sum_{i}a_{i}n_{i} \text{ units of 1/cm}
+.. math:: a = \sigma_{absorption} (\lambda=1.8)
+
+A detailed version of this is found in [2].
+
+Normalized Laue
+###############
+
+The low-:math:`Q` limit of :math:`S(Q)` is :math:`-L` where :math:`L` is called the normalized Laue term
+
+.. math:: bAverage = <b_{coh}> = \frac{1}{N_{atoms}}\sum_{i}b_{coh,i}
+.. math:: bSquaredAverage = <b_{tot}^2> = \frac{1}{N_{atoms}}\sum_{i}b_{tot,i}^2
+.. math:: L = \frac{<b_{tot}^2>-<b_{coh}>^2}{<b_{coh}>^2}
+
+References
+----------
+
+The data used in this algorithm comes from the following paper.
+
+#. Varley F. Sears, *Neutron scattering lengths and cross sections*, Neutron News **3:3** (1992) 26
+   `doi: 10.1080/10448639208218770 <http://dx.doi.org/10.1080/10448639208218770>`_
+#. J. A. K. Howard, O. Johnson, A. J. Schultz and A. M. Stringer, *Determination of the neutron
+   absorption cross section for hydrogen as a function of wavelength with a pulsed neutron
+   source*, J. Appl. Cryst. (1987). 20, 120-122
+   `doi: 10.1107/S0021889887087028 <http://dx.doi.org/10.1107/S0021889887087028>`_
+
+.. categories:: Concepts
diff --git a/docs/source/concepts/SampleEnvironment.rst b/docs/source/concepts/SampleEnvironment.rst
index 48ed51a372bce2dfc35ff964ac12cf82a8943e59..8cc1f99d7fbe1c6cafbdb6f5a55a755a2b2dfd00 100644
--- a/docs/source/concepts/SampleEnvironment.rst
+++ b/docs/source/concepts/SampleEnvironment.rst
@@ -16,9 +16,11 @@ Specification
 
 A sample environment is defined by:
 
-- one or more available containers, each with a defined geometry & composition
-- optional additional components that will be in the beam, each with their own
-  geometry and composition.
+- one or more available containers, each with a defined :ref:`geometry
+  <HowToDefineGeometricShape>` and :ref:`composition <Materials>`
+- optional additional components that will be in the beam, each with
+  their own :ref:`geometry <HowToDefineGeometricShape>` and
+  :ref:`composition <Materials>`
 
 At a minimum a sample environment is expected to define a container with both its
 geometry and composition.
@@ -71,17 +73,17 @@ is used to reference the material when defining a container or component.
 The other attributes define the properties of the material. The allowed attributes
 map to the arguments of a similar name on the :ref:`SetSampleMaterial <algm-SetSampleMaterial>` algorithm
 
-- formula
-- atomicnumber
-- massnumber
-- numberdensity
-- zparameter
-- unitcellvol
-- massdensity
-- totalscatterxsec
-- cohscatterxsec
-- incohscatterxsec
-- absorptionxsec
+- ``formula``
+- ``atomicnumber``
+- ``massnumber``
+- ``numberdensity``
+- ``zparameter``
+- ``unitcellvol``
+- ``massdensity``
+- ``totalscatterxsec``
+- ``cohscatterxsec``
+- ``incohscatterxsec``
+- ``absorptionxsec``
 
 Non-container Components
 ------------------------
diff --git a/docs/source/images/sans_isis_save_options.png b/docs/source/images/sans_isis_save_options.png
new file mode 100644
index 0000000000000000000000000000000000000000..6eacfa6ae22c96b406d47feb4c1d209879cbd6c5
Binary files /dev/null and b/docs/source/images/sans_isis_save_options.png differ
diff --git a/docs/source/images/save_other.png b/docs/source/images/save_other.png
new file mode 100644
index 0000000000000000000000000000000000000000..5813f9e7644b083170b3274332f63d5b1336f2f8
Binary files /dev/null and b/docs/source/images/save_other.png differ
diff --git a/docs/source/interfaces/ISIS SANS v2.rst b/docs/source/interfaces/ISIS SANS v2.rst
index fd8e0d32e655dc54948557cc70c5b9cccce98a77..48e32085d809e6855abf90d123c3b4f63c749f4f 100644
--- a/docs/source/interfaces/ISIS SANS v2.rst	
+++ b/docs/source/interfaces/ISIS SANS v2.rst	
@@ -104,21 +104,23 @@ Columns
 Save Options
 ^^^^^^^^^^^^
 
-.. image::  ../images/sans_isis_v2_run_tab_save_options.png
+.. image::  ../images/sans_isis_save_options.png
    :align: center
-   :width: 300px
-
+   :width: 500px
 
 +-------+--------------------------+-----------------------------------------------------------------------------------------+
-| **1** | **Save location**        | This sets where the reduced data will be made available for the user. The user          |
+| **1** | **Save Other**           | Opens up the save other dialog box :ref:`Save Other <save-other>` which allows          |
+|       |                          | for manual saving of reduced data.                                                      |
++-------+--------------------------+-----------------------------------------------------------------------------------------+
+| **2** | **Save location**        | This sets where the reduced data will be made available for the user. The user          |
 |       |                          | can select to have it only in memory (RAM) with the **Memory** option, saved out as     |
 |       |                          | a file with the **File** option or saved both to file and memory with the **Both**      |
 |       |                          | option.                                                                                 |
 +-------+--------------------------+-----------------------------------------------------------------------------------------+
-| **2** | **Save file formats**    | Allows the user to specify the save file format for the reduced data.                   |
+| **3** | **Save file formats**    | Allows the user to specify the save file format for the reduced data.                   |
 |       |                          |                                                                                         |
 +-------+--------------------------+-----------------------------------------------------------------------------------------+
-| **3** | **Other**                | The **zero error free** option ensures that zero error entries get artificially         |
+| **4** | **Other**                | The **zero error free** option ensures that zero error entries get artificially         |
 |       |                          | inflated when the data is saved to a file. This is beneficial if the data is to be      |
 |       |                          | loaded into other analysis software.                                                    |
 |       |                          | The **Use optimizations** option will reuse already loaded data. This can speed up the  |
diff --git a/docs/source/interfaces/Indirect Data Analysis.rst b/docs/source/interfaces/Indirect Data Analysis.rst
index 93183a1838f8d8be13a8a1dc7b213d02dba30fde..fb973384c7b173f4f4c04aa3a56a937cc1b0ce48 100644
--- a/docs/source/interfaces/Indirect Data Analysis.rst	
+++ b/docs/source/interfaces/Indirect Data Analysis.rst	
@@ -1,4 +1,4 @@
-Indirect Data Analysis
+Indirect Data Analysis
 ======================
 
 .. contents:: Table of Contents
@@ -93,8 +93,10 @@ SE log value
   specified value in the instrument parameters file, and in the absence of such
   specification, defaults to "last value")
 
-Plot Result
-  If enabled will plot the result as a spectra plot.
+Plot Spectrum
+  If enabled it will plot the spectrum represented by the workspace index in the 
+  neighbouring spin box. This workspace index is the index of the spectrum within the 
+  workspace selected in the combobox.
 
 Save Result
   If enabled the result will be saved as a NeXus file in the default save
@@ -178,11 +180,16 @@ Save Result
   directory.
   
 Tiled Plot
-  Produces a tiled plot of the output workspaces generated.
+  Produces a tiled plot of spectra included within the range for the output workspaces 
+  generated. There is a maximum of 18 spectra allowed for a tiled plot. 
 
 Monte Carlo Error Calculation - Number Of Iterations
-  The number of iterations to perform in the Monte Carlo routine for error
-  calculation in I(Q,t)
+  The number of iterations to perform in the Monte Carlo routine for error calculation 
+  in I(Q,t). 
+
+Monte Carlo Error Calculation - Calculate Errors
+  The calculation of errors using a Monte Carlo implementation can be skipped by ticking 
+  the Calculate Errors checkbox.
 
 A note on Binning
 ~~~~~~~~~~~~~~~~~
@@ -271,11 +278,11 @@ Options
 
 Sample
   Either a reduced file (*_red.nxs*) or workspace (*_red*) or an :math:`S(Q,
-  \omega)` file (*_sqw.nxs*) or workspace (*_sqw*).
+  \omega)` file (*_sqw.nxs*, *_sqw.dave*) or workspace (*_sqw*).
 
 Resolution
   Either a resolution file (_res.nxs) or workspace (_res) or an :math:`S(Q,
-  \omega)` file (*_sqw.nxs*) or workspace (*_sqw*).
+  \omega)` file (*_sqw.nxs*, *_sqw.dave*) or workspace (*_sqw*).
 
 Use Delta Function
   Found under 'Custom Function Groups'. Enables use of a delta function.
@@ -424,10 +431,11 @@ The 'Plot Guess' check-box can be used to enable/disable the guess curve in the
 Output
 ~~~~~~
 
-The results of the fit may be plot and saved under the 'Output' section of the fitting interfaces.
+The results of the fit may be plotted and saved under the 'Output' section of the fitting interfaces.
 
-Next to the 'Plot Output' label, you can select a parameter to plot and then click 'Plot' to plot it across the
-fit spectra (if multiple data-sets have been used, a separate plot will be produced for each data-set).
+Next to the 'Plot Output' label, you can select a parameter to plot and then click 'Plot' to plot it with error 
+bars across the fit spectra (if multiple data-sets have been used, a separate plot will be produced for each data-set). 
+The 'Plot Output' options will be disabled after a fit if there is only one data point for the parameters.
 
 Clicking the 'Save Result' button will save the result of the fit to your default save location.
 
@@ -481,9 +489,9 @@ input workspace, using the fitted values from the previous spectrum as input
 values for fitting the next. This is done by means of the
 :ref:`IqtFitSequential <algm-IqtFitSequential>` algorithm.
 
-A sequential fit is run by clicking the Run button at the bottom of the tab, a
-single fit can be done using the Fit Single Spectrum button underneath the
-preview plot.
+A sequential fit is run by clicking the Run button seen just above the output 
+options, a single fit can be done using the Fit Single Spectrum button underneath 
+the preview plot.
 
 Spectrum Selection
 ~~~~~~~~~~~~~~~~~~
diff --git a/docs/source/interfaces/sans_save_other.rst b/docs/source/interfaces/sans_save_other.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6d0ff13b5478eaffb3f955fc40cd753e3f8eb4e4
--- /dev/null
+++ b/docs/source/interfaces/sans_save_other.rst
@@ -0,0 +1,28 @@
+Save Other
+==========
+
+.. image::  ../images/save_other.png
+   :align: right
+   :width: 400px
+
+.. _save-other:
+
+Interface Overview
+------------------
+
+This interface is intended to allow workspaces in the ADS to be easily saved in one of three formats RKH, NxCanSAS and CanSAS.
+
+This uses the three algorithms:
+
+
+:ref:`SaveRKH <algm-SaveRKH>`
+
+:ref:`SaveNXcanSAS <algm-SaveNXcanSAS>`
+
+:ref:`SaveCanSAS1D <algm-SaveCanSAS1D>`
+
+The workspaces are saved into the directory specified using the following naming scheme:
+
+* If a filename is input and one workspace is selected to be saved this name will be used.
+* If a filename is input and multiple workspaces are selected the filename will be appended to the workspace name. 
+* If no filename is input the workspaces will be saved out using the names they have in Mantid.
\ No newline at end of file
diff --git a/docs/source/release/v3.14.0/diffraction.rst b/docs/source/release/v3.14.0/diffraction.rst
index b26d90a4528cc052d4ea2e2e62b4b8773fbe8897..10ae50ca8cbf7d32e808b8ee0a341b4dd1de1117 100644
--- a/docs/source/release/v3.14.0/diffraction.rst
+++ b/docs/source/release/v3.14.0/diffraction.rst
@@ -20,6 +20,7 @@ Improvements
 - :ref:`SNAPReduce <algm-SNAPReduce>` now has progress bar and all output workspaces have history
 - :ref:`SNAPReduce <algm-SNAPReduce>` has been completely refactored. It now uses :ref:`AlignAndFocusPowderFromFiles <algm-AlignAndFocusPowderFromFiles>` for a large part of its functionality. It has progress bar and all output workspaces have history. It is also more memory efficient by reducing the number of temporary workspaces created.
 - :ref:`AlignAndFocusPowder <algm-AlignAndFocusPowder>` and :ref:`AlignAndFocusPowderFromFiles <algm-AlignAndFocusPowderFromFiles>` now support outputting the unfocussed data and weighted events (with time). This allows for event filtering **after** processing the data.
+- :ref:`AlignAndFocusPowderFromFiles <algm-AlignAndFocusPowderFromFiles>` has a significant performance improvement when used with chunking
 - :ref:`LoadWAND <algm-LoadWAND>` has grouping option added and loads faster
 - Mask workspace option added to :ref:`WANDPowderReduction <algm-WANDPowderReduction>`
 - :ref:`Le Bail concept page <Le Bail Fit>` moved from mediawiki
@@ -40,6 +41,7 @@ Improvements
 - :ref:`SaveIsawPeaks <algm-SaveIsawPeaks>` now has option to renumber peaks sequentially.
 - SCD Event Data Reduction Diffraction Interface now has option to create MD HKL workspace.
 - :ref:`IntegratePeaksUsingClusters <algm-IntegratePeaksUsingClusters>` will now treat NaN's as background.
+- :ref:`SetCrystalLocation <algm-SetCrystalLocation>` is a new algorithm to set the sample location in events workspaces.
 
 Bugfixes
 ########
@@ -48,6 +50,9 @@ Bugfixes
 
 - :ref:`FindPeaksMD <algm-FindPeaksMD>` now finds peaks correctly with the crystallography convention setting and reduction with crystallography convention is tested with a system test.
 - :ref:`SaveIsawPeaks <algm-SaveIsawPeaks>` does not have duplicate peak numbers when saving PeaksWorkspaces with more than one RunNumber.
+- :ref:`LoadIsawPeaks <algm-LoadIsawPeaks>` now loads the calibration from the peaks file correctly.
+
+- :ref:`OptimizeCrystalPlacement <algm-OptimizeCrystalPlacement>` now updates the sample location used by peaks.  Previously, the sample was effectively left unmoved. Default for indexing tolerance was lowered to 0.15.
 
 Powder Diffraction
 ------------------
diff --git a/docs/source/release/v3.14.0/direct_inelastic.rst b/docs/source/release/v3.14.0/direct_inelastic.rst
index 0d31b311776de513f30ebb021ae8e0f1e5eaba34..cf3e1b1093888213f396f16a745dbdc6c8f2e175 100644
--- a/docs/source/release/v3.14.0/direct_inelastic.rst
+++ b/docs/source/release/v3.14.0/direct_inelastic.rst
@@ -37,6 +37,7 @@ Bugfixes
 
 - Fixed a bug in :ref:`DirectILLCollectData <algm-DirectILLCollectData>` which prevented the *OutputIncidentEnergyWorkspace* being generated if *IncidentEnergyCalibration* was turned off.
 - Fixed the detector :math:`2\theta` width calculation in :ref:`SofQWNormalisedPolygon <algm-SofQWNormalisedPolygon>`. The algorithm was computing the angle between the detector center and top point, not the actual :math:`2\theta` width.
+- Fixed a bug in :ref:`Rebin2D <algm-Rebin2D>` which requires that an input workspace had to have fractional area weights for the `UseFractionalArea` option to work. The behaviour is now that if the input workspace does not have fractional areas, and `UseFractionalArea` is true, then fractional area tracking will be used with input fractions set to unity.
 
 Interfaces
 ----------
@@ -66,5 +67,13 @@ Improved
 
 - The ``directtools`` plotting and utility module has been updated with improved automatic E ranges, cut labels and other visuals. All functions now should also be applicable to non-ILL data as well.
 
+Instrument definitions
+----------------------
+
+Improved
+########
+
+- IN5: pixel radius and height are now more realistic and the detector ID of the monitor is now 100000 instead of 0.
+
 :ref:`Release 3.14.0 <v3.14.0>`
 
diff --git a/docs/source/release/v3.14.0/framework.rst b/docs/source/release/v3.14.0/framework.rst
index 24571931ce385d49364220b3871152e70502de6a..727dd33f00315630cc0c14d1adb4ba04d29115ae 100644
--- a/docs/source/release/v3.14.0/framework.rst
+++ b/docs/source/release/v3.14.0/framework.rst
@@ -32,11 +32,21 @@ Nexus Geometry Loading
 The changes above have also been encorporated directly into :ref:`LoadEventNexus <algm-LoadEventNexus>`, so it is possible to store data and geometry together for the first time in a NeXus compliant format for Mantid. These changes have made it possible to load experimental ESS event data files directly into Mantid.
 
 
-Archive Searching / ONCat
--------------------------
+Archive Searching
+-----------------
 
+SNS / ONCat
+###########
+
+- SNS file searching has been moved to `ONCAT <https://oncat.ornl.gov/>`_. Due to auto-updating of the ``Facilities.xml``, this was done by directing ``SNSDataSearch`` and ``ORNLDataSearch`` to both use ONCAT.
 - For HFIR instruments that write out raw files with run numbers, we have enabled functionality that allows for the searching of file locations by making calls to ONCat.  To use this, make sure that the "Search Data Archive" option is checked in your "Manage User Directories" settings.  The ``FileFinder`` and algorithms such as :ref:`Load <algm-Load>`  will then accept inputs such as "``HB2C_143210``".
-- In the short term, for SNS instruments, the default "out of the box" behaviour will be to continue using ICAT for archive searching.  This can be manually overridden by changing ``<archiveSearch plugin="SNSDataSearch" />`` to ``<archiveSearch plugin="ORNLDataSearch" />`` in your ``Facilities.xml`` file.  Existing functionality should be almost completely unaffected, except that you may find that archive searching is a little quicker and slightly more robust.  ``ORNLDataSearch`` will become the default option at SNS in a future version of Mantid.
+
+ISIS / ICat
+###########
+
+- The path returned by ICat starting ``\\isis\inst$`` is now overridden by the fully-qualified path starting ``\\isis.cclrc.ac.uk\inst$`` on Windows machines. This makes accessing the archive more reliable over the VPN.
+- On Linux and Mac machines, it is overridden by a path starting ``/archive``.
+- On all machines, you can override this locally by setting ``icatDownload.mountPoint=<my_path>`` in your ``Mantid.user.properties`` file.
 
 Stability
 ---------
@@ -53,6 +63,7 @@ New Algorithms
 - :ref:`MatchSpectra <algm-MatchSpectra>` is an algorithm that calculates factors to match all spectra to a reference spectrum.
 - :ref:`MaskBinsIf <algm-MaskBinsIf>` is an algorithm to mask bins according to criteria specified as a muparser expression.
 - :ref:`MaskNonOverlappingBins <algm-MaskNonOverlappingBins>` masks the bins that do not overlap with another workspace.
+- :ref:`LoadSampleEnvironment <algm-LoadSampleEnvironment>` loads or adds to a sample environment from a .stl file, as well as allowing setting the material of the environment to load.
 - :ref:`ParallaxCorrection <algm-ParallaxCorrection>` will perform a geometric correction for the so-called parallax effect in tube based SANS detectors.
 
 Improvements
@@ -69,11 +80,13 @@ Improvements
 - :ref:`LoadSampleShape <algm-LoadSampleShape-v1>` now supports loading from binary .stl files.
 - :ref:`MaskDetectorsIf <algm-MaskDetectorsIf>` now supports masking a workspace in addition to writing the masking information to a calfile.
 - :ref:`ApplyDetectorScanEffCorr <algm-ApplyDetectorScanEffCorr>` will properly propagate the masked bins in the calibration map to the output workspace.
-- :ref:`LoadSampleShape <algm-LoadSampleShape-v1>` now supports loading from binary .stl files.
 - :ref:`LoadNexusLogs <algm-LoadNexusLogs-v1>` now will load files that have 1D arrays for each time value in the logs, but will not load this data.
 - :ref:`GroupDetectors <algm-GroupDetectors>` now takes masked bins correctly into account when processing histogram workspaces.
 - :ref:`SaveNexusProcessed <algm-SaveNexusProcessed>` and :ref:`LoadNexusProcessed <algm-LoadNexusProcessed>` can now save and load a ``MaskWorkspace``.
 - :ref:`FitPeaks <algm-FitPeaks>` can output parameters' uncertainty (fitting error) in an optional workspace.
+- The documentation in :ref:`EventFiltering` and :ref:`FilterEvents <algm-FilterEvents>` have been extensively rewritten to aid in understanding what the code does.
+- All of the numerical integration based absorption corrections which use :ref:`AbsorptionCorrection <algm-AbsorptionCorrection>` will generate an exception when they fail to generate a gauge volume. Previously, they would silently generate a correction workspace that was all not-a-number (``NAN``).
+- Various clarifications and additional links in the geometry and material documentation pages
 
 Bugfixes
 ########
@@ -90,8 +103,11 @@ Bugfixes
 - The output workspace now keeps the units of the input workspace for all sample log entries of algorithms :ref:`MergeRuns <algm-MergeRuns>` and :ref:`ConjoinXRuns <algm-ConjoinXRuns>`.
 - History for algorithms that took groups sometimes would get incorrect history causing history to be incomplete, so now full group history is saved for all items belonging to the group.
 - Fixed a bug in `SetGoniometer <algm-SetGoniometer>` where it would use the mean log value rather than the time series average value for goniometer angles.
+- Fixed a bug in `AlignAndFocusPowderFromFiles <algm-AlignAndFocusPowderFromFiles>` for using the passed on CompressTolerance and CompressWallClockTolerance in the child `CompressEvents <algm-CompressEvents>` algorithm instead of just in the child `AlignAndFocusPowder <algm-AlignAndFocusPowder>` algorithm.
 - `ConvertToMD <algm-ConvertToMD>` now uses the time-average value for logs when using them as ``OtherDimensions``
 - The input validator is fixed in :ref:`MostLikelyMean <algm-MostLikelyMean>` avoiding a segmentation fault.
+- Fixed a bug in `AlignAndFocusPowder <algm-AlignAndFocusPowder>` where a histogram input workspace did not clone propertly to the output workspace and properly masking a grouping workspace passed to `DiffractionFocussing <algm-DiffractionFocussing>`. Also adds initial unit tests for `AlignAndFocusPowder <algm-AlignAndFocusPowder>`.
+- Fixed a bug in :ref:`ExtractSpectra <algm-ExtractSpectra>` which was causing a wrong last value in the output's vertical axis if the axis type was ``BinEdgeAxis``.
 
 Python
 ------
diff --git a/docs/source/release/v3.14.0/indirect_inelastic.rst b/docs/source/release/v3.14.0/indirect_inelastic.rst
index 1bb7ab20c954022c6d176122f76d8e3f368341a0..2e5d446617d09ccf9f5aa9c0785f87a105e308ec 100644
--- a/docs/source/release/v3.14.0/indirect_inelastic.rst
+++ b/docs/source/release/v3.14.0/indirect_inelastic.rst
@@ -29,12 +29,13 @@ Improvements
 ############
 
 - The Run button is now above the output options, and is disabled during fitting along with the output buttons.
+- The Run button in the Data Analysis tabs is now above the output options, and is disabled during fitting.
 - The Fit Single Spectrum buttons in the Data Analysis tabs MSDFit, ConvFit, I(Q,t)Fit and F(Q)Fit are now disabled
   during fitting.
 - When the InelasticDiffSphere, InelasticDiffRotDiscreteCircle, ElasticDiffSphere or ElasticDiffRotDiscreteCircle
   Fit Types are selected in the ConvFit Tab, the Q values are retrieved from the workspaces, preventing a crash
   when plotting a guess.
-- The Plot buttons in MSDFit, I(Q,t)Fit, ConvFit and F(Q)Fit are disabled after a Run when the result workspace only 
+- The Plot buttons in MSDFit, I(Q,t)Fit, ConvFit and F(Q)Fit are disabled after a Run when the result workspace only
   has one data point to plot.
 - There is now an option to choose which output parameter to plot in MSDFit.
 - An option to skip the calculation of Monte Carlo Errors on the I(Q,t) Tab has been added.
@@ -44,10 +45,19 @@ Improvements
   maximum of 18 plots.
 - The WorkspaceIndex and Q value in the FitPropertyBrowser are now updated when the Plot Spectrum number is changed.
   This improvement can be seen in ConvFit when functions which depend on Q value are selected.
+- Fit and Fit Sequential in the Fit combobox above the FitPropertyBrowser are now disabled while fitting is taking place.
+- The option to choose which workspace index to Plot Spectrum for and from which output workspace is now given in Elwin.
+- ConvFit now allows the loading of Dave ASCII files which end with '_sqw.dave'.
+- The results of a fit in MSDFit, IqtFit, ConvFit and F(Q)Fit are now plotted with error bars.
+- The AddWorkspace windows (opened from the Multiple Input tab) now stay open after adding a workspace to the data table. This 
+  is found on the MSDFit, I(Q,t)Fit, ConvFit and F(Q)Fit interfaces.
+
 
 Bugfixes
 ########
 
+- The workspace(s) loaded into F(Q) Fit are checked for EISF or Width values, and an error message is displayed
+  if neither are present. This prevents an unexpected crash.
 - The parameter values for a selected spectrum are now updated properly when a Fit is run using the Fit String
   option in ConvFit.
 - An unexpected crash is prevented when Plot Current Preview is clicked when no data is loaded. A meaningful error
@@ -58,7 +68,7 @@ Bugfixes
 - A bug where fixed parameters don't remain fixed when using the FABADA minimizer in ConvFit has been corrected.
 - The expression for the Fit type Yi in MSDFit was incorrect and has now been corrected.
 - The x-axis labels in the output plots for MSDFit are now correct.
-- An unexpected error is now prevented when clicking Plot Guess from the Display combo box in ConvFit without first loading 
+- An unexpected error is now prevented when clicking Plot Guess from the Display combo box in ConvFit without first loading
   a reduced file.
 
 
@@ -115,6 +125,16 @@ Bugfixes
 - An unwanted 'Fit' plot is no longer plotted in ResNorm when you click `Plot` in the output options.
 
 
+Simulations Interface
+---------------------
+
+Improvements
+############
+
+- The Run button is now above the output options.
+- The Run, Plot and Save buttons are now disabled while running and plotting is taking place.
+
+
 Diffraction Interface
 ---------------------
 
diff --git a/docs/source/release/v3.14.0/muon.rst b/docs/source/release/v3.14.0/muon.rst
index c7d6102feba1984966d9291435405486ee9e666f..977db1143b0d802c0e20455434396070425833f4 100644
--- a/docs/source/release/v3.14.0/muon.rst
+++ b/docs/source/release/v3.14.0/muon.rst
@@ -18,6 +18,7 @@ Bugfixes
 ########
 - Results table now includes all logs that are common to all of the loaded files.
 - When turning TF Asymmetry mode off it no longer resets the global options.
+- Results table will produce correct values for co-added runs.
 - The x limits on the settings tab will now correct themselves if bad values are entered. 
 
 Algorithms
diff --git a/docs/source/release/v3.14.0/reflectometry.rst b/docs/source/release/v3.14.0/reflectometry.rst
index 48bad3099ba191c4479d0a59a858dd67ccb70684..25eafdc075c27ff14480b0373a497c8ef07d9262 100644
--- a/docs/source/release/v3.14.0/reflectometry.rst
+++ b/docs/source/release/v3.14.0/reflectometry.rst
@@ -59,7 +59,7 @@ ISIS Reflectometry Interface
 New
 ###
 
-
+- Flood correction options have been added to the interface.
 
 Improved
 ########
diff --git a/docs/source/release/v3.14.0/sans.rst b/docs/source/release/v3.14.0/sans.rst
index 3117a6fe38d3028fc5ea8ffac0998c269afb5197..0fec98e4fba12243b97df2c0c760c929dabfd5c0 100644
--- a/docs/source/release/v3.14.0/sans.rst
+++ b/docs/source/release/v3.14.0/sans.rst
@@ -7,6 +7,7 @@ SANS Changes
 
 New
 ###
+* Added manual saving functionality to the new GUI.
 
 - :ref:`SANSILLReduction <algm-SANSILLReduction>` performs SANS data reduction for ILL instruments D11, D22, D33.
 - :ref:`SANSILLIntegration <algm-SANSILLIntegration>` performs integration of corrected SANS data to produce I(Q), I(Phi,Q) or I(Qx,Qy).
@@ -30,6 +31,7 @@ Improved
 * Added a "process all" and "process selected" button to the batch table in place of "process" button.
 * Added a load button to load selected workspaces without processing.
 * Added save_can option to output unsubtracted can and sample workspaces.
+* File path to batch file will be added to your directories automatically upon loading
 
 Bug fixes
 #########
@@ -51,4 +53,14 @@ Removed
 
 - Obsolete *SetupILLD33Reduction* algorithm was removed.
 
+
+ORNL SANS
+---------
+
+Improvements
+############
+
+- ORNL HFIR SANS instruments have new geometries. The monitors have now a shape associated to them. Detector will move to the right position based on log values.
+
+
 :ref:`Release 3.14.0 <v3.14.0>`
diff --git a/docs/source/release/v3.14.0/ui.rst b/docs/source/release/v3.14.0/ui.rst
index de8db0ade55efeb0d09261d72d3812dc5b5618f0..01c92e3a433d5d0378a2b31fb13857931391bd38 100644
--- a/docs/source/release/v3.14.0/ui.rst
+++ b/docs/source/release/v3.14.0/ui.rst
@@ -73,11 +73,23 @@ Changes
 
 - All File Browser dialog boxes will now (by default) display all valid file extensions as the first file filter.
 - Plot -> Advanced now allows for plotting against any property in the ``Run`` object that can be represented as a single number. It uses the time-average value for time series properties and the average for others.
+- A new option in the right-click menu for the results log allows users to set the number of lines retained by the widget. The default is 8192. This avoids memory problems for long running instances.
 
 BugFixes
 ########
 
 - Fixed issue where an open set of data from ITableWorkspace wouldn't update if the data was changed via python
 - Fixed an issue where MantidPlot would crash when renaming workspaces.
+- Fixed issue with filenames containing spaces that are passed to Mantid when launched from the command line
+
+MantidWorkbench
+---------------
+
+Changes
+#######
+- Colorfill plots with uniform bin widths were made more responsive by resampling to 4K resolution and using :func:`~mantid.plots.MantidAxes.imshow`.
+
+BugFixes
+########
 
 :ref:`Release 3.14.0 <v3.14.0>`
diff --git a/instrument/BIOSANS_Definition.xml b/instrument/BIOSANS_Definition.xml
index 07034d2d486155ad929b443ef3c257b08c49aea0..9970ee8c0be6bdd03b341fdf58eef44fa293fc79 100644
--- a/instrument/BIOSANS_Definition.xml
+++ b/instrument/BIOSANS_Definition.xml
@@ -1,679 +1,580 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- For help on the notation used to specify an Instrument Definition File 
-     see http://www.mantidproject.org/IDF -->
-<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
- name="BioSANS" valid-from   ="1900-01-31 23:59:59"
-                           valid-to     ="2012-01-31 23:59:59"
-		          last-modified="2012-03-23 15:02:05">
+<?xml version='1.0' encoding='ASCII'?>
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0"
+			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+			xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
+			name="BIOSANS"
+			valid-from="2016-04-22 00:00:00"
+			valid-to="2100-01-31 23:59:59"
+			last-modified="2018-12-06 17:45:00.000">
+	
+	<defaults>
+		<length unit="meter"/>
+		<angle unit="degree"/>
+		<reference-frame>
+			<along-beam axis="z"/>
+			<pointing-up axis="y"/>
+			<handedness val="right"/>
+		</reference-frame>
+	</defaults>
+	
+	<!--SOURCE AND SAMPLE POSITION-->
+	<component type="moderator">
+		<location z="-13.601"/>
+	</component>
+	<type name="moderator" is="Source"/>
+	
+	<component type="sample-position">
+		<location y="0.0" x="0.0" z="0.0"/>
+	</component>
+	<type name="sample-position" is="SamplePos"/>
+	
+	<!-- ***************************************************************** -->
+	<!--MONITOR 1 -->
+	<component type="monitors" idlist="monitor1">
+		<location/>
+	</component>
+	<type name="monitors">
+	    <component type="monitor">
+    		<location z="-10.5" name="monitor1"/>
+    	</component>
+	</type>
+	<idlist idname="monitor1">
+		<id val="1" />
+	</idlist>
 
-  <!-- TEST DEFINITION: NOT READY FOR SHOW TIME -->
-  
-  <defaults>
-    <length unit="meter"/>
-    <angle unit="degree"/>
-    <reference-frame>
-      <!-- The z-axis is set parallel to and in the direction of the beam. the 
-           y-axis points up and the coordinate system is right handed. -->
-      <along-beam axis="z"/>
-      <pointing-up axis="y"/>
-      <handedness val="right"/>
-    </reference-frame>
-    <default-view axis-view="z+"/>
-  </defaults>
-  
-  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
-  
-  <!-- source and sample-position components 
-  		Place the beam along the z-axis, the sample holder at (0,0,0) -->
+	<!--MONITOR 2 -->
+	<component type="timers" idlist="timer1">
+		<location/>
+	</component>
+	<type name="timers">
+	    <component type="monitor">
+    		<location z="-10.5" name="timer1"/>
+    	</component>
+	</type>
+	<idlist idname="timer1">
+		<id val="2" />
+	</idlist>
 
-  <component type="source">
-    <location x="0.0" y="0.0" z="-1.0"/>
-  </component>
-  <type name="source" is="Source" />
-  
-  <component type="some-sample-holder">
-    <location x="0.0" y="0.0" z="0.0"/>
-  </component>
-  <type name="some-sample-holder" is="SamplePos" />
-  
-  
-  <!-- detector components (including monitors) -->
-  
-  <component type="monitor1" idlist="monitor1">
-    <location z="-0.5"/>
-  </component>
-  <type name="monitor1" is="monitor" />
- 
-  <component type="timer1" idlist="timer1">
-    <location z="-0.5" />
-  </component>
-  <type name="timer1" is="monitor" />
- 
-  <component type="sample_aperture">
-    <location z="0.0"/>
-    <parameter name="Size"> <value val="14.0" /> </parameter>
-  </component>
-  <type name="sample_aperture" />
- 
-
-  <component type="detector1" name="detector1" idlist="det1">
-   <location x="0.0" y="0.0" z="0.0" />
-  </component>   
-
- 
-  <type name="detector1">
-    <component type="tube" >
-		<location x="-0.487050" name="tube0" />
-		<location x="-0.481950" name="tube1" />
-		<location x="-0.476850" name="tube2" />
-		<location x="-0.471750" name="tube3" />
-		<location x="-0.466650" name="tube4" />
-		<location x="-0.461550" name="tube5" />
-		<location x="-0.456450" name="tube6" />
-		<location x="-0.451350" name="tube7" />
-		<location x="-0.446250" name="tube8" />
-		<location x="-0.441150" name="tube9" />
-		<location x="-0.436050" name="tube10" />
-		<location x="-0.430950" name="tube11" />
-		<location x="-0.425850" name="tube12" />
-		<location x="-0.420750" name="tube13" />
-		<location x="-0.415650" name="tube14" />
-		<location x="-0.410550" name="tube15" />
-		<location x="-0.405450" name="tube16" />
-		<location x="-0.400350" name="tube17" />
-		<location x="-0.395250" name="tube18" />
-		<location x="-0.390150" name="tube19" />
-		<location x="-0.385050" name="tube20" />
-		<location x="-0.379950" name="tube21" />
-		<location x="-0.374850" name="tube22" />
-		<location x="-0.369750" name="tube23" />
-		<location x="-0.364650" name="tube24" />
-		<location x="-0.359550" name="tube25" />
-		<location x="-0.354450" name="tube26" />
-		<location x="-0.349350" name="tube27" />
-		<location x="-0.344250" name="tube28" />
-		<location x="-0.339150" name="tube29" />
-		<location x="-0.334050" name="tube30" />
-		<location x="-0.328950" name="tube31" />
-		<location x="-0.323850" name="tube32" />
-		<location x="-0.318750" name="tube33" />
-		<location x="-0.313650" name="tube34" />
-		<location x="-0.308550" name="tube35" />
-		<location x="-0.303450" name="tube36" />
-		<location x="-0.298350" name="tube37" />
-		<location x="-0.293250" name="tube38" />
-		<location x="-0.288150" name="tube39" />
-		<location x="-0.283050" name="tube40" />
-		<location x="-0.277950" name="tube41" />
-		<location x="-0.272850" name="tube42" />
-		<location x="-0.267750" name="tube43" />
-		<location x="-0.262650" name="tube44" />
-		<location x="-0.257550" name="tube45" />
-		<location x="-0.252450" name="tube46" />
-		<location x="-0.247350" name="tube47" />
-		<location x="-0.242250" name="tube48" />
-		<location x="-0.237150" name="tube49" />
-		<location x="-0.232050" name="tube50" />
-		<location x="-0.226950" name="tube51" />
-		<location x="-0.221850" name="tube52" />
-		<location x="-0.216750" name="tube53" />
-		<location x="-0.211650" name="tube54" />
-		<location x="-0.206550" name="tube55" />
-		<location x="-0.201450" name="tube56" />
-		<location x="-0.196350" name="tube57" />
-		<location x="-0.191250" name="tube58" />
-		<location x="-0.186150" name="tube59" />
-		<location x="-0.181050" name="tube60" />
-		<location x="-0.175950" name="tube61" />
-		<location x="-0.170850" name="tube62" />
-		<location x="-0.165750" name="tube63" />
-		<location x="-0.160650" name="tube64" />
-		<location x="-0.155550" name="tube65" />
-		<location x="-0.150450" name="tube66" />
-		<location x="-0.145350" name="tube67" />
-		<location x="-0.140250" name="tube68" />
-		<location x="-0.135150" name="tube69" />
-		<location x="-0.130050" name="tube70" />
-		<location x="-0.124950" name="tube71" />
-		<location x="-0.119850" name="tube72" />
-		<location x="-0.114750" name="tube73" />
-		<location x="-0.109650" name="tube74" />
-		<location x="-0.104550" name="tube75" />
-		<location x="-0.099450" name="tube76" />
-		<location x="-0.094350" name="tube77" />
-		<location x="-0.089250" name="tube78" />
-		<location x="-0.084150" name="tube79" />
-		<location x="-0.079050" name="tube80" />
-		<location x="-0.073950" name="tube81" />
-		<location x="-0.068850" name="tube82" />
-		<location x="-0.063750" name="tube83" />
-		<location x="-0.058650" name="tube84" />
-		<location x="-0.053550" name="tube85" />
-		<location x="-0.048450" name="tube86" />
-		<location x="-0.043350" name="tube87" />
-		<location x="-0.038250" name="tube88" />
-		<location x="-0.033150" name="tube89" />
-		<location x="-0.028050" name="tube90" />
-		<location x="-0.022950" name="tube91" />
-		<location x="-0.017850" name="tube92" />
-		<location x="-0.012750" name="tube93" />
-		<location x="-0.007650" name="tube94" />
-		<location x="-0.002550" name="tube95" />
-		<location x="0.002550" name="tube96" />
-		<location x="0.007650" name="tube97" />
-		<location x="0.012750" name="tube98" />
-		<location x="0.017850" name="tube99" />
-		<location x="0.022950" name="tube100" />
-		<location x="0.028050" name="tube101" />
-		<location x="0.033150" name="tube102" />
-		<location x="0.038250" name="tube103" />
-		<location x="0.043350" name="tube104" />
-		<location x="0.048450" name="tube105" />
-		<location x="0.053550" name="tube106" />
-		<location x="0.058650" name="tube107" />
-		<location x="0.063750" name="tube108" />
-		<location x="0.068850" name="tube109" />
-		<location x="0.073950" name="tube110" />
-		<location x="0.079050" name="tube111" />
-		<location x="0.084150" name="tube112" />
-		<location x="0.089250" name="tube113" />
-		<location x="0.094350" name="tube114" />
-		<location x="0.099450" name="tube115" />
-		<location x="0.104550" name="tube116" />
-		<location x="0.109650" name="tube117" />
-		<location x="0.114750" name="tube118" />
-		<location x="0.119850" name="tube119" />
-		<location x="0.124950" name="tube120" />
-		<location x="0.130050" name="tube121" />
-		<location x="0.135150" name="tube122" />
-		<location x="0.140250" name="tube123" />
-		<location x="0.145350" name="tube124" />
-		<location x="0.150450" name="tube125" />
-		<location x="0.155550" name="tube126" />
-		<location x="0.160650" name="tube127" />
-		<location x="0.165750" name="tube128" />
-		<location x="0.170850" name="tube129" />
-		<location x="0.175950" name="tube130" />
-		<location x="0.181050" name="tube131" />
-		<location x="0.186150" name="tube132" />
-		<location x="0.191250" name="tube133" />
-		<location x="0.196350" name="tube134" />
-		<location x="0.201450" name="tube135" />
-		<location x="0.206550" name="tube136" />
-		<location x="0.211650" name="tube137" />
-		<location x="0.216750" name="tube138" />
-		<location x="0.221850" name="tube139" />
-		<location x="0.226950" name="tube140" />
-		<location x="0.232050" name="tube141" />
-		<location x="0.237150" name="tube142" />
-		<location x="0.242250" name="tube143" />
-		<location x="0.247350" name="tube144" />
-		<location x="0.252450" name="tube145" />
-		<location x="0.257550" name="tube146" />
-		<location x="0.262650" name="tube147" />
-		<location x="0.267750" name="tube148" />
-		<location x="0.272850" name="tube149" />
-		<location x="0.277950" name="tube150" />
-		<location x="0.283050" name="tube151" />
-		<location x="0.288150" name="tube152" />
-		<location x="0.293250" name="tube153" />
-		<location x="0.298350" name="tube154" />
-		<location x="0.303450" name="tube155" />
-		<location x="0.308550" name="tube156" />
-		<location x="0.313650" name="tube157" />
-		<location x="0.318750" name="tube158" />
-		<location x="0.323850" name="tube159" />
-		<location x="0.328950" name="tube160" />
-		<location x="0.334050" name="tube161" />
-		<location x="0.339150" name="tube162" />
-		<location x="0.344250" name="tube163" />
-		<location x="0.349350" name="tube164" />
-		<location x="0.354450" name="tube165" />
-		<location x="0.359550" name="tube166" />
-		<location x="0.364650" name="tube167" />
-		<location x="0.369750" name="tube168" />
-		<location x="0.374850" name="tube169" />
-		<location x="0.379950" name="tube170" />
-		<location x="0.385050" name="tube171" />
-		<location x="0.390150" name="tube172" />
-		<location x="0.395250" name="tube173" />
-		<location x="0.400350" name="tube174" />
-		<location x="0.405450" name="tube175" />
-		<location x="0.410550" name="tube176" />
-		<location x="0.415650" name="tube177" />
-		<location x="0.420750" name="tube178" />
-		<location x="0.425850" name="tube179" />
-		<location x="0.430950" name="tube180" />
-		<location x="0.436050" name="tube181" />
-		<location x="0.441150" name="tube182" />
-		<location x="0.446250" name="tube183" />
-		<location x="0.451350" name="tube184" />
-		<location x="0.456450" name="tube185" />
-		<location x="0.461550" name="tube186" />
-		<location x="0.466650" name="tube187" />
-		<location x="0.471750" name="tube188" />
-		<location x="0.476850" name="tube189" />
-		<location x="0.481950" name="tube190" />
-		<location x="0.487050" name="tube191" />
-
-    </component>
-  </type>
-  
-  <type name="pixel" is="detector">
-    <cuboid id="shape">
-      <left-front-bottom-point x="-0.002550" y="-0.002550" z="0.0"  />
-      <left-front-top-point  x="-0.002550" y="0.002550" z="0.0"  />
-      <left-back-bottom-point  x="-0.002550" y="-0.002550" z="-0.000005"  />
-      <right-front-bottom-point  x="0.002550" y="-0.002550" z="0.0"  />
-    </cuboid>
-    <algebra val="shape" /> 
-  </type>    
-  
-  <type name="tube" outline="yes">
-    <properties/>
-    <component type="pixel">
-		<location y="-0.487050" name="pixel0" />
-		<location y="-0.481950" name="pixel1" />
-		<location y="-0.476850" name="pixel2" />
-		<location y="-0.471750" name="pixel3" />
-		<location y="-0.466650" name="pixel4" />
-		<location y="-0.461550" name="pixel5" />
-		<location y="-0.456450" name="pixel6" />
-		<location y="-0.451350" name="pixel7" />
-		<location y="-0.446250" name="pixel8" />
-		<location y="-0.441150" name="pixel9" />
-		<location y="-0.436050" name="pixel10" />
-		<location y="-0.430950" name="pixel11" />
-		<location y="-0.425850" name="pixel12" />
-		<location y="-0.420750" name="pixel13" />
-		<location y="-0.415650" name="pixel14" />
-		<location y="-0.410550" name="pixel15" />
-		<location y="-0.405450" name="pixel16" />
-		<location y="-0.400350" name="pixel17" />
-		<location y="-0.395250" name="pixel18" />
-		<location y="-0.390150" name="pixel19" />
-		<location y="-0.385050" name="pixel20" />
-		<location y="-0.379950" name="pixel21" />
-		<location y="-0.374850" name="pixel22" />
-		<location y="-0.369750" name="pixel23" />
-		<location y="-0.364650" name="pixel24" />
-		<location y="-0.359550" name="pixel25" />
-		<location y="-0.354450" name="pixel26" />
-		<location y="-0.349350" name="pixel27" />
-		<location y="-0.344250" name="pixel28" />
-		<location y="-0.339150" name="pixel29" />
-		<location y="-0.334050" name="pixel30" />
-		<location y="-0.328950" name="pixel31" />
-		<location y="-0.323850" name="pixel32" />
-		<location y="-0.318750" name="pixel33" />
-		<location y="-0.313650" name="pixel34" />
-		<location y="-0.308550" name="pixel35" />
-		<location y="-0.303450" name="pixel36" />
-		<location y="-0.298350" name="pixel37" />
-		<location y="-0.293250" name="pixel38" />
-		<location y="-0.288150" name="pixel39" />
-		<location y="-0.283050" name="pixel40" />
-		<location y="-0.277950" name="pixel41" />
-		<location y="-0.272850" name="pixel42" />
-		<location y="-0.267750" name="pixel43" />
-		<location y="-0.262650" name="pixel44" />
-		<location y="-0.257550" name="pixel45" />
-		<location y="-0.252450" name="pixel46" />
-		<location y="-0.247350" name="pixel47" />
-		<location y="-0.242250" name="pixel48" />
-		<location y="-0.237150" name="pixel49" />
-		<location y="-0.232050" name="pixel50" />
-		<location y="-0.226950" name="pixel51" />
-		<location y="-0.221850" name="pixel52" />
-		<location y="-0.216750" name="pixel53" />
-		<location y="-0.211650" name="pixel54" />
-		<location y="-0.206550" name="pixel55" />
-		<location y="-0.201450" name="pixel56" />
-		<location y="-0.196350" name="pixel57" />
-		<location y="-0.191250" name="pixel58" />
-		<location y="-0.186150" name="pixel59" />
-		<location y="-0.181050" name="pixel60" />
-		<location y="-0.175950" name="pixel61" />
-		<location y="-0.170850" name="pixel62" />
-		<location y="-0.165750" name="pixel63" />
-		<location y="-0.160650" name="pixel64" />
-		<location y="-0.155550" name="pixel65" />
-		<location y="-0.150450" name="pixel66" />
-		<location y="-0.145350" name="pixel67" />
-		<location y="-0.140250" name="pixel68" />
-		<location y="-0.135150" name="pixel69" />
-		<location y="-0.130050" name="pixel70" />
-		<location y="-0.124950" name="pixel71" />
-		<location y="-0.119850" name="pixel72" />
-		<location y="-0.114750" name="pixel73" />
-		<location y="-0.109650" name="pixel74" />
-		<location y="-0.104550" name="pixel75" />
-		<location y="-0.099450" name="pixel76" />
-		<location y="-0.094350" name="pixel77" />
-		<location y="-0.089250" name="pixel78" />
-		<location y="-0.084150" name="pixel79" />
-		<location y="-0.079050" name="pixel80" />
-		<location y="-0.073950" name="pixel81" />
-		<location y="-0.068850" name="pixel82" />
-		<location y="-0.063750" name="pixel83" />
-		<location y="-0.058650" name="pixel84" />
-		<location y="-0.053550" name="pixel85" />
-		<location y="-0.048450" name="pixel86" />
-		<location y="-0.043350" name="pixel87" />
-		<location y="-0.038250" name="pixel88" />
-		<location y="-0.033150" name="pixel89" />
-		<location y="-0.028050" name="pixel90" />
-		<location y="-0.022950" name="pixel91" />
-		<location y="-0.017850" name="pixel92" />
-		<location y="-0.012750" name="pixel93" />
-		<location y="-0.007650" name="pixel94" />
-		<location y="-0.002550" name="pixel95" />
-		<location y="0.002550" name="pixel96" />
-		<location y="0.007650" name="pixel97" />
-		<location y="0.012750" name="pixel98" />
-		<location y="0.017850" name="pixel99" />
-		<location y="0.022950" name="pixel100" />
-		<location y="0.028050" name="pixel101" />
-		<location y="0.033150" name="pixel102" />
-		<location y="0.038250" name="pixel103" />
-		<location y="0.043350" name="pixel104" />
-		<location y="0.048450" name="pixel105" />
-		<location y="0.053550" name="pixel106" />
-		<location y="0.058650" name="pixel107" />
-		<location y="0.063750" name="pixel108" />
-		<location y="0.068850" name="pixel109" />
-		<location y="0.073950" name="pixel110" />
-		<location y="0.079050" name="pixel111" />
-		<location y="0.084150" name="pixel112" />
-		<location y="0.089250" name="pixel113" />
-		<location y="0.094350" name="pixel114" />
-		<location y="0.099450" name="pixel115" />
-		<location y="0.104550" name="pixel116" />
-		<location y="0.109650" name="pixel117" />
-		<location y="0.114750" name="pixel118" />
-		<location y="0.119850" name="pixel119" />
-		<location y="0.124950" name="pixel120" />
-		<location y="0.130050" name="pixel121" />
-		<location y="0.135150" name="pixel122" />
-		<location y="0.140250" name="pixel123" />
-		<location y="0.145350" name="pixel124" />
-		<location y="0.150450" name="pixel125" />
-		<location y="0.155550" name="pixel126" />
-		<location y="0.160650" name="pixel127" />
-		<location y="0.165750" name="pixel128" />
-		<location y="0.170850" name="pixel129" />
-		<location y="0.175950" name="pixel130" />
-		<location y="0.181050" name="pixel131" />
-		<location y="0.186150" name="pixel132" />
-		<location y="0.191250" name="pixel133" />
-		<location y="0.196350" name="pixel134" />
-		<location y="0.201450" name="pixel135" />
-		<location y="0.206550" name="pixel136" />
-		<location y="0.211650" name="pixel137" />
-		<location y="0.216750" name="pixel138" />
-		<location y="0.221850" name="pixel139" />
-		<location y="0.226950" name="pixel140" />
-		<location y="0.232050" name="pixel141" />
-		<location y="0.237150" name="pixel142" />
-		<location y="0.242250" name="pixel143" />
-		<location y="0.247350" name="pixel144" />
-		<location y="0.252450" name="pixel145" />
-		<location y="0.257550" name="pixel146" />
-		<location y="0.262650" name="pixel147" />
-		<location y="0.267750" name="pixel148" />
-		<location y="0.272850" name="pixel149" />
-		<location y="0.277950" name="pixel150" />
-		<location y="0.283050" name="pixel151" />
-		<location y="0.288150" name="pixel152" />
-		<location y="0.293250" name="pixel153" />
-		<location y="0.298350" name="pixel154" />
-		<location y="0.303450" name="pixel155" />
-		<location y="0.308550" name="pixel156" />
-		<location y="0.313650" name="pixel157" />
-		<location y="0.318750" name="pixel158" />
-		<location y="0.323850" name="pixel159" />
-		<location y="0.328950" name="pixel160" />
-		<location y="0.334050" name="pixel161" />
-		<location y="0.339150" name="pixel162" />
-		<location y="0.344250" name="pixel163" />
-		<location y="0.349350" name="pixel164" />
-		<location y="0.354450" name="pixel165" />
-		<location y="0.359550" name="pixel166" />
-		<location y="0.364650" name="pixel167" />
-		<location y="0.369750" name="pixel168" />
-		<location y="0.374850" name="pixel169" />
-		<location y="0.379950" name="pixel170" />
-		<location y="0.385050" name="pixel171" />
-		<location y="0.390150" name="pixel172" />
-		<location y="0.395250" name="pixel173" />
-		<location y="0.400350" name="pixel174" />
-		<location y="0.405450" name="pixel175" />
-		<location y="0.410550" name="pixel176" />
-		<location y="0.415650" name="pixel177" />
-		<location y="0.420750" name="pixel178" />
-		<location y="0.425850" name="pixel179" />
-		<location y="0.430950" name="pixel180" />
-		<location y="0.436050" name="pixel181" />
-		<location y="0.441150" name="pixel182" />
-		<location y="0.446250" name="pixel183" />
-		<location y="0.451350" name="pixel184" />
-		<location y="0.456450" name="pixel185" />
-		<location y="0.461550" name="pixel186" />
-		<location y="0.466650" name="pixel187" />
-		<location y="0.471750" name="pixel188" />
-		<location y="0.476850" name="pixel189" />
-		<location y="0.481950" name="pixel190" />
-		<location y="0.487050" name="pixel191" />
-    </component>
-  </type>
-  
-  <!-- DETECTOR and MONITOR ID LISTS -->
-
-  <idlist idname="det1">
-        <id start="1000000" step="1000" end="1191000" />
-    <id start="1000001" step="1000" end="1191001" />
-    <id start="1000002" step="1000" end="1191002" />
-    <id start="1000003" step="1000" end="1191003" />
-    <id start="1000004" step="1000" end="1191004" />
-    <id start="1000005" step="1000" end="1191005" />
-    <id start="1000006" step="1000" end="1191006" />
-    <id start="1000007" step="1000" end="1191007" />
-    <id start="1000008" step="1000" end="1191008" />
-    <id start="1000009" step="1000" end="1191009" />
-    <id start="1000010" step="1000" end="1191010" />
-    <id start="1000011" step="1000" end="1191011" />
-    <id start="1000012" step="1000" end="1191012" />
-    <id start="1000013" step="1000" end="1191013" />
-    <id start="1000014" step="1000" end="1191014" />
-    <id start="1000015" step="1000" end="1191015" />
-    <id start="1000016" step="1000" end="1191016" />
-    <id start="1000017" step="1000" end="1191017" />
-    <id start="1000018" step="1000" end="1191018" />
-    <id start="1000019" step="1000" end="1191019" />
-    <id start="1000020" step="1000" end="1191020" />
-    <id start="1000021" step="1000" end="1191021" />
-    <id start="1000022" step="1000" end="1191022" />
-    <id start="1000023" step="1000" end="1191023" />
-    <id start="1000024" step="1000" end="1191024" />
-    <id start="1000025" step="1000" end="1191025" />
-    <id start="1000026" step="1000" end="1191026" />
-    <id start="1000027" step="1000" end="1191027" />
-    <id start="1000028" step="1000" end="1191028" />
-    <id start="1000029" step="1000" end="1191029" />
-    <id start="1000030" step="1000" end="1191030" />
-    <id start="1000031" step="1000" end="1191031" />
-    <id start="1000032" step="1000" end="1191032" />
-    <id start="1000033" step="1000" end="1191033" />
-    <id start="1000034" step="1000" end="1191034" />
-    <id start="1000035" step="1000" end="1191035" />
-    <id start="1000036" step="1000" end="1191036" />
-    <id start="1000037" step="1000" end="1191037" />
-    <id start="1000038" step="1000" end="1191038" />
-    <id start="1000039" step="1000" end="1191039" />
-    <id start="1000040" step="1000" end="1191040" />
-    <id start="1000041" step="1000" end="1191041" />
-    <id start="1000042" step="1000" end="1191042" />
-    <id start="1000043" step="1000" end="1191043" />
-    <id start="1000044" step="1000" end="1191044" />
-    <id start="1000045" step="1000" end="1191045" />
-    <id start="1000046" step="1000" end="1191046" />
-    <id start="1000047" step="1000" end="1191047" />
-    <id start="1000048" step="1000" end="1191048" />
-    <id start="1000049" step="1000" end="1191049" />
-    <id start="1000050" step="1000" end="1191050" />
-    <id start="1000051" step="1000" end="1191051" />
-    <id start="1000052" step="1000" end="1191052" />
-    <id start="1000053" step="1000" end="1191053" />
-    <id start="1000054" step="1000" end="1191054" />
-    <id start="1000055" step="1000" end="1191055" />
-    <id start="1000056" step="1000" end="1191056" />
-    <id start="1000057" step="1000" end="1191057" />
-    <id start="1000058" step="1000" end="1191058" />
-    <id start="1000059" step="1000" end="1191059" />
-    <id start="1000060" step="1000" end="1191060" />
-    <id start="1000061" step="1000" end="1191061" />
-    <id start="1000062" step="1000" end="1191062" />
-    <id start="1000063" step="1000" end="1191063" />
-    <id start="1000064" step="1000" end="1191064" />
-    <id start="1000065" step="1000" end="1191065" />
-    <id start="1000066" step="1000" end="1191066" />
-    <id start="1000067" step="1000" end="1191067" />
-    <id start="1000068" step="1000" end="1191068" />
-    <id start="1000069" step="1000" end="1191069" />
-    <id start="1000070" step="1000" end="1191070" />
-    <id start="1000071" step="1000" end="1191071" />
-    <id start="1000072" step="1000" end="1191072" />
-    <id start="1000073" step="1000" end="1191073" />
-    <id start="1000074" step="1000" end="1191074" />
-    <id start="1000075" step="1000" end="1191075" />
-    <id start="1000076" step="1000" end="1191076" />
-    <id start="1000077" step="1000" end="1191077" />
-    <id start="1000078" step="1000" end="1191078" />
-    <id start="1000079" step="1000" end="1191079" />
-    <id start="1000080" step="1000" end="1191080" />
-    <id start="1000081" step="1000" end="1191081" />
-    <id start="1000082" step="1000" end="1191082" />
-    <id start="1000083" step="1000" end="1191083" />
-    <id start="1000084" step="1000" end="1191084" />
-    <id start="1000085" step="1000" end="1191085" />
-    <id start="1000086" step="1000" end="1191086" />
-    <id start="1000087" step="1000" end="1191087" />
-    <id start="1000088" step="1000" end="1191088" />
-    <id start="1000089" step="1000" end="1191089" />
-    <id start="1000090" step="1000" end="1191090" />
-    <id start="1000091" step="1000" end="1191091" />
-    <id start="1000092" step="1000" end="1191092" />
-    <id start="1000093" step="1000" end="1191093" />
-    <id start="1000094" step="1000" end="1191094" />
-    <id start="1000095" step="1000" end="1191095" />
-    <id start="1000096" step="1000" end="1191096" />
-    <id start="1000097" step="1000" end="1191097" />
-    <id start="1000098" step="1000" end="1191098" />
-    <id start="1000099" step="1000" end="1191099" />
-    <id start="1000100" step="1000" end="1191100" />
-    <id start="1000101" step="1000" end="1191101" />
-    <id start="1000102" step="1000" end="1191102" />
-    <id start="1000103" step="1000" end="1191103" />
-    <id start="1000104" step="1000" end="1191104" />
-    <id start="1000105" step="1000" end="1191105" />
-    <id start="1000106" step="1000" end="1191106" />
-    <id start="1000107" step="1000" end="1191107" />
-    <id start="1000108" step="1000" end="1191108" />
-    <id start="1000109" step="1000" end="1191109" />
-    <id start="1000110" step="1000" end="1191110" />
-    <id start="1000111" step="1000" end="1191111" />
-    <id start="1000112" step="1000" end="1191112" />
-    <id start="1000113" step="1000" end="1191113" />
-    <id start="1000114" step="1000" end="1191114" />
-    <id start="1000115" step="1000" end="1191115" />
-    <id start="1000116" step="1000" end="1191116" />
-    <id start="1000117" step="1000" end="1191117" />
-    <id start="1000118" step="1000" end="1191118" />
-    <id start="1000119" step="1000" end="1191119" />
-    <id start="1000120" step="1000" end="1191120" />
-    <id start="1000121" step="1000" end="1191121" />
-    <id start="1000122" step="1000" end="1191122" />
-    <id start="1000123" step="1000" end="1191123" />
-    <id start="1000124" step="1000" end="1191124" />
-    <id start="1000125" step="1000" end="1191125" />
-    <id start="1000126" step="1000" end="1191126" />
-    <id start="1000127" step="1000" end="1191127" />
-    <id start="1000128" step="1000" end="1191128" />
-    <id start="1000129" step="1000" end="1191129" />
-    <id start="1000130" step="1000" end="1191130" />
-    <id start="1000131" step="1000" end="1191131" />
-    <id start="1000132" step="1000" end="1191132" />
-    <id start="1000133" step="1000" end="1191133" />
-    <id start="1000134" step="1000" end="1191134" />
-    <id start="1000135" step="1000" end="1191135" />
-    <id start="1000136" step="1000" end="1191136" />
-    <id start="1000137" step="1000" end="1191137" />
-    <id start="1000138" step="1000" end="1191138" />
-    <id start="1000139" step="1000" end="1191139" />
-    <id start="1000140" step="1000" end="1191140" />
-    <id start="1000141" step="1000" end="1191141" />
-    <id start="1000142" step="1000" end="1191142" />
-    <id start="1000143" step="1000" end="1191143" />
-    <id start="1000144" step="1000" end="1191144" />
-    <id start="1000145" step="1000" end="1191145" />
-    <id start="1000146" step="1000" end="1191146" />
-    <id start="1000147" step="1000" end="1191147" />
-    <id start="1000148" step="1000" end="1191148" />
-    <id start="1000149" step="1000" end="1191149" />
-    <id start="1000150" step="1000" end="1191150" />
-    <id start="1000151" step="1000" end="1191151" />
-    <id start="1000152" step="1000" end="1191152" />
-    <id start="1000153" step="1000" end="1191153" />
-    <id start="1000154" step="1000" end="1191154" />
-    <id start="1000155" step="1000" end="1191155" />
-    <id start="1000156" step="1000" end="1191156" />
-    <id start="1000157" step="1000" end="1191157" />
-    <id start="1000158" step="1000" end="1191158" />
-    <id start="1000159" step="1000" end="1191159" />
-    <id start="1000160" step="1000" end="1191160" />
-    <id start="1000161" step="1000" end="1191161" />
-    <id start="1000162" step="1000" end="1191162" />
-    <id start="1000163" step="1000" end="1191163" />
-    <id start="1000164" step="1000" end="1191164" />
-    <id start="1000165" step="1000" end="1191165" />
-    <id start="1000166" step="1000" end="1191166" />
-    <id start="1000167" step="1000" end="1191167" />
-    <id start="1000168" step="1000" end="1191168" />
-    <id start="1000169" step="1000" end="1191169" />
-    <id start="1000170" step="1000" end="1191170" />
-    <id start="1000171" step="1000" end="1191171" />
-    <id start="1000172" step="1000" end="1191172" />
-    <id start="1000173" step="1000" end="1191173" />
-    <id start="1000174" step="1000" end="1191174" />
-    <id start="1000175" step="1000" end="1191175" />
-    <id start="1000176" step="1000" end="1191176" />
-    <id start="1000177" step="1000" end="1191177" />
-    <id start="1000178" step="1000" end="1191178" />
-    <id start="1000179" step="1000" end="1191179" />
-    <id start="1000180" step="1000" end="1191180" />
-    <id start="1000181" step="1000" end="1191181" />
-    <id start="1000182" step="1000" end="1191182" />
-    <id start="1000183" step="1000" end="1191183" />
-    <id start="1000184" step="1000" end="1191184" />
-    <id start="1000185" step="1000" end="1191185" />
-    <id start="1000186" step="1000" end="1191186" />
-    <id start="1000187" step="1000" end="1191187" />
-    <id start="1000188" step="1000" end="1191188" />
-    <id start="1000189" step="1000" end="1191189" />
-    <id start="1000190" step="1000" end="1191190" />
-    <id start="1000191" step="1000" end="1191191" />
-
-  </idlist> 
-  
-  <!-- DETECTOR and MONITOR ID LISTS -->
-
-  <idlist idname="monitor1">
-    <id val="1" />  
-  </idlist>
-  <idlist idname="timer1">
-    <id val="2" />  
-  </idlist>
-  
+	<!--MONITOR SHAPE-->
+	<!--FIXME: Do something real here.-->
+	<type is="monitor" name="monitor">
+		<cylinder id="cyl-approx">
+		<centre-of-bottom-base y="0.0" x="0.0" z="0.0"/>
+		<axis y="0.0" x="0.0" z="1.0"/>
+		<radius val="0.01"/>
+		<height val="0.03"/>
+		</cylinder>
+		<algebra val="cyl-approx"/>
+	</type>
+		
+	<!-- ***************************************************************** -->
+	<!-- Main Detector -->
+	<component type="detector1" idstart="3" idfillbyfirst="x" idstep="256" idstepbyrow="1">
+		<location name="detector1">
+			<parameter name="z">
+				<logfile eq="0.001*value" id="sdd"/>
+			</parameter>
+			<parameter name="x">
+				<logfile eq="0.001*value" id="detector-translation"/>
+			</parameter>
+			<parameter name="y">
+        <value val="0.0"/>
+      </parameter>
+		</location>
+	</component>
+	
+	<!-- Detector: -->
+	<type name="detector1" is="rectangular_detector" type="pixel_rectangular" xpixels="192"
+		xstart="0.52525" xstep="-0.0055" ypixels="256" ystart="-0.54825" ystep="0.0043">
+		<properties />
+	</type>
+	
+	<!-- Pixel for Detectors: 5.5x4 mm -->
+	<type is="detector" name="pixel_rectangular">
+		<cuboid id="pixel-shape">
+			<left-front-bottom-point y="-0.002" x="-0.00275" z="0.0" />
+			<left-front-top-point y="0.002" x="-0.00275" z="0.0" />
+			<left-back-bottom-point y="-0.002" x="-0.00275" z="-0.0001" />
+			<right-front-bottom-point y="-0.002" x="0.00275" z="0.0" />
+		</cuboid>
+		<algebra val="pixel-shape" />
+	</type>
+	
+	<!-- ***************************************************************** -->
+	<!-- Wing Detector -->
+	
+	<!-- Detector list def -->
+	<idlist idname="wing_detector_ids">
+		<id start="49155" end="90114" />
+	</idlist>
+	
+	<component type="wing_detector_arm" idlist="wing_detector_ids">
+		<location />
+	</component>
+	
+	<!-- Detector Banks -->
+	<type name="wing_detector_arm">
+		<component type="wing_detector">
+			<location>
+				<parameter name="r-position">
+					<value val="0"/>
+				</parameter>
+				<parameter name="t-position">
+					<logfile id="rotangle"  eq="0.0+value"/>
+				</parameter>
+				<parameter name="p-position">
+					<value val="0"/>
+				</parameter>
+				<parameter name="rotx">
+					<value val="0"/>
+				</parameter>
+				<parameter name="roty">
+					<logfile id="rotangle"  eq="0.0+value"/>
+				</parameter>
+				<parameter name="rotz">
+					<value val="0"/>
+				</parameter>
+			</location>
+		</component>
+	</type>
+	
+	<type name="wing_detector">
+		<component type="wing_tube">
+			
+			<location r="1.13" t="-0.0" name="wing_tube_0" />
+			<location r="1.13" t="-0.278873538391" name="wing_tube_1" />
+			<location r="1.13" t="-0.557747076782" name="wing_tube_2" />
+			<location r="1.13" t="-0.836620615172" name="wing_tube_3" />
+			<location r="1.13" t="-1.11549415356" name="wing_tube_4" />
+			<location r="1.13" t="-1.39436769195" name="wing_tube_5" />
+			<location r="1.13" t="-1.67324123034" name="wing_tube_6" />
+			<location r="1.13" t="-1.95211476874" name="wing_tube_7" />
+			<location r="1.13" t="-2.23098830713" name="wing_tube_8" />
+			<location r="1.13" t="-2.50986184552" name="wing_tube_9" />
+			<location r="1.13" t="-2.78873538391" name="wing_tube_10" />
+			<location r="1.13" t="-3.0676089223" name="wing_tube_11" />
+			<location r="1.13" t="-3.34648246069" name="wing_tube_12" />
+			<location r="1.13" t="-3.62535599908" name="wing_tube_13" />
+			<location r="1.13" t="-3.90422953747" name="wing_tube_14" />
+			<location r="1.13" t="-4.18310307586" name="wing_tube_15" />
+			<location r="1.13" t="-4.46197661425" name="wing_tube_16" />
+			<location r="1.13" t="-4.74085015264" name="wing_tube_17" />
+			<location r="1.13" t="-5.01972369103" name="wing_tube_18" />
+			<location r="1.13" t="-5.29859722943" name="wing_tube_19" />
+			<location r="1.13" t="-5.57747076782" name="wing_tube_20" />
+			<location r="1.13" t="-5.85634430621" name="wing_tube_21" />
+			<location r="1.13" t="-6.1352178446" name="wing_tube_22" />
+			<location r="1.13" t="-6.41409138299" name="wing_tube_23" />
+			<location r="1.13" t="-6.69296492138" name="wing_tube_24" />
+			<location r="1.13" t="-6.97183845977" name="wing_tube_25" />
+			<location r="1.13" t="-7.25071199816" name="wing_tube_26" />
+			<location r="1.13" t="-7.52958553655" name="wing_tube_27" />
+			<location r="1.13" t="-7.80845907494" name="wing_tube_28" />
+			<location r="1.13" t="-8.08733261333" name="wing_tube_29" />
+			<location r="1.13" t="-8.36620615172" name="wing_tube_30" />
+			<location r="1.13" t="-8.64507969012" name="wing_tube_31" />
+			<location r="1.13" t="-8.92395322851" name="wing_tube_32" />
+			<location r="1.13" t="-9.2028267669" name="wing_tube_33" />
+			<location r="1.13" t="-9.48170030529" name="wing_tube_34" />
+			<location r="1.13" t="-9.76057384368" name="wing_tube_35" />
+			<location r="1.13" t="-10.0394473821" name="wing_tube_36" />
+			<location r="1.13" t="-10.3183209205" name="wing_tube_37" />
+			<location r="1.13" t="-10.5971944589" name="wing_tube_38" />
+			<location r="1.13" t="-10.8760679972" name="wing_tube_39" />
+			<location r="1.13" t="-11.1549415356" name="wing_tube_40" />
+			<location r="1.13" t="-11.433815074" name="wing_tube_41" />
+			<location r="1.13" t="-11.7126886124" name="wing_tube_42" />
+			<location r="1.13" t="-11.9915621508" name="wing_tube_43" />
+			<location r="1.13" t="-12.2704356892" name="wing_tube_44" />
+			<location r="1.13" t="-12.5493092276" name="wing_tube_45" />
+			<location r="1.13" t="-12.828182766" name="wing_tube_46" />
+			<location r="1.13" t="-13.1070563044" name="wing_tube_47" />
+			<location r="1.13" t="-13.3859298428" name="wing_tube_48" />
+			<location r="1.13" t="-13.6648033812" name="wing_tube_49" />
+			<location r="1.13" t="-13.9436769195" name="wing_tube_50" />
+			<location r="1.13" t="-14.2225504579" name="wing_tube_51" />
+			<location r="1.13" t="-14.5014239963" name="wing_tube_52" />
+			<location r="1.13" t="-14.7802975347" name="wing_tube_53" />
+			<location r="1.13" t="-15.0591710731" name="wing_tube_54" />
+			<location r="1.13" t="-15.3380446115" name="wing_tube_55" />
+			<location r="1.13" t="-15.6169181499" name="wing_tube_56" />
+			<location r="1.13" t="-15.8957916883" name="wing_tube_57" />
+			<location r="1.13" t="-16.1746652267" name="wing_tube_58" />
+			<location r="1.13" t="-16.4535387651" name="wing_tube_59" />
+			<location r="1.13" t="-16.7324123034" name="wing_tube_60" />
+			<location r="1.13" t="-17.0112858418" name="wing_tube_61" />
+			<location r="1.13" t="-17.2901593802" name="wing_tube_62" />
+			<location r="1.13" t="-17.5690329186" name="wing_tube_63" />
+			<location r="1.13" t="-17.847906457" name="wing_tube_64" />
+			<location r="1.13" t="-18.1267799954" name="wing_tube_65" />
+			<location r="1.13" t="-18.4056535338" name="wing_tube_66" />
+			<location r="1.13" t="-18.6845270722" name="wing_tube_67" />
+			<location r="1.13" t="-18.9634006106" name="wing_tube_68" />
+			<location r="1.13" t="-19.242274149" name="wing_tube_69" />
+			<location r="1.13" t="-19.5211476874" name="wing_tube_70" />
+			<location r="1.13" t="-19.8000212257" name="wing_tube_71" />
+			<location r="1.13" t="-20.0788947641" name="wing_tube_72" />
+			<location r="1.13" t="-20.3577683025" name="wing_tube_73" />
+			<location r="1.13" t="-20.6366418409" name="wing_tube_74" />
+			<location r="1.13" t="-20.9155153793" name="wing_tube_75" />
+			<location r="1.13" t="-21.1943889177" name="wing_tube_76" />
+			<location r="1.13" t="-21.4732624561" name="wing_tube_77" />
+			<location r="1.13" t="-21.7521359945" name="wing_tube_78" />
+			<location r="1.13" t="-22.0310095329" name="wing_tube_79" />
+			<location r="1.13" t="-22.3098830713" name="wing_tube_80" />
+			<location r="1.13" t="-22.5887566097" name="wing_tube_81" />
+			<location r="1.13" t="-22.867630148" name="wing_tube_82" />
+			<location r="1.13" t="-23.1465036864" name="wing_tube_83" />
+			<location r="1.13" t="-23.4253772248" name="wing_tube_84" />
+			<location r="1.13" t="-23.7042507632" name="wing_tube_85" />
+			<location r="1.13" t="-23.9831243016" name="wing_tube_86" />
+			<location r="1.13" t="-24.26199784" name="wing_tube_87" />
+			<location r="1.13" t="-24.5408713784" name="wing_tube_88" />
+			<location r="1.13" t="-24.8197449168" name="wing_tube_89" />
+			<location r="1.13" t="-25.0986184552" name="wing_tube_90" />
+			<location r="1.13" t="-25.3774919936" name="wing_tube_91" />
+			<location r="1.13" t="-25.656365532" name="wing_tube_92" />
+			<location r="1.13" t="-25.9352390703" name="wing_tube_93" />
+			<location r="1.13" t="-26.2141126087" name="wing_tube_94" />
+			<location r="1.13" t="-26.4929861471" name="wing_tube_95" />
+			<location r="1.13" t="-26.7718596855" name="wing_tube_96" />
+			<location r="1.13" t="-27.0507332239" name="wing_tube_97" />
+			<location r="1.13" t="-27.3296067623" name="wing_tube_98" />
+			<location r="1.13" t="-27.6084803007" name="wing_tube_99" />
+			<location r="1.13" t="-27.8873538391" name="wing_tube_100" />
+			<location r="1.13" t="-28.1662273775" name="wing_tube_101" />
+			<location r="1.13" t="-28.4451009159" name="wing_tube_102" />
+			<location r="1.13" t="-28.7239744543" name="wing_tube_103" />
+			<location r="1.13" t="-29.0028479926" name="wing_tube_104" />
+			<location r="1.13" t="-29.281721531" name="wing_tube_105" />
+			<location r="1.13" t="-29.5605950694" name="wing_tube_106" />
+			<location r="1.13" t="-29.8394686078" name="wing_tube_107" />
+			<location r="1.13" t="-30.1183421462" name="wing_tube_108" />
+			<location r="1.13" t="-30.3972156846" name="wing_tube_109" />
+			<location r="1.13" t="-30.676089223" name="wing_tube_110" />
+			<location r="1.13" t="-30.9549627614" name="wing_tube_111" />
+			<location r="1.13" t="-31.2338362998" name="wing_tube_112" />
+			<location r="1.13" t="-31.5127098382" name="wing_tube_113" />
+			<location r="1.13" t="-31.7915833766" name="wing_tube_114" />
+			<location r="1.13" t="-32.0704569149" name="wing_tube_115" />
+			<location r="1.13" t="-32.3493304533" name="wing_tube_116" />
+			<location r="1.13" t="-32.6282039917" name="wing_tube_117" />
+			<location r="1.13" t="-32.9070775301" name="wing_tube_118" />
+			<location r="1.13" t="-33.1859510685" name="wing_tube_119" />
+			<location r="1.13" t="-33.4648246069" name="wing_tube_120" />
+			<location r="1.13" t="-33.7436981453" name="wing_tube_121" />
+			<location r="1.13" t="-34.0225716837" name="wing_tube_122" />
+			<location r="1.13" t="-34.3014452221" name="wing_tube_123" />
+			<location r="1.13" t="-34.5803187605" name="wing_tube_124" />
+			<location r="1.13" t="-34.8591922989" name="wing_tube_125" />
+			<location r="1.13" t="-35.1380658372" name="wing_tube_126" />
+			<location r="1.13" t="-35.4169393756" name="wing_tube_127" />
+			<location r="1.13" t="-35.695812914" name="wing_tube_128" />
+			<location r="1.13" t="-35.9746864524" name="wing_tube_129" />
+			<location r="1.13" t="-36.2535599908" name="wing_tube_130" />
+			<location r="1.13" t="-36.5324335292" name="wing_tube_131" />
+			<location r="1.13" t="-36.8113070676" name="wing_tube_132" />
+			<location r="1.13" t="-37.090180606" name="wing_tube_133" />
+			<location r="1.13" t="-37.3690541444" name="wing_tube_134" />
+			<location r="1.13" t="-37.6479276828" name="wing_tube_135" />
+			<location r="1.13" t="-37.9268012212" name="wing_tube_136" />
+			<location r="1.13" t="-38.2056747595" name="wing_tube_137" />
+			<location r="1.13" t="-38.4845482979" name="wing_tube_138" />
+			<location r="1.13" t="-38.7634218363" name="wing_tube_139" />
+			<location r="1.13" t="-39.0422953747" name="wing_tube_140" />
+			<location r="1.13" t="-39.3211689131" name="wing_tube_141" />
+			<location r="1.13" t="-39.6000424515" name="wing_tube_142" />
+			<location r="1.13" t="-39.8789159899" name="wing_tube_143" />
+			<location r="1.13" t="-40.1577895283" name="wing_tube_144" />
+			<location r="1.13" t="-40.4366630667" name="wing_tube_145" />
+			<location r="1.13" t="-40.7155366051" name="wing_tube_146" />
+			<location r="1.13" t="-40.9944101435" name="wing_tube_147" />
+			<location r="1.13" t="-41.2732836818" name="wing_tube_148" />
+			<location r="1.13" t="-41.5521572202" name="wing_tube_149" />
+			<location r="1.13" t="-41.8310307586" name="wing_tube_150" />
+			<location r="1.13" t="-42.109904297" name="wing_tube_151" />
+			<location r="1.13" t="-42.3887778354" name="wing_tube_152" />
+			<location r="1.13" t="-42.6676513738" name="wing_tube_153" />
+			<location r="1.13" t="-42.9465249122" name="wing_tube_154" />
+			<location r="1.13" t="-43.2253984506" name="wing_tube_155" />
+			<location r="1.13" t="-43.504271989" name="wing_tube_156" />
+			<location r="1.13" t="-43.7831455274" name="wing_tube_157" />
+			<location r="1.13" t="-44.0620190658" name="wing_tube_158" />
+			<location r="1.13" t="-44.3408926041" name="wing_tube_159" />
+		</component>
+	</type>
+	
+	<type name="wing_tube" outline="yes">
+		<component type="wing_pixel">
+			
+			<location y="-0.54825" name="wing_pixel_0" />
+			<location y="-0.54395" name="wing_pixel_1" />
+			<location y="-0.53965" name="wing_pixel_2" />
+			<location y="-0.53535" name="wing_pixel_3" />
+			<location y="-0.53105" name="wing_pixel_4" />
+			<location y="-0.52675" name="wing_pixel_5" />
+			<location y="-0.52245" name="wing_pixel_6" />
+			<location y="-0.51815" name="wing_pixel_7" />
+			<location y="-0.51385" name="wing_pixel_8" />
+			<location y="-0.50955" name="wing_pixel_9" />
+			<location y="-0.50525" name="wing_pixel_10" />
+			<location y="-0.50095" name="wing_pixel_11" />
+			<location y="-0.49665" name="wing_pixel_12" />
+			<location y="-0.49235" name="wing_pixel_13" />
+			<location y="-0.48805" name="wing_pixel_14" />
+			<location y="-0.48375" name="wing_pixel_15" />
+			<location y="-0.47945" name="wing_pixel_16" />
+			<location y="-0.47515" name="wing_pixel_17" />
+			<location y="-0.47085" name="wing_pixel_18" />
+			<location y="-0.46655" name="wing_pixel_19" />
+			<location y="-0.46225" name="wing_pixel_20" />
+			<location y="-0.45795" name="wing_pixel_21" />
+			<location y="-0.45365" name="wing_pixel_22" />
+			<location y="-0.44935" name="wing_pixel_23" />
+			<location y="-0.44505" name="wing_pixel_24" />
+			<location y="-0.44075" name="wing_pixel_25" />
+			<location y="-0.43645" name="wing_pixel_26" />
+			<location y="-0.43215" name="wing_pixel_27" />
+			<location y="-0.42785" name="wing_pixel_28" />
+			<location y="-0.42355" name="wing_pixel_29" />
+			<location y="-0.41925" name="wing_pixel_30" />
+			<location y="-0.41495" name="wing_pixel_31" />
+			<location y="-0.41065" name="wing_pixel_32" />
+			<location y="-0.40635" name="wing_pixel_33" />
+			<location y="-0.40205" name="wing_pixel_34" />
+			<location y="-0.39775" name="wing_pixel_35" />
+			<location y="-0.39345" name="wing_pixel_36" />
+			<location y="-0.38915" name="wing_pixel_37" />
+			<location y="-0.38485" name="wing_pixel_38" />
+			<location y="-0.38055" name="wing_pixel_39" />
+			<location y="-0.37625" name="wing_pixel_40" />
+			<location y="-0.37195" name="wing_pixel_41" />
+			<location y="-0.36765" name="wing_pixel_42" />
+			<location y="-0.36335" name="wing_pixel_43" />
+			<location y="-0.35905" name="wing_pixel_44" />
+			<location y="-0.35475" name="wing_pixel_45" />
+			<location y="-0.35045" name="wing_pixel_46" />
+			<location y="-0.34615" name="wing_pixel_47" />
+			<location y="-0.34185" name="wing_pixel_48" />
+			<location y="-0.33755" name="wing_pixel_49" />
+			<location y="-0.33325" name="wing_pixel_50" />
+			<location y="-0.32895" name="wing_pixel_51" />
+			<location y="-0.32465" name="wing_pixel_52" />
+			<location y="-0.32035" name="wing_pixel_53" />
+			<location y="-0.31605" name="wing_pixel_54" />
+			<location y="-0.31175" name="wing_pixel_55" />
+			<location y="-0.30745" name="wing_pixel_56" />
+			<location y="-0.30315" name="wing_pixel_57" />
+			<location y="-0.29885" name="wing_pixel_58" />
+			<location y="-0.29455" name="wing_pixel_59" />
+			<location y="-0.29025" name="wing_pixel_60" />
+			<location y="-0.28595" name="wing_pixel_61" />
+			<location y="-0.28165" name="wing_pixel_62" />
+			<location y="-0.27735" name="wing_pixel_63" />
+			<location y="-0.27305" name="wing_pixel_64" />
+			<location y="-0.26875" name="wing_pixel_65" />
+			<location y="-0.26445" name="wing_pixel_66" />
+			<location y="-0.26015" name="wing_pixel_67" />
+			<location y="-0.25585" name="wing_pixel_68" />
+			<location y="-0.25155" name="wing_pixel_69" />
+			<location y="-0.24725" name="wing_pixel_70" />
+			<location y="-0.24295" name="wing_pixel_71" />
+			<location y="-0.23865" name="wing_pixel_72" />
+			<location y="-0.23435" name="wing_pixel_73" />
+			<location y="-0.23005" name="wing_pixel_74" />
+			<location y="-0.22575" name="wing_pixel_75" />
+			<location y="-0.22145" name="wing_pixel_76" />
+			<location y="-0.21715" name="wing_pixel_77" />
+			<location y="-0.21285" name="wing_pixel_78" />
+			<location y="-0.20855" name="wing_pixel_79" />
+			<location y="-0.20425" name="wing_pixel_80" />
+			<location y="-0.19995" name="wing_pixel_81" />
+			<location y="-0.19565" name="wing_pixel_82" />
+			<location y="-0.19135" name="wing_pixel_83" />
+			<location y="-0.18705" name="wing_pixel_84" />
+			<location y="-0.18275" name="wing_pixel_85" />
+			<location y="-0.17845" name="wing_pixel_86" />
+			<location y="-0.17415" name="wing_pixel_87" />
+			<location y="-0.16985" name="wing_pixel_88" />
+			<location y="-0.16555" name="wing_pixel_89" />
+			<location y="-0.16125" name="wing_pixel_90" />
+			<location y="-0.15695" name="wing_pixel_91" />
+			<location y="-0.15265" name="wing_pixel_92" />
+			<location y="-0.14835" name="wing_pixel_93" />
+			<location y="-0.14405" name="wing_pixel_94" />
+			<location y="-0.13975" name="wing_pixel_95" />
+			<location y="-0.13545" name="wing_pixel_96" />
+			<location y="-0.13115" name="wing_pixel_97" />
+			<location y="-0.12685" name="wing_pixel_98" />
+			<location y="-0.12255" name="wing_pixel_99" />
+			<location y="-0.11825" name="wing_pixel_100" />
+			<location y="-0.11395" name="wing_pixel_101" />
+			<location y="-0.10965" name="wing_pixel_102" />
+			<location y="-0.10535" name="wing_pixel_103" />
+			<location y="-0.10105" name="wing_pixel_104" />
+			<location y="-0.09675" name="wing_pixel_105" />
+			<location y="-0.09245" name="wing_pixel_106" />
+			<location y="-0.08815" name="wing_pixel_107" />
+			<location y="-0.08385" name="wing_pixel_108" />
+			<location y="-0.07955" name="wing_pixel_109" />
+			<location y="-0.07525" name="wing_pixel_110" />
+			<location y="-0.07095" name="wing_pixel_111" />
+			<location y="-0.06665" name="wing_pixel_112" />
+			<location y="-0.06235" name="wing_pixel_113" />
+			<location y="-0.05805" name="wing_pixel_114" />
+			<location y="-0.05375" name="wing_pixel_115" />
+			<location y="-0.04945" name="wing_pixel_116" />
+			<location y="-0.04515" name="wing_pixel_117" />
+			<location y="-0.04085" name="wing_pixel_118" />
+			<location y="-0.03655" name="wing_pixel_119" />
+			<location y="-0.03225" name="wing_pixel_120" />
+			<location y="-0.02795" name="wing_pixel_121" />
+			<location y="-0.02365" name="wing_pixel_122" />
+			<location y="-0.01935" name="wing_pixel_123" />
+			<location y="-0.01505" name="wing_pixel_124" />
+			<location y="-0.01075" name="wing_pixel_125" />
+			<location y="-0.00645" name="wing_pixel_126" />
+			<location y="-0.00215" name="wing_pixel_127" />
+			<location y="0.00215" name="wing_pixel_128" />
+			<location y="0.00645" name="wing_pixel_129" />
+			<location y="0.01075" name="wing_pixel_130" />
+			<location y="0.01505" name="wing_pixel_131" />
+			<location y="0.01935" name="wing_pixel_132" />
+			<location y="0.02365" name="wing_pixel_133" />
+			<location y="0.02795" name="wing_pixel_134" />
+			<location y="0.03225" name="wing_pixel_135" />
+			<location y="0.03655" name="wing_pixel_136" />
+			<location y="0.04085" name="wing_pixel_137" />
+			<location y="0.04515" name="wing_pixel_138" />
+			<location y="0.04945" name="wing_pixel_139" />
+			<location y="0.05375" name="wing_pixel_140" />
+			<location y="0.05805" name="wing_pixel_141" />
+			<location y="0.06235" name="wing_pixel_142" />
+			<location y="0.06665" name="wing_pixel_143" />
+			<location y="0.07095" name="wing_pixel_144" />
+			<location y="0.07525" name="wing_pixel_145" />
+			<location y="0.07955" name="wing_pixel_146" />
+			<location y="0.08385" name="wing_pixel_147" />
+			<location y="0.08815" name="wing_pixel_148" />
+			<location y="0.09245" name="wing_pixel_149" />
+			<location y="0.09675" name="wing_pixel_150" />
+			<location y="0.10105" name="wing_pixel_151" />
+			<location y="0.10535" name="wing_pixel_152" />
+			<location y="0.10965" name="wing_pixel_153" />
+			<location y="0.11395" name="wing_pixel_154" />
+			<location y="0.11825" name="wing_pixel_155" />
+			<location y="0.12255" name="wing_pixel_156" />
+			<location y="0.12685" name="wing_pixel_157" />
+			<location y="0.13115" name="wing_pixel_158" />
+			<location y="0.13545" name="wing_pixel_159" />
+			<location y="0.13975" name="wing_pixel_160" />
+			<location y="0.14405" name="wing_pixel_161" />
+			<location y="0.14835" name="wing_pixel_162" />
+			<location y="0.15265" name="wing_pixel_163" />
+			<location y="0.15695" name="wing_pixel_164" />
+			<location y="0.16125" name="wing_pixel_165" />
+			<location y="0.16555" name="wing_pixel_166" />
+			<location y="0.16985" name="wing_pixel_167" />
+			<location y="0.17415" name="wing_pixel_168" />
+			<location y="0.17845" name="wing_pixel_169" />
+			<location y="0.18275" name="wing_pixel_170" />
+			<location y="0.18705" name="wing_pixel_171" />
+			<location y="0.19135" name="wing_pixel_172" />
+			<location y="0.19565" name="wing_pixel_173" />
+			<location y="0.19995" name="wing_pixel_174" />
+			<location y="0.20425" name="wing_pixel_175" />
+			<location y="0.20855" name="wing_pixel_176" />
+			<location y="0.21285" name="wing_pixel_177" />
+			<location y="0.21715" name="wing_pixel_178" />
+			<location y="0.22145" name="wing_pixel_179" />
+			<location y="0.22575" name="wing_pixel_180" />
+			<location y="0.23005" name="wing_pixel_181" />
+			<location y="0.23435" name="wing_pixel_182" />
+			<location y="0.23865" name="wing_pixel_183" />
+			<location y="0.24295" name="wing_pixel_184" />
+			<location y="0.24725" name="wing_pixel_185" />
+			<location y="0.25155" name="wing_pixel_186" />
+			<location y="0.25585" name="wing_pixel_187" />
+			<location y="0.26015" name="wing_pixel_188" />
+			<location y="0.26445" name="wing_pixel_189" />
+			<location y="0.26875" name="wing_pixel_190" />
+			<location y="0.27305" name="wing_pixel_191" />
+			<location y="0.27735" name="wing_pixel_192" />
+			<location y="0.28165" name="wing_pixel_193" />
+			<location y="0.28595" name="wing_pixel_194" />
+			<location y="0.29025" name="wing_pixel_195" />
+			<location y="0.29455" name="wing_pixel_196" />
+			<location y="0.29885" name="wing_pixel_197" />
+			<location y="0.30315" name="wing_pixel_198" />
+			<location y="0.30745" name="wing_pixel_199" />
+			<location y="0.31175" name="wing_pixel_200" />
+			<location y="0.31605" name="wing_pixel_201" />
+			<location y="0.32035" name="wing_pixel_202" />
+			<location y="0.32465" name="wing_pixel_203" />
+			<location y="0.32895" name="wing_pixel_204" />
+			<location y="0.33325" name="wing_pixel_205" />
+			<location y="0.33755" name="wing_pixel_206" />
+			<location y="0.34185" name="wing_pixel_207" />
+			<location y="0.34615" name="wing_pixel_208" />
+			<location y="0.35045" name="wing_pixel_209" />
+			<location y="0.35475" name="wing_pixel_210" />
+			<location y="0.35905" name="wing_pixel_211" />
+			<location y="0.36335" name="wing_pixel_212" />
+			<location y="0.36765" name="wing_pixel_213" />
+			<location y="0.37195" name="wing_pixel_214" />
+			<location y="0.37625" name="wing_pixel_215" />
+			<location y="0.38055" name="wing_pixel_216" />
+			<location y="0.38485" name="wing_pixel_217" />
+			<location y="0.38915" name="wing_pixel_218" />
+			<location y="0.39345" name="wing_pixel_219" />
+			<location y="0.39775" name="wing_pixel_220" />
+			<location y="0.40205" name="wing_pixel_221" />
+			<location y="0.40635" name="wing_pixel_222" />
+			<location y="0.41065" name="wing_pixel_223" />
+			<location y="0.41495" name="wing_pixel_224" />
+			<location y="0.41925" name="wing_pixel_225" />
+			<location y="0.42355" name="wing_pixel_226" />
+			<location y="0.42785" name="wing_pixel_227" />
+			<location y="0.43215" name="wing_pixel_228" />
+			<location y="0.43645" name="wing_pixel_229" />
+			<location y="0.44075" name="wing_pixel_230" />
+			<location y="0.44505" name="wing_pixel_231" />
+			<location y="0.44935" name="wing_pixel_232" />
+			<location y="0.45365" name="wing_pixel_233" />
+			<location y="0.45795" name="wing_pixel_234" />
+			<location y="0.46225" name="wing_pixel_235" />
+			<location y="0.46655" name="wing_pixel_236" />
+			<location y="0.47085" name="wing_pixel_237" />
+			<location y="0.47515" name="wing_pixel_238" />
+			<location y="0.47945" name="wing_pixel_239" />
+			<location y="0.48375" name="wing_pixel_240" />
+			<location y="0.48805" name="wing_pixel_241" />
+			<location y="0.49235" name="wing_pixel_242" />
+			<location y="0.49665" name="wing_pixel_243" />
+			<location y="0.50095" name="wing_pixel_244" />
+			<location y="0.50525" name="wing_pixel_245" />
+			<location y="0.50955" name="wing_pixel_246" />
+			<location y="0.51385" name="wing_pixel_247" />
+			<location y="0.51815" name="wing_pixel_248" />
+			<location y="0.52245" name="wing_pixel_249" />
+			<location y="0.52675" name="wing_pixel_250" />
+			<location y="0.53105" name="wing_pixel_251" />
+			<location y="0.53535" name="wing_pixel_252" />
+			<location y="0.53965" name="wing_pixel_253" />
+			<location y="0.54395" name="wing_pixel_254" />
+			<location y="0.54825" name="wing_pixel_255" />
+		</component>
+	</type>
+	
+	<type name="wing_pixel" is="detector">
+		<cylinder id="cyl-approx">
+			<centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+			<axis y="1.0" x="0.0" z="0.0"/>
+			<radius val="0.00275"/>
+			<height val="0.0043"/>
+		</cylinder>
+		<algebra val="cyl-approx"/>
+	</type>
+	
 </instrument>
+
diff --git a/instrument/BIOSANS_Definition_2012.xml b/instrument/BIOSANS_Definition_2012.xml
index 490fb69f3e491ef33ec6ec785506257a79938743..07034d2d486155ad929b443ef3c257b08c49aea0 100644
--- a/instrument/BIOSANS_Definition_2012.xml
+++ b/instrument/BIOSANS_Definition_2012.xml
@@ -1,73 +1,679 @@
-<?xml version='1.0' encoding='ASCII'?>
-<instrument last-modified="2013-03-24 15:02:05"
-	name="BioSANS"
-	valid-from="2012-02-01 00:00:00"
-	valid-to="2016-04-26 23:59:59"
-	xmlns="http://www.mantidproject.org/IDF/1.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd">
-	<!---->
-	<defaults>
-		<length unit="metre"/>
-		<angle unit="degree"/>
-		<reference-frame>
-			<along-beam axis="z"/>
-			<pointing-up axis="y"/>
-			<handedness val="right"/>
-		</reference-frame>
-	</defaults>
-	<!--SOURCE AND SAMPLE POSITION-->
-	<component type="moderator">
-		<location z="-13.601"/>
-	</component>
-	<type is="Source" name="moderator"/>
-	<component type="sample-position">
-		<location y="0.0" x="0.0" z="0.0"/>
-	</component>
-	<type is="SamplePos" name="sample-position"/>
-	
-	<!-- ***************************************************************** -->
-	<!--MONITOR 1 -->
-	<component type="monitor1" idlist="monitor1">
-		<location z="-10.5" />
-	</component>
-	<type name="monitor1" is="monitor" />
-	<idlist idname="monitor1">
-		<id val="1" />
-	</idlist>
-	
-	<!--MONITOR 2 -->
-	<component type="timer1" idlist="timer1">
-		<location z="-10.5" />
-	</component>
-	<type name="timer1" is="monitor" />
-	<idlist idname="timer1">
-		<id val="2" />
-	</idlist>
-	
-	
-	<!-- ***************************************************************** -->
-	
-	<!-- Main Detector -->
-	<component type="detector1" idstart="3" idfillbyfirst="x" idstep="256" idstepbyrow="1">
-		<location z='0' />
-	</component>
-	
-	<!-- Detector: -->
-	<type name="detector1" is="rectangular_detector" type="pixel_rectangular" xpixels="192"
-		xstart="0.52525" xstep="-0.0055" ypixels="256" ystart="-0.54825" ystep="0.0043">
-		<properties />
-	</type>
-	
-	<!-- Pixel for Detectors: 5.5x4 mm -->
-	<type is="detector" name="pixel_rectangular">
-		<cuboid id="pixel-shape">
-			<left-front-bottom-point y="-0.002" x="-0.00275" z="0.0" />
-			<left-front-top-point y="0.002" x="-0.00275" z="0.0" />
-			<left-back-bottom-point y="-0.002" x="-0.00275" z="-0.0001" />
-			<right-front-bottom-point y="-0.002" x="0.00275" z="0.0" />
-		</cuboid>
-		<algebra val="pixel-shape" />
-	</type>
-	
-</instrument>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- For help on the notation used to specify an Instrument Definition File 
+     see http://www.mantidproject.org/IDF -->
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
+ name="BioSANS" valid-from   ="1900-01-31 23:59:59"
+                           valid-to     ="2012-01-31 23:59:59"
+		          last-modified="2012-03-23 15:02:05">
+
+  <!-- TEST DEFINITION: NOT READY FOR SHOW TIME -->
+  
+  <defaults>
+    <length unit="meter"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <!-- The z-axis is set parallel to and in the direction of the beam. the 
+           y-axis points up and the coordinate system is right handed. -->
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+    <default-view axis-view="z+"/>
+  </defaults>
+  
+  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+  
+  <!-- source and sample-position components 
+  		Place the beam along the z-axis, the sample holder at (0,0,0) -->
+
+  <component type="source">
+    <location x="0.0" y="0.0" z="-1.0"/>
+  </component>
+  <type name="source" is="Source" />
+  
+  <component type="some-sample-holder">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type name="some-sample-holder" is="SamplePos" />
+  
+  
+  <!-- detector components (including monitors) -->
+  
+  <component type="monitor1" idlist="monitor1">
+    <location z="-0.5"/>
+  </component>
+  <type name="monitor1" is="monitor" />
+ 
+  <component type="timer1" idlist="timer1">
+    <location z="-0.5" />
+  </component>
+  <type name="timer1" is="monitor" />
+ 
+  <component type="sample_aperture">
+    <location z="0.0"/>
+    <parameter name="Size"> <value val="14.0" /> </parameter>
+  </component>
+  <type name="sample_aperture" />
+ 
+
+  <component type="detector1" name="detector1" idlist="det1">
+   <location x="0.0" y="0.0" z="0.0" />
+  </component>   
+
+ 
+  <type name="detector1">
+    <component type="tube" >
+		<location x="-0.487050" name="tube0" />
+		<location x="-0.481950" name="tube1" />
+		<location x="-0.476850" name="tube2" />
+		<location x="-0.471750" name="tube3" />
+		<location x="-0.466650" name="tube4" />
+		<location x="-0.461550" name="tube5" />
+		<location x="-0.456450" name="tube6" />
+		<location x="-0.451350" name="tube7" />
+		<location x="-0.446250" name="tube8" />
+		<location x="-0.441150" name="tube9" />
+		<location x="-0.436050" name="tube10" />
+		<location x="-0.430950" name="tube11" />
+		<location x="-0.425850" name="tube12" />
+		<location x="-0.420750" name="tube13" />
+		<location x="-0.415650" name="tube14" />
+		<location x="-0.410550" name="tube15" />
+		<location x="-0.405450" name="tube16" />
+		<location x="-0.400350" name="tube17" />
+		<location x="-0.395250" name="tube18" />
+		<location x="-0.390150" name="tube19" />
+		<location x="-0.385050" name="tube20" />
+		<location x="-0.379950" name="tube21" />
+		<location x="-0.374850" name="tube22" />
+		<location x="-0.369750" name="tube23" />
+		<location x="-0.364650" name="tube24" />
+		<location x="-0.359550" name="tube25" />
+		<location x="-0.354450" name="tube26" />
+		<location x="-0.349350" name="tube27" />
+		<location x="-0.344250" name="tube28" />
+		<location x="-0.339150" name="tube29" />
+		<location x="-0.334050" name="tube30" />
+		<location x="-0.328950" name="tube31" />
+		<location x="-0.323850" name="tube32" />
+		<location x="-0.318750" name="tube33" />
+		<location x="-0.313650" name="tube34" />
+		<location x="-0.308550" name="tube35" />
+		<location x="-0.303450" name="tube36" />
+		<location x="-0.298350" name="tube37" />
+		<location x="-0.293250" name="tube38" />
+		<location x="-0.288150" name="tube39" />
+		<location x="-0.283050" name="tube40" />
+		<location x="-0.277950" name="tube41" />
+		<location x="-0.272850" name="tube42" />
+		<location x="-0.267750" name="tube43" />
+		<location x="-0.262650" name="tube44" />
+		<location x="-0.257550" name="tube45" />
+		<location x="-0.252450" name="tube46" />
+		<location x="-0.247350" name="tube47" />
+		<location x="-0.242250" name="tube48" />
+		<location x="-0.237150" name="tube49" />
+		<location x="-0.232050" name="tube50" />
+		<location x="-0.226950" name="tube51" />
+		<location x="-0.221850" name="tube52" />
+		<location x="-0.216750" name="tube53" />
+		<location x="-0.211650" name="tube54" />
+		<location x="-0.206550" name="tube55" />
+		<location x="-0.201450" name="tube56" />
+		<location x="-0.196350" name="tube57" />
+		<location x="-0.191250" name="tube58" />
+		<location x="-0.186150" name="tube59" />
+		<location x="-0.181050" name="tube60" />
+		<location x="-0.175950" name="tube61" />
+		<location x="-0.170850" name="tube62" />
+		<location x="-0.165750" name="tube63" />
+		<location x="-0.160650" name="tube64" />
+		<location x="-0.155550" name="tube65" />
+		<location x="-0.150450" name="tube66" />
+		<location x="-0.145350" name="tube67" />
+		<location x="-0.140250" name="tube68" />
+		<location x="-0.135150" name="tube69" />
+		<location x="-0.130050" name="tube70" />
+		<location x="-0.124950" name="tube71" />
+		<location x="-0.119850" name="tube72" />
+		<location x="-0.114750" name="tube73" />
+		<location x="-0.109650" name="tube74" />
+		<location x="-0.104550" name="tube75" />
+		<location x="-0.099450" name="tube76" />
+		<location x="-0.094350" name="tube77" />
+		<location x="-0.089250" name="tube78" />
+		<location x="-0.084150" name="tube79" />
+		<location x="-0.079050" name="tube80" />
+		<location x="-0.073950" name="tube81" />
+		<location x="-0.068850" name="tube82" />
+		<location x="-0.063750" name="tube83" />
+		<location x="-0.058650" name="tube84" />
+		<location x="-0.053550" name="tube85" />
+		<location x="-0.048450" name="tube86" />
+		<location x="-0.043350" name="tube87" />
+		<location x="-0.038250" name="tube88" />
+		<location x="-0.033150" name="tube89" />
+		<location x="-0.028050" name="tube90" />
+		<location x="-0.022950" name="tube91" />
+		<location x="-0.017850" name="tube92" />
+		<location x="-0.012750" name="tube93" />
+		<location x="-0.007650" name="tube94" />
+		<location x="-0.002550" name="tube95" />
+		<location x="0.002550" name="tube96" />
+		<location x="0.007650" name="tube97" />
+		<location x="0.012750" name="tube98" />
+		<location x="0.017850" name="tube99" />
+		<location x="0.022950" name="tube100" />
+		<location x="0.028050" name="tube101" />
+		<location x="0.033150" name="tube102" />
+		<location x="0.038250" name="tube103" />
+		<location x="0.043350" name="tube104" />
+		<location x="0.048450" name="tube105" />
+		<location x="0.053550" name="tube106" />
+		<location x="0.058650" name="tube107" />
+		<location x="0.063750" name="tube108" />
+		<location x="0.068850" name="tube109" />
+		<location x="0.073950" name="tube110" />
+		<location x="0.079050" name="tube111" />
+		<location x="0.084150" name="tube112" />
+		<location x="0.089250" name="tube113" />
+		<location x="0.094350" name="tube114" />
+		<location x="0.099450" name="tube115" />
+		<location x="0.104550" name="tube116" />
+		<location x="0.109650" name="tube117" />
+		<location x="0.114750" name="tube118" />
+		<location x="0.119850" name="tube119" />
+		<location x="0.124950" name="tube120" />
+		<location x="0.130050" name="tube121" />
+		<location x="0.135150" name="tube122" />
+		<location x="0.140250" name="tube123" />
+		<location x="0.145350" name="tube124" />
+		<location x="0.150450" name="tube125" />
+		<location x="0.155550" name="tube126" />
+		<location x="0.160650" name="tube127" />
+		<location x="0.165750" name="tube128" />
+		<location x="0.170850" name="tube129" />
+		<location x="0.175950" name="tube130" />
+		<location x="0.181050" name="tube131" />
+		<location x="0.186150" name="tube132" />
+		<location x="0.191250" name="tube133" />
+		<location x="0.196350" name="tube134" />
+		<location x="0.201450" name="tube135" />
+		<location x="0.206550" name="tube136" />
+		<location x="0.211650" name="tube137" />
+		<location x="0.216750" name="tube138" />
+		<location x="0.221850" name="tube139" />
+		<location x="0.226950" name="tube140" />
+		<location x="0.232050" name="tube141" />
+		<location x="0.237150" name="tube142" />
+		<location x="0.242250" name="tube143" />
+		<location x="0.247350" name="tube144" />
+		<location x="0.252450" name="tube145" />
+		<location x="0.257550" name="tube146" />
+		<location x="0.262650" name="tube147" />
+		<location x="0.267750" name="tube148" />
+		<location x="0.272850" name="tube149" />
+		<location x="0.277950" name="tube150" />
+		<location x="0.283050" name="tube151" />
+		<location x="0.288150" name="tube152" />
+		<location x="0.293250" name="tube153" />
+		<location x="0.298350" name="tube154" />
+		<location x="0.303450" name="tube155" />
+		<location x="0.308550" name="tube156" />
+		<location x="0.313650" name="tube157" />
+		<location x="0.318750" name="tube158" />
+		<location x="0.323850" name="tube159" />
+		<location x="0.328950" name="tube160" />
+		<location x="0.334050" name="tube161" />
+		<location x="0.339150" name="tube162" />
+		<location x="0.344250" name="tube163" />
+		<location x="0.349350" name="tube164" />
+		<location x="0.354450" name="tube165" />
+		<location x="0.359550" name="tube166" />
+		<location x="0.364650" name="tube167" />
+		<location x="0.369750" name="tube168" />
+		<location x="0.374850" name="tube169" />
+		<location x="0.379950" name="tube170" />
+		<location x="0.385050" name="tube171" />
+		<location x="0.390150" name="tube172" />
+		<location x="0.395250" name="tube173" />
+		<location x="0.400350" name="tube174" />
+		<location x="0.405450" name="tube175" />
+		<location x="0.410550" name="tube176" />
+		<location x="0.415650" name="tube177" />
+		<location x="0.420750" name="tube178" />
+		<location x="0.425850" name="tube179" />
+		<location x="0.430950" name="tube180" />
+		<location x="0.436050" name="tube181" />
+		<location x="0.441150" name="tube182" />
+		<location x="0.446250" name="tube183" />
+		<location x="0.451350" name="tube184" />
+		<location x="0.456450" name="tube185" />
+		<location x="0.461550" name="tube186" />
+		<location x="0.466650" name="tube187" />
+		<location x="0.471750" name="tube188" />
+		<location x="0.476850" name="tube189" />
+		<location x="0.481950" name="tube190" />
+		<location x="0.487050" name="tube191" />
+
+    </component>
+  </type>
+  
+  <type name="pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point x="-0.002550" y="-0.002550" z="0.0"  />
+      <left-front-top-point  x="-0.002550" y="0.002550" z="0.0"  />
+      <left-back-bottom-point  x="-0.002550" y="-0.002550" z="-0.000005"  />
+      <right-front-bottom-point  x="0.002550" y="-0.002550" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" /> 
+  </type>    
+  
+  <type name="tube" outline="yes">
+    <properties/>
+    <component type="pixel">
+		<location y="-0.487050" name="pixel0" />
+		<location y="-0.481950" name="pixel1" />
+		<location y="-0.476850" name="pixel2" />
+		<location y="-0.471750" name="pixel3" />
+		<location y="-0.466650" name="pixel4" />
+		<location y="-0.461550" name="pixel5" />
+		<location y="-0.456450" name="pixel6" />
+		<location y="-0.451350" name="pixel7" />
+		<location y="-0.446250" name="pixel8" />
+		<location y="-0.441150" name="pixel9" />
+		<location y="-0.436050" name="pixel10" />
+		<location y="-0.430950" name="pixel11" />
+		<location y="-0.425850" name="pixel12" />
+		<location y="-0.420750" name="pixel13" />
+		<location y="-0.415650" name="pixel14" />
+		<location y="-0.410550" name="pixel15" />
+		<location y="-0.405450" name="pixel16" />
+		<location y="-0.400350" name="pixel17" />
+		<location y="-0.395250" name="pixel18" />
+		<location y="-0.390150" name="pixel19" />
+		<location y="-0.385050" name="pixel20" />
+		<location y="-0.379950" name="pixel21" />
+		<location y="-0.374850" name="pixel22" />
+		<location y="-0.369750" name="pixel23" />
+		<location y="-0.364650" name="pixel24" />
+		<location y="-0.359550" name="pixel25" />
+		<location y="-0.354450" name="pixel26" />
+		<location y="-0.349350" name="pixel27" />
+		<location y="-0.344250" name="pixel28" />
+		<location y="-0.339150" name="pixel29" />
+		<location y="-0.334050" name="pixel30" />
+		<location y="-0.328950" name="pixel31" />
+		<location y="-0.323850" name="pixel32" />
+		<location y="-0.318750" name="pixel33" />
+		<location y="-0.313650" name="pixel34" />
+		<location y="-0.308550" name="pixel35" />
+		<location y="-0.303450" name="pixel36" />
+		<location y="-0.298350" name="pixel37" />
+		<location y="-0.293250" name="pixel38" />
+		<location y="-0.288150" name="pixel39" />
+		<location y="-0.283050" name="pixel40" />
+		<location y="-0.277950" name="pixel41" />
+		<location y="-0.272850" name="pixel42" />
+		<location y="-0.267750" name="pixel43" />
+		<location y="-0.262650" name="pixel44" />
+		<location y="-0.257550" name="pixel45" />
+		<location y="-0.252450" name="pixel46" />
+		<location y="-0.247350" name="pixel47" />
+		<location y="-0.242250" name="pixel48" />
+		<location y="-0.237150" name="pixel49" />
+		<location y="-0.232050" name="pixel50" />
+		<location y="-0.226950" name="pixel51" />
+		<location y="-0.221850" name="pixel52" />
+		<location y="-0.216750" name="pixel53" />
+		<location y="-0.211650" name="pixel54" />
+		<location y="-0.206550" name="pixel55" />
+		<location y="-0.201450" name="pixel56" />
+		<location y="-0.196350" name="pixel57" />
+		<location y="-0.191250" name="pixel58" />
+		<location y="-0.186150" name="pixel59" />
+		<location y="-0.181050" name="pixel60" />
+		<location y="-0.175950" name="pixel61" />
+		<location y="-0.170850" name="pixel62" />
+		<location y="-0.165750" name="pixel63" />
+		<location y="-0.160650" name="pixel64" />
+		<location y="-0.155550" name="pixel65" />
+		<location y="-0.150450" name="pixel66" />
+		<location y="-0.145350" name="pixel67" />
+		<location y="-0.140250" name="pixel68" />
+		<location y="-0.135150" name="pixel69" />
+		<location y="-0.130050" name="pixel70" />
+		<location y="-0.124950" name="pixel71" />
+		<location y="-0.119850" name="pixel72" />
+		<location y="-0.114750" name="pixel73" />
+		<location y="-0.109650" name="pixel74" />
+		<location y="-0.104550" name="pixel75" />
+		<location y="-0.099450" name="pixel76" />
+		<location y="-0.094350" name="pixel77" />
+		<location y="-0.089250" name="pixel78" />
+		<location y="-0.084150" name="pixel79" />
+		<location y="-0.079050" name="pixel80" />
+		<location y="-0.073950" name="pixel81" />
+		<location y="-0.068850" name="pixel82" />
+		<location y="-0.063750" name="pixel83" />
+		<location y="-0.058650" name="pixel84" />
+		<location y="-0.053550" name="pixel85" />
+		<location y="-0.048450" name="pixel86" />
+		<location y="-0.043350" name="pixel87" />
+		<location y="-0.038250" name="pixel88" />
+		<location y="-0.033150" name="pixel89" />
+		<location y="-0.028050" name="pixel90" />
+		<location y="-0.022950" name="pixel91" />
+		<location y="-0.017850" name="pixel92" />
+		<location y="-0.012750" name="pixel93" />
+		<location y="-0.007650" name="pixel94" />
+		<location y="-0.002550" name="pixel95" />
+		<location y="0.002550" name="pixel96" />
+		<location y="0.007650" name="pixel97" />
+		<location y="0.012750" name="pixel98" />
+		<location y="0.017850" name="pixel99" />
+		<location y="0.022950" name="pixel100" />
+		<location y="0.028050" name="pixel101" />
+		<location y="0.033150" name="pixel102" />
+		<location y="0.038250" name="pixel103" />
+		<location y="0.043350" name="pixel104" />
+		<location y="0.048450" name="pixel105" />
+		<location y="0.053550" name="pixel106" />
+		<location y="0.058650" name="pixel107" />
+		<location y="0.063750" name="pixel108" />
+		<location y="0.068850" name="pixel109" />
+		<location y="0.073950" name="pixel110" />
+		<location y="0.079050" name="pixel111" />
+		<location y="0.084150" name="pixel112" />
+		<location y="0.089250" name="pixel113" />
+		<location y="0.094350" name="pixel114" />
+		<location y="0.099450" name="pixel115" />
+		<location y="0.104550" name="pixel116" />
+		<location y="0.109650" name="pixel117" />
+		<location y="0.114750" name="pixel118" />
+		<location y="0.119850" name="pixel119" />
+		<location y="0.124950" name="pixel120" />
+		<location y="0.130050" name="pixel121" />
+		<location y="0.135150" name="pixel122" />
+		<location y="0.140250" name="pixel123" />
+		<location y="0.145350" name="pixel124" />
+		<location y="0.150450" name="pixel125" />
+		<location y="0.155550" name="pixel126" />
+		<location y="0.160650" name="pixel127" />
+		<location y="0.165750" name="pixel128" />
+		<location y="0.170850" name="pixel129" />
+		<location y="0.175950" name="pixel130" />
+		<location y="0.181050" name="pixel131" />
+		<location y="0.186150" name="pixel132" />
+		<location y="0.191250" name="pixel133" />
+		<location y="0.196350" name="pixel134" />
+		<location y="0.201450" name="pixel135" />
+		<location y="0.206550" name="pixel136" />
+		<location y="0.211650" name="pixel137" />
+		<location y="0.216750" name="pixel138" />
+		<location y="0.221850" name="pixel139" />
+		<location y="0.226950" name="pixel140" />
+		<location y="0.232050" name="pixel141" />
+		<location y="0.237150" name="pixel142" />
+		<location y="0.242250" name="pixel143" />
+		<location y="0.247350" name="pixel144" />
+		<location y="0.252450" name="pixel145" />
+		<location y="0.257550" name="pixel146" />
+		<location y="0.262650" name="pixel147" />
+		<location y="0.267750" name="pixel148" />
+		<location y="0.272850" name="pixel149" />
+		<location y="0.277950" name="pixel150" />
+		<location y="0.283050" name="pixel151" />
+		<location y="0.288150" name="pixel152" />
+		<location y="0.293250" name="pixel153" />
+		<location y="0.298350" name="pixel154" />
+		<location y="0.303450" name="pixel155" />
+		<location y="0.308550" name="pixel156" />
+		<location y="0.313650" name="pixel157" />
+		<location y="0.318750" name="pixel158" />
+		<location y="0.323850" name="pixel159" />
+		<location y="0.328950" name="pixel160" />
+		<location y="0.334050" name="pixel161" />
+		<location y="0.339150" name="pixel162" />
+		<location y="0.344250" name="pixel163" />
+		<location y="0.349350" name="pixel164" />
+		<location y="0.354450" name="pixel165" />
+		<location y="0.359550" name="pixel166" />
+		<location y="0.364650" name="pixel167" />
+		<location y="0.369750" name="pixel168" />
+		<location y="0.374850" name="pixel169" />
+		<location y="0.379950" name="pixel170" />
+		<location y="0.385050" name="pixel171" />
+		<location y="0.390150" name="pixel172" />
+		<location y="0.395250" name="pixel173" />
+		<location y="0.400350" name="pixel174" />
+		<location y="0.405450" name="pixel175" />
+		<location y="0.410550" name="pixel176" />
+		<location y="0.415650" name="pixel177" />
+		<location y="0.420750" name="pixel178" />
+		<location y="0.425850" name="pixel179" />
+		<location y="0.430950" name="pixel180" />
+		<location y="0.436050" name="pixel181" />
+		<location y="0.441150" name="pixel182" />
+		<location y="0.446250" name="pixel183" />
+		<location y="0.451350" name="pixel184" />
+		<location y="0.456450" name="pixel185" />
+		<location y="0.461550" name="pixel186" />
+		<location y="0.466650" name="pixel187" />
+		<location y="0.471750" name="pixel188" />
+		<location y="0.476850" name="pixel189" />
+		<location y="0.481950" name="pixel190" />
+		<location y="0.487050" name="pixel191" />
+    </component>
+  </type>
+  
+  <!-- DETECTOR and MONITOR ID LISTS -->
+
+  <idlist idname="det1">
+        <id start="1000000" step="1000" end="1191000" />
+    <id start="1000001" step="1000" end="1191001" />
+    <id start="1000002" step="1000" end="1191002" />
+    <id start="1000003" step="1000" end="1191003" />
+    <id start="1000004" step="1000" end="1191004" />
+    <id start="1000005" step="1000" end="1191005" />
+    <id start="1000006" step="1000" end="1191006" />
+    <id start="1000007" step="1000" end="1191007" />
+    <id start="1000008" step="1000" end="1191008" />
+    <id start="1000009" step="1000" end="1191009" />
+    <id start="1000010" step="1000" end="1191010" />
+    <id start="1000011" step="1000" end="1191011" />
+    <id start="1000012" step="1000" end="1191012" />
+    <id start="1000013" step="1000" end="1191013" />
+    <id start="1000014" step="1000" end="1191014" />
+    <id start="1000015" step="1000" end="1191015" />
+    <id start="1000016" step="1000" end="1191016" />
+    <id start="1000017" step="1000" end="1191017" />
+    <id start="1000018" step="1000" end="1191018" />
+    <id start="1000019" step="1000" end="1191019" />
+    <id start="1000020" step="1000" end="1191020" />
+    <id start="1000021" step="1000" end="1191021" />
+    <id start="1000022" step="1000" end="1191022" />
+    <id start="1000023" step="1000" end="1191023" />
+    <id start="1000024" step="1000" end="1191024" />
+    <id start="1000025" step="1000" end="1191025" />
+    <id start="1000026" step="1000" end="1191026" />
+    <id start="1000027" step="1000" end="1191027" />
+    <id start="1000028" step="1000" end="1191028" />
+    <id start="1000029" step="1000" end="1191029" />
+    <id start="1000030" step="1000" end="1191030" />
+    <id start="1000031" step="1000" end="1191031" />
+    <id start="1000032" step="1000" end="1191032" />
+    <id start="1000033" step="1000" end="1191033" />
+    <id start="1000034" step="1000" end="1191034" />
+    <id start="1000035" step="1000" end="1191035" />
+    <id start="1000036" step="1000" end="1191036" />
+    <id start="1000037" step="1000" end="1191037" />
+    <id start="1000038" step="1000" end="1191038" />
+    <id start="1000039" step="1000" end="1191039" />
+    <id start="1000040" step="1000" end="1191040" />
+    <id start="1000041" step="1000" end="1191041" />
+    <id start="1000042" step="1000" end="1191042" />
+    <id start="1000043" step="1000" end="1191043" />
+    <id start="1000044" step="1000" end="1191044" />
+    <id start="1000045" step="1000" end="1191045" />
+    <id start="1000046" step="1000" end="1191046" />
+    <id start="1000047" step="1000" end="1191047" />
+    <id start="1000048" step="1000" end="1191048" />
+    <id start="1000049" step="1000" end="1191049" />
+    <id start="1000050" step="1000" end="1191050" />
+    <id start="1000051" step="1000" end="1191051" />
+    <id start="1000052" step="1000" end="1191052" />
+    <id start="1000053" step="1000" end="1191053" />
+    <id start="1000054" step="1000" end="1191054" />
+    <id start="1000055" step="1000" end="1191055" />
+    <id start="1000056" step="1000" end="1191056" />
+    <id start="1000057" step="1000" end="1191057" />
+    <id start="1000058" step="1000" end="1191058" />
+    <id start="1000059" step="1000" end="1191059" />
+    <id start="1000060" step="1000" end="1191060" />
+    <id start="1000061" step="1000" end="1191061" />
+    <id start="1000062" step="1000" end="1191062" />
+    <id start="1000063" step="1000" end="1191063" />
+    <id start="1000064" step="1000" end="1191064" />
+    <id start="1000065" step="1000" end="1191065" />
+    <id start="1000066" step="1000" end="1191066" />
+    <id start="1000067" step="1000" end="1191067" />
+    <id start="1000068" step="1000" end="1191068" />
+    <id start="1000069" step="1000" end="1191069" />
+    <id start="1000070" step="1000" end="1191070" />
+    <id start="1000071" step="1000" end="1191071" />
+    <id start="1000072" step="1000" end="1191072" />
+    <id start="1000073" step="1000" end="1191073" />
+    <id start="1000074" step="1000" end="1191074" />
+    <id start="1000075" step="1000" end="1191075" />
+    <id start="1000076" step="1000" end="1191076" />
+    <id start="1000077" step="1000" end="1191077" />
+    <id start="1000078" step="1000" end="1191078" />
+    <id start="1000079" step="1000" end="1191079" />
+    <id start="1000080" step="1000" end="1191080" />
+    <id start="1000081" step="1000" end="1191081" />
+    <id start="1000082" step="1000" end="1191082" />
+    <id start="1000083" step="1000" end="1191083" />
+    <id start="1000084" step="1000" end="1191084" />
+    <id start="1000085" step="1000" end="1191085" />
+    <id start="1000086" step="1000" end="1191086" />
+    <id start="1000087" step="1000" end="1191087" />
+    <id start="1000088" step="1000" end="1191088" />
+    <id start="1000089" step="1000" end="1191089" />
+    <id start="1000090" step="1000" end="1191090" />
+    <id start="1000091" step="1000" end="1191091" />
+    <id start="1000092" step="1000" end="1191092" />
+    <id start="1000093" step="1000" end="1191093" />
+    <id start="1000094" step="1000" end="1191094" />
+    <id start="1000095" step="1000" end="1191095" />
+    <id start="1000096" step="1000" end="1191096" />
+    <id start="1000097" step="1000" end="1191097" />
+    <id start="1000098" step="1000" end="1191098" />
+    <id start="1000099" step="1000" end="1191099" />
+    <id start="1000100" step="1000" end="1191100" />
+    <id start="1000101" step="1000" end="1191101" />
+    <id start="1000102" step="1000" end="1191102" />
+    <id start="1000103" step="1000" end="1191103" />
+    <id start="1000104" step="1000" end="1191104" />
+    <id start="1000105" step="1000" end="1191105" />
+    <id start="1000106" step="1000" end="1191106" />
+    <id start="1000107" step="1000" end="1191107" />
+    <id start="1000108" step="1000" end="1191108" />
+    <id start="1000109" step="1000" end="1191109" />
+    <id start="1000110" step="1000" end="1191110" />
+    <id start="1000111" step="1000" end="1191111" />
+    <id start="1000112" step="1000" end="1191112" />
+    <id start="1000113" step="1000" end="1191113" />
+    <id start="1000114" step="1000" end="1191114" />
+    <id start="1000115" step="1000" end="1191115" />
+    <id start="1000116" step="1000" end="1191116" />
+    <id start="1000117" step="1000" end="1191117" />
+    <id start="1000118" step="1000" end="1191118" />
+    <id start="1000119" step="1000" end="1191119" />
+    <id start="1000120" step="1000" end="1191120" />
+    <id start="1000121" step="1000" end="1191121" />
+    <id start="1000122" step="1000" end="1191122" />
+    <id start="1000123" step="1000" end="1191123" />
+    <id start="1000124" step="1000" end="1191124" />
+    <id start="1000125" step="1000" end="1191125" />
+    <id start="1000126" step="1000" end="1191126" />
+    <id start="1000127" step="1000" end="1191127" />
+    <id start="1000128" step="1000" end="1191128" />
+    <id start="1000129" step="1000" end="1191129" />
+    <id start="1000130" step="1000" end="1191130" />
+    <id start="1000131" step="1000" end="1191131" />
+    <id start="1000132" step="1000" end="1191132" />
+    <id start="1000133" step="1000" end="1191133" />
+    <id start="1000134" step="1000" end="1191134" />
+    <id start="1000135" step="1000" end="1191135" />
+    <id start="1000136" step="1000" end="1191136" />
+    <id start="1000137" step="1000" end="1191137" />
+    <id start="1000138" step="1000" end="1191138" />
+    <id start="1000139" step="1000" end="1191139" />
+    <id start="1000140" step="1000" end="1191140" />
+    <id start="1000141" step="1000" end="1191141" />
+    <id start="1000142" step="1000" end="1191142" />
+    <id start="1000143" step="1000" end="1191143" />
+    <id start="1000144" step="1000" end="1191144" />
+    <id start="1000145" step="1000" end="1191145" />
+    <id start="1000146" step="1000" end="1191146" />
+    <id start="1000147" step="1000" end="1191147" />
+    <id start="1000148" step="1000" end="1191148" />
+    <id start="1000149" step="1000" end="1191149" />
+    <id start="1000150" step="1000" end="1191150" />
+    <id start="1000151" step="1000" end="1191151" />
+    <id start="1000152" step="1000" end="1191152" />
+    <id start="1000153" step="1000" end="1191153" />
+    <id start="1000154" step="1000" end="1191154" />
+    <id start="1000155" step="1000" end="1191155" />
+    <id start="1000156" step="1000" end="1191156" />
+    <id start="1000157" step="1000" end="1191157" />
+    <id start="1000158" step="1000" end="1191158" />
+    <id start="1000159" step="1000" end="1191159" />
+    <id start="1000160" step="1000" end="1191160" />
+    <id start="1000161" step="1000" end="1191161" />
+    <id start="1000162" step="1000" end="1191162" />
+    <id start="1000163" step="1000" end="1191163" />
+    <id start="1000164" step="1000" end="1191164" />
+    <id start="1000165" step="1000" end="1191165" />
+    <id start="1000166" step="1000" end="1191166" />
+    <id start="1000167" step="1000" end="1191167" />
+    <id start="1000168" step="1000" end="1191168" />
+    <id start="1000169" step="1000" end="1191169" />
+    <id start="1000170" step="1000" end="1191170" />
+    <id start="1000171" step="1000" end="1191171" />
+    <id start="1000172" step="1000" end="1191172" />
+    <id start="1000173" step="1000" end="1191173" />
+    <id start="1000174" step="1000" end="1191174" />
+    <id start="1000175" step="1000" end="1191175" />
+    <id start="1000176" step="1000" end="1191176" />
+    <id start="1000177" step="1000" end="1191177" />
+    <id start="1000178" step="1000" end="1191178" />
+    <id start="1000179" step="1000" end="1191179" />
+    <id start="1000180" step="1000" end="1191180" />
+    <id start="1000181" step="1000" end="1191181" />
+    <id start="1000182" step="1000" end="1191182" />
+    <id start="1000183" step="1000" end="1191183" />
+    <id start="1000184" step="1000" end="1191184" />
+    <id start="1000185" step="1000" end="1191185" />
+    <id start="1000186" step="1000" end="1191186" />
+    <id start="1000187" step="1000" end="1191187" />
+    <id start="1000188" step="1000" end="1191188" />
+    <id start="1000189" step="1000" end="1191189" />
+    <id start="1000190" step="1000" end="1191190" />
+    <id start="1000191" step="1000" end="1191191" />
+
+  </idlist> 
+  
+  <!-- DETECTOR and MONITOR ID LISTS -->
+
+  <idlist idname="monitor1">
+    <id val="1" />  
+  </idlist>
+  <idlist idname="timer1">
+    <id val="2" />  
+  </idlist>
+  
+</instrument>
diff --git a/instrument/BIOSANS_Definition_2016.xml b/instrument/BIOSANS_Definition_2016.xml
index 79d631b3c617bce56bbb3f3fd276ffb3f0604575..490fb69f3e491ef33ec6ec785506257a79938743 100644
--- a/instrument/BIOSANS_Definition_2016.xml
+++ b/instrument/BIOSANS_Definition_2016.xml
@@ -1,14 +1,14 @@
 <?xml version='1.0' encoding='ASCII'?>
-<instrument last-modified="2016-05-19 16:43:36.344312"
-	name="BIOSANS"
-	valid-from="2016-04-22 00:00:00"
-	valid-to="2100-01-31 23:59:59"
+<instrument last-modified="2013-03-24 15:02:05"
+	name="BioSANS"
+	valid-from="2012-02-01 00:00:00"
+	valid-to="2016-04-26 23:59:59"
 	xmlns="http://www.mantidproject.org/IDF/1.0"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd">
-	
+	<!---->
 	<defaults>
-		<length unit="meter"/>
+		<length unit="metre"/>
 		<angle unit="degree"/>
 		<reference-frame>
 			<along-beam axis="z"/>
@@ -16,17 +16,15 @@
 			<handedness val="right"/>
 		</reference-frame>
 	</defaults>
-	
 	<!--SOURCE AND SAMPLE POSITION-->
 	<component type="moderator">
 		<location z="-13.601"/>
 	</component>
-	<type name="moderator" is="Source"/>
-	
+	<type is="Source" name="moderator"/>
 	<component type="sample-position">
 		<location y="0.0" x="0.0" z="0.0"/>
 	</component>
-	<type name="sample-position" is="SamplePos"/>
+	<type is="SamplePos" name="sample-position"/>
 	
 	<!-- ***************************************************************** -->
 	<!--MONITOR 1 -->
@@ -47,7 +45,9 @@
 		<id val="2" />
 	</idlist>
 	
+	
 	<!-- ***************************************************************** -->
+	
 	<!-- Main Detector -->
 	<component type="detector1" idstart="3" idfillbyfirst="x" idstep="256" idstepbyrow="1">
 		<location z='0' />
@@ -70,482 +70,4 @@
 		<algebra val="pixel-shape" />
 	</type>
 	
-	
-	<!-- ***************************************************************** -->
-	<!-- Wing Detector -->
-	
-	<!-- Detector list def -->
-	<idlist idname="wing_detector_ids">
-		<id start="49155" end="90114" />
-	</idlist>
-	
-	<component type="wing_detector_arm" idlist="wing_detector_ids">
-		<location />
-	</component>
-	
-	<!-- Detector Banks -->
-	<type name="wing_detector_arm">
-		<component type="wing_detector">
-			<location>
-				<parameter name="r-position">
-					<value val="0"/>
-				</parameter>
-				<parameter name="t-position">
-					<logfile id="rotangle"  eq="0.0+value"/>
-				</parameter>
-				<parameter name="p-position">
-					<value val="0"/>
-				</parameter>
-				<parameter name="rotx">
-					<value val="0"/>
-				</parameter>
-				<parameter name="roty">
-					<logfile id="rotangle"  eq="0.0+value"/>
-				</parameter>
-				<parameter name="rotz">
-					<value val="0"/>
-				</parameter>
-			</location>
-		</component>
-	</type>
-	
-	<type name="wing_detector">
-		<component type="wing_tube">
-			
-			<location r="1.13" t="-0.0" name="wing_tube_0" />
-			<location r="1.13" t="-0.278873538391" name="wing_tube_1" />
-			<location r="1.13" t="-0.557747076782" name="wing_tube_2" />
-			<location r="1.13" t="-0.836620615172" name="wing_tube_3" />
-			<location r="1.13" t="-1.11549415356" name="wing_tube_4" />
-			<location r="1.13" t="-1.39436769195" name="wing_tube_5" />
-			<location r="1.13" t="-1.67324123034" name="wing_tube_6" />
-			<location r="1.13" t="-1.95211476874" name="wing_tube_7" />
-			<location r="1.13" t="-2.23098830713" name="wing_tube_8" />
-			<location r="1.13" t="-2.50986184552" name="wing_tube_9" />
-			<location r="1.13" t="-2.78873538391" name="wing_tube_10" />
-			<location r="1.13" t="-3.0676089223" name="wing_tube_11" />
-			<location r="1.13" t="-3.34648246069" name="wing_tube_12" />
-			<location r="1.13" t="-3.62535599908" name="wing_tube_13" />
-			<location r="1.13" t="-3.90422953747" name="wing_tube_14" />
-			<location r="1.13" t="-4.18310307586" name="wing_tube_15" />
-			<location r="1.13" t="-4.46197661425" name="wing_tube_16" />
-			<location r="1.13" t="-4.74085015264" name="wing_tube_17" />
-			<location r="1.13" t="-5.01972369103" name="wing_tube_18" />
-			<location r="1.13" t="-5.29859722943" name="wing_tube_19" />
-			<location r="1.13" t="-5.57747076782" name="wing_tube_20" />
-			<location r="1.13" t="-5.85634430621" name="wing_tube_21" />
-			<location r="1.13" t="-6.1352178446" name="wing_tube_22" />
-			<location r="1.13" t="-6.41409138299" name="wing_tube_23" />
-			<location r="1.13" t="-6.69296492138" name="wing_tube_24" />
-			<location r="1.13" t="-6.97183845977" name="wing_tube_25" />
-			<location r="1.13" t="-7.25071199816" name="wing_tube_26" />
-			<location r="1.13" t="-7.52958553655" name="wing_tube_27" />
-			<location r="1.13" t="-7.80845907494" name="wing_tube_28" />
-			<location r="1.13" t="-8.08733261333" name="wing_tube_29" />
-			<location r="1.13" t="-8.36620615172" name="wing_tube_30" />
-			<location r="1.13" t="-8.64507969012" name="wing_tube_31" />
-			<location r="1.13" t="-8.92395322851" name="wing_tube_32" />
-			<location r="1.13" t="-9.2028267669" name="wing_tube_33" />
-			<location r="1.13" t="-9.48170030529" name="wing_tube_34" />
-			<location r="1.13" t="-9.76057384368" name="wing_tube_35" />
-			<location r="1.13" t="-10.0394473821" name="wing_tube_36" />
-			<location r="1.13" t="-10.3183209205" name="wing_tube_37" />
-			<location r="1.13" t="-10.5971944589" name="wing_tube_38" />
-			<location r="1.13" t="-10.8760679972" name="wing_tube_39" />
-			<location r="1.13" t="-11.1549415356" name="wing_tube_40" />
-			<location r="1.13" t="-11.433815074" name="wing_tube_41" />
-			<location r="1.13" t="-11.7126886124" name="wing_tube_42" />
-			<location r="1.13" t="-11.9915621508" name="wing_tube_43" />
-			<location r="1.13" t="-12.2704356892" name="wing_tube_44" />
-			<location r="1.13" t="-12.5493092276" name="wing_tube_45" />
-			<location r="1.13" t="-12.828182766" name="wing_tube_46" />
-			<location r="1.13" t="-13.1070563044" name="wing_tube_47" />
-			<location r="1.13" t="-13.3859298428" name="wing_tube_48" />
-			<location r="1.13" t="-13.6648033812" name="wing_tube_49" />
-			<location r="1.13" t="-13.9436769195" name="wing_tube_50" />
-			<location r="1.13" t="-14.2225504579" name="wing_tube_51" />
-			<location r="1.13" t="-14.5014239963" name="wing_tube_52" />
-			<location r="1.13" t="-14.7802975347" name="wing_tube_53" />
-			<location r="1.13" t="-15.0591710731" name="wing_tube_54" />
-			<location r="1.13" t="-15.3380446115" name="wing_tube_55" />
-			<location r="1.13" t="-15.6169181499" name="wing_tube_56" />
-			<location r="1.13" t="-15.8957916883" name="wing_tube_57" />
-			<location r="1.13" t="-16.1746652267" name="wing_tube_58" />
-			<location r="1.13" t="-16.4535387651" name="wing_tube_59" />
-			<location r="1.13" t="-16.7324123034" name="wing_tube_60" />
-			<location r="1.13" t="-17.0112858418" name="wing_tube_61" />
-			<location r="1.13" t="-17.2901593802" name="wing_tube_62" />
-			<location r="1.13" t="-17.5690329186" name="wing_tube_63" />
-			<location r="1.13" t="-17.847906457" name="wing_tube_64" />
-			<location r="1.13" t="-18.1267799954" name="wing_tube_65" />
-			<location r="1.13" t="-18.4056535338" name="wing_tube_66" />
-			<location r="1.13" t="-18.6845270722" name="wing_tube_67" />
-			<location r="1.13" t="-18.9634006106" name="wing_tube_68" />
-			<location r="1.13" t="-19.242274149" name="wing_tube_69" />
-			<location r="1.13" t="-19.5211476874" name="wing_tube_70" />
-			<location r="1.13" t="-19.8000212257" name="wing_tube_71" />
-			<location r="1.13" t="-20.0788947641" name="wing_tube_72" />
-			<location r="1.13" t="-20.3577683025" name="wing_tube_73" />
-			<location r="1.13" t="-20.6366418409" name="wing_tube_74" />
-			<location r="1.13" t="-20.9155153793" name="wing_tube_75" />
-			<location r="1.13" t="-21.1943889177" name="wing_tube_76" />
-			<location r="1.13" t="-21.4732624561" name="wing_tube_77" />
-			<location r="1.13" t="-21.7521359945" name="wing_tube_78" />
-			<location r="1.13" t="-22.0310095329" name="wing_tube_79" />
-			<location r="1.13" t="-22.3098830713" name="wing_tube_80" />
-			<location r="1.13" t="-22.5887566097" name="wing_tube_81" />
-			<location r="1.13" t="-22.867630148" name="wing_tube_82" />
-			<location r="1.13" t="-23.1465036864" name="wing_tube_83" />
-			<location r="1.13" t="-23.4253772248" name="wing_tube_84" />
-			<location r="1.13" t="-23.7042507632" name="wing_tube_85" />
-			<location r="1.13" t="-23.9831243016" name="wing_tube_86" />
-			<location r="1.13" t="-24.26199784" name="wing_tube_87" />
-			<location r="1.13" t="-24.5408713784" name="wing_tube_88" />
-			<location r="1.13" t="-24.8197449168" name="wing_tube_89" />
-			<location r="1.13" t="-25.0986184552" name="wing_tube_90" />
-			<location r="1.13" t="-25.3774919936" name="wing_tube_91" />
-			<location r="1.13" t="-25.656365532" name="wing_tube_92" />
-			<location r="1.13" t="-25.9352390703" name="wing_tube_93" />
-			<location r="1.13" t="-26.2141126087" name="wing_tube_94" />
-			<location r="1.13" t="-26.4929861471" name="wing_tube_95" />
-			<location r="1.13" t="-26.7718596855" name="wing_tube_96" />
-			<location r="1.13" t="-27.0507332239" name="wing_tube_97" />
-			<location r="1.13" t="-27.3296067623" name="wing_tube_98" />
-			<location r="1.13" t="-27.6084803007" name="wing_tube_99" />
-			<location r="1.13" t="-27.8873538391" name="wing_tube_100" />
-			<location r="1.13" t="-28.1662273775" name="wing_tube_101" />
-			<location r="1.13" t="-28.4451009159" name="wing_tube_102" />
-			<location r="1.13" t="-28.7239744543" name="wing_tube_103" />
-			<location r="1.13" t="-29.0028479926" name="wing_tube_104" />
-			<location r="1.13" t="-29.281721531" name="wing_tube_105" />
-			<location r="1.13" t="-29.5605950694" name="wing_tube_106" />
-			<location r="1.13" t="-29.8394686078" name="wing_tube_107" />
-			<location r="1.13" t="-30.1183421462" name="wing_tube_108" />
-			<location r="1.13" t="-30.3972156846" name="wing_tube_109" />
-			<location r="1.13" t="-30.676089223" name="wing_tube_110" />
-			<location r="1.13" t="-30.9549627614" name="wing_tube_111" />
-			<location r="1.13" t="-31.2338362998" name="wing_tube_112" />
-			<location r="1.13" t="-31.5127098382" name="wing_tube_113" />
-			<location r="1.13" t="-31.7915833766" name="wing_tube_114" />
-			<location r="1.13" t="-32.0704569149" name="wing_tube_115" />
-			<location r="1.13" t="-32.3493304533" name="wing_tube_116" />
-			<location r="1.13" t="-32.6282039917" name="wing_tube_117" />
-			<location r="1.13" t="-32.9070775301" name="wing_tube_118" />
-			<location r="1.13" t="-33.1859510685" name="wing_tube_119" />
-			<location r="1.13" t="-33.4648246069" name="wing_tube_120" />
-			<location r="1.13" t="-33.7436981453" name="wing_tube_121" />
-			<location r="1.13" t="-34.0225716837" name="wing_tube_122" />
-			<location r="1.13" t="-34.3014452221" name="wing_tube_123" />
-			<location r="1.13" t="-34.5803187605" name="wing_tube_124" />
-			<location r="1.13" t="-34.8591922989" name="wing_tube_125" />
-			<location r="1.13" t="-35.1380658372" name="wing_tube_126" />
-			<location r="1.13" t="-35.4169393756" name="wing_tube_127" />
-			<location r="1.13" t="-35.695812914" name="wing_tube_128" />
-			<location r="1.13" t="-35.9746864524" name="wing_tube_129" />
-			<location r="1.13" t="-36.2535599908" name="wing_tube_130" />
-			<location r="1.13" t="-36.5324335292" name="wing_tube_131" />
-			<location r="1.13" t="-36.8113070676" name="wing_tube_132" />
-			<location r="1.13" t="-37.090180606" name="wing_tube_133" />
-			<location r="1.13" t="-37.3690541444" name="wing_tube_134" />
-			<location r="1.13" t="-37.6479276828" name="wing_tube_135" />
-			<location r="1.13" t="-37.9268012212" name="wing_tube_136" />
-			<location r="1.13" t="-38.2056747595" name="wing_tube_137" />
-			<location r="1.13" t="-38.4845482979" name="wing_tube_138" />
-			<location r="1.13" t="-38.7634218363" name="wing_tube_139" />
-			<location r="1.13" t="-39.0422953747" name="wing_tube_140" />
-			<location r="1.13" t="-39.3211689131" name="wing_tube_141" />
-			<location r="1.13" t="-39.6000424515" name="wing_tube_142" />
-			<location r="1.13" t="-39.8789159899" name="wing_tube_143" />
-			<location r="1.13" t="-40.1577895283" name="wing_tube_144" />
-			<location r="1.13" t="-40.4366630667" name="wing_tube_145" />
-			<location r="1.13" t="-40.7155366051" name="wing_tube_146" />
-			<location r="1.13" t="-40.9944101435" name="wing_tube_147" />
-			<location r="1.13" t="-41.2732836818" name="wing_tube_148" />
-			<location r="1.13" t="-41.5521572202" name="wing_tube_149" />
-			<location r="1.13" t="-41.8310307586" name="wing_tube_150" />
-			<location r="1.13" t="-42.109904297" name="wing_tube_151" />
-			<location r="1.13" t="-42.3887778354" name="wing_tube_152" />
-			<location r="1.13" t="-42.6676513738" name="wing_tube_153" />
-			<location r="1.13" t="-42.9465249122" name="wing_tube_154" />
-			<location r="1.13" t="-43.2253984506" name="wing_tube_155" />
-			<location r="1.13" t="-43.504271989" name="wing_tube_156" />
-			<location r="1.13" t="-43.7831455274" name="wing_tube_157" />
-			<location r="1.13" t="-44.0620190658" name="wing_tube_158" />
-			<location r="1.13" t="-44.3408926041" name="wing_tube_159" />
-		</component>
-	</type>
-	
-	<type name="wing_tube" outline="yes">
-		<component type="wing_pixel">
-			
-			<location y="-0.54825" name="wing_pixel_0" />
-			<location y="-0.54395" name="wing_pixel_1" />
-			<location y="-0.53965" name="wing_pixel_2" />
-			<location y="-0.53535" name="wing_pixel_3" />
-			<location y="-0.53105" name="wing_pixel_4" />
-			<location y="-0.52675" name="wing_pixel_5" />
-			<location y="-0.52245" name="wing_pixel_6" />
-			<location y="-0.51815" name="wing_pixel_7" />
-			<location y="-0.51385" name="wing_pixel_8" />
-			<location y="-0.50955" name="wing_pixel_9" />
-			<location y="-0.50525" name="wing_pixel_10" />
-			<location y="-0.50095" name="wing_pixel_11" />
-			<location y="-0.49665" name="wing_pixel_12" />
-			<location y="-0.49235" name="wing_pixel_13" />
-			<location y="-0.48805" name="wing_pixel_14" />
-			<location y="-0.48375" name="wing_pixel_15" />
-			<location y="-0.47945" name="wing_pixel_16" />
-			<location y="-0.47515" name="wing_pixel_17" />
-			<location y="-0.47085" name="wing_pixel_18" />
-			<location y="-0.46655" name="wing_pixel_19" />
-			<location y="-0.46225" name="wing_pixel_20" />
-			<location y="-0.45795" name="wing_pixel_21" />
-			<location y="-0.45365" name="wing_pixel_22" />
-			<location y="-0.44935" name="wing_pixel_23" />
-			<location y="-0.44505" name="wing_pixel_24" />
-			<location y="-0.44075" name="wing_pixel_25" />
-			<location y="-0.43645" name="wing_pixel_26" />
-			<location y="-0.43215" name="wing_pixel_27" />
-			<location y="-0.42785" name="wing_pixel_28" />
-			<location y="-0.42355" name="wing_pixel_29" />
-			<location y="-0.41925" name="wing_pixel_30" />
-			<location y="-0.41495" name="wing_pixel_31" />
-			<location y="-0.41065" name="wing_pixel_32" />
-			<location y="-0.40635" name="wing_pixel_33" />
-			<location y="-0.40205" name="wing_pixel_34" />
-			<location y="-0.39775" name="wing_pixel_35" />
-			<location y="-0.39345" name="wing_pixel_36" />
-			<location y="-0.38915" name="wing_pixel_37" />
-			<location y="-0.38485" name="wing_pixel_38" />
-			<location y="-0.38055" name="wing_pixel_39" />
-			<location y="-0.37625" name="wing_pixel_40" />
-			<location y="-0.37195" name="wing_pixel_41" />
-			<location y="-0.36765" name="wing_pixel_42" />
-			<location y="-0.36335" name="wing_pixel_43" />
-			<location y="-0.35905" name="wing_pixel_44" />
-			<location y="-0.35475" name="wing_pixel_45" />
-			<location y="-0.35045" name="wing_pixel_46" />
-			<location y="-0.34615" name="wing_pixel_47" />
-			<location y="-0.34185" name="wing_pixel_48" />
-			<location y="-0.33755" name="wing_pixel_49" />
-			<location y="-0.33325" name="wing_pixel_50" />
-			<location y="-0.32895" name="wing_pixel_51" />
-			<location y="-0.32465" name="wing_pixel_52" />
-			<location y="-0.32035" name="wing_pixel_53" />
-			<location y="-0.31605" name="wing_pixel_54" />
-			<location y="-0.31175" name="wing_pixel_55" />
-			<location y="-0.30745" name="wing_pixel_56" />
-			<location y="-0.30315" name="wing_pixel_57" />
-			<location y="-0.29885" name="wing_pixel_58" />
-			<location y="-0.29455" name="wing_pixel_59" />
-			<location y="-0.29025" name="wing_pixel_60" />
-			<location y="-0.28595" name="wing_pixel_61" />
-			<location y="-0.28165" name="wing_pixel_62" />
-			<location y="-0.27735" name="wing_pixel_63" />
-			<location y="-0.27305" name="wing_pixel_64" />
-			<location y="-0.26875" name="wing_pixel_65" />
-			<location y="-0.26445" name="wing_pixel_66" />
-			<location y="-0.26015" name="wing_pixel_67" />
-			<location y="-0.25585" name="wing_pixel_68" />
-			<location y="-0.25155" name="wing_pixel_69" />
-			<location y="-0.24725" name="wing_pixel_70" />
-			<location y="-0.24295" name="wing_pixel_71" />
-			<location y="-0.23865" name="wing_pixel_72" />
-			<location y="-0.23435" name="wing_pixel_73" />
-			<location y="-0.23005" name="wing_pixel_74" />
-			<location y="-0.22575" name="wing_pixel_75" />
-			<location y="-0.22145" name="wing_pixel_76" />
-			<location y="-0.21715" name="wing_pixel_77" />
-			<location y="-0.21285" name="wing_pixel_78" />
-			<location y="-0.20855" name="wing_pixel_79" />
-			<location y="-0.20425" name="wing_pixel_80" />
-			<location y="-0.19995" name="wing_pixel_81" />
-			<location y="-0.19565" name="wing_pixel_82" />
-			<location y="-0.19135" name="wing_pixel_83" />
-			<location y="-0.18705" name="wing_pixel_84" />
-			<location y="-0.18275" name="wing_pixel_85" />
-			<location y="-0.17845" name="wing_pixel_86" />
-			<location y="-0.17415" name="wing_pixel_87" />
-			<location y="-0.16985" name="wing_pixel_88" />
-			<location y="-0.16555" name="wing_pixel_89" />
-			<location y="-0.16125" name="wing_pixel_90" />
-			<location y="-0.15695" name="wing_pixel_91" />
-			<location y="-0.15265" name="wing_pixel_92" />
-			<location y="-0.14835" name="wing_pixel_93" />
-			<location y="-0.14405" name="wing_pixel_94" />
-			<location y="-0.13975" name="wing_pixel_95" />
-			<location y="-0.13545" name="wing_pixel_96" />
-			<location y="-0.13115" name="wing_pixel_97" />
-			<location y="-0.12685" name="wing_pixel_98" />
-			<location y="-0.12255" name="wing_pixel_99" />
-			<location y="-0.11825" name="wing_pixel_100" />
-			<location y="-0.11395" name="wing_pixel_101" />
-			<location y="-0.10965" name="wing_pixel_102" />
-			<location y="-0.10535" name="wing_pixel_103" />
-			<location y="-0.10105" name="wing_pixel_104" />
-			<location y="-0.09675" name="wing_pixel_105" />
-			<location y="-0.09245" name="wing_pixel_106" />
-			<location y="-0.08815" name="wing_pixel_107" />
-			<location y="-0.08385" name="wing_pixel_108" />
-			<location y="-0.07955" name="wing_pixel_109" />
-			<location y="-0.07525" name="wing_pixel_110" />
-			<location y="-0.07095" name="wing_pixel_111" />
-			<location y="-0.06665" name="wing_pixel_112" />
-			<location y="-0.06235" name="wing_pixel_113" />
-			<location y="-0.05805" name="wing_pixel_114" />
-			<location y="-0.05375" name="wing_pixel_115" />
-			<location y="-0.04945" name="wing_pixel_116" />
-			<location y="-0.04515" name="wing_pixel_117" />
-			<location y="-0.04085" name="wing_pixel_118" />
-			<location y="-0.03655" name="wing_pixel_119" />
-			<location y="-0.03225" name="wing_pixel_120" />
-			<location y="-0.02795" name="wing_pixel_121" />
-			<location y="-0.02365" name="wing_pixel_122" />
-			<location y="-0.01935" name="wing_pixel_123" />
-			<location y="-0.01505" name="wing_pixel_124" />
-			<location y="-0.01075" name="wing_pixel_125" />
-			<location y="-0.00645" name="wing_pixel_126" />
-			<location y="-0.00215" name="wing_pixel_127" />
-			<location y="0.00215" name="wing_pixel_128" />
-			<location y="0.00645" name="wing_pixel_129" />
-			<location y="0.01075" name="wing_pixel_130" />
-			<location y="0.01505" name="wing_pixel_131" />
-			<location y="0.01935" name="wing_pixel_132" />
-			<location y="0.02365" name="wing_pixel_133" />
-			<location y="0.02795" name="wing_pixel_134" />
-			<location y="0.03225" name="wing_pixel_135" />
-			<location y="0.03655" name="wing_pixel_136" />
-			<location y="0.04085" name="wing_pixel_137" />
-			<location y="0.04515" name="wing_pixel_138" />
-			<location y="0.04945" name="wing_pixel_139" />
-			<location y="0.05375" name="wing_pixel_140" />
-			<location y="0.05805" name="wing_pixel_141" />
-			<location y="0.06235" name="wing_pixel_142" />
-			<location y="0.06665" name="wing_pixel_143" />
-			<location y="0.07095" name="wing_pixel_144" />
-			<location y="0.07525" name="wing_pixel_145" />
-			<location y="0.07955" name="wing_pixel_146" />
-			<location y="0.08385" name="wing_pixel_147" />
-			<location y="0.08815" name="wing_pixel_148" />
-			<location y="0.09245" name="wing_pixel_149" />
-			<location y="0.09675" name="wing_pixel_150" />
-			<location y="0.10105" name="wing_pixel_151" />
-			<location y="0.10535" name="wing_pixel_152" />
-			<location y="0.10965" name="wing_pixel_153" />
-			<location y="0.11395" name="wing_pixel_154" />
-			<location y="0.11825" name="wing_pixel_155" />
-			<location y="0.12255" name="wing_pixel_156" />
-			<location y="0.12685" name="wing_pixel_157" />
-			<location y="0.13115" name="wing_pixel_158" />
-			<location y="0.13545" name="wing_pixel_159" />
-			<location y="0.13975" name="wing_pixel_160" />
-			<location y="0.14405" name="wing_pixel_161" />
-			<location y="0.14835" name="wing_pixel_162" />
-			<location y="0.15265" name="wing_pixel_163" />
-			<location y="0.15695" name="wing_pixel_164" />
-			<location y="0.16125" name="wing_pixel_165" />
-			<location y="0.16555" name="wing_pixel_166" />
-			<location y="0.16985" name="wing_pixel_167" />
-			<location y="0.17415" name="wing_pixel_168" />
-			<location y="0.17845" name="wing_pixel_169" />
-			<location y="0.18275" name="wing_pixel_170" />
-			<location y="0.18705" name="wing_pixel_171" />
-			<location y="0.19135" name="wing_pixel_172" />
-			<location y="0.19565" name="wing_pixel_173" />
-			<location y="0.19995" name="wing_pixel_174" />
-			<location y="0.20425" name="wing_pixel_175" />
-			<location y="0.20855" name="wing_pixel_176" />
-			<location y="0.21285" name="wing_pixel_177" />
-			<location y="0.21715" name="wing_pixel_178" />
-			<location y="0.22145" name="wing_pixel_179" />
-			<location y="0.22575" name="wing_pixel_180" />
-			<location y="0.23005" name="wing_pixel_181" />
-			<location y="0.23435" name="wing_pixel_182" />
-			<location y="0.23865" name="wing_pixel_183" />
-			<location y="0.24295" name="wing_pixel_184" />
-			<location y="0.24725" name="wing_pixel_185" />
-			<location y="0.25155" name="wing_pixel_186" />
-			<location y="0.25585" name="wing_pixel_187" />
-			<location y="0.26015" name="wing_pixel_188" />
-			<location y="0.26445" name="wing_pixel_189" />
-			<location y="0.26875" name="wing_pixel_190" />
-			<location y="0.27305" name="wing_pixel_191" />
-			<location y="0.27735" name="wing_pixel_192" />
-			<location y="0.28165" name="wing_pixel_193" />
-			<location y="0.28595" name="wing_pixel_194" />
-			<location y="0.29025" name="wing_pixel_195" />
-			<location y="0.29455" name="wing_pixel_196" />
-			<location y="0.29885" name="wing_pixel_197" />
-			<location y="0.30315" name="wing_pixel_198" />
-			<location y="0.30745" name="wing_pixel_199" />
-			<location y="0.31175" name="wing_pixel_200" />
-			<location y="0.31605" name="wing_pixel_201" />
-			<location y="0.32035" name="wing_pixel_202" />
-			<location y="0.32465" name="wing_pixel_203" />
-			<location y="0.32895" name="wing_pixel_204" />
-			<location y="0.33325" name="wing_pixel_205" />
-			<location y="0.33755" name="wing_pixel_206" />
-			<location y="0.34185" name="wing_pixel_207" />
-			<location y="0.34615" name="wing_pixel_208" />
-			<location y="0.35045" name="wing_pixel_209" />
-			<location y="0.35475" name="wing_pixel_210" />
-			<location y="0.35905" name="wing_pixel_211" />
-			<location y="0.36335" name="wing_pixel_212" />
-			<location y="0.36765" name="wing_pixel_213" />
-			<location y="0.37195" name="wing_pixel_214" />
-			<location y="0.37625" name="wing_pixel_215" />
-			<location y="0.38055" name="wing_pixel_216" />
-			<location y="0.38485" name="wing_pixel_217" />
-			<location y="0.38915" name="wing_pixel_218" />
-			<location y="0.39345" name="wing_pixel_219" />
-			<location y="0.39775" name="wing_pixel_220" />
-			<location y="0.40205" name="wing_pixel_221" />
-			<location y="0.40635" name="wing_pixel_222" />
-			<location y="0.41065" name="wing_pixel_223" />
-			<location y="0.41495" name="wing_pixel_224" />
-			<location y="0.41925" name="wing_pixel_225" />
-			<location y="0.42355" name="wing_pixel_226" />
-			<location y="0.42785" name="wing_pixel_227" />
-			<location y="0.43215" name="wing_pixel_228" />
-			<location y="0.43645" name="wing_pixel_229" />
-			<location y="0.44075" name="wing_pixel_230" />
-			<location y="0.44505" name="wing_pixel_231" />
-			<location y="0.44935" name="wing_pixel_232" />
-			<location y="0.45365" name="wing_pixel_233" />
-			<location y="0.45795" name="wing_pixel_234" />
-			<location y="0.46225" name="wing_pixel_235" />
-			<location y="0.46655" name="wing_pixel_236" />
-			<location y="0.47085" name="wing_pixel_237" />
-			<location y="0.47515" name="wing_pixel_238" />
-			<location y="0.47945" name="wing_pixel_239" />
-			<location y="0.48375" name="wing_pixel_240" />
-			<location y="0.48805" name="wing_pixel_241" />
-			<location y="0.49235" name="wing_pixel_242" />
-			<location y="0.49665" name="wing_pixel_243" />
-			<location y="0.50095" name="wing_pixel_244" />
-			<location y="0.50525" name="wing_pixel_245" />
-			<location y="0.50955" name="wing_pixel_246" />
-			<location y="0.51385" name="wing_pixel_247" />
-			<location y="0.51815" name="wing_pixel_248" />
-			<location y="0.52245" name="wing_pixel_249" />
-			<location y="0.52675" name="wing_pixel_250" />
-			<location y="0.53105" name="wing_pixel_251" />
-			<location y="0.53535" name="wing_pixel_252" />
-			<location y="0.53965" name="wing_pixel_253" />
-			<location y="0.54395" name="wing_pixel_254" />
-			<location y="0.54825" name="wing_pixel_255" />
-		</component>
-	</type>
-	
-	<type name="wing_pixel" is="detector">
-		<cylinder id="cyl-approx">
-			<centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
-			<axis y="1.0" x="0.0" z="0.0"/>
-			<radius val="0.00275"/>
-			<height val="0.0043"/>
-		</cylinder>
-		<algebra val="cyl-approx"/>
-	</type>
-	
-</instrument>
-
+</instrument>
\ No newline at end of file
diff --git a/instrument/BIOSANS_Parameters.xml b/instrument/BIOSANS_Parameters.xml
index 2a13e9a6e0fea75dbf020db3e12c7c576af71790..765bd09f043a59de076a13c317b91bc3e47f3e50 100644
--- a/instrument/BIOSANS_Parameters.xml
+++ b/instrument/BIOSANS_Parameters.xml
@@ -1,53 +1,55 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<parameter-file instrument = "BIOSANS" valid-from="1900-01-31 23:59:59" valid-to="2012-01-31 23:59:59">
-
-<component-link name = "BIOSANS">
-
-<parameter name="detector-name" type="string">
-  <value val="detector1"/>
-</parameter>
-
-<parameter name="default-incident-timer-spectrum">
-  <value val="2"/>
-</parameter>
-
-<parameter name="default-incident-monitor-spectrum">
-  <value val="1"/>
-</parameter>
-
-<parameter name="number-of-x-pixels">
-  <value val="192"/>
-</parameter>
-
-<parameter name="number-of-y-pixels">
-  <value val="192"/>
-</parameter>
-
-<parameter name="number-of-monitors">
-  <value val="2"/>
-</parameter>
-
-<parameter name="x-pixel-size">
-  <value val="5.1000000"/>
-</parameter>
-
-<parameter name="y-pixel-size">
-  <value val="5.1000000"/>
-</parameter>
-
-<parameter name="detector-distance-offset">
-  <value val="837.9"/>
-</parameter>
-
-<!-- Aperture distances for 8 guides to 0 guides -->
-<parameter name="aperture-distances" type="string">
-  <value val="2018.0, 3426.9, 5449.1, 7473.8, 9497.2, 11527.1, 13546.6, 15568.2, 17594.6" />
-</parameter>
-
-<parameter name="source-distance-offset">
-  <value val="-171.0"/>
-</parameter>
-
-</component-link>
-
+<parameter-file instrument = "BIOSANS"
+				valid-from="2016-04-27 00:00:00"
+				valid-to="2100-01-31 23:59:59">
+	
+	<component-link name = "BIOSANS">
+		
+		<parameter name="detector-name" type="string">
+			<value val="detector1"/>
+		</parameter>
+		
+		<parameter name="default-incident-timer-spectrum">
+			<value val="2"/>
+		</parameter>
+		
+		<parameter name="default-incident-monitor-spectrum">
+			<value val="1"/>
+		</parameter>
+		
+		<parameter name="number-of-x-pixels">
+			<value val="192"/>
+		</parameter>
+		
+		<parameter name="number-of-y-pixels">
+			<value val="256"/>
+		</parameter>
+		
+		<parameter name="number-of-monitors">
+			<value val="2"/>
+		</parameter>
+		
+		<parameter name="x-pixel-size">
+			<value val="5.5"/>
+		</parameter>
+		
+		<parameter name="y-pixel-size">
+			<value val="4.0"/>
+		</parameter>
+		
+		<parameter name="detector-distance-offset">
+			<value val="837.9"/>
+		</parameter>
+		
+		<!-- Aperture distances for 8 guides to 0 guides -->
+		<parameter name="aperture-distances" type="string">
+			<value val="2018.0, 3426.9, 5449.1, 7473.8, 9497.2, 11527.1, 13546.6, 15568.2, 17594.6"/>
+		</parameter>
+		
+		<parameter name="source-distance-offset">
+			<value val="-171.0"/>
+		</parameter>
+		
+	</component-link>
+	
 </parameter-file>
diff --git a/instrument/BIOSANS_Parameters_2012.xml b/instrument/BIOSANS_Parameters_2012.xml
index 57a368b4e7daf38d4f6dc1493d3f30c6ca369eab..2a13e9a6e0fea75dbf020db3e12c7c576af71790 100644
--- a/instrument/BIOSANS_Parameters_2012.xml
+++ b/instrument/BIOSANS_Parameters_2012.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<parameter-file instrument = "BIOSANS" valid-from="2012-02-01 00:00:00" valid-to="2016-04-26 23:59:59">
+<parameter-file instrument = "BIOSANS" valid-from="1900-01-31 23:59:59" valid-to="2012-01-31 23:59:59">
 
 <component-link name = "BIOSANS">
 
@@ -20,7 +20,7 @@
 </parameter>
 
 <parameter name="number-of-y-pixels">
-  <value val="256"/>
+  <value val="192"/>
 </parameter>
 
 <parameter name="number-of-monitors">
diff --git a/instrument/BIOSANS_Parameters_2016.xml b/instrument/BIOSANS_Parameters_2016.xml
index 1978909c8d6156b8a876e94108142d69fb74b734..57a368b4e7daf38d4f6dc1493d3f30c6ca369eab 100644
--- a/instrument/BIOSANS_Parameters_2016.xml
+++ b/instrument/BIOSANS_Parameters_2016.xml
@@ -1,55 +1,53 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<parameter-file instrument = "BIOSANS" valid-from="2016-04-27 00:00:00" valid-to="2100-01-31
-	23:59:59">
-	
-	<component-link name = "BIOSANS">
-		
-		<parameter name="detector-name" type="string">
-			<value val="detector1"/>
-		</parameter>
-		
-		<parameter name="default-incident-timer-spectrum">
-			<value val="2"/>
-		</parameter>
-		
-		<parameter name="default-incident-monitor-spectrum">
-			<value val="1"/>
-		</parameter>
-		
-		<parameter name="number-of-x-pixels">
-			<value val="192"/>
-		</parameter>
-		
-		<parameter name="number-of-y-pixels">
-			<value val="256"/>
-		</parameter>
-		
-		<parameter name="number-of-monitors">
-			<value val="2"/>
-		</parameter>
-		
-		<parameter name="x-pixel-size">
-			<value val="5.5"/>
-		</parameter>
-		
-		<parameter name="y-pixel-size">
-			<value val="4.0"/>
-		</parameter>
-		
-		<parameter name="detector-distance-offset">
-			<value val="837.9"/>
-		</parameter>
-		
-		<!-- Aperture distances for 8 guides to 0 guides -->
-		<parameter name="aperture-distances" type="string">
-			<value val="2018.0, 3426.9, 5449.1, 7473.8, 9497.2, 11527.1, 13546.6, 15568.2, 17594.6"
-				/>
-		</parameter>
-		
-		<parameter name="source-distance-offset">
-			<value val="-171.0"/>
-		</parameter>
-		
-	</component-link>
-	
+<parameter-file instrument = "BIOSANS" valid-from="2012-02-01 00:00:00" valid-to="2016-04-26 23:59:59">
+
+<component-link name = "BIOSANS">
+
+<parameter name="detector-name" type="string">
+  <value val="detector1"/>
+</parameter>
+
+<parameter name="default-incident-timer-spectrum">
+  <value val="2"/>
+</parameter>
+
+<parameter name="default-incident-monitor-spectrum">
+  <value val="1"/>
+</parameter>
+
+<parameter name="number-of-x-pixels">
+  <value val="192"/>
+</parameter>
+
+<parameter name="number-of-y-pixels">
+  <value val="256"/>
+</parameter>
+
+<parameter name="number-of-monitors">
+  <value val="2"/>
+</parameter>
+
+<parameter name="x-pixel-size">
+  <value val="5.1000000"/>
+</parameter>
+
+<parameter name="y-pixel-size">
+  <value val="5.1000000"/>
+</parameter>
+
+<parameter name="detector-distance-offset">
+  <value val="837.9"/>
+</parameter>
+
+<!-- Aperture distances for 8 guides to 0 guides -->
+<parameter name="aperture-distances" type="string">
+  <value val="2018.0, 3426.9, 5449.1, 7473.8, 9497.2, 11527.1, 13546.6, 15568.2, 17594.6" />
+</parameter>
+
+<parameter name="source-distance-offset">
+  <value val="-171.0"/>
+</parameter>
+
+</component-link>
+
 </parameter-file>
diff --git a/instrument/CG2_Definition.xml b/instrument/CG2_Definition.xml
index 3196ab4753b7caef5aa3c03f89ce33d401ab23b9..e722ce9274e7990c583730463d2d8fdd54932bef 100644
--- a/instrument/CG2_Definition.xml
+++ b/instrument/CG2_Definition.xml
@@ -5,8 +5,7 @@
             name="CG2"
             valid-from="2016-04-22 00:00:00"
             valid-to="2100-01-31 23:59:59"
-		    last-modified="2016-05-20 08:24:35.208311">
-
+		        last-modified="2018-12-07 13:07:00.000">
 
   <defaults>
     <length unit="metre"/>
@@ -29,40 +28,67 @@
   </component>
   <type is="SamplePos" name="sample-position"/>
 
-
-  <!-- detector components (including monitors) -->
-
   <!-- ***************************************************************** -->
-  <!--MONITOR 1 -->
-  <component type="monitor1" idlist="monitor1">
-    <location z="-10.5" />
-  </component>
-  <type name="monitor1" is="monitor" />
-  <idlist idname="monitor1">
-    <id val="1" />
-  </idlist>
+	<!--MONITOR 1 -->
+	<component type="monitors" idlist="monitor1">
+		<location/>
+	</component>
+	<type name="monitors">
+	    <component type="monitor">
+    		<location z="-0.5" name="monitor1"/>
+    	</component>
+	</type>
+	<idlist idname="monitor1">
+		<id val="1" />
+	</idlist>
 
- <!--MONITOR 2 -->
-  <component type="timer1" idlist="timer1">
-    <location z="-10.5" />
-  </component>
-  <type name="timer1" is="monitor" />
-   <idlist idname="timer1">
-    <id val="2" />
-  </idlist>
+	<!--MONITOR 2: Timer -->
+	<component type="timers" idlist="timer1">
+		<location/>
+	</component>
+	<type name="timers">
+	    <component type="monitor">
+    		<location z="-0.5" name="timer1"/>
+    	</component>
+	</type>
+	<idlist idname="timer1">
+		<id val="2" />
+	</idlist>
 
+	<!--MONITOR SHAPE-->
+	<!--FIXME: Do something real here.-->
+	<type is="monitor" name="monitor">
+		<cylinder id="cyl-approx">
+		<centre-of-bottom-base y="0.0" x="0.0" z="0.0"/>
+		<axis y="0.0" x="0.0" z="1.0"/>
+		<radius val="0.01"/>
+		<height val="0.03"/>
+		</cylinder>
+		<algebra val="cyl-approx"/>
+	</type>
+
+  <!-- ***************************************************************** -->
   <component type="sample_aperture">
     <location z="0.0"/>
     <parameter name="Size"> <value val="14.0" /> </parameter>
   </component>
   <type name="sample_aperture" />
 
-
 <!-- ***************************************************************** -->
 <!-- Main Detector -->
-<component type="detector1" idstart="3" idfillbyfirst="x" idstep="256" idstepbyrow="1">
-    <location z='0' />
-</component>
+	<component type="detector1" idstart="3" idfillbyfirst="x" idstep="256" idstepbyrow="1">
+		<location name="detector1">
+			<parameter name="z">
+				<logfile eq="0.001*value" id="sdd"/>
+			</parameter>
+			<parameter name="x">
+				<logfile eq="0.001*value" id="detector-translation"/>
+			</parameter>
+      <parameter name="y">
+        <value val="0.0"/>
+      </parameter>
+		</location>
+	</component>
 
 <!-- Detector: -->
 <type name="detector1" is="rectangular_detector" type="pixel"
@@ -71,16 +97,16 @@
     <properties />
 </type>
 
-<!-- Pixel for Detector-->
-<type is="detector" name="pixel">
-    <cylinder id="cyl-approx">
-      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
-      <axis y="1.0" x="0.0" z="0.0"/>
-      <radius val="0.00275"/>
-      <height val="0.0043"/>
-    </cylinder>
-    <algebra val="cyl-approx"/>
-</type>
+	<!-- Pixel for Detectors: 5.5x4.3 mm -->
+	<type is="detector" name="pixel">
+		<cuboid id="pixel-shape">
+			<left-front-bottom-point y="-0.00215" x="-0.00275" z="0.0" />
+			<left-front-top-point y="0.00215" x="-0.00275" z="0.0" />
+			<left-back-bottom-point y="-0.00215" x="-0.00275" z="-0.0001" />
+			<right-front-bottom-point y="-0.00215" x="0.00275" z="0.0" />
+		</cuboid>
+		<algebra val="pixel-shape" />
+	</type>
 
 </instrument>
 
diff --git a/instrument/D11_Parameters.xml b/instrument/D11_Parameters.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba6e3abdd083193242f8b81382304c41d02eebaa
--- /dev/null
+++ b/instrument/D11_Parameters.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<parameter-file instrument = "D11">
+
+    <!-- Tau coefficient for DeadTimeCorrection, to be applied for the entire detector -->
+    <component-link name="D11">
+      <parameter name="tau" type="number">
+        <value val="0.00000042" />
+      </parameter>
+    </component-link>
+
+    <!-- GroupingPattern for DeadTimeCorrection, groups the entire detector-->
+    <component-link name="D11">
+      <parameter name="grouping" type="string">
+        <value val="0-65535"/>
+      </parameter>
+    </component-link>
+
+</parameter-file>
diff --git a/instrument/D11lr_Parameters.xml b/instrument/D11lr_Parameters.xml
new file mode 100644
index 0000000000000000000000000000000000000000..54d3e7732dc60970a111bb1abc18e59dbb43c5df
--- /dev/null
+++ b/instrument/D11lr_Parameters.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<parameter-file instrument = "D11lr">
+
+    <!-- Tau coefficient for DeadTimeCorrection, to be applied for the entire detector -->
+    <component-link name="D11lr">
+      <parameter name="tau" type="number">
+        <value val="0.00000042" />
+      </parameter>
+    </component-link>
+
+    <!-- GroupingPattern for DeadTimeCorrection, groups the entire detector-->
+    <component-link name="D11lr">
+      <parameter name="grouping" type="string">
+        <value val="0-16383"/>
+      </parameter>
+    </component-link>
+
+</parameter-file>
diff --git a/instrument/D22_Parameters.xml b/instrument/D22_Parameters.xml
index 8e2dfcc419bc3ae0288223f14b7ddae66ec5d288..b2bc05852637c405b732b91f10e773bbfe6a3ec5 100644
--- a/instrument/D22_Parameters.xml
+++ b/instrument/D22_Parameters.xml
@@ -1,20 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<parameter-file instrument = "D22" valid-from="2017-10-01 23:59:59">
+<parameter-file instrument = "D22">
 
 
-    <!-- This should be removed when the new way of correction is in the workflow-->
+    <!-- Tau coefficient for DeadTimeCorrection, to be applied tube by tube -->
     <component-link name="D22">
-
-      <!-- This is the formula to model the theta dependency of the
-      detector sensitivities because of varying path lengths in the
-      detector volume. This is evaluated with python eval.
-      Note that the np stands for the numpy, p must be the parallax:
-      p = arctan(x/l2) [in radians], where x is the coordinate of the
-      detector pixel, l2 is the sample to detector distance. -->
-      <parameter name="parallax_old" type="string">
-        <value val="1+0.14*np.exp(-4*np.log(2.)*((np.abs(p)-0.588)/0.414)**2)"/>
+      <parameter name="tau" type="number">
+        <value val="0.0000015" />
       </parameter>
+    </component-link>
 
+    <!-- GroupingPattern for DeadTimeCorrection, groups ws indices tube-wise -->
+    <component-link name="D22">
+      <parameter name="grouping" type="string">
+        <value val="0-255,256-511,512-767,768-1023,1024-1279,1280-1535,1536-1791,1792-2047,2048-2303,2304-2559,2560-2815,2816-3071,3072-3327,3328-3583,3584-3839,3840-4095,4096-4351,4352-4607,4608-4863,4864-5119,5120-5375,5376-5631,5632-5887,5888-6143,6144-6399,6400-6655,6656-6911,6912-7167,7168-7423,7424-7679,7680-7935,7936-8191,8192-8447,8448-8703,8704-8959,8960-9215,9216-9471,9472-9727,9728-9983,9984-10239,10240-10495,10496-10751,10752-11007,11008-11263,11264-11519,11520-11775,11776-12031,12032-12287,12288-12543,12544-12799,12800-13055,13056-13311,13312-13567,13568-13823,13824-14079,14080-14335,14336-14591,14592-14847,14848-15103,15104-15359,15360-15615,15616-15871,15872-16127,16128-16383,16384-16639,16640-16895,16896-17151,17152-17407,17408-17663,17664-17919,17920-18175,18176-18431,18432-18687,18688-18943,18944-19199,19200-19455,19456-19711,19712-19967,19968-20223,20224-20479,20480-20735,20736-20991,20992-21247,21248-21503,21504-21759,21760-22015,22016-22271,22272-22527,22528-22783,22784-23039,23040-23295,23296-23551,23552-23807,23808-24063,24064-24319,24320-24575,24576-24831,24832-25087,25088-25343,25344-25599,25600-25855,25856-26111,26112-26367,26368-26623,26624-26879,26880-27135,27136-27391,27392-27647,27648-27903,27904-28159,28160-28415,28416-28671,28672-28927,28928-29183,29184-29439,29440-29695,29696-29951,29952-30207,30208-30463,30464-30719,30720-30975,30976-31231,31232-31487,31488-31743,31744-31999,32000-32255,32256-32511,32512-32767" />
+      </parameter>
     </component-link>
 
     <!-- These parameters are used in ParallaxCorrection algorithm -->
@@ -22,7 +21,7 @@
     <component-link name="detector">
 
     <parameter name="parallax" type="string">
-		  <value val="1+0.14*exp(-4*log(2.)*((t-0.588)/0.414)^2)"/>
+		  <value val="1+0.14*exp(-4*ln(2.)*((t-0.588)/0.414)^2)"/>
 		</parameter>
 
     <parameter name="direction" type="string">
diff --git a/instrument/D22lr_Parameters.xml b/instrument/D22lr_Parameters.xml
index f8dd9a0f56269a32759875dff22184159868ce96..4c91ab7050f99f8dc7a2d044118c78ac724f99ba 100644
--- a/instrument/D22lr_Parameters.xml
+++ b/instrument/D22lr_Parameters.xml
@@ -1,19 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<parameter-file instrument = "D22lr" valid-from="2017-10-01 23:59:59">
+<parameter-file instrument = "D22lr">
 
-    <!-- This should be removed when the new way of correction is in the workflow-->
+    <!-- Tau coefficient for DeadTimeCorrection, to be applied tube by tube -->
     <component-link name="D22lr">
-
-      <!-- This is the formula to model the theta dependency of the
-      detector sensitivities because of varying path lengths in the
-      detector volume. This is evaluated with python eval.
-      Note that the np stands for the numpy, p must be the parallax:
-      p = arctan(x/l2) [in radians], where x is the coordinate of the
-      detector pixel, l2 is the sample to detector distance. -->
-      <parameter name="parallax_old" type="string">
-        <value val="1+0.14*np.exp(-4*np.log(2.)*((np.abs(p)-0.588)/0.414)**2)"/>
+      <parameter name="tau" type="number">
+        <value val="0.0000015" />
       </parameter>
+    </component-link>
 
+    <!-- GroupingPattern for DeadTimeCorrection, groups ws indices tube-wise -->
+    <component-link name="D22">
+      <parameter name="grouping" type="string">
+        <value val="0-127,128-255,256-383,384-511,512-639,640-767,768-895,896-1023,1024-1151,1152-1279,1280-1407,1408-1535,1536-1663,1664-1791,1792-1919,1920-2047,2048-2175,2176-2303,2304-2431,2432-2559,2560-2687,2688-2815,2816-2943,2944-3071,3072-3199,3200-3327,3328-3455,3456-3583,3584-3711,3712-3839,3840-3967,3968-4095,4096-4223,4224-4351,4352-4479,4480-4607,4608-4735,4736-4863,4864-4991,4992-5119,5120-5247,5248-5375,5376-5503,5504-5631,5632-5759,5760-5887,5888-6015,6016-6143,6144-6271,6272-6399,6400-6527,6528-6655,6656-6783,6784-6911,6912-7039,7040-7167,7168-7295,7296-7423,7424-7551,7552-7679,7680-7807,7808-7935,7936-8063,8064-8191,8192-8319,8320-8447,8448-8575,8576-8703,8704-8831,8832-8959,8960-9087,9088-9215,9216-9343,9344-9471,9472-9599,9600-9727,9728-9855,9856-9983,9984-10111,10112-10239,10240-10367,10368-10495,10496-10623,10624-10751,10752-10879,10880-11007,11008-11135,11136-11263,11264-11391,11392-11519,11520-11647,11648-11775,11776-11903,11904-12031,12032-12159,12160-12287,12288-12415,12416-12543,12544-12671,12672-12799,12800-12927,12928-13055,13056-13183,13184-13311,13312-13439,13440-13567,13568-13695,13696-13823,13824-13951,13952-14079,14080-14207,14208-14335,14336-14463,14464-14591,14592-14719,14720-14847,14848-14975,14976-15103,15104-15231,15232-15359,15360-15487,15488-15615,15616-15743,15744-15871,15872-15999,16000-16127,16128-16255,16256-16383" />
+      </parameter>
     </component-link>
 
     <!-- These parameters are used in ParallaxCorrection algorithm -->
@@ -21,7 +20,7 @@
     <component-link name="detector">
 
     <parameter name="parallax" type="string">
-		  <value val="1+0.14*exp(-4*log(2.)*((abs(t)-0.588)/0.414)^2)"/>
+		  <value val="1+0.14*exp(-4*ln(2.)*((abs(t)-0.588)/0.414)^2)"/>
 		</parameter>
 
     <parameter name="direction" type="string">
diff --git a/instrument/D33_Parameters.xml b/instrument/D33_Parameters.xml
index e4e753af62fefadfb675eef25600f5a9a165234c..f251cbebc229e67f401445a216cad18cbf6bf2a9 100644
--- a/instrument/D33_Parameters.xml
+++ b/instrument/D33_Parameters.xml
@@ -1,5 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<parameter-file instrument = "D33" valid-from = "20th May 2010">
+<parameter-file instrument = "D33">
+
+  <!-- Tau coefficient for DeadTimeCorrection, to be applied tube by tube -->
+  <component-link name="D33">
+    <parameter name="tau" type="number">
+      <value val="0.0000015" />
+    </parameter>
+  </component-link>
+
+  <!-- GroupingPattern for DeadTimeCorrection, groups ws indices tube-wise -->
+  <component-link name="D33">
+    <parameter name="grouping" type="string">
+        <value val="0+128+256+384+512+640+768+896+1024+1152+1280+1408+1536+1664+1792+1920+2048+2176+2304+2432+2560+2688+2816+2944+3072+3200+3328+3456+3584+3712+3840+3968+4096+4224+4352+4480+4608+4736+4864+4992+5120+5248+5376+5504+5632+5760+5888+6016+6144+6272+6400+6528+6656+6784+6912+7040+7168+7296+7424+7552+7680+7808+7936+8064+8192+8320+8448+8576+8704+8832+8960+9088+9216+9344+9472+9600+9728+9856+9984+10112+10240+10368+10496+10624+10752+10880+11008+11136+11264+11392+11520+11648+11776+11904+12032+12160+12288+12416+12544+12672+12800+12928+13056+13184+13312+13440+13568+13696+13824+13952+14080+14208+14336+14464+14592+14720+14848+14976+15104+15232+15360+15488+15616+15744+15872+16000+16128+16256+16384+16512+16640+16768+16896+17024+17152+17280+17408+17536+17664+17792+17920+18048+18176+18304+18432+18560+18688+18816+18944+19072+19200+19328+19456+19584+19712+19840+19968+20096+20224+20352+20480+20608+20736+20864+20992+21120+21248+21376+21504+21632+21760+21888+22016+22144+22272+22400+22528+22656+22784+22912+23040+23168+23296+23424+23552+23680+23808+23936+24064+24192+24320+24448+24576+24704+24832+24960+25088+25216+25344+25472+25600+25728+25856+25984+26112+26240+26368+26496+26624+26752+26880+27008+27136+27264+27392+27520+27648+27776+27904+28032+28160+28288+28416+28544+28672+28800+28928+29056+29184+29312+29440+29568+29696+29824+29952+30080+30208+30336+30464+30592+30720+30848+30976+31104+31232+31360+31488+31616+31744+31872+32000+32128+32256+32384+32512+32640,1+129+257+385+513+641+769+897+1025+1153+1281+1409+1537+1665+1793+1921+2049+2177+2305+2433+2561+2689+2817+2945+3073+3201+3329+3457+3585+3713+3841+3969+4097+4225+4353+4481+4609+4737+4865+4993+5121+5249+5377+5505+5633+5761+5889+6017+6145+6273+6401+6529+6657+6785+6913+7041+7169+7297+7425+7553+7681+7809+7937+8065+8193+8321+8449+8577+8705+8833+8961+9089+9217+9345+9473+9601+9729+9857+9985+10113+10241+10369+10497+10625+10753+10881+11009+11137+11265+11393+11521+11649+11777+11905+12033+12161+12289+12417+12545+12673+12801+12929+13057+13185+13313+13441+13569+13697+13825+13953+14081+14209+14337+14465+14593+14721+14849+14977+15105+15233+15361+15489+15617+15745+15873+16001+16129+16257+16385+16513+16641+16769+16897+17025+17153+17281+17409+17537+17665+17793+17921+18049+18177+18305+18433+18561+18689+18817+18945+19073+19201+19329+19457+19585+19713+19841+19969+20097+20225+20353+20481+20609+20737+20865+20993+21121+21249+21377+21505+21633+21761+21889+22017+22145+22273+22401+22529+22657+22785+22913+23041+23169+23297+23425+23553+23681+23809+23937+24065+24193+24321+24449+24577+24705+24833+24961+25089+25217+25345+25473+25601+25729+25857+25985+26113+26241+26369+26497+26625+26753+26881+27009+27137+27265+27393+27521+27649+27777+27905+28033+28161+28289+28417+28545+28673+28801+28929+29057+29185+29313+29441+29569+29697+29825+29953+30081+30209+30337+30465+30593+30721+30849+30977+31105+31233+31361+31489+31617+31745+31873+32001+32129+32257+32385+32513+32641,2+130+258+386+514+642+770+898+1026+1154+1282+1410+1538+1666+1794+1922+2050+2178+2306+2434+2562+2690+2818+2946+3074+3202+3330+3458+3586+3714+3842+3970+4098+4226+4354+4482+4610+4738+4866+4994+5122+5250+5378+5506+5634+5762+5890+6018+6146+6274+6402+6530+6658+6786+6914+7042+7170+7298+7426+7554+7682+7810+7938+8066+8194+8322+8450+8578+8706+8834+8962+9090+9218+9346+9474+9602+9730+9858+9986+10114+10242+10370+10498+10626+10754+10882+11010+11138+11266+11394+11522+11650+11778+11906+12034+12162+12290+12418+12546+12674+12802+12930+13058+13186+13314+13442+13570+13698+13826+13954+14082+14210+14338+14466+14594+14722+14850+14978+15106+15234+15362+15490+15618+15746+15874+16002+16130+16258+16386+16514+16642+16770+16898+17026+17154+17282+17410+17538+17666+17794+17922+18050+18178+18306+18434+18562+18690+18818+18946+19074+19202+19330+19458+19586+19714+19842+19970+20098+20226+20354+20482+20610+20738+20866+20994+21122+21250+21378+21506+21634+21762+21890+22018+22146+22274+22402+22530+22658+22786+22914+23042+23170+23298+23426+23554+23682+23810+23938+24066+24194+24322+24450+24578+24706+24834+24962+25090+25218+25346+25474+25602+25730+25858+25986+26114+26242+26370+26498+26626+26754+26882+27010+27138+27266+27394+27522+27650+27778+27906+28034+28162+28290+28418+28546+28674+28802+28930+29058+29186+29314+29442+29570+29698+29826+29954+30082+30210+30338+30466+30594+30722+30850+30978+31106+31234+31362+31490+31618+31746+31874+32002+32130+32258+32386+32514+32642,3+131+259+387+515+643+771+899+1027+1155+1283+1411+1539+1667+1795+1923+2051+2179+2307+2435+2563+2691+2819+2947+3075+3203+3331+3459+3587+3715+3843+3971+4099+4227+4355+4483+4611+4739+4867+4995+5123+5251+5379+5507+5635+5763+5891+6019+6147+6275+6403+6531+6659+6787+6915+7043+7171+7299+7427+7555+7683+7811+7939+8067+8195+8323+8451+8579+8707+8835+8963+9091+9219+9347+9475+9603+9731+9859+9987+10115+10243+10371+10499+10627+10755+10883+11011+11139+11267+11395+11523+11651+11779+11907+12035+12163+12291+12419+12547+12675+12803+12931+13059+13187+13315+13443+13571+13699+13827+13955+14083+14211+14339+14467+14595+14723+14851+14979+15107+15235+15363+15491+15619+15747+15875+16003+16131+16259+16387+16515+16643+16771+16899+17027+17155+17283+17411+17539+17667+17795+17923+18051+18179+18307+18435+18563+18691+18819+18947+19075+19203+19331+19459+19587+19715+19843+19971+20099+20227+20355+20483+20611+20739+20867+20995+21123+21251+21379+21507+21635+21763+21891+22019+22147+22275+22403+22531+22659+22787+22915+23043+23171+23299+23427+23555+23683+23811+23939+24067+24195+24323+24451+24579+24707+24835+24963+25091+25219+25347+25475+25603+25731+25859+25987+26115+26243+26371+26499+26627+26755+26883+27011+27139+27267+27395+27523+27651+27779+27907+28035+28163+28291+28419+28547+28675+28803+28931+29059+29187+29315+29443+29571+29699+29827+29955+30083+30211+30339+30467+30595+30723+30851+30979+31107+31235+31363+31491+31619+31747+31875+32003+32131+32259+32387+32515+32643,4+132+260+388+516+644+772+900+1028+1156+1284+1412+1540+1668+1796+1924+2052+2180+2308+2436+2564+2692+2820+2948+3076+3204+3332+3460+3588+3716+3844+3972+4100+4228+4356+4484+4612+4740+4868+4996+5124+5252+5380+5508+5636+5764+5892+6020+6148+6276+6404+6532+6660+6788+6916+7044+7172+7300+7428+7556+7684+7812+7940+8068+8196+8324+8452+8580+8708+8836+8964+9092+9220+9348+9476+9604+9732+9860+9988+10116+10244+10372+10500+10628+10756+10884+11012+11140+11268+11396+11524+11652+11780+11908+12036+12164+12292+12420+12548+12676+12804+12932+13060+13188+13316+13444+13572+13700+13828+13956+14084+14212+14340+14468+14596+14724+14852+14980+15108+15236+15364+15492+15620+15748+15876+16004+16132+16260+16388+16516+16644+16772+16900+17028+17156+17284+17412+17540+17668+17796+17924+18052+18180+18308+18436+18564+18692+18820+18948+19076+19204+19332+19460+19588+19716+19844+19972+20100+20228+20356+20484+20612+20740+20868+20996+21124+21252+21380+21508+21636+21764+21892+22020+22148+22276+22404+22532+22660+22788+22916+23044+23172+23300+23428+23556+23684+23812+23940+24068+24196+24324+24452+24580+24708+24836+24964+25092+25220+25348+25476+25604+25732+25860+25988+26116+26244+26372+26500+26628+26756+26884+27012+27140+27268+27396+27524+27652+27780+27908+28036+28164+28292+28420+28548+28676+28804+28932+29060+29188+29316+29444+29572+29700+29828+29956+30084+30212+30340+30468+30596+30724+30852+30980+31108+31236+31364+31492+31620+31748+31876+32004+32132+32260+32388+32516+32644,5+133+261+389+517+645+773+901+1029+1157+1285+1413+1541+1669+1797+1925+2053+2181+2309+2437+2565+2693+2821+2949+3077+3205+3333+3461+3589+3717+3845+3973+4101+4229+4357+4485+4613+4741+4869+4997+5125+5253+5381+5509+5637+5765+5893+6021+6149+6277+6405+6533+6661+6789+6917+7045+7173+7301+7429+7557+7685+7813+7941+8069+8197+8325+8453+8581+8709+8837+8965+9093+9221+9349+9477+9605+9733+9861+9989+10117+10245+10373+10501+10629+10757+10885+11013+11141+11269+11397+11525+11653+11781+11909+12037+12165+12293+12421+12549+12677+12805+12933+13061+13189+13317+13445+13573+13701+13829+13957+14085+14213+14341+14469+14597+14725+14853+14981+15109+15237+15365+15493+15621+15749+15877+16005+16133+16261+16389+16517+16645+16773+16901+17029+17157+17285+17413+17541+17669+17797+17925+18053+18181+18309+18437+18565+18693+18821+18949+19077+19205+19333+19461+19589+19717+19845+19973+20101+20229+20357+20485+20613+20741+20869+20997+21125+21253+21381+21509+21637+21765+21893+22021+22149+22277+22405+22533+22661+22789+22917+23045+23173+23301+23429+23557+23685+23813+23941+24069+24197+24325+24453+24581+24709+24837+24965+25093+25221+25349+25477+25605+25733+25861+25989+26117+26245+26373+26501+26629+26757+26885+27013+27141+27269+27397+27525+27653+27781+27909+28037+28165+28293+28421+28549+28677+28805+28933+29061+29189+29317+29445+29573+29701+29829+29957+30085+30213+30341+30469+30597+30725+30853+30981+31109+31237+31365+31493+31621+31749+31877+32005+32133+32261+32389+32517+32645,6+134+262+390+518+646+774+902+1030+1158+1286+1414+1542+1670+1798+1926+2054+2182+2310+2438+2566+2694+2822+2950+3078+3206+3334+3462+3590+3718+3846+3974+4102+4230+4358+4486+4614+4742+4870+4998+5126+5254+5382+5510+5638+5766+5894+6022+6150+6278+6406+6534+6662+6790+6918+7046+7174+7302+7430+7558+7686+7814+7942+8070+8198+8326+8454+8582+8710+8838+8966+9094+9222+9350+9478+9606+9734+9862+9990+10118+10246+10374+10502+10630+10758+10886+11014+11142+11270+11398+11526+11654+11782+11910+12038+12166+12294+12422+12550+12678+12806+12934+13062+13190+13318+13446+13574+13702+13830+13958+14086+14214+14342+14470+14598+14726+14854+14982+15110+15238+15366+15494+15622+15750+15878+16006+16134+16262+16390+16518+16646+16774+16902+17030+17158+17286+17414+17542+17670+17798+17926+18054+18182+18310+18438+18566+18694+18822+18950+19078+19206+19334+19462+19590+19718+19846+19974+20102+20230+20358+20486+20614+20742+20870+20998+21126+21254+21382+21510+21638+21766+21894+22022+22150+22278+22406+22534+22662+22790+22918+23046+23174+23302+23430+23558+23686+23814+23942+24070+24198+24326+24454+24582+24710+24838+24966+25094+25222+25350+25478+25606+25734+25862+25990+26118+26246+26374+26502+26630+26758+26886+27014+27142+27270+27398+27526+27654+27782+27910+28038+28166+28294+28422+28550+28678+28806+28934+29062+29190+29318+29446+29574+29702+29830+29958+30086+30214+30342+30470+30598+30726+30854+30982+31110+31238+31366+31494+31622+31750+31878+32006+32134+32262+32390+32518+32646,7+135+263+391+519+647+775+903+1031+1159+1287+1415+1543+1671+1799+1927+2055+2183+2311+2439+2567+2695+2823+2951+3079+3207+3335+3463+3591+3719+3847+3975+4103+4231+4359+4487+4615+4743+4871+4999+5127+5255+5383+5511+5639+5767+5895+6023+6151+6279+6407+6535+6663+6791+6919+7047+7175+7303+7431+7559+7687+7815+7943+8071+8199+8327+8455+8583+8711+8839+8967+9095+9223+9351+9479+9607+9735+9863+9991+10119+10247+10375+10503+10631+10759+10887+11015+11143+11271+11399+11527+11655+11783+11911+12039+12167+12295+12423+12551+12679+12807+12935+13063+13191+13319+13447+13575+13703+13831+13959+14087+14215+14343+14471+14599+14727+14855+14983+15111+15239+15367+15495+15623+15751+15879+16007+16135+16263+16391+16519+16647+16775+16903+17031+17159+17287+17415+17543+17671+17799+17927+18055+18183+18311+18439+18567+18695+18823+18951+19079+19207+19335+19463+19591+19719+19847+19975+20103+20231+20359+20487+20615+20743+20871+20999+21127+21255+21383+21511+21639+21767+21895+22023+22151+22279+22407+22535+22663+22791+22919+23047+23175+23303+23431+23559+23687+23815+23943+24071+24199+24327+24455+24583+24711+24839+24967+25095+25223+25351+25479+25607+25735+25863+25991+26119+26247+26375+26503+26631+26759+26887+27015+27143+27271+27399+27527+27655+27783+27911+28039+28167+28295+28423+28551+28679+28807+28935+29063+29191+29319+29447+29575+29703+29831+29959+30087+30215+30343+30471+30599+30727+30855+30983+31111+31239+31367+31495+31623+31751+31879+32007+32135+32263+32391+32519+32647,8+136+264+392+520+648+776+904+1032+1160+1288+1416+1544+1672+1800+1928+2056+2184+2312+2440+2568+2696+2824+2952+3080+3208+3336+3464+3592+3720+3848+3976+4104+4232+4360+4488+4616+4744+4872+5000+5128+5256+5384+5512+5640+5768+5896+6024+6152+6280+6408+6536+6664+6792+6920+7048+7176+7304+7432+7560+7688+7816+7944+8072+8200+8328+8456+8584+8712+8840+8968+9096+9224+9352+9480+9608+9736+9864+9992+10120+10248+10376+10504+10632+10760+10888+11016+11144+11272+11400+11528+11656+11784+11912+12040+12168+12296+12424+12552+12680+12808+12936+13064+13192+13320+13448+13576+13704+13832+13960+14088+14216+14344+14472+14600+14728+14856+14984+15112+15240+15368+15496+15624+15752+15880+16008+16136+16264+16392+16520+16648+16776+16904+17032+17160+17288+17416+17544+17672+17800+17928+18056+18184+18312+18440+18568+18696+18824+18952+19080+19208+19336+19464+19592+19720+19848+19976+20104+20232+20360+20488+20616+20744+20872+21000+21128+21256+21384+21512+21640+21768+21896+22024+22152+22280+22408+22536+22664+22792+22920+23048+23176+23304+23432+23560+23688+23816+23944+24072+24200+24328+24456+24584+24712+24840+24968+25096+25224+25352+25480+25608+25736+25864+25992+26120+26248+26376+26504+26632+26760+26888+27016+27144+27272+27400+27528+27656+27784+27912+28040+28168+28296+28424+28552+28680+28808+28936+29064+29192+29320+29448+29576+29704+29832+29960+30088+30216+30344+30472+30600+30728+30856+30984+31112+31240+31368+31496+31624+31752+31880+32008+32136+32264+32392+32520+32648,9+137+265+393+521+649+777+905+1033+1161+1289+1417+1545+1673+1801+1929+2057+2185+2313+2441+2569+2697+2825+2953+3081+3209+3337+3465+3593+3721+3849+3977+4105+4233+4361+4489+4617+4745+4873+5001+5129+5257+5385+5513+5641+5769+5897+6025+6153+6281+6409+6537+6665+6793+6921+7049+7177+7305+7433+7561+7689+7817+7945+8073+8201+8329+8457+8585+8713+8841+8969+9097+9225+9353+9481+9609+9737+9865+9993+10121+10249+10377+10505+10633+10761+10889+11017+11145+11273+11401+11529+11657+11785+11913+12041+12169+12297+12425+12553+12681+12809+12937+13065+13193+13321+13449+13577+13705+13833+13961+14089+14217+14345+14473+14601+14729+14857+14985+15113+15241+15369+15497+15625+15753+15881+16009+16137+16265+16393+16521+16649+16777+16905+17033+17161+17289+17417+17545+17673+17801+17929+18057+18185+18313+18441+18569+18697+18825+18953+19081+19209+19337+19465+19593+19721+19849+19977+20105+20233+20361+20489+20617+20745+20873+21001+21129+21257+21385+21513+21641+21769+21897+22025+22153+22281+22409+22537+22665+22793+22921+23049+23177+23305+23433+23561+23689+23817+23945+24073+24201+24329+24457+24585+24713+24841+24969+25097+25225+25353+25481+25609+25737+25865+25993+26121+26249+26377+26505+26633+26761+26889+27017+27145+27273+27401+27529+27657+27785+27913+28041+28169+28297+28425+28553+28681+28809+28937+29065+29193+29321+29449+29577+29705+29833+29961+30089+30217+30345+30473+30601+30729+30857+30985+31113+31241+31369+31497+31625+31753+31881+32009+32137+32265+32393+32521+32649,10+138+266+394+522+650+778+906+1034+1162+1290+1418+1546+1674+1802+1930+2058+2186+2314+2442+2570+2698+2826+2954+3082+3210+3338+3466+3594+3722+3850+3978+4106+4234+4362+4490+4618+4746+4874+5002+5130+5258+5386+5514+5642+5770+5898+6026+6154+6282+6410+6538+6666+6794+6922+7050+7178+7306+7434+7562+7690+7818+7946+8074+8202+8330+8458+8586+8714+8842+8970+9098+9226+9354+9482+9610+9738+9866+9994+10122+10250+10378+10506+10634+10762+10890+11018+11146+11274+11402+11530+11658+11786+11914+12042+12170+12298+12426+12554+12682+12810+12938+13066+13194+13322+13450+13578+13706+13834+13962+14090+14218+14346+14474+14602+14730+14858+14986+15114+15242+15370+15498+15626+15754+15882+16010+16138+16266+16394+16522+16650+16778+16906+17034+17162+17290+17418+17546+17674+17802+17930+18058+18186+18314+18442+18570+18698+18826+18954+19082+19210+19338+19466+19594+19722+19850+19978+20106+20234+20362+20490+20618+20746+20874+21002+21130+21258+21386+21514+21642+21770+21898+22026+22154+22282+22410+22538+22666+22794+22922+23050+23178+23306+23434+23562+23690+23818+23946+24074+24202+24330+24458+24586+24714+24842+24970+25098+25226+25354+25482+25610+25738+25866+25994+26122+26250+26378+26506+26634+26762+26890+27018+27146+27274+27402+27530+27658+27786+27914+28042+28170+28298+28426+28554+28682+28810+28938+29066+29194+29322+29450+29578+29706+29834+29962+30090+30218+30346+30474+30602+30730+30858+30986+31114+31242+31370+31498+31626+31754+31882+32010+32138+32266+32394+32522+32650,11+139+267+395+523+651+779+907+1035+1163+1291+1419+1547+1675+1803+1931+2059+2187+2315+2443+2571+2699+2827+2955+3083+3211+3339+3467+3595+3723+3851+3979+4107+4235+4363+4491+4619+4747+4875+5003+5131+5259+5387+5515+5643+5771+5899+6027+6155+6283+6411+6539+6667+6795+6923+7051+7179+7307+7435+7563+7691+7819+7947+8075+8203+8331+8459+8587+8715+8843+8971+9099+9227+9355+9483+9611+9739+9867+9995+10123+10251+10379+10507+10635+10763+10891+11019+11147+11275+11403+11531+11659+11787+11915+12043+12171+12299+12427+12555+12683+12811+12939+13067+13195+13323+13451+13579+13707+13835+13963+14091+14219+14347+14475+14603+14731+14859+14987+15115+15243+15371+15499+15627+15755+15883+16011+16139+16267+16395+16523+16651+16779+16907+17035+17163+17291+17419+17547+17675+17803+17931+18059+18187+18315+18443+18571+18699+18827+18955+19083+19211+19339+19467+19595+19723+19851+19979+20107+20235+20363+20491+20619+20747+20875+21003+21131+21259+21387+21515+21643+21771+21899+22027+22155+22283+22411+22539+22667+22795+22923+23051+23179+23307+23435+23563+23691+23819+23947+24075+24203+24331+24459+24587+24715+24843+24971+25099+25227+25355+25483+25611+25739+25867+25995+26123+26251+26379+26507+26635+26763+26891+27019+27147+27275+27403+27531+27659+27787+27915+28043+28171+28299+28427+28555+28683+28811+28939+29067+29195+29323+29451+29579+29707+29835+29963+30091+30219+30347+30475+30603+30731+30859+30987+31115+31243+31371+31499+31627+31755+31883+32011+32139+32267+32395+32523+32651,12+140+268+396+524+652+780+908+1036+1164+1292+1420+1548+1676+1804+1932+2060+2188+2316+2444+2572+2700+2828+2956+3084+3212+3340+3468+3596+3724+3852+3980+4108+4236+4364+4492+4620+4748+4876+5004+5132+5260+5388+5516+5644+5772+5900+6028+6156+6284+6412+6540+6668+6796+6924+7052+7180+7308+7436+7564+7692+7820+7948+8076+8204+8332+8460+8588+8716+8844+8972+9100+9228+9356+9484+9612+9740+9868+9996+10124+10252+10380+10508+10636+10764+10892+11020+11148+11276+11404+11532+11660+11788+11916+12044+12172+12300+12428+12556+12684+12812+12940+13068+13196+13324+13452+13580+13708+13836+13964+14092+14220+14348+14476+14604+14732+14860+14988+15116+15244+15372+15500+15628+15756+15884+16012+16140+16268+16396+16524+16652+16780+16908+17036+17164+17292+17420+17548+17676+17804+17932+18060+18188+18316+18444+18572+18700+18828+18956+19084+19212+19340+19468+19596+19724+19852+19980+20108+20236+20364+20492+20620+20748+20876+21004+21132+21260+21388+21516+21644+21772+21900+22028+22156+22284+22412+22540+22668+22796+22924+23052+23180+23308+23436+23564+23692+23820+23948+24076+24204+24332+24460+24588+24716+24844+24972+25100+25228+25356+25484+25612+25740+25868+25996+26124+26252+26380+26508+26636+26764+26892+27020+27148+27276+27404+27532+27660+27788+27916+28044+28172+28300+28428+28556+28684+28812+28940+29068+29196+29324+29452+29580+29708+29836+29964+30092+30220+30348+30476+30604+30732+30860+30988+31116+31244+31372+31500+31628+31756+31884+32012+32140+32268+32396+32524+32652,13+141+269+397+525+653+781+909+1037+1165+1293+1421+1549+1677+1805+1933+2061+2189+2317+2445+2573+2701+2829+2957+3085+3213+3341+3469+3597+3725+3853+3981+4109+4237+4365+4493+4621+4749+4877+5005+5133+5261+5389+5517+5645+5773+5901+6029+6157+6285+6413+6541+6669+6797+6925+7053+7181+7309+7437+7565+7693+7821+7949+8077+8205+8333+8461+8589+8717+8845+8973+9101+9229+9357+9485+9613+9741+9869+9997+10125+10253+10381+10509+10637+10765+10893+11021+11149+11277+11405+11533+11661+11789+11917+12045+12173+12301+12429+12557+12685+12813+12941+13069+13197+13325+13453+13581+13709+13837+13965+14093+14221+14349+14477+14605+14733+14861+14989+15117+15245+15373+15501+15629+15757+15885+16013+16141+16269+16397+16525+16653+16781+16909+17037+17165+17293+17421+17549+17677+17805+17933+18061+18189+18317+18445+18573+18701+18829+18957+19085+19213+19341+19469+19597+19725+19853+19981+20109+20237+20365+20493+20621+20749+20877+21005+21133+21261+21389+21517+21645+21773+21901+22029+22157+22285+22413+22541+22669+22797+22925+23053+23181+23309+23437+23565+23693+23821+23949+24077+24205+24333+24461+24589+24717+24845+24973+25101+25229+25357+25485+25613+25741+25869+25997+26125+26253+26381+26509+26637+26765+26893+27021+27149+27277+27405+27533+27661+27789+27917+28045+28173+28301+28429+28557+28685+28813+28941+29069+29197+29325+29453+29581+29709+29837+29965+30093+30221+30349+30477+30605+30733+30861+30989+31117+31245+31373+31501+31629+31757+31885+32013+32141+32269+32397+32525+32653,14+142+270+398+526+654+782+910+1038+1166+1294+1422+1550+1678+1806+1934+2062+2190+2318+2446+2574+2702+2830+2958+3086+3214+3342+3470+3598+3726+3854+3982+4110+4238+4366+4494+4622+4750+4878+5006+5134+5262+5390+5518+5646+5774+5902+6030+6158+6286+6414+6542+6670+6798+6926+7054+7182+7310+7438+7566+7694+7822+7950+8078+8206+8334+8462+8590+8718+8846+8974+9102+9230+9358+9486+9614+9742+9870+9998+10126+10254+10382+10510+10638+10766+10894+11022+11150+11278+11406+11534+11662+11790+11918+12046+12174+12302+12430+12558+12686+12814+12942+13070+13198+13326+13454+13582+13710+13838+13966+14094+14222+14350+14478+14606+14734+14862+14990+15118+15246+15374+15502+15630+15758+15886+16014+16142+16270+16398+16526+16654+16782+16910+17038+17166+17294+17422+17550+17678+17806+17934+18062+18190+18318+18446+18574+18702+18830+18958+19086+19214+19342+19470+19598+19726+19854+19982+20110+20238+20366+20494+20622+20750+20878+21006+21134+21262+21390+21518+21646+21774+21902+22030+22158+22286+22414+22542+22670+22798+22926+23054+23182+23310+23438+23566+23694+23822+23950+24078+24206+24334+24462+24590+24718+24846+24974+25102+25230+25358+25486+25614+25742+25870+25998+26126+26254+26382+26510+26638+26766+26894+27022+27150+27278+27406+27534+27662+27790+27918+28046+28174+28302+28430+28558+28686+28814+28942+29070+29198+29326+29454+29582+29710+29838+29966+30094+30222+30350+30478+30606+30734+30862+30990+31118+31246+31374+31502+31630+31758+31886+32014+32142+32270+32398+32526+32654,15+143+271+399+527+655+783+911+1039+1167+1295+1423+1551+1679+1807+1935+2063+2191+2319+2447+2575+2703+2831+2959+3087+3215+3343+3471+3599+3727+3855+3983+4111+4239+4367+4495+4623+4751+4879+5007+5135+5263+5391+5519+5647+5775+5903+6031+6159+6287+6415+6543+6671+6799+6927+7055+7183+7311+7439+7567+7695+7823+7951+8079+8207+8335+8463+8591+8719+8847+8975+9103+9231+9359+9487+9615+9743+9871+9999+10127+10255+10383+10511+10639+10767+10895+11023+11151+11279+11407+11535+11663+11791+11919+12047+12175+12303+12431+12559+12687+12815+12943+13071+13199+13327+13455+13583+13711+13839+13967+14095+14223+14351+14479+14607+14735+14863+14991+15119+15247+15375+15503+15631+15759+15887+16015+16143+16271+16399+16527+16655+16783+16911+17039+17167+17295+17423+17551+17679+17807+17935+18063+18191+18319+18447+18575+18703+18831+18959+19087+19215+19343+19471+19599+19727+19855+19983+20111+20239+20367+20495+20623+20751+20879+21007+21135+21263+21391+21519+21647+21775+21903+22031+22159+22287+22415+22543+22671+22799+22927+23055+23183+23311+23439+23567+23695+23823+23951+24079+24207+24335+24463+24591+24719+24847+24975+25103+25231+25359+25487+25615+25743+25871+25999+26127+26255+26383+26511+26639+26767+26895+27023+27151+27279+27407+27535+27663+27791+27919+28047+28175+28303+28431+28559+28687+28815+28943+29071+29199+29327+29455+29583+29711+29839+29967+30095+30223+30351+30479+30607+30735+30863+30991+31119+31247+31375+31503+31631+31759+31887+32015+32143+32271+32399+32527+32655,16+144+272+400+528+656+784+912+1040+1168+1296+1424+1552+1680+1808+1936+2064+2192+2320+2448+2576+2704+2832+2960+3088+3216+3344+3472+3600+3728+3856+3984+4112+4240+4368+4496+4624+4752+4880+5008+5136+5264+5392+5520+5648+5776+5904+6032+6160+6288+6416+6544+6672+6800+6928+7056+7184+7312+7440+7568+7696+7824+7952+8080+8208+8336+8464+8592+8720+8848+8976+9104+9232+9360+9488+9616+9744+9872+10000+10128+10256+10384+10512+10640+10768+10896+11024+11152+11280+11408+11536+11664+11792+11920+12048+12176+12304+12432+12560+12688+12816+12944+13072+13200+13328+13456+13584+13712+13840+13968+14096+14224+14352+14480+14608+14736+14864+14992+15120+15248+15376+15504+15632+15760+15888+16016+16144+16272+16400+16528+16656+16784+16912+17040+17168+17296+17424+17552+17680+17808+17936+18064+18192+18320+18448+18576+18704+18832+18960+19088+19216+19344+19472+19600+19728+19856+19984+20112+20240+20368+20496+20624+20752+20880+21008+21136+21264+21392+21520+21648+21776+21904+22032+22160+22288+22416+22544+22672+22800+22928+23056+23184+23312+23440+23568+23696+23824+23952+24080+24208+24336+24464+24592+24720+24848+24976+25104+25232+25360+25488+25616+25744+25872+26000+26128+26256+26384+26512+26640+26768+26896+27024+27152+27280+27408+27536+27664+27792+27920+28048+28176+28304+28432+28560+28688+28816+28944+29072+29200+29328+29456+29584+29712+29840+29968+30096+30224+30352+30480+30608+30736+30864+30992+31120+31248+31376+31504+31632+31760+31888+32016+32144+32272+32400+32528+32656,17+145+273+401+529+657+785+913+1041+1169+1297+1425+1553+1681+1809+1937+2065+2193+2321+2449+2577+2705+2833+2961+3089+3217+3345+3473+3601+3729+3857+3985+4113+4241+4369+4497+4625+4753+4881+5009+5137+5265+5393+5521+5649+5777+5905+6033+6161+6289+6417+6545+6673+6801+6929+7057+7185+7313+7441+7569+7697+7825+7953+8081+8209+8337+8465+8593+8721+8849+8977+9105+9233+9361+9489+9617+9745+9873+10001+10129+10257+10385+10513+10641+10769+10897+11025+11153+11281+11409+11537+11665+11793+11921+12049+12177+12305+12433+12561+12689+12817+12945+13073+13201+13329+13457+13585+13713+13841+13969+14097+14225+14353+14481+14609+14737+14865+14993+15121+15249+15377+15505+15633+15761+15889+16017+16145+16273+16401+16529+16657+16785+16913+17041+17169+17297+17425+17553+17681+17809+17937+18065+18193+18321+18449+18577+18705+18833+18961+19089+19217+19345+19473+19601+19729+19857+19985+20113+20241+20369+20497+20625+20753+20881+21009+21137+21265+21393+21521+21649+21777+21905+22033+22161+22289+22417+22545+22673+22801+22929+23057+23185+23313+23441+23569+23697+23825+23953+24081+24209+24337+24465+24593+24721+24849+24977+25105+25233+25361+25489+25617+25745+25873+26001+26129+26257+26385+26513+26641+26769+26897+27025+27153+27281+27409+27537+27665+27793+27921+28049+28177+28305+28433+28561+28689+28817+28945+29073+29201+29329+29457+29585+29713+29841+29969+30097+30225+30353+30481+30609+30737+30865+30993+31121+31249+31377+31505+31633+31761+31889+32017+32145+32273+32401+32529+32657,18+146+274+402+530+658+786+914+1042+1170+1298+1426+1554+1682+1810+1938+2066+2194+2322+2450+2578+2706+2834+2962+3090+3218+3346+3474+3602+3730+3858+3986+4114+4242+4370+4498+4626+4754+4882+5010+5138+5266+5394+5522+5650+5778+5906+6034+6162+6290+6418+6546+6674+6802+6930+7058+7186+7314+7442+7570+7698+7826+7954+8082+8210+8338+8466+8594+8722+8850+8978+9106+9234+9362+9490+9618+9746+9874+10002+10130+10258+10386+10514+10642+10770+10898+11026+11154+11282+11410+11538+11666+11794+11922+12050+12178+12306+12434+12562+12690+12818+12946+13074+13202+13330+13458+13586+13714+13842+13970+14098+14226+14354+14482+14610+14738+14866+14994+15122+15250+15378+15506+15634+15762+15890+16018+16146+16274+16402+16530+16658+16786+16914+17042+17170+17298+17426+17554+17682+17810+17938+18066+18194+18322+18450+18578+18706+18834+18962+19090+19218+19346+19474+19602+19730+19858+19986+20114+20242+20370+20498+20626+20754+20882+21010+21138+21266+21394+21522+21650+21778+21906+22034+22162+22290+22418+22546+22674+22802+22930+23058+23186+23314+23442+23570+23698+23826+23954+24082+24210+24338+24466+24594+24722+24850+24978+25106+25234+25362+25490+25618+25746+25874+26002+26130+26258+26386+26514+26642+26770+26898+27026+27154+27282+27410+27538+27666+27794+27922+28050+28178+28306+28434+28562+28690+28818+28946+29074+29202+29330+29458+29586+29714+29842+29970+30098+30226+30354+30482+30610+30738+30866+30994+31122+31250+31378+31506+31634+31762+31890+32018+32146+32274+32402+32530+32658,19+147+275+403+531+659+787+915+1043+1171+1299+1427+1555+1683+1811+1939+2067+2195+2323+2451+2579+2707+2835+2963+3091+3219+3347+3475+3603+3731+3859+3987+4115+4243+4371+4499+4627+4755+4883+5011+5139+5267+5395+5523+5651+5779+5907+6035+6163+6291+6419+6547+6675+6803+6931+7059+7187+7315+7443+7571+7699+7827+7955+8083+8211+8339+8467+8595+8723+8851+8979+9107+9235+9363+9491+9619+9747+9875+10003+10131+10259+10387+10515+10643+10771+10899+11027+11155+11283+11411+11539+11667+11795+11923+12051+12179+12307+12435+12563+12691+12819+12947+13075+13203+13331+13459+13587+13715+13843+13971+14099+14227+14355+14483+14611+14739+14867+14995+15123+15251+15379+15507+15635+15763+15891+16019+16147+16275+16403+16531+16659+16787+16915+17043+17171+17299+17427+17555+17683+17811+17939+18067+18195+18323+18451+18579+18707+18835+18963+19091+19219+19347+19475+19603+19731+19859+19987+20115+20243+20371+20499+20627+20755+20883+21011+21139+21267+21395+21523+21651+21779+21907+22035+22163+22291+22419+22547+22675+22803+22931+23059+23187+23315+23443+23571+23699+23827+23955+24083+24211+24339+24467+24595+24723+24851+24979+25107+25235+25363+25491+25619+25747+25875+26003+26131+26259+26387+26515+26643+26771+26899+27027+27155+27283+27411+27539+27667+27795+27923+28051+28179+28307+28435+28563+28691+28819+28947+29075+29203+29331+29459+29587+29715+29843+29971+30099+30227+30355+30483+30611+30739+30867+30995+31123+31251+31379+31507+31635+31763+31891+32019+32147+32275+32403+32531+32659,20+148+276+404+532+660+788+916+1044+1172+1300+1428+1556+1684+1812+1940+2068+2196+2324+2452+2580+2708+2836+2964+3092+3220+3348+3476+3604+3732+3860+3988+4116+4244+4372+4500+4628+4756+4884+5012+5140+5268+5396+5524+5652+5780+5908+6036+6164+6292+6420+6548+6676+6804+6932+7060+7188+7316+7444+7572+7700+7828+7956+8084+8212+8340+8468+8596+8724+8852+8980+9108+9236+9364+9492+9620+9748+9876+10004+10132+10260+10388+10516+10644+10772+10900+11028+11156+11284+11412+11540+11668+11796+11924+12052+12180+12308+12436+12564+12692+12820+12948+13076+13204+13332+13460+13588+13716+13844+13972+14100+14228+14356+14484+14612+14740+14868+14996+15124+15252+15380+15508+15636+15764+15892+16020+16148+16276+16404+16532+16660+16788+16916+17044+17172+17300+17428+17556+17684+17812+17940+18068+18196+18324+18452+18580+18708+18836+18964+19092+19220+19348+19476+19604+19732+19860+19988+20116+20244+20372+20500+20628+20756+20884+21012+21140+21268+21396+21524+21652+21780+21908+22036+22164+22292+22420+22548+22676+22804+22932+23060+23188+23316+23444+23572+23700+23828+23956+24084+24212+24340+24468+24596+24724+24852+24980+25108+25236+25364+25492+25620+25748+25876+26004+26132+26260+26388+26516+26644+26772+26900+27028+27156+27284+27412+27540+27668+27796+27924+28052+28180+28308+28436+28564+28692+28820+28948+29076+29204+29332+29460+29588+29716+29844+29972+30100+30228+30356+30484+30612+30740+30868+30996+31124+31252+31380+31508+31636+31764+31892+32020+32148+32276+32404+32532+32660,21+149+277+405+533+661+789+917+1045+1173+1301+1429+1557+1685+1813+1941+2069+2197+2325+2453+2581+2709+2837+2965+3093+3221+3349+3477+3605+3733+3861+3989+4117+4245+4373+4501+4629+4757+4885+5013+5141+5269+5397+5525+5653+5781+5909+6037+6165+6293+6421+6549+6677+6805+6933+7061+7189+7317+7445+7573+7701+7829+7957+8085+8213+8341+8469+8597+8725+8853+8981+9109+9237+9365+9493+9621+9749+9877+10005+10133+10261+10389+10517+10645+10773+10901+11029+11157+11285+11413+11541+11669+11797+11925+12053+12181+12309+12437+12565+12693+12821+12949+13077+13205+13333+13461+13589+13717+13845+13973+14101+14229+14357+14485+14613+14741+14869+14997+15125+15253+15381+15509+15637+15765+15893+16021+16149+16277+16405+16533+16661+16789+16917+17045+17173+17301+17429+17557+17685+17813+17941+18069+18197+18325+18453+18581+18709+18837+18965+19093+19221+19349+19477+19605+19733+19861+19989+20117+20245+20373+20501+20629+20757+20885+21013+21141+21269+21397+21525+21653+21781+21909+22037+22165+22293+22421+22549+22677+22805+22933+23061+23189+23317+23445+23573+23701+23829+23957+24085+24213+24341+24469+24597+24725+24853+24981+25109+25237+25365+25493+25621+25749+25877+26005+26133+26261+26389+26517+26645+26773+26901+27029+27157+27285+27413+27541+27669+27797+27925+28053+28181+28309+28437+28565+28693+28821+28949+29077+29205+29333+29461+29589+29717+29845+29973+30101+30229+30357+30485+30613+30741+30869+30997+31125+31253+31381+31509+31637+31765+31893+32021+32149+32277+32405+32533+32661,22+150+278+406+534+662+790+918+1046+1174+1302+1430+1558+1686+1814+1942+2070+2198+2326+2454+2582+2710+2838+2966+3094+3222+3350+3478+3606+3734+3862+3990+4118+4246+4374+4502+4630+4758+4886+5014+5142+5270+5398+5526+5654+5782+5910+6038+6166+6294+6422+6550+6678+6806+6934+7062+7190+7318+7446+7574+7702+7830+7958+8086+8214+8342+8470+8598+8726+8854+8982+9110+9238+9366+9494+9622+9750+9878+10006+10134+10262+10390+10518+10646+10774+10902+11030+11158+11286+11414+11542+11670+11798+11926+12054+12182+12310+12438+12566+12694+12822+12950+13078+13206+13334+13462+13590+13718+13846+13974+14102+14230+14358+14486+14614+14742+14870+14998+15126+15254+15382+15510+15638+15766+15894+16022+16150+16278+16406+16534+16662+16790+16918+17046+17174+17302+17430+17558+17686+17814+17942+18070+18198+18326+18454+18582+18710+18838+18966+19094+19222+19350+19478+19606+19734+19862+19990+20118+20246+20374+20502+20630+20758+20886+21014+21142+21270+21398+21526+21654+21782+21910+22038+22166+22294+22422+22550+22678+22806+22934+23062+23190+23318+23446+23574+23702+23830+23958+24086+24214+24342+24470+24598+24726+24854+24982+25110+25238+25366+25494+25622+25750+25878+26006+26134+26262+26390+26518+26646+26774+26902+27030+27158+27286+27414+27542+27670+27798+27926+28054+28182+28310+28438+28566+28694+28822+28950+29078+29206+29334+29462+29590+29718+29846+29974+30102+30230+30358+30486+30614+30742+30870+30998+31126+31254+31382+31510+31638+31766+31894+32022+32150+32278+32406+32534+32662,23+151+279+407+535+663+791+919+1047+1175+1303+1431+1559+1687+1815+1943+2071+2199+2327+2455+2583+2711+2839+2967+3095+3223+3351+3479+3607+3735+3863+3991+4119+4247+4375+4503+4631+4759+4887+5015+5143+5271+5399+5527+5655+5783+5911+6039+6167+6295+6423+6551+6679+6807+6935+7063+7191+7319+7447+7575+7703+7831+7959+8087+8215+8343+8471+8599+8727+8855+8983+9111+9239+9367+9495+9623+9751+9879+10007+10135+10263+10391+10519+10647+10775+10903+11031+11159+11287+11415+11543+11671+11799+11927+12055+12183+12311+12439+12567+12695+12823+12951+13079+13207+13335+13463+13591+13719+13847+13975+14103+14231+14359+14487+14615+14743+14871+14999+15127+15255+15383+15511+15639+15767+15895+16023+16151+16279+16407+16535+16663+16791+16919+17047+17175+17303+17431+17559+17687+17815+17943+18071+18199+18327+18455+18583+18711+18839+18967+19095+19223+19351+19479+19607+19735+19863+19991+20119+20247+20375+20503+20631+20759+20887+21015+21143+21271+21399+21527+21655+21783+21911+22039+22167+22295+22423+22551+22679+22807+22935+23063+23191+23319+23447+23575+23703+23831+23959+24087+24215+24343+24471+24599+24727+24855+24983+25111+25239+25367+25495+25623+25751+25879+26007+26135+26263+26391+26519+26647+26775+26903+27031+27159+27287+27415+27543+27671+27799+27927+28055+28183+28311+28439+28567+28695+28823+28951+29079+29207+29335+29463+29591+29719+29847+29975+30103+30231+30359+30487+30615+30743+30871+30999+31127+31255+31383+31511+31639+31767+31895+32023+32151+32279+32407+32535+32663,24+152+280+408+536+664+792+920+1048+1176+1304+1432+1560+1688+1816+1944+2072+2200+2328+2456+2584+2712+2840+2968+3096+3224+3352+3480+3608+3736+3864+3992+4120+4248+4376+4504+4632+4760+4888+5016+5144+5272+5400+5528+5656+5784+5912+6040+6168+6296+6424+6552+6680+6808+6936+7064+7192+7320+7448+7576+7704+7832+7960+8088+8216+8344+8472+8600+8728+8856+8984+9112+9240+9368+9496+9624+9752+9880+10008+10136+10264+10392+10520+10648+10776+10904+11032+11160+11288+11416+11544+11672+11800+11928+12056+12184+12312+12440+12568+12696+12824+12952+13080+13208+13336+13464+13592+13720+13848+13976+14104+14232+14360+14488+14616+14744+14872+15000+15128+15256+15384+15512+15640+15768+15896+16024+16152+16280+16408+16536+16664+16792+16920+17048+17176+17304+17432+17560+17688+17816+17944+18072+18200+18328+18456+18584+18712+18840+18968+19096+19224+19352+19480+19608+19736+19864+19992+20120+20248+20376+20504+20632+20760+20888+21016+21144+21272+21400+21528+21656+21784+21912+22040+22168+22296+22424+22552+22680+22808+22936+23064+23192+23320+23448+23576+23704+23832+23960+24088+24216+24344+24472+24600+24728+24856+24984+25112+25240+25368+25496+25624+25752+25880+26008+26136+26264+26392+26520+26648+26776+26904+27032+27160+27288+27416+27544+27672+27800+27928+28056+28184+28312+28440+28568+28696+28824+28952+29080+29208+29336+29464+29592+29720+29848+29976+30104+30232+30360+30488+30616+30744+30872+31000+31128+31256+31384+31512+31640+31768+31896+32024+32152+32280+32408+32536+32664,25+153+281+409+537+665+793+921+1049+1177+1305+1433+1561+1689+1817+1945+2073+2201+2329+2457+2585+2713+2841+2969+3097+3225+3353+3481+3609+3737+3865+3993+4121+4249+4377+4505+4633+4761+4889+5017+5145+5273+5401+5529+5657+5785+5913+6041+6169+6297+6425+6553+6681+6809+6937+7065+7193+7321+7449+7577+7705+7833+7961+8089+8217+8345+8473+8601+8729+8857+8985+9113+9241+9369+9497+9625+9753+9881+10009+10137+10265+10393+10521+10649+10777+10905+11033+11161+11289+11417+11545+11673+11801+11929+12057+12185+12313+12441+12569+12697+12825+12953+13081+13209+13337+13465+13593+13721+13849+13977+14105+14233+14361+14489+14617+14745+14873+15001+15129+15257+15385+15513+15641+15769+15897+16025+16153+16281+16409+16537+16665+16793+16921+17049+17177+17305+17433+17561+17689+17817+17945+18073+18201+18329+18457+18585+18713+18841+18969+19097+19225+19353+19481+19609+19737+19865+19993+20121+20249+20377+20505+20633+20761+20889+21017+21145+21273+21401+21529+21657+21785+21913+22041+22169+22297+22425+22553+22681+22809+22937+23065+23193+23321+23449+23577+23705+23833+23961+24089+24217+24345+24473+24601+24729+24857+24985+25113+25241+25369+25497+25625+25753+25881+26009+26137+26265+26393+26521+26649+26777+26905+27033+27161+27289+27417+27545+27673+27801+27929+28057+28185+28313+28441+28569+28697+28825+28953+29081+29209+29337+29465+29593+29721+29849+29977+30105+30233+30361+30489+30617+30745+30873+31001+31129+31257+31385+31513+31641+31769+31897+32025+32153+32281+32409+32537+32665,26+154+282+410+538+666+794+922+1050+1178+1306+1434+1562+1690+1818+1946+2074+2202+2330+2458+2586+2714+2842+2970+3098+3226+3354+3482+3610+3738+3866+3994+4122+4250+4378+4506+4634+4762+4890+5018+5146+5274+5402+5530+5658+5786+5914+6042+6170+6298+6426+6554+6682+6810+6938+7066+7194+7322+7450+7578+7706+7834+7962+8090+8218+8346+8474+8602+8730+8858+8986+9114+9242+9370+9498+9626+9754+9882+10010+10138+10266+10394+10522+10650+10778+10906+11034+11162+11290+11418+11546+11674+11802+11930+12058+12186+12314+12442+12570+12698+12826+12954+13082+13210+13338+13466+13594+13722+13850+13978+14106+14234+14362+14490+14618+14746+14874+15002+15130+15258+15386+15514+15642+15770+15898+16026+16154+16282+16410+16538+16666+16794+16922+17050+17178+17306+17434+17562+17690+17818+17946+18074+18202+18330+18458+18586+18714+18842+18970+19098+19226+19354+19482+19610+19738+19866+19994+20122+20250+20378+20506+20634+20762+20890+21018+21146+21274+21402+21530+21658+21786+21914+22042+22170+22298+22426+22554+22682+22810+22938+23066+23194+23322+23450+23578+23706+23834+23962+24090+24218+24346+24474+24602+24730+24858+24986+25114+25242+25370+25498+25626+25754+25882+26010+26138+26266+26394+26522+26650+26778+26906+27034+27162+27290+27418+27546+27674+27802+27930+28058+28186+28314+28442+28570+28698+28826+28954+29082+29210+29338+29466+29594+29722+29850+29978+30106+30234+30362+30490+30618+30746+30874+31002+31130+31258+31386+31514+31642+31770+31898+32026+32154+32282+32410+32538+32666,27+155+283+411+539+667+795+923+1051+1179+1307+1435+1563+1691+1819+1947+2075+2203+2331+2459+2587+2715+2843+2971+3099+3227+3355+3483+3611+3739+3867+3995+4123+4251+4379+4507+4635+4763+4891+5019+5147+5275+5403+5531+5659+5787+5915+6043+6171+6299+6427+6555+6683+6811+6939+7067+7195+7323+7451+7579+7707+7835+7963+8091+8219+8347+8475+8603+8731+8859+8987+9115+9243+9371+9499+9627+9755+9883+10011+10139+10267+10395+10523+10651+10779+10907+11035+11163+11291+11419+11547+11675+11803+11931+12059+12187+12315+12443+12571+12699+12827+12955+13083+13211+13339+13467+13595+13723+13851+13979+14107+14235+14363+14491+14619+14747+14875+15003+15131+15259+15387+15515+15643+15771+15899+16027+16155+16283+16411+16539+16667+16795+16923+17051+17179+17307+17435+17563+17691+17819+17947+18075+18203+18331+18459+18587+18715+18843+18971+19099+19227+19355+19483+19611+19739+19867+19995+20123+20251+20379+20507+20635+20763+20891+21019+21147+21275+21403+21531+21659+21787+21915+22043+22171+22299+22427+22555+22683+22811+22939+23067+23195+23323+23451+23579+23707+23835+23963+24091+24219+24347+24475+24603+24731+24859+24987+25115+25243+25371+25499+25627+25755+25883+26011+26139+26267+26395+26523+26651+26779+26907+27035+27163+27291+27419+27547+27675+27803+27931+28059+28187+28315+28443+28571+28699+28827+28955+29083+29211+29339+29467+29595+29723+29851+29979+30107+30235+30363+30491+30619+30747+30875+31003+31131+31259+31387+31515+31643+31771+31899+32027+32155+32283+32411+32539+32667,28+156+284+412+540+668+796+924+1052+1180+1308+1436+1564+1692+1820+1948+2076+2204+2332+2460+2588+2716+2844+2972+3100+3228+3356+3484+3612+3740+3868+3996+4124+4252+4380+4508+4636+4764+4892+5020+5148+5276+5404+5532+5660+5788+5916+6044+6172+6300+6428+6556+6684+6812+6940+7068+7196+7324+7452+7580+7708+7836+7964+8092+8220+8348+8476+8604+8732+8860+8988+9116+9244+9372+9500+9628+9756+9884+10012+10140+10268+10396+10524+10652+10780+10908+11036+11164+11292+11420+11548+11676+11804+11932+12060+12188+12316+12444+12572+12700+12828+12956+13084+13212+13340+13468+13596+13724+13852+13980+14108+14236+14364+14492+14620+14748+14876+15004+15132+15260+15388+15516+15644+15772+15900+16028+16156+16284+16412+16540+16668+16796+16924+17052+17180+17308+17436+17564+17692+17820+17948+18076+18204+18332+18460+18588+18716+18844+18972+19100+19228+19356+19484+19612+19740+19868+19996+20124+20252+20380+20508+20636+20764+20892+21020+21148+21276+21404+21532+21660+21788+21916+22044+22172+22300+22428+22556+22684+22812+22940+23068+23196+23324+23452+23580+23708+23836+23964+24092+24220+24348+24476+24604+24732+24860+24988+25116+25244+25372+25500+25628+25756+25884+26012+26140+26268+26396+26524+26652+26780+26908+27036+27164+27292+27420+27548+27676+27804+27932+28060+28188+28316+28444+28572+28700+28828+28956+29084+29212+29340+29468+29596+29724+29852+29980+30108+30236+30364+30492+30620+30748+30876+31004+31132+31260+31388+31516+31644+31772+31900+32028+32156+32284+32412+32540+32668,29+157+285+413+541+669+797+925+1053+1181+1309+1437+1565+1693+1821+1949+2077+2205+2333+2461+2589+2717+2845+2973+3101+3229+3357+3485+3613+3741+3869+3997+4125+4253+4381+4509+4637+4765+4893+5021+5149+5277+5405+5533+5661+5789+5917+6045+6173+6301+6429+6557+6685+6813+6941+7069+7197+7325+7453+7581+7709+7837+7965+8093+8221+8349+8477+8605+8733+8861+8989+9117+9245+9373+9501+9629+9757+9885+10013+10141+10269+10397+10525+10653+10781+10909+11037+11165+11293+11421+11549+11677+11805+11933+12061+12189+12317+12445+12573+12701+12829+12957+13085+13213+13341+13469+13597+13725+13853+13981+14109+14237+14365+14493+14621+14749+14877+15005+15133+15261+15389+15517+15645+15773+15901+16029+16157+16285+16413+16541+16669+16797+16925+17053+17181+17309+17437+17565+17693+17821+17949+18077+18205+18333+18461+18589+18717+18845+18973+19101+19229+19357+19485+19613+19741+19869+19997+20125+20253+20381+20509+20637+20765+20893+21021+21149+21277+21405+21533+21661+21789+21917+22045+22173+22301+22429+22557+22685+22813+22941+23069+23197+23325+23453+23581+23709+23837+23965+24093+24221+24349+24477+24605+24733+24861+24989+25117+25245+25373+25501+25629+25757+25885+26013+26141+26269+26397+26525+26653+26781+26909+27037+27165+27293+27421+27549+27677+27805+27933+28061+28189+28317+28445+28573+28701+28829+28957+29085+29213+29341+29469+29597+29725+29853+29981+30109+30237+30365+30493+30621+30749+30877+31005+31133+31261+31389+31517+31645+31773+31901+32029+32157+32285+32413+32541+32669,30+158+286+414+542+670+798+926+1054+1182+1310+1438+1566+1694+1822+1950+2078+2206+2334+2462+2590+2718+2846+2974+3102+3230+3358+3486+3614+3742+3870+3998+4126+4254+4382+4510+4638+4766+4894+5022+5150+5278+5406+5534+5662+5790+5918+6046+6174+6302+6430+6558+6686+6814+6942+7070+7198+7326+7454+7582+7710+7838+7966+8094+8222+8350+8478+8606+8734+8862+8990+9118+9246+9374+9502+9630+9758+9886+10014+10142+10270+10398+10526+10654+10782+10910+11038+11166+11294+11422+11550+11678+11806+11934+12062+12190+12318+12446+12574+12702+12830+12958+13086+13214+13342+13470+13598+13726+13854+13982+14110+14238+14366+14494+14622+14750+14878+15006+15134+15262+15390+15518+15646+15774+15902+16030+16158+16286+16414+16542+16670+16798+16926+17054+17182+17310+17438+17566+17694+17822+17950+18078+18206+18334+18462+18590+18718+18846+18974+19102+19230+19358+19486+19614+19742+19870+19998+20126+20254+20382+20510+20638+20766+20894+21022+21150+21278+21406+21534+21662+21790+21918+22046+22174+22302+22430+22558+22686+22814+22942+23070+23198+23326+23454+23582+23710+23838+23966+24094+24222+24350+24478+24606+24734+24862+24990+25118+25246+25374+25502+25630+25758+25886+26014+26142+26270+26398+26526+26654+26782+26910+27038+27166+27294+27422+27550+27678+27806+27934+28062+28190+28318+28446+28574+28702+28830+28958+29086+29214+29342+29470+29598+29726+29854+29982+30110+30238+30366+30494+30622+30750+30878+31006+31134+31262+31390+31518+31646+31774+31902+32030+32158+32286+32414+32542+32670,31+159+287+415+543+671+799+927+1055+1183+1311+1439+1567+1695+1823+1951+2079+2207+2335+2463+2591+2719+2847+2975+3103+3231+3359+3487+3615+3743+3871+3999+4127+4255+4383+4511+4639+4767+4895+5023+5151+5279+5407+5535+5663+5791+5919+6047+6175+6303+6431+6559+6687+6815+6943+7071+7199+7327+7455+7583+7711+7839+7967+8095+8223+8351+8479+8607+8735+8863+8991+9119+9247+9375+9503+9631+9759+9887+10015+10143+10271+10399+10527+10655+10783+10911+11039+11167+11295+11423+11551+11679+11807+11935+12063+12191+12319+12447+12575+12703+12831+12959+13087+13215+13343+13471+13599+13727+13855+13983+14111+14239+14367+14495+14623+14751+14879+15007+15135+15263+15391+15519+15647+15775+15903+16031+16159+16287+16415+16543+16671+16799+16927+17055+17183+17311+17439+17567+17695+17823+17951+18079+18207+18335+18463+18591+18719+18847+18975+19103+19231+19359+19487+19615+19743+19871+19999+20127+20255+20383+20511+20639+20767+20895+21023+21151+21279+21407+21535+21663+21791+21919+22047+22175+22303+22431+22559+22687+22815+22943+23071+23199+23327+23455+23583+23711+23839+23967+24095+24223+24351+24479+24607+24735+24863+24991+25119+25247+25375+25503+25631+25759+25887+26015+26143+26271+26399+26527+26655+26783+26911+27039+27167+27295+27423+27551+27679+27807+27935+28063+28191+28319+28447+28575+28703+28831+28959+29087+29215+29343+29471+29599+29727+29855+29983+30111+30239+30367+30495+30623+30751+30879+31007+31135+31263+31391+31519+31647+31775+31903+32031+32159+32287+32415+32543+32671,32+160+288+416+544+672+800+928+1056+1184+1312+1440+1568+1696+1824+1952+2080+2208+2336+2464+2592+2720+2848+2976+3104+3232+3360+3488+3616+3744+3872+4000+4128+4256+4384+4512+4640+4768+4896+5024+5152+5280+5408+5536+5664+5792+5920+6048+6176+6304+6432+6560+6688+6816+6944+7072+7200+7328+7456+7584+7712+7840+7968+8096+8224+8352+8480+8608+8736+8864+8992+9120+9248+9376+9504+9632+9760+9888+10016+10144+10272+10400+10528+10656+10784+10912+11040+11168+11296+11424+11552+11680+11808+11936+12064+12192+12320+12448+12576+12704+12832+12960+13088+13216+13344+13472+13600+13728+13856+13984+14112+14240+14368+14496+14624+14752+14880+15008+15136+15264+15392+15520+15648+15776+15904+16032+16160+16288+16416+16544+16672+16800+16928+17056+17184+17312+17440+17568+17696+17824+17952+18080+18208+18336+18464+18592+18720+18848+18976+19104+19232+19360+19488+19616+19744+19872+20000+20128+20256+20384+20512+20640+20768+20896+21024+21152+21280+21408+21536+21664+21792+21920+22048+22176+22304+22432+22560+22688+22816+22944+23072+23200+23328+23456+23584+23712+23840+23968+24096+24224+24352+24480+24608+24736+24864+24992+25120+25248+25376+25504+25632+25760+25888+26016+26144+26272+26400+26528+26656+26784+26912+27040+27168+27296+27424+27552+27680+27808+27936+28064+28192+28320+28448+28576+28704+28832+28960+29088+29216+29344+29472+29600+29728+29856+29984+30112+30240+30368+30496+30624+30752+30880+31008+31136+31264+31392+31520+31648+31776+31904+32032+32160+32288+32416+32544+32672,33+161+289+417+545+673+801+929+1057+1185+1313+1441+1569+1697+1825+1953+2081+2209+2337+2465+2593+2721+2849+2977+3105+3233+3361+3489+3617+3745+3873+4001+4129+4257+4385+4513+4641+4769+4897+5025+5153+5281+5409+5537+5665+5793+5921+6049+6177+6305+6433+6561+6689+6817+6945+7073+7201+7329+7457+7585+7713+7841+7969+8097+8225+8353+8481+8609+8737+8865+8993+9121+9249+9377+9505+9633+9761+9889+10017+10145+10273+10401+10529+10657+10785+10913+11041+11169+11297+11425+11553+11681+11809+11937+12065+12193+12321+12449+12577+12705+12833+12961+13089+13217+13345+13473+13601+13729+13857+13985+14113+14241+14369+14497+14625+14753+14881+15009+15137+15265+15393+15521+15649+15777+15905+16033+16161+16289+16417+16545+16673+16801+16929+17057+17185+17313+17441+17569+17697+17825+17953+18081+18209+18337+18465+18593+18721+18849+18977+19105+19233+19361+19489+19617+19745+19873+20001+20129+20257+20385+20513+20641+20769+20897+21025+21153+21281+21409+21537+21665+21793+21921+22049+22177+22305+22433+22561+22689+22817+22945+23073+23201+23329+23457+23585+23713+23841+23969+24097+24225+24353+24481+24609+24737+24865+24993+25121+25249+25377+25505+25633+25761+25889+26017+26145+26273+26401+26529+26657+26785+26913+27041+27169+27297+27425+27553+27681+27809+27937+28065+28193+28321+28449+28577+28705+28833+28961+29089+29217+29345+29473+29601+29729+29857+29985+30113+30241+30369+30497+30625+30753+30881+31009+31137+31265+31393+31521+31649+31777+31905+32033+32161+32289+32417+32545+32673,34+162+290+418+546+674+802+930+1058+1186+1314+1442+1570+1698+1826+1954+2082+2210+2338+2466+2594+2722+2850+2978+3106+3234+3362+3490+3618+3746+3874+4002+4130+4258+4386+4514+4642+4770+4898+5026+5154+5282+5410+5538+5666+5794+5922+6050+6178+6306+6434+6562+6690+6818+6946+7074+7202+7330+7458+7586+7714+7842+7970+8098+8226+8354+8482+8610+8738+8866+8994+9122+9250+9378+9506+9634+9762+9890+10018+10146+10274+10402+10530+10658+10786+10914+11042+11170+11298+11426+11554+11682+11810+11938+12066+12194+12322+12450+12578+12706+12834+12962+13090+13218+13346+13474+13602+13730+13858+13986+14114+14242+14370+14498+14626+14754+14882+15010+15138+15266+15394+15522+15650+15778+15906+16034+16162+16290+16418+16546+16674+16802+16930+17058+17186+17314+17442+17570+17698+17826+17954+18082+18210+18338+18466+18594+18722+18850+18978+19106+19234+19362+19490+19618+19746+19874+20002+20130+20258+20386+20514+20642+20770+20898+21026+21154+21282+21410+21538+21666+21794+21922+22050+22178+22306+22434+22562+22690+22818+22946+23074+23202+23330+23458+23586+23714+23842+23970+24098+24226+24354+24482+24610+24738+24866+24994+25122+25250+25378+25506+25634+25762+25890+26018+26146+26274+26402+26530+26658+26786+26914+27042+27170+27298+27426+27554+27682+27810+27938+28066+28194+28322+28450+28578+28706+28834+28962+29090+29218+29346+29474+29602+29730+29858+29986+30114+30242+30370+30498+30626+30754+30882+31010+31138+31266+31394+31522+31650+31778+31906+32034+32162+32290+32418+32546+32674,35+163+291+419+547+675+803+931+1059+1187+1315+1443+1571+1699+1827+1955+2083+2211+2339+2467+2595+2723+2851+2979+3107+3235+3363+3491+3619+3747+3875+4003+4131+4259+4387+4515+4643+4771+4899+5027+5155+5283+5411+5539+5667+5795+5923+6051+6179+6307+6435+6563+6691+6819+6947+7075+7203+7331+7459+7587+7715+7843+7971+8099+8227+8355+8483+8611+8739+8867+8995+9123+9251+9379+9507+9635+9763+9891+10019+10147+10275+10403+10531+10659+10787+10915+11043+11171+11299+11427+11555+11683+11811+11939+12067+12195+12323+12451+12579+12707+12835+12963+13091+13219+13347+13475+13603+13731+13859+13987+14115+14243+14371+14499+14627+14755+14883+15011+15139+15267+15395+15523+15651+15779+15907+16035+16163+16291+16419+16547+16675+16803+16931+17059+17187+17315+17443+17571+17699+17827+17955+18083+18211+18339+18467+18595+18723+18851+18979+19107+19235+19363+19491+19619+19747+19875+20003+20131+20259+20387+20515+20643+20771+20899+21027+21155+21283+21411+21539+21667+21795+21923+22051+22179+22307+22435+22563+22691+22819+22947+23075+23203+23331+23459+23587+23715+23843+23971+24099+24227+24355+24483+24611+24739+24867+24995+25123+25251+25379+25507+25635+25763+25891+26019+26147+26275+26403+26531+26659+26787+26915+27043+27171+27299+27427+27555+27683+27811+27939+28067+28195+28323+28451+28579+28707+28835+28963+29091+29219+29347+29475+29603+29731+29859+29987+30115+30243+30371+30499+30627+30755+30883+31011+31139+31267+31395+31523+31651+31779+31907+32035+32163+32291+32419+32547+32675,36+164+292+420+548+676+804+932+1060+1188+1316+1444+1572+1700+1828+1956+2084+2212+2340+2468+2596+2724+2852+2980+3108+3236+3364+3492+3620+3748+3876+4004+4132+4260+4388+4516+4644+4772+4900+5028+5156+5284+5412+5540+5668+5796+5924+6052+6180+6308+6436+6564+6692+6820+6948+7076+7204+7332+7460+7588+7716+7844+7972+8100+8228+8356+8484+8612+8740+8868+8996+9124+9252+9380+9508+9636+9764+9892+10020+10148+10276+10404+10532+10660+10788+10916+11044+11172+11300+11428+11556+11684+11812+11940+12068+12196+12324+12452+12580+12708+12836+12964+13092+13220+13348+13476+13604+13732+13860+13988+14116+14244+14372+14500+14628+14756+14884+15012+15140+15268+15396+15524+15652+15780+15908+16036+16164+16292+16420+16548+16676+16804+16932+17060+17188+17316+17444+17572+17700+17828+17956+18084+18212+18340+18468+18596+18724+18852+18980+19108+19236+19364+19492+19620+19748+19876+20004+20132+20260+20388+20516+20644+20772+20900+21028+21156+21284+21412+21540+21668+21796+21924+22052+22180+22308+22436+22564+22692+22820+22948+23076+23204+23332+23460+23588+23716+23844+23972+24100+24228+24356+24484+24612+24740+24868+24996+25124+25252+25380+25508+25636+25764+25892+26020+26148+26276+26404+26532+26660+26788+26916+27044+27172+27300+27428+27556+27684+27812+27940+28068+28196+28324+28452+28580+28708+28836+28964+29092+29220+29348+29476+29604+29732+29860+29988+30116+30244+30372+30500+30628+30756+30884+31012+31140+31268+31396+31524+31652+31780+31908+32036+32164+32292+32420+32548+32676,37+165+293+421+549+677+805+933+1061+1189+1317+1445+1573+1701+1829+1957+2085+2213+2341+2469+2597+2725+2853+2981+3109+3237+3365+3493+3621+3749+3877+4005+4133+4261+4389+4517+4645+4773+4901+5029+5157+5285+5413+5541+5669+5797+5925+6053+6181+6309+6437+6565+6693+6821+6949+7077+7205+7333+7461+7589+7717+7845+7973+8101+8229+8357+8485+8613+8741+8869+8997+9125+9253+9381+9509+9637+9765+9893+10021+10149+10277+10405+10533+10661+10789+10917+11045+11173+11301+11429+11557+11685+11813+11941+12069+12197+12325+12453+12581+12709+12837+12965+13093+13221+13349+13477+13605+13733+13861+13989+14117+14245+14373+14501+14629+14757+14885+15013+15141+15269+15397+15525+15653+15781+15909+16037+16165+16293+16421+16549+16677+16805+16933+17061+17189+17317+17445+17573+17701+17829+17957+18085+18213+18341+18469+18597+18725+18853+18981+19109+19237+19365+19493+19621+19749+19877+20005+20133+20261+20389+20517+20645+20773+20901+21029+21157+21285+21413+21541+21669+21797+21925+22053+22181+22309+22437+22565+22693+22821+22949+23077+23205+23333+23461+23589+23717+23845+23973+24101+24229+24357+24485+24613+24741+24869+24997+25125+25253+25381+25509+25637+25765+25893+26021+26149+26277+26405+26533+26661+26789+26917+27045+27173+27301+27429+27557+27685+27813+27941+28069+28197+28325+28453+28581+28709+28837+28965+29093+29221+29349+29477+29605+29733+29861+29989+30117+30245+30373+30501+30629+30757+30885+31013+31141+31269+31397+31525+31653+31781+31909+32037+32165+32293+32421+32549+32677,38+166+294+422+550+678+806+934+1062+1190+1318+1446+1574+1702+1830+1958+2086+2214+2342+2470+2598+2726+2854+2982+3110+3238+3366+3494+3622+3750+3878+4006+4134+4262+4390+4518+4646+4774+4902+5030+5158+5286+5414+5542+5670+5798+5926+6054+6182+6310+6438+6566+6694+6822+6950+7078+7206+7334+7462+7590+7718+7846+7974+8102+8230+8358+8486+8614+8742+8870+8998+9126+9254+9382+9510+9638+9766+9894+10022+10150+10278+10406+10534+10662+10790+10918+11046+11174+11302+11430+11558+11686+11814+11942+12070+12198+12326+12454+12582+12710+12838+12966+13094+13222+13350+13478+13606+13734+13862+13990+14118+14246+14374+14502+14630+14758+14886+15014+15142+15270+15398+15526+15654+15782+15910+16038+16166+16294+16422+16550+16678+16806+16934+17062+17190+17318+17446+17574+17702+17830+17958+18086+18214+18342+18470+18598+18726+18854+18982+19110+19238+19366+19494+19622+19750+19878+20006+20134+20262+20390+20518+20646+20774+20902+21030+21158+21286+21414+21542+21670+21798+21926+22054+22182+22310+22438+22566+22694+22822+22950+23078+23206+23334+23462+23590+23718+23846+23974+24102+24230+24358+24486+24614+24742+24870+24998+25126+25254+25382+25510+25638+25766+25894+26022+26150+26278+26406+26534+26662+26790+26918+27046+27174+27302+27430+27558+27686+27814+27942+28070+28198+28326+28454+28582+28710+28838+28966+29094+29222+29350+29478+29606+29734+29862+29990+30118+30246+30374+30502+30630+30758+30886+31014+31142+31270+31398+31526+31654+31782+31910+32038+32166+32294+32422+32550+32678,39+167+295+423+551+679+807+935+1063+1191+1319+1447+1575+1703+1831+1959+2087+2215+2343+2471+2599+2727+2855+2983+3111+3239+3367+3495+3623+3751+3879+4007+4135+4263+4391+4519+4647+4775+4903+5031+5159+5287+5415+5543+5671+5799+5927+6055+6183+6311+6439+6567+6695+6823+6951+7079+7207+7335+7463+7591+7719+7847+7975+8103+8231+8359+8487+8615+8743+8871+8999+9127+9255+9383+9511+9639+9767+9895+10023+10151+10279+10407+10535+10663+10791+10919+11047+11175+11303+11431+11559+11687+11815+11943+12071+12199+12327+12455+12583+12711+12839+12967+13095+13223+13351+13479+13607+13735+13863+13991+14119+14247+14375+14503+14631+14759+14887+15015+15143+15271+15399+15527+15655+15783+15911+16039+16167+16295+16423+16551+16679+16807+16935+17063+17191+17319+17447+17575+17703+17831+17959+18087+18215+18343+18471+18599+18727+18855+18983+19111+19239+19367+19495+19623+19751+19879+20007+20135+20263+20391+20519+20647+20775+20903+21031+21159+21287+21415+21543+21671+21799+21927+22055+22183+22311+22439+22567+22695+22823+22951+23079+23207+23335+23463+23591+23719+23847+23975+24103+24231+24359+24487+24615+24743+24871+24999+25127+25255+25383+25511+25639+25767+25895+26023+26151+26279+26407+26535+26663+26791+26919+27047+27175+27303+27431+27559+27687+27815+27943+28071+28199+28327+28455+28583+28711+28839+28967+29095+29223+29351+29479+29607+29735+29863+29991+30119+30247+30375+30503+30631+30759+30887+31015+31143+31271+31399+31527+31655+31783+31911+32039+32167+32295+32423+32551+32679,40+168+296+424+552+680+808+936+1064+1192+1320+1448+1576+1704+1832+1960+2088+2216+2344+2472+2600+2728+2856+2984+3112+3240+3368+3496+3624+3752+3880+4008+4136+4264+4392+4520+4648+4776+4904+5032+5160+5288+5416+5544+5672+5800+5928+6056+6184+6312+6440+6568+6696+6824+6952+7080+7208+7336+7464+7592+7720+7848+7976+8104+8232+8360+8488+8616+8744+8872+9000+9128+9256+9384+9512+9640+9768+9896+10024+10152+10280+10408+10536+10664+10792+10920+11048+11176+11304+11432+11560+11688+11816+11944+12072+12200+12328+12456+12584+12712+12840+12968+13096+13224+13352+13480+13608+13736+13864+13992+14120+14248+14376+14504+14632+14760+14888+15016+15144+15272+15400+15528+15656+15784+15912+16040+16168+16296+16424+16552+16680+16808+16936+17064+17192+17320+17448+17576+17704+17832+17960+18088+18216+18344+18472+18600+18728+18856+18984+19112+19240+19368+19496+19624+19752+19880+20008+20136+20264+20392+20520+20648+20776+20904+21032+21160+21288+21416+21544+21672+21800+21928+22056+22184+22312+22440+22568+22696+22824+22952+23080+23208+23336+23464+23592+23720+23848+23976+24104+24232+24360+24488+24616+24744+24872+25000+25128+25256+25384+25512+25640+25768+25896+26024+26152+26280+26408+26536+26664+26792+26920+27048+27176+27304+27432+27560+27688+27816+27944+28072+28200+28328+28456+28584+28712+28840+28968+29096+29224+29352+29480+29608+29736+29864+29992+30120+30248+30376+30504+30632+30760+30888+31016+31144+31272+31400+31528+31656+31784+31912+32040+32168+32296+32424+32552+32680,41+169+297+425+553+681+809+937+1065+1193+1321+1449+1577+1705+1833+1961+2089+2217+2345+2473+2601+2729+2857+2985+3113+3241+3369+3497+3625+3753+3881+4009+4137+4265+4393+4521+4649+4777+4905+5033+5161+5289+5417+5545+5673+5801+5929+6057+6185+6313+6441+6569+6697+6825+6953+7081+7209+7337+7465+7593+7721+7849+7977+8105+8233+8361+8489+8617+8745+8873+9001+9129+9257+9385+9513+9641+9769+9897+10025+10153+10281+10409+10537+10665+10793+10921+11049+11177+11305+11433+11561+11689+11817+11945+12073+12201+12329+12457+12585+12713+12841+12969+13097+13225+13353+13481+13609+13737+13865+13993+14121+14249+14377+14505+14633+14761+14889+15017+15145+15273+15401+15529+15657+15785+15913+16041+16169+16297+16425+16553+16681+16809+16937+17065+17193+17321+17449+17577+17705+17833+17961+18089+18217+18345+18473+18601+18729+18857+18985+19113+19241+19369+19497+19625+19753+19881+20009+20137+20265+20393+20521+20649+20777+20905+21033+21161+21289+21417+21545+21673+21801+21929+22057+22185+22313+22441+22569+22697+22825+22953+23081+23209+23337+23465+23593+23721+23849+23977+24105+24233+24361+24489+24617+24745+24873+25001+25129+25257+25385+25513+25641+25769+25897+26025+26153+26281+26409+26537+26665+26793+26921+27049+27177+27305+27433+27561+27689+27817+27945+28073+28201+28329+28457+28585+28713+28841+28969+29097+29225+29353+29481+29609+29737+29865+29993+30121+30249+30377+30505+30633+30761+30889+31017+31145+31273+31401+31529+31657+31785+31913+32041+32169+32297+32425+32553+32681,42+170+298+426+554+682+810+938+1066+1194+1322+1450+1578+1706+1834+1962+2090+2218+2346+2474+2602+2730+2858+2986+3114+3242+3370+3498+3626+3754+3882+4010+4138+4266+4394+4522+4650+4778+4906+5034+5162+5290+5418+5546+5674+5802+5930+6058+6186+6314+6442+6570+6698+6826+6954+7082+7210+7338+7466+7594+7722+7850+7978+8106+8234+8362+8490+8618+8746+8874+9002+9130+9258+9386+9514+9642+9770+9898+10026+10154+10282+10410+10538+10666+10794+10922+11050+11178+11306+11434+11562+11690+11818+11946+12074+12202+12330+12458+12586+12714+12842+12970+13098+13226+13354+13482+13610+13738+13866+13994+14122+14250+14378+14506+14634+14762+14890+15018+15146+15274+15402+15530+15658+15786+15914+16042+16170+16298+16426+16554+16682+16810+16938+17066+17194+17322+17450+17578+17706+17834+17962+18090+18218+18346+18474+18602+18730+18858+18986+19114+19242+19370+19498+19626+19754+19882+20010+20138+20266+20394+20522+20650+20778+20906+21034+21162+21290+21418+21546+21674+21802+21930+22058+22186+22314+22442+22570+22698+22826+22954+23082+23210+23338+23466+23594+23722+23850+23978+24106+24234+24362+24490+24618+24746+24874+25002+25130+25258+25386+25514+25642+25770+25898+26026+26154+26282+26410+26538+26666+26794+26922+27050+27178+27306+27434+27562+27690+27818+27946+28074+28202+28330+28458+28586+28714+28842+28970+29098+29226+29354+29482+29610+29738+29866+29994+30122+30250+30378+30506+30634+30762+30890+31018+31146+31274+31402+31530+31658+31786+31914+32042+32170+32298+32426+32554+32682,43+171+299+427+555+683+811+939+1067+1195+1323+1451+1579+1707+1835+1963+2091+2219+2347+2475+2603+2731+2859+2987+3115+3243+3371+3499+3627+3755+3883+4011+4139+4267+4395+4523+4651+4779+4907+5035+5163+5291+5419+5547+5675+5803+5931+6059+6187+6315+6443+6571+6699+6827+6955+7083+7211+7339+7467+7595+7723+7851+7979+8107+8235+8363+8491+8619+8747+8875+9003+9131+9259+9387+9515+9643+9771+9899+10027+10155+10283+10411+10539+10667+10795+10923+11051+11179+11307+11435+11563+11691+11819+11947+12075+12203+12331+12459+12587+12715+12843+12971+13099+13227+13355+13483+13611+13739+13867+13995+14123+14251+14379+14507+14635+14763+14891+15019+15147+15275+15403+15531+15659+15787+15915+16043+16171+16299+16427+16555+16683+16811+16939+17067+17195+17323+17451+17579+17707+17835+17963+18091+18219+18347+18475+18603+18731+18859+18987+19115+19243+19371+19499+19627+19755+19883+20011+20139+20267+20395+20523+20651+20779+20907+21035+21163+21291+21419+21547+21675+21803+21931+22059+22187+22315+22443+22571+22699+22827+22955+23083+23211+23339+23467+23595+23723+23851+23979+24107+24235+24363+24491+24619+24747+24875+25003+25131+25259+25387+25515+25643+25771+25899+26027+26155+26283+26411+26539+26667+26795+26923+27051+27179+27307+27435+27563+27691+27819+27947+28075+28203+28331+28459+28587+28715+28843+28971+29099+29227+29355+29483+29611+29739+29867+29995+30123+30251+30379+30507+30635+30763+30891+31019+31147+31275+31403+31531+31659+31787+31915+32043+32171+32299+32427+32555+32683,44+172+300+428+556+684+812+940+1068+1196+1324+1452+1580+1708+1836+1964+2092+2220+2348+2476+2604+2732+2860+2988+3116+3244+3372+3500+3628+3756+3884+4012+4140+4268+4396+4524+4652+4780+4908+5036+5164+5292+5420+5548+5676+5804+5932+6060+6188+6316+6444+6572+6700+6828+6956+7084+7212+7340+7468+7596+7724+7852+7980+8108+8236+8364+8492+8620+8748+8876+9004+9132+9260+9388+9516+9644+9772+9900+10028+10156+10284+10412+10540+10668+10796+10924+11052+11180+11308+11436+11564+11692+11820+11948+12076+12204+12332+12460+12588+12716+12844+12972+13100+13228+13356+13484+13612+13740+13868+13996+14124+14252+14380+14508+14636+14764+14892+15020+15148+15276+15404+15532+15660+15788+15916+16044+16172+16300+16428+16556+16684+16812+16940+17068+17196+17324+17452+17580+17708+17836+17964+18092+18220+18348+18476+18604+18732+18860+18988+19116+19244+19372+19500+19628+19756+19884+20012+20140+20268+20396+20524+20652+20780+20908+21036+21164+21292+21420+21548+21676+21804+21932+22060+22188+22316+22444+22572+22700+22828+22956+23084+23212+23340+23468+23596+23724+23852+23980+24108+24236+24364+24492+24620+24748+24876+25004+25132+25260+25388+25516+25644+25772+25900+26028+26156+26284+26412+26540+26668+26796+26924+27052+27180+27308+27436+27564+27692+27820+27948+28076+28204+28332+28460+28588+28716+28844+28972+29100+29228+29356+29484+29612+29740+29868+29996+30124+30252+30380+30508+30636+30764+30892+31020+31148+31276+31404+31532+31660+31788+31916+32044+32172+32300+32428+32556+32684,45+173+301+429+557+685+813+941+1069+1197+1325+1453+1581+1709+1837+1965+2093+2221+2349+2477+2605+2733+2861+2989+3117+3245+3373+3501+3629+3757+3885+4013+4141+4269+4397+4525+4653+4781+4909+5037+5165+5293+5421+5549+5677+5805+5933+6061+6189+6317+6445+6573+6701+6829+6957+7085+7213+7341+7469+7597+7725+7853+7981+8109+8237+8365+8493+8621+8749+8877+9005+9133+9261+9389+9517+9645+9773+9901+10029+10157+10285+10413+10541+10669+10797+10925+11053+11181+11309+11437+11565+11693+11821+11949+12077+12205+12333+12461+12589+12717+12845+12973+13101+13229+13357+13485+13613+13741+13869+13997+14125+14253+14381+14509+14637+14765+14893+15021+15149+15277+15405+15533+15661+15789+15917+16045+16173+16301+16429+16557+16685+16813+16941+17069+17197+17325+17453+17581+17709+17837+17965+18093+18221+18349+18477+18605+18733+18861+18989+19117+19245+19373+19501+19629+19757+19885+20013+20141+20269+20397+20525+20653+20781+20909+21037+21165+21293+21421+21549+21677+21805+21933+22061+22189+22317+22445+22573+22701+22829+22957+23085+23213+23341+23469+23597+23725+23853+23981+24109+24237+24365+24493+24621+24749+24877+25005+25133+25261+25389+25517+25645+25773+25901+26029+26157+26285+26413+26541+26669+26797+26925+27053+27181+27309+27437+27565+27693+27821+27949+28077+28205+28333+28461+28589+28717+28845+28973+29101+29229+29357+29485+29613+29741+29869+29997+30125+30253+30381+30509+30637+30765+30893+31021+31149+31277+31405+31533+31661+31789+31917+32045+32173+32301+32429+32557+32685,46+174+302+430+558+686+814+942+1070+1198+1326+1454+1582+1710+1838+1966+2094+2222+2350+2478+2606+2734+2862+2990+3118+3246+3374+3502+3630+3758+3886+4014+4142+4270+4398+4526+4654+4782+4910+5038+5166+5294+5422+5550+5678+5806+5934+6062+6190+6318+6446+6574+6702+6830+6958+7086+7214+7342+7470+7598+7726+7854+7982+8110+8238+8366+8494+8622+8750+8878+9006+9134+9262+9390+9518+9646+9774+9902+10030+10158+10286+10414+10542+10670+10798+10926+11054+11182+11310+11438+11566+11694+11822+11950+12078+12206+12334+12462+12590+12718+12846+12974+13102+13230+13358+13486+13614+13742+13870+13998+14126+14254+14382+14510+14638+14766+14894+15022+15150+15278+15406+15534+15662+15790+15918+16046+16174+16302+16430+16558+16686+16814+16942+17070+17198+17326+17454+17582+17710+17838+17966+18094+18222+18350+18478+18606+18734+18862+18990+19118+19246+19374+19502+19630+19758+19886+20014+20142+20270+20398+20526+20654+20782+20910+21038+21166+21294+21422+21550+21678+21806+21934+22062+22190+22318+22446+22574+22702+22830+22958+23086+23214+23342+23470+23598+23726+23854+23982+24110+24238+24366+24494+24622+24750+24878+25006+25134+25262+25390+25518+25646+25774+25902+26030+26158+26286+26414+26542+26670+26798+26926+27054+27182+27310+27438+27566+27694+27822+27950+28078+28206+28334+28462+28590+28718+28846+28974+29102+29230+29358+29486+29614+29742+29870+29998+30126+30254+30382+30510+30638+30766+30894+31022+31150+31278+31406+31534+31662+31790+31918+32046+32174+32302+32430+32558+32686,47+175+303+431+559+687+815+943+1071+1199+1327+1455+1583+1711+1839+1967+2095+2223+2351+2479+2607+2735+2863+2991+3119+3247+3375+3503+3631+3759+3887+4015+4143+4271+4399+4527+4655+4783+4911+5039+5167+5295+5423+5551+5679+5807+5935+6063+6191+6319+6447+6575+6703+6831+6959+7087+7215+7343+7471+7599+7727+7855+7983+8111+8239+8367+8495+8623+8751+8879+9007+9135+9263+9391+9519+9647+9775+9903+10031+10159+10287+10415+10543+10671+10799+10927+11055+11183+11311+11439+11567+11695+11823+11951+12079+12207+12335+12463+12591+12719+12847+12975+13103+13231+13359+13487+13615+13743+13871+13999+14127+14255+14383+14511+14639+14767+14895+15023+15151+15279+15407+15535+15663+15791+15919+16047+16175+16303+16431+16559+16687+16815+16943+17071+17199+17327+17455+17583+17711+17839+17967+18095+18223+18351+18479+18607+18735+18863+18991+19119+19247+19375+19503+19631+19759+19887+20015+20143+20271+20399+20527+20655+20783+20911+21039+21167+21295+21423+21551+21679+21807+21935+22063+22191+22319+22447+22575+22703+22831+22959+23087+23215+23343+23471+23599+23727+23855+23983+24111+24239+24367+24495+24623+24751+24879+25007+25135+25263+25391+25519+25647+25775+25903+26031+26159+26287+26415+26543+26671+26799+26927+27055+27183+27311+27439+27567+27695+27823+27951+28079+28207+28335+28463+28591+28719+28847+28975+29103+29231+29359+29487+29615+29743+29871+29999+30127+30255+30383+30511+30639+30767+30895+31023+31151+31279+31407+31535+31663+31791+31919+32047+32175+32303+32431+32559+32687,48+176+304+432+560+688+816+944+1072+1200+1328+1456+1584+1712+1840+1968+2096+2224+2352+2480+2608+2736+2864+2992+3120+3248+3376+3504+3632+3760+3888+4016+4144+4272+4400+4528+4656+4784+4912+5040+5168+5296+5424+5552+5680+5808+5936+6064+6192+6320+6448+6576+6704+6832+6960+7088+7216+7344+7472+7600+7728+7856+7984+8112+8240+8368+8496+8624+8752+8880+9008+9136+9264+9392+9520+9648+9776+9904+10032+10160+10288+10416+10544+10672+10800+10928+11056+11184+11312+11440+11568+11696+11824+11952+12080+12208+12336+12464+12592+12720+12848+12976+13104+13232+13360+13488+13616+13744+13872+14000+14128+14256+14384+14512+14640+14768+14896+15024+15152+15280+15408+15536+15664+15792+15920+16048+16176+16304+16432+16560+16688+16816+16944+17072+17200+17328+17456+17584+17712+17840+17968+18096+18224+18352+18480+18608+18736+18864+18992+19120+19248+19376+19504+19632+19760+19888+20016+20144+20272+20400+20528+20656+20784+20912+21040+21168+21296+21424+21552+21680+21808+21936+22064+22192+22320+22448+22576+22704+22832+22960+23088+23216+23344+23472+23600+23728+23856+23984+24112+24240+24368+24496+24624+24752+24880+25008+25136+25264+25392+25520+25648+25776+25904+26032+26160+26288+26416+26544+26672+26800+26928+27056+27184+27312+27440+27568+27696+27824+27952+28080+28208+28336+28464+28592+28720+28848+28976+29104+29232+29360+29488+29616+29744+29872+30000+30128+30256+30384+30512+30640+30768+30896+31024+31152+31280+31408+31536+31664+31792+31920+32048+32176+32304+32432+32560+32688,49+177+305+433+561+689+817+945+1073+1201+1329+1457+1585+1713+1841+1969+2097+2225+2353+2481+2609+2737+2865+2993+3121+3249+3377+3505+3633+3761+3889+4017+4145+4273+4401+4529+4657+4785+4913+5041+5169+5297+5425+5553+5681+5809+5937+6065+6193+6321+6449+6577+6705+6833+6961+7089+7217+7345+7473+7601+7729+7857+7985+8113+8241+8369+8497+8625+8753+8881+9009+9137+9265+9393+9521+9649+9777+9905+10033+10161+10289+10417+10545+10673+10801+10929+11057+11185+11313+11441+11569+11697+11825+11953+12081+12209+12337+12465+12593+12721+12849+12977+13105+13233+13361+13489+13617+13745+13873+14001+14129+14257+14385+14513+14641+14769+14897+15025+15153+15281+15409+15537+15665+15793+15921+16049+16177+16305+16433+16561+16689+16817+16945+17073+17201+17329+17457+17585+17713+17841+17969+18097+18225+18353+18481+18609+18737+18865+18993+19121+19249+19377+19505+19633+19761+19889+20017+20145+20273+20401+20529+20657+20785+20913+21041+21169+21297+21425+21553+21681+21809+21937+22065+22193+22321+22449+22577+22705+22833+22961+23089+23217+23345+23473+23601+23729+23857+23985+24113+24241+24369+24497+24625+24753+24881+25009+25137+25265+25393+25521+25649+25777+25905+26033+26161+26289+26417+26545+26673+26801+26929+27057+27185+27313+27441+27569+27697+27825+27953+28081+28209+28337+28465+28593+28721+28849+28977+29105+29233+29361+29489+29617+29745+29873+30001+30129+30257+30385+30513+30641+30769+30897+31025+31153+31281+31409+31537+31665+31793+31921+32049+32177+32305+32433+32561+32689,50+178+306+434+562+690+818+946+1074+1202+1330+1458+1586+1714+1842+1970+2098+2226+2354+2482+2610+2738+2866+2994+3122+3250+3378+3506+3634+3762+3890+4018+4146+4274+4402+4530+4658+4786+4914+5042+5170+5298+5426+5554+5682+5810+5938+6066+6194+6322+6450+6578+6706+6834+6962+7090+7218+7346+7474+7602+7730+7858+7986+8114+8242+8370+8498+8626+8754+8882+9010+9138+9266+9394+9522+9650+9778+9906+10034+10162+10290+10418+10546+10674+10802+10930+11058+11186+11314+11442+11570+11698+11826+11954+12082+12210+12338+12466+12594+12722+12850+12978+13106+13234+13362+13490+13618+13746+13874+14002+14130+14258+14386+14514+14642+14770+14898+15026+15154+15282+15410+15538+15666+15794+15922+16050+16178+16306+16434+16562+16690+16818+16946+17074+17202+17330+17458+17586+17714+17842+17970+18098+18226+18354+18482+18610+18738+18866+18994+19122+19250+19378+19506+19634+19762+19890+20018+20146+20274+20402+20530+20658+20786+20914+21042+21170+21298+21426+21554+21682+21810+21938+22066+22194+22322+22450+22578+22706+22834+22962+23090+23218+23346+23474+23602+23730+23858+23986+24114+24242+24370+24498+24626+24754+24882+25010+25138+25266+25394+25522+25650+25778+25906+26034+26162+26290+26418+26546+26674+26802+26930+27058+27186+27314+27442+27570+27698+27826+27954+28082+28210+28338+28466+28594+28722+28850+28978+29106+29234+29362+29490+29618+29746+29874+30002+30130+30258+30386+30514+30642+30770+30898+31026+31154+31282+31410+31538+31666+31794+31922+32050+32178+32306+32434+32562+32690,51+179+307+435+563+691+819+947+1075+1203+1331+1459+1587+1715+1843+1971+2099+2227+2355+2483+2611+2739+2867+2995+3123+3251+3379+3507+3635+3763+3891+4019+4147+4275+4403+4531+4659+4787+4915+5043+5171+5299+5427+5555+5683+5811+5939+6067+6195+6323+6451+6579+6707+6835+6963+7091+7219+7347+7475+7603+7731+7859+7987+8115+8243+8371+8499+8627+8755+8883+9011+9139+9267+9395+9523+9651+9779+9907+10035+10163+10291+10419+10547+10675+10803+10931+11059+11187+11315+11443+11571+11699+11827+11955+12083+12211+12339+12467+12595+12723+12851+12979+13107+13235+13363+13491+13619+13747+13875+14003+14131+14259+14387+14515+14643+14771+14899+15027+15155+15283+15411+15539+15667+15795+15923+16051+16179+16307+16435+16563+16691+16819+16947+17075+17203+17331+17459+17587+17715+17843+17971+18099+18227+18355+18483+18611+18739+18867+18995+19123+19251+19379+19507+19635+19763+19891+20019+20147+20275+20403+20531+20659+20787+20915+21043+21171+21299+21427+21555+21683+21811+21939+22067+22195+22323+22451+22579+22707+22835+22963+23091+23219+23347+23475+23603+23731+23859+23987+24115+24243+24371+24499+24627+24755+24883+25011+25139+25267+25395+25523+25651+25779+25907+26035+26163+26291+26419+26547+26675+26803+26931+27059+27187+27315+27443+27571+27699+27827+27955+28083+28211+28339+28467+28595+28723+28851+28979+29107+29235+29363+29491+29619+29747+29875+30003+30131+30259+30387+30515+30643+30771+30899+31027+31155+31283+31411+31539+31667+31795+31923+32051+32179+32307+32435+32563+32691,52+180+308+436+564+692+820+948+1076+1204+1332+1460+1588+1716+1844+1972+2100+2228+2356+2484+2612+2740+2868+2996+3124+3252+3380+3508+3636+3764+3892+4020+4148+4276+4404+4532+4660+4788+4916+5044+5172+5300+5428+5556+5684+5812+5940+6068+6196+6324+6452+6580+6708+6836+6964+7092+7220+7348+7476+7604+7732+7860+7988+8116+8244+8372+8500+8628+8756+8884+9012+9140+9268+9396+9524+9652+9780+9908+10036+10164+10292+10420+10548+10676+10804+10932+11060+11188+11316+11444+11572+11700+11828+11956+12084+12212+12340+12468+12596+12724+12852+12980+13108+13236+13364+13492+13620+13748+13876+14004+14132+14260+14388+14516+14644+14772+14900+15028+15156+15284+15412+15540+15668+15796+15924+16052+16180+16308+16436+16564+16692+16820+16948+17076+17204+17332+17460+17588+17716+17844+17972+18100+18228+18356+18484+18612+18740+18868+18996+19124+19252+19380+19508+19636+19764+19892+20020+20148+20276+20404+20532+20660+20788+20916+21044+21172+21300+21428+21556+21684+21812+21940+22068+22196+22324+22452+22580+22708+22836+22964+23092+23220+23348+23476+23604+23732+23860+23988+24116+24244+24372+24500+24628+24756+24884+25012+25140+25268+25396+25524+25652+25780+25908+26036+26164+26292+26420+26548+26676+26804+26932+27060+27188+27316+27444+27572+27700+27828+27956+28084+28212+28340+28468+28596+28724+28852+28980+29108+29236+29364+29492+29620+29748+29876+30004+30132+30260+30388+30516+30644+30772+30900+31028+31156+31284+31412+31540+31668+31796+31924+32052+32180+32308+32436+32564+32692,53+181+309+437+565+693+821+949+1077+1205+1333+1461+1589+1717+1845+1973+2101+2229+2357+2485+2613+2741+2869+2997+3125+3253+3381+3509+3637+3765+3893+4021+4149+4277+4405+4533+4661+4789+4917+5045+5173+5301+5429+5557+5685+5813+5941+6069+6197+6325+6453+6581+6709+6837+6965+7093+7221+7349+7477+7605+7733+7861+7989+8117+8245+8373+8501+8629+8757+8885+9013+9141+9269+9397+9525+9653+9781+9909+10037+10165+10293+10421+10549+10677+10805+10933+11061+11189+11317+11445+11573+11701+11829+11957+12085+12213+12341+12469+12597+12725+12853+12981+13109+13237+13365+13493+13621+13749+13877+14005+14133+14261+14389+14517+14645+14773+14901+15029+15157+15285+15413+15541+15669+15797+15925+16053+16181+16309+16437+16565+16693+16821+16949+17077+17205+17333+17461+17589+17717+17845+17973+18101+18229+18357+18485+18613+18741+18869+18997+19125+19253+19381+19509+19637+19765+19893+20021+20149+20277+20405+20533+20661+20789+20917+21045+21173+21301+21429+21557+21685+21813+21941+22069+22197+22325+22453+22581+22709+22837+22965+23093+23221+23349+23477+23605+23733+23861+23989+24117+24245+24373+24501+24629+24757+24885+25013+25141+25269+25397+25525+25653+25781+25909+26037+26165+26293+26421+26549+26677+26805+26933+27061+27189+27317+27445+27573+27701+27829+27957+28085+28213+28341+28469+28597+28725+28853+28981+29109+29237+29365+29493+29621+29749+29877+30005+30133+30261+30389+30517+30645+30773+30901+31029+31157+31285+31413+31541+31669+31797+31925+32053+32181+32309+32437+32565+32693,54+182+310+438+566+694+822+950+1078+1206+1334+1462+1590+1718+1846+1974+2102+2230+2358+2486+2614+2742+2870+2998+3126+3254+3382+3510+3638+3766+3894+4022+4150+4278+4406+4534+4662+4790+4918+5046+5174+5302+5430+5558+5686+5814+5942+6070+6198+6326+6454+6582+6710+6838+6966+7094+7222+7350+7478+7606+7734+7862+7990+8118+8246+8374+8502+8630+8758+8886+9014+9142+9270+9398+9526+9654+9782+9910+10038+10166+10294+10422+10550+10678+10806+10934+11062+11190+11318+11446+11574+11702+11830+11958+12086+12214+12342+12470+12598+12726+12854+12982+13110+13238+13366+13494+13622+13750+13878+14006+14134+14262+14390+14518+14646+14774+14902+15030+15158+15286+15414+15542+15670+15798+15926+16054+16182+16310+16438+16566+16694+16822+16950+17078+17206+17334+17462+17590+17718+17846+17974+18102+18230+18358+18486+18614+18742+18870+18998+19126+19254+19382+19510+19638+19766+19894+20022+20150+20278+20406+20534+20662+20790+20918+21046+21174+21302+21430+21558+21686+21814+21942+22070+22198+22326+22454+22582+22710+22838+22966+23094+23222+23350+23478+23606+23734+23862+23990+24118+24246+24374+24502+24630+24758+24886+25014+25142+25270+25398+25526+25654+25782+25910+26038+26166+26294+26422+26550+26678+26806+26934+27062+27190+27318+27446+27574+27702+27830+27958+28086+28214+28342+28470+28598+28726+28854+28982+29110+29238+29366+29494+29622+29750+29878+30006+30134+30262+30390+30518+30646+30774+30902+31030+31158+31286+31414+31542+31670+31798+31926+32054+32182+32310+32438+32566+32694,55+183+311+439+567+695+823+951+1079+1207+1335+1463+1591+1719+1847+1975+2103+2231+2359+2487+2615+2743+2871+2999+3127+3255+3383+3511+3639+3767+3895+4023+4151+4279+4407+4535+4663+4791+4919+5047+5175+5303+5431+5559+5687+5815+5943+6071+6199+6327+6455+6583+6711+6839+6967+7095+7223+7351+7479+7607+7735+7863+7991+8119+8247+8375+8503+8631+8759+8887+9015+9143+9271+9399+9527+9655+9783+9911+10039+10167+10295+10423+10551+10679+10807+10935+11063+11191+11319+11447+11575+11703+11831+11959+12087+12215+12343+12471+12599+12727+12855+12983+13111+13239+13367+13495+13623+13751+13879+14007+14135+14263+14391+14519+14647+14775+14903+15031+15159+15287+15415+15543+15671+15799+15927+16055+16183+16311+16439+16567+16695+16823+16951+17079+17207+17335+17463+17591+17719+17847+17975+18103+18231+18359+18487+18615+18743+18871+18999+19127+19255+19383+19511+19639+19767+19895+20023+20151+20279+20407+20535+20663+20791+20919+21047+21175+21303+21431+21559+21687+21815+21943+22071+22199+22327+22455+22583+22711+22839+22967+23095+23223+23351+23479+23607+23735+23863+23991+24119+24247+24375+24503+24631+24759+24887+25015+25143+25271+25399+25527+25655+25783+25911+26039+26167+26295+26423+26551+26679+26807+26935+27063+27191+27319+27447+27575+27703+27831+27959+28087+28215+28343+28471+28599+28727+28855+28983+29111+29239+29367+29495+29623+29751+29879+30007+30135+30263+30391+30519+30647+30775+30903+31031+31159+31287+31415+31543+31671+31799+31927+32055+32183+32311+32439+32567+32695,56+184+312+440+568+696+824+952+1080+1208+1336+1464+1592+1720+1848+1976+2104+2232+2360+2488+2616+2744+2872+3000+3128+3256+3384+3512+3640+3768+3896+4024+4152+4280+4408+4536+4664+4792+4920+5048+5176+5304+5432+5560+5688+5816+5944+6072+6200+6328+6456+6584+6712+6840+6968+7096+7224+7352+7480+7608+7736+7864+7992+8120+8248+8376+8504+8632+8760+8888+9016+9144+9272+9400+9528+9656+9784+9912+10040+10168+10296+10424+10552+10680+10808+10936+11064+11192+11320+11448+11576+11704+11832+11960+12088+12216+12344+12472+12600+12728+12856+12984+13112+13240+13368+13496+13624+13752+13880+14008+14136+14264+14392+14520+14648+14776+14904+15032+15160+15288+15416+15544+15672+15800+15928+16056+16184+16312+16440+16568+16696+16824+16952+17080+17208+17336+17464+17592+17720+17848+17976+18104+18232+18360+18488+18616+18744+18872+19000+19128+19256+19384+19512+19640+19768+19896+20024+20152+20280+20408+20536+20664+20792+20920+21048+21176+21304+21432+21560+21688+21816+21944+22072+22200+22328+22456+22584+22712+22840+22968+23096+23224+23352+23480+23608+23736+23864+23992+24120+24248+24376+24504+24632+24760+24888+25016+25144+25272+25400+25528+25656+25784+25912+26040+26168+26296+26424+26552+26680+26808+26936+27064+27192+27320+27448+27576+27704+27832+27960+28088+28216+28344+28472+28600+28728+28856+28984+29112+29240+29368+29496+29624+29752+29880+30008+30136+30264+30392+30520+30648+30776+30904+31032+31160+31288+31416+31544+31672+31800+31928+32056+32184+32312+32440+32568+32696,57+185+313+441+569+697+825+953+1081+1209+1337+1465+1593+1721+1849+1977+2105+2233+2361+2489+2617+2745+2873+3001+3129+3257+3385+3513+3641+3769+3897+4025+4153+4281+4409+4537+4665+4793+4921+5049+5177+5305+5433+5561+5689+5817+5945+6073+6201+6329+6457+6585+6713+6841+6969+7097+7225+7353+7481+7609+7737+7865+7993+8121+8249+8377+8505+8633+8761+8889+9017+9145+9273+9401+9529+9657+9785+9913+10041+10169+10297+10425+10553+10681+10809+10937+11065+11193+11321+11449+11577+11705+11833+11961+12089+12217+12345+12473+12601+12729+12857+12985+13113+13241+13369+13497+13625+13753+13881+14009+14137+14265+14393+14521+14649+14777+14905+15033+15161+15289+15417+15545+15673+15801+15929+16057+16185+16313+16441+16569+16697+16825+16953+17081+17209+17337+17465+17593+17721+17849+17977+18105+18233+18361+18489+18617+18745+18873+19001+19129+19257+19385+19513+19641+19769+19897+20025+20153+20281+20409+20537+20665+20793+20921+21049+21177+21305+21433+21561+21689+21817+21945+22073+22201+22329+22457+22585+22713+22841+22969+23097+23225+23353+23481+23609+23737+23865+23993+24121+24249+24377+24505+24633+24761+24889+25017+25145+25273+25401+25529+25657+25785+25913+26041+26169+26297+26425+26553+26681+26809+26937+27065+27193+27321+27449+27577+27705+27833+27961+28089+28217+28345+28473+28601+28729+28857+28985+29113+29241+29369+29497+29625+29753+29881+30009+30137+30265+30393+30521+30649+30777+30905+31033+31161+31289+31417+31545+31673+31801+31929+32057+32185+32313+32441+32569+32697,58+186+314+442+570+698+826+954+1082+1210+1338+1466+1594+1722+1850+1978+2106+2234+2362+2490+2618+2746+2874+3002+3130+3258+3386+3514+3642+3770+3898+4026+4154+4282+4410+4538+4666+4794+4922+5050+5178+5306+5434+5562+5690+5818+5946+6074+6202+6330+6458+6586+6714+6842+6970+7098+7226+7354+7482+7610+7738+7866+7994+8122+8250+8378+8506+8634+8762+8890+9018+9146+9274+9402+9530+9658+9786+9914+10042+10170+10298+10426+10554+10682+10810+10938+11066+11194+11322+11450+11578+11706+11834+11962+12090+12218+12346+12474+12602+12730+12858+12986+13114+13242+13370+13498+13626+13754+13882+14010+14138+14266+14394+14522+14650+14778+14906+15034+15162+15290+15418+15546+15674+15802+15930+16058+16186+16314+16442+16570+16698+16826+16954+17082+17210+17338+17466+17594+17722+17850+17978+18106+18234+18362+18490+18618+18746+18874+19002+19130+19258+19386+19514+19642+19770+19898+20026+20154+20282+20410+20538+20666+20794+20922+21050+21178+21306+21434+21562+21690+21818+21946+22074+22202+22330+22458+22586+22714+22842+22970+23098+23226+23354+23482+23610+23738+23866+23994+24122+24250+24378+24506+24634+24762+24890+25018+25146+25274+25402+25530+25658+25786+25914+26042+26170+26298+26426+26554+26682+26810+26938+27066+27194+27322+27450+27578+27706+27834+27962+28090+28218+28346+28474+28602+28730+28858+28986+29114+29242+29370+29498+29626+29754+29882+30010+30138+30266+30394+30522+30650+30778+30906+31034+31162+31290+31418+31546+31674+31802+31930+32058+32186+32314+32442+32570+32698,59+187+315+443+571+699+827+955+1083+1211+1339+1467+1595+1723+1851+1979+2107+2235+2363+2491+2619+2747+2875+3003+3131+3259+3387+3515+3643+3771+3899+4027+4155+4283+4411+4539+4667+4795+4923+5051+5179+5307+5435+5563+5691+5819+5947+6075+6203+6331+6459+6587+6715+6843+6971+7099+7227+7355+7483+7611+7739+7867+7995+8123+8251+8379+8507+8635+8763+8891+9019+9147+9275+9403+9531+9659+9787+9915+10043+10171+10299+10427+10555+10683+10811+10939+11067+11195+11323+11451+11579+11707+11835+11963+12091+12219+12347+12475+12603+12731+12859+12987+13115+13243+13371+13499+13627+13755+13883+14011+14139+14267+14395+14523+14651+14779+14907+15035+15163+15291+15419+15547+15675+15803+15931+16059+16187+16315+16443+16571+16699+16827+16955+17083+17211+17339+17467+17595+17723+17851+17979+18107+18235+18363+18491+18619+18747+18875+19003+19131+19259+19387+19515+19643+19771+19899+20027+20155+20283+20411+20539+20667+20795+20923+21051+21179+21307+21435+21563+21691+21819+21947+22075+22203+22331+22459+22587+22715+22843+22971+23099+23227+23355+23483+23611+23739+23867+23995+24123+24251+24379+24507+24635+24763+24891+25019+25147+25275+25403+25531+25659+25787+25915+26043+26171+26299+26427+26555+26683+26811+26939+27067+27195+27323+27451+27579+27707+27835+27963+28091+28219+28347+28475+28603+28731+28859+28987+29115+29243+29371+29499+29627+29755+29883+30011+30139+30267+30395+30523+30651+30779+30907+31035+31163+31291+31419+31547+31675+31803+31931+32059+32187+32315+32443+32571+32699,60+188+316+444+572+700+828+956+1084+1212+1340+1468+1596+1724+1852+1980+2108+2236+2364+2492+2620+2748+2876+3004+3132+3260+3388+3516+3644+3772+3900+4028+4156+4284+4412+4540+4668+4796+4924+5052+5180+5308+5436+5564+5692+5820+5948+6076+6204+6332+6460+6588+6716+6844+6972+7100+7228+7356+7484+7612+7740+7868+7996+8124+8252+8380+8508+8636+8764+8892+9020+9148+9276+9404+9532+9660+9788+9916+10044+10172+10300+10428+10556+10684+10812+10940+11068+11196+11324+11452+11580+11708+11836+11964+12092+12220+12348+12476+12604+12732+12860+12988+13116+13244+13372+13500+13628+13756+13884+14012+14140+14268+14396+14524+14652+14780+14908+15036+15164+15292+15420+15548+15676+15804+15932+16060+16188+16316+16444+16572+16700+16828+16956+17084+17212+17340+17468+17596+17724+17852+17980+18108+18236+18364+18492+18620+18748+18876+19004+19132+19260+19388+19516+19644+19772+19900+20028+20156+20284+20412+20540+20668+20796+20924+21052+21180+21308+21436+21564+21692+21820+21948+22076+22204+22332+22460+22588+22716+22844+22972+23100+23228+23356+23484+23612+23740+23868+23996+24124+24252+24380+24508+24636+24764+24892+25020+25148+25276+25404+25532+25660+25788+25916+26044+26172+26300+26428+26556+26684+26812+26940+27068+27196+27324+27452+27580+27708+27836+27964+28092+28220+28348+28476+28604+28732+28860+28988+29116+29244+29372+29500+29628+29756+29884+30012+30140+30268+30396+30524+30652+30780+30908+31036+31164+31292+31420+31548+31676+31804+31932+32060+32188+32316+32444+32572+32700,61+189+317+445+573+701+829+957+1085+1213+1341+1469+1597+1725+1853+1981+2109+2237+2365+2493+2621+2749+2877+3005+3133+3261+3389+3517+3645+3773+3901+4029+4157+4285+4413+4541+4669+4797+4925+5053+5181+5309+5437+5565+5693+5821+5949+6077+6205+6333+6461+6589+6717+6845+6973+7101+7229+7357+7485+7613+7741+7869+7997+8125+8253+8381+8509+8637+8765+8893+9021+9149+9277+9405+9533+9661+9789+9917+10045+10173+10301+10429+10557+10685+10813+10941+11069+11197+11325+11453+11581+11709+11837+11965+12093+12221+12349+12477+12605+12733+12861+12989+13117+13245+13373+13501+13629+13757+13885+14013+14141+14269+14397+14525+14653+14781+14909+15037+15165+15293+15421+15549+15677+15805+15933+16061+16189+16317+16445+16573+16701+16829+16957+17085+17213+17341+17469+17597+17725+17853+17981+18109+18237+18365+18493+18621+18749+18877+19005+19133+19261+19389+19517+19645+19773+19901+20029+20157+20285+20413+20541+20669+20797+20925+21053+21181+21309+21437+21565+21693+21821+21949+22077+22205+22333+22461+22589+22717+22845+22973+23101+23229+23357+23485+23613+23741+23869+23997+24125+24253+24381+24509+24637+24765+24893+25021+25149+25277+25405+25533+25661+25789+25917+26045+26173+26301+26429+26557+26685+26813+26941+27069+27197+27325+27453+27581+27709+27837+27965+28093+28221+28349+28477+28605+28733+28861+28989+29117+29245+29373+29501+29629+29757+29885+30013+30141+30269+30397+30525+30653+30781+30909+31037+31165+31293+31421+31549+31677+31805+31933+32061+32189+32317+32445+32573+32701,62+190+318+446+574+702+830+958+1086+1214+1342+1470+1598+1726+1854+1982+2110+2238+2366+2494+2622+2750+2878+3006+3134+3262+3390+3518+3646+3774+3902+4030+4158+4286+4414+4542+4670+4798+4926+5054+5182+5310+5438+5566+5694+5822+5950+6078+6206+6334+6462+6590+6718+6846+6974+7102+7230+7358+7486+7614+7742+7870+7998+8126+8254+8382+8510+8638+8766+8894+9022+9150+9278+9406+9534+9662+9790+9918+10046+10174+10302+10430+10558+10686+10814+10942+11070+11198+11326+11454+11582+11710+11838+11966+12094+12222+12350+12478+12606+12734+12862+12990+13118+13246+13374+13502+13630+13758+13886+14014+14142+14270+14398+14526+14654+14782+14910+15038+15166+15294+15422+15550+15678+15806+15934+16062+16190+16318+16446+16574+16702+16830+16958+17086+17214+17342+17470+17598+17726+17854+17982+18110+18238+18366+18494+18622+18750+18878+19006+19134+19262+19390+19518+19646+19774+19902+20030+20158+20286+20414+20542+20670+20798+20926+21054+21182+21310+21438+21566+21694+21822+21950+22078+22206+22334+22462+22590+22718+22846+22974+23102+23230+23358+23486+23614+23742+23870+23998+24126+24254+24382+24510+24638+24766+24894+25022+25150+25278+25406+25534+25662+25790+25918+26046+26174+26302+26430+26558+26686+26814+26942+27070+27198+27326+27454+27582+27710+27838+27966+28094+28222+28350+28478+28606+28734+28862+28990+29118+29246+29374+29502+29630+29758+29886+30014+30142+30270+30398+30526+30654+30782+30910+31038+31166+31294+31422+31550+31678+31806+31934+32062+32190+32318+32446+32574+32702,63+191+319+447+575+703+831+959+1087+1215+1343+1471+1599+1727+1855+1983+2111+2239+2367+2495+2623+2751+2879+3007+3135+3263+3391+3519+3647+3775+3903+4031+4159+4287+4415+4543+4671+4799+4927+5055+5183+5311+5439+5567+5695+5823+5951+6079+6207+6335+6463+6591+6719+6847+6975+7103+7231+7359+7487+7615+7743+7871+7999+8127+8255+8383+8511+8639+8767+8895+9023+9151+9279+9407+9535+9663+9791+9919+10047+10175+10303+10431+10559+10687+10815+10943+11071+11199+11327+11455+11583+11711+11839+11967+12095+12223+12351+12479+12607+12735+12863+12991+13119+13247+13375+13503+13631+13759+13887+14015+14143+14271+14399+14527+14655+14783+14911+15039+15167+15295+15423+15551+15679+15807+15935+16063+16191+16319+16447+16575+16703+16831+16959+17087+17215+17343+17471+17599+17727+17855+17983+18111+18239+18367+18495+18623+18751+18879+19007+19135+19263+19391+19519+19647+19775+19903+20031+20159+20287+20415+20543+20671+20799+20927+21055+21183+21311+21439+21567+21695+21823+21951+22079+22207+22335+22463+22591+22719+22847+22975+23103+23231+23359+23487+23615+23743+23871+23999+24127+24255+24383+24511+24639+24767+24895+25023+25151+25279+25407+25535+25663+25791+25919+26047+26175+26303+26431+26559+26687+26815+26943+27071+27199+27327+27455+27583+27711+27839+27967+28095+28223+28351+28479+28607+28735+28863+28991+29119+29247+29375+29503+29631+29759+29887+30015+30143+30271+30399+30527+30655+30783+30911+31039+31167+31295+31423+31551+31679+31807+31935+32063+32191+32319+32447+32575+32703,64+192+320+448+576+704+832+960+1088+1216+1344+1472+1600+1728+1856+1984+2112+2240+2368+2496+2624+2752+2880+3008+3136+3264+3392+3520+3648+3776+3904+4032+4160+4288+4416+4544+4672+4800+4928+5056+5184+5312+5440+5568+5696+5824+5952+6080+6208+6336+6464+6592+6720+6848+6976+7104+7232+7360+7488+7616+7744+7872+8000+8128+8256+8384+8512+8640+8768+8896+9024+9152+9280+9408+9536+9664+9792+9920+10048+10176+10304+10432+10560+10688+10816+10944+11072+11200+11328+11456+11584+11712+11840+11968+12096+12224+12352+12480+12608+12736+12864+12992+13120+13248+13376+13504+13632+13760+13888+14016+14144+14272+14400+14528+14656+14784+14912+15040+15168+15296+15424+15552+15680+15808+15936+16064+16192+16320+16448+16576+16704+16832+16960+17088+17216+17344+17472+17600+17728+17856+17984+18112+18240+18368+18496+18624+18752+18880+19008+19136+19264+19392+19520+19648+19776+19904+20032+20160+20288+20416+20544+20672+20800+20928+21056+21184+21312+21440+21568+21696+21824+21952+22080+22208+22336+22464+22592+22720+22848+22976+23104+23232+23360+23488+23616+23744+23872+24000+24128+24256+24384+24512+24640+24768+24896+25024+25152+25280+25408+25536+25664+25792+25920+26048+26176+26304+26432+26560+26688+26816+26944+27072+27200+27328+27456+27584+27712+27840+27968+28096+28224+28352+28480+28608+28736+28864+28992+29120+29248+29376+29504+29632+29760+29888+30016+30144+30272+30400+30528+30656+30784+30912+31040+31168+31296+31424+31552+31680+31808+31936+32064+32192+32320+32448+32576+32704,65+193+321+449+577+705+833+961+1089+1217+1345+1473+1601+1729+1857+1985+2113+2241+2369+2497+2625+2753+2881+3009+3137+3265+3393+3521+3649+3777+3905+4033+4161+4289+4417+4545+4673+4801+4929+5057+5185+5313+5441+5569+5697+5825+5953+6081+6209+6337+6465+6593+6721+6849+6977+7105+7233+7361+7489+7617+7745+7873+8001+8129+8257+8385+8513+8641+8769+8897+9025+9153+9281+9409+9537+9665+9793+9921+10049+10177+10305+10433+10561+10689+10817+10945+11073+11201+11329+11457+11585+11713+11841+11969+12097+12225+12353+12481+12609+12737+12865+12993+13121+13249+13377+13505+13633+13761+13889+14017+14145+14273+14401+14529+14657+14785+14913+15041+15169+15297+15425+15553+15681+15809+15937+16065+16193+16321+16449+16577+16705+16833+16961+17089+17217+17345+17473+17601+17729+17857+17985+18113+18241+18369+18497+18625+18753+18881+19009+19137+19265+19393+19521+19649+19777+19905+20033+20161+20289+20417+20545+20673+20801+20929+21057+21185+21313+21441+21569+21697+21825+21953+22081+22209+22337+22465+22593+22721+22849+22977+23105+23233+23361+23489+23617+23745+23873+24001+24129+24257+24385+24513+24641+24769+24897+25025+25153+25281+25409+25537+25665+25793+25921+26049+26177+26305+26433+26561+26689+26817+26945+27073+27201+27329+27457+27585+27713+27841+27969+28097+28225+28353+28481+28609+28737+28865+28993+29121+29249+29377+29505+29633+29761+29889+30017+30145+30273+30401+30529+30657+30785+30913+31041+31169+31297+31425+31553+31681+31809+31937+32065+32193+32321+32449+32577+32705,66+194+322+450+578+706+834+962+1090+1218+1346+1474+1602+1730+1858+1986+2114+2242+2370+2498+2626+2754+2882+3010+3138+3266+3394+3522+3650+3778+3906+4034+4162+4290+4418+4546+4674+4802+4930+5058+5186+5314+5442+5570+5698+5826+5954+6082+6210+6338+6466+6594+6722+6850+6978+7106+7234+7362+7490+7618+7746+7874+8002+8130+8258+8386+8514+8642+8770+8898+9026+9154+9282+9410+9538+9666+9794+9922+10050+10178+10306+10434+10562+10690+10818+10946+11074+11202+11330+11458+11586+11714+11842+11970+12098+12226+12354+12482+12610+12738+12866+12994+13122+13250+13378+13506+13634+13762+13890+14018+14146+14274+14402+14530+14658+14786+14914+15042+15170+15298+15426+15554+15682+15810+15938+16066+16194+16322+16450+16578+16706+16834+16962+17090+17218+17346+17474+17602+17730+17858+17986+18114+18242+18370+18498+18626+18754+18882+19010+19138+19266+19394+19522+19650+19778+19906+20034+20162+20290+20418+20546+20674+20802+20930+21058+21186+21314+21442+21570+21698+21826+21954+22082+22210+22338+22466+22594+22722+22850+22978+23106+23234+23362+23490+23618+23746+23874+24002+24130+24258+24386+24514+24642+24770+24898+25026+25154+25282+25410+25538+25666+25794+25922+26050+26178+26306+26434+26562+26690+26818+26946+27074+27202+27330+27458+27586+27714+27842+27970+28098+28226+28354+28482+28610+28738+28866+28994+29122+29250+29378+29506+29634+29762+29890+30018+30146+30274+30402+30530+30658+30786+30914+31042+31170+31298+31426+31554+31682+31810+31938+32066+32194+32322+32450+32578+32706,67+195+323+451+579+707+835+963+1091+1219+1347+1475+1603+1731+1859+1987+2115+2243+2371+2499+2627+2755+2883+3011+3139+3267+3395+3523+3651+3779+3907+4035+4163+4291+4419+4547+4675+4803+4931+5059+5187+5315+5443+5571+5699+5827+5955+6083+6211+6339+6467+6595+6723+6851+6979+7107+7235+7363+7491+7619+7747+7875+8003+8131+8259+8387+8515+8643+8771+8899+9027+9155+9283+9411+9539+9667+9795+9923+10051+10179+10307+10435+10563+10691+10819+10947+11075+11203+11331+11459+11587+11715+11843+11971+12099+12227+12355+12483+12611+12739+12867+12995+13123+13251+13379+13507+13635+13763+13891+14019+14147+14275+14403+14531+14659+14787+14915+15043+15171+15299+15427+15555+15683+15811+15939+16067+16195+16323+16451+16579+16707+16835+16963+17091+17219+17347+17475+17603+17731+17859+17987+18115+18243+18371+18499+18627+18755+18883+19011+19139+19267+19395+19523+19651+19779+19907+20035+20163+20291+20419+20547+20675+20803+20931+21059+21187+21315+21443+21571+21699+21827+21955+22083+22211+22339+22467+22595+22723+22851+22979+23107+23235+23363+23491+23619+23747+23875+24003+24131+24259+24387+24515+24643+24771+24899+25027+25155+25283+25411+25539+25667+25795+25923+26051+26179+26307+26435+26563+26691+26819+26947+27075+27203+27331+27459+27587+27715+27843+27971+28099+28227+28355+28483+28611+28739+28867+28995+29123+29251+29379+29507+29635+29763+29891+30019+30147+30275+30403+30531+30659+30787+30915+31043+31171+31299+31427+31555+31683+31811+31939+32067+32195+32323+32451+32579+32707,68+196+324+452+580+708+836+964+1092+1220+1348+1476+1604+1732+1860+1988+2116+2244+2372+2500+2628+2756+2884+3012+3140+3268+3396+3524+3652+3780+3908+4036+4164+4292+4420+4548+4676+4804+4932+5060+5188+5316+5444+5572+5700+5828+5956+6084+6212+6340+6468+6596+6724+6852+6980+7108+7236+7364+7492+7620+7748+7876+8004+8132+8260+8388+8516+8644+8772+8900+9028+9156+9284+9412+9540+9668+9796+9924+10052+10180+10308+10436+10564+10692+10820+10948+11076+11204+11332+11460+11588+11716+11844+11972+12100+12228+12356+12484+12612+12740+12868+12996+13124+13252+13380+13508+13636+13764+13892+14020+14148+14276+14404+14532+14660+14788+14916+15044+15172+15300+15428+15556+15684+15812+15940+16068+16196+16324+16452+16580+16708+16836+16964+17092+17220+17348+17476+17604+17732+17860+17988+18116+18244+18372+18500+18628+18756+18884+19012+19140+19268+19396+19524+19652+19780+19908+20036+20164+20292+20420+20548+20676+20804+20932+21060+21188+21316+21444+21572+21700+21828+21956+22084+22212+22340+22468+22596+22724+22852+22980+23108+23236+23364+23492+23620+23748+23876+24004+24132+24260+24388+24516+24644+24772+24900+25028+25156+25284+25412+25540+25668+25796+25924+26052+26180+26308+26436+26564+26692+26820+26948+27076+27204+27332+27460+27588+27716+27844+27972+28100+28228+28356+28484+28612+28740+28868+28996+29124+29252+29380+29508+29636+29764+29892+30020+30148+30276+30404+30532+30660+30788+30916+31044+31172+31300+31428+31556+31684+31812+31940+32068+32196+32324+32452+32580+32708,69+197+325+453+581+709+837+965+1093+1221+1349+1477+1605+1733+1861+1989+2117+2245+2373+2501+2629+2757+2885+3013+3141+3269+3397+3525+3653+3781+3909+4037+4165+4293+4421+4549+4677+4805+4933+5061+5189+5317+5445+5573+5701+5829+5957+6085+6213+6341+6469+6597+6725+6853+6981+7109+7237+7365+7493+7621+7749+7877+8005+8133+8261+8389+8517+8645+8773+8901+9029+9157+9285+9413+9541+9669+9797+9925+10053+10181+10309+10437+10565+10693+10821+10949+11077+11205+11333+11461+11589+11717+11845+11973+12101+12229+12357+12485+12613+12741+12869+12997+13125+13253+13381+13509+13637+13765+13893+14021+14149+14277+14405+14533+14661+14789+14917+15045+15173+15301+15429+15557+15685+15813+15941+16069+16197+16325+16453+16581+16709+16837+16965+17093+17221+17349+17477+17605+17733+17861+17989+18117+18245+18373+18501+18629+18757+18885+19013+19141+19269+19397+19525+19653+19781+19909+20037+20165+20293+20421+20549+20677+20805+20933+21061+21189+21317+21445+21573+21701+21829+21957+22085+22213+22341+22469+22597+22725+22853+22981+23109+23237+23365+23493+23621+23749+23877+24005+24133+24261+24389+24517+24645+24773+24901+25029+25157+25285+25413+25541+25669+25797+25925+26053+26181+26309+26437+26565+26693+26821+26949+27077+27205+27333+27461+27589+27717+27845+27973+28101+28229+28357+28485+28613+28741+28869+28997+29125+29253+29381+29509+29637+29765+29893+30021+30149+30277+30405+30533+30661+30789+30917+31045+31173+31301+31429+31557+31685+31813+31941+32069+32197+32325+32453+32581+32709,70+198+326+454+582+710+838+966+1094+1222+1350+1478+1606+1734+1862+1990+2118+2246+2374+2502+2630+2758+2886+3014+3142+3270+3398+3526+3654+3782+3910+4038+4166+4294+4422+4550+4678+4806+4934+5062+5190+5318+5446+5574+5702+5830+5958+6086+6214+6342+6470+6598+6726+6854+6982+7110+7238+7366+7494+7622+7750+7878+8006+8134+8262+8390+8518+8646+8774+8902+9030+9158+9286+9414+9542+9670+9798+9926+10054+10182+10310+10438+10566+10694+10822+10950+11078+11206+11334+11462+11590+11718+11846+11974+12102+12230+12358+12486+12614+12742+12870+12998+13126+13254+13382+13510+13638+13766+13894+14022+14150+14278+14406+14534+14662+14790+14918+15046+15174+15302+15430+15558+15686+15814+15942+16070+16198+16326+16454+16582+16710+16838+16966+17094+17222+17350+17478+17606+17734+17862+17990+18118+18246+18374+18502+18630+18758+18886+19014+19142+19270+19398+19526+19654+19782+19910+20038+20166+20294+20422+20550+20678+20806+20934+21062+21190+21318+21446+21574+21702+21830+21958+22086+22214+22342+22470+22598+22726+22854+22982+23110+23238+23366+23494+23622+23750+23878+24006+24134+24262+24390+24518+24646+24774+24902+25030+25158+25286+25414+25542+25670+25798+25926+26054+26182+26310+26438+26566+26694+26822+26950+27078+27206+27334+27462+27590+27718+27846+27974+28102+28230+28358+28486+28614+28742+28870+28998+29126+29254+29382+29510+29638+29766+29894+30022+30150+30278+30406+30534+30662+30790+30918+31046+31174+31302+31430+31558+31686+31814+31942+32070+32198+32326+32454+32582+32710,71+199+327+455+583+711+839+967+1095+1223+1351+1479+1607+1735+1863+1991+2119+2247+2375+2503+2631+2759+2887+3015+3143+3271+3399+3527+3655+3783+3911+4039+4167+4295+4423+4551+4679+4807+4935+5063+5191+5319+5447+5575+5703+5831+5959+6087+6215+6343+6471+6599+6727+6855+6983+7111+7239+7367+7495+7623+7751+7879+8007+8135+8263+8391+8519+8647+8775+8903+9031+9159+9287+9415+9543+9671+9799+9927+10055+10183+10311+10439+10567+10695+10823+10951+11079+11207+11335+11463+11591+11719+11847+11975+12103+12231+12359+12487+12615+12743+12871+12999+13127+13255+13383+13511+13639+13767+13895+14023+14151+14279+14407+14535+14663+14791+14919+15047+15175+15303+15431+15559+15687+15815+15943+16071+16199+16327+16455+16583+16711+16839+16967+17095+17223+17351+17479+17607+17735+17863+17991+18119+18247+18375+18503+18631+18759+18887+19015+19143+19271+19399+19527+19655+19783+19911+20039+20167+20295+20423+20551+20679+20807+20935+21063+21191+21319+21447+21575+21703+21831+21959+22087+22215+22343+22471+22599+22727+22855+22983+23111+23239+23367+23495+23623+23751+23879+24007+24135+24263+24391+24519+24647+24775+24903+25031+25159+25287+25415+25543+25671+25799+25927+26055+26183+26311+26439+26567+26695+26823+26951+27079+27207+27335+27463+27591+27719+27847+27975+28103+28231+28359+28487+28615+28743+28871+28999+29127+29255+29383+29511+29639+29767+29895+30023+30151+30279+30407+30535+30663+30791+30919+31047+31175+31303+31431+31559+31687+31815+31943+32071+32199+32327+32455+32583+32711,72+200+328+456+584+712+840+968+1096+1224+1352+1480+1608+1736+1864+1992+2120+2248+2376+2504+2632+2760+2888+3016+3144+3272+3400+3528+3656+3784+3912+4040+4168+4296+4424+4552+4680+4808+4936+5064+5192+5320+5448+5576+5704+5832+5960+6088+6216+6344+6472+6600+6728+6856+6984+7112+7240+7368+7496+7624+7752+7880+8008+8136+8264+8392+8520+8648+8776+8904+9032+9160+9288+9416+9544+9672+9800+9928+10056+10184+10312+10440+10568+10696+10824+10952+11080+11208+11336+11464+11592+11720+11848+11976+12104+12232+12360+12488+12616+12744+12872+13000+13128+13256+13384+13512+13640+13768+13896+14024+14152+14280+14408+14536+14664+14792+14920+15048+15176+15304+15432+15560+15688+15816+15944+16072+16200+16328+16456+16584+16712+16840+16968+17096+17224+17352+17480+17608+17736+17864+17992+18120+18248+18376+18504+18632+18760+18888+19016+19144+19272+19400+19528+19656+19784+19912+20040+20168+20296+20424+20552+20680+20808+20936+21064+21192+21320+21448+21576+21704+21832+21960+22088+22216+22344+22472+22600+22728+22856+22984+23112+23240+23368+23496+23624+23752+23880+24008+24136+24264+24392+24520+24648+24776+24904+25032+25160+25288+25416+25544+25672+25800+25928+26056+26184+26312+26440+26568+26696+26824+26952+27080+27208+27336+27464+27592+27720+27848+27976+28104+28232+28360+28488+28616+28744+28872+29000+29128+29256+29384+29512+29640+29768+29896+30024+30152+30280+30408+30536+30664+30792+30920+31048+31176+31304+31432+31560+31688+31816+31944+32072+32200+32328+32456+32584+32712,73+201+329+457+585+713+841+969+1097+1225+1353+1481+1609+1737+1865+1993+2121+2249+2377+2505+2633+2761+2889+3017+3145+3273+3401+3529+3657+3785+3913+4041+4169+4297+4425+4553+4681+4809+4937+5065+5193+5321+5449+5577+5705+5833+5961+6089+6217+6345+6473+6601+6729+6857+6985+7113+7241+7369+7497+7625+7753+7881+8009+8137+8265+8393+8521+8649+8777+8905+9033+9161+9289+9417+9545+9673+9801+9929+10057+10185+10313+10441+10569+10697+10825+10953+11081+11209+11337+11465+11593+11721+11849+11977+12105+12233+12361+12489+12617+12745+12873+13001+13129+13257+13385+13513+13641+13769+13897+14025+14153+14281+14409+14537+14665+14793+14921+15049+15177+15305+15433+15561+15689+15817+15945+16073+16201+16329+16457+16585+16713+16841+16969+17097+17225+17353+17481+17609+17737+17865+17993+18121+18249+18377+18505+18633+18761+18889+19017+19145+19273+19401+19529+19657+19785+19913+20041+20169+20297+20425+20553+20681+20809+20937+21065+21193+21321+21449+21577+21705+21833+21961+22089+22217+22345+22473+22601+22729+22857+22985+23113+23241+23369+23497+23625+23753+23881+24009+24137+24265+24393+24521+24649+24777+24905+25033+25161+25289+25417+25545+25673+25801+25929+26057+26185+26313+26441+26569+26697+26825+26953+27081+27209+27337+27465+27593+27721+27849+27977+28105+28233+28361+28489+28617+28745+28873+29001+29129+29257+29385+29513+29641+29769+29897+30025+30153+30281+30409+30537+30665+30793+30921+31049+31177+31305+31433+31561+31689+31817+31945+32073+32201+32329+32457+32585+32713,74+202+330+458+586+714+842+970+1098+1226+1354+1482+1610+1738+1866+1994+2122+2250+2378+2506+2634+2762+2890+3018+3146+3274+3402+3530+3658+3786+3914+4042+4170+4298+4426+4554+4682+4810+4938+5066+5194+5322+5450+5578+5706+5834+5962+6090+6218+6346+6474+6602+6730+6858+6986+7114+7242+7370+7498+7626+7754+7882+8010+8138+8266+8394+8522+8650+8778+8906+9034+9162+9290+9418+9546+9674+9802+9930+10058+10186+10314+10442+10570+10698+10826+10954+11082+11210+11338+11466+11594+11722+11850+11978+12106+12234+12362+12490+12618+12746+12874+13002+13130+13258+13386+13514+13642+13770+13898+14026+14154+14282+14410+14538+14666+14794+14922+15050+15178+15306+15434+15562+15690+15818+15946+16074+16202+16330+16458+16586+16714+16842+16970+17098+17226+17354+17482+17610+17738+17866+17994+18122+18250+18378+18506+18634+18762+18890+19018+19146+19274+19402+19530+19658+19786+19914+20042+20170+20298+20426+20554+20682+20810+20938+21066+21194+21322+21450+21578+21706+21834+21962+22090+22218+22346+22474+22602+22730+22858+22986+23114+23242+23370+23498+23626+23754+23882+24010+24138+24266+24394+24522+24650+24778+24906+25034+25162+25290+25418+25546+25674+25802+25930+26058+26186+26314+26442+26570+26698+26826+26954+27082+27210+27338+27466+27594+27722+27850+27978+28106+28234+28362+28490+28618+28746+28874+29002+29130+29258+29386+29514+29642+29770+29898+30026+30154+30282+30410+30538+30666+30794+30922+31050+31178+31306+31434+31562+31690+31818+31946+32074+32202+32330+32458+32586+32714,75+203+331+459+587+715+843+971+1099+1227+1355+1483+1611+1739+1867+1995+2123+2251+2379+2507+2635+2763+2891+3019+3147+3275+3403+3531+3659+3787+3915+4043+4171+4299+4427+4555+4683+4811+4939+5067+5195+5323+5451+5579+5707+5835+5963+6091+6219+6347+6475+6603+6731+6859+6987+7115+7243+7371+7499+7627+7755+7883+8011+8139+8267+8395+8523+8651+8779+8907+9035+9163+9291+9419+9547+9675+9803+9931+10059+10187+10315+10443+10571+10699+10827+10955+11083+11211+11339+11467+11595+11723+11851+11979+12107+12235+12363+12491+12619+12747+12875+13003+13131+13259+13387+13515+13643+13771+13899+14027+14155+14283+14411+14539+14667+14795+14923+15051+15179+15307+15435+15563+15691+15819+15947+16075+16203+16331+16459+16587+16715+16843+16971+17099+17227+17355+17483+17611+17739+17867+17995+18123+18251+18379+18507+18635+18763+18891+19019+19147+19275+19403+19531+19659+19787+19915+20043+20171+20299+20427+20555+20683+20811+20939+21067+21195+21323+21451+21579+21707+21835+21963+22091+22219+22347+22475+22603+22731+22859+22987+23115+23243+23371+23499+23627+23755+23883+24011+24139+24267+24395+24523+24651+24779+24907+25035+25163+25291+25419+25547+25675+25803+25931+26059+26187+26315+26443+26571+26699+26827+26955+27083+27211+27339+27467+27595+27723+27851+27979+28107+28235+28363+28491+28619+28747+28875+29003+29131+29259+29387+29515+29643+29771+29899+30027+30155+30283+30411+30539+30667+30795+30923+31051+31179+31307+31435+31563+31691+31819+31947+32075+32203+32331+32459+32587+32715,76+204+332+460+588+716+844+972+1100+1228+1356+1484+1612+1740+1868+1996+2124+2252+2380+2508+2636+2764+2892+3020+3148+3276+3404+3532+3660+3788+3916+4044+4172+4300+4428+4556+4684+4812+4940+5068+5196+5324+5452+5580+5708+5836+5964+6092+6220+6348+6476+6604+6732+6860+6988+7116+7244+7372+7500+7628+7756+7884+8012+8140+8268+8396+8524+8652+8780+8908+9036+9164+9292+9420+9548+9676+9804+9932+10060+10188+10316+10444+10572+10700+10828+10956+11084+11212+11340+11468+11596+11724+11852+11980+12108+12236+12364+12492+12620+12748+12876+13004+13132+13260+13388+13516+13644+13772+13900+14028+14156+14284+14412+14540+14668+14796+14924+15052+15180+15308+15436+15564+15692+15820+15948+16076+16204+16332+16460+16588+16716+16844+16972+17100+17228+17356+17484+17612+17740+17868+17996+18124+18252+18380+18508+18636+18764+18892+19020+19148+19276+19404+19532+19660+19788+19916+20044+20172+20300+20428+20556+20684+20812+20940+21068+21196+21324+21452+21580+21708+21836+21964+22092+22220+22348+22476+22604+22732+22860+22988+23116+23244+23372+23500+23628+23756+23884+24012+24140+24268+24396+24524+24652+24780+24908+25036+25164+25292+25420+25548+25676+25804+25932+26060+26188+26316+26444+26572+26700+26828+26956+27084+27212+27340+27468+27596+27724+27852+27980+28108+28236+28364+28492+28620+28748+28876+29004+29132+29260+29388+29516+29644+29772+29900+30028+30156+30284+30412+30540+30668+30796+30924+31052+31180+31308+31436+31564+31692+31820+31948+32076+32204+32332+32460+32588+32716,77+205+333+461+589+717+845+973+1101+1229+1357+1485+1613+1741+1869+1997+2125+2253+2381+2509+2637+2765+2893+3021+3149+3277+3405+3533+3661+3789+3917+4045+4173+4301+4429+4557+4685+4813+4941+5069+5197+5325+5453+5581+5709+5837+5965+6093+6221+6349+6477+6605+6733+6861+6989+7117+7245+7373+7501+7629+7757+7885+8013+8141+8269+8397+8525+8653+8781+8909+9037+9165+9293+9421+9549+9677+9805+9933+10061+10189+10317+10445+10573+10701+10829+10957+11085+11213+11341+11469+11597+11725+11853+11981+12109+12237+12365+12493+12621+12749+12877+13005+13133+13261+13389+13517+13645+13773+13901+14029+14157+14285+14413+14541+14669+14797+14925+15053+15181+15309+15437+15565+15693+15821+15949+16077+16205+16333+16461+16589+16717+16845+16973+17101+17229+17357+17485+17613+17741+17869+17997+18125+18253+18381+18509+18637+18765+18893+19021+19149+19277+19405+19533+19661+19789+19917+20045+20173+20301+20429+20557+20685+20813+20941+21069+21197+21325+21453+21581+21709+21837+21965+22093+22221+22349+22477+22605+22733+22861+22989+23117+23245+23373+23501+23629+23757+23885+24013+24141+24269+24397+24525+24653+24781+24909+25037+25165+25293+25421+25549+25677+25805+25933+26061+26189+26317+26445+26573+26701+26829+26957+27085+27213+27341+27469+27597+27725+27853+27981+28109+28237+28365+28493+28621+28749+28877+29005+29133+29261+29389+29517+29645+29773+29901+30029+30157+30285+30413+30541+30669+30797+30925+31053+31181+31309+31437+31565+31693+31821+31949+32077+32205+32333+32461+32589+32717,78+206+334+462+590+718+846+974+1102+1230+1358+1486+1614+1742+1870+1998+2126+2254+2382+2510+2638+2766+2894+3022+3150+3278+3406+3534+3662+3790+3918+4046+4174+4302+4430+4558+4686+4814+4942+5070+5198+5326+5454+5582+5710+5838+5966+6094+6222+6350+6478+6606+6734+6862+6990+7118+7246+7374+7502+7630+7758+7886+8014+8142+8270+8398+8526+8654+8782+8910+9038+9166+9294+9422+9550+9678+9806+9934+10062+10190+10318+10446+10574+10702+10830+10958+11086+11214+11342+11470+11598+11726+11854+11982+12110+12238+12366+12494+12622+12750+12878+13006+13134+13262+13390+13518+13646+13774+13902+14030+14158+14286+14414+14542+14670+14798+14926+15054+15182+15310+15438+15566+15694+15822+15950+16078+16206+16334+16462+16590+16718+16846+16974+17102+17230+17358+17486+17614+17742+17870+17998+18126+18254+18382+18510+18638+18766+18894+19022+19150+19278+19406+19534+19662+19790+19918+20046+20174+20302+20430+20558+20686+20814+20942+21070+21198+21326+21454+21582+21710+21838+21966+22094+22222+22350+22478+22606+22734+22862+22990+23118+23246+23374+23502+23630+23758+23886+24014+24142+24270+24398+24526+24654+24782+24910+25038+25166+25294+25422+25550+25678+25806+25934+26062+26190+26318+26446+26574+26702+26830+26958+27086+27214+27342+27470+27598+27726+27854+27982+28110+28238+28366+28494+28622+28750+28878+29006+29134+29262+29390+29518+29646+29774+29902+30030+30158+30286+30414+30542+30670+30798+30926+31054+31182+31310+31438+31566+31694+31822+31950+32078+32206+32334+32462+32590+32718,79+207+335+463+591+719+847+975+1103+1231+1359+1487+1615+1743+1871+1999+2127+2255+2383+2511+2639+2767+2895+3023+3151+3279+3407+3535+3663+3791+3919+4047+4175+4303+4431+4559+4687+4815+4943+5071+5199+5327+5455+5583+5711+5839+5967+6095+6223+6351+6479+6607+6735+6863+6991+7119+7247+7375+7503+7631+7759+7887+8015+8143+8271+8399+8527+8655+8783+8911+9039+9167+9295+9423+9551+9679+9807+9935+10063+10191+10319+10447+10575+10703+10831+10959+11087+11215+11343+11471+11599+11727+11855+11983+12111+12239+12367+12495+12623+12751+12879+13007+13135+13263+13391+13519+13647+13775+13903+14031+14159+14287+14415+14543+14671+14799+14927+15055+15183+15311+15439+15567+15695+15823+15951+16079+16207+16335+16463+16591+16719+16847+16975+17103+17231+17359+17487+17615+17743+17871+17999+18127+18255+18383+18511+18639+18767+18895+19023+19151+19279+19407+19535+19663+19791+19919+20047+20175+20303+20431+20559+20687+20815+20943+21071+21199+21327+21455+21583+21711+21839+21967+22095+22223+22351+22479+22607+22735+22863+22991+23119+23247+23375+23503+23631+23759+23887+24015+24143+24271+24399+24527+24655+24783+24911+25039+25167+25295+25423+25551+25679+25807+25935+26063+26191+26319+26447+26575+26703+26831+26959+27087+27215+27343+27471+27599+27727+27855+27983+28111+28239+28367+28495+28623+28751+28879+29007+29135+29263+29391+29519+29647+29775+29903+30031+30159+30287+30415+30543+30671+30799+30927+31055+31183+31311+31439+31567+31695+31823+31951+32079+32207+32335+32463+32591+32719,80+208+336+464+592+720+848+976+1104+1232+1360+1488+1616+1744+1872+2000+2128+2256+2384+2512+2640+2768+2896+3024+3152+3280+3408+3536+3664+3792+3920+4048+4176+4304+4432+4560+4688+4816+4944+5072+5200+5328+5456+5584+5712+5840+5968+6096+6224+6352+6480+6608+6736+6864+6992+7120+7248+7376+7504+7632+7760+7888+8016+8144+8272+8400+8528+8656+8784+8912+9040+9168+9296+9424+9552+9680+9808+9936+10064+10192+10320+10448+10576+10704+10832+10960+11088+11216+11344+11472+11600+11728+11856+11984+12112+12240+12368+12496+12624+12752+12880+13008+13136+13264+13392+13520+13648+13776+13904+14032+14160+14288+14416+14544+14672+14800+14928+15056+15184+15312+15440+15568+15696+15824+15952+16080+16208+16336+16464+16592+16720+16848+16976+17104+17232+17360+17488+17616+17744+17872+18000+18128+18256+18384+18512+18640+18768+18896+19024+19152+19280+19408+19536+19664+19792+19920+20048+20176+20304+20432+20560+20688+20816+20944+21072+21200+21328+21456+21584+21712+21840+21968+22096+22224+22352+22480+22608+22736+22864+22992+23120+23248+23376+23504+23632+23760+23888+24016+24144+24272+24400+24528+24656+24784+24912+25040+25168+25296+25424+25552+25680+25808+25936+26064+26192+26320+26448+26576+26704+26832+26960+27088+27216+27344+27472+27600+27728+27856+27984+28112+28240+28368+28496+28624+28752+28880+29008+29136+29264+29392+29520+29648+29776+29904+30032+30160+30288+30416+30544+30672+30800+30928+31056+31184+31312+31440+31568+31696+31824+31952+32080+32208+32336+32464+32592+32720,81+209+337+465+593+721+849+977+1105+1233+1361+1489+1617+1745+1873+2001+2129+2257+2385+2513+2641+2769+2897+3025+3153+3281+3409+3537+3665+3793+3921+4049+4177+4305+4433+4561+4689+4817+4945+5073+5201+5329+5457+5585+5713+5841+5969+6097+6225+6353+6481+6609+6737+6865+6993+7121+7249+7377+7505+7633+7761+7889+8017+8145+8273+8401+8529+8657+8785+8913+9041+9169+9297+9425+9553+9681+9809+9937+10065+10193+10321+10449+10577+10705+10833+10961+11089+11217+11345+11473+11601+11729+11857+11985+12113+12241+12369+12497+12625+12753+12881+13009+13137+13265+13393+13521+13649+13777+13905+14033+14161+14289+14417+14545+14673+14801+14929+15057+15185+15313+15441+15569+15697+15825+15953+16081+16209+16337+16465+16593+16721+16849+16977+17105+17233+17361+17489+17617+17745+17873+18001+18129+18257+18385+18513+18641+18769+18897+19025+19153+19281+19409+19537+19665+19793+19921+20049+20177+20305+20433+20561+20689+20817+20945+21073+21201+21329+21457+21585+21713+21841+21969+22097+22225+22353+22481+22609+22737+22865+22993+23121+23249+23377+23505+23633+23761+23889+24017+24145+24273+24401+24529+24657+24785+24913+25041+25169+25297+25425+25553+25681+25809+25937+26065+26193+26321+26449+26577+26705+26833+26961+27089+27217+27345+27473+27601+27729+27857+27985+28113+28241+28369+28497+28625+28753+28881+29009+29137+29265+29393+29521+29649+29777+29905+30033+30161+30289+30417+30545+30673+30801+30929+31057+31185+31313+31441+31569+31697+31825+31953+32081+32209+32337+32465+32593+32721,82+210+338+466+594+722+850+978+1106+1234+1362+1490+1618+1746+1874+2002+2130+2258+2386+2514+2642+2770+2898+3026+3154+3282+3410+3538+3666+3794+3922+4050+4178+4306+4434+4562+4690+4818+4946+5074+5202+5330+5458+5586+5714+5842+5970+6098+6226+6354+6482+6610+6738+6866+6994+7122+7250+7378+7506+7634+7762+7890+8018+8146+8274+8402+8530+8658+8786+8914+9042+9170+9298+9426+9554+9682+9810+9938+10066+10194+10322+10450+10578+10706+10834+10962+11090+11218+11346+11474+11602+11730+11858+11986+12114+12242+12370+12498+12626+12754+12882+13010+13138+13266+13394+13522+13650+13778+13906+14034+14162+14290+14418+14546+14674+14802+14930+15058+15186+15314+15442+15570+15698+15826+15954+16082+16210+16338+16466+16594+16722+16850+16978+17106+17234+17362+17490+17618+17746+17874+18002+18130+18258+18386+18514+18642+18770+18898+19026+19154+19282+19410+19538+19666+19794+19922+20050+20178+20306+20434+20562+20690+20818+20946+21074+21202+21330+21458+21586+21714+21842+21970+22098+22226+22354+22482+22610+22738+22866+22994+23122+23250+23378+23506+23634+23762+23890+24018+24146+24274+24402+24530+24658+24786+24914+25042+25170+25298+25426+25554+25682+25810+25938+26066+26194+26322+26450+26578+26706+26834+26962+27090+27218+27346+27474+27602+27730+27858+27986+28114+28242+28370+28498+28626+28754+28882+29010+29138+29266+29394+29522+29650+29778+29906+30034+30162+30290+30418+30546+30674+30802+30930+31058+31186+31314+31442+31570+31698+31826+31954+32082+32210+32338+32466+32594+32722,83+211+339+467+595+723+851+979+1107+1235+1363+1491+1619+1747+1875+2003+2131+2259+2387+2515+2643+2771+2899+3027+3155+3283+3411+3539+3667+3795+3923+4051+4179+4307+4435+4563+4691+4819+4947+5075+5203+5331+5459+5587+5715+5843+5971+6099+6227+6355+6483+6611+6739+6867+6995+7123+7251+7379+7507+7635+7763+7891+8019+8147+8275+8403+8531+8659+8787+8915+9043+9171+9299+9427+9555+9683+9811+9939+10067+10195+10323+10451+10579+10707+10835+10963+11091+11219+11347+11475+11603+11731+11859+11987+12115+12243+12371+12499+12627+12755+12883+13011+13139+13267+13395+13523+13651+13779+13907+14035+14163+14291+14419+14547+14675+14803+14931+15059+15187+15315+15443+15571+15699+15827+15955+16083+16211+16339+16467+16595+16723+16851+16979+17107+17235+17363+17491+17619+17747+17875+18003+18131+18259+18387+18515+18643+18771+18899+19027+19155+19283+19411+19539+19667+19795+19923+20051+20179+20307+20435+20563+20691+20819+20947+21075+21203+21331+21459+21587+21715+21843+21971+22099+22227+22355+22483+22611+22739+22867+22995+23123+23251+23379+23507+23635+23763+23891+24019+24147+24275+24403+24531+24659+24787+24915+25043+25171+25299+25427+25555+25683+25811+25939+26067+26195+26323+26451+26579+26707+26835+26963+27091+27219+27347+27475+27603+27731+27859+27987+28115+28243+28371+28499+28627+28755+28883+29011+29139+29267+29395+29523+29651+29779+29907+30035+30163+30291+30419+30547+30675+30803+30931+31059+31187+31315+31443+31571+31699+31827+31955+32083+32211+32339+32467+32595+32723,84+212+340+468+596+724+852+980+1108+1236+1364+1492+1620+1748+1876+2004+2132+2260+2388+2516+2644+2772+2900+3028+3156+3284+3412+3540+3668+3796+3924+4052+4180+4308+4436+4564+4692+4820+4948+5076+5204+5332+5460+5588+5716+5844+5972+6100+6228+6356+6484+6612+6740+6868+6996+7124+7252+7380+7508+7636+7764+7892+8020+8148+8276+8404+8532+8660+8788+8916+9044+9172+9300+9428+9556+9684+9812+9940+10068+10196+10324+10452+10580+10708+10836+10964+11092+11220+11348+11476+11604+11732+11860+11988+12116+12244+12372+12500+12628+12756+12884+13012+13140+13268+13396+13524+13652+13780+13908+14036+14164+14292+14420+14548+14676+14804+14932+15060+15188+15316+15444+15572+15700+15828+15956+16084+16212+16340+16468+16596+16724+16852+16980+17108+17236+17364+17492+17620+17748+17876+18004+18132+18260+18388+18516+18644+18772+18900+19028+19156+19284+19412+19540+19668+19796+19924+20052+20180+20308+20436+20564+20692+20820+20948+21076+21204+21332+21460+21588+21716+21844+21972+22100+22228+22356+22484+22612+22740+22868+22996+23124+23252+23380+23508+23636+23764+23892+24020+24148+24276+24404+24532+24660+24788+24916+25044+25172+25300+25428+25556+25684+25812+25940+26068+26196+26324+26452+26580+26708+26836+26964+27092+27220+27348+27476+27604+27732+27860+27988+28116+28244+28372+28500+28628+28756+28884+29012+29140+29268+29396+29524+29652+29780+29908+30036+30164+30292+30420+30548+30676+30804+30932+31060+31188+31316+31444+31572+31700+31828+31956+32084+32212+32340+32468+32596+32724,85+213+341+469+597+725+853+981+1109+1237+1365+1493+1621+1749+1877+2005+2133+2261+2389+2517+2645+2773+2901+3029+3157+3285+3413+3541+3669+3797+3925+4053+4181+4309+4437+4565+4693+4821+4949+5077+5205+5333+5461+5589+5717+5845+5973+6101+6229+6357+6485+6613+6741+6869+6997+7125+7253+7381+7509+7637+7765+7893+8021+8149+8277+8405+8533+8661+8789+8917+9045+9173+9301+9429+9557+9685+9813+9941+10069+10197+10325+10453+10581+10709+10837+10965+11093+11221+11349+11477+11605+11733+11861+11989+12117+12245+12373+12501+12629+12757+12885+13013+13141+13269+13397+13525+13653+13781+13909+14037+14165+14293+14421+14549+14677+14805+14933+15061+15189+15317+15445+15573+15701+15829+15957+16085+16213+16341+16469+16597+16725+16853+16981+17109+17237+17365+17493+17621+17749+17877+18005+18133+18261+18389+18517+18645+18773+18901+19029+19157+19285+19413+19541+19669+19797+19925+20053+20181+20309+20437+20565+20693+20821+20949+21077+21205+21333+21461+21589+21717+21845+21973+22101+22229+22357+22485+22613+22741+22869+22997+23125+23253+23381+23509+23637+23765+23893+24021+24149+24277+24405+24533+24661+24789+24917+25045+25173+25301+25429+25557+25685+25813+25941+26069+26197+26325+26453+26581+26709+26837+26965+27093+27221+27349+27477+27605+27733+27861+27989+28117+28245+28373+28501+28629+28757+28885+29013+29141+29269+29397+29525+29653+29781+29909+30037+30165+30293+30421+30549+30677+30805+30933+31061+31189+31317+31445+31573+31701+31829+31957+32085+32213+32341+32469+32597+32725,86+214+342+470+598+726+854+982+1110+1238+1366+1494+1622+1750+1878+2006+2134+2262+2390+2518+2646+2774+2902+3030+3158+3286+3414+3542+3670+3798+3926+4054+4182+4310+4438+4566+4694+4822+4950+5078+5206+5334+5462+5590+5718+5846+5974+6102+6230+6358+6486+6614+6742+6870+6998+7126+7254+7382+7510+7638+7766+7894+8022+8150+8278+8406+8534+8662+8790+8918+9046+9174+9302+9430+9558+9686+9814+9942+10070+10198+10326+10454+10582+10710+10838+10966+11094+11222+11350+11478+11606+11734+11862+11990+12118+12246+12374+12502+12630+12758+12886+13014+13142+13270+13398+13526+13654+13782+13910+14038+14166+14294+14422+14550+14678+14806+14934+15062+15190+15318+15446+15574+15702+15830+15958+16086+16214+16342+16470+16598+16726+16854+16982+17110+17238+17366+17494+17622+17750+17878+18006+18134+18262+18390+18518+18646+18774+18902+19030+19158+19286+19414+19542+19670+19798+19926+20054+20182+20310+20438+20566+20694+20822+20950+21078+21206+21334+21462+21590+21718+21846+21974+22102+22230+22358+22486+22614+22742+22870+22998+23126+23254+23382+23510+23638+23766+23894+24022+24150+24278+24406+24534+24662+24790+24918+25046+25174+25302+25430+25558+25686+25814+25942+26070+26198+26326+26454+26582+26710+26838+26966+27094+27222+27350+27478+27606+27734+27862+27990+28118+28246+28374+28502+28630+28758+28886+29014+29142+29270+29398+29526+29654+29782+29910+30038+30166+30294+30422+30550+30678+30806+30934+31062+31190+31318+31446+31574+31702+31830+31958+32086+32214+32342+32470+32598+32726,87+215+343+471+599+727+855+983+1111+1239+1367+1495+1623+1751+1879+2007+2135+2263+2391+2519+2647+2775+2903+3031+3159+3287+3415+3543+3671+3799+3927+4055+4183+4311+4439+4567+4695+4823+4951+5079+5207+5335+5463+5591+5719+5847+5975+6103+6231+6359+6487+6615+6743+6871+6999+7127+7255+7383+7511+7639+7767+7895+8023+8151+8279+8407+8535+8663+8791+8919+9047+9175+9303+9431+9559+9687+9815+9943+10071+10199+10327+10455+10583+10711+10839+10967+11095+11223+11351+11479+11607+11735+11863+11991+12119+12247+12375+12503+12631+12759+12887+13015+13143+13271+13399+13527+13655+13783+13911+14039+14167+14295+14423+14551+14679+14807+14935+15063+15191+15319+15447+15575+15703+15831+15959+16087+16215+16343+16471+16599+16727+16855+16983+17111+17239+17367+17495+17623+17751+17879+18007+18135+18263+18391+18519+18647+18775+18903+19031+19159+19287+19415+19543+19671+19799+19927+20055+20183+20311+20439+20567+20695+20823+20951+21079+21207+21335+21463+21591+21719+21847+21975+22103+22231+22359+22487+22615+22743+22871+22999+23127+23255+23383+23511+23639+23767+23895+24023+24151+24279+24407+24535+24663+24791+24919+25047+25175+25303+25431+25559+25687+25815+25943+26071+26199+26327+26455+26583+26711+26839+26967+27095+27223+27351+27479+27607+27735+27863+27991+28119+28247+28375+28503+28631+28759+28887+29015+29143+29271+29399+29527+29655+29783+29911+30039+30167+30295+30423+30551+30679+30807+30935+31063+31191+31319+31447+31575+31703+31831+31959+32087+32215+32343+32471+32599+32727,88+216+344+472+600+728+856+984+1112+1240+1368+1496+1624+1752+1880+2008+2136+2264+2392+2520+2648+2776+2904+3032+3160+3288+3416+3544+3672+3800+3928+4056+4184+4312+4440+4568+4696+4824+4952+5080+5208+5336+5464+5592+5720+5848+5976+6104+6232+6360+6488+6616+6744+6872+7000+7128+7256+7384+7512+7640+7768+7896+8024+8152+8280+8408+8536+8664+8792+8920+9048+9176+9304+9432+9560+9688+9816+9944+10072+10200+10328+10456+10584+10712+10840+10968+11096+11224+11352+11480+11608+11736+11864+11992+12120+12248+12376+12504+12632+12760+12888+13016+13144+13272+13400+13528+13656+13784+13912+14040+14168+14296+14424+14552+14680+14808+14936+15064+15192+15320+15448+15576+15704+15832+15960+16088+16216+16344+16472+16600+16728+16856+16984+17112+17240+17368+17496+17624+17752+17880+18008+18136+18264+18392+18520+18648+18776+18904+19032+19160+19288+19416+19544+19672+19800+19928+20056+20184+20312+20440+20568+20696+20824+20952+21080+21208+21336+21464+21592+21720+21848+21976+22104+22232+22360+22488+22616+22744+22872+23000+23128+23256+23384+23512+23640+23768+23896+24024+24152+24280+24408+24536+24664+24792+24920+25048+25176+25304+25432+25560+25688+25816+25944+26072+26200+26328+26456+26584+26712+26840+26968+27096+27224+27352+27480+27608+27736+27864+27992+28120+28248+28376+28504+28632+28760+28888+29016+29144+29272+29400+29528+29656+29784+29912+30040+30168+30296+30424+30552+30680+30808+30936+31064+31192+31320+31448+31576+31704+31832+31960+32088+32216+32344+32472+32600+32728,89+217+345+473+601+729+857+985+1113+1241+1369+1497+1625+1753+1881+2009+2137+2265+2393+2521+2649+2777+2905+3033+3161+3289+3417+3545+3673+3801+3929+4057+4185+4313+4441+4569+4697+4825+4953+5081+5209+5337+5465+5593+5721+5849+5977+6105+6233+6361+6489+6617+6745+6873+7001+7129+7257+7385+7513+7641+7769+7897+8025+8153+8281+8409+8537+8665+8793+8921+9049+9177+9305+9433+9561+9689+9817+9945+10073+10201+10329+10457+10585+10713+10841+10969+11097+11225+11353+11481+11609+11737+11865+11993+12121+12249+12377+12505+12633+12761+12889+13017+13145+13273+13401+13529+13657+13785+13913+14041+14169+14297+14425+14553+14681+14809+14937+15065+15193+15321+15449+15577+15705+15833+15961+16089+16217+16345+16473+16601+16729+16857+16985+17113+17241+17369+17497+17625+17753+17881+18009+18137+18265+18393+18521+18649+18777+18905+19033+19161+19289+19417+19545+19673+19801+19929+20057+20185+20313+20441+20569+20697+20825+20953+21081+21209+21337+21465+21593+21721+21849+21977+22105+22233+22361+22489+22617+22745+22873+23001+23129+23257+23385+23513+23641+23769+23897+24025+24153+24281+24409+24537+24665+24793+24921+25049+25177+25305+25433+25561+25689+25817+25945+26073+26201+26329+26457+26585+26713+26841+26969+27097+27225+27353+27481+27609+27737+27865+27993+28121+28249+28377+28505+28633+28761+28889+29017+29145+29273+29401+29529+29657+29785+29913+30041+30169+30297+30425+30553+30681+30809+30937+31065+31193+31321+31449+31577+31705+31833+31961+32089+32217+32345+32473+32601+32729,90+218+346+474+602+730+858+986+1114+1242+1370+1498+1626+1754+1882+2010+2138+2266+2394+2522+2650+2778+2906+3034+3162+3290+3418+3546+3674+3802+3930+4058+4186+4314+4442+4570+4698+4826+4954+5082+5210+5338+5466+5594+5722+5850+5978+6106+6234+6362+6490+6618+6746+6874+7002+7130+7258+7386+7514+7642+7770+7898+8026+8154+8282+8410+8538+8666+8794+8922+9050+9178+9306+9434+9562+9690+9818+9946+10074+10202+10330+10458+10586+10714+10842+10970+11098+11226+11354+11482+11610+11738+11866+11994+12122+12250+12378+12506+12634+12762+12890+13018+13146+13274+13402+13530+13658+13786+13914+14042+14170+14298+14426+14554+14682+14810+14938+15066+15194+15322+15450+15578+15706+15834+15962+16090+16218+16346+16474+16602+16730+16858+16986+17114+17242+17370+17498+17626+17754+17882+18010+18138+18266+18394+18522+18650+18778+18906+19034+19162+19290+19418+19546+19674+19802+19930+20058+20186+20314+20442+20570+20698+20826+20954+21082+21210+21338+21466+21594+21722+21850+21978+22106+22234+22362+22490+22618+22746+22874+23002+23130+23258+23386+23514+23642+23770+23898+24026+24154+24282+24410+24538+24666+24794+24922+25050+25178+25306+25434+25562+25690+25818+25946+26074+26202+26330+26458+26586+26714+26842+26970+27098+27226+27354+27482+27610+27738+27866+27994+28122+28250+28378+28506+28634+28762+28890+29018+29146+29274+29402+29530+29658+29786+29914+30042+30170+30298+30426+30554+30682+30810+30938+31066+31194+31322+31450+31578+31706+31834+31962+32090+32218+32346+32474+32602+32730,91+219+347+475+603+731+859+987+1115+1243+1371+1499+1627+1755+1883+2011+2139+2267+2395+2523+2651+2779+2907+3035+3163+3291+3419+3547+3675+3803+3931+4059+4187+4315+4443+4571+4699+4827+4955+5083+5211+5339+5467+5595+5723+5851+5979+6107+6235+6363+6491+6619+6747+6875+7003+7131+7259+7387+7515+7643+7771+7899+8027+8155+8283+8411+8539+8667+8795+8923+9051+9179+9307+9435+9563+9691+9819+9947+10075+10203+10331+10459+10587+10715+10843+10971+11099+11227+11355+11483+11611+11739+11867+11995+12123+12251+12379+12507+12635+12763+12891+13019+13147+13275+13403+13531+13659+13787+13915+14043+14171+14299+14427+14555+14683+14811+14939+15067+15195+15323+15451+15579+15707+15835+15963+16091+16219+16347+16475+16603+16731+16859+16987+17115+17243+17371+17499+17627+17755+17883+18011+18139+18267+18395+18523+18651+18779+18907+19035+19163+19291+19419+19547+19675+19803+19931+20059+20187+20315+20443+20571+20699+20827+20955+21083+21211+21339+21467+21595+21723+21851+21979+22107+22235+22363+22491+22619+22747+22875+23003+23131+23259+23387+23515+23643+23771+23899+24027+24155+24283+24411+24539+24667+24795+24923+25051+25179+25307+25435+25563+25691+25819+25947+26075+26203+26331+26459+26587+26715+26843+26971+27099+27227+27355+27483+27611+27739+27867+27995+28123+28251+28379+28507+28635+28763+28891+29019+29147+29275+29403+29531+29659+29787+29915+30043+30171+30299+30427+30555+30683+30811+30939+31067+31195+31323+31451+31579+31707+31835+31963+32091+32219+32347+32475+32603+32731,92+220+348+476+604+732+860+988+1116+1244+1372+1500+1628+1756+1884+2012+2140+2268+2396+2524+2652+2780+2908+3036+3164+3292+3420+3548+3676+3804+3932+4060+4188+4316+4444+4572+4700+4828+4956+5084+5212+5340+5468+5596+5724+5852+5980+6108+6236+6364+6492+6620+6748+6876+7004+7132+7260+7388+7516+7644+7772+7900+8028+8156+8284+8412+8540+8668+8796+8924+9052+9180+9308+9436+9564+9692+9820+9948+10076+10204+10332+10460+10588+10716+10844+10972+11100+11228+11356+11484+11612+11740+11868+11996+12124+12252+12380+12508+12636+12764+12892+13020+13148+13276+13404+13532+13660+13788+13916+14044+14172+14300+14428+14556+14684+14812+14940+15068+15196+15324+15452+15580+15708+15836+15964+16092+16220+16348+16476+16604+16732+16860+16988+17116+17244+17372+17500+17628+17756+17884+18012+18140+18268+18396+18524+18652+18780+18908+19036+19164+19292+19420+19548+19676+19804+19932+20060+20188+20316+20444+20572+20700+20828+20956+21084+21212+21340+21468+21596+21724+21852+21980+22108+22236+22364+22492+22620+22748+22876+23004+23132+23260+23388+23516+23644+23772+23900+24028+24156+24284+24412+24540+24668+24796+24924+25052+25180+25308+25436+25564+25692+25820+25948+26076+26204+26332+26460+26588+26716+26844+26972+27100+27228+27356+27484+27612+27740+27868+27996+28124+28252+28380+28508+28636+28764+28892+29020+29148+29276+29404+29532+29660+29788+29916+30044+30172+30300+30428+30556+30684+30812+30940+31068+31196+31324+31452+31580+31708+31836+31964+32092+32220+32348+32476+32604+32732,93+221+349+477+605+733+861+989+1117+1245+1373+1501+1629+1757+1885+2013+2141+2269+2397+2525+2653+2781+2909+3037+3165+3293+3421+3549+3677+3805+3933+4061+4189+4317+4445+4573+4701+4829+4957+5085+5213+5341+5469+5597+5725+5853+5981+6109+6237+6365+6493+6621+6749+6877+7005+7133+7261+7389+7517+7645+7773+7901+8029+8157+8285+8413+8541+8669+8797+8925+9053+9181+9309+9437+9565+9693+9821+9949+10077+10205+10333+10461+10589+10717+10845+10973+11101+11229+11357+11485+11613+11741+11869+11997+12125+12253+12381+12509+12637+12765+12893+13021+13149+13277+13405+13533+13661+13789+13917+14045+14173+14301+14429+14557+14685+14813+14941+15069+15197+15325+15453+15581+15709+15837+15965+16093+16221+16349+16477+16605+16733+16861+16989+17117+17245+17373+17501+17629+17757+17885+18013+18141+18269+18397+18525+18653+18781+18909+19037+19165+19293+19421+19549+19677+19805+19933+20061+20189+20317+20445+20573+20701+20829+20957+21085+21213+21341+21469+21597+21725+21853+21981+22109+22237+22365+22493+22621+22749+22877+23005+23133+23261+23389+23517+23645+23773+23901+24029+24157+24285+24413+24541+24669+24797+24925+25053+25181+25309+25437+25565+25693+25821+25949+26077+26205+26333+26461+26589+26717+26845+26973+27101+27229+27357+27485+27613+27741+27869+27997+28125+28253+28381+28509+28637+28765+28893+29021+29149+29277+29405+29533+29661+29789+29917+30045+30173+30301+30429+30557+30685+30813+30941+31069+31197+31325+31453+31581+31709+31837+31965+32093+32221+32349+32477+32605+32733,94+222+350+478+606+734+862+990+1118+1246+1374+1502+1630+1758+1886+2014+2142+2270+2398+2526+2654+2782+2910+3038+3166+3294+3422+3550+3678+3806+3934+4062+4190+4318+4446+4574+4702+4830+4958+5086+5214+5342+5470+5598+5726+5854+5982+6110+6238+6366+6494+6622+6750+6878+7006+7134+7262+7390+7518+7646+7774+7902+8030+8158+8286+8414+8542+8670+8798+8926+9054+9182+9310+9438+9566+9694+9822+9950+10078+10206+10334+10462+10590+10718+10846+10974+11102+11230+11358+11486+11614+11742+11870+11998+12126+12254+12382+12510+12638+12766+12894+13022+13150+13278+13406+13534+13662+13790+13918+14046+14174+14302+14430+14558+14686+14814+14942+15070+15198+15326+15454+15582+15710+15838+15966+16094+16222+16350+16478+16606+16734+16862+16990+17118+17246+17374+17502+17630+17758+17886+18014+18142+18270+18398+18526+18654+18782+18910+19038+19166+19294+19422+19550+19678+19806+19934+20062+20190+20318+20446+20574+20702+20830+20958+21086+21214+21342+21470+21598+21726+21854+21982+22110+22238+22366+22494+22622+22750+22878+23006+23134+23262+23390+23518+23646+23774+23902+24030+24158+24286+24414+24542+24670+24798+24926+25054+25182+25310+25438+25566+25694+25822+25950+26078+26206+26334+26462+26590+26718+26846+26974+27102+27230+27358+27486+27614+27742+27870+27998+28126+28254+28382+28510+28638+28766+28894+29022+29150+29278+29406+29534+29662+29790+29918+30046+30174+30302+30430+30558+30686+30814+30942+31070+31198+31326+31454+31582+31710+31838+31966+32094+32222+32350+32478+32606+32734,95+223+351+479+607+735+863+991+1119+1247+1375+1503+1631+1759+1887+2015+2143+2271+2399+2527+2655+2783+2911+3039+3167+3295+3423+3551+3679+3807+3935+4063+4191+4319+4447+4575+4703+4831+4959+5087+5215+5343+5471+5599+5727+5855+5983+6111+6239+6367+6495+6623+6751+6879+7007+7135+7263+7391+7519+7647+7775+7903+8031+8159+8287+8415+8543+8671+8799+8927+9055+9183+9311+9439+9567+9695+9823+9951+10079+10207+10335+10463+10591+10719+10847+10975+11103+11231+11359+11487+11615+11743+11871+11999+12127+12255+12383+12511+12639+12767+12895+13023+13151+13279+13407+13535+13663+13791+13919+14047+14175+14303+14431+14559+14687+14815+14943+15071+15199+15327+15455+15583+15711+15839+15967+16095+16223+16351+16479+16607+16735+16863+16991+17119+17247+17375+17503+17631+17759+17887+18015+18143+18271+18399+18527+18655+18783+18911+19039+19167+19295+19423+19551+19679+19807+19935+20063+20191+20319+20447+20575+20703+20831+20959+21087+21215+21343+21471+21599+21727+21855+21983+22111+22239+22367+22495+22623+22751+22879+23007+23135+23263+23391+23519+23647+23775+23903+24031+24159+24287+24415+24543+24671+24799+24927+25055+25183+25311+25439+25567+25695+25823+25951+26079+26207+26335+26463+26591+26719+26847+26975+27103+27231+27359+27487+27615+27743+27871+27999+28127+28255+28383+28511+28639+28767+28895+29023+29151+29279+29407+29535+29663+29791+29919+30047+30175+30303+30431+30559+30687+30815+30943+31071+31199+31327+31455+31583+31711+31839+31967+32095+32223+32351+32479+32607+32735,96+224+352+480+608+736+864+992+1120+1248+1376+1504+1632+1760+1888+2016+2144+2272+2400+2528+2656+2784+2912+3040+3168+3296+3424+3552+3680+3808+3936+4064+4192+4320+4448+4576+4704+4832+4960+5088+5216+5344+5472+5600+5728+5856+5984+6112+6240+6368+6496+6624+6752+6880+7008+7136+7264+7392+7520+7648+7776+7904+8032+8160+8288+8416+8544+8672+8800+8928+9056+9184+9312+9440+9568+9696+9824+9952+10080+10208+10336+10464+10592+10720+10848+10976+11104+11232+11360+11488+11616+11744+11872+12000+12128+12256+12384+12512+12640+12768+12896+13024+13152+13280+13408+13536+13664+13792+13920+14048+14176+14304+14432+14560+14688+14816+14944+15072+15200+15328+15456+15584+15712+15840+15968+16096+16224+16352+16480+16608+16736+16864+16992+17120+17248+17376+17504+17632+17760+17888+18016+18144+18272+18400+18528+18656+18784+18912+19040+19168+19296+19424+19552+19680+19808+19936+20064+20192+20320+20448+20576+20704+20832+20960+21088+21216+21344+21472+21600+21728+21856+21984+22112+22240+22368+22496+22624+22752+22880+23008+23136+23264+23392+23520+23648+23776+23904+24032+24160+24288+24416+24544+24672+24800+24928+25056+25184+25312+25440+25568+25696+25824+25952+26080+26208+26336+26464+26592+26720+26848+26976+27104+27232+27360+27488+27616+27744+27872+28000+28128+28256+28384+28512+28640+28768+28896+29024+29152+29280+29408+29536+29664+29792+29920+30048+30176+30304+30432+30560+30688+30816+30944+31072+31200+31328+31456+31584+31712+31840+31968+32096+32224+32352+32480+32608+32736,97+225+353+481+609+737+865+993+1121+1249+1377+1505+1633+1761+1889+2017+2145+2273+2401+2529+2657+2785+2913+3041+3169+3297+3425+3553+3681+3809+3937+4065+4193+4321+4449+4577+4705+4833+4961+5089+5217+5345+5473+5601+5729+5857+5985+6113+6241+6369+6497+6625+6753+6881+7009+7137+7265+7393+7521+7649+7777+7905+8033+8161+8289+8417+8545+8673+8801+8929+9057+9185+9313+9441+9569+9697+9825+9953+10081+10209+10337+10465+10593+10721+10849+10977+11105+11233+11361+11489+11617+11745+11873+12001+12129+12257+12385+12513+12641+12769+12897+13025+13153+13281+13409+13537+13665+13793+13921+14049+14177+14305+14433+14561+14689+14817+14945+15073+15201+15329+15457+15585+15713+15841+15969+16097+16225+16353+16481+16609+16737+16865+16993+17121+17249+17377+17505+17633+17761+17889+18017+18145+18273+18401+18529+18657+18785+18913+19041+19169+19297+19425+19553+19681+19809+19937+20065+20193+20321+20449+20577+20705+20833+20961+21089+21217+21345+21473+21601+21729+21857+21985+22113+22241+22369+22497+22625+22753+22881+23009+23137+23265+23393+23521+23649+23777+23905+24033+24161+24289+24417+24545+24673+24801+24929+25057+25185+25313+25441+25569+25697+25825+25953+26081+26209+26337+26465+26593+26721+26849+26977+27105+27233+27361+27489+27617+27745+27873+28001+28129+28257+28385+28513+28641+28769+28897+29025+29153+29281+29409+29537+29665+29793+29921+30049+30177+30305+30433+30561+30689+30817+30945+31073+31201+31329+31457+31585+31713+31841+31969+32097+32225+32353+32481+32609+32737,98+226+354+482+610+738+866+994+1122+1250+1378+1506+1634+1762+1890+2018+2146+2274+2402+2530+2658+2786+2914+3042+3170+3298+3426+3554+3682+3810+3938+4066+4194+4322+4450+4578+4706+4834+4962+5090+5218+5346+5474+5602+5730+5858+5986+6114+6242+6370+6498+6626+6754+6882+7010+7138+7266+7394+7522+7650+7778+7906+8034+8162+8290+8418+8546+8674+8802+8930+9058+9186+9314+9442+9570+9698+9826+9954+10082+10210+10338+10466+10594+10722+10850+10978+11106+11234+11362+11490+11618+11746+11874+12002+12130+12258+12386+12514+12642+12770+12898+13026+13154+13282+13410+13538+13666+13794+13922+14050+14178+14306+14434+14562+14690+14818+14946+15074+15202+15330+15458+15586+15714+15842+15970+16098+16226+16354+16482+16610+16738+16866+16994+17122+17250+17378+17506+17634+17762+17890+18018+18146+18274+18402+18530+18658+18786+18914+19042+19170+19298+19426+19554+19682+19810+19938+20066+20194+20322+20450+20578+20706+20834+20962+21090+21218+21346+21474+21602+21730+21858+21986+22114+22242+22370+22498+22626+22754+22882+23010+23138+23266+23394+23522+23650+23778+23906+24034+24162+24290+24418+24546+24674+24802+24930+25058+25186+25314+25442+25570+25698+25826+25954+26082+26210+26338+26466+26594+26722+26850+26978+27106+27234+27362+27490+27618+27746+27874+28002+28130+28258+28386+28514+28642+28770+28898+29026+29154+29282+29410+29538+29666+29794+29922+30050+30178+30306+30434+30562+30690+30818+30946+31074+31202+31330+31458+31586+31714+31842+31970+32098+32226+32354+32482+32610+32738,99+227+355+483+611+739+867+995+1123+1251+1379+1507+1635+1763+1891+2019+2147+2275+2403+2531+2659+2787+2915+3043+3171+3299+3427+3555+3683+3811+3939+4067+4195+4323+4451+4579+4707+4835+4963+5091+5219+5347+5475+5603+5731+5859+5987+6115+6243+6371+6499+6627+6755+6883+7011+7139+7267+7395+7523+7651+7779+7907+8035+8163+8291+8419+8547+8675+8803+8931+9059+9187+9315+9443+9571+9699+9827+9955+10083+10211+10339+10467+10595+10723+10851+10979+11107+11235+11363+11491+11619+11747+11875+12003+12131+12259+12387+12515+12643+12771+12899+13027+13155+13283+13411+13539+13667+13795+13923+14051+14179+14307+14435+14563+14691+14819+14947+15075+15203+15331+15459+15587+15715+15843+15971+16099+16227+16355+16483+16611+16739+16867+16995+17123+17251+17379+17507+17635+17763+17891+18019+18147+18275+18403+18531+18659+18787+18915+19043+19171+19299+19427+19555+19683+19811+19939+20067+20195+20323+20451+20579+20707+20835+20963+21091+21219+21347+21475+21603+21731+21859+21987+22115+22243+22371+22499+22627+22755+22883+23011+23139+23267+23395+23523+23651+23779+23907+24035+24163+24291+24419+24547+24675+24803+24931+25059+25187+25315+25443+25571+25699+25827+25955+26083+26211+26339+26467+26595+26723+26851+26979+27107+27235+27363+27491+27619+27747+27875+28003+28131+28259+28387+28515+28643+28771+28899+29027+29155+29283+29411+29539+29667+29795+29923+30051+30179+30307+30435+30563+30691+30819+30947+31075+31203+31331+31459+31587+31715+31843+31971+32099+32227+32355+32483+32611+32739,100+228+356+484+612+740+868+996+1124+1252+1380+1508+1636+1764+1892+2020+2148+2276+2404+2532+2660+2788+2916+3044+3172+3300+3428+3556+3684+3812+3940+4068+4196+4324+4452+4580+4708+4836+4964+5092+5220+5348+5476+5604+5732+5860+5988+6116+6244+6372+6500+6628+6756+6884+7012+7140+7268+7396+7524+7652+7780+7908+8036+8164+8292+8420+8548+8676+8804+8932+9060+9188+9316+9444+9572+9700+9828+9956+10084+10212+10340+10468+10596+10724+10852+10980+11108+11236+11364+11492+11620+11748+11876+12004+12132+12260+12388+12516+12644+12772+12900+13028+13156+13284+13412+13540+13668+13796+13924+14052+14180+14308+14436+14564+14692+14820+14948+15076+15204+15332+15460+15588+15716+15844+15972+16100+16228+16356+16484+16612+16740+16868+16996+17124+17252+17380+17508+17636+17764+17892+18020+18148+18276+18404+18532+18660+18788+18916+19044+19172+19300+19428+19556+19684+19812+19940+20068+20196+20324+20452+20580+20708+20836+20964+21092+21220+21348+21476+21604+21732+21860+21988+22116+22244+22372+22500+22628+22756+22884+23012+23140+23268+23396+23524+23652+23780+23908+24036+24164+24292+24420+24548+24676+24804+24932+25060+25188+25316+25444+25572+25700+25828+25956+26084+26212+26340+26468+26596+26724+26852+26980+27108+27236+27364+27492+27620+27748+27876+28004+28132+28260+28388+28516+28644+28772+28900+29028+29156+29284+29412+29540+29668+29796+29924+30052+30180+30308+30436+30564+30692+30820+30948+31076+31204+31332+31460+31588+31716+31844+31972+32100+32228+32356+32484+32612+32740,101+229+357+485+613+741+869+997+1125+1253+1381+1509+1637+1765+1893+2021+2149+2277+2405+2533+2661+2789+2917+3045+3173+3301+3429+3557+3685+3813+3941+4069+4197+4325+4453+4581+4709+4837+4965+5093+5221+5349+5477+5605+5733+5861+5989+6117+6245+6373+6501+6629+6757+6885+7013+7141+7269+7397+7525+7653+7781+7909+8037+8165+8293+8421+8549+8677+8805+8933+9061+9189+9317+9445+9573+9701+9829+9957+10085+10213+10341+10469+10597+10725+10853+10981+11109+11237+11365+11493+11621+11749+11877+12005+12133+12261+12389+12517+12645+12773+12901+13029+13157+13285+13413+13541+13669+13797+13925+14053+14181+14309+14437+14565+14693+14821+14949+15077+15205+15333+15461+15589+15717+15845+15973+16101+16229+16357+16485+16613+16741+16869+16997+17125+17253+17381+17509+17637+17765+17893+18021+18149+18277+18405+18533+18661+18789+18917+19045+19173+19301+19429+19557+19685+19813+19941+20069+20197+20325+20453+20581+20709+20837+20965+21093+21221+21349+21477+21605+21733+21861+21989+22117+22245+22373+22501+22629+22757+22885+23013+23141+23269+23397+23525+23653+23781+23909+24037+24165+24293+24421+24549+24677+24805+24933+25061+25189+25317+25445+25573+25701+25829+25957+26085+26213+26341+26469+26597+26725+26853+26981+27109+27237+27365+27493+27621+27749+27877+28005+28133+28261+28389+28517+28645+28773+28901+29029+29157+29285+29413+29541+29669+29797+29925+30053+30181+30309+30437+30565+30693+30821+30949+31077+31205+31333+31461+31589+31717+31845+31973+32101+32229+32357+32485+32613+32741,102+230+358+486+614+742+870+998+1126+1254+1382+1510+1638+1766+1894+2022+2150+2278+2406+2534+2662+2790+2918+3046+3174+3302+3430+3558+3686+3814+3942+4070+4198+4326+4454+4582+4710+4838+4966+5094+5222+5350+5478+5606+5734+5862+5990+6118+6246+6374+6502+6630+6758+6886+7014+7142+7270+7398+7526+7654+7782+7910+8038+8166+8294+8422+8550+8678+8806+8934+9062+9190+9318+9446+9574+9702+9830+9958+10086+10214+10342+10470+10598+10726+10854+10982+11110+11238+11366+11494+11622+11750+11878+12006+12134+12262+12390+12518+12646+12774+12902+13030+13158+13286+13414+13542+13670+13798+13926+14054+14182+14310+14438+14566+14694+14822+14950+15078+15206+15334+15462+15590+15718+15846+15974+16102+16230+16358+16486+16614+16742+16870+16998+17126+17254+17382+17510+17638+17766+17894+18022+18150+18278+18406+18534+18662+18790+18918+19046+19174+19302+19430+19558+19686+19814+19942+20070+20198+20326+20454+20582+20710+20838+20966+21094+21222+21350+21478+21606+21734+21862+21990+22118+22246+22374+22502+22630+22758+22886+23014+23142+23270+23398+23526+23654+23782+23910+24038+24166+24294+24422+24550+24678+24806+24934+25062+25190+25318+25446+25574+25702+25830+25958+26086+26214+26342+26470+26598+26726+26854+26982+27110+27238+27366+27494+27622+27750+27878+28006+28134+28262+28390+28518+28646+28774+28902+29030+29158+29286+29414+29542+29670+29798+29926+30054+30182+30310+30438+30566+30694+30822+30950+31078+31206+31334+31462+31590+31718+31846+31974+32102+32230+32358+32486+32614+32742,103+231+359+487+615+743+871+999+1127+1255+1383+1511+1639+1767+1895+2023+2151+2279+2407+2535+2663+2791+2919+3047+3175+3303+3431+3559+3687+3815+3943+4071+4199+4327+4455+4583+4711+4839+4967+5095+5223+5351+5479+5607+5735+5863+5991+6119+6247+6375+6503+6631+6759+6887+7015+7143+7271+7399+7527+7655+7783+7911+8039+8167+8295+8423+8551+8679+8807+8935+9063+9191+9319+9447+9575+9703+9831+9959+10087+10215+10343+10471+10599+10727+10855+10983+11111+11239+11367+11495+11623+11751+11879+12007+12135+12263+12391+12519+12647+12775+12903+13031+13159+13287+13415+13543+13671+13799+13927+14055+14183+14311+14439+14567+14695+14823+14951+15079+15207+15335+15463+15591+15719+15847+15975+16103+16231+16359+16487+16615+16743+16871+16999+17127+17255+17383+17511+17639+17767+17895+18023+18151+18279+18407+18535+18663+18791+18919+19047+19175+19303+19431+19559+19687+19815+19943+20071+20199+20327+20455+20583+20711+20839+20967+21095+21223+21351+21479+21607+21735+21863+21991+22119+22247+22375+22503+22631+22759+22887+23015+23143+23271+23399+23527+23655+23783+23911+24039+24167+24295+24423+24551+24679+24807+24935+25063+25191+25319+25447+25575+25703+25831+25959+26087+26215+26343+26471+26599+26727+26855+26983+27111+27239+27367+27495+27623+27751+27879+28007+28135+28263+28391+28519+28647+28775+28903+29031+29159+29287+29415+29543+29671+29799+29927+30055+30183+30311+30439+30567+30695+30823+30951+31079+31207+31335+31463+31591+31719+31847+31975+32103+32231+32359+32487+32615+32743,104+232+360+488+616+744+872+1000+1128+1256+1384+1512+1640+1768+1896+2024+2152+2280+2408+2536+2664+2792+2920+3048+3176+3304+3432+3560+3688+3816+3944+4072+4200+4328+4456+4584+4712+4840+4968+5096+5224+5352+5480+5608+5736+5864+5992+6120+6248+6376+6504+6632+6760+6888+7016+7144+7272+7400+7528+7656+7784+7912+8040+8168+8296+8424+8552+8680+8808+8936+9064+9192+9320+9448+9576+9704+9832+9960+10088+10216+10344+10472+10600+10728+10856+10984+11112+11240+11368+11496+11624+11752+11880+12008+12136+12264+12392+12520+12648+12776+12904+13032+13160+13288+13416+13544+13672+13800+13928+14056+14184+14312+14440+14568+14696+14824+14952+15080+15208+15336+15464+15592+15720+15848+15976+16104+16232+16360+16488+16616+16744+16872+17000+17128+17256+17384+17512+17640+17768+17896+18024+18152+18280+18408+18536+18664+18792+18920+19048+19176+19304+19432+19560+19688+19816+19944+20072+20200+20328+20456+20584+20712+20840+20968+21096+21224+21352+21480+21608+21736+21864+21992+22120+22248+22376+22504+22632+22760+22888+23016+23144+23272+23400+23528+23656+23784+23912+24040+24168+24296+24424+24552+24680+24808+24936+25064+25192+25320+25448+25576+25704+25832+25960+26088+26216+26344+26472+26600+26728+26856+26984+27112+27240+27368+27496+27624+27752+27880+28008+28136+28264+28392+28520+28648+28776+28904+29032+29160+29288+29416+29544+29672+29800+29928+30056+30184+30312+30440+30568+30696+30824+30952+31080+31208+31336+31464+31592+31720+31848+31976+32104+32232+32360+32488+32616+32744,105+233+361+489+617+745+873+1001+1129+1257+1385+1513+1641+1769+1897+2025+2153+2281+2409+2537+2665+2793+2921+3049+3177+3305+3433+3561+3689+3817+3945+4073+4201+4329+4457+4585+4713+4841+4969+5097+5225+5353+5481+5609+5737+5865+5993+6121+6249+6377+6505+6633+6761+6889+7017+7145+7273+7401+7529+7657+7785+7913+8041+8169+8297+8425+8553+8681+8809+8937+9065+9193+9321+9449+9577+9705+9833+9961+10089+10217+10345+10473+10601+10729+10857+10985+11113+11241+11369+11497+11625+11753+11881+12009+12137+12265+12393+12521+12649+12777+12905+13033+13161+13289+13417+13545+13673+13801+13929+14057+14185+14313+14441+14569+14697+14825+14953+15081+15209+15337+15465+15593+15721+15849+15977+16105+16233+16361+16489+16617+16745+16873+17001+17129+17257+17385+17513+17641+17769+17897+18025+18153+18281+18409+18537+18665+18793+18921+19049+19177+19305+19433+19561+19689+19817+19945+20073+20201+20329+20457+20585+20713+20841+20969+21097+21225+21353+21481+21609+21737+21865+21993+22121+22249+22377+22505+22633+22761+22889+23017+23145+23273+23401+23529+23657+23785+23913+24041+24169+24297+24425+24553+24681+24809+24937+25065+25193+25321+25449+25577+25705+25833+25961+26089+26217+26345+26473+26601+26729+26857+26985+27113+27241+27369+27497+27625+27753+27881+28009+28137+28265+28393+28521+28649+28777+28905+29033+29161+29289+29417+29545+29673+29801+29929+30057+30185+30313+30441+30569+30697+30825+30953+31081+31209+31337+31465+31593+31721+31849+31977+32105+32233+32361+32489+32617+32745,106+234+362+490+618+746+874+1002+1130+1258+1386+1514+1642+1770+1898+2026+2154+2282+2410+2538+2666+2794+2922+3050+3178+3306+3434+3562+3690+3818+3946+4074+4202+4330+4458+4586+4714+4842+4970+5098+5226+5354+5482+5610+5738+5866+5994+6122+6250+6378+6506+6634+6762+6890+7018+7146+7274+7402+7530+7658+7786+7914+8042+8170+8298+8426+8554+8682+8810+8938+9066+9194+9322+9450+9578+9706+9834+9962+10090+10218+10346+10474+10602+10730+10858+10986+11114+11242+11370+11498+11626+11754+11882+12010+12138+12266+12394+12522+12650+12778+12906+13034+13162+13290+13418+13546+13674+13802+13930+14058+14186+14314+14442+14570+14698+14826+14954+15082+15210+15338+15466+15594+15722+15850+15978+16106+16234+16362+16490+16618+16746+16874+17002+17130+17258+17386+17514+17642+17770+17898+18026+18154+18282+18410+18538+18666+18794+18922+19050+19178+19306+19434+19562+19690+19818+19946+20074+20202+20330+20458+20586+20714+20842+20970+21098+21226+21354+21482+21610+21738+21866+21994+22122+22250+22378+22506+22634+22762+22890+23018+23146+23274+23402+23530+23658+23786+23914+24042+24170+24298+24426+24554+24682+24810+24938+25066+25194+25322+25450+25578+25706+25834+25962+26090+26218+26346+26474+26602+26730+26858+26986+27114+27242+27370+27498+27626+27754+27882+28010+28138+28266+28394+28522+28650+28778+28906+29034+29162+29290+29418+29546+29674+29802+29930+30058+30186+30314+30442+30570+30698+30826+30954+31082+31210+31338+31466+31594+31722+31850+31978+32106+32234+32362+32490+32618+32746,107+235+363+491+619+747+875+1003+1131+1259+1387+1515+1643+1771+1899+2027+2155+2283+2411+2539+2667+2795+2923+3051+3179+3307+3435+3563+3691+3819+3947+4075+4203+4331+4459+4587+4715+4843+4971+5099+5227+5355+5483+5611+5739+5867+5995+6123+6251+6379+6507+6635+6763+6891+7019+7147+7275+7403+7531+7659+7787+7915+8043+8171+8299+8427+8555+8683+8811+8939+9067+9195+9323+9451+9579+9707+9835+9963+10091+10219+10347+10475+10603+10731+10859+10987+11115+11243+11371+11499+11627+11755+11883+12011+12139+12267+12395+12523+12651+12779+12907+13035+13163+13291+13419+13547+13675+13803+13931+14059+14187+14315+14443+14571+14699+14827+14955+15083+15211+15339+15467+15595+15723+15851+15979+16107+16235+16363+16491+16619+16747+16875+17003+17131+17259+17387+17515+17643+17771+17899+18027+18155+18283+18411+18539+18667+18795+18923+19051+19179+19307+19435+19563+19691+19819+19947+20075+20203+20331+20459+20587+20715+20843+20971+21099+21227+21355+21483+21611+21739+21867+21995+22123+22251+22379+22507+22635+22763+22891+23019+23147+23275+23403+23531+23659+23787+23915+24043+24171+24299+24427+24555+24683+24811+24939+25067+25195+25323+25451+25579+25707+25835+25963+26091+26219+26347+26475+26603+26731+26859+26987+27115+27243+27371+27499+27627+27755+27883+28011+28139+28267+28395+28523+28651+28779+28907+29035+29163+29291+29419+29547+29675+29803+29931+30059+30187+30315+30443+30571+30699+30827+30955+31083+31211+31339+31467+31595+31723+31851+31979+32107+32235+32363+32491+32619+32747,108+236+364+492+620+748+876+1004+1132+1260+1388+1516+1644+1772+1900+2028+2156+2284+2412+2540+2668+2796+2924+3052+3180+3308+3436+3564+3692+3820+3948+4076+4204+4332+4460+4588+4716+4844+4972+5100+5228+5356+5484+5612+5740+5868+5996+6124+6252+6380+6508+6636+6764+6892+7020+7148+7276+7404+7532+7660+7788+7916+8044+8172+8300+8428+8556+8684+8812+8940+9068+9196+9324+9452+9580+9708+9836+9964+10092+10220+10348+10476+10604+10732+10860+10988+11116+11244+11372+11500+11628+11756+11884+12012+12140+12268+12396+12524+12652+12780+12908+13036+13164+13292+13420+13548+13676+13804+13932+14060+14188+14316+14444+14572+14700+14828+14956+15084+15212+15340+15468+15596+15724+15852+15980+16108+16236+16364+16492+16620+16748+16876+17004+17132+17260+17388+17516+17644+17772+17900+18028+18156+18284+18412+18540+18668+18796+18924+19052+19180+19308+19436+19564+19692+19820+19948+20076+20204+20332+20460+20588+20716+20844+20972+21100+21228+21356+21484+21612+21740+21868+21996+22124+22252+22380+22508+22636+22764+22892+23020+23148+23276+23404+23532+23660+23788+23916+24044+24172+24300+24428+24556+24684+24812+24940+25068+25196+25324+25452+25580+25708+25836+25964+26092+26220+26348+26476+26604+26732+26860+26988+27116+27244+27372+27500+27628+27756+27884+28012+28140+28268+28396+28524+28652+28780+28908+29036+29164+29292+29420+29548+29676+29804+29932+30060+30188+30316+30444+30572+30700+30828+30956+31084+31212+31340+31468+31596+31724+31852+31980+32108+32236+32364+32492+32620+32748,109+237+365+493+621+749+877+1005+1133+1261+1389+1517+1645+1773+1901+2029+2157+2285+2413+2541+2669+2797+2925+3053+3181+3309+3437+3565+3693+3821+3949+4077+4205+4333+4461+4589+4717+4845+4973+5101+5229+5357+5485+5613+5741+5869+5997+6125+6253+6381+6509+6637+6765+6893+7021+7149+7277+7405+7533+7661+7789+7917+8045+8173+8301+8429+8557+8685+8813+8941+9069+9197+9325+9453+9581+9709+9837+9965+10093+10221+10349+10477+10605+10733+10861+10989+11117+11245+11373+11501+11629+11757+11885+12013+12141+12269+12397+12525+12653+12781+12909+13037+13165+13293+13421+13549+13677+13805+13933+14061+14189+14317+14445+14573+14701+14829+14957+15085+15213+15341+15469+15597+15725+15853+15981+16109+16237+16365+16493+16621+16749+16877+17005+17133+17261+17389+17517+17645+17773+17901+18029+18157+18285+18413+18541+18669+18797+18925+19053+19181+19309+19437+19565+19693+19821+19949+20077+20205+20333+20461+20589+20717+20845+20973+21101+21229+21357+21485+21613+21741+21869+21997+22125+22253+22381+22509+22637+22765+22893+23021+23149+23277+23405+23533+23661+23789+23917+24045+24173+24301+24429+24557+24685+24813+24941+25069+25197+25325+25453+25581+25709+25837+25965+26093+26221+26349+26477+26605+26733+26861+26989+27117+27245+27373+27501+27629+27757+27885+28013+28141+28269+28397+28525+28653+28781+28909+29037+29165+29293+29421+29549+29677+29805+29933+30061+30189+30317+30445+30573+30701+30829+30957+31085+31213+31341+31469+31597+31725+31853+31981+32109+32237+32365+32493+32621+32749,110+238+366+494+622+750+878+1006+1134+1262+1390+1518+1646+1774+1902+2030+2158+2286+2414+2542+2670+2798+2926+3054+3182+3310+3438+3566+3694+3822+3950+4078+4206+4334+4462+4590+4718+4846+4974+5102+5230+5358+5486+5614+5742+5870+5998+6126+6254+6382+6510+6638+6766+6894+7022+7150+7278+7406+7534+7662+7790+7918+8046+8174+8302+8430+8558+8686+8814+8942+9070+9198+9326+9454+9582+9710+9838+9966+10094+10222+10350+10478+10606+10734+10862+10990+11118+11246+11374+11502+11630+11758+11886+12014+12142+12270+12398+12526+12654+12782+12910+13038+13166+13294+13422+13550+13678+13806+13934+14062+14190+14318+14446+14574+14702+14830+14958+15086+15214+15342+15470+15598+15726+15854+15982+16110+16238+16366+16494+16622+16750+16878+17006+17134+17262+17390+17518+17646+17774+17902+18030+18158+18286+18414+18542+18670+18798+18926+19054+19182+19310+19438+19566+19694+19822+19950+20078+20206+20334+20462+20590+20718+20846+20974+21102+21230+21358+21486+21614+21742+21870+21998+22126+22254+22382+22510+22638+22766+22894+23022+23150+23278+23406+23534+23662+23790+23918+24046+24174+24302+24430+24558+24686+24814+24942+25070+25198+25326+25454+25582+25710+25838+25966+26094+26222+26350+26478+26606+26734+26862+26990+27118+27246+27374+27502+27630+27758+27886+28014+28142+28270+28398+28526+28654+28782+28910+29038+29166+29294+29422+29550+29678+29806+29934+30062+30190+30318+30446+30574+30702+30830+30958+31086+31214+31342+31470+31598+31726+31854+31982+32110+32238+32366+32494+32622+32750,111+239+367+495+623+751+879+1007+1135+1263+1391+1519+1647+1775+1903+2031+2159+2287+2415+2543+2671+2799+2927+3055+3183+3311+3439+3567+3695+3823+3951+4079+4207+4335+4463+4591+4719+4847+4975+5103+5231+5359+5487+5615+5743+5871+5999+6127+6255+6383+6511+6639+6767+6895+7023+7151+7279+7407+7535+7663+7791+7919+8047+8175+8303+8431+8559+8687+8815+8943+9071+9199+9327+9455+9583+9711+9839+9967+10095+10223+10351+10479+10607+10735+10863+10991+11119+11247+11375+11503+11631+11759+11887+12015+12143+12271+12399+12527+12655+12783+12911+13039+13167+13295+13423+13551+13679+13807+13935+14063+14191+14319+14447+14575+14703+14831+14959+15087+15215+15343+15471+15599+15727+15855+15983+16111+16239+16367+16495+16623+16751+16879+17007+17135+17263+17391+17519+17647+17775+17903+18031+18159+18287+18415+18543+18671+18799+18927+19055+19183+19311+19439+19567+19695+19823+19951+20079+20207+20335+20463+20591+20719+20847+20975+21103+21231+21359+21487+21615+21743+21871+21999+22127+22255+22383+22511+22639+22767+22895+23023+23151+23279+23407+23535+23663+23791+23919+24047+24175+24303+24431+24559+24687+24815+24943+25071+25199+25327+25455+25583+25711+25839+25967+26095+26223+26351+26479+26607+26735+26863+26991+27119+27247+27375+27503+27631+27759+27887+28015+28143+28271+28399+28527+28655+28783+28911+29039+29167+29295+29423+29551+29679+29807+29935+30063+30191+30319+30447+30575+30703+30831+30959+31087+31215+31343+31471+31599+31727+31855+31983+32111+32239+32367+32495+32623+32751,112+240+368+496+624+752+880+1008+1136+1264+1392+1520+1648+1776+1904+2032+2160+2288+2416+2544+2672+2800+2928+3056+3184+3312+3440+3568+3696+3824+3952+4080+4208+4336+4464+4592+4720+4848+4976+5104+5232+5360+5488+5616+5744+5872+6000+6128+6256+6384+6512+6640+6768+6896+7024+7152+7280+7408+7536+7664+7792+7920+8048+8176+8304+8432+8560+8688+8816+8944+9072+9200+9328+9456+9584+9712+9840+9968+10096+10224+10352+10480+10608+10736+10864+10992+11120+11248+11376+11504+11632+11760+11888+12016+12144+12272+12400+12528+12656+12784+12912+13040+13168+13296+13424+13552+13680+13808+13936+14064+14192+14320+14448+14576+14704+14832+14960+15088+15216+15344+15472+15600+15728+15856+15984+16112+16240+16368+16496+16624+16752+16880+17008+17136+17264+17392+17520+17648+17776+17904+18032+18160+18288+18416+18544+18672+18800+18928+19056+19184+19312+19440+19568+19696+19824+19952+20080+20208+20336+20464+20592+20720+20848+20976+21104+21232+21360+21488+21616+21744+21872+22000+22128+22256+22384+22512+22640+22768+22896+23024+23152+23280+23408+23536+23664+23792+23920+24048+24176+24304+24432+24560+24688+24816+24944+25072+25200+25328+25456+25584+25712+25840+25968+26096+26224+26352+26480+26608+26736+26864+26992+27120+27248+27376+27504+27632+27760+27888+28016+28144+28272+28400+28528+28656+28784+28912+29040+29168+29296+29424+29552+29680+29808+29936+30064+30192+30320+30448+30576+30704+30832+30960+31088+31216+31344+31472+31600+31728+31856+31984+32112+32240+32368+32496+32624+32752,113+241+369+497+625+753+881+1009+1137+1265+1393+1521+1649+1777+1905+2033+2161+2289+2417+2545+2673+2801+2929+3057+3185+3313+3441+3569+3697+3825+3953+4081+4209+4337+4465+4593+4721+4849+4977+5105+5233+5361+5489+5617+5745+5873+6001+6129+6257+6385+6513+6641+6769+6897+7025+7153+7281+7409+7537+7665+7793+7921+8049+8177+8305+8433+8561+8689+8817+8945+9073+9201+9329+9457+9585+9713+9841+9969+10097+10225+10353+10481+10609+10737+10865+10993+11121+11249+11377+11505+11633+11761+11889+12017+12145+12273+12401+12529+12657+12785+12913+13041+13169+13297+13425+13553+13681+13809+13937+14065+14193+14321+14449+14577+14705+14833+14961+15089+15217+15345+15473+15601+15729+15857+15985+16113+16241+16369+16497+16625+16753+16881+17009+17137+17265+17393+17521+17649+17777+17905+18033+18161+18289+18417+18545+18673+18801+18929+19057+19185+19313+19441+19569+19697+19825+19953+20081+20209+20337+20465+20593+20721+20849+20977+21105+21233+21361+21489+21617+21745+21873+22001+22129+22257+22385+22513+22641+22769+22897+23025+23153+23281+23409+23537+23665+23793+23921+24049+24177+24305+24433+24561+24689+24817+24945+25073+25201+25329+25457+25585+25713+25841+25969+26097+26225+26353+26481+26609+26737+26865+26993+27121+27249+27377+27505+27633+27761+27889+28017+28145+28273+28401+28529+28657+28785+28913+29041+29169+29297+29425+29553+29681+29809+29937+30065+30193+30321+30449+30577+30705+30833+30961+31089+31217+31345+31473+31601+31729+31857+31985+32113+32241+32369+32497+32625+32753,114+242+370+498+626+754+882+1010+1138+1266+1394+1522+1650+1778+1906+2034+2162+2290+2418+2546+2674+2802+2930+3058+3186+3314+3442+3570+3698+3826+3954+4082+4210+4338+4466+4594+4722+4850+4978+5106+5234+5362+5490+5618+5746+5874+6002+6130+6258+6386+6514+6642+6770+6898+7026+7154+7282+7410+7538+7666+7794+7922+8050+8178+8306+8434+8562+8690+8818+8946+9074+9202+9330+9458+9586+9714+9842+9970+10098+10226+10354+10482+10610+10738+10866+10994+11122+11250+11378+11506+11634+11762+11890+12018+12146+12274+12402+12530+12658+12786+12914+13042+13170+13298+13426+13554+13682+13810+13938+14066+14194+14322+14450+14578+14706+14834+14962+15090+15218+15346+15474+15602+15730+15858+15986+16114+16242+16370+16498+16626+16754+16882+17010+17138+17266+17394+17522+17650+17778+17906+18034+18162+18290+18418+18546+18674+18802+18930+19058+19186+19314+19442+19570+19698+19826+19954+20082+20210+20338+20466+20594+20722+20850+20978+21106+21234+21362+21490+21618+21746+21874+22002+22130+22258+22386+22514+22642+22770+22898+23026+23154+23282+23410+23538+23666+23794+23922+24050+24178+24306+24434+24562+24690+24818+24946+25074+25202+25330+25458+25586+25714+25842+25970+26098+26226+26354+26482+26610+26738+26866+26994+27122+27250+27378+27506+27634+27762+27890+28018+28146+28274+28402+28530+28658+28786+28914+29042+29170+29298+29426+29554+29682+29810+29938+30066+30194+30322+30450+30578+30706+30834+30962+31090+31218+31346+31474+31602+31730+31858+31986+32114+32242+32370+32498+32626+32754,115+243+371+499+627+755+883+1011+1139+1267+1395+1523+1651+1779+1907+2035+2163+2291+2419+2547+2675+2803+2931+3059+3187+3315+3443+3571+3699+3827+3955+4083+4211+4339+4467+4595+4723+4851+4979+5107+5235+5363+5491+5619+5747+5875+6003+6131+6259+6387+6515+6643+6771+6899+7027+7155+7283+7411+7539+7667+7795+7923+8051+8179+8307+8435+8563+8691+8819+8947+9075+9203+9331+9459+9587+9715+9843+9971+10099+10227+10355+10483+10611+10739+10867+10995+11123+11251+11379+11507+11635+11763+11891+12019+12147+12275+12403+12531+12659+12787+12915+13043+13171+13299+13427+13555+13683+13811+13939+14067+14195+14323+14451+14579+14707+14835+14963+15091+15219+15347+15475+15603+15731+15859+15987+16115+16243+16371+16499+16627+16755+16883+17011+17139+17267+17395+17523+17651+17779+17907+18035+18163+18291+18419+18547+18675+18803+18931+19059+19187+19315+19443+19571+19699+19827+19955+20083+20211+20339+20467+20595+20723+20851+20979+21107+21235+21363+21491+21619+21747+21875+22003+22131+22259+22387+22515+22643+22771+22899+23027+23155+23283+23411+23539+23667+23795+23923+24051+24179+24307+24435+24563+24691+24819+24947+25075+25203+25331+25459+25587+25715+25843+25971+26099+26227+26355+26483+26611+26739+26867+26995+27123+27251+27379+27507+27635+27763+27891+28019+28147+28275+28403+28531+28659+28787+28915+29043+29171+29299+29427+29555+29683+29811+29939+30067+30195+30323+30451+30579+30707+30835+30963+31091+31219+31347+31475+31603+31731+31859+31987+32115+32243+32371+32499+32627+32755,116+244+372+500+628+756+884+1012+1140+1268+1396+1524+1652+1780+1908+2036+2164+2292+2420+2548+2676+2804+2932+3060+3188+3316+3444+3572+3700+3828+3956+4084+4212+4340+4468+4596+4724+4852+4980+5108+5236+5364+5492+5620+5748+5876+6004+6132+6260+6388+6516+6644+6772+6900+7028+7156+7284+7412+7540+7668+7796+7924+8052+8180+8308+8436+8564+8692+8820+8948+9076+9204+9332+9460+9588+9716+9844+9972+10100+10228+10356+10484+10612+10740+10868+10996+11124+11252+11380+11508+11636+11764+11892+12020+12148+12276+12404+12532+12660+12788+12916+13044+13172+13300+13428+13556+13684+13812+13940+14068+14196+14324+14452+14580+14708+14836+14964+15092+15220+15348+15476+15604+15732+15860+15988+16116+16244+16372+16500+16628+16756+16884+17012+17140+17268+17396+17524+17652+17780+17908+18036+18164+18292+18420+18548+18676+18804+18932+19060+19188+19316+19444+19572+19700+19828+19956+20084+20212+20340+20468+20596+20724+20852+20980+21108+21236+21364+21492+21620+21748+21876+22004+22132+22260+22388+22516+22644+22772+22900+23028+23156+23284+23412+23540+23668+23796+23924+24052+24180+24308+24436+24564+24692+24820+24948+25076+25204+25332+25460+25588+25716+25844+25972+26100+26228+26356+26484+26612+26740+26868+26996+27124+27252+27380+27508+27636+27764+27892+28020+28148+28276+28404+28532+28660+28788+28916+29044+29172+29300+29428+29556+29684+29812+29940+30068+30196+30324+30452+30580+30708+30836+30964+31092+31220+31348+31476+31604+31732+31860+31988+32116+32244+32372+32500+32628+32756,117+245+373+501+629+757+885+1013+1141+1269+1397+1525+1653+1781+1909+2037+2165+2293+2421+2549+2677+2805+2933+3061+3189+3317+3445+3573+3701+3829+3957+4085+4213+4341+4469+4597+4725+4853+4981+5109+5237+5365+5493+5621+5749+5877+6005+6133+6261+6389+6517+6645+6773+6901+7029+7157+7285+7413+7541+7669+7797+7925+8053+8181+8309+8437+8565+8693+8821+8949+9077+9205+9333+9461+9589+9717+9845+9973+10101+10229+10357+10485+10613+10741+10869+10997+11125+11253+11381+11509+11637+11765+11893+12021+12149+12277+12405+12533+12661+12789+12917+13045+13173+13301+13429+13557+13685+13813+13941+14069+14197+14325+14453+14581+14709+14837+14965+15093+15221+15349+15477+15605+15733+15861+15989+16117+16245+16373+16501+16629+16757+16885+17013+17141+17269+17397+17525+17653+17781+17909+18037+18165+18293+18421+18549+18677+18805+18933+19061+19189+19317+19445+19573+19701+19829+19957+20085+20213+20341+20469+20597+20725+20853+20981+21109+21237+21365+21493+21621+21749+21877+22005+22133+22261+22389+22517+22645+22773+22901+23029+23157+23285+23413+23541+23669+23797+23925+24053+24181+24309+24437+24565+24693+24821+24949+25077+25205+25333+25461+25589+25717+25845+25973+26101+26229+26357+26485+26613+26741+26869+26997+27125+27253+27381+27509+27637+27765+27893+28021+28149+28277+28405+28533+28661+28789+28917+29045+29173+29301+29429+29557+29685+29813+29941+30069+30197+30325+30453+30581+30709+30837+30965+31093+31221+31349+31477+31605+31733+31861+31989+32117+32245+32373+32501+32629+32757,118+246+374+502+630+758+886+1014+1142+1270+1398+1526+1654+1782+1910+2038+2166+2294+2422+2550+2678+2806+2934+3062+3190+3318+3446+3574+3702+3830+3958+4086+4214+4342+4470+4598+4726+4854+4982+5110+5238+5366+5494+5622+5750+5878+6006+6134+6262+6390+6518+6646+6774+6902+7030+7158+7286+7414+7542+7670+7798+7926+8054+8182+8310+8438+8566+8694+8822+8950+9078+9206+9334+9462+9590+9718+9846+9974+10102+10230+10358+10486+10614+10742+10870+10998+11126+11254+11382+11510+11638+11766+11894+12022+12150+12278+12406+12534+12662+12790+12918+13046+13174+13302+13430+13558+13686+13814+13942+14070+14198+14326+14454+14582+14710+14838+14966+15094+15222+15350+15478+15606+15734+15862+15990+16118+16246+16374+16502+16630+16758+16886+17014+17142+17270+17398+17526+17654+17782+17910+18038+18166+18294+18422+18550+18678+18806+18934+19062+19190+19318+19446+19574+19702+19830+19958+20086+20214+20342+20470+20598+20726+20854+20982+21110+21238+21366+21494+21622+21750+21878+22006+22134+22262+22390+22518+22646+22774+22902+23030+23158+23286+23414+23542+23670+23798+23926+24054+24182+24310+24438+24566+24694+24822+24950+25078+25206+25334+25462+25590+25718+25846+25974+26102+26230+26358+26486+26614+26742+26870+26998+27126+27254+27382+27510+27638+27766+27894+28022+28150+28278+28406+28534+28662+28790+28918+29046+29174+29302+29430+29558+29686+29814+29942+30070+30198+30326+30454+30582+30710+30838+30966+31094+31222+31350+31478+31606+31734+31862+31990+32118+32246+32374+32502+32630+32758,119+247+375+503+631+759+887+1015+1143+1271+1399+1527+1655+1783+1911+2039+2167+2295+2423+2551+2679+2807+2935+3063+3191+3319+3447+3575+3703+3831+3959+4087+4215+4343+4471+4599+4727+4855+4983+5111+5239+5367+5495+5623+5751+5879+6007+6135+6263+6391+6519+6647+6775+6903+7031+7159+7287+7415+7543+7671+7799+7927+8055+8183+8311+8439+8567+8695+8823+8951+9079+9207+9335+9463+9591+9719+9847+9975+10103+10231+10359+10487+10615+10743+10871+10999+11127+11255+11383+11511+11639+11767+11895+12023+12151+12279+12407+12535+12663+12791+12919+13047+13175+13303+13431+13559+13687+13815+13943+14071+14199+14327+14455+14583+14711+14839+14967+15095+15223+15351+15479+15607+15735+15863+15991+16119+16247+16375+16503+16631+16759+16887+17015+17143+17271+17399+17527+17655+17783+17911+18039+18167+18295+18423+18551+18679+18807+18935+19063+19191+19319+19447+19575+19703+19831+19959+20087+20215+20343+20471+20599+20727+20855+20983+21111+21239+21367+21495+21623+21751+21879+22007+22135+22263+22391+22519+22647+22775+22903+23031+23159+23287+23415+23543+23671+23799+23927+24055+24183+24311+24439+24567+24695+24823+24951+25079+25207+25335+25463+25591+25719+25847+25975+26103+26231+26359+26487+26615+26743+26871+26999+27127+27255+27383+27511+27639+27767+27895+28023+28151+28279+28407+28535+28663+28791+28919+29047+29175+29303+29431+29559+29687+29815+29943+30071+30199+30327+30455+30583+30711+30839+30967+31095+31223+31351+31479+31607+31735+31863+31991+32119+32247+32375+32503+32631+32759,120+248+376+504+632+760+888+1016+1144+1272+1400+1528+1656+1784+1912+2040+2168+2296+2424+2552+2680+2808+2936+3064+3192+3320+3448+3576+3704+3832+3960+4088+4216+4344+4472+4600+4728+4856+4984+5112+5240+5368+5496+5624+5752+5880+6008+6136+6264+6392+6520+6648+6776+6904+7032+7160+7288+7416+7544+7672+7800+7928+8056+8184+8312+8440+8568+8696+8824+8952+9080+9208+9336+9464+9592+9720+9848+9976+10104+10232+10360+10488+10616+10744+10872+11000+11128+11256+11384+11512+11640+11768+11896+12024+12152+12280+12408+12536+12664+12792+12920+13048+13176+13304+13432+13560+13688+13816+13944+14072+14200+14328+14456+14584+14712+14840+14968+15096+15224+15352+15480+15608+15736+15864+15992+16120+16248+16376+16504+16632+16760+16888+17016+17144+17272+17400+17528+17656+17784+17912+18040+18168+18296+18424+18552+18680+18808+18936+19064+19192+19320+19448+19576+19704+19832+19960+20088+20216+20344+20472+20600+20728+20856+20984+21112+21240+21368+21496+21624+21752+21880+22008+22136+22264+22392+22520+22648+22776+22904+23032+23160+23288+23416+23544+23672+23800+23928+24056+24184+24312+24440+24568+24696+24824+24952+25080+25208+25336+25464+25592+25720+25848+25976+26104+26232+26360+26488+26616+26744+26872+27000+27128+27256+27384+27512+27640+27768+27896+28024+28152+28280+28408+28536+28664+28792+28920+29048+29176+29304+29432+29560+29688+29816+29944+30072+30200+30328+30456+30584+30712+30840+30968+31096+31224+31352+31480+31608+31736+31864+31992+32120+32248+32376+32504+32632+32760,121+249+377+505+633+761+889+1017+1145+1273+1401+1529+1657+1785+1913+2041+2169+2297+2425+2553+2681+2809+2937+3065+3193+3321+3449+3577+3705+3833+3961+4089+4217+4345+4473+4601+4729+4857+4985+5113+5241+5369+5497+5625+5753+5881+6009+6137+6265+6393+6521+6649+6777+6905+7033+7161+7289+7417+7545+7673+7801+7929+8057+8185+8313+8441+8569+8697+8825+8953+9081+9209+9337+9465+9593+9721+9849+9977+10105+10233+10361+10489+10617+10745+10873+11001+11129+11257+11385+11513+11641+11769+11897+12025+12153+12281+12409+12537+12665+12793+12921+13049+13177+13305+13433+13561+13689+13817+13945+14073+14201+14329+14457+14585+14713+14841+14969+15097+15225+15353+15481+15609+15737+15865+15993+16121+16249+16377+16505+16633+16761+16889+17017+17145+17273+17401+17529+17657+17785+17913+18041+18169+18297+18425+18553+18681+18809+18937+19065+19193+19321+19449+19577+19705+19833+19961+20089+20217+20345+20473+20601+20729+20857+20985+21113+21241+21369+21497+21625+21753+21881+22009+22137+22265+22393+22521+22649+22777+22905+23033+23161+23289+23417+23545+23673+23801+23929+24057+24185+24313+24441+24569+24697+24825+24953+25081+25209+25337+25465+25593+25721+25849+25977+26105+26233+26361+26489+26617+26745+26873+27001+27129+27257+27385+27513+27641+27769+27897+28025+28153+28281+28409+28537+28665+28793+28921+29049+29177+29305+29433+29561+29689+29817+29945+30073+30201+30329+30457+30585+30713+30841+30969+31097+31225+31353+31481+31609+31737+31865+31993+32121+32249+32377+32505+32633+32761,122+250+378+506+634+762+890+1018+1146+1274+1402+1530+1658+1786+1914+2042+2170+2298+2426+2554+2682+2810+2938+3066+3194+3322+3450+3578+3706+3834+3962+4090+4218+4346+4474+4602+4730+4858+4986+5114+5242+5370+5498+5626+5754+5882+6010+6138+6266+6394+6522+6650+6778+6906+7034+7162+7290+7418+7546+7674+7802+7930+8058+8186+8314+8442+8570+8698+8826+8954+9082+9210+9338+9466+9594+9722+9850+9978+10106+10234+10362+10490+10618+10746+10874+11002+11130+11258+11386+11514+11642+11770+11898+12026+12154+12282+12410+12538+12666+12794+12922+13050+13178+13306+13434+13562+13690+13818+13946+14074+14202+14330+14458+14586+14714+14842+14970+15098+15226+15354+15482+15610+15738+15866+15994+16122+16250+16378+16506+16634+16762+16890+17018+17146+17274+17402+17530+17658+17786+17914+18042+18170+18298+18426+18554+18682+18810+18938+19066+19194+19322+19450+19578+19706+19834+19962+20090+20218+20346+20474+20602+20730+20858+20986+21114+21242+21370+21498+21626+21754+21882+22010+22138+22266+22394+22522+22650+22778+22906+23034+23162+23290+23418+23546+23674+23802+23930+24058+24186+24314+24442+24570+24698+24826+24954+25082+25210+25338+25466+25594+25722+25850+25978+26106+26234+26362+26490+26618+26746+26874+27002+27130+27258+27386+27514+27642+27770+27898+28026+28154+28282+28410+28538+28666+28794+28922+29050+29178+29306+29434+29562+29690+29818+29946+30074+30202+30330+30458+30586+30714+30842+30970+31098+31226+31354+31482+31610+31738+31866+31994+32122+32250+32378+32506+32634+32762,123+251+379+507+635+763+891+1019+1147+1275+1403+1531+1659+1787+1915+2043+2171+2299+2427+2555+2683+2811+2939+3067+3195+3323+3451+3579+3707+3835+3963+4091+4219+4347+4475+4603+4731+4859+4987+5115+5243+5371+5499+5627+5755+5883+6011+6139+6267+6395+6523+6651+6779+6907+7035+7163+7291+7419+7547+7675+7803+7931+8059+8187+8315+8443+8571+8699+8827+8955+9083+9211+9339+9467+9595+9723+9851+9979+10107+10235+10363+10491+10619+10747+10875+11003+11131+11259+11387+11515+11643+11771+11899+12027+12155+12283+12411+12539+12667+12795+12923+13051+13179+13307+13435+13563+13691+13819+13947+14075+14203+14331+14459+14587+14715+14843+14971+15099+15227+15355+15483+15611+15739+15867+15995+16123+16251+16379+16507+16635+16763+16891+17019+17147+17275+17403+17531+17659+17787+17915+18043+18171+18299+18427+18555+18683+18811+18939+19067+19195+19323+19451+19579+19707+19835+19963+20091+20219+20347+20475+20603+20731+20859+20987+21115+21243+21371+21499+21627+21755+21883+22011+22139+22267+22395+22523+22651+22779+22907+23035+23163+23291+23419+23547+23675+23803+23931+24059+24187+24315+24443+24571+24699+24827+24955+25083+25211+25339+25467+25595+25723+25851+25979+26107+26235+26363+26491+26619+26747+26875+27003+27131+27259+27387+27515+27643+27771+27899+28027+28155+28283+28411+28539+28667+28795+28923+29051+29179+29307+29435+29563+29691+29819+29947+30075+30203+30331+30459+30587+30715+30843+30971+31099+31227+31355+31483+31611+31739+31867+31995+32123+32251+32379+32507+32635+32763,124+252+380+508+636+764+892+1020+1148+1276+1404+1532+1660+1788+1916+2044+2172+2300+2428+2556+2684+2812+2940+3068+3196+3324+3452+3580+3708+3836+3964+4092+4220+4348+4476+4604+4732+4860+4988+5116+5244+5372+5500+5628+5756+5884+6012+6140+6268+6396+6524+6652+6780+6908+7036+7164+7292+7420+7548+7676+7804+7932+8060+8188+8316+8444+8572+8700+8828+8956+9084+9212+9340+9468+9596+9724+9852+9980+10108+10236+10364+10492+10620+10748+10876+11004+11132+11260+11388+11516+11644+11772+11900+12028+12156+12284+12412+12540+12668+12796+12924+13052+13180+13308+13436+13564+13692+13820+13948+14076+14204+14332+14460+14588+14716+14844+14972+15100+15228+15356+15484+15612+15740+15868+15996+16124+16252+16380+16508+16636+16764+16892+17020+17148+17276+17404+17532+17660+17788+17916+18044+18172+18300+18428+18556+18684+18812+18940+19068+19196+19324+19452+19580+19708+19836+19964+20092+20220+20348+20476+20604+20732+20860+20988+21116+21244+21372+21500+21628+21756+21884+22012+22140+22268+22396+22524+22652+22780+22908+23036+23164+23292+23420+23548+23676+23804+23932+24060+24188+24316+24444+24572+24700+24828+24956+25084+25212+25340+25468+25596+25724+25852+25980+26108+26236+26364+26492+26620+26748+26876+27004+27132+27260+27388+27516+27644+27772+27900+28028+28156+28284+28412+28540+28668+28796+28924+29052+29180+29308+29436+29564+29692+29820+29948+30076+30204+30332+30460+30588+30716+30844+30972+31100+31228+31356+31484+31612+31740+31868+31996+32124+32252+32380+32508+32636+32764,125+253+381+509+637+765+893+1021+1149+1277+1405+1533+1661+1789+1917+2045+2173+2301+2429+2557+2685+2813+2941+3069+3197+3325+3453+3581+3709+3837+3965+4093+4221+4349+4477+4605+4733+4861+4989+5117+5245+5373+5501+5629+5757+5885+6013+6141+6269+6397+6525+6653+6781+6909+7037+7165+7293+7421+7549+7677+7805+7933+8061+8189+8317+8445+8573+8701+8829+8957+9085+9213+9341+9469+9597+9725+9853+9981+10109+10237+10365+10493+10621+10749+10877+11005+11133+11261+11389+11517+11645+11773+11901+12029+12157+12285+12413+12541+12669+12797+12925+13053+13181+13309+13437+13565+13693+13821+13949+14077+14205+14333+14461+14589+14717+14845+14973+15101+15229+15357+15485+15613+15741+15869+15997+16125+16253+16381+16509+16637+16765+16893+17021+17149+17277+17405+17533+17661+17789+17917+18045+18173+18301+18429+18557+18685+18813+18941+19069+19197+19325+19453+19581+19709+19837+19965+20093+20221+20349+20477+20605+20733+20861+20989+21117+21245+21373+21501+21629+21757+21885+22013+22141+22269+22397+22525+22653+22781+22909+23037+23165+23293+23421+23549+23677+23805+23933+24061+24189+24317+24445+24573+24701+24829+24957+25085+25213+25341+25469+25597+25725+25853+25981+26109+26237+26365+26493+26621+26749+26877+27005+27133+27261+27389+27517+27645+27773+27901+28029+28157+28285+28413+28541+28669+28797+28925+29053+29181+29309+29437+29565+29693+29821+29949+30077+30205+30333+30461+30589+30717+30845+30973+31101+31229+31357+31485+31613+31741+31869+31997+32125+32253+32381+32509+32637+32765,126+254+382+510+638+766+894+1022+1150+1278+1406+1534+1662+1790+1918+2046+2174+2302+2430+2558+2686+2814+2942+3070+3198+3326+3454+3582+3710+3838+3966+4094+4222+4350+4478+4606+4734+4862+4990+5118+5246+5374+5502+5630+5758+5886+6014+6142+6270+6398+6526+6654+6782+6910+7038+7166+7294+7422+7550+7678+7806+7934+8062+8190+8318+8446+8574+8702+8830+8958+9086+9214+9342+9470+9598+9726+9854+9982+10110+10238+10366+10494+10622+10750+10878+11006+11134+11262+11390+11518+11646+11774+11902+12030+12158+12286+12414+12542+12670+12798+12926+13054+13182+13310+13438+13566+13694+13822+13950+14078+14206+14334+14462+14590+14718+14846+14974+15102+15230+15358+15486+15614+15742+15870+15998+16126+16254+16382+16510+16638+16766+16894+17022+17150+17278+17406+17534+17662+17790+17918+18046+18174+18302+18430+18558+18686+18814+18942+19070+19198+19326+19454+19582+19710+19838+19966+20094+20222+20350+20478+20606+20734+20862+20990+21118+21246+21374+21502+21630+21758+21886+22014+22142+22270+22398+22526+22654+22782+22910+23038+23166+23294+23422+23550+23678+23806+23934+24062+24190+24318+24446+24574+24702+24830+24958+25086+25214+25342+25470+25598+25726+25854+25982+26110+26238+26366+26494+26622+26750+26878+27006+27134+27262+27390+27518+27646+27774+27902+28030+28158+28286+28414+28542+28670+28798+28926+29054+29182+29310+29438+29566+29694+29822+29950+30078+30206+30334+30462+30590+30718+30846+30974+31102+31230+31358+31486+31614+31742+31870+31998+32126+32254+32382+32510+32638+32766,127+255+383+511+639+767+895+1023+1151+1279+1407+1535+1663+1791+1919+2047+2175+2303+2431+2559+2687+2815+2943+3071+3199+3327+3455+3583+3711+3839+3967+4095+4223+4351+4479+4607+4735+4863+4991+5119+5247+5375+5503+5631+5759+5887+6015+6143+6271+6399+6527+6655+6783+6911+7039+7167+7295+7423+7551+7679+7807+7935+8063+8191+8319+8447+8575+8703+8831+8959+9087+9215+9343+9471+9599+9727+9855+9983+10111+10239+10367+10495+10623+10751+10879+11007+11135+11263+11391+11519+11647+11775+11903+12031+12159+12287+12415+12543+12671+12799+12927+13055+13183+13311+13439+13567+13695+13823+13951+14079+14207+14335+14463+14591+14719+14847+14975+15103+15231+15359+15487+15615+15743+15871+15999+16127+16255+16383+16511+16639+16767+16895+17023+17151+17279+17407+17535+17663+17791+17919+18047+18175+18303+18431+18559+18687+18815+18943+19071+19199+19327+19455+19583+19711+19839+19967+20095+20223+20351+20479+20607+20735+20863+20991+21119+21247+21375+21503+21631+21759+21887+22015+22143+22271+22399+22527+22655+22783+22911+23039+23167+23295+23423+23551+23679+23807+23935+24063+24191+24319+24447+24575+24703+24831+24959+25087+25215+25343+25471+25599+25727+25855+25983+26111+26239+26367+26495+26623+26751+26879+27007+27135+27263+27391+27519+27647+27775+27903+28031+28159+28287+28415+28543+28671+28799+28927+29055+29183+29311+29439+29567+29695+29823+29951+30079+30207+30335+30463+30591+30719+30847+30975+31103+31231+31359+31487+31615+31743+31871+31999+32127+32255+32383+32511+32639+32767,32768-33023,33024-33279,33280-33535,33536-33791,33792-34047,34048-34303,34304-34559,34560-34815,34816-35071,35072-35327,35328-35583,35584-35839,35840-36095,36096-36351,36352-36607,36608-36863,36864-37119,37120-37375,37376-37631,37632-37887,37888-38143,38144-38399,38400-38655,38656-38911,38912-39167,39168-39423,39424-39679,39680-39935,39936-40191,40192-40447,40448-40703,40704-40959,40960-41215,41216-41471,41472-41727,41728-41983,41984-42239,42240-42495,42496-42751,42752-43007,43008-43263,43264-43519,43520-43775,43776-44031,44032-44287,44288-44543,44544-44799,44800-45055,45056-45311,45312-45567,45568-45823,45824-46079,46080-46335,46336-46591,46592-46847,46848-47103,47104-47359,47360-47615,47616-47871,47872-48127,48128-48383,48384-48639,48640-48895,48896-49151,49152+49184+49216+49248+49280+49312+49344+49376+49408+49440+49472+49504+49536+49568+49600+49632+49664+49696+49728+49760+49792+49824+49856+49888+49920+49952+49984+50016+50048+50080+50112+50144+50176+50208+50240+50272+50304+50336+50368+50400+50432+50464+50496+50528+50560+50592+50624+50656+50688+50720+50752+50784+50816+50848+50880+50912+50944+50976+51008+51040+51072+51104+51136+51168+51200+51232+51264+51296+51328+51360+51392+51424+51456+51488+51520+51552+51584+51616+51648+51680+51712+51744+51776+51808+51840+51872+51904+51936+51968+52000+52032+52064+52096+52128+52160+52192+52224+52256+52288+52320+52352+52384+52416+52448+52480+52512+52544+52576+52608+52640+52672+52704+52736+52768+52800+52832+52864+52896+52928+52960+52992+53024+53056+53088+53120+53152+53184+53216+53248+53280+53312+53344+53376+53408+53440+53472+53504+53536+53568+53600+53632+53664+53696+53728+53760+53792+53824+53856+53888+53920+53952+53984+54016+54048+54080+54112+54144+54176+54208+54240+54272+54304+54336+54368+54400+54432+54464+54496+54528+54560+54592+54624+54656+54688+54720+54752+54784+54816+54848+54880+54912+54944+54976+55008+55040+55072+55104+55136+55168+55200+55232+55264+55296+55328+55360+55392+55424+55456+55488+55520+55552+55584+55616+55648+55680+55712+55744+55776+55808+55840+55872+55904+55936+55968+56000+56032+56064+56096+56128+56160+56192+56224+56256+56288+56320+56352+56384+56416+56448+56480+56512+56544+56576+56608+56640+56672+56704+56736+56768+56800+56832+56864+56896+56928+56960+56992+57024+57056+57088+57120+57152+57184+57216+57248+57280+57312,49153+49185+49217+49249+49281+49313+49345+49377+49409+49441+49473+49505+49537+49569+49601+49633+49665+49697+49729+49761+49793+49825+49857+49889+49921+49953+49985+50017+50049+50081+50113+50145+50177+50209+50241+50273+50305+50337+50369+50401+50433+50465+50497+50529+50561+50593+50625+50657+50689+50721+50753+50785+50817+50849+50881+50913+50945+50977+51009+51041+51073+51105+51137+51169+51201+51233+51265+51297+51329+51361+51393+51425+51457+51489+51521+51553+51585+51617+51649+51681+51713+51745+51777+51809+51841+51873+51905+51937+51969+52001+52033+52065+52097+52129+52161+52193+52225+52257+52289+52321+52353+52385+52417+52449+52481+52513+52545+52577+52609+52641+52673+52705+52737+52769+52801+52833+52865+52897+52929+52961+52993+53025+53057+53089+53121+53153+53185+53217+53249+53281+53313+53345+53377+53409+53441+53473+53505+53537+53569+53601+53633+53665+53697+53729+53761+53793+53825+53857+53889+53921+53953+53985+54017+54049+54081+54113+54145+54177+54209+54241+54273+54305+54337+54369+54401+54433+54465+54497+54529+54561+54593+54625+54657+54689+54721+54753+54785+54817+54849+54881+54913+54945+54977+55009+55041+55073+55105+55137+55169+55201+55233+55265+55297+55329+55361+55393+55425+55457+55489+55521+55553+55585+55617+55649+55681+55713+55745+55777+55809+55841+55873+55905+55937+55969+56001+56033+56065+56097+56129+56161+56193+56225+56257+56289+56321+56353+56385+56417+56449+56481+56513+56545+56577+56609+56641+56673+56705+56737+56769+56801+56833+56865+56897+56929+56961+56993+57025+57057+57089+57121+57153+57185+57217+57249+57281+57313,49154+49186+49218+49250+49282+49314+49346+49378+49410+49442+49474+49506+49538+49570+49602+49634+49666+49698+49730+49762+49794+49826+49858+49890+49922+49954+49986+50018+50050+50082+50114+50146+50178+50210+50242+50274+50306+50338+50370+50402+50434+50466+50498+50530+50562+50594+50626+50658+50690+50722+50754+50786+50818+50850+50882+50914+50946+50978+51010+51042+51074+51106+51138+51170+51202+51234+51266+51298+51330+51362+51394+51426+51458+51490+51522+51554+51586+51618+51650+51682+51714+51746+51778+51810+51842+51874+51906+51938+51970+52002+52034+52066+52098+52130+52162+52194+52226+52258+52290+52322+52354+52386+52418+52450+52482+52514+52546+52578+52610+52642+52674+52706+52738+52770+52802+52834+52866+52898+52930+52962+52994+53026+53058+53090+53122+53154+53186+53218+53250+53282+53314+53346+53378+53410+53442+53474+53506+53538+53570+53602+53634+53666+53698+53730+53762+53794+53826+53858+53890+53922+53954+53986+54018+54050+54082+54114+54146+54178+54210+54242+54274+54306+54338+54370+54402+54434+54466+54498+54530+54562+54594+54626+54658+54690+54722+54754+54786+54818+54850+54882+54914+54946+54978+55010+55042+55074+55106+55138+55170+55202+55234+55266+55298+55330+55362+55394+55426+55458+55490+55522+55554+55586+55618+55650+55682+55714+55746+55778+55810+55842+55874+55906+55938+55970+56002+56034+56066+56098+56130+56162+56194+56226+56258+56290+56322+56354+56386+56418+56450+56482+56514+56546+56578+56610+56642+56674+56706+56738+56770+56802+56834+56866+56898+56930+56962+56994+57026+57058+57090+57122+57154+57186+57218+57250+57282+57314,49155+49187+49219+49251+49283+49315+49347+49379+49411+49443+49475+49507+49539+49571+49603+49635+49667+49699+49731+49763+49795+49827+49859+49891+49923+49955+49987+50019+50051+50083+50115+50147+50179+50211+50243+50275+50307+50339+50371+50403+50435+50467+50499+50531+50563+50595+50627+50659+50691+50723+50755+50787+50819+50851+50883+50915+50947+50979+51011+51043+51075+51107+51139+51171+51203+51235+51267+51299+51331+51363+51395+51427+51459+51491+51523+51555+51587+51619+51651+51683+51715+51747+51779+51811+51843+51875+51907+51939+51971+52003+52035+52067+52099+52131+52163+52195+52227+52259+52291+52323+52355+52387+52419+52451+52483+52515+52547+52579+52611+52643+52675+52707+52739+52771+52803+52835+52867+52899+52931+52963+52995+53027+53059+53091+53123+53155+53187+53219+53251+53283+53315+53347+53379+53411+53443+53475+53507+53539+53571+53603+53635+53667+53699+53731+53763+53795+53827+53859+53891+53923+53955+53987+54019+54051+54083+54115+54147+54179+54211+54243+54275+54307+54339+54371+54403+54435+54467+54499+54531+54563+54595+54627+54659+54691+54723+54755+54787+54819+54851+54883+54915+54947+54979+55011+55043+55075+55107+55139+55171+55203+55235+55267+55299+55331+55363+55395+55427+55459+55491+55523+55555+55587+55619+55651+55683+55715+55747+55779+55811+55843+55875+55907+55939+55971+56003+56035+56067+56099+56131+56163+56195+56227+56259+56291+56323+56355+56387+56419+56451+56483+56515+56547+56579+56611+56643+56675+56707+56739+56771+56803+56835+56867+56899+56931+56963+56995+57027+57059+57091+57123+57155+57187+57219+57251+57283+57315,49156+49188+49220+49252+49284+49316+49348+49380+49412+49444+49476+49508+49540+49572+49604+49636+49668+49700+49732+49764+49796+49828+49860+49892+49924+49956+49988+50020+50052+50084+50116+50148+50180+50212+50244+50276+50308+50340+50372+50404+50436+50468+50500+50532+50564+50596+50628+50660+50692+50724+50756+50788+50820+50852+50884+50916+50948+50980+51012+51044+51076+51108+51140+51172+51204+51236+51268+51300+51332+51364+51396+51428+51460+51492+51524+51556+51588+51620+51652+51684+51716+51748+51780+51812+51844+51876+51908+51940+51972+52004+52036+52068+52100+52132+52164+52196+52228+52260+52292+52324+52356+52388+52420+52452+52484+52516+52548+52580+52612+52644+52676+52708+52740+52772+52804+52836+52868+52900+52932+52964+52996+53028+53060+53092+53124+53156+53188+53220+53252+53284+53316+53348+53380+53412+53444+53476+53508+53540+53572+53604+53636+53668+53700+53732+53764+53796+53828+53860+53892+53924+53956+53988+54020+54052+54084+54116+54148+54180+54212+54244+54276+54308+54340+54372+54404+54436+54468+54500+54532+54564+54596+54628+54660+54692+54724+54756+54788+54820+54852+54884+54916+54948+54980+55012+55044+55076+55108+55140+55172+55204+55236+55268+55300+55332+55364+55396+55428+55460+55492+55524+55556+55588+55620+55652+55684+55716+55748+55780+55812+55844+55876+55908+55940+55972+56004+56036+56068+56100+56132+56164+56196+56228+56260+56292+56324+56356+56388+56420+56452+56484+56516+56548+56580+56612+56644+56676+56708+56740+56772+56804+56836+56868+56900+56932+56964+56996+57028+57060+57092+57124+57156+57188+57220+57252+57284+57316,49157+49189+49221+49253+49285+49317+49349+49381+49413+49445+49477+49509+49541+49573+49605+49637+49669+49701+49733+49765+49797+49829+49861+49893+49925+49957+49989+50021+50053+50085+50117+50149+50181+50213+50245+50277+50309+50341+50373+50405+50437+50469+50501+50533+50565+50597+50629+50661+50693+50725+50757+50789+50821+50853+50885+50917+50949+50981+51013+51045+51077+51109+51141+51173+51205+51237+51269+51301+51333+51365+51397+51429+51461+51493+51525+51557+51589+51621+51653+51685+51717+51749+51781+51813+51845+51877+51909+51941+51973+52005+52037+52069+52101+52133+52165+52197+52229+52261+52293+52325+52357+52389+52421+52453+52485+52517+52549+52581+52613+52645+52677+52709+52741+52773+52805+52837+52869+52901+52933+52965+52997+53029+53061+53093+53125+53157+53189+53221+53253+53285+53317+53349+53381+53413+53445+53477+53509+53541+53573+53605+53637+53669+53701+53733+53765+53797+53829+53861+53893+53925+53957+53989+54021+54053+54085+54117+54149+54181+54213+54245+54277+54309+54341+54373+54405+54437+54469+54501+54533+54565+54597+54629+54661+54693+54725+54757+54789+54821+54853+54885+54917+54949+54981+55013+55045+55077+55109+55141+55173+55205+55237+55269+55301+55333+55365+55397+55429+55461+55493+55525+55557+55589+55621+55653+55685+55717+55749+55781+55813+55845+55877+55909+55941+55973+56005+56037+56069+56101+56133+56165+56197+56229+56261+56293+56325+56357+56389+56421+56453+56485+56517+56549+56581+56613+56645+56677+56709+56741+56773+56805+56837+56869+56901+56933+56965+56997+57029+57061+57093+57125+57157+57189+57221+57253+57285+57317,49158+49190+49222+49254+49286+49318+49350+49382+49414+49446+49478+49510+49542+49574+49606+49638+49670+49702+49734+49766+49798+49830+49862+49894+49926+49958+49990+50022+50054+50086+50118+50150+50182+50214+50246+50278+50310+50342+50374+50406+50438+50470+50502+50534+50566+50598+50630+50662+50694+50726+50758+50790+50822+50854+50886+50918+50950+50982+51014+51046+51078+51110+51142+51174+51206+51238+51270+51302+51334+51366+51398+51430+51462+51494+51526+51558+51590+51622+51654+51686+51718+51750+51782+51814+51846+51878+51910+51942+51974+52006+52038+52070+52102+52134+52166+52198+52230+52262+52294+52326+52358+52390+52422+52454+52486+52518+52550+52582+52614+52646+52678+52710+52742+52774+52806+52838+52870+52902+52934+52966+52998+53030+53062+53094+53126+53158+53190+53222+53254+53286+53318+53350+53382+53414+53446+53478+53510+53542+53574+53606+53638+53670+53702+53734+53766+53798+53830+53862+53894+53926+53958+53990+54022+54054+54086+54118+54150+54182+54214+54246+54278+54310+54342+54374+54406+54438+54470+54502+54534+54566+54598+54630+54662+54694+54726+54758+54790+54822+54854+54886+54918+54950+54982+55014+55046+55078+55110+55142+55174+55206+55238+55270+55302+55334+55366+55398+55430+55462+55494+55526+55558+55590+55622+55654+55686+55718+55750+55782+55814+55846+55878+55910+55942+55974+56006+56038+56070+56102+56134+56166+56198+56230+56262+56294+56326+56358+56390+56422+56454+56486+56518+56550+56582+56614+56646+56678+56710+56742+56774+56806+56838+56870+56902+56934+56966+56998+57030+57062+57094+57126+57158+57190+57222+57254+57286+57318,49159+49191+49223+49255+49287+49319+49351+49383+49415+49447+49479+49511+49543+49575+49607+49639+49671+49703+49735+49767+49799+49831+49863+49895+49927+49959+49991+50023+50055+50087+50119+50151+50183+50215+50247+50279+50311+50343+50375+50407+50439+50471+50503+50535+50567+50599+50631+50663+50695+50727+50759+50791+50823+50855+50887+50919+50951+50983+51015+51047+51079+51111+51143+51175+51207+51239+51271+51303+51335+51367+51399+51431+51463+51495+51527+51559+51591+51623+51655+51687+51719+51751+51783+51815+51847+51879+51911+51943+51975+52007+52039+52071+52103+52135+52167+52199+52231+52263+52295+52327+52359+52391+52423+52455+52487+52519+52551+52583+52615+52647+52679+52711+52743+52775+52807+52839+52871+52903+52935+52967+52999+53031+53063+53095+53127+53159+53191+53223+53255+53287+53319+53351+53383+53415+53447+53479+53511+53543+53575+53607+53639+53671+53703+53735+53767+53799+53831+53863+53895+53927+53959+53991+54023+54055+54087+54119+54151+54183+54215+54247+54279+54311+54343+54375+54407+54439+54471+54503+54535+54567+54599+54631+54663+54695+54727+54759+54791+54823+54855+54887+54919+54951+54983+55015+55047+55079+55111+55143+55175+55207+55239+55271+55303+55335+55367+55399+55431+55463+55495+55527+55559+55591+55623+55655+55687+55719+55751+55783+55815+55847+55879+55911+55943+55975+56007+56039+56071+56103+56135+56167+56199+56231+56263+56295+56327+56359+56391+56423+56455+56487+56519+56551+56583+56615+56647+56679+56711+56743+56775+56807+56839+56871+56903+56935+56967+56999+57031+57063+57095+57127+57159+57191+57223+57255+57287+57319,49160+49192+49224+49256+49288+49320+49352+49384+49416+49448+49480+49512+49544+49576+49608+49640+49672+49704+49736+49768+49800+49832+49864+49896+49928+49960+49992+50024+50056+50088+50120+50152+50184+50216+50248+50280+50312+50344+50376+50408+50440+50472+50504+50536+50568+50600+50632+50664+50696+50728+50760+50792+50824+50856+50888+50920+50952+50984+51016+51048+51080+51112+51144+51176+51208+51240+51272+51304+51336+51368+51400+51432+51464+51496+51528+51560+51592+51624+51656+51688+51720+51752+51784+51816+51848+51880+51912+51944+51976+52008+52040+52072+52104+52136+52168+52200+52232+52264+52296+52328+52360+52392+52424+52456+52488+52520+52552+52584+52616+52648+52680+52712+52744+52776+52808+52840+52872+52904+52936+52968+53000+53032+53064+53096+53128+53160+53192+53224+53256+53288+53320+53352+53384+53416+53448+53480+53512+53544+53576+53608+53640+53672+53704+53736+53768+53800+53832+53864+53896+53928+53960+53992+54024+54056+54088+54120+54152+54184+54216+54248+54280+54312+54344+54376+54408+54440+54472+54504+54536+54568+54600+54632+54664+54696+54728+54760+54792+54824+54856+54888+54920+54952+54984+55016+55048+55080+55112+55144+55176+55208+55240+55272+55304+55336+55368+55400+55432+55464+55496+55528+55560+55592+55624+55656+55688+55720+55752+55784+55816+55848+55880+55912+55944+55976+56008+56040+56072+56104+56136+56168+56200+56232+56264+56296+56328+56360+56392+56424+56456+56488+56520+56552+56584+56616+56648+56680+56712+56744+56776+56808+56840+56872+56904+56936+56968+57000+57032+57064+57096+57128+57160+57192+57224+57256+57288+57320,49161+49193+49225+49257+49289+49321+49353+49385+49417+49449+49481+49513+49545+49577+49609+49641+49673+49705+49737+49769+49801+49833+49865+49897+49929+49961+49993+50025+50057+50089+50121+50153+50185+50217+50249+50281+50313+50345+50377+50409+50441+50473+50505+50537+50569+50601+50633+50665+50697+50729+50761+50793+50825+50857+50889+50921+50953+50985+51017+51049+51081+51113+51145+51177+51209+51241+51273+51305+51337+51369+51401+51433+51465+51497+51529+51561+51593+51625+51657+51689+51721+51753+51785+51817+51849+51881+51913+51945+51977+52009+52041+52073+52105+52137+52169+52201+52233+52265+52297+52329+52361+52393+52425+52457+52489+52521+52553+52585+52617+52649+52681+52713+52745+52777+52809+52841+52873+52905+52937+52969+53001+53033+53065+53097+53129+53161+53193+53225+53257+53289+53321+53353+53385+53417+53449+53481+53513+53545+53577+53609+53641+53673+53705+53737+53769+53801+53833+53865+53897+53929+53961+53993+54025+54057+54089+54121+54153+54185+54217+54249+54281+54313+54345+54377+54409+54441+54473+54505+54537+54569+54601+54633+54665+54697+54729+54761+54793+54825+54857+54889+54921+54953+54985+55017+55049+55081+55113+55145+55177+55209+55241+55273+55305+55337+55369+55401+55433+55465+55497+55529+55561+55593+55625+55657+55689+55721+55753+55785+55817+55849+55881+55913+55945+55977+56009+56041+56073+56105+56137+56169+56201+56233+56265+56297+56329+56361+56393+56425+56457+56489+56521+56553+56585+56617+56649+56681+56713+56745+56777+56809+56841+56873+56905+56937+56969+57001+57033+57065+57097+57129+57161+57193+57225+57257+57289+57321,49162+49194+49226+49258+49290+49322+49354+49386+49418+49450+49482+49514+49546+49578+49610+49642+49674+49706+49738+49770+49802+49834+49866+49898+49930+49962+49994+50026+50058+50090+50122+50154+50186+50218+50250+50282+50314+50346+50378+50410+50442+50474+50506+50538+50570+50602+50634+50666+50698+50730+50762+50794+50826+50858+50890+50922+50954+50986+51018+51050+51082+51114+51146+51178+51210+51242+51274+51306+51338+51370+51402+51434+51466+51498+51530+51562+51594+51626+51658+51690+51722+51754+51786+51818+51850+51882+51914+51946+51978+52010+52042+52074+52106+52138+52170+52202+52234+52266+52298+52330+52362+52394+52426+52458+52490+52522+52554+52586+52618+52650+52682+52714+52746+52778+52810+52842+52874+52906+52938+52970+53002+53034+53066+53098+53130+53162+53194+53226+53258+53290+53322+53354+53386+53418+53450+53482+53514+53546+53578+53610+53642+53674+53706+53738+53770+53802+53834+53866+53898+53930+53962+53994+54026+54058+54090+54122+54154+54186+54218+54250+54282+54314+54346+54378+54410+54442+54474+54506+54538+54570+54602+54634+54666+54698+54730+54762+54794+54826+54858+54890+54922+54954+54986+55018+55050+55082+55114+55146+55178+55210+55242+55274+55306+55338+55370+55402+55434+55466+55498+55530+55562+55594+55626+55658+55690+55722+55754+55786+55818+55850+55882+55914+55946+55978+56010+56042+56074+56106+56138+56170+56202+56234+56266+56298+56330+56362+56394+56426+56458+56490+56522+56554+56586+56618+56650+56682+56714+56746+56778+56810+56842+56874+56906+56938+56970+57002+57034+57066+57098+57130+57162+57194+57226+57258+57290+57322,49163+49195+49227+49259+49291+49323+49355+49387+49419+49451+49483+49515+49547+49579+49611+49643+49675+49707+49739+49771+49803+49835+49867+49899+49931+49963+49995+50027+50059+50091+50123+50155+50187+50219+50251+50283+50315+50347+50379+50411+50443+50475+50507+50539+50571+50603+50635+50667+50699+50731+50763+50795+50827+50859+50891+50923+50955+50987+51019+51051+51083+51115+51147+51179+51211+51243+51275+51307+51339+51371+51403+51435+51467+51499+51531+51563+51595+51627+51659+51691+51723+51755+51787+51819+51851+51883+51915+51947+51979+52011+52043+52075+52107+52139+52171+52203+52235+52267+52299+52331+52363+52395+52427+52459+52491+52523+52555+52587+52619+52651+52683+52715+52747+52779+52811+52843+52875+52907+52939+52971+53003+53035+53067+53099+53131+53163+53195+53227+53259+53291+53323+53355+53387+53419+53451+53483+53515+53547+53579+53611+53643+53675+53707+53739+53771+53803+53835+53867+53899+53931+53963+53995+54027+54059+54091+54123+54155+54187+54219+54251+54283+54315+54347+54379+54411+54443+54475+54507+54539+54571+54603+54635+54667+54699+54731+54763+54795+54827+54859+54891+54923+54955+54987+55019+55051+55083+55115+55147+55179+55211+55243+55275+55307+55339+55371+55403+55435+55467+55499+55531+55563+55595+55627+55659+55691+55723+55755+55787+55819+55851+55883+55915+55947+55979+56011+56043+56075+56107+56139+56171+56203+56235+56267+56299+56331+56363+56395+56427+56459+56491+56523+56555+56587+56619+56651+56683+56715+56747+56779+56811+56843+56875+56907+56939+56971+57003+57035+57067+57099+57131+57163+57195+57227+57259+57291+57323,49164+49196+49228+49260+49292+49324+49356+49388+49420+49452+49484+49516+49548+49580+49612+49644+49676+49708+49740+49772+49804+49836+49868+49900+49932+49964+49996+50028+50060+50092+50124+50156+50188+50220+50252+50284+50316+50348+50380+50412+50444+50476+50508+50540+50572+50604+50636+50668+50700+50732+50764+50796+50828+50860+50892+50924+50956+50988+51020+51052+51084+51116+51148+51180+51212+51244+51276+51308+51340+51372+51404+51436+51468+51500+51532+51564+51596+51628+51660+51692+51724+51756+51788+51820+51852+51884+51916+51948+51980+52012+52044+52076+52108+52140+52172+52204+52236+52268+52300+52332+52364+52396+52428+52460+52492+52524+52556+52588+52620+52652+52684+52716+52748+52780+52812+52844+52876+52908+52940+52972+53004+53036+53068+53100+53132+53164+53196+53228+53260+53292+53324+53356+53388+53420+53452+53484+53516+53548+53580+53612+53644+53676+53708+53740+53772+53804+53836+53868+53900+53932+53964+53996+54028+54060+54092+54124+54156+54188+54220+54252+54284+54316+54348+54380+54412+54444+54476+54508+54540+54572+54604+54636+54668+54700+54732+54764+54796+54828+54860+54892+54924+54956+54988+55020+55052+55084+55116+55148+55180+55212+55244+55276+55308+55340+55372+55404+55436+55468+55500+55532+55564+55596+55628+55660+55692+55724+55756+55788+55820+55852+55884+55916+55948+55980+56012+56044+56076+56108+56140+56172+56204+56236+56268+56300+56332+56364+56396+56428+56460+56492+56524+56556+56588+56620+56652+56684+56716+56748+56780+56812+56844+56876+56908+56940+56972+57004+57036+57068+57100+57132+57164+57196+57228+57260+57292+57324,49165+49197+49229+49261+49293+49325+49357+49389+49421+49453+49485+49517+49549+49581+49613+49645+49677+49709+49741+49773+49805+49837+49869+49901+49933+49965+49997+50029+50061+50093+50125+50157+50189+50221+50253+50285+50317+50349+50381+50413+50445+50477+50509+50541+50573+50605+50637+50669+50701+50733+50765+50797+50829+50861+50893+50925+50957+50989+51021+51053+51085+51117+51149+51181+51213+51245+51277+51309+51341+51373+51405+51437+51469+51501+51533+51565+51597+51629+51661+51693+51725+51757+51789+51821+51853+51885+51917+51949+51981+52013+52045+52077+52109+52141+52173+52205+52237+52269+52301+52333+52365+52397+52429+52461+52493+52525+52557+52589+52621+52653+52685+52717+52749+52781+52813+52845+52877+52909+52941+52973+53005+53037+53069+53101+53133+53165+53197+53229+53261+53293+53325+53357+53389+53421+53453+53485+53517+53549+53581+53613+53645+53677+53709+53741+53773+53805+53837+53869+53901+53933+53965+53997+54029+54061+54093+54125+54157+54189+54221+54253+54285+54317+54349+54381+54413+54445+54477+54509+54541+54573+54605+54637+54669+54701+54733+54765+54797+54829+54861+54893+54925+54957+54989+55021+55053+55085+55117+55149+55181+55213+55245+55277+55309+55341+55373+55405+55437+55469+55501+55533+55565+55597+55629+55661+55693+55725+55757+55789+55821+55853+55885+55917+55949+55981+56013+56045+56077+56109+56141+56173+56205+56237+56269+56301+56333+56365+56397+56429+56461+56493+56525+56557+56589+56621+56653+56685+56717+56749+56781+56813+56845+56877+56909+56941+56973+57005+57037+57069+57101+57133+57165+57197+57229+57261+57293+57325,49166+49198+49230+49262+49294+49326+49358+49390+49422+49454+49486+49518+49550+49582+49614+49646+49678+49710+49742+49774+49806+49838+49870+49902+49934+49966+49998+50030+50062+50094+50126+50158+50190+50222+50254+50286+50318+50350+50382+50414+50446+50478+50510+50542+50574+50606+50638+50670+50702+50734+50766+50798+50830+50862+50894+50926+50958+50990+51022+51054+51086+51118+51150+51182+51214+51246+51278+51310+51342+51374+51406+51438+51470+51502+51534+51566+51598+51630+51662+51694+51726+51758+51790+51822+51854+51886+51918+51950+51982+52014+52046+52078+52110+52142+52174+52206+52238+52270+52302+52334+52366+52398+52430+52462+52494+52526+52558+52590+52622+52654+52686+52718+52750+52782+52814+52846+52878+52910+52942+52974+53006+53038+53070+53102+53134+53166+53198+53230+53262+53294+53326+53358+53390+53422+53454+53486+53518+53550+53582+53614+53646+53678+53710+53742+53774+53806+53838+53870+53902+53934+53966+53998+54030+54062+54094+54126+54158+54190+54222+54254+54286+54318+54350+54382+54414+54446+54478+54510+54542+54574+54606+54638+54670+54702+54734+54766+54798+54830+54862+54894+54926+54958+54990+55022+55054+55086+55118+55150+55182+55214+55246+55278+55310+55342+55374+55406+55438+55470+55502+55534+55566+55598+55630+55662+55694+55726+55758+55790+55822+55854+55886+55918+55950+55982+56014+56046+56078+56110+56142+56174+56206+56238+56270+56302+56334+56366+56398+56430+56462+56494+56526+56558+56590+56622+56654+56686+56718+56750+56782+56814+56846+56878+56910+56942+56974+57006+57038+57070+57102+57134+57166+57198+57230+57262+57294+57326,49167+49199+49231+49263+49295+49327+49359+49391+49423+49455+49487+49519+49551+49583+49615+49647+49679+49711+49743+49775+49807+49839+49871+49903+49935+49967+49999+50031+50063+50095+50127+50159+50191+50223+50255+50287+50319+50351+50383+50415+50447+50479+50511+50543+50575+50607+50639+50671+50703+50735+50767+50799+50831+50863+50895+50927+50959+50991+51023+51055+51087+51119+51151+51183+51215+51247+51279+51311+51343+51375+51407+51439+51471+51503+51535+51567+51599+51631+51663+51695+51727+51759+51791+51823+51855+51887+51919+51951+51983+52015+52047+52079+52111+52143+52175+52207+52239+52271+52303+52335+52367+52399+52431+52463+52495+52527+52559+52591+52623+52655+52687+52719+52751+52783+52815+52847+52879+52911+52943+52975+53007+53039+53071+53103+53135+53167+53199+53231+53263+53295+53327+53359+53391+53423+53455+53487+53519+53551+53583+53615+53647+53679+53711+53743+53775+53807+53839+53871+53903+53935+53967+53999+54031+54063+54095+54127+54159+54191+54223+54255+54287+54319+54351+54383+54415+54447+54479+54511+54543+54575+54607+54639+54671+54703+54735+54767+54799+54831+54863+54895+54927+54959+54991+55023+55055+55087+55119+55151+55183+55215+55247+55279+55311+55343+55375+55407+55439+55471+55503+55535+55567+55599+55631+55663+55695+55727+55759+55791+55823+55855+55887+55919+55951+55983+56015+56047+56079+56111+56143+56175+56207+56239+56271+56303+56335+56367+56399+56431+56463+56495+56527+56559+56591+56623+56655+56687+56719+56751+56783+56815+56847+56879+56911+56943+56975+57007+57039+57071+57103+57135+57167+57199+57231+57263+57295+57327,49168+49200+49232+49264+49296+49328+49360+49392+49424+49456+49488+49520+49552+49584+49616+49648+49680+49712+49744+49776+49808+49840+49872+49904+49936+49968+50000+50032+50064+50096+50128+50160+50192+50224+50256+50288+50320+50352+50384+50416+50448+50480+50512+50544+50576+50608+50640+50672+50704+50736+50768+50800+50832+50864+50896+50928+50960+50992+51024+51056+51088+51120+51152+51184+51216+51248+51280+51312+51344+51376+51408+51440+51472+51504+51536+51568+51600+51632+51664+51696+51728+51760+51792+51824+51856+51888+51920+51952+51984+52016+52048+52080+52112+52144+52176+52208+52240+52272+52304+52336+52368+52400+52432+52464+52496+52528+52560+52592+52624+52656+52688+52720+52752+52784+52816+52848+52880+52912+52944+52976+53008+53040+53072+53104+53136+53168+53200+53232+53264+53296+53328+53360+53392+53424+53456+53488+53520+53552+53584+53616+53648+53680+53712+53744+53776+53808+53840+53872+53904+53936+53968+54000+54032+54064+54096+54128+54160+54192+54224+54256+54288+54320+54352+54384+54416+54448+54480+54512+54544+54576+54608+54640+54672+54704+54736+54768+54800+54832+54864+54896+54928+54960+54992+55024+55056+55088+55120+55152+55184+55216+55248+55280+55312+55344+55376+55408+55440+55472+55504+55536+55568+55600+55632+55664+55696+55728+55760+55792+55824+55856+55888+55920+55952+55984+56016+56048+56080+56112+56144+56176+56208+56240+56272+56304+56336+56368+56400+56432+56464+56496+56528+56560+56592+56624+56656+56688+56720+56752+56784+56816+56848+56880+56912+56944+56976+57008+57040+57072+57104+57136+57168+57200+57232+57264+57296+57328,49169+49201+49233+49265+49297+49329+49361+49393+49425+49457+49489+49521+49553+49585+49617+49649+49681+49713+49745+49777+49809+49841+49873+49905+49937+49969+50001+50033+50065+50097+50129+50161+50193+50225+50257+50289+50321+50353+50385+50417+50449+50481+50513+50545+50577+50609+50641+50673+50705+50737+50769+50801+50833+50865+50897+50929+50961+50993+51025+51057+51089+51121+51153+51185+51217+51249+51281+51313+51345+51377+51409+51441+51473+51505+51537+51569+51601+51633+51665+51697+51729+51761+51793+51825+51857+51889+51921+51953+51985+52017+52049+52081+52113+52145+52177+52209+52241+52273+52305+52337+52369+52401+52433+52465+52497+52529+52561+52593+52625+52657+52689+52721+52753+52785+52817+52849+52881+52913+52945+52977+53009+53041+53073+53105+53137+53169+53201+53233+53265+53297+53329+53361+53393+53425+53457+53489+53521+53553+53585+53617+53649+53681+53713+53745+53777+53809+53841+53873+53905+53937+53969+54001+54033+54065+54097+54129+54161+54193+54225+54257+54289+54321+54353+54385+54417+54449+54481+54513+54545+54577+54609+54641+54673+54705+54737+54769+54801+54833+54865+54897+54929+54961+54993+55025+55057+55089+55121+55153+55185+55217+55249+55281+55313+55345+55377+55409+55441+55473+55505+55537+55569+55601+55633+55665+55697+55729+55761+55793+55825+55857+55889+55921+55953+55985+56017+56049+56081+56113+56145+56177+56209+56241+56273+56305+56337+56369+56401+56433+56465+56497+56529+56561+56593+56625+56657+56689+56721+56753+56785+56817+56849+56881+56913+56945+56977+57009+57041+57073+57105+57137+57169+57201+57233+57265+57297+57329,49170+49202+49234+49266+49298+49330+49362+49394+49426+49458+49490+49522+49554+49586+49618+49650+49682+49714+49746+49778+49810+49842+49874+49906+49938+49970+50002+50034+50066+50098+50130+50162+50194+50226+50258+50290+50322+50354+50386+50418+50450+50482+50514+50546+50578+50610+50642+50674+50706+50738+50770+50802+50834+50866+50898+50930+50962+50994+51026+51058+51090+51122+51154+51186+51218+51250+51282+51314+51346+51378+51410+51442+51474+51506+51538+51570+51602+51634+51666+51698+51730+51762+51794+51826+51858+51890+51922+51954+51986+52018+52050+52082+52114+52146+52178+52210+52242+52274+52306+52338+52370+52402+52434+52466+52498+52530+52562+52594+52626+52658+52690+52722+52754+52786+52818+52850+52882+52914+52946+52978+53010+53042+53074+53106+53138+53170+53202+53234+53266+53298+53330+53362+53394+53426+53458+53490+53522+53554+53586+53618+53650+53682+53714+53746+53778+53810+53842+53874+53906+53938+53970+54002+54034+54066+54098+54130+54162+54194+54226+54258+54290+54322+54354+54386+54418+54450+54482+54514+54546+54578+54610+54642+54674+54706+54738+54770+54802+54834+54866+54898+54930+54962+54994+55026+55058+55090+55122+55154+55186+55218+55250+55282+55314+55346+55378+55410+55442+55474+55506+55538+55570+55602+55634+55666+55698+55730+55762+55794+55826+55858+55890+55922+55954+55986+56018+56050+56082+56114+56146+56178+56210+56242+56274+56306+56338+56370+56402+56434+56466+56498+56530+56562+56594+56626+56658+56690+56722+56754+56786+56818+56850+56882+56914+56946+56978+57010+57042+57074+57106+57138+57170+57202+57234+57266+57298+57330,49171+49203+49235+49267+49299+49331+49363+49395+49427+49459+49491+49523+49555+49587+49619+49651+49683+49715+49747+49779+49811+49843+49875+49907+49939+49971+50003+50035+50067+50099+50131+50163+50195+50227+50259+50291+50323+50355+50387+50419+50451+50483+50515+50547+50579+50611+50643+50675+50707+50739+50771+50803+50835+50867+50899+50931+50963+50995+51027+51059+51091+51123+51155+51187+51219+51251+51283+51315+51347+51379+51411+51443+51475+51507+51539+51571+51603+51635+51667+51699+51731+51763+51795+51827+51859+51891+51923+51955+51987+52019+52051+52083+52115+52147+52179+52211+52243+52275+52307+52339+52371+52403+52435+52467+52499+52531+52563+52595+52627+52659+52691+52723+52755+52787+52819+52851+52883+52915+52947+52979+53011+53043+53075+53107+53139+53171+53203+53235+53267+53299+53331+53363+53395+53427+53459+53491+53523+53555+53587+53619+53651+53683+53715+53747+53779+53811+53843+53875+53907+53939+53971+54003+54035+54067+54099+54131+54163+54195+54227+54259+54291+54323+54355+54387+54419+54451+54483+54515+54547+54579+54611+54643+54675+54707+54739+54771+54803+54835+54867+54899+54931+54963+54995+55027+55059+55091+55123+55155+55187+55219+55251+55283+55315+55347+55379+55411+55443+55475+55507+55539+55571+55603+55635+55667+55699+55731+55763+55795+55827+55859+55891+55923+55955+55987+56019+56051+56083+56115+56147+56179+56211+56243+56275+56307+56339+56371+56403+56435+56467+56499+56531+56563+56595+56627+56659+56691+56723+56755+56787+56819+56851+56883+56915+56947+56979+57011+57043+57075+57107+57139+57171+57203+57235+57267+57299+57331,49172+49204+49236+49268+49300+49332+49364+49396+49428+49460+49492+49524+49556+49588+49620+49652+49684+49716+49748+49780+49812+49844+49876+49908+49940+49972+50004+50036+50068+50100+50132+50164+50196+50228+50260+50292+50324+50356+50388+50420+50452+50484+50516+50548+50580+50612+50644+50676+50708+50740+50772+50804+50836+50868+50900+50932+50964+50996+51028+51060+51092+51124+51156+51188+51220+51252+51284+51316+51348+51380+51412+51444+51476+51508+51540+51572+51604+51636+51668+51700+51732+51764+51796+51828+51860+51892+51924+51956+51988+52020+52052+52084+52116+52148+52180+52212+52244+52276+52308+52340+52372+52404+52436+52468+52500+52532+52564+52596+52628+52660+52692+52724+52756+52788+52820+52852+52884+52916+52948+52980+53012+53044+53076+53108+53140+53172+53204+53236+53268+53300+53332+53364+53396+53428+53460+53492+53524+53556+53588+53620+53652+53684+53716+53748+53780+53812+53844+53876+53908+53940+53972+54004+54036+54068+54100+54132+54164+54196+54228+54260+54292+54324+54356+54388+54420+54452+54484+54516+54548+54580+54612+54644+54676+54708+54740+54772+54804+54836+54868+54900+54932+54964+54996+55028+55060+55092+55124+55156+55188+55220+55252+55284+55316+55348+55380+55412+55444+55476+55508+55540+55572+55604+55636+55668+55700+55732+55764+55796+55828+55860+55892+55924+55956+55988+56020+56052+56084+56116+56148+56180+56212+56244+56276+56308+56340+56372+56404+56436+56468+56500+56532+56564+56596+56628+56660+56692+56724+56756+56788+56820+56852+56884+56916+56948+56980+57012+57044+57076+57108+57140+57172+57204+57236+57268+57300+57332,49173+49205+49237+49269+49301+49333+49365+49397+49429+49461+49493+49525+49557+49589+49621+49653+49685+49717+49749+49781+49813+49845+49877+49909+49941+49973+50005+50037+50069+50101+50133+50165+50197+50229+50261+50293+50325+50357+50389+50421+50453+50485+50517+50549+50581+50613+50645+50677+50709+50741+50773+50805+50837+50869+50901+50933+50965+50997+51029+51061+51093+51125+51157+51189+51221+51253+51285+51317+51349+51381+51413+51445+51477+51509+51541+51573+51605+51637+51669+51701+51733+51765+51797+51829+51861+51893+51925+51957+51989+52021+52053+52085+52117+52149+52181+52213+52245+52277+52309+52341+52373+52405+52437+52469+52501+52533+52565+52597+52629+52661+52693+52725+52757+52789+52821+52853+52885+52917+52949+52981+53013+53045+53077+53109+53141+53173+53205+53237+53269+53301+53333+53365+53397+53429+53461+53493+53525+53557+53589+53621+53653+53685+53717+53749+53781+53813+53845+53877+53909+53941+53973+54005+54037+54069+54101+54133+54165+54197+54229+54261+54293+54325+54357+54389+54421+54453+54485+54517+54549+54581+54613+54645+54677+54709+54741+54773+54805+54837+54869+54901+54933+54965+54997+55029+55061+55093+55125+55157+55189+55221+55253+55285+55317+55349+55381+55413+55445+55477+55509+55541+55573+55605+55637+55669+55701+55733+55765+55797+55829+55861+55893+55925+55957+55989+56021+56053+56085+56117+56149+56181+56213+56245+56277+56309+56341+56373+56405+56437+56469+56501+56533+56565+56597+56629+56661+56693+56725+56757+56789+56821+56853+56885+56917+56949+56981+57013+57045+57077+57109+57141+57173+57205+57237+57269+57301+57333,49174+49206+49238+49270+49302+49334+49366+49398+49430+49462+49494+49526+49558+49590+49622+49654+49686+49718+49750+49782+49814+49846+49878+49910+49942+49974+50006+50038+50070+50102+50134+50166+50198+50230+50262+50294+50326+50358+50390+50422+50454+50486+50518+50550+50582+50614+50646+50678+50710+50742+50774+50806+50838+50870+50902+50934+50966+50998+51030+51062+51094+51126+51158+51190+51222+51254+51286+51318+51350+51382+51414+51446+51478+51510+51542+51574+51606+51638+51670+51702+51734+51766+51798+51830+51862+51894+51926+51958+51990+52022+52054+52086+52118+52150+52182+52214+52246+52278+52310+52342+52374+52406+52438+52470+52502+52534+52566+52598+52630+52662+52694+52726+52758+52790+52822+52854+52886+52918+52950+52982+53014+53046+53078+53110+53142+53174+53206+53238+53270+53302+53334+53366+53398+53430+53462+53494+53526+53558+53590+53622+53654+53686+53718+53750+53782+53814+53846+53878+53910+53942+53974+54006+54038+54070+54102+54134+54166+54198+54230+54262+54294+54326+54358+54390+54422+54454+54486+54518+54550+54582+54614+54646+54678+54710+54742+54774+54806+54838+54870+54902+54934+54966+54998+55030+55062+55094+55126+55158+55190+55222+55254+55286+55318+55350+55382+55414+55446+55478+55510+55542+55574+55606+55638+55670+55702+55734+55766+55798+55830+55862+55894+55926+55958+55990+56022+56054+56086+56118+56150+56182+56214+56246+56278+56310+56342+56374+56406+56438+56470+56502+56534+56566+56598+56630+56662+56694+56726+56758+56790+56822+56854+56886+56918+56950+56982+57014+57046+57078+57110+57142+57174+57206+57238+57270+57302+57334,49175+49207+49239+49271+49303+49335+49367+49399+49431+49463+49495+49527+49559+49591+49623+49655+49687+49719+49751+49783+49815+49847+49879+49911+49943+49975+50007+50039+50071+50103+50135+50167+50199+50231+50263+50295+50327+50359+50391+50423+50455+50487+50519+50551+50583+50615+50647+50679+50711+50743+50775+50807+50839+50871+50903+50935+50967+50999+51031+51063+51095+51127+51159+51191+51223+51255+51287+51319+51351+51383+51415+51447+51479+51511+51543+51575+51607+51639+51671+51703+51735+51767+51799+51831+51863+51895+51927+51959+51991+52023+52055+52087+52119+52151+52183+52215+52247+52279+52311+52343+52375+52407+52439+52471+52503+52535+52567+52599+52631+52663+52695+52727+52759+52791+52823+52855+52887+52919+52951+52983+53015+53047+53079+53111+53143+53175+53207+53239+53271+53303+53335+53367+53399+53431+53463+53495+53527+53559+53591+53623+53655+53687+53719+53751+53783+53815+53847+53879+53911+53943+53975+54007+54039+54071+54103+54135+54167+54199+54231+54263+54295+54327+54359+54391+54423+54455+54487+54519+54551+54583+54615+54647+54679+54711+54743+54775+54807+54839+54871+54903+54935+54967+54999+55031+55063+55095+55127+55159+55191+55223+55255+55287+55319+55351+55383+55415+55447+55479+55511+55543+55575+55607+55639+55671+55703+55735+55767+55799+55831+55863+55895+55927+55959+55991+56023+56055+56087+56119+56151+56183+56215+56247+56279+56311+56343+56375+56407+56439+56471+56503+56535+56567+56599+56631+56663+56695+56727+56759+56791+56823+56855+56887+56919+56951+56983+57015+57047+57079+57111+57143+57175+57207+57239+57271+57303+57335,49176+49208+49240+49272+49304+49336+49368+49400+49432+49464+49496+49528+49560+49592+49624+49656+49688+49720+49752+49784+49816+49848+49880+49912+49944+49976+50008+50040+50072+50104+50136+50168+50200+50232+50264+50296+50328+50360+50392+50424+50456+50488+50520+50552+50584+50616+50648+50680+50712+50744+50776+50808+50840+50872+50904+50936+50968+51000+51032+51064+51096+51128+51160+51192+51224+51256+51288+51320+51352+51384+51416+51448+51480+51512+51544+51576+51608+51640+51672+51704+51736+51768+51800+51832+51864+51896+51928+51960+51992+52024+52056+52088+52120+52152+52184+52216+52248+52280+52312+52344+52376+52408+52440+52472+52504+52536+52568+52600+52632+52664+52696+52728+52760+52792+52824+52856+52888+52920+52952+52984+53016+53048+53080+53112+53144+53176+53208+53240+53272+53304+53336+53368+53400+53432+53464+53496+53528+53560+53592+53624+53656+53688+53720+53752+53784+53816+53848+53880+53912+53944+53976+54008+54040+54072+54104+54136+54168+54200+54232+54264+54296+54328+54360+54392+54424+54456+54488+54520+54552+54584+54616+54648+54680+54712+54744+54776+54808+54840+54872+54904+54936+54968+55000+55032+55064+55096+55128+55160+55192+55224+55256+55288+55320+55352+55384+55416+55448+55480+55512+55544+55576+55608+55640+55672+55704+55736+55768+55800+55832+55864+55896+55928+55960+55992+56024+56056+56088+56120+56152+56184+56216+56248+56280+56312+56344+56376+56408+56440+56472+56504+56536+56568+56600+56632+56664+56696+56728+56760+56792+56824+56856+56888+56920+56952+56984+57016+57048+57080+57112+57144+57176+57208+57240+57272+57304+57336,49177+49209+49241+49273+49305+49337+49369+49401+49433+49465+49497+49529+49561+49593+49625+49657+49689+49721+49753+49785+49817+49849+49881+49913+49945+49977+50009+50041+50073+50105+50137+50169+50201+50233+50265+50297+50329+50361+50393+50425+50457+50489+50521+50553+50585+50617+50649+50681+50713+50745+50777+50809+50841+50873+50905+50937+50969+51001+51033+51065+51097+51129+51161+51193+51225+51257+51289+51321+51353+51385+51417+51449+51481+51513+51545+51577+51609+51641+51673+51705+51737+51769+51801+51833+51865+51897+51929+51961+51993+52025+52057+52089+52121+52153+52185+52217+52249+52281+52313+52345+52377+52409+52441+52473+52505+52537+52569+52601+52633+52665+52697+52729+52761+52793+52825+52857+52889+52921+52953+52985+53017+53049+53081+53113+53145+53177+53209+53241+53273+53305+53337+53369+53401+53433+53465+53497+53529+53561+53593+53625+53657+53689+53721+53753+53785+53817+53849+53881+53913+53945+53977+54009+54041+54073+54105+54137+54169+54201+54233+54265+54297+54329+54361+54393+54425+54457+54489+54521+54553+54585+54617+54649+54681+54713+54745+54777+54809+54841+54873+54905+54937+54969+55001+55033+55065+55097+55129+55161+55193+55225+55257+55289+55321+55353+55385+55417+55449+55481+55513+55545+55577+55609+55641+55673+55705+55737+55769+55801+55833+55865+55897+55929+55961+55993+56025+56057+56089+56121+56153+56185+56217+56249+56281+56313+56345+56377+56409+56441+56473+56505+56537+56569+56601+56633+56665+56697+56729+56761+56793+56825+56857+56889+56921+56953+56985+57017+57049+57081+57113+57145+57177+57209+57241+57273+57305+57337,49178+49210+49242+49274+49306+49338+49370+49402+49434+49466+49498+49530+49562+49594+49626+49658+49690+49722+49754+49786+49818+49850+49882+49914+49946+49978+50010+50042+50074+50106+50138+50170+50202+50234+50266+50298+50330+50362+50394+50426+50458+50490+50522+50554+50586+50618+50650+50682+50714+50746+50778+50810+50842+50874+50906+50938+50970+51002+51034+51066+51098+51130+51162+51194+51226+51258+51290+51322+51354+51386+51418+51450+51482+51514+51546+51578+51610+51642+51674+51706+51738+51770+51802+51834+51866+51898+51930+51962+51994+52026+52058+52090+52122+52154+52186+52218+52250+52282+52314+52346+52378+52410+52442+52474+52506+52538+52570+52602+52634+52666+52698+52730+52762+52794+52826+52858+52890+52922+52954+52986+53018+53050+53082+53114+53146+53178+53210+53242+53274+53306+53338+53370+53402+53434+53466+53498+53530+53562+53594+53626+53658+53690+53722+53754+53786+53818+53850+53882+53914+53946+53978+54010+54042+54074+54106+54138+54170+54202+54234+54266+54298+54330+54362+54394+54426+54458+54490+54522+54554+54586+54618+54650+54682+54714+54746+54778+54810+54842+54874+54906+54938+54970+55002+55034+55066+55098+55130+55162+55194+55226+55258+55290+55322+55354+55386+55418+55450+55482+55514+55546+55578+55610+55642+55674+55706+55738+55770+55802+55834+55866+55898+55930+55962+55994+56026+56058+56090+56122+56154+56186+56218+56250+56282+56314+56346+56378+56410+56442+56474+56506+56538+56570+56602+56634+56666+56698+56730+56762+56794+56826+56858+56890+56922+56954+56986+57018+57050+57082+57114+57146+57178+57210+57242+57274+57306+57338,49179+49211+49243+49275+49307+49339+49371+49403+49435+49467+49499+49531+49563+49595+49627+49659+49691+49723+49755+49787+49819+49851+49883+49915+49947+49979+50011+50043+50075+50107+50139+50171+50203+50235+50267+50299+50331+50363+50395+50427+50459+50491+50523+50555+50587+50619+50651+50683+50715+50747+50779+50811+50843+50875+50907+50939+50971+51003+51035+51067+51099+51131+51163+51195+51227+51259+51291+51323+51355+51387+51419+51451+51483+51515+51547+51579+51611+51643+51675+51707+51739+51771+51803+51835+51867+51899+51931+51963+51995+52027+52059+52091+52123+52155+52187+52219+52251+52283+52315+52347+52379+52411+52443+52475+52507+52539+52571+52603+52635+52667+52699+52731+52763+52795+52827+52859+52891+52923+52955+52987+53019+53051+53083+53115+53147+53179+53211+53243+53275+53307+53339+53371+53403+53435+53467+53499+53531+53563+53595+53627+53659+53691+53723+53755+53787+53819+53851+53883+53915+53947+53979+54011+54043+54075+54107+54139+54171+54203+54235+54267+54299+54331+54363+54395+54427+54459+54491+54523+54555+54587+54619+54651+54683+54715+54747+54779+54811+54843+54875+54907+54939+54971+55003+55035+55067+55099+55131+55163+55195+55227+55259+55291+55323+55355+55387+55419+55451+55483+55515+55547+55579+55611+55643+55675+55707+55739+55771+55803+55835+55867+55899+55931+55963+55995+56027+56059+56091+56123+56155+56187+56219+56251+56283+56315+56347+56379+56411+56443+56475+56507+56539+56571+56603+56635+56667+56699+56731+56763+56795+56827+56859+56891+56923+56955+56987+57019+57051+57083+57115+57147+57179+57211+57243+57275+57307+57339,49180+49212+49244+49276+49308+49340+49372+49404+49436+49468+49500+49532+49564+49596+49628+49660+49692+49724+49756+49788+49820+49852+49884+49916+49948+49980+50012+50044+50076+50108+50140+50172+50204+50236+50268+50300+50332+50364+50396+50428+50460+50492+50524+50556+50588+50620+50652+50684+50716+50748+50780+50812+50844+50876+50908+50940+50972+51004+51036+51068+51100+51132+51164+51196+51228+51260+51292+51324+51356+51388+51420+51452+51484+51516+51548+51580+51612+51644+51676+51708+51740+51772+51804+51836+51868+51900+51932+51964+51996+52028+52060+52092+52124+52156+52188+52220+52252+52284+52316+52348+52380+52412+52444+52476+52508+52540+52572+52604+52636+52668+52700+52732+52764+52796+52828+52860+52892+52924+52956+52988+53020+53052+53084+53116+53148+53180+53212+53244+53276+53308+53340+53372+53404+53436+53468+53500+53532+53564+53596+53628+53660+53692+53724+53756+53788+53820+53852+53884+53916+53948+53980+54012+54044+54076+54108+54140+54172+54204+54236+54268+54300+54332+54364+54396+54428+54460+54492+54524+54556+54588+54620+54652+54684+54716+54748+54780+54812+54844+54876+54908+54940+54972+55004+55036+55068+55100+55132+55164+55196+55228+55260+55292+55324+55356+55388+55420+55452+55484+55516+55548+55580+55612+55644+55676+55708+55740+55772+55804+55836+55868+55900+55932+55964+55996+56028+56060+56092+56124+56156+56188+56220+56252+56284+56316+56348+56380+56412+56444+56476+56508+56540+56572+56604+56636+56668+56700+56732+56764+56796+56828+56860+56892+56924+56956+56988+57020+57052+57084+57116+57148+57180+57212+57244+57276+57308+57340,49181+49213+49245+49277+49309+49341+49373+49405+49437+49469+49501+49533+49565+49597+49629+49661+49693+49725+49757+49789+49821+49853+49885+49917+49949+49981+50013+50045+50077+50109+50141+50173+50205+50237+50269+50301+50333+50365+50397+50429+50461+50493+50525+50557+50589+50621+50653+50685+50717+50749+50781+50813+50845+50877+50909+50941+50973+51005+51037+51069+51101+51133+51165+51197+51229+51261+51293+51325+51357+51389+51421+51453+51485+51517+51549+51581+51613+51645+51677+51709+51741+51773+51805+51837+51869+51901+51933+51965+51997+52029+52061+52093+52125+52157+52189+52221+52253+52285+52317+52349+52381+52413+52445+52477+52509+52541+52573+52605+52637+52669+52701+52733+52765+52797+52829+52861+52893+52925+52957+52989+53021+53053+53085+53117+53149+53181+53213+53245+53277+53309+53341+53373+53405+53437+53469+53501+53533+53565+53597+53629+53661+53693+53725+53757+53789+53821+53853+53885+53917+53949+53981+54013+54045+54077+54109+54141+54173+54205+54237+54269+54301+54333+54365+54397+54429+54461+54493+54525+54557+54589+54621+54653+54685+54717+54749+54781+54813+54845+54877+54909+54941+54973+55005+55037+55069+55101+55133+55165+55197+55229+55261+55293+55325+55357+55389+55421+55453+55485+55517+55549+55581+55613+55645+55677+55709+55741+55773+55805+55837+55869+55901+55933+55965+55997+56029+56061+56093+56125+56157+56189+56221+56253+56285+56317+56349+56381+56413+56445+56477+56509+56541+56573+56605+56637+56669+56701+56733+56765+56797+56829+56861+56893+56925+56957+56989+57021+57053+57085+57117+57149+57181+57213+57245+57277+57309+57341,49182+49214+49246+49278+49310+49342+49374+49406+49438+49470+49502+49534+49566+49598+49630+49662+49694+49726+49758+49790+49822+49854+49886+49918+49950+49982+50014+50046+50078+50110+50142+50174+50206+50238+50270+50302+50334+50366+50398+50430+50462+50494+50526+50558+50590+50622+50654+50686+50718+50750+50782+50814+50846+50878+50910+50942+50974+51006+51038+51070+51102+51134+51166+51198+51230+51262+51294+51326+51358+51390+51422+51454+51486+51518+51550+51582+51614+51646+51678+51710+51742+51774+51806+51838+51870+51902+51934+51966+51998+52030+52062+52094+52126+52158+52190+52222+52254+52286+52318+52350+52382+52414+52446+52478+52510+52542+52574+52606+52638+52670+52702+52734+52766+52798+52830+52862+52894+52926+52958+52990+53022+53054+53086+53118+53150+53182+53214+53246+53278+53310+53342+53374+53406+53438+53470+53502+53534+53566+53598+53630+53662+53694+53726+53758+53790+53822+53854+53886+53918+53950+53982+54014+54046+54078+54110+54142+54174+54206+54238+54270+54302+54334+54366+54398+54430+54462+54494+54526+54558+54590+54622+54654+54686+54718+54750+54782+54814+54846+54878+54910+54942+54974+55006+55038+55070+55102+55134+55166+55198+55230+55262+55294+55326+55358+55390+55422+55454+55486+55518+55550+55582+55614+55646+55678+55710+55742+55774+55806+55838+55870+55902+55934+55966+55998+56030+56062+56094+56126+56158+56190+56222+56254+56286+56318+56350+56382+56414+56446+56478+56510+56542+56574+56606+56638+56670+56702+56734+56766+56798+56830+56862+56894+56926+56958+56990+57022+57054+57086+57118+57150+57182+57214+57246+57278+57310+57342,49183+49215+49247+49279+49311+49343+49375+49407+49439+49471+49503+49535+49567+49599+49631+49663+49695+49727+49759+49791+49823+49855+49887+49919+49951+49983+50015+50047+50079+50111+50143+50175+50207+50239+50271+50303+50335+50367+50399+50431+50463+50495+50527+50559+50591+50623+50655+50687+50719+50751+50783+50815+50847+50879+50911+50943+50975+51007+51039+51071+51103+51135+51167+51199+51231+51263+51295+51327+51359+51391+51423+51455+51487+51519+51551+51583+51615+51647+51679+51711+51743+51775+51807+51839+51871+51903+51935+51967+51999+52031+52063+52095+52127+52159+52191+52223+52255+52287+52319+52351+52383+52415+52447+52479+52511+52543+52575+52607+52639+52671+52703+52735+52767+52799+52831+52863+52895+52927+52959+52991+53023+53055+53087+53119+53151+53183+53215+53247+53279+53311+53343+53375+53407+53439+53471+53503+53535+53567+53599+53631+53663+53695+53727+53759+53791+53823+53855+53887+53919+53951+53983+54015+54047+54079+54111+54143+54175+54207+54239+54271+54303+54335+54367+54399+54431+54463+54495+54527+54559+54591+54623+54655+54687+54719+54751+54783+54815+54847+54879+54911+54943+54975+55007+55039+55071+55103+55135+55167+55199+55231+55263+55295+55327+55359+55391+55423+55455+55487+55519+55551+55583+55615+55647+55679+55711+55743+55775+55807+55839+55871+55903+55935+55967+55999+56031+56063+56095+56127+56159+56191+56223+56255+56287+56319+56351+56383+56415+56447+56479+56511+56543+56575+56607+56639+56671+56703+56735+56767+56799+56831+56863+56895+56927+56959+56991+57023+57055+57087+57119+57151+57183+57215+57247+57279+57311+57343,57344+57376+57408+57440+57472+57504+57536+57568+57600+57632+57664+57696+57728+57760+57792+57824+57856+57888+57920+57952+57984+58016+58048+58080+58112+58144+58176+58208+58240+58272+58304+58336+58368+58400+58432+58464+58496+58528+58560+58592+58624+58656+58688+58720+58752+58784+58816+58848+58880+58912+58944+58976+59008+59040+59072+59104+59136+59168+59200+59232+59264+59296+59328+59360+59392+59424+59456+59488+59520+59552+59584+59616+59648+59680+59712+59744+59776+59808+59840+59872+59904+59936+59968+60000+60032+60064+60096+60128+60160+60192+60224+60256+60288+60320+60352+60384+60416+60448+60480+60512+60544+60576+60608+60640+60672+60704+60736+60768+60800+60832+60864+60896+60928+60960+60992+61024+61056+61088+61120+61152+61184+61216+61248+61280+61312+61344+61376+61408+61440+61472+61504+61536+61568+61600+61632+61664+61696+61728+61760+61792+61824+61856+61888+61920+61952+61984+62016+62048+62080+62112+62144+62176+62208+62240+62272+62304+62336+62368+62400+62432+62464+62496+62528+62560+62592+62624+62656+62688+62720+62752+62784+62816+62848+62880+62912+62944+62976+63008+63040+63072+63104+63136+63168+63200+63232+63264+63296+63328+63360+63392+63424+63456+63488+63520+63552+63584+63616+63648+63680+63712+63744+63776+63808+63840+63872+63904+63936+63968+64000+64032+64064+64096+64128+64160+64192+64224+64256+64288+64320+64352+64384+64416+64448+64480+64512+64544+64576+64608+64640+64672+64704+64736+64768+64800+64832+64864+64896+64928+64960+64992+65024+65056+65088+65120+65152+65184+65216+65248+65280+65312+65344+65376+65408+65440+65472+65504,57345+57377+57409+57441+57473+57505+57537+57569+57601+57633+57665+57697+57729+57761+57793+57825+57857+57889+57921+57953+57985+58017+58049+58081+58113+58145+58177+58209+58241+58273+58305+58337+58369+58401+58433+58465+58497+58529+58561+58593+58625+58657+58689+58721+58753+58785+58817+58849+58881+58913+58945+58977+59009+59041+59073+59105+59137+59169+59201+59233+59265+59297+59329+59361+59393+59425+59457+59489+59521+59553+59585+59617+59649+59681+59713+59745+59777+59809+59841+59873+59905+59937+59969+60001+60033+60065+60097+60129+60161+60193+60225+60257+60289+60321+60353+60385+60417+60449+60481+60513+60545+60577+60609+60641+60673+60705+60737+60769+60801+60833+60865+60897+60929+60961+60993+61025+61057+61089+61121+61153+61185+61217+61249+61281+61313+61345+61377+61409+61441+61473+61505+61537+61569+61601+61633+61665+61697+61729+61761+61793+61825+61857+61889+61921+61953+61985+62017+62049+62081+62113+62145+62177+62209+62241+62273+62305+62337+62369+62401+62433+62465+62497+62529+62561+62593+62625+62657+62689+62721+62753+62785+62817+62849+62881+62913+62945+62977+63009+63041+63073+63105+63137+63169+63201+63233+63265+63297+63329+63361+63393+63425+63457+63489+63521+63553+63585+63617+63649+63681+63713+63745+63777+63809+63841+63873+63905+63937+63969+64001+64033+64065+64097+64129+64161+64193+64225+64257+64289+64321+64353+64385+64417+64449+64481+64513+64545+64577+64609+64641+64673+64705+64737+64769+64801+64833+64865+64897+64929+64961+64993+65025+65057+65089+65121+65153+65185+65217+65249+65281+65313+65345+65377+65409+65441+65473+65505,57346+57378+57410+57442+57474+57506+57538+57570+57602+57634+57666+57698+57730+57762+57794+57826+57858+57890+57922+57954+57986+58018+58050+58082+58114+58146+58178+58210+58242+58274+58306+58338+58370+58402+58434+58466+58498+58530+58562+58594+58626+58658+58690+58722+58754+58786+58818+58850+58882+58914+58946+58978+59010+59042+59074+59106+59138+59170+59202+59234+59266+59298+59330+59362+59394+59426+59458+59490+59522+59554+59586+59618+59650+59682+59714+59746+59778+59810+59842+59874+59906+59938+59970+60002+60034+60066+60098+60130+60162+60194+60226+60258+60290+60322+60354+60386+60418+60450+60482+60514+60546+60578+60610+60642+60674+60706+60738+60770+60802+60834+60866+60898+60930+60962+60994+61026+61058+61090+61122+61154+61186+61218+61250+61282+61314+61346+61378+61410+61442+61474+61506+61538+61570+61602+61634+61666+61698+61730+61762+61794+61826+61858+61890+61922+61954+61986+62018+62050+62082+62114+62146+62178+62210+62242+62274+62306+62338+62370+62402+62434+62466+62498+62530+62562+62594+62626+62658+62690+62722+62754+62786+62818+62850+62882+62914+62946+62978+63010+63042+63074+63106+63138+63170+63202+63234+63266+63298+63330+63362+63394+63426+63458+63490+63522+63554+63586+63618+63650+63682+63714+63746+63778+63810+63842+63874+63906+63938+63970+64002+64034+64066+64098+64130+64162+64194+64226+64258+64290+64322+64354+64386+64418+64450+64482+64514+64546+64578+64610+64642+64674+64706+64738+64770+64802+64834+64866+64898+64930+64962+64994+65026+65058+65090+65122+65154+65186+65218+65250+65282+65314+65346+65378+65410+65442+65474+65506,57347+57379+57411+57443+57475+57507+57539+57571+57603+57635+57667+57699+57731+57763+57795+57827+57859+57891+57923+57955+57987+58019+58051+58083+58115+58147+58179+58211+58243+58275+58307+58339+58371+58403+58435+58467+58499+58531+58563+58595+58627+58659+58691+58723+58755+58787+58819+58851+58883+58915+58947+58979+59011+59043+59075+59107+59139+59171+59203+59235+59267+59299+59331+59363+59395+59427+59459+59491+59523+59555+59587+59619+59651+59683+59715+59747+59779+59811+59843+59875+59907+59939+59971+60003+60035+60067+60099+60131+60163+60195+60227+60259+60291+60323+60355+60387+60419+60451+60483+60515+60547+60579+60611+60643+60675+60707+60739+60771+60803+60835+60867+60899+60931+60963+60995+61027+61059+61091+61123+61155+61187+61219+61251+61283+61315+61347+61379+61411+61443+61475+61507+61539+61571+61603+61635+61667+61699+61731+61763+61795+61827+61859+61891+61923+61955+61987+62019+62051+62083+62115+62147+62179+62211+62243+62275+62307+62339+62371+62403+62435+62467+62499+62531+62563+62595+62627+62659+62691+62723+62755+62787+62819+62851+62883+62915+62947+62979+63011+63043+63075+63107+63139+63171+63203+63235+63267+63299+63331+63363+63395+63427+63459+63491+63523+63555+63587+63619+63651+63683+63715+63747+63779+63811+63843+63875+63907+63939+63971+64003+64035+64067+64099+64131+64163+64195+64227+64259+64291+64323+64355+64387+64419+64451+64483+64515+64547+64579+64611+64643+64675+64707+64739+64771+64803+64835+64867+64899+64931+64963+64995+65027+65059+65091+65123+65155+65187+65219+65251+65283+65315+65347+65379+65411+65443+65475+65507,57348+57380+57412+57444+57476+57508+57540+57572+57604+57636+57668+57700+57732+57764+57796+57828+57860+57892+57924+57956+57988+58020+58052+58084+58116+58148+58180+58212+58244+58276+58308+58340+58372+58404+58436+58468+58500+58532+58564+58596+58628+58660+58692+58724+58756+58788+58820+58852+58884+58916+58948+58980+59012+59044+59076+59108+59140+59172+59204+59236+59268+59300+59332+59364+59396+59428+59460+59492+59524+59556+59588+59620+59652+59684+59716+59748+59780+59812+59844+59876+59908+59940+59972+60004+60036+60068+60100+60132+60164+60196+60228+60260+60292+60324+60356+60388+60420+60452+60484+60516+60548+60580+60612+60644+60676+60708+60740+60772+60804+60836+60868+60900+60932+60964+60996+61028+61060+61092+61124+61156+61188+61220+61252+61284+61316+61348+61380+61412+61444+61476+61508+61540+61572+61604+61636+61668+61700+61732+61764+61796+61828+61860+61892+61924+61956+61988+62020+62052+62084+62116+62148+62180+62212+62244+62276+62308+62340+62372+62404+62436+62468+62500+62532+62564+62596+62628+62660+62692+62724+62756+62788+62820+62852+62884+62916+62948+62980+63012+63044+63076+63108+63140+63172+63204+63236+63268+63300+63332+63364+63396+63428+63460+63492+63524+63556+63588+63620+63652+63684+63716+63748+63780+63812+63844+63876+63908+63940+63972+64004+64036+64068+64100+64132+64164+64196+64228+64260+64292+64324+64356+64388+64420+64452+64484+64516+64548+64580+64612+64644+64676+64708+64740+64772+64804+64836+64868+64900+64932+64964+64996+65028+65060+65092+65124+65156+65188+65220+65252+65284+65316+65348+65380+65412+65444+65476+65508,57349+57381+57413+57445+57477+57509+57541+57573+57605+57637+57669+57701+57733+57765+57797+57829+57861+57893+57925+57957+57989+58021+58053+58085+58117+58149+58181+58213+58245+58277+58309+58341+58373+58405+58437+58469+58501+58533+58565+58597+58629+58661+58693+58725+58757+58789+58821+58853+58885+58917+58949+58981+59013+59045+59077+59109+59141+59173+59205+59237+59269+59301+59333+59365+59397+59429+59461+59493+59525+59557+59589+59621+59653+59685+59717+59749+59781+59813+59845+59877+59909+59941+59973+60005+60037+60069+60101+60133+60165+60197+60229+60261+60293+60325+60357+60389+60421+60453+60485+60517+60549+60581+60613+60645+60677+60709+60741+60773+60805+60837+60869+60901+60933+60965+60997+61029+61061+61093+61125+61157+61189+61221+61253+61285+61317+61349+61381+61413+61445+61477+61509+61541+61573+61605+61637+61669+61701+61733+61765+61797+61829+61861+61893+61925+61957+61989+62021+62053+62085+62117+62149+62181+62213+62245+62277+62309+62341+62373+62405+62437+62469+62501+62533+62565+62597+62629+62661+62693+62725+62757+62789+62821+62853+62885+62917+62949+62981+63013+63045+63077+63109+63141+63173+63205+63237+63269+63301+63333+63365+63397+63429+63461+63493+63525+63557+63589+63621+63653+63685+63717+63749+63781+63813+63845+63877+63909+63941+63973+64005+64037+64069+64101+64133+64165+64197+64229+64261+64293+64325+64357+64389+64421+64453+64485+64517+64549+64581+64613+64645+64677+64709+64741+64773+64805+64837+64869+64901+64933+64965+64997+65029+65061+65093+65125+65157+65189+65221+65253+65285+65317+65349+65381+65413+65445+65477+65509,57350+57382+57414+57446+57478+57510+57542+57574+57606+57638+57670+57702+57734+57766+57798+57830+57862+57894+57926+57958+57990+58022+58054+58086+58118+58150+58182+58214+58246+58278+58310+58342+58374+58406+58438+58470+58502+58534+58566+58598+58630+58662+58694+58726+58758+58790+58822+58854+58886+58918+58950+58982+59014+59046+59078+59110+59142+59174+59206+59238+59270+59302+59334+59366+59398+59430+59462+59494+59526+59558+59590+59622+59654+59686+59718+59750+59782+59814+59846+59878+59910+59942+59974+60006+60038+60070+60102+60134+60166+60198+60230+60262+60294+60326+60358+60390+60422+60454+60486+60518+60550+60582+60614+60646+60678+60710+60742+60774+60806+60838+60870+60902+60934+60966+60998+61030+61062+61094+61126+61158+61190+61222+61254+61286+61318+61350+61382+61414+61446+61478+61510+61542+61574+61606+61638+61670+61702+61734+61766+61798+61830+61862+61894+61926+61958+61990+62022+62054+62086+62118+62150+62182+62214+62246+62278+62310+62342+62374+62406+62438+62470+62502+62534+62566+62598+62630+62662+62694+62726+62758+62790+62822+62854+62886+62918+62950+62982+63014+63046+63078+63110+63142+63174+63206+63238+63270+63302+63334+63366+63398+63430+63462+63494+63526+63558+63590+63622+63654+63686+63718+63750+63782+63814+63846+63878+63910+63942+63974+64006+64038+64070+64102+64134+64166+64198+64230+64262+64294+64326+64358+64390+64422+64454+64486+64518+64550+64582+64614+64646+64678+64710+64742+64774+64806+64838+64870+64902+64934+64966+64998+65030+65062+65094+65126+65158+65190+65222+65254+65286+65318+65350+65382+65414+65446+65478+65510,57351+57383+57415+57447+57479+57511+57543+57575+57607+57639+57671+57703+57735+57767+57799+57831+57863+57895+57927+57959+57991+58023+58055+58087+58119+58151+58183+58215+58247+58279+58311+58343+58375+58407+58439+58471+58503+58535+58567+58599+58631+58663+58695+58727+58759+58791+58823+58855+58887+58919+58951+58983+59015+59047+59079+59111+59143+59175+59207+59239+59271+59303+59335+59367+59399+59431+59463+59495+59527+59559+59591+59623+59655+59687+59719+59751+59783+59815+59847+59879+59911+59943+59975+60007+60039+60071+60103+60135+60167+60199+60231+60263+60295+60327+60359+60391+60423+60455+60487+60519+60551+60583+60615+60647+60679+60711+60743+60775+60807+60839+60871+60903+60935+60967+60999+61031+61063+61095+61127+61159+61191+61223+61255+61287+61319+61351+61383+61415+61447+61479+61511+61543+61575+61607+61639+61671+61703+61735+61767+61799+61831+61863+61895+61927+61959+61991+62023+62055+62087+62119+62151+62183+62215+62247+62279+62311+62343+62375+62407+62439+62471+62503+62535+62567+62599+62631+62663+62695+62727+62759+62791+62823+62855+62887+62919+62951+62983+63015+63047+63079+63111+63143+63175+63207+63239+63271+63303+63335+63367+63399+63431+63463+63495+63527+63559+63591+63623+63655+63687+63719+63751+63783+63815+63847+63879+63911+63943+63975+64007+64039+64071+64103+64135+64167+64199+64231+64263+64295+64327+64359+64391+64423+64455+64487+64519+64551+64583+64615+64647+64679+64711+64743+64775+64807+64839+64871+64903+64935+64967+64999+65031+65063+65095+65127+65159+65191+65223+65255+65287+65319+65351+65383+65415+65447+65479+65511,57352+57384+57416+57448+57480+57512+57544+57576+57608+57640+57672+57704+57736+57768+57800+57832+57864+57896+57928+57960+57992+58024+58056+58088+58120+58152+58184+58216+58248+58280+58312+58344+58376+58408+58440+58472+58504+58536+58568+58600+58632+58664+58696+58728+58760+58792+58824+58856+58888+58920+58952+58984+59016+59048+59080+59112+59144+59176+59208+59240+59272+59304+59336+59368+59400+59432+59464+59496+59528+59560+59592+59624+59656+59688+59720+59752+59784+59816+59848+59880+59912+59944+59976+60008+60040+60072+60104+60136+60168+60200+60232+60264+60296+60328+60360+60392+60424+60456+60488+60520+60552+60584+60616+60648+60680+60712+60744+60776+60808+60840+60872+60904+60936+60968+61000+61032+61064+61096+61128+61160+61192+61224+61256+61288+61320+61352+61384+61416+61448+61480+61512+61544+61576+61608+61640+61672+61704+61736+61768+61800+61832+61864+61896+61928+61960+61992+62024+62056+62088+62120+62152+62184+62216+62248+62280+62312+62344+62376+62408+62440+62472+62504+62536+62568+62600+62632+62664+62696+62728+62760+62792+62824+62856+62888+62920+62952+62984+63016+63048+63080+63112+63144+63176+63208+63240+63272+63304+63336+63368+63400+63432+63464+63496+63528+63560+63592+63624+63656+63688+63720+63752+63784+63816+63848+63880+63912+63944+63976+64008+64040+64072+64104+64136+64168+64200+64232+64264+64296+64328+64360+64392+64424+64456+64488+64520+64552+64584+64616+64648+64680+64712+64744+64776+64808+64840+64872+64904+64936+64968+65000+65032+65064+65096+65128+65160+65192+65224+65256+65288+65320+65352+65384+65416+65448+65480+65512,57353+57385+57417+57449+57481+57513+57545+57577+57609+57641+57673+57705+57737+57769+57801+57833+57865+57897+57929+57961+57993+58025+58057+58089+58121+58153+58185+58217+58249+58281+58313+58345+58377+58409+58441+58473+58505+58537+58569+58601+58633+58665+58697+58729+58761+58793+58825+58857+58889+58921+58953+58985+59017+59049+59081+59113+59145+59177+59209+59241+59273+59305+59337+59369+59401+59433+59465+59497+59529+59561+59593+59625+59657+59689+59721+59753+59785+59817+59849+59881+59913+59945+59977+60009+60041+60073+60105+60137+60169+60201+60233+60265+60297+60329+60361+60393+60425+60457+60489+60521+60553+60585+60617+60649+60681+60713+60745+60777+60809+60841+60873+60905+60937+60969+61001+61033+61065+61097+61129+61161+61193+61225+61257+61289+61321+61353+61385+61417+61449+61481+61513+61545+61577+61609+61641+61673+61705+61737+61769+61801+61833+61865+61897+61929+61961+61993+62025+62057+62089+62121+62153+62185+62217+62249+62281+62313+62345+62377+62409+62441+62473+62505+62537+62569+62601+62633+62665+62697+62729+62761+62793+62825+62857+62889+62921+62953+62985+63017+63049+63081+63113+63145+63177+63209+63241+63273+63305+63337+63369+63401+63433+63465+63497+63529+63561+63593+63625+63657+63689+63721+63753+63785+63817+63849+63881+63913+63945+63977+64009+64041+64073+64105+64137+64169+64201+64233+64265+64297+64329+64361+64393+64425+64457+64489+64521+64553+64585+64617+64649+64681+64713+64745+64777+64809+64841+64873+64905+64937+64969+65001+65033+65065+65097+65129+65161+65193+65225+65257+65289+65321+65353+65385+65417+65449+65481+65513,57354+57386+57418+57450+57482+57514+57546+57578+57610+57642+57674+57706+57738+57770+57802+57834+57866+57898+57930+57962+57994+58026+58058+58090+58122+58154+58186+58218+58250+58282+58314+58346+58378+58410+58442+58474+58506+58538+58570+58602+58634+58666+58698+58730+58762+58794+58826+58858+58890+58922+58954+58986+59018+59050+59082+59114+59146+59178+59210+59242+59274+59306+59338+59370+59402+59434+59466+59498+59530+59562+59594+59626+59658+59690+59722+59754+59786+59818+59850+59882+59914+59946+59978+60010+60042+60074+60106+60138+60170+60202+60234+60266+60298+60330+60362+60394+60426+60458+60490+60522+60554+60586+60618+60650+60682+60714+60746+60778+60810+60842+60874+60906+60938+60970+61002+61034+61066+61098+61130+61162+61194+61226+61258+61290+61322+61354+61386+61418+61450+61482+61514+61546+61578+61610+61642+61674+61706+61738+61770+61802+61834+61866+61898+61930+61962+61994+62026+62058+62090+62122+62154+62186+62218+62250+62282+62314+62346+62378+62410+62442+62474+62506+62538+62570+62602+62634+62666+62698+62730+62762+62794+62826+62858+62890+62922+62954+62986+63018+63050+63082+63114+63146+63178+63210+63242+63274+63306+63338+63370+63402+63434+63466+63498+63530+63562+63594+63626+63658+63690+63722+63754+63786+63818+63850+63882+63914+63946+63978+64010+64042+64074+64106+64138+64170+64202+64234+64266+64298+64330+64362+64394+64426+64458+64490+64522+64554+64586+64618+64650+64682+64714+64746+64778+64810+64842+64874+64906+64938+64970+65002+65034+65066+65098+65130+65162+65194+65226+65258+65290+65322+65354+65386+65418+65450+65482+65514,57355+57387+57419+57451+57483+57515+57547+57579+57611+57643+57675+57707+57739+57771+57803+57835+57867+57899+57931+57963+57995+58027+58059+58091+58123+58155+58187+58219+58251+58283+58315+58347+58379+58411+58443+58475+58507+58539+58571+58603+58635+58667+58699+58731+58763+58795+58827+58859+58891+58923+58955+58987+59019+59051+59083+59115+59147+59179+59211+59243+59275+59307+59339+59371+59403+59435+59467+59499+59531+59563+59595+59627+59659+59691+59723+59755+59787+59819+59851+59883+59915+59947+59979+60011+60043+60075+60107+60139+60171+60203+60235+60267+60299+60331+60363+60395+60427+60459+60491+60523+60555+60587+60619+60651+60683+60715+60747+60779+60811+60843+60875+60907+60939+60971+61003+61035+61067+61099+61131+61163+61195+61227+61259+61291+61323+61355+61387+61419+61451+61483+61515+61547+61579+61611+61643+61675+61707+61739+61771+61803+61835+61867+61899+61931+61963+61995+62027+62059+62091+62123+62155+62187+62219+62251+62283+62315+62347+62379+62411+62443+62475+62507+62539+62571+62603+62635+62667+62699+62731+62763+62795+62827+62859+62891+62923+62955+62987+63019+63051+63083+63115+63147+63179+63211+63243+63275+63307+63339+63371+63403+63435+63467+63499+63531+63563+63595+63627+63659+63691+63723+63755+63787+63819+63851+63883+63915+63947+63979+64011+64043+64075+64107+64139+64171+64203+64235+64267+64299+64331+64363+64395+64427+64459+64491+64523+64555+64587+64619+64651+64683+64715+64747+64779+64811+64843+64875+64907+64939+64971+65003+65035+65067+65099+65131+65163+65195+65227+65259+65291+65323+65355+65387+65419+65451+65483+65515,57356+57388+57420+57452+57484+57516+57548+57580+57612+57644+57676+57708+57740+57772+57804+57836+57868+57900+57932+57964+57996+58028+58060+58092+58124+58156+58188+58220+58252+58284+58316+58348+58380+58412+58444+58476+58508+58540+58572+58604+58636+58668+58700+58732+58764+58796+58828+58860+58892+58924+58956+58988+59020+59052+59084+59116+59148+59180+59212+59244+59276+59308+59340+59372+59404+59436+59468+59500+59532+59564+59596+59628+59660+59692+59724+59756+59788+59820+59852+59884+59916+59948+59980+60012+60044+60076+60108+60140+60172+60204+60236+60268+60300+60332+60364+60396+60428+60460+60492+60524+60556+60588+60620+60652+60684+60716+60748+60780+60812+60844+60876+60908+60940+60972+61004+61036+61068+61100+61132+61164+61196+61228+61260+61292+61324+61356+61388+61420+61452+61484+61516+61548+61580+61612+61644+61676+61708+61740+61772+61804+61836+61868+61900+61932+61964+61996+62028+62060+62092+62124+62156+62188+62220+62252+62284+62316+62348+62380+62412+62444+62476+62508+62540+62572+62604+62636+62668+62700+62732+62764+62796+62828+62860+62892+62924+62956+62988+63020+63052+63084+63116+63148+63180+63212+63244+63276+63308+63340+63372+63404+63436+63468+63500+63532+63564+63596+63628+63660+63692+63724+63756+63788+63820+63852+63884+63916+63948+63980+64012+64044+64076+64108+64140+64172+64204+64236+64268+64300+64332+64364+64396+64428+64460+64492+64524+64556+64588+64620+64652+64684+64716+64748+64780+64812+64844+64876+64908+64940+64972+65004+65036+65068+65100+65132+65164+65196+65228+65260+65292+65324+65356+65388+65420+65452+65484+65516,57357+57389+57421+57453+57485+57517+57549+57581+57613+57645+57677+57709+57741+57773+57805+57837+57869+57901+57933+57965+57997+58029+58061+58093+58125+58157+58189+58221+58253+58285+58317+58349+58381+58413+58445+58477+58509+58541+58573+58605+58637+58669+58701+58733+58765+58797+58829+58861+58893+58925+58957+58989+59021+59053+59085+59117+59149+59181+59213+59245+59277+59309+59341+59373+59405+59437+59469+59501+59533+59565+59597+59629+59661+59693+59725+59757+59789+59821+59853+59885+59917+59949+59981+60013+60045+60077+60109+60141+60173+60205+60237+60269+60301+60333+60365+60397+60429+60461+60493+60525+60557+60589+60621+60653+60685+60717+60749+60781+60813+60845+60877+60909+60941+60973+61005+61037+61069+61101+61133+61165+61197+61229+61261+61293+61325+61357+61389+61421+61453+61485+61517+61549+61581+61613+61645+61677+61709+61741+61773+61805+61837+61869+61901+61933+61965+61997+62029+62061+62093+62125+62157+62189+62221+62253+62285+62317+62349+62381+62413+62445+62477+62509+62541+62573+62605+62637+62669+62701+62733+62765+62797+62829+62861+62893+62925+62957+62989+63021+63053+63085+63117+63149+63181+63213+63245+63277+63309+63341+63373+63405+63437+63469+63501+63533+63565+63597+63629+63661+63693+63725+63757+63789+63821+63853+63885+63917+63949+63981+64013+64045+64077+64109+64141+64173+64205+64237+64269+64301+64333+64365+64397+64429+64461+64493+64525+64557+64589+64621+64653+64685+64717+64749+64781+64813+64845+64877+64909+64941+64973+65005+65037+65069+65101+65133+65165+65197+65229+65261+65293+65325+65357+65389+65421+65453+65485+65517,57358+57390+57422+57454+57486+57518+57550+57582+57614+57646+57678+57710+57742+57774+57806+57838+57870+57902+57934+57966+57998+58030+58062+58094+58126+58158+58190+58222+58254+58286+58318+58350+58382+58414+58446+58478+58510+58542+58574+58606+58638+58670+58702+58734+58766+58798+58830+58862+58894+58926+58958+58990+59022+59054+59086+59118+59150+59182+59214+59246+59278+59310+59342+59374+59406+59438+59470+59502+59534+59566+59598+59630+59662+59694+59726+59758+59790+59822+59854+59886+59918+59950+59982+60014+60046+60078+60110+60142+60174+60206+60238+60270+60302+60334+60366+60398+60430+60462+60494+60526+60558+60590+60622+60654+60686+60718+60750+60782+60814+60846+60878+60910+60942+60974+61006+61038+61070+61102+61134+61166+61198+61230+61262+61294+61326+61358+61390+61422+61454+61486+61518+61550+61582+61614+61646+61678+61710+61742+61774+61806+61838+61870+61902+61934+61966+61998+62030+62062+62094+62126+62158+62190+62222+62254+62286+62318+62350+62382+62414+62446+62478+62510+62542+62574+62606+62638+62670+62702+62734+62766+62798+62830+62862+62894+62926+62958+62990+63022+63054+63086+63118+63150+63182+63214+63246+63278+63310+63342+63374+63406+63438+63470+63502+63534+63566+63598+63630+63662+63694+63726+63758+63790+63822+63854+63886+63918+63950+63982+64014+64046+64078+64110+64142+64174+64206+64238+64270+64302+64334+64366+64398+64430+64462+64494+64526+64558+64590+64622+64654+64686+64718+64750+64782+64814+64846+64878+64910+64942+64974+65006+65038+65070+65102+65134+65166+65198+65230+65262+65294+65326+65358+65390+65422+65454+65486+65518,57359+57391+57423+57455+57487+57519+57551+57583+57615+57647+57679+57711+57743+57775+57807+57839+57871+57903+57935+57967+57999+58031+58063+58095+58127+58159+58191+58223+58255+58287+58319+58351+58383+58415+58447+58479+58511+58543+58575+58607+58639+58671+58703+58735+58767+58799+58831+58863+58895+58927+58959+58991+59023+59055+59087+59119+59151+59183+59215+59247+59279+59311+59343+59375+59407+59439+59471+59503+59535+59567+59599+59631+59663+59695+59727+59759+59791+59823+59855+59887+59919+59951+59983+60015+60047+60079+60111+60143+60175+60207+60239+60271+60303+60335+60367+60399+60431+60463+60495+60527+60559+60591+60623+60655+60687+60719+60751+60783+60815+60847+60879+60911+60943+60975+61007+61039+61071+61103+61135+61167+61199+61231+61263+61295+61327+61359+61391+61423+61455+61487+61519+61551+61583+61615+61647+61679+61711+61743+61775+61807+61839+61871+61903+61935+61967+61999+62031+62063+62095+62127+62159+62191+62223+62255+62287+62319+62351+62383+62415+62447+62479+62511+62543+62575+62607+62639+62671+62703+62735+62767+62799+62831+62863+62895+62927+62959+62991+63023+63055+63087+63119+63151+63183+63215+63247+63279+63311+63343+63375+63407+63439+63471+63503+63535+63567+63599+63631+63663+63695+63727+63759+63791+63823+63855+63887+63919+63951+63983+64015+64047+64079+64111+64143+64175+64207+64239+64271+64303+64335+64367+64399+64431+64463+64495+64527+64559+64591+64623+64655+64687+64719+64751+64783+64815+64847+64879+64911+64943+64975+65007+65039+65071+65103+65135+65167+65199+65231+65263+65295+65327+65359+65391+65423+65455+65487+65519,57360+57392+57424+57456+57488+57520+57552+57584+57616+57648+57680+57712+57744+57776+57808+57840+57872+57904+57936+57968+58000+58032+58064+58096+58128+58160+58192+58224+58256+58288+58320+58352+58384+58416+58448+58480+58512+58544+58576+58608+58640+58672+58704+58736+58768+58800+58832+58864+58896+58928+58960+58992+59024+59056+59088+59120+59152+59184+59216+59248+59280+59312+59344+59376+59408+59440+59472+59504+59536+59568+59600+59632+59664+59696+59728+59760+59792+59824+59856+59888+59920+59952+59984+60016+60048+60080+60112+60144+60176+60208+60240+60272+60304+60336+60368+60400+60432+60464+60496+60528+60560+60592+60624+60656+60688+60720+60752+60784+60816+60848+60880+60912+60944+60976+61008+61040+61072+61104+61136+61168+61200+61232+61264+61296+61328+61360+61392+61424+61456+61488+61520+61552+61584+61616+61648+61680+61712+61744+61776+61808+61840+61872+61904+61936+61968+62000+62032+62064+62096+62128+62160+62192+62224+62256+62288+62320+62352+62384+62416+62448+62480+62512+62544+62576+62608+62640+62672+62704+62736+62768+62800+62832+62864+62896+62928+62960+62992+63024+63056+63088+63120+63152+63184+63216+63248+63280+63312+63344+63376+63408+63440+63472+63504+63536+63568+63600+63632+63664+63696+63728+63760+63792+63824+63856+63888+63920+63952+63984+64016+64048+64080+64112+64144+64176+64208+64240+64272+64304+64336+64368+64400+64432+64464+64496+64528+64560+64592+64624+64656+64688+64720+64752+64784+64816+64848+64880+64912+64944+64976+65008+65040+65072+65104+65136+65168+65200+65232+65264+65296+65328+65360+65392+65424+65456+65488+65520,57361+57393+57425+57457+57489+57521+57553+57585+57617+57649+57681+57713+57745+57777+57809+57841+57873+57905+57937+57969+58001+58033+58065+58097+58129+58161+58193+58225+58257+58289+58321+58353+58385+58417+58449+58481+58513+58545+58577+58609+58641+58673+58705+58737+58769+58801+58833+58865+58897+58929+58961+58993+59025+59057+59089+59121+59153+59185+59217+59249+59281+59313+59345+59377+59409+59441+59473+59505+59537+59569+59601+59633+59665+59697+59729+59761+59793+59825+59857+59889+59921+59953+59985+60017+60049+60081+60113+60145+60177+60209+60241+60273+60305+60337+60369+60401+60433+60465+60497+60529+60561+60593+60625+60657+60689+60721+60753+60785+60817+60849+60881+60913+60945+60977+61009+61041+61073+61105+61137+61169+61201+61233+61265+61297+61329+61361+61393+61425+61457+61489+61521+61553+61585+61617+61649+61681+61713+61745+61777+61809+61841+61873+61905+61937+61969+62001+62033+62065+62097+62129+62161+62193+62225+62257+62289+62321+62353+62385+62417+62449+62481+62513+62545+62577+62609+62641+62673+62705+62737+62769+62801+62833+62865+62897+62929+62961+62993+63025+63057+63089+63121+63153+63185+63217+63249+63281+63313+63345+63377+63409+63441+63473+63505+63537+63569+63601+63633+63665+63697+63729+63761+63793+63825+63857+63889+63921+63953+63985+64017+64049+64081+64113+64145+64177+64209+64241+64273+64305+64337+64369+64401+64433+64465+64497+64529+64561+64593+64625+64657+64689+64721+64753+64785+64817+64849+64881+64913+64945+64977+65009+65041+65073+65105+65137+65169+65201+65233+65265+65297+65329+65361+65393+65425+65457+65489+65521,57362+57394+57426+57458+57490+57522+57554+57586+57618+57650+57682+57714+57746+57778+57810+57842+57874+57906+57938+57970+58002+58034+58066+58098+58130+58162+58194+58226+58258+58290+58322+58354+58386+58418+58450+58482+58514+58546+58578+58610+58642+58674+58706+58738+58770+58802+58834+58866+58898+58930+58962+58994+59026+59058+59090+59122+59154+59186+59218+59250+59282+59314+59346+59378+59410+59442+59474+59506+59538+59570+59602+59634+59666+59698+59730+59762+59794+59826+59858+59890+59922+59954+59986+60018+60050+60082+60114+60146+60178+60210+60242+60274+60306+60338+60370+60402+60434+60466+60498+60530+60562+60594+60626+60658+60690+60722+60754+60786+60818+60850+60882+60914+60946+60978+61010+61042+61074+61106+61138+61170+61202+61234+61266+61298+61330+61362+61394+61426+61458+61490+61522+61554+61586+61618+61650+61682+61714+61746+61778+61810+61842+61874+61906+61938+61970+62002+62034+62066+62098+62130+62162+62194+62226+62258+62290+62322+62354+62386+62418+62450+62482+62514+62546+62578+62610+62642+62674+62706+62738+62770+62802+62834+62866+62898+62930+62962+62994+63026+63058+63090+63122+63154+63186+63218+63250+63282+63314+63346+63378+63410+63442+63474+63506+63538+63570+63602+63634+63666+63698+63730+63762+63794+63826+63858+63890+63922+63954+63986+64018+64050+64082+64114+64146+64178+64210+64242+64274+64306+64338+64370+64402+64434+64466+64498+64530+64562+64594+64626+64658+64690+64722+64754+64786+64818+64850+64882+64914+64946+64978+65010+65042+65074+65106+65138+65170+65202+65234+65266+65298+65330+65362+65394+65426+65458+65490+65522,57363+57395+57427+57459+57491+57523+57555+57587+57619+57651+57683+57715+57747+57779+57811+57843+57875+57907+57939+57971+58003+58035+58067+58099+58131+58163+58195+58227+58259+58291+58323+58355+58387+58419+58451+58483+58515+58547+58579+58611+58643+58675+58707+58739+58771+58803+58835+58867+58899+58931+58963+58995+59027+59059+59091+59123+59155+59187+59219+59251+59283+59315+59347+59379+59411+59443+59475+59507+59539+59571+59603+59635+59667+59699+59731+59763+59795+59827+59859+59891+59923+59955+59987+60019+60051+60083+60115+60147+60179+60211+60243+60275+60307+60339+60371+60403+60435+60467+60499+60531+60563+60595+60627+60659+60691+60723+60755+60787+60819+60851+60883+60915+60947+60979+61011+61043+61075+61107+61139+61171+61203+61235+61267+61299+61331+61363+61395+61427+61459+61491+61523+61555+61587+61619+61651+61683+61715+61747+61779+61811+61843+61875+61907+61939+61971+62003+62035+62067+62099+62131+62163+62195+62227+62259+62291+62323+62355+62387+62419+62451+62483+62515+62547+62579+62611+62643+62675+62707+62739+62771+62803+62835+62867+62899+62931+62963+62995+63027+63059+63091+63123+63155+63187+63219+63251+63283+63315+63347+63379+63411+63443+63475+63507+63539+63571+63603+63635+63667+63699+63731+63763+63795+63827+63859+63891+63923+63955+63987+64019+64051+64083+64115+64147+64179+64211+64243+64275+64307+64339+64371+64403+64435+64467+64499+64531+64563+64595+64627+64659+64691+64723+64755+64787+64819+64851+64883+64915+64947+64979+65011+65043+65075+65107+65139+65171+65203+65235+65267+65299+65331+65363+65395+65427+65459+65491+65523,57364+57396+57428+57460+57492+57524+57556+57588+57620+57652+57684+57716+57748+57780+57812+57844+57876+57908+57940+57972+58004+58036+58068+58100+58132+58164+58196+58228+58260+58292+58324+58356+58388+58420+58452+58484+58516+58548+58580+58612+58644+58676+58708+58740+58772+58804+58836+58868+58900+58932+58964+58996+59028+59060+59092+59124+59156+59188+59220+59252+59284+59316+59348+59380+59412+59444+59476+59508+59540+59572+59604+59636+59668+59700+59732+59764+59796+59828+59860+59892+59924+59956+59988+60020+60052+60084+60116+60148+60180+60212+60244+60276+60308+60340+60372+60404+60436+60468+60500+60532+60564+60596+60628+60660+60692+60724+60756+60788+60820+60852+60884+60916+60948+60980+61012+61044+61076+61108+61140+61172+61204+61236+61268+61300+61332+61364+61396+61428+61460+61492+61524+61556+61588+61620+61652+61684+61716+61748+61780+61812+61844+61876+61908+61940+61972+62004+62036+62068+62100+62132+62164+62196+62228+62260+62292+62324+62356+62388+62420+62452+62484+62516+62548+62580+62612+62644+62676+62708+62740+62772+62804+62836+62868+62900+62932+62964+62996+63028+63060+63092+63124+63156+63188+63220+63252+63284+63316+63348+63380+63412+63444+63476+63508+63540+63572+63604+63636+63668+63700+63732+63764+63796+63828+63860+63892+63924+63956+63988+64020+64052+64084+64116+64148+64180+64212+64244+64276+64308+64340+64372+64404+64436+64468+64500+64532+64564+64596+64628+64660+64692+64724+64756+64788+64820+64852+64884+64916+64948+64980+65012+65044+65076+65108+65140+65172+65204+65236+65268+65300+65332+65364+65396+65428+65460+65492+65524,57365+57397+57429+57461+57493+57525+57557+57589+57621+57653+57685+57717+57749+57781+57813+57845+57877+57909+57941+57973+58005+58037+58069+58101+58133+58165+58197+58229+58261+58293+58325+58357+58389+58421+58453+58485+58517+58549+58581+58613+58645+58677+58709+58741+58773+58805+58837+58869+58901+58933+58965+58997+59029+59061+59093+59125+59157+59189+59221+59253+59285+59317+59349+59381+59413+59445+59477+59509+59541+59573+59605+59637+59669+59701+59733+59765+59797+59829+59861+59893+59925+59957+59989+60021+60053+60085+60117+60149+60181+60213+60245+60277+60309+60341+60373+60405+60437+60469+60501+60533+60565+60597+60629+60661+60693+60725+60757+60789+60821+60853+60885+60917+60949+60981+61013+61045+61077+61109+61141+61173+61205+61237+61269+61301+61333+61365+61397+61429+61461+61493+61525+61557+61589+61621+61653+61685+61717+61749+61781+61813+61845+61877+61909+61941+61973+62005+62037+62069+62101+62133+62165+62197+62229+62261+62293+62325+62357+62389+62421+62453+62485+62517+62549+62581+62613+62645+62677+62709+62741+62773+62805+62837+62869+62901+62933+62965+62997+63029+63061+63093+63125+63157+63189+63221+63253+63285+63317+63349+63381+63413+63445+63477+63509+63541+63573+63605+63637+63669+63701+63733+63765+63797+63829+63861+63893+63925+63957+63989+64021+64053+64085+64117+64149+64181+64213+64245+64277+64309+64341+64373+64405+64437+64469+64501+64533+64565+64597+64629+64661+64693+64725+64757+64789+64821+64853+64885+64917+64949+64981+65013+65045+65077+65109+65141+65173+65205+65237+65269+65301+65333+65365+65397+65429+65461+65493+65525,57366+57398+57430+57462+57494+57526+57558+57590+57622+57654+57686+57718+57750+57782+57814+57846+57878+57910+57942+57974+58006+58038+58070+58102+58134+58166+58198+58230+58262+58294+58326+58358+58390+58422+58454+58486+58518+58550+58582+58614+58646+58678+58710+58742+58774+58806+58838+58870+58902+58934+58966+58998+59030+59062+59094+59126+59158+59190+59222+59254+59286+59318+59350+59382+59414+59446+59478+59510+59542+59574+59606+59638+59670+59702+59734+59766+59798+59830+59862+59894+59926+59958+59990+60022+60054+60086+60118+60150+60182+60214+60246+60278+60310+60342+60374+60406+60438+60470+60502+60534+60566+60598+60630+60662+60694+60726+60758+60790+60822+60854+60886+60918+60950+60982+61014+61046+61078+61110+61142+61174+61206+61238+61270+61302+61334+61366+61398+61430+61462+61494+61526+61558+61590+61622+61654+61686+61718+61750+61782+61814+61846+61878+61910+61942+61974+62006+62038+62070+62102+62134+62166+62198+62230+62262+62294+62326+62358+62390+62422+62454+62486+62518+62550+62582+62614+62646+62678+62710+62742+62774+62806+62838+62870+62902+62934+62966+62998+63030+63062+63094+63126+63158+63190+63222+63254+63286+63318+63350+63382+63414+63446+63478+63510+63542+63574+63606+63638+63670+63702+63734+63766+63798+63830+63862+63894+63926+63958+63990+64022+64054+64086+64118+64150+64182+64214+64246+64278+64310+64342+64374+64406+64438+64470+64502+64534+64566+64598+64630+64662+64694+64726+64758+64790+64822+64854+64886+64918+64950+64982+65014+65046+65078+65110+65142+65174+65206+65238+65270+65302+65334+65366+65398+65430+65462+65494+65526,57367+57399+57431+57463+57495+57527+57559+57591+57623+57655+57687+57719+57751+57783+57815+57847+57879+57911+57943+57975+58007+58039+58071+58103+58135+58167+58199+58231+58263+58295+58327+58359+58391+58423+58455+58487+58519+58551+58583+58615+58647+58679+58711+58743+58775+58807+58839+58871+58903+58935+58967+58999+59031+59063+59095+59127+59159+59191+59223+59255+59287+59319+59351+59383+59415+59447+59479+59511+59543+59575+59607+59639+59671+59703+59735+59767+59799+59831+59863+59895+59927+59959+59991+60023+60055+60087+60119+60151+60183+60215+60247+60279+60311+60343+60375+60407+60439+60471+60503+60535+60567+60599+60631+60663+60695+60727+60759+60791+60823+60855+60887+60919+60951+60983+61015+61047+61079+61111+61143+61175+61207+61239+61271+61303+61335+61367+61399+61431+61463+61495+61527+61559+61591+61623+61655+61687+61719+61751+61783+61815+61847+61879+61911+61943+61975+62007+62039+62071+62103+62135+62167+62199+62231+62263+62295+62327+62359+62391+62423+62455+62487+62519+62551+62583+62615+62647+62679+62711+62743+62775+62807+62839+62871+62903+62935+62967+62999+63031+63063+63095+63127+63159+63191+63223+63255+63287+63319+63351+63383+63415+63447+63479+63511+63543+63575+63607+63639+63671+63703+63735+63767+63799+63831+63863+63895+63927+63959+63991+64023+64055+64087+64119+64151+64183+64215+64247+64279+64311+64343+64375+64407+64439+64471+64503+64535+64567+64599+64631+64663+64695+64727+64759+64791+64823+64855+64887+64919+64951+64983+65015+65047+65079+65111+65143+65175+65207+65239+65271+65303+65335+65367+65399+65431+65463+65495+65527,57368+57400+57432+57464+57496+57528+57560+57592+57624+57656+57688+57720+57752+57784+57816+57848+57880+57912+57944+57976+58008+58040+58072+58104+58136+58168+58200+58232+58264+58296+58328+58360+58392+58424+58456+58488+58520+58552+58584+58616+58648+58680+58712+58744+58776+58808+58840+58872+58904+58936+58968+59000+59032+59064+59096+59128+59160+59192+59224+59256+59288+59320+59352+59384+59416+59448+59480+59512+59544+59576+59608+59640+59672+59704+59736+59768+59800+59832+59864+59896+59928+59960+59992+60024+60056+60088+60120+60152+60184+60216+60248+60280+60312+60344+60376+60408+60440+60472+60504+60536+60568+60600+60632+60664+60696+60728+60760+60792+60824+60856+60888+60920+60952+60984+61016+61048+61080+61112+61144+61176+61208+61240+61272+61304+61336+61368+61400+61432+61464+61496+61528+61560+61592+61624+61656+61688+61720+61752+61784+61816+61848+61880+61912+61944+61976+62008+62040+62072+62104+62136+62168+62200+62232+62264+62296+62328+62360+62392+62424+62456+62488+62520+62552+62584+62616+62648+62680+62712+62744+62776+62808+62840+62872+62904+62936+62968+63000+63032+63064+63096+63128+63160+63192+63224+63256+63288+63320+63352+63384+63416+63448+63480+63512+63544+63576+63608+63640+63672+63704+63736+63768+63800+63832+63864+63896+63928+63960+63992+64024+64056+64088+64120+64152+64184+64216+64248+64280+64312+64344+64376+64408+64440+64472+64504+64536+64568+64600+64632+64664+64696+64728+64760+64792+64824+64856+64888+64920+64952+64984+65016+65048+65080+65112+65144+65176+65208+65240+65272+65304+65336+65368+65400+65432+65464+65496+65528,57369+57401+57433+57465+57497+57529+57561+57593+57625+57657+57689+57721+57753+57785+57817+57849+57881+57913+57945+57977+58009+58041+58073+58105+58137+58169+58201+58233+58265+58297+58329+58361+58393+58425+58457+58489+58521+58553+58585+58617+58649+58681+58713+58745+58777+58809+58841+58873+58905+58937+58969+59001+59033+59065+59097+59129+59161+59193+59225+59257+59289+59321+59353+59385+59417+59449+59481+59513+59545+59577+59609+59641+59673+59705+59737+59769+59801+59833+59865+59897+59929+59961+59993+60025+60057+60089+60121+60153+60185+60217+60249+60281+60313+60345+60377+60409+60441+60473+60505+60537+60569+60601+60633+60665+60697+60729+60761+60793+60825+60857+60889+60921+60953+60985+61017+61049+61081+61113+61145+61177+61209+61241+61273+61305+61337+61369+61401+61433+61465+61497+61529+61561+61593+61625+61657+61689+61721+61753+61785+61817+61849+61881+61913+61945+61977+62009+62041+62073+62105+62137+62169+62201+62233+62265+62297+62329+62361+62393+62425+62457+62489+62521+62553+62585+62617+62649+62681+62713+62745+62777+62809+62841+62873+62905+62937+62969+63001+63033+63065+63097+63129+63161+63193+63225+63257+63289+63321+63353+63385+63417+63449+63481+63513+63545+63577+63609+63641+63673+63705+63737+63769+63801+63833+63865+63897+63929+63961+63993+64025+64057+64089+64121+64153+64185+64217+64249+64281+64313+64345+64377+64409+64441+64473+64505+64537+64569+64601+64633+64665+64697+64729+64761+64793+64825+64857+64889+64921+64953+64985+65017+65049+65081+65113+65145+65177+65209+65241+65273+65305+65337+65369+65401+65433+65465+65497+65529,57370+57402+57434+57466+57498+57530+57562+57594+57626+57658+57690+57722+57754+57786+57818+57850+57882+57914+57946+57978+58010+58042+58074+58106+58138+58170+58202+58234+58266+58298+58330+58362+58394+58426+58458+58490+58522+58554+58586+58618+58650+58682+58714+58746+58778+58810+58842+58874+58906+58938+58970+59002+59034+59066+59098+59130+59162+59194+59226+59258+59290+59322+59354+59386+59418+59450+59482+59514+59546+59578+59610+59642+59674+59706+59738+59770+59802+59834+59866+59898+59930+59962+59994+60026+60058+60090+60122+60154+60186+60218+60250+60282+60314+60346+60378+60410+60442+60474+60506+60538+60570+60602+60634+60666+60698+60730+60762+60794+60826+60858+60890+60922+60954+60986+61018+61050+61082+61114+61146+61178+61210+61242+61274+61306+61338+61370+61402+61434+61466+61498+61530+61562+61594+61626+61658+61690+61722+61754+61786+61818+61850+61882+61914+61946+61978+62010+62042+62074+62106+62138+62170+62202+62234+62266+62298+62330+62362+62394+62426+62458+62490+62522+62554+62586+62618+62650+62682+62714+62746+62778+62810+62842+62874+62906+62938+62970+63002+63034+63066+63098+63130+63162+63194+63226+63258+63290+63322+63354+63386+63418+63450+63482+63514+63546+63578+63610+63642+63674+63706+63738+63770+63802+63834+63866+63898+63930+63962+63994+64026+64058+64090+64122+64154+64186+64218+64250+64282+64314+64346+64378+64410+64442+64474+64506+64538+64570+64602+64634+64666+64698+64730+64762+64794+64826+64858+64890+64922+64954+64986+65018+65050+65082+65114+65146+65178+65210+65242+65274+65306+65338+65370+65402+65434+65466+65498+65530,57371+57403+57435+57467+57499+57531+57563+57595+57627+57659+57691+57723+57755+57787+57819+57851+57883+57915+57947+57979+58011+58043+58075+58107+58139+58171+58203+58235+58267+58299+58331+58363+58395+58427+58459+58491+58523+58555+58587+58619+58651+58683+58715+58747+58779+58811+58843+58875+58907+58939+58971+59003+59035+59067+59099+59131+59163+59195+59227+59259+59291+59323+59355+59387+59419+59451+59483+59515+59547+59579+59611+59643+59675+59707+59739+59771+59803+59835+59867+59899+59931+59963+59995+60027+60059+60091+60123+60155+60187+60219+60251+60283+60315+60347+60379+60411+60443+60475+60507+60539+60571+60603+60635+60667+60699+60731+60763+60795+60827+60859+60891+60923+60955+60987+61019+61051+61083+61115+61147+61179+61211+61243+61275+61307+61339+61371+61403+61435+61467+61499+61531+61563+61595+61627+61659+61691+61723+61755+61787+61819+61851+61883+61915+61947+61979+62011+62043+62075+62107+62139+62171+62203+62235+62267+62299+62331+62363+62395+62427+62459+62491+62523+62555+62587+62619+62651+62683+62715+62747+62779+62811+62843+62875+62907+62939+62971+63003+63035+63067+63099+63131+63163+63195+63227+63259+63291+63323+63355+63387+63419+63451+63483+63515+63547+63579+63611+63643+63675+63707+63739+63771+63803+63835+63867+63899+63931+63963+63995+64027+64059+64091+64123+64155+64187+64219+64251+64283+64315+64347+64379+64411+64443+64475+64507+64539+64571+64603+64635+64667+64699+64731+64763+64795+64827+64859+64891+64923+64955+64987+65019+65051+65083+65115+65147+65179+65211+65243+65275+65307+65339+65371+65403+65435+65467+65499+65531,57372+57404+57436+57468+57500+57532+57564+57596+57628+57660+57692+57724+57756+57788+57820+57852+57884+57916+57948+57980+58012+58044+58076+58108+58140+58172+58204+58236+58268+58300+58332+58364+58396+58428+58460+58492+58524+58556+58588+58620+58652+58684+58716+58748+58780+58812+58844+58876+58908+58940+58972+59004+59036+59068+59100+59132+59164+59196+59228+59260+59292+59324+59356+59388+59420+59452+59484+59516+59548+59580+59612+59644+59676+59708+59740+59772+59804+59836+59868+59900+59932+59964+59996+60028+60060+60092+60124+60156+60188+60220+60252+60284+60316+60348+60380+60412+60444+60476+60508+60540+60572+60604+60636+60668+60700+60732+60764+60796+60828+60860+60892+60924+60956+60988+61020+61052+61084+61116+61148+61180+61212+61244+61276+61308+61340+61372+61404+61436+61468+61500+61532+61564+61596+61628+61660+61692+61724+61756+61788+61820+61852+61884+61916+61948+61980+62012+62044+62076+62108+62140+62172+62204+62236+62268+62300+62332+62364+62396+62428+62460+62492+62524+62556+62588+62620+62652+62684+62716+62748+62780+62812+62844+62876+62908+62940+62972+63004+63036+63068+63100+63132+63164+63196+63228+63260+63292+63324+63356+63388+63420+63452+63484+63516+63548+63580+63612+63644+63676+63708+63740+63772+63804+63836+63868+63900+63932+63964+63996+64028+64060+64092+64124+64156+64188+64220+64252+64284+64316+64348+64380+64412+64444+64476+64508+64540+64572+64604+64636+64668+64700+64732+64764+64796+64828+64860+64892+64924+64956+64988+65020+65052+65084+65116+65148+65180+65212+65244+65276+65308+65340+65372+65404+65436+65468+65500+65532,57373+57405+57437+57469+57501+57533+57565+57597+57629+57661+57693+57725+57757+57789+57821+57853+57885+57917+57949+57981+58013+58045+58077+58109+58141+58173+58205+58237+58269+58301+58333+58365+58397+58429+58461+58493+58525+58557+58589+58621+58653+58685+58717+58749+58781+58813+58845+58877+58909+58941+58973+59005+59037+59069+59101+59133+59165+59197+59229+59261+59293+59325+59357+59389+59421+59453+59485+59517+59549+59581+59613+59645+59677+59709+59741+59773+59805+59837+59869+59901+59933+59965+59997+60029+60061+60093+60125+60157+60189+60221+60253+60285+60317+60349+60381+60413+60445+60477+60509+60541+60573+60605+60637+60669+60701+60733+60765+60797+60829+60861+60893+60925+60957+60989+61021+61053+61085+61117+61149+61181+61213+61245+61277+61309+61341+61373+61405+61437+61469+61501+61533+61565+61597+61629+61661+61693+61725+61757+61789+61821+61853+61885+61917+61949+61981+62013+62045+62077+62109+62141+62173+62205+62237+62269+62301+62333+62365+62397+62429+62461+62493+62525+62557+62589+62621+62653+62685+62717+62749+62781+62813+62845+62877+62909+62941+62973+63005+63037+63069+63101+63133+63165+63197+63229+63261+63293+63325+63357+63389+63421+63453+63485+63517+63549+63581+63613+63645+63677+63709+63741+63773+63805+63837+63869+63901+63933+63965+63997+64029+64061+64093+64125+64157+64189+64221+64253+64285+64317+64349+64381+64413+64445+64477+64509+64541+64573+64605+64637+64669+64701+64733+64765+64797+64829+64861+64893+64925+64957+64989+65021+65053+65085+65117+65149+65181+65213+65245+65277+65309+65341+65373+65405+65437+65469+65501+65533,57374+57406+57438+57470+57502+57534+57566+57598+57630+57662+57694+57726+57758+57790+57822+57854+57886+57918+57950+57982+58014+58046+58078+58110+58142+58174+58206+58238+58270+58302+58334+58366+58398+58430+58462+58494+58526+58558+58590+58622+58654+58686+58718+58750+58782+58814+58846+58878+58910+58942+58974+59006+59038+59070+59102+59134+59166+59198+59230+59262+59294+59326+59358+59390+59422+59454+59486+59518+59550+59582+59614+59646+59678+59710+59742+59774+59806+59838+59870+59902+59934+59966+59998+60030+60062+60094+60126+60158+60190+60222+60254+60286+60318+60350+60382+60414+60446+60478+60510+60542+60574+60606+60638+60670+60702+60734+60766+60798+60830+60862+60894+60926+60958+60990+61022+61054+61086+61118+61150+61182+61214+61246+61278+61310+61342+61374+61406+61438+61470+61502+61534+61566+61598+61630+61662+61694+61726+61758+61790+61822+61854+61886+61918+61950+61982+62014+62046+62078+62110+62142+62174+62206+62238+62270+62302+62334+62366+62398+62430+62462+62494+62526+62558+62590+62622+62654+62686+62718+62750+62782+62814+62846+62878+62910+62942+62974+63006+63038+63070+63102+63134+63166+63198+63230+63262+63294+63326+63358+63390+63422+63454+63486+63518+63550+63582+63614+63646+63678+63710+63742+63774+63806+63838+63870+63902+63934+63966+63998+64030+64062+64094+64126+64158+64190+64222+64254+64286+64318+64350+64382+64414+64446+64478+64510+64542+64574+64606+64638+64670+64702+64734+64766+64798+64830+64862+64894+64926+64958+64990+65022+65054+65086+65118+65150+65182+65214+65246+65278+65310+65342+65374+65406+65438+65470+65502+65534,57375+57407+57439+57471+57503+57535+57567+57599+57631+57663+57695+57727+57759+57791+57823+57855+57887+57919+57951+57983+58015+58047+58079+58111+58143+58175+58207+58239+58271+58303+58335+58367+58399+58431+58463+58495+58527+58559+58591+58623+58655+58687+58719+58751+58783+58815+58847+58879+58911+58943+58975+59007+59039+59071+59103+59135+59167+59199+59231+59263+59295+59327+59359+59391+59423+59455+59487+59519+59551+59583+59615+59647+59679+59711+59743+59775+59807+59839+59871+59903+59935+59967+59999+60031+60063+60095+60127+60159+60191+60223+60255+60287+60319+60351+60383+60415+60447+60479+60511+60543+60575+60607+60639+60671+60703+60735+60767+60799+60831+60863+60895+60927+60959+60991+61023+61055+61087+61119+61151+61183+61215+61247+61279+61311+61343+61375+61407+61439+61471+61503+61535+61567+61599+61631+61663+61695+61727+61759+61791+61823+61855+61887+61919+61951+61983+62015+62047+62079+62111+62143+62175+62207+62239+62271+62303+62335+62367+62399+62431+62463+62495+62527+62559+62591+62623+62655+62687+62719+62751+62783+62815+62847+62879+62911+62943+62975+63007+63039+63071+63103+63135+63167+63199+63231+63263+63295+63327+63359+63391+63423+63455+63487+63519+63551+63583+63615+63647+63679+63711+63743+63775+63807+63839+63871+63903+63935+63967+63999+64031+64063+64095+64127+64159+64191+64223+64255+64287+64319+64351+64383+64415+64447+64479+64511+64543+64575+64607+64639+64671+64703+64735+64767+64799+64831+64863+64895+64927+64959+64991+65023+65055+65087+65119+65151+65183+65215+65247+65279+65311+65343+65375+65407+65439+65471+65503+65535"/>
+    </parameter>
+  </component-link>
 
   <!-- These parameters are used in ParallaxCorrection algorithm -->
 
diff --git a/instrument/Facilities.xml b/instrument/Facilities.xml
index 7af2dc4cbb824def2b4c7e64eb453f03e682fa2f..bf7f57180884cc1f94eb37c15773169f7c383941 100644
--- a/instrument/Facilities.xml
+++ b/instrument/Facilities.xml
@@ -15,8 +15,8 @@
     <soapendpoint url="https://icatisis.esc.rl.ac.uk/ICATService/ICAT"></soapendpoint>
     <externaldownload url="https://isisicatds.stfc.ac.uk/ids/"></externaldownload>
     <filelocation>
-      <prefix regex="\\\\isis\\inst\$"></prefix>
-      <windows replacement=""></windows>
+      <prefix regex="\\\\isis(?:\.cclrc\.ac\.uk)?\\inst\$"></prefix>
+      <windows replacement="\\\\isis.cclrc.ac.uk\\inst$"></windows>
       <linux replacement="/archive"></linux>
       <mac replacement="/archive"></mac>
     </filelocation>
diff --git a/instrument/GPSANS_Definition.xml b/instrument/GPSANS_Definition.xml
index c66430303444dad5cda058e116eddd44c6fb6ac2..22e8cc134aabc6ed1f3cf9f8033b19c7ef9569ba 100644
--- a/instrument/GPSANS_Definition.xml
+++ b/instrument/GPSANS_Definition.xml
@@ -5,7 +5,7 @@
             name="GPSANS"
             valid-from="1900-01-31 23:59:59"
             valid-to="2100-01-31 23:59:59"
-		    last-modified="2016-05-10 15:38:39.813535">
+		    last-modified="2018-12-10 17:31:39.813535">
 
 
   <defaults>
@@ -61,7 +61,17 @@
 <!-- ***************************************************************** -->
 <!-- Main Detector -->
 <component type="detector1" idstart="3" idfillbyfirst="x" idstep="192" idstepbyrow="1">
-    <location z='0' />
+		<location name="detector1">
+			<parameter name="z">
+				<logfile eq="0.001*value" id="sdd"/>
+			</parameter>
+			<parameter name="x">
+				<logfile eq="0.001*value" id="detector-translation"/>
+			</parameter>
+      <parameter name="y">
+        <value val="0.0"/>
+      </parameter>
+		</location>
 </component>
 
 <!-- Detector: -->
diff --git a/instrument/IN5_Definition.xml b/instrument/IN5_Definition.xml
index 1005f9094c9ede95b645fe17362205e3bcd4dc66..79111ae7bb17a53d8ae6a0963de4a536b74860d1 100644
--- a/instrument/IN5_Definition.xml
+++ b/instrument/IN5_Definition.xml
@@ -1,722 +1,712 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF -->
-<instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" name="IN5" valid-from="1900-01-31 23:59:59"
-valid-to="2100-01-31 23:59:59" last-modified="2018-03-27 11:19:26">
-  <!-- Author: ricardo.leal@ill.fr -->
+<?xml version='1.0' encoding='ASCII'?>
+<instrument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mantidproject.org/IDF/1.0" last-modified="2018-12-12 12:23:39.832773" name="IN5" valid-from="1900-01-31 23:59:59" valid-to="2100-01-31 23:59:59" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd">
+  <!-- This is the instrument definition file of the IN5 spectrometer at the ILL.
+       This file was automatically generated by mantidgeometry/ILL/IDF/in5_generateIDF.py
+       -->
   <defaults>
-    <length unit="meter" />
-    <angle unit="degree" />
+    <length unit="metre"/>
+    <angle unit="degree"/>
     <reference-frame>
-      <!-- The z-axis is set parallel to and in the direction of the beam. the 
-             y-axis points up and the coordinate system is right handed. -->
-      <along-beam axis="z" />
-      <pointing-up axis="y" />
-      <handedness val="right" />
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+      <theta-sign axis="x"/>
     </reference-frame>
   </defaults>
   <component type="frame-overlap_chopper">
-    <location z="-2.10945" />
+    <location x="0.0" y="0.0" z="-2.10945"/>
   </component>
-  <type name="frame-overlap_chopper" is="Source"></type>
-  <!--MONITORS-->
-  <component type="monitors" idlist="monitors">
-    <location />
+  <type is="Source" name="frame-overlap_chopper"/>
+  <component type="sample-position">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type is="SamplePos" name="sample-position"/>
+  <component idlist="monitors" type="monitors">
+    <location/>
   </component>
   <type name="monitors">
     <component type="monitor">
-      <location z="-0.5" name="monitor1" />
+      <location name="monitor" z="-0.5"/>
     </component>
   </type>
-  <!-- Sample position -->
-  <component type="sample-position">
-    <location y="0.0" x="0.0" z="0.0" />
-  </component>
-  <type name="sample-position" is="SamplePos" />
-  <idlist idname="detectors">
-    <id start="1" end="98304" />
+  <type is="monitor" name="monitor">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base p="0.0" r="0.0" t="0.0"/>
+      <axis x="0.0" y="0.0" z="1.0"/>
+      <radius val="0.01"/>
+      <height val="0.03"/>
+    </cylinder>
+    <algebra val="cyl-approx"/>
+  </type>
+  <idlist idname="monitors">
+    <id val="100000"/>
   </idlist>
-  <!-- Detector list def -->
-  <component type="detectors" idlist="detectors">
-    <location />
-  </component>
-  <!-- Detector Banks -->
-  <type name="detectors">
-    <component type="bank_uniq">
-      <location />
-    </component>
+  <type is="detector" name="standard_pixel">
+    <cylinder id="pixel_shape">
+      <centre-of-bottom-base x="0.0" y="0.0" z="-0.00612033195021"/>
+      <axis x="0.0" y="1.0" z="0.0"/>
+      <radius val="0.0122"/>
+      <height val="0.0122406639004"/>
+    </cylinder>
+    <algebra val="pixel_shape"/>
   </type>
-  <!-- Definition of the unique existent bank (made of tubes) -->
   <type name="bank_uniq">
     <component type="standard_tube">
-      <location r="4.000000" t="134.817000" name="tube_1" />
-      <location r="4.000000" t="134.445000" name="tube_2" />
-      <location r="4.000000" t="134.072000" name="tube_3" />
-      <location r="4.000000" t="133.700000" name="tube_4" />
-      <location r="4.000000" t="133.328000" name="tube_5" />
-      <location r="4.000000" t="132.955000" name="tube_6" />
-      <location r="4.000000" t="132.583000" name="tube_7" />
-      <location r="4.000000" t="132.210000" name="tube_8" />
-      <location r="4.000000" t="131.838000" name="tube_9" />
-      <location r="4.000000" t="131.465000" name="tube_10" />
-      <location r="4.000000" t="131.093000" name="tube_11" />
-      <location r="4.000000" t="130.721000" name="tube_12" />
-      <location r="4.000000" t="130.348000" name="tube_13" />
-      <location r="4.000000" t="129.976000" name="tube_14" />
-      <location r="4.000000" t="129.603000" name="tube_15" />
-      <location r="4.000000" t="129.231000" name="tube_16" />
-      <location r="4.000000" t="128.858000" name="tube_17" />
-      <location r="4.000000" t="128.486000" name="tube_18" />
-      <location r="4.000000" t="128.114000" name="tube_19" />
-      <location r="4.000000" t="127.741000" name="tube_20" />
-      <location r="4.000000" t="127.369000" name="tube_21" />
-      <location r="4.000000" t="126.996000" name="tube_22" />
-      <location r="4.000000" t="126.624000" name="tube_23" />
-      <location r="4.000000" t="126.251000" name="tube_24" />
-      <location r="4.000000" t="125.879000" name="tube_25" />
-      <location r="4.000000" t="125.507000" name="tube_26" />
-      <location r="4.000000" t="125.134000" name="tube_27" />
-      <location r="4.000000" t="124.762000" name="tube_28" />
-      <location r="4.000000" t="124.389000" name="tube_29" />
-      <location r="4.000000" t="124.017000" name="tube_30" />
-      <location r="4.000000" t="123.645000" name="tube_31" />
-      <location r="4.000000" t="123.272000" name="tube_32" />
-      <location r="4.000000" t="122.527000" name="tube_33" />
-      <location r="4.000000" t="122.155000" name="tube_34" />
-      <location r="4.000000" t="121.782000" name="tube_35" />
-      <location r="4.000000" t="121.410000" name="tube_36" />
-      <location r="4.000000" t="121.038000" name="tube_37" />
-      <location r="4.000000" t="120.665000" name="tube_38" />
-      <location r="4.000000" t="120.293000" name="tube_39" />
-      <location r="4.000000" t="119.920000" name="tube_40" />
-      <location r="4.000000" t="119.548000" name="tube_41" />
-      <location r="4.000000" t="119.175000" name="tube_42" />
-      <location r="4.000000" t="118.803000" name="tube_43" />
-      <location r="4.000000" t="118.431000" name="tube_44" />
-      <location r="4.000000" t="118.058000" name="tube_45" />
-      <location r="4.000000" t="117.686000" name="tube_46" />
-      <location r="4.000000" t="117.313000" name="tube_47" />
-      <location r="4.000000" t="116.941000" name="tube_48" />
-      <location r="4.000000" t="116.568000" name="tube_49" />
-      <location r="4.000000" t="116.196000" name="tube_50" />
-      <location r="4.000000" t="115.824000" name="tube_51" />
-      <location r="4.000000" t="115.451000" name="tube_52" />
-      <location r="4.000000" t="115.079000" name="tube_53" />
-      <location r="4.000000" t="114.706000" name="tube_54" />
-      <location r="4.000000" t="114.334000" name="tube_55" />
-      <location r="4.000000" t="113.962000" name="tube_56" />
-      <location r="4.000000" t="113.589000" name="tube_57" />
-      <location r="4.000000" t="113.217000" name="tube_58" />
-      <location r="4.000000" t="112.844000" name="tube_59" />
-      <location r="4.000000" t="112.472000" name="tube_60" />
-      <location r="4.000000" t="112.099000" name="tube_61" />
-      <location r="4.000000" t="111.727000" name="tube_62" />
-      <location r="4.000000" t="111.355000" name="tube_63" />
-      <location r="4.000000" t="110.982000" name="tube_64" />
-      <location r="4.000000" t="110.237000" name="tube_65" />
-      <location r="4.000000" t="109.865000" name="tube_66" />
-      <location r="4.000000" t="109.492000" name="tube_67" />
-      <location r="4.000000" t="109.120000" name="tube_68" />
-      <location r="4.000000" t="108.748000" name="tube_69" />
-      <location r="4.000000" t="108.375000" name="tube_70" />
-      <location r="4.000000" t="108.003000" name="tube_71" />
-      <location r="4.000000" t="107.630000" name="tube_72" />
-      <location r="4.000000" t="107.258000" name="tube_73" />
-      <location r="4.000000" t="106.885000" name="tube_74" />
-      <location r="4.000000" t="106.513000" name="tube_75" />
-      <location r="4.000000" t="106.141000" name="tube_76" />
-      <location r="4.000000" t="105.768000" name="tube_77" />
-      <location r="4.000000" t="105.396000" name="tube_78" />
-      <location r="4.000000" t="105.023000" name="tube_79" />
-      <location r="4.000000" t="104.651000" name="tube_80" />
-      <location r="4.000000" t="104.279000" name="tube_81" />
-      <location r="4.000000" t="103.906000" name="tube_82" />
-      <location r="4.000000" t="103.534000" name="tube_83" />
-      <location r="4.000000" t="103.161000" name="tube_84" />
-      <location r="4.000000" t="102.789000" name="tube_85" />
-      <location r="4.000000" t="102.416000" name="tube_86" />
-      <location r="4.000000" t="102.044000" name="tube_87" />
-      <location r="4.000000" t="101.672000" name="tube_88" />
-      <location r="4.000000" t="101.299000" name="tube_89" />
-      <location r="4.000000" t="100.927000" name="tube_90" />
-      <location r="4.000000" t="100.554000" name="tube_91" />
-      <location r="4.000000" t="100.182000" name="tube_92" />
-      <location r="4.000000" t="99.809400" name="tube_93" />
-      <location r="4.000000" t="99.437000" name="tube_94" />
-      <location r="4.000000" t="99.064600" name="tube_95" />
-      <location r="4.000000" t="98.692200" name="tube_96" />
-      <location r="4.000000" t="97.947300" name="tube_97" />
-      <location r="4.000000" t="97.574900" name="tube_98" />
-      <location r="4.000000" t="97.202500" name="tube_99" />
-      <location r="4.000000" t="96.830000" name="tube_100" />
-      <location r="4.000000" t="96.457600" name="tube_101" />
-      <location r="4.000000" t="96.085200" name="tube_102" />
-      <location r="4.000000" t="95.712800" name="tube_103" />
-      <location r="4.000000" t="95.340400" name="tube_104" />
-      <location r="4.000000" t="94.967900" name="tube_105" />
-      <location r="4.000000" t="94.595500" name="tube_106" />
-      <location r="4.000000" t="94.223100" name="tube_107" />
-      <location r="4.000000" t="93.850700" name="tube_108" />
-      <location r="4.000000" t="93.478200" name="tube_109" />
-      <location r="4.000000" t="93.105800" name="tube_110" />
-      <location r="4.000000" t="92.733400" name="tube_111" />
-      <location r="4.000000" t="92.361000" name="tube_112" />
-      <location r="4.000000" t="91.988500" name="tube_113" />
-      <location r="4.000000" t="91.616100" name="tube_114" />
-      <location r="4.000000" t="91.243700" name="tube_115" />
-      <location r="4.000000" t="90.871300" name="tube_116" />
-      <location r="4.000000" t="90.498900" name="tube_117" />
-      <location r="4.000000" t="90.126400" name="tube_118" />
-      <location r="4.000000" t="89.754000" name="tube_119" />
-      <location r="4.000000" t="89.381600" name="tube_120" />
-      <location r="4.000000" t="89.009200" name="tube_121" />
-      <location r="4.000000" t="88.636700" name="tube_122" />
-      <location r="4.000000" t="88.264300" name="tube_123" />
-      <location r="4.000000" t="87.891900" name="tube_124" />
-      <location r="4.000000" t="87.519500" name="tube_125" />
-      <location r="4.000000" t="87.147000" name="tube_126" />
-      <location r="4.000000" t="86.774600" name="tube_127" />
-      <location r="4.000000" t="86.402200" name="tube_128" />
-      <location r="4.000000" t="85.657300" name="tube_129" />
-      <location r="4.000000" t="85.284900" name="tube_130" />
-      <location r="4.000000" t="84.912500" name="tube_131" />
-      <location r="4.000000" t="84.540100" name="tube_132" />
-      <location r="4.000000" t="84.167700" name="tube_133" />
-      <location r="4.000000" t="83.795200" name="tube_134" />
-      <location r="4.000000" t="83.422800" name="tube_135" />
-      <location r="4.000000" t="83.050400" name="tube_136" />
-      <location r="4.000000" t="82.678000" name="tube_137" />
-      <location r="4.000000" t="82.305500" name="tube_138" />
-      <location r="4.000000" t="81.933100" name="tube_139" />
-      <location r="4.000000" t="81.560700" name="tube_140" />
-      <location r="4.000000" t="81.188300" name="tube_141" />
-      <location r="4.000000" t="80.815800" name="tube_142" />
-      <location r="4.000000" t="80.443400" name="tube_143" />
-      <location r="4.000000" t="80.071000" name="tube_144" />
-      <location r="4.000000" t="79.698600" name="tube_145" />
-      <location r="4.000000" t="79.326200" name="tube_146" />
-      <location r="4.000000" t="78.953700" name="tube_147" />
-      <location r="4.000000" t="78.581300" name="tube_148" />
-      <location r="4.000000" t="78.208900" name="tube_149" />
-      <location r="4.000000" t="77.836500" name="tube_150" />
-      <location r="4.000000" t="77.464000" name="tube_151" />
-      <location r="4.000000" t="77.091600" name="tube_152" />
-      <location r="4.000000" t="76.719200" name="tube_153" />
-      <location r="4.000000" t="76.346800" name="tube_154" />
-      <location r="4.000000" t="75.974300" name="tube_155" />
-      <location r="4.000000" t="75.601900" name="tube_156" />
-      <location r="4.000000" t="75.229500" name="tube_157" />
-      <location r="4.000000" t="74.857100" name="tube_158" />
-      <location r="4.000000" t="74.484600" name="tube_159" />
-      <location r="4.000000" t="74.112200" name="tube_160" />
-      <location r="4.000000" t="73.367400" name="tube_161" />
-      <location r="4.000000" t="72.995000" name="tube_162" />
-      <location r="4.000000" t="72.622500" name="tube_163" />
-      <location r="4.000000" t="72.250100" name="tube_164" />
-      <location r="4.000000" t="71.877700" name="tube_165" />
-      <location r="4.000000" t="71.505300" name="tube_166" />
-      <location r="4.000000" t="71.132800" name="tube_167" />
-      <location r="4.000000" t="70.760400" name="tube_168" />
-      <location r="4.000000" t="70.388000" name="tube_169" />
-      <location r="4.000000" t="70.015600" name="tube_170" />
-      <location r="4.000000" t="69.643200" name="tube_171" />
-      <location r="4.000000" t="69.270700" name="tube_172" />
-      <location r="4.000000" t="68.898300" name="tube_173" />
-      <location r="4.000000" t="68.525900" name="tube_174" />
-      <location r="4.000000" t="68.153500" name="tube_175" />
-      <location r="4.000000" t="67.781000" name="tube_176" />
-      <location r="4.000000" t="67.408600" name="tube_177" />
-      <location r="4.000000" t="67.036200" name="tube_178" />
-      <location r="4.000000" t="66.663800" name="tube_179" />
-      <location r="4.000000" t="66.291300" name="tube_180" />
-      <location r="4.000000" t="65.918900" name="tube_181" />
-      <location r="4.000000" t="65.546500" name="tube_182" />
-      <location r="4.000000" t="65.174100" name="tube_183" />
-      <location r="4.000000" t="64.801700" name="tube_184" />
-      <location r="4.000000" t="64.429200" name="tube_185" />
-      <location r="4.000000" t="64.056800" name="tube_186" />
-      <location r="4.000000" t="63.684400" name="tube_187" />
-      <location r="4.000000" t="63.312000" name="tube_188" />
-      <location r="4.000000" t="62.939500" name="tube_189" />
-      <location r="4.000000" t="62.567100" name="tube_190" />
-      <location r="4.000000" t="62.194700" name="tube_191" />
-      <location r="4.000000" t="61.822300" name="tube_192" />
-      <location r="4.000000" t="61.077400" name="tube_193" />
-      <location r="4.000000" t="60.705000" name="tube_194" />
-      <location r="4.000000" t="60.332600" name="tube_195" />
-      <location r="4.000000" t="59.960100" name="tube_196" />
-      <location r="4.000000" t="59.587700" name="tube_197" />
-      <location r="4.000000" t="59.215300" name="tube_198" />
-      <location r="4.000000" t="58.842900" name="tube_199" />
-      <location r="4.000000" t="58.470400" name="tube_200" />
-      <location r="4.000000" t="58.098000" name="tube_201" />
-      <location r="4.000000" t="57.725600" name="tube_202" />
-      <location r="4.000000" t="57.353200" name="tube_203" />
-      <location r="4.000000" t="56.980800" name="tube_204" />
-      <location r="4.000000" t="56.608300" name="tube_205" />
-      <location r="4.000000" t="56.235900" name="tube_206" />
-      <location r="4.000000" t="55.863500" name="tube_207" />
-      <location r="4.000000" t="55.491100" name="tube_208" />
-      <location r="4.000000" t="55.118600" name="tube_209" />
-      <location r="4.000000" t="54.746200" name="tube_210" />
-      <location r="4.000000" t="54.373800" name="tube_211" />
-      <location r="4.000000" t="54.001400" name="tube_212" />
-      <location r="4.000000" t="53.628900" name="tube_213" />
-      <location r="4.000000" t="53.256500" name="tube_214" />
-      <location r="4.000000" t="52.884100" name="tube_215" />
-      <location r="4.000000" t="52.511700" name="tube_216" />
-      <location r="4.000000" t="52.139300" name="tube_217" />
-      <location r="4.000000" t="51.766800" name="tube_218" />
-      <location r="4.000000" t="51.394400" name="tube_219" />
-      <location r="4.000000" t="51.022000" name="tube_220" />
-      <location r="4.000000" t="50.649600" name="tube_221" />
-      <location r="4.000000" t="50.277100" name="tube_222" />
-      <location r="4.000000" t="49.904700" name="tube_223" />
-      <location r="4.000000" t="49.532300" name="tube_224" />
-      <location r="4.000000" t="48.787400" name="tube_225" />
-      <location r="4.000000" t="48.415000" name="tube_226" />
-      <location r="4.000000" t="48.042600" name="tube_227" />
-      <location r="4.000000" t="47.670200" name="tube_228" />
-      <location r="4.000000" t="47.297800" name="tube_229" />
-      <location r="4.000000" t="46.925300" name="tube_230" />
-      <location r="4.000000" t="46.552900" name="tube_231" />
-      <location r="4.000000" t="46.180500" name="tube_232" />
-      <location r="4.000000" t="45.808100" name="tube_233" />
-      <location r="4.000000" t="45.435600" name="tube_234" />
-      <location r="4.000000" t="45.063200" name="tube_235" />
-      <location r="4.000000" t="44.690800" name="tube_236" />
-      <location r="4.000000" t="44.318400" name="tube_237" />
-      <location r="4.000000" t="43.945900" name="tube_238" />
-      <location r="4.000000" t="43.573500" name="tube_239" />
-      <location r="4.000000" t="43.201100" name="tube_240" />
-      <location r="4.000000" t="42.828700" name="tube_241" />
-      <location r="4.000000" t="42.456200" name="tube_242" />
-      <location r="4.000000" t="42.083800" name="tube_243" />
-      <location r="4.000000" t="41.711400" name="tube_244" />
-      <location r="4.000000" t="41.339000" name="tube_245" />
-      <location r="4.000000" t="40.966600" name="tube_246" />
-      <location r="4.000000" t="40.594100" name="tube_247" />
-      <location r="4.000000" t="40.221700" name="tube_248" />
-      <location r="4.000000" t="39.849300" name="tube_249" />
-      <location r="4.000000" t="39.476900" name="tube_250" />
-      <location r="4.000000" t="39.104400" name="tube_251" />
-      <location r="4.000000" t="38.732000" name="tube_252" />
-      <location r="4.000000" t="38.359600" name="tube_253" />
-      <location r="4.000000" t="37.987200" name="tube_254" />
-      <location r="4.000000" t="37.614700" name="tube_255" />
-      <location r="4.000000" t="37.242300" name="tube_256" />
-      <location r="4.000000" t="36.497500" name="tube_257" />
-      <location r="4.000000" t="36.125100" name="tube_258" />
-      <location r="4.000000" t="35.752600" name="tube_259" />
-      <location r="4.000000" t="35.380200" name="tube_260" />
-      <location r="4.000000" t="35.007800" name="tube_261" />
-      <location r="4.000000" t="34.635400" name="tube_262" />
-      <location r="4.000000" t="34.262900" name="tube_263" />
-      <location r="4.000000" t="33.890500" name="tube_264" />
-      <location r="4.000000" t="33.518100" name="tube_265" />
-      <location r="4.000000" t="33.145700" name="tube_266" />
-      <location r="4.000000" t="32.773200" name="tube_267" />
-      <location r="4.000000" t="32.400800" name="tube_268" />
-      <location r="4.000000" t="32.028400" name="tube_269" />
-      <location r="4.000000" t="31.656000" name="tube_270" />
-      <location r="4.000000" t="31.283600" name="tube_271" />
-      <location r="4.000000" t="30.911100" name="tube_272" />
-      <location r="4.000000" t="30.538700" name="tube_273" />
-      <location r="4.000000" t="30.166300" name="tube_274" />
-      <location r="4.000000" t="29.793900" name="tube_275" />
-      <location r="4.000000" t="29.421400" name="tube_276" />
-      <location r="4.000000" t="29.049000" name="tube_277" />
-      <location r="4.000000" t="28.676600" name="tube_278" />
-      <location r="4.000000" t="28.304200" name="tube_279" />
-      <location r="4.000000" t="27.931700" name="tube_280" />
-      <location r="4.000000" t="27.559300" name="tube_281" />
-      <location r="4.000000" t="27.186900" name="tube_282" />
-      <location r="4.000000" t="26.814500" name="tube_283" />
-      <location r="4.000000" t="26.442000" name="tube_284" />
-      <location r="4.000000" t="26.069600" name="tube_285" />
-      <location r="4.000000" t="25.697200" name="tube_286" />
-      <location r="4.000000" t="25.324800" name="tube_287" />
-      <location r="4.000000" t="24.952400" name="tube_288" />
-      <location r="4.000000" t="24.207500" name="tube_289" />
-      <location r="4.000000" t="23.835100" name="tube_290" />
-      <location r="4.000000" t="23.462700" name="tube_291" />
-      <location r="4.000000" t="23.090200" name="tube_292" />
-      <location r="4.000000" t="22.717800" name="tube_293" />
-      <location r="4.000000" t="22.345400" name="tube_294" />
-      <location r="4.000000" t="21.973000" name="tube_295" />
-      <location r="4.000000" t="21.600500" name="tube_296" />
-      <location r="4.000000" t="21.228100" name="tube_297" />
-      <location r="4.000000" t="20.855700" name="tube_298" />
-      <location r="4.000000" t="20.483300" name="tube_299" />
-      <location r="4.000000" t="20.110900" name="tube_300" />
-      <location r="4.000000" t="19.738400" name="tube_301" />
-      <location r="4.000000" t="19.366000" name="tube_302" />
-      <location r="4.000000" t="18.993600" name="tube_303" />
-      <location r="4.000000" t="18.621200" name="tube_304" />
-      <location r="4.000000" t="18.248700" name="tube_305" />
-      <location r="4.000000" t="17.876300" name="tube_306" />
-      <location r="4.000000" t="17.503900" name="tube_307" />
-      <location r="4.000000" t="17.131500" name="tube_308" />
-      <location r="4.000000" t="16.759000" name="tube_309" />
-      <location r="4.000000" t="16.386600" name="tube_310" />
-      <location r="4.000000" t="16.014200" name="tube_311" />
-      <location r="4.000000" t="15.641800" name="tube_312" />
-      <location r="4.000000" t="15.269400" name="tube_313" />
-      <location r="4.000000" t="14.896900" name="tube_314" />
-      <location r="4.000000" t="14.524500" name="tube_315" />
-      <location r="4.000000" t="14.152100" name="tube_316" />
-      <location r="4.000000" t="13.779700" name="tube_317" />
-      <location r="4.000000" t="13.407200" name="tube_318" />
-      <location r="4.000000" t="13.034800" name="tube_319" />
-      <location r="4.000000" t="12.662400" name="tube_320" />
-      <location r="4.000000" t="11.917500" name="tube_321" />
-      <location r="4.000000" t="11.545100" name="tube_322" />
-      <location r="4.000000" t="11.172700" name="tube_323" />
-      <location r="4.000000" t="10.800300" name="tube_324" />
-      <location r="4.000000" t="10.427900" name="tube_325" />
-      <location r="4.000000" t="10.055400" name="tube_326" />
-      <location r="4.000000" t="9.683000" name="tube_327" />
-      <location r="4.000000" t="9.310580" name="tube_328" />
-      <location r="4.000000" t="8.938160" name="tube_329" />
-      <location r="4.000000" t="8.565730" name="tube_330" />
-      <location r="4.000000" t="8.193310" name="tube_331" />
-      <location r="4.000000" t="7.820890" name="tube_332" />
-      <location r="4.000000" t="7.448460" name="tube_333" />
-      <location r="4.000000" t="7.076040" name="tube_334" />
-      <location r="4.000000" t="6.703620" name="tube_335" />
-      <location r="4.000000" t="6.331190" name="tube_336" />
-      <location r="4.000000" t="5.958770" name="tube_337" />
-      <location r="4.000000" t="5.586350" name="tube_338" />
-      <location r="4.000000" t="5.213930" name="tube_339" />
-      <location r="4.000000" t="4.841500" name="tube_340" />
-      <location r="4.000000" t="4.469080" name="tube_341" />
-      <location r="4.000000" t="4.096660" name="tube_342" />
-      <location r="4.000000" t="3.724230" name="tube_343" />
-      <location r="4.000000" t="3.351810" name="tube_344" />
-      <location r="4.000000" t="2.979390" name="tube_345" />
-      <location r="4.000000" t="2.606960" name="tube_346" />
-      <location r="4.000000" t="2.234540" name="tube_347" />
-      <location r="4.000000" t="1.862120" name="tube_348" />
-      <location r="4.000000" t="1.489690" name="tube_349" />
-      <location r="4.000000" t="1.117270" name="tube_350" />
-      <location r="4.000000" t="0.744847" name="tube_351" />
-      <location r="4.000000" t="0.372423" name="tube_352" />
-      <location r="4.000000" t="-0.372423" name="tube_353" />
-      <location r="4.000000" t="-0.744846" name="tube_354" />
-      <location r="4.000000" t="-1.117270" name="tube_355" />
-      <location r="4.000000" t="-1.489690" name="tube_356" />
-      <location r="4.000000" t="-1.862120" name="tube_357" />
-      <location r="4.000000" t="-2.234540" name="tube_358" />
-      <location r="4.000000" t="-2.606960" name="tube_359" />
-      <location r="4.000000" t="-2.979390" name="tube_360" />
-      <location r="4.000000" t="-3.351810" name="tube_361" />
-      <location r="4.000000" t="-3.724230" name="tube_362" />
-      <location r="4.000000" t="-4.096660" name="tube_363" />
-      <location r="4.000000" t="-4.469080" name="tube_364" />
-      <location r="4.000000" t="-4.841500" name="tube_365" />
-      <location r="4.000000" t="-5.213930" name="tube_366" />
-      <location r="4.000000" t="-5.586350" name="tube_367" />
-      <location r="4.000000" t="-5.958770" name="tube_368" />
-      <location r="4.000000" t="-6.331190" name="tube_369" />
-      <location r="4.000000" t="-6.703620" name="tube_370" />
-      <location r="4.000000" t="-7.076040" name="tube_371" />
-      <location r="4.000000" t="-7.448460" name="tube_372" />
-      <location r="4.000000" t="-7.820890" name="tube_373" />
-      <location r="4.000000" t="-8.193310" name="tube_374" />
-      <location r="4.000000" t="-8.565730" name="tube_375" />
-      <location r="4.000000" t="-8.938160" name="tube_376" />
-      <location r="4.000000" t="-9.310580" name="tube_377" />
-      <location r="4.000000" t="-9.683000" name="tube_378" />
-      <location r="4.000000" t="-10.055400" name="tube_379" />
-      <location r="4.000000" t="-10.427900" name="tube_380" />
-      <location r="4.000000" t="-10.800300" name="tube_381" />
-      <location r="4.000000" t="-11.172700" name="tube_382" />
-      <location r="4.000000" t="-11.545100" name="tube_383" />
-      <location r="4.000000" t="-11.917500" name="tube_384" />
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_1" r="4" rot="134.817" t="134.817"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_2" r="4" rot="134.445" t="134.445"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_3" r="4" rot="134.072" t="134.072"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_4" r="4" rot="133.7" t="133.7"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_5" r="4" rot="133.328" t="133.328"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_6" r="4" rot="132.955" t="132.955"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_7" r="4" rot="132.583" t="132.583"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_8" r="4" rot="132.21" t="132.21"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_9" r="4" rot="131.838" t="131.838"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_10" r="4" rot="131.465" t="131.465"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_11" r="4" rot="131.093" t="131.093"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_12" r="4" rot="130.721" t="130.721"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_13" r="4" rot="130.348" t="130.348"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_14" r="4" rot="129.976" t="129.976"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_15" r="4" rot="129.603" t="129.603"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_16" r="4" rot="129.231" t="129.231"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_17" r="4" rot="128.858" t="128.858"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_18" r="4" rot="128.486" t="128.486"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_19" r="4" rot="128.114" t="128.114"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_20" r="4" rot="127.741" t="127.741"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_21" r="4" rot="127.369" t="127.369"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_22" r="4" rot="126.996" t="126.996"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_23" r="4" rot="126.624" t="126.624"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_24" r="4" rot="126.251" t="126.251"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_25" r="4" rot="125.879" t="125.879"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_26" r="4" rot="125.507" t="125.507"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_27" r="4" rot="125.134" t="125.134"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_28" r="4" rot="124.762" t="124.762"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_29" r="4" rot="124.389" t="124.389"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_30" r="4" rot="124.017" t="124.017"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_31" r="4" rot="123.645" t="123.645"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_32" r="4" rot="123.272" t="123.272"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_33" r="4" rot="122.527" t="122.527"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_34" r="4" rot="122.155" t="122.155"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_35" r="4" rot="121.782" t="121.782"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_36" r="4" rot="121.41" t="121.41"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_37" r="4" rot="121.038" t="121.038"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_38" r="4" rot="120.665" t="120.665"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_39" r="4" rot="120.293" t="120.293"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_40" r="4" rot="119.92" t="119.92"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_41" r="4" rot="119.548" t="119.548"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_42" r="4" rot="119.175" t="119.175"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_43" r="4" rot="118.803" t="118.803"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_44" r="4" rot="118.431" t="118.431"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_45" r="4" rot="118.058" t="118.058"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_46" r="4" rot="117.686" t="117.686"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_47" r="4" rot="117.313" t="117.313"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_48" r="4" rot="116.941" t="116.941"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_49" r="4" rot="116.568" t="116.568"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_50" r="4" rot="116.196" t="116.196"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_51" r="4" rot="115.824" t="115.824"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_52" r="4" rot="115.451" t="115.451"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_53" r="4" rot="115.079" t="115.079"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_54" r="4" rot="114.706" t="114.706"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_55" r="4" rot="114.334" t="114.334"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_56" r="4" rot="113.962" t="113.962"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_57" r="4" rot="113.589" t="113.589"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_58" r="4" rot="113.217" t="113.217"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_59" r="4" rot="112.844" t="112.844"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_60" r="4" rot="112.472" t="112.472"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_61" r="4" rot="112.099" t="112.099"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_62" r="4" rot="111.727" t="111.727"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_63" r="4" rot="111.355" t="111.355"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_64" r="4" rot="110.982" t="110.982"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_65" r="4" rot="110.237" t="110.237"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_66" r="4" rot="109.865" t="109.865"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_67" r="4" rot="109.492" t="109.492"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_68" r="4" rot="109.12" t="109.12"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_69" r="4" rot="108.748" t="108.748"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_70" r="4" rot="108.375" t="108.375"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_71" r="4" rot="108.003" t="108.003"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_72" r="4" rot="107.63" t="107.63"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_73" r="4" rot="107.258" t="107.258"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_74" r="4" rot="106.885" t="106.885"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_75" r="4" rot="106.513" t="106.513"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_76" r="4" rot="106.141" t="106.141"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_77" r="4" rot="105.768" t="105.768"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_78" r="4" rot="105.396" t="105.396"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_79" r="4" rot="105.023" t="105.023"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_80" r="4" rot="104.651" t="104.651"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_81" r="4" rot="104.279" t="104.279"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_82" r="4" rot="103.906" t="103.906"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_83" r="4" rot="103.534" t="103.534"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_84" r="4" rot="103.161" t="103.161"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_85" r="4" rot="102.789" t="102.789"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_86" r="4" rot="102.416" t="102.416"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_87" r="4" rot="102.044" t="102.044"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_88" r="4" rot="101.672" t="101.672"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_89" r="4" rot="101.299" t="101.299"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_90" r="4" rot="100.927" t="100.927"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_91" r="4" rot="100.554" t="100.554"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_92" r="4" rot="100.182" t="100.182"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_93" r="4" rot="99.8094" t="99.8094"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_94" r="4" rot="99.437" t="99.437"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_95" r="4" rot="99.0646" t="99.0646"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_96" r="4" rot="98.6922" t="98.6922"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_97" r="4" rot="97.9473" t="97.9473"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_98" r="4" rot="97.5749" t="97.5749"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_99" r="4" rot="97.2025" t="97.2025"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_100" r="4" rot="96.83" t="96.83"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_101" r="4" rot="96.4576" t="96.4576"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_102" r="4" rot="96.0852" t="96.0852"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_103" r="4" rot="95.7128" t="95.7128"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_104" r="4" rot="95.3404" t="95.3404"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_105" r="4" rot="94.9679" t="94.9679"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_106" r="4" rot="94.5955" t="94.5955"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_107" r="4" rot="94.2231" t="94.2231"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_108" r="4" rot="93.8507" t="93.8507"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_109" r="4" rot="93.4782" t="93.4782"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_110" r="4" rot="93.1058" t="93.1058"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_111" r="4" rot="92.7334" t="92.7334"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_112" r="4" rot="92.361" t="92.361"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_113" r="4" rot="91.9885" t="91.9885"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_114" r="4" rot="91.6161" t="91.6161"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_115" r="4" rot="91.2437" t="91.2437"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_116" r="4" rot="90.8713" t="90.8713"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_117" r="4" rot="90.4989" t="90.4989"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_118" r="4" rot="90.1264" t="90.1264"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_119" r="4" rot="89.754" t="89.754"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_120" r="4" rot="89.3816" t="89.3816"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_121" r="4" rot="89.0092" t="89.0092"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_122" r="4" rot="88.6367" t="88.6367"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_123" r="4" rot="88.2643" t="88.2643"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_124" r="4" rot="87.8919" t="87.8919"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_125" r="4" rot="87.5195" t="87.5195"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_126" r="4" rot="87.147" t="87.147"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_127" r="4" rot="86.7746" t="86.7746"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_128" r="4" rot="86.4022" t="86.4022"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_129" r="4" rot="85.6573" t="85.6573"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_130" r="4" rot="85.2849" t="85.2849"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_131" r="4" rot="84.9125" t="84.9125"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_132" r="4" rot="84.5401" t="84.5401"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_133" r="4" rot="84.1677" t="84.1677"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_134" r="4" rot="83.7952" t="83.7952"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_135" r="4" rot="83.4228" t="83.4228"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_136" r="4" rot="83.0504" t="83.0504"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_137" r="4" rot="82.678" t="82.678"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_138" r="4" rot="82.3055" t="82.3055"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_139" r="4" rot="81.9331" t="81.9331"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_140" r="4" rot="81.5607" t="81.5607"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_141" r="4" rot="81.1883" t="81.1883"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_142" r="4" rot="80.8158" t="80.8158"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_143" r="4" rot="80.4434" t="80.4434"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_144" r="4" rot="80.071" t="80.071"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_145" r="4" rot="79.6986" t="79.6986"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_146" r="4" rot="79.3262" t="79.3262"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_147" r="4" rot="78.9537" t="78.9537"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_148" r="4" rot="78.5813" t="78.5813"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_149" r="4" rot="78.2089" t="78.2089"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_150" r="4" rot="77.8365" t="77.8365"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_151" r="4" rot="77.464" t="77.464"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_152" r="4" rot="77.0916" t="77.0916"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_153" r="4" rot="76.7192" t="76.7192"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_154" r="4" rot="76.3468" t="76.3468"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_155" r="4" rot="75.9743" t="75.9743"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_156" r="4" rot="75.6019" t="75.6019"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_157" r="4" rot="75.2295" t="75.2295"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_158" r="4" rot="74.8571" t="74.8571"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_159" r="4" rot="74.4846" t="74.4846"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_160" r="4" rot="74.1122" t="74.1122"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_161" r="4" rot="73.3674" t="73.3674"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_162" r="4" rot="72.995" t="72.995"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_163" r="4" rot="72.6225" t="72.6225"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_164" r="4" rot="72.2501" t="72.2501"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_165" r="4" rot="71.8777" t="71.8777"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_166" r="4" rot="71.5053" t="71.5053"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_167" r="4" rot="71.1328" t="71.1328"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_168" r="4" rot="70.7604" t="70.7604"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_169" r="4" rot="70.388" t="70.388"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_170" r="4" rot="70.0156" t="70.0156"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_171" r="4" rot="69.6432" t="69.6432"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_172" r="4" rot="69.2707" t="69.2707"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_173" r="4" rot="68.8983" t="68.8983"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_174" r="4" rot="68.5259" t="68.5259"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_175" r="4" rot="68.1535" t="68.1535"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_176" r="4" rot="67.781" t="67.781"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_177" r="4" rot="67.4086" t="67.4086"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_178" r="4" rot="67.0362" t="67.0362"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_179" r="4" rot="66.6638" t="66.6638"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_180" r="4" rot="66.2913" t="66.2913"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_181" r="4" rot="65.9189" t="65.9189"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_182" r="4" rot="65.5465" t="65.5465"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_183" r="4" rot="65.1741" t="65.1741"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_184" r="4" rot="64.8017" t="64.8017"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_185" r="4" rot="64.4292" t="64.4292"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_186" r="4" rot="64.0568" t="64.0568"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_187" r="4" rot="63.6844" t="63.6844"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_188" r="4" rot="63.312" t="63.312"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_189" r="4" rot="62.9395" t="62.9395"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_190" r="4" rot="62.5671" t="62.5671"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_191" r="4" rot="62.1947" t="62.1947"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_192" r="4" rot="61.8223" t="61.8223"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_193" r="4" rot="61.0774" t="61.0774"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_194" r="4" rot="60.705" t="60.705"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_195" r="4" rot="60.3326" t="60.3326"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_196" r="4" rot="59.9601" t="59.9601"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_197" r="4" rot="59.5877" t="59.5877"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_198" r="4" rot="59.2153" t="59.2153"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_199" r="4" rot="58.8429" t="58.8429"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_200" r="4" rot="58.4704" t="58.4704"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_201" r="4" rot="58.098" t="58.098"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_202" r="4" rot="57.7256" t="57.7256"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_203" r="4" rot="57.3532" t="57.3532"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_204" r="4" rot="56.9808" t="56.9808"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_205" r="4" rot="56.6083" t="56.6083"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_206" r="4" rot="56.2359" t="56.2359"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_207" r="4" rot="55.8635" t="55.8635"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_208" r="4" rot="55.4911" t="55.4911"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_209" r="4" rot="55.1186" t="55.1186"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_210" r="4" rot="54.7462" t="54.7462"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_211" r="4" rot="54.3738" t="54.3738"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_212" r="4" rot="54.0014" t="54.0014"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_213" r="4" rot="53.6289" t="53.6289"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_214" r="4" rot="53.2565" t="53.2565"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_215" r="4" rot="52.8841" t="52.8841"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_216" r="4" rot="52.5117" t="52.5117"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_217" r="4" rot="52.1393" t="52.1393"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_218" r="4" rot="51.7668" t="51.7668"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_219" r="4" rot="51.3944" t="51.3944"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_220" r="4" rot="51.022" t="51.022"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_221" r="4" rot="50.6496" t="50.6496"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_222" r="4" rot="50.2771" t="50.2771"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_223" r="4" rot="49.9047" t="49.9047"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_224" r="4" rot="49.5323" t="49.5323"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_225" r="4" rot="48.7874" t="48.7874"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_226" r="4" rot="48.415" t="48.415"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_227" r="4" rot="48.0426" t="48.0426"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_228" r="4" rot="47.6702" t="47.6702"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_229" r="4" rot="47.2978" t="47.2978"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_230" r="4" rot="46.9253" t="46.9253"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_231" r="4" rot="46.5529" t="46.5529"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_232" r="4" rot="46.1805" t="46.1805"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_233" r="4" rot="45.8081" t="45.8081"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_234" r="4" rot="45.4356" t="45.4356"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_235" r="4" rot="45.0632" t="45.0632"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_236" r="4" rot="44.6908" t="44.6908"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_237" r="4" rot="44.3184" t="44.3184"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_238" r="4" rot="43.9459" t="43.9459"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_239" r="4" rot="43.5735" t="43.5735"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_240" r="4" rot="43.2011" t="43.2011"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_241" r="4" rot="42.8287" t="42.8287"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_242" r="4" rot="42.4562" t="42.4562"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_243" r="4" rot="42.0838" t="42.0838"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_244" r="4" rot="41.7114" t="41.7114"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_245" r="4" rot="41.339" t="41.339"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_246" r="4" rot="40.9666" t="40.9666"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_247" r="4" rot="40.5941" t="40.5941"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_248" r="4" rot="40.2217" t="40.2217"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_249" r="4" rot="39.8493" t="39.8493"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_250" r="4" rot="39.4769" t="39.4769"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_251" r="4" rot="39.1044" t="39.1044"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_252" r="4" rot="38.732" t="38.732"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_253" r="4" rot="38.3596" t="38.3596"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_254" r="4" rot="37.9872" t="37.9872"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_255" r="4" rot="37.6147" t="37.6147"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_256" r="4" rot="37.2423" t="37.2423"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_257" r="4" rot="36.4975" t="36.4975"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_258" r="4" rot="36.1251" t="36.1251"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_259" r="4" rot="35.7526" t="35.7526"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_260" r="4" rot="35.3802" t="35.3802"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_261" r="4" rot="35.0078" t="35.0078"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_262" r="4" rot="34.6354" t="34.6354"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_263" r="4" rot="34.2629" t="34.2629"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_264" r="4" rot="33.8905" t="33.8905"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_265" r="4" rot="33.5181" t="33.5181"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_266" r="4" rot="33.1457" t="33.1457"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_267" r="4" rot="32.7732" t="32.7732"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_268" r="4" rot="32.4008" t="32.4008"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_269" r="4" rot="32.0284" t="32.0284"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_270" r="4" rot="31.656" t="31.656"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_271" r="4" rot="31.2836" t="31.2836"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_272" r="4" rot="30.9111" t="30.9111"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_273" r="4" rot="30.5387" t="30.5387"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_274" r="4" rot="30.1663" t="30.1663"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_275" r="4" rot="29.7939" t="29.7939"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_276" r="4" rot="29.4214" t="29.4214"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_277" r="4" rot="29.049" t="29.049"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_278" r="4" rot="28.6766" t="28.6766"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_279" r="4" rot="28.3042" t="28.3042"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_280" r="4" rot="27.9317" t="27.9317"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_281" r="4" rot="27.5593" t="27.5593"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_282" r="4" rot="27.1869" t="27.1869"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_283" r="4" rot="26.8145" t="26.8145"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_284" r="4" rot="26.442" t="26.442"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_285" r="4" rot="26.0696" t="26.0696"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_286" r="4" rot="25.6972" t="25.6972"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_287" r="4" rot="25.3248" t="25.3248"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_288" r="4" rot="24.9524" t="24.9524"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_289" r="4" rot="24.2075" t="24.2075"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_290" r="4" rot="23.8351" t="23.8351"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_291" r="4" rot="23.4627" t="23.4627"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_292" r="4" rot="23.0902" t="23.0902"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_293" r="4" rot="22.7178" t="22.7178"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_294" r="4" rot="22.3454" t="22.3454"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_295" r="4" rot="21.973" t="21.973"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_296" r="4" rot="21.6005" t="21.6005"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_297" r="4" rot="21.2281" t="21.2281"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_298" r="4" rot="20.8557" t="20.8557"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_299" r="4" rot="20.4833" t="20.4833"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_300" r="4" rot="20.1109" t="20.1109"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_301" r="4" rot="19.7384" t="19.7384"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_302" r="4" rot="19.366" t="19.366"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_303" r="4" rot="18.9936" t="18.9936"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_304" r="4" rot="18.6212" t="18.6212"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_305" r="4" rot="18.2487" t="18.2487"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_306" r="4" rot="17.8763" t="17.8763"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_307" r="4" rot="17.5039" t="17.5039"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_308" r="4" rot="17.1315" t="17.1315"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_309" r="4" rot="16.759" t="16.759"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_310" r="4" rot="16.3866" t="16.3866"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_311" r="4" rot="16.0142" t="16.0142"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_312" r="4" rot="15.6418" t="15.6418"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_313" r="4" rot="15.2694" t="15.2694"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_314" r="4" rot="14.8969" t="14.8969"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_315" r="4" rot="14.5245" t="14.5245"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_316" r="4" rot="14.1521" t="14.1521"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_317" r="4" rot="13.7797" t="13.7797"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_318" r="4" rot="13.4072" t="13.4072"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_319" r="4" rot="13.0348" t="13.0348"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_320" r="4" rot="12.6624" t="12.6624"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_321" r="4" rot="11.9175" t="11.9175"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_322" r="4" rot="11.5451" t="11.5451"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_323" r="4" rot="11.1727" t="11.1727"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_324" r="4" rot="10.8003" t="10.8003"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_325" r="4" rot="10.4279" t="10.4279"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_326" r="4" rot="10.0554" t="10.0554"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_327" r="4" rot="9.683" t="9.683"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_328" r="4" rot="9.31058" t="9.31058"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_329" r="4" rot="8.93816" t="8.93816"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_330" r="4" rot="8.56573" t="8.56573"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_331" r="4" rot="8.19331" t="8.19331"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_332" r="4" rot="7.82089" t="7.82089"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_333" r="4" rot="7.44846" t="7.44846"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_334" r="4" rot="7.07604" t="7.07604"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_335" r="4" rot="6.70362" t="6.70362"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_336" r="4" rot="6.33119" t="6.33119"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_337" r="4" rot="5.95877" t="5.95877"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_338" r="4" rot="5.58635" t="5.58635"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_339" r="4" rot="5.21393" t="5.21393"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_340" r="4" rot="4.8415" t="4.8415"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_341" r="4" rot="4.46908" t="4.46908"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_342" r="4" rot="4.09666" t="4.09666"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_343" r="4" rot="3.72423" t="3.72423"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_344" r="4" rot="3.35181" t="3.35181"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_345" r="4" rot="2.97939" t="2.97939"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_346" r="4" rot="2.60696" t="2.60696"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_347" r="4" rot="2.23454" t="2.23454"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_348" r="4" rot="1.86212" t="1.86212"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_349" r="4" rot="1.48969" t="1.48969"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_350" r="4" rot="1.11727" t="1.11727"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_351" r="4" rot="0.744847" t="0.744847"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_352" r="4" rot="0.372423" t="0.372423"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_353" r="4" rot="-0.372423" t="-0.372423"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_354" r="4" rot="-0.744846" t="-0.744846"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_355" r="4" rot="-1.11727" t="-1.11727"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_356" r="4" rot="-1.48969" t="-1.48969"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_357" r="4" rot="-1.86212" t="-1.86212"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_358" r="4" rot="-2.23454" t="-2.23454"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_359" r="4" rot="-2.60696" t="-2.60696"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_360" r="4" rot="-2.97939" t="-2.97939"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_361" r="4" rot="-3.35181" t="-3.35181"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_362" r="4" rot="-3.72423" t="-3.72423"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_363" r="4" rot="-4.09666" t="-4.09666"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_364" r="4" rot="-4.46908" t="-4.46908"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_365" r="4" rot="-4.8415" t="-4.8415"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_366" r="4" rot="-5.21393" t="-5.21393"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_367" r="4" rot="-5.58635" t="-5.58635"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_368" r="4" rot="-5.95877" t="-5.95877"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_369" r="4" rot="-6.33119" t="-6.33119"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_370" r="4" rot="-6.70362" t="-6.70362"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_371" r="4" rot="-7.07604" t="-7.07604"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_372" r="4" rot="-7.44846" t="-7.44846"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_373" r="4" rot="-7.82089" t="-7.82089"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_374" r="4" rot="-8.19331" t="-8.19331"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_375" r="4" rot="-8.56573" t="-8.56573"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_376" r="4" rot="-8.93816" t="-8.93816"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_377" r="4" rot="-9.31058" t="-9.31058"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_378" r="4" rot="-9.683" t="-9.683"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_379" r="4" rot="-10.0554" t="-10.0554"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_380" r="4" rot="-10.4279" t="-10.4279"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_381" r="4" rot="-10.8003" t="-10.8003"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_382" r="4" rot="-11.1727" t="-11.1727"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_383" r="4" rot="-11.5451" t="-11.5451"/>
+      <location axis-x="0.0" axis-y="1.0" axis-z="0.0" name="tube_384" r="4" rot="-11.9175" t="-11.9175"/>
     </component>
   </type>
-  <!-- Definition of standard_tube -->
   <type name="standard_tube" outline="yes">
     <component type="standard_pixel">
-      <location y="-1.566805" />
-      <location y="-1.554516" />
-      <location y="-1.542228" />
-      <location y="-1.529939" />
-      <location y="-1.517650" />
-      <location y="-1.505362" />
-      <location y="-1.493073" />
-      <location y="-1.480784" />
-      <location y="-1.468496" />
-      <location y="-1.456207" />
-      <location y="-1.443918" />
-      <location y="-1.431630" />
-      <location y="-1.419341" />
-      <location y="-1.407052" />
-      <location y="-1.394764" />
-      <location y="-1.382475" />
-      <location y="-1.370186" />
-      <location y="-1.357898" />
-      <location y="-1.345609" />
-      <location y="-1.333320" />
-      <location y="-1.321032" />
-      <location y="-1.308743" />
-      <location y="-1.296454" />
-      <location y="-1.284166" />
-      <location y="-1.271877" />
-      <location y="-1.259588" />
-      <location y="-1.247300" />
-      <location y="-1.235011" />
-      <location y="-1.222722" />
-      <location y="-1.210434" />
-      <location y="-1.198145" />
-      <location y="-1.185856" />
-      <location y="-1.173568" />
-      <location y="-1.161279" />
-      <location y="-1.148990" />
-      <location y="-1.136702" />
-      <location y="-1.124413" />
-      <location y="-1.112124" />
-      <location y="-1.099836" />
-      <location y="-1.087547" />
-      <location y="-1.075258" />
-      <location y="-1.062970" />
-      <location y="-1.050681" />
-      <location y="-1.038392" />
-      <location y="-1.026104" />
-      <location y="-1.013815" />
-      <location y="-1.001526" />
-      <location y="-0.989238" />
-      <location y="-0.976949" />
-      <location y="-0.964660" />
-      <location y="-0.952372" />
-      <location y="-0.940083" />
-      <location y="-0.927794" />
-      <location y="-0.915506" />
-      <location y="-0.903217" />
-      <location y="-0.890928" />
-      <location y="-0.878640" />
-      <location y="-0.866351" />
-      <location y="-0.854062" />
-      <location y="-0.841774" />
-      <location y="-0.829485" />
-      <location y="-0.817196" />
-      <location y="-0.804908" />
-      <location y="-0.792619" />
-      <location y="-0.780330" />
-      <location y="-0.768042" />
-      <location y="-0.755753" />
-      <location y="-0.743464" />
-      <location y="-0.731176" />
-      <location y="-0.718887" />
-      <location y="-0.706598" />
-      <location y="-0.694310" />
-      <location y="-0.682021" />
-      <location y="-0.669732" />
-      <location y="-0.657444" />
-      <location y="-0.645155" />
-      <location y="-0.632866" />
-      <location y="-0.620578" />
-      <location y="-0.608289" />
-      <location y="-0.596000" />
-      <location y="-0.583712" />
-      <location y="-0.571423" />
-      <location y="-0.559134" />
-      <location y="-0.546846" />
-      <location y="-0.534557" />
-      <location y="-0.522268" />
-      <location y="-0.509980" />
-      <location y="-0.497691" />
-      <location y="-0.485402" />
-      <location y="-0.473114" />
-      <location y="-0.460825" />
-      <location y="-0.448536" />
-      <location y="-0.436248" />
-      <location y="-0.423959" />
-      <location y="-0.411670" />
-      <location y="-0.399382" />
-      <location y="-0.387093" />
-      <location y="-0.374804" />
-      <location y="-0.362516" />
-      <location y="-0.350227" />
-      <location y="-0.337938" />
-      <location y="-0.325650" />
-      <location y="-0.313361" />
-      <location y="-0.301072" />
-      <location y="-0.288784" />
-      <location y="-0.276495" />
-      <location y="-0.264206" />
-      <location y="-0.251918" />
-      <location y="-0.239629" />
-      <location y="-0.227340" />
-      <location y="-0.215052" />
-      <location y="-0.202763" />
-      <location y="-0.190474" />
-      <location y="-0.178186" />
-      <location y="-0.165897" />
-      <location y="-0.153608" />
-      <location y="-0.141320" />
-      <location y="-0.129031" />
-      <location y="-0.116742" />
-      <location y="-0.104454" />
-      <location y="-0.092165" />
-      <location y="-0.079876" />
-      <location y="-0.067588" />
-      <location y="-0.055299" />
-      <location y="-0.043010" />
-      <location y="-0.030722" />
-      <location y="-0.018433" />
-      <location y="-0.006144" />
-      <location y="0.006144" />
-      <location y="0.018433" />
-      <location y="0.030722" />
-      <location y="0.043010" />
-      <location y="0.055299" />
-      <location y="0.067588" />
-      <location y="0.079876" />
-      <location y="0.092165" />
-      <location y="0.104454" />
-      <location y="0.116742" />
-      <location y="0.129031" />
-      <location y="0.141320" />
-      <location y="0.153608" />
-      <location y="0.165897" />
-      <location y="0.178186" />
-      <location y="0.190474" />
-      <location y="0.202763" />
-      <location y="0.215052" />
-      <location y="0.227340" />
-      <location y="0.239629" />
-      <location y="0.251918" />
-      <location y="0.264206" />
-      <location y="0.276495" />
-      <location y="0.288784" />
-      <location y="0.301072" />
-      <location y="0.313361" />
-      <location y="0.325650" />
-      <location y="0.337938" />
-      <location y="0.350227" />
-      <location y="0.362516" />
-      <location y="0.374804" />
-      <location y="0.387093" />
-      <location y="0.399382" />
-      <location y="0.411670" />
-      <location y="0.423959" />
-      <location y="0.436248" />
-      <location y="0.448536" />
-      <location y="0.460825" />
-      <location y="0.473114" />
-      <location y="0.485402" />
-      <location y="0.497691" />
-      <location y="0.509980" />
-      <location y="0.522268" />
-      <location y="0.534557" />
-      <location y="0.546846" />
-      <location y="0.559134" />
-      <location y="0.571423" />
-      <location y="0.583712" />
-      <location y="0.596000" />
-      <location y="0.608289" />
-      <location y="0.620578" />
-      <location y="0.632866" />
-      <location y="0.645155" />
-      <location y="0.657444" />
-      <location y="0.669732" />
-      <location y="0.682021" />
-      <location y="0.694310" />
-      <location y="0.706598" />
-      <location y="0.718887" />
-      <location y="0.731176" />
-      <location y="0.743464" />
-      <location y="0.755753" />
-      <location y="0.768042" />
-      <location y="0.780330" />
-      <location y="0.792619" />
-      <location y="0.804908" />
-      <location y="0.817196" />
-      <location y="0.829485" />
-      <location y="0.841774" />
-      <location y="0.854062" />
-      <location y="0.866351" />
-      <location y="0.878640" />
-      <location y="0.890928" />
-      <location y="0.903217" />
-      <location y="0.915506" />
-      <location y="0.927794" />
-      <location y="0.940083" />
-      <location y="0.952372" />
-      <location y="0.964660" />
-      <location y="0.976949" />
-      <location y="0.989238" />
-      <location y="1.001526" />
-      <location y="1.013815" />
-      <location y="1.026104" />
-      <location y="1.038392" />
-      <location y="1.050681" />
-      <location y="1.062970" />
-      <location y="1.075258" />
-      <location y="1.087547" />
-      <location y="1.099836" />
-      <location y="1.112124" />
-      <location y="1.124413" />
-      <location y="1.136702" />
-      <location y="1.148990" />
-      <location y="1.161279" />
-      <location y="1.173568" />
-      <location y="1.185856" />
-      <location y="1.198145" />
-      <location y="1.210434" />
-      <location y="1.222722" />
-      <location y="1.235011" />
-      <location y="1.247300" />
-      <location y="1.259588" />
-      <location y="1.271877" />
-      <location y="1.284166" />
-      <location y="1.296454" />
-      <location y="1.308743" />
-      <location y="1.321032" />
-      <location y="1.333320" />
-      <location y="1.345609" />
-      <location y="1.357898" />
-      <location y="1.370186" />
-      <location y="1.382475" />
-      <location y="1.394764" />
-      <location y="1.407052" />
-      <location y="1.419341" />
-      <location y="1.431630" />
-      <location y="1.443918" />
-      <location y="1.456207" />
-      <location y="1.468496" />
-      <location y="1.480784" />
-      <location y="1.493073" />
-      <location y="1.505362" />
-      <location y="1.517650" />
-      <location y="1.529939" />
-      <location y="1.542228" />
-      <location y="1.554516" />
-      <location y="1.566805" />
+      <location y="-1.56680497925"/>
+      <location y="-1.55451631275"/>
+      <location y="-1.54222764625"/>
+      <location y="-1.52993897974"/>
+      <location y="-1.51765031324"/>
+      <location y="-1.50536164673"/>
+      <location y="-1.49307298023"/>
+      <location y="-1.48078431373"/>
+      <location y="-1.46849564722"/>
+      <location y="-1.45620698072"/>
+      <location y="-1.44391831421"/>
+      <location y="-1.43162964771"/>
+      <location y="-1.41934098121"/>
+      <location y="-1.4070523147"/>
+      <location y="-1.3947636482"/>
+      <location y="-1.38247498169"/>
+      <location y="-1.37018631519"/>
+      <location y="-1.35789764869"/>
+      <location y="-1.34560898218"/>
+      <location y="-1.33332031568"/>
+      <location y="-1.32103164917"/>
+      <location y="-1.30874298267"/>
+      <location y="-1.29645431617"/>
+      <location y="-1.28416564966"/>
+      <location y="-1.27187698316"/>
+      <location y="-1.25958831665"/>
+      <location y="-1.24729965015"/>
+      <location y="-1.23501098365"/>
+      <location y="-1.22272231714"/>
+      <location y="-1.21043365064"/>
+      <location y="-1.19814498413"/>
+      <location y="-1.18585631763"/>
+      <location y="-1.17356765113"/>
+      <location y="-1.16127898462"/>
+      <location y="-1.14899031812"/>
+      <location y="-1.13670165162"/>
+      <location y="-1.12441298511"/>
+      <location y="-1.11212431861"/>
+      <location y="-1.0998356521"/>
+      <location y="-1.0875469856"/>
+      <location y="-1.0752583191"/>
+      <location y="-1.06296965259"/>
+      <location y="-1.05068098609"/>
+      <location y="-1.03839231958"/>
+      <location y="-1.02610365308"/>
+      <location y="-1.01381498658"/>
+      <location y="-1.00152632007"/>
+      <location y="-0.989237653568"/>
+      <location y="-0.976948987064"/>
+      <location y="-0.96466032056"/>
+      <location y="-0.952371654056"/>
+      <location y="-0.940082987552"/>
+      <location y="-0.927794321048"/>
+      <location y="-0.915505654544"/>
+      <location y="-0.90321698804"/>
+      <location y="-0.890928321536"/>
+      <location y="-0.878639655032"/>
+      <location y="-0.866350988528"/>
+      <location y="-0.854062322024"/>
+      <location y="-0.84177365552"/>
+      <location y="-0.829484989016"/>
+      <location y="-0.817196322512"/>
+      <location y="-0.804907656008"/>
+      <location y="-0.792618989505"/>
+      <location y="-0.780330323001"/>
+      <location y="-0.768041656497"/>
+      <location y="-0.755752989993"/>
+      <location y="-0.743464323489"/>
+      <location y="-0.731175656985"/>
+      <location y="-0.718886990481"/>
+      <location y="-0.706598323977"/>
+      <location y="-0.694309657473"/>
+      <location y="-0.682020990969"/>
+      <location y="-0.669732324465"/>
+      <location y="-0.657443657961"/>
+      <location y="-0.645154991457"/>
+      <location y="-0.632866324953"/>
+      <location y="-0.620577658449"/>
+      <location y="-0.608288991945"/>
+      <location y="-0.596000325441"/>
+      <location y="-0.583711658937"/>
+      <location y="-0.571422992433"/>
+      <location y="-0.55913432593"/>
+      <location y="-0.546845659426"/>
+      <location y="-0.534556992922"/>
+      <location y="-0.522268326418"/>
+      <location y="-0.509979659914"/>
+      <location y="-0.49769099341"/>
+      <location y="-0.485402326906"/>
+      <location y="-0.473113660402"/>
+      <location y="-0.460824993898"/>
+      <location y="-0.448536327394"/>
+      <location y="-0.43624766089"/>
+      <location y="-0.423958994386"/>
+      <location y="-0.411670327882"/>
+      <location y="-0.399381661378"/>
+      <location y="-0.387092994874"/>
+      <location y="-0.37480432837"/>
+      <location y="-0.362515661866"/>
+      <location y="-0.350226995362"/>
+      <location y="-0.337938328859"/>
+      <location y="-0.325649662355"/>
+      <location y="-0.313360995851"/>
+      <location y="-0.301072329347"/>
+      <location y="-0.288783662843"/>
+      <location y="-0.276494996339"/>
+      <location y="-0.264206329835"/>
+      <location y="-0.251917663331"/>
+      <location y="-0.239628996827"/>
+      <location y="-0.227340330323"/>
+      <location y="-0.215051663819"/>
+      <location y="-0.202762997315"/>
+      <location y="-0.190474330811"/>
+      <location y="-0.178185664307"/>
+      <location y="-0.165896997803"/>
+      <location y="-0.153608331299"/>
+      <location y="-0.141319664795"/>
+      <location y="-0.129030998291"/>
+      <location y="-0.116742331787"/>
+      <location y="-0.104453665284"/>
+      <location y="-0.0921649987796"/>
+      <location y="-0.0798763322756"/>
+      <location y="-0.0675876657717"/>
+      <location y="-0.0552989992678"/>
+      <location y="-0.0430103327638"/>
+      <location y="-0.0307216662599"/>
+      <location y="-0.0184329997559"/>
+      <location y="-0.00614433325197"/>
+      <location y="0.00614433325197"/>
+      <location y="0.0184329997559"/>
+      <location y="0.0307216662599"/>
+      <location y="0.0430103327638"/>
+      <location y="0.0552989992678"/>
+      <location y="0.0675876657717"/>
+      <location y="0.0798763322756"/>
+      <location y="0.0921649987796"/>
+      <location y="0.104453665284"/>
+      <location y="0.116742331787"/>
+      <location y="0.129030998291"/>
+      <location y="0.141319664795"/>
+      <location y="0.153608331299"/>
+      <location y="0.165896997803"/>
+      <location y="0.178185664307"/>
+      <location y="0.190474330811"/>
+      <location y="0.202762997315"/>
+      <location y="0.215051663819"/>
+      <location y="0.227340330323"/>
+      <location y="0.239628996827"/>
+      <location y="0.251917663331"/>
+      <location y="0.264206329835"/>
+      <location y="0.276494996339"/>
+      <location y="0.288783662843"/>
+      <location y="0.301072329347"/>
+      <location y="0.313360995851"/>
+      <location y="0.325649662355"/>
+      <location y="0.337938328859"/>
+      <location y="0.350226995362"/>
+      <location y="0.362515661866"/>
+      <location y="0.37480432837"/>
+      <location y="0.387092994874"/>
+      <location y="0.399381661378"/>
+      <location y="0.411670327882"/>
+      <location y="0.423958994386"/>
+      <location y="0.43624766089"/>
+      <location y="0.448536327394"/>
+      <location y="0.460824993898"/>
+      <location y="0.473113660402"/>
+      <location y="0.485402326906"/>
+      <location y="0.49769099341"/>
+      <location y="0.509979659914"/>
+      <location y="0.522268326418"/>
+      <location y="0.534556992922"/>
+      <location y="0.546845659426"/>
+      <location y="0.55913432593"/>
+      <location y="0.571422992433"/>
+      <location y="0.583711658937"/>
+      <location y="0.596000325441"/>
+      <location y="0.608288991945"/>
+      <location y="0.620577658449"/>
+      <location y="0.632866324953"/>
+      <location y="0.645154991457"/>
+      <location y="0.657443657961"/>
+      <location y="0.669732324465"/>
+      <location y="0.682020990969"/>
+      <location y="0.694309657473"/>
+      <location y="0.706598323977"/>
+      <location y="0.718886990481"/>
+      <location y="0.731175656985"/>
+      <location y="0.743464323489"/>
+      <location y="0.755752989993"/>
+      <location y="0.768041656497"/>
+      <location y="0.780330323001"/>
+      <location y="0.792618989505"/>
+      <location y="0.804907656008"/>
+      <location y="0.817196322512"/>
+      <location y="0.829484989016"/>
+      <location y="0.84177365552"/>
+      <location y="0.854062322024"/>
+      <location y="0.866350988528"/>
+      <location y="0.878639655032"/>
+      <location y="0.890928321536"/>
+      <location y="0.90321698804"/>
+      <location y="0.915505654544"/>
+      <location y="0.927794321048"/>
+      <location y="0.940082987552"/>
+      <location y="0.952371654056"/>
+      <location y="0.96466032056"/>
+      <location y="0.976948987064"/>
+      <location y="0.989237653568"/>
+      <location y="1.00152632007"/>
+      <location y="1.01381498658"/>
+      <location y="1.02610365308"/>
+      <location y="1.03839231958"/>
+      <location y="1.05068098609"/>
+      <location y="1.06296965259"/>
+      <location y="1.0752583191"/>
+      <location y="1.0875469856"/>
+      <location y="1.0998356521"/>
+      <location y="1.11212431861"/>
+      <location y="1.12441298511"/>
+      <location y="1.13670165162"/>
+      <location y="1.14899031812"/>
+      <location y="1.16127898462"/>
+      <location y="1.17356765113"/>
+      <location y="1.18585631763"/>
+      <location y="1.19814498413"/>
+      <location y="1.21043365064"/>
+      <location y="1.22272231714"/>
+      <location y="1.23501098365"/>
+      <location y="1.24729965015"/>
+      <location y="1.25958831665"/>
+      <location y="1.27187698316"/>
+      <location y="1.28416564966"/>
+      <location y="1.29645431617"/>
+      <location y="1.30874298267"/>
+      <location y="1.32103164917"/>
+      <location y="1.33332031568"/>
+      <location y="1.34560898218"/>
+      <location y="1.35789764869"/>
+      <location y="1.37018631519"/>
+      <location y="1.38247498169"/>
+      <location y="1.3947636482"/>
+      <location y="1.4070523147"/>
+      <location y="1.41934098121"/>
+      <location y="1.43162964771"/>
+      <location y="1.44391831421"/>
+      <location y="1.45620698072"/>
+      <location y="1.46849564722"/>
+      <location y="1.48078431373"/>
+      <location y="1.49307298023"/>
+      <location y="1.50536164673"/>
+      <location y="1.51765031324"/>
+      <location y="1.52993897974"/>
+      <location y="1.54222764625"/>
+      <location y="1.55451631275"/>
+      <location y="1.56680497925"/>
     </component>
   </type>
-  <!--MONITOR SHAPE-->
-  <!--FIXME: Do something real here.-->
-  <type is="monitor" name="monitor">
-    <cylinder id="cyl-approx">
-      <centre-of-bottom-base y="0.0" x="0.0" z="0.0" />
-      <axis y="0.0" x="0.0" z="1.0" />
-      <radius val="0.01" />
-      <height val="0.03" />
-    </cylinder>
-    <algebra val="cyl-approx" />
+  <component idlist="detectors" type="detectors">
+    <location/>
+  </component>
+  <type name="detectors">
+    <component type="bank_uniq">
+      <location/>
+    </component>
   </type>
-  <!--MONITOR IDs-->
-  <idlist idname="monitors">
-    <id val="0" />
+  <idlist idname="detectors">
+    <id end="98304" start="1"/>
   </idlist>
-  <type name="standard_pixel" is="detector">
-    <cylinder id="shape">
-      <centre-of-bottom-base x="0.0" y="-0.006144" z="0.0" />
-      <axis x="0.0" y="1.0" z="0.0" />
-      <radius val="0.0127" />
-      <height val=".0114341328125" />
-    </cylinder>
-    <algebra val="shape" />
-  </type>
 </instrument>
diff --git a/instrument/LARMOR_Definition_SEMSANS.xml b/instrument/LARMOR_Definition_SEMSANS.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a35b9fb619fb65180e1b50f70bef4676a1cafec1
--- /dev/null
+++ b/instrument/LARMOR_Definition_SEMSANS.xml
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- For help on the notation used to specify an Instrument Definition File 
+     see http://www.mantidproject.org/IDF -->
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
+ name="LARMOR" valid-from   ="2018-11-15 00:00:00"
+                          valid-to     ="2100-01-31 23:59:59"
+		          last-modified="2100-01-01 10:30:00">
+
+  <defaults>
+    <length unit="meter"/>
+    <angle unit="degree"/>  
+    <reference-frame>
+      <!-- The z-axis is set parallel to and in the direction of the beam. the 
+           y-axis points up and the coordinate system is right handed. -->
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+    <default-view axis-view="z-"/>
+  </defaults>
+
+  
+  <!-- BRIEF DESCRIPTION OF LARMOR INSTRUMENT: 
+  
+      Data provided by Richard Heenan (and Freddie) for the SANS2D instrument
+      12/06/09 this version has X & Y coords detector swapped so orientation
+      is correct for temporary wiring table.
+      18/06/09 better distances for detectors and both at L2=4m, front at X=-1.1m
+      26/06/09 swap front & rear as names wrong, translate front in opposite direction
+	  21/07/09 remove the 150mm sideways shift (i.e. back to symmetrical detector coords)
+	  to simplify manipulations in Mantid and help allow for detector mapping not quite 
+	  as expected.
+	  01/02/10 very small chang eto pixel size 191*5.1=974.2=2*487.05 (was 487.4)
+	  - note have to swap x= and y= in Anders output list !
+      02/04/12 Put in 'no shape monitors' for possible in the future monitors
+      with ID 5-8
+  -->
+  
+  
+  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+  
+  <!-- source and sample-position components -->
+
+  <component type="source">
+    <location />
+  </component>
+  <type name="source" is="Source" />
+  
+  <component type="some-sample-holder">
+    <location z="25.300"/>
+  </component>
+  <type name="some-sample-holder" is="SamplePos" />
+  
+  
+  <!-- detector components (including monitors) -->
+  
+  <component type="monitors" idlist="monitors">
+    <location />
+  </component>
+  
+  <type name="monitors">
+    <component type="monitor-tbd">
+      <!-- better positions and shapes will be defined later -->
+      <location z="9.8195" name="monitor1"/>
+      <location z="20.313" name="monitor2"/>
+      <location z="24.056" name="monitor3"/>
+    </component>
+    <component type="Moderator-Monitor4">
+      <!-- transmisssion detector, either in or out of beam -->
+      <location z="25.760" name="monitor4"/>
+    </component>
+    <component type="monitor-tbd">
+      <!-- better positions and shapes will be defined later -->
+      <location z="29.6500" name="monitor5"/>
+    </component>    
+    
+    <!-- Putting in monitors, which are defined in raw/neuxs
+         files, and have detector IDs, but currently not physically present 
+         on the instrument. Defined with no geometric shape, as they do not 
+         physically exist, and with a dummy position -->
+    <component type="no shape monitor">
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>
+      <location z="0" name="placeholder monitor"/>      
+    </component>  
+    
+  </type>
+  
+  <type name="monitor-tbd" is="monitor">
+    <cylinder id="some-shape">
+      <centre-of-bottom-base r="0.0" t="0.0" p="0.0" />
+      <axis x="0.0" y="0.0" z="1.0" /> 
+      <radius val="0.01" />
+      <height val="0.03" />
+    </cylinder>   
+  </type>
+  
+  <type name="Moderator-Monitor4" is="monitor">
+    <percent-transparency val="99.9" />
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.0125" y="-0.0125" z="0.0"  />
+      <left-front-top-point  x="0.0125" y="-0.0125" z="0.005"  />
+      <left-back-bottom-point  x="-0.0125" y="-0.0125" z="0.0"  />
+      <right-front-bottom-point  x="0.0125" y="0.0125" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>  
+
+  <type name="no shape monitor" is="monitor" />   
+
+  <component type="DetectorBench">
+    <location x="0" y="0" z="25.300"/> 
+  </component>
+
+  <type name="DetectorBench">
+   <component type="LARMORSANSDetector" idlist="LARMORSANSDetector">
+     <location z="4.406" /> 
+   </component>   
+  </type>
+
+ <type name="LARMORSANSDetector">
+ <component type="LARMORUptube">
+<location  x=" -0.3206709  " name="tube1"/>
+<location  x=" -0.3040129  " name="tube3"/>
+<location  x=" -0.2873549  " name="tube5"/>
+<location  x=" -0.2706969  " name="tube7"/>
+<location  x=" -0.2540389  " name="tube9"/>
+<location  x=" -0.2373809  " name="tube11"/>
+<location  x=" -0.2207229  " name="tube13"/>
+<location  x=" -0.2040649  " name="tube15"/>
+<location  x=" -0.1874069  " name="tube17"/>
+<location  x=" -0.1707489  " name="tube19"/>
+<location  x=" -0.1540909  " name="tube21"/>
+<location  x=" -0.1374329  " name="tube23"/>
+<location  x=" -0.1207749  " name="tube25"/>
+<location  x=" -0.1041169  " name="tube27"/>
+<location  x=" -0.0874589  " name="tube29"/>
+<location  x=" -0.0708009  " name="tube31"/>
+<location  x=" -0.0541429  " name="tube33"/>
+<location  x=" -0.0374849  " name="tube35"/>
+<location  x=" -0.0208269  " name="tube37"/>
+<location  x=" -0.0041689  " name="tube39"/>
+<location  x=" 0.0124891   " name="tube41"/>
+<location  x=" 0.0291471   " name="tube43"/>
+<location  x=" 0.0458051   " name="tube45"/>
+<location  x=" 0.0624631   " name="tube47"/>
+<location  x=" 0.0791211   " name="tube49"/>
+<location  x=" 0.0957791   " name="tube51"/>
+<location  x=" 0.1124371   " name="tube53"/>
+<location  x=" 0.1290951   " name="tube55"/>
+<location  x=" 0.1457531   " name="tube57"/>
+<location  x=" 0.1624111   " name="tube59"/>
+<location  x=" 0.1790691   " name="tube61"/>
+<location  x=" 0.1957271   " name="tube63"/>
+<location  x=" 0.2123851   " name="tube65"/>
+<location  x=" 0.2290431   " name="tube67"/>
+<location  x=" 0.2457011   " name="tube69"/>
+<location  x=" 0.2623591   " name="tube71"/>
+<location  x=" 0.2790171   " name="tube73"/>
+<location  x=" 0.2956751   " name="tube75"/>
+<location  x=" 0.3123331   " name="tube77"/>
+<location  x=" 0.3289911   " name="tube79"/>
+</component>
+ <component type="LARMORDowntube">
+<location  x=" -0.3123799  " name="tube2"/>
+<location  x=" -0.2957219  " name="tube4"/>
+<location  x=" -0.2790639  " name="tube6"/>
+<location  x=" -0.2624059  " name="tube8"/>
+<location  x=" -0.2457479  " name="tube10"/>
+<location  x=" -0.2290899  " name="tube12"/>
+<location  x=" -0.2124319  " name="tube14"/>
+<location  x=" -0.1957739  " name="tube16"/>
+<location  x=" -0.1791159  " name="tube18"/>
+<location  x=" -0.1624579  " name="tube20"/>
+<location  x=" -0.1457999  " name="tube22"/>
+<location  x=" -0.1291419  " name="tube24"/>
+<location  x=" -0.1124839  " name="tube26"/>
+<location  x=" -0.0958259  " name="tube28"/>
+<location  x=" -0.0791679  " name="tube30"/>
+<location  x=" -0.0625099  " name="tube32"/>
+<location  x=" -0.0458519  " name="tube34"/>
+<location  x=" -0.0291939  " name="tube36"/>
+<location  x=" -0.0125359  " name="tube38"/>
+<location  x=" 0.0041221   " name="tube40"/>
+<location  x=" 0.0207801   " name="tube42"/>
+<location  x=" 0.0374381   " name="tube44"/>
+<location  x=" 0.0540961   " name="tube46"/>
+<location  x=" 0.0707541   " name="tube48"/>
+<location  x=" 0.0874121   " name="tube50"/>
+<location  x=" 0.1040701   " name="tube52"/>
+<location  x=" 0.1207281   " name="tube54"/>
+<location  x=" 0.1373861   " name="tube56"/>
+<location  x=" 0.1540441   " name="tube58"/>
+<location  x=" 0.1707021   " name="tube60"/>
+<location  x=" 0.1873601   " name="tube62"/>
+<location  x=" 0.2040181   " name="tube64"/>
+<location  x=" 0.2206761   " name="tube66"/>
+<location  x=" 0.2373341   " name="tube68"/>
+<location  x=" 0.2539921   " name="tube70"/>
+<location  x=" 0.2706501   " name="tube72"/>
+<location  x=" 0.2873081   " name="tube74"/>
+<location  x=" 0.3039661   " name="tube76"/>
+<location  x=" 0.3206241   " name="tube78"/>
+<location  x=" 0.3372821   " name="tube80"/>
+</component>
+ </type>
+ 
+ <type name="LARMORUptube" outline="yes">
+ <component type="pixel">
+   <locations y="-0.32" y-end="0.32" n-elements="512" />
+ </component>
+ </type>
+ 
+ <type name="LARMORDowntube" outline="yes">
+ <component type="pixel">
+   <locations y="-0.32" y-end="0.32" n-elements="512" />
+ </component>
+ </type>
+  
+  <type name="pixel" is="detector">
+    <cylinder id="cyl-approx">
+      <centre-of-bottom-base r="0.0" t="0.0" p="0.0" />
+      <axis x="0.0" y="0.2" z="0.0" />
+      <radius val="0.004" />
+      <height val="   1.25E-3" />
+    </cylinder>
+    <algebra val="cyl-approx" />
+  </type>
+
+  <type name="SEMSANSWLSF-pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point x="-3.25e-4" y="-0.0175" z="0.0"  />
+      <left-front-top-point  x="-3.25e-4" y="0.0175" z="0.0"  />
+      <left-back-bottom-point  x="-3.25e-4" y="-0.0175" z="0.01"  />
+      <right-front-bottom-point  x="3.25e-4" y="-0.0175" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+
+ <type name="SEMSANSWLSF-panel">
+   <component type="SEMSANSWLSF-pixel">
+     <locations x="0.0208" x-end="-0.0208" n-elements="64" />
+   </component>
+ </type>
+
+ <component type="SEMSANSWLSFDetector" idlist="SEMSANSWLSFDetector">
+     <location z="29.65" x="-0.5"/> 
+ </component>   
+
+  <type name="WLSF-pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point x="-0.001046875" y="-0.0955" z="0.0"  />
+      <left-front-top-point  x="-0.001046875" y="0.0955" z="0.0"  />
+      <left-back-bottom-point  x="-0.001046875" y="-0.0955" z="0.01"  />
+      <right-front-bottom-point  x="0.001046875" y="-0.0955" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+
+ <type name="WLSF-panel">
+   <component type="WLSF-pixel">
+     <locations x="0.03245" x-end="-0.03245" n-elements="32" />
+   </component>
+ </type>
+
+  <component type="DetectorTrolley">
+    <location x="0" y="0" z="25.300" rot="45.0" axis-x="0.0" axis-y="1.0" axis-z="0.0"/> 
+  </component>
+
+  <type name="DetectorTrolley">
+   <component type="LARMORWLSFDetector" idlist="LARMORWLSFDetector">
+     <location z="0.0" /> 
+   </component>   
+  </type>
+ 
+ <type name="LARMORWLSFDetector">
+	<component type="WLSF-panel">
+		<location  x="0.2345" z="1.090062" name="WLSF-Panel1"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="0.1675" z="1.102347" name="WLSF-Panel2"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="0.1005" z="1.110462" name="WLSF-Panel3"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="0.0335" z="1.114497" name="WLSF-Panel4"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="-0.0335" z="1.114497" name="WLSF-Panel5"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="-0.1005" z="1.110462" name="WLSF-Panel6"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="-0.1675" z="1.102347" name="WLSF-Panel7"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+	<component type="WLSF-panel">
+		<location  x="-0.2345" z="1.090062" name="WLSF-Panel8"> <facing x="0" y="0" z="25.3"/> </location>
+	</component>
+ </type>
+
+ <type name="SEMSANSWLSFDetector">
+	<component type="SEMSANSWLSF-panel">
+		<location  x="0.0" z="0.0" name="SEMSANSWLSF-Panel1"> </location>
+	</component>
+ </type>
+
+  <!-- DETECTOR and MONITOR ID LISTS -->
+
+  <idlist idname="monitors">
+    <id start="1" end="10" />  
+  </idlist>   
+  
+  <idlist idname="LARMORSANSDetector">
+   <id start="1108000" end="1108511" />
+   <id start="1110000" end="1110511" />
+   <id start="1112000" end="1112511" />
+   <id start="1114000" end="1114511" />
+   <id start="1116000" end="1116511" />
+   <id start="1118000" end="1118511" />
+   <id start="1120000" end="1120511" />
+   <id start="1122000" end="1122511" />
+   <id start="1200000" end="1200511" />
+   <id start="1202000" end="1202511" />
+   <id start="1204000" end="1204511" />
+   <id start="1206000" end="1206511" />
+   <id start="1208000" end="1208511" />
+   <id start="1210000" end="1210511" />
+   <id start="1212000" end="1212511" />
+   <id start="1214000" end="1214511" />
+   <id start="1216000" end="1216511" />
+   <id start="1218000" end="1218511" />
+   <id start="1220000" end="1220511" />
+   <id start="1222000" end="1222511" />
+   <id start="1300000" end="1300511" />
+   <id start="1302000" end="1302511" />
+   <id start="1304000" end="1304511" />
+   <id start="1306000" end="1306511" />
+   <id start="1308000" end="1308511" />
+   <id start="1310000" end="1310511" />
+   <id start="1312000" end="1312511" />
+   <id start="1314000" end="1314511" />
+   <id start="1316000" end="1316511" />
+   <id start="1318000" end="1318511" />
+   <id start="1320000" end="1320511" />
+   <id start="1322000" end="1322511" />
+   <id start="1400000" end="1400511" />
+   <id start="1402000" end="1402511" />
+   <id start="1404000" end="1404511" />
+   <id start="1406000" end="1406511" />
+   <id start="1408000" end="1408511" />
+   <id start="1410000" end="1410511" />
+   <id start="1412000" end="1412511" />
+   <id start="1414000" end="1414511" />
+
+   <id start="1109000" end="1109511" />
+   <id start="1111000" end="1111511" />
+   <id start="1113000" end="1113511" />
+   <id start="1115000" end="1115511" />
+   <id start="1117000" end="1117511" />
+   <id start="1119000" end="1119511" />
+   <id start="1121000" end="1121511" />
+   <id start="1123000" end="1123511" />
+   <id start="1201000" end="1201511" />
+   <id start="1203000" end="1203511" />
+   <id start="1205000" end="1205511" />
+   <id start="1207000" end="1207511" />
+   <id start="1209000" end="1209511" />
+   <id start="1211000" end="1211511" />
+   <id start="1213000" end="1213511" />
+   <id start="1215000" end="1215511" />
+   <id start="1217000" end="1217511" />
+   <id start="1219000" end="1219511" />
+   <id start="1221000" end="1221511" />
+   <id start="1223000" end="1223511" />
+   <id start="1301000" end="1301511" />
+   <id start="1303000" end="1303511" />
+   <id start="1305000" end="1305511" />
+   <id start="1307000" end="1307511" />
+   <id start="1309000" end="1309511" />
+   <id start="1311000" end="1311511" />
+   <id start="1313000" end="1313511" />
+   <id start="1315000" end="1315511" />
+   <id start="1317000" end="1317511" />
+   <id start="1319000" end="1319511" />
+   <id start="1321000" end="1321511" />
+   <id start="1323000" end="1323511" />
+   <id start="1401000" end="1401511" />
+   <id start="1403000" end="1403511" />
+   <id start="1405000" end="1405511" />
+   <id start="1407000" end="1407511" />
+   <id start="1409000" end="1409511" />
+   <id start="1411000" end="1411511" />
+   <id start="1413000" end="1413511" />
+   <id start="1415000" end="1415511" />
+  </idlist>
+
+  <idlist idname="LARMORWLSFDetector">
+   <id start="2000016" end="2000031" />
+   <id start="2000032" end="2000047" />
+   <id start="2000048" end="2000063" />
+   <id start="2000000" end="2000015" />
+   <id start="2000080" end="2000095" />
+   <id start="2000096" end="2000111" />
+   <id start="2000112" end="2000127" />
+   <id start="2000064" end="2000079" />
+
+   <id start="2000144" end="2000159" />
+   <id start="2000160" end="2000175" />
+   <id start="2000176" end="2000191" />
+   <id start="2000128" end="2000143" />
+   <id start="2000208" end="2000223" />
+   <id start="2000224" end="2000239" />
+   <id start="2000240" end="2000255" />
+   <id start="2000192" end="2000207" />
+  </idlist>
+  
+  <idlist idname="SEMSANSWLSFDetector">
+   <id start="3000000" end="3000063" />
+  </idlist>
+
+</instrument>
diff --git a/instrument/MERLIN_Definition_2017_02.xml b/instrument/MERLIN_Definition_2017_02.xml
index 062b2d9b1923f5805d38768d5ba07af50ff5e7da..3ce0f1b0f2c0446d87c26b19a38660027b8ddec6 100644
--- a/instrument/MERLIN_Definition_2017_02.xml
+++ b/instrument/MERLIN_Definition_2017_02.xml
@@ -5,8 +5,8 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
  name="MERLIN" valid-from   ="2017-09-12 11:00:01"
-               valid-to     ="2100-01-31 23:59:59"
-               last-modified="2017-09-11 14:00:05">
+               valid-to     ="2018-12-03 17:18:00"
+               last-modified="2019-01-03 13:48:00">
 
   <defaults>
     <length unit="meter"/>
diff --git a/instrument/MERLIN_Definition_2018_03.xml b/instrument/MERLIN_Definition_2018_03.xml
new file mode 100644
index 0000000000000000000000000000000000000000..55a5ed81c14261170c5b417c45d1c42e911e16ba
--- /dev/null
+++ b/instrument/MERLIN_Definition_2018_03.xml
@@ -0,0 +1,882 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- For help on the notation used to specify an Instrument Definition File 
+     see http://www.mantidproject.org/IDF -->
+<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
+ name="MERLIN" valid-from   ="2018-12-03 17:18:01"
+               valid-to     ="2100-01-31 23:59:59"
+               last-modified="2019-01-03 13:48:00">
+
+  <defaults>
+    <length unit="meter"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <!-- The z-axis is set parallel to and in the direction of the beam. the 
+           y-axis points up and the coordinate system is right handed. -->
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+    <default-view view="cylindrical_y"/>
+  </defaults>
+
+  
+  <!-- DESCRIPTION OF INSTRUMENT IN WORDS: 
+  
+    The data for Merlin was obtained from Robert Bewley.
+    
+    2012-05-17 - added names to tubes
+    2013-11-14 - use locations tag in tube definitions
+    2017-09-11 - change to 512 detectors per tube
+  -->
+
+  
+  <!--  SOURCE AND SAMPLE POSITION -->
+  
+  <component type="undulator">
+    <location z="-11.8" />
+  </component>
+  <type name="undulator" is="Source"> </type>
+  
+  <component type="sample-position">
+    <location />
+  </component>
+  <type name="sample-position" is="SamplePos"></type>
+  
+  <!-- Aperture -->
+  <component type="aperture" name="aperture">
+    <location z="-10.1"/>
+  </component>
+ 
+  <type name="aperture">
+  <cuboid id="aperture0">
+    <left-front-bottom-point x="0.047" y="-0.047" z="-0.0001"  />
+    <left-front-top-point  x="0.047" y="-0.047" z="0.0001"  />
+    <left-back-bottom-point  x="-0.047" y="-0.047" z="-0.0001"  />
+    <right-front-bottom-point  x="0.047" y="0.047" z="-0.0001"  />
+  </cuboid>
+  <algebra val="aperture0" />
+  </type>
+ 
+ <!-- Chopper position -->
+ <component type="chopper-position">
+    <location z="-1.8"/>
+    <!--description is="The component provides sample-choper distance, used
+    to estimate chopper delay time and Tobyfit resolution calculations."/-->
+    <parameter name="initial_phase">    
+        <value val="-490000."/>
+        <description is="The initial rotation phase of the disk used to caluclate the time
+        for neutrons arriving at the chopper according to the formula time = delay + initial_phase/Speed"/>    
+    </parameter>
+    <parameter name="ChopperDelayLog" type="string">
+        <value val="Chopper_delay"/>    
+    </parameter>
+    <parameter name="ChopperSpeedLog" type="string">
+        <value val="Chopper_Speed"/>    
+    </parameter>
+    <parameter name="FilterBaseLog" type="string">
+        <value val="good_uah_log"/>    
+    </parameter>
+    <!-- if the log above should be used as it is or 
+    one should calculate its derivative -->
+    <parameter name="filter_with_derivative" type="bool">
+        <value val="True"/>    
+    </parameter>    
+
+  </component>
+  <type name="chopper-position" is="ChopperPos"></type>  
+  
+
+  <!-- DETECTORS -->
+  
+  <component type="door1" idlist="door1">
+    <location />
+  </component>
+  
+  <!-- Uncomment to include door 6. If this is done you MUST also
+       uncomment the <idlist name="door6"> at the bottom of this file
+       -->
+  <component type="door2" idlist="door2">
+    <location />
+  </component>
+  
+  <component type="door3" idlist="door3">
+    <location />
+  </component>
+  
+  <component type="door4" idlist="door4">
+    <location />
+  </component>
+  
+  <component type="door5" idlist="door5">
+    <location />
+  </component>
+  
+  <component type="door6" idlist="door6">
+    <location />
+  </component>
+  
+  <component type="door7" idlist="door7">
+    <location />
+  </component>
+  
+  <component type="door8" idlist="door8">
+    <location />
+  </component>
+  
+  <component type="door9" idlist="door9">
+    <location />
+  </component>
+
+  <component type="monitors" idlist="monitors">
+    <location />
+  </component>
+  
+  <type name="monitors">
+    <component type="monitor">
+      <location r="3.25800" t="180.0" p="0.0" />
+      <!-- old position was 1.50400-->
+      <location r="1.60800" t="180.0" p="0.0" />
+      <location r="1.60800" t="180.0" p="0.0" />
+      <location r="1.60800" t="180.0" p="0.0" />
+      <location r="1.60800" t="180.0" p="0.0" /> 
+      <location r="4.24700" t="0.000" p="0.0" />
+      <location r="4.24700" t="0.000" p="0.0" />
+      <location r="4.24700" t="0.000" p="0.0" />
+      <location r="4.24700" t="0.000" p="0.0" />
+    </component>
+  </type>
+
+  <type name="door1">
+    <component type="standard-tube">
+      <location r="2.5" t="-45.01000" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-44.37977" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-43.74954" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-43.11931" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-42.48908" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-41.85885" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-41.22862" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-40.59839" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="-39.97000" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-39.33977" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-38.70954" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-38.07931" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-37.44908" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-36.81885" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-36.18862" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-35.55839" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="-34.93000" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-34.29977" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-33.66954" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-33.03931" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-32.40908" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-31.77885" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-31.14863" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-30.51840" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="-29.89001" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-29.25978" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-28.62955" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-27.99932" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-27.36909" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-26.73886" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-26.10863" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-25.47840" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>      
+    </component>      
+  </type>
+  
+  <type name="door2">
+    <component type="standard-tube">
+      <location r="2.5" t="-23.57801" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-22.94778" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-22.31755" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-21.68732" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-21.05709" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-20.42686" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-19.79664" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-19.16641" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="-18.53802" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-17.90779" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-17.27756" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-16.64733" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-16.01710" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-15.38687" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-14.75664" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-14.12642" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location> 
+                                      
+      <location r="2.5" t="-13.49803" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-12.86780" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-12.23757" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-11.60734" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-10.97712" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-10.34689" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-9.716660" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-9.086440" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="-8.458050" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-7.827830" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-7.197600" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-6.567380" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-5.937160" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-5.306940" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-4.676720" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="-4.046510" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location> 
+    </component>
+  </type>
+  
+  <type name="door3">
+    <component type="straight-through-beam-tube" >
+      <location r="2.50937" t="5.41821" p="113.91585" name="tube_1_1" > </location>
+      <location r="2.50937" t="5.19467" p="107.56693" name="tube_1_2" > </location>   
+      <location r="2.50937" t="5.04030" p="100.73910" name="tube_1_3" > </location>
+      <location r="2.50937" t="4.96155" p="93.58839" name="tube_1_4"> </location>   
+      <location r="2.50937" t="4.96203" p="86.32413" name="tube_1_5"> </location>
+      <location r="2.50937" t="5.04172" p="79.17615" name="tube_1_6"> </location>   
+      <location r="2.50937" t="5.19697" p="72.35330" name="tube_1_7"> </location>
+      <location r="2.50937" t="5.42130" p="66.01085" name="tube_1_8"> </location>   
+
+      <location r="2.88977" t="30.17630" p="-93.79165" name="tube_2_1" > </location>
+      <location r="2.88977" t="30.14056" p="-92.70872" name="tube_2_2"> </location>   
+      <location r="2.88977" t="30.11674" p="-91.62351" name="tube_2_3"> </location>
+      <location r="2.88977" t="30.10486" p="-90.53695" name="tube_2_4"> </location>   
+      <location r="2.88977" t="30.10493" p="-89.44993" name="tube_2_5"> </location>
+      <location r="2.88977" t="30.11696" p="-88.36337" name="tube_2_6"> </location>   
+      <location r="2.88977" t="30.14092" p="-87.27819" name="tube_2_7"> </location>
+      <location r="2.88977" t="30.17680" p="-86.19529" name="tube_2_8"> </location>         
+    </component>
+    <component type="standard-tube"> 
+      <location r="2.5" t="2.838180 " name="tube_3_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="3.468370 " name="tube_3_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="4.098580 " name="tube_3_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="4.728790 " name="tube_3_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="5.359010 " name="tube_3_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="5.989230 " name="tube_3_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="6.619450 " name="tube_3_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="7.249670 " name="tube_3_8" > <facing x="0" y="0" z="0"/> </location>      
+      <location r="2.5" t="7.878060 " name="tube_4_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="8.508280 " name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="9.138510 " name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="9.768730 " name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="10.398960" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="11.029190" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="11.659410" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="12.289640" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>    
+      <location r="2.5" t="12.918030" name="tube_5_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="13.548260" name="tube_5_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="14.178490" name="tube_5_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="14.808710" name="tube_5_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="15.438940" name="tube_5_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="16.069170" name="tube_5_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="16.699400" name="tube_5_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="17.329630" name="tube_5_8"> <facing x="0" y="0" z="0"/> </location> 
+    </component>
+  </type>
+  
+  <type name="door4">
+    <component type="standard-tube">
+      <location r="2.5" t="19.163020" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="19.793250" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="20.423470" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="21.053700" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="21.683930" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="22.314160" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="22.944390" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="23.574620" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="24.204010" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="24.834240" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="25.464470" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="26.094700" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="26.724930" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="27.355160" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="27.985390" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="28.615620" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location> 
+                                      
+      <location r="2.5" t="29.247010" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="29.877240" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="30.507470" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="31.137700" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="31.767920" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="32.398150" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="33.028380" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="33.658610" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location> 
+                                      
+      <location r="2.5" t="34.288000" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="34.918230" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="35.548460" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="36.178690" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="36.808920" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="37.439150" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="38.069380" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="38.699610" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>      
+    </component>  
+  </type>
+  
+  <type name="door5">
+    <component type="standard-tube">
+      <location r="2.5" t="40.587000" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="41.217230" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="41.847460" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="42.477690" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="43.107920" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="43.738150" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="44.368380" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="44.998610" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="45.629000" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="46.259230" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="46.889460" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="47.519690" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="48.149920" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="48.780150" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="49.410380" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="50.040610" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location>  
+                                      
+      <location r="2.5" t="50.671000" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="51.301230" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="51.931460" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="52.561690" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="53.191920" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="53.822150" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="54.452380" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="55.082610" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="55.713000" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="56.343230" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="56.973460" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="57.603690" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="58.233920" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="58.864150" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="59.494380" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="60.124610" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>      
+    </component>  
+  </type>
+  
+  <type name="door6">
+    <component type="standard-tube">
+      <location r="2.5" t="61.817990" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="62.448220" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="63.078450" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="63.708680" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="64.338910" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="64.969140" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="65.599370" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="66.229600" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="66.859990" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="67.490220" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="68.120450" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="68.750680" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="69.380910" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="70.011140" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="70.641370" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="71.271600" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location> 
+                                      
+      <location r="2.5" t="71.901990" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="72.532220" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="73.162450" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="73.792680" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="74.422910" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="75.053140" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="75.683370" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="76.313600" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="76.943990" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="77.574220" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="78.204450" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="78.834680" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="79.464910" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="80.095140" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="80.725370" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="81.355600" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>      
+    </component>  
+  </type>
+  
+  <type name="door7">
+    <component type="standard-tube">
+      <location r="2.5" t="83.278990" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="83.909220" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="84.539450" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="85.169680" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="85.799910" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="86.430140" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="87.060370" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="87.690600" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="88.320990" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="88.951220" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="89.581450" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="90.211680" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="90.841910" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="91.472140" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="92.102370" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="92.732600" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="93.362990" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="93.993220" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="94.623450" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="95.253680" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="95.883910" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="96.514140" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="97.144370" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="97.774600" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="98.404990" name="tube_4_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="99.035220" name="tube_4_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="99.665450" name="tube_4_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="100.29568" name="tube_4_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="100.92591" name="tube_4_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="101.55614" name="tube_4_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="102.18637" name="tube_4_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="102.81660" name="tube_4_8"> <facing x="0" y="0" z="0"/> </location>      
+    </component>  
+  </type>
+  
+  <type name="door8">
+    <component type="standard-tube">
+      <location r="2.5" t="104.71099" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="105.34122" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="105.97145" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="106.60168" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="107.23191" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="107.86214" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="108.49237" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="109.12260" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="109.75299" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="110.38322" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="111.01345" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="111.64368" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="112.27391" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="112.90414" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="113.53437" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="114.16460" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="114.79499" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="115.42522" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="116.05545" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="116.68568" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="117.31591" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="117.94614" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="118.57636" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="119.20659" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>                                        
+    </component>  
+  </type>
+  
+  <type name="door9">
+    <component type="standard-tube">
+      <location r="2.5" t="121.19498" name="tube_1_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="121.82521" name="tube_1_2" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="122.45544" name="tube_1_3" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="123.08567" name="tube_1_4" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="123.71590" name="tube_1_5" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="124.34613" name="tube_1_6" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="124.97636" name="tube_1_7" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="125.60659" name="tube_1_8" > <facing x="0" y="0" z="0"/> </location>
+                                                   
+      <location r="2.5" t="126.23698" name="tube_2_1" > <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="126.86721" name="tube_2_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="127.49744" name="tube_2_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="128.12767" name="tube_2_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="128.75790" name="tube_2_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="129.38813" name="tube_2_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="130.01836" name="tube_2_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="130.64859" name="tube_2_8"> <facing x="0" y="0" z="0"/> </location>
+                                      
+      <location r="2.5" t="131.27898" name="tube_3_1"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="131.90921" name="tube_3_2"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="132.53944" name="tube_3_3"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="133.16967" name="tube_3_4"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="133.79990" name="tube_3_5"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="134.43013" name="tube_3_6"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="135.06036" name="tube_3_7"> <facing x="0" y="0" z="0"/> </location>
+      <location r="2.5" t="135.69059" name="tube_3_8"> <facing x="0" y="0" z="0"/> </location>                                        
+    </component>  
+  </type>
+  
+     
+  <type name="standard-tube" outline="yes">
+    <component type="standard-pixel">
+      <locations y="-1.4635693359375" y-end="1.46356933593751" n-elements="512"/>
+    </component>
+  </type>
+        
+  <type name="straight-through-beam-tube" outline="yes">
+    <component type="straight-through-beam-pixel">
+      <locations y="0" y-end="1.22879882812501" n-elements="512" />
+    </component>
+  </type>
+  
+  
+  <type name="standard-pixel" is="detector">    
+    <cylinder id="shape">
+      <centre-of-bottom-base x="0.0" y="-0.0028614" z="0.0" />
+      <axis x="0.0" y="1.0" z="0.0" /> 
+      <radius val="0.0127" />
+      <height val="0.00572" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>
+
+  <type name="straight-through-beam-pixel" is="detector">    
+    <cylinder id="shape">
+      <centre-of-bottom-base x="0.0" y="-0.001201172" z="0.0" />
+      <axis x="0.0" y="1.0" z="0.0" /> 
+      <radius val="0.0127" />
+      <height val="0.0024024" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>
+
+  <type name="monitor" is="monitor">
+    <cylinder id="some-shape">
+      <centre-of-bottom-base r="0.0" t="0.0" p="0.0" />
+      <axis x="0.0" y="0.0" z="1.0" /> 
+      <radius val="0.01" />
+      <height val="0.03" />
+    </cylinder> 
+    <algebra val="some-shape" />    
+  </type>
+
+  
+  <!-- DETECTOR ID LISTS -->
+  
+  <idlist idname="monitors">
+    <id val="11" />
+    <id start="21" end="24" />
+    <id start="31" end="34" />    
+  </idlist>
+  
+  <idlist idname="door1">
+    <id start="1110001" end="1110512" />
+    <id start="1120001" end="1120512" />
+    <id start="1130001" end="1130512" />
+    <id start="1140001" end="1140512" />
+    <id start="1150001" end="1150512" />
+    <id start="1160001" end="1160512" />
+    <id start="1170001" end="1170512" />
+    <id start="1180001" end="1180512" />   
+    <id start="1210001" end="1210512" />
+    <id start="1220001" end="1220512" />
+    <id start="1230001" end="1230512" />
+    <id start="1240001" end="1240512" />
+    <id start="1250001" end="1250512" />
+    <id start="1260001" end="1260512" />
+    <id start="1270001" end="1270512" />
+    <id start="1280001" end="1280512" />    
+    <id start="1310001" end="1310512" />
+    <id start="1320001" end="1320512" />
+    <id start="1330001" end="1330512" />
+    <id start="1340001" end="1340512" />
+    <id start="1350001" end="1350512" />
+    <id start="1360001" end="1360512" />
+    <id start="1370001" end="1370512" />
+    <id start="1380001" end="1380512" />    
+    <id start="1410001" end="1410512" />
+    <id start="1420001" end="1420512" />
+    <id start="1430001" end="1430512" />
+    <id start="1440001" end="1440512" />
+    <id start="1450001" end="1450512" />
+    <id start="1460001" end="1460512" />
+    <id start="1470001" end="1470512" />
+    <id start="1480001" end="1480512" />    
+  </idlist>
+  
+  <idlist idname="door2">
+    <id start="2110001" end="2110512" />
+    <id start="2120001" end="2120512" />
+    <id start="2130001" end="2130512" />
+    <id start="2140001" end="2140512" />
+    <id start="2150001" end="2150512" />
+    <id start="2160001" end="2160512" />
+    <id start="2170001" end="2170512" />
+    <id start="2180001" end="2180512" />   
+    <id start="2210001" end="2210512" />
+    <id start="2220001" end="2220512" />
+    <id start="2230001" end="2230512" />
+    <id start="2240001" end="2240512" />
+    <id start="2250001" end="2250512" />
+    <id start="2260001" end="2260512" />
+    <id start="2270001" end="2270512" />
+    <id start="2280001" end="2280512" />   
+    <id start="2310001" end="2310512" />
+    <id start="2320001" end="2320512" />
+    <id start="2330001" end="2330512" />
+    <id start="2340001" end="2340512" />
+    <id start="2350001" end="2350512" />
+    <id start="2360001" end="2360512" />
+    <id start="2370001" end="2370512" />
+    <id start="2380001" end="2380512" />    
+    <id start="2410001" end="2410512" />
+    <id start="2420001" end="2420512" />
+    <id start="2430001" end="2430512" />
+    <id start="2440001" end="2440512" />
+    <id start="2450001" end="2450512" />
+    <id start="2460001" end="2460512" />
+    <id start="2470001" end="2470512" />
+    <id start="2480001" end="2480512" />    
+  </idlist>  
+  
+  <idlist idname="door3">
+    <id start="3110001" end="3110512" />
+    <id start="3120001" end="3120512" />
+    <id start="3130001" end="3130512" />
+    <id start="3140001" end="3140512" />
+    <id start="3150001" end="3150512" />
+    <id start="3160001" end="3160512" />
+    <id start="3170001" end="3170512" />
+    <id start="3180001" end="3180512" />   
+    <id start="3210001" end="3210512" />
+    <id start="3220001" end="3220512" />
+    <id start="3230001" end="3230512" />
+    <id start="3240001" end="3240512" />
+    <id start="3250001" end="3250512" />
+    <id start="3260001" end="3260512" />
+    <id start="3270001" end="3270512" />
+    <id start="3280001" end="3280512" />   
+    <id start="3310001" end="3310512" />
+    <id start="3320001" end="3320512" />
+    <id start="3330001" end="3330512" />
+    <id start="3340001" end="3340512" />
+    <id start="3350001" end="3350512" />
+    <id start="3360001" end="3360512" />
+    <id start="3370001" end="3370512" />
+    <id start="3380001" end="3380512" />    
+    <id start="3410001" end="3410512" />
+    <id start="3420001" end="3420512" />
+    <id start="3430001" end="3430512" />
+    <id start="3440001" end="3440512" />
+    <id start="3450001" end="3450512" />
+    <id start="3460001" end="3460512" />
+    <id start="3470001" end="3470512" />
+    <id start="3480001" end="3480512" />    
+    <id start="3510001" end="3510512" />
+    <id start="3520001" end="3520512" />
+    <id start="3530001" end="3530512" />
+    <id start="3540001" end="3540512" />
+    <id start="3550001" end="3550512" />
+    <id start="3560001" end="3560512" />
+    <id start="3570001" end="3570512" />
+    <id start="3580001" end="3580512" />     
+  </idlist>    
+
+  <idlist idname="door4">
+    <id start="4110001" end="4110512" />
+    <id start="4120001" end="4120512" />
+    <id start="4130001" end="4130512" />
+    <id start="4140001" end="4140512" />
+    <id start="4150001" end="4150512" />
+    <id start="4160001" end="4160512" />
+    <id start="4170001" end="4170512" />
+    <id start="4180001" end="4180512" />   
+    <id start="4210001" end="4210512" />
+    <id start="4220001" end="4220512" />
+    <id start="4230001" end="4230512" />
+    <id start="4240001" end="4240512" />
+    <id start="4250001" end="4250512" />
+    <id start="4260001" end="4260512" />
+    <id start="4270001" end="4270512" />
+    <id start="4280001" end="4280512" />   
+    <id start="4310001" end="4310512" />
+    <id start="4320001" end="4320512" />
+    <id start="4330001" end="4330512" />
+    <id start="4340001" end="4340512" />
+    <id start="4350001" end="4350512" />
+    <id start="4360001" end="4360512" />
+    <id start="4370001" end="4370512" />
+    <id start="4380001" end="4380512" />    
+    <id start="4410001" end="4410512" />
+    <id start="4420001" end="4420512" />
+    <id start="4430001" end="4430512" />
+    <id start="4440001" end="4440512" />
+    <id start="4450001" end="4450512" />
+    <id start="4460001" end="4460512" />
+    <id start="4470001" end="4470512" />
+    <id start="4480001" end="4480512" />    
+  </idlist>  
+
+  <idlist idname="door5">
+    <id start="5110001" end="5110512" />
+    <id start="5120001" end="5120512" />
+    <id start="5130001" end="5130512" />
+    <id start="5140001" end="5140512" />
+    <id start="5150001" end="5150512" />
+    <id start="5160001" end="5160512" />
+    <id start="5170001" end="5170512" />
+    <id start="5180001" end="5180512" />   
+    <id start="5210001" end="5210512" />
+    <id start="5220001" end="5220512" />
+    <id start="5230001" end="5230512" />
+    <id start="5240001" end="5240512" />
+    <id start="5250001" end="5250512" />
+    <id start="5260001" end="5260512" />
+    <id start="5270001" end="5270512" />
+    <id start="5280001" end="5280512" />   
+    <id start="5310001" end="5310512" />
+    <id start="5320001" end="5320512" />
+    <id start="5330001" end="5330512" />
+    <id start="5340001" end="5340512" />
+    <id start="5350001" end="5350512" />
+    <id start="5360001" end="5360512" />
+    <id start="5370001" end="5370512" />
+    <id start="5380001" end="5380512" />    
+    <id start="5410001" end="5410512" />
+    <id start="5420001" end="5420512" />
+    <id start="5430001" end="5430512" />
+    <id start="5440001" end="5440512" />
+    <id start="5450001" end="5450512" />
+    <id start="5460001" end="5460512" />
+    <id start="5470001" end="5470512" />
+    <id start="5480001" end="5480512" />    
+  </idlist>    
+
+  <idlist idname="door6">
+    <id start="6110001" end="6110512" />
+    <id start="6120001" end="6120512" />
+    <id start="6130001" end="6130512" />
+    <id start="6140001" end="6140512" />
+    <id start="6150001" end="6150512" />
+    <id start="6160001" end="6160512" />
+    <id start="6170001" end="6170512" />
+    <id start="6180001" end="6180512" />   
+    <id start="6210001" end="6210512" />
+    <id start="6220001" end="6220512" />
+    <id start="6230001" end="6230512" />
+    <id start="6240001" end="6240512" />
+    <id start="6250001" end="6250512" />
+    <id start="6260001" end="6260512" />
+    <id start="6270001" end="6270512" />
+    <id start="6280001" end="6280512" />   
+    <id start="6310001" end="6310512" />
+    <id start="6320001" end="6320512" />
+    <id start="6330001" end="6330512" />
+    <id start="6340001" end="6340512" />
+    <id start="6350001" end="6350512" />
+    <id start="6360001" end="6360512" />
+    <id start="6370001" end="6370512" />
+    <id start="6380001" end="6380512" />    
+    <id start="6410001" end="6410512" />
+    <id start="6420001" end="6420512" />
+    <id start="6430001" end="6430512" />
+    <id start="6440001" end="6440512" />
+    <id start="6450001" end="6450512" />
+    <id start="6460001" end="6460512" />
+    <id start="6470001" end="6470512" />
+    <id start="6480001" end="6480512" />    
+  </idlist>   
+  
+  <idlist idname="door7">
+    <id start="7110001" end="7110512" />
+    <id start="7120001" end="7120512" />
+    <id start="7130001" end="7130512" />
+    <id start="7140001" end="7140512" />
+    <id start="7150001" end="7150512" />
+    <id start="7160001" end="7160512" />
+    <id start="7170001" end="7170512" />
+    <id start="7180001" end="7180512" />   
+    <id start="7210001" end="7210512" />
+    <id start="7220001" end="7220512" />
+    <id start="7230001" end="7230512" />
+    <id start="7240001" end="7240512" />
+    <id start="7250001" end="7250512" />
+    <id start="7260001" end="7260512" />
+    <id start="7270001" end="7270512" />
+    <id start="7280001" end="7280512" />   
+    <id start="7310001" end="7310512" />
+    <id start="7320001" end="7320512" />
+    <id start="7330001" end="7330512" />
+    <id start="7340001" end="7340512" />
+    <id start="7350001" end="7350512" />
+    <id start="7360001" end="7360512" />
+    <id start="7370001" end="7370512" />
+    <id start="7380001" end="7380512" />    
+    <id start="7410001" end="7410512" />
+    <id start="7420001" end="7420512" />
+    <id start="7430001" end="7430512" />
+    <id start="7440001" end="7440512" />
+    <id start="7450001" end="7450512" />
+    <id start="7460001" end="7460512" />
+    <id start="7470001" end="7470512" />
+    <id start="7480001" end="7480512" />    
+  </idlist>     
+  
+  <idlist idname="door8">
+    <id start="8110001" end="8110512" />
+    <id start="8120001" end="8120512" />
+    <id start="8130001" end="8130512" />
+    <id start="8140001" end="8140512" />
+    <id start="8150001" end="8150512" />
+    <id start="8160001" end="8160512" />
+    <id start="8170001" end="8170512" />
+    <id start="8180001" end="8180512" />   
+    <id start="8210001" end="8210512" />
+    <id start="8220001" end="8220512" />
+    <id start="8230001" end="8230512" />
+    <id start="8240001" end="8240512" />
+    <id start="8250001" end="8250512" />
+    <id start="8260001" end="8260512" />
+    <id start="8270001" end="8270512" />
+    <id start="8280001" end="8280512" />   
+    <id start="8310001" end="8310512" />
+    <id start="8320001" end="8320512" />
+    <id start="8330001" end="8330512" />
+    <id start="8340001" end="8340512" />
+    <id start="8350001" end="8350512" />
+    <id start="8360001" end="8360512" />
+    <id start="8370001" end="8370512" />
+    <id start="8380001" end="8380512" />    
+  </idlist>    
+  
+  <idlist idname="door9">
+    <id start="9110001" end="9110512" />
+    <id start="9120001" end="9120512" />
+    <id start="9130001" end="9130512" />
+    <id start="9140001" end="9140512" />
+    <id start="9150001" end="9150512" />
+    <id start="9160001" end="9160512" />
+    <id start="9170001" end="9170512" />
+    <id start="9180001" end="9180512" />   
+    <id start="9210001" end="9210512" />
+    <id start="9220001" end="9220512" />
+    <id start="9230001" end="9230512" />
+    <id start="9240001" end="9240512" />
+    <id start="9250001" end="9250512" />
+    <id start="9260001" end="9260512" />
+    <id start="9270001" end="9270512" />
+    <id start="9280001" end="9280512" />   
+    <id start="9310001" end="9310512" />
+    <id start="9320001" end="9320512" />
+    <id start="9330001" end="9330512" />
+    <id start="9340001" end="9340512" />
+    <id start="9350001" end="9350512" />
+    <id start="9360001" end="9360512" />
+    <id start="9370001" end="9370512" />
+    <id start="9380001" end="9380512" />    
+  </idlist>   
+
+  <!-- DETECTOR PARAMETERS -->
+  <component-link name="monitors">
+   <parameter name="DelayTime">
+      <value units="microseconds" val="0"/>
+   </parameter>
+  </component-link>
+
+  <!-- Set the same across the reset of the instrument -->
+  <component-link name = "MERLIN">
+    <parameter name="TubePressure">
+      <value units="atm" val="10.0"/>
+    </parameter>
+    <parameter name="TubeThickness">
+      <value units="metre" val="0.0008"/>
+    </parameter>
+    <parameter name="DelayTime">
+      <value units="microseconds" val="-5.3"/>
+    </parameter>
+  </component-link>
+
+  
+</instrument>
diff --git a/instrument/MERLIN_Parameters_2018_03.xml b/instrument/MERLIN_Parameters_2018_03.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8ae55cbec86913160257fc38f556d76d6d3b2cf9
--- /dev/null
+++ b/instrument/MERLIN_Parameters_2018_03.xml
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<parameter-file instrument = "MERLIN" valid-from = "2018-12-03 17:18:01">
+
+<component-link name = "MERLIN">
+
+<!-- files properties : -->
+
+<!-- Specify that the detector positions should be taken from the data file (Not used ) -->
+<parameter name="det-pos-source" type="string">
+  <value val="datafile"/>
+</parameter>
+<!-- The file which defines proper (calibrated) detector positions 
+     if None - it is undefined -->
+<parameter name="det_cal_file" type="string">
+   <value val="det_corr_172.dat"/>
+   <description is = "The file which defines proper (calibrated) detector positions.
+                      If property set to None - this file is undefined."/>
+</parameter>
+<!-- The file which defines detectors to spectra mapping; File extension has to be specified here but filepath not
+     if None - one2one map is used  -->
+<parameter name="map_file" type="string">
+   <value val="None"/>
+</parameter>
+
+<!-- Preferred extension of the data files obtained from DAE, e.g. what to prefer if two 
+     files with the same name and different extension are found
+ -->
+<parameter name="data_file_ext" type="string">
+   <value val=".nxs"/>
+</parameter>
+<!-- The name of the hard mask file to use together with diag masking 4to1_124mod.msk-->
+<parameter name="hard_mask_file" type="string">
+    <value val="None"/>
+</parameter>
+
+<!-- The map file used when calculating absolute units conversion integrals 
+     This map usually groups together large areas of detectors to obtain proper vanadium statistics  -->
+<parameter name="monovan_mapfile" type="string">
+   <value val="mono_van_map.map"/>
+</parameter>
+
+
+
+
+<!-- RunNumber to use for diag instead of the input run number if none - use input run 
+     if yes, will probably change from command line-->
+<parameter name="mask_run" type="string">
+   <value val="None"/>
+</parameter>
+
+<!-- Energy conversion mode direct/indirect/elastic (the one the reducer understands) -->
+<parameter name="deltaE-mode" type="string">
+  <value val="direct"/>
+</parameter>
+
+<!-- normalise_method normalization. To compare different runs with different length one uses normalization by some flux-dependent parameter
+     Available values are: none (-largely meaningless), monitor-1,monitor-2, current 
+     the acceptable values are defined in DirectEnergyConversion initialization routine as recognized by direct energy conversion normalize method
+     these three are currently disabled/unknown:  uamph peak-->
+<parameter name="normalise_method" type="string">
+    <value val="monitor-1"/>
+</parameter>
+
+<!-- Monitor used to estimate total current on the sample while normalizing by monitor 1.  -->
+<parameter name="norm-mon1-spec"   >
+  <value val="69633"/>
+</parameter>
+
+<!-- Time interval used for integration to estimate current on the sample 
+    This interval is usually taken around the monitor peak-->
+<parameter name="norm-mon1-min">
+  <value val="1000"/>
+</parameter>
+<parameter name="norm-mon1-max">
+  <value val="2000"/>
+</parameter>
+<parameter name="norm_mon_integration_range"  type="string">
+  <value val="norm-mon1-min:norm-mon1-max"/>
+</parameter>
+
+<!-- Monitor after chopper used to estimate total current on the sample, if normalization is done on monitor 2  -->
+<parameter name="norm-mon2-spec"  type="int">
+    <value val="69636"/>
+</parameter>
+<!-- Relative energy range (wrt. to the incident energy) in which monitor 2 signal is present and the integration to 
+     calculate monitor-2 current occurs   -->
+<parameter name="mon2_norm_energy_range" type = "string">
+    <value val="0.8,1.2"/>
+</parameter>
+
+<!-- Usually one wants to avoid loading monitors together with data except in special cases. One of this cases is 
+     MARI which monitors numbers are in the beginning of the spectra. If one loads them separately, 
+     spectra numbers change and ISIS hard masks (msk) prepared for workspace with monitors become invalid. 
+     This parameter is actual until Mantid Masking change.
+  -->
+<parameter name="load_monitors_with_workspace"  type="bool">
+<value val="False"/>
+</parameter>
+
+<!-- -->
+<parameter name="ei-mon1-spec"  type="string">
+  <value val="69636"/>
+  <description is="First spectra number (monitor's spectra number) to use when measuring incident energy,
+     or comma separated list of such numbers.
+     Should be spectra with well defined energy peak or monitor's spectra.
+     If list of numbers is provided, the final spectrum is the sum of the spectra with the numbers provided.
+     It is important to have the detectors for these spectra to be located at the same distance from the source,
+     as the position of the combined detector will be defined by the position of the first spectra's detector."/>
+</parameter>
+<!-- -->
+<parameter name="ei-mon2-spec"  type="string">
+  <value val="69638,69639,69640,69641"/>
+  <description is="Second spectra number (monitor's spectra number) to use when measuring incident energy,
+     or comma separated list of such numbers.
+     Should be spectra with well defined energy peak or monitor's spectra.
+     If list of numbers is provided, the final spectrum is the sum of the spectra with the numbers provided.
+     It is important to have the detectors for these spectra to be located at the same distance from the source,
+     as the position of the combined detector will be defined by the position of the first spectra's detector."/>
+</parameter>
+<!-- -->
+<parameter name="ei_mon_spectra"  type="string">
+  <value val="ei-mon1-spec:ei-mon2-spec"/>
+  <description is="List of spectra, used to calculate incident energy of beam in inelastic experiments by GetEi algorithm.
+  It is complex property, dependent on two other properties, namely ei-mon1-spec and ei-mon2-spec, which define spectrum or
+  spectra lists for each of two monitors, used in GetEi calculations"/>
+</parameter>
+<!-- -->
+<parameter name="spectra_to_monitors_list"  type="string">
+  <value val="None"/>
+  <description is="If you use some detectors as monitors and work in event mode,
+    one needs to specify the comma separated list of these detectors as the value of this property
+    to copy detectors spectra to monitors spectra collected in histogram mode.
+    If no such monitors are used, None (or text string 'None' in IDF) has to be specified as the value.
+    This is also necessary in Histogram mode if you want to use some detectors as monitors and 
+    load_monitors_with_workspace is set to False necessary if monitors are measured with different time channels"/>
+</parameter>
+
+<!-- -->
+<parameter name="multirep_tof_specta_list"  type="string">
+    <value val="1,129"/>
+    <description is="List of two spectra corresponding to the detectors which are closest and furthest from the sample.
+    These detectors locations are used to identify TOF range, contributing into each energy range
+     in multirep mode"/>
+</parameter>
+
+
+<!-- by default getEi looks for peaks within (1+-0.1)*TOF_GUES range where TOF_GUES is evaluated on the basis of ei guess.
+    If the peaks are very narrow, or there are a lot of them very close to each other, 
+    this value can be reduced. For example, such situation happens on MARI for very high incident energies Ei=1800.
+ -->
+<parameter name="ei_mon_peak_search_range">
+   <value val="0.1"/>
+</parameter>
+
+
+<parameter name="scale-factor">
+  <value val="1.7016e8"/>
+</parameter>
+
+<parameter name="wb-scale-factor">
+  <value val="1000"/>
+</parameter>
+
+<!-- Remove the count rate seen in the regions of the histograms defined as the background regions -->
+<parameter name="check_background"  type="bool">
+   <value val="False"/>
+   <description is="If True, remove the count rate seen in the regions of the
+     histograms defined as the background regions. 
+     The background region is defined by background_range property."/>
+</parameter>
+<parameter name="nullify_negative_signal"  type="bool">
+  <value val="True"/>
+  <description is="If True and background removed, nullify the negative signal, which
+     may occur at some detectors at some moments of time due to flat background removal and modify errors accordingly.
+     If False, leave signals and errors unchanged. "/>
+</parameter>
+
+
+<!--  detector_van_range- integration in E(mev) for detector(white beam) vanadium data [20,100] -->
+<parameter name="wb-integr-min">
+  <value val="20"/>
+</parameter>
+<parameter name="wb-integr-max">
+  <value val="55"/>
+</parameter>
+<parameter name="wb_integr_range"   type="string">
+    <value val="wb-integr-min:wb-integr-max"/>
+</parameter>
+
+
+<!-- integration range for background tests  (in TOF) - composite property 
+  Used in test to reject high background (FlatBackground) and in High Background tests integration in Diagnostics
+  if diag_background_test_range is not set -->
+<parameter name="bkgd-range-min"> 
+  <value val="12000"/>
+</parameter>
+<parameter name="bkgd-range-max">
+  <value val="18000"/>
+</parameter>
+<parameter name="background_range"  type="string">
+      <value val="bkgd-range-min:bkgd-range-max"/>
+</parameter>
+
+<!-- ******************************** DIAGNOSTICS DEFAILTS **************************************** -->
+
+<!-- Perform diag by bank. These are the spectrum numbers -->
+<parameter name="diag_spectra" type="string">
+  <value val="None"/>
+</parameter>
+
+<!-- Absolute lo threshold for vanadium diag (tiny) -->
+<parameter name="diag_tiny">
+  <value val="1e-10"/>
+</parameter>
+
+<!-- Absolute hi threshold for vanadium diag (large) -->
+<parameter name="diag_huge">
+  <value val="1e10"/>
+</parameter>
+
+<!-- Setting diag to reject zero backgrounds; If true then zeroes in (vanadium) data are masked as fail  -->
+<parameter name="diag_samp_zero"  type="bool">
+  <value val="False"/>
+</parameter>
+
+<!-- Fraction of median to consider counting low for the white beam diag (diag_van_median_rate_limit_hi sv_lo)-->
+<parameter name="diag_samp_lo">
+  <value val="0.0"/>
+</parameter>
+<!-- Fraction of median to consider counting high for the white beam diag (sv_hi)-->
+<parameter name="diag_samp_hi">
+  <value val="1.5"/>
+</parameter>
+
+<!-- Error criterion as a multiple of error bar for background (sv_sig) 
+  i.e. to fail the test, the magnitude of the
+  difference with respect to the median value must also exceed this number of error bars (default=3.3)
+-->  
+<parameter name="diag_samp_sig">
+  <value val="3.3"/>
+</parameter>
+
+<!-- Lower bound defining outliers as fraction of median value (v_out_lo)-->
+<parameter name="diag_van_out_lo">
+  <value val="0.01"/>
+</parameter>
+
+<!-- Upper bound defining outliers as fraction of median value (v_out_hi) -->
+<parameter name="diag_van_out_hi">
+  <value val="100."/>
+</parameter>
+
+<!-- Fraction of median to consider counting low for the white beam diag (vv_lo)  vanlo=0.1  -->
+<parameter name="diag_van_lo">
+  <value val="0.1"/>
+</parameter>
+
+<!-- Fraction of median to consider counting high for the white beam diag (vv_hi) vanhi=1.5 -->
+<parameter name="diag_van_hi">
+  <value val="1.5"/>
+</parameter>
+
+<!-- Error criterion as a multiple of error bar     van_sig  "
+    i.e. to fail the test, the magnitude of the difference with respect to the median value must also exceed this number of error bars (default=0.0)
+-->
+<parameter name="diag_van_sig">
+  <value val="0.0"/>
+</parameter>
+
+<!-- Variation for ratio test with second white beam -->
+<parameter name="diag_variation">
+  <value val="1.1"/>
+</parameter>
+<!-- The range used in diagnostics and rejecting high background.
+  If none, the diag background range uses background ranges from background_range. Has to be directly set otherwise -->
+<parameter name="diag_background_test_range"  type="string" >
+    <value val="None"/>
+</parameter>
+
+<!--  -->
+<!--  Bleeding corrections   -->
+
+<!--  the number of pixels ignored within the bleed test diagnostic -->
+<parameter name="bleed_pixels">
+    <value val="80"/>
+</parameter>
+<!--  the maximum frame rate allowed in a tube -->
+<parameter name="bleed_maxrate">
+    <value val="0.01"/>
+</parameter>
+<!-- True if the bleed tests should be run use_bleeding-->
+<parameter name="diag_bleed_test"  type="bool">
+    <value val="False"/>
+</parameter>
+
+<!-- **************************************** DIAGNOSTICS DEFAILTS END ****************************************    -->
+
+
+<!-- **************************************** ABSOLUTE UNITS CORRECTION DEFAULTS ********************************  -->
+<!-- Absolute units conversion average -->
+<parameter name="monovan_lo_bound">
+  <value val="0.01"/>
+</parameter>
+
+<parameter name="monovan_hi_bound">
+  <value val="100"/>
+</parameter>
+
+<!-- This property is the part of the composite definition for abs_units_van_range: 
+ It specifies the relative to incident energy lower integration limit for monochromatic vanadium in the mono-vanadium integration -->
+<parameter name="monovan_lo_frac">
+  <value val="-0.6"/>
+</parameter>
+
+<!-- This property is the part of the composite definition for abs_units_van_range:
+ It specifies the the lower limit of energy range in the monochromatic-vanadium integration 
+ Used only if abs_units_van_range is set to val="monovan_lo_value,monovan_hi_value"-->
+<parameter name="monovan_lo_value">
+  <value val="-40."/>
+</parameter>
+
+<!-- This property is the part of the composite definition for abs_units_van_range
+ It specifies the relative to incident energy higher integration limit for monochromatic vanadium in the mono-vanadium integration -->
+<parameter name="monovan_hi_frac">
+  <value val="0.6"/>
+</parameter>
+<!-- This property is the part of the composite definition for abs_units_van_range
+ It specifies the the higher limit of energy range in the monochromatic-vanadium integration 
+ Used only if abs_units_van_range is set to val="monovan_lo_value,monovan_hi_value"-->
+<parameter name="monovan_hi_value">
+  <value val="40."/>
+</parameter>
+
+<!-- energy range for integration calculating absolute units correction vanadium data. 
+     if None, range is calculated from monovan_hi_frac/monovan_lo_frac 
+     - providing the fractions of the incident energy      
+     if one wants to specify the energy values here it has to be defined in the form:
+    <value val="monovan_lo_value,monovan_hi_value"/>      -->    
+<parameter name="abs_units_van_range"  type="string">
+  <value val="None"/>
+</parameter>
+<!-- Sample mass used in absolute units normalization and should usually be changed by user-->
+<parameter name="sample_mass">
+  <value val="1"/>
+</parameter>
+<!-- Sample rmm used in absolute units normalization should usually be changed by user -->
+<parameter name="sample_rmm">
+  <value val="1"/>
+</parameter>
+<!-- Vanadium mass used in absolute units normalization and is usually instrument specific (changes rarely) -->
+<parameter name="vanadium-mass">
+  <value val="7.85"/>
+</parameter>
+<!-- if this value set to true, modo-vanadium run is not analysed and masks obtained for arbitrary units are used for mono-vanadium -->
+<parameter name="use_sam_msk_on_monovan" type = "bool">
+  <value val="False"/>
+</parameter>
+
+<!-- if this value is provided (not None) it is string representation of the number used instead of calculating mono-vanadium based normalization factor 
+   one does not need to provide mono-vanadium run if this value is provided as it will be used instead
+  -->
+<parameter name="mono_correction_factor" type="string">
+  <value val="None"/>
+</parameter>
+  
+<!-- **************************************** ABSOLUTE UNITS CORRECTION DEFAULTS END ****************************  -->
+
+<!-- if defined to true, fix incident energy to this value and do not calculate the energy from the run -->
+<parameter name="fixei"  type="bool">
+    <value val="False"/>
+</parameter>
+
+<!--  ****************************************  Workflow control **************************** -->
+
+<!-- This parameter controls the format of output data written by reducer. 
+    Three values are currently supported, namely .spe, .nxspe, and nexus (Mantid workspace) (.nxs)
+     Three possible values for this are defined in DirectEnergyConversion init routine as recognized by save method 
+     If None is there, no internal script saving occurs and one needs to use external save operations -->  
+<parameter name="save_format" type="string">
+   <value val="None"/>
+</parameter>
+
+<!-- If one wants to sum runs. By default no, as in addition to the key word one has to provide list of input run-numbers
+     but presence of this key here allows to propagate this key-word to the reducer   -->
+<parameter name="sum_runs"  type="bool">
+   <value val="False"/>
+</parameter>
+
+<!-- # Run Detector Efficiency Correction -->
+<parameter name="apply_detector_eff"  type="bool">
+   <value val="True"/>
+</parameter>
+<!-- # Multiply result by ki/kf value -->
+<parameter name="apply_kikf_correction"  type="bool">
+   <value val="True"/>
+</parameter>
+
+<!-- The if true, use only hard mask file specified above and do not run diagnostics procedures -->
+<parameter name="use_hard_mask_only" type="bool">
+    <value val="False"/>
+</parameter>
+
+<!-- Parameter specifies if one wants to run diagnostics (which include applying hard mask file) or not-->
+<parameter name="run_diagnostics" type="bool">
+    <value val="True"/>
+</parameter>
+
+
+<!-- If this parameter is set to true, dgreduce will try to load mask from the mask file
+     correspondent to the run if finds it and uses this mask as hard mask only (does not run diagnostics). 
+     If such file has not been found, it will run diagnostics and save the masks into mask file for reuse 
+     Hard Mask file, provided separately or as additional hard mask file is ignored in this case -->
+<parameter name="save_and_reuse_masks"  type="bool">
+   <value val="False"/>
+</parameter>
+
+<!-- The semicolon separated list of possible log names, containing information on crystal rotation.
+     First found log will be used together with motor_offset to identify crystal rotation 
+     (psi in Horace) -->
+<parameter name="motor_log_names"  type="string">
+   <value val="CCR_ROT;wccr"/>
+</parameter>
+<!-- Initial value used to identify crystal rotation angle psi=motor_offset+wccr.timeAverageValue()  -->
+<parameter name="motor_offset">
+   <value val="None"/>
+</parameter>
+
+
+<!-- List of the words which can be used as a command line arguments to define reducer keywords
+     the form is reducer_keword1=synonim1=synonim2=synonim3;reducer_keword1=synonim1a, so, 
+     the reducer keywords are the leftmost values of the keyword assignments below
+     Each keyword met in command line or file above are converted into reducer keyword as below
+-->  
+<parameter name="synonims" type="string">
+   <value val="normalise_method=norm_method;
+       fix_ei=fixei;
+       sum_runs=sum;
+       wb_integr_range=detector_van_range;
+       motor_log_names = motor_name;
+       van_mass=vanadium-mass;
+       check_background = background;
+
+       mon1_norm_spec=norm-mon1-spec;
+       mon2_norm_spec=norm-mon2-spec;
+       scale_factor=scale-factor;
+       wb_scale_factor=wb-scale-factor;
+       monovan_integr_range=abs_units_van_range;
+       monovan_lo_value = monovan-integr-min;
+       monovan_hi_value = monovan-integr-max;
+       bkgd_range = background_range;
+       background_test_range = diag_background_test_range;
+       hard_mask_file=hard_mask;
+       van_out_lo = diag_van_median_rate_limit_lo=diag_van_out_lo;
+       van_out_hi = diag_van_median_rate_limit_hi=diag_van_out_hi;
+       van_lo     = diag_van_median_sigma_lo=diag_van_lo;
+       van_hi     = diag_van_median_sigma_hi=diag_van_hi;
+       van_sig    = diag_van_median_sigma=diag_van_sig;
+       tiny       = diag_tiny;
+       huge       = diag_huge=large;
+       samp_zero  = diag_remove_zero=diag_samp_zero;
+       samp_lo    = diag_samp_median_sigma_lo=diag_samp_lo;
+       samp_hi    = diag_samp_median_sigma_hi=diag_samp_hi;
+       samp_sig   = diag_samp_median_sigma=diag_samp_sig;
+       variation  = diag_variation;
+       bleed_test = bleed = diag_bleed_test;
+       bleed_maxrate= diag_bleed_maxrate;
+       bleed_pixels  = diag_bleed_pixels;
+       deltaE_mode =  deltaE-mode;
+       ei-mon1-spec=ei_mon1_spec;       
+       ei-mon2-spec = test_ei2_mon_spectra=ei_mon2_spec;
+       ei_mon_spectra=test_mon_spectra_composite"
+    />
+</parameter>
+ 
+  <!-- -->
+</component-link>
+
+</parameter-file>
diff --git a/qt/applications/workbench/CMakeLists.txt b/qt/applications/workbench/CMakeLists.txt
index 323ecee823ca5e7bbac587a5b51876e5066d7032..ebee6797a43feea30f910ff9eb719f5e27b68254 100644
--- a/qt/applications/workbench/CMakeLists.txt
+++ b/qt/applications/workbench/CMakeLists.txt
@@ -29,9 +29,28 @@ set ( TEST_FILES
   workbench/widgets/plotselector/test/test_plotselector_view.py
 )
 
+set ( WORKBENCH_TEST_PY_FILES
+  workbench/test/test_fit_interactive_tool.py
+)
+
 set ( PYUNITTEST_RUN_SERIAL ON )
 set ( PYUNITTEST_QT_API pyqt5)
 pyunittest_add_test ( ${CMAKE_CURRENT_SOURCE_DIR}
   workbench ${TEST_FILES}
 )
+
+if ( CMAKE_GENERATOR MATCHES "Visual Studio" OR CMAKE_GENERATOR MATCHES "Xcode" )
+  set ( PYUNITTEST_RUNNER ${CMAKE_BINARY_DIR}/bin/$<CONFIG>/workbench-script.pyw -x)
+else()
+  set ( PYUNITTEST_RUNNER ${CMAKE_BINARY_DIR}/bin/workbench -x)
+endif()
+
+if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    # Tests fail/crash on OSX for unknown reasons. Skipping by the usual way
+    # via @unittest.skipIf also doesn't work.
+    pyunittest_add_test ( ${CMAKE_CURRENT_SOURCE_DIR}
+      workbench_gui ${WORKBENCH_TEST_PY_FILES}
+    )
+endif()
+
 # Not installed yet...
diff --git a/qt/applications/workbench/workbench/app/mainwindow.py b/qt/applications/workbench/workbench/app/mainwindow.py
index 333bfe4a1effe3ef66aac078325a1ef340bcc213..3f5f4e56317ee7a74897a99fb5806a99866c97aa 100644
--- a/qt/applications/workbench/workbench/app/mainwindow.py
+++ b/qt/applications/workbench/workbench/app/mainwindow.py
@@ -140,6 +140,7 @@ class MainWindow(QMainWindow):
 
         # -- instance attributes --
         self.setWindowTitle("Mantid Workbench")
+        self.setObjectName("Mantid Workbench")
 
         # widgets
         self.messagedisplay = None
diff --git a/qt/applications/workbench/workbench/plotting/figuremanager.py b/qt/applications/workbench/workbench/plotting/figuremanager.py
index 4fb09a4c3f4b33417f1ce7f42c15038a72ff5a2d..ecdd18c9a5b021e9bf0f42fdeb76db8ef3ffcb4d 100644
--- a/qt/applications/workbench/workbench/plotting/figuremanager.py
+++ b/qt/applications/workbench/workbench/plotting/figuremanager.py
@@ -20,9 +20,11 @@ from six import text_type
 
 # local imports
 from workbench.plotting.figurewindow import FigureWindow
+from workbench.plotting.figuretype import figure_type, FigureType
 from workbench.plotting.propertiesdialog import LabelEditor, XAxisEditor, YAxisEditor
 from workbench.plotting.toolbar import WorkbenchNavigationToolbar
 from workbench.plotting.qappthreadcall import QAppThreadCall
+from mantidqt.widgets.fitpropertybrowser import FitPropertyBrowser
 
 
 class FigureManagerWorkbench(FigureManagerBase, QObject):
@@ -87,6 +89,7 @@ class FigureManagerWorkbench(FigureManagerBase, QObject):
             self.window.addToolBar(self.toolbar)
             self.toolbar.message.connect(self.statusbar_label.setText)
             self.toolbar.sig_grid_toggle_triggered.connect(self.grid_toggle)
+            self.toolbar.sig_toggle_fit_triggered.connect(self.fit_toggle)
             tbs_height = self.toolbar.sizeHint().height()
         else:
             tbs_height = 0
@@ -99,7 +102,11 @@ class FigureManagerWorkbench(FigureManagerBase, QObject):
         height = cs.height() + self._status_and_tool_height
         self.window.resize(cs.width(), height)
 
+        self.fit_browser = FitPropertyBrowser(canvas)
+        self.fit_browser.closing.connect(self.handle_fit_browser_close)
         self.window.setCentralWidget(canvas)
+        self.window.addDockWidget(Qt.LeftDockWidgetArea, self.fit_browser)
+        self.fit_browser.hide()
 
         if matplotlib.is_interactive():
             self.window.show()
@@ -164,6 +171,10 @@ class FigureManagerWorkbench(FigureManagerBase, QObject):
 
         # Hack to ensure the canvas is up to date
         self.canvas.draw_idle()
+        if figure_type(self.canvas.figure) != FigureType.Line:
+            action = self.toolbar._actions['toggle_fit']
+            action.setEnabled(False)
+            action.setVisible(False)
 
     def destroy(self, *args):
         # check for qApp first, as PySide deletes it in its atexit handler
@@ -187,6 +198,21 @@ class FigureManagerWorkbench(FigureManagerBase, QObject):
             ax.grid()
         canvas.draw_idle()
 
+    def fit_toggle(self):
+        """
+        Toggle fit browser and tool on/off
+        """
+        if self.fit_browser.isVisible():
+            self.fit_browser.hide()
+        else:
+            self.fit_browser.show()
+
+    def handle_fit_browser_close(self):
+        """
+        Respond to a signal that user closed self.fit_browser by clicking the [x] button.
+        """
+        self.toolbar.trigger_fit_toggle_action()
+
     def hold(self):
         """
         Mark this figure as held
diff --git a/qt/applications/workbench/workbench/plotting/functions.py b/qt/applications/workbench/workbench/plotting/functions.py
index 8a1cfbe0f336c3b7ff2a4df1f68d5933ee0f73a8..366a593d2c748d192b22de6390cd01b2c219f2cf 100644
--- a/qt/applications/workbench/workbench/plotting/functions.py
+++ b/qt/applications/workbench/workbench/plotting/functions.py
@@ -196,6 +196,23 @@ def pcolormesh_from_names(names, fig=None):
         return None
 
 
+def use_imshow(ws):
+    if not ws.isCommonBins():
+        return False
+
+    x = ws.dataX(0)
+    difference = np.diff(x)
+    if not np.all(np.isclose(difference[:-1], difference[0])):
+        return False
+
+    y = ws.getAxis(1).extractValues()
+    difference = np.diff(y)
+    if not np.all(np.isclose(difference[:-1], difference[0])):
+        return False
+
+    return True
+
+
 def pcolormesh(workspaces, fig=None):
     """
     Create a figure containing pcolor subplots
@@ -218,7 +235,10 @@ def pcolormesh(workspaces, fig=None):
         if subplot_idx < workspaces_len:
             ws = workspaces[subplot_idx]
             ax.set_title(ws.name())
-            pcm = ax.pcolormesh(ws, cmap=DEFAULT_CMAP)
+            if use_imshow(ws):
+                pcm = ax.imshow(ws, cmap=DEFAULT_CMAP, aspect='auto', origin='lower')
+            else:
+                pcm = ax.pcolormesh(ws, cmap=DEFAULT_CMAP)
             for lbl in ax.get_xticklabels():
                 lbl.set_rotation(45)
             if col_idx < ncols - 1:
diff --git a/qt/applications/workbench/workbench/plotting/test/test_functions.py b/qt/applications/workbench/workbench/plotting/test/test_functions.py
index fe5142ca40871b98b16f659e815d3b3eb4854055..7a48f18b1940db48562da75d6ae57f8788b0107a 100644
--- a/qt/applications/workbench/workbench/plotting/test/test_functions.py
+++ b/qt/applications/workbench/workbench/plotting/test/test_functions.py
@@ -139,7 +139,7 @@ class FunctionsTest(TestCase):
         AnalysisDataService.Instance().addOrReplace(ws_name, self._test_ws)
         fig = pcolormesh_from_names([ws_name])
 
-        self.assertEqual(1, len(fig.gca().collections))
+        self.assertEqual(1, len(fig.gca().images))
 
     def test_pcolormesh_from_names_using_existing_figure(self):
         ws_name = 'test_pcolormesh_from_names-1'
@@ -148,7 +148,7 @@ class FunctionsTest(TestCase):
         fig = pcolormesh_from_names([ws_name], fig=target_fig)
 
         self.assertEqual(fig, target_fig)
-        self.assertEqual(1, len(fig.gca().collections))
+        self.assertEqual(1, len(fig.gca().images))
 
     # ------------- Failure tests -------------
 
diff --git a/qt/applications/workbench/workbench/plotting/toolbar.py b/qt/applications/workbench/workbench/plotting/toolbar.py
index dc99531de3bf956e3410dc708bac1736eda00387..ff89f5b5b09cf9205074887cd87f94cd2bffa82c 100644
--- a/qt/applications/workbench/workbench/plotting/toolbar.py
+++ b/qt/applications/workbench/workbench/plotting/toolbar.py
@@ -26,6 +26,7 @@ class WorkbenchNavigationToolbar(NavigationToolbar2QT):
     sig_grid_toggle_triggered = QtCore.Signal()
     sig_active_triggered = QtCore.Signal()
     sig_hold_triggered = QtCore.Signal()
+    sig_toggle_fit_triggered = QtCore.Signal()
 
     toolitems = (
         ('Home', 'Reset original view', 'fa.home', 'home', None),
@@ -36,7 +37,9 @@ class WorkbenchNavigationToolbar(NavigationToolbar2QT):
         ('Save', 'Save the figure', 'fa.save', 'save_figure', None),
         ('Print','Print the figure', 'fa.print', 'print_figure', None),
         (None, None, None, None, None),
-        ('Customize', 'Configure plot options', 'fa.cog', 'edit_parameters', None)
+        ('Customize', 'Configure plot options', 'fa.cog', 'edit_parameters', None),
+        (None, None, None, None, None),
+        ('Fit', 'Toggle fit browser on/off', None, 'toggle_fit', False),
     )
 
     def _init_toolbar(self):
@@ -79,6 +82,12 @@ class WorkbenchNavigationToolbar(NavigationToolbar2QT):
     def toggle_grid(self):
         self.sig_grid_toggle_triggered.emit()
 
+    def toggle_fit(self):
+        self.sig_toggle_fit_triggered.emit()
+
+    def trigger_fit_toggle_action(self):
+        self._actions['toggle_fit'].trigger()
+
     def print_figure(self):
         printer = QtPrintSupport.QPrinter(QtPrintSupport.QPrinter.HighResolution)
         printer.setOrientation(QtPrintSupport.QPrinter.Landscape)
diff --git a/qt/applications/workbench/workbench/plugins/workspacewidget.py b/qt/applications/workbench/workbench/plugins/workspacewidget.py
index 89d5a9038663d0ad29ee78c0e7c39aa8187bd6bb..f4a5623af11a21bb07b6b12e0a25dd0f8cd9edc9 100644
--- a/qt/applications/workbench/workbench/plugins/workspacewidget.py
+++ b/qt/applications/workbench/workbench/plugins/workspacewidget.py
@@ -12,17 +12,20 @@ from __future__ import (absolute_import, unicode_literals)
 # system imports
 from functools import partial
 
+import matplotlib.pyplot
+from qtpy.QtWidgets import QMessageBox, QVBoxLayout
+
 # third-party library imports
 from mantid.api import AnalysisDataService
+from mantid.kernel import logger
+from mantidqt.widgets.instrumentview.presenter import InstrumentViewPresenter
 from mantidqt.widgets.matrixworkspacedisplay.presenter import MatrixWorkspaceDisplay
 from mantidqt.widgets.samplelogs.presenter import SampleLogs
-from mantidqt.widgets.instrumentview.presenter import InstrumentViewPresenter
+from mantidqt.widgets.tableworkspacedisplay.presenter import TableWorkspaceDisplay
 from mantidqt.widgets.workspacewidget.workspacetreewidget import WorkspaceTreeWidget
-from qtpy.QtWidgets import QMessageBox, QVBoxLayout
-
+from workbench.plotting.functions import can_overplot, pcolormesh, plot, plot_from_names
 # local package imports
 from workbench.plugins.base import PluginWidget
-from workbench.plotting.functions import can_overplot, pcolormesh, plot_from_names, plot
 
 
 class WorkspaceWidget(PluginWidget):
@@ -121,10 +124,20 @@ class WorkspaceWidget(PluginWidget):
 
     def _do_show_data(self, names):
         for ws in self._ads.retrieveWorkspaces(names, unrollGroups=True):
-            # the plot function is being injected in the presenter
-            # this is done so that the plotting library is mockable in testing
-            presenter = MatrixWorkspaceDisplay(ws, plot=plot, parent=self)
-            presenter.view.show()
+            try:
+                MatrixWorkspaceDisplay.supports(ws)
+                # the plot function is being injected in the presenter
+                # this is done so that the plotting library is mockable in testing
+                presenter = MatrixWorkspaceDisplay(ws, plot=plot, parent=self)
+                presenter.view.show()
+            except ValueError:
+                try:
+                    TableWorkspaceDisplay.supports(ws)
+                    presenter = TableWorkspaceDisplay(ws, plot=matplotlib.pyplot, parent=self)
+                    presenter.view.show()
+                except ValueError:
+                    logger.error(
+                        "Could not open workspace: {0} with either MatrixWorkspaceDisplay nor TableWorkspaceDisplay.")
 
     def _action_double_click_workspace(self, name):
         self._do_show_data([name])
diff --git a/qt/applications/workbench/workbench/test/test_fit_interactive_tool.py b/qt/applications/workbench/workbench/test/test_fit_interactive_tool.py
new file mode 100644
index 0000000000000000000000000000000000000000..8810a529b6f5c3f536c1fec3743fa6cc8689f95a
--- /dev/null
+++ b/qt/applications/workbench/workbench/test/test_fit_interactive_tool.py
@@ -0,0 +1,198 @@
+from __future__ import print_function
+import unittest
+
+from qtpy.QtCore import QPoint
+from qtpy.QtGui import QCursor
+
+from mantid.simpleapi import *
+from mantidqt.utils.qt.test.gui_window_test import *
+
+from workbench.plotting.functions import plot, pcolormesh
+from workbench.plotting.globalfiguremanager import GlobalFigureManager
+from workbench.test.workbenchtests import runTests
+
+
+def on_darwin():
+    return sys.platform == 'darwin'
+
+
+@unittest.skipIf(on_darwin(), "Couldn't make it work for a mac")
+class TestFitPropertyBrowser(WorkbenchGuiTest):
+
+    def start(self):
+        if 'ws' not in mtd:
+            ws = Load(r'irs26176_graphite002_conv_1LFixF_s0_to_9_Result.nxs', OutputWorkspace='ws')
+        else:
+            ws = mtd['ws']
+        plot([ws], [1])
+        manager = GlobalFigureManager.get_active()
+        self.w = manager.window
+        trigger_action(find_action_with_text(self.w, 'Fit'))
+        yield 0.1
+        self.fit_browser = manager.fit_browser
+
+    def move_marker(self, canvas, marker, pos, dx, try_other_way_if_failed):
+        tr = self.fit_browser.tool.ax.get_xaxis_transform()
+        x0 = tr.transform((0, 0))[0]
+        dx_pxl = tr.transform((dx, 0))[0] - x0
+        pos.setX(marker.get_x_in_pixels())
+        new_pos = pos + QPoint(dx_pxl, 0)
+        yield drag_mouse(canvas, pos, new_pos)
+        pos1 = canvas.mapFromGlobal(QCursor.pos())
+        if try_other_way_if_failed and pos1 != new_pos:
+            new_x = marker.x + dx
+            marker.on_click(pos.x())
+            marker.mouse_move(new_x)
+            yield 0.1
+            marker.stop()
+
+    def move_start_x(self, canvas, pos, dx, try_other_way_if_failed=True):
+        return self.move_marker(canvas, self.fit_browser.tool.fit_start_x, pos, dx,
+                                try_other_way_if_failed=try_other_way_if_failed)
+
+    def move_end_x(self, canvas, pos, dx, try_other_way_if_failed=True):
+        return self.move_marker(canvas, self.fit_browser.tool.fit_end_x, pos, dx,
+                                try_other_way_if_failed=try_other_way_if_failed)
+
+    def test_fit_range(self):
+        yield self.start()
+        start_x = self.fit_browser.startX()
+        end_x = self.fit_browser.endX()
+        self.assertGreater(end_x, start_x)
+        self.assertGreater(start_x, 0.3)
+        self.assertGreater(2.0, end_x)
+        pos = self.w._canvas.geometry().center()
+        canvas = self.w.childAt(pos)
+        yield self.move_start_x(canvas, pos, 0.5)
+        self.assertAlmostEqual(self.fit_browser.startX(), start_x + 0.5, 1)
+        yield self.move_end_x(canvas, pos, -0.25)
+        self.assertAlmostEqual(self.fit_browser.endX(), end_x - 0.25, 1)
+
+    def test_fit_range_start_moved_too_far(self):
+        yield self.start()
+        start_x = self.fit_browser.startX()
+        end_x = self.fit_browser.endX()
+        self.assertGreater(end_x, start_x)
+        self.assertGreater(start_x, 0.3)
+        self.assertGreater(2.0, end_x)
+        pos = self.w._canvas.geometry().center()
+        canvas = self.w.childAt(pos)
+        yield self.move_end_x(canvas, pos, -0.5)
+        new_end_x = self.fit_browser.endX()
+        self.assertAlmostEqual(new_end_x, end_x - 0.5, 1)
+        yield self.move_start_x(canvas, pos, 1.0)
+        self.assertAlmostEqual(self.fit_browser.startX(), new_end_x)
+
+    def test_fit_range_end_moved_too_far(self):
+        yield self.start()
+        start_x = self.fit_browser.startX()
+        end_x = self.fit_browser.endX()
+        self.assertGreater(end_x, start_x)
+        self.assertGreater(start_x, 0.3)
+        self.assertGreater(2.0, end_x)
+        pos = self.w._canvas.geometry().center()
+        canvas = self.w.childAt(pos)
+        yield self.move_start_x(canvas, pos, 0.5)
+        new_start_x = self.fit_browser.startX()
+        self.assertAlmostEqual(new_start_x, start_x + 0.5, 1)
+        yield self.move_end_x(canvas, pos, -1.0)
+        self.assertAlmostEqual(self.fit_browser.endX(), new_start_x)
+
+    def test_fit_range_moved_start_outside(self):
+        yield self.start()
+        start_x_pxl = self.fit_browser.tool.fit_start_x.get_x_in_pixels()
+        pos = self.w._canvas.geometry().center()
+        canvas = self.w.childAt(pos)
+        yield self.move_start_x(canvas, pos, -2.0, try_other_way_if_failed=False)
+        self.assertTrue(abs(start_x_pxl - self.fit_browser.tool.fit_start_x.get_x_in_pixels()) < 5)
+
+    def test_fit_range_moved_end_outside(self):
+        yield self.start()
+        end_x_pxl = self.fit_browser.tool.fit_end_x.get_x_in_pixels()
+        pos = self.w._canvas.geometry().center()
+        canvas = self.w.childAt(pos)
+        yield self.move_end_x(canvas, pos, 2.0, try_other_way_if_failed=False)
+        self.assertTrue(abs(end_x_pxl - self.fit_browser.tool.fit_end_x.get_x_in_pixels()) < 5)
+
+    def test_fit_range_set_start(self):
+        yield self.start()
+        self.fit_browser.setStartX(0.7)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_start_x.x, 0.7)
+
+    def test_fit_range_set_start_outside(self):
+        yield self.start()
+        self.fit_browser.setStartX(0.1)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_start_x.x, 0.1)
+
+    def test_fit_range_set_start_outside_right(self):
+        yield self.start()
+        self.fit_browser.setStartX(2.0)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_start_x.x, self.fit_browser.endX())
+
+    def test_fit_range_set_end(self):
+        yield self.start()
+        self.fit_browser.setEndX(1.0)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_end_x.x, 1.0)
+
+    def test_fit_range_set_end_outside(self):
+        yield self.start()
+        self.fit_browser.setEndX(2.0)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_end_x.x, 2.0)
+
+    def test_fit_range_set_end_outside_left(self):
+        yield self.start()
+        self.fit_browser.setEndX(0.3)
+        self.assertAlmostEqual(self.fit_browser.tool.fit_end_x.x, self.fit_browser.startX())
+
+    def test_fit(self):
+        yield self.start()
+        self.fit_browser.loadFunction('name=LinearBackground')
+        self.fit_browser.fit()
+        yield self.wait_for_true(lambda: len(self.fit_browser.fit_result_lines) == 2)
+        # self.assertEqual(self.fit_browser.getFittingFunction(), "name=LinearBackground,A0=4.74354,A1=-0.442138")
+        self.assertEqual(len(self.fit_browser.fit_result_lines), 2)
+        del mtd['ws_Workspace']
+        self.fit_browser.fit()
+        yield self.wait_for_true(lambda: len(self.fit_browser.fit_result_lines) == 2)
+        self.assertEqual(len(self.fit_browser.fit_result_lines), 2)
+
+    def start_emu(self):
+        res1 = Load(r'emu00006473.nxs', OutputWorkspace='ws1')
+        Load(r'emu00006475.nxs', OutputWorkspace='ws2')
+        plot([res1[0]], [3, 5, 7])
+        manager = GlobalFigureManager.get_active()
+        self.w = manager.window
+        trigger_action(find_action_with_text(self.w, 'Fit'))
+        yield 0.1
+        self.fit_browser = manager.fit_browser
+
+    def test_ws_index(self):
+        yield self.start_emu()
+        self.assertEqual(self.fit_browser.getWorkspaceNames(), ['ws1'])
+        self.assertEqual(self.fit_browser.workspaceIndex(), 2)
+        self.fit_browser.setWorkspaceIndex(3)
+        yield self.wait_for_true(lambda: self.fit_browser.workspaceIndex() == 4)
+        self.assertEqual(self.fit_browser.workspaceIndex(), 4)
+        self.fit_browser.setWorkspaceIndex(3)
+        yield self.wait_for_true(lambda: self.fit_browser.workspaceIndex() == 2)
+        self.assertEqual(self.fit_browser.workspaceIndex(), 2)
+        self.fit_browser.setWorkspaceIndex(10)
+        yield self.wait_for_true(lambda: self.fit_browser.workspaceIndex() == 6)
+        self.assertEqual(self.fit_browser.workspaceIndex(), 6)
+        self.fit_browser.setWorkspaceIndex(0)
+        yield self.wait_for_true(lambda: self.fit_browser.workspaceIndex() == 2)
+        self.assertEqual(self.fit_browser.workspaceIndex(), 2)
+
+    def test_hidden_fit_for_images(self):
+        if 'ws1' in mtd:
+            ws1 = mtd['ws1']
+        else:
+            ws1 = Load(r'emu00006473.nxs', OutputWorkspace='ws1')[0]
+        pcolormesh([ws1])
+        manager = GlobalFigureManager.get_active()
+        action = manager.toolbar._actions['toggle_fit']
+        self.assertFalse(action.isVisible())
+        self.assertFalse(action.isEnabled())
+
+
+runTests(TestFitPropertyBrowser)
diff --git a/qt/applications/workbench/workbench/test/workbenchtests.py b/qt/applications/workbench/workbench/test/workbenchtests.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3d2f846b87dd9aedc0e0c1150fd1918f7b5bc2b
--- /dev/null
+++ b/qt/applications/workbench/workbench/test/workbenchtests.py
@@ -0,0 +1,51 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+"""
+Utility functions for running python test scripts
+inside Workbench.
+
+Public methods:
+    runTests(): to run Workbench unit tests
+
+"""
+from __future__ import (absolute_import, division, print_function)
+import sys
+import os
+import unittest
+from qtpy.QtCore import QCoreApplication
+from workbench.plotting.qappthreadcall import QAppThreadCall
+
+
+def runTests(classname):
+    """ Run the test suite in the class.
+    Uses the XML runner if the MANTID_SOURCE environment variable was set.
+    """
+    # Custom code to create and run this single test suite
+    suite = QAppThreadCall(unittest.TestSuite)()
+    QAppThreadCall(suite.addTest)(unittest.makeSuite(classname))
+    # Get the XML runner if the environment variable was set
+    src = os.getenv('MANTID_SOURCE')
+    if src is None:
+        runner = QAppThreadCall(unittest.TextTestRunner)()
+    else:
+        sys.path.append(os.path.join(src, "Testing", "Tools", "unittest-xml-reporting", "src"))
+        import xmlrunner
+        runner = QAppThreadCall(xmlrunner.XMLTestRunner)(output='Testing')
+
+    # Run using either runner
+    res = QAppThreadCall(runner.run)(suite)
+
+    # Process some events that ensure MantidPlot closes properly.
+    QCoreApplication.processEvents()
+    QCoreApplication.processEvents()
+    QCoreApplication.processEvents()
+
+    # Close Mantid and set exit code
+    if not res.wasSuccessful():
+        sys.exit(1)
+    else:
+        sys.exit(0)
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/MDLoadingViewAdapter.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/MDLoadingViewAdapter.h
index 310fc0e76c589b5999ce1cbadf9938d34c94d82b..c2d65c087501ca93045deb62ff573ada9b982835 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/MDLoadingViewAdapter.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/MDLoadingViewAdapter.h
@@ -18,8 +18,7 @@ Templated type for wrapping non-MDLoadingView types. Adapter pattern.
 @author Owen Arnold, Tessella plc
 @date 07/09/2011
 */
-template <typename ViewType>
-class DLLExport MDLoadingViewAdapter : public MDLoadingView {
+template <typename ViewType> class MDLoadingViewAdapter : public MDLoadingView {
 private:
   ViewType *m_adaptee;
 
diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
index 5167c678593072683c9cde0b82cbd5a252c16d61..93d78a95d7db305c47fd6b0e4dbfd23f2caebf50 100644
--- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
+++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
@@ -82,6 +82,8 @@ SplatterPlotView::SplatterPlotView(
                    SIGNAL(setRotationToPoint(double, double, double)), this,
                    SLOT(onResetCenterToPoint(double, double, double)));
 
+  this->m_ui.thresholdButton->setToolTip(
+      "Create a threshold filter on the data");
   // Set the threshold button to create a threshold filter on data
   QObject::connect(this->m_ui.thresholdButton, SIGNAL(clicked()), this,
                    SLOT(onThresholdButtonClicked()));
@@ -177,7 +179,6 @@ void SplatterPlotView::render() {
     this->m_splatSource = builder->createFilter(
         "filters", MantidQt::API::MdConstants::MantidParaViewSplatterPlot,
         this->origSrc);
-    src = this->m_splatSource;
   } else {
     // We don't want to load the same peak workspace twice into the splatterplot
     // mode
@@ -292,6 +293,11 @@ void SplatterPlotView::checkPeaksCoordinates() {
 }
 
 void SplatterPlotView::onThresholdButtonClicked() {
+  if (!this->m_threshSource) {
+    // prevent trying to create a filter for empty data (nullptr)
+    // which causes VSI to crash
+    return;
+  }
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
   this->m_threshSource = builder->createFilter(
       "filters", MantidQt::API::MdConstants::Threshold, this->m_splatSource);
@@ -321,12 +327,16 @@ void SplatterPlotView::checkView(ModeControlWidget::Views initialView) {
  */
 void SplatterPlotView::onPickModeToggled(bool state) {
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+
   if (state) {
     pqPipelineSource *src = nullptr;
     if (this->m_threshSource) {
       src = this->m_threshSource;
-    } else {
+    } else if (this->m_splatSource) {
       src = this->m_splatSource;
+    } else {
+      // no sources are present in the view -> don't do anything
+      return;
     }
     this->m_probeSource = builder->createFilter(
         "filters", MantidQt::API::MdConstants::ProbePoint, src);
diff --git a/qt/python/CMakeLists.txt b/qt/python/CMakeLists.txt
index 7d40b45707562a3e3d482fc0ff9107693987794c..dcd76cb16521de35b3d95986e54e301dc9b8017f 100644
--- a/qt/python/CMakeLists.txt
+++ b/qt/python/CMakeLists.txt
@@ -92,6 +92,7 @@ endif ()
 
     mantidqt/widgets/test/test_jupyterconsole.py
     mantidqt/widgets/test/test_messagedisplay.py
+    mantidqt/widgets/test/test_fitpropertybrowser.py
 
     mantidqt/widgets/samplelogs/test/test_samplelogs_model.py
     mantidqt/widgets/samplelogs/test/test_samplelogs_presenter.py
@@ -99,6 +100,13 @@ endif ()
     mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_model.py
     mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_presenter.py
     mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_tableviewmodel.py
+
+    mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_error_column.py
+    mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_marked_columns.py
+    mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_workbench_table_widget_item.py
+
+    mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_model.py
+    mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_presenter.py
   )
 
   # ctest targets for interpreters (Encoder/Decoder) tests only get tested in qt5 as only for workbench
diff --git a/qt/python/mantidqt/CMakeLists.txt b/qt/python/mantidqt/CMakeLists.txt
index 8b2ac266947ceac944c79338e0460175b5292ff4..87da03fb2fc98283bd2b5a486a3efd7b653013a5 100644
--- a/qt/python/mantidqt/CMakeLists.txt
+++ b/qt/python/mantidqt/CMakeLists.txt
@@ -27,6 +27,7 @@ mtd_add_sip_module (
   PYQT_VERSION 4
   INCLUDE_DIRS
     ${PYTHON_INCLUDE_PATH}
+    ${CMAKE_SOURCE_DIR}/Framework/PythonInterface/core/inc
   LINK_LIBS
     ${common_link_libs}
     MantidQtWidgetsCommonQt4
@@ -51,6 +52,7 @@ mtd_add_sip_module (
   PYQT_VERSION 5
   INCLUDE_DIRS
     ${PYTHON_INCLUDE_PATH}
+    ${CMAKE_SOURCE_DIR}/Framework/PythonInterface/core/inc
   LINK_LIBS
     ${common_link_libs}
     MantidQtWidgetsCommonQt5
diff --git a/qt/python/mantidqt/_common.sip b/qt/python/mantidqt/_common.sip
index 5ea5f58fa7afe506bb2882a832746c1994d152bd..4bf55659c6d1a01e35ea3174ebe99a3aeb106324 100644
--- a/qt/python/mantidqt/_common.sip
+++ b/qt/python/mantidqt/_common.sip
@@ -1,10 +1,14 @@
 %ModuleCode
 #include "MantidQtWidgets/Common/Message.h"
+#include "MantidQtWidgets/Common/WorkspaceObserver.h"
+#include "MantidPythonInterface/core/VersionCompat.h"
 // Allows suppression of namespaces within the module
 using namespace MantidQt::MantidWidgets;
 %End
 
 %InitialisationCode
+qRegisterMetaType<std::string>("StdString");
+qRegisterMetaType<Mantid::API::Workspace_sptr>("Workspace");
 qRegisterMetaType<Message>("Message");
 %End
 
@@ -223,7 +227,7 @@ class WorkspaceTreeWidget : QWidget {
 #include "MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h"
 %End
 public:
-  WorkspaceTreeWidget(MantidDisplayBase *mdb /Transfer/,
+  WorkspaceTreeWidget(MantidDisplayBase *mdb /Transfer/, bool viewOnly=false,
                       QWidget *parent /TransferThis/ = nullptr);
 };
 
@@ -233,7 +237,7 @@ class WorkspaceTreeWidgetSimple : WorkspaceTreeWidget {
 #include "MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h"
 %End
 public:
-  WorkspaceTreeWidgetSimple(QWidget *parent /TransferThis/ = nullptr);
+  WorkspaceTreeWidgetSimple(bool viewOnly=false, QWidget *parent /TransferThis/ = nullptr);
 
 signals:
   void plotSpectrumClicked(const QStringList & workspaceNames);
@@ -256,3 +260,36 @@ class ManageUserDirectories : QDialog {
 public:
   ManageUserDirectories(QWidget *parent /TransferThis/ = nullptr);
 };
+
+// ---------------------------------
+// Fit Property Browser
+// ---------------------------------
+class FitPropertyBrowser : public QDockWidget {
+%TypeHeaderCode
+#include "MantidQtWidgets/Common/FitPropertyBrowser.h"
+%End
+public:
+    FitPropertyBrowser(QWidget *parent = nullptr, QObject *mantidui = nullptr);
+    void init();
+    SIP_PYOBJECT getFittingFunction() const;
+%MethodCode
+    auto f = sipCpp->getFittingFunction();
+    sipRes = FROM_CSTRING(f->asString().c_str());
+%End
+    int sizeOfFunctionsGroup() const;
+    void loadFunction(QString funStr);
+    double startX() const;
+    void setStartX(double start);
+    double endX() const;
+    void setEndX(double end);
+    void setXRange(double start, double end);
+    int workspaceIndex() const;
+    void setWorkspaceIndex(int i);
+    QStringList getWorkspaceNames();
+    void fit();
+    void addAllowedSpectra(const QString &wsName, const QList<int> &wsIndices);
+signals:
+    void startXChanged(double);
+    void endXChanged(double);
+    void fittingDone(const QString &);
+};
diff --git a/qt/python/mantidqt/io.py b/qt/python/mantidqt/io.py
index c4736787b2419f0b4f65bf94975dea17250d6515..26ca99d3d6ef867ae77d13e97b45a2f4b7a98f2b 100644
--- a/qt/python/mantidqt/io.py
+++ b/qt/python/mantidqt/io.py
@@ -8,9 +8,10 @@
 #
 
 import os.path
-from qtpy.QtWidgets import QFileDialog
+from qtpy.QtWidgets import QFileDialog, QDialog
 from qtpy.QtCore import QDir
 
+# For storing a persistent directory of where the last file was saved to.
 _LAST_SAVE_DIRECTORY = None
 
 
@@ -24,7 +25,7 @@ def open_a_file_dialog(parent=None,  default_suffix=None, directory=None, file_f
     :param file_filter: String; The filter name and file type e.g. "Python files (*.py)"
     :param accept_mode: enum AcceptMode; Defines the AcceptMode of the dialog, check QFileDialog Class for details
     :param file_mode: enum FileMode; Defines the FileMode of the dialog, check QFileDialog Class for details
-    :return: String; The filename that was selected, it is possible to return a directory so look out for that.
+    :return: String; The filename that was selected, it is possible to return a directory so look out for that
     """
     global _LAST_SAVE_DIRECTORY
     dialog = QFileDialog(parent)
@@ -55,10 +56,12 @@ def open_a_file_dialog(parent=None,  default_suffix=None, directory=None, file_f
     dialog.fileSelected.connect(_set_last_save)
 
     # Wait for dialog to finish before allowing continuation of code
-    dialog.exec_()
+    if dialog.exec_() == QDialog.Rejected:
+        return None
 
     filename = _LAST_SAVE_DIRECTORY
-    # Make sure that the _LAST_SAVE_DIRECTORY is set
+
+    # Make sure that the _LAST_SAVE_DIRECTORY is set as a directory
     if _LAST_SAVE_DIRECTORY is not None and not os.path.isdir(_LAST_SAVE_DIRECTORY):
         # Remove the file for last directory
         _LAST_SAVE_DIRECTORY = os.path.dirname(os.path.abspath(_LAST_SAVE_DIRECTORY))
@@ -68,7 +71,7 @@ def open_a_file_dialog(parent=None,  default_suffix=None, directory=None, file_f
 
 def _set_last_save(filename):
     """
-    Uses the global _LOCAL_SAVE_DIRECTORY to store output from connected signal
+    Uses the global _LAST_SAVE_DIRECTORY to store output from connected signal
     :param filename: String; Value to set _LAST_SAVE_DIRECTORY
     """
     global _LAST_SAVE_DIRECTORY
diff --git a/qt/python/mantidqt/project/__init__.py b/qt/python/mantidqt/project/__init__.py
index 20b85731aa0c9565f89493f598ca368a49d707b3..044ed3c205730d7114d5b66b2a4a733d211106c0 100644
--- a/qt/python/mantidqt/project/__init__.py
+++ b/qt/python/mantidqt/project/__init__.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/plotsloader.py b/qt/python/mantidqt/project/plotsloader.py
index 56637b83c7e5f9b95bbe429dfe161d29dbd0451c..b8862b29e6468ed3fe07a3415b397942e3d04bc5 100644
--- a/qt/python/mantidqt/project/plotsloader.py
+++ b/qt/python/mantidqt/project/plotsloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -8,7 +8,9 @@
 #
 from __future__ import (absolute_import, division, print_function, unicode_literals)
 
-from matplotlib import ticker, axis  # noqa
+import copy
+
+from matplotlib import ticker, text, axis  # noqa
 import matplotlib.colors
 import matplotlib.axes
 
@@ -42,11 +44,20 @@ class PlotsLoader(object):
         import matplotlib.pyplot as plt
         # Grab creation arguments
         creation_args = plot_dict["creationArguments"]
+
+        # Make a copy so it can be applied to the axes, of the plot once created.
+        creation_args_copy = copy.deepcopy(creation_args[0])
+
+        # Populate workspace names
         workspace_name = creation_args[0][0].pop('workspaces')
         workspace = ADS.retrieve(workspace_name)
+
         # Make initial plot
         fig, ax = plt.subplots(subplot_kw={'projection': 'mantid'})
 
+        # Make sure that the axes gets it's creation_args as loading doesn't add them
+        ax.creation_args = creation_args_copy
+
         self.plot_func(workspace, ax, creation_args[0][0])
 
         # If an overplot is necessary plot onto the same figure
diff --git a/qt/python/mantidqt/project/plotssaver.py b/qt/python/mantidqt/project/plotssaver.py
index 5c61a471ebc46a839554d39398931118d76a102f..ab5ca2ced475325e2b4889a9d20e386aaef3d90a 100644
--- a/qt/python/mantidqt/project/plotssaver.py
+++ b/qt/python/mantidqt/project/plotssaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -9,7 +9,7 @@
 from __future__ import (absolute_import, division, print_function, unicode_literals)
 
 from matplotlib import ticker
-import matplotlib.colors
+import matplotlib.axis
 
 from mantid import logger
 
@@ -33,7 +33,8 @@ class PlotsSaver(object):
             try:
                 plot_list.append(self.get_dict_from_fig(plot_dict[index].canvas.figure))
             except BaseException as e:
-                # Catch all errors in here so it can fail silently-ish
+                # Catch all errors in here so it can fail silently-ish, if this is happening on all plots make sure you
+                # have built your project.
                 if isinstance(e, KeyboardInterrupt):
                     raise KeyboardInterrupt
                 logger.warning("A plot was unable to be saved")
diff --git a/qt/python/mantidqt/project/project.py b/qt/python/mantidqt/project/project.py
index 37ae02c86ed62686dd88c99ae2a628150f323be3..7f05907604ee7002a1bfbf3b1d6eaef14af7744e 100644
--- a/qt/python/mantidqt/project/project.py
+++ b/qt/python/mantidqt/project/project.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -10,6 +10,7 @@ from __future__ import (absolute_import, division, print_function, unicode_liter
 
 import os
 from qtpy.QtWidgets import QFileDialog, QMessageBox
+from qtpy.QtGui import QIcon  # noqa
 
 from mantid.api import AnalysisDataService, AnalysisDataServiceObserver
 from mantidqt.io import open_a_file_dialog
@@ -53,25 +54,56 @@ class Project(AnalysisDataServiceObserver):
         if self.last_project_location is None:
             return self.save_as()
         else:
-            # Actually save
-            self._save()
-            self.__saved = True
+            # Offer an are you sure? overwriting GUI
+            answer = self._offer_overwriting_gui()
+
+            if answer == QMessageBox.Yes:
+                # Actually save
+                self._save()
+            # Else do nothing
 
     def save_as(self):
         """
         The function that is called if the save as... button is clicked on the mainwindow
         :return: None; if the user cancels.
         """
-        directory = self._file_dialog(accept_mode=QFileDialog.AcceptSave, file_mode=QFileDialog.DirectoryOnly)
+        path = self._save_file_dialog()
+        if path is None:
+            # Cancel close dialogs
+            return
 
-        # If none then the user cancelled
-        if directory is None:
+        overwriting = False
+        # If the selected path is a project directory ask if overwrite is required?
+        if os.path.exists(os.path.join(path, (os.path.basename(path) + self.project_file_ext))):
+            answer = self._offer_overwriting_gui()
+            if answer == QMessageBox.No:
+                return
+            elif answer == QMessageBox.Yes:
+                overwriting = True
+
+        if not overwriting and os.path.exists(path) and os.listdir(path) != []:
+            QMessageBox.warning(None, "Empty directory or project required!",
+                                "Please choose either an new directory or an already saved project", QMessageBox.Ok)
             return
 
         # todo: get a list of workspaces but to be implemented on GUI implementation
-        self.last_project_location = directory
+        self.last_project_location = path
         self._save()
 
+    @staticmethod
+    def _offer_overwriting_gui():
+        """
+        Offers up a overwriting QMessageBox giving the option to overwrite a project, and returns the reply.
+        :return: QMessaageBox.Yes or QMessageBox.No; The value is the value selected by the user.
+        """
+        return QMessageBox.question(None, "Overwrite project?",
+                                    "Would you like to overwrite the selected project?",
+                                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
+
+    @staticmethod
+    def _save_file_dialog():
+        return open_a_file_dialog(accept_mode=QFileDialog.AcceptSave, file_mode=QFileDialog.Directory)
+
     def _save(self):
         workspaces_to_save = AnalysisDataService.getObjectNames()
         plots_to_save = self.plot_gfm.figs
@@ -81,32 +113,22 @@ class Project(AnalysisDataServiceObserver):
                                    plots_to_save=plots_to_save, interfaces_to_save=interfaces_to_save)
         self.__saved = True
 
-    def _file_dialog(self, accept_mode, file_mode, file_filter=None):
-        path = None
-        # Check if it exists
-        first_pass = True
-        while first_pass or (not os.path.exists(path) and os.path.exists(path + (os.path.basename(path)
-                                                                                 + self.project_file_ext))):
-            first_pass = False
-            path = open_a_file_dialog(accept_mode=accept_mode, file_mode=file_mode, file_filter=file_filter)
-            if path is None:
-                # Cancel close dialogs
-                return
-
-        return path
-
     def load(self):
         """
         The event that is called when open project is clicked on the main window
         :return: None; if the user cancelled.
         """
-        file_name = self._file_dialog(accept_mode=QFileDialog.AcceptOpen, file_mode=QFileDialog.ExistingFile,
-                                      file_filter="Project files ( *" + self.project_file_ext + ")")
-
-        # If none then the user cancelled
+        file_name = self._load_file_dialog()
         if file_name is None:
+            # Cancel close dialogs
             return
 
+        # Sanity check
+        _, file_ext = os.path.splitext(file_name)
+
+        if file_ext != ".mtdproj":
+            QMessageBox.warning(None, "Wrong file type!", "Please select a valid project file", QMessageBox.Ok)
+
         directory = os.path.dirname(file_name)
 
         project_loader = ProjectLoader(self.project_file_ext)
@@ -114,6 +136,10 @@ class Project(AnalysisDataServiceObserver):
         self.last_project_location = directory
         self.__saved = True
 
+    def _load_file_dialog(self):
+        return open_a_file_dialog(accept_mode=QFileDialog.AcceptOpen, file_mode=QFileDialog.ExistingFile,
+                                  file_filter="Project files ( *" + self.project_file_ext + ")")
+
     def offer_save(self, parent):
         """
         :param parent: QWidget; Parent of the QMessageBox that is popped up
diff --git a/qt/python/mantidqt/project/projectloader.py b/qt/python/mantidqt/project/projectloader.py
index 2d9406f20cd01c5ab84e7107ff016f96cb7f8695..cfc3cc997cff9d0fca44cbfa0c8fc63ca215fe08 100644
--- a/qt/python/mantidqt/project/projectloader.py
+++ b/qt/python/mantidqt/project/projectloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/projectsaver.py b/qt/python/mantidqt/project/projectsaver.py
index b24baf57072b1ee0a20baffa3ec1f405948d8e56..5805ae561f5edb2a0a63bacb89a01653c8f1aee5 100644
--- a/qt/python/mantidqt/project/projectsaver.py
+++ b/qt/python/mantidqt/project/projectsaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/test/__init__.py b/qt/python/mantidqt/project/test/__init__.py
index 20b85731aa0c9565f89493f598ca368a49d707b3..044ed3c205730d7114d5b66b2a4a733d211106c0 100644
--- a/qt/python/mantidqt/project/test/__init__.py
+++ b/qt/python/mantidqt/project/test/__init__.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/test/test_plotsloader.py b/qt/python/mantidqt/project/test/test_plotsloader.py
index ec598fb99dfcce38fc7616016f706c925227bb68..df4dd5fc0f70367daf080448fe1e98b1c63bdbec 100644
--- a/qt/python/mantidqt/project/test/test_plotsloader.py
+++ b/qt/python/mantidqt/project/test/test_plotsloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -8,20 +8,25 @@
 #
 from __future__ import (absolute_import, division, print_function, unicode_literals)
 
-import sys
-import unittest
-import matplotlib.pyplot as plt
-import matplotlib.figure
-import matplotlib.text
+import matplotlib
+matplotlib.use('AGG')
 
-from mantidqt.project.plotsloader import PlotsLoader
-import mantid.plots.plotfunctions
-from mantid.api import AnalysisDataService as ADS
-from mantid.dataobjects import Workspace2D
+import sys  # noqa
+import unittest  # noqa
+import matplotlib.pyplot as plt  # noqa
+import matplotlib.figure  # noqa
+import matplotlib.text  # noqa
 
-if sys.version_info.major == 3:
+from mantidqt.project.plotsloader import PlotsLoader  # noqa
+import mantid.plots.plotfunctions  # noqa
+from mantid.api import AnalysisDataService as ADS  # noqa
+from mantid.dataobjects import Workspace2D  # noqa
+
+if sys.version_info.major >= 3:
+    # Python 3 and above
     from unittest import mock
 else:
+    # Python 2
     import mock
 
 
diff --git a/qt/python/mantidqt/project/test/test_plotssaver.py b/qt/python/mantidqt/project/test/test_plotssaver.py
index 92d08be0645c57a637bce0618bb876c94a887c33..2daabd927964171ce8018d5d4eaf70aae1887322 100644
--- a/qt/python/mantidqt/project/test/test_plotssaver.py
+++ b/qt/python/mantidqt/project/test/test_plotssaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -15,11 +15,14 @@ from mantidqt.project.plotssaver import PlotsSaver
 from mantidqt.project.plotsloader import PlotsLoader
 from mantid.simpleapi import CreateSampleWorkspace
 
+import matplotlib
+matplotlib.use('AGG')
+
 
 class PlotsSaverTest(unittest.TestCase):
     def setUp(self):
         CreateSampleWorkspace(OutputWorkspace="ws1")
-        plots_loader = PlotsLoader()
+        self.plots_loader = PlotsLoader()
 
         # Make a figure with a given input with all these values already set
         self.loader_plot_dict = {u'axes': [{u'legend': {u'exists': False}, u'lines': [{u'alpha': 1,
@@ -77,7 +80,7 @@ class PlotsSaverTest(unittest.TestCase):
                                  u'creationArguments': [[{u"workspaces": u"ws1", u"specNum": 2}]],
                                  u'label': u'',
                                  u'properties': {u'dpi': 100.0, u'figHeight': 4.8, u'figWidth': 6.4}}
-        self.fig = plots_loader.make_fig(self.loader_plot_dict, create_plot=False)
+        self.fig = self.plots_loader.make_fig(self.loader_plot_dict, create_plot=False)
 
         self.plot_saver = PlotsSaver()
 
diff --git a/qt/python/mantidqt/project/test/test_project.py b/qt/python/mantidqt/project/test/test_project.py
index ed57781c478df9ecc7f3cbf418966603935a2061..e1198a6e85be09c5d1563dc3c849126ea690f9a9 100644
--- a/qt/python/mantidqt/project/test/test_project.py
+++ b/qt/python/mantidqt/project/test/test_project.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -19,9 +19,11 @@ from mantid.simpleapi import CreateSampleWorkspace, GroupWorkspaces, RenameWorks
 from mantid.api import AnalysisDataService as ADS
 from mantidqt.project.project import Project
 
-if sys.version_info.major == 3:
+if sys.version_info.major >= 3:
+    # Python 3 and above
     from unittest import mock
 else:
+    # Python 2
     import mock
 
 
@@ -53,6 +55,7 @@ class ProjectTest(unittest.TestCase):
         working_directory = tempfile.mkdtemp()
         self.project.last_project_location = working_directory
         CreateSampleWorkspace(OutputWorkspace="ws1")
+        self.project._offer_overwriting_gui = mock.MagicMock(return_value=QMessageBox.Yes)
 
         self.project.save()
 
@@ -60,15 +63,16 @@ class ProjectTest(unittest.TestCase):
         file_list = os.listdir(working_directory)
         self.assertTrue(os.path.basename(working_directory) + ".mtdproj" in file_list)
         self.assertTrue("ws1.nxs" in file_list)
+        self.assertEqual(self.project._offer_overwriting_gui.call_count, 1)
 
     def test_save_as_saves_project_successfully(self):
         working_directory = tempfile.mkdtemp()
-        self.project._file_dialog = mock.MagicMock(return_value=working_directory)
+        self.project._save_file_dialog = mock.MagicMock(return_value=working_directory)
         CreateSampleWorkspace(OutputWorkspace="ws1")
 
         self.project.save_as()
 
-        self.assertEqual(self.project._file_dialog.call_count, 1)
+        self.assertEqual(self.project._save_file_dialog.call_count, 1)
         self.assertTrue(os.path.isdir(working_directory))
         file_list = os.listdir(working_directory)
         self.assertTrue(os.path.basename(working_directory) + ".mtdproj" in file_list)
@@ -77,16 +81,16 @@ class ProjectTest(unittest.TestCase):
     def test_load_calls_loads_successfully(self):
         working_directory = tempfile.mkdtemp()
         return_value_for_load = os.path.join(working_directory, os.path.basename(working_directory) + ".mtdproj")
-        self.project._file_dialog = mock.MagicMock(return_value=working_directory)
+        self.project._save_file_dialog = mock.MagicMock(return_value=working_directory)
         CreateSampleWorkspace(OutputWorkspace="ws1")
         self.project.save_as()
 
-        self.assertEqual(self.project._file_dialog.call_count, 1)
+        self.assertEqual(self.project._save_file_dialog.call_count, 1)
         ADS.clear()
 
-        self.project._file_dialog = mock.MagicMock(return_value=return_value_for_load)
+        self.project._load_file_dialog = mock.MagicMock(return_value=return_value_for_load)
         self.project.load()
-        self.assertEqual(self.project._file_dialog.call_count, 1)
+        self.assertEqual(self.project._load_file_dialog.call_count, 1)
         self.assertEqual(["ws1"], ADS.getObjectNames())
 
     def test_offer_save_does_nothing_if_saved_is_true(self):
diff --git a/qt/python/mantidqt/project/test/test_projectloader.py b/qt/python/mantidqt/project/test/test_projectloader.py
index 869d9e61bae6d95714dc7b136560210520335e3d..5f33fb1227f118f352fbea77880bcbdbaf994354 100644
--- a/qt/python/mantidqt/project/test/test_projectloader.py
+++ b/qt/python/mantidqt/project/test/test_projectloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
@@ -9,13 +9,16 @@
 
 import unittest
 
-from os.path import isdir
-from shutil import rmtree
-import tempfile
+import matplotlib
+matplotlib.use('AGG')
 
-from mantid.api import AnalysisDataService as ADS
-from mantid.simpleapi import CreateSampleWorkspace
-from mantidqt.project import projectloader, projectsaver
+from os.path import isdir  # noqa
+from shutil import rmtree  # noqa
+import tempfile  # noqa
+
+from mantid.api import AnalysisDataService as ADS  # noqa
+from mantid.simpleapi import CreateSampleWorkspace  # noqa
+from mantidqt.project import projectloader, projectsaver  # noqa
 
 
 project_file_ext = ".mtdproj"
diff --git a/qt/python/mantidqt/project/test/test_projectsaver.py b/qt/python/mantidqt/project/test/test_projectsaver.py
index 75eafff11d3b2c354dabc5352f63af3ba1adf24d..08341871d9d7499bea7e2d5d56e852945c519df4 100644
--- a/qt/python/mantidqt/project/test/test_projectsaver.py
+++ b/qt/python/mantidqt/project/test/test_projectsaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/test/test_workspaceloader.py b/qt/python/mantidqt/project/test/test_workspaceloader.py
index dd433316c087ce82d271117348d8266c281b64b3..54a46c2e588586615a411fe3a35366dc337d784a 100644
--- a/qt/python/mantidqt/project/test/test_workspaceloader.py
+++ b/qt/python/mantidqt/project/test/test_workspaceloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/test/test_workspacesaver.py b/qt/python/mantidqt/project/test/test_workspacesaver.py
index 70fa1cf4bb3d1e1a499b18c62c39ef2644a7a0de..4b837776518cbfc90a5e48f305f0e0a2599ac9c0 100644
--- a/qt/python/mantidqt/project/test/test_workspacesaver.py
+++ b/qt/python/mantidqt/project/test/test_workspacesaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/workspaceloader.py b/qt/python/mantidqt/project/workspaceloader.py
index d0dedf78ef4dcc5a3374b0128c7a6c7967e76b8e..b3aeef043f15e122b5b0033a69c81347a6f95abf 100644
--- a/qt/python/mantidqt/project/workspaceloader.py
+++ b/qt/python/mantidqt/project/workspaceloader.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/project/workspacesaver.py b/qt/python/mantidqt/project/workspacesaver.py
index b3e0b583edcc69cd9ef2cafad366eb31b98bf852..2be98f7ecd55d0c51c8ea8d27aa7c41c9a1c4ef8 100644
--- a/qt/python/mantidqt/project/workspacesaver.py
+++ b/qt/python/mantidqt/project/workspacesaver.py
@@ -1,6 +1,6 @@
 # Mantid Repository : https://github.com/mantidproject/mantid
 #
-# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
diff --git a/qt/python/mantidqt/utils/qt/test/__init__.py b/qt/python/mantidqt/utils/qt/test/__init__.py
index a4bb007c63352603aa13af818bdfb0d6ae73f7bc..7b87c75b12b99c51173a877e13518de4aea501f3 100644
--- a/qt/python/mantidqt/utils/qt/test/__init__.py
+++ b/qt/python/mantidqt/utils/qt/test/__init__.py
@@ -15,13 +15,10 @@ from __future__ import absolute_import
 from unittest import TestCase
 
 from qtpy.QtCore import Qt
-from qtpy.QtWidgets import QApplication
 
-from mantidqt.utils.qt.plugins import setup_library_paths
+from .application import get_application
 from .modal_tester import ModalTester
-
-# Hold on to QAPP reference to avoid garbage collection
-_QAPP = None
+from .gui_window_test import GuiWindowTest
 
 
 class GuiTest(TestCase):
@@ -33,10 +30,7 @@ class GuiTest(TestCase):
         """Prepare for test execution.
         Ensure that a (single copy of) QApplication has been created
         """
-        global _QAPP
-        if _QAPP is None:
-            setup_library_paths()
-            _QAPP = QApplication([cls.__name__])
+        get_application(cls.__name__)
 
 
 def select_item_in_tree(tree, item_label):
diff --git a/qt/python/mantidqt/utils/qt/test/application.py b/qt/python/mantidqt/utils/qt/test/application.py
new file mode 100644
index 0000000000000000000000000000000000000000..931ea74d5626b02856901f59dc6c627a3c433bc6
--- /dev/null
+++ b/qt/python/mantidqt/utils/qt/test/application.py
@@ -0,0 +1,30 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+# flake8: noqa
+from __future__ import absolute_import
+from qtpy.QtWidgets import QApplication
+
+from mantidqt.utils.qt.plugins import setup_library_paths
+
+# Hold on to QAPP reference to avoid garbage collection
+_QAPP = None
+
+
+def get_application(name=''):
+    """
+    Initialise and return the global application object
+    :param name: Optional application name
+    :return: Global appliction object
+    """
+    global _QAPP
+    if _QAPP is None:
+        setup_library_paths()
+        _QAPP = QApplication([name])
+    return _QAPP
diff --git a/qt/python/mantidqt/utils/qt/test/gui_test_runner.py b/qt/python/mantidqt/utils/qt/test/gui_test_runner.py
new file mode 100644
index 0000000000000000000000000000000000000000..47de8a408874ee40924a75c86c497df16358f101
--- /dev/null
+++ b/qt/python/mantidqt/utils/qt/test/gui_test_runner.py
@@ -0,0 +1,216 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import absolute_import, print_function
+
+import inspect
+import six
+import traceback
+
+from qtpy.QtCore import QTimer, QMetaObject, Qt
+from qtpy.QtWidgets import QWidget
+
+from mantidqt.utils.qt.test.application import get_application
+
+
+def split_qualified_name(qualified_name):
+    parts = qualified_name.split('.')
+    if len(parts) < 2:
+        raise RuntimeError('Qualified name must include name of the module in which it is defined,'
+                           ' found: {0}'.format(qualified_name))
+    module_name = '.'.join(parts[:-1])
+    name = parts[-1]
+    return module_name, name
+
+
+def create_widget(widget_path):
+    """
+    Imports a widget from a module in mantidqt
+    :param widget_path: A qualified name of a widget, ie mantidqt.mywidget.MyWidget
+    :return: The widget's class.
+    """
+    module_name, widget_name = split_qualified_name(widget_path)
+    m = __import__(module_name, fromlist=[widget_name])
+    widget_generator = getattr(m, widget_name)
+    return widget_generator()
+
+
+class ScriptRunner(object):
+    """
+    Runs a script that interacts with a widget (tests it).
+    If the script is a python generator then after each iteration controls returns
+    to the QApplication's event loop.
+    Generator scripts can yield a positive number. It is treated as the number of seconds
+    before the next iteration is called. During the wait time the event loop is running.
+    """
+    def __init__(self, script, widget=None, close_on_finish=True, pause=0, is_cli=False):
+        """
+        Initialise a runner.
+        :param script: The script to run.
+        :param widget: The widget to test.
+        :param close_on_finish: If true close the widget after the script has finished.
+        :param is_cli: If true the script is to be run from a command line tool. Exceptions are
+            treated slightly differently in this case.
+        """
+        app = get_application()
+        self.script = script
+        self.widget = widget
+        self.close_on_finish = close_on_finish
+        self.pause = pause
+        self.is_cli = is_cli
+        self.error = None
+        self.script_iter = [None]
+        self.pause_timer = QTimer(app)
+        self.pause_timer.setSingleShot(True)
+        self.script_timer = QTimer(app)
+
+    def run(self):
+        ret = run_script(self.script, self.widget)
+        if isinstance(ret, Exception):
+            raise ret
+        self.script_iter = [iter(ret) if inspect.isgenerator(ret) else None]
+        if self.pause != 0:
+            self.script_timer.setInterval(self.pause * 1000)
+        # Zero-timeout timer runs script_runner() between Qt events
+        self.script_timer.timeout.connect(self, Qt.QueuedConnection)
+        QMetaObject.invokeMethod(self.script_timer, 'start', Qt.QueuedConnection)
+
+    def __call__(self):
+        app = get_application()
+        if not self.pause_timer.isActive():
+            try:
+                script_iter = self.script_iter[-1]
+                if script_iter is None:
+                    if self.close_on_finish:
+                        app.closeAllWindows()
+                        app.exit()
+                    return
+                # Run test script until the next 'yield'
+                try:
+                    ret = next(script_iter)
+                except ValueError:
+                    return
+                while ret is not None:
+                    if inspect.isgenerator(ret):
+                        self.script_iter.append(ret)
+                        ret = None
+                    elif isinstance(ret, six.integer_types) or isinstance(ret, float):
+                        # Start non-blocking pause in seconds
+                        self.pause_timer.start(int(ret * 1000))
+                        ret = None
+                    else:
+                        ret = ret()
+            except StopIteration:
+                if len(self.script_iter) > 1:
+                    self.script_iter.pop()
+                else:
+                    self.script_iter = [None]
+                    self.script_timer.stop()
+                    if self.close_on_finish:
+                        app.closeAllWindows()
+                        app.exit(0)
+            except Exception as e:
+                self.script_iter = [None]
+                traceback.print_exc()
+                if self.close_on_finish:
+                    app.exit(1)
+                self.error = e
+
+
+def open_in_window(widget_or_name, script, attach_debugger=True, pause=0,
+                   close_on_finish=False, is_cli=False, in_workbench=False):
+
+    """
+    Displays a widget in a window.
+    :param widget_or_name: A widget to display.
+            1. If a string it's a qualified name of a widget, eg mantidqt.mywidget.MyWidget
+            2. If a callable it must take no arguments and return a QWidget
+            3. If a QWidget it's used directly.
+    :param script: A script to run after the widget is open.
+            1. If a string it's a qualified name of a test function that can be run after the
+            widget is created.
+            2. If a callable it's used directly.
+
+        The test function must have the signature:
+
+            def test(widget):
+                ...
+
+        where argument widget is an instance of the tested widget.
+        The test function can yield from time to time after which the widget can update itself.
+        This will make the test non-blocking and changes can be viewed as the script runs.
+        If the test yields an number it is interpreted as the number of seconds to wait
+        until the next step.
+        The test can yield a generator. In this case it will be iterated over until it stops
+        and the iterations of the main script continue.
+    :param attach_debugger: If true pause to let the user to attache a debugger before starting
+        application.
+    :param pause: A number of seconds to wait between the iterations.
+    :param close_on_finish: An option to close the widget after the script finishes.
+    :param is_cli: If true the script is to be run from a command line tool. Exceptions are
+        treated slightly differently in this case.
+    :param in_workbench: Set to True if the script will be run inside the workbench application.
+    """
+    if attach_debugger:
+        raw_input('Please attach the Debugger now if required. Press any key to continue')
+    app = get_application()
+    if widget_or_name is not None:
+        widget_name = 'Widget to test'
+        if isinstance(widget_or_name, six.string_types):
+            widget = create_widget(widget_or_name)
+            widget_name = widget_or_name
+        elif isinstance(widget_or_name, QWidget):
+            widget = widget_or_name
+        else:
+            widget = widget_or_name()
+        if hasattr(widget, 'setWindowTitle'):
+            widget.setWindowTitle(widget_name)
+        if widget is not None:
+            widget.show()
+    else:
+        widget = None
+
+    script_runner = None
+    if script is not None:
+        try:
+            script_runner = ScriptRunner(script, widget, close_on_finish=close_on_finish, is_cli=is_cli, pause=pause)
+            script_runner.run()
+        except Exception as e:
+            if not is_cli:
+                raise e
+
+    if not in_workbench:
+        ret = app.exec_()
+        if not is_cli and script_runner is not None and script_runner.error is not None:
+            raise script_runner.error
+    else:
+        ret = 0
+    return ret
+
+
+def run_script(script_or_name, widget):
+    """
+    Run a script passing the widget as an argument.
+    :param script_or_name: A callable, class or a name.
+    :param widget: A widget to interact with.
+    :return: Output of the script or an Exception object.
+    """
+    if isinstance(script_or_name, six.string_types):
+        module_name, fun_name = split_qualified_name(script_or_name)
+        m = __import__(module_name, fromlist=[fun_name])
+        fun = getattr(m, fun_name)
+    else:
+        fun = script_or_name
+    try:
+        if inspect.isclass(fun):
+            fun = fun()
+        return fun(widget)
+    except Exception as e:
+        traceback.print_exc()
+        return e
diff --git a/qt/python/mantidqt/utils/qt/test/gui_window_test.py b/qt/python/mantidqt/utils/qt/test/gui_window_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..613da5434c4b187d7e070d7c82233033c2bf87e9
--- /dev/null
+++ b/qt/python/mantidqt/utils/qt/test/gui_window_test.py
@@ -0,0 +1,180 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import print_function
+import inspect
+from unittest import TestCase
+
+from mantidqt.utils.qt.test.gui_test_runner import open_in_window
+from qtpy.QtWidgets import QPushButton, QMenu, QAction, QApplication
+from qtpy.QtCore import Qt, QMetaObject, QTime
+from qtpy.QtTest import QTest
+
+
+def trigger_action(action):
+    QMetaObject.invokeMethod(action, 'trigger', Qt.QueuedConnection)
+
+
+def find_action_with_text(widget, text):
+    for action in widget.findChildren(QAction):
+        if action.text() == text:
+            return action
+    raise RuntimeError("Couldn't find action with text \"{}\"".format(text))
+
+
+def drag_mouse(widget, from_pos, to_pos):
+    QTest.mousePress(widget, Qt.LeftButton, Qt.NoModifier, from_pos)
+    yield
+    QTest.mouseMove(widget, from_pos)
+    yield 0.1
+    QTest.mouseMove(widget, to_pos)
+    yield 0.1
+    QTest.mouseRelease(widget, Qt.LeftButton, Qt.NoModifier, to_pos)
+    yield 0.1
+
+
+class GuiTestBase(object):
+
+    def _call_test_method(self, w):
+        self.widget = w
+        if hasattr(self, self.call_method):
+            return getattr(self, self.call_method)()
+        if self.call_method != 'call':
+            raise RuntimeError("Test class has no method {}".format(self.call_method))
+
+    def wait_for(self, var_name):
+        var = getattr(self, var_name)
+        while var is None:
+            yield
+            var = getattr(self, var_name)
+
+    def wait_for_true(self, fun, timeout_sec=1.0):
+        t = QTime()
+        t.start()
+        timeout_millisec = int(timeout_sec * 1000)
+        while not fun():
+            if t.elapsed() > timeout_millisec:
+                raise StopIteration()
+            yield
+
+    def wait_for_modal(self):
+        return self.wait_for_true(self.get_active_modal_widget)
+
+    def wait_for_popup(self):
+        return self.wait_for_true(self.get_active_popup_widget)
+
+    def run_test(self, method='call', pause=0, close_on_finish=True, attach_debugger=False):
+        self.call_method = method
+        open_in_window(self.create_widget, self._call_test_method, attach_debugger=attach_debugger, pause=pause,
+                       close_on_finish=close_on_finish)
+
+    def get_child(self, child_class, name):
+        children = self.widget.findChildren(child_class, name)
+        if len(children) == 0:
+            raise RuntimeError("Widget doesn't have children of type {0} with name {1}.".format(child_class.__name__,
+                                                                                                name))
+        return children[0]
+
+    @staticmethod
+    def get_active_modal_widget():
+        return QApplication.activeModalWidget()
+
+    @staticmethod
+    def get_active_popup_widget():
+        return QApplication.activePopupWidget()
+
+    def get_menu(self, name):
+        return self.get_child(QMenu, name)
+
+    def get_action(self, name, get_menu=False):
+        action = self.get_child(QAction, name)
+        if not get_menu:
+            return action
+        menus = action.associatedWidgets()
+        if len(menus) == 0:
+            raise RuntimeError("QAction {} isn't associated with any menu".format(name))
+        return action, menus[0]
+
+    def trigger_action(self, name):
+        action, menu = self.get_action(name, get_menu=True)
+        if not menu.isVisible():
+            raise RuntimeError("Action {} isn't visible.".format(name))
+        QMetaObject.invokeMethod(action, 'trigger', Qt.QueuedConnection)
+        menu.close()
+
+    def hover_action(self, name):
+        action, menu = self.get_action(name, get_menu=True)
+        if not menu.isVisible():
+            raise RuntimeError("Action {} isn't visible.".format(name))
+        QMetaObject.invokeMethod(action, 'hover', Qt.QueuedConnection)
+
+    def get_button(self, name):
+        return self.get_child(QPushButton, name)
+
+    def click_button(self, name):
+        button = self.get_button(name)
+        QMetaObject.invokeMethod(button, 'click', Qt.QueuedConnection)
+
+
+def is_test_method(value):
+    if not (inspect.ismethod(value) or inspect.isfunction(value)):
+        return False
+    return value.__name__.startswith('test_')
+
+
+class GuiWindowTest(TestCase, GuiTestBase):
+
+    @classmethod
+    def make_test_wrapper(cls, wrapped_name):
+        def wrapper(self):
+            self.run_test(method=wrapped_name)
+        return wrapper
+
+    @classmethod
+    def setUpClass(cls):
+        cls.test_methods = []
+        cls.widget = None
+        for test in inspect.getmembers(cls, is_test_method):
+            name = test[0]
+            wrapped_name = '_' + name
+            setattr(cls, wrapped_name, test[1])
+            setattr(cls, name, cls.make_test_wrapper(wrapped_name))
+
+
+class MultiTestRunner(object):
+
+    def __init__(self, methods):
+        self.methods = methods
+
+    def __call__(self, w):
+        for method in self.methods:
+            yield method
+
+
+class WorkbenchGuiTest(GuiWindowTest):
+
+    @classmethod
+    def make_test_wrapper(cls, wrapped_name):
+        def wrapper(self):
+            if len(self.test_methods) == 0:
+                self.widget = self.create_widget()
+            self.test_methods.append(getattr(self, wrapped_name))
+        return wrapper
+
+    @classmethod
+    def tearDownClass(cls):
+        runner = MultiTestRunner(cls.test_methods)
+        open_in_window(cls.widget, runner, close_on_finish=True, attach_debugger=False, in_workbench=True)
+
+    def create_widget(self):
+        qapp = QApplication.instance()
+        for w in qapp.allWidgets():
+            if w.objectName() == "Mantid Workbench":
+                return w
+        return qapp.activeWindow()
diff --git a/qt/python/mantidqt/utils/qt/test/modal_tester.py b/qt/python/mantidqt/utils/qt/test/modal_tester.py
index bb54fd235afb776daafe7fb0a49eec05e89b92a7..ba6412453b9cb947fa244814789bb6f72bbc7963 100644
--- a/qt/python/mantidqt/utils/qt/test/modal_tester.py
+++ b/qt/python/mantidqt/utils/qt/test/modal_tester.py
@@ -67,7 +67,10 @@ class ModalTester(object):
             traceback.print_exc()
             self._qapp.exit(0)
         if self.widget is not None:
-            self.widget.exec_()
+            if hasattr(self.widget, 'exec_'):
+                self.widget.exec_()
+            else:
+                self.widget.show()
 
     def _idle(self):
         """
diff --git a/qt/python/mantidqt/utils/qt/test/run_test_app.py b/qt/python/mantidqt/utils/qt/test/run_test_app.py
index 33c18c121c8d0cb7b20edf899871f8da8673314a..b42f3f2e5d1af509c16c660cc0705ee807011fb2 100644
--- a/qt/python/mantidqt/utils/qt/test/run_test_app.py
+++ b/qt/python/mantidqt/utils/qt/test/run_test_app.py
@@ -24,111 +24,16 @@ Optional --script argument expects a name of a function which takes a widget as
 If specified the script is imported and run after the widget is created.
 
 """
-from __future__ import absolute_import, print_function
-
+import argparse
 import sys
-import traceback
-
-from qtpy.QtCore import QTimer
-from qtpy.QtWidgets import QApplication
-
-from mantidqt.utils.qt.plugins import setup_library_paths
-
-
-def split_qualified_name(qualified_name):
-    parts = qualified_name.split('.')
-    if len(parts) < 2:
-        raise RuntimeError('Qualified name must include name of the module in which it is defined,'
-                           ' found: {0}'.format(qualified_name))
-    module_name = '.'.join(parts[:-1])
-    name = parts[-1]
-    return module_name, name
-
-
-def create_widget(widget_path):
-    """
-    Imports a widget from a module in mantidqt
-    :param widget_path: A qualified name of a widget, ie mantidqt.mywidget.MyWidget
-    :return: The widget's class.
-    """
-    module_name, widget_name = split_qualified_name(widget_path)
-    m = __import__(module_name, fromlist=[widget_name])
-    widget_generator = getattr(m, widget_name)
-    return widget_generator()
-
-
-def open_in_window(widget_name, script):
-    """
-    Displays a widget in a window.
-    :param widget_name:  A qualified name of a widget, ie mantidqt.mywidget.MyWidget
-    :param script: A qualified name of a test function that can be run after the
-        widget is created. The test function must have the signature:
-
-            def test(widget):
-                ...
-
-        where argument widget is an instance of the tested widget.
-        The test function can yield from time to time after which the widget can update itself.
-        This will make the test non-blocking and changes can be viewed as the script runs.
-        If the test yields an integer it is interpreted as the number of seconds to wait
-        until the next step.
-    """
-    raw_input('Please attach the Debugger now if required. Press any key to continue')
-    setup_library_paths()
-    app = QApplication([""])
-    w = create_widget(widget_name)
-    w.setWindowTitle(widget_name)
-    w.show()
-
-    if script is not None:
-        try:
-            # If script is a generator script_iter allows non-blocking
-            # test execution
-            script_iter = iter(run_script(script, w))
-            pause_timer = QTimer()
-            pause_timer.setSingleShot(True)
-
-            def idle():
-                if not pause_timer.isActive():
-                    try:
-                        # Run test script until the next 'yield'
-                        pause_sec = script_iter.next()
-                        if pause_sec is not None:
-                            # Start non-blocking pause in seconds
-                            pause_timer.start(int(pause_sec * 1000))
-                    except StopIteration:
-                        pass
-                    except:
-                        traceback.print_exc()
-            timer = QTimer()
-            # Zero-timeout timer runs idle() between Qt events
-            timer.timeout.connect(idle)
-            timer.start()
-        except:
-            pass
-
-    sys.exit(app.exec_())
-
-
-def run_script(script_name, widget):
-    module_name, fun_name = split_qualified_name(script_name)
-    m = __import__(module_name, fromlist=[fun_name])
-    fun = getattr(m, fun_name)
-    try:
-        return fun(widget)
-    except:
-        traceback.print_exc()
-
-
-if __name__ == "__main__":
-    import argparse
-
-    parser = argparse.ArgumentParser()
-    parser.add_argument("widget", help="A qualified name of a widget to open for testing. The name must contain the "
-                                       "python module where the widget is defined, eg mypackage.mymodule.MyWidget")
-    parser.add_argument("--script", help="A qualified name of a python function to run to test the widget."
-                                         " The function must take a single argument - the widget."
-                                         " The name must contain the python module where the function is defined,"
-                                         " eg somepackage.somemodule.test_my_widget")
-    args = parser.parse_args()
-    open_in_window(args.widget, args.script)
+from gui_test_runner import open_in_window
+
+parser = argparse.ArgumentParser()
+parser.add_argument("widget", help="A qualified name of a widget to open for testing. The name must contain the "
+                                   "python module where the widget is defined, eg mypackage.mymodule.MyWidget")
+parser.add_argument("--script", help="A qualified name of a python function to run to test the widget."
+                                     " The function must take a single argument - the widget."
+                                     " The name must contain the python module where the function is defined,"
+                                     " eg somepackage.somemodule.test_my_widget")
+args = parser.parse_args()
+sys.exit(open_in_window(args.widget, args.script, is_cli=True))
diff --git a/scripts/wish/__init__.py b/qt/python/mantidqt/widgets/common/__init__.py
similarity index 100%
rename from scripts/wish/__init__.py
rename to qt/python/mantidqt/widgets/common/__init__.py
diff --git a/qt/python/mantidqt/widgets/common/table_copying.py b/qt/python/mantidqt/widgets/common/table_copying.py
new file mode 100644
index 0000000000000000000000000000000000000000..8eb2f0587e6f3584749672ed736b87b910da8a38
--- /dev/null
+++ b/qt/python/mantidqt/widgets/common/table_copying.py
@@ -0,0 +1,156 @@
+from __future__ import (absolute_import, division, print_function)
+
+from qtpy import QtGui
+from qtpy.QtCore import QPoint
+from qtpy.QtGui import QCursor, QFont, QFontMetrics
+from qtpy.QtWidgets import (QMessageBox, QToolTip)
+
+NO_SELECTION_MESSAGE = "No selection"
+COPY_SUCCESSFUL_MESSAGE = "Copy Successful"
+
+"""
+This module contains the common copying functionality between
+the MatrixWorkspaceDisplay and the TableWorkspaceDisplay.
+"""
+
+
+def copy_spectrum_values(table, ws_read):
+    """
+    Copies the values selected by the user to the system's clipboard
+
+    :param table: Table from which the selection will be read
+    :param ws_read: The workspace read function, that is used to access the data directly
+    """
+    selection_model = table.selectionModel()
+    if not selection_model.hasSelection():
+        show_no_selection_to_copy_toast()
+        return
+    selected_rows = selection_model.selectedRows()  # type: list
+    row_data = []
+
+    for index in selected_rows:
+        row = index.row()
+        data = "\t".join(map(str, ws_read(row)))
+
+        row_data.append(data)
+
+    copy_to_clipboard("\n".join(row_data))
+    show_successful_copy_toast()
+
+
+def copy_bin_values(table, ws_read, num_rows):
+    """
+    Copies the values selected by the user to the system's clipboard
+
+    :param table: Table from which the selection will be read
+    :param ws_read: The workspace read function, that is used to access the data directly
+    :param num_rows: The number of rows in the column
+    """
+    selection_model = table.selectionModel()
+    if not selection_model.hasSelection():
+        show_no_selection_to_copy_toast()
+        return
+    selected_columns = selection_model.selectedColumns()  # type: list
+
+    # Qt gives back a QModelIndex, we need to extract the column from it
+    column_data = []
+    for index in selected_columns:
+        column = index.column()
+        data = [str(ws_read(row)[column]) for row in range(num_rows)]
+        column_data.append(data)
+
+    all_string_rows = []
+    for i in range(num_rows):
+        # Appends ONE value from each COLUMN, this is because the final string is being built vertically
+        # the noqa disables a 'data' variable redefined warning
+        all_string_rows.append("\t".join([data[i] for data in column_data]))  # noqa: F812
+
+    # Finally all rows are joined together with a new line at the end of each row
+    final_string = "\n".join(all_string_rows)
+    copy_to_clipboard(final_string)
+    show_successful_copy_toast()
+
+
+def copy_cells(table):
+    """
+    :type table: QTableView
+    :param table: The table from which the data will be copied.
+    :return:
+    """
+    selectionModel = table.selectionModel()
+    if not selectionModel.hasSelection():
+        show_no_selection_to_copy_toast()
+        return
+
+    selection = selectionModel.selection()
+    selectionRange = selection.first()
+
+    top = selectionRange.top()
+    bottom = selectionRange.bottom()
+    left = selectionRange.left()
+    right = selectionRange.right()
+
+    data = []
+    index = selectionModel.currentIndex()
+    for i in range(top, bottom + 1):
+        for j in range(left, right):
+            data.append(str(index.sibling(i, j).data()))
+            data.append("\t")
+        data.append(str(index.sibling(i, right).data()))
+        data.append("\n")
+
+    # strip the string to remove the trailing new line
+    copy_to_clipboard("".join(data).strip())
+    show_successful_copy_toast()
+
+
+def keypress_copy(table, view, ws_read, num_rows):
+    selectionModel = table.selectionModel()
+    if not selectionModel.hasSelection():
+        show_no_selection_to_copy_toast()
+        return
+
+    if len(selectionModel.selectedRows()) > 0:
+        copy_spectrum_values(table, ws_read)
+    elif len(selectionModel.selectedColumns()) > 0:
+        copy_bin_values(table, ws_read, num_rows)
+    else:
+        copy_cells(table)
+
+
+def show_mouse_toast(message):
+    # Creates a text with empty space to get the height of the rendered text - this is used
+    # to provide the same offset for the tooltip, scaled relative to the current resolution and zoom.
+    font_metrics = QFontMetrics(QFont(" "))
+    # The height itself is divided by 2 just to reduce the offset so that the tooltip is
+    # reasonably position relative to the cursor
+    QToolTip.showText(QCursor.pos() + QPoint(font_metrics.height() / 2, 0), message)
+
+
+def copy_to_clipboard(data):
+    """
+    Uses the QGuiApplication to copy to the system clipboard.
+
+    :type data: str
+    :param data: The data that will be copied to the clipboard
+    :return:
+    """
+    cb = QtGui.QGuiApplication.clipboard()
+    cb.setText(data, mode=cb.Clipboard)
+
+
+def ask_confirmation(self, message, title="Mantid Workbench"):
+    """
+    :param message:
+    :return:
+    """
+    reply = QMessageBox.question(self, title, message, QMessageBox.Yes, QMessageBox.No)
+    return True if reply == QMessageBox.Yes else False
+
+
+def show_no_selection_to_copy_toast():
+    show_mouse_toast(NO_SELECTION_MESSAGE)
+
+
+def show_successful_copy_toast():
+    show_mouse_toast(COPY_SUCCESSFUL_MESSAGE)
diff --git a/qt/python/mantidqt/widgets/fitpropertybrowser.py b/qt/python/mantidqt/widgets/fitpropertybrowser.py
new file mode 100644
index 0000000000000000000000000000000000000000..3b46e47ca04e8665618c658e15461950d38e76d9
--- /dev/null
+++ b/qt/python/mantidqt/widgets/fitpropertybrowser.py
@@ -0,0 +1,224 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantidqt package
+#
+#
+from __future__ import (print_function, absolute_import, unicode_literals)
+
+import re
+import numpy as np
+
+from matplotlib.path import Path
+from matplotlib.patches import PathPatch
+from qtpy.QtCore import QObject, Signal, Qt
+from qtpy.QtGui import QCursor
+from qtpy.QtWidgets import QApplication
+
+from mantid.simpleapi import mtd
+from mantidqt.utils.qt import import_qt
+
+
+BaseBrowser = import_qt('.._common', 'mantidqt.widgets', 'FitPropertyBrowser')
+
+
+class FitPropertyBrowserBase(BaseBrowser):
+
+    def __init__(self, parent=None):
+        super(FitPropertyBrowserBase, self).__init__(parent)
+        self.init()
+
+
+class FitPropertyBrowser(FitPropertyBrowserBase):
+
+    closing = Signal()
+
+    def __init__(self, canvas, parent=None):
+        super(FitPropertyBrowser, self).__init__(parent)
+        self.init()
+        self.canvas = canvas
+        self.tool = None
+        self.fit_result_lines = []
+        self.startXChanged.connect(self.move_start_x)
+        self.endXChanged.connect(self.move_end_x)
+        self.fittingDone.connect(self.fitting_done)
+
+    def closeEvent(self, event):
+        self.closing.emit()
+        BaseBrowser.closeEvent(self, event)
+
+    def show(self):
+        allowed_spectra = {}
+        pattern = re.compile('(.+?): spec (\d+)')
+        for label in [lin.get_label() for lin in self.get_lines()]:
+            a_match = re.match(pattern, label)
+            name, spec = a_match.group(1), int(a_match.group(2))
+            spec_list = allowed_spectra.get(name, [])
+            spec_list.append(spec)
+            allowed_spectra[name] = spec_list
+        for name, spec_list in allowed_spectra.items():
+            self.addAllowedSpectra(name, spec_list)
+        self.tool = FitInteractiveTool(self.canvas)
+        self.tool.fit_start_x_moved.connect(self.setStartX)
+        self.tool.fit_end_x_moved.connect(self.setEndX)
+        self.setXRange(self.tool.fit_start_x.x, self.tool.fit_end_x.x)
+        super(FitPropertyBrowser, self).show()
+
+    def hide(self):
+        if self.tool is not None:
+            self.tool.fit_start_x_moved.disconnect()
+            self.tool.fit_end_x_moved.disconnect()
+            self.tool.disconnect()
+        super(FitPropertyBrowser, self).hide()
+
+    def move_start_x(self, xd):
+        if self.tool is not None:
+            self.tool.move_start_x(xd)
+
+    def move_end_x(self, xd):
+        if self.tool is not None:
+            self.tool.move_end_x(xd)
+
+    def clear_fit_result_lines(self):
+        for lin in self.fit_result_lines:
+            lin.remove()
+        self.fit_result_lines = []
+
+    def get_lines(self):
+        return self.canvas.figure.get_axes()[0].get_lines()
+
+    def fitting_done(self, name):
+        from workbench.plotting.functions import plot
+        name += '_Workspace'
+        ws = mtd[name]
+        self.clear_fit_result_lines()
+        plot([ws], wksp_indices=[1, 2], fig=self.canvas.figure, overplot=True)
+        name += ':'
+        for lin in self.get_lines():
+            if lin.get_label().startswith(name):
+                self.fit_result_lines.append(lin)
+
+
+class VerticalMarker(QObject):
+
+    moved = Signal(float)
+
+    def __init__(self, canvas, x, color):
+        super(VerticalMarker, self).__init__()
+        self.x = x
+        self.ax = canvas.figure.get_axes()[0]
+        y0, y1 = self.ax.get_ylim()
+        path = Path([(x, y0), (x, y1)], [Path.MOVETO, Path.LINETO])
+        self.patch = PathPatch(path, facecolor='None', edgecolor=color, picker=5, linewidth=2.0, animated=True)
+        self.ax.add_patch(self.patch)
+        self.is_moving = False
+
+    def remove(self):
+        self.patch.remove()
+
+    def redraw(self):
+        y0, y1 = self.ax.get_ylim()
+        vertices = self.patch.get_path().vertices
+        vertices[0] = self.x, y0
+        vertices[1] = self.x, y1
+        self.ax.draw_artist(self.patch)
+
+    def get_x_in_pixels(self):
+        x_pixels, _ = self.patch.get_transform().transform((self.x, 0))
+        return x_pixels
+
+    def is_above(self, x):
+        return np.abs(self.get_x_in_pixels() - x) < 3
+
+    def on_click(self, x):
+        if self.is_above(x):
+            self.is_moving = True
+
+    def stop(self):
+        self.is_moving = False
+
+    def mouse_move(self, xd):
+        if self.is_moving and xd is not None:
+            self.x = xd
+            self.moved.emit(xd)
+
+    def should_override_cursor(self, x):
+        return self.is_moving or self.is_above(x)
+
+
+class FitInteractiveTool(QObject):
+
+    fit_start_x_moved = Signal(float)
+    fit_end_x_moved = Signal(float)
+
+    def __init__(self, canvas):
+        super(FitInteractiveTool, self).__init__()
+        self.canvas = canvas
+        ax = canvas.figure.get_axes()[0]
+        self.ax = ax
+        xlim = ax.get_xlim()
+        dx = (xlim[1] - xlim[0]) / 20.
+        start_x = xlim[0] + dx
+        end_x = xlim[1] - dx
+        self.fit_start_x = VerticalMarker(canvas, start_x, 'green')
+        self.fit_end_x = VerticalMarker(canvas, end_x, 'green')
+
+        self.fit_start_x.moved.connect(self.fit_start_x_moved)
+        self.fit_end_x.moved.connect(self.fit_end_x_moved)
+
+        self._cids = []
+        self._cids.append(canvas.mpl_connect('draw_event', self.draw_callback))
+        self._cids.append(canvas.mpl_connect('motion_notify_event', self.motion_notify_callback))
+        self._cids.append(canvas.mpl_connect('button_press_event', self.on_click))
+        self._cids.append(canvas.mpl_connect('button_release_event', self.on_release))
+
+        self.is_cursor_overridden = False
+
+    def disconnect(self):
+        for cid in self._cids:
+            self.canvas.mpl_disconnect(cid)
+        self.fit_start_x.remove()
+        self.fit_end_x.remove()
+
+    def draw_callback(self, event):
+        if self.fit_start_x.x > self.fit_end_x.x:
+            x = self.fit_start_x.x
+            self.fit_start_x.x = self.fit_end_x.x
+            self.fit_end_x.x = x
+        self.fit_start_x.redraw()
+        self.fit_end_x.redraw()
+
+    def motion_notify_callback(self, event):
+        x = event.x
+        if x is not None and (self.fit_start_x.should_override_cursor(x) or self.fit_end_x.should_override_cursor(x)):
+            if not self.is_cursor_overridden:
+                QApplication.setOverrideCursor(QCursor(Qt.SizeHorCursor))
+            self.is_cursor_overridden = True
+        else:
+            QApplication.restoreOverrideCursor()
+            self.is_cursor_overridden = False
+        self.fit_start_x.mouse_move(event.xdata)
+        self.fit_end_x.mouse_move(event.xdata)
+        self.canvas.draw()
+
+    def on_click(self, event):
+        if event.button == 1:
+            self.fit_start_x.on_click(event.x)
+            self.fit_end_x.on_click(event.x)
+
+    def on_release(self, event):
+        self.fit_start_x.stop()
+        self.fit_end_x.stop()
+
+    def move_start_x(self, xd):
+        if xd is not None:
+            self.fit_start_x.x = xd
+            self.canvas.draw()
+
+    def move_end_x(self, xd):
+        if xd is not None:
+            self.fit_end_x.x = xd
+            self.canvas.draw()
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py
index 817bad4e1e02c0ded4925f25bccf0f2e2d43f74c..8afc6d1b6af9499691bba176ff693985619ff779 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/model.py
@@ -14,26 +14,37 @@ from mantid.api import MatrixWorkspace
 from mantid.dataobjects import EventWorkspace, Workspace2D
 from mantidqt.widgets.matrixworkspacedisplay.table_view_model import MatrixWorkspaceTableViewModel, \
     MatrixWorkspaceTableViewModelType
-from mantidqt.widgets.matrixworkspacedisplay.test_helpers.matrixworkspacedisplay_common import MockWorkspace
 
 
 class MatrixWorkspaceDisplayModel(object):
     SPECTRUM_PLOT_LEGEND_STRING = '{}-{}'
     BIN_PLOT_LEGEND_STRING = '{}-bin-{}'
 
-    def __init__(self, ws):
-        if not isinstance(ws, MatrixWorkspace) \
-                and not isinstance(ws, Workspace2D) \
-                and not isinstance(ws, EventWorkspace) \
-                and not isinstance(ws, MockWorkspace):
-            raise ValueError("The workspace type is not supported: {0}".format(type(ws)))
+    ALLOWED_WORKSPACE_TYPES = [MatrixWorkspace, Workspace2D, EventWorkspace]
+
+    @classmethod
+    def supports(cls, ws):
+        """
+        Checks that the provided workspace is supported by this display.
+        :param ws: Workspace to be checked for support
+        :raises ValueError: if the workspace is not supported
+        """
+        if not any(isinstance(ws, allowed_type) for allowed_type in cls.ALLOWED_WORKSPACE_TYPES):
+            raise ValueError("The workspace type is not supported: {0}".format(ws))
 
+    def __init__(self, ws):
+        """
+        Initialise the model with the workspace
+        :param ws: Workspace to be used for providing data
+        :raises ValueError: if the workspace is not supported
+        """
+        self.supports(ws)
         self._ws = ws
 
     def get_name(self):
         return self._ws.name()
 
     def get_item_model(self):
-        return MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.x), \
-               MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.y), \
-               MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.e)
+        return (MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.x),
+                MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.y),
+                MatrixWorkspaceTableViewModel(self._ws, MatrixWorkspaceTableViewModelType.e))
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py
index 7e6457a13f2cd146edb53bddece003bcde5a3210..e01fb1768b4761af792617dc9daa73c9b438ffd5 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/presenter.py
@@ -10,6 +10,8 @@
 from __future__ import absolute_import, division, print_function
 
 from mantid.plots.utility import MantidAxType
+from mantidqt.widgets.common.table_copying import copy_bin_values, copy_cells, copy_spectrum_values, \
+    show_no_selection_to_copy_toast
 from mantidqt.widgets.matrixworkspacedisplay.table_view_model import MatrixWorkspaceTableViewModelType
 from .model import MatrixWorkspaceDisplayModel
 from .view import MatrixWorkspaceDisplayView
@@ -22,6 +24,15 @@ class MatrixWorkspaceDisplay(object):
     NUM_SELECTED_FOR_CONFIRMATION = 10
 
     def __init__(self, ws, plot=None, parent=None, model=None, view=None):
+        """
+        Creates a display for the provided workspace.
+
+        :param ws: Workspace to be displayed
+        :param plot: Plotting function that will be used to plot workspaces. Passed in as parameter to allow mocking
+        :param parent: Parent of the widget
+        :param model: Model to be used by the widget. Passed in as parameter to allow mocking
+        :param view: View to be used by the widget. Passed in as parameter to allow mocking
+        """
         # Create model and view, or accept mocked versions
         self.model = model if model else MatrixWorkspaceDisplayModel(ws)
         self.view = view if view else MatrixWorkspaceDisplayView(self,
@@ -35,105 +46,37 @@ class MatrixWorkspaceDisplay(object):
         self.view.set_context_menu_actions(self.view.table_x)
         self.view.set_context_menu_actions(self.view.table_e)
 
+    @classmethod
+    def supports(cls, ws):
+        """
+        Checks that the provided workspace is supported by this display.
+        :param ws: Workspace to be checked for support
+        :raises ValueError: if the workspace is not supported
+        """
+        return MatrixWorkspaceDisplayModel.supports(ws)
+
     def setup_tables(self):
         # unpacks the list of models returned from getItemModel
         self.view.set_model(*self.model.get_item_model())
 
     def action_copy_spectrum_values(self, table):
-        """
-        Copies the values selected by the user to the system's clipboard
-
-        :param table: Table from which the selection will be read
-        :param ws_read: The workspace read function, that is used to access the data directly
-        """
-        selection_model = table.selectionModel()
-        if not selection_model.hasSelection():
-            self.show_no_selection_to_copy_toast()
-            return
         ws_read = self._get_ws_read_from_type(table.model().type)
-        selected_rows = selection_model.selectedRows()  # type: list
-        row_data = []
-
-        for index in selected_rows:
-            row = index.row()
-            data = "\t".join(map(str, ws_read(row)))
-
-            row_data.append(data)
-
-        self.view.copy_to_clipboard("\n".join(row_data))
-        self.show_successful_copy_toast()
-
-    def show_no_selection_to_copy_toast(self):
-        self.view.show_mouse_toast(self.NO_SELECTION_MESSAGE)
-
-    def show_successful_copy_toast(self):
-        self.view.show_mouse_toast(self.COPY_SUCCESSFUL_MESSAGE)
+        copy_spectrum_values(table, ws_read)
 
     def action_copy_bin_values(self, table):
-        selection_model = table.selectionModel()
-        if not selection_model.hasSelection():
-            self.show_no_selection_to_copy_toast()
-            return
         ws_read = self._get_ws_read_from_type(table.model().type)
-        selected_columns = selection_model.selectedColumns()  # type: list
-
-        # Qt gives back a QModelIndex, we need to extract the column from it
         num_rows = self.model._ws.getNumberHistograms()
-        column_data = []
-        for index in selected_columns:
-            column = index.column()
-            data = [str(ws_read(row)[column]) for row in range(num_rows)]
-            column_data.append(data)
-
-        all_string_rows = []
-        for i in range(num_rows):
-            # Appends ONE value from each COLUMN, this is because the final string is being built vertically
-            # the noqa disables a 'data' variable redefined warning
-            all_string_rows.append("\t".join([data[i] for data in column_data]))  # noqa: F812
-
-        # Finally all rows are joined together with a new line at the end of each row
-        final_string = "\n".join(all_string_rows)
-        self.view.copy_to_clipboard(final_string)
-        self.show_successful_copy_toast()
+        copy_bin_values(table, ws_read, num_rows)
 
     def action_copy_cells(self, table):
-        """
-        :type table: QTableView
-        :param table: The table from which the data will be copied.
-        :return:
-        """
-        selectionModel = table.selectionModel()
-        if not selectionModel.hasSelection():
-            self.show_no_selection_to_copy_toast()
-            return
-
-        selection = selectionModel.selection()
-        selectionRange = selection.first()
-
-        top = selectionRange.top()
-        bottom = selectionRange.bottom()
-        left = selectionRange.left()
-        right = selectionRange.right()
-
-        data = []
-        index = selectionModel.currentIndex()
-        for i in range(top, bottom + 1):
-            for j in range(left, right):
-                data.append(index.sibling(i, j).data())
-                data.append("\t")
-            data.append(index.sibling(i, right).data())
-            data.append("\n")
-
-        # strip the string to remove the trailing new line
-        self.view.copy_to_clipboard("".join(data).strip())
-        self.show_successful_copy_toast()
+        copy_cells(table)
 
     def _do_action_plot(self, table, axis, get_index, plot_errors=False):
         if self.plot is None:
             raise ValueError("Trying to do a plot, but no plotting class dependency was injected in the constructor")
         selection_model = table.selectionModel()
         if not selection_model.hasSelection():
-            self.show_no_selection_to_copy_toast()
+            show_no_selection_to_copy_toast()
             return
 
         if axis == MantidAxType.SPECTRUM:
@@ -167,7 +110,7 @@ class MatrixWorkspaceDisplay(object):
     def action_keypress_copy(self, table):
         selectionModel = table.selectionModel()
         if not selectionModel.hasSelection():
-            self.show_no_selection_to_copy_toast()
+            show_no_selection_to_copy_toast()
             return
 
         if len(selectionModel.selectedRows()) > 0:
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_model.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_model.py
index 19e65995a268bea8f04e3de86229966be4fc3fbb..20b841487d4476a8742db2a3e85cfe8f14cd55c1 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_model.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_model.py
@@ -21,6 +21,10 @@ from mantidqt.widgets.matrixworkspacedisplay.test_helpers.matrixworkspacedisplay
 
 
 class MatrixWorkspaceDisplayModelTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # Allow the MockWorkspace to work within the model
+        MatrixWorkspaceDisplayModel.ALLOWED_WORKSPACE_TYPES.append(MockWorkspace)
 
     def test_get_name(self):
         ws = MockWorkspace()
@@ -43,9 +47,6 @@ class MatrixWorkspaceDisplayModelTest(unittest.TestCase):
         self.assertEqual(e_model.type, MatrixWorkspaceTableViewModelType.e)
 
     def test_raises_with_unsupported_workspace(self):
-        # ws = MockWorkspace()
-        # expected_name = "TEST_WORKSPACE"
-        # ws.name = Mock(return_value=expected_name)
         self.assertRaises(ValueError, lambda: MatrixWorkspaceDisplayModel([]))
         self.assertRaises(ValueError, lambda: MatrixWorkspaceDisplayModel(1))
         self.assertRaises(ValueError, lambda: MatrixWorkspaceDisplayModel("test_string"))
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_presenter.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_presenter.py
index 13f41b61be779632fa8d7fb46420a7f146982023..378dc5956c3868ef52eb8320a9c55b956d8ff7b2 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_presenter.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test/test_matrixworkspacedisplay_presenter.py
@@ -11,8 +11,9 @@ from __future__ import (absolute_import, division, print_function)
 
 import unittest
 
-from mock import Mock
+from mock import Mock, patch
 
+from mantidqt.widgets.matrixworkspacedisplay.model import MatrixWorkspaceDisplayModel
 from mantidqt.widgets.matrixworkspacedisplay.presenter import MatrixWorkspaceDisplay
 from mantidqt.widgets.matrixworkspacedisplay.test_helpers.matrixworkspacedisplay_common import MockQModelIndex, \
     MockWorkspace
@@ -21,6 +22,11 @@ from mantidqt.widgets.matrixworkspacedisplay.test_helpers.mock_matrixworkspacedi
 
 
 class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # Allow the MockWorkspace to work within the model
+        MatrixWorkspaceDisplayModel.ALLOWED_WORKSPACE_TYPES.append(MockWorkspace)
+
     def assertNotCalled(self, mock):
         self.assertEqual(0, mock.call_count)
 
@@ -31,7 +37,9 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         self.assertEqual(3, view.set_context_menu_actions.call_count)
         self.assertEqual(1, view.set_model.call_count)
 
-    def test_action_copy_spectrum_values(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_spectrum_values(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -50,10 +58,12 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
 
         mock_table.selectionModel.assert_called_once_with()
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
-        view.copy_to_clipboard.assert_called_once_with(expected_string)
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
+        mock_copy.assert_called_once_with(expected_string)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
 
-    def test_action_copy_spectrum_values_no_selection(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_spectrum_values_no_selection(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -68,9 +78,12 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
         # the action should never look for rows if there is no selection
         self.assertNotCalled(mock_table.mock_selection_model.selectedRows)
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
+        self.assertNotCalled(mock_copy)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
 
-    def test_action_copy_bin_values(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_bin_values(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -89,11 +102,13 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         presenter.action_copy_bin_values(mock_table)
 
         mock_table.selectionModel.assert_called_once_with()
-        view.copy_to_clipboard.assert_called_once_with(expected_string)
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
+        mock_copy.assert_called_once_with(expected_string)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
 
-    def test_action_copy_bin_values_no_selection(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_bin_values_no_selection(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -108,9 +123,12 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
         # the action should never look for rows if there is no selection
         self.assertNotCalled(mock_table.mock_selection_model.selectedColumns)
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
+        self.assertNotCalled(mock_copy)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
 
-    def test_action_copy_cell(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_cell(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -123,11 +141,13 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         presenter.action_copy_cells(mock_table)
 
         mock_table.selectionModel.assert_called_once_with()
-        self.assertEqual(1, view.copy_to_clipboard.call_count)
+        self.assertEqual(1, mock_copy.call_count)
         self.assertEqual(9, mock_index.sibling.call_count)
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.COPY_SUCCESSFUL_MESSAGE)
 
-    def test_action_copy_cell_no_selection(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    @patch('mantidqt.widgets.common.table_copying.copy_to_clipboard')
+    def test_action_copy_cell_no_selection(self, mock_copy, mock_show_mouse_toast):
         ws = MockWorkspace()
         view = MockMatrixWorkspaceDisplayView()
         presenter = MatrixWorkspaceDisplay(ws, view=view)
@@ -138,9 +158,9 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
 
         mock_table.selectionModel.assert_called_once_with()
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
-        view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
 
-        self.assertNotCalled(view.copy_to_clipboard)
+        self.assertNotCalled(mock_copy)
 
     def common_setup_action_plot(self, table_has_selection=True):
         mock_ws = MockWorkspace()
@@ -224,7 +244,8 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         self.assertNotCalled(mock_table.mock_selection_model.selectedColumns)
         self.assertNotCalled(mock_plot)
 
-    def test_action_plot_spectrum_no_selection(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    def test_action_plot_spectrum_no_selection(self, mock_show_mouse_toast):
         mock_plot, mock_table, mock_view, presenter = self.common_setup_action_plot(table_has_selection=False)
 
         mock_table.mock_selection_model.selectedRows = Mock()
@@ -232,7 +253,7 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
 
         presenter.action_plot_spectrum(mock_table)
 
-        mock_view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
         mock_table.selectionModel.assert_called_once_with()
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
 
@@ -278,13 +299,14 @@ class MatrixWorkspaceDisplayPresenterTest(unittest.TestCase):
         self.assertNotCalled(mock_table.mock_selection_model.selectedRows)
         self.assertNotCalled(mock_plot)
 
-    def test_action_plot_bin_no_selection(self):
+    @patch('mantidqt.widgets.common.table_copying.show_mouse_toast')
+    def test_action_plot_bin_no_selection(self, mock_show_mouse_toast):
         mock_plot, mock_table, mock_view, presenter = self.common_setup_action_plot(table_has_selection=False)
         self.setup_mock_selection(mock_table, num_selected_rows=None, num_selected_cols=None)
 
         presenter.action_plot_bin(mock_table)
 
-        mock_view.show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
+        mock_show_mouse_toast.assert_called_once_with(MatrixWorkspaceDisplay.NO_SELECTION_MESSAGE)
         mock_table.selectionModel.assert_called_once_with()
         mock_table.mock_selection_model.hasSelection.assert_called_once_with()
 
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/matrixworkspacedisplay_common.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/matrixworkspacedisplay_common.py
index 30cc8e48c8d10b13489984c2edb7137a233bacd2..66d406bc55df5213b3bd2f17cbb0b18f7e3d4b4e 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/matrixworkspacedisplay_common.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/matrixworkspacedisplay_common.py
@@ -125,10 +125,27 @@ class MockWorkspace:
         self.maskedBinsIndices = None
         self.isCommonBins = Mock(return_value=True)
 
+        self.column_types = ["int", "float", "string", "v3d", "bool"]
+        self.columnTypes = Mock(return_value=self.column_types)
+
         self.mock_spectrum = MockSpectrum()
         self.getSpectrum = Mock(return_value=self.mock_spectrum)
 
         self.mock_axis = MockMantidAxis()
         self.getAxis = Mock(return_value=self.mock_axis)
 
+        self.setCell = Mock()
+
         self.name = None
+
+    def rowCount(self):
+        pass
+
+    def columnCount(self):
+        pass
+
+    def getColumnNames(self):
+        pass
+
+    def column(self, index):
+        pass
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/mock_matrixworkspacedisplay.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/mock_matrixworkspacedisplay.py
index 4b67e28ccaecd7eb454a28738204067ad12ab743..d3856441e64e699b6baa7fc2adce46d80aff1600 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/mock_matrixworkspacedisplay.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/test_helpers/mock_matrixworkspacedisplay.py
@@ -70,8 +70,6 @@ class MockMatrixWorkspaceDisplayView:
         self.table_y = MockQTableView()
         self.table_e = MockQTableView()
         self.set_model = Mock()
-        self.copy_to_clipboard = Mock()
-        self.show_mouse_toast = Mock()
         self.ask_confirmation = None
 
 
diff --git a/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py b/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py
index 2c123a1b13c4546338e2de61a8135feb974d9366..db6be8b0dbaa5dd255ad8a864893f3888eb106a6 100644
--- a/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py
+++ b/qt/python/mantidqt/widgets/matrixworkspacedisplay/view.py
@@ -12,9 +12,9 @@ from __future__ import (absolute_import, division, print_function)
 from functools import partial
 
 from qtpy import QtGui
-from qtpy.QtCore import QPoint, Qt
-from qtpy.QtGui import QCursor, QFont, QFontMetrics, QKeySequence
-from qtpy.QtWidgets import (QAbstractItemView, QAction, QHeaderView, QMessageBox, QTabWidget, QTableView, QToolTip)
+from qtpy.QtCore import Qt
+from qtpy.QtGui import QKeySequence
+from qtpy.QtWidgets import (QAbstractItemView, QAction, QHeaderView, QMessageBox, QTabWidget, QTableView)
 
 import mantidqt.icons
 from mantidqt.widgets.matrixworkspacedisplay.table_view_model import MatrixWorkspaceTableViewModelType
@@ -144,26 +144,6 @@ class MatrixWorkspaceDisplayView(QTabWidget):
                                                                                          model.model_type)
         table.setModel(model)
 
-    @staticmethod
-    def copy_to_clipboard(data):
-        """
-        Uses the QGuiApplication to copy to the system clipboard.
-
-        :type data: str
-        :param data: The data that will be copied to the clipboard
-        :return:
-        """
-        cb = QtGui.QGuiApplication.clipboard()
-        cb.setText(data, mode=cb.Clipboard)
-
-    def show_mouse_toast(self, message):
-        # Creates a text with empty space to get the height of the rendered text - this is used
-        # to provide the same offset for the tooltip, scaled relative to the current resolution and zoom.
-        font_metrics = QFontMetrics(QFont(" "))
-        # The height itself is divided by 2 just to reduce the offset so that the tooltip is
-        # reasonably position relative to the cursor
-        QToolTip.showText(QCursor.pos() + QPoint(font_metrics.height() / 2, 0), message)
-
     def ask_confirmation(self, message, title="Mantid Workbench"):
         """
         :param message:
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/__init__.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..57d5ae5a28a63ed0dd44886f201c25df7cac61ca
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/__init__.py
@@ -0,0 +1,9 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/__main__.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d11d49143c9e97cd34e51493e4c3eb13ce47d3b
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/__main__.py
@@ -0,0 +1,27 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+
+# To Run - target this package with PyCharm, and __main__ will be executed
+
+import matplotlib
+
+matplotlib.use('Qt5Agg')
+
+
+from qtpy.QtWidgets import QApplication  # noqa: F402
+
+from mantid.simpleapi import Load  # noqa: F402
+from mantidqt.widgets.tableworkspacedisplay.presenter import TableWorkspaceDisplay  # noqa: F402
+import matplotlib.pyplot as plt  # noqa: F402
+
+app = QApplication([])
+ws = Load("SavedTableWorkspace.nxs")
+window = TableWorkspaceDisplay(ws, plt)
+app.exec_()
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/error_column.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/error_column.py
new file mode 100644
index 0000000000000000000000000000000000000000..481a8b98b75cff82ec00b75e08365b8b0d5607d6
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/error_column.py
@@ -0,0 +1,35 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#    This file is part of the mantid workbench.
+#
+#
+
+
+class ErrorColumn:
+    def __init__(self, column, error_for_column, label_index):
+        self.column = column
+        self.error_for_column = error_for_column
+        if self.column == self.error_for_column:
+            raise ValueError("Cannot set Y column to be its own YErr")
+
+        self.label_index = label_index
+
+    def __eq__(self, other):
+        if isinstance(other, ErrorColumn):
+            return self.error_for_column == other.error_for_column or self.column == other.column
+        elif isinstance(other, int):
+            return self.column == other
+        else:
+            raise RuntimeError("Unhandled comparison logic with type {}".format(type(other)))
+
+    def __cmp__(self, other):
+        if isinstance(other, ErrorColumn):
+            return self.column == other.column or self.error_for_column == other.error_for_column
+        elif isinstance(other, int):
+            return self.column == other
+        else:
+            raise RuntimeError("Unhandled comparison logic with type {}".format(type(other)))
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/marked_columns.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/marked_columns.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c30c53d3e2fdd01d721a199cefed8c6d27b4493
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/marked_columns.py
@@ -0,0 +1,111 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#    This file is part of the mantid workbench.
+#
+#
+
+
+class MarkedColumns:
+    X_LABEL = "[X{}]"
+    Y_LABEL = "[Y{}]"
+    Y_ERR_LABEL = "[Y{}_YErr]"
+
+    def __init__(self):
+        self.as_x = []
+        self.as_y = []
+        self.as_y_err = []
+
+    def _add(self, col_index, add_to, remove_from):
+        assert all(
+            add_to is not remove for remove in remove_from), "Can't add and remove from the same list at the same time!"
+        self._remove(col_index, remove_from)
+
+        if col_index not in add_to:
+            add_to.append(col_index)
+
+    def _remove(self, col_index, remove_from):
+        """
+        Remove the column index from all lists
+        :param col_index: The column index to be removed
+        :type remove_from: list[list[Union[int, ErrorColumn]]]
+        :param remove_from: List of lists from which the column index will be removed
+        :return:
+        """
+        for list in remove_from:
+            try:
+                list.remove(col_index)
+            except ValueError:
+                # column not in this list, but might be in another one so we continue the loop
+                continue
+
+        # if the column previously had a Y Err associated with it -> this will remove it from the YErr list
+        self._remove_associated_yerr_columns(col_index)
+
+    def add_x(self, col_index):
+        self._add(col_index, self.as_x, [self.as_y, self.as_y_err])
+
+    def add_y(self, col_index):
+        self._add(col_index, self.as_y, [self.as_x, self.as_y_err])
+
+    def add_y_err(self, err_column):
+        if err_column.error_for_column in self.as_x:
+            raise ValueError("Trying to add YErr for column marked as X.")
+        elif err_column.error_for_column in self.as_y_err:
+            raise ValueError("Trying to add YErr for column marked as YErr.")
+        # remove all labels for the column index
+        len_before_remove = len(self.as_y)
+        self._remove(err_column, [self.as_x, self.as_y, self.as_y_err])
+
+        # Check if the length of the list with columns marked Y has shrunk
+        # -> This means that columns have been removed, and the label_index is now _wrong_
+        # and has to be decremented to match the new label index correctly
+        len_after_remove = len(self.as_y)
+        if err_column.error_for_column > err_column.column and len_after_remove < len_before_remove:
+            err_column.label_index -= (len_before_remove - len_after_remove)
+        self.as_y_err.append(err_column)
+
+    def remove(self, col_index):
+        self._remove(col_index, [self.as_x, self.as_y, self.as_y_err])
+
+    def _remove_associated_yerr_columns(self, col_index):
+        # we can only have 1 Y Err for Y, so iterating and removing's iterator invalidation is not an
+        # issue as the code will exit immediately after the removal
+        for col in self.as_y_err:
+            if col.error_for_column == col_index:
+                self.as_y_err.remove(col)
+                break
+
+    def _make_labels(self, list, label):
+        return [(col_num, label.format(index),) for index, col_num in enumerate(list)]
+
+    def build_labels(self):
+        extra_labels = []
+        extra_labels.extend(self._make_labels(self.as_x, self.X_LABEL))
+        extra_labels.extend(self._make_labels(self.as_y, self.Y_LABEL))
+        err_labels = [(err_col.column, self.Y_ERR_LABEL.format(err_col.label_index),) for index, err_col in
+                      enumerate(self.as_y_err)]
+        extra_labels.extend(err_labels)
+        return extra_labels
+
+    def find_yerr(self, selected_columns):
+        """
+        Retrieve the corresponding YErr column for each Y column, so that it can be plotted
+        :param selected_columns: Selected Y columns for which their YErr columns will be retrieved
+        :return: Dict[Selected Column] = Column with YErr
+        """
+        yerr_for_col = {}
+
+        # for each selected column
+        for col in selected_columns:
+            # find the marked error column
+            for yerr_col in self.as_y_err:
+                # if found append the YErr's source column - so that the data from the columns
+                # can be retrieved for plotting the errors
+                if yerr_col.error_for_column == col:
+                    yerr_for_col[col] = yerr_col.column
+
+        return yerr_for_col
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/model.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ac78cac95aab3b05fa999a6d0accfb4a49e090e
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/model.py
@@ -0,0 +1,89 @@
+# coding=utf-8
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import (absolute_import, division, print_function)
+
+from mantid.dataobjects import PeaksWorkspace, TableWorkspace
+from mantid.kernel import V3D
+from mantidqt.widgets.tableworkspacedisplay.marked_columns import MarkedColumns
+
+
+class TableWorkspaceDisplayModel:
+    SPECTRUM_PLOT_LEGEND_STRING = '{}-{}'
+    BIN_PLOT_LEGEND_STRING = '{}-bin-{}'
+
+    ALLOWED_WORKSPACE_TYPES = [PeaksWorkspace, TableWorkspace]
+
+    @classmethod
+    def supports(cls, ws):
+        """
+        Checks that the provided workspace is supported by this display.
+        :param ws: Workspace to be checked for support
+        :raises ValueError: if the workspace is not supported
+        """
+        if not any(isinstance(ws, allowed_type) for allowed_type in cls.ALLOWED_WORKSPACE_TYPES):
+            raise ValueError("The workspace type is not supported: {0}".format(ws))
+
+    def __init__(self, ws):
+        """
+        Initialise the model with the workspace
+        :param ws: Workspace to be used for providing data
+        :raises ValueError: if the workspace is not supported
+        """
+        self.supports(ws)
+
+        self.ws = ws
+        self.ws_num_rows = self.ws.rowCount()
+        self.ws_num_cols = self.ws.columnCount()
+        self.ws_column_types = self.ws.columnTypes()
+        self.marked_columns = MarkedColumns()
+        self._original_column_headers = self.get_column_headers()
+
+    def _get_v3d_from_str(self, string):
+        if '[' in string and ']' in string:
+            string = string[1:-1]
+        if ',' in string:
+            return V3D(*[float(x) for x in string.split(',')])
+        else:
+            raise ValueError("'{}' is not a valid V3D string.".format(string))
+
+    def original_column_headers(self):
+        return self._original_column_headers[:]
+
+    def build_current_labels(self):
+        return self.marked_columns.build_labels()
+
+    def get_name(self):
+        return self.ws.name()
+
+    def get_column_headers(self):
+        return self.ws.getColumnNames()
+
+    def get_column(self, index):
+        return self.ws.column(index)
+
+    def get_number_of_rows(self):
+        return self.ws_num_rows
+
+    def get_number_of_columns(self):
+        return self.ws_num_cols
+
+    def get_column_header(self, index):
+        return self.get_column_headers()[index]
+
+    def is_peaks_workspace(self):
+        return isinstance(self.ws, PeaksWorkspace)
+
+    def set_cell_data(self, row, col, data, is_v3d):
+        # if the cell contains V3D data, construct a V3D object
+        # from the string to that it can be properly set
+        if is_v3d:
+            data = self._get_v3d_from_str(data)
+        self.ws.setCell(row, col, data)
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/plot_type.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/plot_type.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4a127600497467305e4cfaf9f17c360f71878b9
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/plot_type.py
@@ -0,0 +1,8 @@
+from mantid.py3compat import Enum
+
+
+class PlotType(Enum):
+    LINEAR = 1
+    SCATTER = 2
+    LINE_AND_SYMBOL = 3
+    LINEAR_WITH_ERR = 4
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/presenter.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c05e2e6091ee22375c5505e9d18791fdb23dc24
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/presenter.py
@@ -0,0 +1,327 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import absolute_import, division, print_function
+
+from functools import partial
+
+from qtpy.QtCore import Qt
+
+from mantid.simpleapi import DeleteTableRows, StatisticsOfTableWorkspace
+from mantidqt.widgets.common.table_copying import copy_cells, show_no_selection_to_copy_toast
+from mantidqt.widgets.tableworkspacedisplay.error_column import ErrorColumn
+from mantidqt.widgets.tableworkspacedisplay.plot_type import PlotType
+from mantidqt.widgets.tableworkspacedisplay.workbench_table_widget_item import WorkbenchTableWidgetItem
+from .model import TableWorkspaceDisplayModel
+from .view import TableWorkspaceDisplayView
+
+
+class TableWorkspaceDisplay(object):
+    A_LOT_OF_THINGS_TO_PLOT_MESSAGE = "You selected {} spectra to plot. Are you sure you want to plot that many?"
+    TOO_MANY_SELECTED_FOR_X = "Too many columns are selected to use as X. Please select only 1."
+    TOO_MANY_SELECTED_TO_SORT = "Too many columns are selected to sort by. Please select only 1."
+    TOO_MANY_SELECTED_FOR_PLOT = "Too many columns are selected to plot. Please select only 1."
+    NUM_SELECTED_FOR_CONFIRMATION = 10
+    NO_COLUMN_MARKED_AS_X = "No columns marked as X."
+
+    def __init__(self, ws, plot=None, parent=None, model=None, view=None, name=None):
+        """
+        Creates a display for the provided workspace.
+
+        :param ws: Workspace to be displayed
+        :param parent: Parent of the widget
+        :param plot: Plotting function that will be used to plot workspaces. This requires MatPlotLib directly.
+                     Passed in as parameter to allow mocking
+        :param model: Model to be used by the widget. Passed in as parameter to allow mocking
+        :param view: View to be used by the widget. Passed in as parameter to allow mocking
+        :param name: Custom name for the window
+        """
+        # Create model and view, or accept mocked versions
+        self.model = model if model else TableWorkspaceDisplayModel(ws)
+        self.name = self.model.get_name() if name is None else name
+        self.view = view if view else TableWorkspaceDisplayView(self, parent, self.name)
+        self.parent = parent
+        self.plot = plot
+        self.view.set_context_menu_actions(self.view)
+
+        self.update_column_headers()
+        self.load_data(self.view)
+
+        # connect to cellChanged signal after the data has been loaded
+        # all consecutive triggers will be from user actions
+        self.view.itemChanged.connect(self.handleItemChanged)
+
+    @classmethod
+    def supports(cls, ws):
+        """
+        Checks that the provided workspace is supported by this display.
+        :param ws: Workspace to be checked for support
+        :raises ValueError: if the workspace is not supported
+        """
+        return TableWorkspaceDisplayModel.supports(ws)
+
+    def handleItemChanged(self, item):
+        """
+        :type item: WorkbenchTableWidgetItem
+        :param item:
+        :return:
+        """
+        try:
+            self.model.set_cell_data(item.row(), item.column(), item.data(Qt.DisplayRole), item.is_v3d)
+            item.update()
+        except ValueError:
+            self.view.show_warning("Error: Trying to set invalid data for the column.")
+        except Exception as x:
+            self.view.show_warning("Unknown error occurred: {}".format(x))
+        finally:
+            item.reset()
+
+    def update_column_headers(self):
+        """
+        :param extra_labels: Extra labels to be appended to the column headers.
+                             Expected format: [(id, label), (2, "X"),...]
+        :type extra_labels: List[Tuple[int, str]]
+        :return:
+        """
+        # deep copy the original headers so that they are not changed by the appending of the label
+        column_headers = self.model.original_column_headers()
+        num_headers = len(column_headers)
+        self.view.setColumnCount(num_headers)
+
+        extra_labels = self.model.build_current_labels()
+        if len(extra_labels) > 0:
+            for index, label in extra_labels:
+                column_headers[index] += str(label)
+
+        self.view.setHorizontalHeaderLabels(column_headers)
+
+    def load_data(self, table):
+        num_rows = self.model.get_number_of_rows()
+        table.setRowCount(num_rows)
+
+        num_cols = self.model.get_number_of_columns()
+
+        # the table should be editable if the ws is not PeaksWS
+        editable = not self.model.is_peaks_workspace()
+
+        for col in range(num_cols):
+            column_data = self.model.get_column(col)
+            for row in range(num_rows):
+                item = WorkbenchTableWidgetItem(column_data[row], editable=editable)
+                table.setItem(row, col, item)
+
+    def action_copy_cells(self):
+        copy_cells(self.view)
+
+    def action_copy_bin_values(self):
+        copy_cells(self.view)
+
+    def action_copy_spectrum_values(self):
+        copy_cells(self.view)
+
+    def action_keypress_copy(self):
+        copy_cells(self.view)
+
+    def action_delete_row(self):
+        selection_model = self.view.selectionModel()
+        if not selection_model.hasSelection():
+            show_no_selection_to_copy_toast()
+            return
+
+        selected_rows = selection_model.selectedRows()
+        selected_rows_list = [index.row() for index in selected_rows]
+        selected_rows_str = ",".join([str(row) for row in selected_rows_list])
+
+        DeleteTableRows(self.model.ws, selected_rows_str)
+        # Reverse the list so that we delete in order from bottom -> top
+        # this prevents the row index from shifting up when deleting rows above
+        for row in reversed(selected_rows_list):
+            self.view.removeRow(row)
+
+    def _get_selected_columns(self, max_selected=None, message_if_over_max=None):
+        selection_model = self.view.selectionModel()
+        if not selection_model.hasSelection():
+            show_no_selection_to_copy_toast()
+            raise ValueError("No selection")
+
+        selected_columns = selection_model.selectedColumns()
+        num_selected_columns = len(selected_columns)
+
+        if max_selected and message_if_over_max and num_selected_columns > max_selected:
+            # if over the maximum allowed selection
+            self.view.show_warning(message_if_over_max)
+            raise ValueError("Too many selected")
+        elif num_selected_columns == 0:
+            # if no columns are selected
+            show_no_selection_to_copy_toast()
+            raise ValueError("No selection")
+        else:
+            return [index.column() for index in selected_columns]
+
+    def action_statistics_on_columns(self):
+        try:
+            selected_columns = self._get_selected_columns()
+        except ValueError:
+            return
+
+        stats = StatisticsOfTableWorkspace(self.model.ws, selected_columns)
+        TableWorkspaceDisplay(stats, parent=self.parent, name="Column Statistics of {}".format(self.name))
+
+    def action_hide_selected(self):
+        try:
+            selected_columns = self._get_selected_columns()
+        except ValueError:
+            return
+        for column_index in selected_columns:
+            self.view.hideColumn(column_index)
+
+    def action_show_all_columns(self):
+        for column_index in range(self.view.columnCount()):
+            self.view.showColumn(column_index)
+
+    def _action_set_as(self, add_to_list_func):
+        try:
+            selected_columns = self._get_selected_columns()
+        except ValueError:
+            return
+
+        for col in selected_columns:
+            add_to_list_func(col)
+
+        self.update_column_headers()
+
+    def action_set_as_x(self):
+        self._action_set_as(self.model.marked_columns.add_x)
+
+    def action_set_as_y(self):
+        self._action_set_as(self.model.marked_columns.add_y)
+
+    def action_set_as_y_err(self, error_for_column, label_index):
+        """
+
+        :param error_for_column: The real index of the column for which the error is being marked
+        :param label_index: The index present in the label of the column for which the error is being marked
+                            This will be the number in <ColumnName>[Y10] -> the 10
+        """
+        try:
+            selected_columns = self._get_selected_columns(1, "Too many selected to set as Y Error")
+        except ValueError:
+            return
+
+        selected_column = selected_columns[0]
+        try:
+            err_column = ErrorColumn(selected_column, error_for_column, label_index)
+        except ValueError as e:
+            self.view.show_warning(e.message)
+            return
+
+        self.model.marked_columns.add_y_err(err_column)
+        self.update_column_headers()
+
+    def action_set_as_none(self):
+        self._action_set_as(self.model.marked_columns.remove)
+
+    def action_sort_ascending(self, order):
+        try:
+            selected_columns = self._get_selected_columns(1, self.TOO_MANY_SELECTED_TO_SORT)
+        except ValueError:
+            return
+
+        selected_column = selected_columns[0]
+        self.view.sortByColumn(selected_column, order)
+
+    def action_plot(self, plot_type):
+        try:
+            selected_columns = self._get_selected_columns()
+        except ValueError:
+            return
+
+        x_cols = list(set(selected_columns).intersection(self.model.marked_columns.as_x))
+        num_x_cols = len(x_cols)
+        # if there is more than 1 column marked as X in the selection
+        # -> show toast to the user and do nothing
+        if num_x_cols > 1:
+            self.view.show_warning(self.TOO_MANY_SELECTED_FOR_X)
+            return
+        elif num_x_cols == 1:
+            # Only 1 X column present in the current selection model
+            # -> Use it as X for the plot
+            selected_x = x_cols[0]
+        else:
+            # No X column present in the current selection model
+            # -> Use the first column marked as X (if present)
+            if len(self.model.marked_columns.as_x) == 0:
+                # If no columns are marked as X show user message and exit
+                self.view.show_warning(self.NO_COLUMN_MARKED_AS_X)
+                return
+            selected_x = self.model.marked_columns.as_x[0]
+
+        try:
+            # Remove the X column from the selected columns, this is
+            # in case a column is being used as both X and Y
+            selected_columns.remove(selected_x)
+        except ValueError:
+            pass
+
+        if len(selected_columns) == 0:
+            self.view.show_warning("Cannot plot column against itself.")
+            return
+
+        self._do_plot(selected_columns, selected_x, plot_type)
+
+    def _do_plot(self, selected_columns, selected_x, plot_type):
+        if plot_type == PlotType.LINEAR_WITH_ERR:
+            yerr = self.model.marked_columns.find_yerr(selected_columns)
+            if len(yerr) != len(selected_columns):
+                self.view.show_warning("There is no associated YErr for each selected Y column.")
+                return
+        x = self.model.get_column(selected_x)
+
+        fig, ax = self.plot.subplots(subplot_kw={'projection': 'mantid'})
+        fig.canvas.set_window_title(self.model.get_name())
+        ax.set_xlabel(self.model.get_column_header(selected_x))
+
+        plot_func = self._get_plot_function_from_type(ax, plot_type)
+        kwargs = {}
+        for column in selected_columns:
+            if plot_type == PlotType.LINEAR_WITH_ERR:
+                yerr_column = yerr[column]
+                yerr_column_data = self.model.get_column(yerr_column)
+                kwargs["yerr"] = yerr_column_data
+
+            y = self.model.get_column(column)
+            column_label = self.model.get_column_header(column)
+            try:
+                plot_func(x, y, label='Column {}'.format(column_label), **kwargs)
+            except ValueError as e:
+                #     TODO log error?
+                self.view.show_warning(
+                    "One or more of the columns being plotted contain invalid data for MatPlotLib."
+                    "\n\nError message:\n{}".format(e), "Invalid data - Mantid Workbench")
+                return
+
+            ax.set_ylabel(column_label)
+        ax.legend()
+        fig.show()
+
+    def _get_plot_function_from_type(self, ax, type):
+        if type == PlotType.LINEAR:
+            plot_func = ax.plot
+        elif type == PlotType.SCATTER:
+            plot_func = ax.scatter
+        elif type == PlotType.LINE_AND_SYMBOL:
+            plot_func = partial(ax.plot, marker='o')
+        elif type == PlotType.LINEAR_WITH_ERR:
+            plot_func = ax.errorbar
+        else:
+            raise ValueError("Plot Type: {} not currently supported!".format(type))
+        return plot_func
+
+    def get_columns_marked_as_y(self):
+        return self.model.marked_columns.as_y[:]
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/__init__.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_error_column.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_error_column.py
new file mode 100644
index 0000000000000000000000000000000000000000..4aae73eb81fc9d70ac97e726269ab448600c8a32
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_error_column.py
@@ -0,0 +1,33 @@
+import unittest
+
+from mantidqt.widgets.tableworkspacedisplay.error_column import ErrorColumn
+
+
+class ErrorColumnTest(unittest.TestCase):
+
+    def test_correct_init(self):
+        ErrorColumn(0, 1, 0)
+
+    def test_raises_for_same_y_and_yerr(self):
+        self.assertRaises(ValueError, lambda: ErrorColumn(2, 2, 3))
+
+    def test_eq_versus_ErrorColumn(self):
+        ec1 = ErrorColumn(0, 1, 0)
+        ec2 = ErrorColumn(0, 1, 0)
+        self.assertEqual(ec1, ec2)
+
+        ec1 = ErrorColumn(0, 3, 0)
+        ec2 = ErrorColumn(0, 1, 0)
+        self.assertEqual(ec1, ec2)
+
+        ec1 = ErrorColumn(2, 3, 0)
+        ec2 = ErrorColumn(0, 3, 0)
+        self.assertEqual(ec1, ec2)
+
+    def test_eq_versus_same_int(self):
+        ec = ErrorColumn(150, 1, 0)
+        self.assertEqual(ec, 150)
+
+    def test_eq_unsupported_type(self):
+        ec = ErrorColumn(150, 1, 0)
+        self.assertRaises(RuntimeError, lambda: ec == "awd")
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_marked_columns.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_marked_columns.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d91244c05efa799f6b375048228fca58e48bac3
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_marked_columns.py
@@ -0,0 +1,343 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+from itertools import permutations
+
+from mantidqt.widgets.tableworkspacedisplay.error_column import ErrorColumn
+from mantidqt.widgets.tableworkspacedisplay.marked_columns import MarkedColumns
+
+
+class ReferenceHolder:
+    def __init__(self, test_func, test_list):
+        self.func = test_func
+        self.list = test_list
+
+
+class MarkedColumnsTest(unittest.TestCase):
+
+    def test_add_x(self):
+        mc = MarkedColumns()
+        self.execute_add(mc.add_x, mc.as_x)
+
+    def test_add_y(self):
+        mc = MarkedColumns()
+        self.execute_add(mc.add_y, mc.as_y)
+
+    def execute_add(self, func_to_add, list_to_check):
+        func_to_add(2)
+        self.assertEqual(1, len(list_to_check))
+        func_to_add(3)
+        self.assertEqual(2, len(list_to_check))
+        func_to_add(4000000)
+        self.assertEqual(3, len(list_to_check))
+
+    def test_add_y_err(self):
+        """
+        Test adding YErr columns that do not overlap in any way
+        """
+        mc = MarkedColumns()
+        ec = ErrorColumn(2, 4, 0)
+        mc.add_y_err(ec)
+        self.assertEqual(1, len(mc.as_y_err))
+        ec = ErrorColumn(3, 5, 0)
+        mc.add_y_err(ec)
+        self.assertEqual(2, len(mc.as_y_err))
+        ec = ErrorColumn(1, 6, 0)
+        mc.add_y_err(ec)
+        self.assertEqual(3, len(mc.as_y_err))
+
+    def test_add_x_duplicate_column(self):
+        mc = MarkedColumns()
+        self.execute_add_duplicate_column(mc.add_x, mc.as_x)
+
+    def test_add_y_duplicate_column(self):
+        mc = MarkedColumns()
+        self.execute_add_duplicate_column(mc.add_y, mc.as_y)
+
+    def execute_add_duplicate_column(self, func_to_add, list_to_check):
+        func_to_add(2)
+        self.assertEqual(1, len(list_to_check))
+        func_to_add(2)
+        self.assertEqual(1, len(list_to_check))
+        func_to_add(55)
+        self.assertEqual(2, len(list_to_check))
+        func_to_add(55)
+        self.assertEqual(2, len(list_to_check))
+
+    def test_add_y_err_duplicate_column(self):
+        mc = MarkedColumns()
+        ec = ErrorColumn(2, 4, 0)
+
+        mc.add_y_err(ec)
+        self.assertEqual(1, len(mc.as_y_err))
+        mc.add_y_err(ec)
+        self.assertEqual(1, len(mc.as_y_err))
+
+        ec2 = ErrorColumn(3, 5, 0)
+        mc.add_y_err(ec2)
+        self.assertEqual(2, len(mc.as_y_err))
+        mc.add_y_err(ec2)
+        self.assertEqual(2, len(mc.as_y_err))
+
+    def test_add_already_marked(self):
+        mc = MarkedColumns()
+
+        relevant_funcs = [ReferenceHolder(mc.add_x, mc.as_x),
+                          ReferenceHolder(mc.add_y, mc.as_y)]
+        all_combinations = permutations(relevant_funcs, 2)
+
+        for combination in all_combinations:
+            self.execute_add_already_marked(*combination)
+
+    def execute_add_already_marked(self, first, two):
+        """
+        If trying to mark a column that is already marked -> all other markings must be removed
+        :type first: ReferenceHolder
+        :type two: ReferenceHolder
+        :return:
+        """
+
+        # add column in first
+        first.func(33)
+        self.assertEqual(1, len(first.list))
+
+        # add the same column in the second
+        two.func(33)
+
+        # it should have been removed from the first and only present in the second
+        self.assertEqual(0, len(first.list))
+        self.assertEqual(1, len(two.list))
+
+    def test_add_y_err_duplicate_column_same_source_column(self):
+        """
+        Test for adding a new YErr column with the same source column
+        -> The new YErr must replace the old one
+        """
+        mc = MarkedColumns()
+        ec = ErrorColumn(column=2, error_for_column=4, label_index=0)
+        mc.add_y_err(ec)
+        self.assertEqual(1, len(mc.as_y_err))
+        self.assertEqual(2, mc.as_y_err[0].column)
+        self.assertEqual(4, mc.as_y_err[0].error_for_column)
+
+        # different source column but contains error for the same column
+        # adding this one should replace the first one
+        ec2 = ErrorColumn(column=2, error_for_column=5, label_index=0)
+        mc.add_y_err(ec2)
+        self.assertEqual(1, len(mc.as_y_err))
+        self.assertEqual(2, mc.as_y_err[0].column)
+        self.assertEqual(5, mc.as_y_err[0].error_for_column)
+
+    def test_add_y_err_duplicate_column_different_reference_col(self):
+        """
+        Test for adding a new YErr column with a _different_ source column but same reference column
+        -> The new YErr must replace the old one
+        """
+        mc = MarkedColumns()
+        ec = ErrorColumn(column=2, error_for_column=4, label_index=0)
+        mc.add_y_err(ec)
+        self.assertEqual(1, len(mc.as_y_err))
+        self.assertEqual(2, mc.as_y_err[0].column)
+        self.assertEqual(4, mc.as_y_err[0].error_for_column)
+
+        # different source column but contains error for the same column
+        # adding this one should replace the first one
+        ec2 = ErrorColumn(column=3, error_for_column=4, label_index=0)
+        mc.add_y_err(ec2)
+        self.assertEqual(1, len(mc.as_y_err))
+        self.assertEqual(3, mc.as_y_err[0].column)
+        self.assertEqual(4, mc.as_y_err[0].error_for_column)
+
+    def test_changing_y_to_x_removes_associated_yerr_columns(self):
+        """
+        Test to check if a first column is marked as Y, a second column YErr is associated with it, but then
+        the first one is changed to X - the YErr mark should be removed
+        """
+        mc = MarkedColumns()
+        mc.add_y(4)
+        ec = ErrorColumn(column=2, error_for_column=4, label_index=0)
+        mc.add_y_err(ec)
+
+        # check that we have both a Y col and an associated YErr
+        self.assertEqual(1, len(mc.as_y))
+        self.assertEqual(1, len(mc.as_y_err))
+
+        mc.add_x(4)
+        # changing the column to X should have removed it from Y and Yerr
+        self.assertEqual(1, len(mc.as_x))
+        self.assertEqual(0, len(mc.as_y))
+        self.assertEqual(0, len(mc.as_y_err))
+
+    def test_changing_y_to_none_removes_associated_yerr_columns(self):
+        """
+        Test to check if a first column is marked as Y, a second column YErr is associated with it, but then
+        the first one is changed to X - the YErr mark should be removed
+        """
+        mc = MarkedColumns()
+        mc.add_y(4)
+        ec = ErrorColumn(column=2, error_for_column=4, label_index=0)
+        mc.add_y_err(ec)
+
+        # check that we have both a Y col and an associated YErr
+        self.assertEqual(1, len(mc.as_y))
+        self.assertEqual(1, len(mc.as_y_err))
+
+        mc.remove(4)
+        # changing the column to NONE should have removed it from X, Y and YErr
+        self.assertEqual(0, len(mc.as_x))
+        self.assertEqual(0, len(mc.as_y))
+        self.assertEqual(0, len(mc.as_y_err))
+
+    def test_remove_column(self):
+        mc = MarkedColumns()
+        mc.add_y(4)
+        mc.add_x(3)
+        ec = ErrorColumn(column=2, error_for_column=6, label_index=0)
+        mc.add_y_err(ec)
+
+        self.assertEqual(1, len(mc.as_x))
+        self.assertEqual(1, len(mc.as_y))
+        self.assertEqual(1, len(mc.as_y_err))
+
+        mc.remove(4)
+        self.assertEqual(0, len(mc.as_y))
+        self.assertEqual(1, len(mc.as_y_err))
+        self.assertEqual(1, len(mc.as_x))
+
+        mc.remove(3)
+        self.assertEqual(0, len(mc.as_x))
+        self.assertEqual(0, len(mc.as_y))
+        self.assertEqual(1, len(mc.as_y_err))
+
+        mc.remove(2)
+        self.assertEqual(0, len(mc.as_x))
+        self.assertEqual(0, len(mc.as_y))
+        self.assertEqual(0, len(mc.as_y_err))
+
+    def test_build_labels_x_y(self):
+        # TODO test this edge case: mark all columns Y, remove one that is not the last one!
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+        mc.add_y(3)
+
+        # note that the max Y label number will decrease as more Y columns are being changed to X
+        expected = [(0, '[Y0]'), (1, '[Y1]'), (2, '[Y2]'), (3, '[Y3]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        expected = [(1, '[X0]'), (0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]')]
+        mc.add_x(1)
+        self.assertEqual(expected, mc.build_labels())
+        expected = [(1, '[X0]'), (3, '[X1]'), (0, '[Y0]'), (2, '[Y1]')]
+        mc.add_x(3)
+        self.assertEqual(expected, mc.build_labels())
+
+    def test_build_labels_y_and_yerr_change_middle(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+
+        # change one of the columns to YErr
+        mc.add_y_err(ErrorColumn(1, 0, 0))
+        expected = [(0, '[Y0]'), (2, '[Y1]'), (1, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        # change the last Y column to YErr
+        mc.add_y_err(ErrorColumn(2, 0, 0))
+        expected = [(0, '[Y0]'), (2, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+    def test_build_labels_y_and_yerr_change_first(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+
+        # change one of the columns to YErr
+        mc.add_y_err(ErrorColumn(0, 1, 1))
+        # note: the first column is being set -> this decreases the label index of all columns to its right by 1
+        expected = [(1, '[Y0]'), (2, '[Y1]'), (0, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        # change the last Y column to YErr
+        mc.add_y_err(ErrorColumn(2, 1, 0))
+        expected = [(1, '[Y0]'), (2, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+    def test_build_labels_x_y_and_yerr(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+        mc.add_y(3)
+
+        mc.add_y_err(ErrorColumn(1, 0, 0))
+        expected = [(0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]'), (1, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        expected = [(1, '[X0]'), (0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]')]
+        mc.add_x(1)
+        self.assertEqual(expected, mc.build_labels())
+
+        expected = [(1, '[X0]'), (2, '[Y0]'), (3, '[Y1]'), (0, '[Y1_YErr]')]
+        mc.add_y_err(ErrorColumn(0, 3, 2))
+        self.assertEqual(expected, mc.build_labels())
+
+    def test_fail_to_add_yerr_for_x(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+        mc.add_y(3)
+
+        mc.add_y_err(ErrorColumn(1, 0, 0))
+        expected = [(0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]'), (1, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        expected = [(1, '[X0]'), (0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]')]
+        mc.add_x(1)
+        self.assertEqual(expected, mc.build_labels())
+
+        self.assertRaises(ValueError, lambda: mc.add_y_err(ErrorColumn(0, 1, 2)))
+
+    def test_fail_to_add_yerr_for_another_yerr(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+        mc.add_y(3)
+
+        mc.add_y_err(ErrorColumn(1, 0, 0))
+        expected = [(0, '[Y0]'), (2, '[Y1]'), (3, '[Y2]'), (1, '[Y0_YErr]')]
+        self.assertEqual(expected, mc.build_labels())
+
+        self.assertRaises(ValueError, lambda: mc.add_y_err(ErrorColumn(0, 1, 2)))
+
+    def test_find_yerr(self):
+        mc = MarkedColumns()
+        mc.add_y(0)
+        mc.add_y(1)
+        mc.add_y(2)
+        mc.add_y(3)
+
+        mc.add_y_err(ErrorColumn(4, 1, 1))
+        expected = {1: 4}
+        self.assertEqual(expected, mc.find_yerr([1]))
+        # Replace the Y column, which has an associated YErr. This should remove the YErr as well
+        mc.add_y_err(ErrorColumn(1, 3, 1))
+        expected = {3: 1}
+        self.assertEqual(expected, mc.find_yerr([0, 1, 2, 3]))
+        mc.add_y_err(ErrorColumn(4, 2, 1))
+        expected = {2: 4, 3: 1}
+        self.assertEqual(expected, mc.find_yerr([0, 1, 2, 3]))
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_model.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6cb3a2d6d089cb47e3ba366973b9476cb0d8663
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_model.py
@@ -0,0 +1,107 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import (absolute_import, division, print_function)
+
+import functools
+import unittest
+
+from mock import Mock
+
+from mantid.kernel import V3D
+from mantidqt.widgets.matrixworkspacedisplay.test_helpers.matrixworkspacedisplay_common import \
+    MockWorkspace
+from mantidqt.widgets.tableworkspacedisplay.model import TableWorkspaceDisplayModel
+
+
+def with_mock_model(func):
+    # type: (callable) -> callable
+    @functools.wraps(func)
+    def wrapper(self):
+        ws = MockWorkspace()
+        model = TableWorkspaceDisplayModel(ws)
+        return func(self, model)
+
+    return wrapper
+
+
+class TableWorkspaceDisplayModelTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # Allow the MockWorkspace to work within the model
+        TableWorkspaceDisplayModel.ALLOWED_WORKSPACE_TYPES.append(MockWorkspace)
+
+    def test_get_name(self):
+        ws = MockWorkspace()
+        expected_name = "TEST_WORKSPACE"
+        ws.name = Mock(return_value=expected_name)
+        model = TableWorkspaceDisplayModel(ws)
+
+        self.assertEqual(expected_name, model.get_name())
+
+    def test_raises_with_unsupported_workspace(self):
+        self.assertRaises(ValueError, lambda: TableWorkspaceDisplayModel([]))
+        self.assertRaises(ValueError, lambda: TableWorkspaceDisplayModel(1))
+        self.assertRaises(ValueError, lambda: TableWorkspaceDisplayModel("test_string"))
+
+    @with_mock_model
+    def test_get_v3d_from_str(self, model):
+        """
+        :type model: TableWorkspaceDisplayModel
+        """
+        self.assertEqual(V3D(1, 2, 3), model._get_v3d_from_str("1,2,3"))
+        self.assertEqual(V3D(4, 5, 6), model._get_v3d_from_str("[4,5,6]"))
+
+    @with_mock_model
+    def test_set_cell_data_non_v3d(self, model):
+        """
+        :type model: TableWorkspaceDisplayModel
+        """
+        test_data = 4444
+
+        expected_col = 1111
+        expected_row = 1
+
+        model.set_cell_data(expected_row, expected_col, test_data, False)
+
+        # check that the correct conversion function was retrieved
+        # -> the one for the column for which the data is being set
+        model.ws.setCell.assert_called_once_with(expected_row, expected_col, test_data)
+
+    @with_mock_model
+    def test_set_cell_data_v3d(self, model):
+        """
+        :type model: TableWorkspaceDisplayModel
+        """
+        test_data = "[1,2,3]"
+
+        expected_col = 1111
+        expected_row = 1
+
+        model.set_cell_data(expected_row, expected_col, test_data, True)
+
+        # check that the correct conversion function was retrieved
+        # -> the one for the column for which the data is being set
+        model.ws.setCell.assert_called_once_with(expected_row, expected_col, V3D(1, 2, 3))
+
+    def test_no_raise_with_supported_workspace(self):
+        from mantid.simpleapi import CreateEmptyTableWorkspace
+        ws = MockWorkspace()
+        expected_name = "TEST_WORKSPACE"
+        ws.name = Mock(return_value=expected_name)
+
+        # no need to assert anything - if the constructor raises the test will fail
+        TableWorkspaceDisplayModel(ws)
+
+        ws = CreateEmptyTableWorkspace()
+        TableWorkspaceDisplayModel(ws)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_presenter.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..9fdd788ab0bceddab2ade8e0e3f7d73956223011
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_presenter.py
@@ -0,0 +1,27 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+# from __future__ import (absolute_import, division, print_function)
+
+# import unittest
+
+# from mock import Mock
+
+# from mantidqt.widgets.matrixworkspacedisplay.test_helpers.matrixworkspacedisplay_common import MockQModelIndex, \
+#     MockWorkspace
+# from mantidqt.widgets.matrixworkspacedisplay.test_helpers.mock_matrixworkspacedisplay import MockQTableView
+# from mantidqt.widgets.tableworkspacedisplay.presenter import TableWorkspaceDisplay
+# from mantidqt.widgets.tableworkspacedisplay.test_helpers import MockTableWorkspaceDisplayView
+
+
+# class TableWorkspaceDisplayPresenterTest(unittest.TestCase):
+#     def assertNotCalled(self, mock):
+#         self.assertEqual(0, mock.call_count)
+# if __name__ == '__main__':
+#     unittest.main()
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_workbench_table_widget_item.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_workbench_table_widget_item.py
new file mode 100644
index 0000000000000000000000000000000000000000..a72a72a11290ca2891b9598279107321f7d73e04
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test/test_tableworkspacedisplay_workbench_table_widget_item.py
@@ -0,0 +1,111 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+
+from qtpy.QtCore import Qt
+
+from mantid.kernel import V3D
+from mantidqt.widgets.tableworkspacedisplay.workbench_table_widget_item import WorkbenchTableWidgetItem
+
+
+class WorkbenchTableWidgetItemTest(unittest.TestCase):
+    def test_initialise_editable_int(self):
+        """
+        Test that the widget is correctly initialised and the type is correctly kept in the .data call
+        """
+        mock_data = 12
+        w = WorkbenchTableWidgetItem(mock_data, editable=True)
+        self.assertEqual(mock_data, w.display_data)
+        self.assertEqual(mock_data, w.data(Qt.DisplayRole))
+
+    def test_initialise_editable_bool(self):
+        """
+        Test that the widget is correctly initialised and the type is correctly kept in the .data call
+        """
+        mock_data = True
+        w = WorkbenchTableWidgetItem(mock_data, editable=True)
+        self.assertEqual(mock_data, w.display_data)
+        self.assertEqual(mock_data, w.data(Qt.DisplayRole))
+
+    def test_initialise_readonly(self):
+        """
+        Test that the widget converts everything to string if read only
+        :return:
+        """
+        mock_data = 123
+        w = WorkbenchTableWidgetItem(mock_data, editable=False)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+
+        mock_data = 1.3333333
+        w = WorkbenchTableWidgetItem(mock_data, editable=False)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+
+        mock_data = V3D(1, 2, 3)
+        w = WorkbenchTableWidgetItem(mock_data, editable=False)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+
+        mock_data = True
+        w = WorkbenchTableWidgetItem(mock_data, editable=False)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+
+        mock_data = "apples"
+        w = WorkbenchTableWidgetItem(mock_data, editable=False)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+
+    def test_initialise_editable_with_v3d(self):
+        mock_data = V3D(1, 2, 3)
+        w = WorkbenchTableWidgetItem(mock_data, True)
+        self.assertEqual(str(mock_data), w.data(Qt.DisplayRole))
+        # the original data of the V3D is stored as a string too
+        self.assertEqual(str(mock_data), w.display_data)
+
+    def test_initialise_editable_with_float(self):
+        mock_data = 42.00
+        w = WorkbenchTableWidgetItem(mock_data, True)
+        self.assertEqual(mock_data, w.data(Qt.DisplayRole))
+        self.assertEqual(mock_data, w.display_data)
+
+    def test_lt(self):
+        """
+        Test that the widget properly compares with other widgets.
+
+        :return:
+        """
+        w1 = WorkbenchTableWidgetItem(500, editable=False)
+        w2 = WorkbenchTableWidgetItem(1500, editable=False)
+        self.assertTrue(w1 < w2)
+
+        w1 = WorkbenchTableWidgetItem(100.40, editable=False)
+        w2 = WorkbenchTableWidgetItem(100.41, editable=False)
+        self.assertTrue(w1 < w2)
+
+        w1 = WorkbenchTableWidgetItem("apples", editable=False)
+        w2 = WorkbenchTableWidgetItem("potatoes", editable=False)
+        self.assertTrue(w1 < w2)
+
+    def test_reset(self):
+        w = WorkbenchTableWidgetItem(500, editable=False)
+
+        w.display_data = 4444
+        w.reset()
+
+        self.assertEqual(4444, w.data(Qt.DisplayRole))
+
+    def test_update(self):
+        w = WorkbenchTableWidgetItem(500, editable=False)
+        w.setData(Qt.DisplayRole, 4444)
+        w.update()
+        self.assertEqual(4444, w.display_data)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/test_helpers/__init__.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/test_helpers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..0bd8c24be2b8bafb760d7df108f16bcb30c5ad01
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/test_helpers/__init__.py
@@ -0,0 +1,21 @@
+from mock import Mock
+
+from mantidqt.widgets.matrixworkspacedisplay.test_helpers.mock_matrixworkspacedisplay import MockQTableView
+
+
+class MockTableWorkspaceDisplayView:
+    def __init__(self):
+        self.set_context_menu_actions = Mock()
+        self.table_x = MockQTableView()
+        self.table_y = MockQTableView()
+        self.table_e = MockQTableView()
+        self.set_model = Mock()
+        self.copy_to_clipboard = Mock()
+        self.show_mouse_toast = Mock()
+        self.ask_confirmation = None
+
+
+class MockTableWorkspaceDisplayModel:
+    def __init__(self):
+        self.get_spectrum_plot_label = Mock()
+        self.get_bin_plot_label = Mock()
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/view.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..264535848db926b78f565e7ec1c5af6712156d41
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/view.py
@@ -0,0 +1,212 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+#  This file is part of the mantid workbench.
+#
+#
+from __future__ import (absolute_import, division, print_function)
+
+import sys
+from functools import partial
+
+from qtpy import QtGui
+from qtpy.QtCore import QVariant, Qt
+from qtpy.QtGui import QKeySequence
+from qtpy.QtWidgets import (QAction, QHeaderView, QItemEditorFactory, QMenu, QMessageBox,
+                            QStyledItemDelegate, QTableWidget)
+
+import mantidqt.icons
+from mantidqt.widgets.tableworkspacedisplay.plot_type import PlotType
+
+
+class PreciseDoubleFactory(QItemEditorFactory):
+    def __init__(self):
+        QItemEditorFactory.__init__(self)
+
+    def createEditor(self, user_type, parent):
+        widget = super(PreciseDoubleFactory, self).createEditor(user_type, parent)
+        if user_type == QVariant.Double:
+            widget.setFrame(True)
+            widget.setDecimals(16)
+            widget.setRange(sys.float_info.min, sys.float_info.max)
+
+        return widget
+
+
+class TableWorkspaceDisplayView(QTableWidget):
+    def __init__(self, presenter, parent=None, name=''):
+        super(TableWorkspaceDisplayView, self).__init__(parent)
+
+        self.presenter = presenter
+        self.COPY_ICON = mantidqt.icons.get_icon("fa.files-o")
+        self.DELETE_ROW = mantidqt.icons.get_icon("fa.minus-square-o")
+        self.STATISTICS_ON_ROW = mantidqt.icons.get_icon('fa.fighter-jet')
+        self.GRAPH_ICON = mantidqt.icons.get_icon('fa.line-chart')
+        self.TBD = mantidqt.icons.get_icon('fa.question')
+
+        item_delegate = QStyledItemDelegate(self)
+        item_delegate.setItemEditorFactory(PreciseDoubleFactory())
+        self.setItemDelegate(item_delegate)
+
+        self.setWindowTitle("{} - Mantid".format(name))
+        self.setWindowFlags(Qt.Window)
+
+        self.resize(600, 400)
+        self.show()
+
+    def doubleClickedHeader(self):
+        print("Double clicked WOO")
+
+    def keyPressEvent(self, event):
+        if event.matches(QKeySequence.Copy):
+            self.presenter.action_keypress_copy()
+            return
+        elif event.key() == Qt.Key_F2 or event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
+            self.edit(self.currentIndex())
+            return
+
+    def set_context_menu_actions(self, table):
+        """
+        Sets up the context menu actions for the table
+        :type table: QTableView
+        :param table: The table whose context menu actions will be set up.
+        :param ws_read_function: The read function used to efficiently retrieve data directly from the workspace
+        """
+        copy_action = QAction(self.COPY_ICON, "Copy", table)
+        copy_action.triggered.connect(self.presenter.action_copy_cells)
+
+        table.setContextMenuPolicy(Qt.ActionsContextMenu)
+        table.addAction(copy_action)
+
+        horizontalHeader = table.horizontalHeader()
+        horizontalHeader.setContextMenuPolicy(Qt.CustomContextMenu)
+        horizontalHeader.customContextMenuRequested.connect(self.custom_context_menu)
+
+        verticalHeader = table.verticalHeader()
+        verticalHeader.setContextMenuPolicy(Qt.ActionsContextMenu)
+        verticalHeader.setSectionResizeMode(QHeaderView.Fixed)
+
+        copy_spectrum_values = QAction(self.COPY_ICON, "Copy", verticalHeader)
+        copy_spectrum_values.triggered.connect(self.presenter.action_copy_spectrum_values)
+
+        delete_row = QAction(self.DELETE_ROW, "Delete Row", verticalHeader)
+        delete_row.triggered.connect(self.presenter.action_delete_row)
+
+        separator2 = self.make_separator(verticalHeader)
+
+        verticalHeader.addAction(copy_spectrum_values)
+        verticalHeader.addAction(separator2)
+        verticalHeader.addAction(delete_row)
+
+    def custom_context_menu(self, position):
+        menu_main = QMenu()
+        plot = QMenu("Plot...", menu_main)
+        plot_line = QAction("Line", plot)
+        plot_line.triggered.connect(partial(self.presenter.action_plot, PlotType.LINEAR))
+
+        plot_line_with_yerr = QAction("Line with Y Errors", plot)
+        plot_line_with_yerr.triggered.connect(partial(self.presenter.action_plot, PlotType.LINEAR_WITH_ERR))
+
+        plot_scatter = QAction("Scatter", plot)
+        plot_scatter.triggered.connect(partial(self.presenter.action_plot, PlotType.SCATTER))
+
+        plot_line_and_points = QAction("Line + Symbol", plot)
+        plot_line_and_points.triggered.connect(partial(self.presenter.action_plot, PlotType.LINE_AND_SYMBOL))
+
+        plot.addAction(plot_line)
+        plot.addAction(plot_line_with_yerr)
+        plot.addAction(plot_scatter)
+        plot.addAction(plot_line_and_points)
+        menu_main.addMenu(plot)
+
+        copy_bin_values = QAction(self.COPY_ICON, "Copy", menu_main)
+        copy_bin_values.triggered.connect(self.presenter.action_copy_bin_values)
+
+        set_as_x = QAction("Set as X", menu_main)
+        set_as_x.triggered.connect(self.presenter.action_set_as_x)
+
+        set_as_y = QAction("Set as Y", menu_main)
+        set_as_y.triggered.connect(self.presenter.action_set_as_y)
+
+        set_as_none = QAction("Set as None", menu_main)
+        set_as_none.triggered.connect(self.presenter.action_set_as_none)
+
+        statistics_on_columns = QAction("Statistics on Columns", menu_main)
+        statistics_on_columns.triggered.connect(self.presenter.action_statistics_on_columns)
+
+        hide_selected = QAction("Hide Selected", menu_main)
+        hide_selected.triggered.connect(self.presenter.action_hide_selected)
+
+        show_all_columns = QAction("Show All Columns", menu_main)
+        show_all_columns.triggered.connect(self.presenter.action_show_all_columns)
+
+        sort_ascending = QAction("Sort Ascending", menu_main)
+        sort_ascending.triggered.connect(partial(self.presenter.action_sort_ascending, Qt.AscendingOrder))
+
+        sort_descending = QAction("Sort Descending", menu_main)
+        sort_descending.triggered.connect(partial(self.presenter.action_sort_ascending, Qt.DescendingOrder))
+
+        menu_main.addAction(copy_bin_values)
+        menu_main.addAction(self.make_separator(menu_main))
+        menu_main.addAction(set_as_x)
+        menu_main.addAction(set_as_y)
+
+        marked_y_cols = self.presenter.get_columns_marked_as_y()
+        num_y_cols = len(marked_y_cols)
+
+        # If any columns are marked as Y then generate the set error menu
+        if num_y_cols > 0:
+            menu_set_as_y_err = QMenu("Set error for Y...")
+            for col in range(num_y_cols):
+                set_as_y_err = QAction("Y{}".format(col), menu_main)
+                # the column index of the column relative to the whole table, this is necessary
+                # so that later the data of the column marked as error can be retrieved
+                real_column_index = marked_y_cols[col]
+                # col here holds the index in the LABEL (multiple Y columns have labels Y0, Y1, YN...)
+                # this is NOT the same as the column relative to the WHOLE table
+                set_as_y_err.triggered.connect(partial(self.presenter.action_set_as_y_err, real_column_index, col))
+                menu_set_as_y_err.addAction(set_as_y_err)
+            menu_main.addMenu(menu_set_as_y_err)
+
+        menu_main.addAction(set_as_none)
+        menu_main.addAction(self.make_separator(menu_main))
+        menu_main.addAction(statistics_on_columns)
+        menu_main.addAction(self.make_separator(menu_main))
+        menu_main.addAction(hide_selected)
+        menu_main.addAction(show_all_columns)
+        menu_main.addAction(self.make_separator(menu_main))
+        menu_main.addAction(sort_ascending)
+        menu_main.addAction(sort_descending)
+
+        menu_main.exec_(self.mapToGlobal(position))
+
+    def make_separator(self, horizontalHeader):
+        separator1 = QAction(horizontalHeader)
+        separator1.setSeparator(True)
+        return separator1
+
+    @staticmethod
+    def copy_to_clipboard(data):
+        """
+        Uses the QGuiApplication to copy to the system clipboard.
+
+        :type data: str
+        :param data: The data that will be copied to the clipboard
+        :return:
+        """
+        cb = QtGui.QGuiApplication.clipboard()
+        cb.setText(data, mode=cb.Clipboard)
+
+    def ask_confirmation(self, message, title="Mantid Workbench"):
+        """
+        :param message:
+        :return:
+        """
+        reply = QMessageBox.question(self, title, message, QMessageBox.Yes, QMessageBox.No)
+        return True if reply == QMessageBox.Yes else False
+
+    def show_warning(self, message, title="Mantid Workbench"):
+        QMessageBox.warning(self, title, message)
diff --git a/qt/python/mantidqt/widgets/tableworkspacedisplay/workbench_table_widget_item.py b/qt/python/mantidqt/widgets/tableworkspacedisplay/workbench_table_widget_item.py
new file mode 100644
index 0000000000000000000000000000000000000000..31086a8dd48ab43c1a9c538f16e665abe7890f70
--- /dev/null
+++ b/qt/python/mantidqt/widgets/tableworkspacedisplay/workbench_table_widget_item.py
@@ -0,0 +1,61 @@
+from qtpy.QtCore import Qt
+from qtpy.QtWidgets import QTableWidgetItem
+
+from mantid.kernel import V3D
+
+
+class WorkbenchTableWidgetItem(QTableWidgetItem):
+    def __init__(self, data, editable=False):
+        # if not editable just initialise the ItemWidget as string
+        if isinstance(data, V3D):
+            self.is_v3d = True
+        else:
+            self.is_v3d = False
+
+        if not editable:
+            QTableWidgetItem.__init__(self, str(data))
+            self.setFlags(self.flags() & ~Qt.ItemIsEditable)
+            return
+
+        QTableWidgetItem.__init__(self)
+
+        if isinstance(data, V3D):
+            data = str(data)
+
+        self.display_data = data
+        # this will correctly turn all number cells into number types
+        self.reset()
+
+    def _get_v3d_from_str(self, string):
+        if '[' in string and ']' in string:
+            string = string[1:-1]
+        if ',' in string:
+            return V3D(*[float(x) for x in string.split(',')])
+        else:
+            raise RuntimeError("'{}' is not a valid V3D string.".format(string))
+
+    def __lt__(self, other):
+        """
+        Overrides the comparison to other items. Used to provide correct sorting for types Qt doesn't handle
+        like V3D. Additionally, it makes sure strings are converted to floats for correct comparison.
+
+        This is necessary because if the data is a float then it is stored as a string.
+
+        :type other: WorkbenchTableWidgetItem
+        :param other: Other item that will be compared against
+        :return:
+        """
+        if self.is_v3d:
+            return self._get_v3d_from_str(self.data(Qt.DisplayRole)) < self._get_v3d_from_str(
+                other.data(Qt.DisplayRole))
+        try:
+            # if the data can be parsed as numbers then compare properly, otherwise default to the Qt implementation
+            return float(self.data(Qt.DisplayRole)) < float(other.data(Qt.DisplayRole))
+        except:
+            return super(WorkbenchTableWidgetItem, self).__lt__(other)
+
+    def reset(self):
+        self.setData(Qt.DisplayRole, self.display_data)
+
+    def update(self):
+        self.display_data = self.data(Qt.DisplayRole)
diff --git a/qt/python/mantidqt/widgets/test/test_fitpropertybrowser.py b/qt/python/mantidqt/widgets/test/test_fitpropertybrowser.py
new file mode 100644
index 0000000000000000000000000000000000000000..47ef66ca53a755a669a5df37650bf78280076f93
--- /dev/null
+++ b/qt/python/mantidqt/widgets/test/test_fitpropertybrowser.py
@@ -0,0 +1,108 @@
+from __future__ import (absolute_import, division, print_function)
+import platform
+import sys
+import unittest
+
+from qtpy import PYQT_VERSION
+from qtpy.QtWidgets import QApplication
+from qtpy.QtCore import Qt, QMetaObject
+
+from mantid import FrameworkManager
+from mantidqt.utils.qt.test.gui_window_test import GuiWindowTest
+from mantidqt.widgets.fitpropertybrowser import FitPropertyBrowserBase
+
+
+def on_ubuntu_or_darwin():
+    return ('Ubuntu' in platform.platform() and sys.version[0] == '2' or
+            sys.platform == 'darwin' and PYQT_VERSION[0] == '4')
+
+
+@unittest.skipIf(on_ubuntu_or_darwin(), "Popups don't show on ubuntu with python 2. Unskip when switched to xvfb."
+                                        "Qt4 has a bug on macs which is fixed in Qt5.")
+class TestFitPropertyBrowser(GuiWindowTest):
+
+    def create_widget(self):
+        return FitPropertyBrowserBase()
+
+    def start_setup_menu(self):
+        self.click_button('button_Setup')
+        return self.wait_for_popup()
+
+    def start_find_peaks(self):
+        self.trigger_action('action_FindPeaks')
+
+    def start_manage_setup(self):
+        a, pm = self.get_action('action_ManageSetup', get_menu=True)
+        pm.setActiveAction(a)
+        m = a.menu()
+        m.show()
+        return self.wait_for_popup()
+
+    def start_load_from_string(self):
+        self.trigger_action('action_LoadFromString')
+        return self.wait_for_modal()
+
+    def set_function_string_blah(self):
+        self.set_function_string('blah')
+        return self.wait_for_modal()
+
+    def set_function_string_linear(self):
+        self.set_function_string('name=LinearBackground')
+        return self.wait_for_true(lambda: self.widget.sizeOfFunctionsGroup() == 3)
+
+    def set_function_string(self, text):
+        box = self.get_active_modal_widget()
+        box.setTextValue(text)
+        QMetaObject.invokeMethod(box, 'accept', Qt.QueuedConnection)
+
+    def test_find_peaks_no_workspace(self):
+        yield self.start_setup_menu()
+        m = self.get_menu('menu_Setup')
+        self.assertTrue(m.isVisible())
+        self.start_find_peaks()
+        yield self.wait_for_modal()
+        box = self.get_active_modal_widget()
+        self.assertEqual(box.text(), 'Workspace name is not set')
+        box.close()
+
+    def test_load_from_string_blah(self):
+        yield self.start_setup_menu()
+        yield self.start_manage_setup()
+        yield self.start_load_from_string()
+        yield self.set_function_string_blah()
+        box = self.get_active_modal_widget()
+        self.assertEqual(box.text(),
+                         "Unexpected exception caught:\n\nError in input string to FunctionFactory\nblah")
+        box.close()
+
+    def test_load_from_string_lb(self):
+        yield self.start_setup_menu()
+        yield self.start_manage_setup()
+        yield self.start_load_from_string()
+        yield self.set_function_string_linear()
+        a = self.widget.getFittingFunction()
+        self.assertEqual(a, 'name=LinearBackground,A0=0,A1=0')
+        self.assertEqual(self.widget.sizeOfFunctionsGroup(), 3)
+
+    def test_copy_to_clipboard(self):
+        self.widget.loadFunction('name=LinearBackground,A0=0,A1=0')
+        yield self.start_setup_menu()
+        yield self.start_manage_setup()
+        QApplication.clipboard().clear()
+        self.trigger_action('action_CopyToClipboard')
+        yield self.wait_for_true(lambda: QApplication.clipboard().text() != '')
+        self.assertEqual(QApplication.clipboard().text(), 'name=LinearBackground,A0=0,A1=0')
+
+    def test_clear_model(self):
+        self.widget.loadFunction('name=LinearBackground,A0=0,A1=0')
+        self.assertEqual(self.widget.sizeOfFunctionsGroup(), 3)
+        yield self.start_setup_menu()
+        yield self.start_manage_setup()
+        self.trigger_action('action_ClearModel')
+        yield self.wait_for_true(lambda: self.widget.sizeOfFunctionsGroup() == 2)
+        self.assertEqual(self.widget.sizeOfFunctionsGroup(), 2)
+
+
+if __name__ == '__main__':
+    unittest.main()
+    FrameworkManager.clear()
diff --git a/qt/python/mantidqtpython/mantidqtpython_def.sip b/qt/python/mantidqtpython/mantidqtpython_def.sip
index 071b3c692509323a7b5e319a7cc09eae74de9df3..275edc5bfba5b2fecb4840dc675227521ede9f04 100644
--- a/qt/python/mantidqtpython/mantidqtpython_def.sip
+++ b/qt/python/mantidqtpython/mantidqtpython_def.sip
@@ -1528,7 +1528,47 @@ public:
   virtual std::vector<MantidQt::MantidWidgets::Hint> createHints();
 };
 
+// ---------------------------------
+// WorkspaceWidget and dependencies
+// ---------------------------------
 
+class MantidDisplayBase /Abstract/ {
+%TypeHeaderCode
+#include "MantidQtWidgets/Common/MantidDisplayBase.h"
+%End
+private:
+  MantidDisplayBase();
+};
+
+class MantidTreeModel : MantidQt::MantidWidgets::MantidDisplayBase {
+%TypeHeaderCode
+#include "MantidQtWidgets/Common/MantidTreeModel.h"
+%End
+public:
+  MantidTreeModel();
+private:
+  MantidTreeModel(const MantidQt::MantidWidgets::MantidTreeModel &);
+};
+
+class WorkspaceTreeWidget : QWidget {
+%TypeHeaderCode
+#include "MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h"
+%End
+public:
+  WorkspaceTreeWidget(MantidQt::MantidWidgets::MantidDisplayBase *mdb /Transfer/, bool viewOnly=false,
+                      QWidget *parent /TransferThis/ = nullptr);
+  void refreshWorkspaces();
+  std::vector<std::string> getSelectedWorkspaceNames() const;
+};
+
+// Implementation to override context menu
+class WorkspaceTreeWidgetSimple : MantidQt::MantidWidgets::WorkspaceTreeWidget {
+%TypeHeaderCode
+#include "MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h"
+%End
+public:
+  WorkspaceTreeWidgetSimple(bool viewOnly=false, QWidget *parent /TransferThis/ = nullptr);
+};
 }; // end namespace MantidWidgets
 }; // end namespace MantidQt
 
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflSettingsView.h b/qt/scientific_interfaces/ISISReflectometry/IReflSettingsView.h
index 6456604a05dae210b5b6b424854df3bada122cd0..c098ed8d0b75a94f02c4a874f2d8bd7228af28a5 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflSettingsView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflSettingsView.h
@@ -55,6 +55,8 @@ public:
   virtual std::string getCAlpha() const = 0;
   virtual std::string getCAp() const = 0;
   virtual std::string getCPp() const = 0;
+  virtual std::string getFloodCorrection() const = 0;
+  virtual std::string getFloodWorkspace() const = 0;
   /// Instrument settings
   virtual std::string getIntMonCheck() const = 0;
   virtual std::string getMonitorIntegralMin() const = 0;
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.cpp b/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.cpp
index dd7e68e2f9bf7a09f8104b53f0ec7348c5dcc526..33dadad6f9be5d7200c28045ea888e242b534494 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.cpp
@@ -45,6 +45,7 @@ Initialise the Interface
 void QtReflSettingsView::initLayout() {
   m_ui.setupUi(this);
   initOptionsTable();
+  initFloodCorControls();
 
   connect(m_ui.getExpDefaultsButton, SIGNAL(clicked()), this,
           SLOT(requestExpDefaults()));
@@ -60,6 +61,8 @@ void QtReflSettingsView::initLayout() {
           SLOT(setDetectorCorrectionEnabled(bool)));
   connect(m_ui.polCorrComboBox, SIGNAL(currentIndexChanged(int)), this,
           SLOT(setPolCorPageForIndex(int)));
+  connect(m_ui.floodCorComboBox, SIGNAL(currentIndexChanged(const QString &)),
+          this, SLOT(floodCorComboBoxChanged(const QString &)));
 }
 
 void QtReflSettingsView::initOptionsTable() {
@@ -84,6 +87,11 @@ void QtReflSettingsView::initOptionsTable() {
   table->setMinimumHeight(totalRowHeight + header->height() + padding);
 }
 
+void QtReflSettingsView::initFloodCorControls() {
+  m_ui.floodWorkspaceWsSelector->setOptional(true);
+  m_ui.floodWorkspaceWsSelector->setWorkspaceTypes({"Workspace2D"});
+}
+
 void QtReflSettingsView::connectSettingsChange(QLineEdit &edit) {
   connect(&edit, SIGNAL(textChanged(QString const &)), this,
           SLOT(notifySettingsChanged()));
@@ -164,6 +172,8 @@ void QtReflSettingsView::registerExperimentSettingsWidgets(
   registerSettingWidget(*m_ui.CApEdit, "CAp", alg);
   registerSettingWidget(*m_ui.CPpEdit, "CPp", alg);
   registerSettingWidget(stitchOptionsLineEdit(), "Params", alg);
+  registerSettingWidget(*m_ui.floodCorComboBox, "FloodCorrection", alg);
+  registerSettingWidget(*m_ui.floodWorkspaceWsSelector, "FloodWorkspace", alg);
 }
 
 void QtReflSettingsView::notifySettingsChanged() {
@@ -425,6 +435,12 @@ void QtReflSettingsView::addPerAngleOptionsTableRow() {
   m_ui.optionsTable->setCurrentCell(numRows - 1, 0);
 }
 
+void QtReflSettingsView::floodCorComboBoxChanged(const QString &text) {
+  auto const showWorkspaceSelector = text == "Workspace";
+  m_ui.floodWorkspaceWsSelector->setVisible(showWorkspaceSelector);
+  m_ui.floodWorkspaceWsSelectorLabel->setVisible(showWorkspaceSelector);
+}
+
 std::string QtReflSettingsView::getText(QLineEdit const &lineEdit) const {
   return lineEdit.text().toStdString();
 }
@@ -502,7 +518,7 @@ void QtReflSettingsView::createStitchHints(const std::vector<Hint> &hints) {
                                            &rowSpan, &colSpan);
   // Create the new edit box and add it to the right of the label
   m_stitchEdit = new HintingLineEdit(this, hints);
-  m_ui.expSettingsLayout0->addWidget(m_stitchEdit, row, col + colSpan, 1, 3);
+  m_ui.expSettingsLayout0->addWidget(m_stitchEdit, row, col + colSpan, 1, 1);
 }
 
 /** Return selected analysis mode
@@ -608,6 +624,14 @@ std::string QtReflSettingsView::getCPp() const {
   return getText(*m_ui.CPpEdit);
 }
 
+std::string QtReflSettingsView::getFloodCorrection() const {
+  return getText(*m_ui.floodCorComboBox);
+}
+
+std::string QtReflSettingsView::getFloodWorkspace() const {
+  return getText(*m_ui.floodWorkspaceWsSelector);
+}
+
 /** Return integrated monitors option
  * @return :: integrated monitors check
  */
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.h b/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.h
index b7bc35d69cae71c47de7724c0b548bc563784415..3351e2426852ab4351c77c7e3d733e8bb25098a8 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflSettingsView.h
@@ -58,6 +58,10 @@ public:
   std::string getCAp() const override;
   /// Return Cpp
   std::string getCPp() const override;
+  /// Return FloodCorrection
+  std::string getFloodCorrection() const override;
+  /// Return FloodWorkspace
+  std::string getFloodWorkspace() const override;
   /// Return integrated monitors option
   std::string getIntMonCheck() const override;
   /// Return monitor integral wavelength min
@@ -125,11 +129,13 @@ public slots:
 
 private slots:
   void setPolCorPageForIndex(int index);
+  void floodCorComboBoxChanged(const QString &text);
 
 private:
   /// Initialise the interface
   void initLayout();
   void initOptionsTable();
+  void initFloodCorControls();
   void registerSettingsWidgets(Mantid::API::IAlgorithm_sptr alg);
   void registerInstrumentSettingsWidgets(Mantid::API::IAlgorithm_sptr alg);
   void registerExperimentSettingsWidgets(Mantid::API::IAlgorithm_sptr alg);
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsPresenter.cpp
index 61c7b89f5428dac6eb261ac63c6415c17964651f..32f2d8f81cc9f412bb0f952007bd89607cd7daa5 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsPresenter.cpp
@@ -239,6 +239,8 @@ OptionsQMap ReflSettingsPresenter::getReductionOptions() const {
       addIfNotEmpty(options, "CAp", m_view->getCAp());
       addIfNotEmpty(options, "CPp", m_view->getCPp());
     }
+    addIfNotEmpty(options, "FloodCorrection", m_view->getFloodCorrection());
+    addIfNotEmpty(options, "FloodWorkspace", m_view->getFloodWorkspace());
     addIfNotEmpty(options, "StartOverlap", m_view->getStartOverlap());
     addIfNotEmpty(options, "EndOverlap", m_view->getEndOverlap());
 
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
index b30520a301b423006cb0c7f9c98066ed29824680..21842375ab631d41b5e4af835408e7ca4d492276 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
@@ -453,6 +453,37 @@
           </property>
          </widget>
         </item>
+        <item row="7" column="2">
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Flood Correction</string>
+          </property>
+         </widget>
+        </item>
+        <item row="8" column="2">
+         <widget class="QLabel" name="floodWorkspaceWsSelectorLabel">
+          <property name="text">
+           <string>Flood Workspace</string>
+          </property>
+         </widget>
+        </item>
+        <item row="7" column="3">
+         <widget class="QComboBox" name="floodCorComboBox">
+          <item>
+           <property name="text">
+            <string>Workspace</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>ParameterFile</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="8" column="3">
+         <widget class="MantidQt::MantidWidgets::WorkspaceSelector" name="floodWorkspaceWsSelector"/>
+        </item>
        </layout>
       </item>
       <item>
@@ -790,6 +821,13 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>MantidQt::MantidWidgets::WorkspaceSelector</class>
+   <extends>QComboBox</extends>
+   <header>MantidQtWidgets/Common/WorkspaceSelector.h</header>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/qt/scientific_interfaces/Indirect/CMakeLists.txt b/qt/scientific_interfaces/Indirect/CMakeLists.txt
index f3319726973fef3bf1a82681c244275ec6742406..16a1efc40fb38d955d6920a71c0fdb3900ea7208 100644
--- a/qt/scientific_interfaces/Indirect/CMakeLists.txt
+++ b/qt/scientific_interfaces/Indirect/CMakeLists.txt
@@ -81,6 +81,7 @@ set ( INC_FILES
 	DensityOfStates.h
 	Elwin.h
 	IAddWorkspaceDialog.h
+	IIndirectFitDataView.h
 	IIndirectFitPlotView.h
 	ILLEnergyTransfer.h
 	ISISCalibration.h
@@ -148,6 +149,8 @@ set ( MOC_FILES
     CorrectionsTab.h
     DensityOfStates.h
     Elwin.h
+    IAddWorkspaceDialog.h
+    IIndirectFitDataView.h
     IIndirectFitPlotView.h
     ILLEnergyTransfer.h
     IndirectAddWorkspaceDialog.h
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp
index ec038f7f165c2039f340a79ac2c508310b7b38a0..6050d8c58d90035ea920163aa209bbd0a23efec0 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp
@@ -53,9 +53,9 @@ void ConvFit::setupFitTab() {
   setConvolveMembers(true);
 
   setSampleWSSuffices({"_red", "_sqw"});
-  setSampleFBSuffices({"_red.nxs", "_sqw.nxs"});
+  setSampleFBSuffices({"_red.nxs", "_sqw.nxs", "_sqw.dave"});
   setResolutionWSSuffices({"_res", "_red", "_sqw"});
-  setResolutionFBSuffices({"_res.nxs", "_red.nxs", "_sqw.nxs"});
+  setResolutionFBSuffices({"_res.nxs", "_red.nxs", "_sqw.nxs", "_sqw.dave"});
 
   // Initialise fitTypeStrings
   m_fitStrings["None"] = "";
diff --git a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.cpp b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.cpp
index 46b0024440a929a37335dbfe0191794a930d02b4..2a4471f7079f66be0a746ecb06c183281afcad9c 100644
--- a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.cpp
@@ -80,6 +80,8 @@ ConvFitAddWorkspaceDialog::ConvFitAddWorkspaceDialog(QWidget *parent)
           SLOT(workspaceChanged(const QString &)));
   connect(m_uiForm.ckAllSpectra, SIGNAL(stateChanged(int)), this,
           SLOT(selectAllSpectra(int)));
+  connect(m_uiForm.pbAdd, SIGNAL(clicked()), this, SIGNAL(addData()));
+  connect(m_uiForm.pbClose, SIGNAL(clicked()), this, SIGNAL(closeDialog()));
 }
 
 std::string ConvFitAddWorkspaceDialog::workspaceName() const {
diff --git a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui
index e1634010baceac7f32c3a4d3eebe5d8e4af6b115..a0a25e0a49091019764c39e960d363c52259d962 100644
--- a/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui
+++ b/qt/scientific_interfaces/Indirect/ConvFitAddWorkspaceDialog.ui
@@ -98,13 +98,48 @@
     </widget>
    </item>
    <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
+    <widget class="QFrame" name="frame">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbAdd">
+        <property name="text">
+         <string>Add</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbClose">
+        <property name="text">
+         <string>Close</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
   </layout>
@@ -119,36 +154,40 @@
  <resources/>
  <connections>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
+   <sender>pbAdd</sender>
+   <signal>clicked()</signal>
    <receiver>ConvFitAddWorkspaceDialog</receiver>
-   <slot>accept()</slot>
+   <slot>addData()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
+     <x>276</x>
+     <y>160</y>
     </hint>
     <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
+     <x>269</x>
+     <y>319</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
+   <sender>pbClose</sender>
+   <signal>clicked()</signal>
    <receiver>ConvFitAddWorkspaceDialog</receiver>
-   <slot>reject()</slot>
+   <slot>closeDialog()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
+     <x>340</x>
+     <y>171</y>
     </hint>
     <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
+     <x>335</x>
+     <y>251</y>
     </hint>
    </hints>
   </connection>
  </connections>
+ <slots>
+  <slot>addData()</slot>
+  <slot>closeDialog()</slot>
+ </slots>
 </ui>
diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp
index 676e3213ee5e5ba9cd12c4d759324a21bc51ab87..bea09c66563c3a4e5f4344f6f09311005e4059b4 100644
--- a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.cpp
@@ -8,14 +8,24 @@
 #include "ConvFitAddWorkspaceDialog.h"
 #include "ConvFitDataTablePresenter.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/make_unique.h"
 
+namespace {
+using namespace Mantid::API;
+
+bool isWorkspaceLoaded(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().doesExist(workspaceName);
+}
+
+} // namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
 ConvFitDataPresenter::ConvFitDataPresenter(ConvFitModel *model,
-                                           IndirectFitDataView *view)
+                                           IIndirectFitDataView *view)
     : IndirectFitDataPresenter(
           model, view,
           Mantid::Kernel::make_unique<ConvFitDataTablePresenter>(
@@ -53,7 +63,7 @@ void ConvFitDataPresenter::addWorkspace(ConvFitAddWorkspaceDialog const *dialog,
 void ConvFitDataPresenter::addModelData(const std::string &name) {
   IndirectFitDataPresenter::addModelData(name);
   const auto resolution = getView()->getSelectedResolution();
-  if (!resolution.empty())
+  if (!resolution.empty() && isWorkspaceLoaded(resolution))
     m_convModel->setResolution(resolution, 0);
 }
 
diff --git a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h
index 071d6fb43eb5f05c9e17e87001d7efbed10b4884..f4626227864555e7883c7d3ee487e0c46c350b38 100644
--- a/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h
+++ b/qt/scientific_interfaces/Indirect/ConvFitDataPresenter.h
@@ -16,13 +16,11 @@ namespace IDA {
 
 class ConvFitAddWorkspaceDialog;
 
-/**
-  A presenter.
-*/
-class DLLExport ConvFitDataPresenter : public IndirectFitDataPresenter {
+class MANTIDQT_INDIRECT_DLL ConvFitDataPresenter
+    : public IndirectFitDataPresenter {
   Q_OBJECT
 public:
-  ConvFitDataPresenter(ConvFitModel *model, IndirectFitDataView *view);
+  ConvFitDataPresenter(ConvFitModel *model, IIndirectFitDataView *view);
 
 private slots:
   void setModelResolution(const QString &name);
diff --git a/qt/scientific_interfaces/Indirect/ConvFitModel.h b/qt/scientific_interfaces/Indirect/ConvFitModel.h
index badb10a48fdd9bf9aa79875c47e73483b7e28bac..f8bd76cf9fbd61d768772d048fe025f8540cae4e 100644
--- a/qt/scientific_interfaces/Indirect/ConvFitModel.h
+++ b/qt/scientific_interfaces/Indirect/ConvFitModel.h
@@ -15,6 +15,8 @@ namespace IDA {
 
 class DLLExport ConvFitModel : public IndirectFittingModel {
 public:
+  using IndirectFittingModel::addWorkspace;
+
   ConvFitModel();
   ~ConvFitModel() override;
 
diff --git a/qt/scientific_interfaces/Indirect/DensityOfStates.cpp b/qt/scientific_interfaces/Indirect/DensityOfStates.cpp
index 7fd5aac8a620afb305591a3608983fa4e3b15604..8f1dd0131015a0b4411747a8dbeab4bb3eb2c386 100644
--- a/qt/scientific_interfaces/Indirect/DensityOfStates.cpp
+++ b/qt/scientific_interfaces/Indirect/DensityOfStates.cpp
@@ -28,9 +28,10 @@ DensityOfStates::DensityOfStates(QWidget *parent)
 
   connect(m_uiForm.mwInputFile, SIGNAL(filesFound()), this,
           SLOT(handleFileChange()));
-  // Handle plot and save
-  connect(m_uiForm.pbSave, SIGNAL(clicked()), this, SLOT(saveClicked()));
+
+  connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked()));
   connect(m_uiForm.pbPlot, SIGNAL(clicked()), this, SLOT(plotClicked()));
+  connect(m_uiForm.pbSave, SIGNAL(clicked()), this, SLOT(saveClicked()));
 
   m_uiForm.lwIons->setSelectionMode(QAbstractItemView::MultiSelection);
 }
@@ -68,8 +69,10 @@ bool DensityOfStates::validate() {
  * Configures and executes the DensityOfStates algorithm.
  */
 void DensityOfStates::run() {
+  setRunIsRunning(true);
+
   // Get the SimulatedDensityOfStates algorithm
-  IAlgorithm_sptr dosAlgo =
+  auto dosAlgo =
       AlgorithmManager::Instance().create("SimulatedDensityOfStates");
 
   const auto filename = m_uiForm.mwInputFile->getFirstFilename();
@@ -153,8 +156,11 @@ void DensityOfStates::dosAlgoComplete(bool error) {
   disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
              SLOT(dosAlgoComplete(bool)));
 
-  if (error)
-    return;
+  setRunIsRunning(false);
+  if (error) {
+    setPlotEnabled(false);
+    setSaveEnabled(false);
+  }
 }
 
 /**
@@ -212,7 +218,7 @@ void DensityOfStates::ionLoadComplete(bool error) {
     g_log.error("Could not get a list of ions from .phonon file");
 
   // Get the list of ions from algorithm
-  ITableWorkspace_sptr ionTable =
+  auto ionTable =
       AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("__dos_ions");
   Column_sptr ionColumn = ionTable->getColumn("Species");
   size_t numIons = ionColumn->size();
@@ -232,9 +238,6 @@ void DensityOfStates::ionLoadComplete(bool error) {
 
   // Select all ions by default
   m_uiForm.lwIons->selectAll();
-  // Enable plot and save
-  m_uiForm.pbPlot->setEnabled(true);
-  m_uiForm.pbSave->setEnabled(true);
 }
 
 /**
@@ -247,12 +250,16 @@ void DensityOfStates::loadSettings(const QSettings &settings) {
   m_uiForm.mwInputFile->readSettings(settings.group());
 }
 
+void DensityOfStates::runClicked() { runTab(); }
+
 /**
  * Handle mantid plotting of workspace
  */
 void DensityOfStates::plotClicked() {
+  setPlotIsPlotting(true);
   if (checkADSForPlotSaveWorkspace(m_outputWsName.toStdString(), true))
     plotSpectrum(m_outputWsName);
+  setPlotIsPlotting(false);
 }
 
 /**
@@ -264,5 +271,33 @@ void DensityOfStates::saveClicked() {
   m_batchAlgoRunner->executeBatchAsync();
 }
 
+void DensityOfStates::setRunIsRunning(bool running) {
+  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
+  setButtonsEnabled(!running);
+}
+
+void DensityOfStates::setPlotIsPlotting(bool running) {
+  m_uiForm.pbPlot->setText(running ? "Plotting..." : "Plot Result");
+  setButtonsEnabled(!running);
+}
+
+void DensityOfStates::setButtonsEnabled(bool enabled) {
+  setRunEnabled(enabled);
+  setPlotEnabled(enabled);
+  setSaveEnabled(enabled);
+}
+
+void DensityOfStates::setRunEnabled(bool enabled) {
+  m_uiForm.pbRun->setEnabled(enabled);
+}
+
+void DensityOfStates::setPlotEnabled(bool enabled) {
+  m_uiForm.pbPlot->setEnabled(enabled);
+}
+
+void DensityOfStates::setSaveEnabled(bool enabled) {
+  m_uiForm.pbSave->setEnabled(enabled);
+}
+
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/DensityOfStates.h b/qt/scientific_interfaces/Indirect/DensityOfStates.h
index 15e12577cf3a3d1e1e3385a1721d8db1044c747a..58da9a0baf9e2cd74d926afdb2a7861790ce0650 100644
--- a/qt/scientific_interfaces/Indirect/DensityOfStates.h
+++ b/qt/scientific_interfaces/Indirect/DensityOfStates.h
@@ -31,11 +31,18 @@ private slots:
   void dosAlgoComplete(bool error);
   void handleFileChange();
   void ionLoadComplete(bool error);
-  /// Handle plotting and saving
+  void runClicked();
   void plotClicked();
   void saveClicked();
 
 private:
+  void setRunIsRunning(bool running);
+  void setPlotIsPlotting(bool plotting);
+  void setButtonsEnabled(bool enabled);
+  void setRunEnabled(bool enabled);
+  void setPlotEnabled(bool enabled);
+  void setSaveEnabled(bool enabled);
+
   /// The ui form
   Ui::DensityOfStates m_uiForm;
   /// Name of output workspace
diff --git a/qt/scientific_interfaces/Indirect/DensityOfStates.ui b/qt/scientific_interfaces/Indirect/DensityOfStates.ui
index 7aa9543c7b0084a2f7c44f39a4150295c0daee4a..fd23990a3976ae3e7a25d4e3ff8cbc469094e408 100644
--- a/qt/scientific_interfaces/Indirect/DensityOfStates.ui
+++ b/qt/scientific_interfaces/Indirect/DensityOfStates.ui
@@ -56,7 +56,7 @@
         <x>0</x>
         <y>0</y>
         <width>480</width>
-        <height>379</height>
+        <height>328</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_3">
@@ -242,7 +242,16 @@
          </property>
          <widget class="QWidget" name="pgDOS">
           <layout class="QGridLayout" name="gridLayout_2">
-           <property name="margin">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
             <number>0</number>
            </property>
            <item row="0" column="0">
@@ -413,14 +422,32 @@
            </sizepolicy>
           </property>
           <layout class="QGridLayout" name="gridLayout_3">
-           <property name="margin">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
             <number>0</number>
            </property>
           </layout>
          </widget>
          <widget class="QWidget" name="pgRaman">
           <layout class="QGridLayout" name="gridLayout_4">
-           <property name="margin">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
             <number>0</number>
            </property>
            <item row="0" column="0">
@@ -485,6 +512,60 @@
      </widget>
     </widget>
    </item>
+   <item>
+    <widget class="QGroupBox" name="gbRun">
+     <property name="title">
+      <string>Run</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>7</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>194</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbRun">
+        <property name="text">
+         <string>Run</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>193</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
     <widget class="QGroupBox" name="gbOutput">
      <property name="sizePolicy">
diff --git a/qt/scientific_interfaces/Indirect/Elwin.cpp b/qt/scientific_interfaces/Indirect/Elwin.cpp
index ee340dfee7316ccae7747e8ac4e5aa3d72a8a18e..e449ea05131c0fb2da64d5cb252045ae5ed2ae2a 100644
--- a/qt/scientific_interfaces/Indirect/Elwin.cpp
+++ b/qt/scientific_interfaces/Indirect/Elwin.cpp
@@ -8,6 +8,7 @@
 #include "../General/UserInputValidator.h"
 
 #include "MantidGeometry/Instrument.h"
+#include "MantidQtWidgets/Common/SignalBlocker.h"
 #include "MantidQtWidgets/LegacyQwt/RangeSelector.h"
 
 #include <QFileInfo>
@@ -25,10 +26,30 @@ MatrixWorkspace_sptr getADSMatrixWorkspace(std::string const &workspaceName) {
       workspaceName);
 }
 
+bool doesExistInADS(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().doesExist(workspaceName);
+}
+
 bool isWorkspacePlottable(MatrixWorkspace_sptr workspace) {
   return workspace->y(0).size() > 1;
 }
 
+bool isWorkspacePlottable(std::string const &workspaceName) {
+  return isWorkspacePlottable(getADSMatrixWorkspace(workspaceName));
+}
+
+bool canPlotWorkspace(std::string const &workspaceName) {
+  return doesExistInADS(workspaceName) && isWorkspacePlottable(workspaceName);
+}
+
+std::vector<std::string> getOutputWorkspaceSuffices() {
+  return {"_eq", "_eq2", "_elf", "_elt"};
+}
+
+int getNumberOfSpectra(std::string const &name) {
+  return static_cast<int>(getADSMatrixWorkspace(name)->getNumberHistograms());
+}
+
 } // namespace
 
 namespace MantidQt {
@@ -124,6 +145,9 @@ void Elwin::setup() {
   connect(m_uiForm.pbPlotPreview, SIGNAL(clicked()), this,
           SLOT(plotCurrentPreview()));
 
+  connect(m_uiForm.cbPlotWorkspace, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(updateAvailablePlotSpectra()));
+
   // Set any default values
   m_dblManager->setValue(m_properties["IntegrationStart"], -0.02);
   m_dblManager->setValue(m_properties["IntegrationEnd"], 0.02);
@@ -194,8 +218,7 @@ void Elwin::run() {
   }
 
   // Group input workspaces
-  IAlgorithm_sptr groupWsAlg =
-      AlgorithmManager::Instance().create("GroupWorkspaces");
+  auto groupWsAlg = AlgorithmManager::Instance().create("GroupWorkspaces");
   groupWsAlg->initialize();
   API::BatchAlgorithmRunner::AlgorithmRuntimeProps runTimeProps;
   runTimeProps["InputWorkspaces"] = inputWorkspacesString;
@@ -204,7 +227,7 @@ void Elwin::run() {
   m_batchAlgoRunner->addAlgorithm(groupWsAlg, runTimeProps);
 
   // Configure ElasticWindowMultiple algorithm
-  IAlgorithm_sptr elwinMultAlg =
+  auto elwinMultAlg =
       AlgorithmManager::Instance().create("ElasticWindowMultiple");
   elwinMultAlg->initialize();
 
@@ -260,18 +283,63 @@ void Elwin::unGroupInput(bool error) {
 
   if (!error) {
     if (!m_uiForm.ckGroupInput->isChecked()) {
-      IAlgorithm_sptr ungroupAlg =
-          AlgorithmManager::Instance().create("UnGroupWorkspace");
+      auto ungroupAlg = AlgorithmManager::Instance().create("UnGroupWorkspace");
       ungroupAlg->initialize();
       ungroupAlg->setProperty("InputWorkspace", "IDA_Elwin_Input");
       ungroupAlg->execute();
     }
+
+    updatePlotSpectrumOptions();
+
   } else {
     setPlotResultEnabled(false);
     setSaveResultEnabled(false);
   }
 }
 
+void Elwin::updatePlotSpectrumOptions() {
+  updateAvailablePlotWorkspaces();
+  if (m_uiForm.cbPlotWorkspace->size().isEmpty())
+    setPlotResultEnabled(false);
+  else
+    updateAvailablePlotSpectra();
+}
+
+void Elwin::updateAvailablePlotWorkspaces() {
+  MantidQt::API::SignalBlocker<QObject> blocker(m_uiForm.cbPlotWorkspace);
+  m_uiForm.cbPlotWorkspace->clear();
+  for (auto const &suffix : getOutputWorkspaceSuffices()) {
+    auto const workspaceName = getOutputBasename().toStdString() + suffix;
+    if (canPlotWorkspace(workspaceName))
+      m_uiForm.cbPlotWorkspace->addItem(QString::fromStdString(workspaceName));
+  }
+}
+
+QString Elwin::getPlotWorkspaceName() const {
+  return m_uiForm.cbPlotWorkspace->currentText();
+}
+
+void Elwin::setPlotSpectrumValue(int value) {
+  MantidQt::API::SignalBlocker<QObject> blocker(m_uiForm.spPlotSpectrum);
+  m_uiForm.spPlotSpectrum->setValue(value);
+}
+
+void Elwin::updateAvailablePlotSpectra() {
+  auto const name = m_uiForm.cbPlotWorkspace->currentText().toStdString();
+  auto const maximumValue = getNumberOfSpectra(name) - 1;
+  setPlotSpectrumMinMax(0, maximumValue);
+  setPlotSpectrumValue(0);
+}
+
+void Elwin::setPlotSpectrumMinMax(int minimum, int maximum) {
+  m_uiForm.spPlotSpectrum->setMinimum(minimum);
+  m_uiForm.spPlotSpectrum->setMaximum(maximum);
+}
+
+int Elwin::getPlotSpectrumIndex() const {
+  return m_uiForm.spPlotSpectrum->text().toInt();
+}
+
 bool Elwin::validate() {
   UserInputValidator uiv;
 
@@ -474,87 +542,63 @@ void Elwin::updateRS(QtProperty *prop, double val) {
     backgroundRangeSelector->setMaximum(val);
 }
 
+void Elwin::runClicked() { runTab(); }
+
 /**
  * Handles mantid plotting
  */
 void Elwin::plotClicked() {
   setPlotResultIsPlotting(true);
-
-  auto const workspaceBaseName =
-      getWorkspaceBasename(QString::fromStdString(m_pythonExportWsName));
-
-  plotResult(workspaceBaseName + "_eq");
-  plotResult(workspaceBaseName + "_eq2");
-  plotResult(workspaceBaseName + "_elf");
-  plotResult(workspaceBaseName + "_elt");
-
+  plotSpectrum(getPlotWorkspaceName(), getPlotSpectrumIndex());
   setPlotResultIsPlotting(false);
 }
 
-void Elwin::plotResult(QString const &workspaceName) {
-  auto const name = workspaceName.toStdString();
-  if (checkADSForPlotSaveWorkspace(name, true)) {
-    if (isWorkspacePlottable(getADSMatrixWorkspace(name)))
-      plotSpectrum(workspaceName);
-    else
-      showMessageBox("Plotting a spectrum of the workspace " + workspaceName +
-                     " failed : Workspace only has one data point");
-  }
-}
-
 /**
  * Handles saving of workspaces
  */
 void Elwin::saveClicked() {
-  auto workspaceBaseName =
-      getWorkspaceBasename(QString::fromStdString(m_pythonExportWsName));
-
-  if (checkADSForPlotSaveWorkspace((workspaceBaseName + "_eq").toStdString(),
-                                   false))
-    addSaveWorkspaceToQueue(workspaceBaseName + "_eq");
-
-  if (checkADSForPlotSaveWorkspace((workspaceBaseName + "_eq2").toStdString(),
-                                   false))
-    addSaveWorkspaceToQueue(workspaceBaseName + "_eq2");
-
-  if (checkADSForPlotSaveWorkspace((workspaceBaseName + "_elf").toStdString(),
-                                   false))
-    addSaveWorkspaceToQueue(workspaceBaseName + "_elf");
+  auto const workspaceBaseName = getOutputBasename().toStdString();
 
-  if (checkADSForPlotSaveWorkspace((workspaceBaseName + "_elt").toStdString(),
-                                   false, false))
-    addSaveWorkspaceToQueue(workspaceBaseName + "_elt");
+  for (auto const &suffix : getOutputWorkspaceSuffices())
+    if (checkADSForPlotSaveWorkspace(workspaceBaseName + suffix, false))
+      addSaveWorkspaceToQueue(workspaceBaseName + suffix);
 
   m_batchAlgoRunner->executeBatchAsync();
 }
 
-void Elwin::setRunEnabled(bool enabled) { m_uiForm.pbRun->setEnabled(enabled); }
+QString Elwin::getOutputBasename() {
+  return getWorkspaceBasename(QString::fromStdString(m_pythonExportWsName));
+}
 
-void Elwin::setPlotResultEnabled(bool enabled) {
-  m_uiForm.pbPlot->setEnabled(enabled);
+void Elwin::setRunIsRunning(const bool &running) {
+  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
+  setButtonsEnabled(!running);
 }
 
-void Elwin::setSaveResultEnabled(bool enabled) {
-  m_uiForm.pbSave->setEnabled(enabled);
+void Elwin::setPlotResultIsPlotting(const bool &plotting) {
+  m_uiForm.pbPlot->setText(plotting ? "Plotting..." : "Plot Spectrum");
+  setButtonsEnabled(!plotting);
 }
 
-void Elwin::setButtonsEnabled(bool enabled) {
+void Elwin::setButtonsEnabled(const bool &enabled) {
   setRunEnabled(enabled);
   setPlotResultEnabled(enabled);
   setSaveResultEnabled(enabled);
 }
 
-void Elwin::setRunIsRunning(bool running) {
-  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
-  setButtonsEnabled(!running);
+void Elwin::setRunEnabled(const bool &enabled) {
+  m_uiForm.pbRun->setEnabled(enabled);
 }
 
-void Elwin::setPlotResultIsPlotting(bool plotting) {
-  m_uiForm.pbPlot->setText(plotting ? "Plotting..." : "Plot Result");
-  setButtonsEnabled(!plotting);
+void Elwin::setPlotResultEnabled(const bool &enabled) {
+  m_uiForm.pbPlot->setEnabled(enabled);
+  m_uiForm.cbPlotWorkspace->setEnabled(enabled);
+  m_uiForm.spPlotSpectrum->setEnabled(enabled);
 }
 
-void Elwin::runClicked() { runTab(); }
+void Elwin::setSaveResultEnabled(const bool &enabled) {
+  m_uiForm.pbSave->setEnabled(enabled);
+}
 
 } // namespace IDA
 } // namespace CustomInterfaces
diff --git a/qt/scientific_interfaces/Indirect/Elwin.h b/qt/scientific_interfaces/Indirect/Elwin.h
index f47943fa8be03426fe78f5599323074abdc383b4..07f26e161d093c10509cc1590f790c0e1247b1ac 100644
--- a/qt/scientific_interfaces/Indirect/Elwin.h
+++ b/qt/scientific_interfaces/Indirect/Elwin.h
@@ -29,6 +29,7 @@ private slots:
   void maxChanged(double val);
   void updateRS(QtProperty *prop, double val);
   void unGroupInput(bool error);
+  void updateAvailablePlotSpectra();
   void runClicked();
   void saveClicked();
   void plotClicked();
@@ -43,14 +44,21 @@ private:
                             const QPair<double, double> &range);
   void setDefaultSampleLog(Mantid::API::MatrixWorkspace_const_sptr ws);
 
-  void plotResult(QString const &workspaceName);
+  QString getOutputBasename();
 
-  void setRunEnabled(bool enabled);
-  void setPlotResultEnabled(bool enabled);
-  void setSaveResultEnabled(bool enabled);
-  void setButtonsEnabled(bool enabled);
-  void setRunIsRunning(bool running);
-  void setPlotResultIsPlotting(bool plotting);
+  void updatePlotSpectrumOptions();
+  void updateAvailablePlotWorkspaces();
+  QString getPlotWorkspaceName() const;
+  void setPlotSpectrumValue(int value);
+  void setPlotSpectrumMinMax(int minimum, int maximum);
+  int getPlotSpectrumIndex() const;
+
+  void setRunIsRunning(const bool &running);
+  void setPlotResultIsPlotting(const bool &plotting);
+  void setButtonsEnabled(const bool &enabled);
+  void setRunEnabled(const bool &enabled);
+  void setPlotResultEnabled(const bool &enabled);
+  void setSaveResultEnabled(const bool &enabled);
 
   Ui::Elwin m_uiForm;
   QtTreePropertyBrowser *m_elwTree;
diff --git a/qt/scientific_interfaces/Indirect/Elwin.ui b/qt/scientific_interfaces/Indirect/Elwin.ui
index 9a006e4f6f6588c8dda39978be6957c52429aca9..7439abe27aee0e78f0934395d48ad8c60cec4076 100644
--- a/qt/scientific_interfaces/Indirect/Elwin.ui
+++ b/qt/scientific_interfaces/Indirect/Elwin.ui
@@ -268,13 +268,40 @@
          <string>Output</string>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout_5">
+         <item>
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>Workspace:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="cbPlotWorkspace">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="spPlotSpectrum">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
          <item>
           <widget class="QPushButton" name="pbPlot">
            <property name="enabled">
             <bool>false</bool>
            </property>
            <property name="text">
-            <string>Plot Result</string>
+            <string>Plot Spectrum</string>
            </property>
           </widget>
          </item>
diff --git a/qt/scientific_interfaces/Indirect/IAddWorkspaceDialog.h b/qt/scientific_interfaces/Indirect/IAddWorkspaceDialog.h
index ac647e345159094eafef15fe4d16d72884d3d9bf..d9eec8dde61d9f62c7001ffa81ecea1867438745 100644
--- a/qt/scientific_interfaces/Indirect/IAddWorkspaceDialog.h
+++ b/qt/scientific_interfaces/Indirect/IAddWorkspaceDialog.h
@@ -8,17 +8,23 @@
 #define MANTIDQTCUSTOMINTERFACES_IADDWORKSPACEDIALOG_H_
 
 #include <QDialog>
+#include <QObject>
 
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
 class IAddWorkspaceDialog : public QDialog {
+  Q_OBJECT
 public:
   IAddWorkspaceDialog(QWidget *parent) : QDialog(parent) {}
   virtual std::string workspaceName() const = 0;
   virtual void setWSSuffices(const QStringList &suffices) = 0;
   virtual void setFBSuffices(const QStringList &suffices) = 0;
+
+signals:
+  void addData();
+  void closeDialog();
 };
 
 } // namespace IDA
diff --git a/qt/scientific_interfaces/Indirect/IIndirectFitDataView.h b/qt/scientific_interfaces/Indirect/IIndirectFitDataView.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d01cbbf71c864a205bca727304c1e37bc1f3b07
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IIndirectFitDataView.h
@@ -0,0 +1,65 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQTCUSTOMINTERFACESIDA_IINDIRECTFITDATAVIEW_H_
+#define MANTIDQTCUSTOMINTERFACESIDA_IINDIRECTFITDATAVIEW_H_
+
+#include "../General/UserInputValidator.h"
+#include "DllConfig.h"
+
+#include <QObject>
+#include <QTabWidget>
+#include <QTableWidget>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+class MANTIDQT_INDIRECT_DLL IIndirectFitDataView : public QTabWidget {
+  Q_OBJECT
+
+public:
+  IIndirectFitDataView(QWidget *parent = nullptr) : QTabWidget(parent){};
+  virtual ~IIndirectFitDataView(){};
+
+  virtual QTableWidget *getDataTable() const = 0;
+  virtual bool isMultipleDataTabSelected() const = 0;
+  virtual bool isResolutionHidden() const = 0;
+  virtual void setResolutionHidden(bool hide) = 0;
+  virtual void disableMultipleDataTab() = 0;
+
+  virtual std::string getSelectedSample() const = 0;
+  virtual std::string getSelectedResolution() const = 0;
+
+  virtual QStringList getSampleWSSuffices() const = 0;
+  virtual QStringList getSampleFBSuffices() const = 0;
+  virtual QStringList getResolutionWSSuffices() const = 0;
+  virtual QStringList getResolutionFBSuffices() const = 0;
+
+  virtual void setSampleWSSuffices(QStringList const &suffices) = 0;
+  virtual void setSampleFBSuffices(QStringList const &suffices) = 0;
+  virtual void setResolutionWSSuffices(QStringList const &suffices) = 0;
+  virtual void setResolutionFBSuffices(QStringList const &suffices) = 0;
+
+  virtual void readSettings(QSettings const &settings) = 0;
+  virtual UserInputValidator &validate(UserInputValidator &validator) = 0;
+
+public slots:
+  virtual void displayWarning(std::string const &warning) = 0;
+
+signals:
+  void sampleLoaded(QString const &);
+  void resolutionLoaded(QString const &);
+  void addClicked();
+  void removeClicked();
+  void multipleDataViewSelected();
+  void singleDataViewSelected();
+};
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
+
+#endif
\ No newline at end of file
diff --git a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.cpp b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.cpp
index 55e7a8d0810fadae73b3299a4c87ac10ee1f41e1..2d3c8128512318adaa83a814d6c7aea951ae2778 100644
--- a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.cpp
@@ -81,6 +81,8 @@ AddWorkspaceDialog::AddWorkspaceDialog(QWidget *parent)
           SLOT(workspaceChanged(const QString &)));
   connect(m_uiForm.ckAllSpectra, SIGNAL(stateChanged(int)), this,
           SLOT(selectAllSpectra(int)));
+  connect(m_uiForm.pbAdd, SIGNAL(clicked()), this, SIGNAL(addData()));
+  connect(m_uiForm.pbClose, SIGNAL(clicked()), this, SIGNAL(closeDialog()));
 }
 
 std::string AddWorkspaceDialog::workspaceName() const {
diff --git a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui
index 05630bc5a5fa146e31ba0e9f6ca9876bf94b4f08..17cd5c058891d58f6605a11b64c3cbdb7ef2d60c 100644
--- a/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui
+++ b/qt/scientific_interfaces/Indirect/IndirectAddWorkspaceDialog.ui
@@ -78,13 +78,48 @@
     </widget>
    </item>
    <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
+    <widget class="QFrame" name="frame">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbAdd">
+        <property name="text">
+         <string>Add</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbClose">
+        <property name="text">
+         <string>Close</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
   </layout>
@@ -99,36 +134,40 @@
  <resources/>
  <connections>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
+   <sender>pbAdd</sender>
+   <signal>clicked()</signal>
    <receiver>IndirectAddWorkspaceDialog</receiver>
-   <slot>accept()</slot>
+   <slot>addData()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
+     <x>283</x>
+     <y>157</y>
     </hint>
     <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
+     <x>248</x>
+     <y>294</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
+   <sender>pbClose</sender>
+   <signal>clicked()</signal>
    <receiver>IndirectAddWorkspaceDialog</receiver>
-   <slot>reject()</slot>
+   <slot>closeDialog()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
+     <x>358</x>
+     <y>160</y>
     </hint>
     <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
+     <x>354</x>
+     <y>227</y>
     </hint>
    </hints>
   </connection>
  </connections>
+ <slots>
+  <slot>addData()</slot>
+  <slot>closeDialog()</slot>
+ </slots>
 </ui>
diff --git a/qt/scientific_interfaces/Indirect/IndirectDataTablePresenter.h b/qt/scientific_interfaces/Indirect/IndirectDataTablePresenter.h
index 436fa2ec73e7b7d6bb6cea9c1d5978dc381c896b..17a1c21e7061665685c49938419bca2de4f31f0d 100644
--- a/qt/scientific_interfaces/Indirect/IndirectDataTablePresenter.h
+++ b/qt/scientific_interfaces/Indirect/IndirectDataTablePresenter.h
@@ -21,7 +21,7 @@ namespace IDA {
 /**
   Presenter for a table of indirect fitting data.
 */
-class DLLExport IndirectDataTablePresenter : public QObject {
+class MANTIDQT_INDIRECT_DLL IndirectDataTablePresenter : public QObject {
   Q_OBJECT
 public:
   IndirectDataTablePresenter(IndirectFittingModel *model,
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
index d6bd4633a013bb66c91062b4a62d804467d6a1ab..390f35d6aee103fd98ae33705a5631215549a876 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
@@ -155,8 +155,8 @@ void IndirectFitAnalysisTab::setup() {
 
   connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
           SLOT(updateResultOptions()));
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
-          SLOT(emitUpdateFitTypes()));
+  connect(m_dataPresenter.get(), SIGNAL(updateAvailableFitTypes()), this,
+          SLOT(updateAvailableFitTypes()));
 
   connectDataAndSpectrumPresenters();
   connectDataAndPlotPresenters();
@@ -752,8 +752,7 @@ void IndirectFitAnalysisTab::updateSingleFitOutput(bool error) {
  * and completed within this interface.
  */
 void IndirectFitAnalysisTab::fitAlgorithmComplete(bool error) {
-  setRunIsRunning(false);
-  setFitSingleSpectrumIsFitting(false);
+  enableFitAnalysisButtons(true);
   enablePlotResult(error);
   setSaveResultEnabled(!error);
   updateParameterValues();
@@ -947,7 +946,7 @@ void IndirectFitAnalysisTab::plotSpectrum(
     if (boost::contains(parameter, parameterToPlot)) {
       auto it = labels.find(parameter);
       if (it != labels.end())
-        IndirectTab::plotSpectrum(name, static_cast<int>(it->second));
+        IndirectTab::plotSpectrum(name, static_cast<int>(it->second), true);
     }
   }
 }
@@ -956,7 +955,7 @@ void IndirectFitAnalysisTab::plotSpectrum(
     Mantid::API::MatrixWorkspace_sptr workspace) {
   const auto name = QString::fromStdString(workspace->getName());
   for (auto i = 0u; i < workspace->getNumberHistograms(); ++i)
-    IndirectTab::plotSpectrum(name, static_cast<int>(i));
+    IndirectTab::plotSpectrum(name, static_cast<int>(i), true);
 }
 
 /**
@@ -969,7 +968,7 @@ void IndirectFitAnalysisTab::singleFit() {
 void IndirectFitAnalysisTab::singleFit(std::size_t dataIndex,
                                        std::size_t spectrum) {
   if (validate()) {
-    setFitSingleSpectrumIsFitting(true);
+    enableFitAnalysisButtons(false);
     runSingleFit(m_fittingModel->getSingleFit(dataIndex, spectrum));
   }
 }
@@ -979,8 +978,10 @@ void IndirectFitAnalysisTab::singleFit(std::size_t dataIndex,
  * tab.
  */
 void IndirectFitAnalysisTab::executeFit() {
-  if (validate())
+  if (validate()) {
+    enableFitAnalysisButtons(false);
     runFitAlgorithm(m_fittingModel->getFittingAlgorithm());
+  }
 }
 
 bool IndirectFitAnalysisTab::validate() {
@@ -991,6 +992,9 @@ bool IndirectFitAnalysisTab::validate() {
   const auto invalidFunction = m_fittingModel->isInvalidFunction();
   if (invalidFunction)
     validator.addErrorMessage(QString::fromStdString(*invalidFunction));
+  if (m_fittingModel->numberOfWorkspaces() == 0)
+    validator.addErrorMessage(
+        QString::fromStdString("No data has been selected for a fit."));
 
   const auto error = validator.generateErrorMessage();
   emit showMessageBox(error);
@@ -1001,10 +1005,16 @@ bool IndirectFitAnalysisTab::validate() {
  * Called when the 'Run' button is called in the IndirectTab.
  */
 void IndirectFitAnalysisTab::run() {
-  setRunIsRunning(true);
+  enableFitAnalysisButtons(false);
   runFitAlgorithm(m_fittingModel->getFittingAlgorithm());
 }
 
+void IndirectFitAnalysisTab::enableFitAnalysisButtons(bool enable) {
+  setRunIsRunning(!enable);
+  setFitSingleSpectrumIsFitting(!enable);
+  m_fitPropertyBrowser->setFitEnabled(enable);
+}
+
 void IndirectFitAnalysisTab::setAlgorithmProperties(
     IAlgorithm_sptr fitAlgorithm) const {
   fitAlgorithm->setProperty("Minimizer", m_fitPropertyBrowser->minimizer(true));
@@ -1124,8 +1134,6 @@ void IndirectFitAnalysisTab::updateResultOptions() {
   setSaveResultEnabled(isFit);
 }
 
-void IndirectFitAnalysisTab::emitUpdateFitTypes() { emit updateFitTypes(); }
-
 } // namespace IDA
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
index 3b7727c79ad357d3a9f0db6106aa1fd4a69e4bc8..0417bbcebea28b334205d4570c3d98258f4bd7c0 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
@@ -159,7 +159,6 @@ signals:
   void functionChanged();
   void parameterChanged(const Mantid::API::IFunction *);
   void customBoolChanged(const QString &key, bool value);
-  void updateFitTypes();
 
 protected slots:
 
@@ -214,7 +213,6 @@ protected slots:
 
 private slots:
   void updatePlotGuess();
-  void emitUpdateFitTypes();
 
 private:
   /// Overidden by child class.
@@ -229,6 +227,8 @@ private:
   void connectDataAndSpectrumPresenters();
   void connectDataAndFitBrowserPresenters();
 
+  void enableFitAnalysisButtons(bool enable);
+
   std::unique_ptr<IndirectFittingModel> m_fittingModel;
   MantidWidgets::IndirectFitPropertyBrowser *m_fitPropertyBrowser;
   std::unique_ptr<IndirectFitDataPresenter> m_dataPresenter;
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.cpp b/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.cpp
index d8e2ba70f615a452a2ab97ad2f02d0bdb8627cda..147f312f1c8c0b0d413b06d15886f007fa104929 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.cpp
@@ -14,14 +14,14 @@ namespace CustomInterfaces {
 namespace IDA {
 
 IndirectFitDataPresenter::IndirectFitDataPresenter(IndirectFittingModel *model,
-                                                   IndirectFitDataView *view)
+                                                   IIndirectFitDataView *view)
     : IndirectFitDataPresenter(
           model, view,
           Mantid::Kernel::make_unique<IndirectDataTablePresenter>(
               model, view->getDataTable())) {}
 
 IndirectFitDataPresenter::IndirectFitDataPresenter(
-    IndirectFittingModel *model, IndirectFitDataView *view,
+    IndirectFittingModel *model, IIndirectFitDataView *view,
     std::unique_ptr<IndirectDataTablePresenter> tablePresenter)
     : m_model(model), m_view(view),
       m_tablePresenter(std::move(tablePresenter)) {
@@ -65,7 +65,7 @@ IndirectFitDataPresenter::IndirectFitDataPresenter(
                                       std::size_t)));
 }
 
-IndirectFitDataView const *IndirectFitDataPresenter::getView() const {
+IIndirectFitDataView const *IndirectFitDataPresenter::getView() const {
   return m_view;
 }
 
@@ -147,17 +147,13 @@ IndirectFitDataPresenter::validate(UserInputValidator &validator) {
 }
 
 void IndirectFitDataPresenter::showAddWorkspaceDialog() {
-  const auto dialog = getAddWorkspaceDialog(m_view->parentWidget());
-  dialog->setWSSuffices(m_view->getSampleWSSuffices());
-  dialog->setFBSuffices(m_view->getSampleFBSuffices());
-  dialogExecuted(dialog.get(),
-                 static_cast<QDialog::DialogCode>(dialog->exec()));
-}
-
-void IndirectFitDataPresenter::dialogExecuted(IAddWorkspaceDialog const *dialog,
-                                              QDialog::DialogCode result) {
-  if (result == QDialog::Accepted)
-    addData(dialog);
+  m_addWorkspaceDialog = getAddWorkspaceDialog(m_view->parentWidget());
+  m_addWorkspaceDialog->setWSSuffices(m_view->getSampleWSSuffices());
+  m_addWorkspaceDialog->setFBSuffices(m_view->getSampleFBSuffices());
+  m_addWorkspaceDialog->show();
+  connect(m_addWorkspaceDialog.get(), SIGNAL(addData()), this, SLOT(addData()));
+  connect(m_addWorkspaceDialog.get(), SIGNAL(closeDialog()), this,
+          SLOT(closeDialog()));
 }
 
 std::unique_ptr<IAddWorkspaceDialog>
@@ -165,6 +161,18 @@ IndirectFitDataPresenter::getAddWorkspaceDialog(QWidget *parent) const {
   return Mantid::Kernel::make_unique<AddWorkspaceDialog>(parent);
 }
 
+void IndirectFitDataPresenter::addData() {
+  addData(m_addWorkspaceDialog.get());
+}
+
+void IndirectFitDataPresenter::closeDialog() {
+  disconnect(m_addWorkspaceDialog.get(), SIGNAL(addData()), this,
+             SLOT(addData()));
+  disconnect(m_addWorkspaceDialog.get(), SIGNAL(closeDialog()), this,
+             SLOT(closeDialog()));
+  m_addWorkspaceDialog->close();
+}
+
 void IndirectFitDataPresenter::addData(IAddWorkspaceDialog const *dialog) {
   try {
     addDataToModel(dialog);
@@ -194,6 +202,8 @@ void IndirectFitDataPresenter::addModelData(const std::string &name) {
     m_model->addWorkspace(name);
   } catch (const std::runtime_error &ex) {
     displayWarning("Unable to load workspace:\n" + std::string(ex.what()));
+  } catch (const std::invalid_argument &ex) {
+    displayWarning("Invalid workspace:\n" + std::string(ex.what()));
   }
 }
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.h b/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.h
index 30e4e6e0f17501fb890f45aac909d7a013f4e7ec..871434ca3ac436f06f5b3174f19130e4ee817180 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.h
+++ b/qt/scientific_interfaces/Indirect/IndirectFitDataPresenter.h
@@ -8,10 +8,11 @@
 #define MANTIDQTCUSTOMINTERFACESIDA_INDIRECTFITDATAPRESENTER_H_
 
 #include "IAddWorkspaceDialog.h"
+#include "IIndirectFitDataView.h"
 #include "IndirectDataTablePresenter.h"
-#include "IndirectFitDataView.h"
 #include "IndirectFittingModel.h"
 
+#include "DllConfig.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 #include <QObject>
@@ -20,17 +21,14 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-/**
-  A presenter.
-*/
-class DLLExport IndirectFitDataPresenter : public QObject {
+class MANTIDQT_INDIRECT_DLL IndirectFitDataPresenter : public QObject {
   Q_OBJECT
 public:
   IndirectFitDataPresenter(IndirectFittingModel *model,
-                           IndirectFitDataView *view);
+                           IIndirectFitDataView *view);
 
   IndirectFitDataPresenter(
-      IndirectFittingModel *model, IndirectFitDataView *view,
+      IndirectFittingModel *model, IIndirectFitDataView *view,
       std::unique_ptr<IndirectDataTablePresenter> tablePresenter);
 
   void setSampleWSSuffices(const QStringList &suffices);
@@ -55,6 +53,8 @@ protected slots:
   void setModelFromMultipleData();
   void showAddWorkspaceDialog();
 
+  virtual void closeDialog();
+
 signals:
   void singleSampleLoaded();
   void singleResolutionLoaded();
@@ -69,25 +69,27 @@ signals:
   void requestedAddWorkspaceDialog();
 
 protected:
-  IndirectFitDataView const *getView() const;
+  IIndirectFitDataView const *getView() const;
   void addData(IAddWorkspaceDialog const *dialog);
   virtual void addDataToModel(IAddWorkspaceDialog const *dialog);
   void setSingleModelData(const std::string &name);
   virtual void addModelData(const std::string &name);
   void setResolutionHidden(bool hide);
   void displayWarning(const std::string &warning);
-  virtual void dialogExecuted(IAddWorkspaceDialog const *dialog,
-                              QDialog::DialogCode result);
+
+private slots:
+  void addData();
 
 private:
   virtual std::unique_ptr<IAddWorkspaceDialog>
   getAddWorkspaceDialog(QWidget *parent) const;
   void updateDataInTable(std::size_t dataIndex);
 
+  std::unique_ptr<IAddWorkspaceDialog> m_addWorkspaceDialog;
   IndirectFittingModel *m_model;
   PrivateFittingData m_singleData;
   PrivateFittingData m_multipleData;
-  IndirectFitDataView *m_view;
+  IIndirectFitDataView *m_view;
   std::unique_ptr<IndirectDataTablePresenter> m_tablePresenter;
 };
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitDataView.cpp b/qt/scientific_interfaces/Indirect/IndirectFitDataView.cpp
index aa418c9ee18aeade40dd5278a308993495925c87..d36114c070d0438ca3ad90cda74d1d569b7d95fa 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitDataView.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectFitDataView.cpp
@@ -8,12 +8,20 @@
 
 using namespace Mantid::API;
 
+namespace {
+
+bool isWorkspaceLoaded(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().doesExist(workspaceName);
+}
+
+} // namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
 IndirectFitDataView::IndirectFitDataView(QWidget *parent)
-    : QTabWidget(parent), m_dataForm(new Ui::IndirectFitDataForm) {
+    : IIndirectFitDataView(parent), m_dataForm(new Ui::IndirectFitDataForm) {
   m_dataForm->setupUi(this);
   m_dataForm->dsResolution->hide();
   m_dataForm->lbResolution->hide();
@@ -105,11 +113,30 @@ IndirectFitDataView::validateMultipleData(UserInputValidator &validator) {
 
 UserInputValidator &
 IndirectFitDataView::validateSingleData(UserInputValidator &validator) {
+  validator = validateSample(validator);
+  if (!isResolutionHidden())
+    validator = validateResolution(validator);
+  return validator;
+}
+
+UserInputValidator &
+IndirectFitDataView::validateSample(UserInputValidator &validator) {
+  const auto sampleIsLoaded = isWorkspaceLoaded(getSelectedSample());
   validator.checkDataSelectorIsValid("Sample Input", m_dataForm->dsSample);
 
-  if (!isResolutionHidden())
-    validator.checkDataSelectorIsValid("Resolution Input",
-                                       m_dataForm->dsResolution);
+  if (!sampleIsLoaded)
+    emit sampleLoaded(QString::fromStdString(getSelectedSample()));
+  return validator;
+}
+
+UserInputValidator &
+IndirectFitDataView::validateResolution(UserInputValidator &validator) {
+  const auto resolutionIsLoaded = isWorkspaceLoaded(getSelectedResolution());
+  validator.checkDataSelectorIsValid("Resolution Input",
+                                     m_dataForm->dsResolution);
+
+  if (!resolutionIsLoaded)
+    emit resolutionLoaded(QString::fromStdString(getSelectedResolution()));
   return validator;
 }
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitDataView.h b/qt/scientific_interfaces/Indirect/IndirectFitDataView.h
index 78f98a743a00b737ea21c33534e7776fc53c0c17..7f24863b9f1693962f4242e54c37749302237490 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitDataView.h
+++ b/qt/scientific_interfaces/Indirect/IndirectFitDataView.h
@@ -9,7 +9,10 @@
 
 #include "ui_IndirectFitDataView.h"
 
+#include "IIndirectFitDataView.h"
+
 #include "../General/UserInputValidator.h"
+#include "DllConfig.h"
 
 #include <QTabWidget>
 
@@ -17,44 +20,36 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-class DLLExport IndirectFitDataView : public QTabWidget {
+class MANTIDQT_INDIRECT_DLL IndirectFitDataView : public IIndirectFitDataView {
   Q_OBJECT
 public:
-  IndirectFitDataView(QWidget *parent);
+  IndirectFitDataView(QWidget *parent = nullptr);
   ~IndirectFitDataView() override = default;
 
-  QTableWidget *getDataTable() const;
-  bool isMultipleDataTabSelected() const;
-  bool isResolutionHidden() const;
-  void setResolutionHidden(bool hide);
-  void disableMultipleDataTab();
+  QTableWidget *getDataTable() const override;
+  virtual bool isMultipleDataTabSelected() const override;
+  bool isResolutionHidden() const override;
+  void setResolutionHidden(bool hide) override;
+  void disableMultipleDataTab() override;
 
-  std::string getSelectedSample() const;
-  std::string getSelectedResolution() const;
+  virtual std::string getSelectedSample() const override;
+  std::string getSelectedResolution() const override;
 
-  QStringList getSampleWSSuffices() const;
-  QStringList getSampleFBSuffices() const;
-  QStringList getResolutionWSSuffices() const;
-  QStringList getResolutionFBSuffices() const;
+  virtual QStringList getSampleWSSuffices() const override;
+  virtual QStringList getSampleFBSuffices() const override;
+  QStringList getResolutionWSSuffices() const override;
+  QStringList getResolutionFBSuffices() const override;
 
-  void setSampleWSSuffices(const QStringList &suffices);
-  void setSampleFBSuffices(const QStringList &suffices);
-  void setResolutionWSSuffices(const QStringList &suffices);
-  void setResolutionFBSuffices(const QStringList &suffices);
+  virtual void setSampleWSSuffices(const QStringList &suffices) override;
+  virtual void setSampleFBSuffices(const QStringList &suffices) override;
+  virtual void setResolutionWSSuffices(const QStringList &suffices) override;
+  virtual void setResolutionFBSuffices(const QStringList &suffices) override;
 
-  void readSettings(const QSettings &settings);
-  UserInputValidator &validate(UserInputValidator &validator);
+  void readSettings(const QSettings &settings) override;
+  UserInputValidator &validate(UserInputValidator &validator) override;
 
 public slots:
-  void displayWarning(const std::string &warning);
-
-signals:
-  void sampleLoaded(const QString &);
-  void resolutionLoaded(const QString &);
-  void addClicked();
-  void removeClicked();
-  void multipleDataViewSelected();
-  void singleDataViewSelected();
+  void displayWarning(const std::string &warning) override;
 
 protected slots:
   void emitViewSelected(int index);
@@ -62,6 +57,8 @@ protected slots:
 private:
   UserInputValidator &validateMultipleData(UserInputValidator &validator);
   UserInputValidator &validateSingleData(UserInputValidator &validator);
+  UserInputValidator &validateSample(UserInputValidator &validator);
+  UserInputValidator &validateResolution(UserInputValidator &validator);
 
   std::unique_ptr<Ui::IndirectFitDataForm> m_dataForm;
 };
diff --git a/qt/scientific_interfaces/Indirect/IndirectFittingModel.cpp b/qt/scientific_interfaces/Indirect/IndirectFittingModel.cpp
index 24a20a606dfc25897470eb174008ce2b919ace52..5cffc10d062ec3ab11c967b49c6752a59cce7f77 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFittingModel.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectFittingModel.cpp
@@ -116,11 +116,15 @@ bool equivalentFunctions(IFunction_const_sptr func1,
 std::ostringstream &addInputString(IndirectFitData *fitData,
                                    std::ostringstream &stream) {
   const auto &name = fitData->workspace()->getName();
-  auto addToStream = [&](std::size_t spectrum) {
-    stream << name << ",i" << spectrum << ";";
-  };
-  fitData->applySpectra(addToStream);
-  return stream;
+  if (!name.empty()) {
+    auto addToStream = [&](std::size_t spectrum) {
+      stream << name << ",i" << spectrum << ";";
+    };
+    fitData->applySpectra(addToStream);
+    return stream;
+  } else
+    throw std::runtime_error(
+        "Workspace name is empty. The sample workspace may not be loaded.");
 }
 
 std::string constructInputString(
diff --git a/qt/scientific_interfaces/Indirect/IndirectFittingModel.h b/qt/scientific_interfaces/Indirect/IndirectFittingModel.h
index f0c9f168409215fc61e7b8e684834e7a6ac495c5..097f919ccc7880cd682c2624c2c65eedc738913e 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFittingModel.h
+++ b/qt/scientific_interfaces/Indirect/IndirectFittingModel.h
@@ -79,17 +79,17 @@ public:
                          std::size_t spectrum);
   virtual void setEndX(double endX, std::size_t dataIndex,
                        std::size_t spectrum);
-  void setExcludeRegion(const std::string &exclude, std::size_t dataIndex,
-                        std::size_t spectrum);
+  virtual void setExcludeRegion(const std::string &exclude,
+                                std::size_t dataIndex, std::size_t spectrum);
 
-  void addWorkspace(const std::string &workspaceName);
+  virtual void addWorkspace(const std::string &workspaceName);
   void addWorkspace(const std::string &workspaceName,
                     const std::string &spectra);
   void addWorkspace(const std::string &workspaceName, const Spectra &spectra);
   virtual void addWorkspace(Mantid::API::MatrixWorkspace_sptr workspace,
                             const Spectra &spectra);
   virtual void removeWorkspace(std::size_t index);
-  PrivateFittingData clearWorkspaces();
+  virtual PrivateFittingData clearWorkspaces();
   void setFittingMode(FittingMode mode);
   virtual void setFitFunction(Mantid::API::IFunction_sptr function);
   virtual void setDefaultParameterValue(const std::string &name, double value,
@@ -209,7 +209,8 @@ private:
 template <typename F>
 void IndirectFittingModel::applySpectra(std::size_t index,
                                         const F &functor) const {
-  m_fittingData[index]->applySpectra(functor);
+  if (m_fittingData.size() > 0)
+    m_fittingData[index]->applySpectra(functor);
 }
 
 } // namespace IDA
diff --git a/qt/scientific_interfaces/Indirect/IndirectLoadILL.cpp b/qt/scientific_interfaces/Indirect/IndirectLoadILL.cpp
index b8421038ecf942d4253ea210d9822f5d263a7544..3d6cc1fba4fdfa1120d0f1f4154390bcc11d69d4 100644
--- a/qt/scientific_interfaces/Indirect/IndirectLoadILL.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectLoadILL.cpp
@@ -24,6 +24,13 @@ IndirectLoadILL::IndirectLoadILL(QWidget *parent) : IndirectToolsTab(parent) {
   connect(m_uiForm.mwRun, SIGNAL(filesFound()), this, SLOT(handleFilesFound()));
   connect(m_uiForm.chkUseMap, SIGNAL(toggled(bool)), m_uiForm.mwMapFile,
           SLOT(setEnabled(bool)));
+
+  connect(this,
+          SIGNAL(updateRunButton(bool, std::string const &, QString const &,
+                                 QString const &)),
+          this,
+          SLOT(updateRunButton(bool, std::string const &, QString const &,
+                               QString const &)));
 }
 
 /**
@@ -56,24 +63,29 @@ bool IndirectLoadILL::validate() {
  * script that runs IndirectLoadILL
  */
 void IndirectLoadILL::run() {
+  setRunIsRunning(true);
+
   QString plot("False");
   QString save("None");
 
   QString useMap("False");
   QString rejectZero("False");
 
-  QString filename = m_uiForm.mwRun->getFirstFilename();
-  QFileInfo finfo(filename);
+  QString const filename = m_uiForm.mwRun->getFirstFilename();
+  QFileInfo const finfo(filename);
   QString ext = finfo.suffix().toLower();
 
-  QString instrument = m_uiForm.iicInstrumentConfiguration->getInstrumentName();
-  QString analyser = m_uiForm.iicInstrumentConfiguration->getAnalyserName();
-  QString reflection = m_uiForm.iicInstrumentConfiguration->getReflectionName();
+  QString const instrument =
+      m_uiForm.iicInstrumentConfiguration->getInstrumentName();
+  QString const analyser =
+      m_uiForm.iicInstrumentConfiguration->getAnalyserName();
+  QString const reflection =
+      m_uiForm.iicInstrumentConfiguration->getReflectionName();
 
   if (m_uiForm.chkUseMap->isChecked()) {
     useMap = "True";
   }
-  QString mapPath = m_uiForm.mwMapFile->getFirstFilename();
+  QString const mapPath = m_uiForm.mwMapFile->getFirstFilename();
 
   if (m_uiForm.chkRejectZero->isChecked()) {
     rejectZero = "True";
@@ -107,6 +119,7 @@ void IndirectLoadILL::run() {
     {
       pyFunc += "InxStart";
     } else {
+      setRunIsRunning(false);
       emit showMessageBox("Could not find appropriate loading routine for " +
                           filename);
       return;
@@ -121,6 +134,8 @@ void IndirectLoadILL::run() {
                plot + "'," + save + ")";
   }
   runPythonScript(pyInput);
+
+  setRunIsRunning(false);
 }
 
 /**
@@ -153,5 +168,19 @@ void IndirectLoadILL::handleFilesFound() {
 
 void IndirectLoadILL::runClicked() { runTab(); }
 
+void IndirectLoadILL::setRunIsRunning(bool running) {
+  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
+  setRunEnabled(!running);
+  setPlotOptionsEnabled(!running);
+}
+
+void IndirectLoadILL::setRunEnabled(bool enabled) {
+  m_uiForm.pbRun->setEnabled(enabled);
+}
+
+void IndirectLoadILL::setPlotOptionsEnabled(bool enabled) {
+  m_uiForm.cbPlot->setEnabled(enabled);
+}
+
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectLoadILL.h b/qt/scientific_interfaces/Indirect/IndirectLoadILL.h
index 5a5568041ff0d02d35cafef938012acc5893fb30..1c461917df5caa07a7820f8d69b40818c0e6d28a 100644
--- a/qt/scientific_interfaces/Indirect/IndirectLoadILL.h
+++ b/qt/scientific_interfaces/Indirect/IndirectLoadILL.h
@@ -37,6 +37,10 @@ private slots:
   void runClicked();
 
 private:
+  void setRunIsRunning(bool running);
+  void setRunEnabled(bool enabled);
+  void setPlotOptionsEnabled(bool enabled);
+
   /// Map to store instrument analysers and reflections for this instrument
   QMap<QString, QStringList> m_paramMap;
   /// The ui form
diff --git a/qt/scientific_interfaces/Indirect/IndirectMolDyn.cpp b/qt/scientific_interfaces/Indirect/IndirectMolDyn.cpp
index 7a8a78e5f5ca3b4ddee115abafb2f0e13f5ce83d..3d7bfa55c183b67b892c745f8f3fda267a7cf013 100644
--- a/qt/scientific_interfaces/Indirect/IndirectMolDyn.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectMolDyn.cpp
@@ -14,6 +14,15 @@
 
 using namespace Mantid::API;
 
+namespace {
+
+WorkspaceGroup_sptr getADSWorkspaceGroup(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
+      workspaceName);
+}
+
+} // namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 IndirectMolDyn::IndirectMolDyn(QWidget *parent)
@@ -26,9 +35,13 @@ IndirectMolDyn::IndirectMolDyn(QWidget *parent)
           SLOT(setEnabled(bool)));
   connect(m_uiForm.cbVersion, SIGNAL(currentIndexChanged(const QString &)),
           this, SLOT(versionSelected(const QString &)));
-  // Handle plotting and saving
+
+  connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked()));
   connect(m_uiForm.pbPlot, SIGNAL(clicked()), this, SLOT(plotClicked()));
   connect(m_uiForm.pbSave, SIGNAL(clicked()), this, SLOT(saveClicked()));
+
+  connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+          SLOT(algorithmComplete(bool)));
 }
 
 void IndirectMolDyn::setup() {}
@@ -71,38 +84,44 @@ bool IndirectMolDyn::validate() {
  * Collect the settings on the GUI and run the MolDyn algorithm.
  */
 void IndirectMolDyn::run() {
+  setRunIsRunning(true);
+
   // Get filename and base filename (for naming output workspace group)
-  QString filename = m_uiForm.mwRun->getFirstFilename();
-  QFileInfo fi(filename);
-  QString baseName = fi.baseName();
+  auto const filename = m_uiForm.mwRun->getFirstFilename();
+  auto const baseName = QFileInfo(filename).baseName();
+  auto const functionNames = m_uiForm.leFunctionNames->text().toStdString();
+  bool const symmetrise = m_uiForm.ckSymmetrise->isChecked();
+  bool const cropEnergy = m_uiForm.ckCropEnergy->isChecked();
+  bool const resolution = m_uiForm.ckResolution->isChecked();
 
   // Setup algorithm
-  IAlgorithm_sptr molDynAlg = AlgorithmManager::Instance().create("MolDyn");
+  auto molDynAlg = AlgorithmManager::Instance().create("MolDyn");
   molDynAlg->setProperty("Data", filename.toStdString());
-  molDynAlg->setProperty("Functions",
-                         m_uiForm.leFunctionNames->text().toStdString());
-  molDynAlg->setProperty("SymmetriseEnergy",
-                         m_uiForm.ckSymmetrise->isChecked());
+  molDynAlg->setProperty("Functions", functionNames);
+  molDynAlg->setProperty("SymmetriseEnergy", symmetrise);
   molDynAlg->setProperty("OutputWorkspace", baseName.toStdString());
 
   // Set energy crop option
-  if (m_uiForm.ckCropEnergy->isChecked())
-    molDynAlg->setProperty(
-        "MaxEnergy",
-        QString::number(m_uiForm.dspMaxEnergy->value()).toStdString());
+  if (cropEnergy) {
+    auto const maxEnergy = QString::number(m_uiForm.dspMaxEnergy->value());
+    molDynAlg->setProperty("MaxEnergy", maxEnergy.toStdString());
+  }
 
   // Set instrument resolution option
-  if (m_uiForm.ckResolution->isChecked())
-    molDynAlg->setProperty(
-        "Resolution",
-        m_uiForm.dsResolution->getCurrentDataName().toStdString());
+  if (resolution) {
+    auto const resolutionName = m_uiForm.dsResolution->getCurrentDataName();
+    molDynAlg->setProperty("Resolution", resolutionName.toStdString());
+  }
 
   runAlgorithm(molDynAlg);
+}
 
-  // Enable plot and save
-  m_uiForm.pbPlot->setEnabled(true);
-  m_uiForm.pbSave->setEnabled(true);
-  m_uiForm.cbPlot->setEnabled(true);
+void IndirectMolDyn::algorithmComplete(bool error) {
+  setRunIsRunning(false);
+  if (error) {
+    setPlotEnabled(false);
+    setSaveEnabled(false);
+  }
 }
 
 /**
@@ -124,32 +143,34 @@ void IndirectMolDyn::versionSelected(const QString &version) {
   bool version4(version == "4");
   m_uiForm.mwRun->isForDirectory(version4);
 }
+
+void IndirectMolDyn::runClicked() { runTab(); }
+
 /**
  * Handle plotting of mantid workspace
  */
 void IndirectMolDyn::plotClicked() {
+  setPlotIsPlotting(true);
 
-  QString filename = m_uiForm.mwRun->getFirstFilename();
-  QFileInfo fi(filename);
-  QString baseName = fi.baseName();
+  QString const filename = m_uiForm.mwRun->getFirstFilename();
+  QString const baseName = QFileInfo(filename).baseName();
 
   if (checkADSForPlotSaveWorkspace(baseName.toStdString(), true)) {
 
-    WorkspaceGroup_sptr diffResultsGroup =
-        AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
-            baseName.toStdString());
+    auto const diffResultsGroup = getADSWorkspaceGroup(baseName.toStdString());
+    auto const names = diffResultsGroup->getNames();
+    auto const plotType = m_uiForm.cbPlot->currentText();
 
-    auto names = diffResultsGroup->getNames();
-    auto plotType = m_uiForm.cbPlot->currentText();
-
-    for (const auto &wsName : names) {
+    for (auto const &name : names) {
       if (plotType == "Spectra" || plotType == "Both")
-        plotSpectrum(QString::fromStdString(wsName));
+        plotSpectrum(QString::fromStdString(name));
 
       if (plotType == "Contour" || plotType == "Both")
-        plot2D(QString::fromStdString(wsName));
+        plot2D(QString::fromStdString(name));
     }
   }
+
+  setPlotIsPlotting(false);
 }
 
 /**
@@ -166,5 +187,34 @@ void IndirectMolDyn::saveClicked() {
   m_batchAlgoRunner->executeBatchAsync();
 }
 
+void IndirectMolDyn::setRunIsRunning(bool running) {
+  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
+  setButtonsEnabled(!running);
+}
+
+void IndirectMolDyn::setPlotIsPlotting(bool running) {
+  m_uiForm.pbPlot->setText(running ? "Plotting..." : "Plot");
+  setButtonsEnabled(!running);
+}
+
+void IndirectMolDyn::setButtonsEnabled(bool enabled) {
+  setRunEnabled(enabled);
+  setPlotEnabled(enabled);
+  setSaveEnabled(enabled);
+}
+
+void IndirectMolDyn::setRunEnabled(bool enabled) {
+  m_uiForm.pbRun->setEnabled(enabled);
+}
+
+void IndirectMolDyn::setPlotEnabled(bool enabled) {
+  m_uiForm.pbPlot->setEnabled(enabled);
+  m_uiForm.cbPlot->setEnabled(enabled);
+}
+
+void IndirectMolDyn::setSaveEnabled(bool enabled) {
+  m_uiForm.pbSave->setEnabled(enabled);
+}
+
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectMolDyn.h b/qt/scientific_interfaces/Indirect/IndirectMolDyn.h
index f9ac180f076bc92af7a3930805f55e2926f817a8..0c9489726d59278cb1f50af6faa4b2c2030fc9b8 100644
--- a/qt/scientific_interfaces/Indirect/IndirectMolDyn.h
+++ b/qt/scientific_interfaces/Indirect/IndirectMolDyn.h
@@ -28,11 +28,19 @@ public:
 
 private slots:
   void versionSelected(const QString &);
-  // Handle plotting and saving
+  void runClicked();
   void plotClicked();
   void saveClicked();
+  void algorithmComplete(bool error);
 
 private:
+  void setRunIsRunning(bool running);
+  void setPlotIsPlotting(bool plotting);
+  void setButtonsEnabled(bool enabled);
+  void setRunEnabled(bool enabled);
+  void setPlotEnabled(bool enabled);
+  void setSaveEnabled(bool enabled);
+
   // The ui form
   Ui::IndirectMolDyn m_uiForm;
 };
diff --git a/qt/scientific_interfaces/Indirect/IndirectMolDyn.ui b/qt/scientific_interfaces/Indirect/IndirectMolDyn.ui
index c31855ea59d13da39060efcfce9ddc0d4a3e7780..36aeda0fb4c2e512cd927bd27053af59b230a711 100644
--- a/qt/scientific_interfaces/Indirect/IndirectMolDyn.ui
+++ b/qt/scientific_interfaces/Indirect/IndirectMolDyn.ui
@@ -269,6 +269,60 @@
      </property>
     </spacer>
    </item>
+   <item>
+    <widget class="QGroupBox" name="gbRun">
+     <property name="title">
+      <string>Run</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>7</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>194</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbRun">
+        <property name="text">
+         <string>Run</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>193</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
     <widget class="QGroupBox" name="gbOutput">
      <property name="sizePolicy">
diff --git a/qt/scientific_interfaces/Indirect/IndirectSassena.cpp b/qt/scientific_interfaces/Indirect/IndirectSassena.cpp
index 92536c9c71c20235aa5dfaa6d9297dd26aa51136..0f645c472e9f86de99f314be5238421a78c1a217 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSassena.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectSassena.cpp
@@ -6,6 +6,8 @@
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "IndirectSassena.h"
 
+#include "../General/UserInputValidator.h"
+
 #include <QFileInfo>
 #include <QString>
 
@@ -16,9 +18,10 @@ IndirectSassena::IndirectSassena(QWidget *parent)
   m_uiForm.setupUi(parent);
   connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
           SLOT(handleAlgorithmFinish(bool)));
-  // Handle plotting and saving
-  connect(m_uiForm.pbSave, SIGNAL(clicked()), this, SLOT(saveClicked()));
+
+  connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked()));
   connect(m_uiForm.pbPlot, SIGNAL(clicked()), this, SLOT(plotClicked()));
+  connect(m_uiForm.pbSave, SIGNAL(clicked()), this, SLOT(saveClicked()));
 }
 
 void IndirectSassena::setup() {}
@@ -29,9 +32,14 @@ void IndirectSassena::setup() {}
  * @return Whether the form was valid
  */
 bool IndirectSassena::validate() {
-  // There is very little to actually be invalid here
-  // that was not already done via restrictions on input
-  return true;
+  UserInputValidator uiv;
+
+  auto const inputFileName = m_uiForm.mwInputFile->getFirstFilename();
+  if (inputFileName.isEmpty())
+    uiv.addErrorMessage("Incorrect input file provided.");
+
+  emit showMessageBox(uiv.generateErrorMessage());
+  return uiv.isAllInputValid();
 }
 
 /**
@@ -41,18 +49,17 @@ void IndirectSassena::run() {
   using namespace Mantid::API;
   using MantidQt::API::BatchAlgorithmRunner;
 
-  QString inputFileName = m_uiForm.mwInputFile->getFirstFilename();
-  QFileInfo inputFileInfo(inputFileName);
-  m_outWsName = inputFileInfo.baseName();
+  setRunIsRunning(true);
+
+  QString const inputFileName = m_uiForm.mwInputFile->getFirstFilename();
+  m_outWsName = QFileInfo(inputFileName).baseName();
 
   // If the workspace group already exists then remove it
   if (AnalysisDataService::Instance().doesExist(m_outWsName.toStdString()))
     AnalysisDataService::Instance().deepRemoveGroup(m_outWsName.toStdString());
 
-  IAlgorithm_sptr sassenaAlg =
-      AlgorithmManager::Instance().create("LoadSassena");
+  auto sassenaAlg = AlgorithmManager::Instance().create("LoadSassena");
   sassenaAlg->initialize();
-
   sassenaAlg->setProperty("Filename", inputFileName.toStdString());
   sassenaAlg->setProperty("SortByQVectors", m_uiForm.cbSortQ->isChecked());
   sassenaAlg->setProperty("TimeUnit", m_uiForm.sbTimeUnit->value());
@@ -72,14 +79,11 @@ void IndirectSassena::run() {
  * @param error If the batch was stopped due to error
  */
 void IndirectSassena::handleAlgorithmFinish(bool error) {
-
-  // Nothing to do if the algorithm failed
-  if (error)
-    return;
-
-  // Enable plot and save
-  m_uiForm.pbPlot->setEnabled(true);
-  m_uiForm.pbSave->setEnabled(true);
+  setRunIsRunning(false);
+  if (error) {
+    setPlotEnabled(false);
+    setSaveEnabled(false);
+  }
 }
 
 /**
@@ -92,12 +96,16 @@ void IndirectSassena::loadSettings(const QSettings &settings) {
   m_uiForm.mwInputFile->readSettings(settings.group());
 }
 
+void IndirectSassena::runClicked() { runTab(); }
+
 /**
  * Handle mantid plotting of workspace
  */
 void IndirectSassena::plotClicked() {
+  setPlotIsPlotting(true);
   if (checkADSForPlotSaveWorkspace(m_outWsName.toStdString(), true))
     plotSpectrum(m_outWsName);
+  setPlotIsPlotting(false);
 }
 
 /**
@@ -109,5 +117,33 @@ void IndirectSassena::saveClicked() {
   m_batchAlgoRunner->executeBatchAsync();
 }
 
+void IndirectSassena::setRunIsRunning(bool running) {
+  m_uiForm.pbRun->setText(running ? "Running..." : "Run");
+  setButtonsEnabled(!running);
+}
+
+void IndirectSassena::setPlotIsPlotting(bool running) {
+  m_uiForm.pbPlot->setText(running ? "Plotting..." : "Plot Result");
+  setButtonsEnabled(!running);
+}
+
+void IndirectSassena::setButtonsEnabled(bool enabled) {
+  setRunEnabled(enabled);
+  setPlotEnabled(enabled);
+  setSaveEnabled(enabled);
+}
+
+void IndirectSassena::setRunEnabled(bool enabled) {
+  m_uiForm.pbRun->setEnabled(enabled);
+}
+
+void IndirectSassena::setPlotEnabled(bool enabled) {
+  m_uiForm.pbPlot->setEnabled(enabled);
+}
+
+void IndirectSassena::setSaveEnabled(bool enabled) {
+  m_uiForm.pbSave->setEnabled(enabled);
+}
+
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectSassena.h b/qt/scientific_interfaces/Indirect/IndirectSassena.h
index 0da1000a421683f4efa38f3372a6c6632d6269e2..9249c1a342b3026a8f1e1ec5ca720bec799da6d2 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSassena.h
+++ b/qt/scientific_interfaces/Indirect/IndirectSassena.h
@@ -28,11 +28,18 @@ public:
 private slots:
   /// Handle completion of the algorithm batch
   void handleAlgorithmFinish(bool error);
-  /// Handle plotting and saving
+  void runClicked();
   void plotClicked();
   void saveClicked();
 
 private:
+  void setRunIsRunning(bool running);
+  void setPlotIsPlotting(bool plotting);
+  void setButtonsEnabled(bool enabled);
+  void setRunEnabled(bool enabled);
+  void setPlotEnabled(bool enabled);
+  void setSaveEnabled(bool enabled);
+
   /// The ui form
   Ui::IndirectSassena m_uiForm;
   /// Name of the output workspace group
diff --git a/qt/scientific_interfaces/Indirect/IndirectSassena.ui b/qt/scientific_interfaces/Indirect/IndirectSassena.ui
index 366f646444971972aef57b54fcf3e0428fa7d49f..15c39e4abe2c0feb69ac0510955a79a2b721bfeb 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSassena.ui
+++ b/qt/scientific_interfaces/Indirect/IndirectSassena.ui
@@ -20,7 +20,16 @@
       <string>Input File</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
-      <property name="margin">
+      <property name="leftMargin">
+       <number>6</number>
+      </property>
+      <property name="topMargin">
+       <number>6</number>
+      </property>
+      <property name="rightMargin">
+       <number>6</number>
+      </property>
+      <property name="bottomMargin">
        <number>6</number>
       </property>
       <item row="0" column="1">
@@ -104,6 +113,60 @@
      </property>
     </spacer>
    </item>
+   <item>
+    <widget class="QGroupBox" name="gbRun">
+     <property name="title">
+      <string>Run</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>7</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>194</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbRun">
+        <property name="text">
+         <string>Run</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>193</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
     <widget class="QGroupBox" name="gbOutput">
      <property name="sizePolicy">
diff --git a/qt/scientific_interfaces/Indirect/IndirectSimulation.cpp b/qt/scientific_interfaces/Indirect/IndirectSimulation.cpp
index 64619526c93b24480b8f6154afe1a4a6fd128fe7..2e9dd963631ee613f57101e650c712c972893435 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSimulation.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectSimulation.cpp
@@ -57,7 +57,6 @@ void IndirectSimulation::initLayout() {
 
   // Connect statements for the buttons shared between all tabs on the Indirect
   // Bayes interface
-  connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked()));
   connect(m_uiForm.pbHelp, SIGNAL(clicked()), this, SLOT(helpClicked()));
   connect(m_uiForm.pbManageDirs, SIGNAL(clicked()), this,
           SLOT(manageUserDirectories()));
@@ -110,18 +109,6 @@ void IndirectSimulation::loadSettings() {
   settings.endGroup();
 }
 
-/**
- * Slot to run the underlying algorithm code based on the currently selected
- * tab.
- *
- * This method checks the tabs validate method is passing before calling
- * the run method.
- */
-void IndirectSimulation::runClicked() {
-  int tabIndex = m_uiForm.IndirectSimulationTabs->currentIndex();
-  m_simulationTabs[tabIndex]->runTab();
-}
-
 /**
  * Slot to open a new browser window and navigate to the help page
  * on the wiki for the currently selected tab.
diff --git a/qt/scientific_interfaces/Indirect/IndirectSimulation.h b/qt/scientific_interfaces/Indirect/IndirectSimulation.h
index 37c1b73d0a197e91e21ff3314c4b6bbeb7c504b1..68a5dbeb735e169d16514dfc7dafa6be2b7858dd 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSimulation.h
+++ b/qt/scientific_interfaces/Indirect/IndirectSimulation.h
@@ -47,8 +47,6 @@ public: // public constructor, destructor and functions
   void initLayout() override;
 
 private slots:
-  /// Slot for clicking on the run button
-  void runClicked();
   /// Slot for clicking on the help button
   void helpClicked();
   /// Slot for clicking on the manage directories button
diff --git a/qt/scientific_interfaces/Indirect/IndirectSimulation.ui b/qt/scientific_interfaces/Indirect/IndirectSimulation.ui
index 1add339d839ac98dd93b13129206078a016145a9..fb0505ec23027ef9a77ac6471704bb81ac97f549 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSimulation.ui
+++ b/qt/scientific_interfaces/Indirect/IndirectSimulation.ui
@@ -14,102 +14,82 @@
    <string>Indirect Simulation</string>
   </property>
   <widget class="QWidget" name="centralwidget">
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QTabWidget" name="IndirectSimulationTabs">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="currentIndex">
-      <number>0</number>
-     </property>
-     <widget class="QWidget" name="molDyn">
-      <attribute name="title">
-       <string>MolDyn</string>
-      </attribute>
-     </widget>
-     <widget class="QWidget" name="sassena">
-      <attribute name="title">
-       <string>Sassena</string>
-      </attribute>
-     </widget>
-     <widget class="QWidget" name="dos">
-      <attribute name="title">
-       <string>DensityOfStates</string>
-      </attribute>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="layout_bottom">
-     <item>
-      <widget class="QPushButton" name="pbHelp">
-       <property name="enabled">
-        <bool>true</bool>
-       </property>
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>20</width>
-         <height>20</height>
-        </size>
-       </property>
-       <property name="text">
-        <string>?</string>
-       </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <widget class="QTabWidget" name="IndirectSimulationTabs">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <widget class="QWidget" name="molDyn">
+       <attribute name="title">
+        <string>MolDyn</string>
+       </attribute>
       </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_14">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pbRun">
-       <property name="text">
-        <string>Run</string>
-       </property>
+      <widget class="QWidget" name="sassena">
+       <attribute name="title">
+        <string>Sassena</string>
+       </attribute>
       </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_11">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pbManageDirs">
-       <property name="text">
-        <string>Manage Directories</string>
-       </property>
+      <widget class="QWidget" name="dos">
+       <attribute name="title">
+        <string>DensityOfStates</string>
+       </attribute>
       </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
+     </widget>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="layout_bottom">
+      <item>
+       <widget class="QPushButton" name="pbHelp">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>?</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_14">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbManageDirs">
+        <property name="text">
+         <string>Manage Directories</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+   </layout>
   </widget>
  </widget>
  <resources/>
diff --git a/qt/scientific_interfaces/Indirect/IndirectTab.cpp b/qt/scientific_interfaces/Indirect/IndirectTab.cpp
index 58563d2ccc0677a789d93aa4cd8db2fb327e8cd4..529017811f1b1993111526f0e60d8100e703aa85 100644
--- a/qt/scientific_interfaces/Indirect/IndirectTab.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectTab.cpp
@@ -167,19 +167,23 @@ bool IndirectTab::loadFile(const QString &filename, const QString &outputName,
  */
 void IndirectTab::addSaveWorkspaceToQueue(const QString &wsName,
                                           const QString &filename) {
+  addSaveWorkspaceToQueue(wsName.toStdString(), filename.toStdString());
+}
+
+void IndirectTab::addSaveWorkspaceToQueue(const std::string &wsName,
+                                          const std::string &filename) {
   // Setup the input workspace property
   API::BatchAlgorithmRunner::AlgorithmRuntimeProps saveProps;
-  saveProps["InputWorkspace"] = wsName.toStdString();
+  saveProps["InputWorkspace"] = wsName;
 
   // Setup the algorithm
-  IAlgorithm_sptr saveAlgo =
-      AlgorithmManager::Instance().create("SaveNexusProcessed");
+  auto saveAlgo = AlgorithmManager::Instance().create("SaveNexusProcessed");
   saveAlgo->initialize();
 
-  if (filename.isEmpty())
-    saveAlgo->setProperty("Filename", wsName.toStdString() + ".nxs");
+  if (filename.empty())
+    saveAlgo->setProperty("Filename", wsName + ".nxs");
   else
-    saveAlgo->setProperty("Filename", filename.toStdString());
+    saveAlgo->setProperty("Filename", filename);
 
   // Add the save algorithm to the batch
   m_batchAlgoRunner->addAlgorithm(saveAlgo, saveProps);
@@ -260,19 +264,19 @@ void IndirectTab::plotMultipleSpectra(
  * @param spectraIndex Index of spectrum from each workspace to plot
  */
 void IndirectTab::plotSpectrum(const QStringList &workspaceNames,
-                               int spectraIndex) {
-  if (workspaceNames.isEmpty())
-    return;
-
-  QString pyInput = "from mantidplot import plotSpectrum\n";
-
-  pyInput += "plotSpectrum(['";
-  pyInput += workspaceNames.join("','");
-  pyInput += "'], ";
-  pyInput += QString::number(spectraIndex);
-  pyInput += ")\n";
-
-  m_pythonRunner.runPythonCode(pyInput);
+                               const int &spectraIndex, const bool &errorBars) {
+  if (!workspaceNames.isEmpty()) {
+    const QString errors = errorBars ? "True" : "False";
+
+    QString pyInput = "from mantidplot import plotSpectrum\n";
+    pyInput += "plotSpectrum(['";
+    pyInput += workspaceNames.join("','");
+    pyInput += "'], ";
+    pyInput += QString::number(spectraIndex);
+    pyInput += ", error_bars=" + errors + ")\n";
+
+    m_pythonRunner.runPythonCode(pyInput);
+  }
 }
 
 /**
@@ -281,14 +285,15 @@ void IndirectTab::plotSpectrum(const QStringList &workspaceNames,
  *
  * @param workspaceName Names of workspace to plot
  * @param spectraIndex Workspace Index of spectrum to plot
+ * @param errorBars Is true if you want to plot the error bars
  */
-void IndirectTab::plotSpectrum(const QString &workspaceName, int spectraIndex) {
-  if (workspaceName.isEmpty())
-    return;
-
-  QStringList workspaceNames;
-  workspaceNames << workspaceName;
-  plotSpectrum(workspaceNames, spectraIndex);
+void IndirectTab::plotSpectrum(const QString &workspaceName,
+                               const int &spectraIndex, const bool &errorBars) {
+  if (!workspaceName.isEmpty()) {
+    QStringList workspaceNames;
+    workspaceNames << workspaceName;
+    plotSpectrum(workspaceNames, spectraIndex, errorBars);
+  }
 }
 
 /**
diff --git a/qt/scientific_interfaces/Indirect/IndirectTab.h b/qt/scientific_interfaces/Indirect/IndirectTab.h
index b62834cb7625deeac80f37a2815074c8e5869aeb..3c12d09fc0c630720089271f3e9e6846fc853304 100644
--- a/qt/scientific_interfaces/Indirect/IndirectTab.h
+++ b/qt/scientific_interfaces/Indirect/IndirectTab.h
@@ -81,6 +81,8 @@ protected:
                 const int specMin = -1, const int specMax = -1);
 
   /// Add a SaveNexusProcessed step to the batch queue
+  void addSaveWorkspaceToQueue(const std::string &wsName,
+                               const std::string &filename = "");
   void addSaveWorkspaceToQueue(const QString &wsName,
                                const QString &filename = "");
 
@@ -92,9 +94,11 @@ protected:
   void plotMultipleSpectra(const QStringList &workspaceNames,
                            const std::vector<int> &workspaceIndices);
   /// Plot a spectrum plot with a given ws index
-  void plotSpectrum(const QStringList &workspaceNames, int spectraIndex = 0);
+  void plotSpectrum(const QStringList &workspaceNames,
+                    const int &spectraIndex = 0, const bool &errorBars = false);
   /// Plot a spectrum plot of a given workspace
-  void plotSpectrum(const QString &workspaceName, int spectraIndex = 0);
+  void plotSpectrum(const QString &workspaceName, const int &spectraIndex = 0,
+                    const bool &errorBars = false);
 
   /// Plot a spectrum plot with a given spectra range
   void plotSpectrum(const QStringList &workspaceNames, int specStart,
diff --git a/qt/scientific_interfaces/Indirect/JumpFit.cpp b/qt/scientific_interfaces/Indirect/JumpFit.cpp
index 54b6e98eb5aca5dae98fbc71979e8eb34eccd509..55279d877a33307e9244d958f8fed27b038a37b2 100644
--- a/qt/scientific_interfaces/Indirect/JumpFit.cpp
+++ b/qt/scientific_interfaces/Indirect/JumpFit.cpp
@@ -24,6 +24,18 @@
 
 using namespace Mantid::API;
 
+namespace {
+
+std::vector<std::string> getEISFFunctions() {
+  return {"EISFDiffCylinder", "EISFDiffSphere", "EISFDiffSphereAlkyl"};
+}
+
+std::vector<std::string> getWidthFunctions() {
+  return {"ChudleyElliot", "HallRoss", "FickDiffusion", "TeixeiraWater"};
+}
+
+} // namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
@@ -49,8 +61,8 @@ void JumpFit::setupFitTab() {
   setSampleWSSuffices({"_Result"});
   setSampleFBSuffices({"_Result.nxs"});
 
-  addWidthFunctionsToFitTypeComboBox();
-  addEISFFunctionsToFitTypeComboBox();
+  addFunctions(getWidthFunctions());
+  addFunctions(getEISFFunctions());
 
   m_uiForm->cbParameter->setEnabled(false);
 
@@ -61,42 +73,23 @@ void JumpFit::setupFitTab() {
   connect(this, SIGNAL(functionChanged()), this,
           SLOT(updateModelFitTypeString()));
   connect(m_uiForm->cbParameterType, SIGNAL(currentIndexChanged(int)), this,
-          SLOT(updateParameterFitTypes()));
-  connect(this, SIGNAL(updateFitTypes()), this,
-          SLOT(updateParameterFitTypes()));
-}
-
-void JumpFit::addEISFFunctionsToFitTypeComboBox() {
-  auto &functionFactory = FunctionFactory::Instance();
-  auto const eisfDiffCylinder =
-      functionFactory.createFunction("EISFDiffCylinder");
-  auto const eisfDiffSphere = functionFactory.createFunction("EISFDiffSphere");
-  auto const eisfDiffSphereAklyl =
-      functionFactory.createFunction("EISFDiffSphereAlkyl");
-  addComboBoxFunctionGroup("EISFDiffCylinder", {eisfDiffCylinder});
-  addComboBoxFunctionGroup("EISFDiffSphere", {eisfDiffSphere});
-  addComboBoxFunctionGroup("EISFDiffSphereAlkyl", {eisfDiffSphereAklyl});
-}
-
-void JumpFit::addWidthFunctionsToFitTypeComboBox() {
-  auto &functionFactory = FunctionFactory::Instance();
-  auto const chudleyElliot = functionFactory.createFunction("ChudleyElliot");
-  auto const hallRoss = functionFactory.createFunction("HallRoss");
-  auto const fickDiffusion = functionFactory.createFunction("FickDiffusion");
-  auto const teixeiraWater = functionFactory.createFunction("TeixeiraWater");
-  addComboBoxFunctionGroup("ChudleyElliot", {chudleyElliot});
-  addComboBoxFunctionGroup("HallRoss", {hallRoss});
-  addComboBoxFunctionGroup("FickDiffusion", {fickDiffusion});
-  addComboBoxFunctionGroup("TeixeiraWater", {teixeiraWater});
-}
-
-void JumpFit::updateParameterFitTypes() {
+          SLOT(updateAvailableFitTypes()));
+}
+
+void JumpFit::updateAvailableFitTypes() {
   auto const parameter = m_uiForm->cbParameterType->currentText().toStdString();
   clearFitTypeComboBox();
-  if (parameter == "EISF")
-    addEISFFunctionsToFitTypeComboBox();
-  else if (parameter == "Width")
-    addWidthFunctionsToFitTypeComboBox();
+  if (parameter == "Width")
+    addFunctions(getWidthFunctions());
+  else if (parameter == "EISF")
+    addFunctions(getEISFFunctions());
+}
+
+void JumpFit::addFunctions(std::vector<std::string> const &functions) {
+  auto &factory = FunctionFactory::Instance();
+  for (auto const &function : functions)
+    addComboBoxFunctionGroup(QString::fromStdString(function),
+                             {factory.createFunction(function)});
 }
 
 void JumpFit::updateModelFitTypeString() {
diff --git a/qt/scientific_interfaces/Indirect/JumpFit.h b/qt/scientific_interfaces/Indirect/JumpFit.h
index a81754f9d3f6d6f28a882992962ff291888fb9e3..6b30cc5359e4884fdf8261a43f212bfed3c33495 100644
--- a/qt/scientific_interfaces/Indirect/JumpFit.h
+++ b/qt/scientific_interfaces/Indirect/JumpFit.h
@@ -38,11 +38,10 @@ protected:
   void setSaveResultEnabled(bool enabled) override;
 
 private slots:
-  void updateParameterFitTypes();
+  void updateAvailableFitTypes();
 
 private:
-  void addEISFFunctionsToFitTypeComboBox();
-  void addWidthFunctionsToFitTypeComboBox();
+  void addFunctions(std::vector<std::string> const &functions);
 
   void setPlotResultIsPlotting(bool plotting);
   void setButtonsEnabled(bool enabled);
diff --git a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.cpp b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.cpp
index c461b705cfce1a796baa6e3a65a5ce259e16886a..b24b0629d44d5284f44783527ba3220a531d53c5 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.cpp
+++ b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.cpp
@@ -20,14 +20,21 @@ JumpFitAddWorkspaceDialog::JumpFitAddWorkspaceDialog(QWidget *parent)
 
   connect(m_uiForm.dsWorkspace, SIGNAL(dataReady(const QString &)), this,
           SLOT(emitWorkspaceChanged(const QString &)));
-  connect(m_uiForm.cbParameterType, SIGNAL(currentIndexChanged(int)), this,
-          SLOT(emitParameterTypeChanged(int)));
+  connect(m_uiForm.cbParameterType,
+          SIGNAL(currentIndexChanged(const QString &)), this,
+          SLOT(emitParameterTypeChanged(const QString &)));
+  connect(m_uiForm.pbAdd, SIGNAL(clicked()), this, SIGNAL(addData()));
+  connect(m_uiForm.pbClose, SIGNAL(clicked()), this, SIGNAL(closeDialog()));
 }
 
 std::string JumpFitAddWorkspaceDialog::workspaceName() const {
   return m_uiForm.dsWorkspace->getCurrentDataName().toStdString();
 }
 
+std::string JumpFitAddWorkspaceDialog::parameterType() const {
+  return m_uiForm.cbParameterType->currentText().toStdString();
+}
+
 int JumpFitAddWorkspaceDialog::parameterNameIndex() const {
   return m_uiForm.cbParameterName->currentIndex();
 }
@@ -69,8 +76,8 @@ void JumpFitAddWorkspaceDialog::emitWorkspaceChanged(const QString &name) {
   emit workspaceChanged(this, name.toStdString());
 }
 
-void JumpFitAddWorkspaceDialog::emitParameterTypeChanged(int type) {
-  emit parameterTypeChanged(this, type);
+void JumpFitAddWorkspaceDialog::emitParameterTypeChanged(const QString &type) {
+  emit parameterTypeChanged(this, type.toStdString());
 }
 
 } // namespace IDA
diff --git a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.h b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.h
index 07d967ae762c7fcfe7bbcec42eb5732a946aea0d..91f25d475662e8d8a5e310214c9fe78e350c9b13 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.h
+++ b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.h
@@ -20,6 +20,7 @@ public:
   explicit JumpFitAddWorkspaceDialog(QWidget *parent);
 
   std::string workspaceName() const override;
+  std::string parameterType() const;
   int parameterNameIndex() const;
 
   void setParameterTypes(const std::vector<std::string> &types);
@@ -32,12 +33,13 @@ public:
 
 public slots:
   void emitWorkspaceChanged(const QString &name);
-  void emitParameterTypeChanged(int index);
+  void emitParameterTypeChanged(const QString &index);
 
 signals:
   void workspaceChanged(JumpFitAddWorkspaceDialog *dialog,
                         const std::string &workspace);
-  void parameterTypeChanged(JumpFitAddWorkspaceDialog *dialog, int type);
+  void parameterTypeChanged(JumpFitAddWorkspaceDialog *dialog,
+                            const std::string &type);
 
 private:
   Ui::JumpFitAddWorkspaceDialog m_uiForm;
diff --git a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.ui b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.ui
index b13089f01debef6c24f068d602b867cbf89f029d..ac617568763d48ae4971f88f30877dd3573e80c7 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.ui
+++ b/qt/scientific_interfaces/Indirect/JumpFitAddWorkspaceDialog.ui
@@ -92,13 +92,48 @@
     </widget>
    </item>
    <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
+    <widget class="QFrame" name="frame">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>147</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbAdd">
+        <property name="text">
+         <string>Add</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="pbClose">
+        <property name="text">
+         <string>Close</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
   </layout>
@@ -113,36 +148,40 @@
  <resources/>
  <connections>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
+   <sender>pbAdd</sender>
+   <signal>clicked()</signal>
    <receiver>JumpFitAddWorkspaceDialog</receiver>
-   <slot>accept()</slot>
+   <slot>addData()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>248</x>
-     <y>254</y>
+     <x>273</x>
+     <y>166</y>
     </hint>
     <hint type="destinationlabel">
-     <x>157</x>
-     <y>274</y>
+     <x>270</x>
+     <y>221</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
+   <sender>pbClose</sender>
+   <signal>clicked()</signal>
    <receiver>JumpFitAddWorkspaceDialog</receiver>
-   <slot>reject()</slot>
+   <slot>closeDialog()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>316</x>
-     <y>260</y>
+     <x>369</x>
+     <y>164</y>
     </hint>
     <hint type="destinationlabel">
-     <x>286</x>
-     <y>274</y>
+     <x>361</x>
+     <y>212</y>
     </hint>
    </hints>
   </connection>
  </connections>
+ <slots>
+  <slot>addData()</slot>
+  <slot>closeDialog()</slot>
+ </slots>
 </ui>
diff --git a/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.cpp b/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.cpp
index 1ce170360f61bb6b9ac8b0a0a15cfffb53bd8a66..e319bde0ae935431f849f061b4c7d98db6fc1f65 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.cpp
+++ b/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.cpp
@@ -16,13 +16,13 @@ namespace CustomInterfaces {
 namespace IDA {
 
 JumpFitDataPresenter::JumpFitDataPresenter(
-    JumpFitModel *model, IndirectFitDataView *view, QComboBox *cbParameterType,
+    JumpFitModel *model, IIndirectFitDataView *view, QComboBox *cbParameterType,
     QComboBox *cbParameter, QLabel *lbParameterType, QLabel *lbParameter)
     : IndirectFitDataPresenter(
           model, view,
           Mantid::Kernel::make_unique<JumpFitDataTablePresenter>(
               model, view->getDataTable())),
-      m_activeParameterType(0), m_dataIndex(0),
+      m_activeParameterType("Width"), m_dataIndex(0),
       m_cbParameterType(cbParameterType), m_cbParameter(cbParameter),
       m_lbParameterType(lbParameterType), m_lbParameter(lbParameter),
       m_jumpModel(model) {
@@ -36,19 +36,23 @@ JumpFitDataPresenter::JumpFitDataPresenter(
 
   connect(cbParameterType, SIGNAL(currentIndexChanged(const QString &)), this,
           SLOT(setParameterLabel(const QString &)));
-  connect(cbParameterType, SIGNAL(currentIndexChanged(int)), this,
-          SLOT(updateAvailableParameters(int)));
-  connect(cbParameterType, SIGNAL(currentIndexChanged(int)), this,
+  connect(cbParameterType, SIGNAL(currentIndexChanged(const QString &)), this,
+          SLOT(updateAvailableParameters(QString const &)));
+  connect(cbParameterType, SIGNAL(currentIndexChanged(const QString &)), this,
           SIGNAL(dataChanged()));
   connect(cbParameter, SIGNAL(currentIndexChanged(int)), this,
           SLOT(setSingleModelSpectrum(int)));
   connect(cbParameter, SIGNAL(currentIndexChanged(int)), this,
           SIGNAL(dataChanged()));
 
+  connect(view, SIGNAL(sampleLoaded(const QString &)), this,
+          SLOT(updateAvailableParameterTypes()));
   connect(view, SIGNAL(sampleLoaded(const QString &)), this,
           SLOT(updateAvailableParameters()));
   connect(view, SIGNAL(sampleLoaded(const QString &)), this,
           SLOT(updateParameterSelectionEnabled()));
+  connect(view, SIGNAL(sampleLoaded(const QString &)), this,
+          SIGNAL(updateAvailableFitTypes()));
 
   updateParameterSelectionEnabled();
 }
@@ -67,7 +71,7 @@ void JumpFitDataPresenter::showParameterComboBoxes() {
   m_lbParameterType->show();
 }
 
-void JumpFitDataPresenter::setActiveParameterType(int type) {
+void JumpFitDataPresenter::setActiveParameterType(const std::string &type) {
   m_activeParameterType = type;
 }
 
@@ -76,15 +80,26 @@ void JumpFitDataPresenter::updateActiveDataIndex() {
 }
 
 void JumpFitDataPresenter::updateAvailableParameters() {
-  updateAvailableParameters(m_cbParameterType->currentIndex());
+  updateAvailableParameters(m_cbParameterType->currentText());
 }
 
-void JumpFitDataPresenter::updateAvailableParameters(int typeIndex) {
-  if (typeIndex == 0)
+void JumpFitDataPresenter::updateAvailableParameters(const QString &type) {
+  if (type == "Width")
     setAvailableParameters(m_jumpModel->getWidths(0));
-  else
+  else if (type == "EISF")
     setAvailableParameters(m_jumpModel->getEISF(0));
-  setSingleModelSpectrum(m_cbParameter->currentIndex());
+  else
+    setAvailableParameters({});
+
+  if (!type.isEmpty())
+    setSingleModelSpectrum(m_cbParameter->currentIndex());
+}
+
+void JumpFitDataPresenter::updateAvailableParameterTypes() {
+  MantidQt::API::SignalBlocker<QObject> blocker(m_cbParameterType);
+  m_cbParameterType->clear();
+  for (const auto &type : getParameterTypes(m_dataIndex))
+    m_cbParameterType->addItem(QString::fromStdString(type));
 }
 
 void JumpFitDataPresenter::updateParameterSelectionEnabled() {
@@ -118,24 +133,25 @@ void JumpFitDataPresenter::setDialogParameterNames(
   updateParameterOptions(dialog);
 }
 
-void JumpFitDataPresenter::setDialogParameterNames(
-    JumpFitAddWorkspaceDialog *dialog, int parameterType) {
-  setActiveParameterType(parameterType);
+void JumpFitDataPresenter::dialogParameterTypeUpdated(
+    JumpFitAddWorkspaceDialog *dialog, const std::string &type) {
+  setActiveParameterType(type);
   updateParameterOptions(dialog);
 }
 
 void JumpFitDataPresenter::updateParameterOptions(
     JumpFitAddWorkspaceDialog *dialog) {
-  if (m_activeParameterType == 0)
+  if (m_activeParameterType == "Width")
     dialog->setParameterNames(m_jumpModel->getWidths(m_dataIndex));
-  else
+  else if (m_activeParameterType == "EISF")
     dialog->setParameterNames(m_jumpModel->getEISF(m_dataIndex));
+  else
+    dialog->setParameterNames({});
 }
 
 void JumpFitDataPresenter::updateParameterTypes(
     JumpFitAddWorkspaceDialog *dialog) {
   dialog->setParameterTypes(getParameterTypes(m_dataIndex));
-  setActiveParameterType(0);
 }
 
 std::vector<std::string>
@@ -174,19 +190,16 @@ void JumpFitDataPresenter::setSingleModelSpectrum(int parameterIndex) {
 void JumpFitDataPresenter::setModelSpectrum(int index) {
   if (index < 0)
     throw std::runtime_error("No valid parameter was selected.");
-  else if (m_activeParameterType == 0)
+  else if (m_activeParameterType == "Width")
     m_jumpModel->setActiveWidth(static_cast<std::size_t>(index), m_dataIndex);
   else
     m_jumpModel->setActiveEISF(static_cast<std::size_t>(index), m_dataIndex);
 }
 
-void JumpFitDataPresenter::dialogExecuted(IAddWorkspaceDialog const *dialog,
-                                          QDialog::DialogCode result) {
-  if (result == QDialog::Rejected &&
-      m_jumpModel->numberOfWorkspaces() > m_dataIndex)
+void JumpFitDataPresenter::closeDialog() {
+  if (m_jumpModel->numberOfWorkspaces() > m_dataIndex)
     m_jumpModel->removeWorkspace(m_dataIndex);
-  else
-    IndirectFitDataPresenter::dialogExecuted(dialog, result);
+  IndirectFitDataPresenter::closeDialog();
 }
 
 std::unique_ptr<IAddWorkspaceDialog>
@@ -199,8 +212,11 @@ JumpFitDataPresenter::getAddWorkspaceDialog(QWidget *parent) const {
           SLOT(setDialogParameterNames(JumpFitAddWorkspaceDialog *,
                                        const std::string &)));
   connect(dialog.get(),
-          SIGNAL(parameterTypeChanged(JumpFitAddWorkspaceDialog *, int)), this,
-          SLOT(setDialogParameterNames(JumpFitAddWorkspaceDialog *, int)));
+          SIGNAL(parameterTypeChanged(JumpFitAddWorkspaceDialog *,
+                                      const std::string &)),
+          this,
+          SLOT(dialogParameterTypeUpdated(JumpFitAddWorkspaceDialog *,
+                                          const std::string &)));
   return std::move(dialog);
 }
 
diff --git a/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.h b/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.h
index 9b8b80cb174bf0b21aa6a86c57bb9b9d83ab08d2..8e023cc925c08233ff5b667f13356c611e567258 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.h
+++ b/qt/scientific_interfaces/Indirect/JumpFitDataPresenter.h
@@ -18,36 +18,37 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-/**
-  A presenter.
-*/
-class DLLExport JumpFitDataPresenter : public IndirectFitDataPresenter {
+class MANTIDQT_INDIRECT_DLL JumpFitDataPresenter
+    : public IndirectFitDataPresenter {
   Q_OBJECT
 public:
-  JumpFitDataPresenter(JumpFitModel *model, IndirectFitDataView *view,
+  JumpFitDataPresenter(JumpFitModel *model, IIndirectFitDataView *view,
                        QComboBox *cbParameterType, QComboBox *cbParameter,
                        QLabel *lbParameterType, QLabel *lbParameter);
 
+signals:
+  void updateAvailableFitTypes();
+
 private slots:
   void hideParameterComboBoxes();
   void showParameterComboBoxes();
   void updateAvailableParameters();
-  void updateAvailableParameters(int typeIndex);
+  void updateAvailableParameterTypes();
+  void updateAvailableParameters(const QString &type);
   void updateParameterSelectionEnabled();
   void setParameterLabel(const QString &parameter);
+  void dialogParameterTypeUpdated(JumpFitAddWorkspaceDialog *dialog,
+                                  const std::string &type);
   void setDialogParameterNames(JumpFitAddWorkspaceDialog *dialog,
                                const std::string &workspace);
-  void setDialogParameterNames(JumpFitAddWorkspaceDialog *dialog,
-                               int parameterType);
-  void setActiveParameterType(int type);
+  void setActiveParameterType(const std::string &type);
   void updateActiveDataIndex();
   void setSingleModelSpectrum(int index);
 
 private:
   void setAvailableParameters(const std::vector<std::string> &parameters);
   void addDataToModel(IAddWorkspaceDialog const *dialog) override;
-  void dialogExecuted(IAddWorkspaceDialog const *dialog,
-                      QDialog::DialogCode result) override;
+  void closeDialog() override;
   std::unique_ptr<IAddWorkspaceDialog>
   getAddWorkspaceDialog(QWidget *parent) const override;
   void updateParameterOptions(JumpFitAddWorkspaceDialog *dialog);
@@ -56,7 +57,7 @@ private:
   void addWorkspace(IndirectFittingModel *model, const std::string &name);
   void setModelSpectrum(int index);
 
-  int m_activeParameterType;
+  std::string m_activeParameterType;
   std::size_t m_dataIndex;
 
   QComboBox *m_cbParameterType;
diff --git a/qt/scientific_interfaces/Indirect/JumpFitModel.cpp b/qt/scientific_interfaces/Indirect/JumpFitModel.cpp
index d55b93d8cd6d00b7db3044f9efd3483490f58a31..be4af632db31df389a7632270cb435b90b63cda0 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitModel.cpp
+++ b/qt/scientific_interfaces/Indirect/JumpFitModel.cpp
@@ -227,6 +227,7 @@ void JumpFitModel::addWorkspace(Mantid::API::MatrixWorkspace_sptr workspace,
 }
 
 void JumpFitModel::removeWorkspace(std::size_t index) {
+  m_jumpParameters.erase(getWorkspace(index)->getName());
   IndirectFittingModel::removeFittingData(index);
 }
 
diff --git a/qt/scientific_interfaces/Indirect/JumpFitModel.h b/qt/scientific_interfaces/Indirect/JumpFitModel.h
index e992467267f00d7101a08c54c26d2d633c81bf40..eb95e426631a4bb0bcbd5390c60e0f8cd6113a05 100644
--- a/qt/scientific_interfaces/Indirect/JumpFitModel.h
+++ b/qt/scientific_interfaces/Indirect/JumpFitModel.h
@@ -22,6 +22,8 @@ struct JumpFitParameters {
 
 class DLLExport JumpFitModel : public IndirectFittingModel {
 public:
+  using IndirectFittingModel::addWorkspace;
+
   void addWorkspace(Mantid::API::MatrixWorkspace_sptr workspace,
                     const Spectra &) override;
   void removeWorkspace(std::size_t index) override;
diff --git a/qt/scientific_interfaces/Indirect/test/CMakeLists.txt b/qt/scientific_interfaces/Indirect/test/CMakeLists.txt
index c402c6ca2c551c8e65cf191d18256e192ea6dcf3..d7e32222b1c874f57b413bb56f8e2c12deb55ad6 100644
--- a/qt/scientific_interfaces/Indirect/test/CMakeLists.txt
+++ b/qt/scientific_interfaces/Indirect/test/CMakeLists.txt
@@ -2,12 +2,16 @@
 # Testing
 ###########################################################################
 set ( TEST_FILES
+  ConvFitDataPresenterTest.h
+  IndirectDataTablePresenterTest.h
+  IndirectFitDataPresenterTest.h
   IndirectFitDataTest.h
   IndirectFitOutputTest.h
   IndirectFitPlotModelTest.h
   IndirectFitPlotPresenterTest.h
   IndirectFittingModelTest.h
   IndirectSpectrumSelectionPresenterTest.h
+  JumpFitDataPresenterTest.h
 )
 
 mtd_add_qt_tests (TARGET_NAME MantidQtInterfacesIndirectTest
diff --git a/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h b/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ba9fd4d76fa6dc81aa170d5a3fae0dee6d4440a
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/test/ConvFitDataPresenterTest.h
@@ -0,0 +1,149 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQT_CONVFITDATAPRESENTERTEST_H_
+#define MANTIDQT_CONVFITDATAPRESENTERTEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+
+#include "ConvFitDataPresenter.h"
+#include "ConvFitModel.h"
+#include "IIndirectFitDataView.h"
+
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidTestHelpers/IndirectFitDataCreationHelper.h"
+
+using namespace Mantid::API;
+using namespace Mantid::IndirectFitDataCreationHelper;
+using namespace MantidQt::CustomInterfaces;
+using namespace MantidQt::CustomInterfaces::IDA;
+using namespace testing;
+
+namespace {
+
+std::unique_ptr<QTableWidget> createEmptyTableWidget(int columns, int rows) {
+  auto table = std::make_unique<QTableWidget>(columns, rows);
+  for (auto column = 0; column < columns; ++column)
+    for (auto row = 0; row < rows; ++row)
+      table->setItem(row, column, new QTableWidgetItem("item"));
+  return table;
+}
+
+} // namespace
+
+GNU_DIAG_OFF_SUGGEST_OVERRIDE
+
+/// Mock object to mock the view
+class MockConvFitDataView : public IIndirectFitDataView {
+public:
+  /// Signals
+  void emitResolutionLoaded(QString const &workspaceName) {
+    emit resolutionLoaded(workspaceName);
+  }
+
+  /// Public Methods
+  MOCK_CONST_METHOD0(getDataTable, QTableWidget *());
+  MOCK_CONST_METHOD0(isMultipleDataTabSelected, bool());
+  MOCK_CONST_METHOD0(isResolutionHidden, bool());
+  MOCK_METHOD1(setResolutionHidden, void(bool hide));
+  MOCK_METHOD0(disableMultipleDataTab, void());
+
+  MOCK_CONST_METHOD0(getSelectedSample, std::string());
+  MOCK_CONST_METHOD0(getSelectedResolution, std::string());
+
+  MOCK_CONST_METHOD0(getSampleWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getSampleFBSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionFBSuffices, QStringList());
+
+  MOCK_METHOD1(setSampleWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setSampleFBSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionFBSuffices, void(QStringList const &suffices));
+
+  MOCK_METHOD1(readSettings, void(QSettings const &settings));
+  MOCK_METHOD1(validate, UserInputValidator &(UserInputValidator &validator));
+
+  /// Public slots
+  MOCK_METHOD1(displayWarning, void(std::string const &warning));
+};
+
+/// Mock object to mock the model
+class MockConvFitModel : public ConvFitModel {};
+
+GNU_DIAG_ON_SUGGEST_OVERRIDE
+
+class ConvFitDataPresenterTest : public CxxTest::TestSuite {
+public:
+  /// Needed to make sure everything is initialized
+  ConvFitDataPresenterTest() { FrameworkManager::Instance(); }
+
+  static ConvFitDataPresenterTest *createSuite() {
+    return new ConvFitDataPresenterTest();
+  }
+
+  static void destroySuite(ConvFitDataPresenterTest *suite) { delete suite; }
+
+  void setUp() override {
+    m_view = std::make_unique<NiceMock<MockConvFitDataView>>();
+    m_model = std::make_unique<NiceMock<MockConvFitModel>>();
+
+    m_dataTable = createEmptyTableWidget(6, 5);
+    ON_CALL(*m_view, getDataTable()).WillByDefault(Return(m_dataTable.get()));
+
+    m_presenter = std::make_unique<ConvFitDataPresenter>(
+        std::move(m_model.get()), std::move(m_view.get()));
+
+    SetUpADSWithWorkspace m_ads("WorkspaceName", createWorkspace(6));
+    m_model->addWorkspace("WorkspaceName");
+  }
+
+  void tearDown() override {
+    AnalysisDataService::Instance().clear();
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_view.get()));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_model.get()));
+
+    m_presenter.reset();
+    m_model.reset();
+    m_view.reset();
+    m_dataTable.reset();
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit tests to check for successful mock object instantiation
+  ///----------------------------------------------------------------------
+
+  void test_that_the_presenter_and_mock_objects_have_been_created() {
+    TS_ASSERT(m_presenter);
+    TS_ASSERT(m_model);
+    TS_ASSERT(m_view);
+  }
+
+  void test_that_the_data_table_is_the_size_specified() {
+    TS_ASSERT_EQUALS(m_dataTable->rowCount(), 6);
+    TS_ASSERT_EQUALS(m_dataTable->columnCount(), 6);
+  }
+
+  void
+  test_that_the_model_contains_the_correct_number_of_workspace_after_instantiation() {
+    TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 1);
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit Tests that test the signals, methods and slots of the presenter
+  ///----------------------------------------------------------------------
+
+private:
+  std::unique_ptr<QTableWidget> m_dataTable;
+
+  std::unique_ptr<MockConvFitDataView> m_view;
+  std::unique_ptr<MockConvFitModel> m_model;
+  std::unique_ptr<ConvFitDataPresenter> m_presenter;
+};
+#endif
diff --git a/qt/scientific_interfaces/Indirect/test/IndirectDataTablePresenterTest.h b/qt/scientific_interfaces/Indirect/test/IndirectDataTablePresenterTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..680b7249804417545ddefd1910012424a82bb43f
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/test/IndirectDataTablePresenterTest.h
@@ -0,0 +1,374 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQT_INDIRECTDATATABLEPRESENTERTEST_H_
+#define MANTIDQT_INDIRECTDATATABLEPRESENTERTEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+
+#include "IndirectDataTablePresenter.h"
+#include "IndirectFittingModel.h"
+
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidTestHelpers/IndirectFitDataCreationHelper.h"
+
+using namespace Mantid::API;
+using namespace Mantid::IndirectFitDataCreationHelper;
+using namespace MantidQt::CustomInterfaces::IDA;
+using namespace testing;
+
+namespace {
+
+std::unique_ptr<QTableWidget> createEmptyTableWidget(int columns, int rows) {
+  auto table = std::make_unique<QTableWidget>(columns, rows);
+  for (auto column = 0; column < columns; ++column)
+    for (auto row = 0; row < rows; ++row)
+      table->setItem(row, column, new QTableWidgetItem("item"));
+  return table;
+}
+
+struct TableItem {
+  TableItem(std::string const &value) : m_str(value), m_dbl(0.0) {}
+  TableItem(double const &value)
+      : m_str(QString::number(value, 'g', 16).toStdString()), m_dbl(value) {}
+
+  std::string const &asString() const { return m_str; }
+  QString asQString() const { return QString::fromStdString(m_str); }
+  double const &asDouble() const { return m_dbl; }
+
+  bool operator==(std::string const &value) const {
+    return this->asString() == value;
+  }
+
+private:
+  std::string m_str;
+  double m_dbl;
+};
+
+} // namespace
+
+GNU_DIAG_OFF_SUGGEST_OVERRIDE
+
+/// Mock object to mock the model
+class MockIndirectDataTableModel : public IndirectFittingModel {
+public:
+  /// Public methods
+  MOCK_CONST_METHOD2(getFittingRange,
+                     std::pair<double, double>(std::size_t dataIndex,
+                                               std::size_t spectrum));
+  MOCK_CONST_METHOD2(getExcludeRegion,
+                     std::string(std::size_t dataIndex, std::size_t index));
+  MOCK_CONST_METHOD0(isMultiFit, bool());
+  MOCK_CONST_METHOD0(numberOfWorkspaces, std::size_t());
+
+  MOCK_METHOD3(setStartX, void(double startX, std::size_t dataIndex,
+                               std::size_t spectrum));
+  MOCK_METHOD3(setEndX,
+               void(double endX, std::size_t dataIndex, std::size_t spectrum));
+  MOCK_METHOD3(setExcludeRegion,
+               void(std::string const &exclude, std::size_t dataIndex,
+                    std::size_t spectrum));
+
+private:
+  std::string sequentialFitOutputName() const override { return ""; };
+  std::string simultaneousFitOutputName() const override { return ""; };
+  std::string singleFitOutputName(std::size_t index,
+                                  std::size_t spectrum) const override {
+    UNUSED_ARG(index);
+    UNUSED_ARG(spectrum);
+    return "";
+  };
+
+  std::vector<std::string> getSpectrumDependentAttributes() const override {
+    return {};
+  };
+};
+
+GNU_DIAG_ON_SUGGEST_OVERRIDE
+
+class IndirectDataTablePresenterTest : public CxxTest::TestSuite {
+public:
+  /// Needed to make sure everything is initialized
+  IndirectDataTablePresenterTest() { FrameworkManager::Instance(); }
+
+  static IndirectDataTablePresenterTest *createSuite() {
+    return new IndirectDataTablePresenterTest();
+  }
+
+  static void destroySuite(IndirectDataTablePresenterTest *suite) {
+    delete suite;
+  }
+
+  void setUp() override {
+    m_model = std::make_unique<NiceMock<MockIndirectDataTableModel>>();
+    m_table = createEmptyTableWidget(5, 5);
+    m_presenter = std::make_unique<IndirectDataTablePresenter>(
+        std::move(m_model.get()), std::move(m_table.get()));
+
+    SetUpADSWithWorkspace ads("WorkspaceName", createWorkspace(5));
+    m_model->addWorkspace("WorkspaceName");
+  }
+
+  void tearDown() override {
+    AnalysisDataService::Instance().clear();
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_table.get()));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_model.get()));
+
+    m_presenter.reset();
+    m_model.reset();
+    m_table.reset();
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit tests to check for successful presenter instantiation
+  ///----------------------------------------------------------------------
+
+  void test_that_the_model_has_been_instantiated_correctly() {
+    ON_CALL(*m_model, isMultiFit()).WillByDefault(Return(false));
+
+    EXPECT_CALL(*m_model, isMultiFit()).Times(1).WillOnce(Return(false));
+
+    m_model->isMultiFit();
+  }
+
+  void
+  test_that_invoking_setStartX_will_alter_the_relevant_column_in_the_table() {
+    TableItem const startX(2.2);
+
+    m_presenter->setStartX(startX.asDouble(), 0, 0);
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit Tests that test the signals call the correct methods
+  ///----------------------------------------------------------------------
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_startX_when_the_relevant_column_is_changed() {
+    EXPECT_CALL(*m_model, setStartX(2.0, 0, 0)).Times(1);
+    m_table->item(0, START_X_COLUMN)->setText("2.0");
+  }
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_endX_when_the_relevant_column_is_changed() {
+    EXPECT_CALL(*m_model, setEndX(2.0, 0, 0)).Times(1);
+    m_table->item(0, END_X_COLUMN)->setText("2.0");
+  }
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_excludeRegion_when_the_relevant_column_is_changed() {
+    EXPECT_CALL(*m_model, setExcludeRegion("0-4", 0, 0)).Times(1);
+    m_table->item(0, EXCLUDE_REGION_COLUMN)->setText("0-4");
+  }
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_startX_in_every_row_when_the_relevant_column_is_changed() {
+    TableItem const startX(1.5);
+
+    m_table->item(0, START_X_COLUMN)->setText(startX.asQString());
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+  }
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_endX_in_every_row_when_the_relevant_column_is_changed() {
+    TableItem const endX(2.5);
+
+    m_table->item(0, END_X_COLUMN)->setText(endX.asQString());
+
+    assertValueIsGlobal(END_X_COLUMN, endX);
+  }
+
+  void
+  test_that_the_cellChanged_signal_will_set_the_models_excludeRegion_in_every_row_when_the_relevant_column_is_changed() {
+    TableItem const excludeRegion("2-4");
+
+    m_table->item(0, EXCLUDE_REGION_COLUMN)->setText(excludeRegion.asQString());
+
+    assertValueIsGlobal(EXCLUDE_REGION_COLUMN, excludeRegion);
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit Tests that test the methods and slots of the presenter
+  ///----------------------------------------------------------------------
+
+  void
+  test_that_tableDatasetsMatchModel_returns_false_if_the_number_of_data_positions_is_not_equal_to_the_numberOfWorkspaces() {
+    std::size_t const numberOfWorkspaces(2);
+    ON_CALL(*m_model, numberOfWorkspaces())
+        .WillByDefault(Return(numberOfWorkspaces));
+
+    EXPECT_CALL(*m_model, numberOfWorkspaces())
+        .Times(1)
+        .WillOnce(Return(numberOfWorkspaces));
+
+    TS_ASSERT(!m_presenter->tableDatasetsMatchModel());
+  }
+
+  void
+  test_that_tableDatasetsMatchModel_returns_true_if_the_table_datasets_match_the_model() {
+    EXPECT_CALL(*m_model, numberOfWorkspaces()).Times(1).WillOnce(Return(0));
+    TS_ASSERT(m_presenter->tableDatasetsMatchModel());
+  }
+
+  void
+  test_that_addData_will_add_new_data_if_the_index_is_smaller_than_the_number_of_data_positions() {
+    std::size_t const index(0);
+
+    ON_CALL(*m_model, numberOfWorkspaces()).WillByDefault(Return(2));
+
+    EXPECT_CALL(*m_model, numberOfWorkspaces()).Times(1);
+
+    ExpectationSet getRanges =
+        EXPECT_CALL(*m_model, getFittingRange(index, 0)).Times(1);
+    for (auto spectrum = 1; spectrum < m_table->rowCount(); ++spectrum)
+      getRanges += EXPECT_CALL(*m_model, getFittingRange(index, spectrum))
+                       .Times(1)
+                       .After(getRanges);
+
+    m_presenter->addData(index);
+  }
+
+  void
+  test_that_the_setStartX_slot_will_alter_the_relevant_startX_column_in_the_table() {
+    TableItem const startX(1.1);
+
+    m_presenter->setStartX(startX.asDouble(), 0);
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+  }
+
+  void
+  test_that_the_setEndX_slot_will_alter_the_relevant_endX_column_in_the_table() {
+    TableItem const endX(1.1);
+
+    m_presenter->setEndX(endX.asDouble(), 0);
+
+    assertValueIsGlobal(END_X_COLUMN, endX);
+  }
+
+  void
+  test_that_the_setExcludeRegion_slot_will_alter_the_relevant_excludeRegion_column_in_the_table() {
+    TableItem const excludeRegion("2-3");
+
+    m_presenter->setExcludeRegion(excludeRegion.asString(), 0);
+
+    assertValueIsGlobal(EXCLUDE_REGION_COLUMN, excludeRegion);
+  }
+
+  void
+  test_that_setGlobalFittingRange_will_set_the_startX_and_endX_taken_from_the_fitting_range() {
+    std::size_t const index(0);
+    TableItem const startX(1.0);
+    TableItem const endX(2.0);
+    auto const range = std::make_pair(startX.asDouble(), endX.asDouble());
+
+    ON_CALL(*m_model, getFittingRange(index, 0)).WillByDefault(Return(range));
+
+    EXPECT_CALL(*m_model, getFittingRange(index, 0)).Times(1);
+
+    m_presenter->setGlobalFittingRange(true);
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+    assertValueIsGlobal(END_X_COLUMN, endX);
+  }
+
+  void
+  test_that_setGlobalFittingRange_will_set_the_excludeRegion_when_passed_true() {
+    std::size_t const index(0);
+    TableItem const excludeRegion("1-2");
+
+    ON_CALL(*m_model, getExcludeRegion(index, 0)).WillByDefault(Return("1-2"));
+
+    EXPECT_CALL(*m_model, getExcludeRegion(index, 0)).Times(1);
+
+    m_presenter->setGlobalFittingRange(true);
+
+    assertValueIsGlobal(EXCLUDE_REGION_COLUMN, excludeRegion);
+  }
+
+  void
+  test_that_setGlobalFittingRange_will_connect_the_cellChanged_signal_to_updateAllFittingRangeFrom_when_passed_true() {
+    TableItem const startX(1.0);
+
+    m_presenter->setGlobalFittingRange(true);
+    m_table->item(0, START_X_COLUMN)->setText(startX.asQString());
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+  }
+
+  void
+  test_that_setGlobalFittingRange_will_disconnect_the_cellChanged_signal_when_passed_false_so_that_startX_is_not_global() {
+    int const row(1);
+    TableItem const startX(2.5);
+
+    m_presenter->setGlobalFittingRange(false);
+    m_table->item(row, START_X_COLUMN)->setText(startX.asQString());
+
+    assertValueIsNotGlobal(row, START_X_COLUMN, startX);
+  }
+
+  void
+  test_that_setGlobalFittingRange_will_disconnect_the_cellChanged_signal_when_passed_false_so_that_endX_is_not_global() {
+    int const row(0);
+    TableItem const endX(3.5);
+
+    m_presenter->setGlobalFittingRange(false);
+    m_table->item(row, END_X_COLUMN)->setText(endX.asQString());
+
+    assertValueIsNotGlobal(row, END_X_COLUMN, endX);
+  }
+
+  void test_the_enableTable_slot_will_enable_the_table() {
+    m_presenter->disableTable();
+    TS_ASSERT(!m_table->isEnabled());
+
+    m_presenter->enableTable();
+    TS_ASSERT(m_table->isEnabled());
+  }
+
+  void test_the_disableTable_slot_will_enable_the_table() {
+    m_presenter->enableTable();
+    TS_ASSERT(m_table->isEnabled());
+
+    m_presenter->disableTable();
+    TS_ASSERT(!m_table->isEnabled());
+  }
+
+  void test_that_clearTable_will_clear_the_data_table() {
+    m_presenter->clearTable();
+    TS_ASSERT_EQUALS(m_table->rowCount(), 0);
+  }
+
+private:
+  void assertValueIsGlobal(int column, TableItem const &value) const {
+    for (auto row = 0; row < m_table->rowCount(); ++row)
+      TS_ASSERT_EQUALS(value, getTableItem(row, column));
+  }
+
+  void assertValueIsNotGlobal(int valueRow, int column,
+                              TableItem const &value) const {
+    TS_ASSERT_EQUALS(value.asString(), getTableItem(valueRow, column));
+
+    for (auto row = 0; row < m_table->rowCount(); ++row)
+      if (row != valueRow)
+        TS_ASSERT_DIFFERS(value, getTableItem(row, column));
+  }
+
+  std::string getTableItem(int row, int column) const {
+    return m_table->item(row, column)->text().toStdString();
+  }
+
+  std::unique_ptr<QTableWidget> m_table;
+  std::unique_ptr<MockIndirectDataTableModel> m_model;
+  std::unique_ptr<IndirectDataTablePresenter> m_presenter;
+};
+
+#endif
diff --git a/qt/scientific_interfaces/Indirect/test/IndirectFitDataPresenterTest.h b/qt/scientific_interfaces/Indirect/test/IndirectFitDataPresenterTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8998c4adbb67562f17cda9be0e81ff8f326e4f5a
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/test/IndirectFitDataPresenterTest.h
@@ -0,0 +1,309 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQT_INDIRECTFITDATAPRESENTERTEST_H_
+#define MANTIDQT_INDIRECTFITDATAPRESENTERTEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+
+#include "IIndirectFitDataView.h"
+#include "IndirectDataTablePresenter.h"
+#include "IndirectFitDataPresenter.h"
+#include "IndirectFittingModel.h"
+
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidTestHelpers/IndirectFitDataCreationHelper.h"
+
+using namespace Mantid::API;
+using namespace Mantid::IndirectFitDataCreationHelper;
+using namespace MantidQt::CustomInterfaces;
+using namespace MantidQt::CustomInterfaces::IDA;
+using namespace testing;
+
+namespace {
+
+std::unique_ptr<QTableWidget> createEmptyTableWidget(int columns, int rows) {
+  auto table = std::make_unique<QTableWidget>(columns, rows);
+  for (auto column = 0; column < columns; ++column)
+    for (auto row = 0; row < rows; ++row)
+      table->setItem(row, column, new QTableWidgetItem("item"));
+  return table;
+}
+
+struct TableItem {
+  TableItem(std::string const &value) : m_str(value), m_dbl(0.0) {}
+  TableItem(double const &value)
+      : m_str(QString::number(value, 'g', 16).toStdString()), m_dbl(value) {}
+
+  std::string const &asString() const { return m_str; }
+  double const &asDouble() const { return m_dbl; }
+
+  bool operator==(std::string const &value) const {
+    return this->asString() == value;
+  }
+
+private:
+  std::string m_str;
+  double m_dbl;
+};
+
+} // namespace
+
+GNU_DIAG_OFF_SUGGEST_OVERRIDE
+
+/// Mock object to mock the view
+class MockIIndirectFitDataView : public IIndirectFitDataView {
+public:
+  /// Signals
+  void emitSampleLoaded(QString const &name) { emit sampleLoaded(name); }
+
+  /// Public Methods
+  MOCK_CONST_METHOD0(getDataTable, QTableWidget *());
+  MOCK_CONST_METHOD0(isMultipleDataTabSelected, bool());
+  MOCK_CONST_METHOD0(isResolutionHidden, bool());
+  MOCK_METHOD1(setResolutionHidden, void(bool hide));
+  MOCK_METHOD0(disableMultipleDataTab, void());
+
+  MOCK_CONST_METHOD0(getSelectedSample, std::string());
+  MOCK_CONST_METHOD0(getSelectedResolution, std::string());
+
+  MOCK_CONST_METHOD0(getSampleWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getSampleFBSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionFBSuffices, QStringList());
+
+  MOCK_METHOD1(setSampleWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setSampleFBSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionFBSuffices, void(QStringList const &suffices));
+
+  MOCK_METHOD1(readSettings, void(QSettings const &settings));
+  MOCK_METHOD1(validate, UserInputValidator &(UserInputValidator &validator));
+
+  /// Public slots
+  MOCK_METHOD1(displayWarning, void(std::string const &warning));
+};
+
+/// Mock object to mock the model
+class MockIndirectFitDataModel : public IndirectFittingModel {
+public:
+  using IndirectFittingModel::addWorkspace;
+
+  /// Public Methods
+  MOCK_CONST_METHOD0(isMultiFit, bool());
+  MOCK_CONST_METHOD0(numberOfWorkspaces, std::size_t());
+
+  MOCK_METHOD1(addWorkspace, void(std::string const &workspaceName));
+
+private:
+  std::string sequentialFitOutputName() const override { return ""; };
+  std::string simultaneousFitOutputName() const override { return ""; };
+  std::string singleFitOutputName(std::size_t index,
+                                  std::size_t spectrum) const override {
+    UNUSED_ARG(index);
+    UNUSED_ARG(spectrum);
+    return "";
+  };
+
+  std::vector<std::string> getSpectrumDependentAttributes() const override {
+    return {};
+  };
+};
+
+GNU_DIAG_ON_SUGGEST_OVERRIDE
+
+class IndirectFitDataPresenterTest : public CxxTest::TestSuite {
+public:
+  /// Needed to make sure everything is initialized
+  IndirectFitDataPresenterTest() { FrameworkManager::Instance(); }
+
+  static IndirectFitDataPresenterTest *createSuite() {
+    return new IndirectFitDataPresenterTest();
+  }
+
+  static void destroySuite(IndirectFitDataPresenterTest *suite) {
+    delete suite;
+  }
+
+  void setUp() override {
+    m_view = std::make_unique<NiceMock<MockIIndirectFitDataView>>();
+    m_model = std::make_unique<NiceMock<MockIndirectFitDataModel>>();
+    m_table = createEmptyTableWidget(5, 5);
+
+    m_dataTablePresenter = std::make_unique<IndirectDataTablePresenter>(
+        std::move(m_model.get()), std::move(m_table.get()));
+    m_presenter = std::make_unique<IndirectFitDataPresenter>(
+        std::move(m_model.get()), std::move(m_view.get()),
+        std::move(m_dataTablePresenter));
+
+    SetUpADSWithWorkspace m_ads("WorkspaceName", createWorkspace(5));
+    m_model->addWorkspace("WorkspaceName");
+  }
+
+  void tearDown() override {
+    AnalysisDataService::Instance().clear();
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_view.get()));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_model.get()));
+
+    deleteSetup();
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit tests to check for successful mock object instantiation
+  ///----------------------------------------------------------------------
+
+  void test_that_the_model_has_been_instantiated_correctly() {
+    ON_CALL(*m_model, isMultiFit()).WillByDefault(Return(false));
+
+    EXPECT_CALL(*m_model, isMultiFit()).Times(1).WillOnce(Return(false));
+
+    m_model->isMultiFit();
+  }
+
+  void test_that_the_view_has_been_instantiated_correctly() {
+    std::string const sampleName("SampleName_red");
+    ON_CALL(*m_view, getSelectedSample()).WillByDefault(Return(sampleName));
+
+    EXPECT_CALL(*m_view, getSelectedSample())
+        .Times(1)
+        .WillOnce(Return(sampleName));
+
+    m_view->getSelectedSample();
+  }
+
+  void
+  test_that_invoking_a_presenter_method_will_call_the_relevant_methods_in_the_view_and_model() {
+    ON_CALL(*m_view, isMultipleDataTabSelected()).WillByDefault(Return(true));
+    ON_CALL(*m_model, numberOfWorkspaces()).WillByDefault(Return(2));
+
+    Expectation isMultipleData =
+        EXPECT_CALL(*m_view, isMultipleDataTabSelected())
+            .Times(1)
+            .WillOnce(Return(true));
+    EXPECT_CALL(*m_model, numberOfWorkspaces()).Times(1).After(isMultipleData);
+
+    m_presenter->updateSpectraInTable(0);
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit Tests that test the signals, methods and slots of the presenter
+  ///----------------------------------------------------------------------
+
+  void
+  test_that_the_sampleLoaded_signal_will_add_the_loaded_workspace_to_the_model() {
+    std::string const workspaceName("WorkspaceName2");
+    m_ads->addOrReplace(workspaceName, createWorkspace(5));
+
+    EXPECT_CALL(*m_model, addWorkspace(workspaceName)).Times(Exactly(1));
+
+    m_view->emitSampleLoaded(QString::fromStdString(workspaceName));
+  }
+
+  void
+  test_that_setSampleWSSuffices_will_set_the_sample_workspace_suffices_in_the_view() {
+    QStringList const suffices{"suffix1", "suffix2"};
+
+    EXPECT_CALL(*m_view, setSampleWSSuffices(suffices)).Times(Exactly(1));
+
+    m_presenter->setSampleWSSuffices(suffices);
+  }
+
+  void
+  test_that_setSampleFBSuffices_will_set_the_sample_file_browser_suffices_in_the_view() {
+    QStringList const suffices{"suffix1", "suffix2"};
+
+    EXPECT_CALL(*m_view, setSampleFBSuffices(suffices)).Times(Exactly(1));
+
+    m_presenter->setSampleFBSuffices(suffices);
+  }
+
+  void
+  test_that_setResolutionWSSuffices_will_set_the_resolution_workspace_suffices_in_the_view() {
+    QStringList const suffices{"suffix1", "suffix2"};
+
+    EXPECT_CALL(*m_view, setResolutionWSSuffices(suffices)).Times(Exactly(1));
+
+    m_presenter->setResolutionWSSuffices(suffices);
+  }
+
+  void
+  test_that_setResolutionFBSuffices_will_set_the_resolution_file_browser_suffices_in_the_view() {
+    QStringList const suffices{"suffix1", "suffix2"};
+
+    EXPECT_CALL(*m_view, setResolutionFBSuffices(suffices)).Times(Exactly(1));
+
+    m_presenter->setResolutionFBSuffices(suffices);
+  }
+
+  void
+  test_that_setStartX_will_alter_the_relevant_startX_column_in_the_data_table() {
+    TableItem const startX(2.3);
+
+    m_presenter->setStartX(startX.asDouble(), 0, 0);
+
+    assertValueIsGlobal(START_X_COLUMN, startX);
+  }
+
+  void
+  test_that_setEndX_will_alter_the_relevant_endX_column_in_the_data_table() {
+    TableItem const endX(5.5);
+
+    m_presenter->setEndX(endX.asDouble(), 0, 0);
+
+    assertValueIsGlobal(END_X_COLUMN, endX);
+  }
+
+  void
+  test_that_the_setExcludeRegion_slot_will_alter_the_relevant_excludeRegion_column_in_the_table() {
+    TableItem const excludeRegion("2-3");
+
+    m_presenter->setExclude(excludeRegion.asString(), 0, 0);
+
+    assertValueIsGlobal(EXCLUDE_REGION_COLUMN, excludeRegion);
+  }
+
+  void test_that_loadSettings_will_read_the_settings_from_the_view() {
+    QSettings settings;
+    settings.beginGroup("/ISettings");
+
+    EXPECT_CALL(*m_view, readSettings(_)).Times(Exactly(1));
+
+    m_presenter->loadSettings(settings);
+  }
+
+private:
+  void deleteSetup() {
+    m_presenter.reset();
+    m_model.reset();
+    m_view.reset();
+
+    m_dataTablePresenter.reset();
+    m_table.reset();
+  }
+
+  void assertValueIsGlobal(int column, TableItem const &value) const {
+    for (auto row = 0; row < m_table->rowCount(); ++row)
+      TS_ASSERT_EQUALS(value, getTableItem(row, column));
+  }
+
+  std::string getTableItem(int row, int column) const {
+    return m_table->item(row, column)->text().toStdString();
+  }
+
+  std::unique_ptr<QTableWidget> m_table;
+  std::unique_ptr<IndirectDataTablePresenter> m_dataTablePresenter;
+
+  std::unique_ptr<MockIIndirectFitDataView> m_view;
+  std::unique_ptr<MockIndirectFitDataModel> m_model;
+  std::unique_ptr<IndirectFitDataPresenter> m_presenter;
+
+  SetUpADSWithWorkspace *m_ads;
+};
+
+#endif
diff --git a/qt/scientific_interfaces/Indirect/test/JumpFitDataPresenterTest.h b/qt/scientific_interfaces/Indirect/test/JumpFitDataPresenterTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7fba2207c25ad665c6bbaaa40ec500b189213da
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/test/JumpFitDataPresenterTest.h
@@ -0,0 +1,204 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQT_JUMPFITDATAPRESENTERTEST_H_
+#define MANTIDQT_JUMPFITDATAPRESENTERTEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+
+#include "IIndirectFitDataView.h"
+#include "JumpFitDataPresenter.h"
+#include "JumpFitModel.h"
+
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidTestHelpers/IndirectFitDataCreationHelper.h"
+
+using namespace Mantid::API;
+using namespace Mantid::IndirectFitDataCreationHelper;
+using namespace MantidQt::CustomInterfaces;
+using namespace MantidQt::CustomInterfaces::IDA;
+using namespace testing;
+
+namespace {
+
+QString const PARAMETER_TYPE_LABEL("Fit Parameter:");
+QString const PARAMETER_LABEL("Width:");
+
+QStringList getJumpParameters() {
+  QStringList parameters;
+  parameters << "f1.f1.FWHM"
+             << "f2.f1.FWHM";
+  return parameters;
+}
+
+QStringList getJumpParameterTypes() {
+  QStringList parameterTypes;
+  parameterTypes << "Width"
+                 << "EISF";
+  return parameterTypes;
+}
+
+std::vector<std::string> getTextAxisLabels() {
+  return {"f0.Width", "f1.Width", "f2.Width", "f0.EISF", "f1.EISF", "f2.EISF"};
+}
+
+std::unique_ptr<QLabel> createLabel(QString const &text) {
+  return std::make_unique<QLabel>(text);
+}
+
+std::unique_ptr<QComboBox> createComboBox(QStringList const &items) {
+  auto combBox = std::make_unique<QComboBox>();
+  combBox->addItems(items);
+  return combBox;
+}
+
+std::unique_ptr<QTableWidget> createEmptyTableWidget(int columns, int rows) {
+  auto table = std::make_unique<QTableWidget>(columns, rows);
+  for (auto column = 0; column < columns; ++column)
+    for (auto row = 0; row < rows; ++row)
+      table->setItem(row, column, new QTableWidgetItem("item"));
+  return table;
+}
+
+} // namespace
+
+GNU_DIAG_OFF_SUGGEST_OVERRIDE
+
+/// Mock object to mock the view
+class MockJumpFitDataView : public IIndirectFitDataView {
+public:
+  /// Public Methods
+  MOCK_CONST_METHOD0(getDataTable, QTableWidget *());
+  MOCK_CONST_METHOD0(isMultipleDataTabSelected, bool());
+  MOCK_CONST_METHOD0(isResolutionHidden, bool());
+  MOCK_METHOD1(setResolutionHidden, void(bool hide));
+  MOCK_METHOD0(disableMultipleDataTab, void());
+
+  MOCK_CONST_METHOD0(getSelectedSample, std::string());
+  MOCK_CONST_METHOD0(getSelectedResolution, std::string());
+
+  MOCK_CONST_METHOD0(getSampleWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getSampleFBSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionWSSuffices, QStringList());
+  MOCK_CONST_METHOD0(getResolutionFBSuffices, QStringList());
+
+  MOCK_METHOD1(setSampleWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setSampleFBSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionWSSuffices, void(QStringList const &suffices));
+  MOCK_METHOD1(setResolutionFBSuffices, void(QStringList const &suffices));
+
+  MOCK_METHOD1(readSettings, void(QSettings const &settings));
+  MOCK_METHOD1(validate, UserInputValidator &(UserInputValidator &validator));
+
+  /// Public slots
+  MOCK_METHOD1(displayWarning, void(std::string const &warning));
+};
+
+/// Mock object to mock the model
+class MockJumpFitModel : public JumpFitModel {};
+
+GNU_DIAG_ON_SUGGEST_OVERRIDE
+
+class JumpFitDataPresenterTest : public CxxTest::TestSuite {
+public:
+  /// Needed to make sure everything is initialized
+  JumpFitDataPresenterTest() { FrameworkManager::Instance(); }
+
+  static JumpFitDataPresenterTest *createSuite() {
+    return new JumpFitDataPresenterTest();
+  }
+
+  static void destroySuite(JumpFitDataPresenterTest *suite) { delete suite; }
+
+  void setUp() override {
+    m_view = std::make_unique<NiceMock<MockJumpFitDataView>>();
+    m_model = std::make_unique<NiceMock<MockJumpFitModel>>();
+
+    m_dataTable = createEmptyTableWidget(6, 5);
+    m_ParameterTypeCombo = createComboBox(getJumpParameterTypes());
+    m_ParameterCombo = createComboBox(getJumpParameters());
+    m_ParameterTypeLabel = createLabel(PARAMETER_TYPE_LABEL);
+    m_ParameterLabel = createLabel(PARAMETER_LABEL);
+
+    ON_CALL(*m_view, getDataTable()).WillByDefault(Return(m_dataTable.get()));
+
+    m_presenter = std::make_unique<JumpFitDataPresenter>(
+        std::move(m_model.get()), std::move(m_view.get()),
+        std::move(m_ParameterTypeCombo.get()),
+        std::move(m_ParameterCombo.get()),
+        std::move(m_ParameterTypeLabel.get()),
+        std::move(m_ParameterLabel.get()));
+
+    SetUpADSWithWorkspace m_ads(
+        "WorkspaceName", createWorkspaceWithTextAxis(6, getTextAxisLabels()));
+    m_model->addWorkspace("WorkspaceName");
+  }
+
+  void tearDown() override {
+    AnalysisDataService::Instance().clear();
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_view.get()));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(m_model.get()));
+
+    m_presenter.reset();
+    m_model.reset();
+    m_view.reset();
+
+    m_dataTable.reset();
+    m_ParameterTypeCombo.reset();
+    m_ParameterCombo.reset();
+    m_ParameterTypeLabel.reset();
+    m_ParameterLabel.reset();
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit tests to check for successful mock object instantiation
+  ///----------------------------------------------------------------------
+
+  void test_that_the_presenter_and_mock_objects_have_been_created() {
+    TS_ASSERT(m_presenter);
+    TS_ASSERT(m_model);
+    TS_ASSERT(m_view);
+  }
+
+  void test_that_the_comboboxes_contain_the_items_specified_during_the_setup() {
+    auto const parameterTypes = getJumpParameterTypes();
+    auto const parameters = getJumpParameters();
+
+    TS_ASSERT_EQUALS(m_ParameterTypeCombo->itemText(0), parameterTypes[0]);
+    TS_ASSERT_EQUALS(m_ParameterTypeCombo->itemText(1), parameterTypes[1]);
+    TS_ASSERT_EQUALS(m_ParameterCombo->itemText(0), parameters[0]);
+    TS_ASSERT_EQUALS(m_ParameterCombo->itemText(1), parameters[1]);
+  }
+
+  void test_that_the_labels_have_the_correct_text_after_setup() {
+    TS_ASSERT_EQUALS(m_ParameterTypeLabel->text(), PARAMETER_TYPE_LABEL);
+    TS_ASSERT_EQUALS(m_ParameterLabel->text(), PARAMETER_LABEL);
+  }
+
+  void
+  test_that_the_model_contains_the_correct_number_of_workspace_after_instantiation() {
+    TS_ASSERT_EQUALS(m_model->numberOfWorkspaces(), 1);
+  }
+
+  ///----------------------------------------------------------------------
+  /// Unit Tests that test the signals, methods and slots of the presenter
+  ///----------------------------------------------------------------------
+
+private:
+  std::unique_ptr<QTableWidget> m_dataTable;
+  std::unique_ptr<QComboBox> m_ParameterTypeCombo;
+  std::unique_ptr<QComboBox> m_ParameterCombo;
+  std::unique_ptr<QLabel> m_ParameterTypeLabel;
+  std::unique_ptr<QLabel> m_ParameterLabel;
+
+  std::unique_ptr<MockJumpFitDataView> m_view;
+  std::unique_ptr<MockJumpFitModel> m_model;
+  std::unique_ptr<JumpFitDataPresenter> m_presenter;
+};
+#endif
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
index 0cd01b372443db0b549c290b53e2f4a71a1a4cf2..9ab310573b91ca6947fb84744c6e2c7503a9f977 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
@@ -368,6 +368,17 @@ void WidgetAutoSaver::beginGroup(const QString &name) {
  * Ends the scope of the previous begin group.
  */
 void WidgetAutoSaver::endGroup() { m_settings.endGroup(); }
+/**
+ * Checks if a QString is a numeric value
+ * @param qstring:: QString to test
+ * @returns :: bool if it is a number
+ */
+bool isNumber(const QString &qstring) {
+  bool isNumber = false;
+  auto value = qstring.toDouble(&isNumber);
+  UNUSED_ARG(value);
+  return isNumber;
+}
 
 /**
  * Get a run label for the workspace.
@@ -659,7 +670,6 @@ void groupWorkspaces(const std::string &groupName,
     groupingAlg->execute();
   }
 }
-
 /**
  * Replaces the named log value in the given workspace with the given value
  * @param wsName :: [input] Name of workspace
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.h b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.h
index 215a2c7c6a91ea217b568f1867910e6948ad9877..46e897e825325e043320fe6f9e6c2d9fc66ebf40 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.h
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.h
@@ -45,7 +45,6 @@ enum class MultiFitState { Enabled, Disabled };
 } // namespace Muon
 
 namespace MuonAnalysisHelper {
-
 /// Sets double validator for specified field
 MANTIDQT_MUONINTERFACE_DLL void setDoubleValidator(QLineEdit *field,
                                                    bool allowEmpty = false);
@@ -74,6 +73,7 @@ getRunLabel(const Mantid::API::Workspace_sptr &ws);
 MANTIDQT_MUONINTERFACE_DLL std::string
 getRunLabel(const std::vector<Mantid::API::Workspace_sptr> &wsList);
 
+MANTIDQT_MUONINTERFACE_DLL bool isNumber(const QString &string);
 /// Get a run label given instrument and run numbers
 MANTIDQT_MUONINTERFACE_DLL std::string
 getRunLabel(const std::string &instrument, const std::vector<int> &runNumbers);
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.cpp
index ce0d6c54bc41021e60de5d4b327c21601e9fbeb6..627a5011d120d5b0241ee72cbc3c3b2f5b89a77a 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.cpp
@@ -4,6 +4,7 @@
 //     NScD Oak Ridge National Laboratory, European Spallation Source
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
+
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/ITableWorkspace.h"
@@ -22,7 +23,6 @@ using Mantid::API::ITableWorkspace_sptr;
 using Mantid::API::TableRow;
 using Mantid::API::WorkspaceFactory;
 using Mantid::API::WorkspaceGroup;
-
 namespace {
 
 /**
@@ -91,7 +91,6 @@ MuonAnalysisResultTableCreator::MuonAnalysisResultTableCreator(
         "Log values passed in to result table creator are null!");
   }
 }
-
 /**
  * Create a results table with the given options
  * @returns :: results table workspace
@@ -129,9 +128,13 @@ ITableWorkspace_sptr MuonAnalysisResultTableCreator::createTable() const {
   for (const auto &log : m_logs) {
 
     auto val = valMap[log];
-    // multiple files use strings due to x-y format
-    if (val.canConvert<double>() && !log.endsWith(" (text)")) {
+    auto dashIndex = val.toString().indexOf("-");
 
+    // multiple files use strings due to x-y format
+    if (dashIndex != 0 && dashIndex != -1) {
+      addColumnToTable(table, "str", log.toStdString(), PLOT_TYPE_X);
+    } else if (MuonAnalysisHelper::isNumber(val.toString()) &&
+               !log.endsWith(" (text)")) {
       addColumnToResultsTable(table, wsParamsByLabel, log); //
 
     } else {
@@ -498,13 +501,15 @@ void MuonAnalysisResultTableCreator::writeDataForSingleFit(
         auto seconds =
             val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9;
         valueToWrite = QString::number(seconds);
-      } else if (val.canConvert<double>() && !log.endsWith(" (text)")) {
+      } else if (MuonAnalysisHelper::isNumber(val.toString()) &&
+                 !log.endsWith(" (text)")) {
         valueToWrite = QString::number(val.toDouble());
       } else {
         valueToWrite = val.toString();
       }
 
-      if (val.canConvert<double>() && !log.endsWith(" (text)")) {
+      if (MuonAnalysisHelper::isNumber(val.toString()) &&
+          !log.endsWith(" (text)")) {
         row << valueToWrite.toDouble();
       } else {
         row << valueToWrite.toStdString();
@@ -541,13 +546,13 @@ void MuonAnalysisResultTableCreator::addColumnToResultsTable(
   for (const auto &wsName : paramsByLabel[labelName].keys()) {
     const auto &logValues = m_logValues->value(wsName);
     const auto &val = logValues[log];
-
     // Special case: if log is time in sec, subtract the first start time
     if (log.endsWith(" (s)")) {
       auto seconds =
           val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9;
       valuesPerWorkspace.append(QString::number(seconds));
-    } else if (val.canConvert<double>() && !log.endsWith(" (text)")) {
+    } else if (MuonAnalysisHelper::isNumber(val.toString()) &&
+               !log.endsWith(" (text)")) {
 
       valuesPerWorkspace.append(QString::number(val.toDouble()));
 
@@ -556,6 +561,13 @@ void MuonAnalysisResultTableCreator::addColumnToResultsTable(
     }
   }
   valuesPerWorkspace.sort();
+
+  auto dashIndex = valuesPerWorkspace.front().toStdString().find_first_of("-");
+  if (dashIndex != std::string::npos && dashIndex != 0) {
+
+    addColumnToTable(table, "str", log.toStdString(), PLOT_TYPE_X);
+    return;
+  }
   const auto &min = valuesPerWorkspace.front().toDouble();
   const auto &max = valuesPerWorkspace.back().toDouble();
   if (min == max) {
@@ -594,12 +606,16 @@ void MuonAnalysisResultTableCreator::writeDataForMultipleFits(
         const auto &logValues = m_logValues->value(wsName);
         const auto &val = logValues[log];
 
+        auto dashIndex = val.toString().indexOf("-");
         // Special case: if log is time in sec, subtract the first start time
         if (log.endsWith(" (s)")) {
           auto seconds =
               val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9;
           valuesPerWorkspace.append(QString::number(seconds));
-        } else if (val.canConvert<double>() && !log.endsWith(" (text)")) {
+        } else if (dashIndex != 0 && dashIndex != -1) {
+          valuesPerWorkspace.append(logValues[log].toString());
+        } else if (MuonAnalysisHelper::isNumber(val.toString()) &&
+                   !log.endsWith(" (text)")) {
 
           valuesPerWorkspace.append(QString::number(val.toDouble()));
 
@@ -612,15 +628,42 @@ void MuonAnalysisResultTableCreator::writeDataForMultipleFits(
       // Why not use std::minmax_element? To avoid MSVC warning: QT bug 41092
       // (https://bugreports.qt.io/browse/QTBUG-41092)
       valuesPerWorkspace.sort();
-      const auto &min = valuesPerWorkspace.front().toDouble();
-      const auto &max = valuesPerWorkspace.back().toDouble();
-      if (min == max) {
-        row << min;
-      } else {
+
+      auto dashIndex =
+          valuesPerWorkspace.front().toStdString().find_first_of("-");
+      if (dashIndex != std::string::npos && dashIndex != 0) {
         std::ostringstream oss;
-        oss << valuesPerWorkspace.front().toStdString() << "-"
-            << valuesPerWorkspace.back().toStdString();
+        auto dad = valuesPerWorkspace.front().toStdString();
+        oss << valuesPerWorkspace.front().toStdString();
         row << oss.str();
+
+      } else {
+        if (MuonAnalysisHelper::isNumber(valuesPerWorkspace.front())) {
+          const auto &min = valuesPerWorkspace.front().toDouble();
+          const auto &max = valuesPerWorkspace.back().toDouble();
+          if (min == max) {
+            row << min;
+          } else {
+            std::ostringstream oss;
+            oss << valuesPerWorkspace.front().toStdString() << "-"
+                << valuesPerWorkspace.back().toStdString();
+            row << oss.str();
+          }
+        } else {
+          const auto &front = valuesPerWorkspace.front().toStdString();
+          const auto &back = valuesPerWorkspace.back().toStdString();
+          if (front == back) {
+            row << front;
+          } else {
+            std::ostringstream oss;
+            oss << valuesPerWorkspace[0].toStdString();
+
+            for (int k = 1; k < valuesPerWorkspace.size(); k++) {
+              oss << ", " << valuesPerWorkspace[k].toStdString();
+              row << oss.str();
+            }
+          }
+        }
       }
       columnIndex++;
     }
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
index 779e0258bf55425335de263737f7eaeaa56abc68..fe68a7e0c12a2c2a18561f9b2ae7ab61ea05d3e2 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
@@ -109,4 +109,4 @@ private:
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* MANTIDQT_CUSTOMINTERFACES_MUONANALYSISRESULTTABLECREATOR_H_ */
\ No newline at end of file
+#endif /* MANTIDQT_CUSTOMINTERFACES_MUONANALYSISRESULTTABLECREATOR_H_ */
diff --git a/qt/scientific_interfaces/test/MuonAnalysisHelperTest.h b/qt/scientific_interfaces/test/MuonAnalysisHelperTest.h
index 34e17a04e66040d841e10b38c14401733d0bede2..72e1f51c2d8436077d93376a4716e83b40027daa 100644
--- a/qt/scientific_interfaces/test/MuonAnalysisHelperTest.h
+++ b/qt/scientific_interfaces/test/MuonAnalysisHelperTest.h
@@ -54,6 +54,15 @@ public:
   MuonAnalysisHelperTest() {
     FrameworkManager::Instance(); // So that framework is initialized
   }
+  void test_isNumberInt() { TS_ASSERT(isNumber(QString("12"))); }
+
+  void test_isNumberDouble() { TS_ASSERT(isNumber(QString("1.2"))); }
+  void test_isNumberNegInt() { TS_ASSERT(isNumber(QString("-12"))); }
+  void test_isNumberNegDouble() { TS_ASSERT(isNumber(QString("-1.2"))); }
+  void test_isNumberFail() { TS_ASSERT(!isNumber(QString("ABC"))); }
+  void test_isNumberFailMix() { TS_ASSERT(!isNumber(QString("1BC4"))); }
+  void test_isNumberFailRange() { TS_ASSERT(!isNumber(QString("1-4"))); }
+  void test_isNumberFailRange2() { TS_ASSERT(!isNumber(QString("1 to 4"))); }
 
   void test_getRunLabel_singleWs() {
     std::string label = getRunLabel(createWs("MUSR", 15189));
diff --git a/qt/scientific_interfaces/test/ReflMockObjects.h b/qt/scientific_interfaces/test/ReflMockObjects.h
index 6b7f3d7cead0f4b9c6e5cb0896045b69cbae02a0..9c3af8c3f8fc6cef42939386f939e827ead83338 100644
--- a/qt/scientific_interfaces/test/ReflMockObjects.h
+++ b/qt/scientific_interfaces/test/ReflMockObjects.h
@@ -130,6 +130,8 @@ public:
   MOCK_CONST_METHOD0(getCAlpha, std::string());
   MOCK_CONST_METHOD0(getCAp, std::string());
   MOCK_CONST_METHOD0(getCPp, std::string());
+  MOCK_CONST_METHOD0(getFloodCorrection, std::string());
+  MOCK_CONST_METHOD0(getFloodWorkspace, std::string());
   MOCK_CONST_METHOD0(getIntMonCheck, std::string());
   MOCK_CONST_METHOD0(getMonitorIntegralMin, std::string());
   MOCK_CONST_METHOD0(getMonitorIntegralMax, std::string());
diff --git a/qt/scientific_interfaces/test/ReflSettingsPresenterTest.h b/qt/scientific_interfaces/test/ReflSettingsPresenterTest.h
index 435a6012813952422de09fb230f5c82781e46659..38c2c39296f1df589ed1b8974da0a2ede6322a40 100644
--- a/qt/scientific_interfaces/test/ReflSettingsPresenterTest.h
+++ b/qt/scientific_interfaces/test/ReflSettingsPresenterTest.h
@@ -547,6 +547,7 @@ public:
     EXPECT_CALL(mockView, getCAp()).Times(Exactly(0));
     EXPECT_CALL(mockView, getCPp()).Times(Exactly(0));
     EXPECT_CALL(mockView, getPolarisationCorrections()).Times(Exactly(1));
+    EXPECT_CALL(mockView, getFloodCorrection()).Times(Exactly(1));
     EXPECT_CALL(mockView, getStartOverlap()).Times(Exactly(2));
     EXPECT_CALL(mockView, getEndOverlap()).Times(Exactly(2));
     EXPECT_CALL(mockView, getPerAngleOptions()).Times(Exactly(2));
diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt
index 5fb28c2bcf8be47c26ad9de1341ee1684628927f..2dc7ba3683f76fba110c1eb2ca67511ada5505bc 100644
--- a/qt/widgets/common/CMakeLists.txt
+++ b/qt/widgets/common/CMakeLists.txt
@@ -14,6 +14,7 @@ set ( QT5_SRC_FILES
   src/FindFilesThreadPoolManager.cpp
   src/FindFilesWorker.cpp
   src/FindReplaceDialog.cpp
+  src/FitPropertyBrowser.cpp
   src/FlowLayout.cpp
   src/FunctionBrowser.cpp
   src/GenericDialog.cpp
@@ -35,18 +36,22 @@ set ( QT5_SRC_FILES
   src/MantidWSIndexDialog.cpp
   src/Message.cpp
   src/MessageDisplay.cpp
+  src/MultifitSetupDialog.cpp
   src/MWRunFiles.cpp
   src/OptionsPropertyWidget.cpp
   src/pixmaps.cpp
   src/PluginLibraries.cpp
   src/ProcessingAlgoWidget.cpp
+  src/PropertyHandler.cpp
   src/PropertyWidget.cpp
   src/PropertyWidgetFactory.cpp
   src/PythonRunner.cpp
   src/QtSignalChannel.cpp
   src/RenameParDialog.cpp
   src/ScriptEditor.cpp
+  src/SequentialFitDialog.cpp
   src/SelectFunctionDialog.cpp
+  src/SelectWorkspacesDialog.cpp
   src/TextPropertyWidget.cpp
   src/UserFunctionDialog.cpp
   src/UserSubWindow.cpp
@@ -91,6 +96,7 @@ set ( QT5_MOC_FILES
   inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h
   inc/MantidQtWidgets/Common/FindFilesWorker.h
   inc/MantidQtWidgets/Common/FindReplaceDialog.h
+  inc/MantidQtWidgets/Common/FitPropertyBrowser.h
   inc/MantidQtWidgets/Common/FunctionBrowser.h
   inc/MantidQtWidgets/Common/GenericDialog.h
   inc/MantidQtWidgets/Common/InputController.h
@@ -104,15 +110,19 @@ set ( QT5_MOC_FILES
   inc/MantidQtWidgets/Common/MantidWidget.h
   inc/MantidQtWidgets/Common/MantidWSIndexDialog.h
   inc/MantidQtWidgets/Common/MessageDisplay.h
+  inc/MantidQtWidgets/Common/MultifitSetupDialog.h
   inc/MantidQtWidgets/Common/MWRunFiles.h
   inc/MantidQtWidgets/Common/OptionsPropertyWidget.h
   inc/MantidQtWidgets/Common/ProcessingAlgoWidget.h
+  inc/MantidQtWidgets/Common/PropertyHandler.h
   inc/MantidQtWidgets/Common/PropertyWidget.h
   inc/MantidQtWidgets/Common/PythonRunner.h
   inc/MantidQtWidgets/Common/QtSignalChannel.h
   inc/MantidQtWidgets/Common/RenameParDialog.h
   inc/MantidQtWidgets/Common/ScriptEditor.h
+  inc/MantidQtWidgets/Common/SequentialFitDialog.h
   inc/MantidQtWidgets/Common/SelectFunctionDialog.h
+  inc/MantidQtWidgets/Common/SelectWorkspacesDialog.h
   inc/MantidQtWidgets/Common/TextPropertyWidget.h
   inc/MantidQtWidgets/Common/UserFunctionDialog.h
   inc/MantidQtWidgets/Common/UserSubWindow.h
@@ -157,8 +167,10 @@ set ( QT5_INC_FILES
   inc/MantidQtWidgets/Common/InterfaceFactory.h
   inc/MantidQtWidgets/Common/MantidDesktopServices.h
   inc/MantidQtWidgets/Common/MantidTreeWidgetItem.h
+  inc/MantidQtWidgets/Common/MultifitSetupDialog.h
   inc/MantidQtWidgets/Common/pixmaps.h
   inc/MantidQtWidgets/Common/PropertyWidgetFactory.h
+  inc/MantidQtWidgets/Common/SequentialFitDialog.h
   inc/MantidQtWidgets/Common/WidgetScrollbarDecorator.h
   inc/MantidQtWidgets/Common/WorkspacePresenter/ADSAdapter.h
   inc/MantidQtWidgets/Common/WorkspacePresenter/IWorkspaceDockView.h
@@ -172,9 +184,11 @@ set ( QT5_INC_FILES
 set ( QT5_UI_FILES
   inc/MantidQtWidgets/Common/DataSelector.ui
   inc/MantidQtWidgets/Common/ManageUserDirectories.ui
+  inc/MantidQtWidgets/Common/MultifitSetupDialog.ui
   inc/MantidQtWidgets/Common/MWRunFiles.ui
   inc/MantidQtWidgets/Common/ProcessingAlgoWidget.ui
   inc/MantidQtWidgets/Common/RenameParDialog.ui
+  inc/MantidQtWidgets/Common/SequentialFitDialog.ui
   inc/MantidQtWidgets/Common/SelectFunctionDialog.ui
   inc/MantidQtWidgets/Common/UserFunctionDialog.ui
 )
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h
index b063c100176ec0febd4d90e29814af59aeef5ebe..e7b35a7a19e0eea62ac1c616ad7207fc0cfe0b04 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FitPropertyBrowser.h
@@ -105,6 +105,8 @@ public:
   /// Get function parameter names
   QStringList getParameterNames() const;
 
+  /// Load function
+  void loadFunction(const QString &funcString);
   /// Create a new function
   PropertyHandler *addFunction(const std::string &fnName);
 
@@ -176,6 +178,8 @@ public:
   double endX() const;
   /// Set the end X
   void setEndX(double end) override;
+  /// Set both start and end X
+  void setXRange(double start, double end);
   /// Set LogValue for PlotPeakByLogValue
   void setLogValue(const QString &lv = "");
   /// Get LogValue
@@ -201,11 +205,12 @@ public:
   /// Returns true if the function is ready for a fit
   bool isFitEnabled() const;
 
+  /// Enable/disable the Fit buttons;
+  virtual void setFitEnabled(bool enable);
+
   /// Display a tip
   void setTip(const QString &txt);
 
-  /// return groupMember
-  // const std::string groupMember() const {return m_groupMember;};
   /// alter text of Plot Guess
   void setTextPlotGuess(const QString text);
 
@@ -259,6 +264,11 @@ public:
   /// Allow or disallow sequential fits (depending on whether other conditions
   /// are met)
   void allowSequentialFits(bool allow) override;
+
+  // Methods intended for testing only
+
+  int sizeOfFunctionsGroup() const;
+  void addAllowedSpectra(const QString &wsName, const QList<int> &wsIndices);
 public slots:
   virtual void fit();
   virtual void sequentialFit();
@@ -511,8 +521,7 @@ protected:
 private:
   ///
   QPushButton *createFitMenuButton(QWidget *w);
-  /// load and save function
-  void loadFunction(const QString &funcString);
+  /// save function
   void saveFunction(const QString &fnName);
   /// Check if the workspace can be used in the fit
   virtual bool isWorkspaceValid(Mantid::API::Workspace_sptr) const;
@@ -521,8 +530,6 @@ private:
 
   /// disable undo when the function changes
   void disableUndo();
-  /// Enable/disable the Fit button;
-  virtual void setFitEnabled(bool yes);
   /// Create a string property and set some settings
   QtProperty *addStringProperty(const QString &name) const;
   void setStringPropertyValue(QtProperty *prop, const QString &value) const;
@@ -590,9 +597,6 @@ private:
   /// Default background name
   std::string m_defaultBackground;
 
-  /// The current function index
-  int m_index_;
-
   /// Shows if the PeakPickerTool is on
   bool m_peakToolOn;
 
@@ -608,11 +612,6 @@ private:
   /// The autobackground handler
   PropertyHandler *m_autoBackground;
 
-  /// if isWorkspaceAGroup() is true m_groupMember keeps name of the
-  /// MatrixWorkspace
-  /// fitted with theFunction()
-  // std::string m_groupMember;
-
   /// Log names
   QStringList m_logs;
 
@@ -628,6 +627,14 @@ private:
   /// Should the data be normalised before fitting?
   bool m_shouldBeNormalised;
 
+  /// If non-empty it contains references to the spectra
+  /// allowed to be fitted in this browser:
+  ///   keys are workspace names,
+  ///   values are lists of workspace indices
+  QMap<QString, QList<int>> m_allowedSpectra;
+  /// Store workspace index to revert to in case validation fails
+  int m_oldWorkspaceIndex;
+
   friend class PropertyHandler;
   friend class CreateAttributeProperty;
   friend class SetAttribute;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/IndirectFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/IndirectFitPropertyBrowser.h
index 44f66409e5f92b91698e7c8a5f35bde8686b16eb..0c49f70b188e717e4a2b5851ab2a39651b86e6f3 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/IndirectFitPropertyBrowser.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/IndirectFitPropertyBrowser.h
@@ -65,6 +65,8 @@ public:
 
   void setCustomSettingEnabled(const QString &customName, bool enabled);
 
+  void setFitEnabled(bool enable) override;
+
   void addCheckBoxFunctionGroup(
       const QString &groupName,
       const std::vector<Mantid::API::IFunction_sptr> &functions,
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MessageDisplay.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MessageDisplay.h
index 18763ca86043fa125f3228dc9f7f0999931e6045..2d90920f728b0cad1a22bf558f58c36a98d6f573 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/MessageDisplay.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MessageDisplay.h
@@ -104,6 +104,12 @@ private slots:
   void showContextMenu(const QPoint &event);
   /// Set the global logging level
   void setLogLevel(int priority);
+  /// Set the number of blocks kept by the display
+  void setScrollbackLimit();
+  /// Return the maximum number of lines displayed
+  int maximumLineCount() const;
+  /// Set the maximum number of lines displayed
+  void setMaximumLineCount(int count);
 
 private:
   /// Setup the actions
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h b/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
index 063bb3a66a78d4658e1f97ec5322079edbaa9964..8db856015f9014424029b5a60739013d7f951695 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
@@ -63,8 +63,8 @@ class EXPORT_OPT_MANTIDQT_COMMON WorkspaceTreeWidget
       public IWorkspaceDockView {
   Q_OBJECT
 public:
-  explicit WorkspaceTreeWidget(MantidQt::MantidWidgets::MantidDisplayBase *mdb,
-                               QWidget *parent = nullptr);
+  WorkspaceTreeWidget(MantidQt::MantidWidgets::MantidDisplayBase *mdb,
+                      bool viewOnly = false, QWidget *parent = nullptr);
   ~WorkspaceTreeWidget();
   void dropEvent(QDropEvent *de) override;
 
@@ -165,6 +165,7 @@ private:
   void setupWidgetLayout();
   void setupLoadButtonMenu();
   void setupConnections();
+  void hideButtonToolbar();
 
   MantidQt::MantidWidgets::MantidItemSortScheme
   whichCriteria(SortCriteria criteria);
@@ -242,6 +243,7 @@ private:
   QLineEdit *m_workspaceFilter;
   QActionGroup *m_sortChoiceGroup;
   QFileDialog *m_saveFolderDialog;
+  bool m_viewOnly;
 
   QMenu *m_sortMenu, *m_saveMenu;
   // Context-menu actions
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h b/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h
index e94358dfb29e198c35f898f9c6da2655b282f555..5f87ac0174ac0323bded9fa01049dd6b92c7a5d9 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h
@@ -35,7 +35,7 @@ class EXPORT_OPT_MANTIDQT_COMMON WorkspaceTreeWidgetSimple
     : public WorkspaceTreeWidget {
   Q_OBJECT
 public:
-  explicit WorkspaceTreeWidgetSimple(QWidget *parent = nullptr);
+  explicit WorkspaceTreeWidgetSimple(bool viewOnly, QWidget *parent = nullptr);
   ~WorkspaceTreeWidgetSimple();
 
   // Context Menu Handlers
@@ -52,6 +52,7 @@ signals:
   void showDataClicked(const QStringList &workspaceNames);
 
   void workspaceDoubleClicked(const QString &workspaceName);
+  void treeSelectionChanged();
 
 private slots:
   void onPlotSpectrumClicked();
diff --git a/qt/widgets/common/src/DataSelector.cpp b/qt/widgets/common/src/DataSelector.cpp
index ee2b491d544d91bc683e6784d878666acafa1d61..476c0ea8447f57e7ae6af0d43407f70a94147f4a 100644
--- a/qt/widgets/common/src/DataSelector.cpp
+++ b/qt/widgets/common/src/DataSelector.cpp
@@ -17,6 +17,23 @@
 #include <QMimeData>
 #include <QUrl>
 
+namespace {
+
+std::string extractLastOf(const std::string &str,
+                          const std::string &delimiter) {
+  const auto cutIndex = str.rfind(delimiter);
+  if (cutIndex != std::string::npos)
+    return str.substr(cutIndex, str.size() - cutIndex);
+  return str;
+}
+
+std::string loadAlgName(const std::string &filePath) {
+  const auto suffix = extractLastOf(filePath, ".");
+  return suffix == ".dave" ? "LoadDaveGrp" : "Load";
+}
+
+} // namespace
+
 namespace MantidQt {
 namespace MantidWidgets {
 
@@ -125,8 +142,8 @@ bool DataSelector::isValid() {
         // don't use algorithm runner because we need to know instantly.
         const QString filepath =
             m_uiForm.rfFileInput->getUserInput().toString();
-        const Algorithm_sptr loadAlg =
-            AlgorithmManager::Instance().createUnmanaged("Load");
+        const auto loadAlg = AlgorithmManager::Instance().createUnmanaged(
+            loadAlgName(filepath.toStdString()));
         loadAlg->initialize();
         loadAlg->setProperty("Filename", filepath.toStdString());
         loadAlg->setProperty("OutputWorkspace", wsName.toStdString());
@@ -179,14 +196,14 @@ QString DataSelector::getProblem() const {
  */
 void DataSelector::autoLoadFile(const QString &filepath) {
   using namespace Mantid::API;
-  QString baseName = getWsNameFromFiles();
+  const auto baseName = getWsNameFromFiles().toStdString();
 
   // create instance of load algorithm
-  const Algorithm_sptr loadAlg =
-      AlgorithmManager::Instance().createUnmanaged("Load");
+  const auto loadAlg = AlgorithmManager::Instance().createUnmanaged(
+      loadAlgName(filepath.toStdString()));
   loadAlg->initialize();
   loadAlg->setProperty("Filename", filepath.toStdString());
-  loadAlg->setProperty("OutputWorkspace", baseName.toStdString());
+  loadAlg->setProperty("OutputWorkspace", baseName);
 
   m_algRunner.startAlgorithm(loadAlg);
 }
diff --git a/qt/widgets/common/src/FitPropertyBrowser.cpp b/qt/widgets/common/src/FitPropertyBrowser.cpp
index 2a0881ef619a0387b77535581a07cc770507f99a..18a257bfad10647777a697413679c28349b73867 100644
--- a/qt/widgets/common/src/FitPropertyBrowser.cpp
+++ b/qt/widgets/common/src/FitPropertyBrowser.cpp
@@ -105,13 +105,13 @@ FitPropertyBrowser::FitPropertyBrowser(QWidget *parent, QObject *mantidui)
       m_setupActionRemove(nullptr), m_tip(nullptr), m_fitSelector(nullptr),
       m_fitTree(nullptr), m_currentHandler(nullptr),
       m_defaultFunction("Gaussian"), m_defaultPeak("Gaussian"),
-      m_defaultBackground("LinearBackground"), m_index_(0), m_peakToolOn(false),
+      m_defaultBackground("LinearBackground"), m_peakToolOn(false),
       m_auto_back(false),
       m_autoBgName(QString::fromStdString(
           Mantid::Kernel::ConfigService::Instance().getString(
               "curvefitting.autoBackground"))),
       m_autoBackground(nullptr), m_decimals(-1), m_mantidui(mantidui),
-      m_shouldBeNormalised(false) {
+      m_shouldBeNormalised(false), m_oldWorkspaceIndex(0) {
   Mantid::API::FrameworkManager::Instance().loadPlugins();
 
   // Try to create a Gaussian. Failing will mean that CurveFitting dll is not
@@ -175,8 +175,10 @@ void FitPropertyBrowser::init() {
   /* Create function group */
   QtProperty *functionsGroup = m_groupManager->addProperty("Functions");
 
-  connect(this, SIGNAL(xRangeChanged(double, double)), m_mantidui,
-          SLOT(x_range_from_picker(double, double)));
+  if (m_mantidui) {
+    connect(this, SIGNAL(xRangeChanged(double, double)), m_mantidui,
+            SLOT(x_range_from_picker(double, double)));
+  }
   /* Create input - output properties */
   QtProperty *settingsGroup = m_groupManager->addProperty("Settings");
   m_startX = addDoubleProperty("StartX");
@@ -355,6 +357,7 @@ void FitPropertyBrowser::populateFitMenuButton(QSignalMapper *fitMapper,
  */
 void FitPropertyBrowser::initBasicLayout(QWidget *w) {
   QPushButton *btnFit = createFitMenuButton(w);
+  btnFit->setObjectName("button_Fit");
   // to be able to change windows title from tread
   connect(this, SIGNAL(changeWindowTitle(const QString &)), this,
           SLOT(setWindowTitle(const QString &)));
@@ -387,17 +390,22 @@ void FitPropertyBrowser::initBasicLayout(QWidget *w) {
           SLOT(vectorSizeChanged(QtProperty *)));
 
   QVBoxLayout *layout = new QVBoxLayout(w);
+  layout->setObjectName("vlayout");
   QGridLayout *buttonsLayout = new QGridLayout();
 
   QPushButton *btnDisplay = new QPushButton("Display");
+  btnDisplay->setObjectName("button_Display");
   QMenu *displayMenu = new QMenu(this);
+  displayMenu->setObjectName("menu_Display");
   m_displayActionPlotGuess = new QAction("Plot Guess", this);
   m_displayActionPlotGuess->setEnabled(false);
   m_displayActionQuality = new QAction("Quality", this);
+  m_displayActionQuality->setObjectName("action_Quality");
   m_displayActionQuality->setCheckable(true);
   m_displayActionQuality->setChecked(true);
   m_displayActionClearAll = new QAction("Clear fit curves", this);
   QSignalMapper *displayMapper = new QSignalMapper(this);
+  displayMapper->setObjectName("mapper_Display");
 
   displayMapper->setMapping(m_displayActionPlotGuess, "PlotGuess");
   displayMapper->setMapping(m_displayActionQuality, "Quality");
@@ -416,12 +424,17 @@ void FitPropertyBrowser::initBasicLayout(QWidget *w) {
   btnDisplay->setMenu(displayMenu);
 
   QPushButton *btnSetup = new QPushButton("Setup");
+  btnSetup->setObjectName("button_Setup");
   QMenu *setupMenu = new QMenu(this);
+  setupMenu->setObjectName("menu_Setup");
 
   m_setupActionCustomSetup = new QAction("Custom Setup", this);
   QAction *setupActionManageSetup = new QAction("Manage Setup", this);
+  setupActionManageSetup->setObjectName("action_ManageSetup");
   QAction *setupActionFindPeaks = new QAction("Find Peaks", this);
+  setupActionFindPeaks->setObjectName("action_FindPeaks");
   QAction *setupActionClearFit = new QAction("Clear Model", this);
+  setupActionClearFit->setObjectName("action_ClearModel");
 
   QMenu *setupSubMenuCustom = new QMenu(this);
   m_setupActionCustomSetup->setMenu(setupSubMenuCustom);
@@ -432,7 +445,9 @@ void FitPropertyBrowser::initBasicLayout(QWidget *w) {
   QAction *setupActionSave = new QAction("Save Setup", this);
   m_setupActionRemove = new QAction("Remove Setup", this);
   QAction *setupActionCopyToClipboard = new QAction("Copy To Clipboard", this);
+  setupActionCopyToClipboard->setObjectName("action_CopyToClipboard");
   QAction *setupActionLoadFromString = new QAction("Load From String", this);
+  setupActionLoadFromString->setObjectName("action_LoadFromString");
   QSignalMapper *setupManageMapper = new QSignalMapper(this);
   setupManageMapper->setMapping(setupActionSave, "SaveSetup");
   setupManageMapper->setMapping(setupActionCopyToClipboard, "CopyToClipboard");
@@ -485,6 +500,7 @@ void FitPropertyBrowser::initBasicLayout(QWidget *w) {
   layout->addLayout(buttonsLayout);
   layout->addWidget(m_tip);
   layout->addWidget(m_browser);
+  m_browser->setObjectName("tree_browser");
 
   setWidget(w);
 
@@ -787,10 +803,11 @@ void FitPropertyBrowser::createCompositeFunction(
   }
   setWorkspace(m_compositeFunction);
 
-  PropertyHandler *h = new PropertyHandler(
+  auto h = std::make_unique<PropertyHandler>(
       m_compositeFunction, Mantid::API::CompositeFunction_sptr(), this);
-  m_compositeFunction->setHandler(h);
-  setCurrentFunction(h);
+  m_compositeFunction->setHandler(std::move(h));
+  setCurrentFunction(
+      static_cast<PropertyHandler *>(m_compositeFunction->getHandler()));
 
   if (m_auto_back) {
     addAutoBackground();
@@ -1141,6 +1158,7 @@ void FitPropertyBrowser::setWorkspaceName(const QString &wsName) {
       }
     }
   }
+  setWorkspaceIndex(-1);
 }
 
 /// Get workspace index
@@ -1150,7 +1168,11 @@ int FitPropertyBrowser::workspaceIndex() const {
 
 /// Set workspace index
 void FitPropertyBrowser::setWorkspaceIndex(int i) {
-  m_intManager->setValue(m_workspaceIndex, i);
+  try {
+    m_intManager->setValue(m_workspaceIndex, i);
+  } catch (Mantid::Kernel::Exception::NotFoundError &) {
+    // ignore this error
+  }
 }
 
 /// Get the output name
@@ -1346,20 +1368,48 @@ void FitPropertyBrowser::intChanged(QtProperty *prop) {
     return;
 
   if (prop == m_workspaceIndex) {
+
     auto const workspace =
         convertToMatrixWorkspace(getADSWorkspace(workspaceName()));
 
     if (workspace) {
-      int const numberOfSpectra = getNumberOfSpectra(workspace);
+      auto const allowedIndices =
+          m_allowedSpectra.empty()
+              ? QList<int>()
+              : m_allowedSpectra[QString::fromStdString(workspaceName())];
+      auto const firstIndex =
+          m_allowedSpectra.empty() ? 0 : allowedIndices.front();
+      auto const lastIndex = m_allowedSpectra.empty()
+                                 ? getNumberOfSpectra(workspace) - 1
+                                 : allowedIndices.back();
       int const currentIndex = workspaceIndex();
+      if (currentIndex == m_oldWorkspaceIndex) {
+        return;
+      }
 
-      if (currentIndex < 0) {
-        setWorkspaceIndex(0);
-        emit workspaceIndexChanged(0);
-      } else if (currentIndex >= numberOfSpectra) {
-        setWorkspaceIndex(numberOfSpectra - 1);
-        emit workspaceIndexChanged(numberOfSpectra - 1);
+      auto allowedIndex = currentIndex;
+      if (currentIndex < firstIndex) {
+        allowedIndex = firstIndex;
+      } else if (currentIndex > lastIndex) {
+        allowedIndex = lastIndex;
+      } else if (!m_allowedSpectra.empty() &&
+                 !allowedIndices.contains(currentIndex)) {
+        allowedIndex = m_oldWorkspaceIndex;
+        auto i = allowedIndices.indexOf(m_oldWorkspaceIndex);
+        if (i >= 0) {
+          i = currentIndex > m_oldWorkspaceIndex ? i + 1 : i - 1;
+          if (i >= 0 && i < allowedIndices.size()) {
+            allowedIndex = allowedIndices[i];
+          }
+        }
+      }
+
+      if (allowedIndex != currentIndex) {
+        setWorkspaceIndex(allowedIndex);
+        emit workspaceIndexChanged(allowedIndex);
       }
+
+      m_oldWorkspaceIndex = currentIndex;
     } else
       setWorkspaceIndex(0);
   } else if (prop->propertyName() == "Workspace Index") {
@@ -1732,12 +1782,15 @@ void FitPropertyBrowser::clearFitResultStatus() {
 /// Get and store available workspace names
 void FitPropertyBrowser::populateWorkspaceNames() {
   m_workspaceNames.clear();
-  // QStringList tmp = m_appWindow->mantidUI->getWorkspaceNames();
+  bool allAreAllowed = m_allowedSpectra.isEmpty();
 
   QStringList tmp;
   auto sv = Mantid::API::AnalysisDataService::Instance().getObjectNames();
   for (auto it = sv.begin(); it != sv.end(); ++it) {
-    tmp << QString::fromStdString(*it);
+    auto const &name = QString::fromStdString(*it);
+    if (allAreAllowed || m_allowedSpectra.contains(name)) {
+      tmp << name;
+    }
   }
 
   for (int i = 0; i < tmp.size(); i++) {
@@ -1749,6 +1802,7 @@ void FitPropertyBrowser::populateWorkspaceNames() {
     }
   }
   m_enumManager->setEnumNames(m_workspace, m_workspaceNames);
+  setWorkspaceIndex(-1);
 }
 
 /**
@@ -1780,11 +1834,13 @@ void FitPropertyBrowser::setADSObserveEnabled(bool enabled) {
 void FitPropertyBrowser::addHandle(
     const std::string &wsName,
     const boost::shared_ptr<Mantid::API::Workspace> ws) {
-  if (!isWorkspaceValid(ws))
+  auto const qName = QString::fromStdString(wsName);
+  if (!isWorkspaceValid(ws) ||
+      (!m_allowedSpectra.isEmpty() && !m_allowedSpectra.contains(qName)))
     return;
   QStringList oldWorkspaces = m_workspaceNames;
   QString oldName = QString::fromStdString(workspaceName());
-  int i = m_workspaceNames.indexOf(QString(wsName.c_str()));
+  int i = m_workspaceNames.indexOf(qName);
 
   bool initialSignalsBlocked = m_enumManager->signalsBlocked();
 
@@ -1794,7 +1850,7 @@ void FitPropertyBrowser::addHandle(
       m_enumManager->blockSignals(true);
     }
 
-    m_workspaceNames.append(QString(wsName.c_str()));
+    m_workspaceNames.append(qName);
     m_workspaceNames.sort();
     m_enumManager->setEnumNames(m_workspace, m_workspaceNames);
   }
@@ -1805,12 +1861,6 @@ void FitPropertyBrowser::addHandle(
   }
 
   m_enumManager->blockSignals(initialSignalsBlocked);
-  /*
-  if (m_workspaceNames.size() == 1)
-  {
-    setWorkspaceName(QString::fromStdString(wsName));
-  }
-  */
 }
 
 /// workspace was removed
@@ -1882,6 +1932,11 @@ void FitPropertyBrowser::setEndX(double value) {
   m_doubleManager->setValue(m_endX, value);
 }
 
+void FitPropertyBrowser::setXRange(double start, double end) {
+  m_doubleManager->setValue(m_startX, start);
+  m_doubleManager->setValue(m_endX, end);
+}
+
 ///
 QtBrowserItem *FitPropertyBrowser::findItem(QtBrowserItem *parent,
                                             QtProperty *prop) const {
@@ -2026,10 +2081,10 @@ bool FitPropertyBrowser::isUndoEnabled() const {
          compositeFunction()->nParams() == m_initialParameters.size();
 }
 
-/// Enable/disable the Fit button;
-void FitPropertyBrowser::setFitEnabled(bool yes) {
-  m_fitActionFit->setEnabled(yes);
-  m_fitActionSeqFit->setEnabled(yes);
+/// Enable/disable the Fit buttons;
+void FitPropertyBrowser::setFitEnabled(bool enable) {
+  m_fitActionFit->setEnabled(enable);
+  m_fitActionSeqFit->setEnabled(enable);
 }
 
 /// Returns true if the function is ready for a fit
@@ -3286,5 +3341,25 @@ void FitPropertyBrowser::modifyFitMenu(QAction *fitAction, bool enabled) {
     m_fitMenu->removeAction(fitAction);
   }
 }
+
+int MantidQt::MantidWidgets::FitPropertyBrowser::sizeOfFunctionsGroup() const {
+  return m_functionsGroup->children().size();
+}
+
+void FitPropertyBrowser::addAllowedSpectra(const QString &wsName,
+                                           const QList<int> &wsSpectra) {
+  auto const name = wsName.toStdString();
+  auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name);
+  if (ws) {
+    QList<int> indices;
+    for (auto const i : wsSpectra) {
+      indices.push_back(static_cast<int>(ws->getIndexFromSpectrumNumber(i)));
+    }
+    m_allowedSpectra.insert(wsName, indices);
+  } else {
+    throw std::runtime_error("Workspace " + name + " is not a MatrixWorkspace");
+  }
+}
+
 } // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/widgets/common/src/FunctionBrowser.cpp b/qt/widgets/common/src/FunctionBrowser.cpp
index 435a6f33d7c817bc676cba64996e37af451fbbcc..de3301026f547da6dd096827911848cbcbc65f25 100644
--- a/qt/widgets/common/src/FunctionBrowser.cpp
+++ b/qt/widgets/common/src/FunctionBrowser.cpp
@@ -1379,22 +1379,26 @@ Mantid::API::IFunction_sptr FunctionBrowser::getFunction(QtProperty *prop,
   {
     auto from = m_ties.lowerBound(prop);
     auto to = m_ties.upperBound(prop);
-    QList<QtProperty *> filedTies; // ties can become invalid after some editing
+    // ties can become invalid after some editing
+    QList<QtProperty *> failedTies;
     for (auto it = from; it != to; ++it) {
+      auto const tie =
+          (it->paramName + "=" + m_tieManager->value(it.value().tieProp))
+              .toStdString();
       try {
-        QString tie =
-            it->paramName + "=" + m_tieManager->value(it.value().tieProp);
-        fun->addTies(tie.toStdString());
+        fun->addTies(tie);
       } catch (...) {
-        filedTies << it.value().tieProp;
+        failedTies << it.value().tieProp;
+        g_log.warning() << "Invalid tie has been removed: " << tie << std::endl;
       }
     }
     // remove failed ties from the browser
-    foreach (QtProperty *p, filedTies) {
+    foreach (QtProperty *p, failedTies) {
       auto paramProp = getParentParameterProperty(p);
       if (isLocalParameterProperty(paramProp)) {
-        auto paramName = paramProp->propertyName();
-        setLocalParameterTie(paramName, m_currentDataset, "");
+        auto const paramName = paramProp->propertyName();
+        auto const index = getIndex(paramProp);
+        setLocalParameterTie(index + paramName, m_currentDataset, "");
       }
       removeProperty(p);
     }
diff --git a/qt/widgets/common/src/IndirectFitPropertyBrowser.cpp b/qt/widgets/common/src/IndirectFitPropertyBrowser.cpp
index a816cfdae12e0cd0995828c919ba796e7533de02..50d20973868563d4b9b8657cd1b163da798bddf9 100644
--- a/qt/widgets/common/src/IndirectFitPropertyBrowser.cpp
+++ b/qt/widgets/common/src/IndirectFitPropertyBrowser.cpp
@@ -949,6 +949,10 @@ void IndirectFitPropertyBrowser::setWorkspaceIndex(int i) {
   FitPropertyBrowser::setWorkspaceIndex(i);
 }
 
+void IndirectFitPropertyBrowser::setFitEnabled(bool enable) {
+  FitPropertyBrowser::setFitEnabled(enable);
+}
+
 /**
  * Schedules a fit.
  */
diff --git a/qt/widgets/common/src/MessageDisplay.cpp b/qt/widgets/common/src/MessageDisplay.cpp
index 5b5184a66e01a6ca7f23739e666206a78654463f..780845f7c1a5f9ad9db6a27287a9ef8717f11526 100644
--- a/qt/widgets/common/src/MessageDisplay.cpp
+++ b/qt/widgets/common/src/MessageDisplay.cpp
@@ -15,6 +15,7 @@
 #include <QAction>
 #include <QActionGroup>
 #include <QHBoxLayout>
+#include <QInputDialog>
 #include <QMenu>
 #include <QPlainTextEdit>
 #include <QPoint>
@@ -29,6 +30,11 @@
 namespace {
 // Track number of attachments to generate a unique channel name
 int ATTACH_COUNT = 0;
+
+int DEFAULT_LINE_COUNT_MAX = 8192;
+const char *PRIORITY_KEY_NAME = "MessageDisplayPriority";
+const char *LINE_COUNT_MAX_KEY_NAME = "MessageDisplayLineCountMax";
+
 } // namespace
 
 using Mantid::Kernel::ConfigService;
@@ -47,10 +53,12 @@ namespace MantidWidgets {
  * at the group containing the values
  */
 void MessageDisplay::readSettings(const QSettings &storage) {
-  const int logLevel = storage.value("MessageDisplayPriority", 0).toInt();
+  const int logLevel = storage.value(PRIORITY_KEY_NAME, 0).toInt();
   if (logLevel > 0) {
     ConfigService::Instance().setLogLevel(logLevel, true);
   }
+  setMaximumLineCount(
+      storage.value(LINE_COUNT_MAX_KEY_NAME, DEFAULT_LINE_COUNT_MAX).toInt());
 }
 
 /**
@@ -60,7 +68,8 @@ void MessageDisplay::readSettings(const QSettings &storage) {
  * at the group where the values should be stored.
  */
 void MessageDisplay::writeSettings(QSettings &storage) const {
-  storage.setValue("MessageDisplayPriority", Poco::Logger::root().getLevel());
+  storage.setValue(PRIORITY_KEY_NAME, Poco::Logger::root().getLevel());
+  storage.setValue(LINE_COUNT_MAX_KEY_NAME, maximumLineCount());
 }
 
 /**
@@ -242,20 +251,20 @@ void MessageDisplay::scrollToBottom() {
       m_textDisplay->verticalScrollBar()->maximum());
 }
 
-//------------------------------------------------------------------------------
-// Protected members
-//------------------------------------------------------------------------------
-
 //-----------------------------------------------------------------------------
 // Private slot member functions
 //-----------------------------------------------------------------------------
 
 void MessageDisplay::showContextMenu(const QPoint &mousePos) {
   QMenu *menu = m_textDisplay->createStandardContextMenu();
-  if (!m_textDisplay->document()->isEmpty())
+  menu->addSeparator();
+  if (!m_textDisplay->document()->isEmpty()) {
     menu->addAction("Clear", m_textDisplay, SLOT(clear()));
-
+    menu->addSeparator();
+  }
+  menu->addAction("&Scrollback limit", this, SLOT(setScrollbackLimit()));
   menu->addSeparator();
+
   QMenu *logLevelMenu = menu->addMenu("&Log Level");
   logLevelMenu->addAction(m_error);
   logLevelMenu->addAction(m_warning);
@@ -288,6 +297,38 @@ void MessageDisplay::setLogLevel(int priority) {
   ConfigService::Instance().setLogLevel(priority);
 }
 
+/**
+ * Set the maximum number of blocks kept by the text edit
+ */
+void MessageDisplay::setScrollbackLimit() {
+  constexpr int minLineCountAllowed(-1);
+  setMaximumLineCount(
+      QInputDialog::getInt(this, "", "No. of lines\n(-1 keeps all content)",
+                           maximumLineCount(), minLineCountAllowed));
+}
+
+// The text edit works in blocks but it is not entirely clear what a block
+// is defined as. Experiments showed setting a max block count=1 suppressed
+// all output and a min(block count)==2 was required to see a single line.
+// We have asked the user for lines so add 1 to get the behaviour they
+// would expect. Equally we subtract 1 for the value we show them to
+// keep it consistent
+
+/**
+ * @return The maximum number of lines displayed in the text edit
+ */
+int MessageDisplay::maximumLineCount() const {
+  return m_textDisplay->maximumBlockCount() - 1;
+}
+
+/**
+ * The maximum number of lines that are to be displayed in the text edit
+ * @param count The new maximum number of lines to retain.
+ */
+void MessageDisplay::setMaximumLineCount(int count) {
+  m_textDisplay->setMaximumBlockCount(count + 1);
+}
+
 //-----------------------------------------------------------------------------
 // Private non-slot member functions
 //-----------------------------------------------------------------------------
@@ -346,6 +387,7 @@ void MessageDisplay::initFormats() {
 void MessageDisplay::setupTextArea() {
   m_textDisplay->setReadOnly(true);
   m_textDisplay->ensureCursorVisible();
+  setMaximumLineCount(DEFAULT_LINE_COUNT_MAX);
   m_textDisplay->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
   m_textDisplay->setMouseTracking(true);
   m_textDisplay->setUndoRedoEnabled(false);
diff --git a/qt/widgets/common/src/PropertyHandler.cpp b/qt/widgets/common/src/PropertyHandler.cpp
index e05c45879b1e89bdbc1c107ff4f4d63a92fb7c5b..f13a0e39c1552e747fcdb9e400d48e393714bfc3 100644
--- a/qt/widgets/common/src/PropertyHandler.cpp
+++ b/qt/widgets/common/src/PropertyHandler.cpp
@@ -118,8 +118,8 @@ void PropertyHandler::init() {
         throw std::runtime_error(
             "IFunction expected but func function of another type");
       }
-      PropertyHandler *h = new PropertyHandler(f, m_cf, m_browser);
-      f->setHandler(h);
+      auto h = std::make_unique<PropertyHandler>(f, m_cf, m_browser);
+      f->setHandler(std::move(h));
     }
   }
 
@@ -417,10 +417,10 @@ PropertyHandler *PropertyHandler::addFunction(const std::string &fnName) {
     return nullptr;
   }
 
-  PropertyHandler *h = new PropertyHandler(f, m_cf, m_browser);
-  f->setHandler(h);
+  auto h = std::make_unique<PropertyHandler>(f, m_cf, m_browser);
   h->setAttribute("StartX", m_browser->startX());
   h->setAttribute("EndX", m_browser->endX());
+  f->setHandler(std::move(h));
 
   // enable the change slots
   m_browser->m_changeSlotsEnabled = true;
@@ -431,9 +431,10 @@ PropertyHandler *PropertyHandler::addFunction(const std::string &fnName) {
     m_browser->setDefaultBackgroundType(f->name());
   }
   m_browser->setFocus();
-  m_browser->setCurrentFunction(h);
+  auto return_ptr = static_cast<PropertyHandler *>(f->getHandler());
+  m_browser->setCurrentFunction(return_ptr);
 
-  return h;
+  return return_ptr;
 }
 
 // Removes handled function from its parent function and
@@ -1038,10 +1039,11 @@ Mantid::API::IFunction_sptr PropertyHandler::changeType(QtProperty *prop) {
     emit m_browser->removePlotSignal(this);
 
     Mantid::API::IFunction_sptr f_old = function();
-    PropertyHandler *h = new PropertyHandler(f, m_parent, m_browser, m_item);
+    std::unique_ptr<PropertyHandler> h =
+        std::make_unique<PropertyHandler>(f, m_parent, m_browser, m_item);
     if (this == m_browser->m_autoBackground) {
       if (dynamic_cast<Mantid::API::IBackgroundFunction *>(f.get())) {
-        m_browser->m_autoBackground = h;
+        m_browser->m_autoBackground = h.get();
         h->fit();
 
       } else {
@@ -1051,12 +1053,12 @@ Mantid::API::IFunction_sptr PropertyHandler::changeType(QtProperty *prop) {
     if (m_parent) {
       m_parent->replaceFunctionPtr(f_old, f);
     }
-    f->setHandler(h);
     // calculate the baseline
     if (h->pfun()) {
       h->setCentre(h->centre()); // this sets m_ci
       h->calcBase();
     }
+    f->setHandler(std::move(h));
     // at this point this handler does not exist any more. only return is
     // possible
     return f;
diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
index ff913cf46fd0c2252579e53ed91e65d694e8dd78..d5a3483753b5b8a340626a9d87eb4a3eab5ac7d0 100644
--- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
+++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
@@ -51,10 +51,10 @@ WorkspaceIcons WORKSPACE_ICONS = WorkspaceIcons();
 namespace MantidQt {
 namespace MantidWidgets {
 
-WorkspaceTreeWidget::WorkspaceTreeWidget(MantidDisplayBase *mdb,
+WorkspaceTreeWidget::WorkspaceTreeWidget(MantidDisplayBase *mdb, bool viewOnly,
                                          QWidget *parent)
-    : QWidget(parent), m_mantidDisplayModel(mdb), m_updateCount(0),
-      m_treeUpdating(false), m_promptDelete(false),
+    : QWidget(parent), m_mantidDisplayModel(mdb), m_viewOnly(viewOnly),
+      m_updateCount(0), m_treeUpdating(false), m_promptDelete(false),
       m_saveFileType(SaveFileType::Nexus), m_sortCriteria(SortCriteria::ByName),
       m_sortDirection(SortDirection::Ascending), m_mutex(QMutex::Recursive) {
   setObjectName(
@@ -62,6 +62,7 @@ WorkspaceTreeWidget::WorkspaceTreeWidget(MantidDisplayBase *mdb,
   m_saveMenu = new QMenu(this);
 
   setupWidgetLayout();
+
   setupLoadButtonMenu();
 
   // Dialog box used for user to specify folder to save multiple workspaces into
@@ -87,6 +88,9 @@ WorkspaceTreeWidget::WorkspaceTreeWidget(MantidDisplayBase *mdb,
   auto presenter = boost::make_shared<WorkspacePresenter>(this);
   m_presenter = boost::dynamic_pointer_cast<ViewNotifiable>(presenter);
   presenter->init();
+
+  if (m_viewOnly)
+    hideButtonToolbar();
 }
 
 WorkspaceTreeWidget::~WorkspaceTreeWidget() {}
@@ -1234,9 +1238,11 @@ void WorkspaceTreeWidget::handleClearView() {
 
 /// Handles display of the workspace context menu.
 void WorkspaceTreeWidget::popupMenu(const QPoint &pos) {
-  m_menuPosition = pos;
-  m_presenter->notifyFromView(
-      ViewNotifiable::Flag::PopulateAndShowWorkspaceContextMenu);
+  if (!m_viewOnly) {
+    m_menuPosition = pos;
+    m_presenter->notifyFromView(
+        ViewNotifiable::Flag::PopulateAndShowWorkspaceContextMenu);
+  }
 }
 
 void WorkspaceTreeWidget::popupContextMenu() {
@@ -1744,5 +1750,13 @@ bool WorkspaceTreeWidget::executeAlgorithmAsync(
   return m_mantidDisplayModel->executeAlgorithmAsync(alg, wait);
 }
 
+void WorkspaceTreeWidget::hideButtonToolbar() {
+  m_loadButton->hide();
+  m_saveButton->hide();
+  m_deleteButton->hide();
+  m_groupButton->hide();
+  m_sortButton->hide();
+}
+
 } // namespace MantidWidgets
 } // namespace MantidQt
diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
index 8cd58c9de557b4c6736ff336d21980f03d98f616..76cc1fd38cdce500b2f8b2f84ccecdaf4bd04aed 100644
--- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
+++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidgetSimple.cpp
@@ -25,8 +25,9 @@ using namespace Mantid::Kernel;
 namespace MantidQt {
 namespace MantidWidgets {
 
-WorkspaceTreeWidgetSimple::WorkspaceTreeWidgetSimple(QWidget *parent)
-    : WorkspaceTreeWidget(new MantidTreeModel(), parent),
+WorkspaceTreeWidgetSimple::WorkspaceTreeWidgetSimple(bool viewOnly,
+                                                     QWidget *parent)
+    : WorkspaceTreeWidget(new MantidTreeModel(), viewOnly, parent),
       m_plotSpectrum(new QAction("spectrum...", this)),
       m_overplotSpectrum(new QAction("overplot spectrum...", this)),
       m_plotSpectrumWithErrs(new QAction("spectrum with errors...", this)),
@@ -56,6 +57,8 @@ WorkspaceTreeWidgetSimple::WorkspaceTreeWidgetSimple(QWidget *parent)
   connect(m_showInstrument, SIGNAL(triggered()), this,
           SLOT(onShowInstrumentClicked()));
   connect(m_showData, SIGNAL(triggered()), this, SLOT(onShowDataClicked()));
+  connect(m_tree, SIGNAL(itemSelectionChanged()), this,
+          SIGNAL(treeSelectionChanged()));
 }
 
 WorkspaceTreeWidgetSimple::~WorkspaceTreeWidgetSimple() {}
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 7076273914847480f589d2c892f5ce28fe78f792..cffa4a96bef44543ff077c30171f0aa57c5cc882 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -49,7 +49,7 @@ foreach ( _dir ${_pth_dirs} )
   list ( APPEND _pth_list_install "${_scripts_rel_path}/${_dir}" )
 endforeach()
 list ( APPEND _pth_list_dev ${MSLICE_DEV} )
-list ( APPEND _pth_list_install "${_scripts_rel_path}/Externalinterfaces" )
+list ( APPEND _pth_list_install "${_scripts_rel_path}/ExternalInterfaces" )
 
 # development copy
 set ( _scripts_pth_src "${CMAKE_CURRENT_BINARY_DIR}/mantid-scripts.pth.src" )
@@ -100,6 +100,7 @@ set ( TEST_PY_FILES
       test/DirectReductionHelpersTest.py
       test/ErrorReportPresenterTest.py
       test/IndirectCommonTests.py
+      test/InelasticDirectDetpackmapTest.py
       test/ISISDirecInelasticConfigTest.py
       test/PyChopTest.py
       test/pythonTSVTest.py
diff --git a/scripts/wish/SX_reduction_august2017.py b/scripts/Diffraction/wish/SX_reduction_august2017.py
similarity index 100%
rename from scripts/wish/SX_reduction_august2017.py
rename to scripts/Diffraction/wish/SX_reduction_august2017.py
diff --git a/scripts/Diffraction/wish/__init__.py b/scripts/Diffraction/wish/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/Diffraction/wish/reduce.py b/scripts/Diffraction/wish/reduce.py
new file mode 100644
index 0000000000000000000000000000000000000000..a02669e30c80dce28e8826c1f51cfb03c4684fae
--- /dev/null
+++ b/scripts/Diffraction/wish/reduce.py
@@ -0,0 +1,467 @@
+from __future__ import (absolute_import, division, print_function)
+from mantid import logger
+import mantid.simpleapi as simple
+import os
+import numpy as np
+
+
+class Wish:
+    NUM_PANELS = 11
+    NUM_MONITORS = 6
+    LAMBDA_RANGE = (0.7, 10.35)
+
+    def __init__(self, cal_directory, output_folder, delete_ws,
+                 user_directory="/archive/ndxwish/Instrument/data/cycle_", absorb=True):
+        self.absorb = absorb
+        self.cal_dir = cal_directory
+        self.use_folder = user_directory
+        self.out_folder = output_folder
+        self.deleteWorkspace = delete_ws
+        self.is_vanadium = False
+        self.username = None
+        self.data_directory = None
+        self.user_directory = None
+        self.datafile = None
+        self.userdatadir = None
+        self.userdataprocessed = None
+        self.return_panel = {
+            1: (6, 19461),
+            2: (19462, 38917),
+            3: (38918, 58373),
+            4: (58374, 77829),
+            5: (77830, 97285),
+            6: (97286, 116741),
+            7: (116742, 136197),
+            8: (136198, 155653),
+            9: (155654, 175109),
+            10: (175110, 194565),
+            0: (6, 194565)
+        }
+        self.return_panel_van = {
+            1: (6, 19461),
+            2: (19462, 38917),
+            3: (38918, 58373),
+            4: (58374, 77829),
+            5: (77830, 97285),
+            6: (77830, 97285),
+            7: (58374, 77829),
+            8: (38918, 58373),
+            9: (19462, 38917),
+            10: (6, 19461)
+        }
+        # update to reflect new cycles
+        self.cycle_mapping = [("09_2", (586, 774)), ("09_3", (774, 1728)), ("09_4", (1728, 3334)),
+                              ("09_5", (3334, 16777)), ("10_1", (16777, 17322)), ("10_2", (17322, 17339)),
+                              ("10_3", (17340, 17692)), ("11_1", (17692, 18051)), ("11_2", (18053, 18572)),
+                              ("11_3", (18572, 19608)), ("11_4", (19608, 20420)), ("11_5", (20420, 21111)),
+                              ("12_1", (21117, 21919)), ("12_2", (21919, 22437)), ("12_3", (22438, 23128)),
+                              ("12_4", (23128, 23548)), ("12_5", (23548, 24086)), ("13_1", (24086, 24819)),
+                              ("13_2", (24820, 25317)), ("13_3", (25318, 26148)), ("13_4", (26149, 26661)),
+                              ("13_5", (26661, 27805)), ("14_1", (27806, 28904)), ("14_2", (28904, 29587)),
+                              ("14_3", (29587, 30528)), ("15_1", (30528, 31669)), ("15_2", (31669, 32520)),
+                              ("15_3", (32520, 33278)), ("15_4", (33278, 34171)), ("16_1", (34171, 35222)),
+                              ("16_2", (35222, 35830)), ("16_3", (35830, 36442)), ("16_4", (36442, 37035)),
+                              ("16_5", (37035, 38247)), ("17_1", (38247, 38837)), ("17_2", (38837, 39326)),
+                              ("17_4", (39326, 40469)), ("18_1", (40469, 41846)), ("18_2", (41846, 42708)),
+                              ("18_3", (42708, 43124))]
+
+    def set_user_name(self, username):
+        self.username = username
+
+    def set_data_directory(self, directory="/archive/ndxwish/Instrument/data/cycle_09_5/"):
+        self.data_directory = directory
+
+    def set_user_directory(self, directory):
+        self.user_directory = directory
+
+    def startup(self, cycle='14_3'):
+        user_data_directory = os.path.normpath(self.use_folder + cycle)
+        self.set_data_directory(user_data_directory)
+        logger.notice("Raw Data in :   {}".format(user_data_directory))
+        user_data_processed = self.out_folder
+        self.set_user_directory(directory=user_data_processed)
+        logger.notice("Processed Data in :   {}".format(user_data_processed))
+
+    def get_cycle(self, run_number):
+        for cycle_pair in self.cycle_mapping:
+            if run_number in range(cycle_pair[1][0], cycle_pair[1][1]):
+                return cycle_pair[0]
+        logger.notice("Failed to find cycle")
+
+    # Returns the calibration filename
+    def get_cal(self):
+        return os.path.join(self.cal_dir, "WISH_cycle_15_4_noends_10to10_dodgytube_removed_feb2016.cal")
+
+    # Returns the grouping filename
+    def get_group_file(self):
+        return os.path.join(self.cal_dir, "WISH_cycle_15_4_noends_10to10_dodgytube_removed_feb2016.cal")
+
+    def get_vanadium(self, panel, cycle="09_4"):
+        vanadium_string = {
+            "09_2": "vana318-{}foc-rmbins-smooth50.nx5",
+            "09_3": "vana935-{}foc-SS.nx5",
+            "09_4": "vana3123-{}foc-SS.nx5",
+            "09_5": "vana3123-{}foc-SS.nx5",
+            "11_1": "vana17718-{}foc-SS.nxs",
+            "11_2": "vana16812-{}foc-SS.nx5",
+            "11_3": "vana18590-{}foc-SS-new.nxs",
+            "11_4": "vana19612-{}foc-SF-SS.nxs",
+        }
+        return os.path.join(self.cal_dir, vanadium_string.get(cycle).format(panel))
+
+    def get_file_name(self, run_number, extension):
+        if extension[0] != 's':
+            data_dir = self.data_directory
+        else:
+            data_dir = self.data_directory
+        digit = len(str(run_number))
+        filename = os.path.join(data_dir, "WISH")
+        for i in range(8 - digit):
+            filename = filename + "0"
+        filename += str(run_number) + "." + extension
+        return filename
+
+    # Reads a wish data file return a workspace with a short name
+    def read(self, number, panel, extension):
+        if type(number) is int:
+            filename = self.datafile
+            logger.notice("will be reading filename...{}".format(filename))
+            spectra_min, spectra_max = self.return_panel_van.get(panel) if self.is_vanadium else \
+                self.return_panel.get(panel)
+            if panel != 0:
+                output = "w{0}-{1}".format(number, panel)
+            else:
+                output = "w{}".format(number)
+            shared_load_files(extension, filename, output, spectra_max, spectra_min, False)
+            if extension == "nxs_event":
+                simple.LoadEventNexus(Filename=filename, OutputWorkspace=output, LoadMonitors='1')
+                self.read_event_nexus(number, output, panel)
+            if extension[:10] == "nxs_event_":
+                label, tmin, tmax = split_string_event(extension)
+                output = output + "_" + label
+                if tmax == "end":
+                    simple.LoadEventNexus(Filename=filename, OutputWorkspace=output, FilterByTimeStart=tmin,
+                                          LoadMonitors='1', MonitorsAsEvents='1', FilterMonByTimeStart=tmin)
+                else:
+                    simple.LoadEventNexus(Filename=filename, OutputWorkspace=output, FilterByTimeStart=tmin,
+                                          FilterByTimeStop=tmax, LoadMonitors='1', MonitorsAsEvents='1',
+                                          FilterMonByTimeStart=tmin, FilterMonByTimeStop=tmax)
+                self.read_event_nexus(number, output, panel)
+        else:
+            num_1, num_2 = split_run_string(number)
+            output = "w{0}_{1}-{2}".format(num_1, num_2, panel)
+            output1 = self.load_multi_run_part(extension, num_1, panel)
+            output2 = self.load_multi_run_part(extension, num_2, panel)
+            simple.MergeRuns(output1 + "," + output2, output)
+            simple.DeleteWorkspace(output1)
+            simple.DeleteWorkspace(output2)
+        simple.ConvertUnits(InputWorkspace=output, OutputWorkspace=output, Target="Wavelength", Emode="Elastic")
+        lmin, lmax = Wish.LAMBDA_RANGE
+        simple.CropWorkspace(InputWorkspace=output, OutputWorkspace=output, XMin=lmin, XMax=lmax)
+        monitor_run = "monitor{}".format(number)
+        if monitor_run not in simple.mtd:
+            monitor = self.process_incidentmon(number, extension, spline_terms=70)
+        else:
+            monitor = simple.mtd[monitor_run]
+        simple.NormaliseToMonitor(InputWorkspace=output, OutputWorkspace=output + "norm1", MonitorWorkspace=monitor)
+        simple.NormaliseToMonitor(InputWorkspace=output + "norm1", OutputWorkspace=output + "norm2",
+                                  MonitorWorkspace=monitor, IntegrationRangeMin=0.7, IntegrationRangeMax=10.35)
+        simple.DeleteWorkspace(output)
+        simple.DeleteWorkspace(output + "norm1")
+        simple.RenameWorkspace(InputWorkspace=output + "norm2", OutputWorkspace=output)
+        simple.ConvertUnits(InputWorkspace=output, OutputWorkspace=output, Target="TOF", EMode="Elastic")
+        simple.ReplaceSpecialValues(InputWorkspace=output, OutputWorkspace=output, NaNValue=0.0, NaNError=0.0,
+                                    InfinityValue=0.0, InfinityError=0.0)
+        return output
+
+    def load_multi_run_part(self, extension, run, panel):
+        filename = self.get_file_name(run, extension)
+        logger.notice("reading filename... {}".format(filename))
+        spectra_min, spectra_max = self.return_panel.get(panel)
+        output1 = "w{0}-{1}".format(run, panel)
+        simple.LoadRaw(Filename=filename, OutputWorkspace=output1, SpectrumMin=str(spectra_min),
+                       SpectrumMax=str(spectra_max), LoadLogFiles="0")
+        return output1
+
+    def read_event_nexus(self, number, output, panel):
+        simple.RenameWorkspace("{}_monitors".format(output), "w{}_monitors".format(number))
+        simple.Rebin(InputWorkspace=output, OutputWorkspace=output, Params='6000,-0.00063,110000')
+        simple.ConvertToMatrixWorkspace(output, output)
+        spectra_min, spectra_max = self.return_panel.get(panel)
+        simple.CropWorkspace(InputWorkspace=output, OutputWorkspace=output, StartWorkspaceIndex=spectra_min - 6,
+                             EndWorkspaceIndex=spectra_max - 6)
+        simple.MaskBins(InputWorkspace=output, OutputWorkspace=output, XMin=99900, XMax=106000)
+
+    # Focus dataset for a given panel and return the workspace
+    def focus_onepanel(self, work, focus, panel):
+        cal = "WISH_diff{}"
+        if cal.format("_cal") not in simple.mtd:
+            simple.LoadDiffCal(filename=self.get_cal(), InstrumentName="WISH", WorkspaceName=cal.format(""))
+        simple.AlignDetectors(InputWorkspace=work, OutputWorkspace=work, CalibrationWorkspace=cal.format("_cal"))
+        simple.DiffractionFocussing(InputWorkspace=work, OutputWorkspace=focus, GroupingWorkspace=cal.format("_group"))
+        if self.deleteWorkspace:
+            simple.DeleteWorkspace(work)
+        if panel == 5 or panel == 6:
+            simple.CropWorkspace(InputWorkspace=focus, OutputWorkspace=focus, XMin=0.3)
+        return focus
+
+    def focus(self, work, panel):
+        focus = "{}foc".format(work)
+        if panel != 0:
+            return self.focus_onepanel(work, focus, panel)
+        else:
+            self.focus_onepanel(work, focus, panel)
+            split(focus)
+
+    def process_run(self, number, panel, extension, cycle_vana="09_4", absorb=False, number_density=0.0, scattering=0.0,
+                    attenuation=0.0, height=0.0, radius=0.0):
+        ws_to_focus = self.read(number, panel, extension)
+        if absorb:
+            absorption_corrections(attenuation, height, number_density, radius, scattering, ws_to_focus)
+        focused_ws = self.focus(ws_to_focus, panel)
+
+        panel_crop = {
+            1: (0.8, 53.3),
+            2: (0.5, 13.1),
+            3: (0.5, 7.77),
+            4: (0.4, 5.86),
+            5: (0.35, 4.99),
+            6: (0.35, 4.99),
+            7: (0.4, 5.86),
+            8: (0.5, 7.77),
+            9: (0.5, 13.1),
+            10: (0.8, 53.3)
+        }
+        d_min, d_max = panel_crop.get(panel)
+        simple.CropWorkspace(InputWorkspace=focused_ws, OutputWorkspace=focused_ws, XMin=d_min, XMax=d_max)
+        save_location = os.path.join(self.user_directory, "{0}-{1}{2}.{3}")
+        if panel == 0:
+            for panel_i in range(Wish.NUM_PANELS):
+                focused_ws = "w{0}-{1}foc".format(number, panel_i)
+                simple.CropWorkspace(InputWorkspace=focused_ws, OutputWorkspace=focused_ws, XMin=d_min, XMax=d_max)
+                logger.notice("will try to load a vanadium with the name: {}".format(self.get_vanadium
+                                                                                     (panel_i, cycle_vana)))
+                self.apply_vanadium_corrections(cycle_vana, panel_i, focused_ws)
+                simple.SaveGSS(InputWorkspace=focused_ws,
+                               Filename=save_location.format(number, panel_i, extension, "gss"),
+                               Append=False, Bank=1)
+                simple.SaveFocusedXYE(focused_ws, save_location.format(number, panel_i, extension, "dat"))
+                simple.SaveNexusProcessed(focused_ws, save_location.format(number, panel_i, extension, "nxs"))
+        else:
+            logger.notice("will try to load a vanadium with the name: {}".format(self.get_vanadium
+                                                                                 (panel, cycle_vana)))
+            self.apply_vanadium_corrections(cycle_vana, panel, focused_ws)
+            simple.SaveGSS(InputWorkspace=focused_ws,
+                           Filename=save_location.format(number, panel, extension, "gss"),
+                           Append=False, Bank=1)
+            simple.SaveFocusedXYE(focused_ws, save_location.format(number, panel, extension, "dat"))
+            simple.SaveNexusProcessed(focused_ws, save_location.format(number, panel, extension, "nxs"))
+        return focused_ws
+
+    def apply_vanadium_corrections(self, cyclevana, i, focused_ws):
+        simple.LoadNexusProcessed(Filename=self.get_vanadium(i, cyclevana), OutputWorkspace="vana")
+        simple.RebinToWorkspace(WorkspaceToRebin="vana", WorkspaceToMatch=focused_ws, OutputWorkspace="vana")
+        simple.Divide(LHSWorkspace=focused_ws, RHSWorkspace="vana", OutputWorkspace=focused_ws)
+        simple.DeleteWorkspace("vana")
+        simple.ConvertUnits(InputWorkspace=focused_ws, OutputWorkspace=focused_ws, Target="TOF",
+                            EMode="Elastic")
+        simple.ReplaceSpecialValues(InputWorkspace=focused_ws, OutputWorkspace=focused_ws, NaNValue=0.0,
+                                    NaNError=0.0,
+                                    InfinityValue=0.0, InfinityError=0.0)
+
+    # Create a corrected vanadium (normalise,corrected for attenuation and empty, strip peaks) and
+    # save a a nexus processed file.
+    # It looks like smoothing of 100 works quite well
+    def process_vanadium(self, vanadium, empty, panel, height, radius, cycle_van="09_3", cycle_empty="09_3"):
+        user_data_directory = self.use_folder + cycle_van + '/'
+        self.set_data_directory(user_data_directory)
+        self.datafile = self.get_file_name(vanadium, "raw")
+        vanadium_ws = self.read(vanadium, panel, "raw")
+        user_data_directory = self.use_folder + cycle_empty + '/'
+        self.set_data_directory(user_data_directory)
+        self.datafile = self.get_file_name(empty, "raw")
+        empty_ws = self.read(empty, panel, "raw")
+        simple.Minus(LHSWorkspace=vanadium_ws, RHSWorkspace=empty_ws, OutputWorkspace=vanadium_ws)
+        simple.DeleteWorkspace(empty_ws)
+        absorption_corrections(4.8756, height, 0.07118, radius, 5.16, vanadium_ws)
+        vanfoc = self.focus(vanadium_ws, panel)
+
+        panel_crop = {
+            1: (0.95, 53.3),
+            2: (0.58, 13.1),
+            3: (0.44, 7.77),
+            4: (0.38, 5.86),
+            5: (0.35, 4.99),
+            6: (0.35, 4.99),
+            7: (0.38, 5.86),
+            8: (0.44, 7.77),
+            9: (0.58, 13.1),
+            10: (0.95, 53.3)
+        }
+        d_min, d_max = panel_crop.get(panel)
+        simple.CropWorkspace(InputWorkspace=vanfoc, OutputWorkspace=vanfoc, XMin=d_min, XMax=d_max)
+        spline_coefficient = {
+            1: 120,
+            2: 120,
+            3: 120,
+            4: 130,
+            5: 140,
+            6: 140,
+            7: 130,
+            8: 120,
+            9: 120,
+            10: 120
+        }
+        simple.SplineBackground(InputWorkspace=vanfoc, OutputWorkspace=vanfoc, NCoeff=spline_coefficient.get(panel))
+        smoothing_coefficient = "30" if panel == 3 else "40"
+        simple.SmoothData(InputWorkspace=vanfoc, OutputWorkspace=vanfoc, NPoints=smoothing_coefficient)
+        return
+
+    def create_vanadium_run(self, van_run_number, empty_run_number, panels):
+        self.is_vanadium = True
+        vanadium_cycle = self.get_cycle(van_run_number)
+        empty_cycle = self.get_cycle(empty_run_number)
+        for panel in panels:
+            self.process_vanadium(van_run_number, empty_run_number, panel, 4, 0.14999999999999999, vanadium_cycle,
+                                  empty_cycle)
+        monitor_runs = "monitor{}"
+        simple.DeleteWorkspace(monitor_runs.format(van_run_number))
+        simple.DeleteWorkspace(monitor_runs.format(empty_run_number))
+        simple.DeleteWorkspace("WISH_diff_cal")
+        simple.DeleteWorkspace("WISH_diff_group")
+        simple.DeleteWorkspace("WISH_diff_mask")
+
+    def process_incidentmon(self, number, extension, spline_terms=20):
+        if type(number) is int:
+            filename = self.get_file_name(number, extension)
+            works = "monitor{}".format(number)
+            shared_load_files(extension, filename, works, 4, 4, True)
+            if extension[:9] == "nxs_event":
+                temp = "w{}_monitors".format(number)
+                works = "w{}_monitor4".format(number)
+                simple.Rebin(InputWorkspace=temp, OutputWorkspace=temp, Params='6000,-0.00063,110000',
+                             PreserveEvents=False)
+                simple.ExtractSingleSpectrum(InputWorkspace=temp, OutputWorkspace=works, WorkspaceIndex=3)
+        else:
+            num_1, num_2 = split_run_string(number)
+            works = "monitor{0}_{1}".format(num_1, num_2)
+            filename = self.get_file_name(num_1, extension)
+            works1 = "monitor{}".format(num_1)
+            simple.LoadRaw(Filename=filename, OutputWorkspace=works1, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
+            filename = self.get_file_name(num_2, extension)
+            works2 = "monitor{}".format(num_2)
+            simple.LoadRaw(Filename=filename, OutputWorkspace=works2, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
+            simple.MergeRuns(InputWorkspaces=works1 + "," + works2, OutputWorkspace=works)
+            simple.DeleteWorkspace(works1)
+            simple.DeleteWorkspace(works2)
+        simple.ConvertUnits(InputWorkspace=works, OutputWorkspace=works, Target="Wavelength", Emode="Elastic")
+        lambda_min, lambda_max = Wish.LAMBDA_RANGE
+        simple.CropWorkspace(InputWorkspace=works, OutputWorkspace=works, XMin=lambda_min, XMax=lambda_max)
+        ex_regions = np.array([[4.57, 4.76],
+                              [3.87, 4.12],
+                              [2.75, 2.91],
+                              [2.24, 2.50]])
+        simple.ConvertToDistribution(works)
+
+        for reg in range(0, 4):
+            simple.MaskBins(InputWorkspace=works, OutputWorkspace=works, XMin=ex_regions[reg, 0],
+                            XMax=ex_regions[reg, 1])
+
+        simple.SplineBackground(InputWorkspace=works, OutputWorkspace=works, WorkspaceIndex=0, NCoeff=spline_terms)
+
+        simple.SmoothData(InputWorkspace=works, OutputWorkspace=works, NPoints=40)
+        simple.ConvertFromDistribution(works)
+        return works
+
+    def reduce(self, run_numbers, panels):
+        self.is_vanadium = False
+        for run in run_numbers:
+            self.startup(self.get_cycle(run))
+            self.datafile = self.get_file_name(run, "raw")
+            for panel in panels:
+                wout = self.process_run(run, panel, "raw", "11_4", absorb=self.absorb, number_density=0.025,
+                                        scattering=5.463, attenuation=2.595, height=4.0, radius=0.55)
+                simple.ConvertUnits(InputWorkspace=wout, OutputWorkspace="{}-d".format(wout), Target="dSpacing",
+                                    EMode="Elastic")
+
+            simple.DeleteWorkspace("WISH_diff_cal")
+            simple.DeleteWorkspace("WISH_diff_group")
+            simple.DeleteWorkspace("WISH_diff_mask")
+            simple.DeleteWorkspace("monitor{}".format(run))
+            if 0 in panels:
+                panels = [1, 2, 3, 4, 5]
+            for panel in [x for x in panels if x < 6]:
+                self.save_combined_panel(run, panel)
+
+    def save_combined_panel(self, run, panel):
+        panel_combination = {
+            5: 6,
+            4: 7,
+            3: 8,
+            2: 9,
+            1: 10
+        }
+        input_ws1 = "w{0}-{1}foc".format(run, panel)
+        input_ws2 = "w{0}-{1}foc".format(run, panel_combination.get(panel))
+        combined = "{0}{1}-{2}_{3}foc{4}".format("{0}", run, panel, panel_combination.get(panel), "{1}")
+        combined_save = combined.format("", "{}")
+        combined_ws = combined.format("w", "")
+
+        simple.RebinToWorkspace(WorkspaceToRebin=input_ws2, WorkspaceToMatch=input_ws1, OutputWorkspace=input_ws2,
+                                PreserveEvents='0')
+        simple.Plus(LHSWorkspace=input_ws1, RHSWorkspace=input_ws2, OutputWorkspace=combined_ws)
+        simple.ConvertUnits(InputWorkspace=combined_ws, OutputWorkspace=combined_ws + "-d", Target="dSpacing",
+                            EMode="Elastic")
+
+        simple.SaveGSS(combined_ws, os.path.join(self.user_directory, combined_save.format("raw.gss")), Append=False,
+                       Bank=1)
+        simple.SaveFocusedXYE(combined_ws, os.path.join(self.user_directory, combined_save.format("raw.dat")))
+        simple.SaveNexusProcessed(combined_ws, os.path.join(self.user_directory, combined_save.format("raw.nxs")))
+
+
+def absorption_corrections(attenuation, height, number_density, radius, scattering, input_ws):
+    simple.ConvertUnits(InputWorkspace=input_ws, OutputWorkspace=input_ws, Target="Wavelength", EMode="Elastic")
+    simple.CylinderAbsorption(InputWorkspace=input_ws, OutputWorkspace="absorptionWS",
+                              CylinderSampleHeight=height, CylinderSampleRadius=radius,
+                              AttenuationXSection=attenuation, ScatteringXSection=scattering,
+                              SampleNumberDensity=number_density, NumberOfSlices="10", NumberOfAnnuli="10",
+                              NumberOfWavelengthPoints="25", ExpMethod="Normal")
+    simple.Divide(LHSWorkspace=input_ws, RHSWorkspace="absorptionWS", OutputWorkspace=input_ws)
+    simple.DeleteWorkspace("absorptionWS")
+    simple.ConvertUnits(InputWorkspace=input_ws, OutputWorkspace=input_ws, Target="TOF", EMode="Elastic")
+
+
+def split(focus):
+    for i in range(Wish.NUM_PANELS):
+        out = "{0}-{1}foc".format(focus[0:len(focus) - 3], i + 1)
+        simple.ExtractSingleSpectrum(InputWorkspace=focus, OutputWorkspace=out, WorkspaceIndex=i)
+        simple.DeleteWorkspace(focus)
+
+
+def split_run_string(string):
+    split_list = string.split("+")
+    if split_list[0]:
+        return int(split_list[0]), int(split_list[1])
+
+
+def split_string_event(input_string):
+    # this assumes the form nxs_event_label_tmin_tmax
+    section = input_string.split('_')
+    label = section[2]
+    t_min = section[3]
+    t_max = section[4]
+    return label, t_min, t_max
+
+
+def shared_load_files(extension, filename, ws, spectrum_max, spectrum_min, is_monitor):
+    if not (extension == "nxs" or extension == "raw" or extension[0] == "s"):
+        return False
+    if extension == "nxs":
+        simple.Load(Filename=filename, OutputWorkspace=ws, SpectrumMin=spectrum_min, SpectrumMax=spectrum_min)
+    else:
+        simple.LoadRaw(Filename=filename, OutputWorkspace=ws, SpectrumMin=spectrum_min, SpectrumMax=spectrum_max,
+                       LoadLogFiles="0")
+    simple.Rebin(InputWorkspace=ws, OutputWorkspace=ws, Params='6000,-0.00063,110000')
+    if not is_monitor:
+        simple.MaskBins(InputWorkspace=ws, OutputWorkspace=ws, XMin=99900, XMax=106000)
+    return True
diff --git a/scripts/ErrorReporter/error_report_presenter.py b/scripts/ErrorReporter/error_report_presenter.py
index 02b9dcfb5a170eb5825994bedf064d5f0bb0ef1a..bf7a7d6b6092029c62382a2890cfe067cc47920f 100644
--- a/scripts/ErrorReporter/error_report_presenter.py
+++ b/scripts/ErrorReporter/error_report_presenter.py
@@ -4,9 +4,11 @@
 #     NScD Oak Ridge National Laboratory, European Spallation Source
 #     & Institut Laue - Langevin
 # SPDX - License - Identifier: GPL - 3.0 +
+import os
+
 from mantid.kernel import ErrorReporter, UsageService, ConfigService
 from mantid.kernel import Logger
-from ErrorReporter.retrieve_recovery_files import zip_recovery_directory, remove_recovery_file
+from ErrorReporter.retrieve_recovery_files import zip_recovery_directory
 import requests
 
 
@@ -31,13 +33,21 @@ class ErrorReporterPresenter(object):
 
     def share_all_information(self, continue_working, name, email, text_box):
         uptime = UsageService.getUpTime()
-        zip_recovery_file, file_hash = zip_recovery_directory()
-        status = self._send_report_to_server(share_identifiable=True, uptime=uptime, name=name, email=email, file_hash=file_hash
-                                             , text_box=text_box)
-        self.error_log.notice("Sent complete information")
-        if status == 201:
-            self._upload_recovery_file(zip_recovery_file=zip_recovery_file)
-        remove_recovery_file(zip_recovery_file)
+        try:
+            recovery_archive, file_hash = zip_recovery_directory()
+        except Exception as exc:
+            self.error_log.information("Error creating recovery archive: {}. No recovery information will be sent")
+            recovery_archive, file_hash = None, ""
+        status = self._send_report_to_server(share_identifiable=True, uptime=uptime, name=name, email=email, file_hash=file_hash,
+                                             text_box=text_box)
+        self.error_log.notice("Sent full information")
+        if status == 201 and recovery_archive:
+            self._upload_recovery_file(recovery_archive=recovery_archive)
+            try:
+                os.remove(recovery_archive)
+            except OSError as exc:
+                self.error_log.information("Unable to remove zipped recovery information: {}".format(str(exc)))
+
         self._handle_exit(continue_working)
         return status
 
@@ -62,13 +72,13 @@ class ErrorReporterPresenter(object):
         else:
             self.error_log.error("Continue working.")
 
-    def _upload_recovery_file(self, zip_recovery_file):
+    def _upload_recovery_file(self, recovery_archive):
         url = ConfigService['errorreports.rooturl']
         url = '{}/api/recovery'.format(url)
-        files = {'file': open('{}.zip'.format(zip_recovery_file), 'rb')}
+        files = {'file': open('{}'.format(recovery_archive), 'rb')}
         response = requests.post(url, files=files)
         if response.status_code == 201:
-            self.error_log.notice("Uploaded recovery file to server HTTP response {}".format(response.status_code))
+            self.error_log.notice("Uploaded recovery file to server. HTTP response {}".format(response.status_code))
         else:
             self.error_log.error("Failed to send recovery data HTTP response {}".format(response.status_code))
 
diff --git a/scripts/ErrorReporter/retrieve_recovery_files.py b/scripts/ErrorReporter/retrieve_recovery_files.py
index 519c79ba65b4f910060d272dc4b93d514983aabb..245e1d52bb100df0aedb3d68414e2b4a21e27d1a 100644
--- a/scripts/ErrorReporter/retrieve_recovery_files.py
+++ b/scripts/ErrorReporter/retrieve_recovery_files.py
@@ -10,31 +10,23 @@ def get_properties_directory():
 
 
 def get_recovery_files_path():
-    recovery_files_path = ''
     properties_directory = get_properties_directory()
     if 'recovery' not in os.listdir(properties_directory):
-        return recovery_files_path
+        return None
 
-    recovery_dir_contents = os.listdir(properties_directory + 'recovery')
-    if not recovery_dir_contents:
+    recovery_files_path = os.path.join(properties_directory, 'recovery')
+    if len(os.listdir(recovery_files_path)) > 0:
         return recovery_files_path
-
-    recovery_files_path = properties_directory + 'recovery'
-    return recovery_files_path
+    else:
+        return None
 
 
 def zip_recovery_directory():
     path = get_recovery_files_path()
+    if path is None:
+        return "", ""
     directory = get_properties_directory()
     hash_value = hashlib.md5(str.encode(directory + str(datetime.datetime.now())))
-    zip_file = os.path.join(directory, hash_value.hexdigest())
-    if path:
-        shutil.make_archive(zip_file, 'zip', path)
-        return zip_file, hash_value.hexdigest()
-    return ''
-
-
-def remove_recovery_file(file):
-    directory = get_properties_directory()
-    zip_file = os.path.join(directory, file)
-    os.remove(zip_file + '.zip')
+    base_name = os.path.join(directory, hash_value.hexdigest())
+    zip_file = shutil.make_archive(base_name, 'zip', path)
+    return zip_file, hash_value.hexdigest()
diff --git a/scripts/Inelastic/Direct/detpackmap.py b/scripts/Inelastic/Direct/detpackmap.py
new file mode 100644
index 0000000000000000000000000000000000000000..80ea0754f7aae6e0ca224dc3b10e6d360adfb89c
--- /dev/null
+++ b/scripts/Inelastic/Direct/detpackmap.py
@@ -0,0 +1,10 @@
+def sequoia(name):
+    name = name.strip().upper()
+    packs = (['B{}'.format(i) for i in range(1, 37+1)]
+             + ['C{}'.format(i) for i in range(1, 24+1)]
+             + ['C25T', 'C26T', 'C25B', 'C26B']
+             + ['C{}'.format(i) for i in range(27, 37+1)]
+             + ['D{}'.format(i) for i in range(1, 37+1)]
+             )
+    start_index = 38
+    return start_index + packs.index(name)
diff --git a/scripts/Interface/reduction_gui/reduction/toftof/toftof_reduction.py b/scripts/Interface/reduction_gui/reduction/toftof/toftof_reduction.py
index 18044a392d4056cce3a9d5d16afeab71945d2171..c8ef01994e39dba63e84d8135211c0cb073d3f8f 100644
--- a/scripts/Interface/reduction_gui/reduction/toftof/toftof_reduction.py
+++ b/scripts/Interface/reduction_gui/reduction/toftof/toftof_reduction.py
@@ -60,6 +60,7 @@ class TOFTOFScriptElement(BaseScriptElement):
     # default values
     DEF_prefix     = 'ws'
     DEF_ecFactor   = 1.0
+    DEF_vanEcFactor = 1.0
 
     DEF_binEon     = True
     DEF_binEstart  = 0.0
@@ -100,6 +101,7 @@ class TOFTOFScriptElement(BaseScriptElement):
         self.vanRuns  = ''
         self.vanCmnt  = ''
         self.vanTemp  = OptionalFloat()
+        self.vanEcFactor = self.DEF_vanEcFactor
 
         # empty can runs, comment, and factor
         self.ecRuns   = ''
@@ -150,6 +152,7 @@ class TOFTOFScriptElement(BaseScriptElement):
         put('van_runs',        self.vanRuns)
         put('van_comment',     self.vanCmnt)
         put('van_temperature', self.vanTemp)
+        put('van_ec_factor',   self.vanEcFactor)
 
         put('ec_runs',     self.ecRuns)
         put('ec_temp',     self.ecTemp)
@@ -225,6 +228,7 @@ class TOFTOFScriptElement(BaseScriptElement):
             self.vanRuns  = get_str('van_runs')
             self.vanCmnt  = get_str('van_comment')
             self.vanTemp  = get_optFloat('van_temperature')
+            self.vanEcFactor = get_flt('van_ec_factor', self.DEF_vanEcFactor)
 
             self.ecRuns   = get_str('ec_runs')
             self.ecTemp   = get_optFloat('ec_temp')
@@ -597,10 +601,16 @@ class TOFTOFScriptElement(BaseScriptElement):
             self.l("{} = Scale({}, Factor=ecFactor, Operation='Multiply')"
                    .format(scaledEC, wsECNorm))
             self.l("{} = Minus({}, {})" .format(gDataSubEC, gDataNorm, scaledEC))
+            wslist = [scaledEC]
             if self.subtractECVan:
                 wsVanSubEC = wsVan + 'SubEC'
-                self.l("{} = Minus({}, {})" .format(wsVanSubEC, wsVanNorm, scaledEC))
-            self.delete_workspaces([scaledEC])
+                scaledECvan = self.prefix + 'ScaledECvan'
+                self.l("van_ecFactor = {:.3f}" .format(self.vanEcFactor))
+                self.l("{} = Scale({}, Factor=van_ecFactor, Operation='Multiply')"
+                       .format(scaledECvan, wsECNorm))
+                self.l("{} = Minus({}, {})" .format(wsVanSubEC, wsVanNorm, scaledECvan))
+                wslist.append(scaledECvan)
+            self.delete_workspaces(wslist)
 
         self.l("# group data for processing")
         gDataSource = gDataSubEC if self.ecRuns else gDataNorm
diff --git a/scripts/Interface/reduction_gui/widgets/toftof/toftof_setup.py b/scripts/Interface/reduction_gui/widgets/toftof/toftof_setup.py
index 3bad09059b10877de9dd15a964652a6bc4073224..48e9fd9db863495baac8f2fc4e3707603dc4d812 100644
--- a/scripts/Interface/reduction_gui/widgets/toftof/toftof_setup.py
+++ b/scripts/Interface/reduction_gui/widgets/toftof/toftof_setup.py
@@ -55,6 +55,7 @@ class TOFTOFSetupWidget(BaseWidget):
     TIP_vanRuns = ''
     TIP_vanCmnt = ''
     TIP_vanTemp = 'Temperature (K). Optional.'
+    TIP_vanEcFactor = ''
 
     TIP_ecRuns = ''
     TIP_ecTemp = 'Temperature (K). Optional.'
@@ -178,6 +179,8 @@ class TOFTOFSetupWidget(BaseWidget):
         self.btnSaveDir          = tip(QPushButton('Browse'), self.TIP_btnSaveDir)
 
         self.chkSubtractECVan    = tip(QCheckBox('Subtract empty can from vanadium'), self.TIP_chkSubtractECVan)
+        self.vanEcFactor         = setEnabled(tip(QDoubleSpinBox(), self.TIP_vanEcFactor), self.chkSubtractECVan)
+        set_spin(self.vanEcFactor, 0, 1)
         self.chkReplaceNaNs      = setEnabled(tip(QCheckBox(u'Replace special values in S(Q, ω) with 0'), self.TIP_chkReplaceNaNs),
                                               self.binEon)
         self.chkCreateDiff       = setEnabled(tip(QCheckBox('Create diffractograms'), self.TIP_chkCreateDiff), self.binEon)
@@ -271,7 +274,8 @@ class TOFTOFSetupWidget(BaseWidget):
         grid.addWidget(QLabel('Vanadium runs'), 0, 0)
         grid.addWidget(self.vanRuns,            0, 1, 1, 3)
         grid.addWidget(QLabel('Van. comment'),  1, 0)
-        grid.addWidget(self.vanCmnt,            1, 1, 1, 2)
+        grid.addWidget(self.vanCmnt,            1, 1, 1, 1)
+        grid.addLayout(hbox(QLabel('EC factor'), self.vanEcFactor), 1, 2, 1, 1)
         grid.addLayout(hbox(QLabel('T (K)'), self.vanTemp),         1, 3)
         grid.addWidget(QLabel('Empty can runs'),2, 0)
         grid.addWidget(self.ecRuns,             2, 1, 1, 1)
@@ -359,6 +363,7 @@ class TOFTOFSetupWidget(BaseWidget):
         elem.vanRuns        = line_text(self.vanRuns)
         elem.vanCmnt        = line_text(self.vanCmnt)
         elem.vanTemp        = OptionalFloat(line_text(self.vanTemp))
+        elem.vanEcFactor    = self.vanEcFactor.value()
 
         elem.ecRuns         = line_text(self.ecRuns)
         elem.ecTemp         = OptionalFloat(line_text(self.ecTemp))
@@ -409,6 +414,7 @@ class TOFTOFSetupWidget(BaseWidget):
         self.vanRuns.setText(elem.vanRuns)
         self.vanCmnt.setText(elem.vanCmnt)
         self.vanTemp.setText(str(elem.vanTemp))
+        self.vanEcFactor.setValue(elem.vanEcFactor)
 
         self.ecRuns.setText(elem.ecRuns)
         self.ecTemp.setText(str(elem.ecTemp))
diff --git a/scripts/Interface/ui/sans_isis/CMakeLists.txt b/scripts/Interface/ui/sans_isis/CMakeLists.txt
index 5c0f1c0db6c279405e6adb48876ec3d85ff002ce..71f0e35b679ff8de2910ce9d8020830ed8adb473 100644
--- a/scripts/Interface/ui/sans_isis/CMakeLists.txt
+++ b/scripts/Interface/ui/sans_isis/CMakeLists.txt
@@ -9,6 +9,7 @@ run_selector_widget.ui
 summation_settings_widget.ui
 beam_centre.ui
 diagnostics_page.ui
+save_other_dialog.ui
  )
 
 UiToPy( UI_FILES CompileUISANSDataProcessorInterface)
diff --git a/scripts/Interface/ui/sans_isis/SANSSaveOtherWindow.py b/scripts/Interface/ui/sans_isis/SANSSaveOtherWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..8364330136eee05f0ce30495e04a248f21d91384
--- /dev/null
+++ b/scripts/Interface/ui/sans_isis/SANSSaveOtherWindow.py
@@ -0,0 +1,139 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from . import ui_save_other_dialog as ui_save_other_dialog
+from PyQt4 import QtGui, QtCore
+from sans.common.enums import SaveType
+from mantidqtpython import MantidQt
+
+try:
+    from mantidplot import pymantidplot
+    canMantidPlot = True
+except ImportError:
+    canMantidPlot = False
+
+
+class SANSSaveOtherDialog(QtGui.QDialog, ui_save_other_dialog.Ui_SaveOtherDialog):
+    def __init__(self, parent_widget=None):
+        super(QtGui.QDialog, self).__init__(parent=parent_widget)
+        self.subscribers = []
+        self.setup_view()
+
+    def setup_view(self):
+        self.setupUi(self)
+        self.filename_lineEdit.textChanged.connect(self.on_file_name_changed)
+        self.browse_pushButton.pressed.connect(self.on_browse_clicked)
+        self.save_button.pressed.connect(self.on_save_clicked)
+        self.help_button.clicked.connect(self._on_help_button_clicked)
+        self.cancel_button.pressed.connect(self.on_cancel_clicked)
+        self.directory_lineEdit.textChanged.connect(self.on_directory_changed)
+        self.nxcansas_checkBox.setChecked(True)
+        self.ads_widget = MantidQt.MantidWidgets.WorkspaceTreeWidgetSimple(True, self)
+        self.ads_widget.treeSelectionChanged.connect(self.on_item_selection_changed)
+        self.ads_widget.refreshWorkspaces()
+        self.ads_widget.installEventFilter(self)
+        self.workspace_list_layout.addWidget(self.ads_widget, 0, 1, 4, 1)
+        self.progress_bar_value = 0
+
+    def eventFilter(self, source, event):
+        if event.type() == QtCore.QEvent.KeyPress:
+            return True
+        return QtGui.QWidget.eventFilter(self, source, event)
+
+    def subscribe(self, subscriber):
+        self.subscribers.append(subscriber)
+
+    def on_file_name_changed(self):
+        file_name = str(self.filename_lineEdit.text())
+        for subscriber in self.subscribers:
+            subscriber.on_file_name_changed(file_name)
+
+    def on_browse_clicked(self):
+        for subscriber in self.subscribers:
+            subscriber.on_browse_clicked()
+
+    def on_save_clicked(self):
+        for subscriber in self.subscribers:
+            subscriber.on_save_clicked()
+
+    def on_cancel_clicked(self):
+        for subscriber in self.subscribers:
+            subscriber.on_cancel_clicked()
+
+    def on_directory_changed(self):
+        for subscriber in self.subscribers:
+            subscriber.on_directory_changed(self.current_directory)
+
+    def on_item_selection_changed(self):
+        for subscriber in self.subscribers:
+            subscriber.on_item_selection_changed()
+
+    def get_selected_workspaces(self):
+        return [str(x) for x in self.ads_widget.getSelectedWorkspaceNames()]
+
+    def get_save_options(self):
+        save_types = []
+        if self.RKH_checkBox.isChecked():
+            save_types.append(SaveType.RKH)
+        if self.nxcansas_checkBox.isChecked():
+            save_types.append(SaveType.NXcanSAS)
+        if self.CanSAS_checkBox.isChecked():
+            save_types.append(SaveType.CanSAS)
+        return save_types
+
+    def launch_file_browser(self, current_directory):
+        filename = QtGui.QFileDialog.getExistingDirectory(self, 'Select Directory', current_directory,
+                                                          QtGui.QFileDialog.ShowDirsOnly)
+        return filename
+
+    def rename_filebox(self, name):
+        self.filename_label.setText(name)
+
+    def _on_help_button_clicked(self):
+        pymantidplot.proxies.showCustomInterfaceHelp('sans_save_other')
+
+    @property
+    def progress_bar_minimum(self):
+        return self.progress_bar.minimum()
+
+    @progress_bar_minimum.setter
+    def progress_bar_minimum(self, value):
+        self.progress_bar.setMinimum(value)
+
+    @property
+    def progress_bar_maximum(self):
+        return self.progress_bar.maximum()
+
+    @progress_bar_maximum.setter
+    def progress_bar_maximum(self, value):
+        self.progress_bar.setMaximum(value)
+
+    @property
+    def progress_bar_value(self):
+        return self.progress_bar.value()
+
+    @progress_bar_value.setter
+    def progress_bar_value(self, progress):
+        self.progress_bar.setValue(progress)
+
+    def increment_progress(self):
+        self.progress_bar_value += 1
+
+    @property
+    def current_directory(self):
+        return str(self.directory_lineEdit.text())
+
+    @current_directory.setter
+    def current_directory(self, value):
+        self.directory_lineEdit.setText(value)
+
+    @property
+    def filename(self):
+        return str(self.filename_lineEdit.text())
+
+    @filename.setter
+    def filename(self, value):
+        self.filename_lineEdit.setText(value)
diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py
index 5aaa78592c28b8a36fcdd097e7a74b5fac72e046..97cdf86d4c6c53bc8f10bb48be77326f859f23d1 100644
--- a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py
+++ b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py
@@ -48,6 +48,7 @@ from sans.gui_logic.presenter.add_runs_presenter import AddRunsPagePresenter
 from sans.gui_logic.presenter.run_selector_presenter import RunSelectorPresenter
 from sans.gui_logic.presenter.summation_settings_presenter import SummationSettingsPresenter
 from ui.sans_isis.work_handler import WorkHandler
+from ui.sans_isis.SANSSaveOtherWindow import SANSSaveOtherDialog
 
 DEFAULT_BIN_SETTINGS = \
     '5.5,45.5,50.0, 50.0,1000.0, 500.0,1500.0, 750.0,99750.0, 255.0,100005.0'
@@ -165,6 +166,10 @@ class SANSDataProcessorGui(QMainWindow,
         def on_cut_rows(self):
             pass
 
+        @abstractmethod
+        def on_save_other(self):
+            pass
+
         @abstractmethod
         def on_compatibility_unchecked(self):
             pass
@@ -211,6 +216,7 @@ class SANSDataProcessorGui(QMainWindow,
 
         self.delete_row_button.clicked.connect(self._remove_rows_requested_from_button)
         self.insert_row_button.clicked.connect(self._on_insert_button_pressed)
+        self.save_other_pushButton.clicked.connect(self._on_save_other_button_pressed)
 
         # Attach validators
         self._attach_validators()
@@ -499,6 +505,9 @@ class SANSDataProcessorGui(QMainWindow,
     def _on_insert_button_pressed(self):
         self._call_settings_listeners(lambda listener: listener.on_insert_row())
 
+    def _on_save_other_button_pressed(self):
+        self._call_settings_listeners(lambda listener: listener.on_save_other())
+
     def _on_compatibility_unchecked(self):
         self._call_settings_listeners(lambda listener: listener.on_compatibility_unchecked())
 
@@ -2050,3 +2059,9 @@ class SANSDataProcessorGui(QMainWindow,
         self.data_processor_table.hideColumn(15)
         self.data_processor_table.hideColumn(16)
         self.data_processor_table.hideColumn(17)
+
+    def closeEvent(self, event):
+        for child in self.children():
+            if isinstance(child, SANSSaveOtherDialog):
+                child.done(0)
+        super(QtGui.QMainWindow, self).closeEvent(event)
diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui b/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui
index c424acd82fed9af9a043c670c14437b16523e74e..00b3511c876bb023b87f61edb5b7562e6608def7 100644
--- a/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui
+++ b/scripts/Interface/ui/sans_isis/sans_data_processor_window.ui
@@ -595,6 +595,13 @@ QGroupBox::title {
                 </property>
                </widget>
               </item>
+              <item row="1" column="3">
+               <widget class="QPushButton" name="save_other_pushButton">
+                <property name="text">
+                 <string>Save Other</string>
+                </property>
+               </widget>
+              </item>
              </layout>
             </item>
            </layout>
diff --git a/scripts/Interface/ui/sans_isis/save_other_dialog.ui b/scripts/Interface/ui/sans_isis/save_other_dialog.ui
new file mode 100644
index 0000000000000000000000000000000000000000..65bdeccadd71eca462e8270d7740539e860bb477
--- /dev/null
+++ b/scripts/Interface/ui/sans_isis/save_other_dialog.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SaveOtherDialog</class>
+ <widget class="QDialog" name="SaveOtherDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>541</width>
+    <height>297</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Save Other</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0" colspan="3">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Directory</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" rowspan="6" colspan="4">
+    <layout class="QGridLayout" name="workspace_list_layout"/>
+   </item>
+   <item row="0" column="4">
+    <widget class="QPushButton" name="browse_pushButton">
+     <property name="text">
+      <string>Browse</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="4">
+    <widget class="QCheckBox" name="RKH_checkBox">
+     <property name="text">
+      <string>RKH</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="4">
+    <widget class="QPushButton" name="save_button">
+     <property name="text">
+      <string>Save</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="4">
+    <widget class="QPushButton" name="cancel_button">
+     <property name="text">
+      <string>Close</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="3">
+    <widget class="QLineEdit" name="directory_lineEdit"/>
+   </item>
+   <item row="1" column="3">
+    <widget class="QLineEdit" name="filename_lineEdit"/>
+   </item>
+   <item row="1" column="0" colspan="3">
+    <widget class="QLabel" name="filename_label">
+     <property name="text">
+      <string>Filename</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="4">
+    <widget class="QCheckBox" name="nxcansas_checkBox">
+     <property name="text">
+      <string>NxCanSAS</string>
+     </property>
+    </widget>
+   </item>
+   <item row="7" column="4">
+    <widget class="QCheckBox" name="CanSAS_checkBox">
+     <property name="text">
+      <string>CanSAS</string>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="0">
+    <widget class="QPushButton" name="help_button">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>31</width>
+       <height>31</height>
+      </size>
+     </property>
+     <property name="text">
+      <string>?</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="4">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Save Formats</string>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="1" colspan="4">
+    <widget class="QProgressBar" name="progress_bar">
+     <property name="value">
+      <number>24</number>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scripts/Muon/GUI/Common/ADSHandler/muon_workspace_wrapper.py b/scripts/Muon/GUI/Common/ADSHandler/muon_workspace_wrapper.py
index fa899d8d279199eb4207d3458ae57d941ed2422a..a8a2cabd81098925a28273f1319cd46ed84e6413 100644
--- a/scripts/Muon/GUI/Common/ADSHandler/muon_workspace_wrapper.py
+++ b/scripts/Muon/GUI/Common/ADSHandler/muon_workspace_wrapper.py
@@ -117,7 +117,7 @@ class MuonWorkspaceWrapper(object):
             self._workspace = value
         else:
             raise AttributeError("Attempting to set object of type {}, must be"
-                                 "a Mantid Workspace type")
+                                 " a Mantid Workspace type".format(type(value)))
 
     def show(self, name):
         """
diff --git a/scripts/Muon/GUI/Common/ADSHandler/workspace_naming.py b/scripts/Muon/GUI/Common/ADSHandler/workspace_naming.py
new file mode 100644
index 0000000000000000000000000000000000000000..338a5159f1b4b2a25fad5e2c939f0759cb03c3ef
--- /dev/null
+++ b/scripts/Muon/GUI/Common/ADSHandler/workspace_naming.py
@@ -0,0 +1,61 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+
+
+def get_raw_data_workspace_name(context):
+    return context._base_run_name() + "_raw_data"
+
+
+def get_group_data_workspace_name(context, group_name):
+    if context.is_multi_period():
+        return context._base_run_name() + "; Group; " + group_name + \
+               "; Counts; Periods; " + context.period_string + "; #1"
+    else:
+        return context._base_run_name() + "; Group; " + group_name + "; Counts; #1"
+
+
+def get_pair_data_workspace_name(context, pair_name):
+    if context.is_multi_period():
+        return context._base_run_name() + "; Pair Asym; " + pair_name + "; Periods; " + context.period_string + "; #1"
+    else:
+        return context._base_run_name() + "; Pair Asym; " + pair_name + "; #1"
+
+
+def get_base_data_directory(context):
+    if context.is_multi_period():
+        return context.base_directory + "/" + context._base_run_name() + " Period " + context.period_string + "/"
+    else:
+        return context.base_directory + "/" + context._base_run_name() + "/"
+
+
+def get_raw_data_directory(context):
+    if context.is_multi_period():
+        return context._base_run_name() + " Period " + context.period_string + "; Raw Data/"
+    else:
+        return context._base_run_name() + " Raw Data/"
+
+
+def get_cached_data_directory(context):
+    if context.is_multi_period():
+        return context._base_run_name() + " Period " + context.period_string + "; Cached/"
+    else:
+        return context._base_run_name() + " Cached/"
+
+
+def get_group_data_directory(context):
+    if context.is_multi_period():
+        return context._base_run_name() + " Period " + context.period_string + "; Groups/"
+    else:
+        return context._base_run_name() + " Groups/"
+
+
+def get_pair_data_directory(context):
+    if context.is_multi_period():
+        return context._base_run_name() + " Period " + context.period_string + "; Pairs/"
+    else:
+        return context._base_run_name() + " Pairs/"
diff --git a/scripts/Muon/GUI/Common/calculate_pair_and_group.py b/scripts/Muon/GUI/Common/calculate_pair_and_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..167aa6ccadffa7c2083c681892b541dd5a617c16
--- /dev/null
+++ b/scripts/Muon/GUI/Common/calculate_pair_and_group.py
@@ -0,0 +1,114 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import Muon.GUI.Common.load_utils as load_utils
+
+
+def calculate_group_data(context, group_name):
+    processed_data = _run_pre_processing(context)
+
+    params = _get_MuonGroupingCounts_parameters(context, group_name)
+    params["InputWorkspace"] = processed_data
+    group_data = load_utils.run_MuonGroupingCounts(context, params)
+
+    return group_data
+
+
+def calculate_pair_data(context, pair_name):
+    processed_data = _run_pre_processing(context)
+
+    params = _get_MuonPairingAsymmetry_parameters(context, pair_name)
+    params["InputWorkspace"] = processed_data
+    pair_data = load_utils.run_MuonPairingAsymmetry(context, params)
+
+    return pair_data
+
+
+def _run_pre_processing(context):
+    params = context._get_pre_processing_params()
+    params["InputWorkspace"] = context.loaded_workspace
+    processed_data = load_utils.run_MuonPreProcess(context, params)
+    return processed_data
+
+
+def _get_pre_processing_params(context):
+    pre_process_params = {}
+    try:
+        time_min = context.loaded_data["FirstGoodData"]
+        pre_process_params["TimeMin"] = time_min
+    except KeyError:
+        pass
+
+    try:
+        rebin_args = context.loaded_data["Rebin"]
+        pre_process_params["RebinArgs"] = rebin_args
+    except KeyError:
+        pass
+
+    try:
+        time_offset = context.loaded_data["TimeZero"]
+        pre_process_params["TimeOffset"] = time_offset
+    except KeyError:
+        pass
+
+    try:
+        dead_time_table = context.dead_time_table
+        if dead_time_table is not None:
+            pre_process_params["DeadTimeTable"] = dead_time_table
+    except KeyError:
+        pass
+
+    return pre_process_params
+
+
+def _get_MuonGroupingCounts_parameters(context, group_name):
+    params = {}
+    try:
+        summed_periods = context.loaded_data["SummedPeriods"]
+        params["SummedPeriods"] = str(summed_periods)
+    except KeyError:
+        params["SummedPeriods"] = "1"
+
+    try:
+        subtracted_periods = context.loaded_data["SubtractedPeriods"]
+        params["SubtractedPeriods"] = str(subtracted_periods)
+    except KeyError:
+        params["SubtractedPeriods"] = ""
+
+    group = context._groups.get(group_name, None)
+    if group:
+        params["GroupName"] = group_name
+        params["Grouping"] = ",".join([str(i) for i in group.detectors])
+
+    return params
+
+
+def _get_MuonPairingAsymmetry_parameters(context, pair_name):
+    params = {}
+    try:
+        summed_periods = context.loaded_data["SummedPeriods"]
+        params["SummedPeriods"] = str(summed_periods)
+    except KeyError:
+        params["SummedPeriods"] = "1"
+
+    try:
+        subtracted_periods = context.loaded_data["SubtractedPeriods"]
+        params["SubtractedPeriods"] = str(subtracted_periods)
+    except KeyError:
+        params["SubtractedPeriods"] = ""
+
+    pair = context._pairs.get(pair_name, None)
+
+    if pair:
+        params["SpecifyGroupsManually"] = True
+        params["PairName"] = str(pair_name)
+        detectors1 = ",".join([str(i) for i in context._groups[pair.forward_group].detectors])
+        detectors2 = ",".join([str(i) for i in context._groups[pair.backward_group].detectors])
+        params["Group1"] = detectors1
+        params["Group2"] = detectors2
+        params["Alpha"] = str(pair.alpha)
+
+    return params
diff --git a/scripts/Muon/GUI/Common/load_file_widget/__init__.py b/scripts/Muon/GUI/Common/load_file_widget/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/Muon/GUI/Common/load_file_widget/model.py b/scripts/Muon/GUI/Common/load_file_widget/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..c90ed15701e042e7ba67b7c6e1949849871faa43
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_file_widget/model.py
@@ -0,0 +1,82 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+
+import os
+from mantid.kernel import ConfigService
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+import Muon.GUI.Common.utilities.load_utils as load_utils
+
+
+class BrowseFileWidgetModel(object):
+
+    def __init__(self, loaded_data_store=MuonLoadData()):
+        # Temporary list of filenames used for load thread
+        self._filenames = []
+
+        self._loaded_data_store = loaded_data_store
+
+    @property
+    def loaded_filenames(self):
+        return self._loaded_data_store.get_parameter("filename")
+
+    @property
+    def loaded_workspaces(self):
+        return self._loaded_data_store.get_parameter("workspace")
+
+    @property
+    def loaded_runs(self):
+        return self._loaded_data_store.get_parameter("run")
+
+    # Used with load thread
+    def output(self):
+        pass
+
+    # Used with load thread
+    def cancel(self):
+        pass
+
+    # Used with load thread
+    def loadData(self, filename_list):
+        self._filenames = filename_list
+
+    # Used with load thread
+    def execute(self):
+        failed_files = []
+        for filename in self._filenames:
+            try:
+                ws, run, filename = load_utils.load_workspace_from_filename(filename)
+            except Exception:
+                failed_files += [filename]
+                continue
+            self._loaded_data_store.remove_data(run=run)
+            self._loaded_data_store.add_data(run=run, workspace=ws, filename=filename)
+        if failed_files:
+            message = load_utils.exception_message_for_failed_files(failed_files)
+            raise ValueError(message)
+
+    def clear(self):
+        self._loaded_data_store.clear()
+
+    def remove_previous_data(self):
+        self._loaded_data_store.remove_last_added_data()
+
+    def get_run_list(self):
+        return self.loaded_runs
+
+    def add_directories_to_config_service(self, file_list):
+        """
+        Parses file_list into the unique directories containing the files, and adds these
+        to the global config service. These directories will then be automatically searched in
+        all subsequent Load calls.
+        """
+        dirs = [os.path.dirname(filename) for filename in file_list]
+        dirs = [path if os.path.isdir(path) else "" for path in dirs]
+        dirs = list(set(dirs))
+        if dirs:
+            for directory in dirs:
+                ConfigService.Instance().appendDataSearchDir(directory.encode('ascii', 'ignore'))
diff --git a/scripts/Muon/GUI/Common/load_file_widget/presenter.py b/scripts/Muon/GUI/Common/load_file_widget/presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..648204065528bfd5c27cb2d2c80ac7ff43021504
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_file_widget/presenter.py
@@ -0,0 +1,162 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+
+import copy
+
+from Muon.GUI.Common import thread_model
+import Muon.GUI.Common.utilities.muon_file_utils as file_utils
+import Muon.GUI.Common.utilities.load_utils as load_utils
+
+
+class BrowseFileWidgetPresenter(object):
+
+    def __init__(self, view, model):
+        self._view = view
+        self._model = model
+
+        # Whether to allow single or multiple files to be loaded
+        self._multiple_files = False
+        self._multiple_file_mode = "Single"
+
+        self._use_threading = True
+        self._load_thread = None
+
+        self._view.on_browse_clicked(self.on_browse_button_clicked)
+        self._view.on_file_edit_changed(self.handle_file_changed_by_user)
+
+    def show(self):
+        self._view.show()
+
+    def cancel(self):
+        if self._load_thread is not None:
+            self._load_thread.cancel()
+
+    def create_load_thread(self):
+        return thread_model.ThreadModel(self._model)
+
+    def update_multiple_loading_behaviour(self, text):
+        self._multiple_file_mode = text
+
+    def get_filenames_from_user(self):
+        file_filter = file_utils.filter_for_extensions(["nxs"])
+        directory = ""
+        filenames = self._view.show_file_browser_and_return_selection(file_filter, [directory],
+                                                                      multiple_files=self._multiple_files)
+        # validate
+        filenames = file_utils.parse_user_input_to_files(";".join(filenames))
+        filenames = file_utils.remove_duplicated_files_from_list(filenames)
+        return filenames
+
+    def on_browse_button_clicked(self):
+        filenames = self.get_filenames_from_user()
+        filenames = file_utils.remove_duplicated_files_from_list(filenames)
+        if not self._multiple_files and len(filenames) > 1:
+            self._view.warning_popup("Multiple files selected in single file mode")
+            self._view.reset_edit_to_cached_value()
+            return
+        if filenames:
+            self.handle_loading(filenames)
+
+    def handle_file_changed_by_user(self):
+        user_input = self._view.get_file_edit_text()
+        filenames = file_utils.parse_user_input_to_files(user_input)
+        filenames = file_utils.remove_duplicated_files_from_list(filenames)
+        if not filenames:
+            self._view.reset_edit_to_cached_value()
+            return
+        if not self._multiple_files and len(filenames) > 1:
+            self._view.warning_popup("Multiple files selected in single file mode")
+            self._view.reset_edit_to_cached_value()
+            return
+        if self._multiple_file_mode == "Co-Add":
+            # We don't want to allow messy appending when co-adding
+            self.clear_loaded_data()
+        self.handle_loading(filenames)
+
+    def handle_loading(self, filenames):
+        if self._use_threading:
+            self.handle_load_thread_start(filenames)
+        else:
+            self.handle_load_no_threading(filenames)
+
+    def handle_load_no_threading(self, filenames):
+        self._view.notify_loading_started()
+        self.disable_loading()
+        self._model.loadData(filenames)
+        try:
+            self._model.execute()
+        except ValueError as error:
+            self._view.warning_popup(error.args[0])
+        self.on_loading_finished()
+
+    def handle_load_thread_start(self, filenames):
+        if self._load_thread:
+            return
+        self._view.notify_loading_started()
+        self._load_thread = self.create_load_thread()
+        self._load_thread.threadWrapperSetUp(self.disable_loading,
+                                             self.handle_load_thread_finished,
+                                             self._view.warning_popup)
+        self._load_thread.loadData(filenames)
+        self._load_thread.start()
+
+    def handle_load_thread_finished(self):
+        self._load_thread.deleteLater()
+        self._load_thread = None
+
+        # If in single file mode, remove the previous run
+        if not self._multiple_files and len(self._model.get_run_list()) > 1:
+            self._model.remove_previous_data()
+
+        self.on_loading_finished()
+
+    def on_loading_finished(self):
+        file_list = self._model.loaded_filenames
+        self.set_file_edit(file_list)
+
+        if self._multiple_files and self._multiple_file_mode == "Co-Add":
+            load_utils.combine_loaded_runs(self._model, self._model.loaded_runs)
+
+        self._view.notify_loading_finished()
+        self.enable_loading()
+        self._model.add_directories_to_config_service(file_list)
+
+    def clear_loaded_data(self):
+        self._view.clear()
+        self._model.clear()
+
+    def disable_loading(self):
+        self._view.disable_load_buttons()
+
+    def enable_loading(self):
+        self._view.enable_load_buttons()
+
+    def enable_multiple_files(self, enabled):
+        self._multiple_files = enabled
+
+    @property
+    def workspaces(self):
+        return self._model.loaded_workspaces
+
+    @property
+    def runs(self):
+        return self._model.loaded_runs
+
+    def set_file_edit(self, file_list):
+        file_list = sorted(copy.copy(file_list))
+        if file_list == []:
+            self._view.set_file_edit("No data loaded", False)
+        else:
+            self._view.set_file_edit(";".join(file_list), False)
+
+    # used by parent widget
+    def update_view_from_model(self, file_list):
+        self.set_file_edit(file_list)
+
+    def set_current_instrument(self, instrument):
+        pass
diff --git a/scripts/Muon/GUI/Common/load_file_widget/view.py b/scripts/Muon/GUI/Common/load_file_widget/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..52157be58c84bfa8d10142040d0a373f47f69884
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_file_widget/view.py
@@ -0,0 +1,139 @@
+from __future__ import (absolute_import, division, print_function)
+
+from PyQt4 import QtGui
+from PyQt4.QtCore import pyqtSignal
+import Muon.GUI.Common.message_box as message_box
+
+
+class BrowseFileWidgetView(QtGui.QWidget):
+    # signals for use by parent widgets
+    loadingStarted = pyqtSignal()
+    loadingFinished = pyqtSignal()
+    dataChanged = pyqtSignal()
+
+    def __init__(self, parent=None):
+        super(BrowseFileWidgetView, self).__init__(parent)
+
+        self.horizontal_layout = None
+        self.browse_button = None
+        self.file_path_edit = None
+
+        self.setup_interface_layout()
+
+        self._store_edit_text = False
+        self._stored_edit_text = ""
+        self._cached_text = ""
+
+        self.set_file_edit("No data loaded", False)
+
+        self.file_path_edit.setReadOnly(True)
+
+    def setup_interface_layout(self):
+        self.setObjectName("BrowseFileWidget")
+        self.resize(500, 100)
+
+        self.browse_button = QtGui.QPushButton(self)
+
+        size_policy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        size_policy.setHorizontalStretch(0)
+        size_policy.setVerticalStretch(0)
+        size_policy.setHeightForWidth(self.browse_button.sizePolicy().hasHeightForWidth())
+
+        self.browse_button.setSizePolicy(size_policy)
+        self.browse_button.setObjectName("browseButton")
+        self.browse_button.setText("Browse")
+
+        self.file_path_edit = QtGui.QLineEdit(self)
+
+        size_policy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        size_policy.setHorizontalStretch(0)
+        size_policy.setVerticalStretch(0)
+        size_policy.setHeightForWidth(self.file_path_edit.sizePolicy().hasHeightForWidth())
+
+        self.file_path_edit.setSizePolicy(size_policy)
+        self.file_path_edit.setToolTip("")
+        self.file_path_edit.setObjectName("filePathEdit")
+
+        self.setStyleSheet("QLineEdit {background: #d7d6d5}")
+
+        self.horizontal_layout = QtGui.QHBoxLayout()
+        self.horizontal_layout.setObjectName("horizontalLayout")
+        self.horizontal_layout.addWidget(self.browse_button)
+        self.horizontal_layout.addWidget(self.file_path_edit)
+
+        self.horizontal_layout.setContentsMargins(0, 0, 0, 0)
+        self.horizontal_layout.setMargin(0)
+
+        self.setLayout(self.horizontal_layout)
+
+    def getLayout(self):
+        return self.horizontal_layout
+
+    def on_browse_clicked(self, slot):
+        self.browse_button.clicked.connect(slot)
+
+    def on_file_edit_changed(self, slot):
+        self.file_path_edit.returnPressed.connect(slot)
+
+    def show_file_browser_and_return_selection(self, file_filter, search_directories, multiple_files=False):
+        default_directory = search_directories[0]
+        print("OPENING FILE BROWSER")
+        if multiple_files:
+            chosen_files = QtGui.QFileDialog.getOpenFileNames(self, "Select files", default_directory,
+                                                              file_filter)
+            return [str(chosen_file) for chosen_file in chosen_files]
+        else:
+            chosen_file = QtGui.QFileDialog.getOpenFileName(self, "Select file", default_directory,
+                                                            file_filter)
+            return [str(chosen_file)]
+
+    def disable_loading(self):
+        self.disable_load_buttons()
+        self.loadingStarted.emit()
+
+    def enable_loading(self):
+        self.enable_load_buttons()
+        self.loadingFinished.emit()
+
+    def notify_loading_started(self):
+        self.loadingStarted.emit()
+
+    def notify_loading_finished(self):
+        self.loadingFinished.emit()
+        self.dataChanged.emit()
+
+    def disable_load_buttons(self):
+        self.browse_button.setEnabled(False)
+        self.file_path_edit.setEnabled(False)
+
+    def enable_load_buttons(self):
+        self.browse_button.setEnabled(True)
+        self.file_path_edit.setEnabled(True)
+
+    def get_file_edit_text(self):
+        if self._store_edit_text:
+            return str(self._stored_edit_text)
+        else:
+            return str(self.file_path_edit.text())
+
+    def set_file_edit(self, text, store=False):
+        if store:
+            self._store_edit_text = True
+            self._stored_edit_text = text
+            self.file_path_edit.setText("(... more than 10 files, use right-click -> copy)")
+        else:
+            self.file_path_edit.setText(text)
+        self._cached_text = self.get_file_edit_text()
+
+    def clear(self):
+        self.set_file_edit("No data loaded")
+        self._store_edit_text = False
+        self._cached_text = "No data loaded"
+
+    def reset_edit_to_cached_value(self):
+        tmp = self._cached_text
+        self.set_file_edit(tmp)
+        self._cached_text = tmp
+
+    def warning_popup(self, message):
+        message_box.warning(str(message))
diff --git a/scripts/Muon/GUI/Common/load_run_widget/__init__.py b/scripts/Muon/GUI/Common/load_run_widget/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/Muon/GUI/Common/load_run_widget/model.py b/scripts/Muon/GUI/Common/load_run_widget/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..50e0c37f477557e5dd9c3d03e647dd622b3c3d22
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_run_widget/model.py
@@ -0,0 +1,72 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+import Muon.GUI.Common.utilities.load_utils as load_utils
+
+
+class LoadRunWidgetModel(object):
+    """Stores info on all currently loaded workspaces"""
+
+    def __init__(self, loaded_data_store=MuonLoadData()):
+        # Used with load thread
+        self._filenames = []
+
+        self._loaded_data_store = loaded_data_store
+        self._current_run = None
+
+    def remove_previous_data(self):
+        self._loaded_data_store.remove_last_added_data()
+
+    # Used with load thread
+    def loadData(self, filenames):
+        self._filenames = filenames
+
+    # Used with load thread
+    def execute(self):
+        failed_files = []
+        for filename in self._filenames:
+            try:
+                ws, run, filename = load_utils.load_workspace_from_filename(filename)
+            except Exception:
+                failed_files += [filename]
+                continue
+            self._loaded_data_store.remove_data(run=run)
+            self._loaded_data_store.add_data(run=run, workspace=ws, filename=filename)
+        if failed_files:
+            message = load_utils.exception_message_for_failed_files(failed_files)
+            raise ValueError(message)
+
+    # This is needed to work with thread model
+    def output(self):
+        pass
+
+    def cancel(self):
+        pass
+
+    def clear_loaded_data(self):
+        self._loaded_data_store.clear()
+
+    @property
+    def current_run(self):
+        return self._current_run
+
+    @current_run.setter
+    def current_run(self, run):
+        self._current_run = run
+
+    @property
+    def loaded_filenames(self):
+        return self._loaded_data_store.get_parameter("filename")
+
+    @property
+    def loaded_workspaces(self):
+        return self._loaded_data_store.get_parameter("workspace")
+
+    @property
+    def loaded_runs(self):
+        return self._loaded_data_store.get_parameter("run")
diff --git a/scripts/Muon/GUI/Common/load_run_widget/presenter.py b/scripts/Muon/GUI/Common/load_run_widget/presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..def6ed3060a531819f3712c2ccb3cf52f29cbf38
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_run_widget/presenter.py
@@ -0,0 +1,261 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+
+import copy
+
+from Muon.GUI.Common import thread_model
+import Muon.GUI.Common.utilities.run_string_utils as run_utils
+import Muon.GUI.Common.utilities.muon_file_utils as file_utils
+import Muon.GUI.Common.utilities.load_utils as load_utils
+
+
+class LoadRunWidgetPresenter(object):
+    def __init__(self, view, model):
+        self._view = view
+        self._model = model
+        self._load_thread = None
+
+        self._load_multiple_runs = False
+        self._use_threading = True
+        self._multiple_file_mode = "Co-add"
+
+        self._instrument = ""
+        self._view.set_current_instrument(self._instrument)
+
+        self._set_connections()
+
+    def _set_connections(self):
+        self._view.on_load_current_run_clicked(self.handle_load_current_run)
+        self._view.on_increment_run_clicked(self.handle_increment_run)
+        self._view.on_decrement_run_clicked(self.handle_decrement_run)
+        self._view.on_run_edit_changed(self.handle_run_changed_by_user)
+
+    def show(self):
+        self._view.show()
+
+    # used with threading
+    def create_load_thread(self):
+        return thread_model.ThreadModel(self._model)
+
+    # used with threading
+    def cancel(self):
+        if self._load_thread is not None:
+            self._load_thread.cancel()
+
+    def get_current_instrument(self):
+        return str(self._instrument)
+
+    def set_current_instrument(self, instrument):
+        self._instrument = instrument
+        self._view.set_current_instrument(instrument)
+
+    def disable_loading(self):
+        self._view.disable_load_buttons()
+
+    def enable_loading(self):
+        self._view.enable_load_buttons()
+
+    def clear_loaded_data(self):
+        self._view.clear()
+        self._model.clear_loaded_data()
+
+    def enable_multiple_files(self, enabled):
+        self._load_multiple_runs = enabled
+
+    @property
+    def workspaces(self):
+        return self._model.loaded_workspaces
+
+    @property
+    def filenames(self):
+        return self._model.loaded_filenames
+
+    @property
+    def runs(self):
+        return self._model.loaded_runs
+
+    # used by parent widget
+    def update_view_from_model(self, run_list):
+        self.set_run_edit_from_list(run_list)
+
+    def update_multiple_loading_behaviour(self, text):
+        self._multiple_file_mode = text
+
+    def set_run_edit_from_list(self, run_list):
+        new_list = []
+        for run_item in run_list:
+            if isinstance(run_item, int):
+                new_list += [run_item]
+            elif isinstance(run_item, list):
+                for run in run_item:
+                    new_list += [run]
+        run_string = run_utils.run_list_to_string(new_list)
+        self._view.set_run_edit_text(run_string)
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Loading from user input
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def handle_run_changed_by_user(self):
+        run_string = self._view.get_run_edit_text()
+        run_list = run_utils.run_string_to_list(run_string)
+        file_names = [file_utils.file_path_for_instrument_and_run(self.get_current_instrument(), new_run)
+                      for new_run in run_list]
+
+        if len(file_names) > 1 and not self._load_multiple_runs:
+            self._view.warning_popup("Multiple files selected in single file mode")
+            self._view.reset_run_edit_from_cache()
+            return
+
+        self.handle_loading(file_names, self._use_threading)
+
+    def handle_loading(self, filenames, threaded=True):
+        if threaded:
+            self.handle_load_thread_start(filenames, self.handle_load_thread_finished)
+        else:
+            self.handle_load_no_threading(filenames, self.on_loading_finished)
+
+    def handle_load_no_threading(self, filenames, finished_callback):
+        self.on_loading_start()
+        self._model.loadData(filenames)
+        try:
+            self._model.execute()
+        except ValueError as error:
+            self._view.warning_popup(error.args[0])
+        finished_callback()
+
+    def on_loading_start(self):
+        self._view.notify_loading_started()
+        self.disable_loading()
+
+    def handle_load_thread_start(self, filenames, finished_callback):
+        self.on_loading_start()
+
+        self._load_thread = self.create_load_thread()
+        self._load_thread.threadWrapperSetUp(self.disable_loading,
+                                             finished_callback,
+                                             self._view.warning_popup)
+        self._load_thread.loadData(filenames)
+        self._load_thread.start()
+
+    def handle_load_thread_finished(self):
+
+        self._load_thread.deleteLater()
+        self._load_thread = None
+
+        self.on_loading_finished()
+
+    def on_loading_finished(self):
+        # If in single file mode, remove the previous run
+        if not self._load_multiple_runs and len(self._model.loaded_runs) > 1:
+            self._model.remove_previous_data()
+
+        run_list = self._model.loaded_runs
+        self.set_run_edit_from_list(run_list)
+
+        if self._load_multiple_runs and self._multiple_file_mode == "Co-Add":
+            load_utils.combine_loaded_runs(self._model, run_list)
+
+        self._view.notify_loading_finished()
+        self.enable_loading()
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Loading from current run button
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def handle_load_current_run(self):
+
+        try:
+            current_run_file = file_utils.get_current_run_filename(self.get_current_instrument())
+        except ValueError as error:
+            self._view.warning_popup(error.args[0])
+            return
+
+        if current_run_file == "":
+            self._view.warning_popup("Cannot find directory for current instrument : " + self._instrument)
+            return
+
+        self.handle_loading_current_run([current_run_file], self._use_threading)
+
+    def handle_loading_current_run(self, filenames, threaded=True):
+        if threaded:
+            self.handle_load_thread_start(filenames, self.handle_load_thread_finished_current_run)
+        else:
+            self.handle_load_no_threading(filenames, self.on_loading_current_run_finished)
+
+    def handle_load_thread_finished_current_run(self):
+
+        self._load_thread.deleteLater()
+        self._load_thread = None
+
+        self.on_loading_current_run_finished()
+
+    def on_loading_current_run_finished(self):
+        # If in single file mode, remove the previous run
+        if not self._load_multiple_runs and len(self._model.loaded_runs) > 1:
+            self._model.remove_previous_data()
+
+        # if loaded successfully
+        if self._model.loaded_runs:
+            current_run = self._model.loaded_runs[0]
+            self._view.set_run_edit_without_validator(str(current_run) + " (CURRENT RUN)")
+            self._model.current_run = current_run
+        self._view.notify_loading_finished()
+        self.enable_loading()
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Loading from increment/decrement run buttons
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def handle_increment_run(self):
+        run_list = self.get_incremented_run_list()
+        if not run_list:
+            return
+        new_run = max(run_list)
+
+        if self._model.current_run and new_run > self._model.current_run:
+            self._view.warning_popup("Requested run exceeds the current run for this instrument")
+            return
+
+        file_name = file_utils.file_path_for_instrument_and_run(self.get_current_instrument(), new_run)
+        self.handle_loading([file_name], self._use_threading)
+
+    def handle_decrement_run(self):
+        run_list = self.get_decremented_run_list()
+        if not run_list:
+            return
+        new_run = min(run_list)
+
+        file_name = file_utils.file_path_for_instrument_and_run(self.get_current_instrument(), new_run)
+        self.handle_loading([file_name], self._use_threading)
+
+    def get_incremented_run_list(self):
+        """
+        Updates list of runs by adding a run equal to 1 after to the highest run.
+        """
+        run_list = load_utils.flatten_run_list(copy.copy(self.runs))
+        if run_list is None or len(run_list) == 0:
+            return []
+        if len(run_list) == 1:
+            run_list = [run_list[0], run_utils.increment_run(run_list[0])]
+        else:
+            run_list = run_utils.increment_run_list(run_list)
+        return run_list
+
+    def get_decremented_run_list(self):
+        """
+        Updates list of runs by adding a run equal to 1 before to the lowest run.
+        """
+        run_list = load_utils.flatten_run_list(copy.copy(self.runs))
+        if run_list is None or len(run_list) == 0:
+            return []
+        if len(run_list) == 1:
+            run_list = [run_utils.decrement_run(run_list[0]), run_list[0]]
+        else:
+            run_list = run_utils.decrement_run_list(run_list)
+        return run_list
diff --git a/scripts/Muon/GUI/Common/load_run_widget/view.py b/scripts/Muon/GUI/Common/load_run_widget/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..20ce20f6a2cd1cb634a4a38be1474c6cdba7e280
--- /dev/null
+++ b/scripts/Muon/GUI/Common/load_run_widget/view.py
@@ -0,0 +1,170 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+
+from PyQt4 import QtCore, QtGui
+from PyQt4.QtCore import pyqtSignal as Signal
+
+import Muon.GUI.Common.utilities.run_string_utils as run_utils
+from Muon.GUI.Common.message_box import warning
+
+
+class LoadRunWidgetView(QtGui.QWidget):
+    # signals for parent widgets
+    loadingStarted = Signal()
+    loadingFinished = Signal()
+    dataChanged = Signal()
+
+    def __init__(self, parent=None):
+        super(LoadRunWidgetView, self).__init__(parent)
+        self.load_current_run_button = None
+        self.increment_run_button = None
+        self.decrement_run_button = None
+        self.horizontal_layout = None
+        self.instrument_label = None
+        self.run_edit = None
+        self.spacer_item = None
+
+        self.setup_interface_layout()
+
+        self.set_run_edit_regex()
+
+        self._cached_text = ""
+
+    def setup_interface_layout(self):
+        self.setObjectName("LoadRunWidget")
+        self.resize(468, 45)
+
+        self.load_current_run_button = QtGui.QPushButton(self)
+        self.load_current_run_button.setText("Load Current Run")
+        self.load_current_run_button.setToolTip("Load the current run for the current instrument")
+        self.load_current_run_button.setObjectName("loadCurrentRunButton")
+
+        self.increment_run_button = QtGui.QToolButton(self)
+        self.increment_run_button.setText(">")
+        self.increment_run_button.setToolTip("Increment the run")
+        self.increment_run_button.setObjectName("incrementRunButton")
+
+        self.decrement_run_button = QtGui.QToolButton(self)
+        self.decrement_run_button.setText("<")
+        self.decrement_run_button.setToolTip("Decrement the run")
+        self.decrement_run_button.setObjectName("decrementRunButton")
+
+        self.instrument_label = QtGui.QLabel(self)
+        self.instrument_label.setText("Instrument")
+        self.instrument_label.setToolTip("")
+        self.instrument_label.setObjectName("instrumentLabel")
+
+        self.run_edit = QtGui.QLineEdit(self)
+        self.run_edit.setToolTip(
+            "Enter run number using " + run_utils.delimiter
+            + " and " + run_utils.range_separator + " as delimiter and range-separator respectively")
+        self.run_edit.setObjectName("runEdit")
+
+        self.horizontal_layout = QtGui.QHBoxLayout(self)
+        self.horizontal_layout.setObjectName("horizontalLayout")
+        self.horizontal_layout.addWidget(self.load_current_run_button)
+        self.horizontal_layout.addWidget(self.decrement_run_button)
+        self.horizontal_layout.addWidget(self.instrument_label)
+        self.horizontal_layout.addWidget(self.run_edit)
+        self.horizontal_layout.addWidget(self.increment_run_button)
+
+        self.horizontal_layout.setContentsMargins(0, 0, 0, 0)
+        self.horizontal_layout.setMargin(0)
+
+    def getLayout(self):
+        return self.horizontalLayout
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Enabling / disabling the interface
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def disable_loading(self):
+        self.disable_load_buttons()
+        self.loadingStarted.emit()
+
+    def enable_loading(self):
+        self.enable_load_buttons()
+        self.loadingFinished.emit()
+        self.dataChanged.emit()
+
+    def notify_loading_started(self):
+        self.loadingStarted.emit()
+
+    def notify_loading_finished(self):
+        self.loadingFinished.emit()
+        self.dataChanged.emit()
+
+    def disable_load_buttons(self):
+        self.load_current_run_button.setEnabled(False)
+        self.run_edit.setEnabled(False)
+        self.increment_run_button.setEnabled(False)
+        self.decrement_run_button.setEnabled(False)
+
+    def enable_load_buttons(self):
+        self.load_current_run_button.setEnabled(True)
+        self.run_edit.setEnabled(True)
+        self.increment_run_button.setEnabled(True)
+        self.decrement_run_button.setEnabled(True)
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Instrument / run-edit
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def get_instrument_label(self):
+        return str(self.instrument_label.text())
+
+    def set_instrument_label(self, text):
+        self.instrument_label.setText(text)
+
+    def set_current_instrument(self, instrument):
+        self.instrument_label.setText(instrument)
+
+    def set_run_edit_regex(self):
+        # The regular expression string here is "^[0-9]*([0-9]+[,-]{0,1})*[0-9]+$"
+        regex = QtCore.QRegExp(run_utils.run_string_regex)
+        validator = QtGui.QRegExpValidator(regex)
+        self.run_edit.setValidator(validator)
+
+    def set_run_edit_text(self, text):
+        self.run_edit.setText(text)
+        self._cached_text = self.get_run_edit_text()
+
+    def set_run_edit_without_validator(self, text):
+        self.run_edit.setValidator(None)
+        self.run_edit.setText(text)
+        self.set_run_edit_regex()
+
+    def reset_run_edit_from_cache(self):
+        tmp = self._cached_text
+        self.set_run_edit_text(tmp)
+        self._cached_text = tmp
+
+    def get_run_edit_text(self):
+        return str(self.run_edit.text())
+
+    def warning_popup(self, message):
+        warning(message, parent=self)
+
+    def clear(self):
+        self.set_run_edit_text("")
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Signal/slot connections called by presenter
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def on_decrement_run_clicked(self, slot):
+        self.decrement_run_button.clicked.connect(slot)
+
+    def on_increment_run_clicked(self, slot):
+        self.increment_run_button.clicked.connect(slot)
+
+    def on_load_current_run_clicked(self, slot):
+        self.load_current_run_button.clicked.connect(slot)
+
+    def on_run_edit_changed(self, slot):
+        self.run_edit.returnPressed.connect(slot)
diff --git a/scripts/Muon/GUI/Common/muon_context.py b/scripts/Muon/GUI/Common/muon_context.py
new file mode 100644
index 0000000000000000000000000000000000000000..476e1cacd7026ca1ef6754a4cec01e522a64b932
--- /dev/null
+++ b/scripts/Muon/GUI/Common/muon_context.py
@@ -0,0 +1,14 @@
+from Muon.Gui.Common.muon_data_context import MuonDataContext
+
+
+class MuonContext(object):
+    def __init__(self):
+        self._data_context = MuonDataContext()
+
+    @property
+    def data_context(self):
+        return self._data_context
+
+    @data_context.setter
+    def data_context(self, value):
+        self._data_context = value
diff --git a/scripts/Muon/GUI/Common/muon_data_context.py b/scripts/Muon/GUI/Common/muon_data_context.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e84d777f34a8313d02878cfc8ae5f60a72ba743
--- /dev/null
+++ b/scripts/Muon/GUI/Common/muon_data_context.py
@@ -0,0 +1,296 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from __future__ import (absolute_import, division, print_function)
+
+import Muon.GUI.Common.load_utils as load_utils
+
+from Muon.GUI.Common.muon_group import MuonGroup
+from Muon.GUI.Common.muon_pair import MuonPair
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+from Muon.GUI.Common.muon_file_utils import format_run_for_file
+from Muon.GUI.Common.run_string_utils import run_list_to_string
+from Muon.Gui.Common.ADSHandler.workspace_naming import (get_raw_data_workspace_name, get_group_data_workspace_name,
+                                                         get_pair_data_workspace_name, get_base_data_directory,
+                                                         get_raw_data_directory, get_group_data_directory,
+                                                         get_pair_data_directory)
+
+from Muon.Gui.Common.calculate_pair_and_group import calculate_group_data, calculate_pair_data
+
+from collections import OrderedDict
+
+from mantid.kernel import ConfigServiceImpl, ConfigService
+
+
+def get_default_grouping(instrument, main_field_direction):
+    parameter_name = "Default grouping file"
+    if instrument == "MUSR":
+        parameter_name += " - " + main_field_direction
+    try:
+        grouping_file = ConfigService.getInstrument(instrument).getStringParameter(parameter_name)[0]
+    except IndexError:
+        return [], []
+    instrument_directory = ConfigServiceImpl.Instance().getInstrumentDirectory()
+    filename = instrument_directory + grouping_file
+    new_groups, new_pairs = load_utils.load_grouping_from_XML(filename)
+    return new_groups, new_pairs
+
+
+def construct_empty_group(group_names, group_index=0):
+    """
+    Create an empty MuonGroup appropriate for adding to the current grouping table.
+    """
+    new_group_name = "group_" + str(group_index)
+    while new_group_name in group_names:
+        # modify the name until it is unique
+        group_index += 1
+        new_group_name = "group_" + str(group_index)
+    return MuonGroup(group_name=new_group_name, detector_ids=[1])
+
+
+def construct_empty_pair(group_names, pair_names, pair_index=0):
+    """
+    Create an empty MuonPair appropriate for adding to the current pairing table.
+    """
+    new_pair_name = "pair_" + str(pair_index)
+    while new_pair_name in pair_names:
+        # modify the name until it is unique
+        pair_index += 1
+        new_pair_name = "pair_" + str(pair_index)
+    if len(group_names) == 1:
+        group1 = group_names[0]
+        group2 = group_names[0]
+    elif len(group_names) >= 2:
+        group1 = group_names[0]
+        group2 = group_names[1]
+    else:
+        group1 = None
+        group2 = None
+    return MuonPair(pair_name=new_pair_name,
+                    forward_group_name=group1, backward_group_name=group2, alpha=1.0)
+
+
+class MuonDataContext(object):
+    """
+    The MuonContext is the core class for the MuonAnalysis 2 interface. It stores all the data and parameters used
+    in the interface and serves as the model part of the MVP design pattern for every widget in the interface.
+    By sharing a common instance of this class, the interface remains synchronized by use of the observer pattern to
+    notify subcribers of changes, whi will then respond by updating their view from this commonly shared model.
+
+    The actual processing of data occurs via this class (as it should as the model).
+    """
+
+    # ADS base directory for all workspaces
+    base_directory = "Muon Data"
+
+    def __init__(self, load_data=MuonLoadData()):
+        """
+        Currently, only a single run is loaded into the Home/Grouping tab at once. This is held in the _current_data
+        member. The load widget may load multiple runs at once, these are stored in the _loaded_data member.
+        Groups and Pairs associated to the current run are stored in _grousp and _pairs as ordered dictionaries.
+        """
+        self._groups = OrderedDict()
+        self._pairs = OrderedDict()
+
+        self._loaded_data = load_data
+        self._current_data = {"workspace": load_utils.empty_loaded_data()}  # self.get_result(False)
+
+    def is_data_loaded(self):
+        return self._loaded_data.num_items() > 0
+
+    def is_multi_period(self):
+        return isinstance(self.current_data["OutputWorkspace"], list)
+
+    @property
+    def current_data(self):
+        return self._current_data["workspace"]
+
+    @property
+    def instrument(self):
+        inst = ConfigService.getInstrument()
+        return inst
+
+    @property
+    def current_run(self):
+        return self._current_data["run"]
+
+    @property
+    def run(self):
+        try:
+            # refer to the output of the loading widget (e.g. for co-adding)
+            runs = run_list_to_string(self.current_run)
+        except Exception:
+            # extract from sample logs
+            run_log = self.get_sample_log("run_number")
+            if run_log:
+                runs = run_log.value
+            else:
+                runs = 0
+        return runs
+
+    @property
+    def group_names(self):
+        return self._groups.keys()
+
+    @property
+    def pair_names(self):
+        return self._pairs.keys()
+
+    @property
+    def groups(self):
+        return self._groups
+
+    @property
+    def pairs(self):
+        return self._pairs
+
+    def add_group(self, group):
+        assert isinstance(group, MuonGroup)
+        self._groups[group.name] = group
+
+    def add_pair(self, pair):
+        assert isinstance(pair, MuonPair)
+        self._pairs[pair.name] = pair
+
+    def update_current_data(self):
+        # Update the current data; resetting the groups and pairs to their default values
+        if self._loaded_data.num_items() > 0:
+            self._current_data = self._loaded_data.get_latest_data()
+            self.set_groups_and_pairs_to_default()
+        else:
+            self._current_data = {"workspace": load_utils.empty_loaded_data()}
+
+    @property
+    def loaded_data(self):
+        return self._current_data["workspace"]
+
+    @property
+    def loaded_workspace(self):
+        if self.is_multi_period():
+            # return the first workspace in the group
+            return self.current_data["OutputWorkspace"][0].workspace
+        else:
+            return self.current_data["OutputWorkspace"].workspace
+
+    @property
+    def period_string(self):
+        # Get the period string i.e. "1+2-3+4" to be used in workspace naming.
+        return "1"
+
+    @property
+    def num_detectors(self):
+        try:
+            n_det = self.loaded_workspace.detectorInfo().size()
+        except AttributeError:
+            # default to 1
+            n_det = 1
+        return n_det
+
+    @property
+    def main_field_direction(self):
+        return self.current_data["MainFieldDirection"]
+
+    @property
+    def dead_time_table(self):
+        return self.loaded_data["DeadTimeTable"]
+
+    def get_sample_logs(self):
+        logs = None
+        try:
+            logs = self.loaded_workspace.getSampleDetails()
+        except Exception:
+            print("Cannot find sample logs")
+        return logs
+
+    def get_sample_log(self, log_name):
+        logs = self.get_sample_logs()
+        try:
+            log = logs.getLogData(log_name)
+        except Exception:
+            log = None
+        return log
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Clearing data
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def clear_groups(self):
+        self._groups = OrderedDict()
+
+    def clear_pairs(self):
+        self._pairs = OrderedDict()
+
+    def clear(self):
+        self.clear_groups()
+        self.clear_pairs()
+        self._current_data = {"workspace": load_utils.empty_loaded_data()}
+
+    def _base_run_name(self):
+        """ e.g. EMU0001234 """
+        if isinstance(self.run, int):
+            return str(self.instrument) + format_run_for_file(self.run)
+        else:
+            return str(self.instrument) + self.run
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # Showing workspaces in the ADS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def show_raw_data(self):
+        workspace = self.current_data["OutputWorkspace"]
+        directory = get_base_data_directory(self) + get_raw_data_directory(self)
+
+        if isinstance(workspace, list):
+            # Multi-period data
+            for i, single_ws in enumerate(workspace):
+                name = directory + get_raw_data_workspace_name(self) + "_period_" + str(i)
+                single_ws.show(name)
+        else:
+            # Single period data
+            name = directory + get_raw_data_workspace_name(self)
+            workspace.show(name)
+
+    def show_all_groups(self):
+        for group_name in self._groups.keys():
+            self.show_group_data(group_name)
+
+    def show_group_data(self, group_name, show=True):
+        name = get_group_data_workspace_name(self, group_name)
+        directory = get_base_data_directory(self) + get_group_data_directory(self)
+        workspace = calculate_group_data(self, group_name)
+
+        self._groups[group_name].workspace = load_utils.MuonWorkspace(workspace)
+        if show:
+            self._groups[group_name].workspace.show(directory + name)
+
+    def show_all_pairs(self):
+        for pair_name in self._pairs.keys():
+            self.show_pair_data(pair_name)
+
+    def show_pair_data(self, pair_name, show=True):
+        name = get_pair_data_workspace_name(self, pair_name)
+        directory = get_base_data_directory(self) + get_pair_data_directory(self)
+        workspace = calculate_pair_data(self, pair_name)
+
+        self._pairs[pair_name].workspace = load_utils.MuonWorkspace(workspace)
+        if show:
+            self._pairs[pair_name].workspace.show(directory + name)
+
+    def calculate_all_groups(self):
+        for group_name in self._groups.keys():
+            calculate_group_data(group_name)
+
+    def set_groups_and_pairs_to_default(self):
+        groups, pairs = get_default_grouping(self.instrument, self.main_field_direction)
+
+        self.clear_groups()
+        for group in groups:
+            self.add_group(group)
+
+        self.clear_pairs()
+        for pair in pairs:
+            self.add_pair(pair)
diff --git a/scripts/Muon/GUI/Common/muon_group.py b/scripts/Muon/GUI/Common/muon_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..f641b297821ce43988ba86ca98fe955d0510c197
--- /dev/null
+++ b/scripts/Muon/GUI/Common/muon_group.py
@@ -0,0 +1,71 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+# pylint: disable=C0111
+from __future__ import (absolute_import, division, print_function)
+
+from Muon.GUI.Common.ADSHandler.muon_workspace_wrapper import MuonWorkspaceWrapper
+import six
+
+
+class MuonGroup(object):
+    """
+    Simple structure to store information on a detector group.
+
+    - The name is set at initialization and after that cannot be changed.
+    - The detector list can be modified by passing a list of ints (type checks for this).
+    - The number of detectors is stored.
+    - The workspace associated to the group can be set, but must be of type MuonWorkspaceWrapper.
+    """
+
+    def __init__(self, group_name, detector_ids=[]):
+
+        self._group_name = group_name
+        self._detector_ids = None
+        self.detectors = detector_ids
+        self._workspace = None
+
+    @property
+    def workspace(self):
+        return self._workspace
+
+    @workspace.setter
+    def workspace(self, new_workspace):
+        if isinstance(new_workspace, MuonWorkspaceWrapper):
+            self._workspace = new_workspace
+        else:
+            raise AttributeError("Attempting to set workspace to type " + str(type(new_workspace)) +
+                                 " but should be MuonWorkspaceWrapper")
+
+    @property
+    def name(self):
+        return self._group_name
+
+    @name.setter
+    def name(self, name):
+        raise AttributeError("Attempting to change name from {} to {}. "
+                             "Cannot change name of MuonGroup "
+                             "object".format(self._group_name, name))
+
+    @property
+    def detectors(self):
+        return self._detector_ids
+
+    @property
+    def n_detectors(self):
+        return len(self.detectors)
+
+    @detectors.setter
+    def detectors(self, detector_ids):
+        if isinstance(detector_ids, six.string_types):
+            raise AttributeError("MuonGroup : detectors must be a list of ints.")
+        elif isinstance(detector_ids, list):
+            if sum([not isinstance(item, int) for item in detector_ids]) == 0:
+                self._detector_ids = list(set(sorted(detector_ids)))
+            else:
+                raise AttributeError("MuonGroup : detectors must be a list of ints.")
+        else:
+            raise ValueError("detectors must be a list of ints.")
diff --git a/scripts/Muon/GUI/Common/muon_load_data.py b/scripts/Muon/GUI/Common/muon_load_data.py
index aabae61dda5f4abd8211d6fcdc9c9550d49a6591..53b6f8a2d2ba0c0d3e7f069966db61e708a5e370 100644
--- a/scripts/Muon/GUI/Common/muon_load_data.py
+++ b/scripts/Muon/GUI/Common/muon_load_data.py
@@ -35,20 +35,18 @@ class MuonLoadData:
         can then be used as a keyword into any of the methods of the class. Use singular
         nouns.
         """
-        self.params = {"run": [], "workspace": [], "filename": []}
+        self.params = []
         self.defaults = {"run": 0, "workspace": [], "filename": ""}
-        if self.params.keys() != self.defaults.keys():
-            raise AttributeError("params and defaults dictionaries do not have the same keys.")
 
     def __iter__(self):
         self._n = -1
-        self._max = len(self.params["run"])
+        self._max = len(self.params)
         return self
 
     def __next__(self):
         if self._n < self._max - 1:
             self._n += 1
-            return {key: val[self._n] for key, val in self.params.items()}
+            return self.params[self._n]
         else:
             raise StopIteration
 
@@ -59,33 +57,32 @@ class MuonLoadData:
 
     def num_items(self):
         """Total number of entries"""
-        return len(next(iter(self.params.values())))
+        return len(self.params)
 
     def get_parameter(self, param_name):
         """Get list of entries for a given parameter"""
-        return self.params.get(param_name, None)
+        return [x.get(param_name) for x in self.params]
 
     # Adding/removing data
 
     def add_data(self, **kwargs):
-        for key, value_list in self.params.items():
-            # if keyword not supplied, use default defined in __init__
-            value_list += [kwargs.get(key, self.defaults[key])]
+        new_entry = {}
+        for key, value in self.defaults.items():
+            new_entry[key] = kwargs.get(key, self.defaults[key])
+        self.params.append(new_entry)
 
     def remove_data(self, **kwargs):
         indices = [i for i, j in enumerate(self._matches(**kwargs)) if not j]
-        for key, vals in self.params.items():
-            self.params[key] = [vals[i] for i in indices]
+        self.params = [self.params[i] for i in indices]
 
     def clear(self):
-        self.params = {key: [] for key, _ in self.params.items()}
+        self.params = []
 
     def remove_nth_last_entry(self, n):
         """Remove the nth last entry given to the instance by add_data, n=1 refers to the most
         recently added."""
         keep_indices = [i for i in range(self.num_items()) if i != self.num_items() - n]
-        for key, vals in self.params.items():
-            self.params[key] = [vals[i] for i in keep_indices]
+        self.params = [self.params[i] for i in keep_indices]
 
     def remove_current_data(self):
         """Remove the most recently added data item"""
@@ -98,14 +95,16 @@ class MuonLoadData:
     # Searching
 
     def _matches(self, **kwargs):
-        checks = [kwargs.get(key, None) for key in self.params.keys()]
-        data_values_zip = zip(*self.params.values())
+        matches = []
 
-        return [True if
-                sum([data_value == search_value for (data_value, search_value) in zip(list(data_values), checks)]) > 0
-                else False
-                for data_values in
-                data_values_zip]
+        for entries in self.params:
+            matching_parameters = [entries.get(key) == kwargs.get(key) for key in entries]
+            if sum(matching_parameters) > 0:
+                matches.append(True)
+            else:
+                matches.append(False)
+
+        return matches
 
     def contains_n(self, **kwargs):
         """Counts the number of matching entries where at least one of kwargs matches"""
@@ -123,11 +122,11 @@ class MuonLoadData:
         if self.contains_n(**kwargs) == 1:
             indices = [i for i, val in enumerate(self._matches(**kwargs)) if val is True]
             index = indices[0]
-            return {key: val[index] for key, val in self.params.items()}
+            return self.params[index]
 
     def get_latest_data(self):
         if self.num_items() > 0:
-            return {key: val[-1] for key, val in self.params.items()}
+            return self.params[-1]
         else:
             ret = {key: None for key in self.params.keys()}
             ret["workspace"] = load_utils.empty_loaded_data()
diff --git a/scripts/Muon/GUI/Common/muon_pair.py b/scripts/Muon/GUI/Common/muon_pair.py
new file mode 100644
index 0000000000000000000000000000000000000000..adc36515153a9080123491601ff36ba6e572d734
--- /dev/null
+++ b/scripts/Muon/GUI/Common/muon_pair.py
@@ -0,0 +1,75 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+# pylint: disable=C0111
+from __future__ import (absolute_import, division, print_function)
+
+from Muon.GUI.Common.ADSHandler.muon_workspace_wrapper import MuonWorkspaceWrapper
+
+
+class MuonPair(object):
+    """
+    Simple structure to store information on a detector group pair.
+
+    - The name is set at initialization and after that cannot be changed.
+    - The pair has two groups associated to it, and we store only their names.
+    - The balance parameter is stored and modifiable.
+    - The workspace associated to the pair can be set, but must be of type MuonWorkspaceWrapper.
+    """
+
+    def __init__(self, pair_name,
+                 forward_group_name="",
+                 backward_group_name="",
+                 alpha=1.0):
+
+        self._pair_name = pair_name
+        self._forward_group_name = forward_group_name
+        self._backward_group_name = backward_group_name
+        self._alpha = float(alpha)
+        self._workspace = None
+
+    @property
+    def workspace(self):
+        return self._workspace
+
+    @workspace.setter
+    def workspace(self, new_workspace):
+        if isinstance(new_workspace, MuonWorkspaceWrapper):
+            self._workspace = new_workspace
+        else:
+            raise AttributeError("Attempting to set workspace to type " + str(type(new_workspace)) +
+                                 " but should be MuonWorkspaceWrapper")
+
+    @property
+    def name(self):
+        return self._pair_name
+
+    @property
+    def forward_group(self):
+        return self._forward_group_name
+
+    @property
+    def backward_group(self):
+        return self._backward_group_name
+
+    @forward_group.setter
+    def forward_group(self, new_name):
+        self._forward_group_name = new_name
+
+    @backward_group.setter
+    def backward_group(self, new_name):
+        self._backward_group_name = new_name
+
+    @property
+    def alpha(self):
+        return float("{}".format(self._alpha))
+
+    @alpha.setter
+    def alpha(self, new_alpha):
+        if float(new_alpha) >= 0.0:
+            self._alpha = float(new_alpha)
+        else:
+            raise AttributeError("Alpha must be > 0.0.")
diff --git a/scripts/Muon/GUI/Common/utilities/load_utils.py b/scripts/Muon/GUI/Common/utilities/load_utils.py
index fd58fbd2ce14ca417123fb2ef11ff9f572ad4ae9..38bbf077d2a06f7fa97a99cfab9462ddd1059011 100644
--- a/scripts/Muon/GUI/Common/utilities/load_utils.py
+++ b/scripts/Muon/GUI/Common/utilities/load_utils.py
@@ -15,6 +15,7 @@ from mantid import api
 from mantid.kernel import ConfigServiceImpl
 import Muon.GUI.Common.utilities.muon_file_utils as file_utils
 from Muon.GUI.Common.ADSHandler.muon_workspace_wrapper import MuonWorkspaceWrapper
+import Muon.GUI.Common.utilities.algorithm_utils as algorithm_utils
 
 
 class LoadUtils(object):
@@ -252,3 +253,40 @@ def get_table_workspace_names_from_ADS():
     names = api.AnalysisDataService.Instance().getObjectNames()
     table_names = [name for name in names if isinstance(mtd[name], ITableWorkspace)]
     return table_names
+
+
+def combine_loaded_runs(model, run_list):
+    return_ws = model._loaded_data_store.get_data(run=run_list[0])["workspace"]
+    running_total = return_ws["OutputWorkspace"].workspace
+
+    for run in run_list[1:]:
+        ws = model._loaded_data_store.get_data(run=run)["workspace"]["OutputWorkspace"].workspace
+        running_total = algorithm_utils.run_Plus({
+            "LHSWorkspace": running_total,
+            "RHSWorkspace": ws,
+            "AllowDifferentNumberSpectra": False}
+        )
+        # remove the single loaded filename
+        model._loaded_data_store.remove_data(run=run)
+    model._loaded_data_store.remove_data(run=run_list[0])
+    return_ws["OutputWorkspace"] = MuonWorkspaceWrapper(running_total)
+    model._loaded_data_store.add_data(run=flatten_run_list(run_list), workspace=return_ws,
+                                      filename="Co-added")
+
+
+def flatten_run_list(run_list):
+    """
+    run list might be [1,2,[3,4]] where the [3,4] are co-added
+    """
+    new_list = []
+    for run_item in run_list:
+        if isinstance(run_item, int):
+            new_list += [run_item]
+        elif isinstance(run_item, list):
+            for run in run_item:
+                new_list += [run]
+    return new_list
+
+
+def exception_message_for_failed_files(failed_file_list):
+    return "Could not load the following files : \n - " + "\n - ".join(failed_file_list)
diff --git a/scripts/Muon/GUI/Common/utilities/muon_test_helpers.py b/scripts/Muon/GUI/Common/utilities/muon_test_helpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..add0fef8b769203e3bbbb0d35e9cd89233b6b643
--- /dev/null
+++ b/scripts/Muon/GUI/Common/utilities/muon_test_helpers.py
@@ -0,0 +1,27 @@
+class IteratorWithException:
+    """Wraps a simple iterable (i.e. list) so that it throws a ValueError on a particular index."""
+
+    def __init__(self, iterable, throw_on_index):
+        self.max = len(iterable)
+        self.iterable = iter(iterable)
+
+        self.throw_indices = [index for index in throw_on_index if index < self.max]
+
+    def __iter__(self):
+        self.n = 0
+        return self
+
+    def __next__(self):
+
+        if self.n in self.throw_indices:
+            next(self.iterable)
+            self.n += 1
+            raise ValueError()
+        elif self.n == self.max:
+            raise StopIteration()
+        else:
+            self.n += 1
+            return next(self.iterable)
+
+    # python 3 compatibility
+    next = __next__
diff --git a/scripts/Muon/GUI/Common/utilities/run_string_utils.py b/scripts/Muon/GUI/Common/utilities/run_string_utils.py
index 5286b9f0ef4c2042c7215ee64874f9fa24c5bb95..5840c097ac3e97c8dd081c552069a63328a4a700 100644
--- a/scripts/Muon/GUI/Common/utilities/run_string_utils.py
+++ b/scripts/Muon/GUI/Common/utilities/run_string_utils.py
@@ -13,7 +13,7 @@ import re
 
 delimiter = ","
 range_separator = "-"
-run_string_regex = "^[0-9]*([0-9]+[,-]{0,1})*[0-9]+$"
+run_string_regex = "^[0-9]*([0-9]+\s*[,-]{0,1}\s*)*[0-9]+$"
 max_run_list_size = 100
 valid_float_regex = "^[0-9]+([.][0-9]*)?$"
 valid_name_regex = "^\w+$"
diff --git a/scripts/SANS/sans/algorithm_detail/batch_execution.py b/scripts/SANS/sans/algorithm_detail/batch_execution.py
index 6a5fd12eda8b9fa3bd11d4a3dd5ad6e4f50691a4..939b19448d023f573169fbbcff40b1cf9a74c93a 100644
--- a/scripts/SANS/sans/algorithm_detail/batch_execution.py
+++ b/scripts/SANS/sans/algorithm_detail/batch_execution.py
@@ -978,7 +978,7 @@ def save_to_file(reduction_packages, save_can):
     save_info = state.save
     file_formats = save_info.file_format
     for name_to_save in workspaces_names_to_save:
-        save_workspace_to_file(name_to_save, file_formats)
+        save_workspace_to_file(name_to_save, file_formats, name_to_save)
 
 
 def delete_reduced_workspaces(reduction_packages):
@@ -1113,16 +1113,16 @@ def get_all_names_to_save(reduction_packages, save_can):
     return set(names_to_save)
 
 
-def save_workspace_to_file(output_name, file_formats):
+def save_workspace_to_file(workspace_name, file_formats, file_name):
     """
     Saves the workspace to the different file formats specified in the state object.
 
-    :param output_name: the name of the output workspace and also the name of the file
+    :param workspace_name: the name of the output workspace and also the name of the file
     :param file_formats: a list of file formats to save
     """
     save_name = "SANSSave"
-    save_options = {"InputWorkspace": output_name}
-    save_options.update({"Filename": output_name})
+    save_options = {"InputWorkspace": workspace_name}
+    save_options.update({"Filename": file_name})
 
     if SaveType.Nexus in file_formats:
         save_options.update({"Nexus": True})
diff --git a/scripts/SANS/sans/gui_logic/gui_common.py b/scripts/SANS/sans/gui_logic/gui_common.py
index 7bbaa0b6ad0e0eb5ee601823051e94cdf16aa60d..51bd235c7e8a15c8701ff3052ad31dd8c4af088b 100644
--- a/scripts/SANS/sans/gui_logic/gui_common.py
+++ b/scripts/SANS/sans/gui_logic/gui_common.py
@@ -214,3 +214,23 @@ def open_file_dialog(line_edit, filter_text, directory):
     if isinstance(file_name, tuple):
         file_name = file_name[0]
     line_edit.setText(file_name)
+
+
+def get_batch_file_dir_from_path(batch_file_path):
+    path, file = os.path.split(batch_file_path)
+    if path != "" and path[-1] != "/":
+        # Make string inline with other ConfigService paths
+        path += "/"
+    return path
+
+
+def add_dir_to_datasearch(batch_file_path, current_directories):
+    batch_file_directory = get_batch_file_dir_from_path(batch_file_path)
+    if batch_file_directory != "" and batch_file_directory not in current_directories:
+        current_directories = ";".join([current_directories, batch_file_directory])
+    return batch_file_directory, current_directories
+
+
+def remove_dir_from_datasearch(batch_file_path, directories):
+    new_dirs = ";".join([path for path in directories.split(";") if path != batch_file_path])
+    return new_dirs
diff --git a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py
index cd59b0807c1385be4cd7a17a81f12abf74930ca2..d6740ea3f5a72412f2887777b1575c5c282ea813 100644
--- a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py
+++ b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py
@@ -26,7 +26,8 @@ from sans.gui_logic.presenter.settings_diagnostic_presenter import (SettingsDiag
 from sans.gui_logic.presenter.masking_table_presenter import (MaskingTablePresenter)
 from sans.gui_logic.presenter.beam_centre_presenter import BeamCentrePresenter
 from sans.gui_logic.presenter.add_runs_presenter import OutputDirectoryObserver as SaveDirectoryObserver
-from sans.gui_logic.gui_common import (get_reduction_mode_strings_for_gui, get_string_for_gui_from_instrument)
+from sans.gui_logic.gui_common import (get_reduction_mode_strings_for_gui, get_string_for_gui_from_instrument,
+                                       add_dir_to_datasearch, remove_dir_from_datasearch)
 from sans.common.enums import (BatchReductionEntry, RangeStepType, SampleShape, FitType, RowState, SANSInstrument)
 from sans.user_file.user_file_reader import UserFileReader
 from sans.command_interface.batch_csv_file_parser import BatchCsvParser
@@ -37,6 +38,8 @@ from sans.gui_logic.models.diagnostics_page_model import run_integral, create_st
 from sans.sans_batch import SANSCentreFinder
 from sans.gui_logic.models.create_state import create_states
 from ui.sans_isis.work_handler import WorkHandler
+from ui.sans_isis import SANSSaveOtherWindow
+from sans.gui_logic.presenter.save_other_presenter import SaveOtherPresenter
 
 try:
     import mantidplot
@@ -124,6 +127,9 @@ class RunTabPresenter(object):
         def on_cut_rows(self):
             self._presenter.on_cut_rows_requested()
 
+        def on_save_other(self):
+            self._presenter.on_save_other()
+
         def on_sample_geometry_selection(self, show_geometry):
             self._presenter.on_sample_geometry_view_changed(show_geometry)
 
@@ -326,6 +332,10 @@ class RunTabPresenter(object):
             if not batch_file_path:
                 return
 
+            datasearch_dirs = ConfigService["datasearch.directories"]
+            batch_file_directory, datasearch_dirs = add_dir_to_datasearch(batch_file_path, datasearch_dirs)
+            ConfigService["datasearch.directories"] = datasearch_dirs
+
             if not os.path.exists(batch_file_path):
                 raise RuntimeError(
                     "The batch file path {} does not exist. Make sure a valid batch file path"
@@ -343,6 +353,10 @@ class RunTabPresenter(object):
                 self._add_row_to_table_model(row, index)
             self._table_model.remove_table_entries([len(parsed_rows)])
         except RuntimeError as e:
+            if batch_file_directory:
+                # Remove added directory from datasearch.directories
+                ConfigService["datasearch.directories"] = remove_dir_from_datasearch(batch_file_directory, datasearch_dirs)
+
             self.sans_logger.error("Loading of the batch file failed. {}".format(str(e)))
             self.display_warning_box('Warning', 'Loading of the batch file failed', str(e))
 
@@ -676,6 +690,12 @@ class RunTabPresenter(object):
         """
         return self._table_model.is_empty_row(row)
 
+    def on_save_other(self):
+        self.save_other_presenter = SaveOtherPresenter(parent_presenter=self)
+        save_other_view = SANSSaveOtherWindow.SANSSaveOtherDialog(self._view)
+        self.save_other_presenter.set_view(save_other_view)
+        self.save_other_presenter.show()
+
     # def _validate_rows(self):
     #     """
     #     Validation of the rows. A minimal setup requires that ScatterSample is set.
diff --git a/scripts/SANS/sans/gui_logic/presenter/save_other_presenter.py b/scripts/SANS/sans/gui_logic/presenter/save_other_presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a2d353d67fadceccae4e54965132d0c426c8771
--- /dev/null
+++ b/scripts/SANS/sans/gui_logic/presenter/save_other_presenter.py
@@ -0,0 +1,82 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from mantid import ConfigService
+from mantid import AnalysisDataService
+from sans.algorithm_detail.batch_execution import save_workspace_to_file
+import os
+from mantid.api import WorkspaceGroup
+
+
+class SaveOtherPresenter():
+    def __init__(self, parent_presenter=None):
+        self._parent_presenter = parent_presenter
+        self._view = None
+        self.current_directory = ConfigService['defaultsave.directory']
+        self.filename = ''
+        self.workspace_list = AnalysisDataService.getObjectNames()
+
+    def set_view(self, view=None):
+        if view:
+            self._view = view
+            self._view.subscribe(self)
+            self._view.current_directory = self.current_directory
+
+    def on_file_name_changed(self, file_name):
+        self.filename = file_name
+
+    def on_browse_clicked(self):
+        self.current_directory = self._view.launch_file_browser(self.current_directory)
+        self._view.current_directory = self.current_directory
+
+    def on_save_clicked(self):
+        file_formats = self._view.get_save_options()
+        if not file_formats:
+            return
+        selected_workspaces = self.get_workspaces()
+        selected_filenames = self.get_filenames(selected_workspaces, self.filename)
+
+        self._view.progress_bar_minimum = 0
+        self._view.progress_bar_maximum = len(selected_workspaces)
+        self._view.progress_bar_value = 0
+        for name_to_save, filename in zip(selected_workspaces, selected_filenames):
+            save_workspace_to_file(name_to_save, file_formats, filename)
+            self._view.increment_progress()
+
+    def on_item_selection_changed(self):
+        self.selected_workspaces = self._view.get_selected_workspaces()
+        self._view.progress_bar_value = 0
+
+        if len(self.selected_workspaces) > 1:
+            self._view.rename_filebox('Suffix')
+        else:
+            self._view.rename_filebox('Filename')
+
+    def on_directory_changed(self, directory):
+        self.current_directory = directory
+
+    def on_cancel_clicked(self):
+        self._view.done(0)
+
+    def show(self):
+        self._view.show()
+
+    def get_filenames(self, selected_workspaces, filename):
+        if filename and len(selected_workspaces) == 1:
+            return [os.path.join(self.current_directory, filename)]
+        elif filename:
+            return [os.path.join(self.current_directory, x + '_' + filename) for x in selected_workspaces]
+        else:
+            return [os.path.join(self.current_directory, x) for x in selected_workspaces]
+
+    def get_workspaces(self):
+        simple_list = self._view.get_selected_workspaces()
+        for workspace_name in simple_list:
+            workspace = AnalysisDataService.retrieve(workspace_name)
+            if issubclass(type(workspace),WorkspaceGroup):
+                simple_list.remove(workspace_name)
+                simple_list += list(workspace.getNames())
+        return list(set(simple_list))
diff --git a/scripts/test/ErrorReportPresenterTest.py b/scripts/test/ErrorReportPresenterTest.py
index 3f1a89e1e8ccc1638b4752f21304c9f13cb0fd4d..66d4413a5681faf37bf463858c03d80d40d70b8f 100644
--- a/scripts/test/ErrorReportPresenterTest.py
+++ b/scripts/test/ErrorReportPresenterTest.py
@@ -26,10 +26,6 @@ class ErrorReportPresenterTest(unittest.TestCase):
         self.zip_recovery_mock = zip_recovery_patcher.start()
         self.zip_recovery_mock.return_value = ('zipped_file', 'file_hash')
 
-        file_removal_patcher = mock.patch('ErrorReporter.error_report_presenter.remove_recovery_file')
-        self.addCleanup(file_removal_patcher.stop)
-        self.file_removal_mock = file_removal_patcher.start()
-
         self.view = mock.MagicMock()
         self.exit_code = 255
         self.error_report_presenter = ErrorReporterPresenter(self.view, self.exit_code)
@@ -97,7 +93,7 @@ class ErrorReportPresenterTest(unittest.TestCase):
         self.error_report_presenter._send_report_to_server = mock.MagicMock(return_value=201)
         self.error_report_presenter._upload_recovery_file = mock.MagicMock()
         self.error_report_presenter._handle_exit = mock.MagicMock()
-        
+
         self.error_report_presenter.error_handler(continue_working, share, name, email, text_box)
 
         self.error_report_presenter._send_report_to_server.called_once_with(share_identifiable=True, name=name, email=email,
diff --git a/scripts/test/InelasticDirectDetpackmapTest.py b/scripts/test/InelasticDirectDetpackmapTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..0444a0bc6eff9e3d8fb6a07d0dcbaf61a2a1b935
--- /dev/null
+++ b/scripts/test/InelasticDirectDetpackmapTest.py
@@ -0,0 +1,22 @@
+from Direct.detpackmap import sequoia
+import unittest
+
+
+class InelasticDirectDetpackmapTest(unittest.TestCase):
+
+    def test_sequoia(self):
+        self.assertEqual(sequoia('B1'),  38)
+        self.assertEqual(sequoia('B37'),  74)
+        self.assertEqual(sequoia('C1'),  75)
+        self.assertEqual(sequoia('C25T'),  99)
+        self.assertEqual(sequoia('C26T'),  100)
+        self.assertEqual(sequoia('C25B'),  101)
+        self.assertEqual(sequoia('C26B'),  102)
+        self.assertEqual(sequoia('C37'),  113)
+        self.assertEqual(sequoia('D1'),  114)
+        self.assertEqual(sequoia('D37'),  150)
+        with self.assertRaises(ValueError):
+            sequoia('M38')
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/scripts/test/Muon/CMakeLists.txt b/scripts/test/Muon/CMakeLists.txt
index 992d248d9f9857af2dec381c03bb768e37432f05..f29fc35f9acbf87c07344ddd84c2ff3c6b383404 100644
--- a/scripts/test/Muon/CMakeLists.txt
+++ b/scripts/test/Muon/CMakeLists.txt
@@ -7,6 +7,16 @@ set ( TEST_PY_FILES
    AxisChangerView_test.py
    FFTModel_test.py
    FFTPresenter_test.py
+   load_file_widget/loadfile_model_test.py
+   load_file_widget/loadfile_presenter_single_file_test.py
+   load_file_widget/loadfile_presenter_multiple_file_test.py
+   load_file_widget/loadfile_view_test.py
+   load_run_widget/loadrun_model_test.py
+   load_run_widget/loadrun_presenter_current_run_test.py
+   load_run_widget/loadrun_presenter_single_file_test.py
+   load_run_widget/loadrun_presenter_multiple_file_test.py
+   load_run_widget/loadrun_presenter_increment_decrement_test.py
+   load_run_widget/loadrun_view_test.py
    LoadWidgetModel_test.py
    LoadWidgetPresenter_test.py
    LoadWidgetView_test.py
@@ -18,8 +28,10 @@ set ( TEST_PY_FILES
    PlottingUtils_test.py
    PlottingView_test.py
    transformWidget_test.py
-   utilities/thread_model_test.py
+   utilities/muon_group_test.py
+   utilities/muon_pair_test.py
    utilities/load_utils_test.py
+   utilities/thread_model_test.py
    utilities/muon_workspace_wrapper_test.py
    utilities/muon_workspace_wrapper_directory_test.py
    utilities/muon_load_data_test.py
diff --git a/scripts/test/Muon/PlottingView_test.py b/scripts/test/Muon/PlottingView_test.py
index 16c54482ebee6b48dbd2c307852e1545c0472af4..7fbe9ad99ee98bcd8b123915c3c1931674bbd68b 100644
--- a/scripts/test/Muon/PlottingView_test.py
+++ b/scripts/test/Muon/PlottingView_test.py
@@ -6,12 +6,12 @@
 # SPDX - License - Identifier: GPL - 3.0 +
 import unittest
 
-import os
+import os, sys
 os.environ["QT_API"] = "pyqt"  # noqa E402
 
 from matplotlib.figure import Figure
 
-from mantid.simpleapi import *
+from mantid import WorkspaceFactory
 from mantid import plots
 from Muon.GUI.ElementalAnalysis.Plotting.subPlot_object import subPlot
 from Muon.GUI.ElementalAnalysis.Plotting.plotting_view import PlotView
@@ -26,7 +26,12 @@ except ImportError:
 
 
 def get_subPlot(name):
-    ws1 = CreateWorkspace(DataX=[1, 2, 3, 4], DataY=[4, 5, 6, 7], NSpec=2)
+    data_x, data_y = [1, 2, 3, 4], [4, 5, 6, 7]
+    nspec = 2
+    ws1 = WorkspaceFactory.create("Workspace2D", nspec, len(data_x), len(data_y))
+    for i in range(ws1.getNumberHistograms()):
+        ws1.setX(i, data_x)
+        ws1.setY(i, data_y)
     label1 = "test"
     # create real lines
     fig = Figure()
@@ -37,7 +42,7 @@ def get_subPlot(name):
     subplot.addLine(label1, line1, ws1, 2)
     return subplot, ws1
 
-
+@unittest.skipIf(lambda: sys.platform=='win32'(), "Test segfaults on Windows and code will be removed soon")
 class PlottingViewHelperFunctionTests(unittest.TestCase):
 
     def setUp(self):
@@ -294,6 +299,7 @@ class PlottingViewHelperFunctionTests(unittest.TestCase):
             list(self.view.plots.keys()))
 
 
+@unittest.skipIf(lambda: sys.platform=='win32'(), "Test segfaults on Windows and code will be removed soon")
 class PlottingViewPlotFunctionsTests(unittest.TestCase):
 
     def setUp(self):
diff --git a/scripts/test/Muon/load_file_widget/__init__.py b/scripts/test/Muon/load_file_widget/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/test/Muon/load_file_widget/loadfile_model_test.py b/scripts/test/Muon/load_file_widget/loadfile_model_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..aea20f20e38de326433dae87c7637df582d5888d
--- /dev/null
+++ b/scripts/test/Muon/load_file_widget/loadfile_model_test.py
@@ -0,0 +1,83 @@
+import sys
+import six
+
+import unittest
+
+if sys.version_info.major < 2:
+    from unittest import mock
+else:
+    import mock
+
+from Muon.GUI.Common.load_file_widget.model import BrowseFileWidgetModel
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+from Muon.GUI.Common.utilities.muon_test_helpers import IteratorWithException
+
+class LoadFileWidgetModelTest(unittest.TestCase):
+
+    def setUp(self):
+        self.data = MuonLoadData()
+        self.model = BrowseFileWidgetModel(self.data)
+
+        patcher = mock.patch('Muon.GUI.Common.load_file_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+
+    def mock_load_function(self, files_to_load, load_return_values):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=load_return_values)
+        self.model.loadData(files_to_load)
+
+    def assert_model_empty(self):
+        self.assertEqual(self.model.loaded_workspaces, [])
+        self.assertEqual(self.model.loaded_filenames, [])
+        self.assertEqual(self.model.loaded_runs, [])
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def test_model_initialized_with_empty_lists_of_loaded_data(self):
+        self.assert_model_empty()
+
+    def test_executing_load_without_filenames_does_nothing(self):
+        self.model.execute()
+        self.assert_model_empty()
+
+    def test_execute_successfully_loads_given_files(self):
+        files = ['EMU00019489.nxs', 'EMU00019490.nxs', 'EMU00019491.nxs']
+        load_return_vals = [([1 + i], 19489 + i, filename) for i, filename in enumerate(files)]
+        self.mock_load_function(files, load_return_vals)
+
+        self.model.execute()
+
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[1], [2], [3]])
+        six.assertCountEqual(self, self.model.loaded_filenames, files)
+        six.assertCountEqual(self, self.model.loaded_runs, [19489, 19490, 19491])
+
+    def test_model_is_cleared_correctly(self):
+        files = [r'EMU00019489.nxs', r'EMU00019490.nxs', r'EMU00019491.nxs']
+        load_return_vals = [([1 + i], 19489 + i, filename) for i, filename in enumerate(files)]
+        self.mock_load_function(files, load_return_vals)
+
+        self.model.execute()
+        self.assertEqual(len(self.model.loaded_filenames), 3)
+        self.model.clear()
+
+        self.assert_model_empty()
+
+    def test_execute_throws_if_one_file_does_not_load_correctly_but_still_loads_other_files(self):
+        files = [r'EMU00019489.nxs', r'EMU00019490.nxs', r'EMU00019491.nxs']
+        load_return_vals = [([1 + i], 19489 + i, filename) for i, filename in enumerate(files)]
+
+        # Mock load to throw on a particular index
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock()
+        self.load_utils_patcher.load_workspace_from_filename.side_effect = iter(IteratorWithException(load_return_vals, [1]))
+        self.model.loadData(files)
+        with self.assertRaises(ValueError):
+            self.model.execute()
+
+        six.assertCountEqual(self, self.model.loaded_filenames, [files[i] for i in [0, 2]])
+        six.assertCountEqual(self, self.model.loaded_runs, [19489, 19491])
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_file_widget/loadfile_presenter_multiple_file_test.py b/scripts/test/Muon/load_file_widget/loadfile_presenter_multiple_file_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9f36e8e9dacdf1050c404b49071132825f9dbd1
--- /dev/null
+++ b/scripts/test/Muon/load_file_widget/loadfile_presenter_multiple_file_test.py
@@ -0,0 +1,247 @@
+import six
+import sys
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+from Muon.GUI.Common import mock_widget
+from Muon.GUI.Common.load_file_widget.view import BrowseFileWidgetView
+from Muon.GUI.Common.load_file_widget.presenter import BrowseFileWidgetPresenter
+from Muon.GUI.Common.load_file_widget.model import BrowseFileWidgetModel
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+
+
+class IteratorWithException:
+    """Wraps a simple iterable (i.e. list) so that it throws a ValueError on a particular index."""
+
+    def __init__(self, iterable, throw_on_index):
+        self.max = len(iterable)
+        self.iterable = iter(iterable)
+
+        self.throw_indices = [index for index in throw_on_index if index < self.max]
+
+    def __iter__(self):
+        self.n = 0
+        return self
+
+    def __next__(self):
+
+        if self.n in self.throw_indices:
+            next(self.iterable)
+            self.n += 1
+            raise ValueError()
+        elif self.n == self.max:
+            raise StopIteration()
+        else:
+            self.n += 1
+            return next(self.iterable)
+
+    next = __next__
+
+
+class LoadFileWidgetPresenterMultipleFileModeTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        self.data = MuonLoadData()
+        self.view = BrowseFileWidgetView()
+        self.model = BrowseFileWidgetModel(self.data)
+
+        self.view.disable_load_buttons = mock.Mock()
+        self.view.enable_load_buttons = mock.Mock()
+        self.view.warning_popup = mock.Mock()
+
+        self.presenter = BrowseFileWidgetPresenter(self.view, self.model)
+        self.presenter.enable_multiple_files(True)
+
+        patcher = mock.patch('Muon.GUI.Common.load_file_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+
+    def mock_loading_multiple_files_from_browse(self, runs, workspaces, filenames):
+        self.view.show_file_browser_and_return_selection = mock.Mock(return_value=filenames)
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=zip(workspaces, runs, filenames))
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS : Multiple runs can be selected via browse and entered explicitly using the ";" separator
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_that_cannot_load_same_file_twice_from_same_browse_even_if_filepaths_are_different(self):
+        self.view.show_file_browser_and_return_selection = mock.Mock(
+            return_value=["C:/dir1/file1.nxs", "C:/dir2/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.load_utils_patcher.load_workspace_from_filename.call_count, 2)
+        self.load_utils_patcher.load_workspace_from_filename.assert_any_call("C:/dir1/file1.nxs")
+        self.load_utils_patcher.load_workspace_from_filename.assert_any_call("C:/dir2/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_cannot_load_same_file_twice_from_user_input_even_if_filepaths_are_different(self):
+        self.view.set_file_edit("C:/dir1/file1.nxs;C:/dir2/file1.nxs;C:/dir2/file2.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.load_utils_patcher.load_workspace_from_filename.call_count, 2)
+        self.load_utils_patcher.load_workspace_from_filename.assert_any_call("C:/dir1/file1.nxs")
+        self.load_utils_patcher.load_workspace_from_filename.assert_any_call("C:/dir2/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_cannot_browse_and_load_same_run_twice_even_if_filenames_are_different(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=zip([[1], [2]], [1234, 1234], ["C:/dir1/file1.nxs", "C:/dir1/file2.nxs"]))
+        self.view.show_file_browser_and_return_selection = mock.Mock(
+            return_value=["C:/dir1/file1.nxs", "C:/dir1/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        # Load will take the last occurrence of the run from the list
+        six.assertCountEqual(self, self.model.loaded_filenames, ["C:/dir1/file2.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[2]])
+        six.assertCountEqual(self, self.model.loaded_runs, [1234])
+
+    @run_test_with_and_without_threading
+    def test_that_cannot_input_and_load_same_run_twice_even_if_filenames_are_different(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=zip([[1], [2]], [1234, 1234], ["C:/dir1/file1.nxs", "C:/dir1/file2.nxs"]))
+        self.view.set_file_edit("C:/dir1/file1.nxs;C:/dir1/file2.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        # Load will take the last occurrence of the run from the user input
+        six.assertCountEqual(self, self.model.loaded_filenames, ["C:/dir1/file2.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[2]])
+        six.assertCountEqual(self, self.model.loaded_runs, [1234])
+
+    @run_test_with_and_without_threading
+    def test_that_loading_two_files_from_browse_sets_model_and_interface_correctly(self):
+        self.presenter.enable_multiple_files(True)
+        self.mock_loading_multiple_files_from_browse([1234, 1235], [[1], [2]],
+                                                     ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1], [2]])
+        self.assertEqual(self.model.loaded_runs, [1234, 1235])
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir2/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_loading_two_files_from_user_input_sets_model_and_interface_correctly(self):
+        self.presenter.enable_multiple_files(True)
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=zip([[1], [2]], [1234, 1235], ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"]))
+        self.view.set_file_edit("C:/dir1/file1.nxs;C:/dir2/file2.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1], [2]])
+        self.assertEqual(self.model.loaded_runs, [1234, 1235])
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir2/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_loading_two_files_from_browse_sets_interface_alphabetically(self):
+        self.mock_loading_multiple_files_from_browse([1234, 1235], [[1], [2]],
+                                                     ["C:/dir1/file2.nxs", "C:/dir1/file1.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir1/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_loading_two_files_from_user_input_sets_interface_alphabetically(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(
+            side_effect=zip([[2], [1]], [1235, 1234], ["C:/dir1/file2.nxs", "C:/dir1/file1.nxs"]))
+        self.view.set_file_edit("C:/dir1/file2.nxs;C:/dir1/file1.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir1/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_loading_multiple_files_from_browse_ignores_loads_which_throw(self):
+        self.presenter.enable_multiple_files(True)
+
+        files = ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs", "C:/dir2/file3.nxs"]
+        self.view.show_file_browser_and_return_selection = mock.Mock(return_value=files)
+        load_return_values = [([1], 1234 + i, filename) for i, filename in enumerate(files)]
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(
+            side_effect=iter(IteratorWithException(load_return_values, [1])))
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/file1.nxs", "C:/dir2/file3.nxs"])
+        self.assertEqual(self.model.loaded_runs, [1234, 1236])
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir2/file3.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_browse_allows_loading_of_additional_files(self):
+        self.mock_loading_multiple_files_from_browse([1234, 1235], [[1], [2]],
+                                                     ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.mock_loading_multiple_files_from_browse([1236], [[3]], ["C:/dir1/file3.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames,
+                             ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs", "C:/dir1/file3.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[1], [2], [3]])
+        six.assertCountEqual(self, self.model.loaded_runs, [1234, 1235, 1236])
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir1/file1.nxs;C:/dir1/file3.nxs;C:/dir2/file2.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_loading_an_already_loaded_file_from_browse_overwrites_it(self):
+        self.mock_loading_multiple_files_from_browse([1234, 1235], [[1], [2]],
+                                                     ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        # only checks runs, so can have a different file/workspace (this is why overwriting is
+        # the most useful behaviour in this situation).
+        self.mock_loading_multiple_files_from_browse([1234], [[3]], ["C:/dir2/file1.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames, ["C:/dir2/file1.nxs", "C:/dir2/file2.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[3], [2]])
+        six.assertCountEqual(self, self.model.loaded_runs, [1234, 1235])
+
+        self.assertEqual(self.view.get_file_edit_text(), "C:/dir2/file1.nxs;C:/dir2/file2.nxs")
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_file_widget/loadfile_presenter_single_file_test.py b/scripts/test/Muon/load_file_widget/loadfile_presenter_single_file_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..0506feab4afce72fd710e7629ff3798db931f93a
--- /dev/null
+++ b/scripts/test/Muon/load_file_widget/loadfile_presenter_single_file_test.py
@@ -0,0 +1,302 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+from Muon.GUI.Common.load_file_widget.view import BrowseFileWidgetView
+from Muon.GUI.Common.load_file_widget.presenter import BrowseFileWidgetPresenter
+from Muon.GUI.Common.load_file_widget.model import BrowseFileWidgetModel
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+from Muon.GUI.Common import mock_widget
+
+
+class IteratorWithException:
+    """Wraps a simple iterable (i.e. list) so that it throws a ValueError on a particular index."""
+
+    def __init__(self, iterable, throw_on_index):
+        self.max = len(iterable)
+        self.iterable = iter(iterable)
+
+        self.throw_indices = [index for index in throw_on_index if index < self.max]
+
+    def __iter__(self):
+        self.n = 0
+        return self
+
+    def __next__(self):
+
+        if self.n in self.throw_indices:
+            next(self.iterable)
+            self.n += 1
+            raise ValueError()
+        elif self.n == self.max:
+            raise StopIteration()
+        else:
+            self.n += 1
+            return next(self.iterable)
+
+    next = __next__
+
+
+class LoadFileWidgetPresenterTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        self.view = BrowseFileWidgetView()
+
+        self.view.on_browse_clicked = mock.Mock()
+        self.view.set_file_edit = mock.Mock()
+        self.view.reset_edit_to_cached_value = mock.Mock()
+        self.view.show_file_browser_and_return_selection = mock.Mock(
+            return_value=["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.data = MuonLoadData()
+        self.model = BrowseFileWidgetModel(self.data)
+        self.model.exception_message_for_failed_files = mock.Mock()
+
+        self.view.disable_load_buttons = mock.Mock()
+        self.view.enable_load_buttons = mock.Mock()
+        self.view.warning_popup = mock.Mock()
+
+        self.presenter = BrowseFileWidgetPresenter(self.view, self.model)
+        self.presenter.enable_multiple_files(False)
+
+        patcher = mock.patch('Muon.GUI.Common.load_file_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+
+    def mock_browse_button_to_return_files(self, files):
+        self.view.show_file_browser_and_return_selection = mock.Mock(return_value=files)
+
+    def mock_user_input_text(self, text):
+        self.view.get_file_edit_text = mock.Mock(return_value=text)
+
+    def mock_model_to_load_workspaces(self, workspaces, runs, filenames):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=zip(workspaces, runs, filenames))
+
+    def load_workspaces_into_model_and_view_from_browse(self, workspaces, runs, files):
+        self.mock_model_to_load_workspaces(workspaces, runs, files)
+        self.mock_browse_button_to_return_files(files)
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+    def load_failure(self):
+        raise ValueError("Error text")
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_browser_dialog_opens_when_browse_button_clicked(self):
+        self.mock_browse_button_to_return_files(["file.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.show_file_browser_and_return_selection.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_loading_not_initiated_if_no_file_selected_from_browser(self):
+        self.mock_model_to_load_workspaces([], [], [])
+        self.mock_browse_button_to_return_files([])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.load_utils_patcher.load_workspace_from_filename.call_count, 0)
+
+    @run_test_with_and_without_threading
+    def test_buttons_disabled_while_load_thread_running(self):
+        self.mock_browse_button_to_return_files(["file.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.load_utils_patcher.load_workspace_from_filename.assert_called_once_with("file.nxs")
+        self.assertEqual(self.view.disable_load_buttons.call_count, 1)
+        self.assertEqual(self.view.enable_load_buttons.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_buttons_enabled_after_load_even_if_load_thread_throws(self):
+        self.mock_browse_button_to_return_files(["file.nxs"])
+        self.load_utils_patcher.load_workspace_from_filename.side_effect = self.load_failure
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.load_utils_patcher.load_workspace_from_filename.assert_called_once_with("file.nxs")
+        self.assertEqual(self.view.disable_load_buttons.call_count, 1)
+        self.assertEqual(self.view.enable_load_buttons.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_files_not_loaded_into_model_if_multiple_files_selected_from_browse_in_single_file_mode(self):
+        self.mock_model_to_load_workspaces([[1], [2]], [1234, 1235], ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.mock_browse_button_to_return_files(["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.model.execute = mock.Mock()
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.execute.call_count, 0)
+        self.assertEqual(self.view.disable_load_buttons.call_count, 0)
+        self.assertEqual(self.view.enable_load_buttons.call_count, 0)
+
+    @run_test_with_and_without_threading
+    def test_files_not_loaded_into_model_if_multiple_files_entered_by_user_in_single_file_mode(self):
+        self.mock_user_input_text("C:/dir1/file1.nxs;C:/dir2/file2.nxs")
+        self.mock_model_to_load_workspaces([[1], [2]], [1234, 1235], ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.model.execute = mock.Mock()
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.execute.call_count, 0)
+        self.assertEqual(self.view.disable_load_buttons.call_count, 0)
+        self.assertEqual(self.view.enable_load_buttons.call_count, 0)
+
+    @run_test_with_and_without_threading
+    def test_warning_shown_if_multiple_files_selected_from_browse_in_single_file_mode(self):
+        self.mock_browse_button_to_return_files(["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+        self.mock_model_to_load_workspaces([[1], [2]], [1234, 1235], ["C:/dir1/file1.nxs", "C:/dir2/file2.nxs"])
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_warning_shown_if_multiple_files_entered_by_user_in_single_file_mode(self):
+        self.mock_user_input_text("C:/dir1/file1.nxs;C:/dir2/file2.nxs")
+        self.mock_model_to_load_workspaces([[1], [2]], [1234, 1235], ["C:/dir1/file1.nxs;C:/dir2/file2.nxs"])
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_single_file_from_browse_loaded_into_model_and_view_in_single_file_mode(self):
+        self.mock_browse_button_to_return_files(["C:/dir1/file1.nxs"])
+        self.mock_model_to_load_workspaces([[1]], [1234], ["C:/dir1/file1.nxs"])
+        self.view.set_file_edit = mock.Mock()
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/file1.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1]])
+        self.assertEqual(self.model.loaded_runs, [1234])
+
+        self.view.set_file_edit.assert_called_once_with("C:/dir1/file1.nxs", mock.ANY)
+
+    @run_test_with_and_without_threading
+    def test_single_file_from_user_input_loaded_into_model_and_view_in_single_file_mode(self):
+        self.view.set_file_edit = mock.Mock()
+        self.mock_model_to_load_workspaces([[1]], [1234], ["C:/dir1/file1.nxs"])
+        self.mock_user_input_text("C:/dir1/file1.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/file1.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1]])
+        self.assertEqual(self.model.loaded_runs, [1234])
+
+        self.view.set_file_edit.assert_called_once_with("C:/dir1/file1.nxs", mock.ANY)
+
+    @run_test_with_and_without_threading
+    def test_that_if_invalid_file_selected_in_browser_view_does_not_change(self):
+        self.mock_browse_button_to_return_files(["not_a_file"])
+        self.mock_model_to_load_workspaces([[1]], [1234], ["not_a_file"])
+
+        self.view.set_file_edit = mock.Mock()
+        self.view.reset_edit_to_cached_value = mock.Mock()
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        set_file_edit_count = self.view.set_file_edit.call_count
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.set_file_edit.call_count, set_file_edit_count)
+        self.assertEqual(self.view.reset_edit_to_cached_value.call_count, 0)
+
+    @run_test_with_and_without_threading
+    def test_that_view_reverts_to_previous_text_if_users_supplies_invalid_text(self):
+        self.load_workspaces_into_model_and_view_from_browse([[1]], [1234], ["C:/dir1/EMU0001234.nxs"])
+
+        invalid_user_input = ["some random text", "1+1=2", "..."]
+
+        call_count = self.view.reset_edit_to_cached_value.call_count
+        for invalid_text in invalid_user_input:
+            call_count += 1
+            self.view.get_file_edit_text = mock.Mock(return_value=invalid_text)
+
+            self.presenter.handle_file_changed_by_user()
+            self.wait_for_thread(self.presenter._load_thread)
+
+            self.assertEqual(self.view.reset_edit_to_cached_value.call_count, call_count)
+
+    @run_test_with_and_without_threading
+    def test_that_model_and_interface_revert_to_previous_values_if_load_fails_from_browse(self):
+        self.load_workspaces_into_model_and_view_from_browse([[1]], [1234], ["C:/dir1/EMU0001234.nxs"])
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.on_browse_button_clicked()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/EMU0001234.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1]])
+        self.assertEqual(self.model.loaded_runs, [1234])
+
+        self.assertEqual(self.view.reset_edit_to_cached_value.call_count, 0)
+        self.assertEqual(self.view.set_file_edit.call_args[0][0], "C:/dir1/EMU0001234.nxs")
+
+    @run_test_with_and_without_threading
+    def test_that_model_and_interface_revert_to_previous_values_if_load_fails_from_user_input(self):
+        self.load_workspaces_into_model_and_view_from_browse([[1]], [1234], ["C:/dir1/EMU0001234.nxs"])
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+        self.view.set_file_edit("C:\dir2\EMU000123.nxs")
+
+        self.presenter.handle_file_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.model.loaded_filenames, ["C:/dir1/EMU0001234.nxs"])
+        self.assertEqual(self.model.loaded_workspaces, [[1]])
+        self.assertEqual(self.model.loaded_runs, [1234])
+
+        self.assertEqual(self.view.reset_edit_to_cached_value.call_count, 1)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_file_widget/loadfile_view_test.py b/scripts/test/Muon/load_file_widget/loadfile_view_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa8ea3a4783b9660e0fd2515252ca1f39418ca96
--- /dev/null
+++ b/scripts/test/Muon/load_file_widget/loadfile_view_test.py
@@ -0,0 +1,47 @@
+import unittest
+
+from Muon.GUI.Common import mock_widget
+
+from Muon.GUI.Common.load_file_widget.view import BrowseFileWidgetView
+
+
+class LoadFileWidgetViewTest(unittest.TestCase):
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        self.view = BrowseFileWidgetView()
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def test_view_initialized_with_empty_line_edit(self):
+        self.assertEqual(self.view.get_file_edit_text(), "No data loaded")
+
+    def test_reset_text_to_cache_resets_correctly(self):
+        text = "C:\dir1\dir2\EMU00012345.nxs;C:\dir1\dir2\EMU00012345.nxs"
+        self.view.set_file_edit(text)
+        # User may then overwrite the text in the LineEdit, causing a signal to be sent
+        # and the corresponding slot should implement reset_edit_to_cached_value()
+        self.view.reset_edit_to_cached_value()
+        self.assertEqual(self.view.get_file_edit_text(), text)
+
+    def test_text_clears_from_line_edit_correctly(self):
+        text = "C:\dir1\dir2\EMU00012345.nxs;C:\dir1\dir2\EMU00012345.nxs"
+        self.view.set_file_edit(text)
+        self.view.clear()
+        self.assertEqual(self.view.get_file_edit_text(), "No data loaded")
+        self.view.reset_edit_to_cached_value()
+        self.assertEqual(self.view.get_file_edit_text(), "No data loaded")
+
+    def test_text_stored_correctly_when_not_visible_in_line_edit(self):
+        # This feature is currently unused
+        text = "C:\dir1\dir2\EMU00012345.nxs;C:\dir1\dir2\EMU00012345.nxs"
+        self.view.set_file_edit(text, store=True)
+        self.assertEqual(self.view.get_file_edit_text(), text)
+        self.view.reset_edit_to_cached_value()
+        self.assertEqual(self.view.get_file_edit_text(), text)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_run_widget/__init__.py b/scripts/test/Muon/load_run_widget/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/scripts/test/Muon/load_run_widget/loadrun_model_test.py b/scripts/test/Muon/load_run_widget/loadrun_model_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..45d26184168dda359b3d152aa82cdd1380cbeb20
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_model_test.py
@@ -0,0 +1,92 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+
+from Muon.GUI.Common.load_run_widget.model import LoadRunWidgetModel
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+from Muon.GUI.Common.utilities.muon_test_helpers import IteratorWithException
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+
+class LoadRunWidgetModelTest(unittest.TestCase):
+
+    def test_model_initialized_with_empty_lists_of_loaded_data(self):
+        model = LoadRunWidgetModel(MuonLoadData())
+        self.assertEqual(model.loaded_workspaces, [])
+        self.assertEqual(model.loaded_filenames, [])
+        self.assertEqual(model.loaded_runs, [])
+
+    def test_executing_load_without_filenames_does_nothing(self):
+        model = LoadRunWidgetModel(MuonLoadData())
+        model.execute()
+        self.assertEqual(model.loaded_workspaces, [])
+        self.assertEqual(model.loaded_filenames, [])
+        self.assertEqual(model.loaded_runs, [])
+
+    @mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+    def test_execute_successfully_loads_valid_files(self, load_utils_mock):
+        # Mock the load algorithm
+        files = [r'EMU00019489.nxs', r'EMU00019490.nxs', r'EMU00019491.nxs']
+        load_return_vals = [([1, 2, 3], 19489 + i, filename) for i, filename in enumerate(files)]
+
+        model = LoadRunWidgetModel(MuonLoadData())
+        load_utils_mock.load_workspace_from_filename = mock.MagicMock()
+        load_utils_mock.load_workspace_from_filename.side_effect = load_return_vals
+
+        model.loadData(files)
+        model.execute()
+        self.assertEqual(len(model.loaded_workspaces), len(model.loaded_runs))
+        self.assertEqual(len(model.loaded_workspaces), len(model.loaded_filenames))
+        self.assertEqual(len(model.loaded_workspaces), 3)
+        self.assertEqual(model.loaded_runs[0], 19489)
+        self.assertEqual(model.loaded_runs[1], 19490)
+        self.assertEqual(model.loaded_runs[2], 19491)
+
+    @mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+    def test_model_is_cleared_correctly(self, load_utils_mock):
+        files = [r'EMU00019489.nxs', r'EMU00019490.nxs', r'EMU00019491.nxs']
+        load_return_vals = [([1, 2, 3], filename, 19489 + i) for i, filename in enumerate(files)]
+
+        model = LoadRunWidgetModel(MuonLoadData())
+        load_utils_mock.load_workspace_from_filename = mock.Mock()
+        load_utils_mock.load_workspace_from_filename.side_effect = load_return_vals
+
+        model.loadData(files)
+        model.execute()
+        self.assertEqual(len(model.loaded_runs), 3)
+        model.clear_loaded_data()
+        self.assertEqual(model.loaded_workspaces, [])
+        self.assertEqual(model.loaded_filenames, [])
+        self.assertEqual(model.loaded_runs, [])
+
+    @mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+    def test_execute_throws_if_one_file_does_not_load_correctly_but_still_loads_other_files(self, load_utils_mock):
+        files = [r'EMU00019489.nxs', r'EMU00019490.nxs', r'EMU00019491.nxs']
+        load_return_vals = [([1, 2, 3], 19489 + i, filename) for i, filename in enumerate(files)]
+
+        model = LoadRunWidgetModel(MuonLoadData())
+        load_utils_mock.load_workspace_from_filename = mock.MagicMock()
+
+        load_utils_mock.load_workspace_from_filename.side_effect = iter(IteratorWithException(load_return_vals, [1]))
+
+        model.loadData(files)
+        with self.assertRaises(ValueError):
+            model.execute()
+        self.assertEqual(len(model.loaded_workspaces), 2)
+        self.assertEqual(model.loaded_filenames[0], files[0])
+        self.assertEqual(model.loaded_filenames[1], files[2])
+        self.assertEqual(model.loaded_runs[0], 19489)
+        self.assertEqual(model.loaded_runs[1], 19491)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_run_widget/loadrun_presenter_current_run_test.py b/scripts/test/Muon/load_run_widget/loadrun_presenter_current_run_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..adbc37f0ca23058dd72ac7a9a9a377b811b68b2d
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_presenter_current_run_test.py
@@ -0,0 +1,151 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+from Muon.GUI.Common.load_run_widget.model import LoadRunWidgetModel
+from Muon.GUI.Common.load_run_widget.view import LoadRunWidgetView
+from Muon.GUI.Common.load_run_widget.presenter import LoadRunWidgetPresenter
+from Muon.GUI.Common import mock_widget
+
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+import Muon.GUI.Common.utilities.muon_file_utils as fileUtils
+
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+from PyQt4 import QtGui
+from PyQt4.QtGui import QApplication
+
+
+class LoadRunWidgetLoadCurrentRunTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def load_failure(self):
+        raise ValueError("Error text")
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        # Store an empty widget to parent all the views, and ensure they are deleted correctly
+        self.obj = QtGui.QWidget()
+
+        self.data = MuonLoadData()
+        self.view = LoadRunWidgetView(parent=self.obj)
+        self.model = LoadRunWidgetModel(self.data)
+        self.presenter = LoadRunWidgetPresenter(self.view, self.model)
+
+        self.model.load_workspace_from_filename = mock.Mock(return_value=([1, 2, 3], "currentRun.nxs", 1234))
+        self.view.warning_popup = mock.Mock()
+        self.view.disable_load_buttons = mock.Mock()
+        self.view.enable_load_buttons = mock.Mock()
+
+        self.presenter.set_current_instrument("EMU")
+
+        fileUtils.get_current_run_filename = mock.Mock(return_value="EMU0001234.nxs")
+
+        patcher = mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+        self.load_utils_patcher.exception_message_for_failed_files.return_value = ''
+
+    def tearDown(self):
+        self.obj = None
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_load_current_run_loads_run_into_model(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1, 2, 3], 1234, "currentRun.nxs"))
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, ["currentRun.nxs"])
+        self.assertEqual(self.presenter.runs, [1234])
+        self.assertEqual(self.presenter.workspaces, [[1, 2, 3]])
+
+        self.assertEqual(self.model.current_run, 1234)
+
+    @run_test_with_and_without_threading
+    def test_load_current_run_correctly_displays_run_if_load_successful(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], 1234, "1234.nxs"))
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+        self.assertEqual(self.view.get_run_edit_text(), "1234 (CURRENT RUN)")
+
+    def test_load_current_run_displays_error_message_if_fails_to_load(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_load_current_run_reverts_to_previous_data_if_fails_to_load(self):
+        # set up previous data
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], 1234, "1234.nxs"))
+        self.view.set_run_edit_text("1234")
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, ["1234.nxs"])
+        self.assertEqual(self.presenter.runs, [1234])
+        self.assertEqual(self.presenter.workspaces, [[1]])
+
+    @run_test_with_and_without_threading
+    def test_load_current_run_clears_previous_data_if_load_succeeds(self):
+        # set up previous data
+        self.load_utils_patcher.return_value = ([1], "1234.nxs", 1234)
+        self.view.set_run_edit_text("1234")
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([2], 9999, "9999.nxs"))
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.get_run_edit_text(), "9999 (CURRENT RUN)")
+        self.assertEqual(self.presenter.filenames, ["9999.nxs"])
+        self.assertEqual(self.presenter.runs, [9999])
+        self.assertEqual(self.presenter.workspaces, [[2]])
+
+    @run_test_with_and_without_threading
+    def test_load_current_run_displays_error_if_incrementing_past_current_run(self):
+        # set up current run
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], 1234, "1234.nxs"))
+        self.view.set_run_edit_text("1234")
+        self.presenter.handle_load_current_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_run_widget/loadrun_presenter_increment_decrement_test.py b/scripts/test/Muon/load_run_widget/loadrun_presenter_increment_decrement_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab6e993aee13c7b2229a9b3da801fe77455b3aa7
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_presenter_increment_decrement_test.py
@@ -0,0 +1,188 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+import os
+
+from Muon.GUI.Common.load_run_widget.model import LoadRunWidgetModel
+from Muon.GUI.Common.load_run_widget.view import LoadRunWidgetView
+from Muon.GUI.Common.load_run_widget.presenter import LoadRunWidgetPresenter
+from Muon.GUI.Common import mock_widget
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+from PyQt4 import QtGui
+
+
+class LoadRunWidgetIncrementDecrementSingleFileModeTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        # Store an empty widget to parent all the views, and ensure they are deleted correctly
+        self.obj = QtGui.QWidget()
+
+        self.data = MuonLoadData()
+        self.view = LoadRunWidgetView(parent=self.obj)
+        self.model = LoadRunWidgetModel(self.data)
+        self.presenter = LoadRunWidgetPresenter(self.view, self.model)
+
+        self.view.warning_popup = mock.Mock()
+        self.presenter.enable_multiple_files(False)
+        self.presenter.set_current_instrument("EMU")
+
+        patcher = mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+        self.load_utils_patcher.exception_message_for_failed_files.return_value = ''
+
+        self.load_single_run()
+
+    def tearDown(self):
+        self.obj = None
+
+    def load_single_run(self):
+        self._loaded_run = 1234
+        self._loaded_filename = "EMU00001234.nxs"
+        self._loaded_workspace = [1, 2, 3]
+
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(
+            return_value=(self._loaded_workspace, self._loaded_run, self._loaded_filename))
+        self.view.set_run_edit_text(str(self._loaded_run))
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+    def assert_model_has_not_changed(self):
+        self.assertEqual(self.model.loaded_workspaces, [self._loaded_workspace])
+        self.assertEqual(self.model.loaded_runs, [self._loaded_run])
+        self.assertEqual(self.model.loaded_filenames, [self._loaded_filename])
+
+    def assert_view_has_not_changed(self):
+        self.assertEqual(self.view.get_run_edit_text(), str(self._loaded_run))
+
+    def load_failure(self):
+        raise ValueError("Error text")
+
+    def mock_model_to_throw(self):
+        self.model.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS : Test the increment/decrement buttons in single file mode (can only load one run at a time)
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_that_decrement_run_attempts_to_load_the_correct_run(self):
+        new_filename = "EMU00001233.nxs"
+        load_call_count = self.load_utils_patcher.load_workspace_from_filename.call_count
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.load_utils_patcher.load_workspace_from_filename.call_count, load_call_count + 1)
+        filename = self.load_utils_patcher.load_workspace_from_filename.call_args[0][0]
+        self.assertEqual(os.path.basename(filename), new_filename)
+
+    @run_test_with_and_without_threading
+    def test_that_increment_run_attempts_to_load_the_correct_run(self):
+        new_filename = "EMU00001235.nxs"
+        load_call_count = self.load_utils_patcher.load_workspace_from_filename.call_count
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.load_utils_patcher.load_workspace_from_filename.call_count, load_call_count + 1)
+        filename = self.load_utils_patcher.load_workspace_from_filename.call_args[0][0]
+        self.assertEqual(os.path.basename(filename), new_filename)
+
+    @run_test_with_and_without_threading
+    def test_that_decrement_run_loads_the_data_correctly_by_overwriting_previous_run(self):
+        new_run = self._loaded_run - 1
+        new_filename = "EMU00001233.nxs"
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], new_run, new_filename))
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, [new_filename])
+        self.assertEqual(self.presenter.runs, [new_run])
+        self.assertEqual(self.presenter.workspaces, [[1]])
+
+        self.assertEqual(self.view.get_run_edit_text(), str(new_run))
+
+    @run_test_with_and_without_threading
+    def test_that_increment_run_loads_the_data_correctly_by_overwriting_previous_run(self):
+        new_run = self._loaded_run + 1
+        new_filename = "EMU00001235.nxs"
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], new_run, new_filename))
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, [new_filename])
+        self.assertEqual(self.presenter.runs, [new_run])
+        self.assertEqual(self.presenter.workspaces, [[1]])
+
+        self.assertEqual(self.view.get_run_edit_text(), str(new_run))
+
+    @run_test_with_and_without_threading
+    def test_that_if_decrement_run_fails_the_data_are_returned_to_previous_state(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assert_model_has_not_changed()
+        self.assert_view_has_not_changed()
+#
+    @run_test_with_and_without_threading
+    def test_that_if_increment_run_fails_the_data_are_returned_to_previous_state(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assert_model_has_not_changed()
+        self.assert_view_has_not_changed()
+
+    @run_test_with_and_without_threading
+    def test_that_if_decrement_run_fails_warning_message_is_displayed(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_that_if_increment_run_fails_warning_message_is_displayed(self):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
\ No newline at end of file
diff --git a/scripts/test/Muon/load_run_widget/loadrun_presenter_multiple_file_test.py b/scripts/test/Muon/load_run_widget/loadrun_presenter_multiple_file_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..551849515d1be027b94b304c7aa243c5f5dc568a
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_presenter_multiple_file_test.py
@@ -0,0 +1,192 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+import six
+
+from Muon.GUI.Common.load_run_widget.model import LoadRunWidgetModel
+from Muon.GUI.Common.load_run_widget.view import LoadRunWidgetView
+from Muon.GUI.Common.load_run_widget.presenter import LoadRunWidgetPresenter
+from Muon.GUI.Common import mock_widget
+
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+
+import unittest
+from PyQt4 import QtGui
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+
+class LoadRunWidgetIncrementDecrementMultipleFileModeTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        # Store an empty widget to parent all the views, and ensure they are deleted correctly
+        self.obj = QtGui.QWidget()
+
+        self.data = MuonLoadData()
+        self.view = LoadRunWidgetView(self.obj)
+        self.model = LoadRunWidgetModel(self.data)
+        self.presenter = LoadRunWidgetPresenter(self.view, self.model)
+
+        self.view.warning_popup = mock.Mock()
+
+        self.presenter.enable_multiple_files(True)
+        self.presenter.set_current_instrument("EMU")
+
+        patcher = mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+        self.load_utils_patcher.exception_message_for_failed_files.return_value = ''
+
+    def tearDown(self):
+        self.obj = None
+
+    def load_runs(self, runs, filenames, workspaces):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(
+            side_effect=iter(zip(workspaces, runs, filenames)))
+        run_string = ",".join([str(run) for run in runs])
+        self.view.set_run_edit_text(run_string)
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+    def assert_model_empty(self):
+        self.assertEqual(self.model.loaded_filenames, [])
+        self.assertEqual(self.model.loaded_workspaces, [])
+        self.assertEqual(self.model.loaded_runs, [])
+
+    def assert_view_empty(self):
+        self.assertEqual(self.view.get_run_edit_text(), "")
+
+    def load_failure(self):
+        raise ValueError("Error text")
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS : Test the increment/decrement run buttons in "multiple file" mode
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_that_providing_no_runs_leaves_model_and_view_empty(self):
+        self.view.set_run_edit_text("")
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assert_view_empty()
+        self.assert_model_empty()
+
+    @run_test_with_and_without_threading
+    def test_that_increment_run_does_nothing_if_no_runs_loaded(self):
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assert_view_empty()
+        self.assert_model_empty()
+
+    @run_test_with_and_without_threading
+    def test_that_decrement_run_does_nothing_if_no_runs_loaded(self):
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assert_view_empty()
+        self.assert_model_empty()
+
+    @run_test_with_and_without_threading
+    def test_that_decrement_run_decrements_the_upper_end_of_the_range_of_loaded_runs(self):
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([1], 1, "file1.nxs"))
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames, ["file1.nxs", "file2.nxs", "file3.nxs", "file4.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[1], [2], [3], [4]])
+        six.assertCountEqual(self, self.model.loaded_runs, [1, 2, 3, 4])
+
+        self.assertEqual(self.view.get_run_edit_text(), "1-4")
+
+    @run_test_with_and_without_threading
+    def test_that_increment_run_increments_the_lower_end_of_the_range_of_loaded_runs(self):
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(return_value=([5], 5, "file5.nxs"))
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames, ["file2.nxs", "file3.nxs", "file4.nxs", "file5.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[2], [3], [4], [5]])
+        six.assertCountEqual(self, self.model.loaded_runs, [2, 3, 4, 5])
+
+        self.assertEqual(self.view.get_run_edit_text(), "2-5")
+
+    @run_test_with_and_without_threading
+    def test_that_if_decrement_run_fails_the_data_are_returned_to_previous_state(self):
+
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames, ["file2.nxs", "file3.nxs", "file4.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[2], [3], [4]])
+        six.assertCountEqual(self, self.model.loaded_runs, [2, 3, 4])
+
+        self.assertEqual(self.view.get_run_edit_text(), "2-4")
+
+    @run_test_with_and_without_threading
+    def test_that_if_increment_run_fails_the_data_are_returned_to_previous_state(self):
+
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        six.assertCountEqual(self, self.model.loaded_filenames, ["file2.nxs", "file3.nxs", "file4.nxs"])
+        six.assertCountEqual(self, self.model.loaded_workspaces, [[2], [3], [4]])
+        six.assertCountEqual(self, self.model.loaded_runs, [2, 3, 4])
+
+        self.assertEqual(self.view.get_run_edit_text(), "2-4")
+
+    @run_test_with_and_without_threading
+    def test_that_if_increment_run_fails_warning_message_is_displayed(self):
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_increment_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_that_if_decrement_run_fails_warning_message_is_displayed(self):
+        self.load_runs([2, 3, 4], ["file2.nxs", "file3.nxs", "file4.nxs"], [[2], [3], [4]])
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(side_effect=self.load_failure)
+
+        self.presenter.handle_decrement_run()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_run_widget/loadrun_presenter_single_file_test.py b/scripts/test/Muon/load_run_widget/loadrun_presenter_single_file_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..57574d887e8e91ae29f310c93323611597523b7c
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_presenter_single_file_test.py
@@ -0,0 +1,121 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import sys
+import os
+
+from Muon.GUI.Common.load_run_widget.model import LoadRunWidgetModel
+from Muon.GUI.Common.load_run_widget.view import LoadRunWidgetView
+from Muon.GUI.Common.load_run_widget.presenter import LoadRunWidgetPresenter
+from Muon.GUI.Common import mock_widget
+from Muon.GUI.Common.muon_load_data import MuonLoadData
+
+import unittest
+
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+from PyQt4 import QtGui
+
+
+class LoadRunWidgetPresenterTest(unittest.TestCase):
+    def run_test_with_and_without_threading(test_function):
+        def run_twice(self):
+            test_function(self)
+            self.setUp()
+            self.presenter._use_threading = False
+            test_function(self)
+
+        return run_twice
+
+    def wait_for_thread(self, thread_model):
+        if thread_model:
+            thread_model._thread.wait()
+            self._qapp.processEvents()
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        # Store an empty widget to parent all the views, and ensure they are deleted correctly
+        self.obj = QtGui.QWidget()
+
+        self.data = MuonLoadData()
+        self.view = LoadRunWidgetView(parent=self.obj)
+        self.model = LoadRunWidgetModel(self.data)
+        self.presenter = LoadRunWidgetPresenter(self.view, self.model)
+        self.presenter.enable_multiple_files(False)
+        self.presenter.set_current_instrument("EMU")
+
+        patcher = mock.patch('Muon.GUI.Common.load_run_widget.model.load_utils')
+        self.addCleanup(patcher.stop)
+        self.load_utils_patcher = patcher.start()
+        self.load_utils_patcher.exception_message_for_failed_files.return_value = ''
+
+    def tearDown(self):
+        self.obj = None
+
+    def mock_loading_via_user_input_run(self, workspace, filename, run):
+        self.load_utils_patcher.load_workspace_from_filename = mock.Mock(
+            return_value=(workspace, run, filename))
+        self.view.set_run_edit_text("1234")
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # TESTS
+    # ------------------------------------------------------------------------------------------------------------------
+
+    @run_test_with_and_without_threading
+    def test_model_and_view_initialized_to_contain_no_data(self):
+        self.assertEqual(self.presenter.filenames, [])
+        self.assertEqual(self.presenter.runs, [])
+        self.assertEqual(self.presenter.workspaces, [])
+
+        self.assertEqual(self.view.get_run_edit_text(), "")
+
+    @run_test_with_and_without_threading
+    def test_user_can_enter_a_run_and_load_it_in_single_file_mode(self):
+        self.mock_loading_via_user_input_run([1, 2, 3], "EMU00001234.nxs", 1234)
+
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, ["EMU00001234.nxs"])
+        self.assertEqual(self.presenter.runs, [1234])
+        self.assertEqual(self.presenter.workspaces, [[1, 2, 3]])
+
+    @run_test_with_and_without_threading
+    def test_warning_message_displayed_if_user_enters_multiple_files_in_single_file_mode(self):
+        self.presenter.enable_multiple_files(False)
+        self.view.warning_popup = mock.Mock()
+        self.view.set_run_edit_text("1234,1235,1236")
+
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.view.warning_popup.call_count, 1)
+
+    @run_test_with_and_without_threading
+    def test_data_reverts_to_previous_entry_if_user_enters_multiple_files_in_single_file_mode(self):
+        self.presenter.enable_multiple_files(False)
+
+        # Load some data
+        self.mock_loading_via_user_input_run([1], "1234.nxs", 1234)
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.view.warning_popup = mock.Mock()
+        self.view.set_run_edit_text("1234,1235,1236")
+
+        self.presenter.handle_run_changed_by_user()
+        self.wait_for_thread(self.presenter._load_thread)
+
+        self.assertEqual(self.presenter.filenames, ["1234.nxs"])
+        self.assertEqual(self.presenter.runs, [1234])
+        self.assertEqual(self.presenter.workspaces, [[1]])
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/load_run_widget/loadrun_view_test.py b/scripts/test/Muon/load_run_widget/loadrun_view_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..28ebbc61702c56dc6b2c467fff4d01214dd6a843
--- /dev/null
+++ b/scripts/test/Muon/load_run_widget/loadrun_view_test.py
@@ -0,0 +1,72 @@
+from Muon.GUI.Common.load_run_widget.view import LoadRunWidgetView
+import unittest
+from Muon.GUI.Common import mock_widget
+
+
+class LoadRunWidgetViewTest(unittest.TestCase):
+
+    def setUp(self):
+        self._qapp = mock_widget.mockQapp()
+        self.view = LoadRunWidgetView()
+        self.view.run_edit.insert('')
+
+    def test_run_number_line_edit_doesnt_accept_alphabetical(self):
+        self.view.run_edit.insert('h')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '')
+
+    def test_run_number_line_edit_accepts_simple_number(self):
+        self.view.run_edit.insert('10000')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000')
+
+    def test_run_number_line_edit_accepts_dash_list(self):
+        self.view.run_edit.insert('10000-10')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000-10')
+
+    def test_run_number_line_edit_accepts_comma_list(self):
+        self.view.run_edit.insert('10000,10001')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000,10001')
+
+    def test_run_number_line_edit_accepts_comma_list_with_spaces(self):
+        self.view.run_edit.insert('10000  , 10001')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000  , 10001')
+
+    def test_run_number_line_edit_more_than_2_comma_entries(self):
+        self.view.run_edit.insert('10000,10001,10002')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000,10001,10002')
+
+    def test_run_number_line_edit_accepts_mix_of_ranges_and_commas(self):
+        self.view.run_edit.insert('10000,10001-10002')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '10000,10001-10002')
+
+    def test_run_number_line_edit_does_not_accept_other_special_characters(self):
+        self.view.run_edit.insert('+')
+        self.view.run_edit.insert('=')
+        self.view.run_edit.insert('<')
+        self.view.run_edit.insert('>')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '')
+
+    def test_mixture_of_numbers_and_letters_fails(self):
+        self.view.run_edit.insert('22-3a')
+        result = self.view.run_edit.text()
+
+        self.assertEqual(result, '')
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/utilities/muon_group_test.py b/scripts/test/Muon/utilities/muon_group_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..1539190b6b587acb57608c66da6801b80f9e978a
--- /dev/null
+++ b/scripts/test/Muon/utilities/muon_group_test.py
@@ -0,0 +1,107 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import unittest
+
+from Muon.GUI.Common.muon_group import MuonGroup
+from Muon.GUI.Common.ADSHandler.muon_workspace_wrapper import MuonWorkspaceWrapper
+from mantid.simpleapi import CreateWorkspace
+
+
+class MuonGroupTest(unittest.TestCase):
+    """
+    The MuonGroup object encapsulates the information the describes a group:
+
+    - Its name (string)
+    - A list of detector ids (list of ints)
+    - A workspace (Optional)
+
+    It is intended to be lightweight, but with some type checking and basic logic, intended
+    to prevent obvious misuse. The class is used by the MuonAnalysis interface and so these
+    tests should be amended with care.
+    """
+
+    def test_that_cannot_initialize_MuonGroup_without_name(self):
+        with self.assertRaises(TypeError):
+            MuonGroup()
+
+    def test_that_MuonGroup_name_is_set_correctly(self):
+        group = MuonGroup(group_name="group1")
+
+        self.assertEqual(group.name, "group1")
+
+    def test_that_cannot_set_new_name_on_group(self):
+        group = MuonGroup(group_name="group1")
+
+        with self.assertRaises(AttributeError):
+            group.name = "new_name"
+        self.assertEqual(group.name, "group1")
+
+    def test_that_can_set_workspace_if_MuonWorkspace_object(self):
+        group = MuonGroup(group_name="group1")
+        dataX = [0, 1, 2, 3, 4, 5]
+        dataY = [10, 20, 30, 20, 10]
+        input_workspace = CreateWorkspace(dataX, dataY)
+
+        self.assertIsNone(group.workspace)
+        group.workspace = MuonWorkspaceWrapper(input_workspace)
+        self.assertIsNotNone(group.workspace)
+
+    def test_that_AttributeError_thrown_if_setting_workspace_to_non_MuonWorkspace_object(self):
+        group = MuonGroup(group_name="group1")
+        self.assertIsNone(group.workspace)
+
+        with self.assertRaises(AttributeError):
+            group.workspace = [1, 2, 3]
+        self.assertIsNone(group.workspace)
+
+    def test_that_detector_ids_cannot_be_set_as_string(self):
+        group = MuonGroup(group_name="group1")
+
+        with self.assertRaises(AttributeError):
+            group.detectors = "1"
+            group.detectors = "[1]"
+            group.detectors = "1,2"
+
+    def test_that_detectors_set_as_list_of_ints_is_set_correctly(self):
+        group = MuonGroup(group_name="group1")
+
+        group.detectors = [1, 2, 3, 4, 5]
+
+        self.assertEqual(group.detectors, [1, 2, 3, 4, 5])
+
+    def test_that_detectors_always_in_ascending_order(self):
+        group = MuonGroup(group_name="group1")
+
+        group.detectors = [5, 4, 3, 2, 1]
+
+        self.assertEqual(group.detectors, [1, 2, 3, 4, 5])
+
+    def test_that_duplicated_detectors_are_removed(self):
+        group = MuonGroup(group_name="group1")
+
+        group.detectors = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
+
+        self.assertEqual(group.detectors, [1, 2, 3, 4, 5])
+
+    def test_that_number_of_detectors_is_correct(self):
+        group = MuonGroup(group_name="group1")
+
+        group.detectors = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
+
+        self.assertEqual(group.n_detectors, 5)
+
+    def test_that_can_have_group_with_no_detectors(self):
+        group = MuonGroup(group_name="group1")
+
+        group.detectors = []
+
+        self.assertEqual(group.detectors, [])
+        self.assertEqual(group.n_detectors, 0)
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/Muon/utilities/muon_pair_test.py b/scripts/test/Muon/utilities/muon_pair_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..861fc67bade0431252c595da3bf378e03b27be8e
--- /dev/null
+++ b/scripts/test/Muon/utilities/muon_pair_test.py
@@ -0,0 +1,99 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+import unittest
+
+from Muon.GUI.Common.muon_pair import MuonPair
+from Muon.GUI.Common.ADSHandler.muon_workspace_wrapper import MuonWorkspaceWrapper
+from mantid.simpleapi import CreateWorkspace
+
+
+class MuonPairTest(unittest.TestCase):
+    """
+    The MuonPair object encapsulates the information the describes a pair:
+
+    - Its name
+    - The name of the two groups that are combined to form the pair
+    - The value of alpha
+    - A workspace (Optional)
+
+    It is intended to be lightweight, but with some type checking and basic logic, intended
+    to prevent obvious misuse. The class is used by the MuonAnalysis interface and so these
+    tests should be amended with care.
+    """
+
+    def test_that_cannot_initialize_MuonPair_without_name(self):
+        with self.assertRaises(TypeError):
+            MuonPair()
+
+    def test_that_MuonPair_name_is_set_correctly(self):
+        pair = MuonPair(pair_name="pair1")
+
+        self.assertEqual(pair.name, "pair1")
+
+    def test_that_cannot_set_new_name_on_pair(self):
+        pair = MuonPair(pair_name="pair1")
+
+        with self.assertRaises(AttributeError):
+            pair.name = "new_name"
+        self.assertEqual(pair.name, "pair1")
+
+    def test_that_can_get_and_set_group1_name(self):
+        pair = MuonPair(pair_name="pair1")
+
+        pair.forward_group = "group1"
+
+        self.assertEqual(pair.forward_group, "group1")
+
+    def test_that_can_get_and_set_group2_name(self):
+        pair = MuonPair(pair_name="pair1")
+
+        pair.backward_group = "group2"
+
+        self.assertEqual(pair.backward_group, "group2")
+
+    def test_that_can_only_set_workspace_if_MuonWorkspace_object(self):
+        pair = MuonPair(pair_name="pair1")
+        self.assertIsNone(pair.workspace)
+        dataX = [0, 1, 2, 3, 4, 5]
+        dataY = [10, 20, 30, 20, 10]
+        input_workspace = CreateWorkspace(dataX, dataY)
+
+        pair.workspace = MuonWorkspaceWrapper(input_workspace)
+        self.assertIsNotNone(pair.workspace)
+
+    def test_that_AttributeError_thrown_if_setting_workspace_to_non_MuonWorkspace_object(self):
+        pair = MuonPair(pair_name="pair1")
+
+        self.assertIsNone(pair.workspace)
+        with self.assertRaises(AttributeError):
+            pair.workspace = [1, 2, 3]
+        self.assertIsNone(pair.workspace)
+
+    def test_that_can_set_and_get_float_value_for_alpha(self):
+        pair = MuonPair(pair_name="pair1")
+
+        pair.alpha = 2.0
+
+        self.assertEqual(pair.alpha, 2.0)
+
+    def test_that_can_set_string_value_for_alpha(self):
+        pair = MuonPair(pair_name="pair1")
+
+        pair.alpha = "2.0"
+
+        self.assertEqual(pair.alpha, 2.0)
+
+    def test_that_cannot_add_negative_alpha(self):
+        pair = MuonPair(pair_name="pair1")
+
+        with self.assertRaises(AttributeError):
+            pair.alpha = -1.0
+            pair.alpha = "-1.0"
+
+
+if __name__ == '__main__':
+    unittest.main(buffer=False, verbosity=2)
diff --git a/scripts/test/SANS/gui_logic/CMakeLists.txt b/scripts/test/SANS/gui_logic/CMakeLists.txt
index 0e40f3be69ff3cf74112c5e5a04cc6fe275b7e7b..66bea7107f513c9f6cf15eacf9a63beb1ef457e2 100644
--- a/scripts/test/SANS/gui_logic/CMakeLists.txt
+++ b/scripts/test/SANS/gui_logic/CMakeLists.txt
@@ -23,6 +23,7 @@ set ( TEST_PY_FILES
   diagnostics_page_model_test.py
   create_state_test.py
   batch_process_runner_test.py
+  save_other_presenter_test.py
   create_file_information_test.py
 )
 
diff --git a/scripts/test/SANS/gui_logic/gui_common_test.py b/scripts/test/SANS/gui_logic/gui_common_test.py
index c4ae5de868315a6230444e080bbc24afb74a6842..cad876b4458639ea907ab322316e982366cd472f 100644
--- a/scripts/test/SANS/gui_logic/gui_common_test.py
+++ b/scripts/test/SANS/gui_logic/gui_common_test.py
@@ -9,10 +9,15 @@ from __future__ import (absolute_import, division, print_function)
 import unittest
 
 import mantid
+from mantid.kernel import config
 
 from sans.gui_logic.gui_common import (get_reduction_mode_strings_for_gui, get_reduction_selection,
-                                       get_string_for_gui_from_reduction_mode)
+                                       get_string_for_gui_from_reduction_mode,
+                                       get_batch_file_dir_from_path,
+                                       add_dir_to_datasearch,
+                                       remove_dir_from_datasearch)
 from sans.common.enums import (SANSInstrument, ISISReductionMode)
+import os
 
 
 class GuiCommonTest(unittest.TestCase):
@@ -67,6 +72,58 @@ class GuiCommonTest(unittest.TestCase):
         self.do_test_reduction_mode_string(SANSInstrument.NoInstrument, ISISReductionMode.LAB, "LAB")
         self.do_test_reduction_mode_string(SANSInstrument.NoInstrument, ISISReductionMode.HAB, "HAB")
 
+    def test_that_batch_file_dir_returns_none_if_no_forwardslash(self):
+        a_path = "test_batch_file_path.csv"
+        result = get_batch_file_dir_from_path(a_path)
+        self.assertEqual("", result, "Expected empty string. Returned value was {}".format(result))
+
+    def test_correct_batch_file_dir_returned(self):
+        a_path = "A/Test/Path/batch_file.csv"
+        result = get_batch_file_dir_from_path(a_path)
+
+        expected_result = "A/Test/Path/"
+        self.assertEqual(result, expected_result)
+
+    def test_datasearch_directories_updated(self):
+        current_dirs = "A/Path/"
+        batch_file = "A/Path/To/Batch/File/batch_file.csv"
+        _, result = add_dir_to_datasearch(batch_file, current_dirs)
+
+        expected_result = "A/Path/;A/Path/To/Batch/File/"
+        self.assertEqual(expected_result, result)
+
+    def test_empty_string_not_added_to_datasearch_directories(self):
+        current_dirs = "A/Path/"
+        batch_file = "batch_file.csv"
+        _, result = add_dir_to_datasearch(batch_file, current_dirs)
+
+        expected_result = "A/Path/"
+        self.assertEqual(expected_result, result)
+
+    def test_existing_directory_not_added_to_datasearch_directories(self):
+        current_dirs = "A/Path/;A/Path/Already/Added/"
+        batch_file = "A/Path/Already/Added/batch_file.csv"
+        _, result = add_dir_to_datasearch(batch_file, current_dirs)
+
+        expected_result = "A/Path/;A/Path/Already/Added/"
+        self.assertEqual(expected_result, result)
+
+    def test_directories_unchanged_when_removing_empty_string(self):
+        current_dirs = "A/Path/;Another/Path/"
+        file_to_remove = ""
+        result = remove_dir_from_datasearch(file_to_remove, current_dirs)
+
+        expected_result = "A/Path/;Another/Path/"
+        self.assertEqual(result, expected_result)
+
+    def test_correct_directory_removed(self):
+        current_dirs = "A/Path/;Another/Path/;A/Final/Path/"
+        file_to_remove = "Another/Path/"
+        result = remove_dir_from_datasearch(file_to_remove, current_dirs)
+
+        expected_result = "A/Path/;A/Final/Path/"
+        self.assertEqual(expected_result, result)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py
index 570d3430a3e6c54d38ce9233cd2dcb34c4361c5a..e1b9374a0697f2b6aa9b79ff94302aea89e24529 100644
--- a/scripts/test/SANS/gui_logic/run_tab_presenter_test.py
+++ b/scripts/test/SANS/gui_logic/run_tab_presenter_test.py
@@ -267,6 +267,19 @@ class RunTabPresenterTest(unittest.TestCase):
         self._remove_files(user_file_path=user_file_path)
         self.os_patcher.start()
 
+    def test_batch_file_dir_not_added_to_config_if_batch_file_load_fails(self):
+        presenter = RunTabPresenter(SANSFacility.ISIS)
+        user_file_path = create_user_file(sample_user_file)
+        view, settings_diagnostic_tab, masking_table = create_mock_view(user_file_path, "A/Path/batch_file.csv")
+        presenter.set_view(view)
+
+        presenter.on_batch_file_load()
+        config_dirs = config["datasearch.directories"]
+        result = "A/Path/" in config_dirs
+
+        self.assertFalse(result, "We do not expect A/Path/ to be added to config, "
+                                 "datasearch.directories is now {}".format(config_dirs))
+
     def test_that_gets_states_from_view(self):
         # Arrange
         batch_file_path, user_file_path, presenter, _ = self._get_files_and_mock_presenter(BATCH_FILE_TEST_CONTENT_2)
diff --git a/scripts/test/SANS/gui_logic/save_other_presenter_test.py b/scripts/test/SANS/gui_logic/save_other_presenter_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..e1ecbf325564d2ad05d4e5aa09b2d42f854f7e6c
--- /dev/null
+++ b/scripts/test/SANS/gui_logic/save_other_presenter_test.py
@@ -0,0 +1,84 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+from __future__ import (absolute_import, division, print_function)
+import unittest
+import sys
+from mantid import ConfigService
+from sans.gui_logic.presenter.save_other_presenter import SaveOtherPresenter
+if sys.version_info.major == 3:
+    from unittest import mock
+else:
+    import mock
+
+
+class SaveOtherPresenterTest(unittest.TestCase):
+    def setUp(self):
+        self.mock_view = mock.MagicMock()
+        self.presenter = SaveOtherPresenter()
+        self.presenter.set_view(view=self.mock_view)
+        self.current_directory = ConfigService['defaultsave.directory']
+
+    def test_that_sets_initialises_and_subscribes_to_view(self):
+        self.assertEqual(self.presenter._view, self.mock_view)
+        self.mock_view.subscribe.assert_called_once_with(self.presenter)
+
+    def test_on_cancel_clicked_window_closes(self):
+        self.presenter.on_cancel_clicked()
+
+        self.mock_view.done.assert_called_once_with(0)
+
+    def test_on_browse_clicked_launches_browse_window(self):
+        self.presenter.on_browse_clicked()
+
+        self.mock_view.launch_file_browser.assert_called_once_with(self.current_directory)
+
+    def test_on_file_name_changed_updates_filename(self):
+        self.presenter.on_file_name_changed('test_file')
+
+        self.assertEqual(self.presenter.filename, 'test_file')
+
+    def test_on_item_selection_changed_changes_label_to_suffix_on_multi_selection(self):
+        self.mock_view.get_selected_workspaces.return_value = ['workspace_1', 'workspace_2']
+        self.presenter.on_item_selection_changed()
+
+        self.mock_view.rename_filebox.assert_called_once_with('Suffix')
+
+    def test_on_item_selection_changed_enables_filename_if_single_selection(self):
+        self.mock_view.get_selected_workspaces.return_value = ['workspace_1']
+        self.presenter.on_item_selection_changed()
+
+        self.mock_view.rename_filebox.assert_called_once_with('Filename')
+
+    def test_on_directory_changed_updates_current_directory(self):
+        self.presenter.on_directory_changed('new_dir')
+
+        self.assertEqual(self.presenter.current_directory, 'new_dir')
+
+    def test_get_filenames_returns_full_path_list_for_multi_selection(self):
+        self.presenter.on_directory_changed('base_dir/')
+        returned_list = self.presenter.get_filenames(['workspace_1', 'workspace_2'], 'filename_to_save')
+        expected_list = ['base_dir/workspace_1_filename_to_save', 'base_dir/workspace_2_filename_to_save']
+
+        self.assertEqual(expected_list, returned_list)
+
+    def test_get_filenames_returns_specified_name_for_single_selection(self):
+        self.presenter.on_directory_changed('base_dir/')
+        returned_list = self.presenter.get_filenames(['workspace_1'], 'filename_to_save')
+        expected_list = ['base_dir/filename_to_save']
+
+        self.assertEqual(expected_list, returned_list)
+
+    def test_get_filenames_returns_workspace_name_for_no_specified_name(self):
+        self.presenter.on_directory_changed('base_dir/')
+        returned_list = self.presenter.get_filenames(['workspace_1'], '')
+        expected_list = ['base_dir/workspace_1']
+
+        self.assertEqual(expected_list, returned_list)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/scripts/wish/reduce.py b/scripts/wish/reduce.py
deleted file mode 100644
index 31d1868d68056fcf15c819a968ea692999fef0bc..0000000000000000000000000000000000000000
--- a/scripts/wish/reduce.py
+++ /dev/null
@@ -1,919 +0,0 @@
-# flake8: noqa
-import sys
-from mantid.simpleapi import *
-import numpy as n
-import mantid.simpleapi as mantid
-
-sys.path.insert(0, "/opt/Mantid/bin")
-sys.path.append("/isis/NDXWISH/user/scripts/autoreduction")
-
-
-def Wish_Run(input, cal_directory, user_directory, outputfolder, deleteWorkspace):
-    __name__ = input
-    print("Running")
-    cal_dir = cal_directory
-    use_folder = user_directory
-    out_fold = outputfolder
-
-    def validate(input_file, output_dir):
-        """
-        Autoreduction validate Function
-        -------------------------------
-
-        Function to ensure that the files we want to use in reduction exist.
-        Please add any files/directories to the required_files/dirs lists.
-        """
-        print("Running validation")
-        required_files = [input_file]
-        required_dirs = [output_dir]
-        for file_path in required_files:
-            if not os.path.isfile(file_path):
-                raise RuntimeError("Unable to find file: {}".format(file_path))
-        for dir in required_dirs:
-            if not os.path.isdir(dir):
-                raise RuntimeError("Unable to find directory: {}".format(dir))
-        print("Validation successful")
-
-    # Get the run number from the input data path
-    def get_run_number(data_path):
-        data_path = data_path.split('/')[-1]  # Get the file name
-        data_path = data_path.split('.')[0]  # Remove the extension
-        data_path = data_path[4:]  # Remove the WISH prefix
-        return int(data_path)
-
-    # Get the valid wavelength range, i.e. excluding regions where choppers cut
-    def WISH_getlambdarange():
-        return 0.7, 10.35
-
-    def WISH_setuser(usern):
-        global username
-        username = usern
-
-    def WISH_setdatadir(directory="/archive/ndxwish/Instrument/data/cycle_09_5/"):
-        global wish_datadir
-        wish_datadir = directory
-
-    def WISH_setuserdir(directory):
-        global wish_userdir
-        wish_userdir = directory
-
-    def WISH_setdatafile(filename):
-        global wish_datafile
-        wish_datafile = filename
-
-    def WISH_getdatafile():
-        return wish_datafile
-
-    def WISH_datadir():
-        return wish_datadir
-
-    def WISH_userdir(cycle='cycle_10_1'):
-        return wish_userdir
-
-    def WISH_getcalibration(cycle="11_4"):
-        return cal_dir
-
-    # def WISH_setcalibration(directory):
-        # wish_userdir = cal_dir
-
-    #   This is no longer needed unless run manually
-    def WISH_startup(usern, cycle='14_3'):
-        global userdatadir
-        global userdataprocessed
-        global mtdplt
-        import sys
-        sys.path.append('/home/' + usern + '/Scripts/')
-        # import Mantid_plotting as mtdplt
-        # userdatadir="/home/rawdata/"
-        # userdatadir = "/archive/ndxwish/Instrument/data/cycle_" + cycle + '/'
-        userdatadir = use_folder
-        WISH_setdatadir(userdatadir)
-        print "Raw Data in :   ", userdatadir
-        # userdataprocessed =  r"/home/sjenkins/Documents/WISH"
-        userdataprocessed = out_fold
-        WISH_setuserdir(directory=userdataprocessed)
-        print "Processed Data in :   ", userdataprocessed
-        return
-
-    # Returns the calibration filename
-    def WISH_cal(panel):
-        return WISH_getcalibration() + "WISH_cycle_10_3_noends_10to10.cal"
-        # return "/home/mp43/Desktop/Si_Mar15/test_detOffsets_SiMar15_noends.cal"
-        # return "/home/ryb18365/Desktop/WISH_cycle_10_3_noends_10to10_dodgytubesremoved.cal"
-
-    # Returns the grouping filename
-    def WISH_group():
-        return WISH_getcalibration() + "WISH_cycle_10_3_noends_10to10.cal"
-        # return "/home/mp43/Desktop/Si_Mar15/test_detOffsets_SiMar15_noends.cal"
-        # return "/home/ryb18365/Desktop/WISH_cycle_10_3_noends_10to10_dodgytubesremoved.cal"
-
-    def WISH_getvana(panel, SE="candlestick", cycle="09_4"):
-        if (SE == "candlestick"):
-            if (cycle == "09_2"):
-                return WISH_getcalibration() + "vana318-" + str(panel) + "foc-rmbins-smooth50.nx5"
-            if (cycle == "09_3"):
-                return WISH_getcalibration(cycle) + "vana935-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "09_4"):
-                return WISH_getcalibration(cycle) + "vana3123-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "09_5"):
-                return WISH_getcalibration(cycle) + "vana3123-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "11_4"):
-                return WISH_getcalibration(cycle) + "vana38428-" + str(panel) + "foc-SF-SS.nxs"
-            if (cycle == "18_2"):
-                return WISH_getcalibration(cycle) + "WISHvana41865-" + str(panel) + "foc.nxs"
-        if (SE == "WISHcryo"):
-            if (cycle == "09_2"):
-                return WISH_getcalibration() + "vana318-" + str(panel) + "foc-rmbins-smooth50.nx5"
-            if (cycle == "09_3"):
-                return WISH_getcalibration(cycle) + "vana935-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "09_4"):
-                return WISH_getcalibration(cycle) + "vana3123-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "11_1"):
-                return WISH_getcalibration(cycle) + "vana17718-" + str(panel) + "foc-SS.nxs"
-            if (cycle == "11_2"):
-                return WISH_getcalibration(cycle) + "vana16812-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "11_3"):
-                return WISH_getcalibration(cycle) + "vana18590-" + str(panel) + "foc-SS-new.nxs"
-            if (cycle == "18_2"):
-                return WISH_getcalibration(cycle) + "WISHvana41865-" + str(panel) + "foc.nxs"
-
-    def split_string(t):
-        indxp = 0
-        for i in range(0, len(t)):
-            if (t[i] == "+"):
-                indxp = i
-        if (indxp != 0):
-            return int(t[0:indxp]), int(t[indxp + 1:len(t)])
-
-    def WISH_getemptyinstrument(panel, cycle="09_4"):
-        if (cycle == "09_4"):
-            return WISH_getcalibration(cycle) + "emptyinst3120-" + str(panel) + "foc.nx5"
-
-    def WISH_getempty(panel, SE="WISHcryo", cycle="09_4"):
-        if (SE == "WISHcryo"):
-            if (cycle == "09_2"):
-                return WISH_getcalibration(cycle) + "emptycryo322-" + str(panel) + "-smooth50.nx5"
-            if (cycle == "09_3"):
-                return WISH_getcalibration(cycle) + "emptycryo1725-" + str(panel) + "foc.nx5"
-            if (cycle == "09_4"):
-                return WISH_getcalibration(cycle) + "emptycryo3307-" + str(panel) + "foc.nx5"
-            if (cycle == "09_5"):
-                return WISH_getcalibration(cycle) + "emptycryo16759-" + str(panel) + "foc.nx5"
-            if (cycle == "11_1"):
-                return WISH_getcalibration(cycle) + "emptycryo17712-" + str(panel) + "foc-SS.nxs"
-            if (cycle == "11_2"):
-                return WISH_getcalibration(cycle) + "emptycryo16759-" + str(panel) + "foc-SS.nx5"
-            if (cycle == "11_3"):
-                return WISH_getcalibration(cycle) + "emptycryo17712-" + str(panel) + "foc-SS-new.nxs"
-            if (cycle == "11_4"):
-                return WISH_getcalibration(cycle) + "empty_mag20620-" + str(panel) + "foc-HR-SF.nxs"
-        if (SE == "candlestick"):
-            if (cycle == "09_4"):
-                return WISH_getcalibration(cycle) + "emptyinst3120-" + str(panel) + "foc.nxs"
-            if (cycle == "09_3"):
-                return WISH_getcalibration(cycle) + "emptyinst1726-" + str(panel) + "foc-monitor.nxs"
-            if (cycle == "11_4"):
-                return WISH_getcalibration(cycle) + "emptyinst19618-" + str(panel) + "foc-SF-S.nxs"
-            if (cycle == "17_1"):
-                return WISH_getcalibration(cycle) + "emptyinst38581-" + str(panel) + "foc.nxs"
-
-    def WISH_getfilename(run_number, ext):
-        if (ext[0] != 's'):
-            data_dir = WISH_datadir()
-        else:
-            # data_dir="/datad/ndxwish/"
-            data_dir = WISH_datadir()
-        digit = len(str(run_number))
-        filename = os.path.join(data_dir, "WISH")
-        for i in range(0, 8 - digit):
-            filename = filename + "0"
-        filename += str(run_number) + "." + ext
-        return filename
-
-    def WISH_returnpanel(panel):
-        if (panel == 1):
-            min = 6
-            max = 19461
-        elif (panel == 2):
-            min = 19462
-            max = 38917
-        elif (panel == 3):
-            min = 38918
-            max = 58373
-        elif (panel == 4):
-            min = 58374
-            max = 77829
-        elif (panel == 5):
-            min = 77830
-            max = 97285
-        elif (panel == 6):
-            min = 97286
-            max = 116741
-        elif (panel == 7):
-            min = 116742
-            max = 136197
-        elif (panel == 8):
-            min = 136198
-            max = 155653
-        elif (panel == 9):
-            min = 155654
-            max = 175109
-        elif (panel == 10):
-            min = 175110
-            max = 194565
-        elif (panel == 0):
-            min = 6
-            max = 194565
-        print panel
-        return min, max
-
-    # This function no longer works for a list of numbers
-    # Reads a wish data file return a workspace with a short name
-    def WISH_read(number, panel, ext):
-        if type(number) is int:
-            filename = WISH_getdatafile()  # Changed as full path is set in main now
-            ext = filename.split('.')[-1]  # Get the extension from the inputted filename
-            print "Extension is: " + ext
-            # if (ext[0:10]=="nxs_event"):
-            #    filename=WISH_getfilename(number,"nxs")
-            print "will be reading filename..." + filename
-            min, max = WISH_returnpanel(panel)
-            if (panel != 0):
-                output = "w" + str(number) + "-" + str(panel)
-            else:
-                output = "w" + str(number)
-            if (ext == "raw"):
-                mantid.LoadRaw(Filename=filename, OutputWorkspace=output, SpectrumMin=str(min), SpectrumMax=str(max),
-                               LoadLogFiles="0")
-                mantid.MaskBins(InputWorkspace=output, OutputWorkspace=output, XMin=99900, XMax=106000)
-                print "standard raw file loaded"
-            if (ext[0] == "s"):
-                mantid.LoadRaw(Filename=filename, OutputWorkspace=output, SpectrumMin=str(min), SpectrumMax=str(max),
-                               LoadLogFiles="0")
-                mantid.MaskBins(InputWorkspace=output, OutputWorkspace=output, XMin=99900, XMax=106000)
-                print "sav file loaded"
-            if (ext == "nxs_event"):
-                mantid.LoadEventNexus(Filename=filename, OutputWorkspace=output, LoadMonitors='1')
-                mantid.RenameWorkspace(output + "_monitors", "w" + str(number) + "_monitors")
-                mantid.Rebin(InputWorkspace=output, OutputWorkspace=output, Params='6000,-0.00063,110000')
-                mantid.ConvertToMatrixWorkspace(output, output)
-                min, max = WISH_returnpanel(panel)
-                mantid.CropWorkspace(InputWorkspace=output, OutputWorkspace=output, StartWorkspaceIndex=min - 6,
-                                     EndWorkspaceIndex=max - 6)
-                mantid.MaskBins(InputWorkspace=output, OutputWorkspace=output, XMin=99900, XMax=106000)
-                print "full nexus eventfile loaded"
-            if (ext[0:10] == "nxs_event_"):
-                label, tmin, tmax = split_string_event(ext)
-                output = output + "_" + label
-                if (tmax == "end"):
-                    mantid.LoadEventNexus(Filename=filename, OutputWorkspace=output, FilterByTimeStart=tmin,
-                                          LoadMonitors='1',
-                                          MonitorsAsEvents='1', FilterMonByTimeStart=tmin)
-                else:
-                    mantid.LoadEventNexus(Filename=filename, OutputWorkspace=output, FilterByTimeStart=tmin,
-                                          FilterByTimeStop=tmax,
-                                          LoadMonitors='1', MonitorsAsEvents='1', FilterMonByTimeStart=tmin,
-                                          FilterMonByTimeStop=tmax)
-                    mantid.RenameWorkspace(output + "_monitors", "w" + str(number) + "_monitors")
-                print "renaming monitors done!"
-                mantid.Rebin(InputWorkspace=output, OutputWorkspace=output, Params='6000,-0.00063,110000')
-                mantid.ConvertToMatrixWorkspace(output, output)
-                min, max = WISH_returnpanel(panel)
-                mantid.CropWorkspace(InputWorkspace=output, OutputWorkspace=output, StartWorkspaceIndex=min - 6,
-                                     EndWorkspaceIndex=max - 6)
-                mantid.MaskBins(output, output, XMin=99900, XMax=106000)
-                print "nexus event file chopped"
-            if (ext == "nxs"):
-                mantid.LoadNexus(Filename=filename, OutputWorkspace=output, SpectrumMin=str(min), SpectrumMax=str(max))
-                mantid.MaskBins(InputWorkspace=output, OutputWorkspace=output, XMin=99900, XMax=106000)
-                mantid.ConvertUnits(InputWorkspace=output, OutputWorkspace=output, Target="Wavelength", Emode="Elastic")
-                print "standard histo nxs file loaded"
-        else:
-
-            n1, n2 = split_string(number)
-            output = "w" + str(n1) + "_" + str(n2) + "-" + str(panel)
-            filename = WISH_getfilename(n1, ext)
-            print "reading filename..." + filename
-            min, max = WISH_returnpanel(panel)
-            output1 = "w" + str(n1) + "-" + str(panel)
-            mantid.LoadRaw(Filename=filename, OutputWorkspace=output1, SpectrumMin=str(min), SpectrumMax=str(max),
-                           LoadLogFiles="0")
-            filename = WISH_getfilename(n2, ext)
-            print "reading filename..." + filename
-            min, max = WISH_returnpanel(panel)
-            output2 = "w" + str(n2) + "-" + str(panel)
-            mantid.LoadRaw(Filename=filename, OutputWorkspace=output2, SpectrumMin=str(min), SpectrumMax=str(max),
-                           LoadLogFiles="0")
-            mantid.MergeRuns(output1 + "," + output2, output)
-            mantid.DeleteWorkspace(output1)
-            mantid.DeleteWorkspace(output2)
-            mantid.ConvertUnits(InputWorkspace=output, OutputWorkspace=output, Target="Wavelength", Emode="Elastic")
-        lmin, lmax = WISH_getlambdarange()
-        mantid.CropWorkspace(InputWorkspace=output, OutputWorkspace=output, XMin=lmin, XMax=lmax)
-        monitor = WISH_process_incidentmon(number, ext, spline_terms=70, debug=False)
-        print "first norm to be done"
-        mantid.NormaliseToMonitor(InputWorkspace=output, OutputWorkspace=output + "norm1", MonitorWorkspace=monitor)
-        print "second norm to be done"
-        mantid.NormaliseToMonitor(InputWorkspace=output + "norm1", OutputWorkspace=output + "norm2",
-                                  MonitorWorkspace=monitor,
-                                  IntegrationRangeMin=0.7, IntegrationRangeMax=10.35)
-        mantid.DeleteWorkspace(output)
-        mantid.DeleteWorkspace(output + "norm1")
-        mantid.RenameWorkspace(InputWorkspace=output + "norm2", OutputWorkspace=output)
-        mantid.ConvertUnits(InputWorkspace=output, OutputWorkspace=output, Target="TOF", EMode="Elastic")
-        mantid.ReplaceSpecialValues(InputWorkspace=output, OutputWorkspace=output, NaNValue=0.0, NaNError=0.0,
-                                    InfinityValue=0.0,
-                                    InfinityError=0.0)
-        return output
-
-    # Focus dataset for a given panel and return the workspace
-    def WISH_focus_onepanel(work, focus, panel):
-        mantid.AlignDetectors(InputWorkspace=work, OutputWorkspace=work, CalibrationFile=WISH_cal(panel))
-        mantid.DiffractionFocussing(InputWorkspace=work, OutputWorkspace=focus, GroupingFileName=WISH_group())
-        if (panel == 5 or panel == 6):
-            mantid.CropWorkspace(InputWorkspace=focus, OutputWorkspace=focus, XMin=0.3)
-        return focus
-
-    def WISH_split(focus):
-        for i in range(0, 11):
-            out = focus[0:len(focus) - 3] + "-" + str(i + 1) + "foc"
-            mantid.ExtractSingleSpectrum(InputWorkspace=focus, OutputWorkspace=out, WorkspaceIndex=i)
-            mantid.DeleteWorkspace(focus)
-        return
-
-    def WISH_focus(work, panel):
-        focus = work + "foc"
-        if (panel != 0):
-            WISH_focus_onepanel(work, focus, panel)
-        else:
-            WISH_focus_onepanel(work, focus, panel)
-            WISH_split(focus)
-
-    def WISH_process(number, panel, ext, SEsample="WISHcryo", emptySEcycle="09_4", SEvana="candlestick",
-                     cyclevana="09_4",
-                     absorb=False, nd=0.0, Xs=0.0, Xa=0.0, h=0.0, r=0.0):
-        w = WISH_read(number, panel, ext)
-        print "file read and normalized"
-        if (absorb):
-            mantid.ConvertUnits(InputWorkspace=w, OutputWorkspace=w, Target="Wavelength", EMode="Elastic")
-            mantid.CylinderAbsorption(InputWorkspace=w, OutputWorkspace="T",
-                                      CylinderSampleHeight=h, CylinderSampleRadius=r, AttenuationXSection=Xa,
-                                      ScatteringXSection=Xs, SampleNumberDensity=nd,
-                                      NumberOfSlices="10", NumberOfAnnuli="10", NumberOfWavelengthPoints="25",
-                                      ExpMethod="Normal")
-            mantid.Divide(LHSWorkspace=w, RHSWorkspace="T", OutputWorkspace=w)
-            mantid.DeleteWorkspace("T")
-            mantid.ConvertUnits(InputWorkspace=w, OutputWorkspace=w, Target="TOF", EMode="Elastic")
-        wfoc = WISH_focus(w, panel)
-        print "focussing done!"
-        if type(number) is int:
-            wfocname = "w" + str(number) + "-" + str(panel) + "foc"
-            if (len(ext) > 9):
-                label, tmin, tmax = split_string_event(ext)
-                wfocname = "w" + str(number) + "-" + str(panel) + "_" + label + "foc"
-        else:
-            n1, n2 = split_string(number)
-            wfocname = "w" + str(n1) + "_" + str(n2) + "-" + str(panel) + "foc"
-        if deleteWorkspace:
-            mantid.DeleteWorkspace(w)
-        if (panel == 1):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-        elif (panel == 2):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-        elif (panel == 3):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-        elif (panel == 4):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-        elif (panel == 5):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-        elif (panel == 6):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-        elif (panel == 7):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-        elif (panel == 8):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-        elif (panel == 9):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-        elif (panel == 10):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-
-        if (panel == 0):
-            for i in range(1, 11):
-                wfocname = "w" + str(number) + "-" + str(i) + "foc"
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-                mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-        # print "will try to load an empty with the name:"
-        print panel
-        print SEsample
-        print emptySEcycle
-        print WISH_getempty(panel, SEsample, emptySEcycle)
-        if (panel == 0):
-            for i in range(1, 11):
-                wfocname = "w" + str(number) + "-" + str(i) + "foc"
-                mantid.LoadNexusProcessed(Filename=WISH_getempty(i, SEsample, emptySEcycle), OutputWorkspace="empty")
-                mantid.RebinToWorkspace(WorkspaceToRebin="empty", WorkspaceToMatch=wfocname, OutputWorkspace="empty")
-                mantid.Minus(LHSWorkspace=wfocname, RHSWorkspace="empty", OutputWorkspace=wfocname)
-                mantid.DeleteWorkspace("empty")
-                print "will try to load a vanadium with the name:" + WISH_getvana(i, SEvana, cyclevana)
-                mantid.LoadNexusProcessed(Filename=WISH_getvana(i, SEvana, cyclevana), OutputWorkspace="vana")
-                mantid.RebinToWorkspace(WorkspaceToRebin="vana", WorkspaceToMatch=wfocname, OutputWorkspace="vana")
-                mantid.Divide(LHSWorkspace=wfocname, RHSWorkspace="vana", OutputWorkspace=wfocname)
-                mantid.DeleteWorkspace("vana")
-                mantid.ConvertUnits(InputWorkspace=wfocname, OutputWorkspace=wfocname, Target="TOF", EMode="Elastic")
-                mantid.ReplaceSpecialValues(InputWorkspace=wfocname, OutputWorkspace=wfocname, NaNValue=0.0,
-                                            NaNError=0.0,
-                                            InfinityValue=0.0, InfinityError=0.0)
-                mantid.SaveGSS(InputWorkspace=wfocname,
-                               Filename=os.path.join(WISH_userdir(), (str(number) + "-" + str(i) + ext + ".gss")),
-                               Append=False, Bank=1)
-                mantid.SaveFocusedXYE(wfocname,
-                                      os.path.join(WISH_userdir(), (str(number) + "-" + str(i) + ext + ".dat")))
-                mantid.SaveNexusProcessed(wfocname,
-                                          os.path.join(WISH_userdir(), (str(number) + "-" + str(i) + ext + ".nxs")))
-        else:
-            mantid.LoadNexusProcessed(Filename=WISH_getempty(panel, SEsample, emptySEcycle), OutputWorkspace="empty")
-            mantid.RebinToWorkspace(WorkspaceToRebin="empty", WorkspaceToMatch=wfocname, OutputWorkspace="empty")
-            mantid.Minus(LHSWorkspace=wfocname, RHSWorkspace="empty", OutputWorkspace=wfocname)
-            mantid.DeleteWorkspace("empty")
-            print "will try to load a vanadium with the name:" + WISH_getvana(panel, SEvana, cyclevana)
-            mantid.LoadNexusProcessed(Filename=WISH_getvana(panel, SEvana, cyclevana), OutputWorkspace="vana")
-            mantid.RebinToWorkspace(WorkspaceToRebin="vana", WorkspaceToMatch=wfocname, OutputWorkspace="vana")
-            mantid.Divide(LHSWorkspace=wfocname, RHSWorkspace="vana", OutputWorkspace=wfocname)
-            mantid.DeleteWorkspace("vana")
-            mantid.ConvertUnits(InputWorkspace=wfocname, OutputWorkspace=wfocname, Target="TOF", EMode="Elastic")
-            mantid.ReplaceSpecialValues(InputWorkspace=wfocname, OutputWorkspace=wfocname, NaNValue=0.0, NaNError=0.0,
-                                        InfinityValue=0.0, InfinityError=0.0)
-            mantid.SaveGSS(InputWorkspace=wfocname,
-                           Filename=os.path.join(WISH_userdir(), (str(number) + "-" + str(panel) + ext + ".gss")),
-                           Append=False, Bank=1)
-            mantid.SaveFocusedXYE(wfocname,
-                                  os.path.join(WISH_userdir(), (str(number) + "-" + str(panel) + ext + ".dat")))
-            mantid.SaveNexusProcessed(wfocname,
-                                      os.path.join(WISH_userdir(), (str(number) + "-" + str(panel) + ext + ".nxs")))
-        return wfocname
-
-    # Create a corrected vanadium (normalise,corrected for attenuation and empty, strip peaks) and
-    # save a a nexus processed file.
-    # It looks like smoothing of 100 works quite well
-    def WISH_createvan(van, empty, panel, smoothing, vh, vr, cycle_van="18_2", cycle_empty="17_1"):
-        WISH_startup("ffv81422", cycle_van)
-        WISH_setdatafile(WISH_getfilename(41870, "nxs"))
-        WISH_setdatadir("/archive/ndxwish/Instrument/data/cycle_" + cycle_van + "/")
-        wvan = WISH_read(van, panel, "nxs_event")
-        WISH_startup("ffv81422", cycle_empty)
-        WISH_setdatafile(WISH_getfilename(38581, "nxs"))
-        WISH_setdatadir("/archive/ndxwish/Instrument/data/cycle_" + cycle_empty + "/")
-        wempty = WISH_read(empty, panel, "nxs_event")
-        mantid.Minus(LHSWorkspace=wvan, RHSWorkspace=wempty, OutputWorkspace=wvan)
-        print "read van and empty"
-        mantid.DeleteWorkspace(wempty)
-        mantid.ConvertUnits(InputWorkspace=wvan, OutputWorkspace=wvan, Target="Wavelength", EMode="Elastic")
-        mantid.CylinderAbsorption(InputWorkspace=wvan, OutputWorkspace="T",
-                                  CylinderSampleHeight=str(vh), CylinderSampleRadius=str(vr),
-                                  AttenuationXSection="4.8756",
-                                  ScatteringXSection="5.16", SampleNumberDensity="0.07118",
-                                  NumberOfSlices="10", NumberOfAnnuli="10", NumberOfWavelengthPoints="25",
-                                  ExpMethod="Normal")
-        mantid.Divide(LHSWorkspace=wvan, RHSWorkspace="T", OutputWorkspace=wvan)
-        mantid.DeleteWorkspace("T")
-        mantid.ConvertUnits(InputWorkspace=wvan, OutputWorkspace=wvan, Target="TOF", EMode="Elastic")
-        # vanfoc = WISH_focus(wvan, panel)
-        mantid.DeleteWorkspace(wvan)
-        # StripPeaks(vanfoc,vanfoc)
-        # SmoothData(vanfoc,vanfoc,str(smoothing))
-        return
-
-    def WISH_createempty(empty, panel):
-        wempty = WISH_read(empty, panel, "raw")
-        emptyfoc = WISH_focus(wempty, panel)
-        return emptyfoc
-
-    # Have made no changes here as not called (may not work in future though)
-    def WISH_monitors(rb, ext):
-        # data_dir = WISH_dir()
-        file = WISH_getfilename(rb, ext)
-        wout = "w" + str(rb)
-        print "reading File..." + file
-        mantid.LoadRaw(Filename=file, OutputWorkspace=wout, SpectrumMin=str(1), SpectrumMax=str(5), LoadLogFiles="0")
-        mantid.NormaliseByCurrent(InputWorkspace=wout, OutputWorkspace=wout)
-        mantid.ConvertToDistribution(wout)
-        return wout
-
-    # Have made no changes here as not called (may not work in future though)
-    def WISH_PH_TOF(runnumber, tubemin):
-        min = 6 + (tubenumber - 1) * 128
-        max = min + 128
-        file = WISH_getfilename(runnumber, tubemin)
-        output = "Run" + str(runnumber) + "tube" + str(tubenumber)
-        w = WISH_read(number, panel, ext)
-        print "file read and normalized"
-        if (absorb):
-            mantid.ConvertUnits(w, w, "Wavelength")
-            mantid.CylinderAbsorption(InputWorkspace=w, OutputWorkspace="T",
-                                      CylinderSampleHeight=h, CylinderSampleRadius=r, AttenuationXSection=Xa,
-                                      ScatteringXSection=Xs, SampleNumberDensity=nd,
-                                      NumberOfSlices="10", NumberOfAnnuli="10", NumberOfWavelengthPoints="25",
-                                      ExpMethod="Normal")
-            mantid.Divide(w, "T", w)
-            mantid.DeleteWorkspace("T")
-            mantid.ConvertUnits(InputWorkspace=w, OutputWorkspace=w, Target="TOF", EMode="Elastic")
-        # wfoc = WISH_focus(w, panel)
-        print "focussing done!"
-        if type(number) is int:
-            wfocname = "w" + str(number) + "-" + str(panel) + "foc"
-            if (len(ext) > 9):
-                label, tmin, tmax = split_string_event(ext)
-                wfocname = "w" + str(number) + "-" + str(panel) + "_" + label + "foc"
-        else:
-            n1, n2 = split_string(number)
-            wfocname = "w" + str(n1) + "_" + str(n2) + "-" + str(panel) + "foc"
-        if (panel == 1):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-        elif (panel == 2):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-        elif (panel == 3):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-        elif (panel == 4):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-        elif (panel == 5):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-        if (panel == 10):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.80, XMax=53.3)
-        elif (panel == 9):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=13.1)
-        elif (panel == 8):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.50, XMax=7.77)
-        elif (panel == 7):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.40, XMax=5.86)
-        elif (panel == 6):
-            mantid.CropWorkspace(InputWorkspace=wfocname, OutputWorkspace=wfocname, XMin=0.35, XMax=4.99)
-        # print "will try to load an empty with the name:"
-        print WISH_getempty(panel, SEsample, emptySEcycle)
-        if (panel == 0):
-            for i in range(1, 11):
-                mantid.LoadNexusProcessed(Filename=WISH_getempty(i, SEsample, emptySEcycle), OutputWorkspace="empty")
-                mantid.RebinToWorkspace(WorkspaceToRebin="empty", WorkspaceToMatch=wfocname, OutputWorkspace="empty")
-                mantid.Minus(LHSWorkspace=wfocname, RHSWorkspace="empty", OutputWorkspace=wfocname)
-                mantid.DeleteWorkspace("empty")
-                print "will try to load a vanadium with the name:" + WISH_getvana(i, SEvana, cyclevana)
-                mantid.LoadNexusProcessed(Filename=WISH_getvana(i, SEvana, cyclevana), OutputWorkspace="vana")
-                mantid.RebinToWorkspace(WorkspaceToRebin="vana", WorkspaceToMatch=wfocname, OutputWorkspace="vana")
-                mantid.Divide(LHSWorkspace=wfocname, RHSWorkspace="vana", OutputWorkspace=wfocname)
-                mantid.DeleteWorkspace("vana")
-                mantid.ConvertUnits(InputWorkspace=wfocname, OutputWorkspace=wfocname, Target="TOF", EMode="Elastic")
-        #			SaveGSS(InputWorkspace=wfocname,Filename=WISH_userdir()+str(number)+"-"+str(i)+ext+".gss",Append=False,Bank=1)
-        #			SaveFocusedXYE(wfocname,WISH_userdir()+str(number)+"-"+str(i)+ext+".dat")
-        else:
-            mantid.LoadNexusProcessed(Filename=WISH_getempty(panel, SEsample, emptySEcycle), OutputWorkspace="empty")
-            mantid.RebinToWorkspace(WorkspaceToRebin="empty", WorkspaceToMatch=wfocname, OutputWorkspace="empty")
-            mantid.Minus(LHSWorkspace=wfocname, RHSWorkspace="empty", OutputWorkspace=wfocname)
-            mantid.DeleteWorkspace("empty")
-            print "will try to load a vanadium with the name:" + WISH_getvana(panel, SEvana, cyclevana)
-            mantid.LoadNexusProcessed(Filename=WISH_getvana(panel, SEvana, cyclevana), OutputWorkspace="vana")
-            mantid.RebinToWorkspace(WorkspaceToRebin="vana", WorkspaceToMatch=wfocname, OutputWorkspace="vana")
-            mantid.Divide(LHSWorkspace=wfocname, RHSWorkspace="vana", OutputWorkspace=wfocname)
-            mantid.DeleteWorkspace("vana")
-            mantid.ConvertUnits(InputWorkspace=wfocname, OutputWorkspace=wfocname, Target="TOF", EMode="Elastic")
-        # SaveGSS(InputWorkspace=wfocname,Filename=WISH_userdir()+str(number)+"-"+str(panel)+ext+".gss",
-        # Append=False,Bank=1)
-        # SaveFocusedXYE(wfocname,WISH_userdir()+str(number)+"-"+str(panel)+ext+".dat")
-        return wfocname
-        mantid.LoadRaw(Filename=file, OutputWorkspace=output, spectrummin=str(min), spectrummax=str(max),
-                       LoadLogFiles="0")
-        mantid.Integration(InputWorkspace=output, OutputWorkspace=output + "int")
-        # g = plotTimeBin(output + "int", 0)
-
-    # Smoothing the incident beam monitor using a spline function.
-    # Regions around Bragg edges are masked, before fitting with a  spline function.
-    # Returns a smooth monitor spectrum
-
-    def WISH_process_incidentmon(number, ext, spline_terms=20, debug=False):
-        if type(number) is int:
-            fname = WISH_getdatafile()
-            works = "monitor" + str(number)
-            if (ext == "raw"):
-                works = "monitor" + str(number)
-                mantid.LoadRaw(Filename=fname, OutputWorkspace=works, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
-            if (ext[0] == "s"):
-                works = "monitor" + str(number)
-                mantid.LoadRaw(Filename=fname, OutputWorkspace=works, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
-            if (ext == "nxs"):
-                works = "monitor" + str(number)
-                mantid.LoadNexus(Filename=fname, OutputWorkspace=works, SpectrumMin=4, SpectrumMax=4)
-                mantid.ConvertUnits(InputWorkspace=works, OutputWorkspace=works, Target="Wavelength", Emode="Elastic")
-            if (ext[0:9] == "nxs_event"):
-                temp = "w" + str(number) + "_monitors"
-                works = "w" + str(number) + "_monitor4"
-                mantid.Rebin(InputWorkspace=temp, OutputWorkspace=temp, Params='6000,-0.00063,110000',
-                             PreserveEvents=False)
-                mantid.ExtractSingleSpectrum(InputWorkspace=temp, OutputWorkspace=works, WorkspaceIndex=3)
-        else:
-            n1, n2 = split_string(number)
-            works = "monitor" + str(n1) + "_" + str(n2)
-            fname = WISH_getfilename(n1, ext)
-            works1 = "monitor" + str(n1)
-            mantid.LoadRaw(Filename=fname, OutputWorkspace=works1, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
-            fname = WISH_getfilename(n2, ext)
-            works2 = "monitor" + str(n2)
-            mantid.LoadRaw(Filename=fname, OutputWorkspace=works2, SpectrumMin=4, SpectrumMax=4, LoadLogFiles="0")
-            mantid.MergeRuns(InputWorkspaces=works1 + "," + works2, OutputWorkspace=works)
-            mantid.DeleteWorkspace(works1)
-            mantid.DeleteWorkspace(works2)
-            mantid.ConvertUnits(InputWorkspace=works, OutputWorkspace=works, Target="Wavelength", Emode="Elastic")
-        lmin, lmax = WISH_getlambdarange()
-        mantid.CropWorkspace(InputWorkspace=works, OutputWorkspace=works, XMin=lmin, XMax=lmax)
-        ex_regions = n.zeros((2, 4))
-        ex_regions[:, 0] = [4.57, 4.76]
-        ex_regions[:, 1] = [3.87, 4.12]
-        ex_regions[:, 2] = [2.75, 2.91]
-        ex_regions[:, 3] = [2.24, 2.50]
-        mantid.ConvertToDistribution(works)
-        if (debug):
-            x, y, z = mtdplt.getnarray(works, 0)
-            p.plot(x, y)
-        for reg in range(0, 4):
-            mantid.MaskBins(InputWorkspace=works, OutputWorkspace=works, XMin=ex_regions[0, reg],
-                            XMax=ex_regions[1, reg])
-        if (debug):
-            x, y, z = mtdplt.getnarray(works, LoadRaw0)
-            p.plot(x, y)
-            mantid.SplineBackground(InputWorkspace=works, OutputWorkspace=works, WorkspaceIndex=0, NCoeff=spline_terms)
-        if (debug):
-            x, y, z = mtdplt.getnarray(works, 0)
-            p.plot(x, y)
-            p.show()
-            mantid.SmoothData(InputWorkspace=works, OutputWorkspace=works, NPoints=40)
-        mantid.ConvertFromDistribution(works)
-        return works
-
-    # removes the peaks in a vanadium  run, then performs a spline and a smooth
-    def Removepeaks_spline_smooth_vana(works, panel, debug=False):
-        splineterms = 0
-        smoothterms = 0
-        if (panel == 1):
-            splineterms = 0
-            smoothterms = 30
-        if (panel == 2):
-            splineterms = 0
-            smoothterms = 10
-        if (panel == 3):
-            splineterms = 0
-            smoothterms = 15
-        if (panel == 4):
-            splineterms = 0
-            smoothterms = 15
-        if (panel == 5):
-            splineterms = 0
-            smoothterms = 10
-        if (debug):
-            x, y, z = mantid.getnarray(works, 0)
-            p.plot(x, y)
-        if (splineterms != 0):
-            mantid.SplineBackground(InputWorkspace=works, OutputWorkspace=works, WorkspaceIndex=0, NCoeff=splineterms)
-        if (debug):
-            x, y, z = mantid.getnarray(works, 0)
-            p.plot(x, y)
-        if not (smoothterms == 0):
-            mantid.SmoothData(InputWorkspace=works, OutputWorkspace=works, NPoints=smoothterms)
-        if (debug):
-            x, y, z = mantid.getnarray(works, 0)
-            p.plot(x, y)
-            p.show()
-        return works
-
-    def split_string_event(t):
-        # this assumes the form nxs_event_label_tmin_tmax
-        indx_ = []
-        for i in range(10, len(t)):
-            if (t[i] == "_"):
-                indx_.append(i)
-        label = t[10:indx_[0]]
-        tmin = t[indx_[0] + 1:indx_[1]]
-        tmax = t[indx_[1] + 1:len(t)]
-        return label, tmin, tmax
-
-    def minus_emptycans(runno, empty):
-        panel_list = ['-1foc', '-2foc', '-3foc', '-4foc', '-5foc', '-6foc', '-7foc', '-8foc', '-9foc', '-10foc',
-                      '-1_10foc',
-                      '-2_9foc', '-3_8foc', '-4_7foc', '-5_6foc']
-        for p in panel_list:
-            mantid.Minus(LHSWorkspace='w' + str(runno) + p, RHSWorkspace='w' + str(empty) + p,
-                         OutputWorkspace='w' + str(runno) + 'minus' + str(empty) + p)
-            mantid.ConvertUnits(InputWorkspace='w' + str(runno) + 'minus' + str(empty) + p,
-                                OutputWorkspace='w' + str(runno) + 'minus' + str(empty) + p + '-d', Target='dSpacing')
-            mantid.SaveGSS("w" + str(runno) + 'minus' + str(empty) + p,
-                           os.path.join(WISH_userdir(), (str(i) + p + ".gss")), Append=False, Bank=1)
-
-    def main(input_file, output_dir):
-        # Check files can be found
-        validate(input_file, output_dir)
-
-        # test="nxs_event_1_300.00_600.00"
-        # print split_string_event(test)
-
-        # #####################################################################
-        # #####     			USER SPECIFIC PART STARTS BELOW 									   ##
-        # #####     			IN CASE LINES ABOVE HAVE BEEN EDITED AND SCRIPTS NO LONGER WORK   ##
-        # #####     			LOG OUT AND BACK IN TO THE MACHINE								   ##
-        # #####################################################################
-        # ########### SETTING the paths automatically : WISH_startup(username,cycle_name) ##############
-        # WISH_startup("ryb18365","15_1")
-
-        WISH_setuserdir(output_dir)
-        WISH_setdatafile(input_file)
-        print(output_dir)
-        print(input_file)
-        # #        WISH PROCESS ROUTINES TO EDIT   (penultimate line optional but useful for recovering data later on)  #
-        # To add two raw files together, replace runno (integer, eg. 16800) by a string "int1+int2" (eg "16800+16801" note quotes)
-        # ##############################################################################################
-        # beg=0
-        # end=1800
-        # nbslices=int(end/180)
-        # suffix=[]
-        # for k in range(0,nbslices):
-        #	suffix.append("nxs_event_slice"+str(k)+"_"+str(int(k*180))+"_"+str((k+1)*180))
-
-        # print len(suffix)
-        # print suffix[0], suffix[k]
-
-        # for i in range(24901,24902):
-        #	for j in range(2,3):
-        #		for k in range(0,len(suffix)):
-        #			wout=WISH_process(i,j,suffix[k],"candlestick","11_4","candlestick","11_4",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #			ConvertUnits(wout,wout+"-d","dSpacing")
-        # ##############################################################################################
-        # for i in range(24895,24896):
-        #	for j in range(5,6):
-        #		wout=WISH_process(i,j,"nxs_event_slice1_0_300","candlestick","11_4","candlestick","11_4",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice2_300_600","candlestick","11_4","candlestick","11_4",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice3_600_900","candlestick","11_4","candlestick","11_4",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice4_900_1200","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice5_1200_1500","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice6_1500_1800","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")-4foc
-        #		wout=WISH_process(i,j,"nxs_event_slice7_1800_2100","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice8_2100_2400","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice9_2400_2700","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice10_2700_3000","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice11_3000_3300","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-        #		wout=WISH_process(i,j,"nxs_event_slice12_3300_end","WISHcryo","11_3","WISHcryo","11_3",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-
-        i = get_run_number(input_file)
-        for j in range(1, 11):
-            WISH_process(i, j, "raw", "candlestick", "17_1", "candlestick", "18_2", absorb=False, nd=0.0, Xs=0.0,
-                         Xa=0.0, h=4.0, r=0.4)
-        for j in range(1, 11):
-            wout = WISH_process(i, j, "raw", "candlestick", "17_1", "candlestick", "18_2", absorb=False, nd=0.0, Xs=0.0,
-                                Xa=0.0, h=4.0, r=0.4)
-            mantid.ConvertUnits(InputWorkspace=wout, OutputWorkspace=wout + "-d", Target="dSpacing", EMode="Elastic")
-            #	SaveGSS("w"+str(i)+"-1foc",WISH_userdir()+str(i)+"-1foc"+".gss",Append=False,Bank=1)
-            #	SaveFocusedXYE("w"+str(i)+"-1foc",WISH_userdir()+str(i)+"-1foc"+".dat")
-            #	SaveGSS("w"+str(i)+"-2foc",WISH_userdir()+str(i)+"-2foc"+".gss",Append=False,Bank=1)
-            #	SaveFocusedXYE("w"+str(i)+"-2foc",WISH_userdir()+str(i)+"-2foc"+".dat")
-            mantid.RebinToWorkspace(WorkspaceToRebin="w" + str(i) + "-6foc", WorkspaceToMatch="w" + str(i) + "-5foc",
-                                    OutputWorkspace="w" + str(i) + "-6foc", PreserveEvents='0')
-            mantid.Plus(LHSWorkspace="w" + str(i) + "-5foc", RHSWorkspace="w" + str(i) + "-6foc",
-                        OutputWorkspace="w" + str(i) + "-5_6foc")
-            mantid.ConvertUnits(InputWorkspace="w" + str(i) + "-5_6foc",
-                                OutputWorkspace="w" + str(i) + "-5_6foc" + "-d",
-                                Target="dSpacing", EMode="Elastic")
-            mantid.SaveGSS("w" + str(i) + "-5_6foc", os.path.join(WISH_userdir(), (str(i) + "-5_6raw" + ".gss")),
-                           Append=False, Bank=1)
-            mantid.SaveFocusedXYE("w" + str(i) + "-5_6foc", os.path.join(WISH_userdir(), (str(i) + "-5_6raw" + ".dat")))
-            mantid.SaveNexusProcessed("w" + str(i) + "-5_6foc",
-                                      os.path.join(WISH_userdir(), (str(i) + "-5_6raw" + ".nxs")))
-            mantid.RebinToWorkspace(WorkspaceToRebin="w" + str(i) + "-7foc", WorkspaceToMatch="w" + str(i) + "-4foc",
-                                    OutputWorkspace="w" + str(i) + "-7foc", PreserveEvents='0')
-            mantid.Plus(LHSWorkspace="w" + str(i) + "-4foc", RHSWorkspace="w" + str(i) + "-7foc",
-                        OutputWorkspace="w" + str(i) + "-4_7foc")
-            mantid.ConvertUnits(InputWorkspace="w" + str(i) + "-4_7foc",
-                                OutputWorkspace="w" + str(i) + "-4_7foc" + "-d",
-                                Target="dSpacing", EMode="Elastic")
-            mantid.SaveGSS("w" + str(i) + "-4_7foc", os.path.join(WISH_userdir(), (str(i) + "-4_7raw" + ".gss")),
-                           Append=False, Bank=1)
-            mantid.SaveFocusedXYE("w" + str(i) + "-4_7foc", os.path.join(WISH_userdir(), (str(i) + "-4_7raw" + ".dat")))
-            mantid.SaveNexusProcessed("w" + str(i) + "-4_7foc",
-                                      os.path.join(WISH_userdir(), (str(i) + "-4_7raw" + ".nxs")))
-        mantid.RebinToWorkspace(WorkspaceToRebin="w" + str(i) + "-8foc", WorkspaceToMatch="w" + str(i) + "-3foc",
-                                OutputWorkspace="w" + str(i) + "-8foc", PreserveEvents='0')
-        mantid.Plus(LHSWorkspace="w" + str(i) + "-3foc", RHSWorkspace="w" + str(i) + "-8foc",
-                    OutputWorkspace="w" + str(i) + "-3_8foc")
-        mantid.ConvertUnits(InputWorkspace="w" + str(i) + "-3_8foc", OutputWorkspace="w" + str(i) + "-3_8foc" + "-d",
-                            Target="dSpacing", EMode="Elastic")
-        mantid.SaveGSS("w" + str(i) + "-3_8foc", os.path.join(WISH_userdir(), (str(i) + "-3_8raw" + ".gss")),
-                       Append=False, Bank=1)
-        mantid.SaveFocusedXYE("w" + str(i) + "-3_8foc", os.path.join(WISH_userdir(), (str(i) + "-3_8raw" + ".dat")))
-        mantid.SaveNexusProcessed("w" + str(i) + "-3_8foc", os.path.join(WISH_userdir(), (str(i) + "-3_8raw" + ".nxs")))
-        mantid.RebinToWorkspace(WorkspaceToRebin="w" + str(i) + "-9foc", WorkspaceToMatch="w" + str(i) + "-2foc",
-                                OutputWorkspace="w" + str(i) + "-9foc", PreserveEvents='0')
-        mantid.Plus(LHSWorkspace="w" + str(i) + "-2foc", RHSWorkspace="w" + str(i) + "-9foc",
-                    OutputWorkspace="w" + str(i) + "-2_9foc")
-        mantid.ConvertUnits(InputWorkspace="w" + str(i) + "-2_9foc", OutputWorkspace="w" + str(i) + "-2_9foc" + "-d",
-                            Target="dSpacing", EMode="Elastic")
-        mantid.SaveGSS("w" + str(i) + "-2_9foc", os.path.join(WISH_userdir(), (str(i) + "-2_9raw" + ".gss")),
-                       Append=False, Bank=1)
-        mantid.SaveFocusedXYE("w" + str(i) + "-2_9foc", os.path.join(WISH_userdir(), (str(i) + "-2_9raw" + ".dat")))
-        mantid.SaveNexusProcessed("w" + str(i) + "-2_9foc", os.path.join(WISH_userdir(), (str(i) + "-2_9raw" + ".nxs")))
-        mantid.RebinToWorkspace(WorkspaceToRebin="w" + str(i) + "-10foc", WorkspaceToMatch="w" + str(i) + "-1foc",
-                                OutputWorkspace="w" + str(i) + "-10foc", PreserveEvents='0')
-        mantid.Plus(LHSWorkspace="w" + str(i) + "-1foc", RHSWorkspace="w" + str(i) + "-10foc",
-                    OutputWorkspace="w" + str(i) + "-1_10foc")
-        mantid.ConvertUnits(InputWorkspace="w" + str(i) + "-1_10foc", OutputWorkspace="w" + str(i) + "-1_10foc" + "-d",
-                            Target="dSpacing", EMode="Elastic")
-        mantid.SaveGSS("w" + str(i) + "-1_10foc", os.path.join(WISH_userdir(), (str(i) + "-1_10raw" + ".gss")),
-                       Append=False, Bank=1)
-        mantid.SaveFocusedXYE("w" + str(i) + "-1_10foc", os.path.join(WISH_userdir(), (str(i) + "-1_10raw" + ".dat")))
-        mantid.SaveNexusProcessed("w" + str(i) + "-1_10foc",
-                                  os.path.join(WISH_userdir(), (str(i) + "-1_10raw" + ".nxs")))
-
-        # minus_emptycans(26977,26969)
-        # #############################################################################################
-        # for i in range(23840,23841):
-        #	for j in range(5,0,-1):
-        #		wout=WISH_process(i,j,"raw","candlestick","11_4","candlestick","11_4",absorb=False,nd=0.0,Xs=0.0,Xa=0.0,h=0.0,r=0.0)
-        #		SaveNexusProcessed(wout,WISH_userdir()+wout+".nxs")
-        #		ConvertUnits(wout,wout+"-d","dSpacing")
-
-        # ###########################################################################################
-        # for i in range(18880,18881):
-        #	for j in range(1,6):
-        #		wout=WISH_process(i,j,"raw","WISHcryo","11_3","WISHcryo","11_3",absorb=True,nd=0.0035,Xs=62.27,Xa=429.95,h=4.0,r=0.15)
-        # ###########################################################################################
-        # #########               END OF WISH PROCESS ROUTINES                               ##################
-
-        # #####################################################################
-        # How to retrieve already processed Data without having to reprocess it  (in case Mantid session has been closed #
-        # list_overlap=['5_6','4_7','3_8','2_9','1_10']
-        # for i in range(27739,27740):
-        # for j in range(1,11):
-        #    wr=str(i)+"-"+str(j)+"raw"
-        #    LoadNexusProcessed(Filename=WISH_userdir()+wr+".nxs",OutputWorkspace=wr)
-        #    ConvertUnits(InputWorkspace=wr,OutputWorkspace=wr+"-d",Target="dSpacing")
-        # for k in list_overlap:
-        #   wr=str(i)+"-"+k+"raw"
-        #   LoadNexusProcessed(Filename=WISH_userdir()+wr+".nxs",OutputWorkspace=wr)
-        #  ConvertUnits(InputWorkspace=wr,OutputWorkspace=wr+"-d",Target="dSpacing")
-        #####################################################################
-        # for runno in range(22678,22686):
-        # for j in range(1,6):
-        # wr="w"+str(runno)+"-"+str(j)+"foc"
-
-        # for j in range(1,6):
-        #	Plus("w22663"+"-"+str(j)+"foc","w22664"+"-"+str(j)+"foc","vancan"+"-"+str(j)+"foc")
-        #	SaveGSS(InputWorkspace="vancan"+"-"+str(j)+"foc",Filename=WISH_userdir()+"vancan"+"-"+str(j)+"foc.gss",Append=False,Bank=1)
-
-        # ####################################################################
-        # If you don't have a correct empty, either use the most suitable one or use the lines below ####
-        # for i in range(1197,1410):
-        #	for j in range(1,6):
-        #		wout=WISH_read(i,j,"raw")
-        #		wfoc=WISH_focus(wout,j)
-        # ####################################################################
-        # use the lines below to manually set the paths if needed
-
-        # ########  use the lines below to create a processed empty (instrument, cryostat, can..) run     ########
-        # for i in range(4,5):
-        #	WISH_createempty(20620,i)
-        # SaveNexusProcessed("w16748-"+str(i)+"foc",WISH_userdir()+"emptyinst16748-"+str(i)+"foc.nx5")
-
-    def create_vanadium():
-
-        # ######### use the lines below to process a LoadRawvanadium run                               #################
-        for j in range(1, 11):
-            WISH_createvan(41865, 38581, j, 100, 4.0, 0.15, cycle_van="18_2", cycle_empty="17_1")
-            mantid.CropWorkspace(InputWorkspace="w41865-" + str(j) + "foc", OutputWorkspace="w41865-" + str(j) + "foc",
-                                 XMin='0.35',
-                                 XMax='5.0')
-            Removepeaks_spline_smooth_vana("w41865-" + str(j) + "foc", j, debug=False)
-            mantid.SaveNexusProcessed("w41865-" + str(j) + "foc",
-                                      os.path.join(WISH_userdir(), ("vana41865-" + str(j) + "foc.nxs")))
-
-    if __name__ == "__main__":
-        # WISH_startup("ffv81422", "17_1")
-        # WISH_setdatafile(WISH_getfilename(38581, "nxs"))
-        # for i in range(1, 11):
-        #    print "loop"
-        #    wout = WISH_read(38581, i, "raw")
-        #    wfoc=WISH_focus(wout,i)
-        WISH_startup("ffv81422", "18_2")
-        WISH_setdatafile(WISH_getfilename(41870, "nxs"))
-
-        main(WISH_getdatafile(), WISH_userdir())