diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86181c70cdf399c72ad6026475cba7b92e1e2444..71d382f68e1bc67d1964112468ef298f6d4e16fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -153,11 +153,12 @@ include_directories ( Framework/Kernel/inc )
 include_directories ( Framework/HistogramData/inc )
 include_directories ( Framework/Indexing/inc )
 include_directories ( Framework/Parallel/inc )
+include_directories ( Framework/Beamline/inc )
 include_directories ( Framework/Geometry/inc )
 include_directories ( Framework/API/inc )
 include_directories ( Framework/Types/inc )
 
-set ( CORE_MANTIDLIBS Kernel HistogramData Indexing Geometry API Types )
+set ( CORE_MANTIDLIBS Kernel HistogramData Indexing Beamline Geometry API Types )
 
 if ( ENABLE_MANTIDPLOT AND MAKE_VATES )
 
@@ -308,7 +309,7 @@ if ( ENABLE_CPACK )
         set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},scl-utils,mantidlibs34,mantidlibs34-runtime,mantidlibs34-qt,mantidlibs34-qt-x11,mantidlibs34-qt-webkit,mantidlibs34-qwt5-qt4" )
       else()
         # Require matplotlib >= 1.5 to fix bug in latex rendering
-        set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} qscintilla,qwt5-qt4,python2-matplotlib-qt4 >= 1.5.2,boost >= 1.53.0" )
+        set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} qscintilla,qwt5-qt4,python2-matplotlib-qt4 >= 1.5.2,python2-QtAwesome,boost >= 1.53.0" )
       endif()
 
       # Add software collections for RHEL
@@ -353,7 +354,8 @@ if ( ENABLE_CPACK )
                            "librdkafka++1,"
                            "libpocofoundation${POCO_SOLIB_VERSION},libpocoutil${POCO_SOLIB_VERSION},libpoconet${POCO_SOLIB_VERSION},libpoconetssl${POCO_SOLIB_VERSION},libpococrypto${POCO_SOLIB_VERSION},libpocoxml${POCO_SOLIB_VERSION},"
                            "python-pycifrw (>= 4.2.1),"
-                           "python-yaml")
+                           "python-yaml,"
+                           "python-qtawesome")
         set ( PERFTOOLS_DEB_PACKAGE "libgoogle-perftools4 (>= 1.7)" )
         if( "${UNIX_CODENAME}" STREQUAL "xenial")
             list ( APPEND DEPENDS_LIST ", libhdf5-cpp-11,libnexus0v5 (>= 4.3),libjsoncpp1,libqscintilla2-12v5, libmuparser2v5,libqwtplot3d-qt4-0v5,libgsl2,liboce-foundation10,liboce-modeling10")
diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h
index 5b2fe7cf4790a1d15cb71b20b70fd4eeb02f4d60..a86aab5736417dc15bd658a00fa8d2713501af14 100644
--- a/Framework/API/inc/MantidAPI/Algorithm.h
+++ b/Framework/API/inc/MantidAPI/Algorithm.h
@@ -183,6 +183,9 @@ public:
   /// Function to return the separator token for the category string. A default
   /// implementation ';' is provided
   const std::string categorySeparator() const override { return ";"; }
+  /// Function to return all of the seeAlso (these are not validated) algorithms
+  /// related to this algorithm.A default implementation is provided.
+  const std::vector<std::string> seeAlso() const override { return {}; };
   /// function to return any aliases to the algorithm;  A default implementation
   /// is provided
   const std::string alias() const override { return ""; }
@@ -301,7 +304,7 @@ public:
   /// parent object to fill.
   void trackAlgorithmHistory(boost::shared_ptr<AlgorithmHistory> parentHist);
 
-  typedef std::vector<boost::shared_ptr<Workspace>> WorkspaceVector;
+  using WorkspaceVector = std::vector<boost::shared_ptr<Workspace>>;
 
   void findWorkspaceProperties(WorkspaceVector &inputWorkspaces,
                                WorkspaceVector &outputWorkspaces) const;
@@ -502,7 +505,7 @@ private:
 };
 
 /// Typedef for a shared pointer to an Algorithm
-typedef boost::shared_ptr<Algorithm> Algorithm_sptr;
+using Algorithm_sptr = boost::shared_ptr<Algorithm>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/AlgorithmFactory.h b/Framework/API/inc/MantidAPI/AlgorithmFactory.h
index 9fb52f0d815acab63f2da13836b8bc92edd0f147..49ed56890b29e7b6a01f96d2c3e1c0fb72104c09 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmFactory.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmFactory.h
@@ -163,18 +163,18 @@ private:
   void fillHiddenCategories(std::unordered_set<std::string> *categorySet) const;
 
   /// A typedef for the map of algorithm versions
-  typedef std::map<std::string, int> VersionMap;
+  using VersionMap = std::map<std::string, int>;
   /// The map holding the registered class names and their highest versions
   VersionMap m_vmap;
 };
 
-typedef Mantid::Kernel::SingletonHolder<AlgorithmFactoryImpl> AlgorithmFactory;
+using AlgorithmFactory = Mantid::Kernel::SingletonHolder<AlgorithmFactoryImpl>;
 
 /// Convenient typedef for an UpdateNotification
-typedef Mantid::Kernel::DynamicFactory<Algorithm>::UpdateNotification
-    AlgorithmFactoryUpdateNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DynamicFactory<
-    Algorithm>::UpdateNotification> &AlgorithmFactoryUpdateNotification_ptr;
+using AlgorithmFactoryUpdateNotification =
+    Mantid::Kernel::DynamicFactory<Algorithm>::UpdateNotification;
+using AlgorithmFactoryUpdateNotification_ptr = const Poco::AutoPtr<
+    Mantid::Kernel::DynamicFactory<Algorithm>::UpdateNotification> &;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/AlgorithmHistory.h b/Framework/API/inc/MantidAPI/AlgorithmHistory.h
index 7e6fd4808187da301c77e41e596c64474ce779aa..4485f149f63683fc914c1c9af78212b1879dc0df 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmHistory.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmHistory.h
@@ -34,10 +34,10 @@ template <class T> struct CompareHistory {
 }
 
 // typedefs for algorithm history pointers
-typedef boost::shared_ptr<AlgorithmHistory> AlgorithmHistory_sptr;
-typedef boost::shared_ptr<const AlgorithmHistory> AlgorithmHistory_const_sptr;
-typedef std::set<AlgorithmHistory_sptr,
-                 Detail::CompareHistory<AlgorithmHistory>> AlgorithmHistories;
+using AlgorithmHistory_sptr = boost::shared_ptr<AlgorithmHistory>;
+using AlgorithmHistory_const_sptr = boost::shared_ptr<const AlgorithmHistory>;
+using AlgorithmHistories =
+    std::set<AlgorithmHistory_sptr, Detail::CompareHistory<AlgorithmHistory>>;
 
 /** @class AlgorithmHistory AlgorithmHistory.h API/MAntidAPI/AlgorithmHistory.h
 
diff --git a/Framework/API/inc/MantidAPI/AlgorithmManager.h b/Framework/API/inc/MantidAPI/AlgorithmManager.h
index cc777057963bfc3a4aefe26fa213f946b3bc5997..cc48017841ddb457104a9e6a40ab15c58fa80603 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmManager.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmManager.h
@@ -102,7 +102,7 @@ private:
   mutable std::mutex m_managedMutex;
 };
 
-typedef Mantid::Kernel::SingletonHolder<AlgorithmManagerImpl> AlgorithmManager;
+using AlgorithmManager = Mantid::Kernel::SingletonHolder<AlgorithmManagerImpl>;
 
 } // namespace API
 } // Namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/AlgorithmProperty.h b/Framework/API/inc/MantidAPI/AlgorithmProperty.h
index facb554cb583b8b2bf857061e579ceac54988c59..ed516f223bf9c44e5170bb2d5e7cd32dfea100ea 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmProperty.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmProperty.h
@@ -53,7 +53,7 @@ class DLLExport AlgorithmProperty
     : public Kernel::PropertyWithValue<boost::shared_ptr<IAlgorithm>> {
 public:
   /// Typedef the held type
-  typedef boost::shared_ptr<IAlgorithm> HeldType;
+  using HeldType = boost::shared_ptr<IAlgorithm>;
 
   /// Constructor
   AlgorithmProperty(const std::string &propName,
diff --git a/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Framework/API/inc/MantidAPI/AlgorithmProxy.h
index a8a47f066b1d7fc77d69c92bd2f2304e6908f43b..08cba70c8aa4ddb9ddf0041cbcc9c26798219983 100644
--- a/Framework/API/inc/MantidAPI/AlgorithmProxy.h
+++ b/Framework/API/inc/MantidAPI/AlgorithmProxy.h
@@ -26,7 +26,7 @@ class Void;
 namespace Mantid {
 namespace API {
 class Algorithm;
-typedef boost::shared_ptr<Algorithm> Algorithm_sptr;
+using Algorithm_sptr = boost::shared_ptr<Algorithm>;
 
 /**
 
@@ -79,11 +79,13 @@ public:
   const std::string category() const override { return m_category; }
   /// Function to return all of the categories that contain this algorithm
   const std::vector<std::string> categories() const override;
-  /// Function to return the sperator token for the category string. A default
+  /// Function to return the seperator token for the category string. A default
   /// implementation ',' is provided
   const std::string categorySeparator() const override {
     return m_categorySeparator;
   }
+  /// Function to return all of the seeAlso algorithms related to this algorithm
+  const std::vector<std::string> seeAlso() const override { return m_seeAlso; };
   /// Aliases to the algorithm
   const std::string alias() const override { return m_alias; }
   /// Optional documentation URL for the real algorithm
@@ -183,9 +185,10 @@ private:
   const std::string m_name;     ///< name of the real algorithm
   const std::string m_category; ///< category of the real algorithm
   const std::string
-      m_categorySeparator;     ///< category seperator of the real algorithm
-  const std::string m_alias;   ///< alias to the algorithm
-  const std::string m_helpURL; ///< Optional documentation URL
+      m_categorySeparator; ///< category seperator of the real algorithm
+  const std::vector<std::string> m_seeAlso; ///< seeAlso of the real algorithm
+  const std::string m_alias;                ///< alias to the algorithm
+  const std::string m_helpURL;              ///< Optional documentation URL
   const std::string m_summary; ///<Message to display in GUI and help.
   const int m_version;         ///< version of the real algorithm
 
diff --git a/Framework/API/inc/MantidAPI/AnalysisDataService.h b/Framework/API/inc/MantidAPI/AnalysisDataService.h
index d46cd86ba7f8521020432c596d9594e5a98496c0..81847922571fe8cad12be09b373188510c9f4e29 100644
--- a/Framework/API/inc/MantidAPI/AnalysisDataService.h
+++ b/Framework/API/inc/MantidAPI/AnalysisDataService.h
@@ -178,65 +178,62 @@ private:
   std::string m_illegalChars;
 };
 
-typedef Mantid::Kernel::SingletonHolder<AnalysisDataServiceImpl>
-    AnalysisDataService;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::AddNotification
-    WorkspaceAddNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::AddNotification> &WorkspaceAddNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::
-    BeforeReplaceNotification WorkspaceBeforeReplaceNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::BeforeReplaceNotification> &
-    WorkspaceBeforeReplaceNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::
-    AfterReplaceNotification WorkspaceAfterReplaceNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::AfterReplaceNotification> &
-    WorkspaceAfterReplaceNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::
-    PreDeleteNotification WorkspacePreDeleteNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::PreDeleteNotification> &
-    WorkspacePreDeleteNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::
-    PostDeleteNotification WorkspacePostDeleteNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::PostDeleteNotification> &
-    WorkspacePostDeleteNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::ClearNotification
-    ClearADSNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::DataService<
-    Mantid::API::Workspace>::ClearNotification> &ClearADSNotification_ptr;
-
-typedef Mantid::Kernel::DataService<Mantid::API::Workspace>::RenameNotification
-    WorkspaceRenameNotification;
-typedef const Poco::AutoPtr<
-    Mantid::Kernel::DataService<Mantid::API::Workspace>::RenameNotification> &
-    WorkspaceRenameNotification_ptr;
-
-typedef AnalysisDataServiceImpl::GroupWorkspacesNotification
-    WorkspacesGroupedNotification;
-typedef const Poco::AutoPtr<
-    AnalysisDataServiceImpl::GroupWorkspacesNotification> &
-    WorkspacesGroupedNotification_ptr;
-
-typedef AnalysisDataServiceImpl::UnGroupingWorkspaceNotification
-    WorkspaceUnGroupingNotification;
-typedef const Poco::AutoPtr<
-    AnalysisDataServiceImpl::UnGroupingWorkspaceNotification> &
-    WorkspaceUnGroupingNotification_ptr;
-
-typedef AnalysisDataServiceImpl::GroupUpdatedNotification
-    GroupUpdatedNotification;
-typedef const Poco::AutoPtr<AnalysisDataServiceImpl::GroupUpdatedNotification> &
-    GroupUpdatedNotification_ptr;
+using AnalysisDataService =
+    Mantid::Kernel::SingletonHolder<AnalysisDataServiceImpl>;
+
+using WorkspaceAddNotification =
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::AddNotification;
+using WorkspaceAddNotification_ptr = const Poco::AutoPtr<
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::AddNotification> &;
+
+using WorkspaceBeforeReplaceNotification = Mantid::Kernel::DataService<
+    Mantid::API::Workspace>::BeforeReplaceNotification;
+using WorkspaceBeforeReplaceNotification_ptr =
+    const Poco::AutoPtr<Mantid::Kernel::DataService<
+        Mantid::API::Workspace>::BeforeReplaceNotification> &;
+
+using WorkspaceAfterReplaceNotification = Mantid::Kernel::DataService<
+    Mantid::API::Workspace>::AfterReplaceNotification;
+using WorkspaceAfterReplaceNotification_ptr =
+    const Poco::AutoPtr<Mantid::Kernel::DataService<
+        Mantid::API::Workspace>::AfterReplaceNotification> &;
+
+using WorkspacePreDeleteNotification =
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::PreDeleteNotification;
+using WorkspacePreDeleteNotification_ptr =
+    const Poco::AutoPtr<Mantid::Kernel::DataService<
+        Mantid::API::Workspace>::PreDeleteNotification> &;
+
+using WorkspacePostDeleteNotification =
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::PostDeleteNotification;
+using WorkspacePostDeleteNotification_ptr =
+    const Poco::AutoPtr<Mantid::Kernel::DataService<
+        Mantid::API::Workspace>::PostDeleteNotification> &;
+
+using ClearADSNotification =
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::ClearNotification;
+using ClearADSNotification_ptr = const Poco::AutoPtr<
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::ClearNotification> &;
+
+using WorkspaceRenameNotification =
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::RenameNotification;
+using WorkspaceRenameNotification_ptr = const Poco::AutoPtr<
+    Mantid::Kernel::DataService<Mantid::API::Workspace>::RenameNotification> &;
+
+using WorkspacesGroupedNotification =
+    AnalysisDataServiceImpl::GroupWorkspacesNotification;
+using WorkspacesGroupedNotification_ptr =
+    const Poco::AutoPtr<AnalysisDataServiceImpl::GroupWorkspacesNotification> &;
+
+using WorkspaceUnGroupingNotification =
+    AnalysisDataServiceImpl::UnGroupingWorkspaceNotification;
+using WorkspaceUnGroupingNotification_ptr = const Poco::AutoPtr<
+    AnalysisDataServiceImpl::UnGroupingWorkspaceNotification> &;
+
+using GroupUpdatedNotification =
+    AnalysisDataServiceImpl::GroupUpdatedNotification;
+using GroupUpdatedNotification_ptr =
+    const Poco::AutoPtr<AnalysisDataServiceImpl::GroupUpdatedNotification> &;
 
 } // Namespace API
 } // Namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h
index a08b918d1fd23651341c27c703665444fc950a73..ff983a5556c867cee0ff18f857e617cd6446717b 100644
--- a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h
+++ b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h
@@ -56,8 +56,8 @@ private:
   ~ArchiveSearchFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ArchiveSearchFactoryImpl>
-    ArchiveSearchFactory;
+using ArchiveSearchFactory =
+    Mantid::Kernel::SingletonHolder<ArchiveSearchFactoryImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/BoxController.h b/Framework/API/inc/MantidAPI/BoxController.h
index 4443f09bee81cb8969f1f7bcd805e0b2a77128c9..33b4a976be394de157eff2f52051fd8f07acbff8 100644
--- a/Framework/API/inc/MantidAPI/BoxController.h
+++ b/Framework/API/inc/MantidAPI/BoxController.h
@@ -505,10 +505,10 @@ public:
 };
 
 /// Shared ptr to BoxController
-typedef boost::shared_ptr<BoxController> BoxController_sptr;
+using BoxController_sptr = boost::shared_ptr<BoxController>;
 
 /// Shared ptr to a const BoxController
-typedef boost::shared_ptr<const BoxController> BoxController_const_sptr;
+using BoxController_const_sptr = boost::shared_ptr<const BoxController>;
 
 } // namespace API
 
diff --git a/Framework/API/inc/MantidAPI/CatalogFactory.h b/Framework/API/inc/MantidAPI/CatalogFactory.h
index b6133d3315da6d90d751b8945c3a9e603c90a989..2ddd4da9e05821af19ca39cdd026834d15264023 100644
--- a/Framework/API/inc/MantidAPI/CatalogFactory.h
+++ b/Framework/API/inc/MantidAPI/CatalogFactory.h
@@ -78,7 +78,7 @@ private:
 
 /// The specialisation of the SingletonHolder class that holds the
 /// CatalogFactory
-typedef Mantid::Kernel::SingletonHolder<CatalogFactoryImpl> CatalogFactory;
+using CatalogFactory = Mantid::Kernel::SingletonHolder<CatalogFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/CatalogManager.h b/Framework/API/inc/MantidAPI/CatalogManager.h
index d7bc46ddcffeefbd6927bda3bbf474e4265cecf0..5b03f204dda96f4c48f900b6108f4703e0ec9f50 100644
--- a/Framework/API/inc/MantidAPI/CatalogManager.h
+++ b/Framework/API/inc/MantidAPI/CatalogManager.h
@@ -67,7 +67,7 @@ private:
   std::map<CatalogSession_sptr, ICatalog_sptr> m_activeCatalogs;
 };
 
-typedef Kernel::SingletonHolder<CatalogManagerImpl> CatalogManager;
+using CatalogManager = Kernel::SingletonHolder<CatalogManagerImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/CatalogSession.h b/Framework/API/inc/MantidAPI/CatalogSession.h
index 7de21287b532bf26115c5c1b81f41ef3be70192b..cc40d7ee8d1bb6b40bb70cc1b89cfe5207305848 100644
--- a/Framework/API/inc/MantidAPI/CatalogSession.h
+++ b/Framework/API/inc/MantidAPI/CatalogSession.h
@@ -49,8 +49,8 @@ private:
   std::string m_endpoint;
 };
 
-typedef boost::shared_ptr<CatalogSession> CatalogSession_sptr;
-typedef boost::shared_ptr<const CatalogSession> CatalogSession_const_sptr;
+using CatalogSession_sptr = boost::shared_ptr<CatalogSession>;
+using CatalogSession_const_sptr = boost::shared_ptr<const CatalogSession>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/Column.h b/Framework/API/inc/MantidAPI/Column.h
index 151296175225b9e9012ce8c1ece5e3580ee38d65..9f7feec96c3b326d8e387b74395aea4b73e7022f 100644
--- a/Framework/API/inc/MantidAPI/Column.h
+++ b/Framework/API/inc/MantidAPI/Column.h
@@ -227,8 +227,8 @@ MANTID_API_DLL std::ostream &operator<<(std::ostream &, const API::Boolean &);
 /// Redaing a Boolean from an input stream
 MANTID_API_DLL std::istream &operator>>(std::istream &istr, API::Boolean &);
 
-typedef boost::shared_ptr<Column> Column_sptr;
-typedef boost::shared_ptr<const Column> Column_const_sptr;
+using Column_sptr = boost::shared_ptr<Column>;
+using Column_const_sptr = boost::shared_ptr<const Column>;
 
 } // namespace API
 } // Namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ColumnFactory.h b/Framework/API/inc/MantidAPI/ColumnFactory.h
index df6a3d92e9815754d3eb65eb913c70c4bfe9988e..7b64c5f1d07ad0db9c461eb2813a3e3181c2ce3e 100644
--- a/Framework/API/inc/MantidAPI/ColumnFactory.h
+++ b/Framework/API/inc/MantidAPI/ColumnFactory.h
@@ -63,7 +63,7 @@ private:
   ~ColumnFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ColumnFactoryImpl> ColumnFactory;
+using ColumnFactory = Mantid::Kernel::SingletonHolder<ColumnFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/CompositeDomainMD.h b/Framework/API/inc/MantidAPI/CompositeDomainMD.h
index aadf666d4ec8e7b7fbcc29ab358cb4af56cd7e26..5fffbaf394f2a56a6c0a5c38f2de9dbf87b38e81 100644
--- a/Framework/API/inc/MantidAPI/CompositeDomainMD.h
+++ b/Framework/API/inc/MantidAPI/CompositeDomainMD.h
@@ -53,8 +53,8 @@ public:
   const FunctionDomain &getDomain(size_t i) const override;
 
 protected:
-  mutable IMDIterator *m_iterator; ///< IMDIterator
-  size_t m_totalSize;              ///< The total size of the domain
+  mutable std::unique_ptr<IMDIterator> m_iterator; ///< IMDIterator
+  size_t m_totalSize; ///< The total size of the domain
   mutable std::vector<FunctionDomainMD *>
       m_domains; ///< smaller parts of the domain
 };
diff --git a/Framework/API/inc/MantidAPI/CompositeFunction.h b/Framework/API/inc/MantidAPI/CompositeFunction.h
index aa036857ee7b96e2cc2009dbb23d17cb2694eb5b..5b09515864fdd4c16a7d4093613474363d3c5b18 100644
--- a/Framework/API/inc/MantidAPI/CompositeFunction.h
+++ b/Framework/API/inc/MantidAPI/CompositeFunction.h
@@ -247,9 +247,9 @@ private:
 };
 
 /// shared pointer to the composite function base class
-typedef boost::shared_ptr<CompositeFunction> CompositeFunction_sptr;
+using CompositeFunction_sptr = boost::shared_ptr<CompositeFunction>;
 /// shared pointer to the composite function base class (const version)
-typedef boost::shared_ptr<const CompositeFunction> CompositeFunction_const_sptr;
+using CompositeFunction_const_sptr = boost::shared_ptr<const CompositeFunction>;
 
 /** A Jacobian for individual functions
  */
diff --git a/Framework/API/inc/MantidAPI/ConstraintFactory.h b/Framework/API/inc/MantidAPI/ConstraintFactory.h
index 560770e3bc4f3ebb6076e64a18ca526a59251d18..1b410289828059107a79ea65a50aae890e89cb1b 100644
--- a/Framework/API/inc/MantidAPI/ConstraintFactory.h
+++ b/Framework/API/inc/MantidAPI/ConstraintFactory.h
@@ -72,8 +72,8 @@ private:
   ~ConstraintFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ConstraintFactoryImpl>
-    ConstraintFactory;
+using ConstraintFactory =
+    Mantid::Kernel::SingletonHolder<ConstraintFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/CoordTransform.h b/Framework/API/inc/MantidAPI/CoordTransform.h
index 44559433475fb6cdecc6504e30eefc27cf93449c..653aff2d0c2c4d3cda98716f142d0868ca57f6a2 100644
--- a/Framework/API/inc/MantidAPI/CoordTransform.h
+++ b/Framework/API/inc/MantidAPI/CoordTransform.h
@@ -59,10 +59,10 @@ protected:
 };
 
 // Helper typedef for a shared pointer of this type.
-typedef boost::shared_ptr<CoordTransform> CoordTransform_sptr;
+using CoordTransform_sptr = boost::shared_ptr<CoordTransform>;
 
 // Helper typdef for a const shared pointer of this type.
-typedef boost::shared_ptr<const CoordTransform> CoordTransform_const_sptr;
+using CoordTransform_const_sptr = boost::shared_ptr<const CoordTransform>;
 
 } // namespace Mantid
 } // namespace API
diff --git a/Framework/API/inc/MantidAPI/CostFunctionFactory.h b/Framework/API/inc/MantidAPI/CostFunctionFactory.h
index 26d5b33867beff0ae7a09d168fe54bf604bf2699..c03230c26d0c76ac321df6730c7ab61e533e5d8a 100644
--- a/Framework/API/inc/MantidAPI/CostFunctionFactory.h
+++ b/Framework/API/inc/MantidAPI/CostFunctionFactory.h
@@ -63,8 +63,8 @@ private:
   CostFunctionFactoryImpl();
 };
 
-typedef Mantid::Kernel::SingletonHolder<CostFunctionFactoryImpl>
-    CostFunctionFactory;
+using CostFunctionFactory =
+    Mantid::Kernel::SingletonHolder<CostFunctionFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/DetectorSearcher.h b/Framework/API/inc/MantidAPI/DetectorSearcher.h
index 72bbcadc39a082a0344cbe622ea2cd84bd325774..869ce4b64f92a4f606b2f200d13e7c9324694f3e 100644
--- a/Framework/API/inc/MantidAPI/DetectorSearcher.h
+++ b/Framework/API/inc/MantidAPI/DetectorSearcher.h
@@ -56,7 +56,7 @@ class MANTID_API_DLL DetectorSearcher {
 public:
   /// Search result type representing whether a detector was found and if so
   /// which detector index it was.
-  typedef std::tuple<bool, size_t> DetectorSearchResult;
+  using DetectorSearchResult = std::tuple<bool, size_t>;
 
   /// Create a new DetectorSearcher with the given instrument & detectors
   DetectorSearcher(Geometry::Instrument_const_sptr instrument,
diff --git a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h
index 3759129207aa89eaea8d4c3f2953b48d81d101a0..a8c9c4448bcd63f6dd431b41ac8cca9c335cdf43 100644
--- a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h
+++ b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h
@@ -73,8 +73,8 @@ private:
   using Kernel::DynamicFactory<IDomainCreator>::createUnwrapped;
 };
 
-typedef Mantid::Kernel::SingletonHolder<DomainCreatorFactoryImpl>
-    DomainCreatorFactory;
+using DomainCreatorFactory =
+    Mantid::Kernel::SingletonHolder<DomainCreatorFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Framework/API/inc/MantidAPI/ExperimentInfo.h
index 04a28cd65fee13843f52eb0dcf894653c7a0673b..3da43e523a84172950caa29d61c06bb78c9ca684 100644
--- a/Framework/API/inc/MantidAPI/ExperimentInfo.h
+++ b/Framework/API/inc/MantidAPI/ExperimentInfo.h
@@ -237,10 +237,10 @@ private:
 };
 
 /// Shared pointer to ExperimentInfo
-typedef boost::shared_ptr<ExperimentInfo> ExperimentInfo_sptr;
+using ExperimentInfo_sptr = boost::shared_ptr<ExperimentInfo>;
 
 /// Shared pointer to const ExperimentInfo
-typedef boost::shared_ptr<const ExperimentInfo> ExperimentInfo_const_sptr;
+using ExperimentInfo_const_sptr = boost::shared_ptr<const ExperimentInfo>;
 
 } // namespace Mantid
 } // namespace API
diff --git a/Framework/API/inc/MantidAPI/Expression.h b/Framework/API/inc/MantidAPI/Expression.h
index 338db52c0c4b87f40520d9df2ae97dfe9708dfeb..5f37f9f8789b22028c92a100f2bd45e2621c5ac0 100644
--- a/Framework/API/inc/MantidAPI/Expression.h
+++ b/Framework/API/inc/MantidAPI/Expression.h
@@ -94,7 +94,7 @@ public:
   /// Returns the number of argumens
   size_t size() const { return m_terms.size(); }
   /// Const Iterator tpyedef
-  typedef std::vector<Expression>::const_iterator iterator;
+  using iterator = std::vector<Expression>::const_iterator;
 
   /// An iterator pointing to the start of the expressions
   iterator begin() const { return m_terms.begin(); }
@@ -161,7 +161,7 @@ private:
     size_t prec; ///< The precedence of the connecting operator.
   };
   /// The container type
-  typedef std::vector<Token> Tokens;
+  using Tokens = std::vector<Token>;
   /// Get i-th token
   std::string GetToken(size_t i);
   /// Get the operator connecting i-th token
diff --git a/Framework/API/inc/MantidAPI/FileFinder.h b/Framework/API/inc/MantidAPI/FileFinder.h
index 0e0820eab3b3a2c4940fe13958b2ffdf9ec6af34..e9d486f52f2a1b7d13e9770c018a099c16ee9a55 100644
--- a/Framework/API/inc/MantidAPI/FileFinder.h
+++ b/Framework/API/inc/MantidAPI/FileFinder.h
@@ -97,7 +97,7 @@ private:
   int m_globOption;
 };
 
-typedef Mantid::Kernel::SingletonHolder<FileFinderImpl> FileFinder;
+using FileFinder = Mantid::Kernel::SingletonHolder<FileFinderImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
index a55583d29387187cc2384f425ff56a5977039527..38cebdea415423e734f26a5a7086f2de2cb8ad71 100644
--- a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
+++ b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h
@@ -144,8 +144,8 @@ private:
 };
 
 /// Type for the actual singleton instance
-typedef Mantid::Kernel::SingletonHolder<FileLoaderRegistryImpl>
-    FileLoaderRegistry;
+using FileLoaderRegistry =
+    Mantid::Kernel::SingletonHolder<FileLoaderRegistryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FrameworkManager.h b/Framework/API/inc/MantidAPI/FrameworkManager.h
index d6583bda63ac58bed3f998f054426fb564fc9cf0..204a9f621ae7fe4ce021f21b2ffa954b9d15591b 100644
--- a/Framework/API/inc/MantidAPI/FrameworkManager.h
+++ b/Framework/API/inc/MantidAPI/FrameworkManager.h
@@ -135,7 +135,7 @@ private:
 #endif
 };
 
-typedef Mantid::Kernel::SingletonHolder<FrameworkManagerImpl> FrameworkManager;
+using FrameworkManager = Mantid::Kernel::SingletonHolder<FrameworkManagerImpl>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h
index 7944b5e2f915c9ae3bc403f6f7f6893fc4a1fe83..79212a1a391a262eb85375eb0a291965bfb91cfb 100644
--- a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h
+++ b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h
@@ -61,8 +61,8 @@ private:
   FuncMinimizerFactoryImpl();
 };
 
-typedef Mantid::Kernel::SingletonHolder<FuncMinimizerFactoryImpl>
-    FuncMinimizerFactory;
+using FuncMinimizerFactory =
+    Mantid::Kernel::SingletonHolder<FuncMinimizerFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FunctionDomain.h b/Framework/API/inc/MantidAPI/FunctionDomain.h
index cad64a787ac08e82e37ea2f2e4b69515f91b5662..3be1f23a5427f192c6b00f8c0457ca2d669f3bac 100644
--- a/Framework/API/inc/MantidAPI/FunctionDomain.h
+++ b/Framework/API/inc/MantidAPI/FunctionDomain.h
@@ -56,7 +56,7 @@ public:
 };
 
 /// typedef for a shared pointer
-typedef boost::shared_ptr<FunctionDomain> FunctionDomain_sptr;
+using FunctionDomain_sptr = boost::shared_ptr<FunctionDomain>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FunctionDomain1D.h b/Framework/API/inc/MantidAPI/FunctionDomain1D.h
index 42f2fd295b5868ed90b2ce99d10fdba5f50c5750..dabd2d5284da8db293e39de5c1180b707bba80d9 100644
--- a/Framework/API/inc/MantidAPI/FunctionDomain1D.h
+++ b/Framework/API/inc/MantidAPI/FunctionDomain1D.h
@@ -173,9 +173,9 @@ protected:
 };
 
 /// typedef for a shared pointer to a FunctionDomain1D
-typedef boost::shared_ptr<FunctionDomain1D> FunctionDomain1D_sptr;
+using FunctionDomain1D_sptr = boost::shared_ptr<FunctionDomain1D>;
 /// typedef for a shared pointer to a const FunctionDomain1D
-typedef boost::shared_ptr<const FunctionDomain1D> FunctionDomain1D_const_sptr;
+using FunctionDomain1D_const_sptr = boost::shared_ptr<const FunctionDomain1D>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FunctionDomainMD.h b/Framework/API/inc/MantidAPI/FunctionDomainMD.h
index fa52a8a36689278f9a2ab7e01ee33a19badbbc9e..adc80e5bed649ccf48ecff7ef505b91e7450e606 100644
--- a/Framework/API/inc/MantidAPI/FunctionDomainMD.h
+++ b/Framework/API/inc/MantidAPI/FunctionDomainMD.h
@@ -53,7 +53,7 @@ public:
 
 protected:
   /// IMDIterator
-  mutable IMDIterator *m_iterator;
+  mutable std::unique_ptr<IMDIterator> m_iterator;
   /// start of the domain, 0 <= m_startIndex < m_iterator->getDataSize()
   const size_t m_startIndex;
   /// track the iterator's index, 0 <= m_currentIndex < m_size.
diff --git a/Framework/API/inc/MantidAPI/FunctionFactory.h b/Framework/API/inc/MantidAPI/FunctionFactory.h
index 36962ff28982c4314a0c205ddad372e288284dde..1f88005af127a3e43ef2d76449806cb4feca7054 100644
--- a/Framework/API/inc/MantidAPI/FunctionFactory.h
+++ b/Framework/API/inc/MantidAPI/FunctionFactory.h
@@ -142,14 +142,14 @@ const std::vector<std::string> &FunctionFactoryImpl::getFunctionNames() const {
   return typeNames;
 }
 
-typedef Mantid::Kernel::SingletonHolder<FunctionFactoryImpl> FunctionFactory;
+using FunctionFactory = Mantid::Kernel::SingletonHolder<FunctionFactoryImpl>;
 
 /// Convenient typedef for an UpdateNotification
-typedef FunctionFactoryImpl::UpdateNotification
-    FunctionFactoryUpdateNotification;
+using FunctionFactoryUpdateNotification =
+    FunctionFactoryImpl::UpdateNotification;
 /// Convenient typedef for an UpdateNotification AutoPtr
-typedef const Poco::AutoPtr<FunctionFactoryUpdateNotification> &
-    FunctionFactoryUpdateNotification_ptr;
+using FunctionFactoryUpdateNotification_ptr =
+    const Poco::AutoPtr<FunctionFactoryUpdateNotification> &;
 } // namespace API
 } // namespace Mantid
 
diff --git a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h
index 0fc89d44739ae1f1ec34ce7cdf08914ac1a46356..0b24a04663ed8a60e415872224310a6d6e51042c 100644
--- a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h
+++ b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h
@@ -150,8 +150,8 @@ protected:
   IFunction_sptr m_wrappedFunction;
 };
 
-typedef boost::shared_ptr<FunctionParameterDecorator>
-    FunctionParameterDecorator_sptr;
+using FunctionParameterDecorator_sptr =
+    boost::shared_ptr<FunctionParameterDecorator>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/FunctionProperty.h b/Framework/API/inc/MantidAPI/FunctionProperty.h
index 7d254fce7c864af3fc292154e4385c9e4827d825..64189b6038e7e3ac2ab5920afacd5dc624e7d902 100644
--- a/Framework/API/inc/MantidAPI/FunctionProperty.h
+++ b/Framework/API/inc/MantidAPI/FunctionProperty.h
@@ -56,7 +56,7 @@ public:
 
   /// Bring in the PropertyWithValue assignment operator explicitly (avoids
   /// VSC++ warning)
-  boost::shared_ptr<IFunction> &
+  FunctionProperty &
   operator=(const boost::shared_ptr<IFunction> &value) override;
 
   /// Add the value of another property
diff --git a/Framework/API/inc/MantidAPI/FunctionValues.h b/Framework/API/inc/MantidAPI/FunctionValues.h
index de5cbba735743be3297cdbff926b3ff9be951b04..a4cd43e196434301fbe4728cc5ee789419320a2c 100644
--- a/Framework/API/inc/MantidAPI/FunctionValues.h
+++ b/Framework/API/inc/MantidAPI/FunctionValues.h
@@ -121,7 +121,7 @@ protected:
 };
 
 /// typedef for a shared pointer
-typedef boost::shared_ptr<FunctionValues> FunctionValues_sptr;
+using FunctionValues_sptr = boost::shared_ptr<FunctionValues>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/GridDomain.h b/Framework/API/inc/MantidAPI/GridDomain.h
index 252221c1f403e88639544330a408cce0608cf3dd..4400f9398b81a66a746d832be8d6b1bc151a7e66 100644
--- a/Framework/API/inc/MantidAPI/GridDomain.h
+++ b/Framework/API/inc/MantidAPI/GridDomain.h
@@ -58,7 +58,7 @@ private:
 }; // class IGridDomain
 
 /// typedef for a shared pointer
-typedef boost::shared_ptr<GridDomain> GridDomain_sptr;
+using GridDomain_sptr = boost::shared_ptr<GridDomain>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/GridDomain1D.h b/Framework/API/inc/MantidAPI/GridDomain1D.h
index aea1cebcb6dcfd93febe5cb6f2e0cc083d9493ef..f96efdfa043ea12682028a8a20170c9c6aac0370 100644
--- a/Framework/API/inc/MantidAPI/GridDomain1D.h
+++ b/Framework/API/inc/MantidAPI/GridDomain1D.h
@@ -58,7 +58,7 @@ private:
 }; // class IGridDomain
 
 /// typedef for a shared pointer
-typedef boost::shared_ptr<GridDomain1D> GridDomain1D_sptr;
+using GridDomain1D_sptr = boost::shared_ptr<GridDomain1D>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IAlgorithm.h b/Framework/API/inc/MantidAPI/IAlgorithm.h
index 8f239467dbed783094902c3e663663020eb82c7b..5f8888f7643d113677ab062e2e9591a43ff474c7 100644
--- a/Framework/API/inc/MantidAPI/IAlgorithm.h
+++ b/Framework/API/inc/MantidAPI/IAlgorithm.h
@@ -21,7 +21,7 @@ namespace API {
  *  we need a way of uniquely identifying managed algorithms. It can be
  * AlgorithmID.
  */
-typedef void *AlgorithmID;
+using AlgorithmID = void *;
 
 /**
  IAlgorithm is the interface implemented by the Algorithm base class.
@@ -77,6 +77,9 @@ public:
   /// Function to return the separator token for the category string
   virtual const std::string categorySeparator() const = 0;
 
+  /// Function to return all of the seeAlso algorithms related to this algorithm
+  virtual const std::vector<std::string> seeAlso() const = 0;
+
   /// function to return any aliases of the algorithm.
   virtual const std::string alias() const = 0;
 
diff --git a/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h b/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h
index 84e31b1a6a1bbdbc22967e9f326de0266409c74b..5a4db0b5e7a0cd21d6fa1253d22a294c0ee04351 100644
--- a/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h
+++ b/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::IAlgorithm
 class IAlgorithm;
 /// shared pointer to Mantid::API::IAlgorithm
-typedef boost::shared_ptr<IAlgorithm> IAlgorithm_sptr;
+using IAlgorithm_sptr = boost::shared_ptr<IAlgorithm>;
 /// shared pointer to Mantid::API::IAlgorithm (const version)
-typedef boost::shared_ptr<const IAlgorithm> IAlgorithm_const_sptr;
+using IAlgorithm_const_sptr = boost::shared_ptr<const IAlgorithm>;
 /// unique pointer to Mantid::API::IAlgorithm
-typedef std::unique_ptr<IAlgorithm> IAlgorithm_uptr;
+using IAlgorithm_uptr = std::unique_ptr<IAlgorithm>;
 /// unique pointer to Mantid::API::IAlgorithm (const version)
-typedef std::unique_ptr<const IAlgorithm> IAlgorithm_const_uptr;
+using IAlgorithm_const_uptr = std::unique_ptr<const IAlgorithm>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IArchiveSearch.h b/Framework/API/inc/MantidAPI/IArchiveSearch.h
index 293709de702fc6a77e8d9dfc4df2ae90b91ab917..62a7a773dd712be955e942cb6dc6b838bd0505a3 100644
--- a/Framework/API/inc/MantidAPI/IArchiveSearch.h
+++ b/Framework/API/inc/MantidAPI/IArchiveSearch.h
@@ -68,7 +68,7 @@ public:
 };
 
 /// Typedef for a shared pointer to an IArchiveSearch
-typedef boost::shared_ptr<IArchiveSearch> IArchiveSearch_sptr;
+using IArchiveSearch_sptr = boost::shared_ptr<IArchiveSearch>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/IBackgroundFunction.h b/Framework/API/inc/MantidAPI/IBackgroundFunction.h
index 9e670692b8f5389fd795c4584c2e85db3762573c..0f80ccc8ea7b38be262cd4b9439a6ba0dcbec754 100644
--- a/Framework/API/inc/MantidAPI/IBackgroundFunction.h
+++ b/Framework/API/inc/MantidAPI/IBackgroundFunction.h
@@ -44,7 +44,7 @@ public:
                    const std::vector<double> &Y) = 0;
 };
 
-typedef boost::shared_ptr<IBackgroundFunction> IBackgroundFunction_sptr;
+using IBackgroundFunction_sptr = boost::shared_ptr<IBackgroundFunction>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ICatalog.h b/Framework/API/inc/MantidAPI/ICatalog.h
index d11a7ee7dbff0fc9ca33123de9fdf85de7f1a8f0..e5d68b799a0298a7c156cbf67b4069d10dd4013c 100644
--- a/Framework/API/inc/MantidAPI/ICatalog.h
+++ b/Framework/API/inc/MantidAPI/ICatalog.h
@@ -71,8 +71,8 @@ public:
   virtual void keepAlive() = 0;
 };
 
-typedef boost::shared_ptr<ICatalog> ICatalog_sptr;
-typedef boost::shared_ptr<const ICatalog> ICatalog_const_sptr;
+using ICatalog_sptr = boost::shared_ptr<ICatalog>;
+using ICatalog_const_sptr = boost::shared_ptr<const ICatalog>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/ICatalogInfoService.h b/Framework/API/inc/MantidAPI/ICatalogInfoService.h
index dea2b3bdbe4663fea89566637f20a159179a032c..bc247f862d7295e6c449af456714af43251d567a 100644
--- a/Framework/API/inc/MantidAPI/ICatalogInfoService.h
+++ b/Framework/API/inc/MantidAPI/ICatalogInfoService.h
@@ -52,9 +52,9 @@ public:
   virtual ITableWorkspace_sptr getPublishInvestigations() = 0;
 };
 
-typedef boost::shared_ptr<ICatalogInfoService> ICatalogInfoService_sptr;
-typedef boost::shared_ptr<const ICatalogInfoService>
-    ICatalogInfoService_const_sptr;
+using ICatalogInfoService_sptr = boost::shared_ptr<ICatalogInfoService>;
+using ICatalogInfoService_const_sptr =
+    boost::shared_ptr<const ICatalogInfoService>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/ICostFunction.h b/Framework/API/inc/MantidAPI/ICostFunction.h
index 1522861f9183bdd29c5b76a7d44a753c7ff170b0..eab3633fb6e541f56b332b163cf50cea9782ebea 100644
--- a/Framework/API/inc/MantidAPI/ICostFunction.h
+++ b/Framework/API/inc/MantidAPI/ICostFunction.h
@@ -73,7 +73,7 @@ public:
 };
 
 /// define a shared pointer to a cost function
-typedef boost::shared_ptr<ICostFunction> ICostFunction_sptr;
+using ICostFunction_sptr = boost::shared_ptr<ICostFunction>;
 
 /**
  * Macro for declaring a new type of cost functions to be used with the
diff --git a/Framework/API/inc/MantidAPI/IDomainCreator.h b/Framework/API/inc/MantidAPI/IDomainCreator.h
index 81968349aae3a36bbce6612fdcf624d3fc80f7ec..9e127ad3dde258b52a6cc51d0a0a5b6f48e2dc07 100644
--- a/Framework/API/inc/MantidAPI/IDomainCreator.h
+++ b/Framework/API/inc/MantidAPI/IDomainCreator.h
@@ -147,7 +147,7 @@ protected:
 };
 
 /// Typedef for a shared pointer to IDomainCreator.
-typedef boost::shared_ptr<IDomainCreator> IDomainCreator_sptr;
+using IDomainCreator_sptr = boost::shared_ptr<IDomainCreator>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h
index fa4c3ced2657f7e2b4fc7595293ea28a1ec78322..20ccaa322baf528d7841638c3c3a6ff01da3d468 100644
--- a/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::IEventWorkspace
 class IEventWorkspace;
 /// shared pointer to Mantid::API::IEventWorkspace
-typedef boost::shared_ptr<IEventWorkspace> IEventWorkspace_sptr;
+using IEventWorkspace_sptr = boost::shared_ptr<IEventWorkspace>;
 /// shared pointer to Mantid::API::IEventWorkspace (const version)
-typedef boost::shared_ptr<const IEventWorkspace> IEventWorkspace_const_sptr;
+using IEventWorkspace_const_sptr = boost::shared_ptr<const IEventWorkspace>;
 /// unique pointer to Mantid::API::IEventWorkspace
-typedef std::unique_ptr<IEventWorkspace> IEventWorkspace_uptr;
+using IEventWorkspace_uptr = std::unique_ptr<IEventWorkspace>;
 /// unique pointer to Mantid::API::IEventWorkspace (const version)
-typedef std::unique_ptr<const IEventWorkspace> IEventWorkspace_const_uptr;
+using IEventWorkspace_const_uptr = std::unique_ptr<const IEventWorkspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IFuncMinimizer.h b/Framework/API/inc/MantidAPI/IFuncMinimizer.h
index 5ad967a5f66d30fb265ac13f1b199fe4ac6818d3..9f0ae001b6edd4f104c09c21756153d895435706 100644
--- a/Framework/API/inc/MantidAPI/IFuncMinimizer.h
+++ b/Framework/API/inc/MantidAPI/IFuncMinimizer.h
@@ -74,7 +74,7 @@ protected:
   std::string m_errorString;
 };
 
-typedef boost::shared_ptr<IFuncMinimizer> IFuncMinimizer_sptr;
+using IFuncMinimizer_sptr = boost::shared_ptr<IFuncMinimizer>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IFunction.h b/Framework/API/inc/MantidAPI/IFunction.h
index 4c3a319b5cb6cd4c0ac09bdcc0e691026751e663..3df44db33ceaf041b307f8e1265d3ed081dd0d94 100644
--- a/Framework/API/inc/MantidAPI/IFunction.h
+++ b/Framework/API/inc/MantidAPI/IFunction.h
@@ -625,9 +625,9 @@ private:
 };
 
 /// shared pointer to the function base class
-typedef boost::shared_ptr<IFunction> IFunction_sptr;
+using IFunction_sptr = boost::shared_ptr<IFunction>;
 /// shared pointer to the function base class (const version)
-typedef boost::shared_ptr<const IFunction> IFunction_const_sptr;
+using IFunction_const_sptr = boost::shared_ptr<const IFunction>;
 
 /**
  * Classes inherited from FunctionHandler will handle the function.
diff --git a/Framework/API/inc/MantidAPI/IFunction1D.h b/Framework/API/inc/MantidAPI/IFunction1D.h
index e4fb9302f2543e26a71c4d50fbe8cfecb338b0a8..635dc267cf726236ff7a80d0a7d487e18d000867 100644
--- a/Framework/API/inc/MantidAPI/IFunction1D.h
+++ b/Framework/API/inc/MantidAPI/IFunction1D.h
@@ -95,7 +95,7 @@ protected:
   friend class CurveFitting::Algorithms::Fit;
 };
 
-typedef boost::shared_ptr<IFunction1D> IFunction1D_sptr;
+using IFunction1D_sptr = boost::shared_ptr<IFunction1D>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ILatticeFunction.h b/Framework/API/inc/MantidAPI/ILatticeFunction.h
index 8d6825ae82d7ec2032571b28b53bc8e50a8bc8a9..e5091bb253d58d11dd3abfe86101331a294908c8 100644
--- a/Framework/API/inc/MantidAPI/ILatticeFunction.h
+++ b/Framework/API/inc/MantidAPI/ILatticeFunction.h
@@ -66,7 +66,7 @@ public:
   virtual Geometry::UnitCell getUnitCell() const = 0;
 };
 
-typedef boost::shared_ptr<ILatticeFunction> ILatticeFunction_sptr;
+using ILatticeFunction_sptr = boost::shared_ptr<ILatticeFunction>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ILiveListener.h b/Framework/API/inc/MantidAPI/ILiveListener.h
index 1d9d8be5da5de3600917a41a8eb26ab4f7423b91..2b35b37063d7037603f205b2bedfe034fd6c40e4 100644
--- a/Framework/API/inc/MantidAPI/ILiveListener.h
+++ b/Framework/API/inc/MantidAPI/ILiveListener.h
@@ -146,7 +146,7 @@ public:
 };
 
 /// Shared pointer to an ILiveListener
-typedef boost::shared_ptr<ILiveListener> ILiveListener_sptr;
+using ILiveListener_sptr = boost::shared_ptr<ILiveListener>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h
index c1c1e973e850eaf96c20e38d8280399a407f10e1..8caef8801b5fa487f47328ef5ff6a5a1ca45b30f 100644
--- a/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h
@@ -35,13 +35,13 @@ namespace API {
 /// forward declare of Mantid::API::IMDEventWorkspace
 class IMDEventWorkspace;
 /// Shared pointer to Mantid::API::IMDEventWorkspace
-typedef boost::shared_ptr<IMDEventWorkspace> IMDEventWorkspace_sptr;
+using IMDEventWorkspace_sptr = boost::shared_ptr<IMDEventWorkspace>;
 /// Shared pointer to Mantid::API::IMDEventWorkspace (const version)
-typedef boost::shared_ptr<const IMDEventWorkspace> IMDEventWorkspace_const_sptr;
+using IMDEventWorkspace_const_sptr = boost::shared_ptr<const IMDEventWorkspace>;
 /// unique pointer to Mantid::API::IMDEventWorkspace
-typedef std::unique_ptr<IMDEventWorkspace> IMDEventWorkspace_uptr;
+using IMDEventWorkspace_uptr = std::unique_ptr<IMDEventWorkspace>;
 /// unique pointer to Mantid::API::IMDEventWorkspace (const version)
-typedef std::unique_ptr<const IMDEventWorkspace> IMDEventWorkspace_const_uptr;
+using IMDEventWorkspace_const_uptr = std::unique_ptr<const IMDEventWorkspace>;
 
 } // namespace MDEvents
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h
index 9ef1c56f82e468d14f067f0296acf94bb87b64c2..24d1e97de610ad7388d252211d6c8fc335e75e43 100644
--- a/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::IMDHistoWorkspace
 class IMDHistoWorkspace;
 /// shared pointer to Mantid::API::IMDHistoWorkspace
-typedef boost::shared_ptr<IMDHistoWorkspace> IMDHistoWorkspace_sptr;
+using IMDHistoWorkspace_sptr = boost::shared_ptr<IMDHistoWorkspace>;
 /// shared pointer to Mantid::API::IMDHistoWorkspace (const version)
-typedef boost::shared_ptr<const IMDHistoWorkspace> IMDHistoWorkspace_const_sptr;
+using IMDHistoWorkspace_const_sptr = boost::shared_ptr<const IMDHistoWorkspace>;
 /// unique pointer to Mantid::API::IMDHistoWorkspace
-typedef std::unique_ptr<IMDHistoWorkspace> IMDHistoWorkspace_uptr;
+using IMDHistoWorkspace_uptr = std::unique_ptr<IMDHistoWorkspace>;
 /// unique pointer to Mantid::API::IMDHistoWorkspace (const version)
-typedef std::unique_ptr<const IMDHistoWorkspace> IMDHistoWorkspace_const_uptr;
+using IMDHistoWorkspace_const_uptr = std::unique_ptr<const IMDHistoWorkspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IMDIterator.h b/Framework/API/inc/MantidAPI/IMDIterator.h
index 85d50481879e5824c1e63a9cdf8e01f37cf47ff3..ea8ca2a3ff172de36c622526fc10b380ed487769 100644
--- a/Framework/API/inc/MantidAPI/IMDIterator.h
+++ b/Framework/API/inc/MantidAPI/IMDIterator.h
@@ -5,7 +5,6 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/DllConfig.h"
-#include "MantidAPI/IMDWorkspace.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDTypes.h"
 #include "MantidKernel/VMD.h"
@@ -14,10 +13,18 @@
 namespace Mantid {
 
 namespace API {
-//----------------------------------------------------------------------
-// Forward declaration
-//----------------------------------------------------------------------
-class IMDWorkspace;
+
+/** Enum describing different ways to normalize the signal
+ * in a MDWorkspace.
+ */
+enum MDNormalization {
+  /// Don't normalize = return raw counts
+  NoNormalization = 0,
+  /// Divide the signal by the volume of the box/bin
+  VolumeNormalization = 1,
+  /// Divide the signal by the number of events that contributed to it.
+  NumEventsNormalization = 2
+};
 
 /** This is an interface to an iterator of an IMDWorkspace
 
@@ -83,13 +90,14 @@ public:
   virtual signal_t getError() const = 0;
 
   /// Return a list of vertexes defining the volume pointed to
-  virtual coord_t *getVertexesArray(size_t &numVertices) const = 0;
+  virtual std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const = 0;
 
   /// Return a list of vertexes defining the volume pointed to, enable masking
   /// of dimensions.
-  virtual coord_t *getVertexesArray(size_t &numVertices,
-                                    const size_t outDimensions,
-                                    const bool *maskDim) const = 0;
+  virtual std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const = 0;
 
   /// Returns the position of the center of the box pointed to.
   virtual Mantid::Kernel::VMD getCenter() const = 0;
diff --git a/Framework/API/inc/MantidAPI/IMDNode.h b/Framework/API/inc/MantidAPI/IMDNode.h
index a7e1a9f8ad4a50957db71cd524bbdd8d851acad6..09678f09d8aed97e699c8cd0b5de454ecf34217d 100644
--- a/Framework/API/inc/MantidAPI/IMDNode.h
+++ b/Framework/API/inc/MantidAPI/IMDNode.h
@@ -3,6 +3,7 @@
 
 #include <algorithm>
 #include <string>
+#include <memory>
 #include <vector>
 #include "MantidKernel/VMD.h"
 #include "MantidGeometry/MDGeometry/MDTypes.h"
@@ -277,10 +278,11 @@ public:
   // -------------------------------- Geometry/vertexes-Related
   // -------------------------------------------
   virtual std::vector<Mantid::Kernel::VMD> getVertexes() const = 0;
-  virtual coord_t *getVertexesArray(size_t &numVertices) const = 0;
-  virtual coord_t *getVertexesArray(size_t &numVertices,
-                                    const size_t outDimensions,
-                                    const bool *maskDim) const = 0;
+  virtual std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const = 0;
+  virtual std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const = 0;
   virtual void transformDimensions(std::vector<double> &scaling,
                                    std::vector<double> &offset) = 0;
 
diff --git a/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Framework/API/inc/MantidAPI/IMDWorkspace.h
index d8970c6fdc7b6895b883405248e9385badc1d5d0..8e6069d642a03ee7ee883f74ba5549c3c982bfd8 100644
--- a/Framework/API/inc/MantidAPI/IMDWorkspace.h
+++ b/Framework/API/inc/MantidAPI/IMDWorkspace.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_API_IMDWORKSPACE_H_
 #define MANTID_API_IMDWORKSPACE_H_
 
+#include "MantidAPI/IMDIterator.h"
 #include "MantidAPI/ITableWorkspace_fwd.h"
 #include "MantidAPI/MDGeometry.h"
 #include "MantidAPI/Workspace.h"
@@ -16,20 +17,6 @@ class MDImplicitFunction;
 
 namespace API {
 
-class IMDIterator;
-
-/** Enum describing different ways to normalize the signal
- * in a MDWorkspace.
- */
-enum MDNormalization {
-  /// Don't normalize = return raw counts
-  NoNormalization = 0,
-  /// Divide the signal by the volume of the box/bin
-  VolumeNormalization = 1,
-  /// Divide the signal by the number of events that contributed to it.
-  NumEventsNormalization = 2
-};
-
 static const signal_t MDMaskValue = std::numeric_limits<double>::quiet_NaN();
 
 /** Basic MD Workspace Abstract Class.
@@ -106,7 +93,7 @@ public:
   virtual uint64_t getNEvents() const = 0;
 
   /// Creates a new iterator pointing to the first cell in the workspace
-  virtual std::vector<IMDIterator *> createIterators(
+  virtual std::vector<std::unique_ptr<IMDIterator>> createIterators(
       size_t suggestedNumCores = 1,
       Mantid::Geometry::MDImplicitFunction *function = nullptr) const = 0;
 
@@ -126,7 +113,7 @@ public:
                                const Mantid::Kernel::VMD &end,
                                Mantid::API::MDNormalization normalize) const;
 
-  IMDIterator *createIterator(
+  std::unique_ptr<IMDIterator> createIterator(
       Mantid::Geometry::MDImplicitFunction *function = nullptr) const;
 
   std::string getConvention() const;
@@ -189,9 +176,9 @@ private:
 };
 
 /// Shared pointer to the IMDWorkspace base class
-typedef boost::shared_ptr<IMDWorkspace> IMDWorkspace_sptr;
+using IMDWorkspace_sptr = boost::shared_ptr<IMDWorkspace>;
 /// Shared pointer to the IMDWorkspace base class (const version)
-typedef boost::shared_ptr<const IMDWorkspace> IMDWorkspace_const_sptr;
+using IMDWorkspace_const_sptr = boost::shared_ptr<const IMDWorkspace>;
 }
 }
 #endif // MANTID_API_IMDWORKSPACE_H_
diff --git a/Framework/API/inc/MantidAPI/IMaskWorkspace.h b/Framework/API/inc/MantidAPI/IMaskWorkspace.h
index cd51c350aaf32b1e154f0c4223c362a707c31a88..333a9abbf6d704ff4a3160e181306c543f6539dd 100644
--- a/Framework/API/inc/MantidAPI/IMaskWorkspace.h
+++ b/Framework/API/inc/MantidAPI/IMaskWorkspace.h
@@ -38,6 +38,7 @@ class DLLExport IMaskWorkspace {
 public:
   IMaskWorkspace() = default;
   IMaskWorkspace &operator=(const IMaskWorkspace &) = delete;
+  virtual ~IMaskWorkspace() = default;
   /// Return the workspace typeID
   virtual const std::string id() const { return "IMaskWorkspace"; }
   /// Total number of masked pixels
@@ -65,9 +66,9 @@ protected:
 };
 
 /// shared pointer to the matrix workspace base class
-typedef boost::shared_ptr<IMaskWorkspace> IMaskWorkspace_sptr;
+using IMaskWorkspace_sptr = boost::shared_ptr<IMaskWorkspace>;
 /// shared pointer to the matrix workspace base class (const version)
-typedef boost::shared_ptr<const IMaskWorkspace> IMaskWorkspace_const_sptr;
+using IMaskWorkspace_const_sptr = boost::shared_ptr<const IMaskWorkspace>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/IPawleyFunction.h b/Framework/API/inc/MantidAPI/IPawleyFunction.h
index fcba0af04d202d32274905c4571f24b968f70860..66a9667694159dc7cf318f553d43df6fddbfc68b 100644
--- a/Framework/API/inc/MantidAPI/IPawleyFunction.h
+++ b/Framework/API/inc/MantidAPI/IPawleyFunction.h
@@ -70,7 +70,7 @@ public:
   virtual Kernel::V3D getPeakHKL(size_t i) const = 0;
 };
 
-typedef boost::shared_ptr<IPawleyFunction> IPawleyFunction_sptr;
+using IPawleyFunction_sptr = boost::shared_ptr<IPawleyFunction>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IPeakFunction.h b/Framework/API/inc/MantidAPI/IPeakFunction.h
index 16984f0a6c180b63fe788bfec68c5ebd191cf4fb..c80531b5ed4ce79ddad0c9cdc0c036357ec584b2 100644
--- a/Framework/API/inc/MantidAPI/IPeakFunction.h
+++ b/Framework/API/inc/MantidAPI/IPeakFunction.h
@@ -103,8 +103,8 @@ private:
   static constexpr double DEFAULT_SEARCH_LEVEL = 1e-5;
 };
 
-typedef boost::shared_ptr<IPeakFunction> IPeakFunction_sptr;
-typedef boost::shared_ptr<const IPeakFunction> IPeakFunction_const_sptr;
+using IPeakFunction_sptr = boost::shared_ptr<IPeakFunction>;
+using IPeakFunction_const_sptr = boost::shared_ptr<const IPeakFunction>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h
index 1b62f578bc62b0d43764e16d6865ed401c20ee6e..1c195e34f250eb756314b4607ce89b5a1b6d380a 100644
--- a/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::IPeaksWorkspace
 class IPeaksWorkspace;
 /// shared pointer to Mantid::API::IPeaksWorkspace
-typedef boost::shared_ptr<IPeaksWorkspace> IPeaksWorkspace_sptr;
+using IPeaksWorkspace_sptr = boost::shared_ptr<IPeaksWorkspace>;
 /// shared pointer to Mantid::API::IPeaksWorkspace (const version)
-typedef boost::shared_ptr<const IPeaksWorkspace> IPeaksWorkspace_const_sptr;
+using IPeaksWorkspace_const_sptr = boost::shared_ptr<const IPeaksWorkspace>;
 /// unique pointer to Mantid::API::IPeaksWorkspace
-typedef std::unique_ptr<IPeaksWorkspace> IPeaksWorkspace_uptr;
+using IPeaksWorkspace_uptr = std::unique_ptr<IPeaksWorkspace>;
 /// unique pointer to Mantid::API::IPeaksWorkspace (const version)
-typedef std::unique_ptr<const IPeaksWorkspace> IPeaksWorkspace_const_uptr;
+using IPeaksWorkspace_const_uptr = std::unique_ptr<const IPeaksWorkspace>;
 }
 }
 #endif // MANTID_API_IPEAKWORKSPACE_FWD_H_
diff --git a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
index c9c0cedae08467bb3d730a42d180f906d6316a1b..954ede14500a1c0e4e21fd822dbe6f47f3a69818 100644
--- a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
+++ b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
@@ -159,7 +159,7 @@ protected:
   size_t HEIGHTINDEX;
 };
 
-typedef boost::shared_ptr<IPowderDiffPeakFunction> IPowderDiffPeakFunction_sptr;
+using IPowderDiffPeakFunction_sptr = boost::shared_ptr<IPowderDiffPeakFunction>;
 
 /// Integral for Gamma
 std::complex<double> MANTID_API_DLL E1(std::complex<double> z);
diff --git a/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Framework/API/inc/MantidAPI/IRemoteJobManager.h
index 3abb44a3d1c3eca1c45e221cb33a9f8e229e1538..fd0a780c7ed11d563a7a3e21b3feedfd62e4c801 100644
--- a/Framework/API/inc/MantidAPI/IRemoteJobManager.h
+++ b/Framework/API/inc/MantidAPI/IRemoteJobManager.h
@@ -290,7 +290,7 @@ public:
 };
 
 // shared pointer type for the IRemoteJobManager
-typedef boost::shared_ptr<IRemoteJobManager> IRemoteJobManager_sptr;
+using IRemoteJobManager_sptr = boost::shared_ptr<IRemoteJobManager>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h
index 6d6d3562cd98a742a29079f3c71c8ea9dc227a7e..95fcecee9f7ea3d01103577573d26d46c1be4dc4 100644
--- a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h
+++ b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h
@@ -80,10 +80,10 @@ private:
 };
 
 /// Typedef for a shared pointer to \c TableWorkspace
-typedef boost::shared_ptr<ISplittersWorkspace> ISplittersWorkspace_sptr;
+using ISplittersWorkspace_sptr = boost::shared_ptr<ISplittersWorkspace>;
 /// Typedef for a shared pointer to \c const \c TableWorkspace
-typedef boost::shared_ptr<const ISplittersWorkspace>
-    ISplittersWorkspace_const_sptr;
+using ISplittersWorkspace_const_sptr =
+    boost::shared_ptr<const ISplittersWorkspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h b/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h
index 296fafc4373512530c02a59970fbe3348bf915af..57f6fe154c00c5887b6e9f0def98c62c7bacf4c5 100644
--- a/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::ITableWorkspace
 class ITableWorkspace;
 /// shared pointer to Mantid::API::ITableWorkspace
-typedef boost::shared_ptr<ITableWorkspace> ITableWorkspace_sptr;
+using ITableWorkspace_sptr = boost::shared_ptr<ITableWorkspace>;
 /// shared pointer to Mantid::API::ITableWorkspace (const version)
-typedef boost::shared_ptr<const ITableWorkspace> ITableWorkspace_const_sptr;
+using ITableWorkspace_const_sptr = boost::shared_ptr<const ITableWorkspace>;
 /// unique pointer to Mantid::API::ITableWorkspace
-typedef std::unique_ptr<ITableWorkspace> ITableWorkspace_uptr;
+using ITableWorkspace_uptr = std::unique_ptr<ITableWorkspace>;
 /// unique pointer to Mantid::API::ITableWorkspace (const version)
-typedef std::unique_ptr<const ITableWorkspace> ITableWorkspace_const_uptr;
+using ITableWorkspace_const_uptr = std::unique_ptr<const ITableWorkspace>;
 
 } // namespace API
 } // Namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ITransformScale.h b/Framework/API/inc/MantidAPI/ITransformScale.h
index 1f13b998a4431ee853926ed12a93439b625ea2aa..4469fbbca1981b8fc3e571f160dc62de29d88b52 100644
--- a/Framework/API/inc/MantidAPI/ITransformScale.h
+++ b/Framework/API/inc/MantidAPI/ITransformScale.h
@@ -54,7 +54,7 @@ public:
 }; // class ITransformScale
 
 /// typedef for a shared pointer
-typedef boost::shared_ptr<ITransformScale> ITransformScale_sptr;
+using ITransformScale_sptr = boost::shared_ptr<ITransformScale>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h
index 10b8c9f04b4eb515313e6a0ca0b03df4e1c2318d..69c2261c00635fd8921e8b8c7bb3c3fa85b7f5a8 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h
@@ -64,8 +64,8 @@ private:
   ~ImplicitFunctionFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ImplicitFunctionFactoryImpl>
-    ImplicitFunctionFactory;
+using ImplicitFunctionFactory =
+    Mantid::Kernel::SingletonHolder<ImplicitFunctionFactoryImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h
index f8a5a4bcc7d2bc17494c6f9e50a7bc57eb869aba..e479bcfe1302584d64ad798be6782a17c783ac45 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h
@@ -103,7 +103,7 @@ template <typename T> struct ElementTraits {};
 /** ElementTraits for boolean element types.
 */
 template <> struct ElementTraits<size_t> {
-  typedef size_t ValueType;
+  using ValueType = size_t;
   static std::string formatCS(const ValueType &value) {
     return boost::str(boost::format("%u,") % value);
   }
@@ -115,7 +115,7 @@ template <> struct ElementTraits<size_t> {
 /** ElementTraits for boolean element types.
 */
 template <> struct ElementTraits<bool> {
-  typedef bool ValueType;
+  using ValueType = bool;
   static std::string formatCS(const ValueType &value) {
     return boost::str(boost::format("%u,") % value);
   }
@@ -127,7 +127,7 @@ template <> struct ElementTraits<bool> {
 /** ElementTraits for double element types.
 */
 template <> struct ElementTraits<double> {
-  typedef double ValueType;
+  using ValueType = double;
   static std::string formatCS(const ValueType &value) {
     return boost::str(boost::format("%.4f,") % value);
   }
@@ -139,7 +139,7 @@ template <> struct ElementTraits<double> {
 /** ElementTraits for float element types.
 */
 template <> struct ElementTraits<float> {
-  typedef double ValueType;
+  using ValueType = double;
   static std::string formatCS(const ValueType &value) {
     return boost::str(boost::format("%.4f,") % value);
   }
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h
index d4a3ba774a6156bf1ef9e5390692fbbc3eed5ec5..a769902c6477c51715f2fa70579f7778df242f96 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h
@@ -81,9 +81,9 @@ class MANTID_API_DLL ImplicitFunctionParameterParser {
 public:
   /// Successor type. Unique shared pointer with stack scoped deletion
   /// semantics.
-  typedef boost::interprocess::unique_ptr<
+  using SuccessorType = boost::interprocess::unique_ptr<
       ImplicitFunctionParameterParser,
-      DeleterPolicy<ImplicitFunctionParameterParser>> SuccessorType;
+      DeleterPolicy<ImplicitFunctionParameterParser>>;
 
   virtual ImplicitFunctionParameter *
   createParameter(Poco::XML::Element *parameterElement) = 0;
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h
index 98578f7383c4f556d821c2e5c82922993fe392f2..7bf1cfd831ddaea4eb2e31c0efce2bf65ffe9a7f 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h
@@ -62,9 +62,8 @@ private:
   ~ImplicitFunctionParameterParserFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<
-    ImplicitFunctionParameterParserFactoryImpl>
-    ImplicitFunctionParameterParserFactory;
+using ImplicitFunctionParameterParserFactory =
+    Mantid::Kernel::SingletonHolder<ImplicitFunctionParameterParserFactoryImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h
index b922fe1ae088b1ec87464068852c8a74287f1479..4ad8da99e9b79dcf0fca5e29959831736052d995 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h
@@ -68,9 +68,9 @@ namespace API {
 class MANTID_API_DLL ImplicitFunctionParser {
 public:
   /// Successor type. Unique pointer with stack scoped deletion semantics.
-  typedef boost::interprocess::unique_ptr<ImplicitFunctionParser,
-                                          DeleterPolicy<ImplicitFunctionParser>>
-      SuccessorType;
+  using SuccessorType =
+      boost::interprocess::unique_ptr<ImplicitFunctionParser,
+                                      DeleterPolicy<ImplicitFunctionParser>>;
 
 protected:
   ImplicitFunctionParameterParser::SuccessorType
diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h
index 0c6b2e00f18791a05aa0a4b5f4685beb39060825..38219e7c9cd297dc3406137832babf1813a8d8c8 100644
--- a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h
+++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h
@@ -66,8 +66,8 @@ private:
   ~ImplicitFunctionParserFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ImplicitFunctionParserFactoryImpl>
-    ImplicitFunctionParserFactory;
+using ImplicitFunctionParserFactory =
+    Mantid::Kernel::SingletonHolder<ImplicitFunctionParserFactoryImpl>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/IndexProperty.h b/Framework/API/inc/MantidAPI/IndexProperty.h
index 1952a88d54c173ceae0e07af0c54bd02043681ce..dad8fdd724cf12eb035ae65e8a4a535310a4f5c2 100644
--- a/Framework/API/inc/MantidAPI/IndexProperty.h
+++ b/Framework/API/inc/MantidAPI/IndexProperty.h
@@ -57,7 +57,7 @@ public:
 
   bool isDefault() const override;
   std::string isValid() const override;
-  std::string operator=(const std::string &rhs);
+  IndexProperty &operator=(const std::string &rhs);
   operator Indexing::SpectrumIndexSet() const;
   Indexing::SpectrumIndexSet getIndices() const;
   Indexing::IndexInfo getFilteredIndexInfo() const;
diff --git a/Framework/API/inc/MantidAPI/IndexTypeProperty.h b/Framework/API/inc/MantidAPI/IndexTypeProperty.h
index 4ee308d2584ad4289e862356b3a48fd615d5d544..4ad313bfd15b157b4cf794a3eaddb33ee5f1e330 100644
--- a/Framework/API/inc/MantidAPI/IndexTypeProperty.h
+++ b/Framework/API/inc/MantidAPI/IndexTypeProperty.h
@@ -52,7 +52,7 @@ public:
 
   using PropertyWithValue<std::string>::operator=;
 
-  std::string &operator=(API::IndexType type);
+  IndexTypeProperty &operator=(API::IndexType type);
 
   static std::string generatePropertyName(const std::string &name = "");
 
@@ -63,4 +63,4 @@ private:
 } // namespace API
 } // namespace Mantid
 
-#endif /* MANTID_API_INDEXTYPEPROPERTY_H_ */
\ No newline at end of file
+#endif /* MANTID_API_INDEXTYPEPROPERTY_H_ */
diff --git a/Framework/API/inc/MantidAPI/InstrumentDataService.h b/Framework/API/inc/MantidAPI/InstrumentDataService.h
index 3ff486fb1cecc7484085b00fb9fd8522c14496bd..f5d22334a71cdbabd1ed4038385d0c62bf040921 100644
--- a/Framework/API/inc/MantidAPI/InstrumentDataService.h
+++ b/Framework/API/inc/MantidAPI/InstrumentDataService.h
@@ -48,8 +48,8 @@ private:
   operator=(const InstrumentDataServiceImpl &) = delete;
 };
 
-typedef Mantid::Kernel::SingletonHolder<InstrumentDataServiceImpl>
-    InstrumentDataService;
+using InstrumentDataService =
+    Mantid::Kernel::SingletonHolder<InstrumentDataServiceImpl>;
 
 } // Namespace API
 } // Namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/LiveListenerFactory.h b/Framework/API/inc/MantidAPI/LiveListenerFactory.h
index 5b241e996978b45d0a151a942bdb8dfa9af7290d..4346d7d1568513406d515e3c8270b5550e802b7f 100644
--- a/Framework/API/inc/MantidAPI/LiveListenerFactory.h
+++ b/Framework/API/inc/MantidAPI/LiveListenerFactory.h
@@ -80,7 +80,7 @@ private:
   ILiveListener *createUnwrapped(const std::string &className) const override;
 };
 
-typedef Kernel::SingletonHolder<LiveListenerFactoryImpl> LiveListenerFactory;
+using LiveListenerFactory = Kernel::SingletonHolder<LiveListenerFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/LogManager.h b/Framework/API/inc/MantidAPI/LogManager.h
index 384de831562cc76de246c5719946b8b00821f7ef..50552a46f487eecdef6543909a96bb4b3f8f0534 100644
--- a/Framework/API/inc/MantidAPI/LogManager.h
+++ b/Framework/API/inc/MantidAPI/LogManager.h
@@ -22,7 +22,7 @@ namespace Kernel {
 template <class KEYTYPE, class VALUETYPE> class Cache;
 template <typename TYPE> class TimeSeriesProperty;
 class SplittingInterval;
-typedef std::vector<SplittingInterval> TimeSplitterType;
+using TimeSplitterType = std::vector<SplittingInterval>;
 class PropertyManager;
 }
 
@@ -209,9 +209,9 @@ private:
       m_singleValueCache;
 };
 /// shared pointer to the logManager base class
-typedef boost::shared_ptr<LogManager> LogManager_sptr;
+using LogManager_sptr = boost::shared_ptr<LogManager>;
 /// shared pointer to the logManager base class (const version)
-typedef boost::shared_ptr<const LogManager> LogManager_const_sptr;
+using LogManager_const_sptr = boost::shared_ptr<const LogManager>;
 
 /**
  * Add a property of a specified type (Simply creates a Kernel::Property of that
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
index 089c24ecf53a3df9751d069b1fc45402d4d88596..3fe921d12c0c643e8d0db88fcab6cb146e07c6dc 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
@@ -32,11 +32,11 @@ class Axis;
 class SpectrumDetectorMapping;
 
 /// typedef for the image type
-typedef std::vector<std::vector<double>> MantidImage;
+using MantidImage = std::vector<std::vector<double>>;
 /// shared pointer to MantidImage
-typedef boost::shared_ptr<MantidImage> MantidImage_sptr;
+using MantidImage_sptr = boost::shared_ptr<MantidImage>;
 /// shared pointer to const MantidImage
-typedef boost::shared_ptr<const MantidImage> MantidImage_const_sptr;
+using MantidImage_const_sptr = boost::shared_ptr<const MantidImage>;
 
 //----------------------------------------------------------------------
 /** Base MatrixWorkspace Abstract Class.
@@ -449,7 +449,7 @@ public:
   bool hasMaskedBins(const size_t &workspaceIndex) const;
   /// Masked bins for each spectrum are stored as a set of pairs containing <bin
   /// index, weight>
-  typedef std::map<size_t, double> MaskList;
+  using MaskList = std::map<size_t, double>;
   const MaskList &maskedBins(const size_t &workspaceIndex) const;
   void setMaskedBins(const size_t workspaceIndex, const MaskList &maskedBins);
 
@@ -499,7 +499,7 @@ public:
       const Mantid::API::MDNormalization &normalization) const override;
   /// Create iterators. Partitions the iterators according to the number of
   /// cores.
-  std::vector<IMDIterator *> createIterators(
+  std::vector<std::unique_ptr<IMDIterator>> createIterators(
       size_t suggestedNumCores = 1,
       Mantid::Geometry::MDImplicitFunction *function = nullptr) const override;
 
@@ -622,9 +622,9 @@ protected:
 };
 
 /// shared pointer to the matrix workspace base class
-typedef boost::shared_ptr<MatrixWorkspace> MatrixWorkspace_sptr;
+using MatrixWorkspace_sptr = boost::shared_ptr<MatrixWorkspace>;
 /// shared pointer to the matrix workspace base class (const version)
-typedef boost::shared_ptr<const MatrixWorkspace> MatrixWorkspace_const_sptr;
+using MatrixWorkspace_const_sptr = boost::shared_ptr<const MatrixWorkspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
index 7bcde9b23863f237fa13299422bde7cf00cb29bd..0432b6eefd1d1f7f3895507eebde59c3e7d22c65 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
@@ -60,10 +60,12 @@ public:
 
   signal_t getError() const override;
 
-  coord_t *getVertexesArray(size_t &numVertices) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const override;
 
-  coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions,
-                            const bool *maskDim) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const override;
 
   Mantid::Kernel::VMD getCenter() const override;
 
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h b/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h
index 1d764b9fd8bc680c380eb55a08f26e53090c9ac7..ce00dc64d50ac922c513819b5ffd52bb5890b783 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::MatrixWorkspace
 class MatrixWorkspace;
 /// shared pointer to Mantid::API::MatrixWorkspace
-typedef boost::shared_ptr<MatrixWorkspace> MatrixWorkspace_sptr;
+using MatrixWorkspace_sptr = boost::shared_ptr<MatrixWorkspace>;
 /// shared pointer to Mantid::API::MatrixWorkspace (const version)
-typedef boost::shared_ptr<const MatrixWorkspace> MatrixWorkspace_const_sptr;
+using MatrixWorkspace_const_sptr = boost::shared_ptr<const MatrixWorkspace>;
 /// unique pointer to Mantid::API::MatrixWorkspace
-typedef std::unique_ptr<MatrixWorkspace> MatrixWorkspace_uptr;
+using MatrixWorkspace_uptr = std::unique_ptr<MatrixWorkspace>;
 /// unique pointer to Mantid::API::MatrixWorkspace (const version)
-typedef std::unique_ptr<const MatrixWorkspace> MatrixWorkspace_const_uptr;
+using MatrixWorkspace_const_uptr = std::unique_ptr<const MatrixWorkspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/MuParserUtils.h b/Framework/API/inc/MantidAPI/MuParserUtils.h
index dd075d7598bb4a2094bd73bec01a7d2145204bf1..2476429184a695b107ddfab9947b179ad5c43b67 100644
--- a/Framework/API/inc/MantidAPI/MuParserUtils.h
+++ b/Framework/API/inc/MantidAPI/MuParserUtils.h
@@ -42,7 +42,7 @@ extern const MANTID_API_DLL std::map<double, std::string> MUPARSER_CONSTANTS;
 /// Add a set of default constants to a muParser.
 void MANTID_API_DLL addDefaultConstants(mu::Parser &parser);
 
-typedef double (*oneVarFun)(double); // pointer to a function of one variable
+using oneVarFun = double (*)(double); // pointer to a function of one variable
 extern const MANTID_API_DLL std::map<std::string, oneVarFun>
     MUPARSER_ONEVAR_FUNCTIONS;
 
diff --git a/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h b/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h
index e3fa26d309176f01f3e466eed52406347cffcf2d..3ed263ca478134e659ef0f7d52254c35d2d816cd 100644
--- a/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h
+++ b/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h
@@ -52,7 +52,7 @@ private:
   virtual bool useCustomInputPropertyName() const { return false; }
 
   /// Convenience typdef for workspace names.
-  typedef MultiPeriodGroupWorker::VecWSGroupType VecWSGroupType;
+  using VecWSGroupType = MultiPeriodGroupWorker::VecWSGroupType;
   /// multi period group workspaces.
   VecWSGroupType m_multiPeriodGroups;
   /// Multiperiod group worker.
diff --git a/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h b/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h
index 89b2cad4803e5729108100c031eb3c94fc864120..18a888dadbdea3fae43c0bd5ac55f7b8f37ddd6a 100644
--- a/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h
+++ b/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h
@@ -46,7 +46,7 @@ namespace API {
 class DLLExport MultiPeriodGroupWorker {
 public:
   /// Convenience typdef for workspace names.
-  typedef std::vector<WorkspaceGroup_sptr> VecWSGroupType;
+  using VecWSGroupType = std::vector<WorkspaceGroup_sptr>;
   /// Constructor
   MultiPeriodGroupWorker() = default;
   /// Constructor
diff --git a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h
index 053cb9f33fdd6e921fbc5ead87a25c1ea685e18b..a1eedc145f1ec5c711cdad360a9a1080f72c38a3 100644
--- a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h
+++ b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h
@@ -63,9 +63,9 @@ private:
   std::vector<ExperimentInfo_sptr> m_expInfos;
 };
 
-typedef boost::shared_ptr<MultipleExperimentInfos> MultipleExperimentInfos_sptr;
-typedef boost::shared_ptr<const MultipleExperimentInfos>
-    MultipleExperimentInfos_const_sptr;
+using MultipleExperimentInfos_sptr = boost::shared_ptr<MultipleExperimentInfos>;
+using MultipleExperimentInfos_const_sptr =
+    boost::shared_ptr<const MultipleExperimentInfos>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/Projection.h b/Framework/API/inc/MantidAPI/Projection.h
index 08a600f47a8f921fad7e2d81d97981f0d0645765..ecb29ba18490487a68bddadde06b7f622a839782 100644
--- a/Framework/API/inc/MantidAPI/Projection.h
+++ b/Framework/API/inc/MantidAPI/Projection.h
@@ -82,7 +82,7 @@ protected:
   ProjectionUnit m_units[3];
 };
 
-typedef boost::shared_ptr<Projection> Projection_sptr;
+using Projection_sptr = boost::shared_ptr<Projection>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h
index 8fb819cd541c8f6c73d71136f15eb1b97910405c..e386c860b1cbd916ba81ed37ae88dca47c16d28a 100644
--- a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h
+++ b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h
@@ -87,8 +87,8 @@ private:
 };
 
 // The factory is just a specialisation of SingletonHolder
-typedef Mantid::Kernel::SingletonHolder<RemoteJobManagerFactoryImpl>
-    RemoteJobManagerFactory;
+using RemoteJobManagerFactory =
+    Mantid::Kernel::SingletonHolder<RemoteJobManagerFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/ScriptRepository.h b/Framework/API/inc/MantidAPI/ScriptRepository.h
index e41d02288b997c53df24c7a25b091aaafc5d88ba..36169d635cf371ee5e03a0a4b877960d3866f7df 100644
--- a/Framework/API/inc/MantidAPI/ScriptRepository.h
+++ b/Framework/API/inc/MantidAPI/ScriptRepository.h
@@ -605,7 +605,7 @@ public:
 };
 
 /// shared pointer to the function base class
-typedef boost::shared_ptr<ScriptRepository> ScriptRepository_sptr;
+using ScriptRepository_sptr = boost::shared_ptr<ScriptRepository>;
 }
 }
 
diff --git a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h
index f5bad9732e7069cbea92017de01573c7e2e31be6..69c01aaa76b0c3e83c25c87095a6644b7bcd8401 100644
--- a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h
+++ b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h
@@ -67,8 +67,8 @@ private:
   ~ScriptRepositoryFactoryImpl() override = default;
 };
 
-typedef Mantid::Kernel::SingletonHolder<ScriptRepositoryFactoryImpl>
-    ScriptRepositoryFactory;
+using ScriptRepositoryFactory =
+    Mantid::Kernel::SingletonHolder<ScriptRepositoryFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/SingleValueParameter.h b/Framework/API/inc/MantidAPI/SingleValueParameter.h
index a8bfdf43a801e74c77391b25dcebd7e34d9d2bdd..8736075130a52896ff8aad6ea9a4df709f0815a7 100644
--- a/Framework/API/inc/MantidAPI/SingleValueParameter.h
+++ b/Framework/API/inc/MantidAPI/SingleValueParameter.h
@@ -43,7 +43,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 template <typename Derived, typename ValType>
 class DLLExport SingleValueParameter : public ImplicitFunctionParameter {
 public:
-  typedef ValType ValueType;
+  using ValueType = ValType;
   SingleValueParameter(ValType value);
   SingleValueParameter();
   SingleValueParameter(const SingleValueParameter<Derived, ValType> &other);
@@ -159,7 +159,7 @@ std::string SingleValueParameter<Derived, ValType>::toXMLString() const {
   class classname                                                              \
       : public Mantid::API::SingleValueParameter<classname, type_> {           \
   public:                                                                      \
-    typedef Mantid::API::SingleValueParameter<classname, type_> SuperType;     \
+    using SuperType = Mantid::API::SingleValueParameter<classname, type_>;     \
     static std::string parameterName() { return #classname; }                  \
     classname(type_ value) : SuperType(value) {}                               \
     classname() : SuperType() {}                                               \
diff --git a/Framework/API/inc/MantidAPI/SingleValueParameterParser.h b/Framework/API/inc/MantidAPI/SingleValueParameterParser.h
index 78f562d2248856f733c37bac7789570c6a897533..a0ec788a261d54d2728bc831b848e75e8f2c6217 100644
--- a/Framework/API/inc/MantidAPI/SingleValueParameterParser.h
+++ b/Framework/API/inc/MantidAPI/SingleValueParameterParser.h
@@ -79,7 +79,7 @@ template <class SingleValueParameterType>
 Mantid::API::ImplicitFunctionParameter *
 SingleValueParameterParser<SingleValueParameterType>::createParameter(
     Poco::XML::Element *parameterElement) {
-  typedef typename SingleValueParameterType::ValueType ValType;
+  using ValType = typename SingleValueParameterType::ValueType;
   std::string typeName = parameterElement->getChildElement("Type")->innerText();
   if (SingleValueParameterType::parameterName() != typeName) {
     return m_successor->createParameter(parameterElement);
@@ -101,7 +101,7 @@ template <class SingleValueParameterType>
 SingleValueParameterType *
 SingleValueParameterParser<SingleValueParameterType>::createWithoutDelegation(
     Poco::XML::Element *parameterElement) {
-  typedef typename SingleValueParameterType::ValueType ValType;
+  using ValType = typename SingleValueParameterType::ValueType;
   std::string typeName = parameterElement->getChildElement("Type")->innerText();
   if (SingleValueParameterType::parameterName() != typeName) {
     throw std::runtime_error("The attempted ::createWithoutDelegation failed. "
diff --git a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
index c21655a2b8c82bb3ec0225a0999aecfa763aea24..9c1bbce1b7bb8e9e63ed839df8a9b03cb9cb6569 100644
--- a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
+++ b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
@@ -10,11 +10,11 @@
 namespace Mantid {
 
 /// Map with key = spectrum number, value = workspace index
-typedef std::unordered_map<specnum_t, size_t> spec2index_map;
+using spec2index_map = std::unordered_map<specnum_t, size_t>;
 /// Map with key = detector ID, value = workspace index
-typedef std::unordered_map<detid_t, size_t> detid2index_map;
+using detid2index_map = std::unordered_map<detid_t, size_t>;
 /// Map single det ID of group to its members
-typedef std::unordered_map<detid_t, std::set<detid_t>> det2group_map;
+using det2group_map = std::unordered_map<detid_t, std::set<detid_t>>;
 }
 
 #endif // MANTID_API_SPECTRADETECTORMAP_TYPES
diff --git a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h
index 8e08dd2de44258038e542b85cfe27bc9d20142e2..e8429fa25dfd7568c78e1de69406bf144b4b08eb 100644
--- a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h
+++ b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h
@@ -50,7 +50,7 @@ class MatrixWorkspace;
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 class MANTID_API_DLL SpectrumDetectorMapping {
-  typedef std::unordered_map<specnum_t, std::set<detid_t>> sdmap;
+  using sdmap = std::unordered_map<specnum_t, std::set<detid_t>>;
 
 public:
   explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace,
diff --git a/Framework/API/inc/MantidAPI/TransformScaleFactory.h b/Framework/API/inc/MantidAPI/TransformScaleFactory.h
index 1ec1309ad16e0a7f00552e9853dd26916ff18e59..7ec4daa8562cc6dec1a012947de35356a1d2f85f 100644
--- a/Framework/API/inc/MantidAPI/TransformScaleFactory.h
+++ b/Framework/API/inc/MantidAPI/TransformScaleFactory.h
@@ -66,8 +66,8 @@ private:
   // Do not use default methods
 };
 
-typedef Mantid::Kernel::SingletonHolder<TransformScaleFactoryImpl>
-    TransformScaleFactory;
+using TransformScaleFactory =
+    Mantid::Kernel::SingletonHolder<TransformScaleFactoryImpl>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/VectorParameter.h b/Framework/API/inc/MantidAPI/VectorParameter.h
index 0c64e01b19ed1fd7354f867b4fe6e648be4205e3..efc256f68eeeda2cbe227c947513ec9481cccef5 100644
--- a/Framework/API/inc/MantidAPI/VectorParameter.h
+++ b/Framework/API/inc/MantidAPI/VectorParameter.h
@@ -39,7 +39,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 template <typename Derived, typename ElemType>
 class DLLExport VectorParameter : public ImplicitFunctionParameter {
 public:
-  typedef ElemType ValueType;
+  using ValueType = ElemType;
   VectorParameter();
   VectorParameter(size_t size);
   VectorParameter(const VectorParameter<Derived, ElemType> &other);
@@ -245,7 +245,7 @@ ElemType &VectorParameter<Derived, ElemType>::at(size_t index) {
 #define DECLARE_VECTOR_PARAMETER(classname, type_)                             \
   class classname : public Mantid::API::VectorParameter<classname, type_> {    \
   public:                                                                      \
-    typedef Mantid::API::VectorParameter<classname, type_> SuperType;          \
+    using SuperType = Mantid::API::VectorParameter<classname, type_>;          \
     static std::string parameterName() { return #classname; }                  \
     classname() : SuperType() {}                                               \
     classname(size_t index) : SuperType(index) {}                              \
diff --git a/Framework/API/inc/MantidAPI/VectorParameterParser.h b/Framework/API/inc/MantidAPI/VectorParameterParser.h
index e9908fbb58fe76bd687beaf2e795915d5b6ce7ec..b84dd9635f68028ed0a0c654e1e65867c38482f5 100644
--- a/Framework/API/inc/MantidAPI/VectorParameterParser.h
+++ b/Framework/API/inc/MantidAPI/VectorParameterParser.h
@@ -80,7 +80,7 @@ VectorParameterParser<VectorValueParameterType>::parseVectorParameter(
   boost::split(strs, sValue, boost::is_any_of(","));
 
   auto product = new VectorValueParameterType(strs.size());
-  typedef typename VectorValueParameterType::ValueType ValType;
+  using ValType = typename VectorValueParameterType::ValueType;
   ValType value = 0;
 
   for (size_t i = 0; i < strs.size(); i++) {
diff --git a/Framework/API/inc/MantidAPI/WorkspaceFactory.h b/Framework/API/inc/MantidAPI/WorkspaceFactory.h
index 87f72dbc64bfcf22d27878c75b5d214bf9da735f..beab0e3ab6c9e8ec8d9c44b121f032c85689a7a8 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceFactory.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceFactory.h
@@ -95,7 +95,7 @@ private:
   using Kernel::DynamicFactory<Workspace>::create;
 };
 
-typedef Mantid::Kernel::SingletonHolder<WorkspaceFactoryImpl> WorkspaceFactory;
+using WorkspaceFactory = Mantid::Kernel::SingletonHolder<WorkspaceFactoryImpl>;
 
 template <class T, class... InitArgs>
 boost::shared_ptr<T> createWorkspace(InitArgs... args) {
diff --git a/Framework/API/inc/MantidAPI/WorkspaceGroup.h b/Framework/API/inc/MantidAPI/WorkspaceGroup.h
index 1235c04c8cf11e13f0834be867a981fd8b7cad36..4686b006f59552e94e5b506e67debdaff4d00b40 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceGroup.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceGroup.h
@@ -76,6 +76,8 @@ public:
   Workspace_sptr getItem(const size_t index) const;
   /// Return the workspace by name
   Workspace_sptr getItem(const std::string wsName) const;
+  /// Return all workspaces in the group as one call for thread safety
+  std::vector<Workspace_sptr> getAllItems() const;
   /// Remove a workspace from the group
   void removeItem(const size_t index);
   /// Remove all names from the group but do not touch the ADS
diff --git a/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h b/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h
index d63dfcb8f033d77594fb2b953d7ce22917c68ef9..ee809df0f0a442f508e509666980674026356a37 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::WorkspaceGroup
 class WorkspaceGroup;
 /// shared pointer to Mantid::API::WorkspaceGroup
-typedef boost::shared_ptr<WorkspaceGroup> WorkspaceGroup_sptr;
+using WorkspaceGroup_sptr = boost::shared_ptr<WorkspaceGroup>;
 /// shared pointer to Mantid::API::WorkspaceGroup, pointer to const version
-typedef boost::shared_ptr<const WorkspaceGroup> WorkspaceGroup_const_sptr;
+using WorkspaceGroup_const_sptr = boost::shared_ptr<const WorkspaceGroup>;
 /// unique pointer to Mantid::API::WorkspaceGroup
-typedef std::unique_ptr<WorkspaceGroup> WorkspaceGroup_uptr;
+using WorkspaceGroup_uptr = std::unique_ptr<WorkspaceGroup>;
 /// unique pointer to Mantid::API::WorkspaceGroup (const version)
-typedef std::unique_ptr<const WorkspaceGroup> WorkspaceGroup_const_uptr;
+using WorkspaceGroup_const_uptr = std::unique_ptr<const WorkspaceGroup>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h
index 218c656f74827930156b2eae93168776e8dfd46a..1a071bf00963f63004e551d599b4951a86a9886c 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h
@@ -82,14 +82,14 @@ private:
   const std::vector<specnum_t> m_spectrumNumbers;
 
   /// typedef for Graph object used to hold the calculated information
-  typedef boost::adjacency_list<
+  using Graph = boost::adjacency_list<
       boost::vecS, boost::vecS, boost::directedS,
       boost::property<boost::vertex_name_t, int64_t>,
-      boost::property<boost::edge_name_t, Mantid::Kernel::V3D>> Graph;
+      boost::property<boost::edge_name_t, Mantid::Kernel::V3D>>;
   /// Vertex descriptor object for Graph
-  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
+  using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
   /// map object of int to Graph Vertex descriptor
-  typedef std::unordered_map<specnum_t, Vertex> MapIV;
+  using MapIV = std::unordered_map<specnum_t, Vertex>;
 
   /// Construct the graph based on the given number of neighbours and the
   /// current instument and spectra-detector mapping
diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.h b/Framework/API/inc/MantidAPI/WorkspaceProperty.h
index 75a5d27dfe5373a77687b6f78eeaccd8b61f5cd9..fc9a66d00dff7b8fa0309a6e24532993fafc086f 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceProperty.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.h
@@ -95,8 +95,7 @@ public:
 
   WorkspaceProperty &operator=(const WorkspaceProperty &right);
 
-  boost::shared_ptr<TYPE> &
-  operator=(const boost::shared_ptr<TYPE> &value) override;
+  WorkspaceProperty &operator=(const boost::shared_ptr<TYPE> &value) override;
 
   WorkspaceProperty &operator+=(Kernel::Property const *) override;
 
diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc
index 1dbcb92a0223ffe7d98ac37911be1082c1cc5218..1894b6dded19fe397cfe069421575a33afcee2fd 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc
+++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc
@@ -107,13 +107,14 @@ operator=(const WorkspaceProperty &right) {
  * @return assigned PropertyWithValue
  */
 template <typename TYPE>
-boost::shared_ptr<TYPE> &WorkspaceProperty<TYPE>::
+WorkspaceProperty<TYPE> &WorkspaceProperty<TYPE>::
 operator=(const boost::shared_ptr<TYPE> &value) {
   std::string wsName = value->getName();
   if (this->direction() == Kernel::Direction::Input && !wsName.empty()) {
     m_workspaceName = wsName;
   }
-  return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value);
+  Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value);
+  return *this;
 }
 
 //--------------------------------------------------------------------------------------
diff --git a/Framework/API/inc/MantidAPI/Workspace_fwd.h b/Framework/API/inc/MantidAPI/Workspace_fwd.h
index 20f00cde3a838140de08ebdbd9d0b71b71d4da5b..58d576fdb3863baee5397e43449c5ac6e23ff3c6 100644
--- a/Framework/API/inc/MantidAPI/Workspace_fwd.h
+++ b/Framework/API/inc/MantidAPI/Workspace_fwd.h
@@ -34,13 +34,13 @@ namespace API {
 /// forward declare of Mantid::API::Workspace
 class Workspace;
 /// shared pointer to Mantid::API::Workspace
-typedef boost::shared_ptr<Workspace> Workspace_sptr;
+using Workspace_sptr = boost::shared_ptr<Workspace>;
 /// shared pointer to Mantid::API::Workspace (const version)
-typedef boost::shared_ptr<const Workspace> Workspace_const_sptr;
+using Workspace_const_sptr = boost::shared_ptr<const Workspace>;
 /// unique pointer to Mantid::API::Workspace
-typedef std::unique_ptr<Workspace> Workspace_uptr;
+using Workspace_uptr = std::unique_ptr<Workspace>;
 /// unique pointer to Mantid::API::Workspace (const version)
-typedef std::unique_ptr<const Workspace> Workspace_const_uptr;
+using Workspace_const_uptr = std::unique_ptr<const Workspace>;
 
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/src/AlgorithmProxy.cpp b/Framework/API/src/AlgorithmProxy.cpp
index adf89ce8ac2aebaef3e5280dc1a9f4c0b945c199..94c4df66b0bce314bcad941643edfc42f4144769 100644
--- a/Framework/API/src/AlgorithmProxy.cpp
+++ b/Framework/API/src/AlgorithmProxy.cpp
@@ -19,9 +19,10 @@ AlgorithmProxy::AlgorithmProxy(Algorithm_sptr alg)
       m_executeAsync(new Poco::ActiveMethod<bool, Poco::Void, AlgorithmProxy>(
           this, &AlgorithmProxy::executeAsyncImpl)),
       m_name(alg->name()), m_category(alg->category()),
-      m_categorySeparator(alg->categorySeparator()), m_alias(alg->alias()),
-      m_summary(alg->summary()), m_version(alg->version()), m_alg(alg),
-      m_isExecuted(), m_isLoggingEnabled(true), m_loggingOffset(0),
+      m_categorySeparator(alg->categorySeparator()), m_seeAlso(alg->seeAlso()),
+      m_alias(alg->alias()), m_summary(alg->summary()),
+      m_version(alg->version()), m_alg(alg), m_isExecuted(),
+      m_isLoggingEnabled(true), m_loggingOffset(0),
       m_isAlgStartupLoggingEnabled(true), m_rethrow(false), m_isChild(false),
       m_setAlwaysStoreInADS(true) {
   if (!alg) {
diff --git a/Framework/API/src/EqualBinSizesValidator.cpp b/Framework/API/src/EqualBinSizesValidator.cpp
index 7415acc1b181f67eef1dc55ca3494b4e5f8c43c1..034cdc8acca2a8ab44ff456526e7bdcc3545c3cd 100644
--- a/Framework/API/src/EqualBinSizesValidator.cpp
+++ b/Framework/API/src/EqualBinSizesValidator.cpp
@@ -25,10 +25,10 @@ std::string
 EqualBinSizesValidator::checkValidity(const MatrixWorkspace_sptr &value) const {
   if (!value)
     return "Enter an existing workspace";
-  if (value->getNumberHistograms() == 0 || value->blocksize() == 0)
-    return "Enter a workspace with some data in it";
   if (!value->isCommonBins())
     return "The workspace must have common bin boundaries for all histograms";
+  if (value->getNumberHistograms() == 0 || value->blocksize() == 0)
+    return "Enter a workspace with some data in it";
 
   Kernel::EqualBinsChecker checker(value->readX(0), m_errorLevel,
                                    m_warningLevel);
diff --git a/Framework/API/src/Expression.cpp b/Framework/API/src/Expression.cpp
index d2c5c4d745481511a5366ae3dcef22ffe9805514..2dd51300034702a95503b80fcd6444a4dda2b584 100644
--- a/Framework/API/src/Expression.cpp
+++ b/Framework/API/src/Expression.cpp
@@ -9,7 +9,7 @@
 namespace Mantid {
 namespace API {
 
-typedef Mantid::Kernel::StringTokenizer tokenizer;
+using tokenizer = Mantid::Kernel::StringTokenizer;
 
 const std::string DEFAULT_OPS_STR[] = {";", ",", "=", "== != > < <= >=",
                                        "&& || ^^", "+ -", "* /", "^"};
diff --git a/Framework/API/src/FunctionDomainMD.cpp b/Framework/API/src/FunctionDomainMD.cpp
index 55f26e7bcc07c67bfe08d0640cb8c7f05a451cfd..73652eb0e78d8a55d87ba06ec21736bd79d9189e 100644
--- a/Framework/API/src/FunctionDomainMD.cpp
+++ b/Framework/API/src/FunctionDomainMD.cpp
@@ -34,7 +34,7 @@ FunctionDomainMD::FunctionDomainMD(IMDWorkspace_const_sptr ws, size_t start,
 
 /** Destructor.
  */
-FunctionDomainMD::~FunctionDomainMD() { delete m_iterator; }
+FunctionDomainMD::~FunctionDomainMD() = default;
 
 /// Reset the iterator to point to the start of the domain.
 void FunctionDomainMD::reset() const {
@@ -53,14 +53,14 @@ void FunctionDomainMD::reset() const {
 const IMDIterator *FunctionDomainMD::getNextIterator() const {
   if (m_justReset) {
     m_justReset = false;
-    return m_iterator;
+    return m_iterator.get();
   }
   ++m_currentIndex;
   if (!m_iterator->next() || m_currentIndex >= m_size) {
     m_currentIndex = m_size;
     return nullptr;
   }
-  return m_iterator;
+  return m_iterator.get();
 }
 
 /// Returns the pointer to the original workspace
diff --git a/Framework/API/src/FunctionProperty.cpp b/Framework/API/src/FunctionProperty.cpp
index 3a51eec83738b00a39cb56a55d1c5fc741b403ae..a2f62efc1b4a420c41ae28c27b58f39ea76e00cd 100644
--- a/Framework/API/src/FunctionProperty.cpp
+++ b/Framework/API/src/FunctionProperty.cpp
@@ -31,10 +31,10 @@ FunctionProperty &FunctionProperty::operator=(const FunctionProperty &right) {
   * @param value :: The value to set to
   * @return assigned PropertyWithValue
   */
-boost::shared_ptr<IFunction> &FunctionProperty::
+FunctionProperty &FunctionProperty::
 operator=(const boost::shared_ptr<IFunction> &value) {
-  return Kernel::PropertyWithValue<boost::shared_ptr<IFunction>>::operator=(
-      value);
+  Kernel::PropertyWithValue<boost::shared_ptr<IFunction>>::operator=(value);
+  return *this;
 }
 
 //--------------------------------------------------------------------------------------
diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp
index 033a160b5ba81cddce13f31d625d50eb48d064f0..1285b43072c7d63c6dc48c300af54b6bb057ac98 100644
--- a/Framework/API/src/IMDWorkspace.cpp
+++ b/Framework/API/src/IMDWorkspace.cpp
@@ -26,15 +26,16 @@ IMDWorkspace::IMDWorkspace(const Parallel::StorageMode storageMode)
  * @param function :: Implicit function limiting space to look at
  * @return a single IMDIterator pointer
  */
-IMDIterator *IMDWorkspace::createIterator(
+std::unique_ptr<IMDIterator> IMDWorkspace::createIterator(
     Mantid::Geometry::MDImplicitFunction *function) const {
-  std::vector<IMDIterator *> iterators = this->createIterators(1, function);
+  std::vector<std::unique_ptr<IMDIterator>> iterators =
+      this->createIterators(1, function);
   if (iterators.empty())
     throw std::runtime_error("IMDWorkspace::createIterator(): iterator "
                              "creation was not successful. No iterators "
                              "returned by " +
                              this->id());
-  return iterators[0];
+  return std::move(iterators[0]);
 }
 
 //---------------------------------------------------------------------------------------------
diff --git a/Framework/API/src/IndexProperty.cpp b/Framework/API/src/IndexProperty.cpp
index fa8dedb614158378416296d0df4446720019eea6..ea0cefaa7863d0cac86eb220b7699fe3eca4340b 100644
--- a/Framework/API/src/IndexProperty.cpp
+++ b/Framework/API/src/IndexProperty.cpp
@@ -33,8 +33,9 @@ std::string IndexProperty::isValid() const {
   return error;
 }
 
-std::string IndexProperty::operator=(const std::string &rhs) {
-  return setValue(rhs);
+IndexProperty &IndexProperty::operator=(const std::string &rhs) {
+  setValue(rhs);
+  return *this;
 }
 
 IndexProperty::operator Indexing::SpectrumIndexSet() const {
diff --git a/Framework/API/src/IndexTypeProperty.cpp b/Framework/API/src/IndexTypeProperty.cpp
index 26b14da4fa8868164b5181210776be05949a068d..8df2a25296aa9d6e85edd121a9bbda0dad1c20d6 100644
--- a/Framework/API/src/IndexTypeProperty.cpp
+++ b/Framework/API/src/IndexTypeProperty.cpp
@@ -50,7 +50,7 @@ std::vector<std::string> IndexTypeProperty::allowedValues() const {
 
 bool IndexTypeProperty::isMultipleSelectionAllowed() { return false; }
 
-std::string &IndexTypeProperty::operator=(API::IndexType type) {
+IndexTypeProperty &IndexTypeProperty::operator=(API::IndexType type) {
   std::string val;
 
   switch (type) {
@@ -62,7 +62,8 @@ std::string &IndexTypeProperty::operator=(API::IndexType type) {
     break;
   }
 
-  return *this = val;
+  *this = val;
+  return *this;
 }
 
 std::string IndexTypeProperty::generatePropertyName(const std::string &name) {
diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp
index 12a2ba68ac45b9e2ac0a1882c6106994b2106654..5cd215f3e506f526c3b18f8e549323b89284ba23 100644
--- a/Framework/API/src/MatrixWorkspace.cpp
+++ b/Framework/API/src/MatrixWorkspace.cpp
@@ -1466,7 +1466,7 @@ MatrixWorkspace::getDimensionWithId(std::string id) const {
  * @param function :: implicit function to limit range
  * @return MatrixWorkspaceMDIterator vector
  */
-std::vector<IMDIterator *> MatrixWorkspace::createIterators(
+std::vector<std::unique_ptr<IMDIterator>> MatrixWorkspace::createIterators(
     size_t suggestedNumCores,
     Mantid::Geometry::MDImplicitFunction *function) const {
   // Find the right number of cores to use
@@ -1480,13 +1480,14 @@ std::vector<IMDIterator *> MatrixWorkspace::createIterators(
     numCores = 1;
 
   // Create one iterator per core, splitting evenly amongst spectra
-  std::vector<IMDIterator *> out;
+  std::vector<std::unique_ptr<IMDIterator>> out;
   for (size_t i = 0; i < numCores; i++) {
     size_t begin = (i * numElements) / numCores;
     size_t end = ((i + 1) * numElements) / numCores;
     if (end > numElements)
       end = numElements;
-    out.push_back(new MatrixWorkspaceMDIterator(this, function, begin, end));
+    out.push_back(Kernel::make_unique<MatrixWorkspaceMDIterator>(this, function,
+                                                                 begin, end));
   }
   return out;
 }
@@ -2000,8 +2001,8 @@ void MatrixWorkspace::rebuildDetectorIDGroupings() {
   const auto &allDetIDs = detInfo.detectorIDs();
   const auto &specDefs = m_indexInfo->spectrumDefinitions();
   const auto size = static_cast<int64_t>(m_indexInfo->size());
-  std::atomic<bool> parallelException{false};
-  std::string error;
+  enum class ErrorCode { None, InvalidDetIndex, InvalidTimeIndex };
+  std::atomic<ErrorCode> errorValue(ErrorCode::None);
 #pragma omp parallel for
   for (int64_t i = 0; i < size; ++i) {
     auto &spec = getSpectrum(i);
@@ -2013,23 +2014,29 @@ void MatrixWorkspace::rebuildDetectorIDGroupings() {
       const size_t detIndex = index.first;
       const size_t timeIndex = index.second;
       if (detIndex >= allDetIDs.size()) {
-        parallelException = true;
-        error = "MatrixWorkspace: SpectrumDefinition contains an out-of-range "
-                "detector index, i.e., the spectrum definition does not match "
-                "the instrument in the workspace.";
+        errorValue = ErrorCode::InvalidDetIndex;
       } else if (timeIndex >= detInfo.scanCount(detIndex)) {
-        parallelException = true;
-        error = "MatrixWorkspace: SpectrumDefinition contains an out-of-range "
-                "time index for a detector, i.e., the spectrum definition does "
-                "not match the instrument in the workspace.";
+        errorValue = ErrorCode::InvalidTimeIndex;
       } else {
         detIDs.insert(allDetIDs[detIndex]);
       }
     }
     spec.setDetectorIDs(std::move(detIDs));
   }
-  if (parallelException)
-    throw std::invalid_argument(error);
+  switch (errorValue) {
+  case ErrorCode::InvalidDetIndex:
+    throw std::invalid_argument(
+        "MatrixWorkspace: SpectrumDefinition contains an out-of-range "
+        "detector index, i.e., the spectrum definition does not match "
+        "the instrument in the workspace.");
+  case ErrorCode::InvalidTimeIndex:
+    throw std::invalid_argument(
+        "MatrixWorkspace: SpectrumDefinition contains an out-of-range "
+        "time index for a detector, i.e., the spectrum definition does "
+        "not match the instrument in the workspace.");
+  case ErrorCode::None:
+    ; // nothing to do
+  }
 }
 
 } // namespace API
diff --git a/Framework/API/src/MatrixWorkspaceMDIterator.cpp b/Framework/API/src/MatrixWorkspaceMDIterator.cpp
index 7fd7e4291a4abda9b9a3acfa7001974d9027006e..c08e275918258db4e74624b2d89b1e388398071c 100644
--- a/Framework/API/src/MatrixWorkspaceMDIterator.cpp
+++ b/Framework/API/src/MatrixWorkspaceMDIterator.cpp
@@ -204,13 +204,13 @@ signal_t MatrixWorkspaceMDIterator::getError() const {
 
 //----------------------------------------------------------------------------------------------
 /// Return a list of vertexes defining the volume pointed to
-coord_t *
+std::unique_ptr<coord_t[]>
 MatrixWorkspaceMDIterator::getVertexesArray(size_t & /*numVertices*/) const {
   throw std::runtime_error(
       "MatrixWorkspaceMDIterator::getVertexesArray() not implemented yet");
 }
 
-coord_t *
+std::unique_ptr<coord_t[]>
 MatrixWorkspaceMDIterator::getVertexesArray(size_t & /*numVertices*/,
                                             const size_t /*outDimensions*/,
                                             const bool * /*maskDim*/) const {
diff --git a/Framework/API/src/MuParserUtils.cpp b/Framework/API/src/MuParserUtils.cpp
index 7ff53a0c45b44ab4db2b533c94f28ef4517e5632..c5daee5fee1ddacdbd801c6cb47dfc43d03b27e2 100644
--- a/Framework/API/src/MuParserUtils.cpp
+++ b/Framework/API/src/MuParserUtils.cpp
@@ -41,7 +41,7 @@ void DLLExport addDefaultConstants(mu::Parser &parser) {
   }
 }
 
-typedef double (*oneVarFun)(double); // pointer to a function of one variable
+using oneVarFun = double (*)(double); // pointer to a function of one variable
 const std::map<std::string, oneVarFun> MUPARSER_ONEVAR_FUNCTIONS = {
     {"erf", gsl_sf_erf}, {"erfc", gsl_sf_erfc}};
 
diff --git a/Framework/API/src/MultiPeriodGroupWorker.cpp b/Framework/API/src/MultiPeriodGroupWorker.cpp
index 8d862fefd411318b0198328f8990c348463f0258..ff9e531ee5b71927ed38aa8acd646790b2514409 100644
--- a/Framework/API/src/MultiPeriodGroupWorker.cpp
+++ b/Framework/API/src/MultiPeriodGroupWorker.cpp
@@ -58,7 +58,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups(
   // This is currenly the case for algorithms that take an array of strings as
   // an input where each entry is the name of a workspace.
   if (this->useCustomWorkspaceProperty()) {
-    typedef std::vector<std::string> WorkspaceNameType;
+    using WorkspaceNameType = std::vector<std::string>;
 
     // Perform a check that the input property is the correct type.
     Property *inputProperty =
@@ -85,7 +85,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups(
                                         vecWorkspaceGroups);
     }
   } else {
-    typedef std::vector<boost::shared_ptr<Workspace>> WorkspaceVector;
+    using WorkspaceVector = std::vector<boost::shared_ptr<Workspace>>;
     WorkspaceVector inWorkspaces;
     WorkspaceVector outWorkspaces;
     sourceAlg->findWorkspaceProperties(inWorkspaces, outWorkspaces);
diff --git a/Framework/API/src/MultipleFileProperty.cpp b/Framework/API/src/MultipleFileProperty.cpp
index 6f92bac63f3e9d1a9cbfdced5e235a1c409d7b7c..7d0d7ac5b540f89c973114b11bffecdcbd80ca18 100644
--- a/Framework/API/src/MultipleFileProperty.cpp
+++ b/Framework/API/src/MultipleFileProperty.cpp
@@ -37,18 +37,18 @@ bool doesNotContainWildCard(const std::string &ext) {
 static const std::string SUCCESS("");
 
 // Regular expressions for any adjacent + or , operators
-const std::string INVALID = "\\+\\+|,,|\\+,|,\\+";
+const std::string INVALID = R"(\+\+|,,|\+,|,\+)";
 static const boost::regex REGEX_INVALID(INVALID);
 
 // Regular expressions that represent the allowed instances of , operators
-const std::string NUM_COMMA_ALPHA("(?<=\\d)\\s*,\\s*(?=\\D)");
-const std::string ALPHA_COMMA_ALPHA("(?<=\\D)\\s*,\\s*(?=\\D)");
+const std::string NUM_COMMA_ALPHA(R"((?<=\d)\s*,\s*(?=\D))");
+const std::string ALPHA_COMMA_ALPHA(R"((?<=\D)\s*,\s*(?=\D))");
 const std::string COMMA_OPERATORS = NUM_COMMA_ALPHA + "|" + ALPHA_COMMA_ALPHA;
 static const boost::regex REGEX_COMMA_OPERATORS(COMMA_OPERATORS);
 
 // Regular expressions that represent the allowed instances of + operators
-const std::string NUM_PLUS_ALPHA("(?<=\\d)\\s*\\+\\s*(?=\\D)");
-const std::string ALPHA_PLUS_ALPHA("(?<=\\D)\\s*\\+\\s*(?=\\D)");
+const std::string NUM_PLUS_ALPHA(R"((?<=\d)\s*\+\s*(?=\D))");
+const std::string ALPHA_PLUS_ALPHA(R"((?<=\D)\s*\+\s*(?=\D))");
 const std::string PLUS_OPERATORS = NUM_PLUS_ALPHA + "|" + ALPHA_PLUS_ALPHA;
 static const boost::regex REGEX_PLUS_OPERATORS(PLUS_OPERATORS,
                                                boost::regex_constants::perl);
diff --git a/Framework/API/src/ParameterTie.cpp b/Framework/API/src/ParameterTie.cpp
index 56b2bfb5dd7a501f351deafe205ef76a5f0690f4..1716b93639f3e702cf6454048791fc69cde5e481 100644
--- a/Framework/API/src/ParameterTie.cpp
+++ b/Framework/API/src/ParameterTie.cpp
@@ -81,7 +81,7 @@ void ParameterTie::set(const std::string &expr) {
   }
 
   // Create the template m_expression
-  boost::regex rx("\\b(([[:alpha:]]|_)([[:alnum:]]|_|\\.)*)\\b(?!(\\s*\\())");
+  boost::regex rx(R"(\b(([[:alpha:]]|_)([[:alnum:]]|_|\.)*)\b(?!(\s*\()))");
   std::string input = expr;
   boost::smatch res;
   std::string::const_iterator start = input.begin();
diff --git a/Framework/API/src/ScriptBuilder.cpp b/Framework/API/src/ScriptBuilder.cpp
index 79a8c9da3b0602c55ac7c1faebecf40cc9d9450f..09d704dc60a28fd7c48b8ac1ff1ad0edfd0bf29b 100644
--- a/Framework/API/src/ScriptBuilder.cpp
+++ b/Framework/API/src/ScriptBuilder.cpp
@@ -159,8 +159,7 @@ ScriptBuilder::buildAlgorithmString(AlgorithmHistory_const_sptr algHistory) {
     // remove properties that are not present on a fresh algorithm
     // i.e. remove dynamically added properties
     for (auto prop_iter = props.begin(); prop_iter != props.end();) {
-      if (std::find(freshPropNames.begin(), freshPropNames.end(),
-                    (*prop_iter)->name()) == freshPropNames.end()) {
+      if (freshPropNames.find((*prop_iter)->name()) == freshPropNames.end()) {
         prop_iter = props.erase(prop_iter);
       } else {
         ++prop_iter;
diff --git a/Framework/API/src/SpectraAxisValidator.cpp b/Framework/API/src/SpectraAxisValidator.cpp
index f37f5ebbe8c9dcd14cc9a1cec1736569759164d3..8a5643a92f00c54f6c5cf0e69ff959f197fb6a77 100644
--- a/Framework/API/src/SpectraAxisValidator.cpp
+++ b/Framework/API/src/SpectraAxisValidator.cpp
@@ -25,7 +25,7 @@ SpectraAxisValidator::checkValidity(const MatrixWorkspace_sptr &value) const {
   Mantid::API::Axis *axis;
   try {
     axis = value->getAxis(m_axisNumber);
-  } catch (Kernel::Exception::IndexError) {
+  } catch (Kernel::Exception::IndexError &) {
     return "No axis at index " + std::to_string(m_axisNumber) +
            " available in the workspace";
   }
diff --git a/Framework/API/src/WorkspaceGroup.cpp b/Framework/API/src/WorkspaceGroup.cpp
index 172d62382ad26aa4fa325c8a76ff3561f6141e50..f8d33ea0ec4e1752d37bc8dcba21183ff721d199 100644
--- a/Framework/API/src/WorkspaceGroup.cpp
+++ b/Framework/API/src/WorkspaceGroup.cpp
@@ -195,6 +195,13 @@ Workspace_sptr WorkspaceGroup::getItem(const std::string wsName) const {
                           " not contained in the group");
 }
 
+/** Return all workspaces in the group as one call for thread safety
+ */
+std::vector<Workspace_sptr> WorkspaceGroup::getAllItems() const {
+  std::lock_guard<std::recursive_mutex> _lock(m_mutex);
+  return m_workspaces;
+}
+
 /// Empty all the entries out of the workspace group. Does not remove the
 /// workspaces from the ADS.
 void WorkspaceGroup::removeAll() { m_workspaces.clear(); }
diff --git a/Framework/API/test/ADSValidatorTest.h b/Framework/API/test/ADSValidatorTest.h
index 7431b08552679840e1a5ca7e0f64e4fd535d2048..7302df6f71916fe967c4d683eefd17bba062810f 100644
--- a/Framework/API/test/ADSValidatorTest.h
+++ b/Framework/API/test/ADSValidatorTest.h
@@ -28,7 +28,7 @@ private:
 };
 }
 
-typedef std::vector<std::string> StringVector;
+using StringVector = std::vector<std::string>;
 
 class ADSValidatorTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/API/test/AlgorithmManagerTest.h b/Framework/API/test/AlgorithmManagerTest.h
index fcdbcdcb517c2be1450ddaa158082765143d565f..281451bef434cd7cbd53ea9a93b274855b880418 100644
--- a/Framework/API/test/AlgorithmManagerTest.h
+++ b/Framework/API/test/AlgorithmManagerTest.h
@@ -139,13 +139,13 @@ public:
     TS_ASSERT_THROWS_NOTHING(
         alg = AlgorithmManager::Instance().create("AlgTest", 1));
     TS_ASSERT_DIFFERS(dynamic_cast<AlgorithmProxy *>(alg.get()),
-                      static_cast<AlgorithmProxy *>(0));
+                      static_cast<AlgorithmProxy *>(nullptr));
     TS_ASSERT_THROWS_NOTHING(
         alg = AlgorithmManager::Instance().create("AlgTestSecond", 1));
     TS_ASSERT_DIFFERS(dynamic_cast<AlgorithmProxy *>(alg.get()),
-                      static_cast<AlgorithmProxy *>(0));
+                      static_cast<AlgorithmProxy *>(nullptr));
     TS_ASSERT_DIFFERS(dynamic_cast<IAlgorithm *>(alg.get()),
-                      static_cast<IAlgorithm *>(0));
+                      static_cast<IAlgorithm *>(nullptr));
     TS_ASSERT_EQUALS(AlgorithmManager::Instance().size(),
                      2); // To check that crea is called on local objects
   }
@@ -157,8 +157,8 @@ public:
     Bptr = AlgorithmManager::Instance().createUnmanaged("AlgTest");
     TS_ASSERT_DIFFERS(Aptr, Bptr);
     TS_ASSERT_EQUALS(AlgorithmManager::Instance().size(), 1);
-    TS_ASSERT_DIFFERS(Aptr.get(), static_cast<Algorithm *>(0));
-    TS_ASSERT_DIFFERS(Bptr.get(), static_cast<Algorithm *>(0));
+    TS_ASSERT_DIFFERS(Aptr.get(), static_cast<Algorithm *>(nullptr));
+    TS_ASSERT_DIFFERS(Bptr.get(), static_cast<Algorithm *>(nullptr));
   }
 
   void testCreateNoProxy() {
@@ -169,7 +169,7 @@ public:
     TSM_ASSERT("Was created as a AlgorithmProxy",
                dynamic_cast<AlgorithmProxy *>(Aptr.get()));
     TSM_ASSERT("Was NOT created as a AlgorithmProxy",
-               dynamic_cast<AlgorithmProxy *>(Bptr.get()) == NULL);
+               dynamic_cast<AlgorithmProxy *>(Bptr.get()) == nullptr);
   }
 
   // This will be called back when an algo starts
diff --git a/Framework/API/test/AlgorithmProxyTest.h b/Framework/API/test/AlgorithmProxyTest.h
index d8d745c15a792e855eb84fe363c7aff5bc925fab..58b97aa90b343835ef79e2371bfd2b7827f4b8af 100644
--- a/Framework/API/test/AlgorithmProxyTest.h
+++ b/Framework/API/test/AlgorithmProxyTest.h
@@ -29,6 +29,9 @@ public:
   const std::string category() const override {
     return "ProxyCat";
   } ///< Algorithm's category for identification
+  const std::vector<std::string> seeAlso() const override {
+    return {"elephant", "seal"};
+  } ///< Algorithm's seeAlso
   const std::string alias() const override {
     return "Dog";
   } ///< Algorithm's alias
@@ -134,6 +137,8 @@ public:
     TS_ASSERT_EQUALS(alg->version(), 1);
     TS_ASSERT_EQUALS(alg->category(), "ProxyCat");
     TS_ASSERT_EQUALS(alg->alias(), "Dog");
+    std::vector<std::string> seeAlsoList{"elephant", "seal"};
+    TS_ASSERT_EQUALS(alg->seeAlso(), seeAlsoList);
     TS_ASSERT(alg->isInitialized());
     TS_ASSERT(alg->existsProperty("prop1"));
     TS_ASSERT(alg->existsProperty("prop2"));
diff --git a/Framework/API/test/AlgorithmTest.h b/Framework/API/test/AlgorithmTest.h
index 92f3c17252ceb9c6a6e124cc28390e644b356b16..bac48ae042bb14ff67f076267cb1c510a09c411f 100644
--- a/Framework/API/test/AlgorithmTest.h
+++ b/Framework/API/test/AlgorithmTest.h
@@ -241,6 +241,13 @@ public:
     TS_ASSERT_EQUALS(algv3.categories(), result);
   }
 
+  void testSeeAlso() {
+    std::vector<std::string> result{"rabbit"};
+    result.emplace_back("goldfish");
+    result.emplace_back("Spotted Hyena");
+    TS_ASSERT_EQUALS(alg.seeAlso(), result);
+  }
+
   void testAlias() { TS_ASSERT_EQUALS(alg.alias(), "Dog"); }
 
   void testIsChild() {
@@ -361,7 +368,7 @@ public:
   }
 
   void test_Construction_Via_Valid_String_With_No_Properties() {
-    IAlgorithm_sptr testAlg = runFromString("{\"name\":\"ToyAlgorithm\"}");
+    IAlgorithm_sptr testAlg = runFromString(R"({"name":"ToyAlgorithm"})");
     TS_ASSERT_EQUALS(testAlg->name(), "ToyAlgorithm");
     TS_ASSERT_EQUALS(testAlg->version(), 2);
   }
@@ -808,10 +815,10 @@ public:
     IAlgorithm_sptr algNonConst;
     TS_ASSERT_THROWS_NOTHING(
         algConst = manager.getValue<IAlgorithm_const_sptr>(algName));
-    TS_ASSERT(algConst != NULL);
+    TS_ASSERT(algConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(algNonConst =
                                  manager.getValue<IAlgorithm_sptr>(algName));
-    TS_ASSERT(algNonConst != NULL);
+    TS_ASSERT(algNonConst != nullptr);
     TS_ASSERT_EQUALS(algConst, algNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -819,9 +826,9 @@ public:
     IAlgorithm_const_sptr algCastConst;
     IAlgorithm_sptr algCastNonConst;
     TS_ASSERT_THROWS_NOTHING(algCastConst = (IAlgorithm_const_sptr)val);
-    TS_ASSERT(algCastConst != NULL);
+    TS_ASSERT(algCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(algCastNonConst = (IAlgorithm_sptr)val);
-    TS_ASSERT(algCastNonConst != NULL);
+    TS_ASSERT(algCastNonConst != nullptr);
     TS_ASSERT_EQUALS(algCastConst, algCastNonConst);
   }
 
diff --git a/Framework/API/test/AnalysisDataServiceTest.h b/Framework/API/test/AnalysisDataServiceTest.h
index 6e1aabdb7018e988d9292028431796c5af0823ec..8b8c0c2240a2d48362e6938c32392b5fac504638 100644
--- a/Framework/API/test/AnalysisDataServiceTest.h
+++ b/Framework/API/test/AnalysisDataServiceTest.h
@@ -23,7 +23,7 @@ private:
     throw std::runtime_error("Cloning of MockWorkspace is not implemented.");
   }
 };
-typedef boost::shared_ptr<MockWorkspace> MockWorkspace_sptr;
+using MockWorkspace_sptr = boost::shared_ptr<MockWorkspace>;
 }
 
 class AnalysisDataServiceTest : public CxxTest::TestSuite {
diff --git a/Framework/API/test/ExperimentInfoTest.h b/Framework/API/test/ExperimentInfoTest.h
index 8941eb1eb703072d3fa0975588b1fc08104de21c..71806ba8cc0a38e91d3d733c74df8d705ba91b91 100644
--- a/Framework/API/test/ExperimentInfoTest.h
+++ b/Framework/API/test/ExperimentInfoTest.h
@@ -129,7 +129,7 @@ public:
   void test_Setting_A_New_Chopper_With_NULL_Ptr_Throws() {
     ExperimentInfo_sptr ws = createTestInfoWithChopperPoints(1);
 
-    TS_ASSERT_THROWS(ws->setChopperModel(NULL), std::invalid_argument);
+    TS_ASSERT_THROWS(ws->setChopperModel(nullptr), std::invalid_argument);
   }
 
   void test_Setting_A_New_Chopper_To_Point_Lower_Point_Succeeds() {
@@ -526,9 +526,8 @@ public:
     std::pair<std::unordered_multimap<std::string, fromToEntry>::iterator,
               std::unordered_multimap<std::string, fromToEntry>::iterator> ret;
 
-    for (auto setIt = idfIdentifiers.begin(); setIt != idfIdentifiers.end();
-         setIt++) {
-      ret = idfFiles.equal_range(*setIt);
+    for (const auto &idfIdentifier : idfIdentifiers) {
+      ret = idfFiles.equal_range(idfIdentifier);
       for (it1 = ret.first; it1 != ret.second; ++it1) {
         for (it2 = ret.first; it2 != ret.second; ++it2) {
           if (it1 != it2) {
@@ -729,10 +728,10 @@ public:
     ExperimentInfo_sptr eiNonConst;
     TS_ASSERT_THROWS_NOTHING(
         eiConst = manager.getValue<ExperimentInfo_const_sptr>(eiName));
-    TS_ASSERT(eiConst != NULL);
+    TS_ASSERT(eiConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(eiNonConst =
                                  manager.getValue<ExperimentInfo_sptr>(eiName));
-    TS_ASSERT(eiNonConst != NULL);
+    TS_ASSERT(eiNonConst != nullptr);
     TS_ASSERT_EQUALS(eiConst, eiNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -740,9 +739,9 @@ public:
     ExperimentInfo_const_sptr eiCastConst;
     ExperimentInfo_sptr eiCastNonConst;
     TS_ASSERT_THROWS_NOTHING(eiCastConst = (ExperimentInfo_const_sptr)val);
-    TS_ASSERT(eiCastConst != NULL);
+    TS_ASSERT(eiCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(eiCastNonConst = (ExperimentInfo_sptr)val);
-    TS_ASSERT(eiCastNonConst != NULL);
+    TS_ASSERT(eiCastNonConst != nullptr);
     TS_ASSERT_EQUALS(eiCastConst, eiCastNonConst);
   }
 
diff --git a/Framework/API/test/FakeAlgorithms.h b/Framework/API/test/FakeAlgorithms.h
index 8c3744aa40f17c07ccf658d03c5a8741cea4e598..706ea9e8f5a2ab977e9da2634338c97731424a6e 100644
--- a/Framework/API/test/FakeAlgorithms.h
+++ b/Framework/API/test/FakeAlgorithms.h
@@ -23,6 +23,9 @@ public:
   } ///< Algorithm's category for identification
   const std::string alias() const override { return "Dog"; }
   const std::string summary() const override { return "Test summary"; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"rabbit", "goldfish", "Spotted Hyena"};
+  }
 
   void init() override {
     declareProperty("prop1", "value");
diff --git a/Framework/API/test/FermiChopperModelTest.h b/Framework/API/test/FermiChopperModelTest.h
index 527a4c39080c18287032ac7242f7913378380252..195295e201b4f8e3012ee5000196417b200683ed 100644
--- a/Framework/API/test/FermiChopperModelTest.h
+++ b/Framework/API/test/FermiChopperModelTest.h
@@ -9,8 +9,8 @@
 #include <boost/make_shared.hpp>
 
 class FermiChopperModelTest : public CxxTest::TestSuite {
-  typedef boost::shared_ptr<Mantid::API::FermiChopperModel>
-      FermiChopperModel_sptr;
+  using FermiChopperModel_sptr =
+      boost::shared_ptr<Mantid::API::FermiChopperModel>;
 
 public:
   void test_Default_Object_Throws_When_Computing_Pulse_Variance() {
diff --git a/Framework/API/test/FunctionTest.h b/Framework/API/test/FunctionTest.h
index 5fddb7db7ede1ded85bc67723df7603676bfcaf1..7b770abc57554c6061e88db687fa472238d6771e 100644
--- a/Framework/API/test/FunctionTest.h
+++ b/Framework/API/test/FunctionTest.h
@@ -411,10 +411,10 @@ public:
     IFunction_sptr funcNonConst;
     TS_ASSERT_THROWS_NOTHING(
         funcConst = manager.getValue<IFunction_const_sptr>(funcName));
-    TS_ASSERT(funcConst != NULL);
+    TS_ASSERT(funcConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(funcNonConst =
                                  manager.getValue<IFunction_sptr>(funcName));
-    TS_ASSERT(funcNonConst != NULL);
+    TS_ASSERT(funcNonConst != nullptr);
     TS_ASSERT_EQUALS(funcConst, funcNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -422,9 +422,9 @@ public:
     IFunction_const_sptr funcCastConst;
     IFunction_sptr funcCastNonConst;
     TS_ASSERT_THROWS_NOTHING(funcCastConst = (IFunction_const_sptr)val);
-    TS_ASSERT(funcCastConst != NULL);
+    TS_ASSERT(funcCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(funcCastNonConst = (IFunction_sptr)val);
-    TS_ASSERT(funcCastNonConst != NULL);
+    TS_ASSERT(funcCastNonConst != nullptr);
     TS_ASSERT_EQUALS(funcCastConst, funcCastNonConst);
   }
 
diff --git a/Framework/API/test/GroupingLoaderTest.h b/Framework/API/test/GroupingLoaderTest.h
index c6aa0e50d51f0eb689f9b89a80fba6d220d48da5..4258fb1cbf2d0b1679c9d325a2e55abba787356d 100644
--- a/Framework/API/test/GroupingLoaderTest.h
+++ b/Framework/API/test/GroupingLoaderTest.h
@@ -25,11 +25,11 @@ public:
     auto dataPaths = ConfigService::Instance().getDataSearchDirs();
 
     // Find the path of AutoTestData
-    for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) {
-      Poco::Path path(*it);
+    for (auto &dataPath : dataPaths) {
+      Poco::Path path(dataPath);
 
       if (path.directory(path.depth() - 1) == "UnitTest") {
-        m_testDataDir = *it;
+        m_testDataDir = dataPath;
         break;
       }
     }
diff --git a/Framework/API/test/IMDWorkspaceTest.h b/Framework/API/test/IMDWorkspaceTest.h
index b7476124c4b20b73fc1add3603d20e1520dbac84..e8b9d8aa3e3055937968eb58d982e0d0665161e1 100644
--- a/Framework/API/test/IMDWorkspaceTest.h
+++ b/Framework/API/test/IMDWorkspaceTest.h
@@ -125,10 +125,10 @@ public:
     IMDWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<IMDWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<IMDWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -136,9 +136,9 @@ public:
     IMDWorkspace_const_sptr wsCastConst;
     IMDWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/API/test/IkedaCarpenterModeratorTest.h b/Framework/API/test/IkedaCarpenterModeratorTest.h
index 96c73f6ce2e517029c3585468be559a960ca07bf..7e21d119bb087e95816a584f162226e49b99170e 100644
--- a/Framework/API/test/IkedaCarpenterModeratorTest.h
+++ b/Framework/API/test/IkedaCarpenterModeratorTest.h
@@ -8,8 +8,8 @@
 
 class IkedaCarpenterModeratorTest : public CxxTest::TestSuite {
 public:
-  typedef boost::shared_ptr<Mantid::API::IkedaCarpenterModerator>
-      IkedaCarpenterModerator_sptr;
+  using IkedaCarpenterModerator_sptr =
+      boost::shared_ptr<Mantid::API::IkedaCarpenterModerator>;
 
   void test_Default_Object_Returns_Zero_Mean_Time() {
     Mantid::API::IkedaCarpenterModerator ikmod;
diff --git a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
index 5d1f3979ffd901762e948ea5a47ca148c73f9883..3a9cdaa5cbf1a2537bd0d7318361f02ada776a1b 100644
--- a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
+++ b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
@@ -52,8 +52,8 @@ public:
 
   void test_iterating() {
     boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS();
-    IMDIterator *it = nullptr;
-    TS_ASSERT_THROWS_NOTHING(it = ws->createIterator(NULL));
+    std::unique_ptr<IMDIterator> it;
+    TS_ASSERT_THROWS_NOTHING(it = ws->createIterator(nullptr));
     TS_ASSERT_EQUALS(it->getDataSize(), 20);
     TS_ASSERT_DELTA(it->getSignal(), 0.0, 1e-5);
     it->next();
@@ -83,24 +83,21 @@ public:
     TS_ASSERT_DELTA(it->getError(), 22.0, 1e-5);
     TS_ASSERT_DELTA(it->getCenter()[0], 3.0, 1e-5);
     TS_ASSERT_DELTA(it->getCenter()[1], 2.0, 1e-5);
-    delete it;
   }
 
   /** Create a set of iterators that can be applied in parallel */
   void test_parallel_iterators() {
     boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS();
     // The number of output cannot be larger than the number of histograms
-    std::vector<IMDIterator *> it = ws->createIterators(10, NULL);
+    auto it = ws->createIterators(10, nullptr);
     TS_ASSERT_EQUALS(it.size(), 4);
-    for (size_t i = 0; i < it.size(); ++i)
-      delete it[i];
 
     // Split in 4 iterators
-    std::vector<IMDIterator *> iterators = ws->createIterators(4, NULL);
+    auto iterators = ws->createIterators(4, nullptr);
     TS_ASSERT_EQUALS(iterators.size(), 4);
 
     for (size_t i = 0; i < iterators.size(); i++) {
-      IMDIterator *it = iterators[i];
+      IMDIterator *it = iterators[i].get();
       const double i_d = static_cast<double>(i);
       // Only 5 elements per each iterator
       TS_ASSERT_EQUALS(it->getDataSize(), 5);
@@ -116,19 +113,17 @@ public:
       TS_ASSERT(it->next());
       TS_ASSERT(it->next());
       TS_ASSERT(!it->next());
-      delete it;
     }
   }
 
   void test_get_is_masked() {
     boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS();
-    IMDIterator *it = ws->createIterator(NULL);
+    auto it = ws->createIterator(nullptr);
     const auto &spectrumInfo = ws->spectrumInfo();
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
       TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), it->getIsMasked());
       it->next();
     }
-    delete it;
   }
 
   void testUnequalBins() {
@@ -141,11 +136,11 @@ public:
     TS_ASSERT_THROWS(ws->blocksize(), std::logic_error);
     TS_ASSERT_EQUALS(ws->size(), 17);
     // Split in 4 iterators
-    std::vector<IMDIterator *> iterators = ws->createIterators(4, nullptr);
+    auto iterators = ws->createIterators(4, nullptr);
     TS_ASSERT_EQUALS(iterators.size(), 4);
 
     for (size_t i = 0; i < iterators.size(); i++) {
-      IMDIterator *it = iterators[i];
+      auto it = iterators[i].get();
       const double i_d = static_cast<double>(i);
       if (i == 0) {
         // Only 5 elements per each iterator
@@ -174,7 +169,6 @@ public:
         TS_ASSERT(it->next());
       }
       TS_ASSERT(!it->next());
-      delete it;
     }
   }
 };
diff --git a/Framework/API/test/MatrixWorkspaceTest.h b/Framework/API/test/MatrixWorkspaceTest.h
index ae4ccae9b724eb02919a1b458e9505a3974c39ad..15181c2648700c1cdb313ce461372d7b897d3b18 100644
--- a/Framework/API/test/MatrixWorkspaceTest.h
+++ b/Framework/API/test/MatrixWorkspaceTest.h
@@ -1018,7 +1018,7 @@ public:
   void test_setMDMasking() {
     WorkspaceTester ws;
     TSM_ASSERT_THROWS("Characterisation test. This is not implemented.",
-                      ws.setMDMasking(NULL), std::runtime_error);
+                      ws.setMDMasking(nullptr), std::runtime_error);
   }
 
   void test_clearMDMasking() {
@@ -1569,10 +1569,10 @@ public:
     MatrixWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<MatrixWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<MatrixWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -1580,9 +1580,9 @@ public:
     MatrixWorkspace_const_sptr wsCastConst;
     MatrixWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (MatrixWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (MatrixWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
diff --git a/Framework/API/test/MultiPeriodGroupAlgorithmTest.h b/Framework/API/test/MultiPeriodGroupAlgorithmTest.h
index 6bd1b7a2ac46be60fb2eda3dd2eb79e650a5dcfb..baff00192e9550f93c063ce15346afd4c13279a6 100644
--- a/Framework/API/test/MultiPeriodGroupAlgorithmTest.h
+++ b/Framework/API/test/MultiPeriodGroupAlgorithmTest.h
@@ -214,7 +214,7 @@ public:
     WorkspaceGroup_sptr wsgroup =
         Mantid::API::AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
             "outWS");
-    TS_ASSERT(wsgroup != NULL);
+    TS_ASSERT(wsgroup != nullptr);
     TS_ASSERT_EQUALS(a->size(), wsgroup->size());
   }
 
@@ -241,7 +241,7 @@ public:
     WorkspaceGroup_sptr wsgroup =
         Mantid::API::AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
             "outWS");
-    TS_ASSERT(wsgroup != NULL);
+    TS_ASSERT(wsgroup != nullptr);
     TS_ASSERT_EQUALS(a->size(), wsgroup->size());
   }
 };
diff --git a/Framework/API/test/NotebookBuilderTest.h b/Framework/API/test/NotebookBuilderTest.h
index 4de0ec170fd49a35242bbae09e4f01626cd5b3c3..7ae7f7ecff6cbd89b16b409312aa4926402c03e6 100644
--- a/Framework/API/test/NotebookBuilderTest.h
+++ b/Framework/API/test/NotebookBuilderTest.h
@@ -211,7 +211,7 @@ public:
 
   void test_Build_Unrolled() {
     std::string result_markdown =
-        "               \"source\" : \"Child algorithms of TopLevelAlgorithm\"";
+        R"(               "source" : "Child algorithms of TopLevelAlgorithm")";
     std::string result_code =
         "               \"input\" : \"BasicAlgorithm(PropertyA='FirstOne')\",";
 
@@ -254,7 +254,7 @@ public:
 
   void test_Partially_Unrolled() {
     std::string result_markdown =
-        "               \"source\" : \"Child algorithms of TopLevelAlgorithm\"";
+        R"(               "source" : "Child algorithms of TopLevelAlgorithm")";
     std::string result_code =
         "               \"input\" : \"BasicAlgorithm(PropertyA='FirstOne')\",";
 
diff --git a/Framework/API/test/ScopedWorkspaceTest.h b/Framework/API/test/ScopedWorkspaceTest.h
index 52cf923ba5bc41bea669048c3fa18017f1c204b0..4ccccfd06a494c0b224a1a42d3cf6443e743d94a 100644
--- a/Framework/API/test/ScopedWorkspaceTest.h
+++ b/Framework/API/test/ScopedWorkspaceTest.h
@@ -26,7 +26,7 @@ private:
     throw std::runtime_error("Cloning of MockWorkspace is not implemented.");
   }
 };
-typedef boost::shared_ptr<MockWorkspace> MockWorkspace_sptr;
+using MockWorkspace_sptr = boost::shared_ptr<MockWorkspace>;
 
 class ScopedWorkspaceTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/API/test/VectorParameterParserTest.h b/Framework/API/test/VectorParameterParserTest.h
index 00fd6f9a94c01685edb2f9bb3e2cb577675dc6ec..68d06dd2bc305f0ab0cb15e7ef4364efdcaff2f2 100644
--- a/Framework/API/test/VectorParameterParserTest.h
+++ b/Framework/API/test/VectorParameterParserTest.h
@@ -15,15 +15,15 @@ private:
   DECLARE_VECTOR_PARAMETER(ConcreteVectorDblParam, double)
 
   // Declare a concrete vector parameter parser for testing.
-  typedef VectorParameterParser<ConcreteVectorDblParam>
-      ConcreteVectorDblParamParser;
+  using ConcreteVectorDblParamParser =
+      VectorParameterParser<ConcreteVectorDblParam>;
 
   // Declare a concrete type with elements of type bool for testing.
   DECLARE_VECTOR_PARAMETER(ConcreteVectorBoolParam, bool)
 
   // Declare a concrete vector parameter parser for testing.
-  typedef VectorParameterParser<ConcreteVectorBoolParam>
-      ConcreteVectorBoolParamParser;
+  using ConcreteVectorBoolParamParser =
+      VectorParameterParser<ConcreteVectorBoolParam>;
 
 public:
   void testParsesParmeterValue1D() {
@@ -97,8 +97,8 @@ public:
 
   void testChainOfResponsibility() {
     // Local declare of a successor parser with a successor parameter.
-    typedef VectorParameterParser<SucessorVectorParameter>
-        ConcreteSuccessorVectorParameterParser;
+    using ConcreteSuccessorVectorParameterParser =
+        VectorParameterParser<SucessorVectorParameter>;
 
     DOMParser pParser;
     std::string xmlToParse = "<Parameter><Type>SucessorVectorParameter</"
diff --git a/Framework/API/test/WorkspaceGroupTest.h b/Framework/API/test/WorkspaceGroupTest.h
index b04f5dc32c96b306f906d08533fc880416da71c1..9cffbe83d9ca782a1632ce7c21f1a9ffdd0a3b3f 100644
--- a/Framework/API/test/WorkspaceGroupTest.h
+++ b/Framework/API/test/WorkspaceGroupTest.h
@@ -241,6 +241,17 @@ public:
     AnalysisDataService::Instance().clear();
   }
 
+  void test_getAllItems() {
+    WorkspaceGroup_sptr group = makeGroup();
+    auto items = group->getAllItems();
+    TS_ASSERT_EQUALS(group->size(), 3);
+    TS_ASSERT_EQUALS(items.size(), 3);
+    TS_ASSERT_EQUALS(items[0], group->getItem(0));
+    TS_ASSERT_EQUALS(items[1], group->getItem(1));
+    TS_ASSERT_EQUALS(items[2], group->getItem(2));
+    AnalysisDataService::Instance().clear();
+  }
+
   void test_deleting_workspaces() {
     WorkspaceGroup_sptr group = makeGroup();
     TS_ASSERT(AnalysisDataService::Instance().doesExist("group"));
@@ -368,10 +379,10 @@ public:
     WorkspaceGroup_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<WorkspaceGroup_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<WorkspaceGroup_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -379,9 +390,9 @@ public:
     WorkspaceGroup_const_sptr wsCastConst;
     WorkspaceGroup_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (WorkspaceGroup_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (WorkspaceGroup_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
@@ -400,10 +411,10 @@ public:
     Workspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<Workspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<Workspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -411,9 +422,9 @@ public:
     Workspace_const_sptr wsCastConst;
     Workspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (Workspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (Workspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index 5ecfac48d9482a8f4e31436084f61b53f4eaf60c..718bafd253d14129472a1ff990850e30fb6d9688 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -142,6 +142,7 @@ set ( SRC_FILES
 	src/FindPeakBackground.cpp
 	src/FindPeaks.cpp
 	src/FitPeak.cpp
+	src/FitPeaks.cpp
 	src/FixGSASInstrumentFile.cpp
 	src/FlatPlateAbsorption.cpp
 	src/GeneralisedSecondDifference.cpp
@@ -241,9 +242,8 @@ set ( SRC_FILES
 	src/RebinToWorkspace.cpp
 	src/Rebunch.cpp
 	src/RecordPythonScript.cpp
-	src/ReflectometryReductionOne.cpp
+	src/ReflectometryMomentumTransfer.cpp
 	src/ReflectometryReductionOne2.cpp
-	src/ReflectometryReductionOneAuto.cpp
 	src/ReflectometryReductionOneAuto2.cpp
 	src/ReflectometryWorkflowBase.cpp
 	src/ReflectometryWorkflowBase2.cpp
@@ -475,6 +475,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/FindPeakBackground.h
 	inc/MantidAlgorithms/FindPeaks.h
 	inc/MantidAlgorithms/FitPeak.h
+	inc/MantidAlgorithms/FitPeaks.h
 	inc/MantidAlgorithms/FixGSASInstrumentFile.h
 	inc/MantidAlgorithms/FlatPlateAbsorption.h
 	inc/MantidAlgorithms/GSLFunctions.h
@@ -578,9 +579,8 @@ set ( INC_FILES
 	inc/MantidAlgorithms/RebinToWorkspace.h
 	inc/MantidAlgorithms/Rebunch.h
 	inc/MantidAlgorithms/RecordPythonScript.h
-	inc/MantidAlgorithms/ReflectometryReductionOne.h
+	inc/MantidAlgorithms/ReflectometryMomentumTransfer.h
 	inc/MantidAlgorithms/ReflectometryReductionOne2.h
-	inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
 	inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h
 	inc/MantidAlgorithms/ReflectometryWorkflowBase.h
 	inc/MantidAlgorithms/ReflectometryWorkflowBase2.h
@@ -820,6 +820,7 @@ set ( TEST_FILES
 	FindPeakBackgroundTest.h
 	FindPeaksTest.h
 	FitPeakTest.h
+	FitPeaksTest.h
 	FixGSASInstrumentFileTest.h
 	FlatPlateAbsorptionTest.h
 	GeneralisedSecondDifferenceTest.h
@@ -915,10 +916,9 @@ set ( TEST_FILES
 	RebinToWorkspaceTest.h
 	RebunchTest.h
 	RectangularBeamProfileTest.h
+	ReflectometryMomentumTransferTest.h
 	ReflectometryReductionOne2Test.h
 	ReflectometryReductionOneAuto2Test.h
-	ReflectometryReductionOneAutoTest.h
-	ReflectometryReductionOneTest.h
 	RegroupTest.h
 	RemoveBackgroundTest.h
 	RemoveBinsTest.h
@@ -945,6 +945,7 @@ set ( TEST_FILES
 	SignalOverErrorTest.h
 	SmoothDataTest.h
 	SmoothNeighboursTest.h
+	SofQCommonTest.h
 	SofQWCentreTest.h
 	SofQWCutTest.h
 	SofQWNormalisedPolygonTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h
index e6364cd9839fe74ac26c49387740c0563db85d5d..486756882e079b13b58a46d953c7e93d43bb2237 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h
@@ -147,8 +147,8 @@ private:
   double m_lambdaFixed; ///< The wavelength corresponding to the fixed energy,
   /// if provided
 
-  typedef double (*expfunction)(
-      double);             ///< Typedef pointer to exponential function
+  using expfunction =
+      double (*)(double);  ///< Typedef pointer to exponential function
   expfunction EXPONENTIAL; ///< Pointer to exponential function
 };
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h b/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h
index c8b36aa070b09584f11a75574c24e8353bb2f07b..f582c8c6c1b21c70d8d2868753d3ddb692a4c3e4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLog"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h b/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h
index da8a8f5d8f5793c167452bdbc7d0a3bdaa7ea162..c43944616a49e17a9fe74d6433d5e99cfb2bff6f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h
@@ -42,6 +42,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Comment"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h b/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h
index 7e93f7274f5446dcb25705a6e958acdf0532a2cc..ebf67e387d92590d308b26a398a3e6baa4578028 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h
@@ -43,6 +43,9 @@ public:
   }
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddPeakHKL", "CalculatePeaksHKL"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Peaks"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h b/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h
index d9bbd4035431d0a4af7f0a4f5243f387af32dffa..651547a0d1b13b492501230c7d46031175a36f09 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLogMultiple", "AddTimeSeriesLog", "DeleteLog", "LoadLog"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h b/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h
index 5ac9b054c3e85f217ed704fe0b399cbe278f2636..a5ab0398aedd48646ef213e247205b156df757f0 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLog", "GetTimeSeriesLogInformation", "MergeLogs"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
index 6d5dd1fb37c9a8fd5a1ecf8dfae60517a5243065..5e8d7abfde3b88f2f0a8dd33ab065cd712039946 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h
@@ -67,6 +67,9 @@ public:
 
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"DiffractionFocussing", "AlignAndFocusPowder"};
+  }
   /// Algorithm's category for identification. @see Algorithm::category
   const std::string category() const override;
   /// Cross-check properties with each other @see IAlgorithm::validateInputs
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h
index 8da2489d4b9fe35e61927ab61ce785dd927a38e5..63fbee31b02bc5db32ffcaa90c8428286ee7bdba 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h
@@ -43,6 +43,9 @@ class DLLExport AnnularRingAbsorption : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h
index 8e387758a60503d2437da2242522f064c77aad04..358ccc766114e8b7d389235c086dfcd4b7abca9f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h
@@ -88,6 +88,14 @@ public:
   AnyShapeAbsorption();
   /// Algorithm's name
   const std::string name() const override { return "AbsorptionCorrection"; }
+
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetSampleMaterial",          "CreateSampleShape",
+            "DefineGaugeVolume",          "CylinderAbsorption",
+            "FlatPlateAbsorption",        "AnnularRingAbsorption",
+            "CuboidGaugeVolumeAbsorption"};
+  }
+
   /// Summary of algorithms purpose
   const std::string summary() const override {
     return "Calculates an approximation of the attenuation due to absorption "
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h
index 0fa090ffc8cf29425346d97bdeb52b6f9bd73c40..a69fd074bb4446ccefe64f29b86a25049acd2b4d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h
@@ -46,6 +46,9 @@ class DLLExport AppendSpectra : public WorkspaceJoiners {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConjoinSpectra"};
+  }
 
 private:
   // Overridden Algorithm methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h b/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h
index 92565b4245ccb79dab76a5d92b0a409f560aadf8..d5ab58b031d0b0acbc80ce46f94b3d15c30fcdcb 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalMuonDeadTime"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Muon;CorrectionFunctions\\EfficiencyCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h
index 0e72040355f20b22cd4fb4dfec83e8c5c867383f..8de12765a49ff9b324d9a258e8f72b82a9681e15 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h
@@ -55,6 +55,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateTransmission", "CalculateTransmissionBeamSpreader"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "SANS;CorrectionFunctions\\TransmissionCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h b/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h
index 66d57249ef52277cd27220bafac69e5c709f66a7..753103dba02176380d1662e1d318e7d55386de30 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateMuonAsymmetry"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h b/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h
index 5ce3d96a863ea66b1de46d70cbe86b16b14cb16b..86a6004356e20972c6ebe031703c52cf49b1d0b3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h
@@ -40,6 +40,9 @@ class MANTID_ALGORITHMS_DLL Bin2DPowderDiffraction : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Rebin2D"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   /// Cross-check properties with each other @see IAlgorithm::validateInputs
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h
index 812134927adde97d30329ebe61e199c59ffa041b..67d854720a0c7e49d205142a547ba6e585d28606 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"InvertMask"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
index 6dfa0e3120bd6cca3343272aff59cea0f9767f2f..27e60f7b4330d031bc265746264a9bb7309cb6b3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
@@ -63,8 +63,8 @@ public:
    * Value at that index: workspace index of the rhs to apply to the WI in the
    * lhs. -1 if not found.
    */
-  typedef std::vector<int64_t> BinaryOperationTable;
-  typedef boost::shared_ptr<BinaryOperationTable> BinaryOperationTable_sptr;
+  using BinaryOperationTable = std::vector<int64_t>;
+  using BinaryOperationTable_sptr = boost::shared_ptr<BinaryOperationTable>;
 
   static BinaryOperationTable_sptr
   buildBinaryOperationTable(const API::MatrixWorkspace_const_sptr &lhs,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h
index 32cfe9bfe32fdaf1cb0fc97fe040f99526042646..b69e9cb25e1e29f9c4a080923be0f7b9b8bfc5bd 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ApplyDeadTimeCorr"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h
index 0c6a6270046151f56a61891836b4a31d41a1521a..f0a7e0990b59bcd5e1be5486e20815624bf8bbfd 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h
@@ -47,6 +47,9 @@ class DLLExport CalculateCountRate : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ChangePulsetime"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   /// Helper function: true if count rate should be normalized and false
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
index 257cce3dfbfeb9a3902d5070fd1ec04aa2dfeaac..155ac49fbaeb558c3e8d5990c9faebe5ca0061d4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
@@ -38,6 +38,9 @@ public:
   const std::string name() const override;
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertDiffCal"};
+  }
   const std::string category() const override;
   /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
   const std::string summary() const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h
index 8945063171207f13bec4ba99e5bb5e2d6c9488d6..86c75f949426c50e72b3566871f9ad96a0527c4c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h
@@ -70,6 +70,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AsymmetryCalc"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
index f5b5ebf757d71358a161a6d93e69031c6ba33ff1..40c82fc53e6a1425bcec5e5eeef2ed33bb9c00fb 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h
@@ -37,6 +37,9 @@ class MANTID_ALGORITHMS_DLL CalculatePolynomialBackground
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RemoveBackground", "CreateUserDefinedBackground"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h
index f4654b9b73521c63128283a49bfae837c8a61858..7482d0f0294f4aca0714df98226b98cd88694a0f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h
@@ -40,6 +40,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"NRCalculateSlitResolution"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h
index 803747c9ca562babc5b6e91f3029a169c5ed2a60..a29fd88d5ea5f33dc4a64da992932e18cb24e43b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h
@@ -76,6 +76,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateTransmissionBeamSpreader", "ApplyTransmissionCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "SANS;CorrectionFunctions\\TransmissionCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h
index 58f4637c9a08493c2fdc3acf147433c27ce2d35d..919bc42fb6d77c2cb4f094194652c3365e0e7efc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h
@@ -85,6 +85,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateTransmission", "ApplyTransmissionCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "SANS;CorrectionFunctions\\TransmissionCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h
index c9f8d162a279f6eb480492feae001fc866f190dd..60e7c39ce6ac1f282d56eb936b13badf720dd378 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h
@@ -51,6 +51,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"ScaleX"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Axes"; }
   /// Algorithm's Alternate Name
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h
index 3fbcf270422f8b233d64176fc6c959cc2c002f95..4e0d49695fd47b59348f6d419886b7e7bd0c0152 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h
@@ -10,6 +10,9 @@ class DLLExport ChangeLogTime : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateLogTimeCorrection", "ChangePulsetime", "ShiftLogTime"};
+  }
   const std::string category() const override;
   /// Algorithm's summary
   const std::string summary() const override {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h
index 0b0e66481946e0e204b1bc26956669be10199028..55cbc9c2fbfbbb78f1913c93158c5b1031a36609 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h
@@ -24,6 +24,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateLogTimeCorrection", "CalculateCountRate"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Events;Transforms\\Axes";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h b/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h
index 6a8b8a95df0ce2e34954b287e76f0b74dc470278..8a53f4d604ddba775fe55ab9ce8c0b7522c73ea3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h
@@ -87,6 +87,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CompareWorkspaces"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h b/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h
index 290523641391b8d74ed4650deffb4f5c2c9c841e..37a04194b3db0fa4ce081732f7f0e3f0775dc674 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h
@@ -44,8 +44,13 @@ public:
     return "Transforms\\Splitting";
   } ///< @return the algorithms category
   int version() const override {
+
     return (1);
   } ///< @return version number of algorithm
+
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractSpectra"};
+  }
   /// Algorithm's summary
   const std::string summary() const override {
     return "Splits an input workspace into a grouped workspace, where each "
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h
index c6487ce37ce1bbdb2056feac8390029108401c21..c18ef3f0588a2e824b4c7c86b71bf61a4f00845f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h
@@ -33,6 +33,9 @@ class MANTID_ALGORITHMS_DLL ClearCache final : public API::Algorithm {
 public:
   const std::string name() const override final;
   int version() const override final;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CleanFileCache"};
+  }
   const std::string category() const override final;
   const std::string summary() const override final;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h
index b39849874d698a9fc4e89bb8ee5ac8cd664786a8..d24d9dd115be8e5dbe1417443c611f1e278fb803 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h
@@ -40,6 +40,9 @@ public:
   const std::string summary() const override;
   const std::string category() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CopyInstrumentParameters"};
+  }
 
 private:
   void init() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h
index 99eb3d1fb125b485d7c45aef974d596d27e8b90e..d50afc77ffae7a1cb9212ab1ce34e8d40fd236b8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h
@@ -34,6 +34,9 @@ class DLLExport ClearMaskFlag : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors"};
+  }
   const std::string category() const override;
   /// Algorithm's summary
   const std::string summary() const override {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h
index fa27e65da2241cd37e2829ac752ddadb2cd43e28..95dd39b1fb7406006a159466524050fd8960a77e 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h
@@ -40,6 +40,9 @@ class MANTID_ALGORITHMS_DLL ClearMaskedSpectra
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors", "MaskInstrument"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h
index d22e997dd59359ed7faecf90ec1a62eb4bf0504a..3152a123de2825f876e7014cf185b2755488c14b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h
@@ -51,6 +51,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CompareWorkspaces"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Comment.h b/Framework/Algorithms/inc/MantidAlgorithms/Comment.h
index 6db408913c375d7497e58e41431b4180075ab000..d8e7bb888d3ed5a597b351bc6a7a11cba97fae65 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Comment.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Comment.h
@@ -33,6 +33,9 @@ class DLLExport Comment : public API::DistributedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RemoveWorkspaceHistory"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h
index 88b4ec69a721b78b49cb1bca33d67ba1e1acd7f8..dd7b806f982572a5941fb1febd33ac7a272dd0be 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h
@@ -76,6 +76,9 @@ public:
 
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CheckWorkspacesMatch", "CompareSampleLogs", "CloneWorkspace"};
+  }
 
   /// Algorithm's category for identification. @see Algorithm::category
   const std::string category() const override { return "Utility\\Workspaces"; }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h
index ff4dfcc488bb339bae0eca58993833cd1ab813aa..ac635cd6b76ed5d1b1ca9d740d61cd4b43f97033 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h
@@ -64,6 +64,9 @@ public:
   const std::string name() const override { return "ConjoinWorkspaces"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConjoinSpectra", "ConjoinXRuns", "MergeRuns"};
+  }
 
 private:
   // Overridden Algorithm methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h
index 082160564d16f3e5f29dcf1aa7927a6f8248b697..87f2f1774bc610813ccd143d2c8133e640902837 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h
@@ -39,6 +39,9 @@ class DLLExport ConvertAxesToRealSpace : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertSpectrumAxis", "ConvertUnits"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h
index 568f6a168fa92668f29f3731c082c57f040cd356..b60657819969531f1fc58fe87fe57e14acc89155 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h
@@ -51,6 +51,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertUnits"};
+  }
   const std::string category() const override;
 
 protected:
@@ -72,7 +75,7 @@ private:
     double value;
     bool isGeometric;
   };
-  typedef boost::shared_ptr<Variable> Variable_ptr;
+  using Variable_ptr = boost::shared_ptr<Variable>;
 
   void setAxisValue(const double &value, std::vector<Variable_ptr> &variables);
   void calculateValues(mu::Parser &p, std::vector<double> &vec,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h
index 9efc415141be4b49c3b8547f75c5223e07820d8e..3244c5f8c1b3cb77648612c241b62b2b89828c6c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h
@@ -33,6 +33,9 @@ class DLLExport ConvertDiffCal : public API::ParallelAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateDIFC"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h
index 19bfe10f0f90261a62fd1564db9dc96360a89cab..77212c5bdb6f08d6fead74609fed98ce5ef81260 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h
@@ -51,6 +51,9 @@ public:
   }
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToDistribution"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Distribution";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
index b104840265ffd0444140bc4e3e149c1a3b57b010..2184cbfa9420a3c9a7fc7f1a7c939bc5e070e337 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (2); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertAxesToRealSpace", "ConvertUnits"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Units;Transforms\\Axes";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h
index 1d2071bff6c690ff6f7278892bfd342a4dea0d64..96b38bf7aa85300b852551c8f623a633975761c2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h
@@ -59,6 +59,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertMDHistoToMatrixWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h
index bc00562a1017bfc3d6d384f1e9e2ffdf1473d87b..115e0ee62a74b2c6fa97bb3ca0af2768b758623d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h
@@ -53,6 +53,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CorrectTOFAxis"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Inelastic\\Corrections;CorrectionFunctions\\InstrumentCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h
index 1a73ad98da0e1c47691ea5afdefb871b1c58f503..dc2d624acc14fe17f3b92e5af7c6498401d09e3d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h
@@ -50,6 +50,9 @@ public:
   }
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertFromDistribution"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Distribution";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h
index 002d9a88f3458c7e9ef0c8d2423121ca84dc3a81..25fc51d41746eb1f39a3f12903c9b4f8904ef180 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMatrixWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Events"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h
index 762f8298b577c9a06930351f268f0ea7e7ddd0ff..54a0e7c764948939d8b441d088f86221e3d4890f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h
@@ -46,7 +46,9 @@ public:
     return "Converts a workspace containing point data into one containing "
            "histograms.";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToPointData"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Axes"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h
index b54ea719a056ab866beb37df3c5f519b46888f47..b678284d18aa43cb0e83664f24f32554fffe4124 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h
@@ -55,6 +55,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToEventWorkspace", "Rebin"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Events"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h
index ad628c2de7a59a68778ea2814b7599ba6b65b955..052d24418f4dd1555aa43df57117096b64cd52e4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h
@@ -46,7 +46,9 @@ public:
     return "Converts a workspace containing histogram data into one containing "
            "point data.";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToHistogram"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Axes"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
index 17b12f37a7c0fd720ce38d0adf29c2676b61c32b..9d856b2453fdecd1ca88473ac6f57dc3882f5738 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
@@ -75,6 +75,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertAxisByFormula", "ConvertAxesToRealSpace",
+            "ConvertSpectrumAxis", "ConvertToYSpace"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Units"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h
index 9dd9c12630537fbdbe80c27e512708491e1e4e25..d162e7172f1805bb79918fd3b44d988220fba2d1 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h
@@ -48,6 +48,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CopyLogs"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h
index 5740e3cae41ea0a185d546a855f46748172558e0..56a41ccf8a8a04af4abb1598dea9b4fec65041a7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h
@@ -67,6 +67,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ClearInstrumentParameters"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h
index 9ac0cda49912afd79fa61048eb6f2dc9a1144cba..0bdae1199d34e136b0fb2c546ded484fdf366971 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h
@@ -51,6 +51,10 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateLogPropertyTable", "CopyDetectorMapping",
+            "CheckForSampleLogs", "CopySample"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h b/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h
index 0fd33a490570e6d4db633771b8270fc9e951588d..8b2a8cdfd4ceaa2f15dc946110174fdd58f9777a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CompareSampleLogs", "CopyLogs", "CheckForSampleLogs"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Sample;Utility\\Workspaces";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h b/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h
index 1c0ebc3900a32fcc0c2f372c3f5f91700a6e8302..53d13250b5cbaede15a2aae3ee2ff080e8c024bb 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h
@@ -43,6 +43,9 @@ class MANTID_ALGORITHMS_DLL CorrectTOFAxis : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToConstantL2"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h
index b49059fc4fd1a757667ac9dba28488d9d3ecd61c..2a6b275cbb34c7ceb56b54ec493b26fc04d1e260 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h
@@ -73,6 +73,11 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReadGroupsFromFile",   "CreateDummyCalFile", "AlignDetectors",
+            "DiffractionFocussing", "LoadCalFile",        "SaveCalFile",
+            "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling\\CalFiles";
@@ -80,7 +85,7 @@ public:
 
 private:
   /// Calibration entries map
-  typedef std::map<int, std::pair<int, int>> instrcalmap;
+  using instrcalmap = std::map<int, std::pair<int, int>>;
   /// Initialisation code
   void init() override;
   /// Execution code
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h
index c67ea73bb2e8ecf8bf794bcc20f188cbac4f5f66..6b85d2588603c831ad8f507350e8fe78197a1a3d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h
@@ -72,6 +72,11 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReadGroupsFromFile",   "CreateCalFileByNames", "AlignDetectors",
+            "DiffractionFocussing", "LoadCalFile",          "SaveCalFile",
+            "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling\\CalFiles";
@@ -79,7 +84,7 @@ public:
 
 private:
   /// Calibration entries map
-  typedef std::map<int, std::pair<int, int>> instrcalmap;
+  using instrcalmap = std::map<int, std::pair<int, int>>;
   /// Initialisation code
   void init() override;
   /// Execution code
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h
index 7c8303357864322e7688f356067e181b641fb8b5..defb4365f0d401199088d6c8dd3a7908a92fb413 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h
@@ -36,6 +36,9 @@ class MANTID_ALGORITHMS_DLL CreateEPP : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindEPP"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h
index 3114ba65dc9e1807839efe7ab7f53692710b64a3..3ea99f0c802613edfe9e3735d08c9232a6a1130a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h
@@ -27,6 +27,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"DiffractionFocussing", "LoadCalFile"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h
index 9e1b2ab1af49b2e732d541fc2fd7ac53cf5348ae..aa1126df4a5c04bb8d5f2d924ab3a96e05d0d335 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h
@@ -40,6 +40,9 @@ public:
   const std::string name() const override { return "CreateLogPropertyTable"; };
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CopyLogs"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h
index a854f532299e4b25c48d494510855cdf909e37a5..69b99c16991f186b6fef18453b589400417e35c0 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h
@@ -54,6 +54,9 @@ public:
   }
 
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ChangePulsetime", "ShiftLogTime"};
+  }
   const std::string category() const override {
     return "Events\\EventFiltering";
   }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h b/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h
index 05a492c96117909428bebbee9de939962af8a97a..1b77bb1653b388237d7ef5b3af94641e89110292 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h
@@ -57,7 +57,9 @@ public:
     return "Runs a diagnostic test for saturation of PSD tubes and creates a "
            "MaskWorkspace marking the failed tube spectra.";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"IdentifyNoisyDetectors"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h
index c89ea8575bb787006aedc1ac3dd6ff1e48441023..b82ffbe83ab095d0847d2895c903c4edea9b7587 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h
@@ -23,6 +23,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SortPeaksWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\Peaks;Utility\\Workspaces";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
index 097365525c3fca27085ceddb2f081be04890a088..c6af3b525d9b6bd70d4fce979de05bd5f6c097f9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
@@ -43,6 +43,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateWorkspace"};
+  }
   const std::string category() const override;
   /// Algorithm's summary
   const std::string summary() const override {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h
index 6f12e8453a57d28a3c54df065907b76b6e9d4a31..177f8fcab211cefe2b8c2b6b209756c9df6346b6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h
@@ -53,6 +53,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h
index 03d9025360afc8c886d55c8c92622e2e7d02463d..c366d823bd5982c0dce231d20aefd351116f5cf9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h
@@ -36,6 +36,9 @@ public:
   const std::string name() const override;
   const std::string summary() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateTransmissionWorkspaceAuto"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h
index d70bbe6c2c9e0ff7685909718dd32e46e98c3f78..ce18cd219a09f6397ccc603af4f8a5e68b447fe8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h
@@ -40,6 +40,9 @@ public:
   }
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateTransmissionWorkspace"};
+  }
   /// Algorithm's category for identification. @see Algorithm::category
   const std::string category() const override { return "Reflectometry\\ISIS"; }
   /// Algorithm's summary for documentation
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h
index 1c23eefb9575c3965b1cc8c99a103f5e748adee0..d69dce914417d3e51dd157228ba5a91fd56b3d39 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h
@@ -44,6 +44,9 @@ public:
   const std::string name() const override;
   /// Version number
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RemoveBackground", "CalculatePolynomialBackground"};
+  }
   /// Category algorithm belongs to
   const std::string category() const override;
   /// Description of algorithm
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h
index 7e4f3c1169f436be53ef6277993e75e07a420504..fba8eb347f2bf2cfe35d6adb192df9ff02416858 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h
@@ -9,7 +9,7 @@ namespace Algorithms {
 *  CreateWorkspace Algorithm
 *
 *  This algorithm constructs a MatrixWorkspace when passed a vector for each of
-*the X, Y, and E
+*the X, Y, E, and Dx
 *  data values. The unit for the X Axis can optionally be specified as any of
 *the units in the
 *  Kernel's UnitFactory.
@@ -65,6 +65,9 @@ public:
     return (1);
   } ///< @return version number of algorithm
 
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateSingleValuedWorkspace", "CreateSampleWorkspace"};
+  }
   std::map<std::string, std::string> validateInputs() override;
 
 protected:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h b/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h
index d847fa91c390f3628483bdbc7f883fe77771a368..330848923dfc58d9e8ea33be43548e240d2840b4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h
@@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL CropToComponent final
 public:
   const std::string name() const override final;
   int version() const override final;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CropWorkspace"};
+  }
   const std::string category() const override final;
   const std::string summary() const override final;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h
index f4917f1b15db944956c8f01f73982562ed29c6e6..cec199a358a3f63c65354548feabae165f7af150 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h
@@ -75,6 +75,10 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CropWorkspaceRagged", "CropToComponent", "RemoveBins",
+            "ExtractSingleSpectrum", "ExtractSpectra"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Splitting";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h b/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h
index 199d1651a759dcb73bf0cbe6840f4192d311ddfb..64a710667f309cdcf8e597444ed2927f990eb8ad 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h
@@ -72,6 +72,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GetDetectorOffsets"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Arithmetic"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h
index 9496e24b5dbe25bcd9333a8403a780ba8a0a5233..a9eaaa3fe70d980c72fefe5f27f1213d680fb0e8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
 
 private:
   std::string sampleXML() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h
index 3f6a68b2fcfd42f5e7998da53a7b08c2ddc1d8c9..002d5d2ca357fce25d7fc17edf3750ae09ee8705 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h
@@ -100,6 +100,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
 
 private:
   void defineProperties() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h
index 12c5a0dedef05d34d7505a61e6dd4874790659fe..35bf4200a4eaf21f6777155285b994366e56cffa 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h
@@ -37,6 +37,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLog", "RenameLog"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h
index 045f2df92cbd500891068a2589dfe8a70fff2797..406e0a2c29bb16c7b8b73d8b600ef9990a6a2dde 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h
@@ -47,6 +47,9 @@ public:
   const std::string category() const override { return "Utility\\Workspaces"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DeleteWorkspaces"};
+  }
 
 private:
   /// Overridden init
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h
index 5fb03e7629060c25327a550019f952636d83ece2..af374634491729601114dc224d3f7d978a1608ef 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h
@@ -48,6 +48,9 @@ public:
   const std::string category() const override { return "Utility\\Workspaces"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DeleteWorkspace"};
+  }
 
 private:
   /// Overridden init
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h
index 6c25619a6d391ca6835f0aba7ba2e216cda25ad9..8f8d42bebc65ec80921043a687142d54fdec165a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h
@@ -59,6 +59,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindDetectorsOutsideLimits", "FindDeadDetectors",
+            "MedianDetectorTest", "DetectorEfficiencyVariation"};
+  }
 
 private:
   // Overridden Algorithm methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
index 473265ec925b9b3141b8099a11f484b9e0215901..de8a1a4827be8274e7842bef989f5c8ae26f5f17 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
@@ -97,6 +97,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"He3TubeEfficiency", "DetectorEfficiencyCorUser"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\EfficiencyCorrections;Inelastic\\Corrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h
index d37642568e5bcd836788de722336507fc0aa11a9..875e336428328fc7cf3fef125cb46ed9bfb2148c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h
@@ -62,6 +62,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"DetectorEfficiencyCor"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h
index ea4732a42848d1f62f61853b9f7e1c3866232119..cb57fadb7dfe44b91c47754755a52c51d0263370 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h
@@ -73,6 +73,9 @@ public:
   const std::string category() const override;
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DetectorDiagnostic"};
+  }
 
 protected:
   // Overridden Algorithm methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h
index 2f574ba31e8dec2f3c8b1e2016970ff2389e5b93..f6df300325a8bcc93a37c93a367db419e6997704 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h
@@ -53,6 +53,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AlignComponents", "GetDetOffsetsMultiPeaks"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\Calibration;"
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h
index f480d4d18789afa9059b78c63a086e48ac0142d6..93be5a461032abbee24bffbfa8ec4982abd07504 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h
@@ -90,6 +90,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AlignDetectors", "AlignAndFocusPowder", "LoadCalFile"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\Focussing";
@@ -123,7 +126,7 @@ private:
 
   // This map needs to be ordered to process the groups in order.
   /// typedef for the storage of each group's X vector
-  typedef std::map<int, boost::shared_ptr<MantidVec>> group2vectormap;
+  using group2vectormap = std::map<int, boost::shared_ptr<MantidVec>>;
   /// Map from udet to group
   std::vector<int> udet2group;
   /// The list of group numbers
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
index eec9111b43acb9165aa489f1febaa71a1636ce1f..58ed5e56097ccf1e4bfca2cfb1416f4ee08dc6bc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Plus", "Minus", "Multiply"};
+  }
 
 private:
   void init() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h
index 8eca5028f2c1abb2d994679901b58ee22376e44f..b4a839b7704ea5cbdf8cfa6238ffd30585cf1ffa 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReactorSANSResolution"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h b/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h
index 8db8dcae7ecea95bdee1115f0a6ea5b817566719..d7d1ee0e14e3b844d2f331f99e3061bf04f0b542 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Integration"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Inelastic\\Indirect"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h b/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h
index b6f1f75ddcedbdb58771a6d5c9f1744304ceedc4..d8ca4d92550e4bbeee653c9cda2d4d73e7eb4ca3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h
@@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL EstimateDivergence : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"EstimateResolutionDiffraction"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h b/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h
index ce8ec2d8d919f0416bd0ef6c475c28b96be0e532..dca712bdd1c95eceee2a312403d2355ee3536b87 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"EstimateDivergence"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h b/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h
index 784a465f25696fcc8d45fc79622e7520f2c24d1c..f68b314d3527c11278bfca92b8c9b4b52615bfed 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h
@@ -58,6 +58,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Power", "Logarithm"};
+  }
 
 private:
   // Overridden UnaryOperation methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h
index d0471988b87cd7edb8ccfbf0ab44adc767615d34..426525e90b60fe0d434ccba5a951ff3d8ccdad0b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h
@@ -65,6 +65,10 @@ public:
   }
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MagFormFactorCorrection", "PowerLawCorrection",
+            "OneMinusExponentialCor", "PolynomialCorrection"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "CorrectionFunctions"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h b/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h
index eb102b7b5e10c0fa2c8a0a16e2c1b4254e6d4d74..3c08034cfc17018f5cab197d078ce7bd9a1d46da 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h
@@ -41,6 +41,9 @@ public:
   const std::string name() const override { return "ExportTimeSeriesLog"; };
 
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"GetTimeSeriesLogInformation"};
+  }
 
   const std::string category() const override {
     return "Diffraction\\DataHandling;Events\\EventFiltering";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h
index 03273d2ac66807e3ef4a45a96fc9b4e0620db168..f2c655866554c50e28a389ade2763d35a5fc9b00 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h
@@ -55,6 +55,10 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FFT",     "FFTDerivative", "MaxEnt",
+            "RealFFT", "SassenaFFT",    "FFTSmooth"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Arithmetic\\FFT"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h
index 1395599033b26dce0b15867f0d2bd38e075d45e9..db6ed184f7cb74531b96fd1ebb85d14b6b8261e8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractMaskToTable"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h
index a2da267a776c2492fd65a0a0e8ea990409f9a4cf..a1b87289f1d9f77a6a740ddef66bcc5a0c01bf65 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h
@@ -46,6 +46,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractMask"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h
index 298ca2bf47705f6bd356f9d3fad5c5fb2f195240..2ef1ec068764c442453bbfc084126c03ae52c41b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h
@@ -52,6 +52,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CropWorkspace", "ExtractSpectra", "PerformIndexOperations"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Splitting";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h
index 39bf1d6753d15bdab7612b2dcafe362b2f2ea386..e34b54c0b0685ef518c5d8fd6a916c2d872f19f6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h
@@ -37,6 +37,10 @@ class DLLExport ExtractSpectra : public API::DistributedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CropWorkspace", "ExtractSingleSpectrum", "ExtractUnmaskedSpectra",
+            "PerformIndexOperations"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h
index ca372477cfadb1e9bacaa585660d33e5df6ccb95..1b52e0c51b17887ffe8436180ad29430e65c4afe 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h
@@ -34,6 +34,9 @@ class MANTID_ALGORITHMS_DLL ExtractUnmaskedSpectra : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RemoveMaskedSpectra"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFT.h b/Framework/Algorithms/inc/MantidAlgorithms/FFT.h
index 072ce8cdd3ab980fe77fff6e8c7e4c5c0aa58dc6..82f6aedf00c51173c515e26a6154fedc9a4be81f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FFT.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FFT.h
@@ -60,6 +60,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractFFTSpectrum", "FFTDerivative", "MaxEnt", "RealFFT",
+            "SassenaFFT", "FFTSmooth"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic\\FFT"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h b/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h
index 00b88117866498d833085b87f0cf90c87ee74148..6f5b3c06070b816bc41839313f8ef2c64b31ecb2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h
@@ -53,6 +53,10 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractFFTSpectrum", "FFT", "MaxEnt", "RealFFT", "SassenaFFT",
+            "FFTSmooth"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Arithmetic\\FFT"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h
index 5706a7006eb243e93b7ee7df0b61b4646c86b22f..2fc57c42ca5ab3efb508dcabb7bd46d9c1719d2b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FFT", "WienerSmooth"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Arithmetic\\FFT;Transforms\\Smoothing";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h
index c57eab8d1130f311f8c863d0a03b048c26c67092..a2344de1000c29cece3077291443f93838df89da 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h
@@ -56,6 +56,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FilterByTime", "FilterByLogValue"};
+  }
 
   const std::string category() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h
index 0e9eb5773cee83b4d2ccdf38b5ae7635a8245cc1..adae9416d81ebec063b9cee2a9281b238cb137a7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h
@@ -42,6 +42,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"FilterByXValue", "FilterEvents", "FilterLogByTime",
+            "FilterBadPulses", "FilterByTime"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Events\\EventFiltering";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h
index 8bd8398a9e1dcefa106277551c8057e008ab5f1e..9177dd53f8d4c685ab8b9e78b6d661d6aaff7dcc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h
@@ -49,6 +49,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventNexus", "FilterByXValue", "FilterEvents",
+            "FilterLogByTime", "FilterBadPulses"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Events\\EventFiltering";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h
index 95e703d2c46fb9526fd66281490d956679c4fdf1..73648a3f59d6bc14ea47438e336a8a3f9a9883b6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FilterByTime", "FilterByLogValue", "FilterBadPulses"};
+  }
   const std::string category() const override;
 
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h
index f7cb0a4ee73de572529e2750786c89e2dbb5fcc9..08d166fdcaaae2a30017c8c010d840308cf54071 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h
@@ -67,6 +67,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GenerateEventsFilter", "FilterByTime", "FilterByLogValue"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h b/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h
index a1cd8654046a9fbac7b1ac67adedd599fbcd543f..f5893103918f5e05ce15bce4d93bfe82df6c9f46 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h
@@ -50,6 +50,7 @@ public:
 
   /// Algorithm's version
   int version() const override { return (2); }
+
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h
index 9581d8fd6d84ada45dbce3ec9788f9da18fe51f3..cfbbd00da511d56ee99ca75cb3002d88dd65c7c2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h
@@ -75,6 +75,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindDetectorsOutsideLimits", "DetectorDiagnostic"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Diagnostics"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h b/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h
index aaca7555e042c8af83ada6b50759a2accd66174d..ffe28acd94d40804b52ecb999fb10a1b8b199cb9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h
@@ -79,6 +79,9 @@ public:
   const std::string category() const override;
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindDeadDetectors", "DetectorDiagnostic"};
+  }
 
 private:
   /// Overridden init
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h
index d2737dc9b9912c4300da78081506f77d8a2f595b..ec2ed38057e11149782ae36fc7b114fa1b6129f9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h
@@ -49,6 +49,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Utility\\Calculation"; }
@@ -80,8 +81,7 @@ private:
   /// Implement abstract Algorithm methods
   void exec() override;
   double moment4(MantidVec &X, size_t n, double mean);
-  void estimateBackground(const HistogramData::HistogramX &X,
-                          const HistogramData::HistogramY &Y,
+  void estimateBackground(const HistogramData::Histogram &histogram,
                           const size_t i_min, const size_t i_max,
                           const size_t p_min, const size_t p_max,
                           const bool hasPeak, double &out_bg0, double &out_bg1,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h
index 7cdaf8d08bb3ac3487f964e3a49bd302c51e002b..3a5aeafd2926662ced520b98f7ddc35ec9415006 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h
@@ -78,6 +78,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MatchPeaks", "FindPeaksMD", "GeneratePeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Optimization\\PeakFinding";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h b/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h
index f89d0d207afd0ad63543b6d6180f196d18b35bd4..abb09b22a1de96badcd49aa2c62674da09c5b811 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h
@@ -80,6 +80,7 @@ private:
 
   /// Version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
   /// Init
   void init() override;
   /// Exec
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FitPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/FitPeaks.h
new file mode 100644
index 0000000000000000000000000000000000000000..afbd53c8da720e1812edfc14ba05780e6ced2666
--- /dev/null
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FitPeaks.h
@@ -0,0 +1,319 @@
+#ifndef MANTID_ALGORITHMS_FITPEAKS_H_
+#define MANTID_ALGORITHMS_FITPEAKS_H_
+
+#include "MantidAPI/Algorithm.h"
+#include "MantidAPI/FunctionValues.h"
+#include "MantidAPI/IBackgroundFunction.h"
+#include "MantidAPI/IPeakFunction.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/MultiDomainFunction.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "MantidKernel/System.h"
+#include "MantidKernel/cow_ptr.h"
+
+namespace Mantid {
+namespace HistogramData {
+class HistogramX;
+class HistogramY;
+}
+
+namespace Algorithms {
+
+namespace FitPeaksAlgorithm {
+struct FitFunction {
+  API::IPeakFunction_sptr peakfunction;
+  API::IBackgroundFunction_sptr bkgdfunction;
+};
+
+class PeakFitResult {
+public:
+  PeakFitResult(size_t num_peaks, size_t num_params);
+  double getPeakPosition(size_t ipeak);
+  double getCost(size_t ipeak);
+  size_t getNumberParameters();
+  double getParameterValue(size_t ipeak, size_t iparam);
+  void setRecord(size_t ipeak, const double cost, const double peak_position,
+                 FitFunction fit_functions);
+  void setPosition(size_t ipeak, double position);
+  void setFunctionParameters(size_t ipeak, std::vector<double> &param_values);
+
+private:
+  /// number of function parameters
+  size_t function_parameters_number_;
+  // goodness of fitting
+  std::vector<double> costs;
+  // fitted peak positions
+  std::vector<double> fitted_peak_positions;
+  // fitted peak and background parameters
+  std::vector<std::vector<double>> function_parameters_vector;
+};
+}
+
+class DLLExport FitPeaks : public API::Algorithm {
+public:
+  FitPeaks();
+
+  /// Algorithm's name
+  const std::string name() const override { return "FitPeaks"; }
+
+  /// Summary of algorithms purpose
+  const std::string summary() const override {
+    return "Fit one or multiple peaks in all spectra of a given workspace";
+  }
+
+  /// Algorithm's version
+  int version() const override { return (1); }
+
+  /// Algorithm's category for identification
+  const std::string category() const override { return "Optimization"; }
+
+private:
+  /// Init
+  void init() override;
+  /// Main exec method
+  void exec() override;
+
+  /// process inputs (main and child algorithms)
+  void processInputs();
+  /// peak centers
+  void processInputPeakCenters();
+  /// process inputs about fitted peak positions' tolerance
+  void processInputPeakTolerance();
+  /// process inputs for peak and background functions
+  void processInputFunctions();
+  /// process inputs for peak fitting range
+  void processInputFitRanges();
+
+  /// Generate output workspaces
+  void generateFittedParametersValueWorkspace();
+  /// main method to create output workspaces
+  void generateOutputPeakPositionWS();
+  /// Generate workspace for calculated values
+  void generateCalculatedPeaksWS();
+
+  /// Convert peak function's parameter names to parameter
+  /// index for fast access
+  void convertParametersNameToIndex();
+
+  /// methods to retrieve fit range and peak centers
+  std::vector<double> getExpectedPeakPositions(size_t wi);
+  std::pair<double, double> getPeakFitWindow(size_t wi, size_t ipeak);
+
+  enum EstimatePeakWidth { NoEstimation, Observation, InstrumentResolution };
+  enum PeakFitResult { NOSIGNAL, LOWPEAK, OUTOFBOUND, GOOD };
+
+  /// suites of method to fit peaks
+  void fitPeaks();
+
+  /// fit peaks in a same spectrum
+  void fitSpectrumPeaks(
+      size_t wi, const std::vector<double> &expected_peak_centers,
+      boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result);
+
+  /// fit background
+  bool fitBackground(const size_t &ws_index,
+                     const std::pair<double, double> &fit_window,
+                     const double &expected_peak_pos,
+                     API::IBackgroundFunction_sptr bkgd_func);
+
+  // Peak fitting suite
+  double fitIndividualPeak(
+      size_t wi, API::IAlgorithm_sptr fitter, const double expected_peak_center,
+      const std::pair<double, double> &fitwindow, const bool high,
+      API::IBackgroundFunction_sptr high_background_function,
+      const bool observe_peak_width, API::IPeakFunction_sptr peakfunction,
+      API::IBackgroundFunction_sptr bkgdfunc);
+
+  /// Methods to fit functions (general)
+  double fitFunctionSD(API::IAlgorithm_sptr fit,
+                       API::IPeakFunction_sptr peak_function,
+                       API::IBackgroundFunction_sptr bkgd_function,
+                       API::MatrixWorkspace_sptr dataws, size_t wsindex,
+                       double xmin, double xmax,
+                       const double &expected_peak_center,
+                       bool observe_peak_width, bool estimate_background);
+
+  double fitFunctionMD(API::IFunction_sptr fit_function,
+                       API::MatrixWorkspace_sptr dataws, size_t wsindex,
+                       std::vector<double> &vec_xmin,
+                       std::vector<double> &vec_xmax);
+
+  /// fit a single peak with high background
+  double fitFunctionHighBackground(
+      API::IAlgorithm_sptr fit, const std::pair<double, double> &fit_window,
+      const size_t &ws_index, const double &expected_peak_center,
+      bool observe_peak_width, API::IPeakFunction_sptr peakfunction,
+      API::IBackgroundFunction_sptr bkgdfunc,
+      API::IBackgroundFunction_sptr high_bkgd_function);
+
+  /// get vector X, Y and E in a given range
+  void getRangeData(size_t iws, const std::pair<double, double> &fit_window,
+                    std::vector<double> &vec_x, std::vector<double> &vec_y,
+                    std::vector<double> &vec_e);
+
+  /// Reduce background
+  void reduceBackground(API::IBackgroundFunction_sptr bkgd_func,
+                        const std::vector<double> &vec_x,
+                        std::vector<double> &vec_y);
+
+  API::MatrixWorkspace_sptr
+  createMatrixWorkspace(const std::vector<double> &vec_x,
+                        const std::vector<double> &vec_y,
+                        const std::vector<double> &vec_e);
+
+  /// Esitmate background by 'observation'
+  void estimateBackground(const HistogramData::Histogram &histogram,
+                          const std::pair<double, double> &peak_window,
+                          API::IBackgroundFunction_sptr bkgd_function);
+  /// estimate linear background
+  void estimateLinearBackground(const HistogramData::Histogram &histogram,
+                                double left_window_boundary,
+                                double right_window_boundary, double &bkgd_a0,
+                                double &bkgd_a1);
+
+  /// Estimate peak parameters by 'observation'
+  int estimatePeakParameters(API::MatrixWorkspace_sptr dataws, size_t wi,
+                             const std::pair<double, double> &peak_window,
+                             API::IPeakFunction_sptr peakfunction,
+                             API::IBackgroundFunction_sptr bkgdfunction,
+                             bool observe_peak_width);
+
+  bool decideToEstimatePeakWidth(size_t peak_index,
+                                 API::IPeakFunction_sptr peak_function);
+
+  /// observe peak center
+  int observePeakCenter(const HistogramData::HistogramX &vector_x,
+                        const HistogramData::HistogramY &vector_y,
+                        API::FunctionValues &bkgd_values, size_t start_index,
+                        size_t stop_index, double &peak_center,
+                        size_t &peak_center_index, double &peak_intensity);
+
+  /// Observe peak width
+  double observePeakWidth(const HistogramData::HistogramX &vector_x,
+                          const HistogramData::HistogramY &vector_y,
+                          API::FunctionValues &bkgd_values, double peak_height,
+                          size_t ipeak, size_t istart, size_t istop);
+
+  /// Process the result from fitting a single peak
+  void processSinglePeakFitResult(
+      size_t wsindex, size_t peakindex, const double cost,
+      const std::vector<double> &expected_peak_positions,
+      FitPeaksAlgorithm::FitFunction fitfunction,
+      boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result);
+
+  /// calculate peak+background for fitted
+  void calculateFittedPeaks();
+
+  /// Get the parameter name for peak height (I or height or etc)
+  std::string
+  getPeakHeightParameterName(API::IPeakFunction_const_sptr peak_function);
+
+  /// Set the workspaces and etc to output properties
+  void processOutputs();
+
+  /// Write result of peak fit per spectrum to output analysis workspaces
+  void
+  writeFitResult(size_t wi, const std::vector<double> &expected_positions,
+                 boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result,
+                 bool noevents);
+
+  //------- Workspaces-------------------------------------
+  /// mandatory input and output workspaces
+  API::MatrixWorkspace_sptr m_inputMatrixWS;
+  bool m_inputIsDSpace;
+  /// event workspace for input
+  DataObjects::EventWorkspace_const_sptr m_inputEventWS; // cast from m_inputWS
+  /// output workspace for peak positions
+  API::MatrixWorkspace_sptr
+      m_outputPeakPositionWorkspace; // output workspace for peak positions
+  /// matrix workspace contains number of events of each spectrum
+  API::MatrixWorkspace_const_sptr m_eventNumberWS;
+  /// optional output analysis workspaces
+  /// table workspace for fitted parameters
+  API::ITableWorkspace_sptr m_fittedParamTable;
+  /// matrix workspace contained calcalated peaks+background from fitted result
+  /// it has same number of spectra of input workspace even if only part of
+  /// spectra to have peaks to fit
+  API::MatrixWorkspace_sptr m_fittedPeakWS;
+
+  //-------- Functions ------------------------------------------------------
+  /// Peak profile name
+  API::IPeakFunction_sptr m_peakFunction;
+  /// Background function
+  API::IBackgroundFunction_sptr m_bkgdFunction;
+  /// Linear background function for high background fitting
+  API::IBackgroundFunction_sptr m_linearBackgroundFunction;
+
+  /// Minimzer
+  std::string m_minimizer;
+  /// Cost function
+  std::string m_costFunction;
+  /// Fit from right or left
+  bool m_fitPeaksFromRight;
+
+  //-------- Input param init values --------------------------------
+  /// input starting parameters' indexes in peak function
+  std::vector<size_t> m_initParamIndexes;
+
+  /// Designed peak positions and tolerance
+  std::vector<double> m_peakCenters;
+  API::MatrixWorkspace_const_sptr m_peakCenterWorkspace;
+  size_t m_numPeaksToFit;
+  bool m_uniformPeakPositions;
+
+  /// flag to estimate peak width from
+  double m_peakDSpacePercentage;
+
+  //--------- Fitting range -----------------------------------------
+  /// start index
+  size_t m_startWorkspaceIndex;
+  /// stop index (workspace index of the last spectrum included)
+  size_t m_stopWorkspaceIndex;
+  /// flag whether the peak center workspace has only a subset of spectra to fit
+  bool m_partialSpectra;
+  std::vector<double> m_peakPosTolerances;
+
+  /// Flag for observing peak width: there are 3 states (1) no estimation (2)
+  /// from 'observation' (3) calculated from instrument resolution
+  EstimatePeakWidth m_peakWidthEstimateApproach;
+  bool m_constrainPeaksPosition;
+
+  /// peak windows
+  std::vector<std::vector<double>> m_peakWindowVector;
+  API::MatrixWorkspace_const_sptr m_peakWindowWorkspace;
+  bool m_uniformPeakWindows;
+  bool m_partialWindowSpectra;
+  /// flag to calcualte peak fit window from instrument resolution
+  bool m_calculateWindowInstrument;
+
+  /// input peak parameters' names
+  std::vector<std::string> m_peakParamNames;
+  /// input peak parameters' starting values corresponding to above peak
+  /// parameter names
+  std::vector<double> m_initParamValues;
+  /// table workspace for profile parameters' starting value
+  API::ITableWorkspace_const_sptr m_profileStartingValueTable;
+  /// flag for profile startng value being uniform or not
+  bool m_uniformProfileStartingValue;
+
+  // Criteria for fitting peaks
+  /// minimum peak height without background and it also serves as the criteria
+  /// for observed peak parameter
+  double m_minPeakHeight;
+
+  /// flag for high background
+  bool m_highBackground;
+  double m_bkgdSimga; // TODO - add to properties
+
+  //----- Result criterias ---------------
+  /// peak positon tolerance case b, c and d
+  bool m_peakPosTolCase234;
+};
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif /* MANTID_ALGORITHMS_FITPEAKS_H_ */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h b/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h
index 7376307abd1519d0c6b6ff150636fab8b7fda685..7743225df33a2726ace2f0bff280cbd92a3aff5e 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h
@@ -41,6 +41,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadGSASInstrumentFile"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h
index 4253708e9012be597cdacccfe2c95a74981e593c..e043d49b51ff8b49a769b688a0f47ba114a28624 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h
@@ -88,6 +88,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
 
 protected:
   void initialiseCachedDistances() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h b/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
index 7c8f6930d787d34d67ee92772b05c6ae093b569d..9e12f0b9e998bc9723cb78bf13ca72f545fa9bce 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h
@@ -73,6 +73,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FilterEvents", "FilterByTime", "FilterByLogValue"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Events\\EventFiltering";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h b/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h
index 882baeea5390607278bccd072ab339d8abba6a3e..93e9b72a6f886489caa51b2378d5857af04a8392 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h
@@ -51,6 +51,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RecordPythonScript", "GeneratePythonScript"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Python"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h
index a7dbfa7302535af666521ac015bf69a6c6bf8ffd..0a921362f4ce3a3eff49d7d0371be05fad61f046 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h
@@ -53,6 +53,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindPeaks", "MatchPeaks"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Peaks"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h
index 90db547f68428134283aef4b81e233d45fe064e3..4e98759a22659360a539e8e9edd6f1f8666a58d7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RecordPythonScript", "GenerateIPythonNotebook"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Python"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h
index 7cdd5ef79a4488cb70af5e7809ea319364ac7aff..10d97d6341a887f026229b8298401ebc20ff8d62 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h
@@ -55,6 +55,7 @@ public:
   }
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override { return {"GetEi"}; }
   /// Algorithm's category for identification. @see Algorithm::category
   const std::string category() const override { return "Inelastic\\Ei"; };
   /// Cross-check properties with each other @see IAlgorithm::validateInputs
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h
index fe45add3a6220f0b6dfeba044ad29a73dc2c28af..35faf98d455cd34f4bd6956ce0a797e7495413fe 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h
@@ -70,6 +70,9 @@ public:
   const std::string name() const override { return "GetDetOffsetsMultiPeaks"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GetDetectorOffsets"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\Calibration";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h b/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h
index f7b2392926d0514e94827017d5393070106b44c2..0e08637ad9b5717926a57a5c8928f68d4de6d694 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h
@@ -47,6 +47,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GetDetOffsetsMultiPeaks", "CalibrateRectangularDetectors",
+            "AlignComponents"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\Calibration";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
index c717122ebd9bc0c80f36732f0e8eaadae56db7ee..57ac117c7915a97b907e596622c973e46e803ddf 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
@@ -80,6 +80,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GetAllEi", "GetEiMonDet", "GetEiT0atSNS"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Inelastic\\Ei"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h b/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h
index fc8b693dd75203792788ce866656159f0981f2a2..66e032bb63737df399c6e89201c9fa42e8244355 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h
@@ -56,6 +56,7 @@ public:
 
   /// Returns algorithm's version for identification
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override { return {"GetEi"}; }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Inelastic\\Ei"; }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h b/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h
index 8776e174d15550dfe8091e085dbe28578fcb0a71..169b4bbb421779289e2c551214ec3c921a6e35b6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h
@@ -50,6 +50,9 @@ public:
   }
 
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLogMultiple"};
+  }
   const std::string category() const override {
     return "Diffraction\\Utility;Events\\EventFiltering";
   }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h
index 97a25bb314f68d4ae5767296cf0052384e957aff..b7e5f75380aa2be52ce31b91662d3fb4860bb2c7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"UnGroupWorkspace"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Transforms\\Grouping;Utility\\Workspaces";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h
index 5496735501c4494fc91b25e97190bc3af34a978f..9aec8352820aa25e99cb4cf4a5351bf6f27c1c30 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h
@@ -79,6 +79,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\AbsorptionCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
index 275d5bdce0ac6acaf4c7609b10e85c24baa4d2cb..b3372121aa92d471e1dfdfea464310de8b091fcb 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
@@ -73,6 +73,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DetectorEfficiencyCor"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\EfficiencyCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h
index b648722f7c7baa5b35281d2389b75cb447cdfb47..d1f01cdafa48532d074d026ef2114dc596d30c98 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h
@@ -87,8 +87,8 @@ private:
   subtractBackgroundWS(API::MatrixWorkspace_sptr ws,
                        API::MatrixWorkspace_sptr background);
 
-  typedef void (IQTransform::*TransformFunc)(API::MatrixWorkspace_sptr);
-  typedef std::map<std::string, TransformFunc> TransformMap;
+  using TransformFunc = void (IQTransform::*)(API::MatrixWorkspace_sptr);
+  using TransformMap = std::map<std::string, TransformFunc>;
   TransformMap
       m_transforms; ///< A map of transformation name and function pointers
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h
index 429d437f9547b0023a09498bbe04ba7244fde975..020a2193d25ad2c269657f9ada15bfe536480b73 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h
@@ -55,6 +55,10 @@ public:
     return (1);
   } ///< @return version number of algorithm
 
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePSDBleedMask"};
+  }
+
 private:
   void init() override; ///< Initialise the algorithm. Declare properties, etc.
   void exec() override; ///< Executes the algorithm.
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h b/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h
index caa647670c595e8c6abc692385689f563eec0a29..4610fa03e45c81060b99a272bc162ef3f9711f2f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h
@@ -40,6 +40,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Integration"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Integration.h b/Framework/Algorithms/inc/MantidAlgorithms/Integration.h
index 37eae9987736f8baa0d236acd6024b017a2bf853..20a1320c1dc3d7d4d00bb8bac34bcc468cd20505 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Integration.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Integration.h
@@ -67,6 +67,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegrateByComponent", "Rebin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Arithmetic;Transforms\\Rebin";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h b/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h
index 458b4b79d752326a88b25f659c0b7c5e499778a8..55adc55e8e0c5de5793b53dbcb55782242a35fcc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h
@@ -79,6 +79,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Rebin"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Rebin"; }
   /// Alias for the algorithm. Must override so it doesn't get parent class's
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h b/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h
index 5fbb20ac6df707bc8a9050c2636476ca150d65e9..8790333978911704950397a26651c5ec70cbc0c8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"BinaryOperateMasks", "MaskDetectors"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h
index e2da673079df0d129e3cd05df8c44e6658d2a895..d1921f4400f55c978522221b563cc36c9d6c14bf 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h
@@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL LineProfile : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RingProfile"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h b/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h
index 4831106bddb4fc7c75dff091ac016eb2beb0c49c..c5cf955fc3f4f1ac7d049ae48b7a69c4e514ef24 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Power", "Exponential"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Arithmetic"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h
index ba973bfdf0ed4f4c7dfc5e3a3bbd5f0626b1e6f2..e7f64c86975de8b9b2c0a45ec1f2cfd8903b7059 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h
@@ -35,6 +35,9 @@ class DLLExport LorentzCorrection : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AnvredCorrection"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h
index 98d2ac575b8eefa7635f4d3a804dadf725a3bb44..0799f810be77a87aff597ceb02fd13a3d7f9af69 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h
@@ -56,6 +56,7 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"SofQW"}; }
   /// Algorithm's category for identification
   const std::string category() const override { return "CorrectionFunctions"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
index 743d0a81787122f2c4cabb96a3c9b53f3051b82a..85e5b5b1082961c7759cfbd2112ece8d0f902b74 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h
@@ -64,6 +64,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskBinsFromTable"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h
index 740c88c9d8c1184f114f4a9b3d39ed54675b257a..c8974c5b7eb50fa40f0ef6d84a5d3d1bb42e9546 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h
@@ -46,6 +46,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskBins"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h
index 3eba9354807671c37aa4c21433f8048295e615bf..d4fd299ed3b8e218d96b32a4546fccf2922e18df 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\Masking;Transforms\\Masking";
@@ -66,7 +69,7 @@ private:
   /// Returns an allowed values statement to insert into decumentation
   std::string allowedValuesStatement(const std::vector<std::string> &vals);
   // Typedef for det to value map
-  typedef std::unordered_map<detid_t, bool> udet2valuem;
+  using udet2valuem = std::unordered_map<detid_t, bool>;
   /// A map of detector numbers to mask boolean
   udet2valuem umap;
   /// Get the properties
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h
index ef6837232280d79e99b2ce84335c6890cc1aecdb..1c3c0493bee19553e8d3e769b284fa5b975ee4b9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h
@@ -39,6 +39,9 @@ class MANTID_ALGORITHMS_DLL MaskInstrument : public API::DistributedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors", "ClearMaskedSpectra"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Max.h b/Framework/Algorithms/inc/MantidAlgorithms/Max.h
index 8f3a089b5b330808be03cdbb9d73989be672f567..ad8c92dcb33dc3cd4b0de0b2dedf487a70fcba3e 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Max.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Max.h
@@ -58,6 +58,9 @@ public:
   const std::string name() const override { return "Max"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Min", "MaxMin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic"; }
   /// Summary of algorithms purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h
index 14582e526742301a99018823c6f50467dc7850ea..3980cda6bcf3eab7bb86a6697d3f05dda9af6e38 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h
@@ -43,6 +43,10 @@ public:
   const std::string name() const override;
   /// Algorithm's version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "RealFFT",
+            "SassenaFFT", "FFTSmooth"};
+  }
   /// Algorithm's category
   const std::string category() const override;
   /// Algorithm's summary
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h
index f2cb873b2f86f158612941a7cdce8aa49ba51981..32a59b4c69333fe288219c52f0106fee76e8987d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h
@@ -65,6 +65,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Max", "Min"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h b/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h
index 695b0320bb1f5c544d6cdb8c61894fb89aab8523..dba48a980ca7d7012a1320dc427c647507732a95 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h
@@ -77,6 +77,9 @@ public:
   const std::string category() const override;
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DetectorDiagnostic"};
+  }
 
 private:
   // Overridden Algorithm methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
index 90d1c922c6acce2d16173aa40610808eba8e801b..8165863d77555247ec954431ad17e014827e89c9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
@@ -74,6 +74,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConjoinWorkspaces"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Merging"; }
   // Overriden MultiPeriodGroupAlgorithm method.
@@ -96,7 +99,7 @@ private:
   /// An addition table is a list of pairs: First int = workspace index in the
   /// EW being added, Second int = workspace index to which it will be added in
   /// the OUTPUT EW. -1 if it should add a new entry at the end.
-  typedef std::vector<std::pair<int, int>> AdditionTable;
+  using AdditionTable = std::vector<std::pair<int, int>>;
   /// Copy the history from the input workspaces to the output workspaces
   template <typename Container>
   void copyHistoryFromInputWorkspaces(const Container &workspaces) {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Min.h b/Framework/Algorithms/inc/MantidAlgorithms/Min.h
index 4787828eb9da7394e20169ecebc296fc261e4452..f218d65f67967922353b27cbabbb0ef6230a232f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Min.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Min.h
@@ -58,6 +58,9 @@ public:
   const std::string name() const override { return "Min"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Max", "MaxMin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic"; }
   /// Summary of algorithms purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
index 5e6a402ccb6eaf08b051171cab30a1467916d3f8..bd9acf03cbe136b5a45d225e7d5bce4364841a80 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h
@@ -58,6 +58,9 @@ public:
   const std::string alias() const override;
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Plus", "Divide", "Multiply"};
+  }
 
 private:
   // Overridden BinaryOperation methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h
index fd98511d3727727ad96f5072f6c06a7b57e396df..97af2302028da11342b46616260191abb16f8b6d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h
@@ -86,6 +86,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ModeratorTzeroLinear"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\InstrumentCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h
index 9a3ead956e753515297df78533816916d46f2687..f0fb409e222298646c75b36eb34e75dc274a1742 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h
@@ -88,6 +88,9 @@ public:
   const std::string summary() const override;
   /// Algorithm's version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ModeratorTzero"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h b/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h
index 1b9c80ef93b430614ee09d73a63df5f4ff5c7a49..75ede8e3a45bbcf339800a81ac65d5c3ac086c57 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h
@@ -26,6 +26,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"NormaliseToMonitor"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\NormalisationCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h
index 179ca161b01bc2ec2207527a7bee08c921f96728..2d627213fc7646f145c00c5b2be2deb4c2932f6d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h
@@ -49,6 +49,10 @@ public:
   const std::string name() const override { return "MonteCarloAbsorption"; }
   /// Algorithm's version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MayersSampleCorrection", "MultipleScatteringCylinderAbsorption",
+            "PearlMCAbsorption", "VesuvioCalculateMS"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\AbsorptionCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h b/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h
index f673f021c8179e5e42628164f1829598e3ebc9de..0d71ccd28e6c53d24fc0fd96fee1833a442e0fb0 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h
@@ -35,6 +35,7 @@ class MANTID_ALGORITHMS_DLL MostLikelyMean : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override { return {"Mean"}; }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h
index ab2190f5bf9fa46fadddf2d3a6e49d054f002728..c3bf17eb48b23974a9bd5e755017b37ac9ce140f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h
@@ -49,6 +49,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MonteCarloAbsorption", "MayersSampleCorrection",
+            "PearlMCAbsorption", "VesuvioCalculateMS"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
index 716a97bb14ae4c4516d060f139a180b83b655b94..4300b55bbe16ad6f9f6a7275f65c80e4f7daab28 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Plus", "Minus", "Divide"};
+  }
 
 private:
   // Overridden BinaryOperation methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h b/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h
index 3ff7887c9dec03a9fb5b7aa1aae874221f0864d3..a1345d9249284008f0a7d5e4d2a0f152023adcb3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h
@@ -54,6 +54,9 @@ public:
   }
 
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Multiply"};
+  }
   const std::string category() const override {
     return "Arithmetic;CorrectionFunctions";
   }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h
index e8f6eeab26bd38282bb880220c4761f68af15985..8a2a880bd6a519ced4d0ab3d924d82ed3142add4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h
@@ -37,6 +37,9 @@ class DLLExport NRCalculateSlitResolution : public API::DataProcessorAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateSlits"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h
index c41872d84f016b308ff7653a6b127eee2d2dbf39..46c22074df6fa513d04abd8e8e737a193c8cd408 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h
@@ -58,6 +58,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Divide"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\NormalisationCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h
index 70f9574d2b755e2464085a93f4e89b1988e2f65a..802dd0dce9f58faa89d1e830cbb4b0fdb3db9fec 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h
@@ -55,6 +55,7 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override { return {"Divide"}; }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
index 0d62e5d949d7d81b28b2dcc154dbafa34ad152bf..c99bc15fc87a6c61ecaac68c0355fd88d73280c0 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
@@ -88,6 +88,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Divide"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\NormalisationCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h
index c3719f59bfc343e84e2093473d2941562f469d45..ca93683fcb2eab5f47e4cac7504f0fefc647c0e5 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h
@@ -67,6 +67,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"Divide"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\NormalisationCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h b/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h
index e6f247584e89e4124ba7ccbd1fbd0ce3efda0dbc..b6dfe1d62ce70270bc7ee5621c11aa2a34bb1233 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h
@@ -65,6 +65,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MagFormFactorCorrection", "ExponentialCorrection",
+            "PowerLawCorrection"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "CorrectionFunctions"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h b/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h
index bacf0c065f8bf982a47d449cedecf52ab227a13f..bb44e769669dbfb7f44e40037a9202b2762ce418 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h
@@ -41,6 +41,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalibrateRectangularDetectors"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h b/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h
index 860285ea1a8e6d7cf08892b194b4f7366b46c22a..597021442b178b67b7ada3eb5cbb9f6fccd475c4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h
@@ -15,7 +15,7 @@ namespace Kernel {
 /// forward declaration
 class PropertyMantager;
 /// Typedef for a shared pointer to a PropertyManager
-typedef boost::shared_ptr<PropertyManager> PropertyManager_sptr;
+using PropertyManager_sptr = boost::shared_ptr<PropertyManager>;
 }
 
 namespace Algorithms {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h
index fb7dd244241e88c5266cc3baadc5e7b73e918463..4fc13a297bc9316b7f751c07edc03acb45008e41 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h
@@ -22,6 +22,7 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override { return {"FFT"}; }
   /// Algorithm's category for identification
   const std::string category() const override;
   /// @copydoc Algorithm::validateInputs()
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h b/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h
index a5fe87e91037f55f1b325e7c8ca61cf175d8f7a9..28577cc96ab6dafb27f3bc01171caa140e0c1f79 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h
@@ -67,7 +67,7 @@ private:
   // Overridden Algorithm methods
   void init() override;
   void exec() override;
-  typedef double (*fptr)(const double time, const double decayConstant);
+  using fptr = double (*)(const double, const double);
   fptr getApodizationFunction(const std::string method);
   HistogramData::Histogram
   applyApodizationFunction(const HistogramData::Histogram &histogram,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h b/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h
index fa32a9e561a6977ada13500e89cd61dcc05920fb..62fe4913a32832a292f971dab5bcb4eef44e3712 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h
@@ -40,6 +40,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractSpectra"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h b/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h
index d47ca50770df2ce0664f44d5d00f3a376ef35a3c..8b9ffafb6b58e2918fac970b76ee09232462dc25 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h
@@ -44,7 +44,9 @@ public:
   const std::string summary() const override {
     return "Generates a quadrature phase signal.";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"MuonMaxent"};
+  }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
   /// Algorithm's category for identification overriding a virtual method
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h
index e23fc5a28264cdddbbe250b781dab83b2a34fa76..f804ee642d97f165e1ea1ac3625c2827c66c7610 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h
@@ -69,6 +69,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AsymmetryCalc", "CalculateMuonAsymmetry", "PlotPeakByLogValue"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
index c06e1cbe8ea3c99f3e5426d391486b9300206c48..1e6239de2bf991966994b182fef7775ec15f158c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h
@@ -58,6 +58,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Divide", "Minus", "Multiply"};
+  }
 
 private:
   // Overridden BinaryOperation methods
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h
index 82a9adc2c20e83e65221a9d0ce6e0fb67196004a..07a29b9ac673c631055fc1bef90e9b75fe0a5c06 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h
@@ -41,6 +41,9 @@ class DLLExport PolarizationCorrection : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PolarizationEfficiencyCor"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h
index 53ed383886519c6642b7644a94f9188e6b000d3a..a84f32e031f8438b57c56ca2048771cc9befbc91 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h
@@ -42,6 +42,9 @@ class MANTID_ALGORITHMS_DLL PolarizationEfficiencyCor : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PolarizationCorrection"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h
index 9461f9ba196522cd56c579c3cc12f299dc4fe34a..b287e7bdf302398033a2794a68f83f535dfecc6b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h
@@ -63,6 +63,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"OneMinusExponentialCor", "MagFormFactorCorrection",
+            "ExponentialCorrection", "PowerLawCorrection"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "CorrectionFunctions"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Power.h b/Framework/Algorithms/inc/MantidAlgorithms/Power.h
index 193cb7458748a104e30c35d12d7818d2a393282d..ece61ba23d36f25de04213a4f14372acbe3657c3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Power.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Power.h
@@ -59,6 +59,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Exponential", "Logarithm"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h
index ae78311091a8a653ed333886e30af9b782a8ab77..970c63de36c7228541db3793ec86a22dd37680da 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h
@@ -63,6 +63,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"PolynomialCorrection", "OneMinusExponentialCor",
+            "MagFormFactorCorrection", "ExponentialCorrection"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "CorrectionFunctions"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h b/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h
index e0779024764f9147a15978c86755ba7033597e43..75184ff5b4d5d35ebff108a6563d53ad11fd383b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h
@@ -52,6 +52,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (2); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Q1DWeighted", "Qxy"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h b/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h
index e0ca710e74cdd010deb044563101a4b2837b4ccf..02dbe13c83fec21905ac38a009389d4d88244db7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h
@@ -56,6 +56,7 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"Q1D"}; }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h b/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h
index fe36eda1772cc38252b9a66c58f47bf80de86ffb..f91222a9542ad6c7881ec70aff8005568169443a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h
@@ -58,6 +58,7 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"Q1D"}; }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h b/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h
index f23184aafc15adabd0a598e6ecdfa780268fe121..3fe15b988d54022df644550bb5456aa69796be96 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateMuonAsymmetry"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h b/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h
index af0fc0257a7b3dc1c45123cb20a2ab739c7de655..8f1eba680b5a35ff100373f561069986bc262803 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h
@@ -46,6 +46,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RingProfile", "RadiusSum"};
+  }
   const std::string category() const override;
 
   static bool inputWorkspaceHasInstrumentAssociated(API::MatrixWorkspace_sptr);
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h
index a217c2db1be62131eea609f205b276fd5f9ef584..6ba55dde1feb5755b7927aadcca62321539d0623 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h
@@ -90,6 +90,11 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateDummyCalFile",   "CreateCalFileByNames", "AlignDetectors",
+            "DiffractionFocussing", "LoadCalFile",          "SaveCalFile",
+            "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling\\CalFiles";
@@ -98,7 +103,7 @@ public:
 private:
   /// Map containing the detector entries found in the *.cal file. The key is
   /// the udet number, the value of is a pair of <group,selected>.
-  typedef std::unordered_map<int, std::pair<int, int>> calmap;
+  using calmap = std::unordered_map<int, std::pair<int, int>>;
   /// Initialisation code
   void init() override;
   /// Execution code
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h b/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h
index bba0209f62036629b7956d220a3fce703d3e484a..2c6201579c94b3a6db1bc8656d38d549d69669e8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h
@@ -44,6 +44,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "MaxEnt",
+            "SassenaFFT", "FFTSmooth"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic\\FFT"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h
index 51240422723fff002224841577099ecf5c786564..585cc66d27981fd28792f12157f5b768cf386257 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h
@@ -67,6 +67,11 @@ public:
   const std::string category() const override { return "Transforms\\Rebin"; }
   /// Algorithm's aliases
   const std::string alias() const override { return "rebin"; }
+  /// Algorithm's seeAlso
+  const std::vector<std::string> seeAlso() const override {
+    return {"RebinToWorkspace", "Rebin2D",           "Rebunch",
+            "Regroup",          "RebinByPulseTimes", "RebinByTimeAtSample"};
+  }
 
   static std::vector<double>
   rebinParamsFromInput(const std::vector<double> &inParams,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h
index d5e0b2c3206d122a2e5b5eb9acde5b24463e6750..59981e907cef251590101342d7e12a34505d0e75 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h
@@ -48,6 +48,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Rebin", "SofQW"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Rebin"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h
index 711aabe826fcfc11cc2fda25fe6c1fd9f74bf7e1..74a7579fd416e0b9bcdcc0351e9cad1131d5a43d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h
@@ -41,7 +41,12 @@ public:
   }
 
   int version() const override;
+
   const std::string category() const override;
+  /// Algorithm's seeAlso
+  const std::vector<std::string> seeAlso() const override {
+    return {"Rebin", "RebinByTimeAtSample"};
+  }
 
 private:
   /// Do the algorithm specific histogramming.
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h
index 6bca5d6b0e0f19593b7a6e6c80fb14508ce1724d..7316a4e271260dcd864b72be7c05e26e2062bc60 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h
@@ -36,8 +36,13 @@ class DLLExport RebinByTimeAtSample : public RebinByTimeBase {
 public:
   const std::string name() const override;
   int version() const override;
+
   const std::string category() const override;
   const std::string summary() const override;
+  /// Algorithm's seeAlso
+  const std::vector<std::string> seeAlso() const override {
+    return {"Rebin", "RebinByPulseTimes"};
+  }
 
 private:
   void doHistogramming(Mantid::API::IEventWorkspace_sptr inWS,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h
index 62cf3439e3cde365de2a34bfca9db9bc014f5891..3518bb59c6ccfcdfee42e308999b06ba2098cc81 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h
@@ -57,8 +57,11 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Rebin"; }
+  /// Algorithm's seeAlso
+  const std::vector<std::string> seeAlso() const override { return {"Rebin"}; }
 
 protected:
   Parallel::ExecutionMode getParallelExecutionMode(
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h
index 6ab2eec810516b9831da8158261a60ec28e484f3..51d1ca1c91c438783b4a30bf582214d62808898f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h
@@ -67,6 +67,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Rebin"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Rebin"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h b/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h
index f60f3d88c2376b233d497f26824252b9f6b75c14..5acc3d276ed77c313a2cfa071c26e9b8cbcfcee2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"GenerateIPythonNotebook", "GeneratePythonScript"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Utility\\Python"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryMomentumTransfer.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryMomentumTransfer.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ac618e6d4788cea2473f4734d2280c92fb7d9ed
--- /dev/null
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryMomentumTransfer.h
@@ -0,0 +1,103 @@
+#ifndef MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFER_H_
+#define MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFER_H_
+
+#include "MantidAPI/Algorithm.h"
+#include "MantidAlgorithms/DllConfig.h"
+
+namespace Mantid {
+namespace Algorithms {
+
+/** Converts wavelength to momentum transfer and calculates the Qz
+  resolution for reflectometers at continuous beam sources."
+
+  Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class MANTID_ALGORITHMS_DLL ReflectometryMomentumTransfer
+    : public API::Algorithm {
+public:
+  const std::string name() const override;
+  int version() const override;
+  const std::string category() const override;
+  const std::string summary() const override;
+
+private:
+  enum class SumType { LAMBDA, Q };
+  struct Setup {
+    double chopperOpening{0.};
+    double chopperPairDistance{0.};
+    double chopperPeriod{0.};
+    double chopperRadius{0.};
+    double detectorResolution{0.};
+    size_t foregroundStart{0};
+    size_t foregroundEnd{0};
+    size_t directForegroundStart{0};
+    size_t directForegroundEnd{0};
+    double l1{0.};
+    double l2{0.};
+    double pixelSize{0.};
+    bool polarized{false};
+    double slit1Slit2Distance{0.};
+    double slit1Size{0.};
+    double slit1SizeDirectBeam{0.};
+    double slit2SampleDistance{0.};
+    double slit2Size{0.};
+    double slit2SizeDirectBeam{0.};
+    SumType sumType{SumType::LAMBDA};
+    double tofChannelWidth{0.};
+  };
+  void init() override;
+  void exec() override;
+  double angularResolutionSquared(API::MatrixWorkspace_sptr &ws,
+                                  const API::MatrixWorkspace &directWS,
+                                  const size_t wsIndex, const Setup &setup,
+                                  const double beamFWHM,
+                                  const double directBeamFWHM,
+                                  const double incidentFWHM,
+                                  const double slit1FWHM);
+  double beamRMSVariation(API::MatrixWorkspace_sptr &ws, const size_t start,
+                          const size_t end);
+  void convertToMomentumTransfer(API::MatrixWorkspace_sptr &ws);
+  double detectorAngularResolution(const API::MatrixWorkspace &ws,
+                                   const size_t wsIndex, const Setup &setup,
+                                   const double incidentFWHM);
+  const Setup createSetup(const API::MatrixWorkspace &ws,
+                          const API::MatrixWorkspace &directWS);
+  double incidentAngularSpread(const Setup &setup);
+  double interslitDistance(const API::MatrixWorkspace &ws);
+  double sampleWaviness(API::MatrixWorkspace_sptr &ws,
+                        const API::MatrixWorkspace &directWS,
+                        const size_t wsIndex, const Setup &setup,
+                        const double beamFWHM, const double directBeamFWHM,
+                        const double incidentFWHM);
+  double slit1AngularSpread(const Setup &setup);
+  double slit2AngularSpread(const API::MatrixWorkspace &ws,
+                            const size_t wsIndex, const Setup &setup);
+  double slitSize(const API::MatrixWorkspace &ws, const std::string &logEntry);
+  double wavelengthResolutionSquared(const API::MatrixWorkspace &ws,
+                                     const size_t wsIndex, const Setup &setup,
+                                     const double wavelength);
+};
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif /* MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFER_H_ */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h
deleted file mode 100644
index 0a0c6854d40826e5b7cd823d1b79b7a9510333ee..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_
-#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_
-
-#include "MantidKernel/System.h"
-#include "MantidAlgorithms/DllConfig.h"
-#include "MantidAPI/MatrixWorkspace_fwd.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidAlgorithms/ReflectometryWorkflowBase.h"
-
-namespace Mantid {
-namespace Algorithms {
-
-/** ReflectometryReductionOne : Reflectometry reduction of a single input TOF
- workspace to an IvsQ workspace.
-
- Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
- National Laboratory & European Spallation Source
-
- This file is part of Mantid.
-
- Mantid is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- Mantid is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
- File change history is stored at: <https://github.com/mantidproject/mantid>
- Code Documentation is available at: <http://doxygen.mantidproject.org>
- */
-class DLLExport ReflectometryReductionOne : public ReflectometryWorkflowBase {
-public:
-  const std::string name() const override;
-  /// Summary of algorithms purpose
-  const std::string summary() const override {
-    return "Reduces a single TOF/Lambda reflectometry run into a mod Q vs I/I0 "
-           "workspace. Performs transmission corrections.";
-  }
-
-  int version() const override;
-  const std::string category() const override;
-
-  /// Convert to an IvsQ workspace. Performs detector positional corrections
-  /// based on the component name and the theta value.
-  Mantid::API::MatrixWorkspace_sptr toIvsQ(API::MatrixWorkspace_sptr &toConvert,
-                                           const bool bCorrectPosition,
-                                           OptionalDouble &thetaInDeg,
-                                           const bool isPointDetector);
-
-private:
-  /** Overridden Algorithm methods **/
-
-  void init() override;
-
-  void exec() override;
-
-  /// Get the surface sample component
-  Mantid::Geometry::IComponent_const_sptr
-  getSurfaceSampleComponent(Mantid::Geometry::Instrument_const_sptr inst);
-
-  /// Get the detector component
-  Mantid::Geometry::IComponent_const_sptr
-  getDetectorComponent(Mantid::Geometry::Instrument_const_sptr inst,
-                       const bool isPointDetector);
-
-  /// Correct detector positions.
-  API::MatrixWorkspace_sptr
-  correctPosition(API::MatrixWorkspace_sptr &toCorrect,
-                  const double &thetaInDeg, const bool isPointDetector);
-
-  /// Perform a transmission correction on the input IvsLam workspace
-  API::MatrixWorkspace_sptr transmissonCorrection(
-      API::MatrixWorkspace_sptr IvsLam, const MinMax &wavelengthInterval,
-      const OptionalMinMax &wavelengthMonitorBackgroundInterval,
-      const OptionalMinMax &wavelengthMonitorIntegrationInterval,
-      const OptionalInteger &i0MonitorIndex,
-      API::MatrixWorkspace_sptr firstTransmissionRun,
-      OptionalMatrixWorkspace_sptr secondTransmissionRun,
-      const OptionalDouble &stitchingStart,
-      const OptionalDouble &stitchingDelta, const OptionalDouble &stitchingEnd,
-      const OptionalDouble &stitchingStartOverlap,
-      const OptionalDouble &stitchingEndOverlap,
-      const std::string &numeratorProcessingCommands);
-
-  /// Perform transmission correction using either PolynomialCorrection
-  /// or ExponentialCorrection.
-  API::MatrixWorkspace_sptr
-  algorithmicCorrection(API::MatrixWorkspace_sptr IvsLam);
-
-  /// Verify spectrum maps
-  void verifySpectrumMaps(API::MatrixWorkspace_const_sptr ws1,
-                          API::MatrixWorkspace_const_sptr ws2,
-                          const bool severe = false);
-  /// returns angle for source rotation
-  double getAngleForSourceRotation(API::MatrixWorkspace_sptr toConvert,
-                                   double thetaOut);
-};
-
-} // namespace Algorithms
-} // namespace Mantid
-
-#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_ */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h
index 49a8f680da0f60ef7bbbee69bdc303e11b73c018..d947f14b6381a0561b867d645542233ef62dfe35 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h
@@ -56,6 +56,9 @@ public:
   }
   /// Algorithm's version for identification.
   int version() const override { return 2; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReflectometryReductionOneAuto"};
+  }
   /// Algorithm's category for identification.
   const std::string category() const override { return "Reflectometry"; };
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
deleted file mode 100644
index 5b84f40d83371650a724a21303f6dbd34a8bdb05..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_
-#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_
-
-#include "MantidAPI/Algorithm.h"
-#include "MantidAPI/DataProcessorAlgorithm.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
-#include "MantidKernel/System.h"
-
-#include <boost/optional.hpp>
-
-namespace Mantid {
-namespace Algorithms {
-
-/** ReflectometryReductionOneAuto : Algorithm to run ReflectometryReductionOne,
-attempting to pick instrument parameters for
- * missing properties.
-
-Copyright &copy; 2014 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-class DLLExport ReflectometryReductionOneAuto
-    : public API::DataProcessorAlgorithm {
-public:
-  const std::string name() const override;
-  int version() const override;
-  const std::string category() const override;
-  const std::string summary() const override;
-
-  // For (multiperiod) workspace groups
-  bool checkGroups() override;
-  bool processGroups() override;
-
-private:
-  void init() override;
-  void exec() override;
-  template <typename T> boost::optional<T> isSet(std::string propName) const;
-  Mantid::API::Workspace_sptr
-  sumOverTransmissionGroup(Mantid::API::WorkspaceGroup_sptr &transGroup);
-
-  std::string pNRLabel() const { return "PNR"; }
-  std::string pALabel() const { return "PA"; }
-  std::string crhoLabel() const { return "CRho"; }
-  std::string cppLabel() const { return "CPp"; }
-  std::string cAlphaLabel() const { return "CAlpha"; }
-  std::string cApLabel() const { return "CAp"; }
-  std::string noPolarizationCorrectionMode() const { return "None"; }
-};
-
-} // namespace Algorithms
-} // namespace Mantid
-
-#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_ */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h
index dddab606aeaacc25ae2bb1059c2259cc3163112b..6cca5e217006f13101bf89d05de85ca7ad2cf764 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h
@@ -36,6 +36,9 @@ class DLLExport ReflectometryReductionOneAuto2
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReflectometryReductionOne"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h b/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h
index a301f7c678caac0359c55a1efa977069a6ede356..9818529a54a9b3e3291d99469c722e85c4e76eee 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h
@@ -60,6 +60,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Rebin"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Rebin"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h
index 79fa181b28f224c50297b7bdd67132bf0f538ffe..d208dbfa4451d45a8398077e137d814c0298ff45 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h
@@ -71,6 +71,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CropWorkspace"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Transforms\\Splitting";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h
index 7ab51404be3088ff5e2a128d3faac92c7a795845..21769da0facb552071b2646d032c5bee4b5b5bc6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h
@@ -59,6 +59,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Muon"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h
index 95d106f840ebd5416081e928a1790b0b4d3c3473..2a1f98e0a90b2ca4cc7c370204f3e264d49b7db2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h
@@ -34,6 +34,9 @@ class DLLExport RemoveMaskedSpectra : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractUnmaskedSpectra"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h
index 5c2e4ffaa0197583288fb557bd597ad45fc8ad93..cde17cd34f02db2de43d7574e38ca8ca3a447c5a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h
@@ -38,6 +38,9 @@ public:
   const std::string name() const override;
   const std::string summary() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Comment"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h
index fcde2879ca7e806c156052801f926bd8ff3b8bf5..324819fb3e1f03895f7883b0dfbb30eb6495e7e1 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"RenameWorkspaces"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Utility\\Workspaces"; }
   /// Check that input params are valid
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h
index 59e5f4f39e0e88d2d467ca7a494def39c224306f..052e3e015760631e6a88c089a6d780708b49f5e2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"RenameWorkspace"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h b/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h
index ec56de62ac3e1d6ce808dfb0f627cf400f43041e..4a9d517a0782bc6b98e2a8edf9e24ef249126f9f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h
@@ -37,6 +37,10 @@ class DLLExport ResampleX : public Algorithms::Rebin {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RebinToWorkspace", "Rebin2D",           "Rebunch",
+            "Regroup",          "RebinByPulseTimes", "RebinByTimeAtSample"};
+  }
   const std::string category() const override;
   const std::string alias() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h b/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h
index 1d4e8b3d43fffbf854d6daf6d7816e67ca6fbafc..c3def823b2d1c3aac682345b9cbf569781beacb2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ModifyDetectorDotDatFile"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h
index e5a96681c94f9c219c4fda3a88adc5f64ed331d6..7e0be63d5420e9c41ba38992375a9ff0d48a0c34 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h
@@ -47,6 +47,9 @@ public:
   }
 
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LineProfile"};
+  }
   const std::string category() const override {
     return "Transforms\\Grouping";
   };
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h
index 7093a030439be1cc9dd394771052b7b2cbbb0d51..3b2e9a7eebcc2d1e217af5a965b036efef6f9b08 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h
@@ -64,6 +64,7 @@ private:
   std::string m_instrumentName;
   bool m_isHistogramData;
   bool m_isScanning;
+  std::vector<bool> m_hasDx;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h
index 6863ce49bdf7296f15f47af21dcc8c4fcb549edd..babc0ee6c3b07d81b64a99c9fd75c397f4cbee1e 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h
@@ -86,8 +86,8 @@ public:
 private:
   Kernel::Logger &m_logger;
 
-  typedef std::pair<std::string, MergeLogType> SampleLogsKey;
-  typedef std::map<SampleLogsKey, SampleLogBehaviour> SampleLogsMap;
+  using SampleLogsKey = std::pair<std::string, MergeLogType>;
+  using SampleLogsMap = std::map<SampleLogsKey, SampleLogBehaviour>;
   SampleLogsMap m_logMap;
   std::vector<std::shared_ptr<Kernel::Property>> m_addeeLogMap;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h
index 9d336dc788650a1714a71adfae24b5d4f18b746a..19719ae48c055eb4b7f33bc770d7c4225719cec8 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h
@@ -39,6 +39,9 @@ public:
   int version() const override;
   const std::string category() const override;
   const std::string summary() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MonteCarloAbsorption", "MultipleScatteringCylinderAbsorption"};
+  }
 
 private:
   void init() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h b/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h
index e1b131edc2cbb04e8900055e6d7b79a6b20fbcaa..254c77abb8be5520e019472d048448eae3f14142 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h
@@ -47,6 +47,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "MaxEnt", "RealFFT",
+            "FFTSmooth"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic\\FFT"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Scale.h b/Framework/Algorithms/inc/MantidAlgorithms/Scale.h
index 5c451b14fcb7b6895775c1e3e2c7f039f50c2ce8..f87b8a15d9cb62857babdad4b908cd03e96e5640 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Scale.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Scale.h
@@ -55,6 +55,7 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"ScaleX"}; }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Arithmetic;CorrectionFunctions";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
index f1ea4fa1da59fd253e59bb028009aac2c0e413e9..82c1995077e284a857000f031c963fd14792d388 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ChangeBinOffset", "Scale"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Arithmetic;CorrectionFunctions";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h b/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h
index 316649738e8fdb9136f4a3a85c015768c5a88260..ec65580bc127e1bb7198d7c5b8cbf72d060eb361 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h
@@ -46,6 +46,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"RotateInstrumentComponent", "MoveInstrumentComponent"};
+  }
   const std::string category() const override;
   std::map<std::string, std::string> validateInputs() override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h b/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h
index 8b233e6439095cb5159d570e0263c473bb81240e..eff5195d540a13a0854bda1022f5e2767e7693ca 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h
@@ -36,6 +36,9 @@ class DLLExport ShiftLogTime : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateLogTimeCorrection", "ChangePulsetime", "ChangeLogTime"};
+  }
   const std::string category() const override;
 
   /// Summary of algorithms purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h
index b8c0717991bab7be5bfe610ba5d72622c59db342..851e655056075e7584f2b7443fa480e9025ca98c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h
@@ -63,6 +63,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SmoothNeighbours"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Transforms\\Smoothing";
@@ -75,8 +78,8 @@ private:
   void exec() override;
   int validateSpectrumInGroup(size_t wi);
   // This map does not need to be ordered, just a lookup for udet
-  /// typedef for the storage of the UDET-group mapping
-  typedef std::map<detid_t, int> udet2groupmap;
+  /// type alias for the storage of the UDET-group mapping
+  using udet2groupmap = std::map<detid_t, int>;
   std::vector<int> udet2group;
   API::MatrixWorkspace_const_sptr inputWorkspace;
 };
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h
index 0417d77a594f9ff5391f719f23deef89198070dc..4c9c7781fb160df162546e0c3b407e332f6e17a5 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h
@@ -12,7 +12,7 @@
 
 namespace Mantid {
 namespace Algorithms {
-typedef std::map<specnum_t, Mantid::Kernel::V3D> SpectraDistanceMap;
+using SpectraDistanceMap = std::map<specnum_t, Mantid::Kernel::V3D>;
 
 /*
 Filters spectra detector list by radius.
@@ -92,6 +92,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SmoothData"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Transforms\\Smoothing";
@@ -149,7 +152,7 @@ private:
   Mantid::API::MatrixWorkspace_sptr inWS;
 
   /// Each neighbours is specified as a pair with workspace index, weight.
-  typedef std::pair<size_t, double> weightedNeighbour;
+  using weightedNeighbour = std::pair<size_t, double>;
 
   /// Vector of list of neighbours (with weight) for each workspace index.
   std::vector<std::vector<weightedNeighbour>> m_neighbours;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQCommon.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQCommon.h
index 9af665db2acaeb26f7797c05c906e806f89b3c8f..fe237d1ba455ccb159c3b9da03c045b042c164a3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SofQCommon.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQCommon.h
@@ -4,12 +4,12 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidGeometry/IDetector.h"
-// Two small routines used by all SofQW algorithms intended to provide united
+// Routines used by all SofQW algorithms intended to provide united
 // user interface to all SofQ algorihtms.
 namespace Mantid {
 namespace Algorithms {
 
-struct SofQCommon {
+struct DLLExport SofQCommon {
 
   /// E Mode
   int m_emode;
@@ -26,6 +26,26 @@ struct SofQCommon {
 
   /// Get the efixed value for the given detector
   double getEFixed(const Geometry::IDetector &det) const;
+
+  /// Calculate the Q value
+  double q(const double deltaE, const double twoTheta,
+           const Geometry::IDetector *det) const;
+
+  /// Estimate minimum and maximum momentum transfer.
+  std::pair<double, double> qBinHints(const API::MatrixWorkspace &ws,
+                                      const double minE,
+                                      const double maxE) const;
+
+private:
+  double directQ(const double deltaE, const double twoTheta) const;
+  double indirectQ(const double deltaE, const double twoTheta,
+                   const Geometry::IDetector *det) const;
+  std::pair<double, double> qBinHintsDirect(const API::MatrixWorkspace &ws,
+                                            const double minE,
+                                            const double maxE) const;
+  std::pair<double, double> qBinHintsIndirect(const API::MatrixWorkspace &ws,
+                                              const double minE,
+                                              const double maxE) const;
 };
 }
 }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h
index 2326fc7fb2b37ce8293f76ca4e4bf3fde87f5580..614ac829ee0db6b6a6a84a0929dba820b324ab93 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h
@@ -5,7 +5,13 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/DataProcessorAlgorithm.h"
+
 #include "MantidAlgorithms/SofQCommon.h"
+#include "MantidAPI/BinEdgeAxis.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidKernel/UnitFactory.h"
+#include "MantidKernel/VectorHelper.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -48,6 +54,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 File change history is stored at: <https://github.com/mantidproject/mantid>
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
+
+struct SofQCommon;
+
 class DLLExport SofQW : public API::DataProcessorAlgorithm {
 public:
   /// Algorithm's name
@@ -57,28 +66,96 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SofQWCentre", "SofQWPolygon", "SofQWNormalisedPolygon", "Rebin2D"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Inelastic\\SofQW"; }
   /// Create the output workspace
-  static API::MatrixWorkspace_sptr
-  setUpOutputWorkspace(const API::MatrixWorkspace_const_sptr &inputWorkspace,
-                       const std::vector<double> &qbinParams,
-                       std::vector<double> &qAxis,
-                       const std::vector<double> &ebinParams);
+  template <typename Workspace>
+  static std::unique_ptr<Workspace> setUpOutputWorkspace(
+      const API::MatrixWorkspace &inputWorkspace,
+      const std::vector<double> &qbinParams, std::vector<double> &qAxis,
+      const std::vector<double> &ebinParams, const SofQCommon &emodeProperties);
   /// Create the input properties on the given algorithm object
   static void createCommonInputProperties(API::Algorithm &alg);
-  /// Energy to K constant
-  static double energyToK();
 
 private:
   /// Initialization code
   void init() override;
   /// Execution code
   void exec() override;
-
-  SofQCommon m_EmodeProperties;
 };
 
+/** Creates the output workspace, setting the axes according to the input
+ * binning parameters
+ *  @tparam     Workspace The type of the workspace to create
+ *  @param[in]  inputWorkspace The input workspace
+ *  @param[in]  qbinParams The q-bin parameters from the user
+ *  @param[out] qAxis The 'vertical' (q) axis defined by the given parameters
+ *  @param[out] ebinParams The 'horizontal' (energy) axis parameters (optional)
+ *  @param[in]  emodeProperties The initialized SofQCommon object corresponding
+ *              to the input workspace and calling algorithm
+ *  @return A pointer to the newly-created workspace
+ */
+template <typename Workspace>
+std::unique_ptr<Workspace> SofQW::setUpOutputWorkspace(
+    const API::MatrixWorkspace &inputWorkspace,
+    const std::vector<double> &qbinParams, std::vector<double> &qAxis,
+    const std::vector<double> &ebinParams, const SofQCommon &emodeProperties) {
+  using Kernel::VectorHelper::createAxisFromRebinParams;
+  // Create vector to hold the new X axis values
+  HistogramData::BinEdges xAxis(0);
+  double eMin{std::nan("")};
+  double eMax{std::nan("")};
+  if (ebinParams.empty()) {
+    xAxis = inputWorkspace.binEdges(0);
+  } else if (ebinParams.size() == 1) {
+    inputWorkspace.getXMinMax(eMin, eMax);
+    createAxisFromRebinParams(ebinParams, xAxis.mutableRawData(), true, true,
+                              eMin, eMax);
+  } else {
+    createAxisFromRebinParams(ebinParams, xAxis.mutableRawData());
+  }
+  // Create a vector to temporarily hold the vertical ('y') axis and populate
+  // that
+  int yLength;
+  if (qbinParams.size() == 1) {
+    if (std::isnan(eMin)) {
+      inputWorkspace.getXMinMax(eMin, eMax);
+    }
+    double qMin;
+    double qMax;
+    std::tie(qMin, qMax) =
+        emodeProperties.qBinHints(inputWorkspace, eMin, eMax);
+    yLength =
+        createAxisFromRebinParams(qbinParams, qAxis, true, true, qMin, qMax);
+  } else {
+    yLength = createAxisFromRebinParams(qbinParams, qAxis);
+  }
+
+  // Create output workspace, bin edges are same as in inputWorkspace index 0
+  auto outputWorkspace =
+      DataObjects::create<Workspace>(inputWorkspace, yLength - 1, xAxis);
+
+  // Create a binned numeric axis to replace the default vertical one
+  API::Axis *const verticalAxis = new API::BinEdgeAxis(qAxis);
+  outputWorkspace->replaceAxis(1, verticalAxis);
+
+  // Set the axis units
+  verticalAxis->unit() =
+      Kernel::UnitFactory::Instance().create("MomentumTransfer");
+  verticalAxis->title() = "|Q|";
+
+  // Set the X axis title (for conversion to MD)
+  outputWorkspace->getAxis(0)->title() = "Energy transfer";
+
+  outputWorkspace->setYUnit("");
+  outputWorkspace->setYUnitLabel("Intensity");
+
+  return outputWorkspace;
+}
+
 } // namespace Algorithms
 } // namespace Mantid
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h
index f850e0d0329099d4d79859534889cccd6c6b1e08..d191545c1bbb0686f56a84dd7410c76057d6a9a3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h
@@ -62,23 +62,16 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SofQW", "Rebin2D"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Inelastic\\SofQW"; }
-  /// Create the output workspace
-  static API::MatrixWorkspace_sptr
-  setUpOutputWorkspace(API::MatrixWorkspace_const_sptr inputWorkspace,
-                       const std::vector<double> &binParams,
-                       std::vector<double> &newAxis,
-                       const std::vector<double> &ebinParams);
-  /// Convert the workspace to a distribution
-  void makeDistribution(API::MatrixWorkspace_sptr outputWS,
-                        const std::vector<double> qAxis);
-  /// Create the input properties on the given algorithm object
-  static void createInputProperties(API::Algorithm &alg);
-  /// Energy to K constant
-  static double energyToK();
 
 private:
+  /// Convert the workspace to a distribution
+  static void makeDistribution(API::MatrixWorkspace &outputWS,
+                               const std::vector<double> &qAxis);
   /// Initialization code
   void init() override;
   /// Execution code
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h
index e3a4a37bb9a2cf7b74136e77c18b71ba3d722683..336502330594d513892e7799ccde9c596366c5b4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h
@@ -4,10 +4,6 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAlgorithms/Rebin2D.h"
-#include "MantidGeometry/Math/Quadrilateral.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidDataObjects/RebinnedOutput.h"
-#include <list>
 #include "MantidAlgorithms/SofQCommon.h"
 
 namespace Mantid {
@@ -59,7 +55,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class DLLExport SofQWNormalisedPolygon : public Rebin2D {
 public:
   /// Default constructor
-  SofQWNormalisedPolygon();
+  SofQWNormalisedPolygon() = default;
   /// Algorithm's name for identification
   const std::string name() const override;
   const std::string alias() const override { return "SofQW3"; }
@@ -71,6 +67,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SofQW", "SofQWPolygon", "Rebin2D"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override;
 
@@ -80,29 +79,15 @@ private:
   /// Run the algorithm
   void exec() override;
 
-  /// Calculate the Q value for given conditions.
-  double calculateQ(const double efixed, const int emode, const double deltaE,
-                    const double twoTheta, const double azimuthal) const;
-  /// Init variables cache base on the given workspace
-  void initCachedValues(const API::MatrixWorkspace_const_sptr &workspace);
   /// Init the theta index
   void
   initAngularCachesNonPSD(const API::MatrixWorkspace_const_sptr &workspace);
   /// Get angles and calculate angular widths.
   void initAngularCachesPSD(const API::MatrixWorkspace_const_sptr &workspace);
 
-  /// Create the output workspace
-  DataObjects::RebinnedOutput_sptr
-  setUpOutputWorkspace(const API::MatrixWorkspace &inputWorkspace,
-                       const std::vector<double> &qbinParams,
-                       std::vector<double> &qAxis,
-                       const std::vector<double> &ebinParams);
-
   SofQCommon m_EmodeProperties;
   /// Output Q axis
   std::vector<double> m_Qout;
-  /// Single value theta width
-  double m_thetaWidth;
   /// Array for the two theta angles
   std::vector<double> m_theta;
   /// Array for the azimuthal angles
@@ -112,7 +97,7 @@ private:
   /// Array for the azimuthal widths
   std::vector<double> m_phiWidths;
   /// Offset for finding neighbor in nearest tube
-  int m_detNeighbourOffset;
+  int m_detNeighbourOffset{-1};
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h
index 250dd2cc982abde0737101181198ee2d684bb8ed..1d26d550c4a73786d8f4e34d742a6c7e94e253cf 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h
@@ -5,8 +5,6 @@
 //----------------------------------------------------------------------
 #include "MantidAlgorithms/SofQCommon.h"
 #include "MantidAlgorithms/Rebin2D.h"
-#include "MantidGeometry/Math/Quadrilateral.h"
-#include "MantidGeometry/IDetector.h"
 #include <list>
 
 namespace Mantid {
@@ -71,6 +69,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SofQW", "SofQWNormalisedPolygon", "Rebin2D"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Inelastic\\SofQW"; }
 
@@ -79,19 +80,12 @@ private:
   void init() override;
   /// Run the algorithm
   void exec() override;
-  /// Calculate the Q value for a direct instrument
-  double calculateDirectQ(const double efixed, const double deltaE,
-                          const double twoTheta, const double psi) const;
-  /// Calculate the Q value for an indirect instrument
-  double calculateIndirectQ(const double efixed, const double deltaE,
-                            const double twoTheta, const double psi) const;
   /// Init variables cache base on the given workspace
   void initCachedValues(API::MatrixWorkspace_const_sptr workspace);
   /// Init the theta index
   void initThetaCache(const API::MatrixWorkspace &workspace);
 
   SofQCommon m_EmodeProperties;
-  //---------------------------------------------------------------------------------
   /// Output Q axis
   std::vector<double> m_Qout;
   /// Input theta points
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h b/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h
index 18553ffd1bdbd83d506d92d6014972b54cbaaaa7..1538828b14863dc9efca9589a6409c8d28c46f53 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h
@@ -57,6 +57,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Divide"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\InstrumentCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h b/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h
index 9401200dad195a49a800b07a538c1dc488185eb7..757f1bd48ad427ae075558884a1841ab40d67fdc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Events;Utility\\Sorting";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h b/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h
index 3171b7d784d40c6246a05de736583e709108b42f..298627ace522469244953a2cb5b821a77e0d9e12 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GroupDetectors"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Grouping"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h b/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h
index 4b8ebfaa3b7c018a25a1d618fc941c1a602884db..c270d52d3a16de2da7f084877ea60518ddd1d54a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h
@@ -3,10 +3,10 @@
 
 #include <tuple>
 
-#include "MantidKernel/IndexSet.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAlgorithms/DllConfig.h"
+#include "MantidKernel/IndexSet.h"
 
 namespace Mantid {
 
@@ -56,14 +56,14 @@ private:
    *
    * Used for generating a sequence 0,1,2,.... for extracting arguments from
    * tuple. */
-  template <int...> struct seq {};
+  template <std::size_t...> struct seq {};
   // Doxygen does not like recursive types.
-  template <int N, int... S>
+  template <std::size_t N, std::size_t... S>
   struct gens                                     /** @cond */
       : gens<N - 1, N - 1, S...> /** @endcond */ {/** @cond */
   };
-  template <int... S> struct gens<0, S...> {/** @endcond */
-    typedef seq<S...> type;
+  template <std::size_t... S> struct gens<0, S...> {/** @endcond */
+    using type = seq<S...>;
   };
 
   /** Helpers for for_each(), struct contains and 2 specializations.
@@ -78,7 +78,7 @@ private:
   template <typename Tp> struct contains<Tp> : std::false_type {};
 
   /// Internal implementation of for_each().
-  template <class... Flags, class WS, class T, int... S, class OP>
+  template <class... Flags, class WS, class T, std::size_t... S, class OP>
   void for_each(WS &workspace, T getters, seq<S...>, const OP &operation) {
     // If we get the flag Indices::FromProperty we use a potential user-defined
     // range property, otherwise default to the full range of all histograms.
@@ -169,7 +169,7 @@ void SpectrumAlgorithm::ifEventWorkspaceClearMRU(
     const DataObjects::EventWorkspace &workspace);
 
 /// Typedef for a shared pointer to a SpectrumAlgorithm
-typedef boost::shared_ptr<SpectrumAlgorithm> SpectrumAlgorithm_sptr;
+using SpectrumAlgorithm_sptr = boost::shared_ptr<SpectrumAlgorithm>;
 
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h
index f42949c5a556d6a9941825ea728003e3d55e071a..b19f06488580088dfa9d8265309e2fa0e1460b05 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SpecularReflectionPositionCorrect"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h
index e015c4d451ae3e334da49534a59faf3f8fd3fb98..850bcd3b154302c8a33133d47b3231e452f7f344 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h
@@ -38,6 +38,9 @@ public:
   const std::string summary() const override;
   /// Version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SpecularReflectionCalculateTheta"};
+  }
   /// Category
   const std::string category() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h
index 84431eefc0ea8ef28d899250434850d888b60ba4..273c57b45b377243fc73e1b19ddbf0710b1beee6 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h
@@ -96,6 +96,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
 
 protected:
   API::MatrixWorkspace_sptr m_inputWS;     ///< A pointer to the input workspace
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h
index a11a01e463b5584b5ee45f701cd48c836cc0bc79..28d040083b0c027238ef87b6f48d0f07376289cd 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h
@@ -43,13 +43,16 @@ public:
   const std::string summary() const override {
     return "Stitches single histogram matrix workspaces together";
   }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Stitch1DMany"};
+  }
   /// Does the x-axis have non-zero errors
   bool hasNonzeroErrors(Mantid::API::MatrixWorkspace_sptr ws);
 
 private:
   /// Helper typedef. For storing indexes of special values per spectra per
   /// workspace.
-  typedef std::vector<std::vector<size_t>> SpecialTypeIndexes;
+  using SpecialTypeIndexes = std::vector<std::vector<size_t>>;
   /// Overwrites Algorithm method.
   void init() override;
   /// Overwrites Algorithm method.
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h
index 47761af10a6e545b7624ee3737c10a10d62c653a..d0008c838cd6bf7987ec327774291b144a9ef9d2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h
@@ -38,6 +38,9 @@ public:
   const std::string name() const override { return "Stitch1DMany"; }
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Stitch1D"};
+  }
   /// Algorithm's category for identification. @see Algorithm::category
   const std::string category() const override { return "Reflectometry"; }
   /// Summary of algorithm's purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h
index aea54a092d9a594203e67038b0910e8d009f29c4..e1239529cc27f591028dffa361c7d0889ae0f74e 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h
@@ -63,6 +63,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindPeaks", "StripVanadiumPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\PeakCorrections;Optimization\\PeakFinding";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h b/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h
index da5ac35ef604e883add0d998da14deaa12591e09..b180b29dc9218b25e1a508e2c3efc37c727aa33b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h
@@ -39,6 +39,9 @@ public:
   const std::string name() const override { return "StripVanadiumPeaks"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindPeaks", "StripPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "CorrectionFunctions\\PeakCorrections;Optimization\\PeakFinding;"
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h
index 12d4de12a8e3759960f0a25b2f58230117cda933..dc6aeeb2f98b2fa958dbe965284f8d3e0de2266a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h
@@ -43,6 +43,9 @@ public:
   const std::string name() const override { return "SumEventsByLogValue"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FilterByLogValue"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Events"; }
   /// Summary of algorithms purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h b/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h
index 2f91f202760f6e43cf3e5dbfee719fcc39c4f87e..c8686555f233ce57ca883292877c272eb6f9d634 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h
@@ -55,6 +55,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SumSpectra", "SumRowColumn"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Grouping"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h b/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h
index 17115c98e2e2f0116e00c41b3985554f5fc5b81a..08b79627cb4f144b3be749c49b02d0564898876a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h
@@ -4,7 +4,10 @@
 #include "MantidAlgorithms/DllConfig.h"
 
 #include "MantidAPI/Algorithm.h"
-#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/Progress.h"
+
+#include <list>
 
 namespace Mantid {
 namespace Algorithms {
@@ -45,6 +48,9 @@ public:
            "supported.";
   }
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SumSpectra"};
+  }
 
 private:
   void init() override;
@@ -72,7 +78,9 @@ private:
 
   double distanceFromAngle(const int angleIndex, const double angle) const;
 
-  int m_mirrorDetectors;
+  int m_mirrorDetectors; /// holds the sign flipper for 2theta
+
+  std::unique_ptr<API::Progress> m_progress;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h b/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h
index b0f4e1c2a2d3a41b72facfeac2c8cff569ba02f0..a718e8722144b91a243ba5d6c0815c5697d8e2d2 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h
@@ -74,6 +74,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SumSpectra", "SumNeighbours"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "SANS;Transforms\\Grouping";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
index 16d6b3cb000610a6689d3a72c78f2e616f1d6313..98d0b97d42809ad79b4ff4bb1633848dea1c7eca 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
@@ -65,8 +65,13 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SumNeighbours"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Grouping"; }
+  /// Cross-input validation
+  std::map<std::string, std::string> validateInputs() override;
 
 private:
   /// Handle logic for RebinnedOutput workspaces
@@ -80,7 +85,6 @@ private:
 
   // Overridden Algorithm methods
   void init() override;
-  std::map<std::string, std::string> validateInputs() override;
   void exec() override;
   void execEvent(API::MatrixWorkspace_sptr outputWorkspace,
                  API::Progress &progress, size_t &numSpectra, size_t &numMasked,
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h
index 101fda8c0b0175a0b8aacbd99a8868c6fdce2c0a..1079f291e9f87848c2b36da59baa61d09b0b2cd3 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h
@@ -46,6 +46,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"TOFSANSResolutionByPixel"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h
index f30e41a307e3a58af4af8f597b8dde4f5f09af30..107c9e7f2d56d324150eb03eb5c418c73996a301 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h
@@ -30,6 +30,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"TOFSANSResolution"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "SANS"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h b/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h
index dd5678552f5a6aca225a8571dfc18a5f53fb9d5d..5e9c8f42af954fdc1feea888df4fdbcc503b7bd9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h
@@ -57,6 +57,10 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Transpose3D", "TransposeMD", "ConvertUnits", "ConvertSpectrumAxis",
+            "ConvertAxesToRealSpace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Transforms\\Axes"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h
index 1dce4cfb17114184a71d37cd5f46cbc04b9fca9c..756753c15353b756b8e42bb5a3669353897a9436 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"GroupWorkspaces"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Transforms\\Grouping;Utility\\Workspaces";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
index 15645cf61399d617a3a6a693180ba8233cfaf630..83c3747b8defefd594f7a7b44785251229831919 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
@@ -61,6 +61,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"UnwrapMonitorsInTOF", "UnwrapSNS"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "CorrectionFunctions\\InstrumentCorrections";
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h
index 25382da7a800d27c809236b4e56a1b09dba370a0..b8ccd3b95339108c4a473cb0da252fd1e872de8d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h
@@ -38,6 +38,9 @@ class MANTID_ALGORITHMS_DLL UnwrapMonitorsInTOF : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"UnwrapMonitor", "UnwrapSNS"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
index a2fa09ad8fda193d2b10575a3abcdea95b5f30e9..51d555418235a8ead93763737a79c74d49bf9fea 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
@@ -60,6 +60,7 @@ public:
   }
 
   int version() const override { return 1; }
+
   const std::string category() const override {
     return "CorrectionFunctions\\InstrumentCorrections";
   }
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h b/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h
index 8fe8749094d8bdb276eeca9e64cd078c4c8d9be2..d3cc774266662034fcc379e23018fc37d8103999 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"DownloadInstrument"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/VesuvioL1ThetaResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/VesuvioL1ThetaResolution.h
index fe50065651b4391505ad172f52a783eb9a34785d..47724e868248153458eabe8650d251dd30737696 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/VesuvioL1ThetaResolution.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/VesuvioL1ThetaResolution.h
@@ -6,8 +6,6 @@
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/IComponent.h"
 
-#include <boost/random/mersenne_twister.hpp>
-
 namespace Mantid {
 namespace Algorithms {
 
@@ -49,20 +47,18 @@ private:
   void loadInstrument();
 
   void calculateDetector(const Mantid::Geometry::IDetector &detector,
+                         std::function<double()> &flatRandomVariateGen,
                          std::vector<double> &l1Values,
                          std::vector<double> &thetaValues);
   Mantid::API::MatrixWorkspace_sptr
   processDistribution(Mantid::API::MatrixWorkspace_sptr ws,
                       const double binWidth);
-  double random();
 
   Mantid::API::MatrixWorkspace_sptr m_instWorkspace;
   Mantid::Geometry::IComponent_const_sptr m_sample;
   Mantid::API::MatrixWorkspace_sptr m_outputWorkspace;
   Mantid::API::MatrixWorkspace_sptr m_l1DistributionWs;
   Mantid::API::MatrixWorkspace_sptr m_thetaDistributionWs;
-
-  boost::mt19937 m_generator;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
index fdd1a7a39a150bca603152a7fdcdcf4f85cbbd26..e3872f59bf26293ac0f76318490ce7d22b7432ec 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h
@@ -51,6 +51,7 @@ public:
   }
 
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override { return {"Mean"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Arithmetic"; }
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h
index e61de16ed746b3dcd3cfc6c8824dcad9e002f631..21cfe3befca51fa127892e06f048973757a5dba5 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Mean", "WeightedMean"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h b/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h
index 6390c452d1e153f46c1e664dbfd1eca76b597914..d37bcde93b5b502de6fdabdac05efe441f3828fa 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h
@@ -37,6 +37,9 @@ class DLLExport WienerSmooth : public API::Algorithm {
 public:
   const std::string name() const override { return "WienerSmooth"; }
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FFTSmooth"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h b/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h
index 89030b9cee06fab5de9bb6415a7cd1a66245fd60..dd4cc1b0f358cebe2dad1d666681f5ddaf3242dc 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h
@@ -6,6 +6,7 @@
 
 namespace Mantid {
 namespace HistogramData {
+class HistogramDx;
 class HistogramX;
 }
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/CalculateTransmission.cpp b/Framework/Algorithms/src/CalculateTransmission.cpp
index e1ea669899bebc2e60d9a69199c331c4a56c5611..77feb1f7a8579368babba52f46bd41cc6b17a2d8 100644
--- a/Framework/Algorithms/src/CalculateTransmission.cpp
+++ b/Framework/Algorithms/src/CalculateTransmission.cpp
@@ -265,7 +265,7 @@ CalculateTransmission::extractSpectra(API::MatrixWorkspace_sptr ws,
   // means that lexical_cast cannot be used directly as the call is ambiguous
   // so we need to define a function pointer that can resolve the overloaded
   // lexical_cast function
-  typedef std::string (*from_size_t)(const size_t &);
+  using from_size_t = std::string (*)(const size_t &);
 
   std::transform(
       indices.begin(), indices.end(), indexStrings.begin(),
diff --git a/Framework/Algorithms/src/CompareWorkspaces.cpp b/Framework/Algorithms/src/CompareWorkspaces.cpp
index 5724a852f34bbdbd698a9f73e863f23059a8ed7f..5f3bf5634af90902bb896484413ce08da0fec54d 100644
--- a/Framework/Algorithms/src/CompareWorkspaces.cpp
+++ b/Framework/Algorithms/src/CompareWorkspaces.cpp
@@ -383,7 +383,7 @@ bool CompareWorkspaces::compareEventWorkspaces(
   ews2.sortAll(PULSETIMETOF_SORT, m_progress.get());
 
   if (!m_progress) {
-    throw new std::runtime_error("The progress pointer was found to be null!");
+    throw std::runtime_error("The progress pointer was found to be null!");
   }
 
   // Determine the tolerance for "tof" attribute and "weight" of events
diff --git a/Framework/Algorithms/src/ConjoinXRuns.cpp b/Framework/Algorithms/src/ConjoinXRuns.cpp
index 2fea96c2810fa1c8868ab1ea3d041d4dcbb73628..b9fc326800d0c28120bc9f78085fd9a4785ba6d1 100644
--- a/Framework/Algorithms/src/ConjoinXRuns.cpp
+++ b/Framework/Algorithms/src/ConjoinXRuns.cpp
@@ -10,6 +10,10 @@
 #include "MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h"
 #include "MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidHistogramData/HistogramDx.h"
+#include "MantidHistogramData/HistogramE.h"
+#include "MantidHistogramData/HistogramX.h"
+#include "MantidHistogramData/HistogramY.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/ListValidator.h"
@@ -122,7 +126,7 @@ std::map<std::string, std::string> ConjoinXRuns::validateInputs() {
     } else {
       try {
         ws->blocksize();
-      } catch (std::length_error) {
+      } catch (std::length_error &) {
         issues[INPUT_WORKSPACE_PROPERTY] +=
             "Workspace " + ws->getName() +
             " has different number of points per histogram\n";
@@ -254,8 +258,8 @@ void ConjoinXRuns::fillHistory() {
   if (!isChild()) {
     // Loop over the input workspaces, making the call that copies their
     // history to the output one
-    for (auto inWS = m_inputWS.begin(); inWS != m_inputWS.end(); ++inWS) {
-      m_outWS->history().addHistory((*inWS)->getHistory());
+    for (auto &inWS : m_inputWS) {
+      m_outWS->history().addHistory(inWS->getHistory());
     }
     // Add the history for the current algorithm to the output
     m_outWS->history().addHistory(m_history);
@@ -274,25 +278,31 @@ void ConjoinXRuns::joinSpectrum(int64_t wsIndex) {
   std::vector<double> spectrum;
   std::vector<double> errors;
   std::vector<double> axis;
+  std::vector<double> x;
+  std::vector<double> xerrors;
   spectrum.reserve(m_outWS->blocksize());
   errors.reserve(m_outWS->blocksize());
   axis.reserve(m_outWS->blocksize());
   size_t index = static_cast<size_t>(wsIndex);
-
   for (const auto &input : m_inputWS) {
-    auto y = input->y(index).rawData();
-    auto e = input->e(index).rawData();
-    std::vector<double> x;
+    const auto &y = input->y(index);
+    spectrum.insert(spectrum.end(), y.begin(), y.end());
+    const auto &e = input->e(index);
+    errors.insert(errors.end(), e.begin(), e.end());
     if (m_logEntry.empty()) {
-      x = input->x(index).rawData();
+      const auto &x = input->x(index);
+      axis.insert(axis.end(), x.begin(), x.end());
     } else {
       x = m_axisCache[input->getName()];
+      axis.insert(axis.end(), x.begin(), x.end());
+    }
+    if (input->hasDx(index)) {
+      const auto &dx = input->dx(index);
+      xerrors.insert(xerrors.end(), dx.begin(), dx.end());
     }
-    spectrum.insert(spectrum.end(), y.begin(), y.end());
-    errors.insert(errors.end(), e.begin(), e.end());
-    axis.insert(axis.end(), x.begin(), x.end());
   }
-
+  if (!xerrors.empty())
+    m_outWS->setPointStandardDeviations(index, xerrors);
   m_outWS->mutableY(index) = spectrum;
   m_outWS->mutableE(index) = errors;
   m_outWS->mutableX(index) = axis;
diff --git a/Framework/Algorithms/src/CreateCalFileByNames.cpp b/Framework/Algorithms/src/CreateCalFileByNames.cpp
index c15105423451ab1fb989e6c65e5a96b66763d6f2..dbc4804af45886493d87ba7b4176b8457aea4822 100644
--- a/Framework/Algorithms/src/CreateCalFileByNames.cpp
+++ b/Framework/Algorithms/src/CreateCalFileByNames.cpp
@@ -88,9 +88,9 @@ void CreateCalFileByNames::exec() {
   vgroups.clear();
 
   // Find Detectors that belong to groups
-  typedef boost::shared_ptr<const Geometry::ICompAssembly> sptr_ICompAss;
-  typedef boost::shared_ptr<const Geometry::IComponent> sptr_IComp;
-  typedef boost::shared_ptr<const Geometry::IDetector> sptr_IDet;
+  using sptr_ICompAss = boost::shared_ptr<const Geometry::ICompAssembly>;
+  using sptr_IComp = boost::shared_ptr<const Geometry::IComponent>;
+  using sptr_IDet = boost::shared_ptr<const Geometry::IDetector>;
   std::queue<std::pair<sptr_ICompAss, int>> assemblies;
   sptr_ICompAss current =
       boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(inst);
diff --git a/Framework/Algorithms/src/CreateDummyCalFile.cpp b/Framework/Algorithms/src/CreateDummyCalFile.cpp
index 163b64b8c4ae134b178d9a86a8148e7c44f21274..607310f25805a5cd436e2c7d62590ad7a356841c 100644
--- a/Framework/Algorithms/src/CreateDummyCalFile.cpp
+++ b/Framework/Algorithms/src/CreateDummyCalFile.cpp
@@ -85,9 +85,9 @@ void CreateDummyCalFile::exec() {
   vgroups.clear();
 
   // Find Detectors that belong to groups
-  typedef boost::shared_ptr<const Geometry::ICompAssembly> sptr_ICompAss;
-  typedef boost::shared_ptr<const Geometry::IComponent> sptr_IComp;
-  typedef boost::shared_ptr<const Geometry::IDetector> sptr_IDet;
+  using sptr_ICompAss = boost::shared_ptr<const Geometry::ICompAssembly>;
+  using sptr_IComp = boost::shared_ptr<const Geometry::IComponent>;
+  using sptr_IDet = boost::shared_ptr<const Geometry::IDetector>;
   std::queue<std::pair<sptr_ICompAss, int>> assemblies;
   sptr_ICompAss current =
       boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(inst);
diff --git a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
index fba1465d0357ef3ee12047bc4f9bf95ba7dcae0b..c22d148a5edebddc0e150111c2a54c1ff20d124a 100644
--- a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
@@ -249,9 +249,9 @@ std::map<detid_t, int> makeGroupingByNames(std::string GroupNames,
   // Find Detectors that belong to groups
   if (!group_map.empty()) {
     // Find Detectors that belong to groups
-    typedef boost::shared_ptr<const Geometry::ICompAssembly> sptr_ICompAss;
-    typedef boost::shared_ptr<const Geometry::IComponent> sptr_IComp;
-    typedef boost::shared_ptr<const Geometry::IDetector> sptr_IDet;
+    using sptr_ICompAss = boost::shared_ptr<const Geometry::ICompAssembly>;
+    using sptr_IComp = boost::shared_ptr<const Geometry::IComponent>;
+    using sptr_IDet = boost::shared_ptr<const Geometry::IDetector>;
     std::queue<std::pair<sptr_ICompAss, int>> assemblies;
     sptr_ICompAss current =
         boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(inst);
diff --git a/Framework/Algorithms/src/CreatePSDBleedMask.cpp b/Framework/Algorithms/src/CreatePSDBleedMask.cpp
index 5d6b750f40d43fe0e1a0931c35d4676056c34780..cbbe9f8f9bde7bde09581f199b0aa6423ca4cb5d 100644
--- a/Framework/Algorithms/src/CreatePSDBleedMask.cpp
+++ b/Framework/Algorithms/src/CreatePSDBleedMask.cpp
@@ -94,7 +94,7 @@ void CreatePSDBleedMask::exec() {
   const int numSpectra =
       static_cast<int>(inputWorkspace->getNumberHistograms());
   // Keep track of a map of tubes to lists of indices
-  typedef std::map<Geometry::ComponentID, std::vector<int>> TubeIndex;
+  using TubeIndex = std::map<Geometry::ComponentID, std::vector<int>>;
   TubeIndex tubeMap;
 
   API::Progress progress(this, 0.0, 1.0, numSpectra);
diff --git a/Framework/Algorithms/src/CreateWorkspace.cpp b/Framework/Algorithms/src/CreateWorkspace.cpp
index 768ebe0b2095c84f4bd10ad661262e0f4ea6fcb4..ca572b5f910b21c0137de45514dc418de5316c97 100644
--- a/Framework/Algorithms/src/CreateWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateWorkspace.cpp
@@ -17,7 +17,6 @@
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidIndexing/SpectrumIndexSet.h"
 #include "MantidHistogramData/HistogramBuilder.h"
-#include "MantidTypes/SpectrumDefinition.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -47,7 +46,7 @@ void CreateWorkspace::init() {
   declareProperty(Kernel::make_unique<ArrayProperty<double>>("DataY", required),
                   "Y-axis data values for workspace (measures).");
   declareProperty(make_unique<ArrayProperty<double>>("DataE"),
-                  "Error values for workspace. Optional.");
+                  "Error values for workspace.");
   declareProperty(make_unique<PropertyWithValue<int>>("NSpec", 1),
                   "Number of spectra to divide data into.");
   declareProperty("UnitX", "", "The unit to assign to the XAxis");
@@ -70,6 +69,8 @@ void CreateWorkspace::init() {
                                                    Direction::Input,
                                                    PropertyMode::Optional),
                   "Name of a parent workspace.");
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>("Dx"),
+                  "X error values for workspace (optional).");
   std::vector<std::string> propOptions{
       Parallel::toString(Parallel::StorageMode::Cloned),
       Parallel::toString(Parallel::StorageMode::Distributed),
@@ -102,6 +103,7 @@ void CreateWorkspace::exec() {
   const Property *const dataXprop = getProperty("DataX");
   const Property *const dataYprop = getProperty("DataY");
   const Property *const dataEprop = getProperty("DataE");
+  const Property *const errorDxprop = getProperty("Dx");
 
   const ArrayProperty<double> *pCheck = nullptr;
 
@@ -120,6 +122,11 @@ void CreateWorkspace::exec() {
     throw std::invalid_argument("DataE cannot be casted to a double vector");
   const std::vector<double> &dataE = *pCheck;
 
+  pCheck = dynamic_cast<const ArrayProperty<double> *>(errorDxprop);
+  if (!pCheck)
+    throw std::invalid_argument("Dx cannot be casted to a double vector");
+  const std::vector<double> &dX = *pCheck;
+
   const int nSpec = getProperty("NSpec");
   const std::string xUnit = getProperty("UnitX");
   const std::string vUnit = getProperty("VerticalAxisUnit");
@@ -159,6 +166,13 @@ void CreateWorkspace::exec() {
     histogramBuilder.setX(xSize);
   }
   histogramBuilder.setY(ySize);
+
+  if (!dX.empty()) {
+    if (dX.size() != dataY.size())
+      throw std::runtime_error("Dx must have the same size as DataY");
+    histogramBuilder.setDx(ySize);
+  }
+
   histogramBuilder.setDistribution(getProperty("Distribution"));
   auto histogram = histogramBuilder.build();
 
@@ -212,6 +226,10 @@ void CreateWorkspace::exec() {
       outputWS->mutableE(local_i)
           .assign(dataE.begin() + yStart, dataE.begin() + yEnd);
 
+    if (!dX.empty())
+      outputWS->mutableDx(local_i)
+          .assign(dX.begin() + yStart, dX.begin() + yEnd);
+
     progress.report();
     PARALLEL_END_INTERUPT_REGION
   }
diff --git a/Framework/Algorithms/src/CylinderAbsorption.cpp b/Framework/Algorithms/src/CylinderAbsorption.cpp
index b8653ecc69e99a7d56f5bdb75c894efaa39cc97e..731b7fc4ff8d5fae054a28ab7c1f6a67017374a7 100644
--- a/Framework/Algorithms/src/CylinderAbsorption.cpp
+++ b/Framework/Algorithms/src/CylinderAbsorption.cpp
@@ -82,7 +82,7 @@ std::string CylinderAbsorption::sampleXML() {
   xmlShapeStream << "<cylinder id=\"detector-shape\"> "
                  << "<centre-of-bottom-base x=\"" << samplePos.X() << "\" y=\""
                  << cylinderBase << "\" z=\"" << samplePos.Z() << "\" /> "
-                 << "<axis x=\"0\" y=\"1\" z=\"0\" /> "
+                 << R"(<axis x="0" y="1" z="0" /> )"
                  << "<radius val=\"" << m_cylRadius << "\" /> "
                  << "<height val=\"" << m_cylHeight << "\" /> "
                  << "</cylinder>";
diff --git a/Framework/Algorithms/src/DiffractionFocussing.cpp b/Framework/Algorithms/src/DiffractionFocussing.cpp
index b4cac6232c9d4fa8ee992438e889ef0fdd733c72..354ba051a11408e58f45f100753e07d0e7455e94 100644
--- a/Framework/Algorithms/src/DiffractionFocussing.cpp
+++ b/Framework/Algorithms/src/DiffractionFocussing.cpp
@@ -83,12 +83,12 @@ void DiffractionFocussing::exec() {
   if (iprogress_step == 0)
     iprogress_step = 1;
   std::vector<int64_t> resultIndeces;
-  for (auto g = groupNumbers.cbegin(); g != groupNumbers.end(); ++g) {
+  for (auto groupNumber : groupNumbers) {
     if (iprogress++ % iprogress_step == 0) {
       progress(0.68 + double(iprogress) / iprogress_count / 3);
     }
-    auto from = detectorGroups.lower_bound(*g);
-    auto to = detectorGroups.upper_bound(*g);
+    auto from = detectorGroups.lower_bound(groupNumber);
+    auto to = detectorGroups.upper_bound(groupNumber);
     std::vector<detid_t> detectorList;
     for (auto d = from; d != to; ++d)
       detectorList.push_back(static_cast<detid_t>(d->second));
diff --git a/Framework/Algorithms/src/DiffractionFocussing2.cpp b/Framework/Algorithms/src/DiffractionFocussing2.cpp
index 3924340f985afc8302f547d153d09db3bb731ea1..58c6ee88d20a646829d6e54c8aa987e1b9e0fffc 100644
--- a/Framework/Algorithms/src/DiffractionFocussing2.cpp
+++ b/Framework/Algorithms/src/DiffractionFocussing2.cpp
@@ -532,7 +532,7 @@ void DiffractionFocussing2::determineRebinParameters() {
   std::ostringstream mess;
 
   // typedef for the storage of the group ranges
-  typedef std::map<int, std::pair<double, double>> group2minmaxmap;
+  using group2minmaxmap = std::map<int, std::pair<double, double>>;
   // Map from group number to its associated range parameters <Xmin,Xmax,step>
   group2minmaxmap group2minmax;
   group2minmaxmap::iterator gpit;
diff --git a/Framework/Algorithms/src/ExtractMask.cpp b/Framework/Algorithms/src/ExtractMask.cpp
index c595ccdad76938f19932bd873cdbfb7bc8bc72ac..2d474bf92b4c81227dcf97f01509a07d7ce648c5 100644
--- a/Framework/Algorithms/src/ExtractMask.cpp
+++ b/Framework/Algorithms/src/ExtractMask.cpp
@@ -54,9 +54,12 @@ void ExtractMask::exec() {
   std::vector<detid_t> detectorList;
   const auto &detInfo = inputWS->detectorInfo();
   const auto &detIds = detInfo.detectorIDs();
-  for (size_t i = 0; i < detInfo.size(); ++i)
-    if (detInfo.isMasked(i))
+  for (size_t i = 0; i < detInfo.size(); ++i) {
+    if ((inputWSIsSpecial && inputMaskWS->isMasked(detIds[i])) ||
+        detInfo.isMasked(i)) {
       detectorList.push_back(detIds[i]);
+    }
+  }
 
   // Create a new workspace for the results, copy from the input to ensure
   // that we copy over the instrument and current masking
diff --git a/Framework/Algorithms/src/FindPeakBackground.cpp b/Framework/Algorithms/src/FindPeakBackground.cpp
index cb58a596f719c1e7476b522a53fc0e4c9d67abde..e932254eb80313092c07d9014db50a02f988d731 100644
--- a/Framework/Algorithms/src/FindPeakBackground.cpp
+++ b/Framework/Algorithms/src/FindPeakBackground.cpp
@@ -6,6 +6,7 @@
 #include "MantidAlgorithms/FindPeaks.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidHistogramData/EstimatePolynomial.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/Statistics.h"
@@ -17,8 +18,6 @@ using namespace Mantid::API;
 using namespace Mantid::Kernel;
 using namespace Mantid::DataObjects;
 using namespace std;
-using Mantid::HistogramData::HistogramX;
-using Mantid::HistogramData::HistogramY;
 
 namespace Mantid {
 namespace Algorithms {
@@ -136,10 +135,9 @@ int FindPeakBackground::findBackground(
     const HistogramData::Histogram &histogram, const size_t &l0,
     const size_t &n, std::vector<size_t> &peak_min_max_indexes,
     std::vector<double> &bkgd3) {
-  auto &inpX = histogram.x();
-  auto &inpY = histogram.y();
-  size_t sizex = inpX.size(); // inpWS->x(inpwsindex).size();
-  size_t sizey = inpY.size(); // inpWS->y(inpwsindex).size();
+  const size_t sizex = histogram.x().size();
+  const auto &inpY = histogram.y();
+  const size_t sizey = inpY.size();
 
   int goodfit(0);
 
@@ -213,7 +211,6 @@ int FindPeakBackground::findBackground(
       }
     }
     size_t min_peak, max_peak;
-    double a0 = 0., a1 = 0., a2 = 0.;
     if (!peaks.empty()) {
       g_log.debug() << "Peaks' size = " << peaks.size()
                     << " -> esitmate background. \n";
@@ -223,7 +220,7 @@ int FindPeakBackground::findBackground(
 
       // save endpoints
       min_peak = peaks[0].start;
-      // extra point for histogram input
+      // extra point for histogram input - TODO change to use Histogram better
       max_peak = peaks[0].stop + sizex - sizey;
       goodfit = 1;
     } else {
@@ -235,7 +232,8 @@ int FindPeakBackground::findBackground(
       goodfit = 2;
     }
 
-    estimateBackground(inpX, inpY, l0, n, min_peak, max_peak, (!peaks.empty()),
+    double a0 = 0., a1 = 0., a2 = 0.;
+    estimateBackground(histogram, l0, n, min_peak, max_peak, (!peaks.empty()),
                        a0, a1, a2);
 
     // Add a new row
@@ -254,8 +252,7 @@ int FindPeakBackground::findBackground(
 
 //----------------------------------------------------------------------------------------------
 /** Estimate background
-* @param X :: vec for X
-* @param Y :: vec for Y
+* @param histogram :: data to find peak background in
 * @param i_min :: index of minimum in X to estimate background
 * @param i_max :: index of maximum in X to estimate background
 * @param p_min :: index of peak min in X to estimate background
@@ -266,141 +263,18 @@ int FindPeakBackground::findBackground(
 * @param out_bg2 :: a2 = 0
 */
 void FindPeakBackground::estimateBackground(
-    const HistogramX &X, const HistogramY &Y, const size_t i_min,
+    const HistogramData::Histogram &histogram, const size_t i_min,
     const size_t i_max, const size_t p_min, const size_t p_max,
     const bool hasPeak, double &out_bg0, double &out_bg1, double &out_bg2) {
-  // Validate input
-  if (i_min >= i_max)
-    throw std::runtime_error("i_min cannot larger or equal to i_max");
-  if ((hasPeak) && (p_min >= p_max))
-    throw std::runtime_error("p_min cannot larger or equal to p_max");
-
-  // set all parameters to zero
-  out_bg0 = 0.;
-  out_bg1 = 0.;
-  out_bg2 = 0.;
-
-  // accumulate sum
-  double sum = 0.0;
-  double sumX = 0.0;
-  double sumY = 0.0;
-  double sumX2 = 0.0;
-  double sumXY = 0.0;
-  double sumX2Y = 0.0;
-  double sumX3 = 0.0;
-  double sumX4 = 0.0;
-  for (size_t i = i_min; i < i_max; ++i) {
-    if (i >= p_min && i < p_max)
-      continue;
-    sum += 1.0;
-    sumX += X[i];
-    sumX2 += X[i] * X[i];
-    sumY += Y[i];
-    sumXY += X[i] * Y[i];
-    sumX2Y += X[i] * X[i] * Y[i];
-    sumX3 += X[i] * X[i] * X[i];
-    sumX4 += X[i] * X[i] * X[i] * X[i];
-  }
-
-  // Estimate flat background
-  double bg0_flat = 0.;
-  if (sum != 0.)
-    bg0_flat = sumY / sum;
-
-  // Estimate linear - use Cramer's rule for 2 x 2 matrix
-  double bg0_linear = 0.;
-  double bg1_linear = 0.;
-  double determinant = sum * sumX2 - sumX * sumX;
-  if (determinant != 0) {
-    bg0_linear = (sumY * sumX2 - sumX * sumXY) / determinant;
-    bg1_linear = (sum * sumXY - sumY * sumX) / determinant;
-  }
-
-  // Estimate quadratic - use Cramer's rule for 3 x 3 matrix
-
-  // | a b c |
-  // | d e f |
-  // | g h i |
-  // 3 x 3 determinate:  aei+bfg+cdh-ceg-bdi-afh
-
-  double bg0_quadratic = 0.;
-  double bg1_quadratic = 0.;
-  double bg2_quadratic = 0.;
-  determinant = sum * sumX2 * sumX4 + sumX * sumX3 * sumX2 +
-                sumX2 * sumX * sumX3 - sumX2 * sumX2 * sumX2 -
-                sumX * sumX * sumX4 - sum * sumX3 * sumX3;
-  if (determinant != 0) {
-    bg0_quadratic =
-        (sumY * sumX2 * sumX4 + sumX * sumX3 * sumX2Y + sumX2 * sumXY * sumX3 -
-         sumX2 * sumX2 * sumX2Y - sumX * sumXY * sumX4 - sumY * sumX3 * sumX3) /
-        determinant;
-    bg1_quadratic =
-        (sum * sumXY * sumX4 + sumY * sumX3 * sumX2 + sumX2 * sumX * sumX2Y -
-         sumX2 * sumXY * sumX2 - sumY * sumX * sumX4 - sum * sumX3 * sumX2Y) /
-        determinant;
-    bg2_quadratic =
-        (sum * sumX2 * sumX2Y + sumX * sumXY * sumX2 + sumY * sumX * sumX3 -
-         sumY * sumX2 * sumX2 - sumX * sumX * sumX2Y - sum * sumXY * sumX3) /
-        determinant;
-  }
-
-  double chisq_flat = 0.;
-  double chisq_linear = 0.;
-  double chisq_quadratic = 0.;
-  if (sum != 0) {
-    double num_points = 0.;
-    // calculate the chisq - not normalized by the number of points
-    for (size_t i = i_min; i < i_max; ++i) {
-      if (i >= p_min && i < p_max)
-        continue;
-
-      num_points += 1.;
-
-      // accumulate for flat
-      chisq_flat += (bg0_flat - Y[i]) * (bg0_flat - Y[i]);
-
-      // accumulate for linear
-      double temp = bg0_linear + bg1_linear * X[i] - Y[i];
-      chisq_linear += (temp * temp);
-
-      // accumulate for quadratic
-      temp = bg0_quadratic + bg1_quadratic * X[i] +
-             bg2_quadratic * X[i] * X[i] - Y[i];
-      chisq_quadratic += (temp * temp);
-    }
-
-    // convert to <reduced chisq> = chisq / (<number points> - <number
-    // parameters>)
-    chisq_flat = chisq_flat / (num_points - 1.);
-    chisq_linear = chisq_linear / (num_points - 2.);
-    chisq_quadratic = chisq_quadratic / (num_points - 3.);
-  }
-  const double INVALID_CHISQ(1.e10); // big invalid value
-  if (m_backgroundType == "Flat") {
-    chisq_linear = INVALID_CHISQ;
-    chisq_quadratic = INVALID_CHISQ;
-  } else if (m_backgroundType == "Linear") {
-    chisq_quadratic = INVALID_CHISQ;
-  }
-
-  g_log.debug() << "flat: " << bg0_flat << " + " << 0. << "x + " << 0.
-                << "x^2 reduced chisq=" << chisq_flat << "\n";
-  g_log.debug() << "line: " << bg0_linear << " + " << bg1_linear << "x + " << 0.
-                << "x^2  reduced chisq=" << chisq_linear << "\n";
-  g_log.debug() << "quad: " << bg0_quadratic << " + " << bg1_quadratic << "x + "
-                << bg2_quadratic << "x^2  reduced chisq=" << chisq_quadratic
-                << "\n";
-
-  // choose the right background function to apply
-  if ((chisq_quadratic < chisq_flat) && (chisq_quadratic < chisq_linear)) {
-    out_bg0 = bg0_quadratic;
-    out_bg1 = bg1_quadratic;
-    out_bg2 = bg2_quadratic;
-  } else if ((chisq_linear < chisq_flat) && (chisq_linear < chisq_quadratic)) {
-    out_bg0 = bg0_linear;
-    out_bg1 = bg1_linear;
+  double redux_chisq;
+  if (hasPeak) {
+    HistogramData::estimateBackground(m_backgroundOrder, histogram, i_min,
+                                      i_max, p_min, p_max, out_bg0, out_bg1,
+                                      out_bg2, redux_chisq);
   } else {
-    out_bg0 = bg0_flat;
+    HistogramData::estimatePolynomial(m_backgroundOrder, histogram, i_min,
+                                      i_max, out_bg0, out_bg1, out_bg2,
+                                      redux_chisq);
   }
 
   g_log.information() << "Estimated background: A0 = " << out_bg0
diff --git a/Framework/Algorithms/src/FitPeaks.cpp b/Framework/Algorithms/src/FitPeaks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..22154ce738a1e34dd478dfb479c9e6bb38192c95
--- /dev/null
+++ b/Framework/Algorithms/src/FitPeaks.cpp
@@ -0,0 +1,2164 @@
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include "MantidAlgorithms/FitPeaks.h"
+#include "MantidAPI/Axis.h"
+#include "MantidAPI/CompositeFunction.h"
+#include "MantidAPI/CostFunctionFactory.h"
+#include "MantidAPI/FuncMinimizerFactory.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/FunctionProperty.h"
+#include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceProperty.h"
+#include "MantidAlgorithms/FindPeakBackground.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidHistogramData/EstimatePolynomial.h"
+#include "MantidHistogramData/HistogramIterator.h"
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/IValidator.h"
+#include "MantidKernel/ListValidator.h"
+#include "MantidKernel/StartsWithValidator.h"
+
+#include "MantidAPI/MultiDomainFunction.h"
+
+#include "boost/algorithm/string.hpp"
+#include "boost/algorithm/string/trim.hpp"
+
+using namespace Mantid;
+using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Kernel;
+using Mantid::HistogramData::Histogram;
+using Mantid::HistogramData::HistogramX;
+using Mantid::HistogramData::HistogramY;
+using namespace std;
+
+const size_t MIN_EVENTS = 100;
+
+namespace Mantid {
+namespace Algorithms {
+
+namespace FitPeaksAlgorithm {
+
+//----------------------------------------------------------------------------------------------
+/** Initiailization
+ * @brief PeakFitResult::PeakFitResult
+ * @param num_peaks
+ * @param num_params
+ */
+PeakFitResult::PeakFitResult(size_t num_peaks, size_t num_params) {
+  // check input
+  if (num_peaks == 0 || num_params == 0)
+    throw std::runtime_error("No peak or no parameter error.");
+  function_parameters_number_ = num_params;
+
+  //
+  fitted_peak_positions.resize(num_peaks, -1);
+  costs.resize(num_peaks, DBL_MAX);
+  function_parameters_vector.resize(num_peaks);
+  for (size_t ipeak = 0; ipeak < num_peaks; ++ipeak) {
+    function_parameters_vector[ipeak].resize(num_params);
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief PeakFitResult::getNumberParameters
+ * @return
+ */
+size_t PeakFitResult::getNumberParameters() {
+  return function_parameters_number_;
+}
+
+double PeakFitResult::getParameterValue(size_t ipeak, size_t iparam) {
+  return function_parameters_vector[ipeak][iparam];
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief PeakFitResult::getPeakPosition
+ * @param ipeak
+ * @return
+ */
+double PeakFitResult::getPeakPosition(size_t ipeak) {
+  return fitted_peak_positions[ipeak];
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief PeakFitResult::getCost
+ * @param ipeak
+ * @return
+ */
+double PeakFitResult::getCost(size_t ipeak) { return costs[ipeak]; }
+
+//----------------------------------------------------------------------------------------------
+/** set the peak fitting record/parameter for one peak
+ * @brief PeakFitResult::setRecord
+ * @param ipeak
+ * @param cost
+ * @param peak_position
+ * @param fit_functions
+ */
+void PeakFitResult::setRecord(size_t ipeak, const double cost,
+                              const double peak_position,
+                              FitFunction fit_functions) {
+  // check input
+  if (ipeak >= costs.size())
+    throw std::runtime_error("Peak index is out of range.");
+
+  // set the values
+  costs[ipeak] = cost;
+
+  // set peak position
+  fitted_peak_positions[ipeak] = peak_position;
+
+  // transfer from peak function to vector
+  size_t peak_num_params = fit_functions.peakfunction->nParams();
+  for (size_t ipar = 0; ipar < peak_num_params; ++ipar) {
+    // peak function
+    function_parameters_vector[ipeak][ipar] =
+        fit_functions.peakfunction->getParameter(ipar);
+  }
+  for (size_t ipar = 0; ipar < fit_functions.bkgdfunction->nParams(); ++ipar) {
+    // background function
+    function_parameters_vector[ipeak][ipar + peak_num_params] =
+        fit_functions.bkgdfunction->getParameter(ipar);
+  }
+
+  return;
+}
+}
+
+//----------------------------------------------------------------------------------------------
+/** Get an index of a value in a sorted vector.  The index should be the item
+ * with value nearest to X
+  */
+size_t findXIndex(const std::vector<double> &vecx, double x) {
+  size_t index;
+  if (x <= vecx.front()) {
+    index = 0;
+  } else if (x >= vecx.back()) {
+    index = vecx.size() - 1;
+  } else {
+    vector<double>::const_iterator fiter =
+        lower_bound(vecx.begin(), vecx.end(), x);
+    if (fiter == vecx.end())
+      throw runtime_error("It seems impossible to have this value. ");
+
+    index = static_cast<size_t>(fiter - vecx.begin());
+    if (x - vecx[index - 1] < vecx[index] - x)
+      --index;
+  }
+
+  return index;
+}
+
+enum PeakFitResult { NOSIGNAL, LOWPEAK, OUTOFBOUND, GOOD };
+
+//----------------------------------------------------------------------------------------------
+/** constructor
+ * @brief FitPeaks::FitPeaks
+ */
+FitPeaks::FitPeaks()
+    : m_fitPeaksFromRight(true), m_numPeaksToFit(0), m_minPeakHeight(20.),
+      m_bkgdSimga(1.), m_peakPosTolCase234(false) {}
+
+//----------------------------------------------------------------------------------------------
+/** initialize the properties
+ * @brief FitPeaks::init
+ */
+void FitPeaks::init() {
+  declareProperty(Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+                      "InputWorkspace", "", Direction::Input),
+                  "Name of the input workspace for peak fitting.");
+  declareProperty(Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+                      "OutputWorkspace", "", Direction::Output),
+                  "Name of the output workspace containing peak centers for "
+                  "fitting offset."
+                  "The output workspace is point data."
+                  "Each workspace index corresponds to a spectrum. "
+                  "Each X value ranges from 0 to N-1, where N is the number of "
+                  "peaks to fit. "
+                  "Each Y value is the peak position obtained by peak fitting. "
+                  "Negative value is used for error signals. "
+                  "-1 for data is zero;  -2 for maximum value is smaller than "
+                  "specified minimum value."
+                  "and -3 for non-converged fitting.");
+
+  // properties about fitting range and criteria
+  declareProperty("StartWorkspaceIndex", EMPTY_INT(),
+                  "Starting workspace index for fit");
+  declareProperty("StopWorkspaceIndex", EMPTY_INT(),
+                  "Last workspace index to fit (which is included)");
+
+  // properties about peak positions to fit
+  declareProperty(Kernel::make_unique<ArrayProperty<double>>("PeakCenters"),
+                  "List of peak centers to fit against.");
+  declareProperty(
+      Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+          "PeakCentersWorkspace", "", Direction::Input, PropertyMode::Optional),
+      "MatrixWorkspace containing peak centers");
+
+  std::string peakcentergrp("Peak Positions");
+  setPropertyGroup("PeakCenters", peakcentergrp);
+  setPropertyGroup("PeakCentersWorkspace", peakcentergrp);
+
+  // properties about peak profile
+  std::vector<std::string> peakNames =
+      FunctionFactory::Instance().getFunctionNames<API::IPeakFunction>();
+  declareProperty("PeakFunction", "Gaussian",
+                  boost::make_shared<StringListValidator>(peakNames));
+  vector<string> bkgdtypes{"Flat", "Linear", "Quadratic"};
+  declareProperty("BackgroundType", "Linear",
+                  boost::make_shared<StringListValidator>(bkgdtypes),
+                  "Type of Background.");
+
+  std::string funcgroup("Function Types");
+  setPropertyGroup("PeakFunction", funcgroup);
+  setPropertyGroup("BackgroundType", funcgroup);
+
+  // properties about peak range including fitting window and peak width
+  // (percentage)
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("FitWindowBoundaryList"),
+      "List of left boundaries of the peak fitting window corresponding to "
+      "PeakCenters.");
+
+  declareProperty(Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+                      "FitPeakWindowWorkspace", "", Direction::Input,
+                      PropertyMode::Optional),
+                  "MatrixWorkspace for of peak windows");
+
+  auto min = boost::make_shared<BoundedValidator<double>>();
+  min->setLower(1e-3);
+  declareProperty("PeakWidthPercent", EMPTY_DBL(), min,
+                  "The estimated peak width as a "
+                  "percentage of the d-spacing "
+                  "of the center of the peak.");
+
+  std::string fitrangeegrp("Peak Range Setup");
+  setPropertyGroup("PeakWidthPercent", fitrangeegrp);
+  setPropertyGroup("FitWindowBoundaryList", fitrangeegrp);
+  setPropertyGroup("FitPeakWindowWorkspace", fitrangeegrp);
+
+  // properties about peak parameters' names and value
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<std::string>>("PeakParameterNames"),
+      "List of peak parameters' names");
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("PeakParameterValues"),
+      "List of peak parameters' value");
+  declareProperty(Kernel::make_unique<WorkspaceProperty<TableWorkspace>>(
+                      "PeakParameterValueTable", "", Direction::Input,
+                      PropertyMode::Optional),
+                  "Name of the an optional workspace, whose each column "
+                  "corresponds to given peak parameter names"
+                  ", and each row corresponds to a subset of spectra.");
+
+  std::string startvaluegrp("Strting Parameters Setup");
+  setPropertyGroup("PeakParameterNames", startvaluegrp);
+  setPropertyGroup("PeakParameterValues", startvaluegrp);
+  setPropertyGroup("PeakParameterValueTable", startvaluegrp);
+
+  // optimization setup
+  declareProperty("FitFromRight", true,
+                  "Flag for the order to fit peaks.  If true, peaks are fitted "
+                  "from rightmost;"
+                  "Otherwise peaks are fitted from leftmost.");
+
+  std::vector<std::string> minimizerOptions =
+      API::FuncMinimizerFactory::Instance().getKeys();
+  declareProperty("Minimizer", "Levenberg-Marquardt",
+                  Kernel::IValidator_sptr(
+                      new Kernel::StartsWithValidator(minimizerOptions)),
+                  "Minimizer to use for fitting. Minimizers available are "
+                  "\"Levenberg-Marquardt\", \"Simplex\","
+                  "\"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate "
+                  "gradient (Polak-Ribiere imp.)\", \"BFGS\", and "
+                  "\"Levenberg-MarquardtMD\"");
+
+  std::array<string, 2> costFuncOptions = {{"Least squares", "Rwp"}};
+  declareProperty("CostFunction", "Least squares",
+                  Kernel::IValidator_sptr(
+                      new Kernel::ListValidator<std::string>(costFuncOptions)),
+                  "Cost functions");
+
+  std::string optimizergrp("Optimization Setup");
+  setPropertyGroup("Minimizer", optimizergrp);
+  setPropertyGroup("CostFunction", optimizergrp);
+
+  // other helping information
+  declareProperty(
+      "FindBackgroundSigma", 1.0,
+      "Multiplier of standard deviations of the variance for convergence of "
+      "peak elimination.  Default is 1.0. ");
+
+  declareProperty("HighBackground", true,
+                  "Flag whether the data has high background comparing to "
+                  "peaks' intensities. "
+                  "For example, vanadium peaks usually have high background.");
+
+  declareProperty(
+      Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+          "EventNumberWorkspace", "", Direction::Input, PropertyMode::Optional),
+      "Name of an optional workspace, whose each spectrum corresponds to each "
+      "spectrum "
+      "in input workspace. "
+      "It has 1 value of each spectrum, standing for the number of events of "
+      "the corresponding spectrum.");
+
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("PositionTolerance"),
+      "List of tolerance on fitted peak positions against given peak positions."
+      "If there is only one value given, then ");
+
+  declareProperty("MinimumPeakHeight", EMPTY_DBL(),
+                  "Minimum peak height such that all the fitted peaks with "
+                  "height under this value will be excluded.");
+
+  declareProperty(
+      "ConstrainPeakPositions", true,
+      "If true peak position will be constrained by estimated positions "
+      "(highest Y value position) and "
+      "the peak width either estimted by observation or calculate.");
+
+  std::string helpgrp("Additional Information");
+
+  setPropertyGroup("EventNumberWorkspace", helpgrp);
+
+  // additional output for reviewing
+  declareProperty(Kernel::make_unique<WorkspaceProperty<API::ITableWorkspace>>(
+                      "OutputPeakParametersWorkspace", "", Direction::Output),
+                  "Name of workspace containing all fitted peak parameters.  "
+                  "X-values are spectra/workspace index.");
+  declareProperty(
+      Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+          "FittedPeaksWorkspace", "", Direction::Output,
+          PropertyMode::Optional),
+      "Name of the output matrix workspace with fitted peak. "
+      "This output workspace have the same dimesion as the input workspace."
+      "The Y values belonged to peaks to fit are replaced by fitted value. "
+      "Values of estimated background are used if peak fails to be fit.");
+
+  std::string addoutgrp("Analysis");
+  setPropertyGroup("OutputPeakParametersWorkspace", addoutgrp);
+  setPropertyGroup("FittedPeaksWorkspace", addoutgrp);
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** main method to fit peaks
+ * @brief FitPeaks::exec
+ */
+void FitPeaks::exec() {
+  // process inputs
+  processInputs();
+
+  // create output workspaces
+  generateOutputPeakPositionWS();
+  generateFittedParametersValueWorkspace();
+  generateCalculatedPeaksWS();
+
+  // fit peaks
+  fitPeaks();
+
+  // set the output workspaces to properites
+  processOutputs();
+}
+
+//----------------------------------------------------------------------------------------------
+/** process inputs
+ * @brief FitPeaks::processInputs
+ */
+void FitPeaks::processInputs() {
+  // input workspaces
+  m_inputMatrixWS = getProperty("InputWorkspace");
+  std::string event_ws_name = getPropertyValue("EventNumberWorkspace");
+  if (event_ws_name.empty())
+    m_eventNumberWS = nullptr;
+  else
+    m_eventNumberWS = getProperty("EventNumberWorkspace");
+
+  if (m_inputMatrixWS->getAxis(0)->unit()->unitID() == "dSpacing")
+    m_inputIsDSpace = true;
+  else
+    m_inputIsDSpace = false;
+
+  // spectra to fit
+  int start_wi = getProperty("StartWorkspaceIndex");
+  if (isEmpty(start_wi))
+    m_startWorkspaceIndex = 0;
+  else
+    m_startWorkspaceIndex = static_cast<size_t>(start_wi);
+
+  // last spectrum's workspace index, which is included
+  int stop_wi = getProperty("StopWorkspaceIndex");
+  if (isEmpty(stop_wi))
+    m_stopWorkspaceIndex = m_inputMatrixWS->getNumberHistograms() - 1;
+  else {
+    m_stopWorkspaceIndex = static_cast<size_t>(stop_wi);
+    if (m_stopWorkspaceIndex > m_inputMatrixWS->getNumberHistograms() - 1)
+      m_stopWorkspaceIndex = m_inputMatrixWS->getNumberHistograms() - 1;
+  }
+
+  // optimizer, cost function and fitting scheme
+  m_minimizer = getPropertyValue("Minimizer");
+  m_costFunction = getPropertyValue("CostFunction");
+  m_fitPeaksFromRight = getProperty("FitFromRight");
+  m_constrainPeaksPosition = getProperty("ConstrainPeakPositions");
+
+  // Peak centers, tolerance and fitting range
+  processInputPeakCenters();
+  // check
+  if (m_numPeaksToFit == 0)
+    throw std::runtime_error("number of peaks to fit is zero.");
+  // about how to estimate the peak width
+  m_peakDSpacePercentage = getProperty("PeakWidthPercent");
+  if (isEmpty(m_peakDSpacePercentage))
+    m_peakDSpacePercentage = -1;
+  else if (m_peakDSpacePercentage <= 0)
+    throw std::invalid_argument(
+        "Peak D-spacing percentage cannot be negative or zero!");
+  g_log.debug() << "DeltaD/D = " << m_peakDSpacePercentage << "\n";
+
+  // set up background
+  m_highBackground = getProperty("HighBackground");
+  m_bkgdSimga = getProperty("FindBackgroundSigma");
+
+  // Set up peak and background functions
+  processInputFunctions();
+  // about peak width and other peak parameter estimating method
+  if (m_inputIsDSpace && m_peakDSpacePercentage > 0)
+    m_peakWidthEstimateApproach = EstimatePeakWidth::InstrumentResolution;
+  else if (m_peakFunction->name() == "Gaussian")
+    m_peakWidthEstimateApproach = EstimatePeakWidth::Observation;
+  else
+    m_peakWidthEstimateApproach = EstimatePeakWidth::NoEstimation;
+  g_log.debug() << "Process inputs [3] peak type: " << m_peakFunction->name()
+                << ", background type: " << m_bkgdFunction->name() << "\n";
+
+  processInputPeakTolerance();
+  processInputFitRanges();
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** process inputs for peak profile and background
+ * @brief FitPeaks::processInputFunctions
+ */
+void FitPeaks::processInputFunctions() {
+  // peak functions
+  std::string peakfunctiontype = getPropertyValue("PeakFunction");
+  m_peakFunction = boost::dynamic_pointer_cast<IPeakFunction>(
+      API::FunctionFactory::Instance().createFunction(peakfunctiontype));
+
+  // background functions
+  std::string bkgdfunctiontype = getPropertyValue("BackgroundType");
+  std::string bkgdname;
+  if (bkgdfunctiontype == "Linear")
+    bkgdname = "LinearBackground";
+  else if (bkgdfunctiontype == "Flat")
+    bkgdname = "FlatBackground";
+  else
+    bkgdname = bkgdfunctiontype;
+  m_bkgdFunction = boost::dynamic_pointer_cast<IBackgroundFunction>(
+      API::FunctionFactory::Instance().createFunction(bkgdname));
+  if (m_highBackground)
+    m_linearBackgroundFunction =
+        boost::dynamic_pointer_cast<IBackgroundFunction>(
+            API::FunctionFactory::Instance().createFunction(
+                "LinearBackground"));
+  else
+    m_linearBackgroundFunction = nullptr;
+
+  // input peak parameters
+  std::string partablename = getPropertyValue("PeakParameterValueTable");
+  m_peakParamNames = getProperty("PeakParameterNames");
+  if (partablename.empty() && (!m_peakParamNames.empty())) {
+    // use uniform starting value of peak parameters
+    m_initParamValues = getProperty("PeakParameterValues");
+    // check whether given parameter names and initial values match
+    if (m_peakParamNames.size() != m_initParamValues.size())
+      throw std::invalid_argument("PeakParameterNames and PeakParameterValues "
+                                  "have different number of items.");
+    // convert the parameter name in string to parameter name in integer index
+    convertParametersNameToIndex();
+    // set the flag
+    m_uniformProfileStartingValue = true;
+  } else if ((!partablename.empty()) && m_peakParamNames.empty()) {
+    // use non-uniform starting value of peak parameters
+    m_uniformProfileStartingValue = false;
+    m_profileStartingValueTable = getProperty(partablename);
+  } else if ((!partablename.empty()) && m_peakParamNames.size() > 0) {
+    // user specifies both of them causing confusion
+    throw std::invalid_argument("Parameter value table and initial parameter "
+                                "name/value vectors cannot be given "
+                                "simultanenously.");
+  } else {
+    // user specifies nothing
+    g_log.warning("Neither parameter value table nor initial "
+                  "parameter name/value vectors is specified. Fitting might "
+                  "not be reliable for peak profile other than Gaussian");
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** process and check for inputs about peak fitting range (i.e., window)
+ * Note: What is the output of the method?
+ * @brief FitPeaks::processInputFitRanges
+ */
+void FitPeaks::processInputFitRanges() {
+  // get peak fit window
+  std::vector<double> peakwindow = getProperty("FitWindowBoundaryList");
+  std::string peakwindowname = getPropertyValue("FitPeakWindowWorkspace");
+
+  // in most case, calculate window by instrument resolution is False
+  m_calculateWindowInstrument = false;
+
+  if ((!peakwindow.empty()) && peakwindowname.empty()) {
+    // Peak windows are uniform among spectra: use vector for peak windows
+    m_uniformPeakWindows = true;
+
+    // check peak positions
+    if (!m_uniformPeakPositions)
+      throw std::invalid_argument(
+          "Uniform peak range/window requires uniform peak positions.");
+    // check size
+    if (peakwindow.size() != m_numPeaksToFit * 2)
+      throw std::invalid_argument(
+          "Peak window vector must be twice as large as number of peaks.");
+
+    // set up window to m_peakWindowVector
+    m_peakWindowVector.resize(m_numPeaksToFit);
+    for (size_t i = 0; i < m_numPeaksToFit; ++i) {
+      std::vector<double> peakranges(2);
+      peakranges[0] = peakwindow[i * 2];
+      peakranges[1] = peakwindow[i * 2 + 1];
+      // check peak window (range) against peak centers
+      if ((peakranges[0] < m_peakCenters[i]) &&
+          (m_peakCenters[i] < peakranges[1])) {
+        // pass check: set
+        m_peakWindowVector[i] = peakranges;
+      } else {
+        // failed
+        std::stringstream errss;
+        errss << "Peak " << i
+              << ": user specifies an invalid range and peak center against "
+              << peakranges[0] << " < " << m_peakCenters[i] << " < "
+              << peakranges[1];
+        throw std::invalid_argument(errss.str());
+      }
+    } // END-FOR
+    // END for uniform peak window
+  } else if (peakwindow.empty() && (!peakwindowname.empty())) {
+    // use matrix workspace for non-uniform peak windows
+    m_peakWindowWorkspace = getProperty("FitPeakWindowWorkspace");
+    m_uniformPeakWindows = false;
+
+    // check size
+    if (m_peakWindowWorkspace->getNumberHistograms() ==
+        m_inputMatrixWS->getNumberHistograms())
+      m_partialWindowSpectra = false;
+    else if (m_peakWindowWorkspace->getNumberHistograms() ==
+             (m_stopWorkspaceIndex - m_startWorkspaceIndex + 1))
+      m_partialWindowSpectra = true;
+    else
+      throw std::invalid_argument(
+          "Peak window workspace has unmatched number of spectra");
+
+    // check range for peak windows and peak positions
+    size_t window_index_start(0);
+    if (m_partialWindowSpectra)
+      window_index_start = m_startWorkspaceIndex;
+    size_t center_index_start(0);
+    if (m_partialSpectra)
+      center_index_start = m_startWorkspaceIndex;
+
+    // check each spectrum whether the window is defined with the correct size
+    for (size_t wi = 0; wi < m_peakWindowWorkspace->getNumberHistograms();
+         ++wi) {
+      // check size
+      if (m_peakWindowWorkspace->y(wi).size() != m_numPeaksToFit * 2) {
+        std::stringstream errss;
+        errss << "Peak window workspace index " << wi
+              << " has incompatible number of fit windows (x2) "
+              << m_peakWindowWorkspace->y(wi).size()
+              << "with the number of peaks " << m_numPeaksToFit << " to fit.";
+        throw std::invalid_argument(errss.str());
+      }
+
+      // check window range against peak center
+      size_t window_index = window_index_start + wi;
+      size_t center_index = window_index - center_index_start;
+
+      for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+        double left_w_bound = m_peakWindowWorkspace->y(wi)[ipeak * 2];
+        double right_w_bound = m_peakWindowWorkspace->y(wi)[ipeak * 2 + 1];
+        double center = m_peakCenterWorkspace->x(center_index)[ipeak];
+        if (!(left_w_bound < center && center < right_w_bound)) {
+          std::stringstream errss;
+          errss << "Workspace index " << wi << " has incompatible peak window ("
+                << left_w_bound << ", " << right_w_bound << ") with " << ipeak
+                << "-th expected peak's center " << center;
+          throw std::runtime_error(errss.str());
+        }
+      }
+    }
+  } else if (peakwindow.empty()) {
+    // no peak window is defined, then the peak window will be estimated by
+    // delta(D)/D
+    if (m_inputIsDSpace && m_peakDSpacePercentage > 0)
+      m_calculateWindowInstrument = true;
+    else
+      throw std::invalid_argument("Without definition of peak window, the "
+                                  "input workspace must be in unit of dSpacing "
+                                  "and Delta(D)/D must be given!");
+
+  } else {
+    // non-supported situation
+    throw std::invalid_argument("One and only one of peak window array and "
+                                "peak window workspace can be specified.");
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Processing peaks centers and fitting tolerance information from input.  the
+ * parameters that are
+ * set including
+ * 1. m_peakCenters/m_peakCenterWorkspace/m_uniformPeakPositions
+ * (bool)/m_partialSpectra (bool)
+ * 2. m_peakPosTolerances (vector)
+ * 3. m_numPeaksToFit
+ * @brief FitPeaks::processInputPeakCenters
+ */
+void FitPeaks::processInputPeakCenters() {
+  // peak centers
+  m_peakCenters = getProperty("PeakCenters");
+  std::string peakpswsname = getPropertyValue("PeakCentersWorkspace");
+  if ((!m_peakCenters.empty()) && peakpswsname.empty()) {
+    // peak positions are uniform among all spectra
+    m_uniformPeakPositions = true;
+    // number of peaks to fit!
+    m_numPeaksToFit = m_peakCenters.size();
+  } else if (m_peakCenters.empty() && (!peakpswsname.empty())) {
+    // peak positions can be different among spectra
+    m_uniformPeakPositions = false;
+    m_peakCenterWorkspace = getProperty("PeakCentersWorkspace");
+    // number of peaks to fit!
+    m_numPeaksToFit = m_peakCenterWorkspace->x(0).size();
+
+    // check matrix worksapce for peak positions
+    const size_t numhist = m_peakCenterWorkspace->getNumberHistograms();
+    if (numhist == m_inputMatrixWS->size())
+      m_partialSpectra = false;
+    else if (numhist == m_stopWorkspaceIndex - m_startWorkspaceIndex + 1)
+      m_partialSpectra = true;
+    else
+      throw std::invalid_argument(
+          "Input peak center workspace has wrong number of spectra.");
+
+  } else {
+    std::stringstream errss;
+    errss << "One and only one in 'PeakCenters' (vector) and "
+             "'PeakCentersWorkspace' shall be given. "
+          << "'PeakCenters' has size " << m_peakCenters.size()
+          << ", and name of peak center workspace "
+          << "is " << peakpswsname;
+    throw std::invalid_argument(errss.str());
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Processing peak fitting tolerance information from input.  The parameters
+ * that are
+ * set including
+ * 2. m_peakPosTolerances (vector)
+ * @brief FitPeaks::ProcessInputPeakTolerance
+ */
+void FitPeaks::processInputPeakTolerance() {
+  // check code integrity
+  if (m_numPeaksToFit == 0)
+    throw std::runtime_error("ProcessInputPeakTolerance() must be called after "
+                             "ProcessInputPeakCenters()");
+
+  // peak tolerance
+  m_peakPosTolerances = getProperty("PositionTolerance");
+
+  if (m_peakPosTolerances.empty()) {
+    // case 2, 3, 4
+    m_peakPosTolerances.clear();
+    m_peakPosTolCase234 = true;
+  } else if (m_peakPosTolerances.size() == 1) {
+    // only 1 uniform peak position tolerance is defined: expand to all peaks
+    double peak_tol = m_peakPosTolerances[0];
+    m_peakPosTolerances.resize(m_numPeaksToFit, peak_tol);
+  } else if (m_peakPosTolerances.size() != m_numPeaksToFit) {
+    // not uniform but number of peaks does not match
+    g_log.error() << "number of peak position tolerance "
+                  << m_peakPosTolerances.size()
+                  << " is not same as number of peaks " << m_numPeaksToFit
+                  << "\n";
+    throw std::runtime_error("Number of peak position tolerances and number of "
+                             "peaks to fit are inconsistent.");
+  }
+
+  // minimum peak height: set default to zero
+  m_minPeakHeight = getProperty("MinimumPeakHeight");
+  if (isEmpty(m_minPeakHeight))
+    m_minPeakHeight = 0.;
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Convert the input initial parameter name/value to parameter index/value for
+ * faster access
+ * according to the parameter name and peak profile function
+ * @brief FitPeaks::ConvertParametersNameToIndex
+ * Output: m_initParamIndexes will be set up
+ */
+void FitPeaks::convertParametersNameToIndex() {
+  // get a map for peak profile parameter name and parameter index
+  std::map<std::string, size_t> parname_index_map;
+  for (size_t iparam = 0; iparam < m_peakFunction->nParams(); ++iparam)
+    parname_index_map.insert(
+        std::make_pair(m_peakFunction->parameterName(iparam), iparam));
+
+  // define peak parameter names (class variable) if using table
+  if (m_profileStartingValueTable)
+    m_peakParamNames = m_profileStartingValueTable->getColumnNames();
+
+  // map the input parameter names to parameter indexes
+  for (const auto &paramName : m_peakParamNames) {
+    std::map<std::string, size_t>::iterator locator =
+        parname_index_map.find(paramName);
+    if (locator != parname_index_map.end())
+      m_initParamIndexes.push_back(locator->second);
+    else {
+      // a parameter name that is not defined in the peak profile function.  An
+      // out-of-range index is thus set to this
+      g_log.warning() << "Given peak parameter " << paramName
+                      << " is not an allowed parameter of peak "
+                         "function " << m_peakFunction->name() << "\n";
+      m_initParamIndexes.push_back(m_peakFunction->nParams() * 10);
+    }
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** main method to fit peaks among all
+ * @brief FitPeaks::fitPeaks
+ */
+void FitPeaks::fitPeaks() {
+  // cppcheck-suppress syntaxError
+  PRAGMA_OMP(parallel for schedule(dynamic, 1) )
+  for (int wi = static_cast<int>(m_startWorkspaceIndex);
+       wi <= static_cast<int>(m_stopWorkspaceIndex); ++wi) {
+
+    PARALLEL_START_INTERUPT_REGION
+
+    // peaks to fit
+    std::vector<double> expected_peak_centers =
+        getExpectedPeakPositions(static_cast<size_t>(wi));
+
+    // initialize output for this
+    size_t numfuncparams =
+        m_peakFunction->nParams() + m_bkgdFunction->nParams();
+    boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result =
+        boost::make_shared<FitPeaksAlgorithm::PeakFitResult>(m_numPeaksToFit,
+                                                             numfuncparams);
+
+    // check number of events
+    bool noevents(false);
+    if (m_eventNumberWS &&
+        m_eventNumberWS->histogram(static_cast<size_t>(wi)).x()[0] < 1.0) {
+      // no event with additional event number workspace
+      noevents = true;
+    } else if (m_inputEventWS &&
+               m_inputEventWS->getNumberEvents() < MIN_EVENTS) {
+      // too few events for peak fitting
+      noevents = true;
+    } else {
+      // fit
+      fitSpectrumPeaks(static_cast<size_t>(wi), expected_peak_centers,
+                       fit_result);
+      //    fitted_peak_centers, fitted_parameters, &peak_chi2_vec);
+    }
+
+    PARALLEL_CRITICAL(FindPeaks_WriteOutput) {
+      writeFitResult(static_cast<size_t>(wi), expected_peak_centers, fit_result,
+                     // fitted_peak_centers, fitted_parameters, peak_chi2_vec,
+                     noevents);
+    }
+
+    PARALLEL_END_INTERUPT_REGION
+  }
+
+  PARALLEL_CHECK_INTERUPT_REGION
+}
+
+//----------------------------------------------------------------------------------------------
+/** Fit peaks across one single spectrum
+ * @brief FitPeaks::fitSpectrumPeaks
+ * @param wi
+ * @param expected_peak_centers
+ * @param fit_result
+ */
+void FitPeaks::fitSpectrumPeaks(
+    size_t wi, const std::vector<double> &expected_peak_centers,
+    boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result) {
+  // Set up sub algorithm Fit for peak and background
+  IAlgorithm_sptr peak_fitter; // both peak and background (combo)
+  try {
+    peak_fitter = createChildAlgorithm("Fit", -1, -1, false);
+  } catch (Exception::NotFoundError &) {
+    std::stringstream errss;
+    errss << "The FitPeak algorithm requires the CurveFitting library";
+    g_log.error(errss.str());
+    throw std::runtime_error(errss.str());
+  }
+
+  // Clone the function
+  IPeakFunction_sptr peakfunction =
+      boost::dynamic_pointer_cast<API::IPeakFunction>(m_peakFunction->clone());
+  IBackgroundFunction_sptr bkgdfunction =
+      boost::dynamic_pointer_cast<API::IBackgroundFunction>(
+          m_bkgdFunction->clone());
+  CompositeFunction_sptr compfunc = boost::make_shared<CompositeFunction>();
+  compfunc->addFunction(peakfunction);
+  compfunc->addFunction(bkgdfunction);
+
+  // high background to reduce
+  API::IBackgroundFunction_sptr high_bkgd_func(nullptr);
+  if (m_linearBackgroundFunction)
+    high_bkgd_func = boost::dynamic_pointer_cast<API::IBackgroundFunction>(
+        m_linearBackgroundFunction->clone());
+
+  // set up properties of algorithm (reference) 'Fit'
+  peak_fitter->setProperty("Minimizer", m_minimizer);
+  peak_fitter->setProperty("CostFunction", m_costFunction);
+  peak_fitter->setProperty("CalcErrors", true);
+
+  for (size_t fit_index = 0; fit_index < m_numPeaksToFit; ++fit_index) {
+
+    // convert fit index to peak index (in ascending order)
+    size_t peak_index(fit_index);
+    if (m_fitPeaksFromRight)
+      peak_index = m_numPeaksToFit - fit_index - 1;
+
+    // get expected peak position
+    double expected_peak_pos = expected_peak_centers[peak_index];
+    double x0 = m_inputMatrixWS->histogram(wi).x().front();
+    double xf = m_inputMatrixWS->histogram(wi).x().back();
+    double cost(DBL_MAX);
+    if (expected_peak_pos <= x0 || expected_peak_pos >= xf) {
+      // out of range and there won't be any fit
+      peakfunction->setIntensity(0);
+      peakfunction->setCentre(expected_peak_pos);
+    } else {
+      // find out the peak position to fit
+      std::pair<double, double> peak_window_i =
+          getPeakFitWindow(wi, peak_index);
+
+      bool observe_peak_width =
+          decideToEstimatePeakWidth(fit_index, peakfunction);
+
+      // do fitting with peak and background function (no analysis at this
+      // point)
+      cost = fitIndividualPeak(wi, peak_fitter, expected_peak_pos,
+                               peak_window_i, m_highBackground, high_bkgd_func,
+                               observe_peak_width, peakfunction, bkgdfunction);
+    }
+
+    // process fitting result
+    FitPeaksAlgorithm::FitFunction fit_function;
+    fit_function.peakfunction = peakfunction;
+    fit_function.bkgdfunction = bkgdfunction;
+
+    processSinglePeakFitResult(wi, peak_index, cost, expected_peak_centers,
+                               fit_function, fit_result);
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Decide whether to estimate peak width.  If not, then set the width related
+ * peak parameters from
+ * user specified starting value
+ * @brief FitPeaks::DecideToEstimatePeakWidth
+ * @param peak_index
+ * @param peak_function
+ * @return
+ */
+bool FitPeaks::decideToEstimatePeakWidth(
+    size_t peak_index, API::IPeakFunction_sptr peak_function) {
+  bool observe_peak_width(false);
+
+  if (!m_initParamIndexes.empty()) {
+    // user specifies starting value of peak parameters
+    if (peak_index == 0) {
+      // first peak.  using the user-specified value
+      for (size_t i = 0; i < m_initParamIndexes.size(); ++i) {
+        size_t param_index = m_initParamIndexes[i];
+        double param_value = m_initParamValues[i];
+        peak_function->setParameter(param_index, param_value);
+      }
+    } else {
+      // using the fitted paramters from the previous fitting result
+      // do noting
+    }
+  } else {
+    // by observation
+    observe_peak_width = true;
+  }
+
+  return observe_peak_width;
+}
+
+//----------------------------------------------------------------------------------------------
+/** retrieve the fitted peak information from functions and set to output
+ * vectors
+ * @brief FitPeaks::processSinglePeakFitResult
+ * @param wsindex
+ * @param peakindex
+ * @param cost
+ * @param expected_peak_positions
+ * @param fitfunction
+ * @param fit_result
+ */
+void FitPeaks::processSinglePeakFitResult(
+    size_t wsindex, size_t peakindex, const double cost,
+    const std::vector<double> &expected_peak_positions,
+    FitPeaksAlgorithm::FitFunction fitfunction,
+    boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result) {
+  // determine peak position tolerance
+  double postol(DBL_MAX);
+  bool case23(false);
+  if (m_peakPosTolCase234) {
+    // peak tolerance is not defined
+    if (m_numPeaksToFit == 1) {
+      // case (d) one peak only
+      postol = m_inputMatrixWS->histogram(wsindex).x().back() -
+               m_inputMatrixWS->histogram(wsindex).x().front();
+    } else {
+      // case b and c: more than 1 peaks without defined peak tolerance
+      case23 = true;
+    }
+  } else {
+    // user explicitly specified
+    if (peakindex >= m_peakPosTolerances.size())
+      throw std::runtime_error("Peak tolerance out of index");
+    postol = m_peakPosTolerances[peakindex];
+  }
+
+  // get peak position and analyze the fitting is good or not by various
+  // criteria
+  double peak_pos = fitfunction.peakfunction->centre();
+  bool good_fit(false);
+  if ((cost < 0) || (cost >= DBL_MAX - 1.)) {
+    // unphysical cost function value
+    peak_pos = -4;
+  } else if (fitfunction.peakfunction->height() < m_minPeakHeight) {
+    // peak height is under minimum request
+    peak_pos = -3;
+  } else if (case23) {
+    // case b and c to check peak position without defined peak tolerance
+    std::pair<double, double> fitwindow = getPeakFitWindow(wsindex, peakindex);
+    if (fitwindow.first < fitwindow.second) {
+      // peak fit window is specified or calculated: use peak window as position
+      // tolerance
+      if (peak_pos < fitwindow.first || peak_pos > fitwindow.second) {
+        // peak is out of fit window
+        peak_pos = -2;
+        g_log.debug() << "Peak position " << peak_pos << " is out of fit "
+                      << "window boundary " << fitwindow.first << ", "
+                      << fitwindow.second << "\n";
+      } else
+        good_fit = true;
+    } else {
+      // use the 1/2 distance to neiboring peak without defined peak window
+      double left_bound(-1);
+      if (peakindex > 0)
+        left_bound = 0.5 * (expected_peak_positions[peakindex] -
+                            expected_peak_positions[peakindex - 1]);
+      double right_bound(-1);
+      if (peakindex < m_numPeaksToFit - 1)
+        right_bound = 0.5 * (expected_peak_positions[peakindex + 1] -
+                             expected_peak_positions[peakindex]);
+      if (left_bound < 0)
+        left_bound = right_bound;
+      if (right_bound < left_bound)
+        right_bound = left_bound;
+      if (left_bound < 0 || right_bound < 0)
+        throw std::runtime_error("Code logic error such that left or right "
+                                 "boundary of peak position is negative.");
+      if (peak_pos < left_bound || peak_pos > right_bound)
+        peak_pos = -2.5;
+      else
+        good_fit = true;
+    }
+  } else if (fabs(fitfunction.peakfunction->centre() -
+                  expected_peak_positions[peakindex]) > postol) {
+    // peak center is not within tolerance
+    peak_pos = -5;
+    g_log.debug() << "Peak position difference "
+                  << fabs(fitfunction.peakfunction->centre() -
+                          expected_peak_positions[peakindex])
+                  << " is out of range of tolerance: " << postol << "\n";
+  } else {
+    // all criteria are passed
+    good_fit = true;
+  }
+
+  // set cost function to DBL_MAX if fitting is bad
+  double adjust_cost(cost);
+  if (!good_fit) {
+    // set the cost function value to DBL_MAX
+    adjust_cost = DBL_MAX;
+  }
+
+  // reset cost
+  if (adjust_cost > DBL_MAX - 1) {
+    fitfunction.peakfunction->setIntensity(0);
+  }
+
+  // chi2
+  fit_result->setRecord(peakindex, adjust_cost, peak_pos, fitfunction);
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+// TODO/NOW - Implement such that it can be parallelized
+/** calculate fitted peaks with background in the output workspace
+ * @brief FitPeaks::calculateFittedPeaks
+ */
+void FitPeaks::calculateFittedPeaks() {
+  // check
+  if (!m_fittedParamTable)
+    throw std::runtime_error("No parameters");
+
+  size_t num_peakfunc_params = m_peakFunction->nParams();
+  size_t num_bkgdfunc_params = m_bkgdFunction->nParams();
+
+  // TODO/LATER - Implement OpenMP parallelizatoin
+  for (size_t iws = m_startWorkspaceIndex; iws <= m_stopWorkspaceIndex; ++iws) {
+    // TODO/LATER - Parallelization macro shall be put here
+
+    // get a copy of peak function and background function
+    IPeakFunction_sptr peak_function =
+        boost::dynamic_pointer_cast<IPeakFunction>(m_peakFunction->clone());
+    IBackgroundFunction_sptr bkgd_function =
+        boost::dynamic_pointer_cast<IBackgroundFunction>(
+            m_bkgdFunction->clone());
+
+    for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+      // get and set the peak function parameters
+      size_t row_index =
+          (iws - m_startWorkspaceIndex) * m_numPeaksToFit + ipeak;
+      for (size_t ipar = 0; ipar < num_peakfunc_params; ++ipar) {
+        double value_i = m_fittedParamTable->cell<double>(row_index, 2 + ipar);
+        peak_function->setParameter(ipar, value_i);
+      }
+
+      // check whether the peak has a fit or not
+      if (fabs(peak_function->height()) < 1.E-20)
+        continue;
+
+      // get and set the background function parameters
+      for (size_t ipar = 0; ipar < num_bkgdfunc_params; ++ipar) {
+        double value_i = m_fittedParamTable->cell<double>(
+            row_index, 2 + num_peakfunc_params + ipar);
+        bkgd_function->setParameter(ipar, value_i);
+      }
+
+      // use domain and function to calcualte
+      // get the range of start and stop to construct a function domain
+      auto vec_x = m_fittedPeakWS->x(iws);
+      std::pair<double, double> peakwindow = getPeakFitWindow(iws, ipeak);
+      std::vector<double>::const_iterator start_x_iter =
+          std::lower_bound(vec_x.begin(), vec_x.end(), peakwindow.first);
+      std::vector<double>::const_iterator stop_x_iter =
+          std::lower_bound(vec_x.begin(), vec_x.end(), peakwindow.second);
+
+      if (start_x_iter == stop_x_iter)
+        throw std::runtime_error("Range size is zero");
+
+      FunctionDomain1DVector domain(start_x_iter, stop_x_iter);
+      FunctionValues values(domain);
+      CompositeFunction_sptr comp_func =
+          boost::make_shared<API::CompositeFunction>();
+      comp_func->addFunction(peak_function);
+      comp_func->addFunction(bkgd_function);
+      comp_func->function(domain, values);
+
+      // copy over the values
+      size_t istart = static_cast<size_t>(start_x_iter - vec_x.begin());
+      size_t istop = static_cast<size_t>(stop_x_iter - vec_x.begin());
+      for (size_t yindex = istart; yindex < istop; ++yindex)
+        m_fittedPeakWS->dataY(iws)[yindex] =
+            values.getCalculated(yindex - istart);
+    } // END-FOR (ipeak)
+  }   // END-FOR (iws)
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/**  Estimate background: There are two methods that will be tried.
+ * First, algorithm FindPeakBackground will be tried;
+ * If it fails, then a linear background estimator will be called.
+ */
+void FitPeaks::estimateBackground(const Histogram &histogram,
+                                  const std::pair<double, double> &peak_window,
+                                  API::IBackgroundFunction_sptr bkgd_function) {
+  if (peak_window.first >= peak_window.second)
+    throw std::runtime_error("Invalid peak window");
+
+  // use the simple way to find linear background
+  double bkgd_a0, bkgd_a1;
+  this->estimateLinearBackground(histogram, peak_window.first,
+                                 peak_window.second, bkgd_a0, bkgd_a1);
+
+  // set result
+  // FIXME - this is not flexible for background other than
+  // flat/linear/quadratic
+  bkgd_function->setParameter(0, bkgd_a0);
+  if (bkgd_function->nParams() > 1)
+    bkgd_function->setParameter(1, bkgd_a1);
+  if (bkgd_function->nParams() > 2)
+    bkgd_function->setParameter(2, 0.);
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/**  Estimate peak profile's parameters values via observation
+ * including
+ * (1) peak center (2) peak intensity  (3) peak width depending on peak type
+ * @brief FitPeaks::EstimatePeakParameters
+ * @param dataws
+ * @param wi
+ * @param peak_window
+ * @param peakfunction
+ * @param bkgdfunction
+ * @param observe_peak_width
+ * @return
+ */
+int FitPeaks::estimatePeakParameters(
+    API::MatrixWorkspace_sptr dataws, size_t wi,
+    const std::pair<double, double> &peak_window,
+    API::IPeakFunction_sptr peakfunction,
+    API::IBackgroundFunction_sptr bkgdfunction, bool observe_peak_width) {
+  // get the range of start and stop to construct a function domain
+  auto vector_x = dataws->x(wi);
+  std::vector<double>::const_iterator start_iter =
+      std::lower_bound(vector_x.begin(), vector_x.end(), peak_window.first);
+  std::vector<double>::const_iterator stop_iter =
+      std::lower_bound(vector_x.begin(), vector_x.end(), peak_window.second);
+  size_t start_index = static_cast<size_t>(start_iter - vector_x.begin());
+  size_t stop_index = static_cast<size_t>(stop_iter - vector_x.begin());
+
+  // calculate background
+  if (start_index == stop_index)
+    throw std::runtime_error("Range size is zero");
+
+  FunctionDomain1DVector domain(start_iter, stop_iter);
+  FunctionValues bkgd_values(domain);
+  bkgdfunction->function(domain, bkgd_values);
+
+  const auto vector_y = dataws->y(wi);
+
+  // Estimate peak center
+  double peak_center, peak_height;
+  size_t peak_center_index;
+  int result = observePeakCenter(vector_x, vector_y, bkgd_values, start_index,
+                                 stop_index, peak_center, peak_center_index,
+                                 peak_height);
+
+  // set the peak center
+  if (result == GOOD) {
+    // use values from background to locate FWHM
+    peakfunction->setCentre(peak_center);
+    peakfunction->setHeight(peak_height);
+  } else {
+    g_log.debug() << "Observation result is NOT good but " << result << "\n";
+  }
+
+  // Estimate FHWM (peak width)
+  if (result == GOOD && observe_peak_width &&
+      m_peakWidthEstimateApproach != EstimatePeakWidth::NoEstimation) {
+    // observe peak width
+    double peak_width =
+        observePeakWidth(vector_x, vector_y, bkgd_values, peak_height,
+                         peak_center_index, start_index, stop_index);
+    if (peak_width > 0) {
+      peakfunction->setFwhm(peak_width);
+    }
+  }
+
+  return result;
+}
+
+//----------------------------------------------------------------------------------------------
+/// Guess/estimate peak center and thus height by observation
+int FitPeaks::observePeakCenter(const HistogramX &vector_x,
+                                const HistogramY &vector_y,
+                                FunctionValues &bkgd_values, size_t start_index,
+                                size_t stop_index, double &peak_center,
+                                size_t &peak_center_index,
+                                double &peak_height) {
+  // initialize paramters
+  double peak_bkgd_max = 0;
+  peak_height = 0;
+  peak_center_index = -1;
+  peak_center = 0;
+
+  // locate highest pure peakk position
+  size_t num_pts = min(stop_index - start_index, bkgd_values.size());
+  for (size_t i = 0; i < num_pts; ++i) {
+    // get index in vector X and y; do the check
+    size_t curr_index =
+        i + start_index; // current index in full vector X. remember that
+    if (curr_index > vector_x.size())
+      throw std::logic_error(
+          "It is not possible to go out of boundary of vector X");
+
+    // get Y value, reduce by background and check against max Y value
+    double y = vector_y[curr_index] - bkgd_values.getCalculated(i);
+    if (y > peak_height) {
+      peak_height = y;
+      peak_center = vector_x[curr_index];
+      peak_center_index = curr_index;
+    }
+    if (vector_y[curr_index] > peak_bkgd_max)
+      peak_bkgd_max = vector_y[curr_index];
+  }
+
+  // check peak height and determine the case integer to return
+  // any case other than GOOD will lead to a non-peak-fit
+  const size_t MAGIC3(3);
+  int result(0);
+  if (peak_bkgd_max < 1.0E-10) {
+    // none-event, but no signal within region
+    result = NOSIGNAL;
+  } else if (peak_height < m_minPeakHeight) {
+    // peak too low
+    result = LOWPEAK;
+  } else if ((peak_center_index - start_index) < MAGIC3 ||
+             (stop_index - peak_center_index) < MAGIC3) {
+    // peak not at center
+    result = OUTOFBOUND;
+  } else {
+    result = GOOD;
+  }
+
+  return result;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief FitPeaks::ObservePeakWidth
+ * @param vector_x
+ * @param vector_y
+ * @param bkgd_values
+ * @param peak_height
+ * @param ipeak
+ * @param istart
+ * @param istop
+ * @return peak width as double
+ */
+double FitPeaks::observePeakWidth(const HistogramX &vector_x,
+                                  const HistogramY &vector_y,
+                                  FunctionValues &bkgd_values,
+                                  double peak_height, size_t ipeak,
+                                  size_t istart, size_t istop) {
+  double peak_width(-0.);
+
+  if (m_peakWidthEstimateApproach == EstimatePeakWidth::InstrumentResolution) {
+    // width from guessing from delta(D)/D
+    double peak_center = vector_x[ipeak];
+    peak_width = peak_center * m_peakDSpacePercentage;
+  } else if (m_peakWidthEstimateApproach == EstimatePeakWidth::Observation) {
+    // observe peak width by estimating FWHM from observation
+    // the approach is to locate the first bin with intensity larger than half
+    // peak height from left and right
+    // check input
+    if (istart >= ipeak || ipeak >= istop)
+      throw std::runtime_error(
+          "Input error for index of peak, left and right side of fit window");
+    if (peak_height <= 0.)
+      throw std::runtime_error(
+          "It is not possible to have sub zero peak height region");
+
+    // search from the left half maximum
+    size_t ileft_max = istart;
+    size_t num_pts = min(istop - istart, bkgd_values.size());
+    for (size_t i = 0; i <= ipeak; ++i) {
+      // get index in vector X and y; do the check
+      size_t curr_index =
+          i + istart; // current index in full vector X. remember that
+      if (curr_index > vector_x.size())
+        throw std::logic_error(
+            "It is not possible to go out of boundary of vector X");
+
+      // get Y value, reduce by background and check against max Y value
+      double y = vector_y[curr_index] - bkgd_values.getCalculated(i);
+      if (y >= 0.5 * peak_height) {
+        ileft_max = curr_index;
+        break;
+      } else if (curr_index == ipeak)
+        throw std::runtime_error("Found peak center point is the only data "
+                                 "point with intensity larger than half "
+                                 "maximum");
+    }
+
+    // search for the right half maximum
+    size_t iright_max = istop;
+    for (size_t i = num_pts - 1; i >= ipeak - istart; --i) {
+      size_t curr_index =
+          i + istart; // current index in full vector X. remember that
+      if (curr_index > vector_x.size())
+        throw std::logic_error(
+            "It is not possible to go out of boundary of vector X");
+
+      // get Y value, reduce by background and check against max Y value
+      double y = vector_y[curr_index] - bkgd_values.getCalculated(i);
+      // first data point larger than half height from right
+      if (y >= 0.5 * peak_height) {
+        iright_max = curr_index;
+        break;
+      } else if (curr_index == ipeak)
+        throw std::runtime_error("Found peak center point is the only data "
+                                 "point with intensity larger than half "
+                                 "maximum");
+    }
+
+    peak_width = vector_x[iright_max] - vector_x[ileft_max];
+  } else {
+    // get from last peak or from input!
+    throw std::runtime_error(
+        "This case for obsering peak width is not supported.");
+  }
+
+  return peak_width;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Fit background function
+ * @brief FitPeaks::FitBackground
+ * @param ws_index
+ * @param fit_window
+ * @param expected_peak_pos
+ * @param bkgd_func
+ * @return
+ */
+bool FitPeaks::fitBackground(const size_t &ws_index,
+                             const std::pair<double, double> &fit_window,
+                             const double &expected_peak_pos,
+                             API::IBackgroundFunction_sptr bkgd_func) {
+
+  // find out how to fit background
+  const auto &points = m_inputMatrixWS->histogram(ws_index).points();
+  size_t start_index = findXIndex(points.rawData(), fit_window.first);
+  size_t stop_index = findXIndex(points.rawData(), fit_window.second);
+  size_t expected_peak_index = findXIndex(points.rawData(), expected_peak_pos);
+
+  // treat 5 as a magic number - TODO explain why
+  bool good_fit(false);
+  if (expected_peak_index - start_index > 10 && // TODO explain why 10
+      stop_index - expected_peak_index - stop_index > 10) {
+    // enough data points left for multi-domain fitting
+    // set a smaller fit window
+    std::vector<double> vec_min(2);
+    std::vector<double> vec_max(2);
+
+    vec_min[0] = fit_window.first;
+    vec_max[0] = points[expected_peak_index - 5];
+    vec_min[1] = points[expected_peak_index + 5];
+    vec_max[1] = fit_window.second;
+
+    // reset background function value
+    bkgd_func->setParameter(0, 0.);
+    if (bkgd_func->nParams() > 1)
+      bkgd_func->setParameter(1, 0.);
+
+    double chi2 =
+        fitFunctionMD(bkgd_func, m_inputMatrixWS, ws_index, vec_min, vec_max);
+
+    // process
+    if (chi2 < DBL_MAX - 1) {
+      good_fit = true;
+    }
+
+  } else {
+    // fit as a single domain function.  check whether the result is good or bad
+
+    // TODO FROM HERE!
+    g_log.error("Don't know what to do with background fitting with single "
+                "domain function!");
+  }
+
+  return good_fit;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Fit an individual peak
+ * @brief FitPeaks::FitIndividualPeak
+ * @param wi
+ * @param fitter
+ * @param expected_peak_center
+ * @param fitwindow
+ * @param high
+ * @param high_background_function
+ * @param observe_peak_width:: flag to estimate peak width (by observation) or
+ * not
+ * @param peakfunction
+ * @param bkgdfunc
+ * @return
+ */
+double FitPeaks::fitIndividualPeak(
+    size_t wi, API::IAlgorithm_sptr fitter, const double expected_peak_center,
+    const std::pair<double, double> &fitwindow, const bool high,
+    API::IBackgroundFunction_sptr high_background_function,
+    const bool observe_peak_width, API::IPeakFunction_sptr peakfunction,
+    API::IBackgroundFunction_sptr bkgdfunc) {
+  double cost(DBL_MAX);
+
+  if (high) {
+    // fit peak with high background!
+    cost = fitFunctionHighBackground(
+        fitter, fitwindow, wi, expected_peak_center, observe_peak_width,
+        peakfunction, bkgdfunc, high_background_function);
+  } else {
+    // fit peak and background
+    cost = fitFunctionSD(fitter, peakfunction, bkgdfunc, m_inputMatrixWS, wi,
+                         fitwindow.first, fitwindow.second,
+                         expected_peak_center, observe_peak_width, true);
+  }
+
+  return cost;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Fit function in single domain (mostly applied for fitting peak + background)
+ * with estimating peak parameters
+ * This is the core fitting algorithm to deal with the simplest situation
+ * @exception :: Fit.isExecuted is false (cannot be executed)
+ * @brief FitPeaks::FitFunctionSD
+ * @param fit
+ * @param peak_function
+ * @param bkgd_function
+ * @param dataws
+ * @param wsindex
+ * @param xmin
+ * @param xmax
+ * @param expected_peak_center
+ * @param observe_peak_width
+ * @param estimate_background
+ * @return
+ */
+double FitPeaks::fitFunctionSD(IAlgorithm_sptr fit,
+                               API::IPeakFunction_sptr peak_function,
+                               API::IBackgroundFunction_sptr bkgd_function,
+                               API::MatrixWorkspace_sptr dataws, size_t wsindex,
+                               double xmin, double xmax,
+                               const double &expected_peak_center,
+                               bool observe_peak_width,
+                               bool estimate_background) {
+
+  // generate peak window
+  std::pair<double, double> peak_window = std::make_pair(xmin, xmax);
+
+  // Estimate background
+  if (estimate_background) {
+    const auto &histogram = dataws->histogram(wsindex);
+    estimateBackground(histogram, peak_window, bkgd_function);
+  } else {
+    for (size_t n = 0; n < bkgd_function->nParams(); ++n)
+      bkgd_function->setParameter(n, 0);
+  }
+
+  // Estimate peak profile parameter
+  int result =
+      estimatePeakParameters(dataws, wsindex, peak_window, peak_function,
+                             bkgd_function, observe_peak_width);
+  if (result != GOOD)
+    peak_function->setCentre(expected_peak_center);
+
+  // Create the composition function
+  CompositeFunction_sptr comp_func =
+      boost::make_shared<API::CompositeFunction>();
+  comp_func->addFunction(peak_function);
+  comp_func->addFunction(bkgd_function);
+  IFunction_sptr fitfunc = boost::dynamic_pointer_cast<IFunction>(comp_func);
+
+  // Set the properties
+  fit->setProperty("Function", fitfunc);
+  fit->setProperty("InputWorkspace", dataws);
+  fit->setProperty("WorkspaceIndex", static_cast<int>(wsindex));
+  fit->setProperty("MaxIterations", 50); // magic number
+  fit->setProperty("StartX", xmin);
+  fit->setProperty("EndX", xmax);
+
+  if (m_constrainPeaksPosition) {
+    // set up a constraint on peak position
+    double peak_center = peak_function->centre();
+    double peak_width = peak_function->fwhm();
+    std::stringstream peak_center_constraint;
+    peak_center_constraint << (peak_center - 0.5 * peak_width) << " < f0."
+                           << peak_function->getCentreParameterName() << " < "
+                           << (peak_center + 0.5 * peak_width);
+
+    // set up a constraint on peak height
+
+    fit->setProperty("Constraints", peak_center_constraint.str());
+  }
+
+  // Execute fit and get result of fitting background
+  // m_sstream << "FitSingleDomain: " << fit->asString() << ".\n";
+  g_log.debug() << "[E1201] FitSingleDomain Before fitting, Fit function: "
+                << fit->asString() << "\n";
+
+  fit->executeAsChildAlg();
+
+  g_log.debug() << "[E1202] FitSingleDomain After fitting, Fit function: "
+                << fit->asString() << "\n";
+
+  if (!fit->isExecuted()) {
+    g_log.error("Fitting peak SD (single domain) failed to execute.");
+    throw std::runtime_error(
+        "Fitting peak SD (single domain) failed to execute.");
+  }
+
+  // Retrieve result
+  std::string fitStatus = fit->getProperty("OutputStatus");
+  double chi2 = DBL_MAX;
+  if (fitStatus == "success") {
+    chi2 = fit->getProperty("OutputChi2overDoF");
+    fitfunc = fit->getProperty("Function");
+  }
+
+  return chi2;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief FitPeaks::FitFunctionMD
+ * @param fit_function :: function to fit
+ * @param dataws :: matrix workspace to fit with
+ * @param wsindex ::  workspace index of the spectrum in matrix workspace
+ * @param vec_xmin :: minimin values of domains
+ * @param vec_xmax :: maximim values of domains
+ * @return
+ */
+double FitPeaks::fitFunctionMD(API::IFunction_sptr fit_function,
+                               API::MatrixWorkspace_sptr dataws, size_t wsindex,
+                               std::vector<double> &vec_xmin,
+                               std::vector<double> &vec_xmax) {
+  // Validate
+  if (vec_xmin.size() != vec_xmax.size())
+    throw runtime_error("Sizes of xmin and xmax (vectors) are not equal. ");
+
+  // Note: after testing it is found that multi-domain Fit cannot be reused
+  API::IAlgorithm_sptr fit;
+  try {
+    fit = createChildAlgorithm("Fit", -1, -1, false);
+  } catch (Exception::NotFoundError &) {
+    std::stringstream errss;
+    errss << "The FitPeak algorithm requires the CurveFitting library";
+    throw std::runtime_error(errss.str());
+  }
+  // set up background fit instance
+  fit->setProperty("Minimizer", m_minimizer);
+  fit->setProperty("CostFunction", m_costFunction);
+  fit->setProperty("CalcErrors", true);
+
+  // This use multi-domain; but does not know how to set up IFunction_sptr
+  // fitfunc,
+  boost::shared_ptr<MultiDomainFunction> md_function =
+      boost::make_shared<MultiDomainFunction>();
+
+  // Set function first
+  md_function->addFunction(fit_function);
+
+  //  set domain for function with index 0 covering both sides
+  md_function->clearDomainIndices();
+  std::vector<size_t> ii(2);
+  ii[0] = 0;
+  ii[1] = 1;
+  md_function->setDomainIndices(0, ii);
+
+  // Set the properties
+  fit->setProperty("Function",
+                   boost::dynamic_pointer_cast<IFunction>(md_function));
+  fit->setProperty("InputWorkspace", dataws);
+  fit->setProperty("WorkspaceIndex", static_cast<int>(wsindex));
+  fit->setProperty("StartX", vec_xmin[0]);
+  fit->setProperty("EndX", vec_xmax[0]);
+  fit->setProperty("InputWorkspace_1", dataws);
+  fit->setProperty("WorkspaceIndex_1", static_cast<int>(wsindex));
+  fit->setProperty("StartX_1", vec_xmin[1]);
+  fit->setProperty("EndX_1", vec_xmax[1]);
+  fit->setProperty("MaxIterations", 50);
+
+  // Execute
+  fit->execute();
+  if (!fit->isExecuted()) {
+    throw runtime_error("Fit is not executed on multi-domain function/data. ");
+  }
+
+  // Retrieve result
+  std::string fitStatus = fit->getProperty("OutputStatus");
+
+  double chi2 = DBL_MAX;
+  if (fitStatus == "success") {
+    chi2 = fit->getProperty("OutputChi2overDoF");
+  }
+
+  return chi2;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Fit peak with high background
+ * @brief FitPeaks::FitFunctionHighBackground
+ * @param fit
+ * @param fit_window
+ * @param ws_index
+ * @param expected_peak_center
+ * @param observe_peak_width
+ * @param peakfunction
+ * @param bkgdfunc
+ * @param high_bkgd_function
+ * @return
+ */
+double FitPeaks::fitFunctionHighBackground(
+    IAlgorithm_sptr fit, const std::pair<double, double> &fit_window,
+    const size_t &ws_index, const double &expected_peak_center,
+    bool observe_peak_width, API::IPeakFunction_sptr peakfunction,
+    API::IBackgroundFunction_sptr bkgdfunc,
+    API::IBackgroundFunction_sptr high_bkgd_function) {
+  // Fit the background first if there is enough data points
+  fitBackground(ws_index, fit_window, expected_peak_center, high_bkgd_function);
+
+  // Get partial of the data
+  std::vector<double> vec_x, vec_y, vec_e;
+  getRangeData(ws_index, fit_window, vec_x, vec_y, vec_e);
+
+  // Reduce the background
+  reduceBackground(high_bkgd_function, vec_x, vec_y);
+
+  // Create a new workspace
+  API::MatrixWorkspace_sptr reduced_bkgd_ws =
+      createMatrixWorkspace(vec_x, vec_y, vec_e);
+
+  // Fit peak with background
+  double cost = fitFunctionSD(fit, peakfunction, bkgdfunc, reduced_bkgd_ws, 0,
+                              vec_x.front(), vec_x.back(), expected_peak_center,
+                              observe_peak_width, false);
+
+  // add the reduced background back
+  bkgdfunc->setParameter(0, bkgdfunc->getParameter(0) +
+                                high_bkgd_function->getParameter(0));
+  bkgdfunc->setParameter(1, bkgdfunc->getParameter(1) +
+                                high_bkgd_function->getParameter(1));
+
+  return cost;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Create a single spectrum workspace for fitting
+ * @brief FitPeaks::CreateMatrixWorkspace
+ * @param vec_x
+ * @param vec_y
+ * @param vec_e
+ * @return
+ */
+API::MatrixWorkspace_sptr
+FitPeaks::createMatrixWorkspace(const std::vector<double> &vec_x,
+                                const std::vector<double> &vec_y,
+                                const std::vector<double> &vec_e) {
+  size_t size = vec_x.size();
+  size_t ysize = vec_y.size();
+
+  MatrixWorkspace_sptr matrix_ws =
+      WorkspaceFactory::Instance().create("Workspace2D", 1, size, ysize);
+
+  auto &dataX = matrix_ws->mutableX(0);
+  auto &dataY = matrix_ws->mutableY(0);
+  auto &dataE = matrix_ws->mutableE(0);
+
+  dataX.assign(vec_x.cbegin(), vec_x.cend());
+  dataY.assign(vec_y.cbegin(), vec_y.cend());
+  dataE.assign(vec_e.cbegin(), vec_e.cend());
+
+  return matrix_ws;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief FitPeaks::generateOutputWorkspaces
+ */
+void FitPeaks::generateOutputPeakPositionWS() {
+  // create output workspace for peak positions: can be partial spectra to input
+  // workspace
+  size_t num_hist = m_stopWorkspaceIndex - m_startWorkspaceIndex + 1;
+  m_outputPeakPositionWorkspace = WorkspaceFactory::Instance().create(
+      "Workspace2D", num_hist, m_numPeaksToFit, m_numPeaksToFit);
+  // set default
+  for (size_t wi = 0; wi < num_hist; ++wi) {
+    // TODO - Parallization OpenMP
+
+    // convert to workspace index of input data workspace
+    size_t inp_wi = wi + m_startWorkspaceIndex;
+    std::vector<double> expected_position = getExpectedPeakPositions(inp_wi);
+    for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+      m_outputPeakPositionWorkspace->dataX(wi)[ipeak] =
+          expected_position[ipeak];
+    }
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief FitPeaks::GenerateFittedParametersValueWorkspace
+ */
+void FitPeaks::generateFittedParametersValueWorkspace() {
+  // peak parameter workspace
+  std::string param_table_name =
+      getPropertyValue("OutputPeakParametersWorkspace");
+
+  // check whether it is not asked to create such table workspace
+  if (param_table_name.size() == 0) {
+    // Skip if it is not specified
+    m_fittedParamTable = nullptr;
+    return;
+  }
+
+  // create
+  m_fittedParamTable =
+      WorkspaceFactory::Instance().createTable("TableWorkspace");
+  // add columns
+  m_fittedParamTable->addColumn("int", "wsindex");
+  m_fittedParamTable->addColumn("int", "peakindex");
+  for (size_t iparam = 0; iparam < m_peakFunction->nParams(); ++iparam)
+    m_fittedParamTable->addColumn("double",
+                                  m_peakFunction->parameterName(iparam));
+  for (size_t iparam = 0; iparam < m_bkgdFunction->nParams(); ++iparam)
+    m_fittedParamTable->addColumn("double",
+                                  m_bkgdFunction->parameterName(iparam));
+  m_fittedParamTable->addColumn("double", "chi2");
+
+  // add rows
+  for (size_t iws = m_startWorkspaceIndex; iws <= m_stopWorkspaceIndex; ++iws) {
+    for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+      size_t row_index = m_fittedParamTable->rowCount();
+      m_fittedParamTable->appendRow();
+      m_fittedParamTable->cell<int>(row_index, static_cast<size_t>(0)) =
+          static_cast<int>(iws);
+      m_fittedParamTable->cell<int>(row_index, 1) = static_cast<int>(ipeak);
+    }
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Generate the output MatrixWorkspace for calculated peaks
+ * @brief FitPeaks::GenerateCalculatedPeaksWS
+ */
+void FitPeaks::generateCalculatedPeaksWS() {
+  // matrix workspace contained calculated peaks from fitting
+  std::string fit_ws_name = getPropertyValue("FittedPeaksWorkspace");
+  if (fit_ws_name.size() == 0) {
+    // skip if user does not specify
+    m_fittedPeakWS = nullptr;
+    return;
+  }
+
+  // create
+  m_fittedPeakWS = API::WorkspaceFactory::Instance().create(m_inputMatrixWS);
+  for (size_t iws = 0; iws < m_fittedPeakWS->getNumberHistograms(); ++iws) {
+    auto out_vecx = m_fittedPeakWS->histogram(iws).x();
+    auto in_vecx = m_inputMatrixWS->histogram(iws).x();
+    for (size_t j = 0; j < out_vecx.size(); ++j) {
+      m_fittedPeakWS->dataX(iws)[j] = in_vecx[j];
+    }
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/** set up output workspaces
+ * @brief FitPeaks::setOutputProperties
+ */
+void FitPeaks::processOutputs() {
+  setProperty("OutputWorkspace", m_outputPeakPositionWorkspace);
+
+  // optional
+  if (m_fittedParamTable)
+    setProperty("OutputPeakParametersWorkspace", m_fittedParamTable);
+
+  // optional
+  if (m_fittedPeakWS && m_fittedParamTable) {
+    g_log.debug("about to calcualte fitted peaks");
+    calculateFittedPeaks();
+    setProperty("FittedPeaksWorkspace", m_fittedPeakWS);
+  }
+}
+
+//----------------------------------------------------------------------------------------------
+/** Get the expected peak's position
+ * @brief FitPeaks::getExpectedPeakPositions
+ * @param wi
+ * @return
+ */
+std::vector<double> FitPeaks::getExpectedPeakPositions(size_t wi) {
+  // check
+  if (wi < m_startWorkspaceIndex || wi > m_stopWorkspaceIndex) {
+    std::stringstream errss;
+    errss << "Workspace index " << wi << " is out of range ["
+          << m_startWorkspaceIndex << ", " << m_stopWorkspaceIndex << "]";
+    throw std::runtime_error(errss.str());
+  }
+
+  // initialize output array
+  std::vector<double> exp_centers(m_numPeaksToFit);
+
+  if (m_uniformPeakPositions) {
+    // uniform peak centers among spectra: simple copy
+    exp_centers = m_peakCenters;
+  } else {
+    // no uniform peak center.  locate the input workspace index
+    // in the peak center workspace peak in the workspae
+
+    // get the relative workspace index in input peak position workspace
+    size_t peak_wi = wi - m_startWorkspaceIndex;
+    // get values
+    exp_centers = m_peakCenterWorkspace->y(peak_wi).rawData();
+  }
+
+  return exp_centers;
+}
+
+//----------------------------------------------------------------------------------------------
+/** get the peak fit window
+ * @brief FitPeaks::getPeakFitWindow
+ * @param wi
+ * @param ipeak :: index of peak
+ * @return
+ */
+std::pair<double, double> FitPeaks::getPeakFitWindow(size_t wi, size_t ipeak) {
+  // check workspace index
+  if (wi < m_startWorkspaceIndex || wi > m_stopWorkspaceIndex) {
+    std::stringstream errss;
+    errss << "Workspace index " << wi << " is out of range ["
+          << m_startWorkspaceIndex << ", " << m_stopWorkspaceIndex << "]";
+    throw std::runtime_error(errss.str());
+  }
+
+  // check peak index
+  if (ipeak >= m_numPeaksToFit) {
+    std::stringstream errss;
+    errss << "Peak index " << ipeak << " is out of range (" << m_numPeaksToFit
+          << ")";
+    throw std::runtime_error(errss.str());
+  }
+
+  double left(0), right(0);
+  if (m_calculateWindowInstrument) {
+    // calcualte peak window by delta(d)/d
+    double peak_pos = getExpectedPeakPositions(wi)[ipeak];
+    // calcalate expected peak width
+    double estimate_peak_width = peak_pos * m_peakDSpacePercentage;
+    // using a MAGIC number to estimate the peak window
+    double MAGIC = 3.0;
+    left = peak_pos - estimate_peak_width * MAGIC;
+    right = peak_pos + estimate_peak_width * MAGIC;
+  } else if (m_uniformPeakWindows) {
+    // uniform peak fit window
+    assert(m_peakWindowVector.size() > 0); // peak fit window must be given!
+
+    left = m_peakWindowVector[ipeak][0];
+    right = m_peakWindowVector[ipeak][1];
+  } else if (m_peakWindowWorkspace) {
+    // no uniform peak fit window.  locate peak in the workspace
+    // get workspace index in m_peakWindowWorkspace
+    size_t window_wi = wi - m_startWorkspaceIndex;
+
+    left = m_peakWindowWorkspace->y(window_wi)[ipeak * 2];
+    right = m_peakWindowWorkspace->y(window_wi)[ipeak * 2 + 1];
+  } else {
+    throw std::runtime_error("Unhandled case for get peak fit window!");
+  }
+
+  return std::make_pair(left, right);
+}
+
+//----------------------------------------------------------------------------------------------
+/** get vector X, Y and E in a given range
+ * @brief FitPeaks::GetRangeData
+ * @param iws
+ * @param fit_window
+ * @param vec_x
+ * @param vec_y
+ * @param vec_e
+ */
+void FitPeaks::getRangeData(size_t iws,
+                            const std::pair<double, double> &fit_window,
+                            std::vector<double> &vec_x,
+                            std::vector<double> &vec_y,
+                            std::vector<double> &vec_e) {
+
+  // get the original vector of X and determine the start and end index
+  const vector<double> orig_x = m_inputMatrixWS->histogram(iws).x().rawData();
+  size_t left_index =
+      std::lower_bound(orig_x.begin(), orig_x.end(), fit_window.first) -
+      orig_x.begin();
+  size_t right_index =
+      std::lower_bound(orig_x.begin(), orig_x.end(), fit_window.second) -
+      orig_x.begin();
+  if (left_index >= right_index) {
+    std::stringstream err_ss;
+    err_ss << "Unable to get subset of histogram from given fit window. "
+           << "Fit window: " << fit_window.first << ", " << fit_window.second
+           << ". Vector X's range is " << orig_x.front() << ", "
+           << orig_x.back();
+    throw std::runtime_error(err_ss.str());
+  }
+
+  // copy X, Y and E
+  size_t num_elements = right_index - left_index;
+  vec_x.resize(num_elements);
+  std::copy(orig_x.begin() + left_index, orig_x.begin() + right_index,
+            vec_x.begin());
+
+  // modify right_index if it is at the end
+  if (m_inputMatrixWS->isHistogramData() && right_index == orig_x.size() - 1) {
+    right_index -= 1;
+    if (right_index == left_index)
+      throw std::runtime_error("Histogram workspace have same left and right "
+                               "boundary index for Y and E.");
+    num_elements -= 1;
+  }
+
+  // get original vector of Y and E
+  const std::vector<double> orig_y =
+      m_inputMatrixWS->histogram(iws).y().rawData();
+  const std::vector<double> orig_e =
+      m_inputMatrixWS->histogram(iws).e().rawData();
+  vec_y.resize(num_elements);
+  vec_e.resize(num_elements);
+  std::copy(orig_y.begin() + left_index, orig_y.begin() + right_index,
+            vec_y.begin());
+  std::copy(orig_e.begin() + left_index, orig_e.begin() + right_index,
+            vec_e.begin());
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+// find 2 local minima: draw a line as background to reduce
+// find 1 local minima: a flat background
+void FitPeaks::reduceBackground(API::IBackgroundFunction_sptr bkgd_func,
+                                const std::vector<double> &vec_x,
+                                std::vector<double> &vec_y) {
+
+  // find out all local minima
+  std::vector<size_t> local_min_indices;
+  if ((vec_y)[0] <= (vec_y)[1])
+    local_min_indices.push_back(0);
+  for (size_t i = 1; i < vec_y.size() - 1; ++i) {
+    if ((vec_y)[i] <= (vec_y)[i - 1] && (vec_y)[i] <= (vec_y)[i + 1])
+      local_min_indices.push_back(i);
+  }
+  size_t lastindex = vec_y.size() - 1;
+  if ((vec_y)[lastindex] <= (vec_y)[lastindex - 1])
+    local_min_indices.push_back(lastindex);
+
+  if (local_min_indices.size() == 0)
+    throw std::runtime_error(
+        "It is not possible to have less than 0 local minimum for a peak");
+
+  FunctionDomain1DVector vectorx(vec_x.begin(), vec_x.end());
+  FunctionValues vector_bkgd(vectorx);
+  bkgd_func->function(vectorx, vector_bkgd);
+
+  // Reduce the background from the calculated background
+  for (size_t i = 0; i < vec_y.size(); ++i) {
+    (vec_y)[i] -= vector_bkgd[i];
+    // it is better not to mess up with E here
+  }
+
+  return;
+}
+
+void FitPeaks::estimateLinearBackground(const Histogram &histogram,
+                                        double left_window_boundary,
+                                        double right_window_boundary,
+                                        double &bkgd_a0, double &bkgd_a1) {
+  const auto &vecX = histogram.points();
+  size_t istart = findXIndex(vecX.rawData(), left_window_boundary);
+  size_t istop = findXIndex(vecX.rawData(), right_window_boundary);
+
+  double bg2, chisq;
+  // TODO explain why 3 is the right number
+  HistogramData::estimateBackground(1, histogram, istart, istop, istart + 3,
+                                    istop - 3, bkgd_a0, bkgd_a1, bg2, chisq);
+}
+
+//----------------------------------------------------------------------------------------------
+/**  Write result of peak fit per spectrum to output analysis workspaces
+ * @brief FitPeaks::writeFitResult
+ * @param wi
+ * @param expected_positions
+ * @param fit_result
+ * @param noevents
+ */
+void FitPeaks::writeFitResult(
+    size_t wi, const std::vector<double> &expected_positions,
+    boost::shared_ptr<FitPeaksAlgorithm::PeakFitResult> fit_result,
+    bool noevents) {
+
+  // convert to
+  size_t out_wi = wi - m_startWorkspaceIndex;
+  if (out_wi >= m_outputPeakPositionWorkspace->getNumberHistograms()) {
+    g_log.error() << "workspace index " << wi
+                  << " is out of output peak position workspace "
+                  << "range of spectra, which contains "
+                  << m_outputPeakPositionWorkspace->getNumberHistograms()
+                  << " spectra"
+                  << "\n";
+    throw std::runtime_error(
+        "Out of boundary to set output peak position workspace");
+  }
+
+  // Fill the output peak position workspace
+  for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+    double exp_peak_pos(expected_positions[ipeak]);
+    double fitted_peak_pos(-1); // default for no event or no signal
+    double peak_chi2(-1E20);    // use negative number for NO fit
+    if (!noevents) {
+      fitted_peak_pos =
+          fit_result->getPeakPosition(ipeak); // fitted_positions[ipeak];
+      peak_chi2 = fit_result->getCost(ipeak); // peak_chi2_vec[ipeak];
+    }
+
+    m_outputPeakPositionWorkspace->mutableX(out_wi)[ipeak] = exp_peak_pos;
+    m_outputPeakPositionWorkspace->mutableY(out_wi)[ipeak] = fitted_peak_pos;
+    m_outputPeakPositionWorkspace->mutableE(out_wi)[ipeak] = peak_chi2;
+  }
+
+  // return if it is not asked to write fitted peak parameters
+  if (!m_fittedParamTable)
+    return;
+
+  // Output the peak parameters to the table workspace
+  // check vector size
+
+  // last column of the table is for chi2
+  size_t chi2_index = m_fittedParamTable->columnCount() - 1;
+  for (size_t ipeak = 0; ipeak < m_numPeaksToFit; ++ipeak) {
+    // get row number
+    size_t row_index = out_wi * m_numPeaksToFit + ipeak;
+    // check again with the column size versus peak parameter values
+    if (fit_result->getNumberParameters() !=
+        m_fittedParamTable->columnCount() - 3) {
+      g_log.error() << "Peak " << ipeak << " has "
+                    << fit_result->getNumberParameters()
+                    << " parameters.  Parameter table shall have 3 more "
+                       "columns.  But not it has "
+                    << m_fittedParamTable->columnCount() << " columns\n";
+      throw std::runtime_error(
+          "Peak parameter vector for one peak has different sizes to output "
+          "table workspace");
+    }
+
+    if (noevents) {
+      // no signals: just pass
+      ;
+    } else {
+      // case for fit peak with signals
+      for (size_t iparam = 0;
+           iparam <
+               fit_result
+                   ->getNumberParameters(); // peak_parameters[ipeak].size();
+           ++iparam) {
+        size_t col_index = iparam + 2;
+        if (col_index >= m_fittedParamTable->columnCount()) {
+          stringstream err_ss;
+          err_ss << "Try to access FittedParamTable's " << col_index
+                 << "-th column, which is out of range [0, "
+                 << m_fittedParamTable->columnCount() << ")";
+          const std::vector<std::string> &col_names =
+              m_fittedParamTable->getColumnNames();
+          for (const auto &name : col_names)
+            err_ss << name << "  ";
+          throw std::runtime_error(err_ss.str());
+        }
+        m_fittedParamTable->cell<double>(row_index, col_index) =
+            fit_result->getParameterValue(ipeak, iparam);
+      } // end for (iparam)
+      // set chi2
+      m_fittedParamTable->cell<double>(row_index, chi2_index) =
+          fit_result->getCost(ipeak);
+    }
+  }
+
+  return;
+}
+
+//----------------------------------------------------------------------------------------------
+/**
+ * @brief FitPeaks::getPeakHeightParameterName
+ * @param peak_function
+ * @return
+ */
+std::string FitPeaks::getPeakHeightParameterName(
+    API::IPeakFunction_const_sptr peak_function) {
+  std::string height_name("");
+
+  std::vector<std::string> peak_parameters = peak_function->getParameterNames();
+  for (const auto &name : peak_parameters) {
+    if (name == "Height") {
+      height_name = "Height";
+      break;
+    } else if (name == "I") {
+      height_name = "I";
+      break;
+    } else if (name == "Intensity") {
+      height_name = "Intensity";
+      break;
+    }
+  }
+
+  if (height_name.empty())
+    throw std::runtime_error("Peak height parameter name cannot be found.");
+
+  return height_name;
+}
+
+DECLARE_ALGORITHM(FitPeaks)
+
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Framework/Algorithms/src/GeneratePeaks.cpp b/Framework/Algorithms/src/GeneratePeaks.cpp
index 474c3b71b9c14945a862905ea029c071e8139b33..880d8d42a5ef43323bc2973331caa188e0870847 100644
--- a/Framework/Algorithms/src/GeneratePeaks.cpp
+++ b/Framework/Algorithms/src/GeneratePeaks.cpp
@@ -769,11 +769,11 @@ GeneratePeaks::createDataWorkspace(std::vector<double> binparameters) {
   }
 
   Indexing::IndexInfo indices(specNums.size());
-  indices.setSpectrumNumbers(std::move(specNums));
   // There is no instrument, so the automatic build of a 1:1 mapping would fail.
   // Need to set empty grouping manually.
   indices.setSpectrumDefinitions(
       std::vector<SpectrumDefinition>(specNums.size()));
+  indices.setSpectrumNumbers(std::move(specNums));
   return create<Workspace2D>(indices, BinEdges(std::move(xarray)));
 }
 
diff --git a/Framework/Algorithms/src/MagFormFactorCorrection.cpp b/Framework/Algorithms/src/MagFormFactorCorrection.cpp
index ed5942f120738cef99b2c1a83917f8dda51feda5..cacd1d509d9f2e28abf8781e684fcb900462ec9f 100644
--- a/Framework/Algorithms/src/MagFormFactorCorrection.cpp
+++ b/Framework/Algorithms/src/MagFormFactorCorrection.cpp
@@ -84,8 +84,8 @@ void MagFormFactorCorrection::exec() {
   // Gets the vector of form factor values
   std::vector<double> FF;
   FF.reserve(Qvals.size());
-  for (int64_t iQ = 0; iQ < (int64_t)Qvals.size(); iQ++) {
-    FF.push_back(ion.analyticalFormFactor(Qvals[iQ] * Qvals[iQ]));
+  for (double Qval : Qvals) {
+    FF.push_back(ion.analyticalFormFactor(Qval * Qval));
   }
   if (!ffwsStr.empty()) {
     MatrixWorkspace_sptr ffws = API::WorkspaceFactory::Instance().create(
diff --git a/Framework/Algorithms/src/MaxEnt.cpp b/Framework/Algorithms/src/MaxEnt.cpp
index a87781e0f0bf5a2e7cfc7071efcfe2602e1df43c..c6d708b81a3877fc27f798b9d7e83b2181edea8e 100644
--- a/Framework/Algorithms/src/MaxEnt.cpp
+++ b/Framework/Algorithms/src/MaxEnt.cpp
@@ -53,39 +53,35 @@ const double THRESHOLD = 1E-6;
 
 /** removes zeros from converged results
 * @param ws :: [input] The input workspace with zeros
-* @param maxIt :: [input] The max number of iteration this alg used
+* @param itCount [input] The number of iterations this alg used for each
+* spectrum
 * @param yLabel :: [input] y-label to use for returned ws
 * @return : ws cut down in lenght to maxIt
 */
-MatrixWorkspace_sptr removeZeros(const MatrixWorkspace_sptr &ws,
-                                 const size_t maxIt,
-                                 const ::std::string yLabel) {
+MatrixWorkspace_sptr removeZeros(MatrixWorkspace_sptr &ws,
+                                 const std::vector<size_t> &itCount,
+                                 const std::string &yLabel) {
 
   ws->setYUnitLabel(yLabel);
-  try {
-    ws->getAxis(0)->unit() =
-        UnitFactory::Instance().create("Number of Iterations");
-  } catch (Exception::NotFoundError &) {
-    ws->getAxis(0)->unit() = UnitFactory::Instance().create("Label");
-    Unit_sptr unit = ws->getAxis(0)->unit();
-    boost::shared_ptr<Units::Label> label =
-        boost::dynamic_pointer_cast<Units::Label>(unit);
-    label->setLabel("Number of Iterations", "");
-  }
+  ws->getAxis(0)->unit() = UnitFactory::Instance().create("Label");
+  Unit_sptr unit = ws->getAxis(0)->unit();
+  boost::shared_ptr<Units::Label> label =
+      boost::dynamic_pointer_cast<Units::Label>(unit);
+  label->setLabel("Number of Iterations", "");
 
-  if (maxIt == ws->readY(0).size()) {
-    return ws;
-  }
   const size_t nspec = ws->getNumberHistograms();
-  MatrixWorkspace_sptr outWS =
-      WorkspaceFactory::Instance().create(ws, nspec, maxIt, maxIt);
+  if (itCount.empty()) {
+    return ws; // In case, we don't have any spectra
+  }
   for (size_t spec = 0; spec < nspec; spec++) {
-    outWS->setPoints(spec, Points(maxIt, LinearGenerator(0.0, 1.0)));
-    auto Data = ws->readY(spec);
-    outWS->setCounts(spec,
-                     std::vector<double>(Data.begin(), Data.begin() + maxIt));
+    auto &dataX = ws->dataX(spec);
+    dataX.resize(itCount[spec]);
+    auto &dataY = ws->dataY(spec);
+    dataY.resize(itCount[spec]);
+    auto &dataE = ws->dataE(spec);
+    dataE.resize(itCount[spec]);
   }
-  return outWS;
+  return ws;
 }
 }
 
@@ -274,14 +270,14 @@ void MaxEnt::exec() {
   // Distance penalty for current image
   const double distEps = getProperty("DistancePenalty");
   // Maximum number of iterations
-  const size_t niter = getProperty("MaxIterations");
+  const size_t nIter = getProperty("MaxIterations");
   // Maximum number of iterations in alpha chop
   const size_t alphaIter = getProperty("AlphaChopIterations");
   // Number of spectra and datapoints
   // Read input workspace
   MatrixWorkspace_const_sptr inWS = getProperty("InputWorkspace");
   // Number of spectra
-  size_t nspec = inWS->getNumberHistograms();
+  size_t nSpec = inWS->getNumberHistograms();
   // Number of data points - assumed to be constant between spectra or
   // this will throw an exception
   size_t npoints = inWS->blocksize() * resolutionFactor;
@@ -290,7 +286,7 @@ void MaxEnt::exec() {
 
   // For now have the requirement that data must have non-zero
   // (and positive!) errors
-  for (size_t s = 0; s < nspec; s++) {
+  for (size_t s = 0; s < nSpec; s++) {
     auto errors = inWS->e(s).rawData();
 
     size_t npoints = errors.size();
@@ -337,22 +333,24 @@ void MaxEnt::exec() {
   MatrixWorkspace_sptr outEvolChi;
   MatrixWorkspace_sptr outEvolTest;
 
-  nspec = complexData ? nspec / 2 : nspec;
+  nSpec = complexData ? nSpec / 2 : nSpec;
   outImageWS =
-      WorkspaceFactory::Instance().create(inWS, 2 * nspec, npoints, npoints);
+      WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npoints, npoints);
   for (size_t i = 0; i < outImageWS->getNumberHistograms(); ++i)
     outImageWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1));
   outDataWS =
-      WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints);
+      WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npointsX, npoints);
   for (size_t i = 0; i < outDataWS->getNumberHistograms(); ++i)
     outDataWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1));
-  outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter);
-  outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter);
+  outEvolChi = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter);
+  outEvolTest = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter);
 
   npoints = complexImage ? npoints * 2 : npoints;
-  size_t maxIt = 0; // used to determine max iterations used by alg
-  outEvolChi->setPoints(0, Points(niter, LinearGenerator(0.0, 1.0)));
-  for (size_t s = 0; s < nspec; s++) {
+  std::vector<size_t> iterationCounts;
+  iterationCounts.reserve(nSpec);
+  outEvolChi->setPoints(0, Points(nIter, LinearGenerator(0.0, 1.0)));
+
+  for (size_t spec = 0; spec < nSpec; spec++) {
 
     // Start distribution (flat background)
     std::vector<double> image(npoints, background);
@@ -360,22 +358,22 @@ void MaxEnt::exec() {
     std::vector<double> data;
     std::vector<double> errors;
     if (complexData) {
-      data = toComplex(inWS, s, false);  // false -> data
-      errors = toComplex(inWS, s, true); // true -> errors
+      data = toComplex(inWS, spec, false);  // false -> data
+      errors = toComplex(inWS, spec, true); // true -> errors
     } else {
-      data = inWS->y(s).rawData();
-      errors = inWS->e(s).rawData();
+      data = inWS->y(spec).rawData();
+      errors = inWS->e(spec).rawData();
     }
 
     // To record the algorithm's progress
-    std::vector<double> evolChi(niter, 0.);
-    std::vector<double> evolTest(niter, 0.);
+    std::vector<double> evolChi(nIter, 0.);
+    std::vector<double> evolTest(nIter, 0.);
 
     // Progress
-    Progress progress(this, 0.0, 1.0, niter);
+    Progress progress(this, 0.0, 1.0, nIter);
 
     // Run maxent algorithm
-    for (size_t it = 0; it < niter; it++) {
+    for (size_t it = 0; it < nIter; it++) {
 
       // Iterates one step towards the solution. This means calculating
       // quadratic coefficients, search directions, angle and chi-sq
@@ -397,15 +395,15 @@ void MaxEnt::exec() {
       double currAngle = maxentCalculator.getAngle();
       evolChi[it] = currChisq;
       evolTest[it] = currAngle;
-      if (it > maxIt) {
-        maxIt = it;
-      }
+
       // Stop condition, solution found
       if ((std::abs(currChisq / ChiTargetOverN - 1.) < chiEps) &&
           (currAngle < angle)) {
 
-        g_log.information() << "Stopped after " << it << " iterations"
+        // it + 1 iterations have been done because we count from zero
+        g_log.information() << "Stopped after " << it + 1 << " iterations"
                             << std::endl;
+        iterationCounts.push_back(it + 1);
         break;
       }
 
@@ -416,32 +414,32 @@ void MaxEnt::exec() {
 
       progress.report();
 
-    } // iterations
+    } // Next Iteration
 
     // Get calculated data
     auto solData = maxentCalculator.getReconstructedData();
     auto solImage = maxentCalculator.getImage();
 
     // Populate the output workspaces
-    populateDataWS(inWS, s, nspec, solData, complexData, outDataWS);
-    populateImageWS(inWS, s, nspec, solImage, complexImage, outImageWS,
+    populateDataWS(inWS, spec, nSpec, solData, complexData, outDataWS);
+    populateImageWS(inWS, spec, nSpec, solImage, complexImage, outImageWS,
                     autoShift);
 
     // Populate workspaces recording the evolution of Chi and Test
     // X values
-    outEvolChi->setSharedX(s, outEvolChi->sharedX(0));
-    outEvolTest->setSharedX(s, outEvolChi->sharedX(0));
+    outEvolChi->setSharedX(spec, outEvolChi->sharedX(0));
+    outEvolTest->setSharedX(spec, outEvolChi->sharedX(0));
 
     // Y values
-    outEvolChi->setCounts(s, std::move(evolChi));
-    outEvolTest->setCounts(s, std::move(evolTest));
+    outEvolChi->setCounts(spec, std::move(evolChi));
+    outEvolTest->setCounts(spec, std::move(evolTest));
     // No errors
 
   } // Next spectrum
-  // add 1 to maxIt to account for starting at 0
-  maxIt++;
-  setProperty("EvolChi", removeZeros(outEvolChi, maxIt, "Chi squared"));
-  setProperty("EvolAngle", removeZeros(outEvolTest, maxIt, "Maximum Angle"));
+  setProperty("EvolChi",
+              removeZeros(outEvolChi, iterationCounts, "Chi squared"));
+  setProperty("EvolAngle",
+              removeZeros(outEvolTest, iterationCounts, "Maximum Angle"));
   setProperty("ReconstructedImage", outImageWS);
   setProperty("ReconstructedData", outDataWS);
 }
diff --git a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
index 744a0f5aed4c277ecc40eef434ff96b0855e13b5..11eba34270c9eae24ac23507b533dd1b1d5084d3 100644
--- a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
+++ b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
@@ -51,7 +51,7 @@ void MonitorEfficiencyCorUser::exec() {
   // file
   try {
     mon_counts_log = getValFromInstrumentDef("monitor_counts_log");
-  } catch (Kernel::Exception::InstrumentDefinitionError) {
+  } catch (Kernel::Exception::InstrumentDefinitionError &) {
     // the default value is monitor_counts
     mon_counts_log = "monitor_counts";
   }
diff --git a/Framework/Algorithms/src/NormaliseByDetector.cpp b/Framework/Algorithms/src/NormaliseByDetector.cpp
index 35d8b68ea84bd92dbeae797270a49ef2f2bc8c42..5ff4b8526afbde3b03367d0c171b806c3730960a 100644
--- a/Framework/Algorithms/src/NormaliseByDetector.cpp
+++ b/Framework/Algorithms/src/NormaliseByDetector.cpp
@@ -108,7 +108,7 @@ void NormaliseByDetector::processHistogram(size_t wsIndex,
   const std::string &fitFunctionName = foundFittingParam.getFunction();
   IFunction_sptr function =
       FunctionFactory::Instance().createFunction(fitFunctionName);
-  typedef std::vector<std::string> ParamNames;
+  using ParamNames = std::vector<std::string>;
   ParamNames allParamNames = function->getParameterNames();
 
   // Lookup each parameter name.
diff --git a/Framework/Algorithms/src/PDFFourierTransform.cpp b/Framework/Algorithms/src/PDFFourierTransform.cpp
index efd92caa5d60349175f4d818fa922c8ba6abaed3..58d8c50d48233879f78eb923962c184edfbf80e3 100644
--- a/Framework/Algorithms/src/PDFFourierTransform.cpp
+++ b/Framework/Algorithms/src/PDFFourierTransform.cpp
@@ -257,7 +257,7 @@ void PDFFourierTransform::exec() {
   } else {
     std::stringstream msg;
     msg << "Input data x-axis with unit \"" << inputXunit
-        << "\" is not supported (use \"MomentumTransfer\" or \"dSpacing\")";
+        << R"(" is not supported (use "MomentumTransfer" or "dSpacing"))";
     throw std::invalid_argument(msg.str());
   }
   g_log.debug() << "Input unit is " << inputXunit << "\n";
diff --git a/Framework/Algorithms/src/PaddingAndApodization.cpp b/Framework/Algorithms/src/PaddingAndApodization.cpp
index f6e5086ab4efcae3d14894df9cac81b8bca7321f..971921a9fafa39a6514472464e37d48d19cc6691 100644
--- a/Framework/Algorithms/src/PaddingAndApodization.cpp
+++ b/Framework/Algorithms/src/PaddingAndApodization.cpp
@@ -125,7 +125,7 @@ void PaddingAndApodization::exec() {
   setProperty("OutputWorkspace", outputWS);
 }
 
-typedef double (*fptr)(const double time, const double decayConstant);
+using fptr = double (*)(const double, const double);
 /**
 * Gets a pointer to the relevant
 * apodization function
diff --git a/Framework/Algorithms/src/PerformIndexOperations.cpp b/Framework/Algorithms/src/PerformIndexOperations.cpp
index 8b31982a6ad0131b906f46600cd6c2c1fc9e6360..22ed20a842f082700d746bae1f7e887abbb1cad0 100644
--- a/Framework/Algorithms/src/PerformIndexOperations.cpp
+++ b/Framework/Algorithms/src/PerformIndexOperations.cpp
@@ -45,7 +45,7 @@ public:
 };
 
 /// Helper typedef
-typedef std::vector<boost::shared_ptr<Command>> VecCommands;
+using VecCommands = std::vector<boost::shared_ptr<Command>>;
 
 /**
  * Command yielding no result.
@@ -140,7 +140,7 @@ public:
 };
 
 /// Helper typedef for vector of command parsers
-typedef std::vector<boost::shared_ptr<CommandParser>> VecCommandParsers;
+using VecCommandParsers = std::vector<boost::shared_ptr<CommandParser>>;
 
 /**
  * Command parser base class for common concrete command parser types.
@@ -172,7 +172,7 @@ class AdditionParserRange : public CommandParserBase<AdditionCommand> {
 public:
 private:
   boost::regex getRegex() const override {
-    return boost::regex("^\\s*[0-9]+\\s*\\-\\s*[0-9]+\\s*$");
+    return boost::regex(R"(^\s*[0-9]+\s*\-\s*[0-9]+\s*$)");
   }
   std::string getSeparator() const override { return "-"; }
 };
@@ -184,7 +184,7 @@ class AdditionParser : public CommandParser {
 public:
   Command *interpret(const std::string &instruction) const override {
     Command *command = nullptr;
-    boost::regex ex("^\\s*[0-9]+\\s*\\+\\s*[0-9]+\\s*$");
+    boost::regex ex(R"(^\s*[0-9]+\s*\+\s*[0-9]+\s*$)");
     if (boost::regex_match(instruction, ex)) {
       std::vector<std::string> arguments;
       boost::split(arguments, instruction, boost::is_any_of("+"));
@@ -210,7 +210,7 @@ class CropParserRange : public CommandParserBase<CropCommand> {
 public:
 private:
   boost::regex getRegex() const override {
-    return boost::regex("^\\s*[0-9]+\\s*:\\s*[0-9]+\\s*$");
+    return boost::regex(R"(^\s*[0-9]+\s*:\s*[0-9]+\s*$)");
   }
   std::string getSeparator() const override { return ":"; }
 };
@@ -319,7 +319,7 @@ void PerformIndexOperations::exec() {
       this->getProperty("ProcessingInstructions");
 
   boost::regex re(
-      "^\\s*[0-9]+\\s*$|^(\\s*,*[0-9]+(\\s*(,|:|\\+|\\-)\\s*)*[0-9]*)*$");
+      R"(^\s*[0-9]+\s*$|^(\s*,*[0-9]+(\s*(,|:|\+|\-)\s*)*[0-9]*)*$)");
   if (!boost::regex_match(processingInstructions, re)) {
     throw std::invalid_argument("ProcessingInstructions are not well formed: " +
                                 processingInstructions);
diff --git a/Framework/Algorithms/src/PolarizationCorrection.cpp b/Framework/Algorithms/src/PolarizationCorrection.cpp
index d3f4983a28dda537a8e7659fc3320d01f9db9164..b3c949ab0997a07d1c6a669a21fae007e0109d2c 100644
--- a/Framework/Algorithms/src/PolarizationCorrection.cpp
+++ b/Framework/Algorithms/src/PolarizationCorrection.cpp
@@ -102,7 +102,7 @@ void validateInputWorkspace(WorkspaceGroup_sptr &ws) {
   }
 }
 
-typedef std::vector<double> VecDouble;
+using VecDouble = std::vector<double>;
 }
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp
index 553dcd3ab9573e8e92ee3d3fe285e4610c53fd5e..8a143b35f67b0825a31152b1d68be1cbaafeb94f 100644
--- a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp
+++ b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp
@@ -557,13 +557,13 @@ void PolarizationEfficiencyCor::checkConsistentX(
   const auto &P2x = efficiencies.P2->x();
   checkX(P2x, "P2");
   // A local helper function to check an input workspace against F1.
-  auto checkWS = [&F1x, &checkX](const API::MatrixWorkspace_sptr &ws,
-                                 const std::string &tag) {
-    const auto nHist = ws->getNumberHistograms();
-    for (size_t i = 0; i != nHist; ++i) {
-      checkX(ws->x(i), tag);
-    }
-  };
+  auto checkWS =
+      [&checkX](const API::MatrixWorkspace_sptr &ws, const std::string &tag) {
+        const auto nHist = ws->getNumberHistograms();
+        for (size_t i = 0; i != nHist; ++i) {
+          checkX(ws->x(i), tag);
+        }
+      };
   if (inputs.mmWS) {
     checkWS(inputs.mmWS, Flippers::OffOff);
   }
diff --git a/Framework/Algorithms/src/RealFFT.cpp b/Framework/Algorithms/src/RealFFT.cpp
index 4c8d099ca5f9c651223820a16236832e40745501..43df23eaba2906f532251afb6c3f09c01fdbad8e 100644
--- a/Framework/Algorithms/src/RealFFT.cpp
+++ b/Framework/Algorithms/src/RealFFT.cpp
@@ -52,7 +52,7 @@ void RealFFT::init() {
   std::vector<std::string> fft_dir{"Forward", "Backward"};
   declareProperty(
       "Transform", "Forward", boost::make_shared<StringListValidator>(fft_dir),
-      "The direction of the transform: \"Forward\" or \"Backward\".");
+      R"(The direction of the transform: "Forward" or "Backward".)");
   declareProperty(
       "IgnoreXBins", false,
       "Ignores the requirement that X bins be linear and of the same size. "
diff --git a/Framework/Algorithms/src/ReflectometryMomentumTransfer.cpp b/Framework/Algorithms/src/ReflectometryMomentumTransfer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6034af2f88e97b45932f37f7b8393a6d7869a384
--- /dev/null
+++ b/Framework/Algorithms/src/ReflectometryMomentumTransfer.cpp
@@ -0,0 +1,559 @@
+#include "MantidAlgorithms/ReflectometryMomentumTransfer.h"
+
+#include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceUnitValidator.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidGeometry/Instrument.h"
+#include "MantidKernel/ArrayLengthValidator.h"
+#include "MantidKernel/ListValidator.h"
+#include "MantidKernel/MandatoryValidator.h"
+#include "MantidKernel/PhysicalConstants.h"
+
+#include <boost/math/special_functions/pow.hpp>
+
+namespace {
+/// A private namespace for algorithm's property names.
+namespace Prop {
+static const std::string CHOPPER_OPENING{"ChopperOpening"};
+static const std::string CHOPPER_PAIR_DIST{"ChopperPairDistance"};
+static const std::string CHOPPER_RADIUS{"ChopperRadius"};
+static const std::string CHOPPER_SPEED{"ChopperSpeed"};
+static const std::string DETECTOR_RESOLUTION{"DetectorResolution"};
+static const std::string DIRECT_BEAM_WS{"DirectBeamWorkspace"};
+static const std::string DIRECT_FOREGROUND{"DirectForeground"};
+static const std::string INPUT_WS{"InputWorkspace"};
+static const std::string OUTPUT_WS{"OutputWorkspace"};
+static const std::string PIXEL_SIZE{"PixelSize"};
+static const std::string POLARIZED{"Polarized"};
+static const std::string REFLECTED_BEAM_WS{"ReflectedBeamWorkspace"};
+static const std::string REFLECTED_FOREGROUND{"ReflectedForeground"};
+static const std::string SLIT1_NAME{"Slit1Name"};
+static const std::string SLIT1_SIZE_LOG{"Slit1SizeSampleLog"};
+static const std::string SLIT2_NAME{"Slit2Name"};
+static const std::string SLIT2_SIZE_LOG{"Slit2SizeSampleLog"};
+static const std::string SUM_TYPE{"SummationType"};
+static const std::string TOF_CHANNEL_WIDTH{"TOFChannelWidth"};
+} // namespace Prop
+
+/// Choices for the SUM_TYPE property.
+namespace SumTypeChoice {
+static const std::string LAMBDA{"SumInLambda"};
+static const std::string Q{"SumInQ"};
+} // namespace SumTypeChoice
+
+/// A conversion factor from e.g. slit opening to FWHM of Gaussian equivalent.
+constexpr double FWHM_GAUSSIAN_EQUIVALENT{0.68};
+
+/// Convert degrees to radians.
+constexpr double inRad(const double a) noexcept { return a / 180. * M_PI; }
+} // namespace
+
+namespace Mantid {
+namespace Algorithms {
+
+using Mantid::API::WorkspaceProperty;
+using Mantid::Kernel::Direction;
+
+// Register the algorithm into the AlgorithmFactory
+DECLARE_ALGORITHM(ReflectometryMomentumTransfer)
+
+//----------------------------------------------------------------------------------------------
+
+/// Algorithms name for identification. @see Algorithm::name
+const std::string ReflectometryMomentumTransfer::name() const {
+  return "ReflectometryMomentumTransfer";
+}
+
+/// Algorithm's version for identification. @see Algorithm::version
+int ReflectometryMomentumTransfer::version() const { return 1; }
+
+/// Algorithm's category for identification. @see Algorithm::category
+const std::string ReflectometryMomentumTransfer::category() const {
+  return "ILL\\Reflectometry;Reflectometry";
+}
+
+/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
+const std::string ReflectometryMomentumTransfer::summary() const {
+  return "Convert wavelength to momentum transfer and calculate the Qz "
+         "resolution for reflectometers at continuous beam sources.";
+}
+
+/** Initialize the algorithm's properties.
+ */
+void ReflectometryMomentumTransfer::init() {
+  auto inWavelength =
+      boost::make_shared<API::WorkspaceUnitValidator>("Wavelength");
+  auto twoElementArray =
+      boost::make_shared<Kernel::ArrayLengthValidator<int>>(2);
+  auto mandatoryDouble =
+      boost::make_shared<Kernel::MandatoryValidator<double>>();
+  auto mandatoryString =
+      boost::make_shared<Kernel::MandatoryValidator<std::string>>();
+  std::vector<std::string> sumTypes(2);
+  sumTypes.front() = SumTypeChoice::LAMBDA;
+  sumTypes.back() = SumTypeChoice::Q;
+  auto acceptableSumTypes =
+      boost::make_shared<Kernel::ListValidator<std::string>>(sumTypes);
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(
+          Prop::INPUT_WS, "", Direction::Input, inWavelength),
+      "A reflectivity workspace in wavelenght.");
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(
+          Prop::OUTPUT_WS, "", Direction::Output, inWavelength),
+      "The input workspace with DX values set to the Qz resolution.");
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(
+          Prop::REFLECTED_BEAM_WS, "", Direction::Input, inWavelength),
+      "A reflected beam workspace in wavelength.");
+  declareProperty(Prop::REFLECTED_FOREGROUND, std::vector<int>(),
+                  twoElementArray,
+                  "A two element list [start, end] defining the reflected beam "
+                  "foreground region in workspace indices.");
+  declareProperty(
+      Kernel::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>(
+          Prop::DIRECT_BEAM_WS, "", Direction::Input),
+      "A direct beam workspace in wavelength.");
+  declareProperty(Prop::DIRECT_FOREGROUND, std::vector<int>(), twoElementArray,
+                  "A two element list [start, end] defining the direct beam "
+                  "foreground region in workspace indices.");
+  declareProperty(Prop::SUM_TYPE, SumTypeChoice::LAMBDA, acceptableSumTypes,
+                  "The type of summation performed for the input workspace.");
+  declareProperty(Prop::POLARIZED, false,
+                  "True if the input workspace is part of polarization "
+                  "analysis experiment, false otherwise.");
+  declareProperty(Prop::PIXEL_SIZE, EMPTY_DBL(), mandatoryDouble,
+                  "Detector pixel size, in meters.");
+  declareProperty(Prop::DETECTOR_RESOLUTION, EMPTY_DBL(), mandatoryDouble,
+                  "Detector pixel resolution, in meters.");
+  declareProperty(Prop::CHOPPER_SPEED, EMPTY_DBL(), mandatoryDouble,
+                  "Chopper speed, in rpm.");
+  declareProperty(Prop::CHOPPER_OPENING, EMPTY_DBL(), mandatoryDouble,
+                  "The opening angle between the two choppers, in degrees.");
+  declareProperty(Prop::CHOPPER_RADIUS, EMPTY_DBL(), mandatoryDouble,
+                  "Chopper radius, in meters.");
+  declareProperty(Prop::CHOPPER_PAIR_DIST, EMPTY_DBL(), mandatoryDouble,
+                  "The gap between two choppers, in meters.");
+  declareProperty(Prop::SLIT1_NAME, "", mandatoryString,
+                  "Name of the first slit component.");
+  declareProperty(Prop::SLIT1_SIZE_LOG, "", mandatoryString,
+                  "The sample log entry for the first slit opening.");
+  declareProperty(Prop::SLIT2_NAME, "", mandatoryString,
+                  "Name of the second slit component.");
+  declareProperty(Prop::SLIT2_SIZE_LOG, "", mandatoryString,
+                  "The sample log entry for the second slit opening.");
+  declareProperty(Prop::TOF_CHANNEL_WIDTH, EMPTY_DBL(), mandatoryDouble,
+                  "TOF bin width, in microseconds.");
+}
+
+/** Execute the algorithm.
+ */
+void ReflectometryMomentumTransfer::exec() {
+  using namespace boost::math;
+  API::MatrixWorkspace_sptr inWS = getProperty(Prop::INPUT_WS);
+  API::MatrixWorkspace_sptr reflectedWS = getProperty(Prop::REFLECTED_BEAM_WS);
+  API::MatrixWorkspace_sptr directWS = getProperty(Prop::DIRECT_BEAM_WS);
+  auto setup = createSetup(*reflectedWS, *directWS);
+  API::MatrixWorkspace_sptr outWS;
+  outWS = inWS->clone();
+  convertToMomentumTransfer(outWS);
+  const auto beamFWHM =
+      beamRMSVariation(reflectedWS, setup.foregroundStart, setup.foregroundEnd);
+  const auto directBeamFWHM = beamRMSVariation(
+      directWS, setup.directForegroundStart, setup.directForegroundEnd);
+  const auto incidentFWHM = incidentAngularSpread(setup);
+  const auto slit1FWHM = slit1AngularSpread(setup);
+  const auto &spectrumInfo = inWS->spectrumInfo();
+  const int64_t nHisto = static_cast<int64_t>(outWS->getNumberHistograms());
+  PARALLEL_FOR_IF(Kernel::threadSafe(*inWS, *directWS, *outWS))
+  for (int64_t i = 0; i < nHisto; ++i) {
+    PARALLEL_START_INTERUPT_REGION
+    const auto wsIndex = static_cast<size_t>(i);
+    const auto &wavelengths = inWS->points(wsIndex);
+    const auto &qs = outWS->points(wsIndex);
+    auto dx = Kernel::make_cow<HistogramData::HistogramDx>(qs.size(), 0);
+    outWS->setSharedDx(wsIndex, dx);
+    if (spectrumInfo.isMonitor(wsIndex) || spectrumInfo.isMasked(wsIndex)) {
+      // Skip monitors & masked spectra, leave DX to zero.
+      continue;
+    }
+    auto &resolutions = outWS->mutableDx(wsIndex);
+    for (size_t i = 0; i < wavelengths.size(); ++i) {
+      const auto wavelength = wavelengths[i] * 1e-10;
+      const auto deltaLambdaSq =
+          wavelengthResolutionSquared(*inWS, wsIndex, setup, wavelength);
+      const auto deltaThetaSq =
+          angularResolutionSquared(inWS, *directWS, wsIndex, setup, beamFWHM,
+                                   directBeamFWHM, incidentFWHM, slit1FWHM);
+      // q is inversely proportional to wavelength but sorted in ascending
+      // order.
+      const auto qIndex = qs.size() - i - 1;
+      resolutions[qIndex] =
+          qs[qIndex] * std::sqrt(deltaLambdaSq + deltaThetaSq);
+    }
+    PARALLEL_END_INTERUPT_REGION
+  }
+  PARALLEL_CHECK_INTERUPT_REGION
+  setProperty(Prop::OUTPUT_WS, outWS);
+}
+
+/** Calculate the squared angular resolution.
+ *
+ * @param ws the reflectivity workspace
+ * @param directWS the reference direct beam workspace
+ * @param wsIndex a workspace index to the reflectivity workspace
+ * @param setup a setup object for the reflected beam
+ * @param beamFWHM reflected beam angular FWHM
+ * @param directBeamFWHM direct beam angular FWHM
+ * @param incidentFWHM RMS spread of the incident beam
+ * @param slit1FWHM RMS spread due to the first slit
+ * @return the squared fractional angular resolution
+ */
+double ReflectometryMomentumTransfer::angularResolutionSquared(
+    API::MatrixWorkspace_sptr &ws, const API::MatrixWorkspace &directWS,
+    const size_t wsIndex, const Setup &setup, const double beamFWHM,
+    const double directBeamFWHM, const double incidentFWHM,
+    const double slit1FWHM) {
+  using namespace boost::math;
+  const auto waviness = sampleWaviness(ws, directWS, wsIndex, setup, beamFWHM,
+                                       directBeamFWHM, incidentFWHM);
+  const auto slit2FWHM = slit2AngularSpread(*ws, wsIndex, setup);
+  const auto &spectrumInfo = ws->spectrumInfo();
+  const auto l2 = spectrumInfo.l2(wsIndex);
+  const auto braggAngle = 0.5 * spectrumInfo.twoTheta(wsIndex);
+  if (setup.sumType == SumType::Q) {
+    if (waviness > 0) {
+      if (slit1FWHM >= 2. * waviness) {
+        return (pow<2>(setup.detectorResolution / l2) + pow<2>(slit2FWHM) +
+                pow<2>(waviness)) /
+               pow<2>(braggAngle);
+      } else {
+        return (pow<2>(setup.detectorResolution / 2. / l2) + pow<2>(slit2FWHM) +
+                pow<2>(slit1FWHM)) /
+               pow<2>(braggAngle);
+      }
+    } else {
+      if (slit1FWHM > setup.detectorResolution / l2) {
+        return (pow<2>(setup.detectorResolution / l2) + pow<2>(slit2FWHM)) /
+               pow<2>(braggAngle);
+      } else {
+        const double incidentSpread = incidentFWHM;
+        return (pow<2>(incidentSpread) +
+                pow<2>(setup.detectorResolution / l2)) /
+               pow<2>(braggAngle);
+      }
+    }
+  } else { // SumType::LAMBDA
+    const auto foregroundWidth =
+        static_cast<double>(setup.foregroundEnd - setup.foregroundStart + 1) *
+        setup.pixelSize;
+    const auto foregroundWidthLimited =
+        pow<2>(FWHM_GAUSSIAN_EQUIVALENT) *
+        (pow<2>(foregroundWidth) + pow<2>(setup.slit2Size)) /
+        pow<2>(l2 * braggAngle);
+    double angularResolution;
+    if (setup.polarized) {
+      angularResolution = pow<2>(incidentFWHM / braggAngle);
+    } else {
+      angularResolution =
+          (pow<2>(incidentFWHM) + pow<2>(waviness)) / pow<2>(braggAngle);
+    }
+    return std::min(angularResolution, foregroundWidthLimited);
+  }
+}
+
+/** Calculate the FWHM of a beam (reflected or direct).
+ *
+ * @param ws a reference workspace
+ * @param start foreground start workspace index
+ * @param end foreground end workspace index
+ * @return FWHM
+ */
+double ReflectometryMomentumTransfer::beamRMSVariation(
+    API::MatrixWorkspace_sptr &ws, const size_t start, const size_t end) {
+  // det_fwhm and detdb_fwhm in COSMOS
+  using namespace boost::math;
+  auto integrate = createChildAlgorithm("Integration");
+  integrate->setProperty("InputWorkspace", ws);
+  integrate->setProperty("OutputWorkspace", "unused_for_child");
+  integrate->setProperty("StartWorkspaceIndex", static_cast<int>(start));
+  integrate->setProperty("EndWorkspaceIndex", static_cast<int>(end));
+  integrate->execute();
+  API::MatrixWorkspace_const_sptr integratedWS =
+      integrate->getProperty("OutputWorkspace");
+  double sum{0.};
+  double weighedSum{0.};
+  std::vector<double> thetaDistribution(integratedWS->getNumberHistograms());
+  for (size_t i = 0; i < thetaDistribution.size(); ++i) {
+    const auto total = integratedWS->y(i).front();
+    thetaDistribution[i] = total;
+    sum += total;
+    weighedSum += static_cast<double>(i) * total;
+  }
+  const double massCenter = weighedSum / sum;
+  double variance{0.};
+  for (size_t i = 0; i < thetaDistribution.size(); ++i) {
+    variance +=
+        thetaDistribution[i] * pow<2>(massCenter - static_cast<double>(i));
+  }
+  variance /= sum;
+  const double pixelSize = getProperty(Prop::PIXEL_SIZE);
+  return 2. * std::sqrt(2. * std::log(2.)) * pixelSize * std::sqrt(variance);
+}
+
+/** Convert a workspace's X units to momentum transfer in-place.
+ *
+ * @param ws a workspace to convert.
+ */
+void ReflectometryMomentumTransfer::convertToMomentumTransfer(
+    API::MatrixWorkspace_sptr &ws) {
+  auto convert = createChildAlgorithm("ConvertUnits");
+  convert->setProperty("InputWorkspace", ws);
+  convert->setProperty("OutputWorkspace", "unused_for_child");
+  convert->setProperty("Target", "MomentumTransfer");
+  convert->execute();
+  ws = convert->getProperty("OutputWorkspace");
+}
+
+/** Calculate the detector angular resolution.
+ *
+ * @param ws a reflectivity workspace
+ * @param wsIndex a workspace index to the reflectivity workspace
+ * @param setup reflected beam setup
+ * @param incidentFWHM spread of the incident beam
+ * @return the da quantity
+ */
+double ReflectometryMomentumTransfer::detectorAngularResolution(
+    const API::MatrixWorkspace &ws, const size_t wsIndex, const Setup &setup,
+    const double incidentFWHM) {
+  // da_det in COSMOS
+  using namespace boost::math;
+  const auto slitSizeRatio = setup.slit2Size / setup.slit1Size;
+  const auto &spectrumInfo = ws.spectrumInfo();
+  const auto slit2Detector =
+      setup.slit2SampleDistance + spectrumInfo.l2(wsIndex);
+  const auto virtualSourceDist =
+      slit2Detector +
+      (slitSizeRatio * setup.slit1Slit2Distance) / (1. + slitSizeRatio);
+  return std::sqrt(pow<2>(incidentFWHM * virtualSourceDist) +
+                   pow<2>(setup.detectorResolution));
+}
+
+/** Generate a setup for the reflected beam experiment.
+ *
+ * @param ws the reflectivity workspace
+ * @param directWS corresponding direct beam workspace
+ * @return a setup object
+ */
+const ReflectometryMomentumTransfer::Setup
+ReflectometryMomentumTransfer::createSetup(
+    const API::MatrixWorkspace &ws, const API::MatrixWorkspace &directWS) {
+  Setup s;
+  s.chopperOpening = inRad(getProperty(Prop::CHOPPER_OPENING));
+  s.chopperPairDistance = getProperty(Prop::CHOPPER_PAIR_DIST);
+  s.chopperPeriod =
+      1. / (static_cast<double>(getProperty(Prop::CHOPPER_SPEED)) / 60.);
+  s.chopperRadius = getProperty(Prop::CHOPPER_RADIUS);
+  s.detectorResolution = getProperty(Prop::DETECTOR_RESOLUTION);
+  std::vector<int> foreground = getProperty(Prop::REFLECTED_FOREGROUND);
+  auto lowPixel = static_cast<size_t>(foreground.front());
+  auto highPixel = static_cast<size_t>(foreground.back());
+  s.foregroundStart = std::min(lowPixel, highPixel);
+  s.foregroundEnd = std::max(lowPixel, highPixel);
+  foreground = getProperty(Prop::DIRECT_FOREGROUND);
+  lowPixel = static_cast<size_t>(foreground.front());
+  highPixel = static_cast<size_t>(foreground.back());
+  s.directForegroundStart = std::min(lowPixel, highPixel);
+  s.directForegroundEnd = std::max(lowPixel, highPixel);
+  s.pixelSize = getProperty(Prop::PIXEL_SIZE);
+  s.polarized = getProperty(Prop::POLARIZED);
+  s.slit1Slit2Distance = interslitDistance(ws);
+  const std::string slit1SizeEntry = getProperty(Prop::SLIT1_SIZE_LOG);
+  s.slit1Size = slitSize(ws, slit1SizeEntry);
+  s.slit1SizeDirectBeam = slitSize(directWS, slit1SizeEntry);
+  const std::string slit2Name = getProperty(Prop::SLIT2_NAME);
+  auto instrument = ws.getInstrument();
+  auto slit2 = instrument->getComponentByName(slit2Name);
+  const auto &spectrumInfo = ws.spectrumInfo();
+  const auto samplePos = spectrumInfo.samplePosition();
+  s.slit2SampleDistance = (slit2->getPos() - samplePos).norm();
+  const std::string slit2SizeEntry = getProperty(Prop::SLIT2_SIZE_LOG);
+  s.slit2Size = slitSize(ws, slit2SizeEntry);
+  s.slit2SizeDirectBeam = slitSize(directWS, slit2SizeEntry);
+  const std::string sumType = getProperty(Prop::SUM_TYPE);
+  s.sumType = sumType == SumTypeChoice::LAMBDA ? SumType::LAMBDA : SumType::Q;
+  s.tofChannelWidth =
+      static_cast<double>(getProperty(Prop::TOF_CHANNEL_WIDTH)) * 1e-6;
+  return s;
+}
+
+/** Calculate the range of angles in the reflection plane determined by
+ *  the collimation.
+ *
+ * @param setup a setup object
+ * @return the incident FWHM
+ */
+double
+ReflectometryMomentumTransfer::incidentAngularSpread(const Setup &setup) {
+  // da in COSMOS
+  using namespace boost::math;
+  return FWHM_GAUSSIAN_EQUIVALENT *
+         std::sqrt((pow<2>(setup.slit1Size) + pow<2>(setup.slit2Size))) /
+         setup.slit1Slit2Distance;
+}
+
+/** Give the gap between the two slits, in meters.
+ *
+ * @param ws the reflectivity workspace
+ * @return the slit gap, in meters
+ */
+double ReflectometryMomentumTransfer::interslitDistance(
+    const API::MatrixWorkspace &ws) {
+  const std::string slit1Name = getProperty(Prop::SLIT1_NAME);
+  const std::string slit2Name = getProperty(Prop::SLIT2_NAME);
+  auto instrument = ws.getInstrument();
+  auto slit1 = instrument->getComponentByName(slit1Name);
+  auto slit2 = instrument->getComponentByName(slit2Name);
+  return (slit1->getPos() - slit2->getPos()).norm();
+}
+
+/** Calculate sample RMS waviness.
+ *
+ * @param ws the reflectivity workspace
+ * @param directWS reference direct beam workspace
+ * @param wsIndex workspace index to the reflectivity workspace
+ * @param setup a setup object
+ * @param beamFWHM reflected beam RMS variation
+ * @param directBeamFWHM direct beam RMS variation
+ * @param incidentFWHM incident beam angular spread
+ * @return the waviness
+ */
+double ReflectometryMomentumTransfer::sampleWaviness(
+    API::MatrixWorkspace_sptr &ws, const API::MatrixWorkspace &directWS,
+    const size_t wsIndex, const Setup &setup, const double beamFWHM,
+    const double directBeamFWHM, const double incidentFWHM) {
+  // om_fwhm in COSMOS
+  using namespace boost::math;
+  const double slitSizeTolerance{0.00004};
+  if (std::abs(setup.slit1Size - setup.slit1SizeDirectBeam) >=
+          slitSizeTolerance ||
+      std::abs(setup.slit2Size - setup.slit2SizeDirectBeam) >=
+          slitSizeTolerance) {
+    // Differing slit sizes branch from COSMOS.
+    const double daDet =
+        detectorAngularResolution(*ws, wsIndex, setup, incidentFWHM);
+    if (beamFWHM - daDet >= 0) {
+      const auto a = std::sqrt(pow<2>(beamFWHM) - pow<2>(daDet));
+      if (a >= setup.pixelSize) {
+        const auto directL2 = directWS.spectrumInfo().l2(wsIndex);
+        return 0.5 * a / directL2;
+      }
+    }
+  } else if (pow<2>(beamFWHM) - pow<2>(directBeamFWHM) >= 0) {
+    const auto a = std::sqrt(pow<2>(beamFWHM) - pow<2>(directBeamFWHM));
+    if (a >= setup.pixelSize) {
+      const auto directL2 = directWS.spectrumInfo().l2(wsIndex);
+      return 0.5 * a / directL2;
+    }
+  }
+  return 0.;
+}
+
+/** Calculate the angular spread due to the first slit.
+ *
+ * @param setup a reflected beam setup object
+ * @return the spread
+ */
+double ReflectometryMomentumTransfer::slit1AngularSpread(const Setup &setup) {
+  // S2_fwhm in COSMOS
+  return FWHM_GAUSSIAN_EQUIVALENT * setup.slit1Size / setup.slit1Slit2Distance;
+}
+
+/** Calculate the angular spread due to the second slit.
+ *
+ * @param ws the reflectivity workspace
+ * @param wsIndex a workspace index to the reflectivity workspace
+ * @param setup reflected beam setup
+ * @return the spread
+ */
+double ReflectometryMomentumTransfer::slit2AngularSpread(
+    const API::MatrixWorkspace &ws, const size_t wsIndex, const Setup &setup) {
+  // s3_fwhm in COSMOS.
+  const auto &spectrumInfo = ws.spectrumInfo();
+  const auto slit2Detector =
+      setup.slit2SampleDistance + spectrumInfo.l2(wsIndex);
+  return FWHM_GAUSSIAN_EQUIVALENT * setup.slit2Size / slit2Detector;
+}
+
+/** Read the slit size from samle logs.
+ *
+ * @param ws workspace to investigate
+ * @param logEntry name of the slit opening sample log
+ * @return the slit opening, in meters
+ */
+double ReflectometryMomentumTransfer::slitSize(const API::MatrixWorkspace &ws,
+                                               const std::string &logEntry) {
+  auto &run = ws.run();
+  const double opening = run.getPropertyValueAsType<double>(logEntry);
+  const auto &units = run.getProperty(logEntry)->units();
+  if (units.empty()) {
+    m_log.warning() << "Slit opening entry " << logEntry
+                    << " has no unit. Assuming meters.\n";
+    return opening;
+  } else if (units == "m") {
+    return opening;
+  } else if (units == "mm") {
+    return opening * 1e-3;
+  } else {
+    m_log.warning() << "Slit opening entry " << logEntry
+                    << " has an unknown unit. Assuming meters.\n";
+    return opening;
+  }
+}
+
+/** Calculate the squared resolution due to wavelength variance.
+ *
+ * @param ws the reflectivity workspace
+ * @param wsIndex a workspace index to the reflectivity workspace
+ * @param setup reflected beam setup
+ * @param wavelength wavelength, in meters
+ * @return the fractional resolution squared
+ */
+double ReflectometryMomentumTransfer::wavelengthResolutionSquared(
+    const API::MatrixWorkspace &ws, const size_t wsIndex, const Setup &setup,
+    const double wavelength) {
+  // err_res in COSMOS
+  using namespace boost::math;
+  using namespace PhysicalConstants;
+  const auto &spectrumInfo = ws.spectrumInfo();
+  const auto l1 = spectrumInfo.l1();
+  const auto l2 = spectrumInfo.l2(wsIndex);
+  const auto flightDistance = l1 + l2;
+  const auto chopperResolution = setup.chopperPairDistance +
+                                 h * setup.chopperOpening *
+                                     setup.chopperPeriod /
+                                     (2. * M_PI * NeutronMass * wavelength);
+  const auto detectorResolution =
+      h * setup.tofChannelWidth / (NeutronMass * wavelength);
+  const auto partialResolution =
+      0.49 * (3. * pow<2>(chopperResolution) + pow<2>(detectorResolution) +
+              3. * chopperResolution * detectorResolution) /
+      (2. * chopperResolution + detectorResolution) / flightDistance;
+  const auto flightDistRatio =
+      (l1 - setup.slit2SampleDistance) / setup.slit1Slit2Distance;
+  const auto a =
+      flightDistRatio * (setup.slit1Size + setup.slit2Size) + setup.slit1Size;
+  const auto b = flightDistRatio * std::abs(setup.slit1Size - setup.slit2Size) +
+                 setup.slit1Size;
+  const auto wavelengthSmearing =
+      0.49 * (pow<3>(a) - pow<3>(b)) / (pow<2>(a) - pow<2>(b));
+  const auto widthResolution = wavelengthSmearing * setup.chopperPeriod /
+                               (2. * M_PI * setup.chopperRadius) * h /
+                               (NeutronMass * wavelength * flightDistance);
+  return pow<2>(partialResolution) + pow<2>(widthResolution);
+}
+
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Framework/Algorithms/src/ReflectometryReductionOne.cpp
deleted file mode 100644
index 3d8e2a2dc971cb8260577504d599e7df3bdaac57..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/src/ReflectometryReductionOne.cpp
+++ /dev/null
@@ -1,855 +0,0 @@
-#include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h"
-#include "MantidAlgorithms/ReflectometryReductionOne.h"
-#include "MantidAPI/Axis.h"
-#include "MantidAPI/WorkspaceUnitValidator.h"
-#include "MantidGeometry/Instrument/ReferenceFrame.h"
-#include "MantidKernel/ListValidator.h"
-#include "MantidKernel/ArrayProperty.h"
-#include "MantidKernel/EnabledWhenProperty.h"
-#include "MantidKernel/Tolerance.h"
-#include "MantidKernel/Unit.h"
-
-using namespace Mantid::Kernel;
-using namespace Mantid::API;
-using namespace Mantid::Geometry;
-
-namespace Mantid {
-namespace Algorithms {
-
-/*Anonomous namespace */
-namespace {
-/**
-* Helper non-member function for translating all the workspace indexes in an
-*origin workspace into workspace indexes
-* of a host end-point workspace. This is done using spectrum numbers as the
-*intermediate.
-*
-* This function will throw a runtime error if the specId are not found to exist
-*on the host end-point workspace.
-*
-* @param originWS : Origin workspace, which provides the original workspace
-*index to spectrum number mapping.
-* @param hostWS : Workspace onto which the resulting workspace indexes will be
-*hosted
-* @return Remapped workspace indexes applicable for the host workspace. results
-*as comma separated string.
-*/
-std::string createWorkspaceIndexListFromDetectorWorkspace(
-    MatrixWorkspace_const_sptr originWS, MatrixWorkspace_const_sptr hostWS) {
-  auto spectrumMap = originWS->getSpectrumToWorkspaceIndexMap();
-  auto it = spectrumMap.begin();
-  std::stringstream result;
-  specnum_t specId = (*it).first;
-  result << static_cast<int>(hostWS->getIndexFromSpectrumNumber(specId));
-  ++it;
-  for (; it != spectrumMap.end(); ++it) {
-    specId = (*it).first;
-    result << ","
-           << static_cast<int>(hostWS->getIndexFromSpectrumNumber(specId));
-  }
-  return result.str();
-}
-
-const std::string multiDetectorAnalysis = "MultiDetectorAnalysis";
-const std::string pointDetectorAnalysis = "PointDetectorAnalysis";
-const std::string tofUnitId = "TOF";
-const std::string wavelengthUnitId = "Wavelength";
-
-/**
-* Helper free function to get the ordered spectrum numbers from a workspace.
-* @param ws
-* @return
-*/
-std::vector<int> getSpectrumNumbers(MatrixWorkspace_sptr &ws) {
-  auto specToWSIndexMap = ws->getSpectrumToWorkspaceIndexMap();
-  std::vector<int> keys(specToWSIndexMap.size());
-  size_t i = 0;
-  for (auto it = specToWSIndexMap.begin(); it != specToWSIndexMap.end();
-       ++it, ++i) {
-    keys[i] = static_cast<int>(it->first);
-  }
-  std::sort(
-      keys.begin(),
-      keys.end()); // Sort the keys, as the order is not guaranteed in the map.
-
-  return keys;
-}
-
-/**
-* Helper free function to calculate MomentumTransfer from lambda and theta
-* @param lambda : Value in wavelength
-* @param theta  : Value in Degrees
-* @return MomentumTransfer
-* @
-*/
-double calculateQ(double lambda, double theta) {
-  if (lambda == 0.0)
-    throw std::runtime_error("Minimum/Maximum value of the IvsLambda Workspace "
-                             "is 0. Cannot calculate Q");
-  double thetaInRad = theta * M_PI / 180;
-  return (4 * M_PI * sin(thetaInRad)) / lambda;
-}
-}
-/* End of ananomous namespace */
-
-// Register the algorithm into the AlgorithmFactory
-DECLARE_ALGORITHM(ReflectometryReductionOne)
-
-//----------------------------------------------------------------------------------------------
-/// Algorithm's name for identification. @see Algorithm::name
-const std::string ReflectometryReductionOne::name() const {
-  return "ReflectometryReductionOne";
-}
-
-/// Algorithm's version for identification. @see Algorithm::version
-int ReflectometryReductionOne::version() const { return 1; }
-
-/// Algorithm's category for identification. @see Algorithm::category
-const std::string ReflectometryReductionOne::category() const {
-  return "Reflectometry";
-}
-
-//----------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------
-/** Initialize the algorithm's properties.
-*/
-void ReflectometryReductionOne::init() {
-
-  declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>(
-                      "InputWorkspace", "", Direction::Input),
-                  "Run to reduce.");
-
-  std::vector<std::string> propOptions;
-  propOptions.push_back(pointDetectorAnalysis);
-  propOptions.push_back(multiDetectorAnalysis);
-
-  declareProperty(
-      "AnalysisMode", "PointDetectorAnalysis",
-      boost::make_shared<StringListValidator>(propOptions),
-      "The type of analysis to perform. Point detector or multi detector.");
-
-  declareProperty(make_unique<ArrayProperty<int>>("RegionOfDirectBeam"),
-                  "Indices of the spectra a pair (lower, upper) that mark the "
-                  "ranges that correspond to the direct beam in multi-detector "
-                  "mode.");
-
-  this->initIndexInputs();
-  this->initWavelengthInputs();
-
-  declareProperty(make_unique<PropertyWithValue<std::string>>(
-                      "DetectorComponentName", "", Direction::Input),
-                  "Name of the detector component i.e. point-detector. If "
-                  "these are not specified, the algorithm will attempt lookup "
-                  "using a standard naming convention.");
-
-  declareProperty(make_unique<PropertyWithValue<std::string>>(
-                      "SampleComponentName", "", Direction::Input),
-                  "Name of the sample component i.e. some-surface-holder. If "
-                  "these are not specified, the algorithm will attempt lookup "
-                  "using a standard naming convention.");
-
-  declareProperty(make_unique<WorkspaceProperty<>>("OutputWorkspace", "",
-                                                   Direction::Output),
-                  "Output Workspace IvsQ.");
-
-  declareProperty(make_unique<WorkspaceProperty<>>("OutputWorkspaceWavelength",
-                                                   "", Direction::Output,
-                                                   PropertyMode::Optional),
-                  "Output Workspace IvsLam. Intermediate workspace.");
-
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "ThetaIn", Mantid::EMPTY_DBL(), Direction::Input),
-                  "Final theta value in degrees. Optional, this value will be "
-                  "calculated internally and provided as ThetaOut if not "
-                  "provided.");
-
-  declareProperty(make_unique<PropertyWithValue<double>>(
-                      "ThetaOut", Mantid::EMPTY_DBL(), Direction::Output),
-                  "Calculated final theta in degrees.");
-
-  declareProperty("NormalizeByIntegratedMonitors", true,
-                  "Normalize by dividing by the integrated monitors.");
-
-  declareProperty(make_unique<PropertyWithValue<bool>>(
-                      "CorrectDetectorPositions", true, Direction::Input),
-                  "Correct detector positions using ThetaIn (if given)");
-
-  declareProperty(
-      make_unique<WorkspaceProperty<MatrixWorkspace>>(
-          "FirstTransmissionRun", "", Direction::Input, PropertyMode::Optional),
-      "First transmission run, or the low wavelength transmission run if "
-      "SecondTransmissionRun is also provided.");
-
-  auto inputValidator = boost::make_shared<WorkspaceUnitValidator>(tofUnitId);
-  declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>(
-                      "SecondTransmissionRun", "", Direction::Input,
-                      PropertyMode::Optional, inputValidator),
-                  "Second, high wavelength transmission run. Optional. Causes "
-                  "the FirstTransmissionRun to be treated as the low "
-                  "wavelength transmission run.");
-
-  this->initStitchingInputs();
-
-  declareProperty(make_unique<PropertyWithValue<bool>>("StrictSpectrumChecking",
-                                                       true, Direction::Input),
-                  "Enforces spectrum number checking prior to normalization");
-
-  std::vector<std::string> correctionAlgorithms = {
-      "None", "PolynomialCorrection", "ExponentialCorrection"};
-  declareProperty("CorrectionAlgorithm", "None",
-                  boost::make_shared<StringListValidator>(correctionAlgorithms),
-                  "The type of correction to perform.");
-
-  declareProperty(make_unique<ArrayProperty<double>>("Polynomial"),
-                  "Coefficients to be passed to the PolynomialCorrection"
-                  " algorithm.");
-
-  declareProperty(
-      make_unique<PropertyWithValue<double>>("C0", 0.0, Direction::Input),
-      "C0 value to be passed to the ExponentialCorrection algorithm.");
-
-  declareProperty(
-      make_unique<PropertyWithValue<double>>("C1", 0.0, Direction::Input),
-      "C1 value to be passed to the ExponentialCorrection algorithm.");
-
-  setPropertyGroup("CorrectionAlgorithm", "Polynomial Corrections");
-  setPropertyGroup("Polynomial", "Polynomial Corrections");
-  setPropertyGroup("C0", "Polynomial Corrections");
-  setPropertyGroup("C1", "Polynomial Corrections");
-
-  setPropertySettings(
-      "Polynomial",
-      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-          "CorrectionAlgorithm", IS_EQUAL_TO, "PolynomialCorrection"));
-  setPropertySettings(
-      "C0", Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection"));
-  setPropertySettings(
-      "C1", Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection"));
-
-  setPropertyGroup("FirstTransmissionRun", "Transmission");
-  setPropertyGroup("SecondTransmissionRun", "Transmission");
-  setPropertyGroup("Params", "Transmission");
-  setPropertyGroup("StartOverlap", "Transmission");
-  setPropertyGroup("EndOverlap", "Transmission");
-
-  // Only ask for transmission parameters when a FirstTranmissionRun has been
-  // provided
-  setPropertySettings("SecondTransmissionRun",
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "FirstTransmissionRun", IS_NOT_DEFAULT));
-  setPropertySettings("Params",
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "FirstTransmissionRun", IS_NOT_DEFAULT));
-  setPropertySettings("StartOverlap",
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "FirstTransmissionRun", IS_NOT_DEFAULT));
-  setPropertySettings("EndOverlap",
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "FirstTransmissionRun", IS_NOT_DEFAULT));
-
-  // Only use region of direct beam when in multi-detector analysis mode.
-  setPropertySettings(
-      "RegionOfDirectBeam",
-      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-          "AnalysisMode", IS_EQUAL_TO, "MultiDetectorAnalysis"));
-  declareProperty("ScaleFactor", Mantid::EMPTY_DBL(),
-                  "Factor you wish to scale Q workspace by.", Direction::Input);
-  declareProperty("MomentumTransferMinimum", Mantid::EMPTY_DBL(),
-                  "Minimum Q value in IvsQ "
-                  "Workspace. Used for Rebinning "
-                  "the IvsQ Workspace",
-                  Direction::Input);
-  declareProperty("MomentumTransferStep", Mantid::EMPTY_DBL(),
-                  "Resolution value in IvsQ Workspace. Used for Rebinning the "
-                  "IvsQ Workspace. This value will be made minus to apply "
-                  "logarithmic rebinning. If you wish to have linear "
-                  "bin-widths then please provide a negative DQQ",
-                  Direction::Input);
-  declareProperty("MomentumTransferMaximum", Mantid::EMPTY_DBL(),
-                  "Maximum Q value in IvsQ "
-                  "Workspace. Used for Rebinning "
-                  "the IvsQ Workspace",
-                  Direction::Input);
-}
-
-/**
-* Correct the position of the detectors based on the input theta value.
-* @param toCorrect : Workspace to correct detector positions on.
-* @param thetaInDeg : Theta in degrees to use in correction calculations.
-* @param isPointDetector : True if using point detector analysis
-* @return Copy with positions corrected.
-*/
-MatrixWorkspace_sptr
-ReflectometryReductionOne::correctPosition(API::MatrixWorkspace_sptr &toCorrect,
-                                           const double &thetaInDeg,
-                                           const bool isPointDetector) {
-  g_log.debug("Correcting position using theta.");
-
-  auto correctPosAlg = this->createChildAlgorithm(
-      "SpecularReflectionPositionCorrect", -1, -1, true, 1);
-  correctPosAlg->initialize();
-  correctPosAlg->setProperty("InputWorkspace", toCorrect);
-
-  const std::string analysisMode = this->getProperty("AnalysisMode");
-  correctPosAlg->setProperty("AnalysisMode", analysisMode);
-  auto instrument = toCorrect->getInstrument();
-  IComponent_const_sptr sample = this->getSurfaceSampleComponent(instrument);
-  correctPosAlg->setProperty("SampleComponentName", sample->getName());
-  correctPosAlg->setProperty("TwoThetaIn", thetaInDeg * 2);
-
-  if (isPointDetector) {
-    IComponent_const_sptr detector =
-        this->getDetectorComponent(instrument, isPointDetector);
-    correctPosAlg->setProperty("DetectorComponentName", detector->getName());
-  } else {
-    auto specNumbers = getSpectrumNumbers(toCorrect);
-    correctPosAlg->setProperty("SpectrumNumbersOfDetectors", specNumbers);
-    for (auto specNumber : specNumbers) {
-      std::stringstream buffer;
-      buffer << "Writing out: " << specNumber;
-      g_log.notice(buffer.str());
-    }
-  }
-  correctPosAlg->execute();
-  MatrixWorkspace_sptr corrected =
-      correctPosAlg->getProperty("OutputWorkspace");
-
-  return corrected;
-}
-/**
-* @param toConvert : workspace used to get instrument components
-* @param thetaOut : angle between sample and detectors (in Degrees)
-* @return Theta : the value by which we rotate the source (in Degrees)
-*/
-double ReflectometryReductionOne::getAngleForSourceRotation(
-    MatrixWorkspace_sptr toConvert, double thetaOut) {
-  auto instrument = toConvert->getInstrument();
-  auto instrumentUpVector = instrument->getReferenceFrame()->vecPointingUp();
-  // check to see if calculated theta is the same as theta from instrument setup
-  auto instrumentBeamDirection = instrument->getBeamDirection();
-  double currentThetaInFromInstrument =
-      instrumentUpVector.angle(instrumentBeamDirection) * (180 / M_PI) - 90;
-  bool isInThetaEqualToOutTheta =
-      std::abs(currentThetaInFromInstrument - thetaOut) <
-      Mantid::Kernel::Tolerance;
-  // the angle by which we rotate the source
-  double rotationTheta = 0.0;
-  if (!isInThetaEqualToOutTheta /*source needs rotation*/) {
-    rotationTheta = thetaOut - currentThetaInFromInstrument;
-  }
-  return rotationTheta;
-}
-
-/**
-* Convert an input workspace into an IvsQ workspace.
-*
-* @param toConvert : Workspace to convert
-* @param bCorrectPosition : Flag to indicate that detector positions should be
-*corrected based on the input theta values.
-* @param thetaInDeg : Theta in Degrees. Used for correction.
-* @param isPointDetector: Is point detector analysis
-* @return
-*/
-Mantid::API::MatrixWorkspace_sptr ReflectometryReductionOne::toIvsQ(
-    API::MatrixWorkspace_sptr &toConvert, const bool bCorrectPosition,
-    OptionalDouble &thetaInDeg, const bool isPointDetector) {
-  /*
-  * Can either calculate a missing theta value for the purposes of reporting,
-  * or correct positions based on a theta value,
-  * but not both. The processing is effectively circular if both are applied.
-  */
-  if (!thetaInDeg.is_initialized()) {
-    g_log.debug("Calculating final theta.");
-
-    auto correctThetaAlg = this->createChildAlgorithm(
-        "SpecularReflectionCalculateTheta", -1, -1, true, 1);
-    correctThetaAlg->initialize();
-    correctThetaAlg->setProperty("InputWorkspace", toConvert);
-    const std::string analysisMode = this->getProperty("AnalysisMode");
-    correctThetaAlg->setProperty("AnalysisMode", analysisMode);
-    const std::string sampleComponentName =
-        this->getProperty("SampleComponentName");
-    correctThetaAlg->setProperty("SampleComponentName", sampleComponentName);
-    if (isPointDetector) {
-      const std::string detectorComponentName =
-          this->getPropertyValue("DetectorComponentName");
-      correctThetaAlg->setProperty("DetectorComponentName",
-                                   detectorComponentName);
-    } else {
-      std::vector<int> spectrumNumbers = getSpectrumNumbers(toConvert);
-      correctThetaAlg->setProperty("SpectrumNumbersOfDetectors",
-                                   spectrumNumbers);
-    }
-    correctThetaAlg->execute();
-    const double twoTheta = correctThetaAlg->getProperty("TwoTheta");
-
-    thetaInDeg = twoTheta / 2;
-
-  } else if (bCorrectPosition) {
-    toConvert = correctPosition(toConvert, thetaInDeg.get(), isPointDetector);
-  }
-
-  // Rotate the source (needed before ConvertUnits)
-  double rotationTheta = getAngleForSourceRotation(toConvert, thetaInDeg.get());
-  if (rotationTheta != 0.0) {
-    auto rotateSource = this->createChildAlgorithm("RotateSource");
-    rotateSource->setChild(true);
-    rotateSource->initialize();
-    rotateSource->setProperty("Workspace", toConvert);
-    rotateSource->setProperty("Angle", rotationTheta);
-    rotateSource->execute();
-  }
-
-  // Always convert units.
-  auto convertUnits = this->createChildAlgorithm("ConvertUnits");
-  convertUnits->initialize();
-  convertUnits->setProperty("InputWorkspace", toConvert);
-  convertUnits->setProperty("Target", "MomentumTransfer");
-  convertUnits->execute();
-  MatrixWorkspace_sptr inQ = convertUnits->getProperty("OutputWorkspace");
-
-  // Rotate the source back to its original position
-  if (rotationTheta != 0.0) {
-    // for IvsLam Workspace
-    auto rotateSource = this->createChildAlgorithm("RotateSource");
-    rotateSource->setChild(true);
-    rotateSource->initialize();
-    rotateSource->setProperty("Workspace", toConvert);
-    rotateSource->setProperty("Angle", -rotationTheta);
-    rotateSource->execute();
-    // for IvsQ Workspace
-    rotateSource->setProperty("Workspace", inQ);
-    rotateSource->setProperty("Angle", -rotationTheta);
-    rotateSource->execute();
-  }
-
-  return inQ;
-}
-
-/**
-* Get the sample component. Use the name provided as a property as the basis
-*for the lookup as a priority.
-*
-* Throws if the name is invalid.
-* @param inst : Instrument to search through
-* @return : The component : The component object found.
-*/
-Mantid::Geometry::IComponent_const_sptr
-ReflectometryReductionOne::getSurfaceSampleComponent(
-    Mantid::Geometry::Instrument_const_sptr inst) {
-  std::string sampleComponent = "some-surface-holder";
-  if (!isPropertyDefault("SampleComponentName")) {
-    sampleComponent = this->getPropertyValue("SampleComponentName");
-  }
-  auto searchResult = inst->getComponentByName(sampleComponent);
-  if (searchResult == nullptr) {
-    throw std::invalid_argument(sampleComponent +
-                                " does not exist. Check input properties.");
-  }
-  return searchResult;
-}
-
-/**
-* Get the detector component. Use the name provided as a property as the basis
-*for the lookup as a priority.
-*
-* Throws if the name is invalid.
-* @param inst : Instrument to search through.
-* @param isPointDetector : True if this is a point detector. Used to guess a
-*name.
-* @return The component : The component object found.
-*/
-boost::shared_ptr<const Mantid::Geometry::IComponent>
-ReflectometryReductionOne::getDetectorComponent(
-    Mantid::Geometry::Instrument_const_sptr inst, const bool isPointDetector) {
-  std::string componentToCorrect =
-      isPointDetector ? "point-detector" : "line-detector";
-  if (!isPropertyDefault("DetectorComponentName")) {
-    componentToCorrect = this->getPropertyValue("DetectorComponentName");
-  }
-  boost::shared_ptr<const IComponent> searchResult =
-      inst->getComponentByName(componentToCorrect);
-  if (searchResult == nullptr) {
-    throw std::invalid_argument(componentToCorrect +
-                                " does not exist. Check input properties.");
-  }
-  return searchResult;
-}
-
-//----------------------------------------------------------------------------------------------
-/** Execute the algorithm.
-*/
-void ReflectometryReductionOne::exec() {
-  MatrixWorkspace_sptr runWS = getProperty("InputWorkspace");
-
-  OptionalMatrixWorkspace_sptr firstTransmissionRun;
-  OptionalMatrixWorkspace_sptr secondTransmissionRun;
-  OptionalDouble stitchingStart;
-  OptionalDouble stitchingDelta;
-  OptionalDouble stitchingEnd;
-  OptionalDouble stitchingStartOverlap;
-  OptionalDouble stitchingEndOverlap;
-
-  getTransmissionRunInfo(firstTransmissionRun, secondTransmissionRun,
-                         stitchingStart, stitchingDelta, stitchingEnd,
-                         stitchingStartOverlap, stitchingEndOverlap);
-
-  OptionalDouble theta;
-  if (!isPropertyDefault("ThetaIn")) {
-    double temp = this->getProperty("ThetaIn");
-    theta = temp;
-  }
-  const std::string strAnalysisMode = getProperty("AnalysisMode");
-  const bool isPointDetector = (pointDetectorAnalysis == strAnalysisMode);
-  const bool isMultiDetector = (multiDetectorAnalysis == strAnalysisMode);
-
-  const MinMax wavelengthInterval =
-      this->getMinMax("WavelengthMin", "WavelengthMax");
-
-  const std::string processingCommands = getWorkspaceIndexList();
-
-  OptionalWorkspaceIndexes directBeam;
-  fetchOptionalLowerUpperPropertyValue("RegionOfDirectBeam", isPointDetector,
-                                       directBeam);
-
-  auto instrument = runWS->getInstrument();
-
-  const OptionalInteger i0MonitorIndex = checkForOptionalInstrumentDefault<int>(
-      this, "I0MonitorIndex", instrument, "I0MonitorIndex");
-
-  const OptionalMinMax monitorBackgroundWavelengthInterval = getOptionalMinMax(
-      this, "MonitorBackgroundWavelengthMin", "MonitorBackgroundWavelengthMax",
-      instrument, "MonitorBackgroundWavelengthMin",
-      "MonitorBackgroundWavelengthMax");
-  const OptionalMinMax monitorIntegrationWavelengthInterval = getOptionalMinMax(
-      this, "MonitorIntegrationWavelengthMin",
-      "MonitorIntegrationWavelengthMax", instrument,
-      "MonitorIntegrationWavelengthMin", "MonitorIntegrationWavelengthMax");
-
-  const bool correctDetectorPositions = getProperty("CorrectDetectorPositions");
-
-  MatrixWorkspace_sptr IvsLam; // Output workspace
-  MatrixWorkspace_sptr IvsQ;   // Output workspace
-
-  auto xUnitID = runWS->getAxis(0)->unit()->unitID();
-
-  if (xUnitID == "Wavelength") {
-    // If the input workspace is in lambda, we don't need to do any corrections,
-    // just use it as is.
-    g_log.information("Input workspace already in unit 'Wavelength'. Skipping "
-                      "lambda conversions.");
-    IvsLam = runWS;
-  } else if (xUnitID == "TOF") {
-    // If the input workspace is in TOF, do some corrections and generate IvsLam
-    // from it.
-    DetectorMonitorWorkspacePair inLam =
-        toLam(runWS, processingCommands, i0MonitorIndex, wavelengthInterval,
-              monitorBackgroundWavelengthInterval);
-    auto detectorWS = inLam.get<0>();
-    auto monitorWS = inLam.get<1>();
-
-    if (isMultiDetector) {
-      if (directBeam.is_initialized()) {
-        // Sum over the direct beam.
-        WorkspaceIndexList db = directBeam.get();
-        std::stringstream buffer;
-        buffer << db.front() << "-" << db.back();
-        MatrixWorkspace_sptr regionOfDirectBeamWS =
-            this->toLamDetector(buffer.str(), runWS, wavelengthInterval);
-
-        // Rebin to the detector workspace
-        auto rebinToWorkspaceAlg =
-            this->createChildAlgorithm("RebinToWorkspace");
-        rebinToWorkspaceAlg->initialize();
-        rebinToWorkspaceAlg->setProperty("WorkspaceToRebin",
-                                         regionOfDirectBeamWS);
-        rebinToWorkspaceAlg->setProperty("WorkspaceToMatch", detectorWS);
-        rebinToWorkspaceAlg->execute();
-        regionOfDirectBeamWS =
-            rebinToWorkspaceAlg->getProperty("OutputWorkspace");
-
-        // Normalize by the direct beam.
-        detectorWS = divide(detectorWS, regionOfDirectBeamWS);
-      }
-    }
-
-    const bool normalizeByIntMon = getProperty("NormalizeByIntegratedMonitors");
-    if (normalizeByIntMon) {
-      auto integrationAlg = this->createChildAlgorithm("Integration");
-      integrationAlg->initialize();
-      integrationAlg->setProperty("InputWorkspace", monitorWS);
-      if (monitorIntegrationWavelengthInterval.is_initialized()) {
-        integrationAlg->setProperty(
-            "RangeLower", monitorIntegrationWavelengthInterval.get().get<0>());
-        integrationAlg->setProperty(
-            "RangeUpper", monitorIntegrationWavelengthInterval.get().get<1>());
-      }
-      integrationAlg->execute();
-      MatrixWorkspace_sptr integratedMonitor =
-          integrationAlg->getProperty("OutputWorkspace");
-
-      IvsLam = divide(
-          detectorWS,
-          integratedMonitor); // Normalize by the integrated monitor counts.
-    } else {
-      IvsLam = divide(detectorWS, monitorWS);
-    }
-  } else {
-    // Neither TOF or Lambda? Abort.
-    throw std::invalid_argument(
-        "InputWorkspace must have units of TOF or Wavelength");
-  }
-
-  if (firstTransmissionRun.is_initialized()) {
-    // Perform transmission correction.
-    IvsLam = this->transmissonCorrection(
-        IvsLam, wavelengthInterval, monitorBackgroundWavelengthInterval,
-        monitorIntegrationWavelengthInterval, i0MonitorIndex,
-        firstTransmissionRun.get(), secondTransmissionRun, stitchingStart,
-        stitchingDelta, stitchingEnd, stitchingStartOverlap,
-        stitchingEndOverlap, processingCommands);
-  } else if (getPropertyValue("CorrectionAlgorithm") != "None") {
-    IvsLam = algorithmicCorrection(IvsLam);
-  } else {
-    g_log.warning("No transmission correction will be applied.");
-  }
-
-  IvsQ = this->toIvsQ(IvsLam, correctDetectorPositions, theta, isPointDetector);
-  double momentumTransferMinimum = getProperty("MomentumTransferMinimum");
-  double momentumTransferStep = getProperty("MomentumTransferStep");
-  double momentumTransferMaximum = getProperty("MomentumTransferMaximum");
-  MantidVec QParams;
-  if (isDefault("MomentumTransferMinimum"))
-    momentumTransferMinimum = calculateQ(IvsLam->x(0).back(), theta.get());
-  if (isDefault("MomentumTransferMaximum"))
-    momentumTransferMaximum = calculateQ(IvsLam->x(0).front(), theta.get());
-  if (isDefault("MomentumTransferStep")) {
-    // if the DQQ is not given for this run.
-    // we will use NRCalculateSlitResolution to produce this value
-    // for us.
-    IAlgorithm_sptr calcResAlg =
-        createChildAlgorithm("NRCalculateSlitResolution");
-    calcResAlg->setProperty("Workspace", runWS);
-    calcResAlg->setProperty("TwoTheta", theta.get());
-    calcResAlg->execute();
-    if (!calcResAlg->isExecuted())
-      throw std::runtime_error(
-          "NRCalculateSlitResolution failed. Please manually "
-          "enter a value for MomentumTransferStep.");
-    momentumTransferStep = calcResAlg->getProperty("Resolution");
-  }
-  if (momentumTransferMinimum > momentumTransferMaximum)
-    throw std::invalid_argument("MomentumTransferMinimum must be less than "
-                                "MomentumTransferMaximum. Please check your "
-                                "inputs for these Properties.");
-  QParams.push_back(momentumTransferMinimum);
-  QParams.push_back(-momentumTransferStep);
-  QParams.push_back(momentumTransferMaximum);
-  IAlgorithm_sptr algRebin = this->createChildAlgorithm("Rebin");
-  algRebin->initialize();
-  algRebin->setProperty("InputWorkspace", IvsQ);
-  algRebin->setProperty("OutputWorkspace", IvsQ);
-  algRebin->setProperty("Params", QParams);
-  algRebin->execute();
-  if (!algRebin->isExecuted())
-    throw std::runtime_error("Failed to run Rebin algorithm");
-  IvsQ = algRebin->getProperty("OutputWorkspace");
-  double scaleFactor = getProperty("ScaleFactor");
-  if (!isDefault("ScaleFactor")) {
-    IAlgorithm_sptr algScale = this->createChildAlgorithm("Scale");
-    algScale->initialize();
-    algScale->setProperty("InputWorkspace", IvsQ);
-    algScale->setProperty("OutputWorkspace", IvsQ);
-    algScale->setProperty("Factor", 1.0 / scaleFactor);
-    algScale->execute();
-    if (!algScale->isExecuted())
-      throw std::runtime_error("Failed to run Scale algorithm");
-    IvsQ = algScale->getProperty("OutputWorkspace");
-  }
-  setProperty("ThetaOut", theta.get());
-  setProperty("OutputWorkspaceWavelength", IvsLam);
-  setProperty("OutputWorkspace", IvsQ);
-  // setting these values so the Interface can retrieve them from
-  // ReflectometryReductionOneAuto.
-  setProperty("MomentumTransferMinimum", momentumTransferMinimum);
-  setProperty("MomentumTransferStep", momentumTransferStep);
-  setProperty("MomentumTransferMaximum", momentumTransferMaximum);
-}
-
-/**
-* Perform Transmission Corrections.
-* @param IvsLam : Run workspace which is to be normalized by the results of the
-* transmission corrections.
-* @param wavelengthInterval : Wavelength interval for the run workspace.
-* @param wavelengthMonitorBackgroundInterval : Wavelength interval for the
-* monitor background
-* @param wavelengthMonitorIntegrationInterval : Wavelength interval for the
-* monitor integration
-* @param i0MonitorIndex : Monitor index for the I0 monitor
-* @param firstTransmissionRun : The first transmission run
-* @param secondTransmissionRun : The second transmission run (optional)
-* @param stitchingStart : Stitching start in wavelength (optional but dependent
-* on secondTransmissionRun)
-* @param stitchingDelta : Stitching delta in wavelength (optional but dependent
-* on secondTransmissionRun)
-* @param stitchingEnd : Stitching end in wavelength (optional but dependent on
-* secondTransmissionRun)
-* @param stitchingStartOverlap : Stitching start wavelength overlap (optional
-* but dependent on secondTransmissionRun)
-* @param stitchingEndOverlap : Stitching end wavelength overlap (optional but
-* dependent on secondTransmissionRun)
-* @param numeratorProcessingCommands: Processing commands used on detector
-* workspace.
-* @return Normalized run workspace by the transmission workspace, which have
-* themselves been converted to Lam, normalized by monitors and possibly
-* stitched together.
-*/
-MatrixWorkspace_sptr ReflectometryReductionOne::transmissonCorrection(
-    MatrixWorkspace_sptr IvsLam, const MinMax &wavelengthInterval,
-    const OptionalMinMax &wavelengthMonitorBackgroundInterval,
-    const OptionalMinMax &wavelengthMonitorIntegrationInterval,
-    const OptionalInteger &i0MonitorIndex,
-    MatrixWorkspace_sptr firstTransmissionRun,
-    OptionalMatrixWorkspace_sptr secondTransmissionRun,
-    const OptionalDouble &stitchingStart, const OptionalDouble &stitchingDelta,
-    const OptionalDouble &stitchingEnd,
-    const OptionalDouble &stitchingStartOverlap,
-    const OptionalDouble &stitchingEndOverlap,
-    const std::string &numeratorProcessingCommands) {
-  g_log.debug(
-      "Extracting first transmission run workspace indexes from spectra");
-
-  const bool strictSpectrumChecking = getProperty("StrictSpectrumChecking");
-
-  MatrixWorkspace_sptr denominator = firstTransmissionRun;
-  Unit_const_sptr xUnit = firstTransmissionRun->getAxis(0)->unit();
-  if (xUnit->unitID() == tofUnitId) {
-    std::string spectrumProcessingCommands = numeratorProcessingCommands;
-    /*
-    If we have strict spectrum checking, the processing commands need to be
-    made from the
-    numerator workspace AND the transmission workspace based on matching
-    spectrum numbers.
-    */
-    if (strictSpectrumChecking) {
-      spectrumProcessingCommands =
-          createWorkspaceIndexListFromDetectorWorkspace(IvsLam,
-                                                        firstTransmissionRun);
-    }
-
-    // Make the transmission run.
-    auto alg = this->createChildAlgorithm("CreateTransmissionWorkspace", -1, -1,
-                                          true, 1);
-    alg->initialize();
-    alg->setProperty("FirstTransmissionRun", firstTransmissionRun);
-    if (secondTransmissionRun.is_initialized()) {
-      alg->setProperty("SecondTransmissionRun", secondTransmissionRun.get());
-
-      if (stitchingStart.is_initialized() && stitchingEnd.is_initialized() &&
-          stitchingDelta.is_initialized()) {
-        const std::vector<double> params = {
-            stitchingStart.get(), stitchingDelta.get(), stitchingEnd.get()};
-        alg->setProperty("Params", params);
-      } else if (stitchingDelta.is_initialized()) {
-        alg->setProperty("Params",
-                         std::vector<double>(1, stitchingDelta.get()));
-      }
-      if (stitchingStartOverlap.is_initialized()) {
-        alg->setProperty("StartOverlap", stitchingStartOverlap.get());
-      }
-      if (stitchingEndOverlap.is_initialized()) {
-        alg->setProperty("EndOverlap", stitchingEndOverlap.get());
-      }
-    }
-    alg->setProperty("ProcessingInstructions", spectrumProcessingCommands);
-    if (i0MonitorIndex.is_initialized()) {
-      alg->setProperty("I0MonitorIndex", i0MonitorIndex.get());
-    }
-    alg->setProperty("WavelengthMin", wavelengthInterval.get<0>());
-    alg->setProperty("WavelengthMax", wavelengthInterval.get<1>());
-    if (wavelengthMonitorBackgroundInterval.is_initialized()) {
-      alg->setProperty("MonitorBackgroundWavelengthMin",
-                       wavelengthMonitorBackgroundInterval.get().get<0>());
-      alg->setProperty("MonitorBackgroundWavelengthMax",
-                       wavelengthMonitorBackgroundInterval.get().get<1>());
-    }
-    if (wavelengthMonitorIntegrationInterval.is_initialized()) {
-      alg->setProperty("MonitorIntegrationWavelengthMin",
-                       wavelengthMonitorIntegrationInterval.get().get<0>());
-      alg->setProperty("MonitorIntegrationWavelengthMax",
-                       wavelengthMonitorIntegrationInterval.get().get<1>());
-    }
-    alg->execute();
-    denominator = alg->getProperty("OutputWorkspace");
-  }
-
-  // Rebin the transmission run to be the same as the input.
-  auto rebinToWorkspaceAlg = this->createChildAlgorithm("RebinToWorkspace");
-  rebinToWorkspaceAlg->initialize();
-  rebinToWorkspaceAlg->setProperty("WorkspaceToMatch", IvsLam);
-  rebinToWorkspaceAlg->setProperty("WorkspaceToRebin", denominator);
-  rebinToWorkspaceAlg->execute();
-  denominator = rebinToWorkspaceAlg->getProperty("OutputWorkspace");
-
-  verifySpectrumMaps(IvsLam, denominator, strictSpectrumChecking);
-
-  // Do normalization.
-  MatrixWorkspace_sptr normalizedIvsLam = divide(IvsLam, denominator);
-  return normalizedIvsLam;
-}
-
-/**
-* Perform transmission correction using alternative correction algorithms.
-* @param IvsLam : Run workspace which is to be normalized by the results of the
-* transmission corrections.
-* @return Corrected workspace
-*/
-MatrixWorkspace_sptr
-ReflectometryReductionOne::algorithmicCorrection(MatrixWorkspace_sptr IvsLam) {
-
-  const std::string corrAlgName = getProperty("CorrectionAlgorithm");
-
-  IAlgorithm_sptr corrAlg = createChildAlgorithm(corrAlgName);
-  corrAlg->initialize();
-  if (corrAlgName == "PolynomialCorrection") {
-    corrAlg->setPropertyValue("Coefficients", getPropertyValue("Polynomial"));
-  } else if (corrAlgName == "ExponentialCorrection") {
-    corrAlg->setPropertyValue("C0", getPropertyValue("C0"));
-    corrAlg->setPropertyValue("C1", getPropertyValue("C1"));
-  } else {
-    throw std::runtime_error("Unknown correction algorithm: " + corrAlgName);
-  }
-
-  corrAlg->setProperty("InputWorkspace", IvsLam);
-  corrAlg->setProperty("Operation", "Divide");
-  corrAlg->execute();
-
-  return corrAlg->getProperty("OutputWorkspace");
-}
-
-/**
-@param ws1 : First workspace to compare
-@param ws2 : Second workspace to compare against
-@param severe: True to indicate that failure to verify should result in an
-exception. Otherwise a warning is generated.
-*/
-void ReflectometryReductionOne::verifySpectrumMaps(
-    MatrixWorkspace_const_sptr ws1, MatrixWorkspace_const_sptr ws2,
-    const bool severe) {
-  auto map1 = ws1->getSpectrumToWorkspaceIndexMap();
-  auto map2 = ws2->getSpectrumToWorkspaceIndexMap();
-  if (map1 != map2) {
-    std::string message = "Spectrum maps between workspaces do NOT match up.";
-    if (severe) {
-      throw std::invalid_argument(message);
-    } else {
-      this->g_log.warning(message);
-    }
-  }
-}
-
-} // namespace Algorithms
-} // namespace Mantid
diff --git a/Framework/Algorithms/src/ReflectometryReductionOne2.cpp b/Framework/Algorithms/src/ReflectometryReductionOne2.cpp
index 28612fa314a91b43d1e3637296907b06db5ca938..9c83839c57f76676fcec1ddbdad5e7807eba3beb 100644
--- a/Framework/Algorithms/src/ReflectometryReductionOne2.cpp
+++ b/Framework/Algorithms/src/ReflectometryReductionOne2.cpp
@@ -10,6 +10,7 @@
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/StringTokenizer.h"
 #include "MantidKernel/Unit.h"
+#include "MantidKernel/UnitFactory.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
@@ -789,24 +790,48 @@ MatrixWorkspace_sptr ReflectometryReductionOne2::algorithmicCorrection(
   return corrAlg->getProperty("OutputWorkspace");
 }
 
-/**
-* The input workspace (in wavelength) to convert to Q
-* @param inputWS : the input workspace to convert
+/** Convert a workspace to Q
+*
+* @param inputWS : The input workspace (in wavelength) to convert to Q
 * @return : output workspace in Q
 */
 MatrixWorkspace_sptr
 ReflectometryReductionOne2::convertToQ(MatrixWorkspace_sptr inputWS) {
-
-  // Convert to Q
-  auto convertUnits = this->createChildAlgorithm("ConvertUnits");
-  convertUnits->initialize();
-  convertUnits->setProperty("InputWorkspace", inputWS);
-  convertUnits->setProperty("Target", "MomentumTransfer");
-  convertUnits->setProperty("AlignBins", false);
-  convertUnits->execute();
-  MatrixWorkspace_sptr IvsQ = convertUnits->getProperty("OutputWorkspace");
-
-  return IvsQ;
+  bool const moreThanOneDetector = inputWS->getDetector(0)->nDets() > 1;
+  bool const shouldCorrectAngle =
+      !(*getProperty("ThetaIn")).isDefault() && !summingInQ();
+  if (shouldCorrectAngle && moreThanOneDetector) {
+    if (inputWS->getNumberHistograms() > 1) {
+      throw std::invalid_argument(
+          "Expected a single group in "
+          "ProcessingInstructions to be able to "
+          "perform angle correction, found " +
+          std::to_string(inputWS->getNumberHistograms()));
+    }
+    MatrixWorkspace_sptr IvsQ = inputWS->clone();
+    auto &XOut0 = IvsQ->mutableX(0);
+    const auto &XIn0 = inputWS->x(0);
+    double const theta = getProperty("ThetaIn");
+    double const factor = 4.0 * M_PI * sin(theta * M_PI / 180.0);
+    std::transform(XIn0.rbegin(), XIn0.rend(), XOut0.begin(),
+                   [factor](double x) { return factor / x; });
+    auto &Y0 = IvsQ->mutableY(0);
+    auto &E0 = IvsQ->mutableE(0);
+    std::reverse(Y0.begin(), Y0.end());
+    std::reverse(E0.begin(), E0.end());
+    IvsQ->getAxis(0)->unit() =
+        UnitFactory::Instance().create("MomentumTransfer");
+    return IvsQ;
+  } else {
+    auto convertUnits = this->createChildAlgorithm("ConvertUnits");
+    convertUnits->initialize();
+    convertUnits->setProperty("InputWorkspace", inputWS);
+    convertUnits->setProperty("Target", "MomentumTransfer");
+    convertUnits->setProperty("AlignBins", false);
+    convertUnits->execute();
+    MatrixWorkspace_sptr IvsQ = convertUnits->getProperty("OutputWorkspace");
+    return IvsQ;
+  }
 }
 
 /**
@@ -1334,5 +1359,6 @@ void ReflectometryReductionOne2::verifySpectrumMaps(
     }
   }
 }
+
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp
deleted file mode 100644
index d2a2701bda63b4f12f4ac9a603b86d1ada1277d9..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp
+++ /dev/null
@@ -1,848 +0,0 @@
-#include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h"
-#include "MantidAlgorithms/ReflectometryReductionOneAuto.h"
-#include "MantidAPI/WorkspaceGroup.h"
-#include "MantidAPI/WorkspaceUnitValidator.h"
-#include "MantidKernel/ArrayProperty.h"
-#include "MantidKernel/BoundedValidator.h"
-#include "MantidKernel/EnabledWhenProperty.h"
-#include "MantidKernel/ListValidator.h"
-#include "MantidKernel/RebinParamsValidator.h"
-#include <boost/optional.hpp>
-
-/*Anonymous namespace*/
-namespace {
-/**
-* Helper free function to calculate MomentumTransfer from lambda and theta
-* @param lambda : Value in wavelength
-* @param theta  : Value in Degrees
-* @return MomentumTransfer
-* @
-*/
-double calculateQ(double lambda, double theta) {
-  if (lambda == 0.0)
-    throw std::runtime_error("Minimum/Maximum value of the IvsLambda Workspace "
-                             "is 0. Cannot calculate Q");
-  double thetaInRad = theta * M_PI / 180;
-  return (4 * M_PI * sin(thetaInRad)) / lambda;
-}
-}
-/*end of Anonymous namespace*/
-namespace Mantid {
-namespace Algorithms {
-
-using namespace Mantid::Kernel;
-using namespace Mantid::API;
-
-// Register the algorithm into the AlgorithmFactory
-DECLARE_ALGORITHM(ReflectometryReductionOneAuto)
-
-//----------------------------------------------------------------------------------------------
-
-/// Algorithm's name for identification. @see Algorithm::name
-const std::string ReflectometryReductionOneAuto::name() const {
-  return "ReflectometryReductionOneAuto";
-}
-
-/// Algorithm's version for identification. @see Algorithm::version
-int ReflectometryReductionOneAuto::version() const { return 1; }
-
-/// Algorithm's category for identification. @see Algorithm::category
-const std::string ReflectometryReductionOneAuto::category() const {
-  return "Reflectometry\\ISIS";
-}
-
-/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
-const std::string ReflectometryReductionOneAuto::summary() const {
-  return "Reduces a single TOF/Lambda reflectometry run into a mod Q vs I/I0 "
-         "workspace. Performs transmission corrections.";
-}
-
-//----------------------------------------------------------------------------------------------
-/** Initialize the algorithm's properties.
-*/
-void ReflectometryReductionOneAuto::init() {
-  declareProperty(
-      make_unique<WorkspaceProperty<MatrixWorkspace>>(
-          "InputWorkspace", "", Direction::Input, PropertyMode::Mandatory),
-      "Input run in TOF or Lambda");
-
-  std::vector<std::string> analysis_modes{"PointDetectorAnalysis",
-                                          "MultiDetectorAnalysis"};
-  auto analysis_mode_validator =
-      boost::make_shared<StringListValidator>(analysis_modes);
-
-  declareProperty(
-      make_unique<ArrayProperty<int>>("RegionOfDirectBeam", Direction::Input),
-      "Indices of the spectra a pair (lower, upper) that mark the ranges that "
-      "correspond to the direct beam in multi-detector mode.");
-
-  declareProperty("AnalysisMode", analysis_modes[0], analysis_mode_validator,
-                  "Analysis Mode to Choose", Direction::Input);
-
-  declareProperty(
-      make_unique<WorkspaceProperty<MatrixWorkspace>>(
-          "FirstTransmissionRun", "", Direction::Input, PropertyMode::Optional),
-      "First transmission run workspace in TOF or Wavelength");
-
-  auto tof_validator = boost::make_shared<WorkspaceUnitValidator>("TOF");
-  declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>(
-                      "SecondTransmissionRun", "", Direction::Input,
-                      PropertyMode::Optional, tof_validator),
-                  "Second transmission run workspace in TOF");
-  declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>(
-                      "OutputWorkspace", "", Direction::Output),
-                  "Output workspace in wavelength q");
-  declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>(
-                      "OutputWorkspaceWavelength", "", Direction::Output),
-                  "Output workspace in wavelength");
-
-  declareProperty(
-      make_unique<ArrayProperty<double>>(
-          "Params", boost::make_shared<RebinParamsValidator>(true)),
-      "A comma separated list of first bin boundary, width, last bin boundary. "
-      "These parameters are used for stitching together transmission runs. "
-      "Values are in wavelength (angstroms). This input is only needed if a "
-      "SecondTransmission run is provided.");
-
-  declareProperty("StartOverlap", Mantid::EMPTY_DBL(), "Overlap in Q.",
-                  Direction::Input);
-
-  declareProperty("EndOverlap", Mantid::EMPTY_DBL(), "End overlap in Q.",
-                  Direction::Input);
-  declareProperty("ScaleFactor", 1.0,
-                  "Factor you wish to scale Q workspace by.", Direction::Input);
-  auto index_bounds = boost::make_shared<BoundedValidator<int>>();
-  index_bounds->setLower(0);
-
-  declareProperty(make_unique<PropertyWithValue<int>>(
-                      "I0MonitorIndex", Mantid::EMPTY_INT(), Direction::Input),
-                  "I0 monitor workspace index. Optional.");
-  declareProperty(make_unique<PropertyWithValue<std::string>>(
-                      "ProcessingInstructions", "", Direction::Input),
-                  "Grouping pattern of workspace indices to yield only the"
-                  " detectors of interest. See GroupDetectors for syntax.");
-  declareProperty("WavelengthMin", Mantid::EMPTY_DBL(),
-                  "Wavelength Min in angstroms", Direction::Input);
-  declareProperty("WavelengthMax", Mantid::EMPTY_DBL(),
-                  "Wavelength Max in angstroms", Direction::Input);
-  declareProperty("WavelengthStep", Mantid::EMPTY_DBL(),
-                  "Wavelength step in angstroms", Direction::Input);
-  declareProperty("MomentumTransferMinimum", Mantid::EMPTY_DBL(),
-                  "Minimum Q value in IvsQ "
-                  "Workspace. Used for Rebinning "
-                  "the IvsQ Workspace",
-                  Direction::Input);
-  declareProperty("MomentumTransferStep", Mantid::EMPTY_DBL(),
-                  "Resolution value in IvsQ Workspace. Used for Rebinning the "
-                  "IvsQ Workspace. This value will be made minus to apply "
-                  "logarithmic rebinning. If you wish to have linear "
-                  "bin-widths then please provide a negative DQQ",
-                  Direction::Input);
-  declareProperty("MomentumTransferMaximum", Mantid::EMPTY_DBL(),
-                  "Maximum Q value in IvsQ "
-                  "Workspace. Used for Rebinning "
-                  "the IvsQ Workspace",
-                  Direction::Input);
-  declareProperty("MonitorBackgroundWavelengthMin", Mantid::EMPTY_DBL(),
-                  "Monitor wavelength background min in angstroms",
-                  Direction::Input);
-  declareProperty("MonitorBackgroundWavelengthMax", Mantid::EMPTY_DBL(),
-                  "Monitor wavelength background max in angstroms",
-                  Direction::Input);
-  declareProperty("MonitorIntegrationWavelengthMin", Mantid::EMPTY_DBL(),
-                  "Monitor integral min in angstroms", Direction::Input);
-  declareProperty("MonitorIntegrationWavelengthMax", Mantid::EMPTY_DBL(),
-                  "Monitor integral max in angstroms", Direction::Input);
-  declareProperty(make_unique<PropertyWithValue<std::string>>(
-                      "DetectorComponentName", "", Direction::Input),
-                  "Name of the detector component i.e. point-detector. If "
-                  "these are not specified, the algorithm will attempt lookup "
-                  "using a standard naming convention.");
-  declareProperty(make_unique<PropertyWithValue<std::string>>(
-                      "SampleComponentName", "", Direction::Input),
-                  "Name of the sample component i.e. some-surface-holder. If "
-                  "these are not specified, the algorithm will attempt lookup "
-                  "using a standard naming convention.");
-
-  declareProperty("ThetaIn", Mantid::EMPTY_DBL(), "Final theta in degrees",
-                  Direction::Input);
-  declareProperty("ThetaOut", Mantid::EMPTY_DBL(),
-                  "Calculated final theta in degrees.", Direction::Output);
-
-  declareProperty("NormalizeByIntegratedMonitors", true,
-                  "Normalize by dividing by the integrated monitors.");
-
-  declareProperty("CorrectDetectorPositions", true,
-                  "Correct detector positions using ThetaIn (if given)");
-
-  declareProperty("StrictSpectrumChecking", true,
-                  "Strict checking between spectrum numbers in input "
-                  "workspaces and transmission workspaces.");
-  std::vector<std::string> correctionAlgorithms = {
-      "None", "AutoDetect", "PolynomialCorrection", "ExponentialCorrection"};
-  declareProperty("CorrectionAlgorithm", "AutoDetect",
-                  boost::make_shared<StringListValidator>(correctionAlgorithms),
-                  "The type of correction to perform.");
-
-  declareProperty(make_unique<ArrayProperty<double>>("Polynomial"),
-                  "Coefficients to be passed to the PolynomialCorrection"
-                  " algorithm.");
-
-  declareProperty(
-      make_unique<PropertyWithValue<double>>("C0", 0.0, Direction::Input),
-      "C0 value to be passed to the ExponentialCorrection algorithm.");
-
-  declareProperty(
-      make_unique<PropertyWithValue<double>>("C1", 0.0, Direction::Input),
-      "C1 value to be passed to the ExponentialCorrection algorithm.");
-
-  setPropertyGroup("CorrectionAlgorithm", "Polynomial Corrections");
-  setPropertyGroup("Polynomial", "Polynomial Corrections");
-  setPropertyGroup("C0", "Polynomial Corrections");
-  setPropertyGroup("C1", "Polynomial Corrections");
-
-  setPropertySettings(
-      "Polynomial",
-      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-          "CorrectionAlgorithm", IS_EQUAL_TO, "PolynomialCorrection"));
-  setPropertySettings(
-      "C0", Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection"));
-  setPropertySettings(
-      "C1", Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection"));
-
-  // Polarization correction inputs --------------
-  std::vector<std::string> propOptions;
-  propOptions.push_back(noPolarizationCorrectionMode());
-  propOptions.push_back(pALabel());
-  propOptions.push_back(pNRLabel());
-
-  declareProperty("PolarizationAnalysis", noPolarizationCorrectionMode(),
-                  boost::make_shared<StringListValidator>(propOptions),
-                  "What Polarization mode will be used?\n"
-                  "None: No correction\n"
-                  "PNR: Polarized Neutron Reflectivity mode\n"
-                  "PA: Full Polarization Analysis PNR-PA");
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>(cppLabel(), Direction::Input),
-      "Effective polarizing power of the polarizing system. "
-      "Expressed as a ratio 0 < Pp < 1");
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>(cApLabel(), Direction::Input),
-      "Effective polarizing power of the analyzing system. "
-      "Expressed as a ratio 0 < Ap < 1");
-  declareProperty(
-      Kernel::make_unique<ArrayProperty<double>>(crhoLabel(), Direction::Input),
-      "Ratio of efficiencies of polarizer spin-down to polarizer "
-      "spin-up. This is characteristic of the polarizer flipper. "
-      "Values are constants for each term in a polynomial "
-      "expression.");
-  declareProperty(Kernel::make_unique<ArrayProperty<double>>(cAlphaLabel(),
-                                                             Direction::Input),
-                  "Ratio of efficiencies of analyzer spin-down to analyzer "
-                  "spin-up. This is characteristic of the analyzer flipper. "
-                  "Values are factors for each term in a polynomial "
-                  "expression.");
-  setPropertyGroup("PolarizationAnalysis", "Polarization Corrections");
-  setPropertyGroup(cppLabel(), "Polarization Corrections");
-  setPropertyGroup(cApLabel(), "Polarization Corrections");
-  setPropertyGroup(crhoLabel(), "Polarization Corrections");
-  setPropertyGroup(cAlphaLabel(), "Polarization Corrections");
-  setPropertySettings(cppLabel(),
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "PolarizationAnalysis", IS_NOT_EQUAL_TO,
-                          noPolarizationCorrectionMode()));
-  setPropertySettings(cApLabel(),
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "PolarizationAnalysis", IS_NOT_EQUAL_TO,
-                          noPolarizationCorrectionMode()));
-  setPropertySettings(crhoLabel(),
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "PolarizationAnalysis", IS_NOT_EQUAL_TO,
-                          noPolarizationCorrectionMode()));
-  setPropertySettings(cAlphaLabel(),
-                      Kernel::make_unique<Kernel::EnabledWhenProperty>(
-                          "PolarizationAnalysis", IS_NOT_EQUAL_TO,
-                          noPolarizationCorrectionMode()));
-}
-
-//----------------------------------------------------------------------------------------------
-/** Execute the algorithm.
-*/
-void ReflectometryReductionOneAuto::exec() {
-  MatrixWorkspace_sptr in_ws = getProperty("InputWorkspace");
-  auto instrument = in_ws->getInstrument();
-
-  // Get all the inputs.
-
-  std::string output_workspace_name = getPropertyValue("OutputWorkspace");
-  std::string output_workspace_lam_name =
-      getPropertyValue("OutputWorkspaceWavelength");
-  std::string analysis_mode = getPropertyValue("AnalysisMode");
-  MatrixWorkspace_sptr first_ws = getProperty("FirstTransmissionRun");
-  MatrixWorkspace_sptr second_ws = getProperty("SecondTransmissionRun");
-  auto start_overlap = isSet<double>("StartOverlap");
-  auto end_overlap = isSet<double>("EndOverlap");
-  auto params = isSet<MantidVec>("Params");
-  auto i0_monitor_index = checkForOptionalInstrumentDefault<int>(
-      this, "I0MonitorIndex", instrument, "I0MonitorIndex");
-
-  std::string processing_commands;
-  if (this->getPointerToProperty("ProcessingInstructions")->isDefault()) {
-    if (analysis_mode == "PointDetectorAnalysis") {
-      std::vector<double> pointStart =
-          instrument->getNumberParameter("PointDetectorStart");
-      std::vector<double> pointStop =
-          instrument->getNumberParameter("PointDetectorStop");
-
-      if (pointStart.empty() || pointStop.empty())
-        throw std::runtime_error(
-            "If ProcessingInstructions is not specified, BOTH "
-            "PointDetectorStart "
-            "and PointDetectorStop must exist as instrument parameters.\n"
-            "Please check if you meant to enter ProcessingInstructions or "
-            "if your instrument parameter file is correct.");
-
-      const int detStart = static_cast<int>(pointStart[0]);
-      const int detStop = static_cast<int>(pointStop[0]);
-
-      if (detStart == detStop) {
-        // If the range given only specifies one detector, we pass along just
-        // that one detector
-        processing_commands = std::to_string(detStart);
-      } else {
-        // Otherwise, we create a range.
-        processing_commands =
-            std::to_string(detStart) + ":" + std::to_string(detStop);
-      }
-    } else {
-      std::vector<double> multiStart =
-          instrument->getNumberParameter("MultiDetectorStart");
-      if (multiStart.empty())
-        throw std::runtime_error(
-            "If ProcessingInstructions is not specified, MultiDetectorStart"
-            "must exist as an instrument parameter.\n"
-            "Please check if you meant to enter ProcessingInstructions or "
-            "if your instrument parameter file is correct.");
-      processing_commands = std::to_string(static_cast<int>(multiStart[0])) +
-                            ":" +
-                            std::to_string(in_ws->getNumberHistograms() - 1);
-    }
-  } else {
-    std::string processing_commands_temp =
-        this->getProperty("ProcessingInstructions");
-    processing_commands = processing_commands_temp;
-  }
-
-  double wavelength_min = checkForMandatoryInstrumentDefault<double>(
-      this, "WavelengthMin", instrument, "LambdaMin");
-  double wavelength_max = checkForMandatoryInstrumentDefault<double>(
-      this, "WavelengthMax", instrument, "LambdaMax");
-  auto wavelength_step = isSet<double>("WavelengthStep");
-  auto wavelength_back_min = checkForOptionalInstrumentDefault<double>(
-      this, "MonitorBackgroundWavelengthMin", instrument,
-      "MonitorBackgroundMin");
-  auto wavelength_back_max = checkForOptionalInstrumentDefault<double>(
-      this, "MonitorBackgroundWavelengthMax", instrument,
-      "MonitorBackgroundMax");
-  auto wavelength_integration_min = checkForOptionalInstrumentDefault<double>(
-      this, "MonitorIntegrationWavelengthMin", instrument,
-      "MonitorIntegralMin");
-  auto wavelength_integration_max = checkForOptionalInstrumentDefault<double>(
-      this, "MonitorIntegrationWavelengthMax", instrument,
-      "MonitorIntegralMax");
-
-  auto detector_component_name = isSet<std::string>("DetectorComponentName");
-  auto sample_component_name = isSet<std::string>("SampleComponentName");
-  auto theta_in = isSet<double>("ThetaIn");
-  auto region_of_direct_beam = isSet<std::vector<int>>("RegionOfDirectBeam");
-
-  bool correct_positions = this->getProperty("CorrectDetectorPositions");
-  bool strict_spectrum_checking = this->getProperty("StrictSpectrumChecking");
-  bool norm_by_int_mons = getProperty("NormalizeByIntegratedMonitors");
-  const std::string correction_algorithm = getProperty("CorrectionAlgorithm");
-
-  // Pass the arguments and execute the main algorithm.
-
-  IAlgorithm_sptr refRedOne =
-      createChildAlgorithm("ReflectometryReductionOne", -1, -1, true, 1);
-  refRedOne->initialize();
-  if (refRedOne->isInitialized()) {
-    refRedOne->setProperty("InputWorkspace", in_ws);
-    refRedOne->setProperty("AnalysisMode", analysis_mode);
-    refRedOne->setProperty("OutputWorkspace", output_workspace_name);
-    refRedOne->setProperty("OutputWorkspaceWavelength",
-                           output_workspace_lam_name);
-    refRedOne->setProperty("NormalizeByIntegratedMonitors", norm_by_int_mons);
-
-    if (i0_monitor_index.is_initialized()) {
-      if (i0_monitor_index.get() >= 0)
-        refRedOne->setProperty("I0MonitorIndex", i0_monitor_index.get());
-      else
-        throw std::invalid_argument(
-            "I0MonitorIndex must be an integer greater than or equal to 0");
-    }
-    refRedOne->setProperty("ProcessingInstructions", processing_commands);
-    refRedOne->setProperty("WavelengthMin", wavelength_min);
-    refRedOne->setProperty("WavelengthMax", wavelength_max);
-    if (wavelength_back_min.is_initialized())
-      refRedOne->setProperty("MonitorBackgroundWavelengthMin",
-                             wavelength_back_min.get());
-    if (wavelength_back_max.is_initialized())
-      refRedOne->setProperty("MonitorBackgroundWavelengthMax",
-                             wavelength_back_max.get());
-    if (wavelength_integration_min.is_initialized())
-      refRedOne->setProperty("MonitorIntegrationWavelengthMin",
-                             wavelength_integration_min.get());
-    if (wavelength_integration_max.is_initialized())
-      refRedOne->setProperty("MonitorIntegrationWavelengthMax",
-                             wavelength_integration_max.get());
-    refRedOne->setProperty("CorrectDetectorPositions", correct_positions);
-    refRedOne->setProperty("StrictSpectrumChecking", strict_spectrum_checking);
-    if (correction_algorithm == "PolynomialCorrection") {
-      // Copy across the polynomial
-      refRedOne->setProperty("CorrectionAlgorithm", "PolynomialCorrection");
-      refRedOne->setProperty("Polynomial", getPropertyValue("Polynomial"));
-    } else if (correction_algorithm == "ExponentialCorrection") {
-      // Copy across c0 and c1
-      refRedOne->setProperty("CorrectionAlgorithm", "ExponentialCorrection");
-      refRedOne->setProperty("C0", getPropertyValue("C0"));
-      refRedOne->setProperty("C1", getPropertyValue("C1"));
-    } else if (correction_algorithm == "AutoDetect") {
-      // Figure out what to do from the instrument
-      try {
-        auto inst = in_ws->getInstrument();
-
-        const std::vector<std::string> corrVec =
-            inst->getStringParameter("correction");
-        const std::string correctionStr = !corrVec.empty() ? corrVec[0] : "";
-
-        if (correctionStr.empty())
-          throw std::runtime_error(
-              "'correction' instrument parameter was not found.");
-
-        const std::vector<std::string> polyVec =
-            inst->getStringParameter("polynomial");
-        const std::string polyStr = !polyVec.empty() ? polyVec[0] : "";
-
-        const std::vector<std::string> c0Vec = inst->getStringParameter("C0");
-        const std::string c0Str = !c0Vec.empty() ? c0Vec[0] : "";
-
-        const std::vector<std::string> c1Vec = inst->getStringParameter("C1");
-        const std::string c1Str = !c1Vec.empty() ? c1Vec[0] : "";
-
-        if (correctionStr == "polynomial" && polyStr.empty())
-          throw std::runtime_error(
-              "'polynomial' instrument parameter was not found.");
-
-        if (correctionStr == "exponential" && (c0Str.empty() || c1Str.empty()))
-          throw std::runtime_error(
-              "'C0' or 'C1' instrument parameter was not found.");
-
-        if (correctionStr == "polynomial") {
-          refRedOne->setProperty("CorrectionAlgorithm", "PolynomialCorrection");
-          refRedOne->setProperty("Polynomial", polyStr);
-        } else if (correctionStr == "exponential") {
-          refRedOne->setProperty("CorrectionAlgorithm",
-                                 "ExponentialCorrection");
-          refRedOne->setProperty("C0", c0Str);
-          refRedOne->setProperty("C1", c1Str);
-        }
-
-      } catch (std::runtime_error &e) {
-        g_log.warning() << "Could not autodetect polynomial correction method. "
-                           "Polynomial correction will not be performed. "
-                           "Reason for failure: " << e.what() << '\n';
-        refRedOne->setProperty("CorrectionAlgorithm", "None");
-      }
-
-    } else {
-      // None was selected
-      refRedOne->setProperty("CorrectionAlgorithm", "None");
-    }
-
-    if (first_ws) {
-      refRedOne->setProperty("FirstTransmissionRun", first_ws);
-    }
-
-    if (second_ws) {
-      refRedOne->setProperty("SecondTransmissionRun", second_ws);
-    }
-
-    if (start_overlap.is_initialized()) {
-      refRedOne->setProperty("StartOverlap", start_overlap.get());
-    }
-
-    if (end_overlap.is_initialized()) {
-      refRedOne->setProperty("EndOverlap", end_overlap.get());
-    }
-
-    if (params.is_initialized()) {
-      refRedOne->setProperty("Params", params.get());
-    }
-
-    if (wavelength_step.is_initialized()) {
-      refRedOne->setProperty("WavelengthStep", wavelength_step.get());
-    }
-
-    if (region_of_direct_beam.is_initialized()) {
-      refRedOne->setProperty("RegionOfDirectBeam", region_of_direct_beam.get());
-    }
-
-    if (detector_component_name.is_initialized()) {
-      refRedOne->setProperty("DetectorComponentName",
-                             detector_component_name.get());
-    }
-
-    if (sample_component_name.is_initialized()) {
-      refRedOne->setProperty("SampleComponentName",
-                             sample_component_name.get());
-    }
-
-    if (theta_in.is_initialized()) {
-      refRedOne->setProperty("ThetaIn", theta_in.get());
-    }
-    double scaleFactor = getProperty("ScaleFactor");
-    if (scaleFactor != 1.0) {
-      refRedOne->setProperty("ScaleFactor", scaleFactor);
-    }
-    auto momentumTransferMinimum = isSet<double>("MomentumTransferMinimum");
-    auto momentumTransferStep = isSet<double>("MomentumTransferStep");
-    auto momentumTransferMaximum = isSet<double>("MomentumTransferMaximum");
-
-    if (momentumTransferStep.is_initialized()) {
-      refRedOne->setProperty("MomentumTransferStep",
-                             momentumTransferStep.get());
-    }
-    if (momentumTransferMinimum.is_initialized())
-      refRedOne->setProperty("MomentumTransferMinimum",
-                             momentumTransferMinimum.get());
-    if (momentumTransferMaximum.is_initialized())
-      refRedOne->setProperty("MomentumTransferMaximum",
-                             momentumTransferMaximum.get());
-    if (theta_in.is_initialized()) {
-      if (!momentumTransferMinimum.is_initialized())
-        momentumTransferMinimum = calculateQ(wavelength_max, theta_in.get());
-      if (!momentumTransferStep.is_initialized()) {
-        IAlgorithm_sptr calcResAlg =
-            AlgorithmManager::Instance().create("NRCalculateSlitResolution");
-        calcResAlg->setProperty("Workspace", in_ws);
-        calcResAlg->setProperty("TwoTheta", theta_in.get());
-        calcResAlg->execute();
-        if (!calcResAlg->isExecuted())
-          throw std::runtime_error(
-              "NRCalculateSlitResolution failed. Please manually "
-              "enter a value in the dQ/Q column.");
-        double resolution = calcResAlg->getProperty("Resolution");
-        momentumTransferStep = resolution;
-      }
-      if (!momentumTransferMaximum.is_initialized())
-        momentumTransferMaximum = calculateQ(wavelength_min, theta_in.get());
-      refRedOne->setProperty("MomentumTransferMinimum",
-                             momentumTransferMinimum.get());
-      refRedOne->setProperty("MomentumTransferStep",
-                             momentumTransferStep.get());
-      refRedOne->setProperty("MomentumTransferMaximum",
-                             momentumTransferMaximum.get());
-    }
-    refRedOne->execute();
-    if (!refRedOne->isExecuted()) {
-      throw std::runtime_error(
-          "ReflectometryReductionOne did not execute sucessfully");
-    }
-
-    MatrixWorkspace_sptr new_IvsQ1 = refRedOne->getProperty("OutputWorkspace");
-    MatrixWorkspace_sptr new_IvsLam1 =
-        refRedOne->getProperty("OutputWorkspaceWavelength");
-    double thetaOut1 = refRedOne->getProperty("ThetaOut");
-    setProperty("OutputWorkspace", new_IvsQ1);
-    setProperty("OutputWorkspaceWavelength", new_IvsLam1);
-    setProperty("ThetaOut", thetaOut1);
-    // set properties so they can be retrieved by GenericDataProcesser if
-    // necessary.
-    setProperty("MomentumTransferMinimum",
-                boost::lexical_cast<double>(
-                    refRedOne->getPropertyValue("MomentumTransferMinimum")));
-    setProperty("MomentumTransferStep",
-                boost::lexical_cast<double>(
-                    refRedOne->getPropertyValue("MomentumTransferStep")));
-    setProperty("MomentumTransferMaximum",
-                boost::lexical_cast<double>(
-                    refRedOne->getPropertyValue("MomentumTransferMaximum")));
-    if (theta_in.is_initialized())
-      setProperty("ThetaIn", theta_in.get());
-    else
-      setProperty("ThetaIn", thetaOut1 / 2.);
-
-  } else {
-    throw std::runtime_error(
-        "ReflectometryReductionOne could not be initialised");
-  }
-}
-
-template <typename T>
-boost::optional<T>
-ReflectometryReductionOneAuto::isSet(std::string propName) const {
-  auto algProperty = this->getPointerToProperty(propName);
-  if (algProperty->isDefault()) {
-    return boost::optional<T>();
-  } else {
-    T value = this->getProperty(propName);
-    return boost::optional<T>(value);
-  }
-}
-
-bool ReflectometryReductionOneAuto::checkGroups() {
-  std::string wsName = getPropertyValue("InputWorkspace");
-
-  try {
-    auto ws =
-        AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(wsName);
-    if (ws)
-      return true;
-  } catch (...) {
-  }
-  return false;
-}
-/**
- * Sum over transmission group workspaces to produce one
- * workspace.
- * @param transGroup : The transmission group to be processed
- * @return A workspace pointer containing the sum of transmission workspaces.
- */
-Mantid::API::Workspace_sptr
-ReflectometryReductionOneAuto::sumOverTransmissionGroup(
-    WorkspaceGroup_sptr &transGroup) {
-  // Handle transmission runs
-
-  // we clone the first member of transmission group as to
-  // avoid addition in place which would affect the original
-  // workspace member.
-  //
-  // We used .release because clone() will return a unique_ptr.
-  // we need to release the ownership of the pointer so that it
-  // can be cast into a shared_ptr of type Workspace.
-  Workspace_sptr transmissionRunSum(transGroup->getItem(0)->clone());
-
-  // make a variable to store the overall total of the summation
-  MatrixWorkspace_sptr total;
-  // set up and initialize plus algorithm.
-  auto plusAlg = this->createChildAlgorithm("Plus");
-  plusAlg->setChild(true);
-  // plusAlg->setRethrows(true);
-  plusAlg->initialize();
-  // now accumalate the group members
-  for (size_t item = 1; item < transGroup->size(); ++item) {
-    plusAlg->setProperty("LHSWorkspace", transmissionRunSum);
-    plusAlg->setProperty("RHSWorkspace", transGroup->getItem(item));
-    plusAlg->setProperty("OutputWorkspace", transmissionRunSum);
-    plusAlg->execute();
-    total = plusAlg->getProperty("OutputWorkspace");
-  }
-  return total;
-}
-
-bool ReflectometryReductionOneAuto::processGroups() {
-  // isPolarizationCorrectionOn is used to decide whether
-  // we should process our Transmission WorkspaceGroup members
-  // as individuals (not multiperiod) when PolarizationCorrection is off,
-  // or sum over all of the workspaces in the group
-  // and used that sum as our TransmissionWorkspace when PolarizationCorrection
-  // is on.
-  const bool isPolarizationCorrectionOn =
-      this->getPropertyValue("PolarizationAnalysis") !=
-      noPolarizationCorrectionMode();
-
-  // this algorithm effectively behaves as MultiPeriodGroupAlgorithm
-  m_usingBaseProcessGroups = true;
-
-  // Get our input workspace group
-  auto group = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
-      getPropertyValue("InputWorkspace"));
-  // Get name of IvsQ workspace
-  const std::string outputIvsQ = this->getPropertyValue("OutputWorkspace");
-  // Get name of IvsLam workspace
-  const std::string outputIvsLam =
-      this->getPropertyValue("OutputWorkspaceWavelength");
-
-  // Create a copy of ourselves
-  Algorithm_sptr alg = this->createChildAlgorithm(
-      this->name(), -1, -1, this->isLogging(), this->version());
-  alg->setChild(false);
-  alg->setRethrows(true);
-
-  // Copy all the non-workspace properties over
-  std::vector<Property *> props = this->getProperties();
-  for (auto &prop : props) {
-    if (prop) {
-      IWorkspaceProperty *wsProp = dynamic_cast<IWorkspaceProperty *>(prop);
-      if (!wsProp)
-        alg->setPropertyValue(prop->name(), prop->value());
-    }
-  }
-
-  // Check if the transmission runs are groups or not
-  const std::string firstTrans = this->getPropertyValue("FirstTransmissionRun");
-  WorkspaceGroup_sptr firstTransG;
-  if (!firstTrans.empty()) {
-    auto firstTransWS =
-        AnalysisDataService::Instance().retrieveWS<Workspace>(firstTrans);
-    firstTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(firstTransWS);
-
-    if (!firstTransG) {
-      // we only have one transmission workspace, so we use it as it is.
-      alg->setProperty("FirstTransmissionRun", firstTrans);
-    } else if (group->size() != firstTransG->size() &&
-               !isPolarizationCorrectionOn) {
-      // if they are not the same size then we cannot associate a transmission
-      // group workspace member with every input group workpspace member.
-      throw std::runtime_error("FirstTransmissionRun WorkspaceGroup must be "
-                               "the same size as the InputWorkspace "
-                               "WorkspaceGroup");
-    }
-  }
-
-  const std::string secondTrans =
-      this->getPropertyValue("SecondTransmissionRun");
-  WorkspaceGroup_sptr secondTransG;
-  if (!secondTrans.empty()) {
-    auto secondTransWS =
-        AnalysisDataService::Instance().retrieveWS<Workspace>(secondTrans);
-    secondTransG = boost::dynamic_pointer_cast<WorkspaceGroup>(secondTransWS);
-
-    if (!secondTransG)
-      // we only have one transmission workspace, so we use it as it is.
-      alg->setProperty("SecondTransmissionRun", secondTrans);
-
-    else if (group->size() != secondTransG->size() &&
-             !isPolarizationCorrectionOn) {
-      // if they are not the same size then we cannot associate a transmission
-      // group workspace member with every input group workpspace member.
-      throw std::runtime_error("SecondTransmissionRun WorkspaceGroup must be "
-                               "the same size as the InputWorkspace "
-                               "WorkspaceGroup");
-    }
-  }
-  std::vector<std::string> IvsQGroup, IvsLamGroup;
-
-  // Execute algorithm over each group member (or period, if this is
-  // multiperiod)
-  size_t numMembers = group->size();
-  for (size_t i = 0; i < numMembers; ++i) {
-    const std::string IvsQName = outputIvsQ + "_" + std::to_string(i + 1);
-    const std::string IvsLamName = outputIvsLam + "_" + std::to_string(i + 1);
-
-    // If our transmission run is a group and PolarizationCorrection is on
-    // then we sum our transmission group members.
-    //
-    // This is done inside of the for loop to avoid the wrong workspace being
-    // used when these arguments are passed through to the exec() method.
-    // If this is not set in the loop, exec() will fetch the first workspace
-    // from the specified Transmission Group workspace that the user entered.
-    if (firstTransG && isPolarizationCorrectionOn) {
-      auto firstTransmissionSum = sumOverTransmissionGroup(firstTransG);
-      alg->setProperty("FirstTransmissionRun", firstTransmissionSum);
-    }
-    if (secondTransG && isPolarizationCorrectionOn) {
-      auto secondTransmissionSum = sumOverTransmissionGroup(secondTransG);
-      alg->setProperty("SecondTransmissionRun", secondTransmissionSum);
-    }
-
-    // Otherwise, if polarization correction is off, we process them
-    // using one transmission group member at a time.
-    if (firstTransG && !isPolarizationCorrectionOn) // polarization off
-      alg->setProperty("FirstTransmissionRun",
-                       firstTransG->getItem(i)->getName());
-    if (secondTransG && !isPolarizationCorrectionOn) // polarization off
-      alg->setProperty("SecondTransmissionRun",
-                       secondTransG->getItem(i)->getName());
-
-    alg->setProperty("InputWorkspace", group->getItem(i)->getName());
-    alg->setProperty("OutputWorkspace", IvsQName);
-    alg->setProperty("OutputWorkspaceWavelength", IvsLamName);
-    alg->execute();
-
-    MatrixWorkspace_sptr tempFirstTransWS =
-        alg->getProperty("FirstTransmissionRun");
-
-    IvsQGroup.push_back(IvsQName);
-    IvsLamGroup.push_back(IvsLamName);
-
-    // We use the first group member for our thetaout value
-    if (i == 0)
-      this->setPropertyValue("ThetaOut", alg->getPropertyValue("ThetaOut"));
-  }
-
-  // Group the IvsQ and IvsLam workspaces
-  Algorithm_sptr groupAlg = this->createChildAlgorithm("GroupWorkspaces");
-  groupAlg->setChild(false);
-  groupAlg->setRethrows(true);
-
-  groupAlg->setProperty("InputWorkspaces", IvsLamGroup);
-  groupAlg->setProperty("OutputWorkspace", outputIvsLam);
-  groupAlg->execute();
-
-  groupAlg->setProperty("InputWorkspaces", IvsQGroup);
-  groupAlg->setProperty("OutputWorkspace", outputIvsQ);
-  groupAlg->execute();
-
-  // If this is a multiperiod workspace and we have polarization corrections
-  // enabled
-  if (isPolarizationCorrectionOn) {
-    if (group->isMultiperiod()) {
-      // Perform polarization correction over the IvsLam group
-      Algorithm_sptr polAlg =
-          this->createChildAlgorithm("PolarizationCorrection");
-      polAlg->setChild(false);
-      polAlg->setRethrows(true);
-
-      polAlg->setProperty("InputWorkspace", outputIvsLam);
-      polAlg->setProperty("OutputWorkspace", outputIvsLam);
-      polAlg->setProperty("PolarizationAnalysis",
-                          this->getPropertyValue("PolarizationAnalysis"));
-      polAlg->setProperty("CPp", this->getPropertyValue(cppLabel()));
-      polAlg->setProperty("CRho", this->getPropertyValue(crhoLabel()));
-      polAlg->setProperty("CAp", this->getPropertyValue(cApLabel()));
-      polAlg->setProperty("CAlpha", this->getPropertyValue(cAlphaLabel()));
-      polAlg->execute();
-
-      // Now we've overwritten the IvsLam workspaces, we'll need to recalculate
-      // the IvsQ ones
-      alg->setProperty("FirstTransmissionRun", "");
-      alg->setProperty("SecondTransmissionRun", "");
-      for (size_t i = 0; i < numMembers; ++i) {
-        const std::string IvsQName = outputIvsQ + "_" + std::to_string(i + 1);
-        const std::string IvsLamName =
-            outputIvsLam + "_" + std::to_string(i + 1);
-        alg->setProperty("InputWorkspace", IvsLamName);
-        alg->setProperty("OutputWorkspace", IvsQName);
-        alg->setProperty("CorrectionAlgorithm", "None");
-        alg->setProperty("OutputWorkspaceWavelength", IvsLamName);
-        alg->execute();
-      }
-    } else {
-      g_log.warning("Polarization corrections can only be performed on "
-                    "multiperiod workspaces.");
-    }
-  }
-
-  // We finished successfully
-  // set the values of these properties so they can be retrieved by the
-  // Interface.
-  this->setProperty("MomentumTransferMinimum",
-                    boost::lexical_cast<double>(
-                        alg->getPropertyValue("MomentumTransferMinimum")));
-  this->setProperty("MomentumTransferStep",
-                    boost::lexical_cast<double>(
-                        alg->getPropertyValue("MomentumTransferStep")));
-  this->setProperty("MomentumTransferMaximum",
-                    boost::lexical_cast<double>(
-                        alg->getPropertyValue("MomentumTransferMaximum")));
-  // setting output properties.
-  this->setPropertyValue("OutputWorkspace", outputIvsQ);
-  this->setPropertyValue("OutputWorkspaceWavelength", outputIvsLam);
-  return true;
-}
-} // namespace Algorithms
-} // namespace Mantid
diff --git a/Framework/Algorithms/src/RemoveBins.cpp b/Framework/Algorithms/src/RemoveBins.cpp
index d6a57216f2a4449ee442d6f12edea30a1012cf2b..3cdeaa1ca48885c0e4ebeb9f4ba75cca47394814 100644
--- a/Framework/Algorithms/src/RemoveBins.cpp
+++ b/Framework/Algorithms/src/RemoveBins.cpp
@@ -49,10 +49,10 @@ void RemoveBins::init() {
   std::vector<std::string> units = UnitFactory::Instance().getKeys();
 
   // remove some known units that will not work
-  units.erase(std::remove(units.begin(), units.end(), "Empty"));
-  units.erase(std::remove(units.begin(), units.end(), "Label"));
-  units.erase(std::remove(units.begin(), units.end(), "Time"));
-  units.erase(std::remove(units.begin(), units.end(), "Degrees"));
+  units.erase(std::remove(units.begin(), units.end(), "Empty"), units.end());
+  units.erase(std::remove(units.begin(), units.end(), "Label"), units.end());
+  units.erase(std::remove(units.begin(), units.end(), "Time"), units.end());
+  units.erase(std::remove(units.begin(), units.end(), "Degrees"), units.end());
 
   // add a default do nothing value
   units.insert(units.begin(), "AsInput");
diff --git a/Framework/Algorithms/src/RingProfile.cpp b/Framework/Algorithms/src/RingProfile.cpp
index b54b772a09f23dfbea72486416c5fffb87407738..8ffb30a6e900a02799ca94be59af26f7e3fffa22 100644
--- a/Framework/Algorithms/src/RingProfile.cpp
+++ b/Framework/Algorithms/src/RingProfile.cpp
@@ -418,8 +418,8 @@ void RingProfile::processInstrumentRingProfile(
 
     const MantidVec &refY = inputWS->getSpectrum(i).dataY();
     // accumulate the values of this spectrum inside this bin
-    for (size_t sp_ind = 0; sp_ind < refY.size(); sp_ind++)
-      output_bins[bin_n] += refY[sp_ind];
+    for (double sp_ind : refY)
+      output_bins[bin_n] += sp_ind;
   }
 }
 
diff --git a/Framework/Algorithms/src/RunCombinationHelpers/RunCombinationHelper.cpp b/Framework/Algorithms/src/RunCombinationHelpers/RunCombinationHelper.cpp
index adde7248cd6b49cd7d33761001365862c8b6e500..4f8ae81b93dc3130e2744df0dec37505e93362a3 100644
--- a/Framework/Algorithms/src/RunCombinationHelpers/RunCombinationHelper.cpp
+++ b/Framework/Algorithms/src/RunCombinationHelpers/RunCombinationHelper.cpp
@@ -54,6 +54,11 @@ void RunCombinationHelper::setReferenceProperties(MatrixWorkspace_sptr ref) {
   m_isHistogramData = ref->isHistogramData();
   m_isScanning = ref->detectorInfo().isScanning();
   m_instrumentName = ref->getInstrument()->getName();
+  if (m_numberSpectra) {
+    m_hasDx.reserve(m_numberSpectra);
+    for (unsigned int i = 0; i < m_numberSpectra; ++i)
+      m_hasDx.push_back(ref->hasDx(i));
+  }
 }
 
 //----------------------------------------------------------------------------------------------
@@ -65,7 +70,7 @@ void RunCombinationHelper::setReferenceProperties(MatrixWorkspace_sptr ref) {
 std::string
 RunCombinationHelper::checkCompatibility(MatrixWorkspace_sptr ws,
                                          bool checkNumberHistograms) {
-  std::string errors = "";
+  std::string errors;
   if (ws->getNumberHistograms() != m_numberSpectra && checkNumberHistograms)
     errors += "different number of histograms; ";
   if (ws->getAxis(0)->unit()->unitID() != m_xUnit)
@@ -83,6 +88,16 @@ RunCombinationHelper::checkCompatibility(MatrixWorkspace_sptr ws,
               "detectors; ";
   if (ws->getInstrument()->getName() != m_instrumentName)
     errors += "different instrument names; ";
+  if (ws->getNumberHistograms() == m_numberSpectra) {
+    if (!m_hasDx.empty()) {
+      for (unsigned int i = 0; i < m_numberSpectra; ++i) {
+        if (m_hasDx[i] != ws->hasDx(i)) {
+          errors += "spectra must have either Dx values or not; ";
+          break;
+        }
+      }
+    }
+  }
   return errors;
 }
 
diff --git a/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp b/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp
index 281a0c31ce8dbfd8a1788ee7ffaa3c73af8215a9..6c2580cd1e834a5b88cc81a262223f2feda3796b 100644
--- a/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp
@@ -286,8 +286,8 @@ createSparseWS(const API::MatrixWorkspace &modelWS,
     }
     const auto e = modelWS.getEFixed(detIDs[0]);
     const auto &sparseDetIDs = ws->detectorInfo().detectorIDs();
-    for (size_t i = 0; i < sparseDetIDs.size(); ++i) {
-      ws->setEFixed(sparseDetIDs[i], e);
+    for (int sparseDetID : sparseDetIDs) {
+      ws->setEFixed(sparseDetID, e);
     }
   }
   return API::MatrixWorkspace_uptr(ws.release());
diff --git a/Framework/Algorithms/src/SmoothNeighbours.cpp b/Framework/Algorithms/src/SmoothNeighbours.cpp
index dbbae50f50d7ec87f949b14b63edb84d3bb28958..53f1f980a86ab6df0aa0f7ee6baca35ffda50488 100644
--- a/Framework/Algorithms/src/SmoothNeighbours.cpp
+++ b/Framework/Algorithms/src/SmoothNeighbours.cpp
@@ -24,8 +24,8 @@ using namespace Mantid::Geometry;
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
-typedef std::vector<Mantid::Kernel::Property *> VecProperties;
-typedef const VecProperties ConstVecProperties;
+using VecProperties = std::vector<Mantid::Kernel::Property *>;
+using ConstVecProperties = const VecProperties;
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/SofQCommon.cpp b/Framework/Algorithms/src/SofQCommon.cpp
index cf91dedcf8df673eba2951cdc0a801b6f87045cc..6c0836db7c39f645374b0e4b73c5c9f28876ff47 100644
--- a/Framework/Algorithms/src/SofQCommon.cpp
+++ b/Framework/Algorithms/src/SofQCommon.cpp
@@ -2,6 +2,11 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidKernel/PhysicalConstants.h"
+#include "MantidKernel/Unit.h"
+#include "MantidKernel/UnitConversion.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -71,7 +76,7 @@ double SofQCommon::getEFixed(const Geometry::IDetector &det) const {
     if (m_efixedGiven)
       efixed = m_efixed; // user provided a value
     else {
-      std::vector<double> param = det.getNumberParameter("EFixed");
+      const std::vector<double> param = det.getNumberParameter("EFixed");
       if (param.empty())
         throw std::runtime_error(
             "Cannot find EFixed parameter for component \"" + det.getName() +
@@ -82,5 +87,150 @@ double SofQCommon::getEFixed(const Geometry::IDetector &det) const {
   }
   return efixed;
 }
+
+/**
+ * Calculate the Q value
+ * @param deltaE The energy transfer in meV
+ * @param twoTheta The scattering angle in radians
+ * @param det A pointer to the corresponding detector, can be nullptr
+ *        for direct emode.
+ * @return The momentum transfer in A-1
+ */
+double SofQCommon::q(const double deltaE, const double twoTheta,
+                     const Geometry::IDetector *det) const {
+  if (m_emode == 1) {
+    return directQ(deltaE, twoTheta);
+  }
+  return indirectQ(deltaE, twoTheta, det);
+}
+
+/**
+ * Return a pair of (minimum Q, maximum Q) for given workspace.
+ * @param ws a workspace
+ * @param minE minimum energy transfer in ws
+ * @param maxE maximum energy transfer in ws
+ * @return a pair containing global minimun and maximum Q
+ */
+std::pair<double, double> SofQCommon::qBinHints(const API::MatrixWorkspace &ws,
+                                                const double minE,
+                                                const double maxE) const {
+  if (m_emode == 1) {
+    return qBinHintsDirect(ws, minE, maxE);
+  }
+  return qBinHintsIndirect(ws, minE, maxE);
+}
+
+/**
+ * Calculate the Q value for a direct instrument
+ * @param deltaE The energy change
+ * @param twoTheta The value of the scattering angle
+ * @return The value of Q
+ */
+double SofQCommon::directQ(const double deltaE, const double twoTheta) const {
+  using Mantid::PhysicalConstants::E_mev_toNeutronWavenumberSq;
+  const double ki = std::sqrt(m_efixed / E_mev_toNeutronWavenumberSq);
+  const double kf =
+      std::sqrt((m_efixed - deltaE) / E_mev_toNeutronWavenumberSq);
+  return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(twoTheta));
+}
+
+/**
+ * Calculate the Q value for an  indirect instrument
+ * @param deltaE The energy change
+ * @param twoTheta The value of the scattering angle
+ * @param det A pointer to the corresponding Detector
+ * @return The value of Q
+ */
+double SofQCommon::indirectQ(const double deltaE, const double twoTheta,
+                             const Geometry::IDetector *det) const {
+  using Mantid::PhysicalConstants::E_mev_toNeutronWavenumberSq;
+  if (!det) {
+    throw std::runtime_error("indirectQ: det is nullptr.");
+  }
+  const auto efixed = getEFixed(*det);
+  const double ki = std::sqrt((efixed + deltaE) / E_mev_toNeutronWavenumberSq);
+  const double kf = std::sqrt(efixed / E_mev_toNeutronWavenumberSq);
+  return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(twoTheta));
+}
+
+/**
+ * Return a pair of (minimum Q, maximum Q) for given
+ * direct geometry workspace.
+ * @param ws a workspace
+ * @param minE minimum energy transfer in ws
+ * @param maxE maximum energy transfer in ws
+ * @return a pair containing global minimun and maximum Q
+ */
+std::pair<double, double>
+SofQCommon::qBinHintsDirect(const API::MatrixWorkspace &ws, const double minE,
+                            const double maxE) const {
+  using namespace Mantid::PhysicalConstants;
+  auto minTwoTheta = std::numeric_limits<double>::max();
+  auto maxTwoTheta = std::numeric_limits<double>::lowest();
+  const auto &spectrumInfo = ws.spectrumInfo();
+  for (size_t i = 0; i < spectrumInfo.size(); ++i) {
+    if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
+      continue;
+    }
+    const auto twoTheta = spectrumInfo.twoTheta(i);
+    if (twoTheta < minTwoTheta) {
+      minTwoTheta = twoTheta;
+    }
+    if (twoTheta > maxTwoTheta) {
+      maxTwoTheta = twoTheta;
+    }
+  }
+  if (minTwoTheta == std::numeric_limits<double>::max()) {
+    throw std::runtime_error("Could not determine Q binning: workspace does "
+                             "not contain usable spectra.");
+  }
+  std::array<double, 4> q;
+  q[0] = directQ(minE, minTwoTheta);
+  q[1] = directQ(minE, maxTwoTheta);
+  q[2] = directQ(maxE, minTwoTheta);
+  q[3] = directQ(maxE, maxTwoTheta);
+  const auto minmaxQ = std::minmax_element(q.cbegin(), q.cend());
+  return std::make_pair(*minmaxQ.first, *minmaxQ.second);
+}
+
+/**
+ * Return a pair of (minimum Q, maximum Q) for given
+ * indirect geometry workspace. Estimates the Q range from all detectors.
+ * If workspace contains grouped detectors/not all detectors are linked
+ * to a spectrum, the returned interval may be larger than actually needed.
+ * @param ws a workspace
+ * @param minE minimum energy transfer in ws
+ * @param maxE maximum energy transfer in ws
+ * @return a pair containing global minimun and maximum Q
+ */
+std::pair<double, double>
+SofQCommon::qBinHintsIndirect(const API::MatrixWorkspace &ws, const double minE,
+                              const double maxE) const {
+  using namespace Mantid::PhysicalConstants;
+  auto minQ = std::numeric_limits<double>::max();
+  auto maxQ = std::numeric_limits<double>::lowest();
+  const auto &detectorInfo = ws.detectorInfo();
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    if (detectorInfo.isMasked(i) || detectorInfo.isMonitor(i)) {
+      continue;
+    }
+    const auto twoTheta = detectorInfo.twoTheta(i);
+    const auto &det = detectorInfo.detector(i);
+    const auto Q1 = indirectQ(minE, twoTheta, &det);
+    const auto Q2 = indirectQ(maxE, twoTheta, &det);
+    const auto minmaxQ = std::minmax(Q1, Q2);
+    if (minmaxQ.first < minQ) {
+      minQ = minmaxQ.first;
+    }
+    if (minmaxQ.second > maxQ) {
+      maxQ = minmaxQ.second;
+    }
+  }
+  if (minQ == std::numeric_limits<double>::max()) {
+    throw std::runtime_error("Could not determine Q binning: workspace does "
+                             "not contain usable spectra.");
+  }
+  return std::make_pair(minQ, maxQ);
+}
 }
 }
diff --git a/Framework/Algorithms/src/SofQW.cpp b/Framework/Algorithms/src/SofQW.cpp
index 87db034129f95de987b52007648f5e956dd2c8bb..1a28a172985d4b600499be0f506d314cf9582805 100644
--- a/Framework/Algorithms/src/SofQW.cpp
+++ b/Framework/Algorithms/src/SofQW.cpp
@@ -1,12 +1,10 @@
 #include <stdexcept>
 
-#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/SpectraAxisValidator.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
-#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidAlgorithms/SofQW.h"
 #include "MantidDataObjects/Histogram1D.h"
@@ -15,10 +13,7 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/ListValidator.h"
-#include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/RebinParamsValidator.h"
-#include "MantidKernel/UnitFactory.h"
-#include "MantidKernel/VectorHelper.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -26,15 +21,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(SofQW)
 
-/// Energy to K constant
-double SofQW::energyToK() {
-  static const double energyToK = 8.0 * M_PI * M_PI *
-                                  PhysicalConstants::NeutronMass *
-                                  PhysicalConstants::meV * 1e-20 /
-                                  (PhysicalConstants::h * PhysicalConstants::h);
-  return energyToK;
-}
-
 using namespace Kernel;
 using namespace API;
 
@@ -95,7 +81,7 @@ void SofQW::createCommonInputProperties(API::Algorithm &alg) {
       "The bin parameters to use for the q axis (in the format used by the "
       ":ref:`algm-Rebin` algorithm).");
 
-  std::vector<std::string> propOptions{"Direct", "Indirect"};
+  const std::vector<std::string> propOptions{"Direct", "Indirect"};
   alg.declareProperty("EMode", "",
                       boost::make_shared<StringListValidator>(propOptions),
                       "The energy transfer analysis mode (Direct/Indirect)");
@@ -140,57 +126,5 @@ void SofQW::exec() {
   m_progress->report("Creating output workspace");
 }
 
-/** Creates the output workspace, setting the axes according to the input
- * binning parameters
- *  @param[in]  inputWorkspace The input workspace
- *  @param[in]  qbinParams The q-bin parameters from the user
- *  @param[out] qAxis The 'vertical' (q) axis defined by the given parameters
- *  @param[out] ebinParams The 'horizontal' (energy) axis parameters (optional)
- *  @return A pointer to the newly-created workspace
- */
-API::MatrixWorkspace_sptr SofQW::setUpOutputWorkspace(
-    const API::MatrixWorkspace_const_sptr &inputWorkspace,
-    const std::vector<double> &qbinParams, std::vector<double> &qAxis,
-    const std::vector<double> &ebinParams) {
-  // Create vector to hold the new X axis values
-  HistogramData::BinEdges xAxis(0);
-  int xLength;
-  if (ebinParams.empty()) {
-    xAxis = inputWorkspace->refX(0);
-    xLength = static_cast<int>(xAxis.size());
-  } else {
-    xLength = static_cast<int>(VectorHelper::createAxisFromRebinParams(
-        ebinParams, xAxis.mutableRawData()));
-  }
-  // Create a vector to temporarily hold the vertical ('y') axis and populate
-  // that
-  const int yLength = static_cast<int>(
-      VectorHelper::createAxisFromRebinParams(qbinParams, qAxis));
-
-  // Create the output workspace
-  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
-      inputWorkspace, yLength - 1, xLength, xLength - 1);
-  // Create a numeric axis to replace the default vertical one
-  Axis *const verticalAxis = new BinEdgeAxis(qAxis);
-  outputWorkspace->replaceAxis(1, verticalAxis);
-
-  // Now set the axis values
-  for (int i = 0; i < yLength - 1; ++i) {
-    outputWorkspace->setBinEdges(i, xAxis);
-  }
-
-  // Set the axis units
-  verticalAxis->unit() = UnitFactory::Instance().create("MomentumTransfer");
-  verticalAxis->title() = "|Q|";
-
-  // Set the X axis title (for conversion to MD)
-  outputWorkspace->getAxis(0)->title() = "Energy transfer";
-
-  outputWorkspace->setYUnit("");
-  outputWorkspace->setYUnitLabel("Intensity");
-
-  return outputWorkspace;
-}
-
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/SofQWCentre.cpp b/Framework/Algorithms/src/SofQWCentre.cpp
index 089e8911eb2d0d1e6b1eb82ee671cc40ddf4b0a6..c5fbcd1f92603d46bbb3ed9ca2197aa1fdaac83e 100644
--- a/Framework/Algorithms/src/SofQWCentre.cpp
+++ b/Framework/Algorithms/src/SofQWCentre.cpp
@@ -1,29 +1,12 @@
 #include "MantidAlgorithms/SofQWCentre.h"
 #include "MantidAlgorithms/SofQW.h"
-#include "MantidDataObjects/Histogram1D.h"
-#include "MantidAPI/BinEdgeAxis.h"
-#include "MantidAPI/CommonBinsValidator.h"
-#include "MantidGeometry/Instrument/DetectorInfo.h"
-#include "MantidAPI/HistogramValidator.h"
-#include "MantidAPI/InstrumentValidator.h"
-#include "MantidAPI/SpectraAxisValidator.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/SpectrumInfo.h"
-#include "MantidAPI/WorkspaceFactory.h"
-#include "MantidAPI/WorkspaceUnitValidator.h"
+#include "MantidDataObjects/Histogram1D.h"
+#include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/DetectorGroup.h"
-#include "MantidKernel/ArrayProperty.h"
-#include "MantidKernel/BoundedValidator.h"
-#include "MantidKernel/CompositeValidator.h"
-#include "MantidKernel/ListValidator.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidKernel/PhysicalConstants.h"
-#include "MantidKernel/RebinParamsValidator.h"
-#include "MantidKernel/UnitFactory.h"
-#include "MantidKernel/VectorHelper.h"
-
-#include <numeric>
-#include <stdexcept>
 
 namespace Mantid {
 namespace Algorithms {
@@ -31,15 +14,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(SofQWCentre)
 
-/// Energy to K constant
-double SofQWCentre::energyToK() {
-  static const double energyToK = 8.0 * M_PI * M_PI *
-                                  PhysicalConstants::NeutronMass *
-                                  PhysicalConstants::meV * 1e-20 /
-                                  (PhysicalConstants::h * PhysicalConstants::h);
-  return energyToK;
-}
-
 using namespace Kernel;
 using namespace API;
 
@@ -50,6 +24,7 @@ void SofQWCentre::init() { SofQW::createCommonInputProperties(*this); }
 
 void SofQWCentre::exec() {
   using namespace Geometry;
+  using PhysicalConstants::E_mev_toNeutronWavenumberSq;
 
   MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
 
@@ -61,10 +36,14 @@ void SofQWCentre::exec() {
         "The input workspace must have common binning across all spectra");
   }
 
+  m_EmodeProperties.initCachedValues(*inputWorkspace, this);
+  const int emode = m_EmodeProperties.m_emode;
+
   std::vector<double> verticalAxis;
   MatrixWorkspace_sptr outputWorkspace =
-      SofQW::setUpOutputWorkspace(inputWorkspace, getProperty("QAxisBinning"),
-                                  verticalAxis, getProperty("EAxisBinning"));
+      SofQW::setUpOutputWorkspace<DataObjects::Workspace2D>(
+          *inputWorkspace, getProperty("QAxisBinning"), verticalAxis,
+          getProperty("EAxisBinning"), m_EmodeProperties);
   setProperty("OutputWorkspace", outputWorkspace);
   const auto &xAxis = outputWorkspace->binEdges(0).rawData();
 
@@ -72,9 +51,6 @@ void SofQWCentre::exec() {
   std::vector<specnum_t> specNumberMapping;
   std::vector<detid_t> detIDMapping;
 
-  m_EmodeProperties.initCachedValues(*inputWorkspace, this);
-  int emode = m_EmodeProperties.m_emode;
-
   const auto &detectorInfo = inputWorkspace->detectorInfo();
   const auto &spectrumInfo = inputWorkspace->spectrumInfo();
   V3D beamDir = detectorInfo.samplePosition() - detectorInfo.sourcePosition();
@@ -82,11 +58,6 @@ void SofQWCentre::exec() {
   double l1 = detectorInfo.l1();
   g_log.debug() << "Source-sample distance: " << l1 << '\n';
 
-  // Conversion constant for E->k. k(A^-1) = sqrt(energyToK*E(meV))
-  const double energyToK = 8.0 * M_PI * M_PI * PhysicalConstants::NeutronMass *
-                           PhysicalConstants::meV * 1e-20 /
-                           (PhysicalConstants::h * PhysicalConstants::h);
-
   // Loop over input workspace bins, reassigning data to correct bin in output
   // qw workspace
   const size_t numHists = inputWorkspace->getNumberHistograms();
@@ -158,8 +129,8 @@ void SofQWCentre::exec() {
             throw std::runtime_error(
                 "Negative incident energy. Check binning.");
 
-          const V3D ki = beamDir * sqrt(energyToK * ei);
-          const V3D kf = scatterDir * (sqrt(energyToK * (ef)));
+          const V3D ki = beamDir * sqrt(ei / E_mev_toNeutronWavenumberSq);
+          const V3D kf = scatterDir * sqrt(ef / E_mev_toNeutronWavenumberSq);
           const double q = (ki - kf).norm();
 
           // Test whether it's in range of the Q axis
@@ -198,7 +169,7 @@ void SofQWCentre::exec() {
 
   // If the input workspace was a distribution, need to divide by q bin width
   if (inputWorkspace->isDistribution())
-    this->makeDistribution(outputWorkspace, verticalAxis);
+    this->makeDistribution(*outputWorkspace, verticalAxis);
 
   // Set the output spectrum-detector mapping
   SpectrumDetectorMapping outputDetectorMap(specNumberMapping, detIDMapping);
@@ -222,15 +193,15 @@ void SofQWCentre::exec() {
  *  @param outputWS :: The output workspace
  *  @param qAxis ::    A vector of the q bin boundaries
  */
-void SofQWCentre::makeDistribution(API::MatrixWorkspace_sptr outputWS,
-                                   const std::vector<double> qAxis) {
+void SofQWCentre::makeDistribution(API::MatrixWorkspace &outputWS,
+                                   const std::vector<double> &qAxis) {
   std::vector<double> widths(qAxis.size());
   std::adjacent_difference(qAxis.begin(), qAxis.end(), widths.begin());
 
-  const size_t numQBins = outputWS->getNumberHistograms();
+  const size_t numQBins = outputWS.getNumberHistograms();
   for (size_t i = 0; i < numQBins; ++i) {
-    auto &Y = outputWS->mutableY(i);
-    auto &E = outputWS->mutableE(i);
+    auto &Y = outputWS.mutableY(i);
+    auto &E = outputWS.mutableE(i);
     std::transform(Y.begin(), Y.end(), Y.begin(),
                    std::bind2nd(std::divides<double>(), widths[i + 1]));
     std::transform(E.begin(), E.end(), E.begin(),
diff --git a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
index e5833ee1064a41ecf52d2a2c339723849501f863..4352476b1d7ed7b4f02975f16cf8a34ee3359428 100644
--- a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
+++ b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
@@ -1,27 +1,23 @@
 #include "MantidAlgorithms/SofQWNormalisedPolygon.h"
 #include "MantidAlgorithms/SofQW.h"
-#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/WorkspaceNearestNeighbourInfo.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/SpectrumInfo.h"
-#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/FractionalRebinning.h"
-#include "MantidDataObjects/WorkspaceCreation.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Objects/IObject.h"
 #include "MantidIndexing/IndexInfo.h"
-#include "MantidKernel/UnitFactory.h"
-#include "MantidKernel/VectorHelper.h"
+#include "MantidKernel/PhysicalConstants.h"
 #include "MantidTypes/SpectrumDefinition.h"
 
 namespace Mantid {
 namespace Algorithms {
 // Setup typedef for later use
-typedef std::map<specnum_t, Mantid::Kernel::V3D> SpectraDistanceMap;
-typedef Geometry::IDetector_const_sptr DetConstPtr;
+using SpectraDistanceMap = std::map<specnum_t, Mantid::Kernel::V3D>;
+using DetConstPtr = Geometry::IDetector_const_sptr;
 
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(SofQWNormalisedPolygon)
@@ -31,10 +27,6 @@ using namespace Mantid::Geometry;
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
-/// Default constructor
-SofQWNormalisedPolygon::SofQWNormalisedPolygon()
-    : Rebin2D(), m_Qout(), m_thetaWidth(0.0), m_detNeighbourOffset(-1) {}
-
 /**
  * @return the name of the Algorithm
  */
@@ -72,9 +64,12 @@ void SofQWNormalisedPolygon::exec() {
         "The input workspace must have common binning across all spectra");
   }
 
-  RebinnedOutput_sptr outputWS =
-      this->setUpOutputWorkspace(*inputWS, getProperty("QAxisBinning"), m_Qout,
-                                 getProperty("EAxisBinning"));
+  // Compute input caches
+  m_EmodeProperties.initCachedValues(*inputWS, this);
+
+  RebinnedOutput_sptr outputWS = SofQW::setUpOutputWorkspace<RebinnedOutput>(
+      *inputWS, getProperty("QAxisBinning"), m_Qout,
+      getProperty("EAxisBinning"), m_EmodeProperties);
   g_log.debug() << "Workspace type: " << outputWS->id() << '\n';
   setProperty("OutputWorkspace", outputWS);
   const size_t nEnergyBins = inputWS->blocksize();
@@ -88,9 +83,6 @@ void SofQWNormalisedPolygon::exec() {
   m_progress = boost::shared_ptr<API::Progress>(
       new API::Progress(this, 0.0, 1.0, nreports));
 
-  // Compute input caches
-  m_EmodeProperties.initCachedValues(*inputWS, this);
-
   std::vector<double> par =
       inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset");
   if (par.empty()) {
@@ -103,7 +95,6 @@ void SofQWNormalisedPolygon::exec() {
   }
 
   const auto &X = inputWS->x(0);
-  int emode = m_EmodeProperties.m_emode;
 
   const auto &inputIndices = inputWS->indexInfo();
   const auto &spectrumInfo = inputWS->spectrumInfo();
@@ -117,23 +108,20 @@ void SofQWNormalisedPolygon::exec() {
     if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
       continue;
     }
+    const auto *det =
+        m_EmodeProperties.m_emode == 1 ? nullptr : &spectrumInfo.detector(i);
 
-    double theta = this->m_theta[i];
-    double phi = this->m_phi[i];
-    double thetaWidth = this->m_thetaWidths[i];
-    double phiWidth = this->m_phiWidths[i];
+    const double theta = this->m_theta[i];
+    const double phi = this->m_phi[i];
+    const double thetaWidth = this->m_thetaWidths[i];
+    const double phiWidth = this->m_phiWidths[i];
 
     // Compute polygon points
-    double thetaHalfWidth = 0.5 * thetaWidth;
-    double phiHalfWidth = 0.5 * phiWidth;
+    const double thetaHalfWidth = 0.5 * thetaWidth;
 
     const double thetaLower = theta - thetaHalfWidth;
     const double thetaUpper = theta + thetaHalfWidth;
 
-    const double phiLower = phi - phiHalfWidth;
-    const double phiUpper = phi + phiHalfWidth;
-
-    const double efixed = m_EmodeProperties.getEFixed(spectrumInfo.detector(i));
     const auto specNo = static_cast<specnum_t>(inputIndices.spectrumNumber(i));
     std::stringstream logStream;
     for (size_t j = 0; j < nEnergyBins; ++j) {
@@ -143,16 +131,12 @@ void SofQWNormalisedPolygon::exec() {
       const double dE_j = X[j];
       const double dE_jp1 = X[j + 1];
 
-      const double lrQ =
-          this->calculateQ(efixed, emode, dE_jp1, thetaLower, phiLower);
+      const double lrQ = m_EmodeProperties.q(dE_jp1, thetaLower, det);
 
-      const V2D ll(dE_j,
-                   this->calculateQ(efixed, emode, dE_j, thetaLower, phiLower));
+      const V2D ll(dE_j, m_EmodeProperties.q(dE_j, thetaLower, det));
       const V2D lr(dE_jp1, lrQ);
-      const V2D ur(dE_jp1, this->calculateQ(efixed, emode, dE_jp1, thetaUpper,
-                                            phiUpper));
-      const V2D ul(dE_j,
-                   this->calculateQ(efixed, emode, dE_j, thetaUpper, phiUpper));
+      const V2D ur(dE_jp1, m_EmodeProperties.q(dE_jp1, thetaUpper, det));
+      const V2D ul(dE_j, m_EmodeProperties.q(dE_j, thetaUpper, det));
       if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
         logStream << "Spectrum=" << specNo << ", theta=" << theta
                   << ",thetaWidth=" << thetaWidth << ", phi=" << phi
@@ -209,34 +193,6 @@ void SofQWNormalisedPolygon::exec() {
   }
 }
 
-/**
- * Calculate the Q value for a given set of energy transfer, scattering
- * and azimuthal angle.
- * @param efixed :: An fixed energy value
- * @param emode  :: the energy evaluation mode
- * @param deltaE :: The energy change
- * @param twoTheta :: The value of the scattering angle
- * @param azimuthal :: The value of the azimuthual angle
- * @return The value of Q
- */
-double SofQWNormalisedPolygon::calculateQ(const double efixed, int emode,
-                                          const double deltaE,
-                                          const double twoTheta,
-                                          const double azimuthal) const {
-  double ki = 0.0;
-  double kf = 0.0;
-  if (emode == 1) {
-    ki = std::sqrt(efixed * SofQW::energyToK());
-    kf = std::sqrt((efixed - deltaE) * SofQW::energyToK());
-  } else if (emode == 2) {
-    ki = std::sqrt((deltaE + efixed) * SofQW::energyToK());
-    kf = std::sqrt(efixed * SofQW::energyToK());
-  }
-  const double Qx = ki - kf * std::cos(twoTheta);
-  const double Qy = -kf * std::sin(twoTheta) * std::cos(azimuthal);
-  const double Qz = -kf * std::sin(twoTheta) * std::sin(azimuthal);
-  return std::sqrt(Qx * Qx + Qy * Qy + Qz * Qz);
-}
 /**
  * A map detector ID and Q ranges
  * This method looks unnecessary as it could be calculated on the fly but
@@ -396,54 +352,5 @@ void SofQWNormalisedPolygon::initAngularCachesPSD(
   }
 }
 
-/** Creates the output workspace, setting the axes according to the input
- * binning parameters
- *  @param[in]  inputWorkspace The input workspace
- *  @param[in]  qbinParams The q-bin parameters from the user
- *  @param[out] qAxis The 'vertical' (q) axis defined by the given parameters
- *  @param[out] ebinParams The 'horizontal' (energy) axis parameters (optional)
- *  @return A pointer to the newly-created workspace
- */
-RebinnedOutput_sptr SofQWNormalisedPolygon::setUpOutputWorkspace(
-    const API::MatrixWorkspace &inputWorkspace,
-    const std::vector<double> &qbinParams, std::vector<double> &qAxis,
-    const std::vector<double> &ebinParams) {
-  using Kernel::VectorHelper::createAxisFromRebinParams;
-
-  HistogramData::BinEdges xAxis(0);
-  // Create vector to hold the new X axis values
-  if (ebinParams.empty()) {
-    xAxis = inputWorkspace.binEdges(0);
-  } else {
-    static_cast<void>(
-        createAxisFromRebinParams(ebinParams, xAxis.mutableRawData()));
-  }
-
-  // Create a vector to temporarily hold the vertical ('y') axis and populate
-  // that
-  const int yLength = static_cast<int>(
-      VectorHelper::createAxisFromRebinParams(qbinParams, qAxis));
-
-  // Create output workspace, bin edges are same as in inputWorkspace index 0
-  auto outputWorkspace =
-      create<RebinnedOutput>(inputWorkspace, yLength - 1, xAxis);
-
-  // Create a binned numeric axis to replace the default vertical one
-  Axis *const verticalAxis = new BinEdgeAxis(qAxis);
-  outputWorkspace->replaceAxis(1, verticalAxis);
-
-  // Set the axis units
-  verticalAxis->unit() = UnitFactory::Instance().create("MomentumTransfer");
-  verticalAxis->title() = "|Q|";
-
-  // Set the X axis title (for conversion to MD)
-  outputWorkspace->getAxis(0)->title() = "Energy transfer";
-
-  outputWorkspace->setYUnit("");
-  outputWorkspace->setYUnitLabel("Intensity");
-
-  return std::move(outputWorkspace);
-}
-
 } // namespace Mantid
 } // namespace Algorithms
diff --git a/Framework/Algorithms/src/SofQWPolygon.cpp b/Framework/Algorithms/src/SofQWPolygon.cpp
index 8fe9b4c015a2c7f98485cd0adb88583ae22dbc39..3ed19abc4295e75e9818447d7b99b2329f523714 100644
--- a/Framework/Algorithms/src/SofQWPolygon.cpp
+++ b/Framework/Algorithms/src/SofQWPolygon.cpp
@@ -4,10 +4,13 @@
 #include "MantidAPI/SpectraAxis.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/SpectrumInfo.h"
+#include "MantidDataObjects/FractionalRebinning.h"
 #include "MantidGeometry/Math/PolygonIntersection.h"
 #include "MantidGeometry/Math/Quadrilateral.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
-#include "MantidDataObjects/FractionalRebinning.h"
+#include "MantidIndexing/IndexInfo.h"
+#include "MantidKernel/PhysicalConstants.h"
+#include "MantidTypes/SpectrumDefinition.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -39,38 +42,26 @@ void SofQWPolygon::exec() {
         "The input workspace must have common binning across all spectra");
   }
 
-  MatrixWorkspace_sptr outputWS =
-      SofQW::setUpOutputWorkspace(inputWS, getProperty("QAxisBinning"), m_Qout,
-                                  getProperty("EAxisBinning"));
-  setProperty("OutputWorkspace", outputWS);
-  const size_t nenergyBins = inputWS->blocksize();
-
   // Progress reports & cancellation
   const size_t nreports(static_cast<size_t>(inputWS->getNumberHistograms() *
                                             inputWS->blocksize()));
   m_progress = boost::shared_ptr<API::Progress>(
       new API::Progress(this, 0.0, 1.0, nreports));
-
   // Compute input caches
   this->initCachedValues(inputWS);
 
+  MatrixWorkspace_sptr outputWS =
+      SofQW::setUpOutputWorkspace<DataObjects::Workspace2D>(
+          *inputWS, getProperty("QAxisBinning"), m_Qout,
+          getProperty("EAxisBinning"), m_EmodeProperties);
+  setProperty("OutputWorkspace", outputWS);
+  const size_t nenergyBins = inputWS->blocksize();
+
   const size_t nTheta = m_thetaPts.size();
   const auto &X = inputWS->x(0);
 
   // Holds the spectrum-detector mapping
-  std::vector<specnum_t> specNumberMapping;
-  std::vector<detid_t> detIDMapping;
-
-  // Select the calculate Q method based on the mode
-  // rather than doing this repeatedly in the loop
-  typedef double (SofQWPolygon::*QCalculation)(double, double, double, double)
-      const;
-  QCalculation qCalculator;
-  if (m_EmodeProperties.m_emode == 1) {
-    qCalculator = &SofQWPolygon::calculateDirectQ;
-  } else {
-    qCalculator = &SofQWPolygon::calculateIndirectQ;
-  }
+  std::vector<SpectrumDefinition> detIDMapping(outputWS->getNumberHistograms());
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
   for (int64_t i = 0; i < static_cast<int64_t>(nTheta);
@@ -85,11 +76,11 @@ void SofQWPolygon::exec() {
     }
 
     const auto &spectrumInfo = inputWS->spectrumInfo();
-    const auto &det = spectrumInfo.detector(i);
-    double halfWidth(0.5 * m_thetaWidth);
+    const auto *det =
+        m_EmodeProperties.m_emode == 1 ? nullptr : &spectrumInfo.detector(i);
+    const double halfWidth(0.5 * m_thetaWidth);
     const double thetaLower = theta - halfWidth;
     const double thetaUpper = theta + halfWidth;
-    const double efixed = m_EmodeProperties.getEFixed(det);
 
     for (size_t j = 0; j < nenergyBins; ++j) {
       m_progress->report("Computing polygon intersections");
@@ -98,13 +89,12 @@ void SofQWPolygon::exec() {
       const double dE_j = X[j];
       const double dE_jp1 = X[j + 1];
 
-      const double lrQ = (this->*qCalculator)(efixed, dE_jp1, thetaLower, 0.0);
+      const double lrQ = m_EmodeProperties.q(dE_jp1, thetaLower, det);
 
-      const V2D ll(dE_j, (this->*qCalculator)(efixed, dE_j, thetaLower, 0.0));
+      const V2D ll(dE_j, m_EmodeProperties.q(dE_j, thetaLower, det));
       const V2D lr(dE_jp1, lrQ);
-      const V2D ur(dE_jp1,
-                   (this->*qCalculator)(efixed, dE_jp1, thetaUpper, 0.0));
-      const V2D ul(dE_j, (this->*qCalculator)(efixed, dE_j, thetaUpper, 0.0));
+      const V2D ur(dE_jp1, m_EmodeProperties.q(dE_jp1, thetaUpper, det));
+      const V2D ul(dE_j, m_EmodeProperties.q(dE_j, thetaUpper, det));
       Quadrilateral inputQ = Quadrilateral(ll, lr, ur, ul);
 
       DataObjects::FractionalRebinning::rebinToOutput(inputQ, inputWS, i, j,
@@ -116,9 +106,11 @@ void SofQWPolygon::exec() {
       if (qIndex != 0 && qIndex < static_cast<int>(m_Qout.size())) {
         // Add this spectra-detector pair to the mapping
         PARALLEL_CRITICAL(SofQWPolygon_spectramap) {
-          specNumberMapping.push_back(
-              outputWS->getSpectrum(qIndex - 1).getSpectrumNo());
-          detIDMapping.push_back(det.getID());
+          // Could do a more complete merge of spectrum definitions here, but
+          // historically only the ID of the first detector in the spectrum is
+          // used, so I am keeping that for now.
+          detIDMapping[qIndex - 1].add(
+              spectrumInfo.spectrumDefinition(i)[0].first);
         }
       }
     }
@@ -131,8 +123,9 @@ void SofQWPolygon::exec() {
                                                     m_progress);
 
   // Set the output spectrum-detector mapping
-  SpectrumDetectorMapping outputDetectorMap(specNumberMapping, detIDMapping);
-  outputWS->updateSpectraUsing(outputDetectorMap);
+  auto outputIndices = outputWS->indexInfo();
+  outputIndices.setSpectrumDefinitions(std::move(detIDMapping));
+  outputWS->setIndexInfo(outputIndices);
 
   // Replace any NaNs in outputWorkspace with zeroes
   if (this->getProperty("ReplaceNaNs")) {
@@ -148,45 +141,6 @@ void SofQWPolygon::exec() {
   }
 }
 
-/**
- * Calculate the Q value for a direct instrument
- * @param efixed An efixed value
- * @param deltaE The energy change
- * @param twoTheta The value of the scattering angle
- * @param psi The value of the azimuth
- * @return The value of Q
- */
-double SofQWPolygon::calculateDirectQ(const double efixed, const double deltaE,
-                                      const double twoTheta,
-                                      const double psi) const {
-  const double ki = std::sqrt(efixed * SofQW::energyToK());
-  const double kf = std::sqrt((efixed - deltaE) * SofQW::energyToK());
-  const double Qx = ki - kf * std::cos(twoTheta);
-  const double Qy = -kf * std::sin(twoTheta) * std::cos(psi);
-  const double Qz = -kf * std::sin(twoTheta) * std::sin(psi);
-  return std::sqrt(Qx * Qx + Qy * Qy + Qz * Qz);
-}
-
-/**
- * Calculate the Q value for a direct instrument
- * @param efixed An efixed value
- * @param deltaE The energy change
- * @param twoTheta The value of the scattering angle
- * @param psi The value of the azimuth
- * @return The value of Q
- */
-double SofQWPolygon::calculateIndirectQ(const double efixed,
-                                        const double deltaE,
-                                        const double twoTheta,
-                                        const double psi) const {
-  UNUSED_ARG(psi);
-  const double ki = std::sqrt((efixed + deltaE) * SofQW::energyToK());
-  const double kf = std::sqrt(efixed * SofQW::energyToK());
-  const double Qx = ki - kf * std::cos(twoTheta);
-  const double Qy = -kf * std::sin(twoTheta);
-  return std::sqrt(Qx * Qx + Qy * Qy);
-}
-
 /**
  * Init variables caches
  * @param workspace :: Workspace pointer
diff --git a/Framework/Algorithms/src/SpecularReflectionPositionCorrect2.cpp b/Framework/Algorithms/src/SpecularReflectionPositionCorrect2.cpp
index 8a6d09083e3b2d7696b11e40e6d4a18b75fb3355..c2303b52fc180b1b6e9163561d7972da44729226 100644
--- a/Framework/Algorithms/src/SpecularReflectionPositionCorrect2.cpp
+++ b/Framework/Algorithms/src/SpecularReflectionPositionCorrect2.cpp
@@ -71,11 +71,14 @@ void SpecularReflectionPositionCorrect2::init() {
 
   declareProperty(
       Mantid::Kernel::make_unique<PropertyWithValue<std::string>>(
-          "DetectorComponentName", "",
-          boost::make_shared<MandatoryValidator<std::string>>(),
-          Direction::Input),
+          "DetectorComponentName", "", Direction::Input),
       "Name of the detector component to correct, i.e. point-detector");
 
+  declareProperty("DetectorID", -1,
+                  "The ID of the detector to correct. If both "
+                  "the component name and the detector ID "
+                  "are set the latter will be used.");
+
   declareProperty(
       Mantid::Kernel::make_unique<PropertyWithValue<std::string>>(
           "SampleComponentName", "some-surface-holder", Direction::Input),
@@ -108,10 +111,17 @@ void SpecularReflectionPositionCorrect2::exec() {
   auto inst = outWS->getInstrument();
 
   // Detector
+  const int detectorID = getProperty("DetectorID");
   const std::string detectorName = getProperty("DetectorComponentName");
-  if (!inst->getComponentByName(detectorName))
-    throw std::runtime_error("Detector component not found.");
-  IComponent_const_sptr detector = inst->getComponentByName(detectorName);
+
+  IComponent_const_sptr detector;
+  if (detectorID > 0) {
+    detector = inst->getDetector(detectorID);
+  } else {
+    if (!inst->getComponentByName(detectorName))
+      throw std::runtime_error("Detector component not found.");
+    detector = inst->getComponentByName(detectorName);
+  }
   const V3D detectorPosition = detector->getPos();
 
   // Sample
@@ -165,7 +175,11 @@ void SpecularReflectionPositionCorrect2::exec() {
   auto moveAlg = createChildAlgorithm("MoveInstrumentComponent");
   moveAlg->initialize();
   moveAlg->setProperty("Workspace", outWS);
-  moveAlg->setProperty("ComponentName", detectorName);
+  if (!detectorName.empty()) {
+    moveAlg->setProperty("ComponentName", detectorName);
+  } else {
+    moveAlg->setProperty("DetectorID", detectorID);
+  }
   moveAlg->setProperty("RelativePosition", false);
   moveAlg->setProperty(beamAxis, beamOffsetFromOrigin);
   moveAlg->setProperty(horizontalAxis, 0.0);
diff --git a/Framework/Algorithms/src/Stitch1D.cpp b/Framework/Algorithms/src/Stitch1D.cpp
index e334f7b4cae7d21cd6b268d602f3c81367b3651b..553365f31092bdb21f3a0e007e6e253fdfad9f8b 100644
--- a/Framework/Algorithms/src/Stitch1D.cpp
+++ b/Framework/Algorithms/src/Stitch1D.cpp
@@ -25,7 +25,7 @@ using Mantid::HistogramData::HistogramE;
 
 namespace {
 
-typedef boost::tuple<double, double> MinMaxTuple;
+using MinMaxTuple = boost::tuple<double, double>;
 MinMaxTuple calculateXIntersection(MatrixWorkspace_sptr lhsWS,
                                    MatrixWorkspace_sptr rhsWS) {
   return MinMaxTuple(rhsWS->x(0).front(), lhsWS->x(0).back());
diff --git a/Framework/Algorithms/src/SumOverlappingTubes.cpp b/Framework/Algorithms/src/SumOverlappingTubes.cpp
index 9f6da909ce7eb7d31a40b20ff3e4affb90eb2b61..fac9121644d4c47cbccd746003c11caaf722fd88 100644
--- a/Framework/Algorithms/src/SumOverlappingTubes.cpp
+++ b/Framework/Algorithms/src/SumOverlappingTubes.cpp
@@ -2,6 +2,7 @@
 
 #include "MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h"
 #include "MantidAPI/ADSValidator.h"
+#include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
@@ -21,6 +22,8 @@
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
+#include <boost/math/special_functions/round.hpp>
+
 namespace Mantid {
 namespace Algorithms {
 
@@ -70,20 +73,23 @@ void SumOverlappingTubes::init() {
   declareProperty(
       make_unique<PropertyWithValue<bool>>("Normalise", true, Direction::Input),
       "If true normalise to the number of entries added for a particular "
-      "scattering angle. If the maximum entries accross all the scattering "
-      "angles is N_MAX, and the number of entries for a scattering angle is N, "
-      "the normalisation is performed as N_MAX / N.");
+      "scattering angle. ");
   auto toleranceValidator =
       boost::make_shared<BoundedValidator<double>>(0.0, 0.0);
   toleranceValidator->clearUpper();
   declareProperty("ScatteringAngleTolerance", 0.0, toleranceValidator,
                   "The relative tolerance for the scattering angles before the "
                   "counts are split.");
+  declareProperty(make_unique<PropertyWithValue<bool>>("MirrorScatteringAngles",
+                                                       false, Direction::Input),
+                  "A flag to mirror the signed 2thetas. ");
 }
 
 void SumOverlappingTubes::exec() {
   getInputParameters();
 
+  m_progress = make_unique<Progress>(this, 0.0, 1.0, m_workspaceList.size());
+
   HistogramData::Points x(m_numPoints, LinearGenerator(m_startScatteringAngle,
                                                        m_stepScatteringAngle));
 
@@ -102,52 +108,40 @@ void SumOverlappingTubes::exec() {
   Unit_sptr xUnit = outputWS->getAxis(0)->unit();
   boost::shared_ptr<Units::Label> xLabel =
       boost::dynamic_pointer_cast<Units::Label>(xUnit);
-  xLabel->setLabel("Tube Angle", "degrees");
+  xLabel->setLabel("Scattering Angle", "degrees");
 
   const auto normalisation = performBinning(outputWS);
 
-  auto maxEntry = 0.0;
-  for (const auto &vector : normalisation)
-    maxEntry =
-        std::max(*std::max_element(vector.begin(), vector.end()), maxEntry);
   if (getProperty("Normalise"))
     for (size_t i = 0; i < m_numPoints; ++i)
       for (size_t j = 0; j < m_numHistograms; ++j) {
         // Avoid spurious normalisation for low counting cells
         if (normalisation[j][i] < 1e-15)
           continue;
-        outputWS->mutableY(j)[i] *= maxEntry / normalisation[j][i];
-        outputWS->mutableE(j)[i] *= maxEntry / normalisation[j][i];
+        outputWS->mutableY(j)[i] /= normalisation[j][i];
+        outputWS->mutableE(j)[i] /= normalisation[j][i];
       }
 
   setProperty("OutputWorkspace", outputWS);
 }
 
 void SumOverlappingTubes::getInputParameters() {
+
+  // This is flag for flipping the sign of 2theta
+  m_mirrorDetectors = getProperty("MirrorScatteringAngles") ? -1 : 1;
+
   const std::vector<std::string> inputWorkspaces =
       getProperty("InputWorkspaces");
   auto workspaces = RunCombinationHelper::unWrapGroups(inputWorkspaces);
   RunCombinationHelper combHelper;
   m_workspaceList = combHelper.validateInputWorkspaces(workspaces, g_log);
-
   m_outputType = getPropertyValue("OutputType");
   const auto &instrument = m_workspaceList.front()->getInstrument();
-
-  // For D2B at the ILL the detectors are flipped when comparing with other
-  // powder diffraction instruments such as D20. It is still desired to show
-  // angles as positive however, so here we check if we need to multiple angle
-  // calculations by -1.
-  m_mirrorDetectors = 1;
-  auto mirrorDetectors = instrument->getBoolParameter("mirror_detector_angles");
-  if (!mirrorDetectors.empty() && mirrorDetectors[0])
-    m_mirrorDetectors = -1;
-
   std::string componentName = "";
   auto componentNameParam =
       instrument->getStringParameter("detector_for_height_axis");
   if (!componentNameParam.empty())
     componentName = componentNameParam[0];
-
   getScatteringAngleBinning();
   getHeightAxis(componentName);
 }
@@ -205,6 +199,7 @@ void SumOverlappingTubes::getScatteringAngleBinning() {
 
 void SumOverlappingTubes::getHeightAxis(const std::string &componentName) {
   std::vector<double> heightBinning = getProperty("HeightAxis");
+  m_heightAxis.clear();
   if (componentName.length() == 0 && heightBinning.empty())
     throw std::runtime_error("No detector_for_height_axis parameter for this "
                              "instrument. Please enter a value for the "
@@ -269,6 +264,7 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) {
 
   // loop over all workspaces
   for (auto &ws : m_workspaceList) {
+    m_progress->report("Processing workspace " + std::string(ws->getName()));
     // loop over spectra
     const auto &specInfo = ws->spectrumInfo();
     for (size_t i = 0; i < specInfo.size(); ++i) {
@@ -298,8 +294,8 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) {
         angle = specInfo.signedTwoTheta(i);
       angle *= m_mirrorDetectors * 180.0 / M_PI;
 
-      int angleIndex =
-          int((angle - m_startScatteringAngle) / m_stepScatteringAngle + 0.5);
+      int angleIndex = boost::math::iround((angle - m_startScatteringAngle) /
+                                           m_stepScatteringAngle);
 
       // point is out of range, a warning should have been generated already for
       // the theta index
@@ -347,7 +343,9 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) {
         yData[angleIndex] += counts;
         eData[angleIndex] =
             sqrt(eData[angleIndex] * eData[angleIndex] + error * error);
-        normalisation[heightIndex][angleIndex]++;
+        if (counts != 0.) {
+          normalisation[heightIndex][angleIndex]++;
+        }
       }
     }
   }
diff --git a/Framework/Algorithms/src/SumSpectra.cpp b/Framework/Algorithms/src/SumSpectra.cpp
index d1f363ed62966c022583a0524735dbb6825c41ec..9decd3375fe68b775228607fce6ece91ef88ed45 100644
--- a/Framework/Algorithms/src/SumSpectra.cpp
+++ b/Framework/Algorithms/src/SumSpectra.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/RebinnedOutput.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
@@ -20,6 +21,85 @@ using namespace Kernel;
 using namespace API;
 using namespace DataObjects;
 
+namespace {
+/**
+ * @param validationOutput Output map to be populated with any errors
+ * @param ws An input workspace to verify
+ * @param minIndex Minimum index of range to sum
+ * @param maxIndex Mmaximum index of range to sum
+ * @param indices A list of indices to sum
+ */
+bool validateSingleMatrixWorkspace(
+    std::map<std::string, std::string> &validationOutput,
+    const MatrixWorkspace &ws, const int minIndex, const int maxIndex,
+    const std::vector<int> &indices) {
+  bool success(true);
+  const int numSpectra = static_cast<int>(ws.getNumberHistograms());
+  // check StartWorkSpaceIndex,  >=0 done by validator
+  if (minIndex >= numSpectra) {
+    validationOutput["StartWorkspaceIndex"] =
+        "Selected minimum workspace index is greater than available "
+        "spectra.";
+    success = false;
+  }
+  // check EndWorkspaceIndex in range
+  if (maxIndex != EMPTY_INT()) {
+    // check EndWorkspaceIndex in range
+    if (maxIndex >= numSpectra) {
+      validationOutput["EndWorkspaceIndex"] =
+          "Selected maximum workspace index is greater than available "
+          "spectra.";
+      success = false;
+      // check StartWorkspaceIndex < EndWorkspaceIndex
+    }
+  }
+  // check ListOfWorkspaceIndices in range
+  for (const auto index : indices) {
+    if ((index >= numSpectra) || (index < 0)) {
+      validationOutput["ListOfWorkspaceIndices"] =
+          "One or more indices out of range of available spectra.";
+      success = false;
+      break;
+    }
+  }
+  return success;
+}
+
+/**
+* @param validationOutput Output map to be populated with any errors
+* @param name A string identifier for an input workspace to verify
+* @param minIndex Minimum index of range to sum
+* @param maxIndex Mmaximum index of range to sum
+* @param indices A list of indices to sum
+*/
+void validateWorkspaceName(std::map<std::string, std::string> &validationOutput,
+                           const std::string &name, const int minIndex,
+                           const int maxIndex,
+                           const std::vector<int> &indices) {
+  const auto &ads = AnalysisDataService::Instance();
+  if (!ads.doesExist(name))
+    return;
+  auto wsGroup = ads.retrieveWS<WorkspaceGroup>(name);
+  if (!wsGroup)
+    return;
+  size_t index = 0;
+  for (const auto &item : *wsGroup) {
+    auto matrixWs = boost::dynamic_pointer_cast<MatrixWorkspace>(item);
+    if (!matrixWs) {
+      validationOutput["InputWorkspace"] =
+          "Input group contains an invalid workspace type at item " +
+          std::to_string(index) + ". All members must be a  MatrixWorkspace";
+      break;
+    }
+    if (!validateSingleMatrixWorkspace(validationOutput, *matrixWs, minIndex,
+                                       maxIndex, indices)) {
+      break;
+    }
+    ++index;
+  }
+}
+}
+
 /** Initialisation method.
  *
  */
@@ -80,50 +160,27 @@ std::map<std::string, std::string> SumSpectra::validateInputs() {
   // create the map
   std::map<std::string, std::string> validationOutput;
 
-  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");
-  const int numSpectra =
-      static_cast<int>(localworkspace->getNumberHistograms());
+  // Non-workspace checks
   const int minIndex = getProperty("StartWorkspaceIndex");
   const int maxIndex = getProperty("EndWorkspaceIndex");
-
-  // check StartWorkSpaceIndex,  >=0 done by validator
-  if (minIndex >= numSpectra) {
-    validationOutput["StartWorkspaceIndex"] =
-        "Selected minimum workspace index is greater than available spectra.";
-  }
-
-  // check EndWorkspaceIndex in range
-  if (maxIndex != EMPTY_INT()) {
-    // check EndWorkspaceIndex in range
-    if (maxIndex >= numSpectra) {
-      validationOutput["EndWorkspaceIndex"] =
-          "Selected maximum workspace index is greater than available spectra.";
-      // check StartWorkspaceIndex < EndWorkspaceIndex
-    } else if (minIndex > maxIndex) {
-      validationOutput["StartWorkspaceIndex"] =
-          "Selected minimum workspace "
-          "index is greater than selected "
-          "maximum workspace index.";
-      validationOutput["EndWorkspaceIndex"] =
-          "Selected maximum workspace index "
-          "is lower than selected minimum "
-          "workspace index.";
-    }
-  }
-
-  // check ListOfWorkspaceIndices in range
-  const std::vector<int> indices_list = getProperty("ListOfWorkspaceIndices");
-  if (!indices_list.empty()) { // only if specified
-    // indices are assumed to be sorted
-    for (const auto index : indices_list) {
-      if ((index >= numSpectra) || (index < 0)) {
-        validationOutput["ListOfWorkspaceIndices"] =
-            "One or more indices out of range of available spectra.";
-        break;
-      }
+  if (minIndex > maxIndex) {
+    validationOutput["StartWorkspaceIndex"] = "Selected minimum workspace "
+                                              "index is greater than selected "
+                                              "maximum workspace index.";
+    validationOutput["EndWorkspaceIndex"] = "Selected maximum workspace index "
+                                            "is lower than selected minimum "
+                                            "workspace index.";
+  } else {
+    const std::vector<int> indices = getProperty("ListOfWorkspaceIndices");
+    if (MatrixWorkspace_const_sptr singleWs = getProperty("InputWorkspace")) {
+      validateSingleMatrixWorkspace(validationOutput, *singleWs, minIndex,
+                                    maxIndex, indices);
+    } else {
+      validateWorkspaceName(validationOutput,
+                            getPropertyValue("InputWorkspace"), minIndex,
+                            maxIndex, indices);
     }
   }
-
   return validationOutput;
 }
 
diff --git a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
index 5058883a38015414a45735df2eec8bbe9a0b8c39..eb6fcfb146b71f239c57fd678099abed5d78ee6b 100644
--- a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
+++ b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
@@ -12,13 +12,12 @@
 #include "MantidKernel/Statistics.h"
 #include "MantidKernel/Unit.h"
 
-#include <fstream>
-
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/trim.hpp>
 #include <boost/make_shared.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <boost/random/uniform_real.hpp>
+
+#include <fstream>
+#include <random>
 
 namespace Mantid {
 namespace Algorithms {
@@ -29,11 +28,6 @@ using namespace Mantid::Geometry;
 
 namespace {
 Mantid::Kernel::Logger g_log("VesuvioL1ThetaResolution");
-
-class SquareRoot {
-public:
-  double operator()(double x) { return sqrt(x); }
-};
 }
 
 // Register the algorithm into the AlgorithmFactory
@@ -108,10 +102,6 @@ void VesuvioL1ThetaResolution::init() {
 /** Execute the algorithm.
  */
 void VesuvioL1ThetaResolution::exec() {
-  // Set up random number generator
-  m_generator.seed(static_cast<boost::mt19937::result_type>(
-      static_cast<int>(getProperty("Seed"))));
-
   // Load the instrument workspace
   loadInstrument();
 
@@ -173,9 +163,13 @@ void VesuvioL1ThetaResolution::exec() {
 
   // Set up progress reporting
   Progress prog(this, 0.0, 1.0, numHist);
+  const int seed(getProperty("Seed"));
+  std::mt19937 randEngine(static_cast<std::mt19937::result_type>(seed));
+  std::uniform_real_distribution<> flatDistrib(0.0, 1.0);
+  std::function<double()> flatVariateGen(
+      [&randEngine, &flatDistrib]() { return flatDistrib(randEngine); });
 
   const auto &spectrumInfo = m_instWorkspace->spectrumInfo();
-
   // Loop for all detectors
   for (size_t i = 0; i < numHist; i++) {
     std::vector<double> l1;
@@ -189,7 +183,7 @@ void VesuvioL1ThetaResolution::exec() {
     g_log.information() << "Detector ID " << det.getID() << '\n';
 
     // Do simulation
-    calculateDetector(det, l1, theta);
+    calculateDetector(det, flatVariateGen, l1, theta);
 
     // Calculate statistics for L1 and theta
     Statistics l1Stats = getStatistics(l1);
@@ -350,8 +344,8 @@ void VesuvioL1ThetaResolution::loadInstrument() {
 /** Loads the instrument into a workspace.
  */
 void VesuvioL1ThetaResolution::calculateDetector(
-    const IDetector &detector, std::vector<double> &l1Values,
-    std::vector<double> &thetaValues) {
+    const IDetector &detector, std::function<double()> &flatRandomVariateGen,
+    std::vector<double> &l1Values, std::vector<double> &thetaValues) {
   const int numEvents = getProperty("NumEvents");
   l1Values.reserve(numEvents);
   thetaValues.reserve(numEvents);
@@ -389,16 +383,16 @@ void VesuvioL1ThetaResolution::calculateDetector(
   // This loop is not iteration limited but highly unlikely to ever become
   // infinate
   while (l1Values.size() < static_cast<size_t>(numEvents)) {
-    const double xs = -sampleWidth / 2 + sampleWidth * random();
+    const double xs = -sampleWidth / 2 + sampleWidth * flatRandomVariateGen();
     const double ys = 0.0;
-    const double zs = -sampleWidth / 2 + sampleWidth * random();
+    const double zs = -sampleWidth / 2 + sampleWidth * flatRandomVariateGen();
     const double rs = sqrt(pow(xs, 2) + pow(zs, 2));
 
     if (rs <= sampleWidth / 2) {
-      const double a = -detWidth / 2 + detWidth * random();
+      const double a = -detWidth / 2 + detWidth * flatRandomVariateGen();
       const double xd = x0 - a * cos(theta);
       const double yd = y0 + a * sin(theta);
-      const double zd = -detHeight / 2 + detHeight * random();
+      const double zd = -detHeight / 2 + detHeight * flatRandomVariateGen();
 
       const double l1 =
           sqrt(pow(xd - xs, 2) + pow(yd - ys, 2) + pow(zd - zs, 2));
@@ -450,21 +444,12 @@ VesuvioL1ThetaResolution::processDistribution(MatrixWorkspace_sptr ws,
   for (size_t i = 0; i < numHist; i++) {
     auto &y = ws->y(i);
     auto &e = ws->mutableE(i);
-
-    std::transform(y.begin(), y.end(), e.begin(), SquareRoot());
+    std::transform(y.begin(), y.end(), e.begin(),
+                   [](double x) { return sqrt(x); });
   }
 
   return ws;
 }
 
-//----------------------------------------------------------------------------------------------
-/** Generates a random number.
- */
-double VesuvioL1ThetaResolution::random() {
-  typedef boost::uniform_real<double> uniform_double;
-  return boost::variate_generator<boost::mt19937 &, uniform_double>(
-      m_generator, uniform_double(0.0, 1.0))();
-}
-
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/XDataConverter.cpp b/Framework/Algorithms/src/XDataConverter.cpp
index 84a3750a32323dd78699d588a409ada4ba773dc6..06c4dab887f37239bf0eb69df954b830df37185d 100644
--- a/Framework/Algorithms/src/XDataConverter.cpp
+++ b/Framework/Algorithms/src/XDataConverter.cpp
@@ -69,6 +69,9 @@ void XDataConverter::exec() {
     outputWS->setSharedY(i, inputWS->sharedY(i));
     outputWS->setSharedE(i, inputWS->sharedE(i));
     setXData(outputWS, inputWS, i);
+    if (inputWS->hasDx(i)) {
+      outputWS->setSharedDx(i, inputWS->sharedDx(i));
+    }
     prog.report();
 
     PARALLEL_END_INTERUPT_REGION
diff --git a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
index 368464508ac3f10825c77ffae089bb965b12668d..a0d98406167040f49013d5d6ec74baa425080b13 100644
--- a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
+++ b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
@@ -45,9 +45,9 @@ public:
 
     const double delta(1e-04);
     const size_t middle_index = 4;
-    TS_ASSERT_DELTA(0.9694, outWS->readY(0).front(), delta);
-    TS_ASSERT_DELTA(0.8035, outWS->readY(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.6530, outWS->readY(0).back(), delta);
+    TS_ASSERT_DELTA(0.9678, outWS->readY(0).front(), delta);
+    TS_ASSERT_DELTA(0.7950, outWS->readY(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.6590, outWS->readY(0).back(), delta);
   }
 
   //-------------------- Failure cases --------------------------------
diff --git a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
index 04f3c54d9930516ace687dce8c227ad8f6c63659..4cfbbc0ed295cba11a85d8ad64d3f08a17c42849 100644
--- a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
+++ b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h
@@ -157,8 +157,8 @@ public:
     // Now test with a gauge volume used.
     // Create a small cylinder to be the gauge volume
     std::string cylinder = "<cylinder id=\"shape\"> ";
-    cylinder += "<centre-of-bottom-base x=\"0.0\" y=\"-0.01\" z=\"0.0\" /> ";
-    cylinder += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    cylinder += R"(<centre-of-bottom-base x="0.0" y="-0.01" z="0.0" /> )";
+    cylinder += R"(<axis x="0.0" y="0.0" z="1" /> )";
     cylinder += "<radius val=\"0.1\" /> ";
     cylinder += "<height val=\"0.02\" /> ";
     cylinder += "</cylinder>";
diff --git a/Framework/Algorithms/test/BinaryOperateMasksTest.h b/Framework/Algorithms/test/BinaryOperateMasksTest.h
index f5fb9d1ad1eb6c6f070fce4ea860bc332491781b..886f12eef1e7b8db08e559aab2aea50b5d46abbd 100644
--- a/Framework/Algorithms/test/BinaryOperateMasksTest.h
+++ b/Framework/Algorithms/test/BinaryOperateMasksTest.h
@@ -72,7 +72,7 @@ public:
 
     std::cout << "\nTest I Is Completed\n";
 
-    if (ws1 == NULL) {
+    if (ws1 == nullptr) {
       std::cout << "\nWorkspace1 is NULL\n";
     }
 
@@ -100,13 +100,13 @@ public:
       ws4 = AnalysisDataService::Instance()
                 .retrieveWS<DataObjects::MaskWorkspace>(ws4name);
 
-      if (ws4 == NULL) {
+      if (ws4 == nullptr) {
         std::cout << "Workspace4 is NULL\n";
       } else {
         std::cout << "Workspace4 is good at output of NOT.  Number Histogram = "
                   << ws4->getNumberHistograms() << '\n';
       }
-      if (ws1 == NULL) {
+      if (ws1 == nullptr) {
         std::cout << "Workspace1 is NULL\n";
       } else {
         std::cout << "Workspace1 is good at output of NOT.  Number Histogram = "
diff --git a/Framework/Algorithms/test/ChangeTimeZeroTest.h b/Framework/Algorithms/test/ChangeTimeZeroTest.h
index 88520874edfd302ae7e0121422fd82786aa7e4cf..c0dd81f2f1d66f5b275966ec56bf2ce78eee3fae 100644
--- a/Framework/Algorithms/test/ChangeTimeZeroTest.h
+++ b/Framework/Algorithms/test/ChangeTimeZeroTest.h
@@ -487,11 +487,11 @@ private:
 
     auto logs = ws->run().getLogData();
     // Go over each log and check the times
-    for (auto iter = logs.begin(); iter != logs.end(); ++iter) {
-      if (dynamic_cast<Mantid::Kernel::ITimeSeriesProperty *>(*iter)) {
-        do_check_time_series(*iter, timeShift);
-      } else if (dynamic_cast<PropertyWithValue<std::string> *>(*iter)) {
-        do_check_property_with_string_value(*iter, timeShift);
+    for (auto &log : logs) {
+      if (dynamic_cast<Mantid::Kernel::ITimeSeriesProperty *>(log)) {
+        do_check_time_series(log, timeShift);
+      } else if (dynamic_cast<PropertyWithValue<std::string> *>(log)) {
+        do_check_property_with_string_value(log, timeShift);
       }
     }
 
@@ -509,8 +509,8 @@ private:
     // Iterator over all entries of the time series and check if they are
     // altered
     double secondCounter = timeShift;
-    for (auto it = times.begin(); it != times.end(); ++it) {
-      double secs = DateAndTime::secondsFromDuration(*it - m_startTime);
+    for (auto &time : times) {
+      double secs = DateAndTime::secondsFromDuration(time - m_startTime);
       TSM_ASSERT_DELTA("Time series logs should have shifted times.", secs,
                        secondCounter, 1e-5);
       ++secondCounter;
diff --git a/Framework/Algorithms/test/ConjoinXRunsTest.h b/Framework/Algorithms/test/ConjoinXRunsTest.h
index 8133133d9614ad865bb76317ee54976b307c5e5a..fd1e397fdc023c13b3409f3dc3fe9a8e0d96696f 100644
--- a/Framework/Algorithms/test/ConjoinXRunsTest.h
+++ b/Framework/Algorithms/test/ConjoinXRunsTest.h
@@ -8,15 +8,26 @@
 #include "MantidAlgorithms/AddSampleLog.h"
 #include "MantidAlgorithms/AddTimeSeriesLog.h"
 #include "MantidAlgorithms/ConjoinXRuns.h"
+#include "MantidHistogramData/Counts.h"
+#include "MantidHistogramData/HistogramDx.h"
+#include "MantidHistogramData/HistogramE.h"
+#include "MantidHistogramData/HistogramX.h"
+#include "MantidHistogramData/HistogramY.h"
+#include "MantidHistogramData/Points.h"
 #include "MantidKernel/Unit.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using Mantid::Algorithms::ConjoinXRuns;
 using Mantid::Algorithms::AddSampleLog;
 using Mantid::Algorithms::AddTimeSeriesLog;
+using Mantid::HistogramData::Counts;
+using Mantid::HistogramData::HistogramDx;
+using Mantid::HistogramData::HistogramE;
+using Mantid::HistogramData::HistogramX;
+using Mantid::HistogramData::HistogramY;
+using Mantid::HistogramData::Points;
 using namespace Mantid::API;
 using namespace WorkspaceCreationHelper;
-using namespace Mantid::HistogramData;
 
 class ConjoinXRunsTest : public CxxTest::TestSuite {
 public:
@@ -26,37 +37,33 @@ public:
   static void destroySuite(ConjoinXRunsTest *suite) { delete suite; }
 
   void setUp() override {
-    MatrixWorkspace_sptr ws1 = create2DWorkspace123(5, 3); // 3 points
-    MatrixWorkspace_sptr ws2 = create2DWorkspace154(5, 2); // 2 points
-    MatrixWorkspace_sptr ws3 = create2DWorkspace123(5, 1); // 1 point
-    MatrixWorkspace_sptr ws4 = create2DWorkspace154(5, 1); // 1 point
-    MatrixWorkspace_sptr ws5 = create2DWorkspace123(5, 3); // 3 points
-    MatrixWorkspace_sptr ws6 = create2DWorkspace123(5, 3); // 3 points
-
-    ws1->getAxis(0)->setUnit("TOF");
-    ws2->getAxis(0)->setUnit("TOF");
-    ws3->getAxis(0)->setUnit("TOF");
-    ws4->getAxis(0)->setUnit("TOF");
-    ws5->getAxis(0)->setUnit("TOF");
-    ws6->getAxis(0)->setUnit("TOF");
-
-    storeWS("ws1", ws1);
-    storeWS("ws2", ws2);
-    storeWS("ws3", ws3);
-    storeWS("ws4", ws4);
-    storeWS("ws5", ws5);
-    storeWS("ws6", ws6);
-
+    std::vector<MatrixWorkspace_sptr> ws(6);
+    // Workspaces have 5 spectra must be point data, don't have masks and have
+    // dx
+    ws[0] = create2DWorkspace123(5, 3, false, std::set<int64_t>(),
+                                 true); // 3 points
+    ws[1] = create2DWorkspace154(5, 2, false, std::set<int64_t>(),
+                                 true); // 2 points
+    ws[2] =
+        create2DWorkspace123(5, 1, false, std::set<int64_t>(), true); // 1 point
+    ws[3] =
+        create2DWorkspace154(5, 1, false, std::set<int64_t>(), true); // 1 point
+    ws[4] = create2DWorkspace123(5, 3, false, std::set<int64_t>(),
+                                 true); // 3 points
+    ws[5] = create2DWorkspace123(5, 3, false, std::set<int64_t>(),
+                                 true); // 3 points
     m_testWS = {"ws1", "ws2", "ws3", "ws4", "ws5", "ws6"};
+
+    for (unsigned int i = 0; i < ws.size(); ++i) {
+      ws[i]->getAxis(0)->setUnit("TOF");
+      storeWS(m_testWS[i], ws[i]);
+    }
   }
 
   void tearDown() override {
-    removeWS("ws1");
-    removeWS("ws2");
-    removeWS("ws3");
-    removeWS("ws4");
-    removeWS("ws5");
-    removeWS("ws6");
+    for (unsigned int i = 0; i < m_testWS.size(); ++i) {
+      removeWS(m_testWS[i]);
+    }
     m_testWS.clear();
   }
 
@@ -80,34 +87,43 @@ public:
     TS_ASSERT_EQUALS(out->blocksize(), 7);
     TS_ASSERT(!out->isHistogramData());
     TS_ASSERT_EQUALS(out->getAxis(0)->unit()->unitID(), "TOF");
+    std::vector<double> x{1., 2., 3., 1., 2., 1., 1.};
+    std::vector<double> y{2., 2., 2., 5., 5., 2., 5.};
+    std::vector<double> e{3., 3., 3., 4., 4., 3., 4.};
+    TS_ASSERT_EQUALS(out->x(0).rawData(), x);
+    TS_ASSERT_EQUALS(out->y(0).rawData(), y);
+    TS_ASSERT_EQUALS(out->e(0).rawData(), e);
+    TSM_ASSERT_EQUALS("Dx and y values are the same", out->dx(0).rawData(), y);
+  }
+
+  void testWSWithoutDxValues() {
+    // Workspaces have 5 spectra must be point data
+    MatrixWorkspace_sptr ws0 = create2DWorkspace123(5, 3); // 3 points
+    MatrixWorkspace_sptr ws1 = create2DWorkspace154(5, 2); // 2 points
+    ws0->getAxis(0)->setUnit("TOF");
+    ws1->getAxis(0)->setUnit("TOF");
+    storeWS("ws_0", ws0);
+    storeWS("ws_1", ws1);
+    m_testee.setProperty("InputWorkspaces",
+                         std::vector<std::string>{"ws_0", "ws_1"});
+    m_testee.setProperty("OutputWorkspace", "out");
+    TS_ASSERT_THROWS_NOTHING(m_testee.execute());
+    TS_ASSERT(m_testee.isExecuted());
+
+    MatrixWorkspace_sptr out =
+        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("out");
 
-    std::vector<double> spectrum = out->y(0).rawData();
-    std::vector<double> error = out->e(0).rawData();
-    std::vector<double> xaxis = out->x(0).rawData();
-
-    TS_ASSERT_EQUALS(spectrum[0], 2.);
-    TS_ASSERT_EQUALS(spectrum[1], 2.);
-    TS_ASSERT_EQUALS(spectrum[2], 2.);
-    TS_ASSERT_EQUALS(spectrum[3], 5.);
-    TS_ASSERT_EQUALS(spectrum[4], 5.);
-    TS_ASSERT_EQUALS(spectrum[5], 2.);
-    TS_ASSERT_EQUALS(spectrum[6], 5.);
-
-    TS_ASSERT_EQUALS(error[0], 3.);
-    TS_ASSERT_EQUALS(error[1], 3.);
-    TS_ASSERT_EQUALS(error[2], 3.);
-    TS_ASSERT_EQUALS(error[3], 4.);
-    TS_ASSERT_EQUALS(error[4], 4.);
-    TS_ASSERT_EQUALS(error[5], 3.);
-    TS_ASSERT_EQUALS(error[6], 4.);
-
-    TS_ASSERT_EQUALS(xaxis[0], 1.);
-    TS_ASSERT_EQUALS(xaxis[1], 2.);
-    TS_ASSERT_EQUALS(xaxis[2], 3.);
-    TS_ASSERT_EQUALS(xaxis[3], 1.);
-    TS_ASSERT_EQUALS(xaxis[4], 2.);
-    TS_ASSERT_EQUALS(xaxis[5], 1.);
-    TS_ASSERT_EQUALS(xaxis[6], 1.);
+    TS_ASSERT(out);
+    TS_ASSERT_EQUALS(out->getNumberHistograms(), 5);
+    TS_ASSERT_EQUALS(out->blocksize(), 5);
+    TS_ASSERT(!out->isHistogramData());
+    TS_ASSERT_EQUALS(out->getAxis(0)->unit()->unitID(), "TOF");
+    std::vector<double> x{1., 2., 3., 1., 2.};
+    std::vector<double> y{2., 2., 2., 5., 5.};
+    std::vector<double> e{3., 3., 3., 4., 4.};
+    TS_ASSERT_EQUALS(out->x(0).rawData(), x);
+    TS_ASSERT_EQUALS(out->y(0).rawData(), y);
+    TS_ASSERT_EQUALS(out->e(0).rawData(), e);
   }
 
   void testFailDifferentNumberBins() {
@@ -127,9 +143,11 @@ public:
     MatrixWorkspace_sptr ws6 =
         AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("ws6");
 
-    Counts counts{{4, 9, 16}};
-    Points points{{0.4, 0.9, 1.1}};
-    ws6->setHistogram(3, points, counts);
+    for (auto i = 0; i < 5;
+         i++) { // modify all 5 spectra of ws6 in terms of y and x
+      ws6->mutableY(i) = {4., 9., 16.};
+      ws6->mutableX(i) = {0.4, 0.9, 1.1};
+    }
 
     m_testee.setProperty("InputWorkspaces",
                          std::vector<std::string>{"ws1", "ws6"});
@@ -146,55 +164,17 @@ public:
     TS_ASSERT(!out->isHistogramData());
     TS_ASSERT_EQUALS(out->getAxis(0)->unit()->unitID(), "TOF");
 
-    auto spectrum0 = out->y(0).rawData();
-    auto error0 = out->e(0).rawData();
-    auto xaxis0 = out->x(0).rawData();
-
-    TS_ASSERT_EQUALS(spectrum0[0], 2.);
-    TS_ASSERT_EQUALS(spectrum0[1], 2.);
-    TS_ASSERT_EQUALS(spectrum0[2], 2.);
-    TS_ASSERT_EQUALS(spectrum0[3], 2.);
-    TS_ASSERT_EQUALS(spectrum0[4], 2.);
-    TS_ASSERT_EQUALS(spectrum0[5], 2.);
-
-    TS_ASSERT_EQUALS(error0[0], 3.);
-    TS_ASSERT_EQUALS(error0[1], 3.);
-    TS_ASSERT_EQUALS(error0[2], 3.);
-    TS_ASSERT_EQUALS(error0[3], 3.);
-    TS_ASSERT_EQUALS(error0[4], 3.);
-    TS_ASSERT_EQUALS(error0[5], 3.);
-
-    TS_ASSERT_EQUALS(xaxis0[0], 1.);
-    TS_ASSERT_EQUALS(xaxis0[1], 2.);
-    TS_ASSERT_EQUALS(xaxis0[2], 3.);
-    TS_ASSERT_EQUALS(xaxis0[3], 1.);
-    TS_ASSERT_EQUALS(xaxis0[4], 2.);
-    TS_ASSERT_EQUALS(xaxis0[5], 3.);
-
-    auto spectrum3 = out->y(3).rawData();
-    auto error3 = out->e(3).rawData();
-    auto xaxis3 = out->x(3).rawData();
-
-    TS_ASSERT_EQUALS(spectrum3[0], 2.);
-    TS_ASSERT_EQUALS(spectrum3[1], 2.);
-    TS_ASSERT_EQUALS(spectrum3[2], 2.);
-    TS_ASSERT_EQUALS(spectrum3[3], 4.);
-    TS_ASSERT_EQUALS(spectrum3[4], 9.);
-    TS_ASSERT_EQUALS(spectrum3[5], 16.);
-
-    TS_ASSERT_EQUALS(error3[0], 3.);
-    TS_ASSERT_EQUALS(error3[1], 3.);
-    TS_ASSERT_EQUALS(error3[2], 3.);
-    TS_ASSERT_EQUALS(error3[3], 2.);
-    TS_ASSERT_EQUALS(error3[4], 3.);
-    TS_ASSERT_EQUALS(error3[5], 4.);
-
-    TS_ASSERT_EQUALS(xaxis3[0], 1.);
-    TS_ASSERT_EQUALS(xaxis3[1], 2.);
-    TS_ASSERT_EQUALS(xaxis3[2], 3.);
-    TS_ASSERT_EQUALS(xaxis3[3], 0.4);
-    TS_ASSERT_EQUALS(xaxis3[4], 0.9);
-    TS_ASSERT_EQUALS(xaxis3[5], 1.1);
+    std::vector<double> x_vec{1., 2., 3., .4, .9, 1.1};
+    std::vector<double> y_vec{2., 2., 2., 4., 9., 16.};
+    std::vector<double> e_vec{3., 3., 3., 3., 3., 3.};
+    std::vector<double> dx_vec{2., 2., 2., 2., 2., 2.};
+    // Check all 5 spectra
+    for (auto i = 0; i < 5; i++) {
+      TS_ASSERT_EQUALS(out->y(i).rawData(), y_vec);
+      TS_ASSERT_EQUALS(out->e(i).rawData(), e_vec);
+      TS_ASSERT_EQUALS(out->x(i).rawData(), x_vec);
+      TS_ASSERT_EQUALS(out->dx(i).rawData(), dx_vec);
+    }
   }
 
   void testFailWithNumLog() {
@@ -245,16 +225,12 @@ public:
     TS_ASSERT_EQUALS(out->getNumberHistograms(), 5);
     TS_ASSERT_EQUALS(out->getAxis(0)->unit()->unitID(), "Energy");
 
-    std::vector<double> xaxis = out->x(0).rawData();
-    std::vector<double> spectrum = out->y(0).rawData();
-    std::vector<double> error = out->e(0).rawData();
-
-    TS_ASSERT_EQUALS(xaxis[0], 0.7);
-    TS_ASSERT_EQUALS(xaxis[1], 1.1);
-    TS_ASSERT_EQUALS(spectrum[0], 2.);
-    TS_ASSERT_EQUALS(spectrum[1], 5.);
-    TS_ASSERT_EQUALS(error[0], 3.);
-    TS_ASSERT_EQUALS(error[1], 4.);
+    TS_ASSERT_EQUALS(out->x(0)[0], 0.7);
+    TS_ASSERT_EQUALS(out->x(0)[1], 1.1);
+    TS_ASSERT_EQUALS(out->y(0)[0], 2.);
+    TS_ASSERT_EQUALS(out->y(0)[1], 5.);
+    TS_ASSERT_EQUALS(out->e(0)[0], 3.);
+    TS_ASSERT_EQUALS(out->e(0)[1], 4.);
   }
 
   void testFailWithStringLog() {
@@ -315,27 +291,13 @@ public:
     TS_ASSERT_EQUALS(out->blocksize(), 5);
     TS_ASSERT_EQUALS(out->getNumberHistograms(), 5);
 
-    std::vector<double> spectrum = out->y(0).rawData();
-    std::vector<double> xaxis = out->x(0).rawData();
-    std::vector<double> error = out->e(0).rawData();
-
-    TS_ASSERT_EQUALS(spectrum[0], 2.);
-    TS_ASSERT_EQUALS(spectrum[1], 2.);
-    TS_ASSERT_EQUALS(spectrum[2], 2.);
-    TS_ASSERT_EQUALS(spectrum[3], 5.);
-    TS_ASSERT_EQUALS(spectrum[4], 5.);
-
-    TS_ASSERT_EQUALS(error[0], 3.);
-    TS_ASSERT_EQUALS(error[1], 3.);
-    TS_ASSERT_EQUALS(error[2], 3.);
-    TS_ASSERT_EQUALS(error[3], 4.);
-    TS_ASSERT_EQUALS(error[4], 4.);
-
-    TS_ASSERT_EQUALS(xaxis[0], 5.7);
-    TS_ASSERT_EQUALS(xaxis[1], 6.1);
-    TS_ASSERT_EQUALS(xaxis[2], 6.7);
-    TS_ASSERT_EQUALS(xaxis[3], 8.3);
-    TS_ASSERT_EQUALS(xaxis[4], 9.5);
+    std::vector<double> y_vec{2., 2., 2., 5., 5.};
+    std::vector<double> x_vec{5.7, 6.1, 6.7, 8.3, 9.5};
+    std::vector<double> e_vec{3., 3., 3., 4., 4.};
+    TS_ASSERT_EQUALS(out->y(0).rawData(), y_vec);
+    TS_ASSERT_EQUALS(out->x(0).rawData(), x_vec);
+    TS_ASSERT_EQUALS(out->e(0).rawData(), e_vec);
+    TS_ASSERT_EQUALS(out->dx(0).rawData(), y_vec)
   }
 
   void testFailWithNumSeriesLog() {
@@ -402,7 +364,8 @@ public:
   void setUp() override {
     m_ws.reserve(100);
     for (size_t i = 0; i < 100; ++i) {
-      MatrixWorkspace_sptr ws = create2DWorkspace123(10000, 100);
+      MatrixWorkspace_sptr ws =
+          create2DWorkspace123(2000, 100, false, std::set<int64_t>(), true);
       std::string name = "ws" + std::to_string(i);
       storeWS(name, ws);
       m_ws.push_back(name);
diff --git a/Framework/Algorithms/test/ConvertToHistogramTest.h b/Framework/Algorithms/test/ConvertToHistogramTest.h
index 0af9416c715ef295b7019e352fe57a6c4103b763..5ac8871d696e8cf6e224b75d33658a5569aeb123 100644
--- a/Framework/Algorithms/test/ConvertToHistogramTest.h
+++ b/Framework/Algorithms/test/ConvertToHistogramTest.h
@@ -13,12 +13,18 @@ using Mantid::API::MatrixWorkspace_sptr;
 using Mantid::Algorithms::ConvertToHistogram;
 using Mantid::DataObjects::Workspace2D_sptr;
 using Mantid::MantidVecPtr;
+using Mantid::HistogramData::HistogramDx;
 using Mantid::HistogramData::LinearGenerator;
 using Mantid::HistogramData::Points;
+using Mantid::Kernel::make_cow;
 
 class ConvertToHistogramTest : public CxxTest::TestSuite {
 
 public:
+  void tearDown() override {
+    Mantid::API::AnalysisDataService::Instance().clear();
+  }
+
   void test_That_The_Algorithm_Has_Two_Properties() {
     ConvertToHistogram alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize());
@@ -38,7 +44,6 @@ public:
 
     // Check that the algorithm just pointed the output data at the input
     TS_ASSERT_EQUALS(&(*testWS), &(*outputWS));
-    Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName());
   }
 
   void test_A_Point_Data_InputWorkspace_Is_Converted_To_A_Histogram() {
@@ -63,43 +68,40 @@ public:
     TS_ASSERT_EQUALS(outputWS->isHistogramData(), true);
     const int numBoundaries = numYPoints + 1;
 
-    // This makes the new X values more readable rather than using a dynamic
-    // array
-    // so I'll live with the hard coding
     const double expectedX[11] = {-0.5, 0.5, 1.5, 2.5, 3.5, 4.5,
                                   5.5,  6.5, 7.5, 8.5, 9.5};
     for (int j = 0; j < numBoundaries; ++j) {
       TS_ASSERT_EQUALS(outputWS->readX(0)[j], expectedX[j]);
     }
+  }
 
-    // for( int i = 0; i < numSpectra; ++i )
-    // {
-    //   const Mantid::MantidVec & yValues = outputWS->readY(i);
-    //   const Mantid::MantidVec & xValues = outputWS->readX(i);
-    //   const Mantid::MantidVec & eValues = outputWS->readE(i);
-
-    //   TS_ASSERT_EQUALS(xValues.size(), numBins);
-    //   // The y and e values sizes be unchanged
-    //   TS_ASSERT_EQUALS(yValues.size(), numYPoints);
-    //   TS_ASSERT_EQUALS(eValues.size(), numYPoints);
-
-    //   for( int j = 0; j < numYPoints; ++j )
-    //   {
-    // 	// Now the data. Y and E unchanged
-    // 	TS_ASSERT_EQUALS(yValues[j], 2.0);
-    // 	TS_ASSERT_EQUALS(eValues[j], M_SQRT2);
-
-    // 	// X data originally was 0->10 in steps of 1. Now it should be the
-    // centre of each bin which is
-    // 	// 1.0 away from the last centre
-    // 	const double expectedX = 0.5 + j*1.0;
-    // 	TS_ASSERT_EQUALS(xValues[j], expectedX);
-    //   }
-    //   // And the final X points
-    //   TS_ASSERT_EQUALS(xValues.back(), 100.);
-    // }
-
-    Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName());
+  void test_Dx_Data_Is_Handled_Correctly() {
+    // Creates a workspace with 10 points
+    constexpr int numYPoints{10};
+    constexpr int numSpectra{2};
+    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace123(
+        numSpectra, numYPoints, false);
+    double xErrors[numYPoints] = {0.1, 0.2, 0.3, 0.4, 0.5,
+                                  0.6, 0.7, 0.8, 0.9, 1.0};
+    auto dxs = make_cow<HistogramDx>(xErrors, xErrors + numYPoints);
+    // Reset the X data to something reasonable, set Dx.
+    Points x(numYPoints, LinearGenerator(0.0, 1.0));
+    for (int i = 0; i < numSpectra; ++i) {
+      testWS->setPoints(i, x);
+      testWS->setSharedDx(i, dxs);
+    }
+    TS_ASSERT(!testWS->isHistogramData())
+    MatrixWorkspace_sptr outputWS = runAlgorithm(testWS);
+    TS_ASSERT(outputWS);
+    TS_ASSERT(outputWS->isHistogramData())
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      TS_ASSERT(outputWS->hasDx(i))
+      const auto &dx = outputWS->dx(i);
+      TS_ASSERT_EQUALS(dx.size(), numYPoints)
+      for (size_t j = 0; j < dx.size(); ++j) {
+        TS_ASSERT_EQUALS(dx[j], xErrors[j])
+      }
+    }
   }
 
 private:
diff --git a/Framework/Algorithms/test/ConvertToPointDataTest.h b/Framework/Algorithms/test/ConvertToPointDataTest.h
index 287621e1ecb944169405ce0425df9be9f515d458..33a2a42f94137f5a76665ef3f902fb2bde5ab1cf 100644
--- a/Framework/Algorithms/test/ConvertToPointDataTest.h
+++ b/Framework/Algorithms/test/ConvertToPointDataTest.h
@@ -17,6 +17,10 @@ using Mantid::DataObjects::Workspace2D_sptr;
 class ConvertToPointDataTest : public CxxTest::TestSuite {
 
 public:
+  void tearDown() override {
+    Mantid::API::AnalysisDataService::Instance().clear();
+  }
+
   void test_That_The_Algorithm_Has_Two_Properties() {
     ConvertToPointData alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize());
@@ -35,7 +39,6 @@ public:
 
     // Check that the algorithm just pointed the output data at the input
     TS_ASSERT_EQUALS(&(*testWS), &(*outputWS));
-    Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName());
   }
 
   void test_A_Uniformly_Binned_Histogram_Is_Transformed_Correctly() {
@@ -94,8 +97,6 @@ public:
     TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(0), 0);
     TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(1), 2);
     TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(2), 4);
-
-    Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName());
   }
 
   void test_A_Non_Uniformly_Binned_Histogram_Is_Transformed_Correctly() {
@@ -103,8 +104,9 @@ public:
     double xBoundaries[11] = {0.0,  1.0,  3.0,  5.0,  6.0, 7.0,
                               10.0, 13.0, 16.0, 17.0, 17.5};
     const int numSpectra(2);
-    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspaceBinned(
-        numSpectra, 11, xBoundaries);
+    Workspace2D_sptr testWS =
+        WorkspaceCreationHelper::create2DWorkspaceNonUniformlyBinned(
+            numSpectra, 11, xBoundaries);
     const size_t numBins = testWS->blocksize();
     TS_ASSERT_EQUALS(testWS->isHistogramData(), true);
 
@@ -139,6 +141,30 @@ public:
     }
   }
 
+  void test_Dx_Data_Is_Handled_Correctly() {
+    constexpr size_t numBins{11};
+    double xBoundaries[numBins] = {0.0,  1.0,  3.0,  5.0,  6.0, 7.0,
+                                   10.0, 13.0, 16.0, 17.0, 17.5};
+    constexpr int numSpectra{2};
+    Workspace2D_sptr testWS =
+        WorkspaceCreationHelper::create2DWorkspaceNonUniformlyBinned(
+            numSpectra, numBins, xBoundaries, true);
+    TS_ASSERT(testWS->isHistogramData())
+    double xErrors[numBins - 1] = {0.1, 0.2, 0.3, 0.4, 0.5,
+                                   0.6, 0.7, 0.8, 0.9, 1.0};
+    MatrixWorkspace_sptr outputWS = runAlgorithm(testWS);
+    TS_ASSERT(outputWS)
+    TS_ASSERT(!outputWS->isHistogramData())
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      TS_ASSERT(outputWS->hasDx(i))
+      const auto &dx = outputWS->dx(i);
+      TS_ASSERT_EQUALS(dx.size(), numBins - 1)
+      for (size_t j = 0; j < dx.size(); ++j) {
+        TS_ASSERT_DELTA(dx[j], xErrors[j], 1E-16);
+      }
+    }
+  }
+
 private:
   MatrixWorkspace_sptr runAlgorithm(Workspace2D_sptr inputWS) {
     IAlgorithm_sptr alg(new ConvertToPointData());
diff --git a/Framework/Algorithms/test/ConvertUnitsTest.h b/Framework/Algorithms/test/ConvertUnitsTest.h
index 5340a181e069a70531faf64483ab83ae65a1f31b..67db2df5870fcdea567328f07c94caf32a162c3e 100644
--- a/Framework/Algorithms/test/ConvertUnitsTest.h
+++ b/Framework/Algorithms/test/ConvertUnitsTest.h
@@ -714,7 +714,7 @@ public:
         WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(1, 10,
                                                                         false);
     ws->getAxis(0)->setUnit("TOF");
-    ws->sortAll(sortType, NULL);
+    ws->sortAll(sortType, nullptr);
 
     if (sortType == TOF_SORT) {
       // Only threadsafe if all the event lists are sorted
diff --git a/Framework/Algorithms/test/CopyInstrumentParametersTest.h b/Framework/Algorithms/test/CopyInstrumentParametersTest.h
index 6109c023b2a07f06eedd00f32a98864ad31746be..4a5b449f498d632b0680169d54022ead2d385197 100644
--- a/Framework/Algorithms/test/CopyInstrumentParametersTest.h
+++ b/Framework/Algorithms/test/CopyInstrumentParametersTest.h
@@ -3,32 +3,25 @@
 
 #include <cxxtest/TestSuite.h>
 
-#include "MantidDataHandling/LoadInstrument.h"
-#include "MantidAPI/IAlgorithm.h"
 #include "MantidAlgorithms/CopyInstrumentParameters.h"
-#include "MantidAPI/Workspace.h"
-#include "MantidDataObjects/Workspace2D.h"
-#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
-#include "WorkspaceCreationHelperTest.h"
-#include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/ITableWorkspace.h"
-#include "MantidAPI/TableRow.h"
 #include "MantidKernel/V3D.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Component.h"
-#include "MantidDataHandling/LoadEmptyInstrument.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cmath>
 #include <stdexcept>
 
 using namespace Mantid::Algorithms;
 using namespace Mantid::API;
-using namespace Mantid::Kernel;
-using namespace Mantid::DataObjects;
-using Mantid::Geometry::IDetector_const_sptr;
-using Mantid::Geometry::IComponent_const_sptr;
+using Mantid::Geometry::Instrument_const_sptr;
+using Mantid::Geometry::ParameterMap;
+using Mantid::Kernel::V3D;
 
 class CopyInstrumentParametersTest : public CxxTest::TestSuite {
 public:
@@ -62,10 +55,10 @@ public:
     TS_ASSERT_THROWS_NOTHING(
         copyInstParam.setPropertyValue("OutputWorkspace", wsName2));
     // Get instrument of input workspace and move some detectors
-    Geometry::ParameterMap *pmap;
+    ParameterMap *pmap;
     pmap = &(ws1->instrumentParameters());
     auto &detectorInfoWs1 = ws1->mutableDetectorInfo();
-    Geometry::Instrument_const_sptr instrument = ws1->getInstrument();
+    Instrument_const_sptr instrument = ws1->getInstrument();
     detectorInfoWs1.setPosition(0, V3D(6.0, 0.0, 0.7));
     detectorInfoWs1.setPosition(1, V3D(6.0, 0.1, 0.7));
 
@@ -119,8 +112,8 @@ public:
     AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
     dataStore.add(wsName1, ws1);
 
-    Geometry::Instrument_const_sptr instrument = ws1->getInstrument();
-    Geometry::ParameterMap *pmap;
+    Instrument_const_sptr instrument = ws1->getInstrument();
+    ParameterMap *pmap;
     pmap = &(ws1->instrumentParameters());
     // add auxiliary instrument parameters
     pmap->addDouble(instrument.get(), "Ei", 100);
@@ -218,8 +211,8 @@ public:
     AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
     dataStore.add(m_SourceWSName, ws1);
 
-    Geometry::Instrument_const_sptr instrument = ws1->getInstrument();
-    Geometry::ParameterMap *pmap;
+    Instrument_const_sptr instrument = ws1->getInstrument();
+    ParameterMap *pmap;
     pmap = &(ws1->instrumentParameters());
     for (size_t i = 0; i < n_Parameters; i++) {
       // add auxiliary instrument parameters
@@ -230,7 +223,8 @@ public:
     // calibrate detectors;
     auto &detectorInfo = ws1->mutableDetectorInfo();
     for (size_t i = 0; i < n_detectors; i++) {
-      auto detIndex = detectorInfo.indexOf(static_cast<Mantid::detid_t>(i + 1));
+      size_t detIndex =
+          detectorInfo.indexOf(static_cast<Mantid::detid_t>(i + 1));
       detectorInfo.setPosition(
           detIndex, V3D(sin(M_PI * double(i)), cos(M_PI * double(i / 500)), 7));
     }
@@ -270,7 +264,7 @@ public:
 
     AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
     MatrixWorkspace_sptr ws2 =
-        dataStore.retrieveWS<API::MatrixWorkspace>(m_TargetWSName);
+        dataStore.retrieveWS<MatrixWorkspace>(m_TargetWSName);
     auto instr2 = ws2->getInstrument();
 
     auto param_names = instr2->getParameterNames();
diff --git a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
index 6647ebd9c676eb173ba35b53a2301bff45fb6119..da7c08c0a7501bc6db2d47bf6631e26476e10720 100644
--- a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
+++ b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
@@ -62,7 +62,7 @@ public:
 
     ws->getAxis(0)->setUnit("TOF");
 
-    ws->sortAll(PULSETIME_SORT, NULL);
+    ws->sortAll(PULSETIME_SORT, nullptr);
 
     // Add some chopper TDCs to the workspace.
     double period = 1 / 293.383;
diff --git a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
index 9f715efd114ee6cd38c1f9eaa01e34482070dcbd..8b524bcdf6a3a88e1e33b809991dfdbe62553238 100644
--- a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
@@ -10,7 +10,6 @@
 
 #include <cxxtest/TestSuite.h>
 #include <algorithm>
-#include "MantidAlgorithms/ReflectometryReductionOne.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
@@ -22,7 +21,6 @@
 using namespace Mantid;
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
-using namespace Mantid::Algorithms;
 using namespace WorkspaceCreationHelper;
 
 class CreateTransmissionWorkspaceTest : public CxxTest::TestSuite {
diff --git a/Framework/Algorithms/test/CreateWorkspaceTest.h b/Framework/Algorithms/test/CreateWorkspaceTest.h
index 86bdb52c4548a7e12ecf297860b591df4601dcb3..823ba7ba664060bf0ab132f115c95343ef1e4fad 100644
--- a/Framework/Algorithms/test/CreateWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateWorkspaceTest.h
@@ -23,6 +23,7 @@ void run_create(const Parallel::Communicator &comm,
   alg->setProperty<std::vector<double>>("DataX", dataEYX);
   alg->setProperty<std::vector<double>>("DataY", dataEYX);
   alg->setProperty<std::vector<double>>("DataE", dataEYX);
+  alg->setProperty<std::vector<double>>("Dx", dataEYX);
   alg->setProperty("ParallelStorageMode", storageMode);
   alg->execute();
   MatrixWorkspace_const_sptr ws = alg->getProperty("OutputWorkspace");
@@ -73,6 +74,8 @@ public:
         alg.setProperty<std::vector<double>>("DataY", dataEYX));
     TS_ASSERT_THROWS_NOTHING(
         alg.setProperty<std::vector<double>>("DataE", dataEYX));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setProperty<std::vector<double>>("Dx", dataEYX));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("UnitX", "Wavelength"));
     TS_ASSERT_THROWS_NOTHING(
         alg.setPropertyValue("VerticalAxisUnit", "MomentumTransfer"));
@@ -95,17 +98,14 @@ public:
     // No parent workspace -> no instrument -> no detectors -> no mapping.
     TS_ASSERT_EQUALS(ws->getSpectrum(0).getDetectorIDs().size(), 0);
 
-    TS_ASSERT_EQUALS(ws->x(0)[0], 0);
-    TS_ASSERT_EQUALS(ws->x(0)[1], 1.234);
-    TS_ASSERT_EQUALS(ws->x(0)[2], 2.468);
-    TS_ASSERT_EQUALS(ws->y(0)[0], 0);
-    TS_ASSERT_EQUALS(ws->y(0)[1], 1.234);
-    TS_ASSERT_EQUALS(ws->y(0)[2], 2.468);
-    TS_ASSERT_EQUALS(ws->e(0)[0], 0);
-    TS_ASSERT_EQUALS(ws->e(0)[1], 1.234);
-    TS_ASSERT_EQUALS(ws->e(0)[2], 2.468);
+    for (size_t i = 0; i < dataEYX.size(); ++i) {
+      TS_ASSERT_EQUALS(ws->x(0)[i], dataEYX[i]);
+    }
+    for (size_t i = 0; i < dataEYX.size(); ++i) {
+      TS_ASSERT_EQUALS(ws->y(0)[i], dataEYX[i]);
+      TS_ASSERT_EQUALS(ws->e(0)[i], dataEYX[i]);
+    }
     TS_ASSERT_EQUALS(ws->getAxis(0)->unit()->caption(), "Wavelength");
-
     TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->unitID(), "MomentumTransfer");
     TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->caption(), "q");
 
@@ -122,6 +122,54 @@ public:
             "test_CreateWorkspace"));
   }
 
+  void testCreateBinEdges() {
+    Mantid::Algorithms::CreateWorkspace createBinEdges;
+    TS_ASSERT_THROWS_NOTHING(createBinEdges.initialize());
+
+    std::vector<double> dataX{5.5, 6.8, 9.1, 12.3};
+    std::vector<double> dataEYDx{0.0, 1.234, 2.468};
+
+    TS_ASSERT_THROWS_NOTHING(createBinEdges.setProperty<int>("NSpec", 1));
+    TS_ASSERT_THROWS_NOTHING(
+        createBinEdges.setProperty<std::vector<double>>("DataX", dataX));
+    TS_ASSERT_THROWS_NOTHING(
+        createBinEdges.setProperty<std::vector<double>>("DataY", dataEYDx));
+    TS_ASSERT_THROWS_NOTHING(
+        createBinEdges.setProperty<std::vector<double>>("DataE", dataEYDx));
+    TS_ASSERT_THROWS_NOTHING(
+        createBinEdges.setProperty<std::vector<double>>("Dx", dataEYDx));
+    TS_ASSERT_THROWS_NOTHING(createBinEdges.setPropertyValue(
+        "OutputWorkspace", "test_CreateWorkspace"));
+    TS_ASSERT_THROWS_NOTHING(createBinEdges.execute());
+
+    TS_ASSERT(createBinEdges.isExecuted());
+    Mantid::API::MatrixWorkspace_const_sptr ws;
+
+    TS_ASSERT_THROWS_NOTHING(
+        ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
+            Mantid::API::AnalysisDataService::Instance().retrieve(
+                "test_CreateWorkspace")));
+
+    TS_ASSERT(ws->isHistogramData());
+    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
+    // No parent workspace -> no instrument -> no detectors -> no mapping.
+    TS_ASSERT_EQUALS(ws->getSpectrum(0).getDetectorIDs().size(), 0);
+
+    for (size_t i = 0; i < dataX.size(); ++i) {
+      TS_ASSERT_EQUALS(ws->x(0)[i], dataX[i]);
+    }
+    for (size_t i = 0; i < dataEYDx.size(); ++i) {
+      TS_ASSERT_EQUALS(ws->y(0)[i], dataEYDx[i]);
+      TS_ASSERT_EQUALS(ws->e(0)[i], dataEYDx[i]);
+      TS_ASSERT_EQUALS(ws->dx(0)[i], dataEYDx[i]);
+    }
+
+    // Remove the created workspace
+    TS_ASSERT_THROWS_NOTHING(
+        Mantid::API::AnalysisDataService::Instance().remove(
+            "test_CreateWorkspace"));
+  }
+
   void testCreateTextAxis() {
     std::vector<std::string> textAxis{"I've Got", "A Lovely", "Bunch Of",
                                       "Coconuts"};
@@ -157,11 +205,12 @@ public:
     alg.setProperty<int>("NSpec", 4);
 
     std::vector<double> values{1.0, 2.0, 3.0, 4.0};
+    std::vector<double> xVals{1.1, 2.2};
 
-    alg.setProperty<std::vector<double>>("DataX",
-                                         std::vector<double>{1.1, 2.2});
+    alg.setProperty<std::vector<double>>("DataX", xVals);
     alg.setProperty<std::vector<double>>("DataY", values);
     alg.setProperty<std::vector<double>>("DataE", values);
+    alg.setProperty<std::vector<double>>("Dx", xVals);
 
     TS_ASSERT_THROWS(alg.execute(), std::invalid_argument);
   }
@@ -302,6 +351,7 @@ public:
     creator.setProperty("DataX", *vec);
     creator.setProperty("DataY", *vec);
     creator.setProperty("DataE", *vec);
+    creator.setProperty("Dx", *vec);
     creator.setProperty("NSpec", 10000);
     TS_ASSERT(creator.execute());
   }
diff --git a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
index 419b32dd424a8296ab76140502f35116300e2a48..1203cd31423cc81381f875cad06a8bb3fe585d3d 100644
--- a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
+++ b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
@@ -113,8 +113,8 @@ private:
     using namespace Mantid::DataObjects;
 
     std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"1.0\" z=\"0\" /> ";
+    xmlShape += R"(<centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="1.0" z="0" /> )";
     xmlShape += "<radius val=\"0.0127\" /> ";
     xmlShape += "<height val=\"1\" /> ";
     xmlShape += "</cylinder>";
@@ -128,13 +128,13 @@ private:
     const int ndets(2);
     std::vector<Detector *> detectors;
     for (int i = 0; i < ndets; ++i) {
-      Detector *detector = new Detector("det", i + 1, shape, NULL);
+      Detector *detector = new Detector("det", i + 1, shape, nullptr);
       detector->setPos(i * 0.2, i * 0.2, 5);
       instrument->add(detector);
       instrument->markAsDetector(detector);
       detectors.push_back(detector);
     }
-    ObjComponent *sample = new ObjComponent("sample", shape, NULL);
+    ObjComponent *sample = new ObjComponent("sample", shape, nullptr);
     sample->setPos(0, 0, 0);
     instrument->markAsSamplePos(sample);
 
diff --git a/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h b/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h
index f91e385f02b7b81454bbfdcb26d5750c8f700674..cfeac3a09db0fcac766ec7fb03ed96b2c29d6b56 100644
--- a/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h
+++ b/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h
@@ -130,8 +130,8 @@ public:
       inputB->setBinEdges(j, x);
       std::vector<double> forInputA, forInputB;
       // the spectravalues will be multiples of the random numbers above
-      for (int l = 0; l < ySize; ++l) {
-        forInputA.push_back(yArray[l]);
+      for (double y : yArray) {
+        forInputA.push_back(y);
         // there is going to be a small difference between the workspaces that
         // will vary with histogram number
         forInputB.push_back(forInputA.back() *
diff --git a/Framework/Algorithms/test/DiffractionFocussing2Test.h b/Framework/Algorithms/test/DiffractionFocussing2Test.h
index c0a0e67a77556bb6bd9b94a5cf500e5d1d4dd43c..c22f2022a26acc70a81acc4121ba86ef0b2c3690 100644
--- a/Framework/Algorithms/test/DiffractionFocussing2Test.h
+++ b/Framework/Algorithms/test/DiffractionFocussing2Test.h
@@ -270,7 +270,7 @@ public:
     alg->execute();
     ws = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(
         "SNAP_empty");
-    ws->sortAll(TOF_SORT, NULL);
+    ws->sortAll(TOF_SORT, nullptr);
 
     // Fill a whole bunch of events
     PARALLEL_FOR_NO_WSP_CHECK()
diff --git a/Framework/Algorithms/test/ExtractMaskTest.h b/Framework/Algorithms/test/ExtractMaskTest.h
index e9803cf60e6c508e7227aaed47f558044a704f42..94d2c8503d51653c5e4398497cafaaeae39d1004 100644
--- a/Framework/Algorithms/test/ExtractMaskTest.h
+++ b/Framework/Algorithms/test/ExtractMaskTest.h
@@ -6,6 +6,7 @@
 #include "MantidAlgorithms/ExtractMask.h"
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
@@ -59,6 +60,67 @@ public:
     AnalysisDataService::Instance().remove(outputWS->getName());
   }
 
+  void test_That_Masked_Detector_List_Populated_When_Passed_A_Mask_Workspace() {
+    // Create a simple test workspace
+    const int nvectors(50), nbins(10);
+    Workspace2D_sptr inputWS =
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
+    // Mask every 10th spectra
+    std::set<int64_t> maskedIndices;
+    for (int i = 0; i < 50; i += 10) {
+      maskedIndices.insert(i);
+    }
+    // A few randoms
+    maskedIndices.insert(5);
+    maskedIndices.insert(23);
+    maskedIndices.insert(37);
+    inputWS = WorkspaceCreationHelper::maskSpectra(inputWS, maskedIndices);
+    const std::string inputName("inputWSMask");
+    AnalysisDataService::Instance().add(inputName, inputWS);
+    MaskWorkspace_sptr inputWSMask = runExtractMask(inputName);
+    std::vector<Mantid::detid_t> expectedDetectorList = {1,  6,  11, 21,
+                                                         24, 31, 38, 41};
+
+    std::vector<Mantid::detid_t> detectorList;
+
+    TS_ASSERT_THROWS_NOTHING(
+        detectorList = runExtractMaskReturnList(inputWSMask->getName()));
+    TS_ASSERT_EQUALS(detectorList, expectedDetectorList)
+
+    AnalysisDataService::Instance().remove(inputName);
+    AnalysisDataService::Instance().remove(inputWSMask->getName());
+  }
+
+  void test_That_Masked_Detector_List_Populated_When_Passed_A_Workspace() {
+    // Create a simple test workspace
+    const int nvectors(50), nbins(10);
+    Workspace2D_sptr inputWS =
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
+    // Mask every 10th spectra
+    std::set<int64_t> maskedIndices;
+    for (int i = 0; i < 50; i += 10) {
+      maskedIndices.insert(i);
+    }
+    // A few randoms
+    maskedIndices.insert(5);
+    maskedIndices.insert(23);
+    maskedIndices.insert(37);
+    inputWS = WorkspaceCreationHelper::maskSpectra(inputWS, maskedIndices);
+    const std::string inputName("inputWS");
+    AnalysisDataService::Instance().add(inputName, inputWS);
+
+    std::vector<Mantid::detid_t> expectedDetectorList = {1,  6,  11, 21,
+                                                         24, 31, 38, 41};
+
+    std::vector<Mantid::detid_t> detectorList;
+
+    TS_ASSERT_THROWS_NOTHING(detectorList =
+                                 runExtractMaskReturnList(inputName));
+    TS_ASSERT_EQUALS(detectorList, expectedDetectorList)
+
+    AnalysisDataService::Instance().remove(inputName);
+  }
+
 private:
   // The input workspace should be in the analysis data service
   MaskWorkspace_sptr runExtractMask(const std::string &inputName) {
@@ -82,6 +144,21 @@ private:
     }
   }
 
+  std::vector<Mantid::detid_t>
+  runExtractMaskReturnList(const std::string &inputName) {
+    ExtractMask maskExtractor;
+    maskExtractor.initialize();
+    maskExtractor.setPropertyValue("InputWorkspace", inputName);
+    const std::string outputName("masking");
+    maskExtractor.setPropertyValue("OutputWorkspace", outputName);
+    maskExtractor.setRethrows(true);
+    maskExtractor.execute();
+    std::vector<Mantid::detid_t> detectorList =
+        maskExtractor.getProperty("DetectorList");
+    AnalysisDataService::Instance().remove(outputName);
+    return detectorList;
+  }
+
   void doTest(MatrixWorkspace_const_sptr inputWS,
               MaskWorkspace_const_sptr outputWS) {
     TS_ASSERT_EQUALS(outputWS->blocksize(), 1);
diff --git a/Framework/Algorithms/test/FilterEventsTest.h b/Framework/Algorithms/test/FilterEventsTest.h
index 7cbc4ae3eccc68e16f5301496607a942a3149200..10c83e09c25e84558615562f78ad2b7547957cb3 100644
--- a/Framework/Algorithms/test/FilterEventsTest.h
+++ b/Framework/Algorithms/test/FilterEventsTest.h
@@ -254,8 +254,8 @@ public:
     AnalysisDataService::Instance().remove("Splitter02");
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -350,9 +350,9 @@ public:
     AnalysisDataService::Instance().remove("Splitter02");
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      std::cout << "Delete output workspace name: " << outputwsnames[i] << "\n";
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      std::cout << "Delete output workspace name: " << outputwsname << "\n";
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -435,8 +435,8 @@ public:
 
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -493,8 +493,8 @@ public:
     // Delete all the workspaces generated here
     AnalysisDataService::Instance().remove("MockDirectEventWS");
     AnalysisDataService::Instance().remove("SplitterTableX");
-    for (size_t i = 0; i < vecwsname.size(); ++i) {
-      AnalysisDataService::Instance().remove(vecwsname[i]);
+    for (const auto &workspaceName : vecwsname) {
+      AnalysisDataService::Instance().remove(workspaceName);
     }
 
     return;
@@ -544,8 +544,8 @@ public:
     AnalysisDataService::Instance().remove("SplitterTableX");
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -608,8 +608,8 @@ public:
     AnalysisDataService::Instance().remove("MockIndirectEventWS");
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -781,10 +781,10 @@ public:
     //  Test the sample logs
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
+    for (const auto &outputwsname : outputwsnames) {
       EventWorkspace_sptr filtered_ws =
           boost::dynamic_pointer_cast<DataObjects::EventWorkspace>(
-              AnalysisDataService::Instance().retrieve(outputwsnames[i]));
+              AnalysisDataService::Instance().retrieve(outputwsname));
 
       TS_ASSERT(filtered_ws->run().hasProperty("LogA"));
       TS_ASSERT(filtered_ws->run().hasProperty("LogB"));
@@ -805,8 +805,8 @@ public:
     // clean up all the workspaces generated
     AnalysisDataService::Instance().remove("Test10");
     AnalysisDataService::Instance().remove("Splitter10");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -977,8 +977,8 @@ public:
     AnalysisDataService::Instance().remove("TableSplitter1");
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -1033,10 +1033,10 @@ public:
 
     std::vector<std::string> outputwsnames =
         filter.getProperty("OutputWorkspaceNames");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
+    for (const auto &outputwsname : outputwsnames) {
       EventWorkspace_sptr childworkspace =
           boost::dynamic_pointer_cast<EventWorkspace>(
-              AnalysisDataService::Instance().retrieve(outputwsnames[i]));
+              AnalysisDataService::Instance().retrieve(outputwsname));
       TS_ASSERT(childworkspace);
       // there is 1 sample logs that is excluded from propagating to the child
       // workspaces. LogB is not TSP, so it won't be excluded even if it is
@@ -1051,8 +1051,8 @@ public:
     // clean workspaces
     AnalysisDataService::Instance().remove("Test12");
     AnalysisDataService::Instance().remove("TableSplitter2");
-    for (size_t i = 0; i < outputwsnames.size(); ++i) {
-      AnalysisDataService::Instance().remove(outputwsnames[i]);
+    for (const auto &outputwsname : outputwsnames) {
+      AnalysisDataService::Instance().remove(outputwsname);
     }
 
     return;
@@ -1587,8 +1587,7 @@ public:
     // 2. Add rows
     const auto &detectorInfo = inpws->detectorInfo();
     const auto detids = detectorInfo.detectorIDs();
-    for (size_t i = 0; i < detids.size(); ++i) {
-      int detid = detids[i];
+    for (int detid : detids) {
       double factor = 0.75;
       TableRow newrow = corrtable->appendRow();
       newrow << detid << factor;
diff --git a/Framework/Algorithms/test/FitPeaksTest.h b/Framework/Algorithms/test/FitPeaksTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..01f19f16c8c7b9e07923049dedfc7deb8bf7875d
--- /dev/null
+++ b/Framework/Algorithms/test/FitPeaksTest.h
@@ -0,0 +1,784 @@
+#ifndef MANTID_ALGORITHMS_FITPEAKSTEST_H_
+#define MANTID_ALGORITHMS_FITPEAKSTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/Axis.h"
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAlgorithms/FitPeaks.h"
+#include "MantidDataHandling/LoadNexusProcessed.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidKernel/UnitFactory.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
+using Mantid::Algorithms::FitPeaks;
+
+using namespace Mantid;
+using namespace Mantid::API;
+using namespace Mantid::Kernel;
+using namespace Mantid::DataObjects;
+
+using namespace std;
+
+using Mantid::HistogramData::Points;
+using Mantid::HistogramData::Counts;
+using Mantid::HistogramData::CountStandardDeviations;
+
+class FitPeaksTest : public CxxTest::TestSuite {
+private:
+  std::string m_inputWorkspaceName;
+
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static FitPeaksTest *createSuite() {
+    API::FrameworkManager::Instance();
+    return new FitPeaksTest();
+  }
+  static void destroySuite(FitPeaksTest *suite) { delete suite; }
+
+  void test_Init() {
+    // Generate input workspace
+    // m_inputWorkspaceName = loadVulcanHighAngleData();
+    m_inputWorkspaceName = "temp_workspace";
+    createTestData(m_inputWorkspaceName);
+
+    // Initialize FitPeak
+    FitPeaks fitpeaks;
+
+    fitpeaks.initialize();
+    TS_ASSERT(fitpeaks.isInitialized());
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /**
+   * @brief test_multiPeaksMultiSpectra
+   */
+  void test_multiPeaksMultiSpectra() {
+    // set up parameters with starting value
+    std::vector<string> peakparnames;
+    std::vector<double> peakparvalues;
+    createTestParameters(peakparnames, peakparvalues);
+
+    // initialize algorithm to test
+    FitPeaks fitpeaks;
+
+    fitpeaks.initialize();
+    TS_ASSERT(fitpeaks.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("InputWorkspace", m_inputWorkspaceName));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StartWorkspaceIndex", 0));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StopWorkspaceIndex", 2));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("PeakCenters", "5.0, 10.0"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("FitWindowBoundaryList", "2.5, 6.5, 8.0, 12.0"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("FitFromRight", true));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakParameterValues", peakparvalues));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("HighBackground", false));
+
+    fitpeaks.setProperty("OutputWorkspace", "PeakPositionsWS");
+    fitpeaks.setProperty("OutputPeakParametersWorkspace", "PeakParametersWS");
+    fitpeaks.setProperty("FittedPeaksWorkspace", "FittedPeaksWS");
+    fitpeaks.setProperty("ConstrainPeakPositions", false);
+
+    fitpeaks.execute();
+
+    // check result
+    TS_ASSERT(fitpeaks.isExecuted());
+    if (!fitpeaks.isExecuted())
+      return;
+
+    // get fitted peak data
+    API::MatrixWorkspace_sptr main_out_ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve("PeakPositionsWS"));
+    TS_ASSERT(main_out_ws);
+    TS_ASSERT_EQUALS(main_out_ws->getNumberHistograms(), 3);
+
+    API::MatrixWorkspace_sptr plot_ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve("FittedPeaksWS"));
+    TS_ASSERT(plot_ws);
+    TS_ASSERT_EQUALS(plot_ws->getNumberHistograms(), 3);
+
+    API::ITableWorkspace_sptr param_ws =
+        boost::dynamic_pointer_cast<API::ITableWorkspace>(
+            AnalysisDataService::Instance().retrieve("PeakParametersWS"));
+    TS_ASSERT(param_ws);
+    TS_ASSERT_EQUALS(param_ws->rowCount(), 6);
+
+    // check values: fitted peak positions
+    // spectrum 1
+    auto fitted_positions_0 = main_out_ws->histogram(0).y();
+    TS_ASSERT_EQUALS(fitted_positions_0.size(), 2); // with 2 peaks to fit
+    TS_ASSERT_DELTA(fitted_positions_0[0], 5.0, 1.E-6);
+    TS_ASSERT_DELTA(fitted_positions_0[1], 10.0, 1.E-6);
+    // spectrum 3
+    auto fitted_positions_2 = main_out_ws->histogram(2).y();
+    TS_ASSERT_EQUALS(fitted_positions_2.size(), 2); // with 2 peaks to fit
+    TS_ASSERT_DELTA(fitted_positions_2[0], 5.03, 1.E-6);
+    TS_ASSERT_DELTA(fitted_positions_2[1], 10.02, 1.E-6);
+
+    // check other fitted parameters including height and width
+    // spectrum 2
+    double ws1peak0_height = param_ws->cell<double>(2, 2);
+    double ws1peak0_width = param_ws->cell<double>(2, 4);
+    TS_ASSERT_DELTA(ws1peak0_height, 4., 1E-6);
+    TS_ASSERT_DELTA(ws1peak0_width, 0.17, 1E-6);
+
+    double ws1peak1_height = param_ws->cell<double>(3, 2);
+    double ws1peak1_width = param_ws->cell<double>(3, 4);
+    TS_ASSERT_DELTA(ws1peak1_height, 2., 1E-6);
+    TS_ASSERT_DELTA(ws1peak1_width, 0.12, 1E-6);
+
+    // check the fitted peak workspace
+    API::MatrixWorkspace_sptr data_ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            API::AnalysisDataService::Instance().retrieve(
+                m_inputWorkspaceName));
+    TS_ASSERT_EQUALS(plot_ws->histogram(0).x().size(),
+                     data_ws->histogram(0).x().size());
+    TS_ASSERT_DELTA(plot_ws->histogram(0).x().front(),
+                    data_ws->histogram(0).x().front(), 1E-10);
+    TS_ASSERT_DELTA(plot_ws->histogram(0).x().back(),
+                    data_ws->histogram(0).x().back(), 1E-10);
+
+    // clean up
+    AnalysisDataService::Instance().remove("PeakPositionsWS");
+    AnalysisDataService::Instance().remove("FittedPeaksWS");
+    AnalysisDataService::Instance().remove("PeakParametersWS");
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Test on single peak on partial spectra
+    */
+  void Ntest_singlePeakMultiSpectra() {
+    // Generate input workspace
+    // std::string input_ws_name = loadVulcanHighAngleData();
+
+    // Generate peak and background parameters
+    std::vector<string> peakparnames;
+    std::vector<double> peakparvalues;
+    gen_PeakParameters(peakparnames, peakparvalues);
+
+    // Initialize FitPeak
+    FitPeaks fitpeaks;
+
+    fitpeaks.initialize();
+    TS_ASSERT(fitpeaks.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("InputWorkspace", m_inputWorkspaceName));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("StartWorkspaceIndex", 19990));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StopWorkspaceIndex", 20000));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("PeakCenters", "1.0758"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("FitWindowLeftBoundary", "1.05"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("FitWindowRightBoundary", "1.15"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("PeakRanges", "0.02"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakParameterValues", peakparvalues));
+
+    fitpeaks.setProperty("OutputWorkspace", "PeakPositionsWS3");
+    fitpeaks.setProperty("OutputPeakParametersWorkspace", "PeakParametersWS3");
+    fitpeaks.setProperty("FittedPeaksWorkspace", "FittedPeaksWS3");
+
+    fitpeaks.execute();
+    TS_ASSERT(fitpeaks.isExecuted());
+
+    // check output workspaces
+    TS_ASSERT(
+        API::AnalysisDataService::Instance().doesExist("PeakPositionsWS3"));
+    TS_ASSERT(
+        API::AnalysisDataService::Instance().doesExist("PeakParametersWS3"));
+    TS_ASSERT(API::AnalysisDataService::Instance().doesExist("FittedPeaksWS3"));
+
+    // about the parameters
+    API::MatrixWorkspace_sptr peak_params_ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve("PeakParametersWS3"));
+    TS_ASSERT(peak_params_ws);
+    TS_ASSERT_EQUALS(peak_params_ws->getNumberHistograms(), 5);
+    TS_ASSERT_EQUALS(peak_params_ws->histogram(0).x().size(), 10);
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Test on init and setup
+    */
+  void Ntest_SingleSpectrum3Peaks() {
+    // Generate input workspace
+    // std::string input_ws_name = loadVulcanHighAngleData();
+
+    // Generate peak and background parameters
+    std::vector<string> peakparnames;
+    std::vector<double> peakparvalues;
+    gen_PeakParameters(peakparnames, peakparvalues);
+
+    // Initialize FitPeak
+    FitPeaks fitpeaks;
+
+    fitpeaks.initialize();
+    TS_ASSERT(fitpeaks.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("InputWorkspace", m_inputWorkspaceName));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StartWorkspaceIndex", 6468));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StopWorkspaceIndex", 24900));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakCenters", "1.0758, 0.89198"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("FitWindowLeftBoundary", "1.05, 0.87"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("FitWindowRightBoundary", "1.15, 0.92"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("PeakRanges", "0.02, 0.015"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakParameterValues", peakparvalues));
+
+    fitpeaks.setProperty("OutputWorkspace", "PeakPositionsWS2");
+    fitpeaks.setProperty("OutputPeakParametersWorkspace", "PeakParametersWS2");
+    fitpeaks.setProperty("FittedPeaksWorkspace", "FittedPeaksWS2");
+
+    fitpeaks.execute();
+    TS_ASSERT(fitpeaks.isExecuted());
+
+    TS_ASSERT(
+        API::AnalysisDataService::Instance().doesExist("PeakPositionsWS2"));
+
+    TS_ASSERT(API::AnalysisDataService::Instance().doesExist("FittedPeaksWS2"));
+    API::MatrixWorkspace_sptr fitted_data_ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            API::AnalysisDataService::Instance().retrieve("FittedPeaksWS2"));
+    TS_ASSERT(fitted_data_ws);
+
+    // API::MatrixWorkspace_const_sptr fitted_data_ws =
+    // fitpeaks.getProperty("FittedPeaksWS2");
+    TS_ASSERT_EQUALS(fitted_data_ws->getNumberHistograms(), 24900);
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Test a subset of spectra that do not have any count
+   * Thus, 2 main features of algorithm FitPeaks will be examed here
+   * 1. partial spectra
+   * 2. no signal with event count workspace
+   * @brief test_NoSignaleWorkspace2D
+   */
+  void test_NoSignaleWorkspace2D() {
+    // load file to workspace
+    std::string input_ws_name("PG3_733");
+
+    // Start by loading our NXS file
+    IAlgorithm *loader =
+        Mantid::API::FrameworkManager::Instance().createAlgorithm("LoadNexus");
+    loader->setPropertyValue("Filename", "PG3_733.nxs");
+    loader->setPropertyValue("OutputWorkspace", input_ws_name);
+    loader->execute();
+    TS_ASSERT(loader->isExecuted());
+
+    // create an EventNumberWorkspace
+    std::string event_number_ws_name("PG3_733_EventNumbers");
+    createEventNumberWorkspace(event_number_ws_name, 4, 3);
+
+    // Initialize FitPeak
+    FitPeaks fit_peaks_alg;
+
+    fit_peaks_alg.initialize();
+    TS_ASSERT(fit_peaks_alg.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fit_peaks_alg.setProperty("InputWorkspace", input_ws_name));
+
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty(
+        "PeakCenters", "0.5044,0.5191,0.5350,0.5526,0.5936,0.6178,0.6453,0."
+                       "6768,0.7134,0.7566,0.8089,0.8737,0.9571,1.0701,1.2356,"
+                       "1.5133,2.1401"));
+    TS_ASSERT_THROWS_NOTHING(
+        fit_peaks_alg.setProperty("StartWorkspaceIndex", 3));
+    TS_ASSERT_THROWS_NOTHING(
+        fit_peaks_alg.setProperty("StopWorkspaceIndex", 3));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty("FitFromRight", false));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty("HighBackground", true));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty(
+        "PeakWidthPercent", 0.016)); // typical powgen's
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty("EventNumberWorkspace",
+                                                       event_number_ws_name));
+
+    std::string peak_pos_ws_name("PG3_733_peak_positions");
+    std::string peak_param_ws_name("PG3_733_peak_params");
+    fit_peaks_alg.setProperty("OutputWorkspace", peak_pos_ws_name);
+    fit_peaks_alg.setProperty("OutputPeakParametersWorkspace",
+                              peak_param_ws_name);
+
+    fit_peaks_alg.execute();
+    TS_ASSERT(fit_peaks_alg.isExecuted());
+    if (!fit_peaks_alg.isExecuted())
+      return;
+
+    // get result
+    bool peak_pos_ws_exist, peak_param_ws_exist;
+    API::MatrixWorkspace_sptr peak_pos_ws =
+        CheckAndRetrieveMatrixWorkspace(peak_pos_ws_name, &peak_pos_ws_exist);
+    API::ITableWorkspace_sptr peak_param_ws = CheckAndRetrieveTableWorkspace(
+        peak_param_ws_name, &peak_param_ws_exist);
+
+    // fitted peak position workspace.  should contain 1 spectrum for workspace
+    // index 3
+    if (peak_pos_ws_exist) {
+      TS_ASSERT_EQUALS(peak_pos_ws->getNumberHistograms(), 1);
+      HistogramData::HistogramX hist_x = peak_pos_ws->histogram(0).x();
+      HistogramData::HistogramY hist_y = peak_pos_ws->histogram(0).y();
+      TS_ASSERT_EQUALS(hist_y.size(), 17);
+      TS_ASSERT_DELTA(hist_x[0], 0.5044, 1.E-12);
+      TS_ASSERT_DELTA(hist_y[0], -1., 1.E-12);
+    }
+
+    if (peak_param_ws_exist) {
+      TS_ASSERT_EQUALS(peak_param_ws->rowCount(), 17);
+    }
+
+    if (!peak_pos_ws_exist || !peak_param_ws_exist)
+      return;
+
+    // clean up
+    AnalysisDataService::Instance().remove("PG3_733");
+    AnalysisDataService::Instance().remove("PG3_733_EventNumbers");
+    AnalysisDataService::Instance().remove(peak_pos_ws_name);
+    AnalysisDataService::Instance().remove("PG3_733_peak_params");
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Test fit Gaussian peaks with high background
+   * @brief Later_test_HighBackgroundPeaks
+   */
+  void test_HighBackgroundPeaks() {
+    // load file to workspace
+    std::string input_ws_name("PG3_733");
+
+    // Start by loading our NXS file
+    IAlgorithm *loader =
+        Mantid::API::FrameworkManager::Instance().createAlgorithm("LoadNexus");
+    loader->setPropertyValue("Filename", "PG3_733.nxs");
+    loader->setPropertyValue("OutputWorkspace", input_ws_name);
+    loader->execute();
+    TS_ASSERT(loader->isExecuted());
+
+    // Initialize FitPeak
+    FitPeaks fit_peaks_alg;
+
+    fit_peaks_alg.initialize();
+    TS_ASSERT(fit_peaks_alg.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fit_peaks_alg.setProperty("InputWorkspace", input_ws_name));
+
+    TS_ASSERT_THROWS_NOTHING(
+        fit_peaks_alg.setProperty("BackgroundType", "Quadratic"));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty(
+        "PeakCenters", "0.6768,0.7134,0.7566,0.8089,0.8737,0.9571,1.0701,1."
+                       "2356, 1.5133, 2.1401"));
+    fit_peaks_alg.setProperty("StartWorkspaceIndex", 0);
+    fit_peaks_alg.setProperty("StopWorkspaceIndex", 3);
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty("FitFromRight", true));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty("HighBackground", true));
+    TS_ASSERT_THROWS_NOTHING(fit_peaks_alg.setProperty(
+        "PeakWidthPercent", 0.016)); // typical powgen's
+
+    std::string output_ws_name("PG3_733_stripped");
+    std::string peak_pos_ws_name("PG3_733_peak_positions");
+    std::string peak_param_ws_name("PG3_733_peak_params");
+    fit_peaks_alg.setProperty("OutputWorkspace", peak_pos_ws_name);
+    fit_peaks_alg.setProperty("OutputPeakParametersWorkspace",
+                              peak_param_ws_name);
+    fit_peaks_alg.setProperty("FittedPeaksWorkspace", output_ws_name);
+
+    fit_peaks_alg.execute();
+    TS_ASSERT(fit_peaks_alg.isExecuted());
+    if (!fit_peaks_alg.isExecuted())
+      return;
+
+    // Check result
+    bool peak_pos_ws_exist, peak_param_ws_exist, fitted_peak_ws_exist;
+    API::MatrixWorkspace_sptr peak_pos_ws =
+        CheckAndRetrieveMatrixWorkspace(peak_pos_ws_name, &peak_pos_ws_exist);
+    API::MatrixWorkspace_sptr fitted_peak_ws =
+        CheckAndRetrieveMatrixWorkspace(output_ws_name, &fitted_peak_ws_exist);
+    API::ITableWorkspace_sptr peak_param_ws = CheckAndRetrieveTableWorkspace(
+        peak_param_ws_name, &peak_param_ws_exist);
+
+    // check peak positions
+    if (peak_pos_ws_exist) {
+      TS_ASSERT_EQUALS(peak_pos_ws->getNumberHistograms(), 4);
+      TS_ASSERT_EQUALS(peak_pos_ws->histogram(0).size(), 10);
+      TS_ASSERT_DELTA(peak_pos_ws->histogram(0).y().back(), 2.1483553, 0.0005);
+    }
+
+    if (fitted_peak_ws_exist) {
+      TS_ASSERT_EQUALS(fitted_peak_ws->getNumberHistograms(), 4);
+    }
+
+    if (peak_param_ws_exist) {
+      TS_ASSERT_EQUALS(peak_param_ws->rowCount(), 40);
+      TS_ASSERT_EQUALS(peak_param_ws->columnCount(), 9);
+      TS_ASSERT_EQUALS(peak_param_ws->cell<int>(10, 0), 1);
+      TS_ASSERT_EQUALS(peak_param_ws->cell<int>(22, 1), 2);
+
+      // check first peak's height, center and sigma
+      TS_ASSERT_DELTA(peak_param_ws->cell<double>(9, 2), 414.48, 10.0);
+      TS_ASSERT_DELTA(peak_param_ws->cell<double>(9, 3), 2.14836, 0.0006);
+      TS_ASSERT_DELTA(peak_param_ws->cell<double>(9, 4), 0.005051, 0.0005);
+    }
+
+    // Clean up
+    AnalysisDataService::Instance().remove(input_ws_name);
+    AnalysisDataService::Instance().remove(output_ws_name);
+    AnalysisDataService::Instance().remove(peak_pos_ws_name);
+    AnalysisDataService::Instance().remove(peak_param_ws_name);
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Test on VULCAN's data including 2 different starting value of peak
+   * profiles
+    */
+  void test_multiple_peak_profiles() {
+    // Generate input workspace
+    std::string input_ws_name = loadVulcanHighAngleData();
+    API::MatrixWorkspace_sptr input_ws =
+        boost::dynamic_pointer_cast<MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve(input_ws_name));
+
+    // Generate peak and background parameters
+    std::vector<string> peakparnames;
+    std::vector<double> peakparvalues;
+    gen_PeakParameters(peakparnames, peakparvalues);
+
+    // Initialize FitPeak
+    FitPeaks fitpeaks;
+
+    fitpeaks.initialize();
+    TS_ASSERT(fitpeaks.isInitialized());
+
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("InputWorkspace", input_ws_name));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StartWorkspaceIndex", 0));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("StopWorkspaceIndex", 5));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakFunction", "BackToBackExponential"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("BackgroundType", "Linear"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty(
+        "PeakCenters", "0.6867, 0.728299, 0.89198, 1.0758"));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty(
+        "FitWindowBoundaryList",
+        "0.67, 0.709, 0.71, 0.76, 0.87, 0.92, 1.05, 1.15"));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakParameterNames", peakparnames));
+    TS_ASSERT_THROWS_NOTHING(
+        fitpeaks.setProperty("PeakParameterValues", peakparvalues));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("FitFromRight", true));
+    TS_ASSERT_THROWS_NOTHING(fitpeaks.setProperty("HighBackground", false));
+
+    fitpeaks.setProperty("OutputWorkspace", "PeakPositionsWS2");
+    fitpeaks.setProperty("OutputPeakParametersWorkspace", "PeakParametersWS2");
+    fitpeaks.setProperty("FittedPeaksWorkspace", "FittedPeaksWS2");
+
+    fitpeaks.execute();
+    TS_ASSERT(fitpeaks.isExecuted());
+
+    // Check outputs
+    bool peak_pos_ws_exist, peak_param_ws_exist, fitted_ws_exist;
+    API::MatrixWorkspace_sptr peak_pos_ws =
+        CheckAndRetrieveMatrixWorkspace("PeakPositionsWS2", &peak_pos_ws_exist);
+    API::MatrixWorkspace_sptr fitted_ws =
+        CheckAndRetrieveMatrixWorkspace("FittedPeaksWS2", &fitted_ws_exist);
+    API::ITableWorkspace_sptr peak_param_ws = CheckAndRetrieveTableWorkspace(
+        "PeakParametersWS2", &peak_param_ws_exist);
+
+    if (peak_pos_ws_exist) {
+      // workspace for peak positions from fitted value
+      TS_ASSERT_EQUALS(peak_pos_ws->getNumberHistograms(), 6);
+      HistogramData::HistogramY peak_pos_0 = peak_pos_ws->histogram(0).y();
+      HistogramData::HistogramE pos_error_0 = peak_pos_ws->histogram(0).e();
+      TS_ASSERT_DELTA(peak_pos_0[0], -4,
+                      0.0000001); // peak is out of data range
+      TS_ASSERT(pos_error_0[0] > 1E20);
+      TS_ASSERT(pos_error_0[3] < 100.);
+    }
+
+    if (fitted_ws_exist) {
+      // workspace for calculated peaks from fitted data
+      TS_ASSERT_EQUALS(fitted_ws->getNumberHistograms(),
+                       input_ws->getNumberHistograms());
+    }
+
+    if (peak_param_ws_exist) {
+      // workspace for calcualted peak parameters
+      TS_ASSERT_EQUALS(peak_param_ws->rowCount(), 4 * 6);
+      // check third spectrum
+      size_t iws = 2;
+      double peak_intensity_2_0 = peak_param_ws->cell<double>(iws * 4, 2);
+      TS_ASSERT_DELTA(peak_intensity_2_0, 0., 1.E-20);
+      // double peak_intensity_2_2 = peak_param_ws->cell<double>(iws * 4 + 2,
+      // 2);
+      // TS_ASSERT_DELTA(peak_intensity_2_2, 213.03, 0.03); // TODO re-enable
+      double peak_intensity_2_3 = peak_param_ws->cell<double>(iws * 4 + 3, 2);
+      TS_ASSERT_DELTA(peak_intensity_2_3, 1161.78, 4.0);
+    }
+
+    // clean
+    AnalysisDataService::Instance().remove(input_ws_name);
+    AnalysisDataService::Instance().remove("PeakPositionsWS2");
+    AnalysisDataService::Instance().remove("FittedPeaksWS2");
+    AnalysisDataService::Instance().remove("PeakParametersWS2");
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Generate peak parameters for Back-to-back exponential convoluted by
+   * Gaussian
+   * FitPeak(InputWorkspace='diamond_high_res_d', OutputWorkspace='peak0_19999',
+   * ParameterTableWorkspace='peak0_19999_Param', WorkspaceIndex=19999,
+   * PeakFunctionType='BackToBackExponential', PeakParameterNames='I,A,B,X0,S',
+   * PeakParameterValues='2.5e+06,5400,1700,1.07,0.000355',
+   * FittedPeakParameterValues='129.407,-1.82258e+06,-230935,1.06065,-0.0154214',
+   * BackgroundParameterNames='A0,A1', BackgroundParameterValues='0,0',
+   * FittedBackgroundParameterValues='3694.92,-3237.13', FitWindow='1.05,1.14',
+   * PeakRange='1.06,1.09',
+   * MinGuessedPeakWidth=10, MaxGuessedPeakWidth=20, GuessedPeakWidthStep=1,
+   * PeakPositionTolerance=0.02)
+    */
+  void gen_PeakParameters(vector<string> &parnames, vector<double> &parvalues) {
+    parnames.clear();
+    parvalues.clear();
+
+    parnames.emplace_back("I");
+    parvalues.push_back(2.5e+06);
+
+    parnames.emplace_back("A");
+    parvalues.push_back(5400);
+
+    parnames.emplace_back("B");
+    parvalues.push_back(1700);
+
+    parnames.emplace_back("X0");
+    parvalues.push_back(1.07);
+
+    parnames.emplace_back("S");
+    parvalues.push_back(0.000355);
+
+    return;
+  }
+
+  //--------------------------------------------------------------------------------------------------------------
+  /** create a multiple spectra workspace containing counts
+   * @brief createEventNumberWorkspace
+   * @param event_number_ws_name
+   * @param num_spec
+   * @param empty_ws_index
+   */
+  void createEventNumberWorkspace(const std::string &event_number_ws_name,
+                                  size_t num_spec, size_t empty_ws_index) {
+    // create a MatrixWorkspace
+    MatrixWorkspace_sptr matrix_ws =
+        WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
+            static_cast<int>(num_spec), 1);
+
+    // set spectrum without counts
+    matrix_ws->mutableY(empty_ws_index) = 0.;
+
+    // add to ADS
+    AnalysisDataService::Instance().addOrReplace(event_number_ws_name,
+                                                 matrix_ws);
+  }
+
+  //--------------------------------------------------------------------------------------------------------------
+  /** create basic testing data set containing some Gaussian peaks
+   * @brief createTestData
+   * @param workspacename
+   */
+  void createTestData(const std::string &workspacename) {
+    // ---- Create the simple workspace -------
+    size_t num_spec = 3;
+
+    MatrixWorkspace_sptr WS =
+        WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
+            static_cast<int>(num_spec), 300);
+    WS->getAxis(0)->unit() =
+        Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
+
+    // change the resolution of the binning
+    for (size_t i = 0; i < num_spec; ++i)
+      WS->mutableX(i) *= 0.05;
+
+    // spectrum 1 (ws=0)
+    const auto &xvals = WS->points(0);
+    std::transform(xvals.cbegin(), xvals.cend(), WS->mutableY(0).begin(),
+                   [](const double x) {
+                     return exp(-0.5 * pow((x - 10) / 0.1, 2)) +
+                            2.0 * exp(-0.5 * pow((x - 5) / 0.15, 2)) + 1.E-10;
+                   });
+    const auto &yvals = WS->histogram(0).y();
+    std::transform(yvals.cbegin(), yvals.cend(), WS->mutableE(0).begin(),
+                   [](const double y) { return sqrt(y); });
+
+    if (num_spec > 1) {
+      const auto &xvals1 = WS->points(1);
+      std::transform(xvals1.cbegin(), xvals1.cend(), WS->mutableY(1).begin(),
+                     [](const double x) {
+                       return 2. * exp(-0.5 * pow((x - 9.98) / 0.12, 2)) +
+                              4.0 * exp(-0.5 * pow((x - 5.01) / 0.17, 2));
+                     });
+      const auto &yvals1 = WS->histogram(1).y();
+      std::transform(yvals1.cbegin(), yvals1.cend(), WS->mutableE(1).begin(),
+                     [](const double y) { return sqrt(y); });
+    }
+
+    if (num_spec > 2) {
+      const auto &xvals2 = WS->points(2);
+      std::transform(xvals2.cbegin(), xvals2.cend(), WS->mutableY(2).begin(),
+                     [](const double x) {
+                       return 10 * exp(-0.5 * pow((x - 10.02) / 0.14, 2)) +
+                              3.0 * exp(-0.5 * pow((x - 5.03) / 0.19, 2));
+                     });
+      const auto &yvals2 = WS->histogram(2).y();
+      std::transform(yvals2.cbegin(), yvals2.cend(), WS->mutableE(2).begin(),
+                     [](const double y) { return sqrt(y); });
+    }
+
+    AnalysisDataService::Instance().addOrReplace(workspacename, WS);
+
+    //    auto vecx = WS->x(2);
+    //    auto vecy = WS->y(2);
+    //    for (size_t i = 0; i < vecx.size(); ++i)
+    //      std::cout << vecx[i] << "\t" << vecy[i] << "\n";
+
+    return;
+  }
+
+  void createTestParameters(vector<string> &parnames,
+                            vector<double> &parvalues) {
+    parnames.clear();
+    parvalues.clear();
+
+    parnames.emplace_back("I");
+    parvalues.push_back(2.5e+06);
+
+    parnames.emplace_back("S");
+    parvalues.push_back(0.1);
+
+    parnames.emplace_back("X0");
+    parvalues.push_back(10.0);
+
+    return;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Generate a workspace contains peaks with profile as back to back
+   * exponenential convoluted
+   * by Gaussian
+    */
+  std::string loadVulcanHighAngleData() {
+    DataHandling::LoadNexusProcessed loader;
+    loader.initialize();
+
+    loader.setProperty("Filename", "vulcan_diamond.nxs");
+    loader.setProperty("OutputWorkspace", "diamond_3peaks");
+
+    loader.execute();
+
+    TS_ASSERT(AnalysisDataService::Instance().doesExist("diamond_3peaks"));
+
+    API::MatrixWorkspace_sptr ws =
+        boost::dynamic_pointer_cast<API::MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve("diamond_3peaks"));
+    TS_ASSERT(ws);
+
+    return "diamond_3peaks";
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Check whether a workspace exists or not
+   * @brief CheckAndRetrieveMatrixWorkspace
+   * @param ws_name
+   * @param correct
+   * @return
+   */
+  API::MatrixWorkspace_sptr
+  CheckAndRetrieveMatrixWorkspace(const std::string &ws_name, bool *correct) {
+    // retrieve workspace
+    API::MatrixWorkspace_sptr workspace;
+    bool exist = AnalysisDataService::Instance().doesExist(ws_name);
+    TS_ASSERT(exist);
+    if (!exist) {
+      std::cout << "Workspace " << ws_name << " does not exist in ADS."
+                << "\n";
+      *correct = false;
+      return workspace;
+    }
+
+    // check workspace type
+    workspace = boost::dynamic_pointer_cast<MatrixWorkspace>(
+        AnalysisDataService::Instance().retrieve(ws_name));
+    TS_ASSERT(workspace);
+    if (!workspace) {
+      std::cout << "Workspace " << ws_name << " is not a MatrixWorkspace."
+                << "\n";
+      *correct = false;
+      return workspace;
+    }
+
+    *correct = true;
+    return workspace;
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Check whether a workspace exists or not
+   * @brief CheckAndRetrieveMatrixWorkspace
+   * @param ws_name
+   * @param correct
+   * @return
+   */
+  API::ITableWorkspace_sptr
+  CheckAndRetrieveTableWorkspace(const std::string &ws_name, bool *correct) {
+    // retrieve workspace
+    API::ITableWorkspace_sptr workspace;
+    bool exist = AnalysisDataService::Instance().doesExist(ws_name);
+    TS_ASSERT(exist);
+    if (!exist) {
+      std::cout << "Workspace " << ws_name << " does not exist in ADS."
+                << "\n";
+      *correct = false;
+      return workspace;
+    }
+
+    // check workspace type
+    workspace = boost::dynamic_pointer_cast<ITableWorkspace>(
+        AnalysisDataService::Instance().retrieve(ws_name));
+    TS_ASSERT(workspace);
+    if (!workspace) {
+      std::cout << "Workspace " << ws_name << " is not a TableWorkspace."
+                << "\n";
+      *correct = false;
+      return workspace;
+    }
+
+    *correct = true;
+    return workspace;
+  }
+};
+
+#endif /* MANTID_ALGORITHMS_FITPEAKSTEST_H_ */
diff --git a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
index 161da6b66676e8cdb6a629117882ae84222db436..cbd4cdfeb4ba454945b84f300eaac91d6cfb499c 100644
--- a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
+++ b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
@@ -65,7 +65,7 @@ public:
     create_test_workspace(workspaceName);
 
     std::string result[] = {
-        "{", "   \"metadata\" : {", "      \"name\" : \"Mantid Notebook\"",
+        "{", "   \"metadata\" : {", R"(      "name" : "Mantid Notebook")",
         "   },", "   \"nbformat\" : 3,", "   \"nbformat_minor\" : 0,",
         "   \"worksheets\" : [", "      {"};
 
@@ -156,7 +156,7 @@ public:
     history.addHistory(boost::make_shared<AlgorithmHistory>(
         API::AlgorithmHistory(pAlg.get())));
 
-    pAlg.reset(NULL);
+    pAlg.reset(nullptr);
   }
 };
 
diff --git a/Framework/Algorithms/test/GeneratePythonScriptTest.h b/Framework/Algorithms/test/GeneratePythonScriptTest.h
index 67ac94d0a325c0b133ba0c14d194724bd09ecf18..f88f2d1cfd42fed80f4a34f3767308c5c6f0f29d 100644
--- a/Framework/Algorithms/test/GeneratePythonScriptTest.h
+++ b/Framework/Algorithms/test/GeneratePythonScriptTest.h
@@ -159,7 +159,7 @@ public:
     history.addHistory(boost::make_shared<AlgorithmHistory>(
         API::AlgorithmHistory(pAlg.get())));
 
-    pAlg.reset(NULL);
+    pAlg.reset(nullptr);
   }
 };
 
diff --git a/Framework/Algorithms/test/GroupWorkspacesTest.h b/Framework/Algorithms/test/GroupWorkspacesTest.h
index 0b9fa7e31c0bb1bba51c9b562e415d4be0c32ae7..bc183339d67f933d2927f0be610fe640d5c4932d 100644
--- a/Framework/Algorithms/test/GroupWorkspacesTest.h
+++ b/Framework/Algorithms/test/GroupWorkspacesTest.h
@@ -196,8 +196,8 @@ public:
 
 private:
   void addTestMatrixWorkspacesToADS(const std::vector<std::string> &inputs) {
-    for (auto it = inputs.begin(); it != inputs.end(); ++it) {
-      addTestMatrixWorkspaceToADS(*it);
+    for (const auto &input : inputs) {
+      addTestMatrixWorkspaceToADS(input);
     }
   }
 
@@ -258,9 +258,9 @@ private:
                      const std::vector<std::string> &members) {
     auto &ads = Mantid::API::AnalysisDataService::Instance();
 
-    for (auto it = members.begin(); it != members.end(); ++it) {
-      if (ads.doesExist(*it))
-        ads.remove(*it);
+    for (const auto &member : members) {
+      if (ads.doesExist(member))
+        ads.remove(member);
     }
     if (ads.doesExist(groupName))
       ads.remove(groupName);
diff --git a/Framework/Algorithms/test/LorentzCorrectionTest.h b/Framework/Algorithms/test/LorentzCorrectionTest.h
index 0190630e7c05d0fe7a15421d4a327132ad0fe7af..99cdf9c705039ad5dddcaccbdf7bc53e17d2c979 100644
--- a/Framework/Algorithms/test/LorentzCorrectionTest.h
+++ b/Framework/Algorithms/test/LorentzCorrectionTest.h
@@ -126,7 +126,7 @@ public:
     alg.setPropertyValue("OutputWorkspace", "temp");
     alg.execute();
     MatrixWorkspace_sptr out_ws = alg.getProperty("OutputWorkspace");
-    TS_ASSERT(out_ws != NULL);
+    TS_ASSERT(out_ws != nullptr);
 
     const std::string unitID = out_ws->getAxis(0)->unit()->unitID();
     TS_ASSERT_EQUALS(unitID, "Wavelength");
diff --git a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
index 6a8da3947062320d8ffa54aeaf6b62fa14f84655..2c87197dfa9390e08183f1b4e76b43de84af6dd0 100644
--- a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
+++ b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
@@ -7,7 +7,6 @@
 #include "MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
-#include "MantidKernel/MersenneTwister.h"
 #include "MantidKernel/WarningSuppressions.h"
 #include "MonteCarloTesting.h"
 
@@ -76,8 +75,8 @@ public:
     const size_t nevents(10), maxTries(1);
     MCAbsorptionStrategy mcabs(testBeamProfile, testThinAnnulus, nevents,
                                maxTries);
-    MersenneTwister rng;
-    rng.setSeed(1);
+    MockRNG rng;
+    EXPECT_CALL(rng, nextValue()).WillRepeatedly(Return(0.5));
     const double lambdaBefore(2.5), lambdaAfter(3.5);
     const V3D endPos(0.7, 0.7, 1.4);
     TS_ASSERT_THROWS(mcabs.calculate(rng, endPos, lambdaBefore, lambdaAfter),
diff --git a/Framework/Algorithms/test/MaskBinsFromTableTest.h b/Framework/Algorithms/test/MaskBinsFromTableTest.h
index 4bf775b5486cac562a74b0afba2b242adb15c7ee..210d8061e634876534f5172d16e54010148feb00 100644
--- a/Framework/Algorithms/test/MaskBinsFromTableTest.h
+++ b/Framework/Algorithms/test/MaskBinsFromTableTest.h
@@ -183,8 +183,8 @@ public:
     speclist.push_back(6);
     speclist.push_back(7);
     speclist.push_back(8);
-    for (size_t iws = 0; iws < speclist.size(); ++iws) {
-      auto &yvec = WS->y(speclist[iws]);
+    for (int spectrum : speclist) {
+      auto &yvec = WS->y(spectrum);
       for (size_t bin = 0; bin < yvec.size(); ++bin) {
         if (bin >= 4 && bin < 7) {
           TS_ASSERT_EQUALS(yvec[bin], 0.0);
diff --git a/Framework/Algorithms/test/MayersSampleCorrectionStrategyTest.h b/Framework/Algorithms/test/MayersSampleCorrectionStrategyTest.h
index 08f4eb68aeb35070b981d8517128440baa759339..2c2216e12d4c7c2f266f9673e8c60fe6b511e5a0 100644
--- a/Framework/Algorithms/test/MayersSampleCorrectionStrategyTest.h
+++ b/Framework/Algorithms/test/MayersSampleCorrectionStrategyTest.h
@@ -54,9 +54,9 @@ public:
     const double muR(0.01), abs(0.0003);
     auto absFactor = mscat.calculateMS(irp, muR, abs);
 
-    const double delta = 1e-8;
-    TS_ASSERT_DELTA(0.00461391, absFactor.first, delta);
-    TS_ASSERT_DELTA(67.25351289, absFactor.second, delta);
+    const double delta = 1e-6;
+    TS_ASSERT_DELTA(0.004671, absFactor.first, delta);
+    TS_ASSERT_DELTA(29.258163, absFactor.second, delta);
   }
 
   void test_Corrects_Both_Absorption_And_Multiple_Scattering_For_Point_Data() {
@@ -75,11 +75,11 @@ public:
     TS_ASSERT_DELTA(100.0, tof.front(), delta);
     TS_ASSERT_DELTA(199.0, tof.back(), delta);
 
-    TS_ASSERT_DELTA(0.37497317, signal.front(), delta);
-    TS_ASSERT_DELTA(0.37629282, signal.back(), delta);
+    TS_ASSERT_DELTA(0.375086, signal.front(), delta);
+    TS_ASSERT_DELTA(0.377762, signal.back(), delta);
 
-    TS_ASSERT_DELTA(0.26514607, error.front(), delta);
-    TS_ASSERT_DELTA(0.2660792, error.back(), delta);
+    TS_ASSERT_DELTA(0.265226, error.front(), delta);
+    TS_ASSERT_DELTA(0.267118, error.back(), delta);
   }
 
   void
@@ -99,11 +99,11 @@ public:
     TS_ASSERT_DELTA(99.5, tof.front(), delta);
     TS_ASSERT_DELTA(199.5, tof.back(), delta);
 
-    TS_ASSERT_DELTA(0.37497317, signal.front(), delta);
-    TS_ASSERT_DELTA(0.37629282, signal.back(), delta);
+    TS_ASSERT_DELTA(0.375086, signal.front(), delta);
+    TS_ASSERT_DELTA(0.377762, signal.back(), delta);
 
-    TS_ASSERT_DELTA(0.26514607, error.front(), delta);
-    TS_ASSERT_DELTA(0.2660792, error.back(), delta);
+    TS_ASSERT_DELTA(0.265226, error.front(), delta);
+    TS_ASSERT_DELTA(0.267118, error.back(), delta);
   }
 
   void test_Corrects_For_Absorption_For_Histogram_Data() {
@@ -151,11 +151,11 @@ public:
     TS_ASSERT_DELTA(99.5, tof.front(), delta);
     TS_ASSERT_DELTA(199.5, tof.back(), delta);
 
-    TS_ASSERT_DELTA(0.37553636, signal.front(), delta);
-    TS_ASSERT_DELTA(0.37554482, signal.back(), delta);
+    TS_ASSERT_DELTA(0.374857, signal.front(), delta);
+    TS_ASSERT_DELTA(0.377747, signal.back(), delta);
 
-    TS_ASSERT_DELTA(0.26554431, error.front(), delta);
-    TS_ASSERT_DELTA(0.26555029, error.back(), delta);
+    TS_ASSERT_DELTA(0.265064, error.front(), delta);
+    TS_ASSERT_DELTA(0.267107, error.back(), delta);
   }
 
   void test_MutlipleScattering_NRuns_Parameter() {
@@ -178,11 +178,11 @@ public:
     TS_ASSERT_DELTA(99.5, tof.front(), delta);
     TS_ASSERT_DELTA(199.5, tof.back(), delta);
 
-    TS_ASSERT_DELTA(0.37376334, signal.front(), delta);
-    TS_ASSERT_DELTA(0.37123648, signal.back(), delta);
+    TS_ASSERT_DELTA(0.375848, signal.front(), delta);
+    TS_ASSERT_DELTA(0.386508, signal.back(), delta);
 
-    TS_ASSERT_DELTA(0.26429059, error.front(), delta);
-    TS_ASSERT_DELTA(0.26250383, error.back(), delta);
+    TS_ASSERT_DELTA(0.265765, error.front(), delta);
+    TS_ASSERT_DELTA(0.273302, error.back(), delta);
   }
 
   // ---------------------- Failure tests -----------------------------
@@ -211,7 +211,7 @@ private:
     pars.sigmaAbs = 5.08;
     pars.cylRadius = 0.0025;
     pars.cylHeight = 0.04;
-    pars.msNEvents = 10000;
+    pars.msNEvents = 500;
     pars.msNRuns = 10;
     return pars;
   }
diff --git a/Framework/Algorithms/test/MayersSampleCorrectionTest.h b/Framework/Algorithms/test/MayersSampleCorrectionTest.h
index afe1d9e66bad182de662fb0634f3083b0734ec07..42131f160f4480b30c087455fb6e7fc79bb3480a 100644
--- a/Framework/Algorithms/test/MayersSampleCorrectionTest.h
+++ b/Framework/Algorithms/test/MayersSampleCorrectionTest.h
@@ -41,11 +41,11 @@ public:
     TS_ASSERT_DELTA(99.5, tof.front(), delta);
     TS_ASSERT_DELTA(199.5, tof.back(), delta);
 
-    TS_ASSERT_DELTA(0.37666067, signal.front(), delta);
-    TS_ASSERT_DELTA(0.37553044, signal.back(), delta);
+    TS_ASSERT_DELTA(0.374435, signal.front(), delta);
+    TS_ASSERT_DELTA(0.377909, signal.back(), delta);
 
-    TS_ASSERT_DELTA(0.26633931, error.front(), delta);
-    TS_ASSERT_DELTA(0.26554012, error.back(), delta);
+    TS_ASSERT_DELTA(0.264766, error.front(), delta);
+    TS_ASSERT_DELTA(0.267222, error.back(), delta);
   }
 
   void test_Success_With_Just_Absorption_Correction() {
diff --git a/Framework/Algorithms/test/MedianDetectorTestTest.h b/Framework/Algorithms/test/MedianDetectorTestTest.h
index cfccc53ddd12d811965a103858a8b10aa712c32b..81be253a63a2a3a69deb98cf98b539caa60e7436 100644
--- a/Framework/Algorithms/test/MedianDetectorTestTest.h
+++ b/Framework/Algorithms/test/MedianDetectorTestTest.h
@@ -180,8 +180,8 @@ public:
                                      1,   0, 15, 4,     0, 0.001, 2e-10,
                                      0,   8, 0,  1e-4,  1, 7,     11};
     m_YSum = 0;
-    for (int i = 0; i < specLength - 1; i++) {
-      m_YSum += yArray[i];
+    for (double i : yArray) {
+      m_YSum += i;
     }
 
     // most error values will be small so that they wont affect the tests
diff --git a/Framework/Algorithms/test/MergeRunsTest.h b/Framework/Algorithms/test/MergeRunsTest.h
index 24f962ba1f78cea7ae95093099842a213459671d..a895e35e8d63a90189ea519d0595e90f03181e12 100644
--- a/Framework/Algorithms/test/MergeRunsTest.h
+++ b/Framework/Algorithms/test/MergeRunsTest.h
@@ -3,25 +3,21 @@
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cxxtest/TestSuite.h>
-#include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <stdarg.h>
 
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidAPI/SpectrumInfo.h"
-#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAlgorithms/GroupWorkspaces.h"
 #include "MantidAlgorithms/MergeRuns.h"
-#include "MantidAlgorithms/GroupWorkspaces.h"
 #include "MantidAlgorithms/Rebin.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include <boost/make_shared.hpp>
 #include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
 #include <MantidAlgorithms/RunCombinationHelpers/RunCombinationHelper.h>
 #include <MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h>
 #include "MantidTypes/SpectrumDefinition.h"
@@ -281,7 +277,7 @@ private:
     TS_ASSERT_THROWS_NOTHING(alg.execute());
     MatrixWorkspace_sptr wsOut = Mantid::API::AnalysisDataService::Instance()
                                      .retrieveWS<MatrixWorkspace>("out");
-    TS_ASSERT(wsOut != NULL);
+    TS_ASSERT(wsOut != nullptr);
     for (size_t j = 0; j < wsOut->getNumberHistograms(); ++j) {
       using Mantid::MantidVec;
       auto &xValues = wsOut->x(j);
@@ -305,17 +301,17 @@ public:
 
   MergeRunsTest() {
     AnalysisDataService::Instance().add(
-        "in1", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1));
+        "in1", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1.));
     AnalysisDataService::Instance().add(
-        "in2", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1));
+        "in2", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1.));
     AnalysisDataService::Instance().add(
-        "in3", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1));
+        "in3", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 1.));
     AnalysisDataService::Instance().add(
-        "in4", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 5, 20));
+        "in4", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 5, 20.));
     AnalysisDataService::Instance().add(
-        "in5", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 5, 3.5, 2));
+        "in5", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 5, 3.5, 2.));
     AnalysisDataService::Instance().add(
-        "in6", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 3, 2, 2));
+        "in6", WorkspaceCreationHelper::create2DWorkspaceBinned(3, 3, 2., 2.));
   }
 
   void checkOutput(std::string wsname) {
@@ -930,13 +926,13 @@ public:
     WorkspaceGroup_sptr wsgroup =
         Mantid::API::AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
             "outer");
-    TS_ASSERT(wsgroup != NULL);
+    TS_ASSERT(wsgroup != nullptr);
     TS_ASSERT_EQUALS(input->size(), wsgroup->size());
     // Loop through each workspace in the group
     for (size_t i = 0; i < wsgroup->size(); ++i) {
       MatrixWorkspace_sptr ws =
           boost::dynamic_pointer_cast<MatrixWorkspace>(wsgroup->getItem(i));
-      TS_ASSERT(ws != NULL);
+      TS_ASSERT(ws != nullptr);
       TS_ASSERT_EQUALS(expectedNumHistograms, ws->getNumberHistograms());
       // Loop through each histogram in each workspace
       for (size_t j = 0; j < ws->getNumberHistograms(); ++j) {
diff --git a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
index aa0072b8dc41698136a550525b463a3a1f9a223f..1c56a75997740c67fc1f64b5af67f436b1daa585 100644
--- a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
+++ b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
@@ -112,15 +112,15 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0074366635, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.00014222815, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(1.64562e-05, outputWS->y(0).back(), delta);
-    TS_ASSERT_DELTA(0.0073977126, outputWS->y(2).front(), delta);
-    TS_ASSERT_DELTA(0.0001373456, outputWS->y(2)[middle_index], delta);
-    TS_ASSERT_DELTA(1.3673737e-05, outputWS->y(2).back(), delta);
-    TS_ASSERT_DELTA(0.0074180214, outputWS->y(4).front(), delta);
-    TS_ASSERT_DELTA(0.00013650999, outputWS->y(4)[middle_index], delta);
-    TS_ASSERT_DELTA(1.2496885e-05, outputWS->y(4).back(), delta);
+    TS_ASSERT_DELTA(0.006335, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000092, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000029, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.006265, outputWS->y(2).front(), delta);
+    TS_ASSERT_DELTA(0.000137, outputWS->y(2)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000031, outputWS->y(2).back(), delta);
+    TS_ASSERT_DELTA(0.006294, outputWS->y(4).front(), delta);
+    TS_ASSERT_DELTA(0.000230, outputWS->y(4)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000035, outputWS->y(4).back(), delta);
   }
 
   void test_Workspace_With_Just_Sample_For_Direct() {
@@ -133,9 +133,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0032600806, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.00040160571, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.00027626768, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.002188, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000131, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000276, outputWS->y(0).back(), delta);
   }
 
   void test_Workspace_With_Just_Sample_For_Indirect() {
@@ -148,9 +148,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0014451101, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(9.4166161e-05, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(4.0118175e-05, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.001107, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000023, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000051, outputWS->y(0).back(), delta);
   }
 
   void test_Workspace_With_Sample_And_Container() {
@@ -163,9 +163,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0035900048, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(4.5651813e-05, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(1.2391338e-06, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.003521, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000225, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000018, outputWS->y(0).back(), delta);
   }
 
   void test_Workspace_Beam_Size_Set() {
@@ -177,10 +177,10 @@ public:
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
     const size_t middle_index(4);
-    TS_ASSERT_DELTA(0.004365258, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(9.8703289e-05, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.002546, outputWS->y(0).front(), delta);
     const double delta2(1e-08);
-    TS_ASSERT_DELTA(1.7373459e-08, outputWS->y(0).back(), delta2);
+    TS_ASSERT_DELTA(0.0000005359, outputWS->y(0)[middle_index], delta2);
+    TS_ASSERT_DELTA(0.0000046103, outputWS->y(0).back(), delta2);
   }
 
   void test_Linear_Interpolation() {
@@ -193,10 +193,10 @@ public:
 
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
-    TS_ASSERT_DELTA(0.0074366635, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.00041446262, outputWS->y(0)[3], delta);
-    TS_ASSERT_DELTA(0.00048307523, outputWS->y(0)[4], delta);
-    TS_ASSERT_DELTA(2.8600668e-05, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.006335, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000432, outputWS->y(0)[3], delta);
+    TS_ASSERT_DELTA(0.000321, outputWS->y(0)[4], delta);
+    TS_ASSERT_DELTA(0.000438, outputWS->y(0).back(), delta);
   }
 
   void test_CSpline_Interpolation() {
@@ -209,11 +209,11 @@ public:
 
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
-    TS_ASSERT_DELTA(0.0074366635, outputWS->y(0).front(), delta);
-    // Interpolation gives negative value due to test setup
-    TS_ASSERT_DELTA(-7.0992356e-05, outputWS->y(0)[3], delta);
-    TS_ASSERT_DELTA(0.00048307523, outputWS->y(0)[4], delta);
-    TS_ASSERT_DELTA(2.8600668e-05, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.006335, outputWS->y(0).front(), delta);
+    // Interpolation gives some negative value due to test setup
+    TS_ASSERT_DELTA(0.000016, outputWS->y(0)[3], delta);
+    TS_ASSERT_DELTA(0.000321, outputWS->y(0)[4], delta);
+    TS_ASSERT_DELTA(0.000438, outputWS->y(0).back(), delta);
   }
 
   //---------------------------------------------------------------------------
@@ -278,14 +278,14 @@ public:
     verifyDimensions(wsProps, outputWS);
     const double delta{1e-04};
     const size_t middle_index{4};
-    TS_ASSERT_DELTA(0.00411903, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(3.11845e-05, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.003861, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000062, outputWS->y(0)[middle_index], delta);
     TS_ASSERT_DELTA(3.8547e-07, outputWS->y(0).back(), delta);
-    TS_ASSERT_DELTA(0.00408066, outputWS->y(2).front(), delta);
+    TS_ASSERT_DELTA(0.003804, outputWS->y(2).front(), delta);
     TS_ASSERT_DELTA(3.30326e-05, outputWS->y(2)[middle_index], delta);
     TS_ASSERT_DELTA(3.84174e-07, outputWS->y(2).back(), delta);
-    TS_ASSERT_DELTA(0.00408664, outputWS->y(4).front(), delta);
-    TS_ASSERT_DELTA(3.67267e-05, outputWS->y(4)[middle_index], delta);
+    TS_ASSERT_DELTA(0.003797, outputWS->y(4).front(), delta);
+    TS_ASSERT_DELTA(0.000174, outputWS->y(4)[middle_index], delta);
     TS_ASSERT_DELTA(4.21291e-07, outputWS->y(4).back(), delta);
   }
 
@@ -299,9 +299,10 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.00134398, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(6.37626e-05, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(6.97537e-05, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.001065, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000137, outputWS->y(0)[middle_index], delta);
+    const double delta2(1e-08);
+    TS_ASSERT_DELTA(0.00000167, outputWS->y(0).back(), delta2);
   }
 
   void test_Sparse_Instrument_For_Indirect() {
@@ -314,8 +315,8 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.000333585, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(9.85491e-06, outputWS->y(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.000606, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(0.000022, outputWS->y(0)[middle_index], delta);
     TS_ASSERT_DELTA(9.16794e-07, outputWS->y(0).back(), delta);
   }
 
diff --git a/Framework/Algorithms/test/NormaliseByDetectorTest.h b/Framework/Algorithms/test/NormaliseByDetectorTest.h
index a66f14d5b4a18204ea4f7b7cab353e68f1725c9c..63aa2b3f5a85ddd8827a06e5a08217caeeb3dd2b 100644
--- a/Framework/Algorithms/test/NormaliseByDetectorTest.h
+++ b/Framework/Algorithms/test/NormaliseByDetectorTest.h
@@ -51,7 +51,7 @@ do_test_doesnt_throw_on_execution(MatrixWorkspace_sptr inputWS,
   TS_ASSERT_THROWS_NOTHING(alg.execute());
   MatrixWorkspace_sptr outWS =
       AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("out");
-  TS_ASSERT(outWS != NULL);
+  TS_ASSERT(outWS != nullptr);
   return outWS;
 }
 
@@ -225,7 +225,7 @@ private:
   create_workspace_with_incomplete_detector_level_only_fit_functions(
       MatrixWorkspace_sptr original = boost::shared_ptr<MatrixWorkspace>()) {
     MatrixWorkspace_sptr ws = original;
-    if (original == NULL) {
+    if (original == nullptr) {
       // Create a default workspace with no-fitting functions.
       ws = create_workspace_with_no_fitting_functions();
     }
@@ -649,7 +649,7 @@ public:
 private:
   /// Helper method to run common sanity checks.
   void do_basic_checks(MatrixWorkspace_sptr normalisedWS) {
-    TS_ASSERT(normalisedWS != NULL);
+    TS_ASSERT(normalisedWS != nullptr);
     TS_ASSERT(ws->getNumberHistograms() == normalisedWS->getNumberHistograms());
     TS_ASSERT(ws->x(0).size() == normalisedWS->x(0).size());
     TS_ASSERT(ws->y(0).size() == normalisedWS->y(0).size());
diff --git a/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h b/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h
index 95d3c0843918c79bfa2b9af915b4fa2bdaa977e0..4da29ea57d10eef0a8d385d97c70a43b61823984 100644
--- a/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h
+++ b/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h
@@ -213,8 +213,8 @@ public:
 
     const std::vector<Property *> &expectedProps = expected->getProperties();
 
-    for (std::size_t i = 0; i < expectedProps.size(); ++i) {
-      const std::string name = expectedProps[i]->name();
+    for (auto expectedProp : expectedProps) {
+      const std::string name = expectedProp->name();
       TS_ASSERT_EQUALS(expected->getPropertyValue(name),
                        observed->getPropertyValue(name));
     }
diff --git a/Framework/Algorithms/test/RebinByPulseTimesTest.h b/Framework/Algorithms/test/RebinByPulseTimesTest.h
index 63095f03137da0e520441cc185592ddc947f7a7c..fe6bfb4b78f74b5d8c8fbc809a22c681d505e2ed 100644
--- a/Framework/Algorithms/test/RebinByPulseTimesTest.h
+++ b/Framework/Algorithms/test/RebinByPulseTimesTest.h
@@ -10,7 +10,7 @@ using Mantid::Algorithms::RebinByPulseTimes;
 //=====================================================================================
 // Functional Tests
 //=====================================================================================
-typedef RebinByTimeBaseTest<RebinByPulseTimes> Super;
+using Super = RebinByTimeBaseTest<RebinByPulseTimes>;
 class RebinByPulseTimesTest : public CxxTest::TestSuite, public Super {
 
 public:
diff --git a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h
index 6529dd117106debb785a3e2e8a09fb3798cf70da..481148a9648f1aa808b7bb9efa99b95745d65dd0 100644
--- a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h
+++ b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h
@@ -31,8 +31,7 @@ createSinglePulseEventWorkspace(const V3D &sourcePosition,
 
   // Make fake events
   for (size_t pix = 0; pix < numberspectra; pix++) {
-    for (size_t i = 0; i < allSpectraTOF.size(); i++) {
-      const double tof = allSpectraTOF[i];
+    for (double tof : allSpectraTOF) {
       uint64_t pulseTime(0); // Pulse time is always zero. Same pulse.
       retVal->getSpectrum(pix) += TofEvent(tof, pulseTime);
     }
@@ -55,7 +54,7 @@ createSinglePulseEventWorkspace(const V3D &sourcePosition,
 //=====================================================================================
 // Functional Tests
 //=====================================================================================
-typedef RebinByTimeBaseTest<RebinByTimeAtSample> Super;
+using Super = RebinByTimeBaseTest<RebinByTimeAtSample>;
 class RebinByTimeAtSampleTest : public CxxTest::TestSuite, public Super {
 
 public:
diff --git a/Framework/Algorithms/test/RebinByTimeBaseTest.h b/Framework/Algorithms/test/RebinByTimeBaseTest.h
index c9b8d5f17bede6330ef6ccd952d3aa4421dd7b19..1f3f4ab0f1fd93c9a9654f592d14e13373e83f43 100644
--- a/Framework/Algorithms/test/RebinByTimeBaseTest.h
+++ b/Framework/Algorithms/test/RebinByTimeBaseTest.h
@@ -526,7 +526,7 @@ public:
     // Simple tests. Functionality tests cover this much better.
     MatrixWorkspace_sptr outWS =
         AnalysisDataService::Instance().retrieveWS<Workspace2D>("outWS");
-    TS_ASSERT(outWS != NULL);
+    TS_ASSERT(outWS != nullptr);
   }
 };
 
diff --git a/Framework/Algorithms/test/RebinTest.h b/Framework/Algorithms/test/RebinTest.h
index 00ea719f4815fea3275828127e1670443f765c05..17cb8232c6161526c2efd9f1c478b468f8b66551 100644
--- a/Framework/Algorithms/test/RebinTest.h
+++ b/Framework/Algorithms/test/RebinTest.h
@@ -424,9 +424,8 @@ public:
 
     // turn the mask list into an array like the Y values
     MantidVec weights(outY.size(), 0);
-    for (MatrixWorkspace::MaskList::const_iterator it = mask.begin();
-         it != mask.end(); ++it) {
-      weights[it->first] = it->second;
+    for (auto it : mask) {
+      weights[it.first] = it.second;
     }
 
     // the degree of masking must be the same as the reduction in the y-value,
@@ -484,9 +483,8 @@ public:
 
     // turn the mask list into an array like the Y values
     MantidVec weights(outY.size(), 0);
-    for (MatrixWorkspace::MaskList::const_iterator it = mask.begin();
-         it != mask.end(); ++it) {
-      weights[it->first] = it->second;
+    for (auto it : mask) {
+      weights[it.first] = it.second;
     }
 
     // the degree of masking must be the same as the reduction in the y-value,
diff --git a/Framework/Algorithms/test/ReflectometryMomentumTransferTest.h b/Framework/Algorithms/test/ReflectometryMomentumTransferTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e0d090613f05d0c9ebdd26a6d1914571d7c8e16
--- /dev/null
+++ b/Framework/Algorithms/test/ReflectometryMomentumTransferTest.h
@@ -0,0 +1,580 @@
+#ifndef MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFERTEST_H_
+#define MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFERTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/ReflectometryMomentumTransfer.h"
+
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/Axis.h"
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidKernel/Unit.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
+#include <boost/math/special_functions/pow.hpp>
+
+using namespace Mantid;
+
+namespace {
+constexpr double CHOPPER_GAP{0.23};
+constexpr double CHOPPER_OPENING_ANGLE{33.}; // degrees
+constexpr double CHOPPER_RADIUS{0.3};
+constexpr double CHOPPER_SPEED{990.};
+constexpr double DET_DIST{4.};
+constexpr double DET_RESOLUTION{0.002};
+constexpr double L1{8.};
+constexpr double PIXEL_SIZE{0.0015};
+// h / NeutronMass
+constexpr double PLANCK_PER_KG{3.9560340102631226e-7};
+constexpr double SLIT1_SIZE{0.03};
+constexpr double SLIT1_DIST{1.2};
+constexpr double SLIT2_DIST{0.3};
+constexpr double SLIT2_SIZE{0.02};
+constexpr double TOF_BIN_WIDTH{70.}; // microseconds
+} // namespace
+
+class ReflectometryMomentumTransferTest : 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 ReflectometryMomentumTransferTest *createSuite() {
+    return new ReflectometryMomentumTransferTest();
+  }
+  static void destroySuite(ReflectometryMomentumTransferTest *suite) {
+    delete suite;
+  }
+
+  ReflectometryMomentumTransferTest() { API::FrameworkManager::Instance(); }
+
+  void test_Init() {
+    Algorithms::ReflectometryMomentumTransfer alg;
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+  }
+
+  void test_XYEFromInputUnchangedAndMonitorDXSetToZero() {
+    auto inputWS = make_ws(0.5 / 180. * M_PI);
+    API::MatrixWorkspace_sptr directWS = inputWS->clone();
+    auto alg = make_alg(inputWS, directWS, "SumInLambda", false);
+    TS_ASSERT_THROWS_NOTHING(alg->execute();)
+    TS_ASSERT(alg->isExecuted())
+
+    API::MatrixWorkspace_sptr outputWS = alg->getProperty("OutputWorkspace");
+    TS_ASSERT(outputWS);
+    const auto axis = outputWS->getAxis(0);
+    TS_ASSERT_EQUALS(axis->unit()->unitID(), "MomentumTransfer")
+    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(),
+                     inputWS->getNumberHistograms())
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      const auto &inXs = inputWS->x(i);
+      const auto &outXs = outputWS->x(i);
+      TS_ASSERT_EQUALS(outXs.size(), inXs.size())
+      TS_ASSERT(outputWS->hasDx(i))
+      if (i == 1) {
+        // Monitor should have Dx = 0
+        TS_ASSERT(outputWS->spectrumInfo().isMonitor(i))
+        const auto &outDx = outputWS->dx(i);
+        for (size_t j = 0; j < outDx.size(); ++j) {
+          TS_ASSERT_EQUALS(outDx[j], 0.)
+        }
+      }
+      const auto &inYs = inputWS->y(i);
+      const auto &outYs = outputWS->y(i);
+      TS_ASSERT_EQUALS(outYs.rawData(), inYs.rawData())
+      const auto &inEs = inputWS->e(i);
+      const auto &outEs = outputWS->e(i);
+      TS_ASSERT_EQUALS(outEs.rawData(), inEs.rawData())
+    }
+  }
+
+  void test_nonpolarizedSumInLambdaResultsAreValid() {
+    const bool polarized(false);
+    const std::string sumType{"SumInLambda"};
+    sameReflectedAndDirectSlitSizes(polarized, sumType);
+  }
+
+  void test_polarizedSumInLambdaResultsAreValid() {
+    const bool polarized(true);
+    const std::string sumType{"SumInLambda"};
+    sameReflectedAndDirectSlitSizes(polarized, sumType);
+  }
+
+  void test_nonpolarizedSumInQResultsAreValid() {
+    const bool polarized(false);
+    const std::string sumType{"SumInQ"};
+    sameReflectedAndDirectSlitSizes(polarized, sumType);
+  }
+
+  void test_polarizedSumInQResultsAreValid() {
+    const bool polarized(true);
+    const std::string sumType{"SumInQ"};
+    sameReflectedAndDirectSlitSizes(polarized, sumType);
+  }
+
+  void test_differentReflectedAndDirectSlitSizes() {
+    using namespace boost::math;
+    const bool polarized{false};
+    const std::string sumType{"SumInLambda"};
+    auto inputWS = make_ws(0.5 / 180. * M_PI);
+    inputWS->mutableY(0) = 1. / static_cast<double>(inputWS->y(0).size());
+    API::MatrixWorkspace_sptr directWS = inputWS->clone();
+    auto &run = directWS->mutableRun();
+    constexpr bool overwrite{true};
+    const std::string meters{"m"};
+    run.addProperty("slit1.size", 1.5 * SLIT1_SIZE, meters, overwrite);
+    run.addProperty("slit2.size", 1.5 * SLIT2_SIZE, meters, overwrite);
+    auto alg = make_alg(inputWS, directWS, sumType, polarized);
+    TS_ASSERT_THROWS_NOTHING(alg->execute();)
+    TS_ASSERT(alg->isExecuted())
+    API::MatrixWorkspace_sptr outputWS = alg->getProperty("OutputWorkspace");
+    TS_ASSERT(outputWS);
+    alg = API::AlgorithmManager::Instance().createUnmanaged("ConvertUnits");
+    alg->initialize();
+    alg->setChild(true);
+    alg->setRethrows(true);
+    alg->setProperty("InputWorkspace", inputWS);
+    alg->setProperty("OutputWorkspace", "unused_for_child");
+    alg->setProperty("Target", "MomentumTransfer");
+    alg->execute();
+    API::MatrixWorkspace_sptr qWS = alg->getProperty("OutputWorkspace");
+    const auto axis = outputWS->getAxis(0);
+    TS_ASSERT_EQUALS(axis->unit()->unitID(), "MomentumTransfer")
+    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(),
+                     inputWS->getNumberHistograms())
+    const auto &spectrumInfo = outputWS->spectrumInfo();
+    const auto &dirSpectrumInfo = directWS->spectrumInfo();
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      const auto &inQs = qWS->points(i);
+      const auto &outPoints = outputWS->points(i);
+      TS_ASSERT_EQUALS(outPoints.size(), inQs.size())
+      TS_ASSERT(outputWS->hasDx(i))
+      if (i != 1) {
+        TS_ASSERT(!outputWS->spectrumInfo().isMonitor(i))
+        const auto &outDx = outputWS->dx(i);
+        TS_ASSERT_EQUALS(outDx.size(), inQs.size())
+        const auto &lambdas = inputWS->points(i);
+        const auto l2 = spectrumInfo.l2(i);
+        const auto dirL2 = dirSpectrumInfo.l2(i);
+        const auto angle_bragg = spectrumInfo.twoTheta(i) / 2.;
+        for (size_t j = 0; j < lambdas.size(); ++j) {
+          const auto lambda = lambdas[j] * 1e-10;
+          const size_t qIndex = inQs.size() - j - 1;
+          const auto q = inQs[qIndex];
+          const auto resE = std::sqrt(pow<2>(err_res(lambda, l2)) +
+                                      pow<2>(width_res(lambda, l2)));
+          const auto detFwhm = det_fwhm(*inputWS, 0, 0);
+          const auto dirDetFwhm = det_fwhm(*directWS, 0, 0);
+          const auto omFwhm =
+              om_fwhm(l2, dirL2, SLIT1_SIZE, SLIT2_SIZE, detFwhm, dirDetFwhm);
+          const auto rayE =
+              err_ray(l2, angle_bragg, sumType, polarized, omFwhm);
+          const auto fractionalResolution =
+              std::sqrt(pow<2>(resE) + pow<2>(rayE));
+          TS_ASSERT_EQUALS(outPoints[qIndex], q)
+          TS_ASSERT_DELTA(outDx[qIndex], q * fractionalResolution, 1e-7)
+        }
+      } else {
+        // Monitor should have Dx = 0
+        TS_ASSERT(outputWS->spectrumInfo().isMonitor(i))
+        const auto &outDx = outputWS->dx(i);
+        for (size_t j = 0; j < outDx.size(); ++j) {
+          TS_ASSERT_EQUALS(outDx[j], 0.)
+        }
+      }
+    }
+  }
+
+private:
+  void sameReflectedAndDirectSlitSizes(const bool polarized,
+                                       const std::string &sumType) {
+    using namespace boost::math;
+    auto inputWS = make_ws(0.5 / 180. * M_PI);
+    inputWS->mutableY(0) = 1. / static_cast<double>(inputWS->y(0).size());
+    API::MatrixWorkspace_sptr directWS = inputWS->clone();
+    auto &run = directWS->mutableRun();
+    constexpr bool overwrite{true};
+    const std::string meters{"m"};
+    run.addProperty("slit1.size", SLIT1_SIZE, meters, overwrite);
+    run.addProperty("slit2.size", SLIT2_SIZE, meters, overwrite);
+    auto alg = make_alg(inputWS, directWS, sumType, polarized);
+    TS_ASSERT_THROWS_NOTHING(alg->execute();)
+    TS_ASSERT(alg->isExecuted())
+    API::MatrixWorkspace_sptr outputWS = alg->getProperty("OutputWorkspace");
+    TS_ASSERT(outputWS);
+    alg = API::AlgorithmManager::Instance().createUnmanaged("ConvertUnits");
+    alg->initialize();
+    alg->setChild(true);
+    alg->setRethrows(true);
+    alg->setProperty("InputWorkspace", inputWS);
+    alg->setProperty("OutputWorkspace", "unused_for_child");
+    alg->setProperty("Target", "MomentumTransfer");
+    alg->execute();
+    API::MatrixWorkspace_sptr qWS = alg->getProperty("OutputWorkspace");
+    const auto axis = outputWS->getAxis(0);
+    TS_ASSERT_EQUALS(axis->unit()->unitID(), "MomentumTransfer")
+    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(),
+                     inputWS->getNumberHistograms())
+    const auto &spectrumInfo = outputWS->spectrumInfo();
+    const auto &dirSpectrumInfo = directWS->spectrumInfo();
+    for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) {
+      const auto &inQs = qWS->points(i);
+      const auto &outPoints = outputWS->points(i);
+      TS_ASSERT_EQUALS(outPoints.size(), inQs.size())
+      TS_ASSERT(outputWS->hasDx(i))
+      if (i != 1) {
+        TS_ASSERT(!outputWS->spectrumInfo().isMonitor(i))
+        const auto &outDx = outputWS->dx(i);
+        TS_ASSERT_EQUALS(outDx.size(), inQs.size())
+        const auto &lambdas = inputWS->points(i);
+        const auto l2 = spectrumInfo.l2(i);
+        const auto dirL2 = dirSpectrumInfo.l2(i);
+        const auto angle_bragg = spectrumInfo.twoTheta(i) / 2.;
+        for (size_t j = 0; j < lambdas.size(); ++j) {
+          const auto lambda = lambdas[j] * 1e-10;
+          const size_t qIndex = inQs.size() - j - 1;
+          const auto q = inQs[qIndex];
+          const auto resE = std::sqrt(pow<2>(err_res(lambda, l2)) +
+                                      pow<2>(width_res(lambda, l2)));
+          const auto detFwhm = det_fwhm(*inputWS, 0, 0);
+          const auto dirDetFwhm = det_fwhm(*directWS, 0, 0);
+          const auto omFwhm =
+              om_fwhm(l2, dirL2, SLIT1_SIZE, SLIT2_SIZE, detFwhm, dirDetFwhm);
+          const auto rayE =
+              err_ray(l2, angle_bragg, sumType, polarized, omFwhm);
+          const auto fractionalResolution =
+              std::sqrt(pow<2>(resE) + pow<2>(rayE));
+          TS_ASSERT_EQUALS(outPoints[qIndex], q)
+          TS_ASSERT_DELTA(outDx[qIndex], q * fractionalResolution, 1e-7)
+        }
+      } else {
+        // Monitor should have Dx = 0
+        TS_ASSERT(outputWS->spectrumInfo().isMonitor(i))
+        const auto &outDx = outputWS->dx(i);
+        for (size_t j = 0; j < outDx.size(); ++j) {
+          TS_ASSERT_EQUALS(outDx[j], 0.)
+        }
+      }
+    }
+  }
+
+  API::Algorithm_sptr make_alg(API::MatrixWorkspace_sptr inputWS,
+                               API::MatrixWorkspace_sptr directWS,
+                               const std::string &sumType,
+                               const bool polarized) {
+    std::vector<int> foreground(2);
+    foreground.front() = 0;
+    foreground.back() = 0;
+    auto alg = boost::make_shared<Algorithms::ReflectometryMomentumTransfer>();
+    alg->setChild(true);
+    alg->setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg->initialize())
+    TS_ASSERT(alg->isInitialized())
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("InputWorkspace", inputWS))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setPropertyValue("OutputWorkspace", "_unused_for_child"))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("ReflectedBeamWorkspace", inputWS))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("ReflectedForeground", foreground))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("DirectBeamWorkspace", directWS))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("DirectForeground", foreground))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("SummationType", sumType))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("Polarized", polarized))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("PixelSize", PIXEL_SIZE))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("DetectorResolution", DET_RESOLUTION))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("ChopperSpeed", CHOPPER_SPEED))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("ChopperOpening", CHOPPER_OPENING_ANGLE))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("ChopperRadius", CHOPPER_RADIUS))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("ChopperpairDistance", CHOPPER_GAP))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("Slit1Name", "slit1"))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("Slit1SizeSampleLog", "slit1.size"))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("Slit2Name", "slit2"))
+    TS_ASSERT_THROWS_NOTHING(
+        alg->setProperty("Slit2SizeSampleLog", "slit2.size"))
+    TS_ASSERT_THROWS_NOTHING(alg->setProperty("TOFChannelWidth", TOF_BIN_WIDTH))
+    return alg;
+  }
+
+  API::MatrixWorkspace_sptr make_ws(const double braggAngle) {
+    using namespace WorkspaceCreationHelper;
+    constexpr double startX{1000.};
+    const Kernel::V3D sourcePos{0., 0., -L1};
+    const Kernel::V3D &monitorPos = sourcePos;
+    const Kernel::V3D samplePos{
+        0., 0., 0.,
+    };
+    const auto detZ = DET_DIST * std::cos(2 * braggAngle);
+    const auto detY = DET_DIST * std::sin(2 * braggAngle);
+    const Kernel::V3D detectorPos{0., detY, detZ};
+    const Kernel::V3D slit1Pos{0., 0., -SLIT1_DIST};
+    const Kernel::V3D slit2Pos{0., 0., -SLIT2_DIST};
+    constexpr int nHisto{2};
+    constexpr int nBins{100};
+    auto ws = create2DWorkspaceWithReflectometryInstrument(
+        startX, slit1Pos, slit2Pos, SLIT1_SIZE, SLIT2_SIZE, sourcePos,
+        monitorPos, samplePos, detectorPos, nHisto, nBins, TOF_BIN_WIDTH);
+    // Add slit sizes to sample logs, too.
+    auto &run = ws->mutableRun();
+    constexpr bool overwrite{true};
+    const std::string meters{"m"};
+    run.addProperty("slit1.size", SLIT1_SIZE, meters, overwrite);
+    run.addProperty("slit2.size", SLIT2_SIZE, meters, overwrite);
+    auto alg =
+        API::AlgorithmManager::Instance().createUnmanaged("ConvertUnits");
+    alg->initialize();
+    alg->setChild(true);
+    alg->setRethrows(true);
+    alg->setProperty("InputWorkspace", ws);
+    alg->setPropertyValue("OutputWorkspace", "_unused_for_child");
+    alg->setProperty("Target", "Wavelength");
+    alg->setProperty("EMode", "Elastic");
+    alg->execute();
+    return alg->getProperty("OutputWorkspace");
+  }
+
+  double det_fwhm(const API::MatrixWorkspace &ws, const size_t fgd_first,
+                  const size_t fgd_last) {
+    using namespace boost::math;
+    std::vector<double> angd;
+    const auto &spectrumInfo = ws.spectrumInfo();
+    for (size_t i = fgd_first; i <= fgd_last; ++i) {
+      if (spectrumInfo.isMonitor(i)) {
+        continue;
+      }
+      const auto &ys = ws.y(i);
+      const auto sum = std::accumulate(ys.cbegin(), ys.cend(), 0.0);
+      angd.emplace_back(sum);
+    }
+    const auto temp = [&angd]() {
+      double sum{0.0};
+      for (size_t i = 0; i < angd.size(); ++i) {
+        sum += static_cast<double>(i) * angd[i];
+      }
+      return sum;
+    }();
+    const auto total_angd = std::accumulate(angd.cbegin(), angd.cend(), 0.0);
+    const auto pref = temp / total_angd + static_cast<double>(fgd_first);
+    const auto angd_cen = pref - static_cast<double>(fgd_first);
+    const auto tt = [&angd, &angd_cen]() {
+      double sum{0.0};
+      for (size_t i = 0; i < angd.size(); ++i) {
+        sum += angd[i] * pow<2>(angd_cen - static_cast<double>(i));
+      }
+      return sum;
+    }();
+    return 2. * std::sqrt(2. * std::log(2.)) * PIXEL_SIZE *
+           std::sqrt(tt / total_angd);
+  }
+
+  double err_ray(const double l2, const double angle_bragg,
+                 const std::string &sumType, const bool polarized,
+                 const double om_fwhm) {
+    using namespace boost::math;
+    const auto interslit = SLIT1_DIST - SLIT2_DIST;
+    const auto da = 0.68 * std::sqrt((pow<2>(SLIT1_SIZE) + pow<2>(SLIT2_SIZE)) /
+                                     pow<2>(interslit));
+    const auto s2_fwhm = (0.68 * SLIT1_SIZE) / interslit;
+    const auto s3_fwhm = (0.68 * SLIT2_SIZE) / (SLIT2_DIST + l2);
+    double err_ray1;
+    if (sumType == "SumInQ") {
+      if (om_fwhm > 0) {
+        if (s2_fwhm >= 2 * om_fwhm) {
+          err_ray1 = std::sqrt(pow<2>(DET_RESOLUTION / l2) + pow<2>(s3_fwhm) +
+                               pow<2>(om_fwhm)) /
+                     angle_bragg;
+        } else {
+          err_ray1 = std::sqrt(pow<2>(DET_RESOLUTION / (2. * l2)) +
+                               pow<2>(s3_fwhm) + pow<2>(s2_fwhm)) /
+                     angle_bragg;
+        }
+      } else {
+        if (s2_fwhm > DET_RESOLUTION / l2) {
+          err_ray1 = std::sqrt(pow<2>(DET_RESOLUTION / l2) + pow<2>(s3_fwhm)) /
+                     angle_bragg;
+        } else {
+          err_ray1 =
+              std::sqrt(pow<2>(da) + pow<2>(DET_RESOLUTION / l2)) / angle_bragg;
+        }
+      }
+    } else {
+      if (polarized) {
+        err_ray1 = std::sqrt(pow<2>(da)) / angle_bragg;
+      } else {
+        err_ray1 = std::sqrt(pow<2>(da) + pow<2>(om_fwhm)) / angle_bragg;
+      }
+    }
+    const auto err_ray_temp =
+        0.68 *
+        std::sqrt((pow<2>(PIXEL_SIZE) + pow<2>(SLIT2_SIZE)) / pow<2>(l2)) /
+        angle_bragg;
+    return std::min(err_ray1, err_ray_temp);
+  }
+
+  double err_res(const double lambda, const double l2) {
+    using namespace boost::math;
+    const auto tofd = L1 + l2;
+    const auto period = 60. / CHOPPER_SPEED;
+    const auto det_res =
+        PLANCK_PER_KG * TOF_BIN_WIDTH * 1e-6 / lambda / (2 * tofd);
+    const auto chop_res =
+        (CHOPPER_GAP +
+         (PLANCK_PER_KG * CHOPPER_OPENING_ANGLE * period / (360 * lambda))) /
+        (2 * tofd);
+    return 0.98 *
+           (3 * pow<2>(chop_res) + pow<2>(det_res) + 3 * chop_res * det_res) /
+           (2 * chop_res + det_res);
+  }
+
+  double om_fwhm(const double l2, const double dirl2, const double dirs2w,
+                 const double dirs3w, const double det_fwhm,
+                 const double detdb_fwhm) {
+    using namespace boost::math;
+    const double sdr = SLIT2_DIST + l2;
+    const double ratio = SLIT2_SIZE / SLIT1_SIZE;
+    const double interslit = SLIT1_DIST - SLIT2_DIST;
+    const double vs = sdr + (ratio * interslit) / (1 + ratio);
+    const double da = 0.68 * std::sqrt(pow<2>(SLIT1_SIZE) +
+                                       pow<2>(SLIT2_SIZE) / pow<2>(interslit));
+    const double da_det = std::sqrt(pow<2>(da * vs) + pow<2>(DET_RESOLUTION));
+    double om_fwhm{0};
+    if (std::abs(SLIT1_SIZE - dirs2w) >= 0.00004 ||
+        std::abs(SLIT2_SIZE - dirs3w) >= 0.00004) {
+      if ((det_fwhm - da_det) >= 0.) {
+        if (std::sqrt(pow<2>(det_fwhm) - pow<2>(da_det)) >= PIXEL_SIZE) {
+          om_fwhm = 0.5 * std::sqrt(pow<2>(det_fwhm) - pow<2>(da_det)) / dirl2;
+        } else {
+          om_fwhm = 0;
+        }
+      }
+    } else {
+      if (pow<2>(det_fwhm) - pow<2>(detdb_fwhm) >= 0.) {
+        if (std::sqrt(pow<2>(det_fwhm) - pow<2>(detdb_fwhm)) >= PIXEL_SIZE) {
+          om_fwhm =
+              0.5 * std::sqrt(pow<2>(det_fwhm) - pow<2>(detdb_fwhm)) / dirl2;
+        } else {
+          om_fwhm = 0.;
+        }
+      } else {
+        om_fwhm = 0.;
+      }
+    }
+    return om_fwhm;
+  }
+
+  double width_res(const double lambda, const double l2) {
+    using namespace boost::math;
+    const auto tofd = L1 + l2;
+    const auto period = 60. / CHOPPER_SPEED;
+    const auto sdr = SLIT2_DIST + l2;
+    const auto interslit = SLIT1_DIST - SLIT2_DIST;
+    const auto tempratio = (tofd - sdr) / interslit;
+    const auto tempa =
+        tempratio * std::abs(SLIT1_SIZE - SLIT2_SIZE) + SLIT1_SIZE;
+    const auto tempb = tempratio * (SLIT1_SIZE + SLIT2_SIZE) + SLIT1_SIZE;
+    const auto tempwidthfwhm = 0.49 * (pow<3>(tempb) - pow<3>(tempa)) /
+                               (pow<2>(tempb) - pow<2>(tempa));
+    return tempwidthfwhm * period / (2 * M_PI * CHOPPER_RADIUS) *
+           PLANCK_PER_KG / lambda / tofd;
+  }
+};
+
+class ReflectometryMomentumTransferTestPerformance : public CxxTest::TestSuite {
+public:
+  void setUp() override {
+    m_reflectedWS = makeWS();
+    m_directWS = m_reflectedWS->clone();
+    m_algorithm = makeAlgorithm(m_reflectedWS, m_directWS);
+  }
+
+  void test_performance() {
+    for (int i = 0; i < 1000; ++i)
+      m_algorithm->execute();
+  }
+
+private:
+  static API::IAlgorithm_sptr
+  makeAlgorithm(API::MatrixWorkspace_sptr &reflectedWS,
+                API::MatrixWorkspace_sptr &directWS) {
+    std::vector<int> foreground(2);
+    foreground.front() = 0;
+    foreground.back() = 0;
+    auto alg = boost::make_shared<Algorithms::ReflectometryMomentumTransfer>();
+    alg->setChild(true);
+    alg->setRethrows(true);
+    alg->initialize();
+    alg->isInitialized();
+    alg->setProperty("InputWorkspace", reflectedWS);
+    alg->setPropertyValue("OutputWorkspace", "_unused_for_child");
+    alg->setProperty("ReflectedBeamWorkspace", reflectedWS);
+    alg->setProperty("ReflectedForeground", foreground);
+    alg->setProperty("DirectBeamWorkspace", directWS);
+    alg->setProperty("DirectForeground", foreground);
+    alg->setProperty("SummationType", "SumInLambda");
+    alg->setProperty("Polarized", false);
+    alg->setProperty("PixelSize", PIXEL_SIZE);
+    alg->setProperty("DetectorResolution", DET_RESOLUTION);
+    alg->setProperty("ChopperSpeed", CHOPPER_SPEED);
+    alg->setProperty("ChopperOpening", CHOPPER_OPENING_ANGLE);
+    alg->setProperty("ChopperRadius", CHOPPER_RADIUS);
+    alg->setProperty("ChopperpairDistance", CHOPPER_GAP);
+    alg->setProperty("Slit1Name", "slit1");
+    alg->setProperty("Slit1SizeSampleLog", "slit1.size");
+    alg->setProperty("Slit2Name", "slit2");
+    alg->setProperty("Slit2SizeSampleLog", "slit2.size");
+    alg->setProperty("TOFChannelWidth", TOF_BIN_WIDTH);
+    return alg;
+  }
+
+  static API::MatrixWorkspace_sptr makeWS() {
+    using namespace WorkspaceCreationHelper;
+    constexpr double startX{1000.};
+    const Kernel::V3D sourcePos{0., 0., -L1};
+    const Kernel::V3D &monitorPos = sourcePos;
+    const Kernel::V3D samplePos{
+        0., 0., 0.,
+    };
+    const double braggAngle{0.7};
+    const auto detZ = DET_DIST * std::cos(2 * braggAngle);
+    const auto detY = DET_DIST * std::sin(2 * braggAngle);
+    const Kernel::V3D detectorPos{0., detY, detZ};
+    const Kernel::V3D slit1Pos{0., 0., -SLIT1_DIST};
+    const Kernel::V3D slit2Pos{0., 0., -SLIT2_DIST};
+    constexpr int nHisto{2};
+    constexpr int nBins{10000};
+    auto ws = create2DWorkspaceWithReflectometryInstrument(
+        startX, slit1Pos, slit2Pos, SLIT1_SIZE, SLIT2_SIZE, sourcePos,
+        monitorPos, samplePos, detectorPos, nHisto, nBins, TOF_BIN_WIDTH);
+    // Add slit sizes to sample logs, too.
+    auto &run = ws->mutableRun();
+    constexpr bool overwrite{true};
+    const std::string meters{"m"};
+    run.addProperty("slit1.size", SLIT1_SIZE, meters, overwrite);
+    run.addProperty("slit2.size", SLIT2_SIZE, meters, overwrite);
+    auto convertUnits =
+        API::AlgorithmManager::Instance().createUnmanaged("ConvertUnits");
+    convertUnits->initialize();
+    convertUnits->setChild(true);
+    convertUnits->setRethrows(true);
+    convertUnits->setProperty("InputWorkspace", ws);
+    convertUnits->setPropertyValue("OutputWorkspace", "_unused_for_child");
+    convertUnits->setProperty("Target", "Wavelength");
+    convertUnits->setProperty("EMode", "Elastic");
+    convertUnits->execute();
+    API::MatrixWorkspace_sptr outWS =
+        convertUnits->getProperty("OutputWorkspace");
+    return outWS;
+  }
+
+private:
+  API::IAlgorithm_sptr m_algorithm;
+  API::MatrixWorkspace_sptr m_directWS;
+  API::MatrixWorkspace_sptr m_reflectedWS;
+};
+
+#endif /* MANTID_ALGORITHMS_REFLECTOMETRYMOMENTUMTRANSFERTEST_H_ */
diff --git a/Framework/Algorithms/test/ReflectometryReductionOne2Test.h b/Framework/Algorithms/test/ReflectometryReductionOne2Test.h
index 5ea8486ee85e25e3ee417542c2e772ae974ed694..cc52d1b307dd8c9a762b2a88848c86898288a34e 100644
--- a/Framework/Algorithms/test/ReflectometryReductionOne2Test.h
+++ b/Framework/Algorithms/test/ReflectometryReductionOne2Test.h
@@ -7,6 +7,8 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidHistogramData/HistogramY.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
@@ -581,6 +583,108 @@ public:
     TS_ASSERT_DELTA(outQ->y(0)[7], 2.607359, 1e-6);
   }
 
+  void test_angle_correction() {
+
+    ReflectometryReductionOne2 alg;
+
+    auto inputWS = MatrixWorkspace_sptr(std::move(m_multiDetectorWS->clone()));
+    setYValuesToWorkspace(*inputWS);
+
+    alg.setChild(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", inputWS);
+    alg.setProperty("WavelengthMin", 1.5);
+    alg.setProperty("WavelengthMax", 15.0);
+    alg.setPropertyValue("ProcessingInstructions", "1+2");
+    alg.setPropertyValue("OutputWorkspace", "IvsQ");
+    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
+
+    double const theta = 22.0;
+    alg.setProperty("ThetaIn", theta);
+    alg.execute();
+    MatrixWorkspace_sptr outLam = alg.getProperty("OutputWorkspaceWavelength");
+    MatrixWorkspace_sptr outQ = alg.getProperty("OutputWorkspace");
+
+    auto const &qX = outQ->x(0);
+    auto const &lamX = outLam->x(0);
+
+    std::vector<double> lamXinv(lamX.size() + 3);
+    std::reverse_copy(lamX.begin(), lamX.end(), lamXinv.begin());
+
+    auto factor = 4.0 * M_PI * sin(theta * M_PI / 180.0);
+    for (size_t i = 0; i < qX.size(); ++i) {
+      TS_ASSERT_DELTA(qX[i], factor / lamXinv[i], 1e-14);
+    }
+
+    auto const &lamY = outLam->y(0);
+    TS_ASSERT_DELTA(lamY[0], 19, 1e-2);
+    TS_ASSERT_DELTA(lamY[6], 49, 1e-2);
+    TS_ASSERT_DELTA(lamY[13], 84, 1e-2);
+
+    auto const &qY = outQ->y(0);
+    TS_ASSERT_DELTA(qY[0], 84, 1e-2);
+    TS_ASSERT_DELTA(qY[6], 54, 1e-2);
+    TS_ASSERT_DELTA(qY[13], 19, 1e-2);
+  }
+
+  void test_no_angle_correction() {
+
+    ReflectometryReductionOne2 alg;
+
+    auto inputWS = MatrixWorkspace_sptr(std::move(m_multiDetectorWS->clone()));
+    setYValuesToWorkspace(*inputWS);
+
+    alg.setChild(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", inputWS);
+    alg.setProperty("WavelengthMin", 1.5);
+    alg.setProperty("WavelengthMax", 15.0);
+    alg.setPropertyValue("ProcessingInstructions", "2");
+    alg.setPropertyValue("OutputWorkspace", "IvsQ");
+    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
+
+    alg.setProperty("ThetaIn", 22.0);
+    alg.execute();
+    MatrixWorkspace_sptr outLam = alg.getProperty("OutputWorkspaceWavelength");
+    MatrixWorkspace_sptr outQ = alg.getProperty("OutputWorkspace");
+
+    auto const &qX = outQ->x(0);
+    auto const &lamX = outLam->x(0);
+
+    std::vector<double> lamXinv(lamX.size() + 3);
+    std::reverse_copy(lamX.begin(), lamX.end(), lamXinv.begin());
+
+    auto factor = 4.0 * M_PI * sin(22.5 * M_PI / 180.0);
+    for (size_t i = 0; i < qX.size(); ++i) {
+      TS_ASSERT_DELTA(qX[i], factor / lamXinv[i], 1e-14);
+    }
+
+    auto const &lamY = outLam->y(0);
+    TS_ASSERT_DELTA(lamY[0], 11, 1e-2);
+    TS_ASSERT_DELTA(lamY[6], 29, 1e-2);
+    TS_ASSERT_DELTA(lamY[13], 50, 1e-2);
+
+    auto const &qY = outQ->y(0);
+    TS_ASSERT_DELTA(qY[0], 50, 1e-2);
+    TS_ASSERT_DELTA(qY[6], 32, 1e-2);
+    TS_ASSERT_DELTA(qY[13], 11, 1e-2);
+  }
+
+  void test_angle_correction_multi_group() {
+    ReflectometryReductionOne2 alg;
+    alg.setChild(true);
+    alg.setRethrows(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspace", m_multiDetectorWS);
+    alg.setProperty("WavelengthMin", 1.5);
+    alg.setProperty("WavelengthMax", 15.0);
+    alg.setPropertyValue("ProcessingInstructions", "1+2, 3");
+    alg.setPropertyValue("OutputWorkspace", "IvsQ");
+    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
+    alg.setProperty("ThetaIn", 22.0);
+    TS_ASSERT_THROWS(alg.execute(), std::invalid_argument);
+  }
+
 private:
   // Do standard algorithm setup
   void setupAlgorithm(ReflectometryReductionOne2 &alg,
@@ -661,6 +765,15 @@ private:
 
     return outQ;
   }
+
+  void setYValuesToWorkspace(MatrixWorkspace &ws) {
+    for (size_t i = 0; i < ws.getNumberHistograms(); ++i) {
+      auto &y = ws.mutableY(i);
+      for (size_t j = 0; j < y.size(); ++j) {
+        y[j] += double(j + 1) * double(i + 1);
+      }
+    }
+  }
 };
 
 #endif /* ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONE2TEST_H_ */
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h b/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
index 7faa8beb0c14086329b187589b22f22070a5227f..328fd8d98ea89de92988c67e1981416f07747db4 100644
--- a/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
+++ b/Framework/Algorithms/test/ReflectometryReductionOneAuto2Test.h
@@ -244,7 +244,7 @@ public:
     alg.setProperty("OutputWorkspace", "IvsQ");
     alg.setProperty("OutputWorkspaceBinned", "IvsQ_binned");
     alg.setProperty("OutputWorkspaceWavelength", "IvsLam");
-    alg.setProperty("ProcessingInstructions", "3:4");
+    alg.setProperty("ProcessingInstructions", "3");
     alg.execute();
     MatrixWorkspace_sptr out = alg.getProperty("OutputWorkspace");
 
@@ -270,26 +270,17 @@ public:
     TS_ASSERT_EQUALS(instIn->getComponentByName("linear-detector")->getPos(),
                      instOut->getComponentByName("linear-detector")->getPos());
 
-    // Only 'point-detector' and 'point-detector2' should have been moved
-    // vertically (along Y)
+    // Only 'point-detector' should have been moved vertically (along Y)
 
     auto point1In = instIn->getComponentByName("point-detector")->getPos();
-    auto point2In = instIn->getComponentByName("point-detector2")->getPos();
     auto point1Out = instOut->getComponentByName("point-detector")->getPos();
-    auto point2Out = instOut->getComponentByName("point-detector2")->getPos();
 
     TS_ASSERT_EQUALS(point1In.X(), point1Out.X());
     TS_ASSERT_EQUALS(point1In.Z(), point1Out.Z());
-    TS_ASSERT_EQUALS(point2In.X(), point2Out.X());
-    TS_ASSERT_EQUALS(point2In.Z(), point2Out.Z());
     TS_ASSERT_DIFFERS(point1In.Y(), point1Out.Y());
-    TS_ASSERT_DIFFERS(point2In.Y(), point2Out.Y());
     TS_ASSERT_DELTA(point1Out.Y() /
                         (point1Out.Z() - instOut->getSample()->getPos().Z()),
                     std::tan(theta * 2 * M_PI / 180), 1e-4);
-    TS_ASSERT_DELTA(point2Out.Y() /
-                        (point2Out.Z() - instOut->getSample()->getPos().Z()),
-                    std::tan(theta * 2 * M_PI / 180), 1e-4);
   }
 
   void test_correct_detector_position_rotation_POLREF() {
@@ -399,7 +390,7 @@ public:
     alg.setProperty("OutputWorkspace", "IvsQ");
     alg.setProperty("OutputWorkspaceBinned", "IvsQ_binned");
     alg.setProperty("OutputWorkspaceWavelength", "IvsLam");
-    alg.setProperty("ProcessingInstructions", "3:4");
+    alg.setProperty("ProcessingInstructions", "3");
     alg.execute();
     MatrixWorkspace_sptr corrected = alg.getProperty("OutputWorkspace");
 
@@ -417,26 +408,18 @@ public:
     TS_ASSERT_EQUALS(instIn->getComponentByName("linear-detector")->getPos(),
                      instOut->getComponentByName("linear-detector")->getPos());
 
-    // Only 'point-detector' and 'point-detector2' should have been moved
+    // Only 'point-detector' should have been moved
     // vertically (along Y)
 
     auto point1In = instIn->getComponentByName("point-detector")->getPos();
-    auto point2In = instIn->getComponentByName("point-detector2")->getPos();
     auto point1Out = instOut->getComponentByName("point-detector")->getPos();
-    auto point2Out = instOut->getComponentByName("point-detector2")->getPos();
 
     TS_ASSERT_EQUALS(point1In.X(), point1Out.X());
     TS_ASSERT_EQUALS(point1In.Z(), point1Out.Z());
-    TS_ASSERT_EQUALS(point2In.X(), point2Out.X());
-    TS_ASSERT_EQUALS(point2In.Z(), point2Out.Z());
     TS_ASSERT_DIFFERS(point1In.Y(), point1Out.Y());
-    TS_ASSERT_DIFFERS(point2In.Y(), point2Out.Y());
     TS_ASSERT_DELTA(point1Out.Y() /
                         (point1Out.Z() - instOut->getSample()->getPos().Z()),
                     std::tan(theta * 2 * M_PI / 180), 1e-4);
-    TS_ASSERT_DELTA(point2Out.Y() /
-                        (point2Out.Z() - instOut->getSample()->getPos().Z()),
-                    std::tan(theta * 2 * M_PI / 180), 1e-4);
   }
 
   void test_override_ThetaIn_without_correcting_detectors() {
@@ -452,7 +435,7 @@ public:
     alg.setProperty("OutputWorkspace", "IvsQ");
     alg.setProperty("OutputWorkspaceBinned", "IvsQ_binned");
     alg.setProperty("OutputWorkspaceWavelength", "IvsLam");
-    alg.setProperty("ProcessingInstructions", "3:4");
+    alg.setProperty("ProcessingInstructions", "3");
     alg.execute();
     MatrixWorkspace_sptr corrected = alg.getProperty("OutputWorkspace");
 
@@ -463,12 +446,9 @@ public:
     // the detectors should not have been moved
 
     auto point1In = instIn->getComponentByName("point-detector")->getPos();
-    auto point2In = instIn->getComponentByName("point-detector2")->getPos();
     auto point1Out = instOut->getComponentByName("point-detector")->getPos();
-    auto point2Out = instOut->getComponentByName("point-detector2")->getPos();
 
     TS_ASSERT_EQUALS(point1In, point1Out);
-    TS_ASSERT_EQUALS(point2In, point2Out);
   }
 
   void test_sum_transmission_workspaces() {
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h b/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h
deleted file mode 100644
index 4a452f1ee0f0a5e51badcca4bbe05ddb422701a9..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h
+++ /dev/null
@@ -1,798 +0,0 @@
-#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_
-#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_
-
-#include <cxxtest/TestSuite.h>
-
-#include "MantidAPI/AlgorithmManager.h"
-#include "MantidAPI/Axis.h"
-#include "MantidAPI/FrameworkManager.h"
-#include "MantidAPI/WorkspaceGroup.h"
-#include "MantidAPI/WorkspaceHistory.h"
-#include "MantidAlgorithms/ReflectometryReductionOneAuto.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/ReferenceFrame.h"
-#include "MantidKernel/Unit.h"
-#include "MantidTestHelpers/WorkspaceCreationHelper.h"
-
-using Mantid::Algorithms::ReflectometryReductionOneAuto;
-using namespace Mantid::API;
-using namespace Mantid::DataObjects;
-using namespace Mantid::Geometry;
-using namespace Mantid::Kernel;
-using Mantid::MantidVec;
-using Mantid::MantidVecPtr;
-using Mantid::HistogramData::BinEdges;
-
-namespace {
-class PropertyFinder {
-private:
-  const std::string m_propertyName;
-
-public:
-  PropertyFinder(const std::string &propertyName)
-      : m_propertyName(propertyName) {}
-  bool operator()(const PropertyHistories::value_type &candidate) const {
-    return candidate->name() == m_propertyName;
-  }
-};
-
-template <typename T>
-T findPropertyValue(PropertyHistories &histories,
-                    const std::string &propertyName) {
-  PropertyFinder finder(propertyName);
-  auto it = std::find_if(histories.begin(), histories.end(), finder);
-  return boost::lexical_cast<T>((*it)->value());
-}
-}
-
-class ReflectometryReductionOneAutoTest : 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 ReflectometryReductionOneAutoTest *createSuite() {
-    return new ReflectometryReductionOneAutoTest();
-  }
-  static void destroySuite(ReflectometryReductionOneAutoTest *suite) {
-    delete suite;
-  }
-
-  MatrixWorkspace_sptr m_TOF;
-  MatrixWorkspace_sptr m_NotTOF;
-  MatrixWorkspace_sptr m_dataWorkspace;
-  MatrixWorkspace_sptr m_transWorkspace1;
-  MatrixWorkspace_sptr m_transWorkspace2;
-  WorkspaceGroup_sptr m_multiDetectorWorkspace;
-  const std::string outWSQName;
-  const std::string outWSLamName;
-  const std::string inWSName;
-  const std::string transWSName;
-
-  ReflectometryReductionOneAutoTest()
-      : outWSQName("ReflectometryReductionOneAutoTest_OutputWS_Q"),
-        outWSLamName("ReflectometryReductionOneAutoTest_OutputWS_Lam"),
-        inWSName("ReflectometryReductionOneAutoTest_InputWS"),
-        transWSName("ReflectometryReductionOneAutoTest_TransWS") {
-    MantidVec xData = {0, 0, 0, 0};
-    MantidVec yData = {0, 0, 0};
-
-    auto createWorkspace =
-        AlgorithmManager::Instance().create("CreateWorkspace");
-    createWorkspace->initialize();
-    createWorkspace->setProperty("UnitX", "1/q");
-    createWorkspace->setProperty("DataX", xData);
-    createWorkspace->setProperty("DataY", yData);
-    createWorkspace->setProperty("NSpec", 1);
-    createWorkspace->setPropertyValue("OutputWorkspace", "NotTOF");
-    createWorkspace->execute();
-    m_NotTOF =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("NotTOF");
-
-    createWorkspace->setProperty("UnitX", "TOF");
-    createWorkspace->setProperty("DataX", xData);
-    createWorkspace->setProperty("DataY", yData);
-    createWorkspace->setProperty("NSpec", 1);
-    createWorkspace->setPropertyValue("OutputWorkspace", "TOF");
-    createWorkspace->execute();
-    m_TOF = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("TOF");
-
-    IAlgorithm_sptr lAlg = AlgorithmManager::Instance().create("Load");
-    lAlg->setChild(true);
-    lAlg->initialize();
-    lAlg->setProperty("Filename", "INTER00013460.nxs");
-    lAlg->setPropertyValue("OutputWorkspace", "demo_ws");
-    lAlg->execute();
-    Workspace_sptr temp = lAlg->getProperty("OutputWorkspace");
-    m_dataWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);
-    // m_dataWorkspace =
-    // AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("data_ws");
-
-    lAlg->setProperty("Filename", "INTER00013463.nxs");
-    lAlg->setPropertyValue("OutputWorkspace", "trans_ws_1");
-    lAlg->execute();
-    temp = lAlg->getProperty("OutputWorkspace");
-    m_transWorkspace1 = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);
-    // m_transWorkspace1 =
-    // AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("trans_ws_1");
-
-    lAlg->setProperty("Filename", "INTER00013464.nxs");
-    lAlg->setPropertyValue("OutputWorkspace", "trans_ws_2");
-    lAlg->execute();
-    temp = lAlg->getProperty("OutputWorkspace");
-    m_transWorkspace2 = boost::dynamic_pointer_cast<MatrixWorkspace>(temp);
-    // m_transWorkspace2 =
-    // AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("trans_ws_2");
-
-    lAlg->setPropertyValue("Filename", "POLREF00004699.nxs");
-    lAlg->setPropertyValue("OutputWorkspace", "multidetector_ws_1");
-    lAlg->execute();
-    temp = lAlg->getProperty("OutputWorkspace");
-    m_multiDetectorWorkspace =
-        boost::dynamic_pointer_cast<WorkspaceGroup>(temp);
-    AnalysisDataService::Instance().addOrReplace("multidetector_group",
-                                                 m_multiDetectorWorkspace);
-  }
-  ~ReflectometryReductionOneAutoTest() override {
-    AnalysisDataService::Instance().remove("TOF");
-    AnalysisDataService::Instance().remove("NotTOF");
-    AnalysisDataService::Instance().remove("multidetector_group");
-    AnalysisDataService::Instance().remove("multidetector_group_1");
-    AnalysisDataService::Instance().remove("multidetector_group_2");
-  }
-
-  IAlgorithm_sptr construct_standard_algorithm() {
-    auto alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    alg->initialize();
-    alg->setProperty("InputWorkspace", m_TOF);
-    alg->setProperty("WavelengthMin", 0.0);
-    alg->setProperty("WavelengthMax", 1.0);
-    alg->setProperty("I0MonitorIndex", 0);
-    alg->setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg->setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg->setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg->setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg->setProperty("MomentumTransferStep", 0.1);
-    alg->setPropertyValue("ProcessingInstructions", "0");
-    alg->setPropertyValue("OutputWorkspace", outWSQName);
-    alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName);
-    alg->setRethrows(true);
-    return alg;
-  }
-
-  void test_Init() {
-    ReflectometryReductionOneAuto alg;
-    TS_ASSERT_THROWS_NOTHING(alg.initialize());
-    TS_ASSERT(alg.isInitialized());
-  }
-
-  void test_check_input_workpace_not_tof_or_wavelength_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("InputWorkspace", m_NotTOF);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_check_first_transmission_workspace_not_tof_or_wavelength_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("FirstTransmissionRun", m_NotTOF);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_check_second_transmission_workspace_not_tof_throws() {
-    auto alg = construct_standard_algorithm();
-    TS_ASSERT_THROWS(alg->setProperty("SecondTransmissionRun", m_NotTOF),
-                     std::invalid_argument);
-  }
-
-  void test_proivde_second_transmission_run_without_first_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("SecondTransmissionRun", m_TOF);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_end_overlap_must_be_greater_than_start_overlap_or_throw() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("FirstTransmissionRun", m_TOF);
-    alg->setProperty("SecondTransmissionRun", m_TOF);
-    MantidVec params = {0.0, 0.1, 1.0};
-    alg->setProperty("Params", params);
-    alg->setProperty("StartOverlap", 0.6);
-    alg->setProperty("EndOverlap", 0.4);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_must_provide_wavelengths() {
-    auto algWithMax =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    algWithMax->initialize();
-    algWithMax->setProperty("InputWorkspace", m_TOF);
-    algWithMax->setProperty("FirstTransmissionRun", m_TOF);
-    algWithMax->setProperty("SecondTransmissionRun", m_TOF);
-    algWithMax->setProperty("ProcessingInstructions", "3:4");
-    algWithMax->setProperty("MomentumTransferStep", 0.1);
-    algWithMax->setProperty("WavelengthMax", 1.0);
-    algWithMax->setPropertyValue("OutputWorkspace", "out_ws_Q");
-    algWithMax->setPropertyValue("OutputWorkspaceWavelength", "out_ws_Lam");
-    algWithMax->setRethrows(true);
-    TS_ASSERT_THROWS(algWithMax->execute(), std::runtime_error);
-
-    auto algWithMin =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    algWithMin->initialize();
-    algWithMin->setProperty("InputWorkspace", m_TOF);
-    algWithMin->setProperty("FirstTransmissionRun", m_TOF);
-    algWithMin->setProperty("SecondTransmissionRun", m_TOF);
-    algWithMin->setProperty("ProcessingInstructions", "3:4");
-    algWithMin->setProperty("MomentumTransferStep", 0.1);
-    algWithMin->setProperty("WavelengthMin", 1.0);
-    algWithMin->setPropertyValue("OutputWorkspace", "out_ws_Q");
-    algWithMin->setPropertyValue("OutputWorkspaceWavelength", "out_ws_Lam");
-    algWithMin->setRethrows(true);
-    TS_ASSERT_THROWS(algWithMin->execute(), std::runtime_error);
-  }
-
-  void test_wavelength_min_greater_wavelength_max_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("WavelengthMin", 1.0);
-    alg->setProperty("WavelengthMax", 0.0);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void
-  test_monitor_background_wavelength_min_greater_monitor_background_wavelength_max_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("MonitorBackgroundWavelengthMin", 1.0);
-    alg->setProperty("MonitorBackgroundWavelengthMax", 0.0);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void
-  test_monitor_integration_wavelength_min_greater_monitor_integration_wavelength_max_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("MonitorIntegrationWavelengthMin", 1.0);
-    alg->setProperty("MonitorIntegrationWavelengthMax", 0.0);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_monitor_index_positive() {
-    auto alg = construct_standard_algorithm();
-    auto tempInst = m_TOF->getInstrument();
-    m_TOF->setInstrument(m_dataWorkspace->getInstrument());
-    alg->setProperty("InputWorkspace", m_TOF);
-    TS_ASSERT_THROWS(alg->execute(), std::runtime_error);
-    m_TOF->setInstrument(tempInst);
-  }
-  void
-  test_cannot_set_direct_beam_region_of_interest_without_multidetector_run() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("AnalysisMode", "PointDetectorAnalysis");
-    std::vector<int> RegionOfDirectBeam = {1, 2};
-    alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_region_of_direct_beam_indexes_cannot_be_negative_or_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("AnalysisMode", "MultiDetectorAnalysis");
-    std::vector<int> RegionOfDirectBeam = {0, -1};
-    alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void
-  test_region_of_direct_beam_indexes_must_be_provided_as_min_max_order_or_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("AnalysisMode", "MultiDetectorAnalysis");
-    std::vector<int> RegionOfDirectBeam = {1, 0};
-    alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam);
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-
-  void test_bad_detector_component_name_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("DetectorComponentName", "made-up");
-    TS_ASSERT_THROWS(alg->execute(), std::runtime_error);
-  }
-
-  void test_bad_sample_component_name_throws() {
-    auto alg = construct_standard_algorithm();
-    alg->setProperty("SampleComponentName", "made-up");
-    TS_ASSERT_THROWS(alg->execute(), std::runtime_error);
-  }
-  void test_exec() {
-    IAlgorithm_sptr alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    alg->setRethrows(true);
-    TS_ASSERT_THROWS_NOTHING(alg->initialize());
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setProperty("InputWorkspace", m_dataWorkspace));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setProperty("AnalysisMode", "PointDetectorAnalysis"));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspace", outWSQName));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName));
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1));
-    alg->execute();
-    TS_ASSERT(alg->isExecuted());
-
-    MatrixWorkspace_sptr outWS =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(outWSQName);
-
-    auto inst = m_dataWorkspace->getInstrument();
-    auto workspaceHistory = outWS->getHistory();
-    AlgorithmHistory_const_sptr workerAlgHistory =
-        workspaceHistory.getAlgorithmHistory(0)->getChildAlgorithmHistory(0);
-    auto vecPropertyHistories = workerAlgHistory->getProperties();
-
-    const double wavelengthMin =
-        findPropertyValue<double>(vecPropertyHistories, "WavelengthMin");
-    const double wavelengthMax =
-        findPropertyValue<double>(vecPropertyHistories, "WavelengthMax");
-    const double monitorBackgroundWavelengthMin = findPropertyValue<double>(
-        vecPropertyHistories, "MonitorBackgroundWavelengthMin");
-    const double monitorBackgroundWavelengthMax = findPropertyValue<double>(
-        vecPropertyHistories, "MonitorBackgroundWavelengthMax");
-    const double monitorIntegrationWavelengthMin = findPropertyValue<double>(
-        vecPropertyHistories, "MonitorIntegrationWavelengthMin");
-    const double monitorIntegrationWavelengthMax = findPropertyValue<double>(
-        vecPropertyHistories, "MonitorIntegrationWavelengthMax");
-    const int i0MonitorIndex =
-        findPropertyValue<int>(vecPropertyHistories, "I0MonitorIndex");
-    std::string processingInstructions = findPropertyValue<std::string>(
-        vecPropertyHistories, "ProcessingInstructions");
-    std::vector<std::string> pointDetectorStartStop;
-    boost::split(pointDetectorStartStop, processingInstructions,
-                 boost::is_any_of(":"));
-
-    TS_ASSERT_EQUALS(inst->getNumberParameter("LambdaMin")[0], wavelengthMin);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("LambdaMax")[0], wavelengthMax);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorBackgroundMin")[0],
-                     monitorBackgroundWavelengthMin);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorBackgroundMax")[0],
-                     monitorBackgroundWavelengthMax);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorIntegralMin")[0],
-                     monitorIntegrationWavelengthMin);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorIntegralMax")[0],
-                     monitorIntegrationWavelengthMax);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("I0MonitorIndex")[0],
-                     i0MonitorIndex);
-    TS_ASSERT_EQUALS(inst->getNumberParameter("PointDetectorStart")[0],
-                     boost::lexical_cast<double>(pointDetectorStartStop[0]));
-    TS_ASSERT_EQUALS(pointDetectorStartStop.size(), 1);
-
-    // Remove workspace from the data service.
-    AnalysisDataService::Instance().remove(outWSQName);
-    AnalysisDataService::Instance().remove(outWSLamName);
-  }
-
-  void test_missing_instrument_parameters_throws() {
-    auto tinyWS =
-        WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument();
-    auto inst = tinyWS->getInstrument();
-
-    inst->getParameterMap()->addDouble(inst.get(), "I0MonitorIndex", 1.0);
-
-    tinyWS->mutableRun().addLogData(
-        new PropertyWithValue<double>("Theta", 0.12345));
-    tinyWS->mutableRun().addLogData(
-        new PropertyWithValue<std::string>("run_number", "12345"));
-
-    IAlgorithm_sptr alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    alg->setRethrows(true);
-    TS_ASSERT_THROWS_NOTHING(alg->initialize());
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("InputWorkspace", tinyWS));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspace", outWSQName));
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName));
-    TS_ASSERT_THROWS_ANYTHING(alg->execute());
-
-    // Remove workspace from the data service.
-    AnalysisDataService::Instance().remove(outWSQName);
-    AnalysisDataService::Instance().remove(outWSLamName);
-  }
-
-  void test_normalize_by_detmon() {
-    // Prepare workspace
-    //-----------------
-    // Single bin from 1->2
-    BinEdges x{1, 2};
-
-    // 2 spectra, 2 x values, 1 y value per spectra
-    auto tinyWS = createWorkspace<Workspace2D>(2, 2, 1);
-    tinyWS->setBinEdges(0, x);
-    tinyWS->setBinEdges(1, x);
-    tinyWS->setCounts(0, 1, 10.0);
-    tinyWS->setCountStandardDeviations(0, 1, 0.0);
-    tinyWS->setCounts(1, 1, 5.0);
-    tinyWS->setCountStandardDeviations(1, 1, 0.0);
-
-    tinyWS->setTitle("Test histogram");
-    tinyWS->getAxis(0)->setUnit("Wavelength");
-    tinyWS->setYUnit("Counts");
-
-    // Prepare instrument
-    //------------------
-    Instrument_sptr instrument = boost::make_shared<Instrument>();
-    instrument->setReferenceFrame(
-        boost::make_shared<ReferenceFrame>(Y, X, Left, "0,0,0"));
-
-    ObjComponent *source = new ObjComponent("source");
-    source->setPos(V3D(0, 0, 0));
-    instrument->add(source);
-    instrument->markAsSource(source);
-
-    ObjComponent *sample = new ObjComponent("some-surface-holder");
-    source->setPos(V3D(15, 0, 0));
-    instrument->add(sample);
-    instrument->markAsSamplePos(sample);
-
-    Detector *det = new Detector("point-detector", 1, nullptr);
-    det->setPos(20, (20 - sample->getPos().X()), 0);
-    instrument->add(det);
-    instrument->markAsDetector(det);
-
-    Detector *monitor = new Detector("Monitor", 2, nullptr);
-    monitor->setPos(14, 0, 0);
-    instrument->add(monitor);
-    instrument->markAsMonitor(monitor);
-
-    // Add instrument to workspace
-    tinyWS->setInstrument(instrument);
-    tinyWS->getSpectrum(0).addDetectorID(det->getID());
-    tinyWS->getSpectrum(1).addDetectorID(monitor->getID());
-
-    // Now we can parameterize the instrument
-    auto tinyInst = tinyWS->getInstrument();
-    ParameterMap_sptr params = tinyInst->getParameterMap();
-    params->addDouble(tinyInst.get(), "PointDetectorStart", 0.0);
-    params->addDouble(tinyInst.get(), "PointDetectorStop", 0.0);
-    params->addDouble(tinyInst.get(), "I0MonitorIndex", 1.0);
-    params->addDouble(tinyInst.get(), "LambdaMin", 0.0);
-    params->addDouble(tinyInst.get(), "LambdaMax", 10.0);
-    params->addDouble(tinyInst.get(), "MonitorBackgroundMin", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorBackgroundMax", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorIntegralMin", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorIntegralMax", 10.0);
-
-    tinyWS->mutableRun().addLogData(
-        new PropertyWithValue<double>("Theta", 0.1));
-
-    // Run the required algorithms
-    //---------------------------
-
-    // Convert units
-    IAlgorithm_sptr conv = AlgorithmManager::Instance().create("ConvertUnits");
-    conv->initialize();
-    conv->setProperty("InputWorkspace", tinyWS);
-    conv->setProperty("OutputWorkspace", inWSName);
-    conv->setProperty("Target", "TOF");
-    conv->execute();
-    TS_ASSERT(conv->isExecuted());
-
-    // Reduce
-    IAlgorithm_sptr alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    alg->setRethrows(true);
-    TS_ASSERT_THROWS_NOTHING(alg->initialize());
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("InputWorkspace", inWSName));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setProperty("NormalizeByIntegratedMonitors", false));
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspace", outWSQName));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName));
-    alg->execute();
-    TS_ASSERT(alg->isExecuted());
-
-    // Get results
-    MatrixWorkspace_sptr outWSLam =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
-            outWSLamName);
-
-    // Check results (10 / 5 = 2)
-    TS_ASSERT_DELTA(outWSLam->readY(0)[0], 2, 1e-5);
-    TS_ASSERT_DELTA(outWSLam->readX(0)[0], 1, 1e-5);
-    TS_ASSERT_DELTA(outWSLam->readX(0)[1], 2, 1e-5);
-
-    // Remove workspace from the data service.
-    AnalysisDataService::Instance().remove(inWSName);
-    AnalysisDataService::Instance().remove(outWSQName);
-    AnalysisDataService::Instance().remove(outWSLamName);
-  }
-
-  void test_i0_monitor_index_not_required() {
-    // Prepare instrument
-    //------------------
-    // hold the current instrument assigned to m_dataWorkspace
-    auto m_dataWorkspaceInstHolder = m_dataWorkspace->getInstrument();
-    Instrument_sptr instrument = boost::make_shared<Instrument>();
-    instrument->setReferenceFrame(
-        boost::make_shared<ReferenceFrame>(Y, X, Left, "0,0,0"));
-
-    ObjComponent *source = new ObjComponent("source");
-    source->setPos(V3D(0, 0, 0));
-    instrument->add(source);
-    instrument->markAsSource(source);
-
-    ObjComponent *sample = new ObjComponent("some-surface-holder");
-    source->setPos(V3D(15, 0, 0));
-    instrument->add(sample);
-    instrument->markAsSamplePos(sample);
-
-    Detector *det = new Detector("point-detector", 1, nullptr);
-    det->setPos(20, (20 - sample->getPos().X()), 0);
-    instrument->add(det);
-    instrument->markAsDetector(det);
-
-    Detector *monitor = new Detector("Monitor", 2, nullptr);
-    monitor->setPos(14, 0, 0);
-    instrument->add(monitor);
-    instrument->markAsMonitor(monitor);
-
-    // Add new instrument to workspace
-    m_dataWorkspace->setInstrument(instrument);
-
-    // Now we can parameterize the instrument
-    // without setting the I0MonitorIndex
-    auto tinyInst = m_dataWorkspace->getInstrument();
-    ParameterMap_sptr params = tinyInst->getParameterMap();
-    params->addDouble(tinyInst.get(), "PointDetectorStart", 0.0);
-    params->addDouble(tinyInst.get(), "PointDetectorStop", 0.0);
-    params->addDouble(tinyInst.get(), "LambdaMin", 0.0);
-    params->addDouble(tinyInst.get(), "LambdaMax", 10.0);
-    params->addDouble(tinyInst.get(), "MonitorBackgroundMin", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorBackgroundMax", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorIntegralMin", 0.0);
-    params->addDouble(tinyInst.get(), "MonitorIntegralMax", 10.0);
-
-    // Reduce
-    IAlgorithm_sptr alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1);
-    alg->setRethrows(true);
-    alg->setChild(true);
-    TS_ASSERT_THROWS_NOTHING(alg->initialize());
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setProperty("InputWorkspace", m_dataWorkspace));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setProperty("I0MonitorIndex", Mantid::EMPTY_INT()));
-    TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspace", outWSQName));
-    TS_ASSERT_THROWS_NOTHING(
-        alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName));
-    // we have intentionally not set
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-
-    // Remove workspace from the data service.
-    AnalysisDataService::Instance().remove(inWSName);
-    AnalysisDataService::Instance().remove(outWSQName);
-    AnalysisDataService::Instance().remove(outWSLamName);
-
-    // reset the instrument associated with m_dataWorkspace
-    m_dataWorkspace->setInstrument(m_dataWorkspaceInstHolder);
-  }
-  void test_point_detector_run_with_single_transmission_workspace() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(true);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "3,4");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setProperty("InputWorkspace", m_dataWorkspace);
-    alg.setProperty("FirstTransmissionRun", m_transWorkspace1);
-    alg.setProperty("ThetaIn", 0.2);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-
-    TS_ASSERT_THROWS_NOTHING(alg.execute());
-
-    double thetaOut = alg.getProperty("ThetaOut");
-    TSM_ASSERT_EQUALS("Theta in and out should be the same", thetaOut, 0.2);
-
-    MatrixWorkspace_sptr IvsLam = alg.getProperty("OutputWorkspaceWavelength");
-    TSM_ASSERT("OutputWorkspaceWavelength should be a valid matrix workspace",
-               IvsLam);
-
-    MatrixWorkspace_sptr IvsQ = alg.getProperty("OutputWorkspace");
-    TSM_ASSERT("OutputWorkspace should be a valid matrix workspace", IvsQ);
-
-    TSM_ASSERT_EQUALS("OutputWorkspaceWavelength should have two histograms",
-                      IvsLam->getNumberHistograms(), 2);
-  }
-
-  void test_point_detector_run_with_two_transmission_workspaces() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(true);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "3, 4");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setProperty("InputWorkspace", m_dataWorkspace);
-    alg.setProperty("FirstTransmissionRun", m_transWorkspace1);
-    alg.setProperty("SecondTransmissionRun", m_transWorkspace2);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-
-    TS_ASSERT_THROWS_NOTHING(alg.execute());
-  }
-
-  void test_spectrum_map_mismatch_throws_when_strict() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(true);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "3");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-
-    alg.setProperty("InputWorkspace", m_dataWorkspace);
-    alg.execute();
-
-    MatrixWorkspace_sptr trans = alg.getProperty("OutputWorkspaceWavelength");
-    alg.setProperty("FirstTransmissionRun", trans);
-    alg.setProperty("ProcessingInstructions", "4");
-    TS_ASSERT_THROWS_ANYTHING(alg.execute());
-  }
-
-  void test_spectrum_map_mismatch_doesnt_throw_when_not_strict() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(true);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "3");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-
-    alg.setProperty("InputWorkspace", m_dataWorkspace);
-    alg.execute();
-
-    MatrixWorkspace_sptr trans = alg.getProperty("OutputWorkspaceWavelength");
-    alg.setProperty("FirstTransmissionRun", trans);
-    alg.setProperty("ProcessingInstructions", "4");
-    alg.setProperty("StrictSpectrumChecking", "0");
-    TS_ASSERT_THROWS_NOTHING(alg.execute());
-  }
-
-  void test_multidetector_run() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(false);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "10");
-    alg.setProperty("AnalysisMode", "MultiDetectorAnalysis");
-    alg.setProperty("CorrectDetectorPositions", "0");
-    alg.setProperty("DetectorComponentName", "lineardetector");
-    alg.setProperty("RegionOfDirectBeam", "20, 30");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setProperty("ThetaIn", 0.1);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-    alg.setPropertyValue("InputWorkspace", "multidetector_group");
-
-    TS_ASSERT_THROWS_NOTHING(alg.execute());
-
-    MatrixWorkspace_sptr IvsLam_1 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsLam_1");
-    TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace",
-               IvsLam_1);
-    TS_ASSERT_EQUALS("Wavelength", IvsLam_1->getAxis(0)->unit()->unitID());
-    MatrixWorkspace_sptr IvsLam_2 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsLam_2");
-    TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace",
-               IvsLam_2);
-    TS_ASSERT_EQUALS("Wavelength", IvsLam_2->getAxis(0)->unit()->unitID());
-
-    MatrixWorkspace_sptr IvsQ_1 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsQ_1");
-    TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_1);
-    TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_1->getAxis(0)->unit()->unitID());
-    MatrixWorkspace_sptr IvsQ_2 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsQ_2");
-    TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_2);
-    TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_2->getAxis(0)->unit()->unitID());
-
-    MatrixWorkspace_sptr tempWS = boost::dynamic_pointer_cast<MatrixWorkspace>(
-        m_multiDetectorWorkspace->getItem(0));
-    auto instrBefore = tempWS->getInstrument();
-    auto detectorBefore = instrBefore->getComponentByName("lineardetector");
-    auto instrAfter = IvsLam_1->getInstrument();
-    auto detectorAfter = instrAfter->getComponentByName("lineardetector");
-    TS_ASSERT_DELTA(detectorBefore->getPos().Z(), detectorAfter->getPos().Z(),
-                    0.0001)
-
-    AnalysisDataService::Instance().remove("IvsLam");
-    AnalysisDataService::Instance().remove("IvsLam_1");
-    AnalysisDataService::Instance().remove("IvsLam_2");
-    AnalysisDataService::Instance().remove("IvsQ");
-    AnalysisDataService::Instance().remove("IvsQ_1");
-    AnalysisDataService::Instance().remove("IvsQ_2");
-  }
-
-  void test_multidetector_run_correct_positions() {
-    ReflectometryReductionOneAuto alg;
-    alg.initialize();
-    alg.setChild(false);
-    alg.setProperty("WavelengthMin", 1.0);
-    alg.setProperty("WavelengthMax", 2.0);
-    alg.setProperty("I0MonitorIndex", 0);
-    alg.setProperty("ProcessingInstructions", "73");
-    alg.setProperty("AnalysisMode", "MultiDetectorAnalysis");
-    alg.setProperty("CorrectDetectorPositions", "1");
-    alg.setProperty("DetectorComponentName", "lineardetector");
-    alg.setProperty("RegionOfDirectBeam", "28, 29");
-    alg.setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg.setProperty("MonitorBackgroundWavelengthMax", 1.0);
-    alg.setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg.setProperty("MonitorIntegrationWavelengthMax", 1.0);
-    alg.setProperty("ThetaIn", 0.49);
-    alg.setPropertyValue("OutputWorkspace", "IvsQ");
-    alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam");
-    alg.setPropertyValue("InputWorkspace", "multidetector_group");
-
-    TS_ASSERT_THROWS_NOTHING(alg.execute());
-
-    MatrixWorkspace_sptr IvsLam_1 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsLam_1");
-    TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace",
-               IvsLam_1);
-    TS_ASSERT_EQUALS("Wavelength", IvsLam_1->getAxis(0)->unit()->unitID());
-    MatrixWorkspace_sptr IvsLam_2 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsLam_2");
-    TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace",
-               IvsLam_2);
-    TS_ASSERT_EQUALS("Wavelength", IvsLam_2->getAxis(0)->unit()->unitID());
-
-    MatrixWorkspace_sptr IvsQ_1 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsQ_1");
-    TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_1);
-    TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_1->getAxis(0)->unit()->unitID());
-    MatrixWorkspace_sptr IvsQ_2 =
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("IvsQ_2");
-    TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_2);
-    TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_2->getAxis(0)->unit()->unitID());
-
-    auto instr = IvsLam_1->getInstrument();
-    auto detectorPos = instr->getComponentByName("lineardetector");
-    TS_ASSERT_DELTA(-0.05714, detectorPos->getPos().Z(), 0.0001)
-
-    AnalysisDataService::Instance().remove("IvsLam");
-    AnalysisDataService::Instance().remove("IvsLam_1");
-    AnalysisDataService::Instance().remove("IvsLam_2");
-    AnalysisDataService::Instance().remove("IvsQ");
-    AnalysisDataService::Instance().remove("IvsQ_1");
-    AnalysisDataService::Instance().remove("IvsQ_2");
-  }
-};
-
-#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_ */
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneTest.h b/Framework/Algorithms/test/ReflectometryReductionOneTest.h
deleted file mode 100644
index a8072ac9bd1df85b01ffa14a0eee9bb67922cccd..0000000000000000000000000000000000000000
--- a/Framework/Algorithms/test/ReflectometryReductionOneTest.h
+++ /dev/null
@@ -1,395 +0,0 @@
-#ifndef ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_
-#define ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_
-
-#include <cxxtest/TestSuite.h>
-#include <algorithm>
-#include "MantidAlgorithms/ReflectometryReductionOne.h"
-#include "MantidAPI/AlgorithmManager.h"
-#include "MantidAPI/Axis.h"
-#include "MantidAPI/FrameworkManager.h"
-#include "MantidAPI/MatrixWorkspace.h"
-#include "MantidTestHelpers/WorkspaceCreationHelper.h"
-#include "MantidGeometry/Instrument/ReferenceFrame.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidKernel/Unit.h"
-
-using namespace Mantid;
-using namespace Mantid::Kernel;
-using namespace Mantid::API;
-using namespace Mantid::Algorithms;
-using namespace Mantid::Geometry;
-using namespace WorkspaceCreationHelper;
-
-class ReflectometryReductionOneTest : public CxxTest::TestSuite {
-private:
-  MatrixWorkspace_sptr m_tinyReflWS;
-
-public:
-  // This pair of boilerplate methods prevent the suite being created statically
-  // This means the constructor isn't called when running other tests
-  static ReflectometryReductionOneTest *createSuite() {
-    return new ReflectometryReductionOneTest();
-  }
-  static void destroySuite(ReflectometryReductionOneTest *suite) {
-    delete suite;
-  }
-
-  ReflectometryReductionOneTest() {
-    FrameworkManager::Instance();
-    m_tinyReflWS = create2DWorkspaceWithReflectometryInstrument();
-  }
-
-  void test_tolam() {
-    MatrixWorkspace_sptr toConvert = m_tinyReflWS;
-    std::vector<int> detectorIndexRange;
-    size_t workspaceIndexToKeep1 = 1;
-    const int monitorIndex = 0;
-
-    specnum_t specId1 =
-        toConvert->getSpectrum(workspaceIndexToKeep1).getSpectrumNo();
-    specnum_t monitorSpecId =
-        toConvert->getSpectrum(monitorIndex).getSpectrumNo();
-
-    // Define one spectra to keep
-    detectorIndexRange.push_back(static_cast<int>(workspaceIndexToKeep1));
-    std::stringstream buffer;
-    buffer << workspaceIndexToKeep1;
-    const std::string detectorIndexRangesStr = buffer.str();
-
-    // Define a wavelength range for the detector workspace
-    const double wavelengthMin = 1.0;
-    const double wavelengthMax = 15;
-    const double backgroundWavelengthMin = 17;
-    const double backgroundWavelengthMax = 20;
-
-    ReflectometryReductionOne alg;
-
-    // Run the conversion.
-    ReflectometryWorkflowBase::DetectorMonitorWorkspacePair inLam =
-        alg.toLam(toConvert, detectorIndexRangesStr, monitorIndex,
-                  boost::tuple<double, double>(wavelengthMin, wavelengthMax),
-                  boost::tuple<double, double>(backgroundWavelengthMin,
-                                               backgroundWavelengthMax));
-
-    // Unpack the results
-    MatrixWorkspace_sptr detectorWS = inLam.get<0>();
-    MatrixWorkspace_sptr monitorWS = inLam.get<1>();
-
-    /* ---------- Checks for the detector workspace ------------------*/
-
-    // Check units.
-    TS_ASSERT_EQUALS("Wavelength", detectorWS->getAxis(0)->unit()->unitID());
-
-    // Check the number of spectrum kept.
-    TS_ASSERT_EQUALS(1, detectorWS->getNumberHistograms());
-
-    auto map = detectorWS->getSpectrumToWorkspaceIndexMap();
-    // Check the spectrum Nos retained.
-    TS_ASSERT_EQUALS(map[specId1], 0);
-
-    // Check the cropped x range
-    auto copyX = detectorWS->x(0);
-    std::sort(copyX.begin(), copyX.end());
-    TS_ASSERT(copyX.front() >= wavelengthMin);
-    TS_ASSERT(copyX.back() <= wavelengthMax);
-
-    /* ------------- Checks for the monitor workspace --------------------*/
-    // Check units.
-    TS_ASSERT_EQUALS("Wavelength", monitorWS->getAxis(0)->unit()->unitID());
-
-    // Check the number of spectrum kept. This should only ever be 1.
-    TS_ASSERT_EQUALS(1, monitorWS->getNumberHistograms());
-
-    map = monitorWS->getSpectrumToWorkspaceIndexMap();
-    // Check the spectrum Nos retained.
-    TS_ASSERT_EQUALS(map[monitorSpecId], 0);
-  }
-
-  IAlgorithm_sptr construct_standard_algorithm() {
-    auto alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOne", 1);
-    alg->setRethrows(true);
-    alg->setChild(true);
-    alg->initialize();
-    alg->setProperty("InputWorkspace", m_tinyReflWS);
-    alg->setProperty("WavelengthMin", 1.0);
-    alg->setProperty("WavelengthMax", 2.0);
-    alg->setProperty("I0MonitorIndex", 1);
-    alg->setProperty("MonitorBackgroundWavelengthMin", 1.0);
-    alg->setProperty("MonitorBackgroundWavelengthMax", 2.0);
-    alg->setProperty("MonitorIntegrationWavelengthMin", 1.2);
-    alg->setProperty("MonitorIntegrationWavelengthMax", 1.5);
-    alg->setProperty("MomentumTransferStep", 0.1);
-    alg->setPropertyValue("ProcessingInstructions", "0");
-    alg->setPropertyValue("OutputWorkspace", "x");
-    alg->setPropertyValue("OutputWorkspaceWavelength", "y");
-    alg->setRethrows(true);
-    return alg;
-  }
-
-  void test_execute() {
-    auto alg = construct_standard_algorithm();
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr workspaceInQ = alg->getProperty("OutputWorkspace");
-    MatrixWorkspace_sptr workspaceInLam =
-        alg->getProperty("OutputWorkspaceWavelength");
-    const double theta = alg->getProperty("ThetaOut");
-    UNUSED_ARG(theta)
-    UNUSED_ARG(workspaceInQ)
-    UNUSED_ARG(workspaceInLam)
-  }
-
-  void test_calculate_theta() {
-
-    auto alg = construct_standard_algorithm();
-
-    alg->execute();
-    // Should not throw
-
-    const double outTwoTheta = alg->getProperty("ThetaOut");
-    TS_ASSERT_DELTA(45.0, outTwoTheta, 0.00001);
-  }
-
-  void test_source_rotation_after_second_reduction() {
-    // set up the axis for the instrument
-    Instrument_sptr instrument = boost::make_shared<Instrument>();
-    instrument->setReferenceFrame(boost::make_shared<ReferenceFrame>(
-        Y /*up*/, Z /*along*/, Right, "0,0,0"));
-
-    // add a source
-    ObjComponent *source = new ObjComponent("source");
-    source->setPos(V3D(0, 0, -1));
-    instrument->add(source);
-    instrument->markAsSource(source);
-
-    // add a sample
-    ObjComponent *sample = new ObjComponent("some-surface-holder");
-    sample->setPos(V3D(0, 0, 0));
-    instrument->add(sample);
-    instrument->markAsSamplePos(sample);
-
-    // add a detector
-    Detector *det = new Detector("point-detector", 1, nullptr);
-    det->setPos(V3D(0, 1, 1));
-    instrument->add(det);
-    instrument->markAsDetector(det);
-
-    // set the instrument to this workspace
-    m_tinyReflWS->setInstrument(instrument);
-    // set this detector ready for processing instructions
-    m_tinyReflWS->getSpectrum(0).setDetectorID(det->getID());
-
-    auto alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOne", 1);
-    alg->setRethrows(true);
-    alg->setChild(true);
-    alg->initialize();
-    alg->setProperty("InputWorkspace", m_tinyReflWS);
-    alg->setProperty("WavelengthMin", 1.0);
-    alg->setProperty("WavelengthMax", 15.0);
-    alg->setProperty("I0MonitorIndex", 0);
-    alg->setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg->setProperty("MonitorBackgroundWavelengthMax", 0.0);
-    alg->setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg->setProperty("MonitorIntegrationWavelengthMax", 0.0);
-    alg->setProperty("MomentumTransferStep", 0.1);
-    alg->setProperty("NormalizeByIntegratedMonitors", false);
-    alg->setProperty("CorrectDetectorPositions", true);
-    alg->setProperty("CorrectionAlgorithm", "None");
-    alg->setPropertyValue("ProcessingInstructions", "1");
-    alg->setPropertyValue("OutputWorkspace", "x");
-    alg->setPropertyValue("OutputWorkspaceWavelength", "y");
-    alg->setRethrows(true);
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr outLam = alg->getProperty("OutputWorkspaceWavelength");
-    MatrixWorkspace_sptr outQ = alg->getProperty("OutputWorkspace");
-
-    TS_ASSERT_EQUALS(m_tinyReflWS->getInstrument()->getSource()->getPos(),
-                     outLam->getInstrument()->getSource()->getPos());
-    TS_ASSERT_EQUALS(outLam->getInstrument()->getSource()->getPos(),
-                     outQ->getInstrument()->getSource()->getPos());
-  }
-  void test_post_processing_scale_step() {
-    auto alg = construct_standard_algorithm();
-    auto inWS =
-        WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument(
-            2.0);
-    inWS->getAxis(0)->setUnit("Wavelength");
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("ScaleFactor", 1.0);
-    alg->setProperty("ThetaIn", 1.5);
-    alg->setProperty("OutputWorkspace", "Test");
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr nonScaledWS = alg->getProperty("OutputWorkspace");
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("ScaleFactor", 0.5);
-    alg->setProperty("OutputWorkspace", "scaledTest");
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr scaledWS = alg->getProperty("OutputWorkspace");
-    // compare y data instead of workspaces.
-    auto &scaledYData = scaledWS->y(0);
-    auto &nonScaledYData = nonScaledWS->y(0);
-    TS_ASSERT_EQUALS(scaledYData.front(), 2 * nonScaledYData.front());
-    TS_ASSERT_EQUALS(scaledYData[scaledYData.size() / 2],
-                     2 * nonScaledYData[nonScaledYData.size() / 2]);
-    TS_ASSERT_EQUALS(scaledYData.back(), 2 * nonScaledYData.back());
-    // Remove workspace from the data service.
-    AnalysisDataService::Instance().remove("Test");
-    AnalysisDataService::Instance().remove("scaledTest");
-  }
-  void test_post_processing_rebin_step_with_params_not_provided() {
-    auto alg = construct_standard_algorithm();
-    auto inWS = create2DWorkspace154(1, 10, true);
-    // this instrument does not have a "slit-gap" property
-    // defined in the IPF, so NRCalculateSlitResolution should throw.
-    inWS->setInstrument(m_tinyReflWS->getInstrument());
-    inWS->getAxis(0)->setUnit("Wavelength");
-    // Setup bad bin edges, Rebin will throw (not NRCalculateSlitResolution?)
-    inWS->mutableX(0) = inWS->x(0)[0];
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("OutputWorkspace", "rebinnedWS");
-    TS_ASSERT_THROWS(alg->execute(), std::invalid_argument);
-  }
-  void test_post_processing_rebin_step_with_partial_params_provided() {
-    auto alg = construct_standard_algorithm();
-    auto inWS = create2DWorkspace154(1, 10, true);
-    inWS->setInstrument(m_tinyReflWS->getInstrument());
-    inWS->getAxis(0)->setUnit("Wavelength");
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("MomentumTransferMaximum", 15.0);
-    alg->setProperty("OutputWorkspace", "rebinnedWS");
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace");
-    auto &xData = rebinnedIvsQWS->x(0);
-    // based off the equation for logarithmic binning X(i+1)=X(i)(1+|dX|)
-    double binWidthFromLogarithmicEquation = fabs((xData[1] / xData[0]) - 1);
-    TSM_ASSERT_DELTA("DQQ should be the same as abs(x[1]/x[0] - 1)",
-                     binWidthFromLogarithmicEquation, 0.1, 1e-06);
-    TSM_ASSERT_DELTA("Qmax should be the same as last Params entry (5.0)",
-                     xData.back(), 15.0, 1e-06);
-  }
-  void test_post_processing_rebin_step_with_logarithmic_rebinning() {
-    auto alg = construct_standard_algorithm();
-    auto inWS = create2DWorkspace154(1, 10, true);
-    inWS->setInstrument(m_tinyReflWS->getInstrument());
-    inWS->getAxis(0)->setUnit("Wavelength");
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("MomentumTransferMinimum", 1.0);
-    alg->setProperty("MomentumTransferStep", 0.2);
-    alg->setProperty("MomentumTransferMaximum", 5.0);
-    alg->setProperty("OutputWorkspace", "rebinnedWS");
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace");
-    auto &xData = rebinnedIvsQWS->x(0);
-    TSM_ASSERT_EQUALS("QMin should be the same as first Param entry (1.0)",
-                      xData[0], 1.0);
-    // based off the equation for logarithmic binning X(i+1)=X(i)(1+|dX|)
-    double binWidthFromLogarithmicEquation = fabs((xData[1] / xData[0]) - 1);
-    TSM_ASSERT_DELTA("DQQ should be the same as abs(x[1]/x[0] - 1)",
-                     binWidthFromLogarithmicEquation, 0.2, 1e-06);
-    TSM_ASSERT_EQUALS("QMax should be the same as last Param entry",
-                      xData.back(), 5.0);
-  }
-  void test_post_processing_rebin_step_with_linear_rebinning() {
-    auto alg = construct_standard_algorithm();
-    auto inWS = create2DWorkspace154(1, 10, true);
-    inWS->setInstrument(m_tinyReflWS->getInstrument());
-    inWS->getAxis(0)->setUnit("Wavelength");
-    alg->setProperty("InputWorkspace", inWS);
-    alg->setProperty("MomentumTransferMinimum", 1.577);
-    alg->setProperty("MomentumTransferStep", -0.2);
-    alg->setProperty("MomentumTransferMaximum", 5.233);
-    alg->setProperty("OutputWorkspace", "rebinnedWS");
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-    MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace");
-    auto &xData = rebinnedIvsQWS->x(0);
-    TSM_ASSERT_DELTA("QMin should be the same as the first Param entry (1.577)",
-                     xData[0], 1.577, 1e-06);
-    TSM_ASSERT_DELTA("DQQ should the same as 0.2", xData[1] - xData[0], 0.2,
-                     1e-06);
-    TSM_ASSERT_DELTA("QMax should be the same as the last Param entry (5.233)",
-                     xData.back(), 5.233, 1e-06);
-  }
-  void test_Qrange() {
-    // set up the axis for the instrument
-    Instrument_sptr instrument = boost::make_shared<Instrument>();
-    instrument->setReferenceFrame(boost::make_shared<ReferenceFrame>(
-        Y /*up*/, Z /*along*/, Right, "0,0,0"));
-
-    // add a source
-    ObjComponent *source = new ObjComponent("source");
-    source->setPos(V3D(0, 0, -1));
-    instrument->add(source);
-    instrument->markAsSource(source);
-
-    // add a sample
-    ObjComponent *sample = new ObjComponent("some-surface-holder");
-    sample->setPos(V3D(0, 0, 0));
-    instrument->add(sample);
-    instrument->markAsSamplePos(sample);
-
-    // add a detector
-    Detector *det = new Detector("point-detector", 1, nullptr);
-    det->setPos(V3D(0, 1, 1));
-    instrument->add(det);
-    instrument->markAsDetector(det);
-
-    // set the instrument to this workspace
-    m_tinyReflWS->setInstrument(instrument);
-    // set this detector ready for processing instructions
-    m_tinyReflWS->getSpectrum(0).setDetectorID(det->getID());
-
-    auto alg =
-        AlgorithmManager::Instance().create("ReflectometryReductionOne", 1);
-    alg->setRethrows(true);
-    alg->setChild(true);
-    alg->initialize();
-    alg->setProperty("InputWorkspace", m_tinyReflWS);
-    alg->setProperty("WavelengthMin", 1.0);
-    alg->setProperty("WavelengthMax", 15.0);
-    alg->setProperty("I0MonitorIndex", 0);
-    alg->setProperty("MonitorBackgroundWavelengthMin", 0.0);
-    alg->setProperty("MonitorBackgroundWavelengthMax", 0.0);
-    alg->setProperty("MonitorIntegrationWavelengthMin", 0.0);
-    alg->setProperty("MonitorIntegrationWavelengthMax", 0.0);
-    alg->setProperty("MomentumTransferStep", 0.1);
-    alg->setProperty("NormalizeByIntegratedMonitors", false);
-    alg->setProperty("CorrectDetectorPositions", true);
-    alg->setProperty("CorrectionAlgorithm", "None");
-    alg->setPropertyValue("ProcessingInstructions", "1");
-    alg->setPropertyValue("OutputWorkspace", "x");
-    alg->setPropertyValue("OutputWorkspaceWavelength", "y");
-    alg->setRethrows(true);
-    TS_ASSERT_THROWS_NOTHING(alg->execute());
-
-    // retrieve the IvsLam workspace
-    MatrixWorkspace_sptr inLam = alg->getProperty("OutputWorkspaceWavelength");
-    // retrieve the IvsQ workspace
-    MatrixWorkspace_sptr inQ = alg->getProperty("OutputWorkspace");
-    // retrieve our Theta
-    double outTheta = alg->getProperty("ThetaOut");
-
-    TS_ASSERT_DELTA(45.0, outTheta, 0.00001);
-    TS_ASSERT_EQUALS(source->getPos(),
-                     inQ->getInstrument()->getSource()->getPos());
-    // convert from degrees to radians for sin() function
-    double outThetaInRadians = outTheta * M_PI / 180;
-
-    double lamMin = inLam->x(0).front();
-    double lamMax = inLam->x(0).back();
-
-    // Derive our QMin and QMax from the equation
-    double qMinFromEQ = (4 * M_PI * sin(outThetaInRadians)) / lamMax;
-    double qMaxFromEQ = (4 * M_PI * sin(outThetaInRadians)) / lamMin;
-
-    // Get our QMin and QMax from the workspace
-    auto qMinFromWS = inQ->x(0).front();
-    auto qMaxFromWS = inQ->x(0).back();
-
-    // Compare the two values (they should be identical)
-    TS_ASSERT_DELTA(qMinFromEQ, qMinFromWS, 0.00001);
-    TS_ASSERT_DELTA(qMaxFromEQ, qMaxFromWS, 0.00001);
-  }
-};
-
-#endif /* ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_ */
diff --git a/Framework/Algorithms/test/RemoveBackgroundTest.h b/Framework/Algorithms/test/RemoveBackgroundTest.h
index c01c9209a077cc5256ef2ef3c76c8841d49e1f65..8139f055e6f27be7cd8e90c4ce43321777b1e007 100644
--- a/Framework/Algorithms/test/RemoveBackgroundTest.h
+++ b/Framework/Algorithms/test/RemoveBackgroundTest.h
@@ -195,8 +195,8 @@ public:
     auto clone = cloneSourceWS();
     // set negative values to signal
     auto &Y = clone->dataY(0);
-    for (size_t i = 0; i < Y.size(); i++) {
-      Y[i] = -1000;
+    for (double &i : Y) {
+      i = -1000;
     }
     // Create zero background workspace
     // Create the workspace
diff --git a/Framework/Algorithms/test/RunCombinationHelperTest.h b/Framework/Algorithms/test/RunCombinationHelperTest.h
index 3545278c02b8566f13f1ef4bde72be731ae3138d..154f72f6e45db91f3c45b0b4f9cf854e5b245218 100644
--- a/Framework/Algorithms/test/RunCombinationHelperTest.h
+++ b/Framework/Algorithms/test/RunCombinationHelperTest.h
@@ -9,15 +9,18 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidHistogramData/HistogramDx.h"
 #include "MantidAlgorithms/CreateSampleWorkspace.h"
 #include "MantidAlgorithms/GroupWorkspaces.h"
 #include "MantidKernel/UnitFactory.h"
+#include "MantidKernel/make_cow.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using Mantid::Algorithms::RunCombinationHelper;
 using Mantid::Algorithms::GroupWorkspaces;
 using Mantid::Algorithms::CreateSampleWorkspace;
 using namespace Mantid::API;
+using namespace Mantid::HistogramData;
 using namespace Mantid::Kernel;
 using namespace WorkspaceCreationHelper;
 
@@ -122,6 +125,16 @@ public:
                      "different X units; different spectrum axis units; ");
   }
 
+  void testIncompatibleDx() {
+    // create a workspace where spectrum 1 has Dx
+    MatrixWorkspace_sptr ws2 = m_reference->clone();
+    auto dx =
+        Mantid::Kernel::make_cow<Mantid::HistogramData::HistogramDx>(3, 0.2);
+    ws2->setSharedDx(1, dx);
+    TS_ASSERT_EQUALS(m_testee.checkCompatibility(ws2),
+                     "spectra must have either Dx values or not; ");
+  }
+
   void test_scanning_workspaces_throw_no_error() {
     const auto scanWS1 = createSampleScanningWorkspace(2);
     const auto scanWS2 = createSampleScanningWorkspace(2);
diff --git a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
index 989a5db08afb529893d4136852ba96c7d3a1f44d..f4b89655dea41c2ac3ab7715133004950c8d25fa 100644
--- a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
+++ b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
@@ -51,7 +51,7 @@ createTestInstrument(const Mantid::detid_t id,
   Detector *det0(nullptr);
   if (!detShapeXML.empty()) {
     auto shape = ShapeFactory().createShape(detShapeXML);
-    det0 = new Detector("det0", id, shape, NULL);
+    det0 = new Detector("det0", id, shape, nullptr);
   } else {
     det0 = new Detector("det0", id, nullptr);
   }
diff --git a/Framework/Algorithms/test/SassenaFFTTest.h b/Framework/Algorithms/test/SassenaFFTTest.h
index 4c15d0aa2fc5219da2356e5a9f2e1f2b96e7434c..a5736da301499ef73005aad7a142507008b6b799 100644
--- a/Framework/Algorithms/test/SassenaFFTTest.h
+++ b/Framework/Algorithms/test/SassenaFFTTest.h
@@ -144,10 +144,10 @@ private:
       double sum = 0.0;
       double average = 0.0;
       MantidVec::iterator itx = xv.begin();
-      for (MantidVec::iterator it = yv.begin(); it != yv.end(); ++it) {
+      for (double &y : yv) {
         factor = exp(exponentFactor * (*itx));
-        sum += (*it) * factor;
-        average += (*it) * (*itx) * factor;
+        sum += y * factor;
+        average += y * (*itx) * factor;
         ++itx;
       }
       average /= sum;
@@ -186,9 +186,9 @@ private:
       xv = ws->readX(i);
       MantidVec::iterator itx = xv.begin();
       double sum = 0.0;
-      for (MantidVec::iterator it = yv.begin(); it != yv.end(); ++it) {
+      for (double &y : yv) {
         factor = exp(exponentFactor * (*itx));
-        sum += (*it) * factor;
+        sum += y * factor;
         ++itx;
       }
       sum *= dx / static_cast<double>(nbins);
diff --git a/Framework/Algorithms/test/SofQCommonTest.h b/Framework/Algorithms/test/SofQCommonTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fdd5ecc550627489ac0a9b2410922b0ab428bb7
--- /dev/null
+++ b/Framework/Algorithms/test/SofQCommonTest.h
@@ -0,0 +1,270 @@
+#ifndef MANTID_ALGORITHMS_SOFQCOMMONTEST_H
+#define MANTID_ALGORITHMS_SOFQCOMMONTEST_H
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/SofQCommon.h"
+
+#include "MantidAlgorithms/SofQW.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidKernel/PhysicalConstants.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
+class SofQCommonTest : 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 SofQCommonTest *createSuite() { return new SofQCommonTest(); }
+  static void destroySuite(SofQCommonTest *suite) { delete suite; }
+
+  void test_initDirectGeometryEiFromSampleLogs() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Direct");
+    Algorithms::SofQCommon s;
+    auto ws = create2DWorkspaceWithFullInstrument(1, 1);
+    const double Ei{2.3};
+    ws->mutableRun().addProperty("Ei", Ei);
+    s.initCachedValues(*ws, &alg);
+    TS_ASSERT_EQUALS(s.m_emode, 1)
+    TS_ASSERT_EQUALS(s.m_efixed, Ei)
+  }
+
+  void test_initDirectGeometryEiFromAlgorithm() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Direct");
+    const double Ei{2.3};
+    alg.setProperty("EFixed", Ei);
+    Algorithms::SofQCommon s;
+    auto ws = create2DWorkspaceWithFullInstrument(1, 1);
+    s.initCachedValues(*ws, &alg);
+    TS_ASSERT_EQUALS(s.m_emode, 1)
+    TS_ASSERT_EQUALS(s.m_efixed, Ei)
+  }
+
+  void test_initIndirectGeometry() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    const double Ef{2.3};
+    alg.setProperty("EFixed", Ef);
+    Algorithms::SofQCommon s;
+    auto ws = create2DWorkspaceWithFullInstrument(1, 1);
+    s.initCachedValues(*ws, &alg);
+    TS_ASSERT_EQUALS(s.m_emode, 2)
+    TS_ASSERT_EQUALS(s.m_efixed, Ef)
+  }
+
+  void test_getEFixedDirectGeometry() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Direct");
+    const double Ei{2.3};
+    alg.setProperty("EFixed", Ei);
+    Algorithms::SofQCommon s;
+    auto ws = create2DWorkspaceWithFullInstrument(13, 1);
+    s.initCachedValues(*ws, &alg);
+    const auto &detectorInfo = ws->detectorInfo();
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      TS_ASSERT_EQUALS(s.getEFixed(detectorInfo.detector(i)), Ei);
+    }
+  }
+
+  void test_getEFixedFromDetectorsIndirectGeometry() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    Algorithms::SofQCommon s;
+    const size_t nHist{13};
+    auto ws = create2DWorkspaceWithFullInstrument(nHist, 1);
+    for (size_t i = 0; i < nHist; ++i) {
+      const auto comp = "pixel-" + std::to_string(i) + ")";
+      const auto Ef = static_cast<double>(i) + 0.38;
+      setEFixed(ws, comp, Ef);
+    }
+    s.initCachedValues(*ws, &alg);
+    const auto &detectorInfo = ws->detectorInfo();
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      const auto E = static_cast<double>(i) + 0.38;
+      TS_ASSERT_EQUALS(s.getEFixed(detectorInfo.detector(i)), E);
+    }
+  }
+
+  void test_getEFixedIndirectGeometryAlgorithPropertiesOverrideIPF() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    const double Ef{2.3};
+    alg.setProperty("EFixed", Ef);
+    Algorithms::SofQCommon s;
+    const size_t nHist{13};
+    auto ws = create2DWorkspaceWithFullInstrument(nHist, 1);
+    for (size_t i = 0; i < nHist; ++i) {
+      const auto comp = "pixel-" + std::to_string(i) + ")";
+      const auto eParam = static_cast<double>(i) + 0.77;
+      setEFixed(ws, comp, eParam);
+    }
+    s.initCachedValues(*ws, &alg);
+    const auto &detectorInfo = ws->detectorInfo();
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      TS_ASSERT_EQUALS(s.getEFixed(detectorInfo.detector(i)), Ef);
+    }
+  }
+
+  void test_qBinHintsDirect() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Direct");
+    Algorithms::SofQCommon s;
+    const size_t nBins{23};
+    auto ws = create2DWorkspaceWithFullInstrument(1, nBins);
+    const auto minDeltaE = ws->x(0).front();
+    const auto maxDeltaE = ws->x(0).back();
+    const auto Ei = 2. * static_cast<double>(nBins);
+    ws->mutableRun().addProperty("Ei", Ei);
+    const auto minQ = directQ(Ei, minDeltaE);
+    const auto maxQ = directQ(Ei, maxDeltaE);
+    s.initCachedValues(*ws, &alg);
+    double minE;
+    double maxE;
+    ws->getXMinMax(minE, maxE);
+    const auto minmaxQ = s.qBinHints(*ws, minE, maxE);
+    TS_ASSERT(minmaxQ.first < minmaxQ.second)
+    TS_ASSERT_EQUALS(minmaxQ.first, minQ)
+    TS_ASSERT_DELTA(minmaxQ.second, maxQ, 1e-12)
+  }
+
+  void test_qBinHintsIndirect() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    Algorithms::SofQCommon s;
+    const size_t nBins{23};
+    const size_t nDets{2};
+    auto ws = create2DWorkspaceWithFullInstrument(nDets, nBins);
+    const auto &spectrumInfo = ws->spectrumInfo();
+    const auto twoTheta0 = spectrumInfo.twoTheta(0);
+    const auto twoTheta1 = spectrumInfo.twoTheta(1);
+    const double eFixed0{3.7};
+    const double eFixed1{2.3};
+    setEFixed(ws, "pixel-0)", eFixed0);
+    setEFixed(ws, "pixel-1)", eFixed1);
+    const auto minDeltaE = ws->x(0).front();
+    const auto maxDeltaE = ws->x(0).back();
+    const auto minQ = std::min(indirectQ(eFixed0, minDeltaE, twoTheta0),
+                               indirectQ(eFixed1, minDeltaE, twoTheta1));
+    const auto maxQ = std::max(indirectQ(eFixed0, maxDeltaE, twoTheta1),
+                               indirectQ(eFixed1, maxDeltaE, twoTheta1));
+    s.initCachedValues(*ws, &alg);
+    double minE;
+    double maxE;
+    ws->getXMinMax(minE, maxE);
+    const auto minmaxQ = s.qBinHints(*ws, minE, maxE);
+    TS_ASSERT_EQUALS(minmaxQ.first, minQ)
+    TS_ASSERT_DELTA(minmaxQ.second, maxQ, 1e-12)
+  }
+
+  void testDirectQ() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Direct");
+    Algorithms::SofQCommon s;
+    const size_t nBins{1};
+    auto ws = create2DWorkspaceWithFullInstrument(5, nBins);
+    const auto Ei = 4.2;
+    ws->mutableRun().addProperty("Ei", Ei);
+    s.initCachedValues(*ws, &alg);
+    const auto &detectorInfo = ws->detectorInfo();
+    const auto testDeltaE = -Ei / 1.8;
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      const auto twoTheta = detectorInfo.twoTheta(i);
+      const auto expected = directQ(Ei, testDeltaE, twoTheta);
+      TS_ASSERT_EQUALS(s.q(testDeltaE, twoTheta, nullptr), expected)
+    }
+  }
+
+  void testIndirectQ() {
+    using namespace Mantid;
+    using namespace WorkspaceCreationHelper;
+    Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    Algorithms::SofQCommon s;
+    const size_t nBins{1};
+    auto ws = create2DWorkspaceWithFullInstrument(2, nBins);
+    const std::array<double, 2> Ef{{3.7, 2.3}};
+    setEFixed(ws, "pixel-0)", Ef[0]);
+    setEFixed(ws, "pixel-1)", Ef[1]);
+    s.initCachedValues(*ws, &alg);
+    const auto &detectorInfo = ws->detectorInfo();
+    const auto testDeltaE = -1.8;
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      const auto &det = detectorInfo.detector(i);
+      const auto twoTheta = detectorInfo.twoTheta(i);
+      const auto expected = indirectQ(Ef[i], testDeltaE, twoTheta);
+      TS_ASSERT_DELTA(s.q(testDeltaE, twoTheta, &det), expected, 1e-12)
+    }
+  }
+
+private:
+  static double k(const double E) {
+    using namespace Mantid;
+    using PhysicalConstants::h_bar;
+    using PhysicalConstants::meV;
+    using PhysicalConstants::NeutronMass;
+    return std::sqrt(2 * NeutronMass * E * meV) / h_bar * 1e-10;
+  }
+
+  static double indirectQ(const double Ef, const double DeltaE,
+                          const double twoTheta = 0.) {
+    const auto kf = k(Ef);
+    const auto Ei = Ef + DeltaE;
+    const auto ki = k(Ei);
+    return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(twoTheta));
+  }
+
+  static double directQ(const double Ei, const double DeltaE,
+                        const double twoTheta = 0.) {
+    const auto ki = k(Ei);
+    const auto Ef = Ei - DeltaE;
+    const auto kf = k(Ef);
+    return std::sqrt(ki * ki + kf * kf - 2. * ki * kf * std::cos(twoTheta));
+  }
+
+  static void setEFixed(Mantid::API::MatrixWorkspace_sptr ws,
+                        const std::string &component, const double eFixed) {
+    using namespace Mantid;
+    auto alg = API::AlgorithmManager::Instance().createUnmanaged(
+        "SetInstrumentParameter");
+    alg->initialize();
+    alg->setChild(true);
+    alg->setProperty("Workspace", ws);
+    alg->setProperty("ComponentName", component);
+    alg->setProperty("ParameterName", "EFixed");
+    alg->setProperty("ParameterType", "Number");
+    alg->setProperty("Value", std::to_string(eFixed));
+    alg->execute();
+  }
+};
+
+#endif /* MANTID_ALGORITHMS_SOFQCOMMONTEST_H */
diff --git a/Framework/Algorithms/test/SofQWCutTest.h b/Framework/Algorithms/test/SofQWCutTest.h
index 93f98324fcaa6b6e0b94500c46071ac522bb585c..60f86cc05a0ceaa4101f5f2029446d09eac94a50 100644
--- a/Framework/Algorithms/test/SofQWCutTest.h
+++ b/Framework/Algorithms/test/SofQWCutTest.h
@@ -12,6 +12,7 @@
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Unit.h"
 #include "MantidDataHandling/LoadNexusProcessed.h"
+#include "MantidDataHandling/CreateSimulationWorkspace.h"
 
 #include <boost/make_shared.hpp>
 
@@ -188,16 +189,16 @@ public:
     TS_ASSERT_EQUALS((*(ws_q->getAxis(1)))(0), 0.0);
     TS_ASSERT_DELTA((*(ws_q->getAxis(1)))(400), 5.0, delta);
     TS_ASSERT_EQUALS((*(ws_q->getAxis(1)))(800), 10.);
-    TS_ASSERT_DELTA(ws_q->readY(64)[0], 0.144715421, delta);
-    TS_ASSERT_DELTA(ws_q->readE(64)[0], 0.007981350, delta);
-    TS_ASSERT_DELTA(ws_q->readY(345)[0], 0.658678386, delta);
-    TS_ASSERT_DELTA(ws_q->readE(345)[0], 0.029371568, delta);
-    TS_ASSERT_DELTA(ws_q->readY(595)[0], 0.159563545, delta);
-    TS_ASSERT_DELTA(ws_q->readE(595)[0], 0.012046158, delta);
-    TS_ASSERT_DELTA(ws_q->readY(683)[0], 0.178108225, delta);
-    TS_ASSERT_DELTA(ws_q->readE(683)[0], 0.019119298, delta);
-    TS_ASSERT_DELTA(ws_q->readY(745)[0], 2.086237760, delta);
-    TS_ASSERT_DELTA(ws_q->readE(745)[0], 0.048837503, delta);
+    TS_ASSERT_DELTA(ws_q->readY(64)[0], 1.447154208, delta);
+    TS_ASSERT_DELTA(ws_q->readE(64)[0], 0.079813500, delta);
+    TS_ASSERT_DELTA(ws_q->readY(345)[0], 6.586783859, delta);
+    TS_ASSERT_DELTA(ws_q->readE(345)[0], 0.293715678, delta);
+    TS_ASSERT_DELTA(ws_q->readY(595)[0], 1.595635453, delta);
+    TS_ASSERT_DELTA(ws_q->readE(595)[0], 0.120461583, delta);
+    TS_ASSERT_DELTA(ws_q->readY(683)[0], 1.781082246, delta);
+    TS_ASSERT_DELTA(ws_q->readE(683)[0], 0.191192978, delta);
+    TS_ASSERT_DELTA(ws_q->readY(745)[0], 20.862377605, delta);
+    TS_ASSERT_DELTA(ws_q->readE(745)[0], 0.488375031, delta);
 
     auto ws_e =
         boost::dynamic_pointer_cast<MatrixWorkspace>(result->getItem(1));
@@ -210,16 +211,57 @@ public:
     TS_ASSERT_EQUALS(ws_e->getAxis(1)->unit()->unitID(), "MomentumTransfer");
     TS_ASSERT_EQUALS((*(ws_e->getAxis(1)))(0), 5.);
     TS_ASSERT_EQUALS((*(ws_e->getAxis(1)))(1), 10.);
-    TS_ASSERT_DELTA(ws_e->readY(0)[3], 2.003485282, delta);
-    TS_ASSERT_DELTA(ws_e->readE(0)[3], 0.013726709, delta);
-    TS_ASSERT_DELTA(ws_e->readY(0)[20], 0.136945077, delta);
-    TS_ASSERT_DELTA(ws_e->readE(0)[20], 0.003767914, delta);
-    TS_ASSERT_DELTA(ws_e->readY(0)[27], 0.158356991, delta);
-    TS_ASSERT_DELTA(ws_e->readE(0)[27], 0.004113822, delta);
-    TS_ASSERT_DELTA(ws_e->readY(0)[78], 0.197240860, delta);
-    TS_ASSERT_DELTA(ws_e->readE(0)[78], 0.005446083, delta);
-    TS_ASSERT_DELTA(ws_e->readY(0)[119], 0.027223857, delta);
-    TS_ASSERT_DELTA(ws_e->readE(0)[119], 0.003277629, delta);
+    TS_ASSERT_DELTA(ws_e->readY(0)[3], 3.339142136, delta);
+    TS_ASSERT_DELTA(ws_e->readE(0)[3], 0.022877849, delta);
+    TS_ASSERT_DELTA(ws_e->readY(0)[20], 0.228241794, delta);
+    TS_ASSERT_DELTA(ws_e->readE(0)[20], 0.006279856, delta);
+    TS_ASSERT_DELTA(ws_e->readY(0)[27], 0.263928319, delta);
+    TS_ASSERT_DELTA(ws_e->readE(0)[27], 0.006856371, delta);
+    TS_ASSERT_DELTA(ws_e->readY(0)[78], 0.328734767, delta);
+    TS_ASSERT_DELTA(ws_e->readE(0)[78], 0.009076805, delta);
+    TS_ASSERT_DELTA(ws_e->readY(0)[119], 0.045373095, delta);
+    TS_ASSERT_DELTA(ws_e->readE(0)[119], 0.005462714, delta);
+  }
+
+  void test_sofqw3_zerobinwidth() {
+    // This test sets up a workspace which can yield a bin with zero width
+    // to check the code FractionalRebinning code handles this correctly
+    const double delta(1e-08);
+    Mantid::DataHandling::CreateSimulationWorkspace create_ws;
+    create_ws.initialize();
+    create_ws.setChild(true);
+    create_ws.setPropertyValue("Instrument", "MARI");
+    create_ws.setPropertyValue("BinParams", "-5,0.5,24");
+    create_ws.setPropertyValue("OutputWorkspace", "__unused");
+    create_ws.execute();
+
+    MatrixWorkspace_sptr createdWS = create_ws.getProperty("OutputWorkspace");
+    auto inWS = boost::dynamic_pointer_cast<MatrixWorkspace>(createdWS);
+    // Sets one spectrum to zero so final value is not unity.
+    inWS->setCounts(300, std::vector<double>(58, 0.));
+
+    Mantid::Algorithms::SofQWNormalisedPolygon sqw;
+    sqw.initialize();
+    sqw.setChild(true);
+    TS_ASSERT_THROWS_NOTHING(sqw.setProperty("InputWorkspace", inWS));
+    TS_ASSERT_THROWS_NOTHING(
+        sqw.setPropertyValue("OutputWorkspace", "__unused"));
+    TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("QAxisBinning", "0,10,10"));
+    TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("EMode", "Direct"));
+    TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("EFixed", "25"));
+    TS_ASSERT_THROWS_NOTHING(
+        sqw.setPropertyValue("EAxisBinning", "-1.5,3,1.5"));
+    TS_ASSERT_THROWS_NOTHING(sqw.execute());
+    TS_ASSERT(sqw.isExecuted());
+
+    MatrixWorkspace_sptr ws = sqw.getProperty("OutputWorkspace");
+    TS_ASSERT_EQUALS(ws->getAxis(0)->length(), 2);
+    TS_ASSERT_EQUALS(ws->getAxis(0)->unit()->unitID(), "DeltaE");
+    TS_ASSERT_EQUALS((*(ws->getAxis(0)))(0), -1.5);
+    TS_ASSERT_EQUALS((*(ws->getAxis(0)))(1), 1.5);
+    TS_ASSERT_EQUALS(ws->getAxis(1)->length(), 2);
+    TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->unitID(), "MomentumTransfer");
+    TS_ASSERT_DELTA(ws->readY(0)[0], 0.998910675, delta);
   }
 };
 
diff --git a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
index 26588e4816b39cd7e799f6d47617fdc5da4630ff..1cdb86180f20448cd3dada8eaea5f9ddcf9f4a3b 100644
--- a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
+++ b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
@@ -62,7 +62,7 @@ public:
 
     // Spectra-detector mapping
     const size_t nspectra(6);
-    typedef std::set<int> IDSet;
+    using IDSet = std::set<int>;
     std::vector<IDSet> expectedIDs(nspectra);
     IDSet s1 = {3};
     expectedIDs[0] = s1;
@@ -85,6 +85,117 @@ public:
       TS_ASSERT_EQUALS(expectedIDs[i], spectrum.getDetectorIDs());
     }
   }
+
+  void testEAndQBinningParams() {
+    // SofQWNormalisedPolygon uses it's own setUpOutputWorkspace while
+    // the other SofQW* algorithms use the one in SofQW.
+    auto inWS = SofQWTest::loadTestFile();
+    Mantid::Algorithms::SofQWNormalisedPolygon alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inWS))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "_unused"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EMode", "Indirect"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EFixed", 1.84))
+    const std::vector<double> eBinParams{-0.5, 0.1, -0.1, 0.2, 0.4};
+    const std::vector<double> expectedEBinEdges{-0.5, -0.4, -0.3, -0.2,
+                                                -0.1, 0.1,  0.3,  0.4};
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EAxisBinning", eBinParams))
+    const std::vector<double> qBinParams{0.5, 0.1, 1.0, 0.2, 2.};
+    const std::vector<double> expectedQBinEdges{0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
+                                                1.2, 1.4, 1.6, 1.8, 2.};
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("QAxisBinning", qBinParams))
+    TS_ASSERT_THROWS_NOTHING(alg.execute())
+    TS_ASSERT(alg.isExecuted())
+    Mantid::API::MatrixWorkspace_sptr outWS =
+        alg.getProperty("OutputWorkspace");
+    TS_ASSERT_EQUALS(outWS->getNumberHistograms(), expectedQBinEdges.size() - 1)
+    for (size_t i = 0; i < outWS->getNumberHistograms(); ++i) {
+      const auto &x = outWS->x(i);
+      for (size_t j = 0; j < x.size(); ++j) {
+        TS_ASSERT_DELTA(x[j], expectedEBinEdges[j], 1e-12)
+      }
+    }
+    const auto axis = outWS->getAxis(1);
+    TS_ASSERT_EQUALS(axis->length(), expectedQBinEdges.size())
+    for (size_t i = 0; i < axis->length(); ++i) {
+      TS_ASSERT_DELTA(axis->getValue(i), expectedQBinEdges[i], 1e-12)
+    }
+  }
+
+  void testEBinWidthAsEAxisBinning() {
+    // SofQWNormalisedPolygon uses it's own setUpOutputWorkspace while
+    // the other SofQW* algorithms use the one in SofQW.
+    auto inWS = SofQWTest::loadTestFile();
+    Mantid::Algorithms::SofQWNormalisedPolygon alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inWS))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "_unused"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EMode", "Indirect"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EFixed", 1.84))
+    const double dE{0.3};
+    const std::vector<double> eBinParams{dE};
+    std::vector<double> expectedEBinEdges;
+    const auto firstEdge = inWS->x(0).front();
+    const auto lastEdge = inWS->x(0).back();
+    auto currentEdge = firstEdge;
+    while (currentEdge < lastEdge) {
+      expectedEBinEdges.emplace_back(currentEdge);
+      currentEdge += dE;
+    }
+    expectedEBinEdges.emplace_back(lastEdge);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EAxisBinning", eBinParams))
+    const std::vector<double> qBinParams{0.5, 0.1, 1.0, 0.2, 2.};
+    const std::vector<double> expectedQBinEdges{0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
+                                                1.2, 1.4, 1.6, 1.8, 2.};
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("QAxisBinning", qBinParams))
+    TS_ASSERT_THROWS_NOTHING(alg.execute())
+    TS_ASSERT(alg.isExecuted())
+    Mantid::API::MatrixWorkspace_sptr outWS =
+        alg.getProperty("OutputWorkspace");
+    TS_ASSERT_EQUALS(outWS->getNumberHistograms(), expectedQBinEdges.size() - 1)
+    for (size_t i = 0; i < outWS->getNumberHistograms(); ++i) {
+      const auto &x = outWS->x(i);
+      for (size_t j = 0; j < x.size(); ++j) {
+        TS_ASSERT_DELTA(x[j], expectedEBinEdges[j], 1e-12)
+      }
+    }
+    const auto axis = outWS->getAxis(1);
+    TS_ASSERT_EQUALS(axis->length(), expectedQBinEdges.size())
+    for (size_t i = 0; i < axis->length(); ++i) {
+      TS_ASSERT_DELTA(axis->getValue(i), expectedQBinEdges[i], 1e-12)
+    }
+  }
+
+  void testQBinWidthAsQAxisBinning() {
+    // SofQWNormalisedPolygon uses it's own setUpOutputWorkspace while
+    // the other SofQW* algorithms use the one in SofQW.
+    auto inWS = SofQWTest::loadTestFile();
+    Mantid::Algorithms::SofQWNormalisedPolygon alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inWS))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "_unused"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EMode", "Indirect"))
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("EFixed", 1.84))
+    const double dQ{0.023};
+    const std::vector<double> qBinParams{dQ};
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("QAxisBinning", qBinParams))
+    TS_ASSERT_THROWS_NOTHING(alg.execute())
+    TS_ASSERT(alg.isExecuted())
+    Mantid::API::MatrixWorkspace_sptr outWS =
+        alg.getProperty("OutputWorkspace");
+    const auto axis = outWS->getAxis(1);
+    // Test only the Q bin width, not the actual edges.
+    for (size_t i = 0; i < axis->length() - 1; ++i) {
+      const auto delta = axis->getValue(i + 1) - axis->getValue(i);
+      TS_ASSERT_DELTA(delta, dQ, 1e-12);
+    }
+  }
 };
 
 class SofQWNormalisedPolygonTestPerformance : public CxxTest::TestSuite {
diff --git a/Framework/Algorithms/test/SofQWPolygonTest.h b/Framework/Algorithms/test/SofQWPolygonTest.h
index ba471e5d45036188061b8f0ce6f96708cc4b8b2d..a4befaa06112d4984025c45337264b40d362ec11 100644
--- a/Framework/Algorithms/test/SofQWPolygonTest.h
+++ b/Framework/Algorithms/test/SofQWPolygonTest.h
@@ -59,7 +59,7 @@ public:
 
     // Spectra-detector mapping
     const size_t nspectra(6);
-    typedef std::set<int> IDSet;
+    using IDSet = std::set<int>;
     std::vector<IDSet> expectedIDs(nspectra);
     IDSet s1 = {3};
     expectedIDs[0] = s1;
diff --git a/Framework/Algorithms/test/SofQWTest.h b/Framework/Algorithms/test/SofQWTest.h
index 695e9b5dbb6361df26bfe01a4be8a52f0a32528a..003d3e9f9ce4695eed28a1447832391925d7d41d 100644
--- a/Framework/Algorithms/test/SofQWTest.h
+++ b/Framework/Algorithms/test/SofQWTest.h
@@ -3,12 +3,14 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/SofQW.h"
+#include "MantidAlgorithms/SofQCommon.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/Unit.h"
 #include "MantidDataHandling/LoadNexusProcessed.h"
+#include "MantidDataObjects/Workspace2D.h"
 
 #include <boost/make_shared.hpp>
 
@@ -16,9 +18,7 @@ using namespace Mantid::API;
 
 class SofQWTest : public CxxTest::TestSuite {
 public:
-  template <typename SQWType>
-  static Mantid::API::MatrixWorkspace_sptr
-  runSQW(const std::string &method = "") {
+  static Mantid::API::MatrixWorkspace_sptr loadTestFile() {
     Mantid::DataHandling::LoadNexusProcessed loader;
     loader.initialize();
     loader.setChild(true);
@@ -31,15 +31,21 @@ public:
     auto inWS =
         boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(loadedWS);
     WorkspaceHelpers::makeDistribution(inWS);
+    return inWS;
+  }
+
+  template <typename SQWType>
+  static Mantid::API::MatrixWorkspace_sptr
+  runSQW(const std::string &method = "") {
+    auto inWS = loadTestFile();
 
     SQWType sqw;
     sqw.initialize();
+    sqw.setRethrows(true);
     // Cannot be marked as child or history is not recorded
     TS_ASSERT_THROWS_NOTHING(sqw.setProperty("InputWorkspace", inWS));
-    std::ostringstream wsname;
-    wsname << "_tmp_" << loadedWS;
-    TS_ASSERT_THROWS_NOTHING(
-        sqw.setPropertyValue("OutputWorkspace", wsname.str()));
+    const std::string wsname{"_tmp_"};
+    TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("OutputWorkspace", wsname));
     TS_ASSERT_THROWS_NOTHING(
         sqw.setPropertyValue("QAxisBinning", "0.5,0.25,2"));
     TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("EMode", "Indirect"));
@@ -51,9 +57,8 @@ public:
     TS_ASSERT(sqw.isExecuted());
 
     auto &dataStore = Mantid::API::AnalysisDataService::Instance();
-    auto result =
-        dataStore.retrieveWS<Mantid::API::MatrixWorkspace>(wsname.str());
-    dataStore.remove(wsname.str());
+    auto result = dataStore.retrieveWS<Mantid::API::MatrixWorkspace>(wsname);
+    dataStore.remove(wsname);
 
     return result;
   }
@@ -130,9 +135,121 @@ public:
     TS_ASSERT(!nanFound);
   }
 
+  void testSetUpOutputWorkspace() {
+    auto inWS = loadTestFile();
+    Mantid::Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    alg.setProperty("EFixed", 1.84);
+    Mantid::Algorithms::SofQCommon emodeProperties;
+    emodeProperties.initCachedValues(*inWS, &alg);
+    const std::vector<double> eBinParams{-0.5, 0.1, -0.1, 0.2, 0.4};
+    const std::vector<double> expectedEBinEdges{-0.5, -0.4, -0.3, -0.2,
+                                                -0.1, 0.1,  0.3,  0.4};
+    const std::vector<double> qBinParams{0.5, 0.1, 1.0, 0.2, 2.};
+    const std::vector<double> expectedQBinEdges{0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
+                                                1.2, 1.4, 1.6, 1.8, 2.};
+    std::vector<double> qAxis;
+    auto outWS = Mantid::Algorithms::SofQW::setUpOutputWorkspace<
+        Mantid::DataObjects::Workspace2D>(*inWS, qBinParams, qAxis, eBinParams,
+                                          emodeProperties);
+    TS_ASSERT_EQUALS(outWS->getNumberHistograms(), expectedQBinEdges.size() - 1)
+    for (size_t i = 0; i < outWS->getNumberHistograms(); ++i) {
+      const auto &x = outWS->x(i);
+      for (size_t j = 0; j < x.size(); ++j) {
+        TS_ASSERT_DELTA(x[j], expectedEBinEdges[j], 1e-12)
+      }
+    }
+    const auto axis = outWS->getAxis(1);
+    TS_ASSERT_EQUALS(axis->length(), qAxis.size())
+    TS_ASSERT_EQUALS(qAxis.size(), expectedQBinEdges.size())
+    for (size_t i = 0; i < qAxis.size(); ++i) {
+      TS_ASSERT_EQUALS(axis->getValue(i), qAxis[i])
+      TS_ASSERT_DELTA(qAxis[i], expectedQBinEdges[i], 1e-12)
+    }
+  }
+
+  void testSetUpOutputWorkspaceWithEnergyBinWidthOnly() {
+    auto inWS = loadTestFile();
+
+    Mantid::Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    alg.setProperty("EFixed", 1.84);
+    Mantid::Algorithms::SofQCommon emodeProperties;
+    emodeProperties.initCachedValues(*inWS, &alg);
+    const double dE{0.3};
+    const std::vector<double> eBinParams{dE};
+    std::vector<double> expectedEBinEdges;
+    const auto firstEdge = inWS->x(0).front();
+    const auto lastEdge = inWS->x(0).back();
+    auto currentEdge = firstEdge;
+    while (currentEdge < lastEdge) {
+      expectedEBinEdges.emplace_back(currentEdge);
+      currentEdge += dE;
+    }
+    expectedEBinEdges.emplace_back(lastEdge);
+    const std::vector<double> qBinParams{0.5, 0.25, 2.};
+    const std::vector<double> expectedQBinEdges{0.5, 0.75, 1., 1.25,
+                                                1.5, 1.75, 2.};
+    std::vector<double> qAxis;
+    auto outWS = Mantid::Algorithms::SofQW::setUpOutputWorkspace<
+        Mantid::DataObjects::Workspace2D>(*inWS, qBinParams, qAxis, eBinParams,
+                                          emodeProperties);
+    TS_ASSERT_EQUALS(outWS->getNumberHistograms(), expectedQBinEdges.size() - 1)
+    for (size_t i = 0; i < outWS->getNumberHistograms(); ++i) {
+      const auto &x = outWS->x(i);
+      for (size_t j = 0; j < x.size(); ++j) {
+        TS_ASSERT_DELTA(x[j], expectedEBinEdges[j], 1e-12)
+      }
+    }
+    const auto axis = outWS->getAxis(1);
+    TS_ASSERT_EQUALS(axis->length(), qAxis.size())
+    TS_ASSERT_EQUALS(qAxis.size(), expectedQBinEdges.size())
+    for (size_t i = 0; i < qAxis.size(); ++i) {
+      TS_ASSERT_EQUALS(axis->getValue(i), qAxis[i])
+      TS_ASSERT_DELTA(qAxis[i], expectedQBinEdges[i], 1e-12)
+    }
+  }
+
+  void testSetUpOutputWorkspaceWithQBinWidthOnly() {
+    auto inWS = loadTestFile();
+
+    Mantid::Algorithms::SofQW alg;
+    alg.initialize();
+    alg.setProperty("EMode", "Indirect");
+    alg.setProperty("EFixed", 1.84);
+    Mantid::Algorithms::SofQCommon emodeProperties;
+    emodeProperties.initCachedValues(*inWS, &alg);
+    const std::vector<double> eBinParams{-0.3, 0.2, 0.5};
+    const std::vector<double> expectedEBinEdges{-0.3, -0.1, 0.1, 0.3, 0.5};
+    const double dQ{0.023};
+    const std::vector<double> qBinParams{dQ};
+    std::vector<double> qAxis;
+    auto outWS = Mantid::Algorithms::SofQW::setUpOutputWorkspace<
+        Mantid::DataObjects::Workspace2D>(*inWS, qBinParams, qAxis, eBinParams,
+                                          emodeProperties);
+    for (size_t i = 0; i < outWS->getNumberHistograms(); ++i) {
+      const auto &x = outWS->x(i);
+      for (size_t j = 0; j < x.size(); ++j) {
+        TS_ASSERT_DELTA(x[j], expectedEBinEdges[j], 1e-12)
+      }
+    }
+    const auto axis = outWS->getAxis(1);
+    TS_ASSERT_EQUALS(axis->length(), qAxis.size())
+    for (size_t i = 0; i < qAxis.size(); ++i) {
+      TS_ASSERT_EQUALS(axis->getValue(i), qAxis[i])
+    }
+    // Test only the Q bin width, not the actual edges.
+    for (size_t i = 0; i < qAxis.size() - 1; ++i) {
+      const auto delta = qAxis[i + 1] - qAxis[i];
+      TS_ASSERT_DELTA(delta, dQ, 1e-12);
+    }
+  }
+
 private:
-  bool isAlgorithmInHistory(const Mantid::API::MatrixWorkspace &result,
-                            const std::string &name) {
+  static bool isAlgorithmInHistory(const Mantid::API::MatrixWorkspace &result,
+                                   const std::string &name) {
     // Loaded nexus file has 13 other entries
     const auto &wsHistory = result.getHistory();
     const auto &lastAlg = wsHistory.getAlgorithmHistory(wsHistory.size() - 1);
diff --git a/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h b/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h
index b30cda65156c17ee563dffa678e106d7c1481c78..4ff1d63a9e9601f9d45942d6934778c072d45f25 100644
--- a/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h
+++ b/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h
@@ -22,7 +22,7 @@
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
 
-typedef boost::tuple<double, double> VerticalHorizontalOffsetType;
+using VerticalHorizontalOffsetType = boost::tuple<double, double>;
 
 class SpecularReflectionAlgorithmTest {
 protected:
diff --git a/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h b/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h
index e9e8e0b82c0253f9e8b28d9462af3f47dda102d0..b142f1198f844e2cd67af99c6a656e2b2ea79cda 100644
--- a/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h
+++ b/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h
@@ -20,7 +20,7 @@ private:
   // Initialise the algorithm and set the properties
   void setupAlgorithm(SpecularReflectionPositionCorrect2 &alg,
                       const double twoTheta, const std::string &correctionType,
-                      const std::string &detectorName) {
+                      const std::string &detectorName, int detectorID = 0) {
     if (!alg.isInitialized())
       alg.initialize();
     alg.setChild(true);
@@ -30,6 +30,8 @@ private:
       alg.setProperty("DetectorCorrectionType", correctionType);
     if (!detectorName.empty())
       alg.setProperty("DetectorComponentName", detectorName);
+    if (detectorID > 0)
+      alg.setProperty("DetectorID", detectorID);
     alg.setPropertyValue("OutputWorkspace", "test_out");
   }
 
@@ -103,6 +105,17 @@ public:
   }
 
   void test_detector_component_is_valid() {
+    SpecularReflectionPositionCorrect2 alg;
+    alg.initialize();
+    alg.setChild(true);
+    alg.setProperty("InputWorkspace", m_interWS);
+    alg.setProperty("DetectorID", 222222222);
+    alg.setProperty("TwoTheta", 1.4);
+    alg.setPropertyValue("OutputWorkspace", "test_out");
+    TS_ASSERT_THROWS_ANYTHING(alg.execute());
+  }
+
+  void test_detector_id_is_valid() {
     SpecularReflectionPositionCorrect2 alg;
     alg.initialize();
     alg.setChild(true);
@@ -147,6 +160,28 @@ public:
     TS_ASSERT_DELTA(detOut.Y(), 0.06508, 1e-5);
   }
 
+  void test_correct_point_detector_via_detid_vertical_shift_default() {
+    // Omit the DetectorCorrectionType property to check that a vertical shift
+    // is done by default
+    SpecularReflectionPositionCorrect2 alg;
+    setupAlgorithm(alg, 1.4, "", "", 4);
+    MatrixWorkspace_const_sptr outWS = runAlgorithm(alg);
+
+    auto instrIn = m_interWS->getInstrument();
+    auto instrOut = outWS->getInstrument();
+
+    // Sample should not have moved
+    auto sampleIn = instrIn->getSample()->getPos();
+    auto sampleOut = instrOut->getSample()->getPos();
+    TS_ASSERT_EQUALS(sampleIn, sampleOut);
+    // 'point-detector' should have been moved vertically only
+    auto detIn = instrIn->getComponentByName("point-detector")->getPos();
+    auto detOut = instrOut->getComponentByName("point-detector")->getPos();
+    TS_ASSERT_EQUALS(detIn.X(), detOut.X());
+    TS_ASSERT_EQUALS(detIn.Z(), detOut.Z());
+    TS_ASSERT_DELTA(detOut.Y(), 0.06508, 1e-5);
+  }
+
   void test_correct_point_detector_rotation() {
     SpecularReflectionPositionCorrect2 alg;
     setupAlgorithm(alg, 1.4, "RotateAroundSample", "point-detector");
@@ -164,7 +199,28 @@ public:
     auto detIn = instrIn->getComponentByName("point-detector")->getPos();
     auto detOut = instrOut->getComponentByName("point-detector")->getPos();
     TS_ASSERT_EQUALS(detIn.X(), detOut.X());
-    TS_ASSERT_DELTA(detOut.Z(), 19.69921, 1e-5);
+    TS_ASSERT_DELTA(detOut.Z(), 2.66221, 1e-5);
+    TS_ASSERT_DELTA(detOut.Y(), 0.06506, 1e-5);
+  }
+
+  void test_correct_point_detector_by_detid_rotation() {
+    SpecularReflectionPositionCorrect2 alg;
+    setupAlgorithm(alg, 1.4, "RotateAroundSample", "", 4);
+    MatrixWorkspace_const_sptr outWS = runAlgorithm(alg);
+
+    auto instrIn = m_interWS->getInstrument();
+    auto instrOut = outWS->getInstrument();
+
+    // Sample should not have moved
+    auto sampleIn = instrIn->getSample()->getPos();
+    auto sampleOut = instrOut->getSample()->getPos();
+    TS_ASSERT_EQUALS(sampleIn, sampleOut);
+    // 'point-detector' should have been moved  both vertically and in
+    // the beam direction
+    auto detIn = instrIn->getComponentByName("point-detector")->getPos();
+    auto detOut = instrOut->getComponentByName("point-detector")->getPos();
+    TS_ASSERT_EQUALS(detIn.X(), detOut.X());
+    TS_ASSERT_DELTA(detOut.Z(), 2.66221, 1e-5);
     TS_ASSERT_DELTA(detOut.Y(), 0.06506, 1e-5);
   }
 
@@ -205,7 +261,7 @@ public:
     auto detIn = instrIn->getComponentByName("linear-detector")->getPos();
     auto detOut = instrOut->getComponentByName("linear-detector")->getPos();
     TS_ASSERT_EQUALS(detIn.X(), detOut.X());
-    TS_ASSERT_DELTA(detOut.Z(), 20.19906, 1e-5);
+    TS_ASSERT_DELTA(detOut.Z(), 3.162055, 1e-5);
     TS_ASSERT_DELTA(detOut.Y(), 0.07728, 1e-5);
   }
 };
diff --git a/Framework/Algorithms/test/Stitch1DTest.h b/Framework/Algorithms/test/Stitch1DTest.h
index 5c23756d31daf65d1f72cdba44108cf2940aba9d..fab1d86938b60529bf8f2eecc7e7f8c50685acf9 100644
--- a/Framework/Algorithms/test/Stitch1DTest.h
+++ b/Framework/Algorithms/test/Stitch1DTest.h
@@ -66,7 +66,7 @@ private:
   MatrixWorkspace_sptr a;
   MatrixWorkspace_sptr b;
   std::vector<double> x;
-  typedef boost::tuple<MatrixWorkspace_sptr, double> ResultType;
+  using ResultType = boost::tuple<MatrixWorkspace_sptr, double>;
 
   MatrixWorkspace_sptr make_arbitrary_point_ws() {
     const auto &x = HistogramX(3, LinearGenerator(-1, 0.2));
@@ -384,8 +384,7 @@ public:
     }
     // Check that the output E-Values are correct. Output Error values should
     // all be zero
-    for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) {
-      double temp = *itr;
+    for (double temp : stitched_e) {
       TS_ASSERT_EQUALS(temp, 0);
     }
     // Check that the output X-Values are correct.
@@ -416,8 +415,7 @@ public:
     }
     // Check that the output E-Values are correct. Output Error values should
     // all be zero
-    for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) {
-      double temp = *itr;
+    for (double temp : stitched_e) {
       TS_ASSERT_EQUALS(temp, 0);
     }
     // Check that the output X-Values are correct.
@@ -449,8 +447,7 @@ public:
     }
     // Check that the output E-Values are correct. Output Error values should
     // all be zero
-    for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) {
-      double temp = *itr;
+    for (double temp : stitched_e) {
       TS_ASSERT_EQUALS(temp, 0);
     }
     // Check that the output X-Values are correct.
@@ -482,8 +479,7 @@ public:
     }
     // Check that the output E-Values are correct. Output Error values should
     // all be zero
-    for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) {
-      double temp = *itr;
+    for (double temp : stitched_e) {
       TS_ASSERT_EQUALS(temp, 0);
     }
     // Check that the output X-Values are correct.
diff --git a/Framework/Algorithms/test/SumOverlappingTubesTest.h b/Framework/Algorithms/test/SumOverlappingTubesTest.h
index c1b6ff578798d6e851ef6fc587e671c81df28f25..cee05ac312192a436b356c94376469b6d3a004d3 100644
--- a/Framework/Algorithms/test/SumOverlappingTubesTest.h
+++ b/Framework/Algorithms/test/SumOverlappingTubesTest.h
@@ -5,15 +5,15 @@
 
 #include "MantidAlgorithms/SumOverlappingTubes.h"
 
-#include "MantidAPI/Axis.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/Axis.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/ScanningWorkspaceBuilder.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidIndexing/IndexInfo.h"
-#include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTypes/Core/DateAndTime.h"
 
@@ -98,14 +98,15 @@ public:
     return testWS;
   }
 
-  void verifySuccessCase(double expectedCounts = 2.0) {
+  void verifySuccessCase(double expectedCounts = 2.0,
+                         double expectedErrors = sqrt(2.0)) {
     MatrixWorkspace_sptr outWS =
         boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
             AnalysisDataService::Instance().retrieve("outWS"));
 
     verifyScatteringAngleAxis(outWS, N_TUBES);
     verifyHeightAxis(outWS);
-    verifySpectraHaveSameCounts(outWS, expectedCounts);
+    verifySpectraHaveSameCounts(outWS, expectedCounts, expectedErrors);
   }
 
   void verifyScatteringAngleAxis(const MatrixWorkspace_sptr &outWS,
@@ -127,13 +128,13 @@ public:
 
   void verifySpectraHaveSameCounts(MatrixWorkspace_sptr outWS,
                                    double expectedCounts = 2.0,
+                                   double expectedErrors = sqrt(2.0),
                                    bool checkErrors = true) {
     for (size_t i = 0; i < N_TUBES; ++i)
       for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
         TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[i], expectedCounts, 1e-6)
         if (checkErrors)
-          TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[i], sqrt(expectedCounts),
-                          1e-6)
+          TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[i], expectedErrors, 1e-6)
       }
   }
 
@@ -196,6 +197,7 @@ public:
     alg.setProperty("OutputWorkspace", "outWS");
     alg.setProperty("OutputType", "2DTubes");
     alg.setProperty("ScatteringAngleBinning", "22.5");
+    alg.setProperty("MirrorScatteringAngles", true);
     TS_ASSERT_THROWS_NOTHING(alg.execute());
 
     MatrixWorkspace_sptr outWS =
@@ -209,7 +211,7 @@ public:
       TS_ASSERT_DELTA(xAxis->getValue(i), 22.5 * double(i), 1e-6)
 
     verifyHeightAxis(outWS);
-    verifySpectraHaveSameCounts(outWS, 2.0);
+    verifySpectraHaveSameCounts(outWS, 2.0, sqrt(2.0));
 
     AnalysisDataService::Instance().remove("testWS");
     AnalysisDataService::Instance().remove("outWS");
@@ -318,7 +320,7 @@ public:
     alg.setProperty("ScatteringAngleBinning", "22.5");
     TS_ASSERT_THROWS_NOTHING(alg.execute());
 
-    verifySuccessCase(6.0);
+    verifySuccessCase(2.0, sqrt(6) / 3.);
 
     AnalysisDataService::Instance().remove("testWS");
     AnalysisDataService::Instance().remove("outWS");
@@ -490,7 +492,7 @@ public:
     verifyScatteringAngleAxis(outWS, N_TUBES + 2);
     verifyHeightAxis(outWS);
 
-    verifySpectraHaveSameCounts(outWS, 6.0, false);
+    verifySpectraHaveSameCounts(outWS, 2.0, sqrt(2.0), false);
 
     AnalysisDataService::Instance().remove("testWS");
     AnalysisDataService::Instance().remove("outWS");
@@ -518,35 +520,33 @@ public:
 
     size_t bin = 0;
     for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 6.0, 1e-6)
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(2.0) * 3.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 2.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(2.0), 1e-6)
     }
 
     bin = 1;
     for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 6.0, 1e-6)
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(4.0) * 3.0 / 2.0,
-                      1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 2.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(4.0) / 2.0, 1e-6)
     }
 
     for (size_t i = 2; i < 5; ++i) {
       for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
-        TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[i], 6.0, 1e-6)
-        TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[i], sqrt(6.0), 1e-6)
+        TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[i], 2.0, 1e-6)
+        TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[i], sqrt(6.0) / 3., 1e-6)
       }
     }
 
     bin = 5;
     for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 6.0, 1e-6)
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(4.0) * 3.0 / 2.0,
-                      1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 2.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(4.0) / 2.0, 1e-6)
     }
 
     bin = 6;
     for (size_t j = 0; j < N_PIXELS_PER_TUBE; ++j) {
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 6.0, 1e-6)
-      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(2.0) * 3.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).y()[bin], 2.0, 1e-6)
+      TS_ASSERT_DELTA(outWS->getSpectrum(j).e()[bin], sqrt(2.0), 1e-6)
     }
 
     AnalysisDataService::Instance().remove("testWS");
@@ -567,6 +567,7 @@ public:
     alg.setProperty("Normalise", false);
     if (oneDimensional)
       alg.setProperty("OutputType", "1D");
+    alg.setProperty("MirrorScatteringAngles", false);
     TS_ASSERT_THROWS_NOTHING(alg.execute());
 
     auto outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
diff --git a/Framework/Algorithms/test/SumSpectraTest.h b/Framework/Algorithms/test/SumSpectraTest.h
index 3fe7fb648fd8cc4de5800048391f868e8746c2c3..0e212da443f363f6cbf1525a4ae4ae29a8d8b8ec 100644
--- a/Framework/Algorithms/test/SumSpectraTest.h
+++ b/Framework/Algorithms/test/SumSpectraTest.h
@@ -39,6 +39,89 @@ public:
     TS_ASSERT(alg.isInitialized());
   }
 
+  void testValidateInputsWithDefaultsPasses() {
+    Mantid::Algorithms::SumSpectra runner;
+    runner.initialize();
+    auto validationErrors = runner.validateInputs();
+    TS_ASSERT(validationErrors.empty());
+  }
+
+  void testValidateInputsWithMinGreaterThanMaxReturnErrors() {
+    Mantid::Algorithms::SumSpectra runner;
+    runner.initialize();
+    runner.setProperty("StartWorkspaceIndex", 10);
+    runner.setProperty("EndWorkspaceIndex", 9);
+    auto validationErrors = runner.validateInputs();
+    TS_ASSERT_EQUALS(2, validationErrors.size());
+    TSM_ASSERT_THROWS_NOTHING(
+        "Validation errors should contain a StartWorkspaceIndex entry",
+        validationErrors["StartWorkspaceIndex"]);
+    TSM_ASSERT_THROWS_NOTHING(
+        "Validation errors should contain an EndWorkspaceIndex entry",
+        validationErrors["EndWorkspaceIndex"]);
+  }
+
+  void testValidateInputsWithWorkspaceChecksAgainstWorkspaceSize() {
+    Mantid::Algorithms::SumSpectra runner;
+    runner.setChild(true);
+    runner.initialize();
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace123(3, 1);
+
+    // bad start workspace index
+    runner.setProperty("InputWorkspace", testWS);
+    runner.setProperty("StartWorkspaceIndex", 3);
+    auto validationErrors = runner.validateInputs();
+    TS_ASSERT_EQUALS(1, validationErrors.size());
+    TSM_ASSERT_THROWS_NOTHING(
+        "Validation errors should contain a StartWorkspaceIndex entry",
+        validationErrors["StartWorkspaceIndex"]);
+
+    // bad end workspace index
+    runner.setProperty("StartWorkspaceIndex", 0);
+    runner.setProperty("EndWorkspaceIndex", 5);
+    validationErrors = runner.validateInputs();
+    TS_ASSERT_EQUALS(1, validationErrors.size());
+    TSM_ASSERT_THROWS_NOTHING(
+        "Validation errors should contain a EndWorkspaceIndex entry",
+        validationErrors["EndWorkspaceIndex"]);
+  }
+
+  void testValidateInputsWithValidWorkspaceGroup() {
+    Mantid::Algorithms::SumSpectra runner;
+    runner.setChild(true);
+    runner.initialize();
+    const std::string nameStem(
+        "SumSpectraTest_testValidateInputsWithValidWorkspaceGroup");
+    auto testGroup =
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 1, 1, nameStem);
+    runner.setProperty("InputWorkspace", nameStem);
+
+    auto validationErrors = runner.validateInputs();
+    TS_ASSERT(validationErrors.empty());
+
+    Mantid::API::AnalysisDataService::Instance().remove(nameStem);
+  }
+
+  void testValidateInputsWithWorkspaceGroupAndInvalidIndex() {
+    Mantid::Algorithms::SumSpectra runner;
+    runner.setChild(true);
+    runner.initialize();
+    const std::string nameStem(
+        "SumSpectraTest_testValidateInputsWithWorkspaceGroupAndInvalidIndex");
+    auto testGroup =
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 1, 1, nameStem);
+    runner.setPropertyValue("InputWorkspace", nameStem);
+    runner.setProperty("StartWorkspaceIndex", 11);
+
+    auto validationErrors = runner.validateInputs();
+    TS_ASSERT_EQUALS(1, validationErrors.size());
+    TSM_ASSERT_THROWS_NOTHING(
+        "Validation errors should contain StartWorkspaceIndex",
+        validationErrors["StartWorkspaceIndex"]);
+
+    Mantid::API::AnalysisDataService::Instance().remove(nameStem);
+  }
+
   void testExecWithLimits() {
     if (!alg.isInitialized()) {
       alg.initialize();
diff --git a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
index 980b8035bf049eb687f0ab7d8ae3ed3f94b73fc0..7d7ddbd661f76f61a94df2939604bc62e9b08518 100644
--- a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
+++ b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
@@ -62,7 +62,7 @@ createTestInstrument(const Mantid::detid_t id,
   Detector *det0(nullptr);
   if (!detShapeXML.empty()) {
     auto shape = ShapeFactory().createShape(detShapeXML);
-    det0 = new Detector("det0", id, shape, NULL);
+    det0 = new Detector("det0", id, shape, nullptr);
   } else {
     det0 = new Detector("det0", id, nullptr);
   }
diff --git a/Framework/Algorithms/test/UnGroupWorkspaceTest.h b/Framework/Algorithms/test/UnGroupWorkspaceTest.h
index 70a5ea9404c01f1d1bb99a5e6f909149074df88e..62e6379b4d41eda4f2fa52b3b87c464f8824728e 100644
--- a/Framework/Algorithms/test/UnGroupWorkspaceTest.h
+++ b/Framework/Algorithms/test/UnGroupWorkspaceTest.h
@@ -102,8 +102,8 @@ private:
     auto newGroup = boost::make_shared<Mantid::API::WorkspaceGroup>();
 
     auto &ads = Mantid::API::AnalysisDataService::Instance();
-    for (auto it = inputs.begin(); it != inputs.end(); ++it) {
-      auto ws = addTestMatrixWorkspaceToADS(*it);
+    for (const auto &input : inputs) {
+      auto ws = addTestMatrixWorkspaceToADS(input);
       newGroup->addWorkspace(ws);
     }
     ads.add(name, newGroup);
@@ -120,9 +120,9 @@ private:
   void removeFromADS(const std::vector<std::string> &members) {
     auto &ads = Mantid::API::AnalysisDataService::Instance();
 
-    for (auto it = members.begin(); it != members.end(); ++it) {
-      if (ads.doesExist(*it))
-        ads.remove(*it);
+    for (const auto &member : members) {
+      if (ads.doesExist(member))
+        ads.remove(member);
     }
   }
 };
diff --git a/Framework/Algorithms/test/WorkspaceCreationHelperTest.h b/Framework/Algorithms/test/WorkspaceCreationHelperTest.h
index f56173e6a3f265fb1237bd961ed00aa21cbe32b5..e788871524e4bfade6d5977e735470f3d60f3c72 100644
--- a/Framework/Algorithms/test/WorkspaceCreationHelperTest.h
+++ b/Framework/Algorithms/test/WorkspaceCreationHelperTest.h
@@ -1,14 +1,9 @@
 #ifndef MANTID_ALGORITHMS_WORKSPACECREATIONHELPERTEST_H_
 #define MANTID_ALGORITHMS_WORKSPACECREATIONHELPERTEST_H_
 
-#include "MantidKernel/System.h"
-#include "MantidKernel/Timer.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cxxtest/TestSuite.h>
-#include "MantidAPI/SpectraDetectorTypes.h"
 
-using namespace Mantid;
-using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
 /** Test class for the helpers in MantidTestHelpers/WorkspaceCreationHelper.h */
@@ -36,6 +31,19 @@ public:
     TS_ASSERT(ws->getSpectrum(0).hasDetectorID(100));
     TS_ASSERT(ws->getSpectrum(1).hasDetectorID(101));
   }
+
+  void test_create2DWorkspaceWithValues() {
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace123(
+        1, 2, false, std::set<int64_t>(), true);
+    TS_ASSERT(ws);
+    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
+    TS_ASSERT_EQUALS(ws->size(), 2);
+    TS_ASSERT(ws->hasDx(0));
+    TS_ASSERT_EQUALS(ws->dx(0).rawData()[0], 2.);
+    Workspace2D_sptr ws2 = WorkspaceCreationHelper::create2DWorkspace123(
+        1, 2, false, std::set<int64_t>(), false);
+    TS_ASSERT(!ws2->hasDx(0));
+  }
 };
 
 #endif /* MANTID_ALGORITHMS_WORKSPACECREATIONHELPERTEST_H_ */
diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
index edc8082ed89b61c42102e1cca799997351da7dff..a8883732d2d26155b18d85df9c08f5eb57da20b8 100644
--- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
+++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h
@@ -52,6 +52,7 @@ private:
   boost::shared_ptr<const std::vector<std::pair<size_t, size_t>>>
       m_componentRanges;
   boost::shared_ptr<const std::vector<size_t>> m_parentIndices;
+  boost::shared_ptr<std::vector<std::vector<size_t>>> m_children;
   Mantid::Kernel::cow_ptr<std::vector<Eigen::Vector3d>> m_positions;
   Mantid::Kernel::cow_ptr<std::vector<
       Eigen::Quaterniond, Eigen::aligned_allocator<Eigen::Quaterniond>>>
@@ -98,6 +99,7 @@ public:
       boost::shared_ptr<const std::vector<std::pair<size_t, size_t>>>
           componentRanges,
       boost::shared_ptr<const std::vector<size_t>> parentIndices,
+      boost::shared_ptr<std::vector<std::vector<size_t>>> children,
       boost::shared_ptr<std::vector<Eigen::Vector3d>> positions,
       boost::shared_ptr<std::vector<
           Eigen::Quaterniond, Eigen::aligned_allocator<Eigen::Quaterniond>>>
@@ -112,7 +114,9 @@ public:
   std::unique_ptr<ComponentInfo> cloneWithoutDetectorInfo() const;
   std::vector<size_t> detectorsInSubtree(const size_t componentIndex) const;
   std::vector<size_t> componentsInSubtree(const size_t componentIndex) const;
+  const std::vector<size_t> &children(const size_t componentIndex) const;
   size_t size() const;
+  size_t numberOfDetectorsInSubtree(const size_t componentIndex) const;
   bool isDetector(const size_t componentIndex) const {
     return componentIndex < m_assemblySortedDetectorIndices->size();
   }
diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentType.h b/Framework/Beamline/inc/MantidBeamline/ComponentType.h
index 9548fac56244a43b907f5b23df7afe5c59c72efc..c5e33293a06915eef466511ce25289f9311aa010 100644
--- a/Framework/Beamline/inc/MantidBeamline/ComponentType.h
+++ b/Framework/Beamline/inc/MantidBeamline/ComponentType.h
@@ -6,6 +6,7 @@ namespace Mantid {
 namespace Beamline {
 enum class ComponentType {
   Generic,
+  Infinite,
   Rectangular,
   Structured,
   Unstructured,
diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp
index 2e53c46e4701f61f27dc7d83f3181585efc2d2f0..6baef33046eb9e3973cd0eee83ee5f21f78b384c 100644
--- a/Framework/Beamline/src/ComponentInfo.cpp
+++ b/Framework/Beamline/src/ComponentInfo.cpp
@@ -38,6 +38,7 @@ ComponentInfo::ComponentInfo(
     boost::shared_ptr<const std::vector<std::pair<size_t, size_t>>>
         componentRanges,
     boost::shared_ptr<const std::vector<size_t>> parentIndices,
+    boost::shared_ptr<std::vector<std::vector<size_t>>> children,
     boost::shared_ptr<std::vector<Eigen::Vector3d>> positions,
     boost::shared_ptr<std::vector<Eigen::Quaterniond,
                                   Eigen::aligned_allocator<Eigen::Quaterniond>>>
@@ -52,7 +53,8 @@ ComponentInfo::ComponentInfo(
       m_detectorRanges(std::move(detectorRanges)),
       m_componentRanges(std::move(componentRanges)),
       m_parentIndices(std::move(parentIndices)),
-      m_positions(std::move(positions)), m_rotations(std::move(rotations)),
+      m_children(std::move(children)), m_positions(std::move(positions)),
+      m_rotations(std::move(rotations)),
       m_scaleFactors(std::move(scaleFactors)),
       m_componentType(std::move(componentType)), m_names(std::move(names)),
       m_size(m_assemblySortedDetectorIndices->size() +
@@ -92,6 +94,19 @@ ComponentInfo::ComponentInfo(
     throw std::invalid_argument("ComponentInfo should be provided same number "
                                 "of names as number of components");
   }
+
+  // Calculate total size of all assemblies
+  auto assemTotalSize = std::accumulate(
+      m_children->begin(), m_children->end(), static_cast<size_t>(1),
+      [](size_t size, const std::vector<size_t> &assem) {
+        return size += assem.size();
+      });
+
+  if (assemTotalSize != m_size) {
+    throw std::invalid_argument("ComponentInfo should be provided an "
+                                "instrument tree which contains same number "
+                                "components");
+  }
 }
 
 std::unique_ptr<ComponentInfo> ComponentInfo::cloneWithoutDetectorInfo() const {
@@ -140,8 +155,24 @@ ComponentInfo::componentsInSubtree(const size_t componentIndex) const {
   return indices;
 }
 
+const std::vector<size_t> &
+ComponentInfo::children(const size_t componentIndex) const {
+  static const std::vector<size_t> emptyVec;
+
+  if (!isDetector(componentIndex))
+    return (*m_children)[compOffsetIndex(componentIndex)];
+
+  return emptyVec;
+}
+
 size_t ComponentInfo::size() const { return m_size; }
 
+size_t
+ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const {
+  auto range = detectorRangeInSubtree(componentIndex);
+  return std::distance(range.begin(), range.end());
+}
+
 Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const {
   checkNoTimeDependence();
   if (isDetector(componentIndex)) {
@@ -301,7 +332,8 @@ void ComponentInfo::setPosition(const size_t componentIndex,
   if (isDetector(componentIndex))
     return m_detectorInfo->setPosition(componentIndex, newPosition);
 
-  // Optimization: Not using detectorsInSubtree and componentsInSubtree to avoid
+  // Optimization: Not using detectorsInSubtree and componentsInSubtree to
+  // avoid
   // memory allocations.
   // Optimization: Split loop over detectors and other components.
   const auto detectorRange = detectorRangeInSubtree(componentIndex);
diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h
index 4af0a9d5fdbcce57e4d88c88190e1f9d48b204c9..dcd6c92dc07b0e2f27a43dd5ac5511390072ce08 100644
--- a/Framework/Beamline/test/ComponentInfoTest.h
+++ b/Framework/Beamline/test/ComponentInfoTest.h
@@ -66,6 +66,11 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) {
   auto isRectangularBank =
       boost::make_shared<std::vector<ComponentType>>(1, ComponentType::Generic);
 
+  std::vector<size_t> branch(detPositions.size());
+  std::iota(branch.begin(), branch.end(), 0);
+  auto children =
+      boost::make_shared<std::vector<std::vector<size_t>>>(1, branch);
+
   auto componentInfo = boost::make_shared<ComponentInfo>(
       bankSortedDetectorIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
@@ -73,8 +78,8 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) {
       bankSortedComponentIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
-      parentIndices, positions, rotations, scaleFactors, isRectangularBank,
-      names, -1, -1);
+      parentIndices, children, positions, rotations, scaleFactors,
+      isRectangularBank, names, -1, -1);
 
   componentInfo->setDetectorInfo(detectorInfo.get());
 
@@ -141,6 +146,8 @@ makeTreeExampleAndReturnGeometricArguments() {
   // Rectangular bank flag
   auto isRectangularBank =
       boost::make_shared<std::vector<ComponentType>>(2, ComponentType::Generic);
+  auto children = boost::make_shared<std::vector<std::vector<size_t>>>(
+      2, std::vector<size_t>(2));
 
   auto compInfo = boost::make_shared<ComponentInfo>(
       bankSortedDetectorIndices,
@@ -149,7 +156,7 @@ makeTreeExampleAndReturnGeometricArguments() {
       bankSortedComponentIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
-      parentIndices, compPositions, compRotations, scaleFactors,
+      parentIndices, children, compPositions, compRotations, scaleFactors,
       isRectangularBank, names, -1, -1);
 
   compInfo->setDetectorInfo(detectorInfo.get());
@@ -208,6 +215,9 @@ makeTreeExample() {
   auto isRectangularBank =
       boost::make_shared<std::vector<ComponentType>>(2, ComponentType::Generic);
 
+  auto children = boost::make_shared<std::vector<std::vector<size_t>>>(
+      2, std::vector<size_t>(2));
+
   auto componentInfo = boost::make_shared<ComponentInfo>(
       bankSortedDetectorIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
@@ -215,8 +225,8 @@ makeTreeExample() {
       bankSortedComponentIndices,
       boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
           componentRanges),
-      parentIndices, positions, rotations, scaleFactors, isRectangularBank,
-      names, -1, -1);
+      parentIndices, children, positions, rotations, scaleFactors,
+      isRectangularBank, names, -1, -1);
 
   componentInfo->setDetectorInfo(detectorInfo.get());
 
@@ -273,23 +283,28 @@ public:
         boost::make_shared<const std::vector<size_t>>(
             std::vector<size_t>{0, 1, 2});
     auto bankSortedComponentIndices =
-        boost::make_shared<const std::vector<size_t>>(std::vector<size_t>{});
-    auto parentIndices = boost::make_shared<const std::vector<size_t>>(
-        std::vector<size_t>{9, 9, 9}); // These indices are invalid, but that's
-                                       // ok as not being tested here
+        boost::make_shared<const std::vector<size_t>>(std::vector<size_t>(1));
+    auto parentIndices =
+        boost::make_shared<const std::vector<size_t>>(std::vector<size_t>{
+            9, 9, 9, 9}); // These indices are invalid, but that's
+                          // ok as not being tested here
     auto detectorRanges =
-        boost::make_shared<const std::vector<std::pair<size_t, size_t>>>();
+        boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
+            1, std::pair<size_t, size_t>{0, 2});
     auto componentRanges =
         boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
             std::vector<std::pair<size_t, size_t>>{});
-    auto positions = boost::make_shared<PosVec>();
-    auto rotations = boost::make_shared<RotVec>();
-    auto scaleFactors = boost::make_shared<PosVec>(3);
-    auto names = boost::make_shared<StrVec>(3);
-    auto isRectangularBank = boost::make_shared<std::vector<ComponentType>>();
+    auto positions = boost::make_shared<PosVec>(1);
+    auto rotations = boost::make_shared<RotVec>(1);
+    auto scaleFactors = boost::make_shared<PosVec>(4);
+    auto names = boost::make_shared<StrVec>(4);
+    auto isRectangularBank = boost::make_shared<std::vector<ComponentType>>(1);
+    auto children = boost::make_shared<std::vector<std::vector<size_t>>>(
+        1, std::vector<size_t>(3));
+
     ComponentInfo componentInfo(bankSortedDetectorIndices, detectorRanges,
                                 bankSortedComponentIndices, componentRanges,
-                                parentIndices, positions, rotations,
+                                parentIndices, children, positions, rotations,
                                 scaleFactors, isRectangularBank, names, -1, -1);
 
     DetectorInfo detectorInfo; // Detector info size 0
@@ -325,11 +340,14 @@ public:
     auto names = boost::make_shared<StrVec>();
     auto isRectangularBank = boost::make_shared<std::vector<ComponentType>>(
         2, ComponentType::Generic);
+    auto children = boost::make_shared<
+        std::vector<std::vector<size_t>>>(); // invalid but not being tested
+
     TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges,
                                    bankSortedComponentIndices, componentRanges,
-                                   parentIndices, positions, rotations,
-                                   scaleFactors, isRectangularBank, names, -1,
-                                   -1),
+                                   parentIndices, children, positions,
+                                   rotations, scaleFactors, isRectangularBank,
+                                   names, -1, -1),
                      std::invalid_argument &);
   }
 
@@ -365,16 +383,62 @@ public:
             std::vector<std::pair<size_t, size_t>>{{0, 0}});
     auto isRectangularBank = boost::make_shared<std::vector<ComponentType>>(
         2, ComponentType::Generic);
+    auto children = boost::make_shared<
+        std::vector<std::vector<size_t>>>(); // invalid but not being tested
+
+    TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges,
+                                   componentsInSubtree, componentRanges,
+                                   parentIndices, children, positions,
+                                   rotations, scaleFactors, isRectangularBank,
+                                   names, -1, -1),
+                     std::invalid_argument &);
+  }
+
+  void test_throw_if_instrument_tree_not_same_size_as_number_of_components() {
+    /*
+    * Positions are rotations are only currently stored for non-detector
+    * components
+    * We should have as many detectorRanges as we have non-detector components
+    * too.
+    * All vectors should be the same size.
+    */
+    auto detectorsInSubtree =
+        boost::make_shared<const std::vector<size_t>>(); // No detector indices
+                                                         // in this example!
+
+    auto componentsInSubtree =
+        boost::make_shared<const std::vector<size_t>>(std::vector<size_t>{0});
+
+    auto detectorRanges =
+        boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
+            1, std::pair<size_t, size_t>(0, 0));
+
+    auto parentIndices = boost::make_shared<const std::vector<size_t>>(
+        std::vector<size_t>{9, 9, 9}); // These indices are invalid, but that's
+                                       // ok as not being tested here
+    auto positions = boost::make_shared<PosVec>(1);
+    auto rotations = boost::make_shared<RotVec>(1);
+
+    auto scaleFactors = boost::make_shared<PosVec>(1);
+    auto names = boost::make_shared<StrVec>(1);
+    // Only one component. So single empty component range.
+    auto componentRanges =
+        boost::make_shared<const std::vector<std::pair<size_t, size_t>>>(
+            std::vector<std::pair<size_t, size_t>>{{0, 0}});
+    auto componentTypes =
+        boost::make_shared<std::vector<Mantid::Beamline::ComponentType>>(
+            1, Mantid::Beamline::ComponentType::Generic);
+    auto children = boost::make_shared<std::vector<std::vector<size_t>>>(
+        1, std::vector<size_t>{1, 2}); // invalid
 
     TS_ASSERT_THROWS(
         ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree,
-                      componentRanges, parentIndices, positions, rotations,
-                      scaleFactors, isRectangularBank, names, -1, -1),
+                      componentRanges, parentIndices, children, positions,
+                      rotations, scaleFactors, componentTypes, names, -1, -1),
         std::invalid_argument &);
   }
 
   void test_read_positions_rotations() {
-
     auto allOutputs = makeTreeExampleAndReturnGeometricArguments();
 
     // Resulting ComponentInfo
diff --git a/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h b/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h
index 49e3de7345dd88a50c55b0f0118d229fe3e516f9..4eaf865ad8c7c85b40b32ae3daeb29bec5c4e03c 100644
--- a/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h
@@ -34,6 +34,9 @@ class DLLExport AddPeakHKL : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddPeak"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h b/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h
index b207795b4efa92701f104e1c5972d48761fee52f..684e31e4aeea43eb8b0650129c33b79558f3398e 100644
--- a/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h
+++ b/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h
@@ -87,6 +87,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LorentzCorrection"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Crystal\\Corrections;CorrectionFunctions\\AbsorptionCorrections";
diff --git a/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h b/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h
index b66b64d5f46dc0a7a0722a4a63b1c02fa03551da..41136356c25729cf41e7f7f7b720e9cbf856e60c 100644
--- a/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddPeak"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h b/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h
index be18c24679b1826d18651fe6a772becd2fe5bb16..a95255657f998ac0461baa92987b7e090cd0c9ad 100644
--- a/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h
+++ b/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h
@@ -46,6 +46,7 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override { return {"SetUB"}; }
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\UBMatrix"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h b/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h
index f5e0c4fdfaaca15b3c2636ac752e6593f164d9fe..73fc45672012e8b8afd405afd20deafded93a4ba 100644
--- a/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h
@@ -27,6 +27,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CentroidPeaksMD", "PeakIntegration"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Peaks"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/ClearUB.h b/Framework/Crystal/inc/MantidCrystal/ClearUB.h
index 9785a49ec2156d922b21652ab0079ac9b84607bf..04c6c405e88100f9e988542fa5a85a0b5e25a823 100644
--- a/Framework/Crystal/inc/MantidCrystal/ClearUB.h
+++ b/Framework/Crystal/inc/MantidCrystal/ClearUB.h
@@ -45,6 +45,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "HasUB"};
+  }
   const std::string category() const override;
 
 protected:
diff --git a/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h b/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h
index 713b976808e8d12add4d109a9a7e1b92c56b5218..8d83e8f41340e8381ec585afacb8dadcafca1790 100644
--- a/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h
+++ b/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h
@@ -40,7 +40,7 @@ class ImplClusterRegister;
 class DLLExport ClusterRegister {
 public:
   /// Cluster map
-  typedef std::map<size_t, boost::shared_ptr<ICluster>> MapCluster;
+  using MapCluster = std::map<size_t, boost::shared_ptr<ICluster>>;
 
   /// Constructor
   ClusterRegister();
diff --git a/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h b/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h
index b72fb786fdaa70fc009d2b13e0e1fe47a717dae4..150268c2eff02e50bb2121ca6760bd1de0b59a77 100644
--- a/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h
+++ b/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePeaksWorkspace"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h
index c097b1ea5bee67cad74d755a72b21b6e0c3f66d6..6f7c72faba9e2d48c724bb02949e9563acd4646e 100644
--- a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h
+++ b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h
@@ -22,16 +22,16 @@ class ICluster;
  * Namespace containing useful typedefs
  */
 namespace ConnectedComponentMappingTypes {
-typedef boost::tuple<double, double> SignalErrorSQPair;
-typedef std::map<size_t, SignalErrorSQPair> LabelIdIntensityMap;
-typedef std::map<Mantid::Kernel::V3D, size_t> PositionToLabelIdMap;
-typedef std::vector<size_t> VecIndexes;
-typedef std::vector<DisjointElement> VecElements;
-typedef std::unordered_set<size_t> SetIds;
-typedef std::map<size_t, boost::shared_ptr<Mantid::Crystal::ICluster>>
-    ClusterMap;
-typedef boost::tuple<Mantid::API::IMDHistoWorkspace_sptr, ClusterMap>
-    ClusterTuple;
+using SignalErrorSQPair = boost::tuple<double, double>;
+using LabelIdIntensityMap = std::map<size_t, SignalErrorSQPair>;
+using PositionToLabelIdMap = std::map<Mantid::Kernel::V3D, size_t>;
+using VecIndexes = std::vector<size_t>;
+using VecElements = std::vector<DisjointElement>;
+using SetIds = std::unordered_set<size_t>;
+using ClusterMap =
+    std::map<size_t, boost::shared_ptr<Mantid::Crystal::ICluster>>;
+using ClusterTuple =
+    boost::tuple<Mantid::API::IMDHistoWorkspace_sptr, ClusterMap>;
 }
 
 class BackgroundStrategy;
diff --git a/Framework/Crystal/inc/MantidCrystal/CountReflections.h b/Framework/Crystal/inc/MantidCrystal/CountReflections.h
index bf1a72a7f0a77e00faf7172980ead02471873238..b06c2af7705e0951ff1c7e818c88bb251b910be9 100644
--- a/Framework/Crystal/inc/MantidCrystal/CountReflections.h
+++ b/Framework/Crystal/inc/MantidCrystal/CountReflections.h
@@ -41,6 +41,9 @@ class DLLExport CountReflections : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PredictPeaks", "SortHKL"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h b/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h
index ac57e4c18d49f49682267db52aad413831508d12..f725a968f4416452868ff3499e93006c1abc7ba1 100644
--- a/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h
+++ b/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePeaksWorkspace", "CombinePeaksWorkspaces"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h
index 94af78ff45a53011ce3df581a0665f5bce22db94..579d3225477883c9140ba5ee17dbddc53e56e2b9 100644
--- a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h
@@ -42,11 +42,14 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePeaksWorkspace"};
+  }
   const std::string category() const override;
 
 private:
   /// Typedef for the function to get the variable we're filtering against
-  typedef std::function<double(const Geometry::IPeak &)> FilterFunction;
+  using FilterFunction = std::function<double(const Geometry::IPeak &)>;
 
   /// Override for algorithm init
   void init() override;
diff --git a/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h b/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h
index 6951b5625dc84de7e3a94ac77534de11cda9840a..5431772a914a403833ab3c3644378872de5406a8 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h
@@ -40,6 +40,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksUsingClusters"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h
index afc833946a84193511ca752019dbc42258ba11bd..6c9e8db9866753046087c94649ea3994d6d85b2b 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h
@@ -14,7 +14,7 @@
 namespace Mantid {
 namespace Crystal {
 
-typedef std::vector<FindSXPeaksHelper::SXPeak> peakvector;
+using peakvector = std::vector<FindSXPeaksHelper::SXPeak>;
 
 /** Search detector space for single crystal peaks.
 
@@ -64,6 +64,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IndexSXPeaks"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Crystal\\Peaks;Optimization\\PeakFinding";
diff --git a/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h b/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h
index 83c03c8fc5f103a00c2cc49e1f142e3e52301e0f..e021920f5c8ee9f3d7f1af280ce54bbc7c6a566f 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h
@@ -122,6 +122,7 @@ private:
  * ------------------------------------------------------------------------------------------
  */
 struct DLLExport BackgroundStrategy {
+  virtual ~BackgroundStrategy() = default;
   virtual bool isBelowBackground(const double intensity,
                                  const HistogramData::HistogramY &y) const = 0;
 };
@@ -155,6 +156,7 @@ public:
                       const double minValue = EMPTY_DBL(),
                       const double maxValue = EMPTY_DBL(),
                       const XAxisUnit units = XAxisUnit::TOF);
+  virtual ~PeakFindingStrategy() = default;
   PeakList findSXPeaks(const HistogramData::HistogramX &x,
                        const HistogramData::HistogramY &y,
                        const int workspaceIndex) const;
@@ -219,6 +221,7 @@ private:
  */
 class DLLExport CompareStrategy {
 public:
+  virtual ~CompareStrategy() = default;
   virtual bool compare(const SXPeak &lhs, const SXPeak &rhs) const = 0;
 };
 
@@ -253,6 +256,7 @@ private:
 class DLLExport ReducePeakListStrategy {
 public:
   ReducePeakListStrategy(const CompareStrategy *compareStrategy);
+  virtual ~ReducePeakListStrategy() = default;
   virtual std::vector<SXPeak>
   reduce(const std::vector<SXPeak> &peaks,
          Mantid::Kernel::ProgressBase &progress) const = 0;
diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h
index 91351b5cbcf2c825567fbad5da3f1c995c7ce9f0..1850af09c1423d0161983d691665b622088303f5 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h
@@ -40,6 +40,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "FindUBUsingIndexedPeaks", "FindUBUsingLatticeParameters",
+            "FindUBUsingMinMaxD"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override;
diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h
index a50d04231a88d7a782ff27abc6c6431f40807894..4d7456eefd8b7305edc0ea3130c58b294ab0d351 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h
@@ -41,6 +41,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "FindUBUsingFFT", "FindUBUsingLatticeParameters",
+            "FindUBUsingMinMaxD"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\UBMatrix"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h
index dc8eebab33015d1b5cf2c85e76db846ea74efa4d..1cb69eba444ea677381a57097432dbd9821f542b 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h
@@ -43,6 +43,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingMinMaxD"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\UBMatrix"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h
index 49ae0c5435529232c555d89283262fb16d9d649a..d62b5093268266408642bb66a605329808c7e4fc 100644
--- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h
+++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h
@@ -45,6 +45,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override;
diff --git a/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h b/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h
index a15567c4e641725a25ff012b8315faa48f097e16..5365e4828283f74b50bb350dd2de1831efec0f87 100644
--- a/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h
+++ b/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetGoniometer"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Goniometer"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/HasUB.h b/Framework/Crystal/inc/MantidCrystal/HasUB.h
index 0b4ae3cb02b6af0a127ecff759059858f0ff39de..4937aebd190231c2b379671e34f61e5e6a9edf26 100644
--- a/Framework/Crystal/inc/MantidCrystal/HasUB.h
+++ b/Framework/Crystal/inc/MantidCrystal/HasUB.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetUB", "ClearUB"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/ICluster.h b/Framework/Crystal/inc/MantidCrystal/ICluster.h
index 0b07650f4cc3e43bebbce7992c1de1f4cc9c4d03..745c9401cb8030ceeaefd30af38e33c84336409b 100644
--- a/Framework/Crystal/inc/MantidCrystal/ICluster.h
+++ b/Framework/Crystal/inc/MantidCrystal/ICluster.h
@@ -39,7 +39,7 @@ namespace Crystal {
  */
 class DLLExport ICluster {
 public:
-  typedef boost::tuple<double, double> ClusterIntegratedValues;
+  using ClusterIntegratedValues = boost::tuple<double, double>;
 
   /// integrate the cluster
   virtual ClusterIntegratedValues integrate(
diff --git a/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h b/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h
index b205ac8cbfe818e7bab25ea71de957cfc1e128ca..792114abb63ca28ec0edb4fc808a5d76824870b4 100644
--- a/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IndexSXPeaks"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Peaks"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
index bb7a92f68c9de6772634f8ec7a904cd75f01817a..df864e4f7a2ab452d37e2d6a611cae285ce2d126 100644
--- a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
@@ -163,6 +163,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IndexPeaks"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Peaks"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h
index 837aeff6fe7a15b0ad06380ed28bddc03c429f59..da247e5f06cb6f13e423d84c4c76fafc4ac46c19 100644
--- a/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h
+++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h
@@ -245,6 +245,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"PeakIntegration"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Integration"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h
index cfce138cd8a98be533b099ae2e3616c09e0a7cc7..0330ce088f6dc2e0069c3c118c93fa127869a26b 100644
--- a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h
+++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h
@@ -34,6 +34,10 @@ class DLLExport IntegratePeaksHybrid : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksUsingClusters", "IntegratePeaksMDHKL",
+            "IntegratePeaksMD", "IntegratePeaksCWSD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h
index 1b6615135f267b9c744c15dad89786b6543eb52c..85bdca7257a72d4d6ec28bf36f51a7d6361ad09a 100644
--- a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h
+++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h
@@ -40,6 +40,10 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksHybrid", "IntegratePeaksMDHKL", "IntegratePeaksMD",
+            "IntegratePeaksCWSD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadHKL.h b/Framework/Crystal/inc/MantidCrystal/LoadHKL.h
index 92842034004dca194e4c06c976e20493686e3b82..80582648ed920362afa2a26fa33344d2994f1d8c 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadHKL.h
@@ -27,6 +27,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveHKL"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Text";
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
index 7352a0a069f701b56e59051f7d8a4c1e5f54ea3f..3292dc08c389206083c119161e7e2153219f06f3 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
@@ -29,6 +29,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveIsawPeaks"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override {
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h
index 09c220e8fc72bce4ae230a69af1b042a76855d09..5e6289b756e1b3bb686da7a334a5e14ab6828612 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveIsawPeaks", "SaveIsawUB"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Text";
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h
index 6b0835fca4ccc7a421b7ced9e3e780af29c34e3d..00c86fc298c2fc416e9669da1f781b84a8cb46fb 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h
@@ -26,6 +26,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveIsawUB"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Isaw";
diff --git a/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
index 018fb73a50b6a332dd6179f8c9888bc9f1ce8cf7..afe832b53da3afa8d9b367d92c14f4b9f6977e91 100644
--- a/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
+++ b/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h
@@ -45,6 +45,9 @@ public:
   const std::string name() const override { return "MaskPeaksWorkspace"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePeaksWorkspace"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Peaks"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h b/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h
index 5f11c2f9dc6e0f57dbd7c6f65946f2b10a6aea12..6a96a5e364c242899d59091d15668f6da18beb21 100644
--- a/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h
+++ b/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h
@@ -55,6 +55,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Cell"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h b/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h
index 548d9238aa017be2efaa11fb2fa4336c9dfe09b6..5801c136b27791850257a9f9289379655f9d5d35 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h
@@ -43,6 +43,9 @@ public:
   const std::string name() const override { return "PeakIntegration"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeakTimeSlices", "CentroidPeaks"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Crystal\\Integration"; }
   /// Summary of algorithms purpose
diff --git a/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h b/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h
index 22526c5a707cd4ccca7d2249c5d9d26c25370ed3..5991e2db6c612649dfd5fa2011de054b951597b6 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PeakIntegration"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h b/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h
index 29e46581d4ca976a058354f0bdb0f5446da117a1..f3c426200421b82633ab26691e119263333dc673 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h
@@ -34,10 +34,12 @@ public:
   const std::vector<DataObjects::Peak> &getPeaks() const { return m_peaks; }
   size_t count() const { return m_peaks.size(); }
 
+  std::vector<double> getWavelengths() const;
   std::vector<double> getIntensities() const;
   std::vector<double> getSigmas() const;
 
-  UniqueReflection removeOutliers(double sigmaCritical = 3.0) const;
+  UniqueReflection removeOutliers(double sigmaCritical = 3.0,
+                                  bool weightedZ = false) const;
   void setPeaksIntensityAndSigma(double intensity, double sigma);
 
 private:
@@ -109,7 +111,21 @@ public:
         m_redundancy(0.0), m_rMerge(0.0), m_rPim(0.0), m_meanIOverSigma(0.0),
         m_dspacingMin(0.0), m_dspacingMax(0.0), m_chiSquared(0.0), m_peaks() {
     m_peaks.reserve(reflections.getObservedReflectionCount());
-    calculatePeaksStatistics(reflections.getReflections());
+    std::string equivalentIntensities = "Mean";
+    double sigmaCritical = 3.0;
+    bool weightedZ = false;
+    calculatePeaksStatistics(reflections.getReflections(),
+                             equivalentIntensities, sigmaCritical, weightedZ);
+  }
+  explicit PeaksStatistics(const UniqueReflectionCollection &reflections,
+                           std::string &equivalentIntensities,
+                           double &sigmaCritical, bool &weightedZ)
+      : m_measuredReflections(0), m_uniqueReflections(0), m_completeness(0.0),
+        m_redundancy(0.0), m_rMerge(0.0), m_rPim(0.0), m_meanIOverSigma(0.0),
+        m_dspacingMin(0.0), m_dspacingMax(0.0), m_chiSquared(0.0), m_peaks() {
+    m_peaks.reserve(reflections.getObservedReflectionCount());
+    calculatePeaksStatistics(reflections.getReflections(),
+                             equivalentIntensities, sigmaCritical, weightedZ);
   }
 
   /// Total number of observed reflections - no symmetry is taken into
@@ -152,7 +168,9 @@ public:
 
 private:
   void calculatePeaksStatistics(
-      const std::map<Kernel::V3D, UniqueReflection> &uniqueReflections);
+      const std::map<Kernel::V3D, UniqueReflection> &uniqueReflections,
+      std::string &equivalentIntensities, double &sigmaCritical,
+      bool &weightedZ);
 
   double getIOverSigmaSum(const std::vector<double> &sigmas,
                           const std::vector<double> &intensities) const;
diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h b/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h
index 7d703d788f64e65335d8b8ff29658c1a99e27012..59bc599256f06894bc8bd84053f93c12d23695f6 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h
@@ -39,6 +39,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PeaksOnSurface"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h b/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h
index 90e23d87c02a3fdc562f8d4b39a68198c0b66c12..ecd5100e933cfaa2632d11e2a03b78d874ec9290 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h
@@ -8,8 +8,8 @@
 namespace Mantid {
 namespace Crystal {
 
-typedef std::vector<Mantid::Kernel::V3D> VecV3D;
-typedef std::vector<VecV3D> VecVecV3D;
+using VecV3D = std::vector<Mantid::Kernel::V3D>;
+using VecVecV3D = std::vector<VecV3D>;
 
 /** PeaksIntersection : Abstract base algorithm class for algorithms that
   identify peaks interacting with one or more surfaces
diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h b/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h
index ecd75678effa12dae5d9f01cdf7f35684639dd26..a156efcb55de0a398d6daf997f7d9209961359cc 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PeaksInRegion"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h b/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h
index 3a2c319f1a456c6232e94af0b0ded1eac4c666e4..03142b147140a65b0e984bb70b481d1290d00fb3 100644
--- a/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"PredictPeaks"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Peaks"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h b/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h
index 922a6ad9ab78a4b6f2b7365920979482134d4df2..a4a61759f7d1a7bc1ecc6ad208f1f40fbcaa69d6 100644
--- a/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h
@@ -39,6 +39,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CountReflections", "PredictFractionalPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Peaks"; }
 
@@ -64,7 +67,8 @@ private:
 
   void calculateQAndAddToOutput(const Kernel::V3D &hkl,
                                 const Kernel::DblMatrix &orientedUB,
-                                const Kernel::DblMatrix &goniometerMatrix);
+                                const Kernel::DblMatrix &goniometerMatrix,
+                                int &seqNum);
 
 private:
   /// Get the predicted detector direction from Q
diff --git a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
index b95ca3f7276d8abd1aef5e6038d497af6ef23b9c..541fa748f8e2378da555ff82b2a1db0814e01257 100644
--- a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
+++ b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateUMatrix"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override;
diff --git a/Framework/Crystal/inc/MantidCrystal/SaveHKL.h b/Framework/Crystal/inc/MantidCrystal/SaveHKL.h
index 392e2d0484dffa483605bc876031fca669346d42..f258a559c17b5ab13e7578beca928231fbafd803 100644
--- a/Framework/Crystal/inc/MantidCrystal/SaveHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/SaveHKL.h
@@ -25,6 +25,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadHKL"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Text";
diff --git a/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h
index df8d19a4f3fc626e9da5ea978e1880b8f39a7575..094005a25e2bc59e103bc3ab25753cac72483be7 100644
--- a/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h
@@ -30,6 +30,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadIsawPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Isaw";
diff --git a/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h b/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h
index f80f316859d5184dd085e3842d215d1269c3afc7..a1beabf73d0341828b7ec51d785e71ff192f7065 100644
--- a/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h
+++ b/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadIsawUB"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\DataHandling;DataHandling\\Isaw";
diff --git a/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h b/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h
index 81dc93b6f4812fd8f57e3c2cdea7005b253397c3..445263acdf3ab3ab1c7a87afd1d3f8859f6b3ccb 100644
--- a/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h
+++ b/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h
@@ -40,8 +40,13 @@ private:
 
   DataObjects::PeaksWorkspace_sptr ws;
   void sizeBanks(std::string bankName, int &nCols, int &nRows);
-  std::vector<int> crystalSystem(Geometry::OrientedLattice lattice,
-                                 std::vector<DataObjects::Peak> peaks);
+
+  const std::vector<std::string> m_typeList{
+      "TRICLINIC", "MONOCLINIC",   "ORTHORHOMBIC", "TETRAGONAL",
+      "HEXAGONAL", "RHOMBOHEDRAL", "CUBIC"};
+
+  const std::vector<std::string> m_centeringList{"P", "A", "B", "C",
+                                                 "I", "F", "R"};
 };
 
 } // namespace Mantid
diff --git a/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h b/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h
index fbe9134f074dc20c1c8e63b8062f6a0787db0101..1e448ee097ba8dc5b392c62be72b69a601b4e1ed 100644
--- a/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h
+++ b/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h
@@ -43,6 +43,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Cell"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h b/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h
index a6b4a6f01d64fa8dce9a783fa0975f9bab4824bd..2254043d5c438c0af70b766746679fe1fb43fea1 100644
--- a/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h
+++ b/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h
@@ -44,6 +44,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Cell"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h b/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h
index 817b2e7af432d785b06afd26fca9e9c85ff8776d..c48931dc6b830eec7e4c6dd6ec0b8159b3d02f92 100644
--- a/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h
+++ b/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h
@@ -25,6 +25,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"GoniometerAnglesFromPhiRotation"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Goniometer"; }
 
diff --git a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h
index 61ce8d748da168952a1bda7bf842173746bd3945..5a271da941ca64e8203f4bf0c49705659ad826b2 100644
--- a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h
+++ b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h
@@ -48,14 +48,17 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD", "ConvertToDiffractionMDWorkspace"};
+  }
   const std::string category() const override;
 
 private:
   void init() override;
   void exec() override;
   std::vector<std::string> m_specialCoordinatesNames;
-  typedef std::map<std::string, Mantid::Kernel::SpecialCoordinateSystem>
-      SpecialCoordinatesNameMap;
+  using SpecialCoordinatesNameMap =
+      std::map<std::string, Mantid::Kernel::SpecialCoordinateSystem>;
   SpecialCoordinatesNameMap m_specialCoordinatesMap;
   static const std::string QLabOption();
   static const std::string QSampleOption();
diff --git a/Framework/Crystal/inc/MantidCrystal/SetUB.h b/Framework/Crystal/inc/MantidCrystal/SetUB.h
index 481137668a9b8be23f4622fd26682e947ae114a9..6c105fe4681d0c678ee762d0c29d9f67043eb398 100644
--- a/Framework/Crystal/inc/MantidCrystal/SetUB.h
+++ b/Framework/Crystal/inc/MantidCrystal/SetUB.h
@@ -46,6 +46,10 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters", "FindUBUsingMinMaxD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h b/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h
index 1787aa59cfc6edc4e05856ce0fdc0c609d2164f4..368de1c811cbedc6773c2422d965efc71968d79d 100644
--- a/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h
+++ b/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h
@@ -53,6 +53,9 @@ public:
   }
 
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"StatisticsOfPeaksWorkspace"};
+  }
 
   const std::string category() const override { return "Crystal\\Peaks"; };
 
diff --git a/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h b/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h
index d890f6cac205f038cedf09525b5b0bfe09e656bf..977cbaa4e2cfd5bf1b7c55f9cf4f055c74544eed 100644
--- a/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h
+++ b/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h
@@ -43,6 +43,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks",
+            "FindUBUsingLatticeParameters"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "Crystal\\Cell"; }
diff --git a/Framework/Crystal/inc/MantidCrystal/SortHKL.h b/Framework/Crystal/inc/MantidCrystal/SortHKL.h
index f2a72e51f2a684dfc686d3f140d3be196c3d979d..ba95a470fd5087c970d6b1fd7a367a13256566a2 100644
--- a/Framework/Crystal/inc/MantidCrystal/SortHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/SortHKL.h
@@ -41,9 +41,12 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"TransformHKL"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "Crystal\\Peaks;DataHandling\\Text;Utility\\Sorting";
+    return R"(Crystal\Peaks;DataHandling\Text;Utility\Sorting)";
   }
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h
index 27f8e9d5f13e927c20d46ed38eae6b6437a4bdd3..78034d3109244f23511beed431183d1406ff1d62 100644
--- a/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h
+++ b/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreatePeaksWorkspace"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h
index dae2543c1f6df4ba180ae4d6770335ddd4141295..baa26ff154923aa21399e60752e117ecd2b70a91 100644
--- a/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h
+++ b/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h
@@ -28,6 +28,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ShowPeakHKLOffsets"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Crystal\\Peaks;DataHandling\\Text";
diff --git a/Framework/Crystal/inc/MantidCrystal/TransformHKL.h b/Framework/Crystal/inc/MantidCrystal/TransformHKL.h
index 5b8dd122cff92012d4c1e5690c29e5b86cc897fb..2c174d2fe1f7736e24e0412df11c37b48cdb31c4 100644
--- a/Framework/Crystal/inc/MantidCrystal/TransformHKL.h
+++ b/Framework/Crystal/inc/MantidCrystal/TransformHKL.h
@@ -41,6 +41,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SortHKL"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override;
diff --git a/Framework/Crystal/src/Cluster.cpp b/Framework/Crystal/src/Cluster.cpp
index b64629b5be1a2a832843a2a4806c3a574a287e13..629f7b3df24de89054b91863e57f63f3cf22a858 100644
--- a/Framework/Crystal/src/Cluster.cpp
+++ b/Framework/Crystal/src/Cluster.cpp
@@ -2,7 +2,7 @@
 #include "MantidAPI/IMDHistoWorkspace.h"
 
 namespace {
-typedef std::vector<Mantid::Crystal::DisjointElement> VecElements;
+using VecElements = std::vector<Mantid::Crystal::DisjointElement>;
 }
 
 namespace Mantid {
diff --git a/Framework/Crystal/src/ClusterRegister.cpp b/Framework/Crystal/src/ClusterRegister.cpp
index a82c609abea34b061c204266d9ccd983057c6577..81ffb3b33c924491bef6d55484a6a2041ed1d13c 100644
--- a/Framework/Crystal/src/ClusterRegister.cpp
+++ b/Framework/Crystal/src/ClusterRegister.cpp
@@ -26,13 +26,13 @@ public:
   ClusterRegister::MapCluster m_unique;
 
   /// Type for identifying label groups
-  typedef std::list<std::unordered_set<size_t>> GroupType;
+  using GroupType = std::list<std::unordered_set<size_t>>;
 
   /// Groups of labels to maintain
   GroupType m_groups;
 
   /// Type for identifying labels already seen
-  typedef std::unordered_set<size_t> LabelHash;
+  using LabelHash = std::unordered_set<size_t>;
 
   /// Hash of labels merged
   LabelHash m_labelHash;
diff --git a/Framework/Crystal/src/ConnectedComponentLabeling.cpp b/Framework/Crystal/src/ConnectedComponentLabeling.cpp
index 920b852f6ff40a16667a14155518ee925957d22f..e4117ccdf0362383b6b52abe100be4ee1e2ea7be 100644
--- a/Framework/Crystal/src/ConnectedComponentLabeling.cpp
+++ b/Framework/Crystal/src/ConnectedComponentLabeling.cpp
@@ -95,8 +95,8 @@ bool does_contain_key(const Container &container,
   return container.find(value) != container.end();
 }
 
-typedef boost::tuple<size_t, size_t> EdgeIndexPair;
-typedef std::vector<EdgeIndexPair> VecEdgeIndexPair;
+using EdgeIndexPair = boost::tuple<size_t, size_t>;
+using VecEdgeIndexPair = std::vector<EdgeIndexPair>;
 
 /**
  * Free function performing the CCL implementation over a range defined by the
@@ -288,9 +288,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree(
   const int nThreadsToUse = getNThreads();
 
   if (nThreadsToUse > 1) {
-    std::vector<API::IMDIterator *> iterators =
-        ws->createIterators(nThreadsToUse);
-
+    auto iterators = ws->createIterators(nThreadsToUse);
     const size_t maxClustersPossible =
         calculateMaxClusters(ws.get(), nThreadsToUse);
 
@@ -303,7 +301,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree(
     g_log.debug("Parallel solve local CCL");
     // PARALLEL_FOR_NO_WSP_CHECK()
     for (int i = 0; i < nThreadsToUse; ++i) {
-      API::IMDIterator *iterator = iterators[i];
+      API::IMDIterator *iterator = iterators[i].get();
       boost::scoped_ptr<BackgroundStrategy> strategy(
           baseStrategy->clone());                     // local strategy
       VecEdgeIndexPair &edgeVec = parallelEdgeVec[i]; // local edge indexes
@@ -364,12 +362,12 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree(
     clusterMap = clusterRegister.clusters(neighbourElements);
 
   } else {
-    API::IMDIterator *iterator = ws->createIterator(nullptr);
+    auto iterator = ws->createIterator(nullptr);
     VecEdgeIndexPair edgeIndexPair; // This should never get filled in a single
                                     // threaded situation.
     size_t endLabelId = doConnectedComponentLabeling(
-        iterator, baseStrategy, neighbourElements, progress, maxNeighbours,
-        m_startId, edgeIndexPair);
+        iterator.get(), baseStrategy, neighbourElements, progress,
+        maxNeighbours, m_startId, edgeIndexPair);
 
     // Create clusters from labels.
     for (size_t labelId = m_startId; labelId != endLabelId; ++labelId) {
@@ -383,7 +381,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree(
     iterator->jumpTo(0); // Reset
     do {
       const size_t currentIndex = iterator->getLinearIndex();
-      if (!baseStrategy->isBackground(iterator)) {
+      if (!baseStrategy->isBackground(iterator.get())) {
         const int labelAtIndex = neighbourElements[currentIndex].getRoot();
         clusterMap[labelAtIndex]->addIndex(currentIndex);
       }
diff --git a/Framework/Crystal/src/FindClusterFaces.cpp b/Framework/Crystal/src/FindClusterFaces.cpp
index 1341c61e917a694fc836abe3e1c0ec6f8f5064bb..0cfe98c93e987aae2285d0edbaebcb7bd71f3d8d 100644
--- a/Framework/Crystal/src/FindClusterFaces.cpp
+++ b/Framework/Crystal/src/FindClusterFaces.cpp
@@ -20,9 +20,9 @@ using namespace Mantid::API;
 namespace {
 using namespace Mantid::Crystal;
 // Map of label ids to peak index in peaks workspace.
-typedef std::map<int, int> LabelMap;
+using LabelMap = std::map<int, int>;
 // Optional set of labels
-typedef boost::optional<LabelMap> OptionalLabelPeakIndexMap;
+using OptionalLabelPeakIndexMap = boost::optional<LabelMap>;
 
 /**
 * Create an optional label set for filtering.
@@ -72,8 +72,8 @@ struct ClusterFace {
   double radius;
 };
 
-typedef std::deque<ClusterFace> ClusterFaces;
-typedef std::vector<ClusterFaces> VecClusterFaces;
+using ClusterFaces = std::deque<ClusterFace>;
+using VecClusterFaces = std::vector<ClusterFaces>;
 
 /**
 Check that the data point signal value is an integer.
@@ -331,7 +331,7 @@ void FindClusterFaces::exec() {
   for (int it = 0; it < nIterators; ++it) {
     PARALLEL_START_INTERUPT_REGION
     ClusterFaces &localClusterFaces = clusterFaces[it];
-    auto mdIterator = mdIterators[it];
+    auto mdIterator = mdIterators[it].get();
 
     if (usingFiltering) {
       executeFiltered(mdIterator, localClusterFaces, progress, clusterImage,
diff --git a/Framework/Crystal/src/FindSXPeaksHelper.cpp b/Framework/Crystal/src/FindSXPeaksHelper.cpp
index cd9e4099fb0f469f6e5d3055a0c58aab7d65b8dc..2346859acb55e4cce5e4010f77cc585c109b14a9 100644
--- a/Framework/Crystal/src/FindSXPeaksHelper.cpp
+++ b/Framework/Crystal/src/FindSXPeaksHelper.cpp
@@ -587,9 +587,9 @@ FindMaxReduceStrategy::reduce(const std::vector<SXPeak> &peaks,
 }
 
 // Define some graph elements
-typedef adjacency_list<vecS, vecS, undirectedS, SXPeak *> PeakGraph;
-typedef boost::graph_traits<PeakGraph>::vertex_descriptor Vertex;
-typedef boost::graph_traits<PeakGraph>::edge_descriptor Edge;
+using PeakGraph = adjacency_list<vecS, vecS, undirectedS, SXPeak *>;
+using Vertex = boost::graph_traits<PeakGraph>::vertex_descriptor;
+using Edge = boost::graph_traits<PeakGraph>::edge_descriptor;
 
 std::vector<std::vector<SXPeak *>> FindMaxReduceStrategy::getPeakGroups(
     const std::vector<SXPeak> &peakList,
diff --git a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp
index 9498ee75d2f0a3b7daf9487ca9c0f7c116691762..6ecb083a9d3dbaeeb271848c0fa7aa0aec7602c6 100644
--- a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp
+++ b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp
@@ -598,10 +598,10 @@ void IntegratePeakTimeSlices::exec() {
                                        "Mrow is negative.");
             }
 
-            lastRow = static_cast<int>(params[i] + .5);
+            lastRow = boost::math::iround(params[i]);
             i = findNameInVector("Mcol", names);
             if (i >= 0)
-              lastCol = static_cast<int>(params[i] + .5);
+              lastCol = boost::math::iround(params[i]);
             prog.report();
 
           } else if (dir > 0)
diff --git a/Framework/Crystal/src/LoadHKL.cpp b/Framework/Crystal/src/LoadHKL.cpp
index a629fc879488406df9ab26d2cf5686d775a61e20..666562eac9ae71b0910296b9a72c2b5160f4aaf0 100644
--- a/Framework/Crystal/src/LoadHKL.cpp
+++ b/Framework/Crystal/src/LoadHKL.cpp
@@ -85,16 +85,19 @@ void LoadHKL::exec() {
     double wl = std::stod(line.substr(32, 8));
     double tbar, trans, scattering;
     int run, bank;
+    int seqNum;
     if (cosines) {
       tbar = std::stod(line.substr(40, 8)); // tbar
       run = std::stoi(line.substr(102, 6));
       trans = std::stod(line.substr(114, 7)); // transmission
+      seqNum = std::stoi(line.substr(109, 7));
       bank = std::stoi(line.substr(121, 4));
       scattering = std::stod(line.substr(125, 9));
     } else {
       tbar = std::stod(line.substr(40, 7)); // tbar
       run = std::stoi(line.substr(47, 7));
       trans = std::stod(line.substr(61, 7)); // transmission
+      seqNum = std::stoi(line.substr(54, 7));
       bank = std::stoi(line.substr(68, 4));
       scattering = std::stod(line.substr(72, 9));
     }
@@ -115,6 +118,7 @@ void LoadHKL::exec() {
     peak.setIntensity(Inti);
     peak.setSigmaIntensity(SigI);
     peak.setRunNumber(run);
+    peak.setPeakNumber(seqNum);
     std::ostringstream oss;
     oss << "bank" << bank;
     std::string bankName = oss.str();
diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp
index 194e3125fea904e5bdc1a8a6faadb9ac5dd4736e..db2f3a2998b0b6dbc353954c1c70101da9664465 100644
--- a/Framework/Crystal/src/LoadIsawPeaks.cpp
+++ b/Framework/Crystal/src/LoadIsawPeaks.cpp
@@ -213,8 +213,8 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS,
     boost::erase_all(bankName, bankPart);
     int bank = 0;
     Strings::convert(bankName, bank);
-    for (size_t j = 0; j < det.size(); j++) {
-      if (bank == det[j]) {
+    for (int j : det) {
+      if (bank == j) {
         bank = 0;
         continue;
       }
@@ -268,8 +268,6 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS,
   double Inti;
   double SigI;
 
-  seqNum = -1;
-
   std::string s = lastStr;
 
   if (s.length() < 1 && in.good()) // blank line
@@ -334,6 +332,7 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS,
   peak.setIntensity(Inti);
   peak.setSigmaIntensity(SigI);
   peak.setBinCount(IPK);
+  peak.setPeakNumber(seqNum);
   // Return the peak
   return peak;
 }
@@ -488,7 +487,7 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
     oss << bankString << bankNum;
     std::string bankName = oss.str();
 
-    int seqNum = -1;
+    int seqNum;
 
     try {
       // Read the peak
diff --git a/Framework/Crystal/src/PeakStatisticsTools.cpp b/Framework/Crystal/src/PeakStatisticsTools.cpp
index bf1d288c6a2f3b0afad7143c076fca9a575d3913..be199079e7e902278585080dd166f15aa84e3699 100644
--- a/Framework/Crystal/src/PeakStatisticsTools.cpp
+++ b/Framework/Crystal/src/PeakStatisticsTools.cpp
@@ -16,6 +16,19 @@ using namespace Mantid::DataObjects;
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
 
+/// Returns a vector with the wavelengths of the Peaks stored in this
+/// reflection.
+std::vector<double> UniqueReflection::getWavelengths() const {
+  std::vector<double> wavelengths;
+  wavelengths.reserve(m_peaks.size());
+
+  std::transform(
+      m_peaks.begin(), m_peaks.end(), std::back_inserter(wavelengths),
+      [](const DataObjects::Peak &peak) { return peak.getWavelength(); });
+
+  return wavelengths;
+}
+
 /// Returns a vector with the intensities of the Peaks stored in this
 /// reflection.
 std::vector<double> UniqueReflection::getIntensities() const {
@@ -44,7 +57,8 @@ std::vector<double> UniqueReflection::getSigmas() const {
 
 /// Removes peaks whose intensity deviates more than sigmaCritical from the
 /// intensities' mean.
-UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical) const {
+UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical,
+                                                  bool weightedZ) const {
   if (sigmaCritical <= 0.0) {
     throw std::invalid_argument(
         "Critical sigma value has to be greater than 0.");
@@ -54,7 +68,13 @@ UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical) const {
 
   if (m_peaks.size() > 2) {
     auto intensities = getIntensities();
-    auto zScores = Kernel::getZscore(intensities);
+    std::vector<double> zScores;
+    if (!weightedZ) {
+      zScores = Kernel::getZscore(intensities);
+    } else {
+      auto sigmas = getSigmas();
+      zScores = Kernel::getWeightedZscore(intensities, sigmas);
+    }
 
     for (size_t i = 0; i < zScores.size(); ++i) {
       if (zScores[i] <= sigmaCritical) {
@@ -196,9 +216,15 @@ UniqueReflectionCollection::getReflections() const {
  * group of equivalent reflections.
  *
  * @param uniqueReflections :: Map of unique reflections and peaks.
+ * @param equivalentIntensities :: Mean or median for statistics of equivalent
+ *peaks.
+ * @param sigmaCritical :: Number of standard deviations for outliers.
+ * @param weightedZ :: True for weighted Zscore
  */
 void PeaksStatistics::calculatePeaksStatistics(
-    const std::map<V3D, UniqueReflection> &uniqueReflections) {
+    const std::map<V3D, UniqueReflection> &uniqueReflections,
+    std::string &equivalentIntensities, double &sigmaCritical,
+    bool &weightedZ) {
   double rMergeNumerator = 0.0;
   double rPimNumerator = 0.0;
   double intensitySumRValues = 0.0;
@@ -212,7 +238,8 @@ void PeaksStatistics::calculatePeaksStatistics(
       ++m_uniqueReflections;
 
       // Possibly remove outliers.
-      auto outliersRemoved = unique.second.removeOutliers();
+      auto outliersRemoved =
+          unique.second.removeOutliers(sigmaCritical, weightedZ);
 
       // I/sigma is calculated for all reflections, even if there is only one
       // observation.
@@ -225,9 +252,12 @@ void PeaksStatistics::calculatePeaksStatistics(
       if (outliersRemoved.count() > 1) {
         // Get mean, standard deviation for intensities
         auto intensityStatistics = Kernel::getStatistics(
-            intensities, StatOptions::Mean | StatOptions::UncorrectedStdDev);
+            intensities, StatOptions::Mean | StatOptions::UncorrectedStdDev |
+                             StatOptions::Median);
 
         double meanIntensity = intensityStatistics.mean;
+        if (equivalentIntensities == "Median")
+          meanIntensity = intensityStatistics.median;
 
         /* This was in the original algorithm, not entirely sure where it is
          * used. It's basically the sum of all relative standard deviations.
diff --git a/Framework/Crystal/src/PeaksOnSurface.cpp b/Framework/Crystal/src/PeaksOnSurface.cpp
index 232a9f159d71ada08cf0340a4765b75cbad34d14..0a3953f32f07ab2c4be41a0bc447ca959d28be68 100644
--- a/Framework/Crystal/src/PeaksOnSurface.cpp
+++ b/Framework/Crystal/src/PeaksOnSurface.cpp
@@ -3,7 +3,7 @@
 #include "MantidKernel/MandatoryValidator.h"
 
 using namespace Mantid::Kernel;
-typedef std::vector<double> VecDouble;
+using VecDouble = std::vector<double>;
 
 namespace Mantid {
 namespace Crystal {
diff --git a/Framework/Crystal/src/PredictFractionalPeaks.cpp b/Framework/Crystal/src/PredictFractionalPeaks.cpp
index 635338b4dcddbf35b2d61f4632b654558ef3f415..1bf1b8f4caa55f21a2dcd12ef999bf0796089c0d 100644
--- a/Framework/Crystal/src/PredictFractionalPeaks.cpp
+++ b/Framework/Crystal/src/PredictFractionalPeaks.cpp
@@ -9,6 +9,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Objects/InstrumentRayTracer.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ArrayLengthValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
@@ -129,16 +130,16 @@ void PredictFractionalPeaks::exec() {
 
   V3D hkl;
   int peakNum = 0;
-  int NPeaks = Peaks->getNumberPeaks();
+  const auto NPeaks = Peaks->getNumberPeaks();
   Kernel::Matrix<double> Gon;
   Gon.identityMatrix();
 
-  double Hmin = getProperty("Hmin");
-  double Hmax = getProperty("Hmax");
-  double Kmin = getProperty("Kmin");
-  double Kmax = getProperty("Kmax");
-  double Lmin = getProperty("Lmin");
-  double Lmax = getProperty("Lmax");
+  const double Hmin = getProperty("Hmin");
+  const double Hmax = getProperty("Hmax");
+  const double Kmin = getProperty("Kmin");
+  const double Kmax = getProperty("Kmax");
+  const double Lmin = getProperty("Lmin");
+  const double Lmax = getProperty("Lmax");
 
   int N = NPeaks;
   if (includePeaksInRange) {
@@ -147,7 +148,7 @@ void PredictFractionalPeaks::exec() {
     N = max<int>(100, N);
   }
   IPeak &peak0 = Peaks->getPeak(0);
-  int RunNumber = peak0.getRunNumber();
+  auto RunNumber = peak0.getRunNumber();
   Gon = peak0.getGoniometerMatrix();
   Progress prog(this, 0.0, 1.0, N);
   if (includePeaksInRange) {
@@ -165,6 +166,7 @@ void PredictFractionalPeaks::exec() {
   vector<vector<int>> AlreadyDonePeaks;
   bool done = false;
   int ErrPos = 1; // Used to determine position in code of a throw
+  Geometry::InstrumentRayTracer tracer(Peaks->getInstrument());
   while (!done) {
     for (double hOffset : hOffsets) {
       for (double kOffset : kOffsets) {
@@ -190,7 +192,7 @@ void PredictFractionalPeaks::exec() {
 
             peak->setGoniometerMatrix(Gon);
 
-            if (Qs[2] > 0 && peak->findDetector()) {
+            if (Qs[2] > 0 && peak->findDetector(tracer)) {
               ErrPos = 2;
               vector<int> SavPk{RunNumber,
                                 boost::math::iround(1000.0 * hkl1[0]),
diff --git a/Framework/Crystal/src/PredictPeaks.cpp b/Framework/Crystal/src/PredictPeaks.cpp
index 5dec60e24ced90c773d60e183c74ae2ea16c235c..26a76731256ca2ff7affdfaf5b4f9872ad77e647 100644
--- a/Framework/Crystal/src/PredictPeaks.cpp
+++ b/Framework/Crystal/src/PredictPeaks.cpp
@@ -274,6 +274,7 @@ void PredictPeaks::exec() {
     HKLFilterWavelength lambdaFilter(orientedUB, lambdaMin, lambdaMax);
 
     size_t allowedPeakCount = 0;
+    int seqNum = 1;
 
     bool useExtendedDetectorSpace = getProperty("PredictPeaksOutsideDetectors");
     if (useExtendedDetectorSpace &&
@@ -284,8 +285,9 @@ void PredictPeaks::exec() {
 
     for (auto &possibleHKL : possibleHKLs) {
       if (lambdaFilter.isAllowed(possibleHKL)) {
+        calculateQAndAddToOutput(possibleHKL, orientedUB, goniometerMatrix,
+                                 seqNum);
         ++allowedPeakCount;
-        calculateQAndAddToOutput(possibleHKL, orientedUB, goniometerMatrix);
       }
       prog.report();
     }
@@ -471,10 +473,12 @@ void PredictPeaks::setStructureFactorCalculatorFromSample(
  * @param hkl
  * @param orientedUB
  * @param goniometerMatrix
+ * @param seqNum
  */
 void PredictPeaks::calculateQAndAddToOutput(const V3D &hkl,
                                             const DblMatrix &orientedUB,
-                                            const DblMatrix &goniometerMatrix) {
+                                            const DblMatrix &goniometerMatrix,
+                                            int &seqNum) {
   // The q-vector direction of the peak is = goniometer * ub * hkl_vector
   // This is in inelastic convention: momentum transfer of the LATTICE!
   // Also, q does have a 2pi factor = it is equal to 2pi/wavelength.
@@ -535,6 +539,8 @@ void PredictPeaks::calculateQAndAddToOutput(const V3D &hkl,
   // Save the run number found before.
   peak->setRunNumber(m_runNumber);
   peak->setHKL(hkl * m_qConventionFactor);
+  peak->setPeakNumber(seqNum);
+  seqNum++;
 
   if (m_sfCalculator) {
     peak->setIntensity(m_sfCalculator->getFSquared(hkl));
diff --git a/Framework/Crystal/src/SCDCalibratePanels.cpp b/Framework/Crystal/src/SCDCalibratePanels.cpp
index 7ec8c15ed7bb0b02ff291f07d4975c043887fa60..be3bd66cf023288475cbe10d1eeb676070260bdb 100644
--- a/Framework/Crystal/src/SCDCalibratePanels.cpp
+++ b/Framework/Crystal/src/SCDCalibratePanels.cpp
@@ -102,9 +102,9 @@ void SCDCalibratePanels::exec() {
   std::vector<std::string> parameter_workspaces(
       MyBankNames.size() + MyPanels.size(), "params_");
   int i = 0;
-  for (auto iBank = MyPanels.begin(); iBank != MyPanels.end(); ++iBank) {
-    fit_workspaces[i] += *iBank;
-    parameter_workspaces[i] += *iBank;
+  for (auto &MyPanel : MyPanels) {
+    fit_workspaces[i] += MyPanel;
+    parameter_workspaces[i] += MyPanel;
     i++;
   }
   if (snapPanels) {
@@ -122,9 +122,9 @@ void SCDCalibratePanels::exec() {
                    << " degrees\n";
   }
 
-  for (auto iBank = MyBankNames.begin(); iBank != MyBankNames.end(); ++iBank) {
-    fit_workspaces[i] += *iBank;
-    parameter_workspaces[i] += *iBank;
+  for (auto &MyBankName : MyBankNames) {
+    fit_workspaces[i] += MyBankName;
+    parameter_workspaces[i] += MyBankName;
     i++;
   }
   if (bankPanels) {
@@ -601,9 +601,9 @@ void SCDCalibratePanels::saveXmlFile(
     else
       scaley = 1.;
 
-    oss3 << "  <parameter name =\"scalex\"><value val=\"" << scalex
+    oss3 << R"(  <parameter name ="scalex"><value val=")" << scalex
          << "\" /> </parameter>\n";
-    oss3 << "  <parameter name =\"scaley\"><value val=\"" << scaley
+    oss3 << R"(  <parameter name ="scaley"><value val=")" << scaley
          << "\" /> </parameter>\n";
     oss3 << "</component-link>\n";
   } // for each bank in the group
diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp
index 95f66ca36c1a1536cf33ac15c23620f2e46853af..c91416f25c3d8350fc7248107e70a39ab9369cfa 100644
--- a/Framework/Crystal/src/SaveHKL.cpp
+++ b/Framework/Crystal/src/SaveHKL.cpp
@@ -185,8 +185,8 @@ void SaveHKL::exec() {
   std::string bankPart = "?";
   // We must sort the peaks first by run, then bank #, and save the list of
   // workspace indices of it
-  typedef std::map<int, std::vector<size_t>> bankMap_t;
-  typedef std::map<int, bankMap_t> runMap_t;
+  using bankMap_t = std::map<int, std::vector<size_t>>;
+  using runMap_t = std::map<int, bankMap_t>;
   std::set<int> uniqueBanks;
   std::set<int> uniqueRuns;
   runMap_t runMap;
@@ -345,6 +345,7 @@ void SaveHKL::exec() {
           continue;
         }
         int run = p.getRunNumber();
+        int seqNum = p.getPeakNumber();
         int bank = 0;
         std::string bankName = p.getBankName();
         int nCols, nRows;
@@ -546,7 +547,7 @@ void SaveHKL::exec() {
 
           out << std::setw(6) << run;
 
-          out << std::setw(6) << wi + 1;
+          out << std::setw(6) << seqNum;
 
           out << std::setw(7) << std::fixed << std::setprecision(4)
               << transmission;
diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp
index fd1d3c1b0023787a95a4fd437e7a9b05b76cac1c..6cda29d7aa21a8864823d758f1ae21d75852a6cd 100644
--- a/Framework/Crystal/src/SaveIsawPeaks.cpp
+++ b/Framework/Crystal/src/SaveIsawPeaks.cpp
@@ -62,8 +62,8 @@ void SaveIsawPeaks::exec() {
 
   // We must sort the peaks first by run, then bank #, and save the list of
   // workspace indices of it
-  typedef std::map<int, std::vector<size_t>> bankMap_t;
-  typedef std::map<int, bankMap_t> runMap_t;
+  using bankMap_t = std::map<int, std::vector<size_t>>;
+  using runMap_t = std::map<int, bankMap_t>;
   std::set<int, std::less<int>> uniqueBanks;
   if (!inst)
     throw std::runtime_error(
@@ -259,13 +259,14 @@ void SaveIsawPeaks::exec() {
     qSign = 1.0;
   // ============================== Save all Peaks
   // =========================================
-  // Sequence number
-  int seqNum = 1;
 
   // Go in order of run numbers
+  int maxPeakNumb = 0;
+  int appendPeakNumb = 0;
   runMap_t::iterator runMap_it;
   for (runMap_it = runMap.begin(); runMap_it != runMap.end(); ++runMap_it) {
     // Start of a new run
+    appendPeakNumb += maxPeakNumb;
     int run = runMap_it->first;
     bankMap_t &bankMap = runMap_it->second;
 
@@ -310,7 +311,8 @@ void SaveIsawPeaks::exec() {
           Peak &p = peaks[wi];
 
           // Sequence (run) number
-          out << "3" << std::setw(7) << seqNum;
+          maxPeakNumb = std::max(maxPeakNumb, p.getPeakNumber());
+          out << "3" << std::setw(7) << p.getPeakNumber() + appendPeakNumb;
 
           // HKL's are flipped by -1 because of the internal Q convention
           // unless Crystallography convention
@@ -383,8 +385,6 @@ void SaveIsawPeaks::exec() {
               }
             }
           }
-          // Count the sequence
-          seqNum++;
         }
       }
     }
diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp
index 5d097aa0aff0a82a3306adf772ad93479fa563b0..eedd9fe56437588b4d047a6e1a5aac07f6a9b05b 100644
--- a/Framework/Crystal/src/SaveLauenorm.cpp
+++ b/Framework/Crystal/src/SaveLauenorm.cpp
@@ -10,6 +10,8 @@
 #include "MantidKernel/Strings.h"
 #include "MantidAPI/Sample.h"
 #include "MantidGeometry/Instrument/Goniometer.h"
+#include "boost/math/special_functions/round.hpp"
+
 #include <fstream>
 #include <iostream>
 #include <iomanip>
@@ -66,6 +68,15 @@ void SaveLauenorm::init() {
                                                       Direction::Input),
       "Comma deliminated string of bank numbers to exclude for example 1,2,5");
   declareProperty("LaueScaleFormat", false, "New format for Lauescale");
+
+  declareProperty("CrystalSystem", m_typeList[0],
+                  boost::make_shared<Kernel::StringListValidator>(m_typeList),
+                  "The conventional cell type to use");
+
+  declareProperty(
+      "Centering", m_centeringList[0],
+      boost::make_shared<Kernel::StringListValidator>(m_centeringList),
+      "The centering for the conventional cell");
 }
 
 //----------------------------------------------------------------------------------------------
@@ -86,7 +97,12 @@ void SaveLauenorm::exec() {
   double minIntensity = getProperty("MinIntensity");
   int widthBorder = getProperty("WidthBorder");
   bool newFormat = getProperty("LaueScaleFormat");
-
+  std::string cellType = getProperty("CrystalSystem");
+  auto iter = std::find(m_typeList.begin(), m_typeList.end(), cellType);
+  auto cellNo = 1 + std::distance(m_typeList.begin(), iter);
+  std::string cent = getProperty("Centering");
+  auto iter2 = std::find(m_centeringList.begin(), m_centeringList.end(), cent);
+  auto centerNo = 1 + std::distance(m_centeringList.begin(), iter2);
   // sequenceNo and run number
   int sequenceNo = 0;
   int oldSequence = -1;
@@ -124,7 +140,7 @@ void SaveLauenorm::exec() {
   auto inst = ws->getInstrument();
   OrientedLattice lattice;
   if (newFormat) {
-    type = "RunNumber";
+    type = "Both Bank and RunNumber";
     if (!ws->sample().hasOrientedLattice()) {
 
       const std::string fft("FindUBUsingIndexedPeaks");
@@ -312,11 +328,11 @@ void SaveLauenorm::exec() {
             << 1.0 / lattice.a() << std::setw(12) << std::setprecision(4)
             << 1.0 / lattice.b() << std::setw(12) << std::setprecision(4)
             << 1.0 / lattice.c() << std::setw(9)
-            << static_cast<int>(lattice.alpha() + 0.5) << std::setw(9)
-            << static_cast<int>(lattice.beta() + 0.5) << std::setw(9)
-            << static_cast<int>(lattice.gamma() + 0.5) << "\n";
-        std::vector<int> systemNo = crystalSystem(lattice, peaks);
-        out << "SYST    " << systemNo[0] << "   " << systemNo[1] << "   0   0"
+            << boost::math::iround(lattice.alpha()) << std::setw(9)
+            << boost::math::iround(lattice.beta()) << std::setw(9)
+            << boost::math::iround(lattice.gamma()) << '\n';
+
+        out << "SYST    " << cellNo << "   " << centerNo << "   1   3"
             << "\n";
         out << "RAST      0.050"
             << "\n";
@@ -362,10 +378,10 @@ void SaveLauenorm::exec() {
         out << "BULG    0.00000     0.00000     0.00000     0.00000     "
                "0.00000     0.00000 \n";
         out << "CTOF     " << L2 << "\n";
-        out << "YSCA     0.00000     0.00000     0.00000     0.00000     "
-               "0.00000     0.00000\n";
-        out << "CRAT     0.00000     0.00000     0.00000     0.00000     "
-               "0.00000     0.00000\n";
+        out << "YSCA     1.00000     1.00000     1.00000     1.00000     "
+               "1.00000     1.00000\n";
+        out << "CRAT     1.00000     1.00000     1.00000     1.00000     "
+               "1.00000     1.00000\n";
         out << "MINI          ";
         if (minIntensity != EMPTY_DBL()) {
           out << minIntensity << "\n";
@@ -418,7 +434,7 @@ void SaveLauenorm::exec() {
     out << std::setw(10) << std::fixed << std::setprecision(5) << lambda;
     if (newFormat) {
       // mult nodal ovlp close h2 k2 l2 nidx lambda2 ipoint
-      out << " 1 0 0 0 0 0 0 0 0 0 ";
+      out << " 1 0 0 0 0 0 0 0 0.0 0 ";
     }
 
     if (newFormat) {
@@ -506,102 +522,6 @@ void SaveLauenorm::sizeBanks(std::string bankName, int &nCols, int &nRows) {
     nCols = static_cast<int>(children.size());
   }
 }
-std::vector<int> SaveLauenorm::crystalSystem(OrientedLattice lattice,
-                                             std::vector<Peak> peaks) {
-  std::vector<int> systemVec;
-  int alpha = static_cast<int>(lattice.alpha() + 0.5);
-  int beta = static_cast<int>(lattice.beta() + 0.5);
-  int gamma = static_cast<int>(lattice.gamma() + 0.5);
-  int a = static_cast<int>(lattice.a() * 1000 + 0.5);
-  int b = static_cast<int>(lattice.b() * 1000 + 0.5);
-  int c = static_cast<int>(lattice.c() * 1000 + 0.5);
-  if (alpha == 90 && beta == 90 && gamma == 90) {
-    if (a == b && a == c) {
-      systemVec.push_back(7); // cubic I,F
-    } else if (a == b) {
-      systemVec.push_back(4); // tetragonal I
-    } else {
-      systemVec.push_back(3); // orthorhombic I,A,B,C,F
-    }
-  } else if (alpha == 90 && beta == 90 && gamma == 120 && a == b) {
-    systemVec.push_back(6); // hexagonal
-  } else if ((alpha == 90 && beta == 90) || (alpha == 90 && gamma == 90) ||
-             (beta == 90 && gamma == 90)) {
-    systemVec.push_back(2); // monoclinic I,A,B,C
-  } else if (alpha == 90 && beta == 90 && gamma != 90 && a == b && a == c) {
-    systemVec.push_back(5); // rhombohedral R
-  } else {
-    systemVec.push_back(1); // triclinic
-  }
-  int i = 0;
-  int fp = 0;
-  int fm = 0;
-  int cc = 0;
-  int bc = 0;
-  int ac = 0;
-  int r = 0;
-  int total = 0;
-  for (size_t j = 0; j < peaks.size(); j++) {
-    int h = static_cast<int>(peaks[j].getH() + 0.5);
-    int k = static_cast<int>(peaks[j].getK() + 0.5);
-    int l = static_cast<int>(peaks[j].getL() + 0.5);
-    if (h + k + l == 0)
-      continue;
-    total++;
-    if ((h + k + l) % 2 == 0) {
-      i++;
-    }
-    if (h % 2 == 0 && k % 2 == 0 && l % 2 == 0) {
-      fp++;
-    }
-    if (h % 2 != 0 && k % 2 != 0 && l % 2 != 0) {
-      fm++;
-    }
-    if ((h + k) % 2 == 0) {
-      cc++;
-    }
-    if ((h + l) % 2 == 0) {
-      bc++;
-    }
-    if ((k + l) % 2 == 0) {
-      ac++;
-    }
-    if ((-h + k + l) % 3 == 0) {
-      r++;
-    }
-  }
-  int maxCen = 1;
-  int maxPeaks = 0;
-  if (maxPeaks < i) {
-    maxCen = 2; // I
-    maxPeaks = i;
-  }
-  if (maxPeaks < ac) {
-    maxCen = 3; // A
-    maxPeaks = ac;
-  }
-  if (maxPeaks < bc) {
-    maxCen = 4; // B
-    maxPeaks = bc;
-  }
-  if (maxPeaks < cc) {
-    maxCen = 5; // C
-    maxPeaks = cc;
-  }
-  if (maxPeaks < fp || maxPeaks < fm) {
-    maxCen = 6; // F
-    maxPeaks = std::max(fp, fm);
-  }
-  if (maxPeaks < r) {
-    maxCen = 7; // R
-    maxPeaks = r;
-  }
-  if (maxPeaks < 6 * total / 10) {
-    maxCen = 1; // P
-  }
-  systemVec.push_back(maxCen); // P
-  return systemVec;
-}
 
 } // namespace Mantid
 } // namespace Crystal
diff --git a/Framework/Crystal/src/SortHKL.cpp b/Framework/Crystal/src/SortHKL.cpp
index 976b92085587fa9522e0648ba9c54735d51e4619..f77708bfa28d97c98529f2a370bf8b6b7e43a1f8 100644
--- a/Framework/Crystal/src/SortHKL.cpp
+++ b/Framework/Crystal/src/SortHKL.cpp
@@ -1,16 +1,16 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/Sample.h"
-
+#include "MantidDataObjects/Workspace2D.h"
 #include "MantidCrystal/SortHKL.h"
-
+#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
-
+#include "MantidAPI/TextAxis.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidGeometry/Crystal/PointGroupFactory.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
-
+#include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/Utils.h"
 
@@ -84,6 +84,22 @@ void SortHKL::init() {
   declareProperty("Append", false,
                   "Append to output table workspace if true.\n"
                   "If false, new output table workspace (default).");
+  std::vector<std::string> equivTypes{"Mean", "Median"};
+  declareProperty("EquivalentIntensities", equivTypes[0],
+                  boost::make_shared<StringListValidator>(equivTypes),
+                  "Replace intensities by mean(default), "
+                  "or median.");
+  declareProperty(Kernel::make_unique<PropertyWithValue<double>>(
+                      "SigmaCritical", 3.0, Direction::Input),
+                  "Removes peaks whose intensity deviates more than "
+                  "SigmaCritical from the mean (or median).");
+  declareProperty(
+      make_unique<WorkspaceProperty<MatrixWorkspace>>(
+          "EquivalentsWorkspace", "EquivalentIntensities", Direction::Output),
+      "Output Equivalent Intensities");
+  declareProperty("WeightedZScore", false,
+                  "Use weighted ZScore if true.\n"
+                  "If false, standard ZScore (default).");
 }
 
 void SortHKL::exec() {
@@ -101,8 +117,112 @@ void SortHKL::exec() {
 
   UniqueReflectionCollection uniqueReflections =
       getUniqueReflections(peaks, cell);
+  std::string equivalentIntensities = getPropertyValue("EquivalentIntensities");
+  double sigmaCritical = getProperty("SigmaCritical");
+  bool weightedZ = getProperty("WeightedZScore");
+
+  MatrixWorkspace_sptr UniqWksp =
+      Mantid::API::WorkspaceFactory::Instance().create(
+          "Workspace2D", uniqueReflections.getReflections().size(), 20, 20);
+  int counter = 0;
+  size_t maxPeaks = 0;
+  auto taxis = new TextAxis(uniqueReflections.getReflections().size());
+  UniqWksp->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength");
+  for (const auto &unique : uniqueReflections.getReflections()) {
+    /* Since all possible unique reflections are explored
+     * there may be 0 observations for some of them.
+     * In that case, nothing can be done.*/
+
+    if (unique.second.count() > 2) {
+      taxis->setLabel(counter, "   " + unique.second.getHKL().toString());
+      auto &UniqX = UniqWksp->mutableX(counter);
+      auto &UniqY = UniqWksp->mutableY(counter);
+      auto &UniqE = UniqWksp->mutableE(counter);
+      counter++;
+      auto wavelengths = unique.second.getWavelengths();
+      auto intensities = unique.second.getIntensities();
+      g_log.debug() << "HKL " << unique.second.getHKL() << "\n";
+      g_log.debug() << "Intensities ";
+      for (const auto &e : intensities)
+        g_log.debug() << e << "  ";
+      g_log.debug() << "\n";
+      std::vector<double> zScores;
+      if (!weightedZ) {
+        zScores = Kernel::getZscore(intensities);
+      } else {
+        auto sigmas = unique.second.getSigmas();
+        zScores = Kernel::getWeightedZscore(intensities, sigmas);
+      }
+
+      if (zScores.size() > maxPeaks)
+        maxPeaks = zScores.size();
+      // Possibly remove outliers.
+      auto outliersRemoved =
+          unique.second.removeOutliers(sigmaCritical, weightedZ);
+
+      auto intensityStatistics =
+          Kernel::getStatistics(outliersRemoved.getIntensities(),
+                                StatOptions::Mean | StatOptions::Median);
+
+      g_log.debug() << "Mean = " << intensityStatistics.mean
+                    << "  Median = " << intensityStatistics.median << "\n";
+      // sort wavelengths & intensities
+      for (size_t i = 0; i < wavelengths.size(); i++) {
+        size_t i0 = i;
+        for (size_t j = i + 1; j < wavelengths.size(); j++) {
+          if (wavelengths[j] < wavelengths[i0]) // Change was here!
+          {
+            i0 = j;
+          }
+        }
+        double temp = wavelengths[i0];
+        wavelengths[i0] = wavelengths[i];
+        wavelengths[i] = temp;
+        temp = intensities[i0];
+        intensities[i0] = intensities[i];
+        intensities[i] = temp;
+      }
+      g_log.debug() << "Zscores ";
+      for (size_t i = 0; i < std::min(zScores.size(), static_cast<size_t>(20));
+           ++i) {
+        UniqX[i] = wavelengths[i];
+        UniqY[i] = intensities[i];
+        if (zScores[i] > sigmaCritical)
+          UniqE[i] = intensities[i];
+        else if (equivalentIntensities == "Mean")
+          UniqE[i] = intensityStatistics.mean - intensities[i];
+        else
+          UniqE[i] = intensityStatistics.median - intensities[i];
+        g_log.debug() << zScores[i] << "  ";
+      }
+      for (size_t i = zScores.size(); i < 20; ++i) {
+        UniqX[i] = wavelengths[zScores.size() - 1];
+        UniqY[i] = intensities[zScores.size() - 1];
+        UniqE[i] = 0.0;
+      }
+      g_log.debug() << "\n";
+    }
+  }
+
+  if (counter > 0) {
+    MatrixWorkspace_sptr UniqWksp2 =
+        Mantid::API::WorkspaceFactory::Instance().create("Workspace2D", counter,
+                                                         maxPeaks, maxPeaks);
+    for (int64_t i = 0; i < counter; ++i) {
+      auto &outSpec = UniqWksp2->getSpectrum(i);
+      const auto &inSpec = UniqWksp->getSpectrum(i);
+      outSpec.setHistogram(inSpec.histogram());
+      // Copy the spectrum number/detector IDs
+      outSpec.copyInfoFrom(inSpec);
+    }
+    UniqWksp2->replaceAxis(1, taxis);
+    setProperty("EquivalentsWorkspace", UniqWksp2);
+  } else {
+    setProperty("EquivalentsWorkspace", UniqWksp);
+  }
 
-  PeaksStatistics peaksStatistics(uniqueReflections);
+  PeaksStatistics peaksStatistics(uniqueReflections, equivalentIntensities,
+                                  sigmaCritical, weightedZ);
 
   // Store the statistics for output.
   const std::string tableName = getProperty("StatisticsTable");
diff --git a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp
index fc67fa1e3ebd99c3dbc9cd587475fb186ac66718..3a1351badd3ea597548405cdf5962fbb44023989 100644
--- a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp
+++ b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp
@@ -6,6 +6,7 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidDataObjects/Workspace2D.h"
 
 #include <fstream>
 
@@ -75,6 +76,22 @@ void StatisticsOfPeaksWorkspace::init() {
                   boost::make_shared<StringListValidator>(sortTypes),
                   "Sort the peaks by resolution shell in d-Spacing(default), "
                   "bank, run number, or only overall statistics.");
+  std::vector<std::string> equivTypes{"Mean", "Median"};
+  declareProperty("EquivalentIntensities", equivTypes[0],
+                  boost::make_shared<StringListValidator>(equivTypes),
+                  "Replace intensities by mean(default), "
+                  "or median.");
+  declareProperty(Kernel::make_unique<PropertyWithValue<double>>(
+                      "SigmaCritical", 3.0, Direction::Input),
+                  "Removes peaks whose intensity deviates more than "
+                  "SigmaCritical from the mean (or median).");
+  declareProperty(
+      make_unique<WorkspaceProperty<MatrixWorkspace>>(
+          "EquivalentsWorkspace", "EquivalentIntensities", Direction::Output),
+      "Output Equivalent Intensities");
+  declareProperty("WeightedZScore", false,
+                  "Use weighted ZScore if true.\n"
+                  "If false, standard ZScore (default).");
 }
 
 //----------------------------------------------------------------------------------------------
@@ -177,6 +194,9 @@ void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws,
   std::string latticeCentering = getPropertyValue("LatticeCentering");
   std::string wkspName = getPropertyValue("OutputWorkspace");
   std::string tableName = getPropertyValue("StatisticsTable");
+  std::string equivalentIntensities = getPropertyValue("EquivalentIntensities");
+  double sigmaCritical = getProperty("SigmaCritical");
+  bool weightedZ = getProperty("WeightedZScore");
   API::IAlgorithm_sptr statsAlg = createChildAlgorithm("SortHKL");
   statsAlg->setProperty("InputWorkspace", ws);
   statsAlg->setPropertyValue("OutputWorkspace", wkspName);
@@ -186,12 +206,17 @@ void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws,
   statsAlg->setProperty("RowName", runName);
   if (runName != "Overall")
     statsAlg->setProperty("Append", true);
+  statsAlg->setPropertyValue("EquivalentIntensities", equivalentIntensities);
+  statsAlg->setProperty("SigmaCritical", sigmaCritical);
+  statsAlg->setProperty("WeightedZScore", weightedZ);
   statsAlg->executeAsChildAlg();
   PeaksWorkspace_sptr statsWksp = statsAlg->getProperty("OutputWorkspace");
   ITableWorkspace_sptr tablews = statsAlg->getProperty("StatisticsTable");
+  MatrixWorkspace_sptr equivws = statsAlg->getProperty("EquivalentsWorkspace");
   if (runName == "Overall")
     setProperty("OutputWorkspace", statsWksp);
   setProperty("StatisticsTable", tablews);
+  setProperty("EquivalentsWorkspace", equivws);
 }
 
 } // namespace Mantid
diff --git a/Framework/Crystal/test/AnvredCorrectionTest.h b/Framework/Crystal/test/AnvredCorrectionTest.h
index 9cfe9fe7607267ea0a27924ebafa56ad3a7ecabd..c85b2647689a16ed26652ffe88d03bda4d54153d 100644
--- a/Framework/Crystal/test/AnvredCorrectionTest.h
+++ b/Framework/Crystal/test/AnvredCorrectionTest.h
@@ -12,11 +12,6 @@
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/FacilityHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 #include <math.h>
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/Crystal/test/CentroidPeaksTest.h b/Framework/Crystal/test/CentroidPeaksTest.h
index 42a0d5a74db7b96b1ea33c108ba281e66ebf2899..332cf6e8d5b66aeeb340a5c068a077769f6ecd88 100644
--- a/Framework/Crystal/test/CentroidPeaksTest.h
+++ b/Framework/Crystal/test/CentroidPeaksTest.h
@@ -15,13 +15,9 @@
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/FacilityHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 #include <cxxtest/TestSuite.h>
-#include <math.h>
+#include <cmath>
+#include <random>
 
 using namespace Mantid;
 using namespace Mantid::Crystal;
@@ -48,27 +44,8 @@ public:
     int numPixels = 10000;
     int numBins = 16;
     double binDelta = 10.0;
-    boost::mt19937 rng;
-    boost::uniform_real<double> u2(0, 1.0); // Random from 0 to 1.0
-    boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>>
-        genUnit(rng, u2);
-    int randomSeed = 1;
-    rng.seed((unsigned int)(randomSeed));
-    size_t nd = 1;
-    // Make a random generator for each dimensions
-    typedef boost::variate_generator<boost::mt19937 &,
-                                     boost::uniform_real<double>> gen_t;
-    gen_t *gens[1];
-    for (size_t d = 0; d < nd; ++d) {
-      double min = -1.;
-      double max = 1.;
-      if (max <= min)
-        throw std::invalid_argument(
-            "UniformParams: min must be < max for all dimensions.");
-      boost::uniform_real<double> u(min, max); // Range
-      gen_t *gen = new gen_t(rng, u);
-      gens[d] = gen;
-    }
+    std::mt19937 rng(1);
+    std::uniform_real_distribution<double> flat(-1.0, 1.0);
 
     boost::shared_ptr<EventWorkspace> retVal = create<EventWorkspace>(
         numPixels, BinEdges(numBins, LinearGenerator(0.0, binDelta)));
@@ -104,16 +81,11 @@ public:
                                 (pix % 100 - 50.5) * (pix % 100 - 50.5)));
       for (int i = 0; i < r; i++) {
         el += TofEvent(
-            5844. +
-                10. * (((*gens[0])() + (*gens[0])() + (*gens[0])()) * 2. - 3.),
+            5844. + 10. * ((flat(rng) + flat(rng) + flat(rng)) * 2. - 3.),
             run_start + double(i));
       }
     }
 
-    /// Clean up the generators
-    for (size_t d = 0; d < nd; ++d)
-      delete gens[d];
-
     // Some sanity checks
     TS_ASSERT_EQUALS(retVal->getInstrument()->getName(), "MINITOPAZ");
     std::map<int, Geometry::IDetector_const_sptr> dets;
diff --git a/Framework/Crystal/test/ClusterIntegrationBaseTest.h b/Framework/Crystal/test/ClusterIntegrationBaseTest.h
index d9b6e454ef057d216a855fe8b52ddea24dce9ba7..56d0fe03679e84f778f9cf847ebf0296094b8b0d 100644
--- a/Framework/Crystal/test/ClusterIntegrationBaseTest.h
+++ b/Framework/Crystal/test/ClusterIntegrationBaseTest.h
@@ -28,11 +28,11 @@ using namespace Mantid::DataObjects;
 using namespace Mantid::Geometry;
 
 // Helper typedef
-typedef boost::tuple<IMDHistoWorkspace_sptr, IPeaksWorkspace_sptr>
-    MDHistoPeaksWSTuple;
+using MDHistoPeaksWSTuple =
+    boost::tuple<IMDHistoWorkspace_sptr, IPeaksWorkspace_sptr>;
 // Helper typedef
-typedef boost::tuple<IMDEventWorkspace_sptr, IPeaksWorkspace_sptr>
-    MDEventPeaksWSTuple;
+using MDEventPeaksWSTuple =
+    boost::tuple<IMDEventWorkspace_sptr, IPeaksWorkspace_sptr>;
 
 class ClusterIntegrationBaseTest {
 protected:
diff --git a/Framework/Crystal/test/ConnectedComponentLabelingTest.h b/Framework/Crystal/test/ConnectedComponentLabelingTest.h
index 81beb4d05b422152c0ce2ca58e0470a39968e9da..dc161cfcc893e95b8d09b96e1b004768e78437de 100644
--- a/Framework/Crystal/test/ConnectedComponentLabelingTest.h
+++ b/Framework/Crystal/test/ConnectedComponentLabelingTest.h
@@ -410,9 +410,8 @@ public:
                              clusterThreeIndexes.end());
 
     // Add elevated signal to the workspace at cluster indexes.
-    for (auto it = allClusterIndexes.begin(); it != allClusterIndexes.end();
-         ++it) {
-      inWS->setSignalAt(*it, raisedSignal);
+    for (auto &clusterIndex : allClusterIndexes) {
+      inWS->setSignalAt(clusterIndex, raisedSignal);
     }
 
     // ---------- Run the cluster finding
diff --git a/Framework/Crystal/test/DisjointElementTest.h b/Framework/Crystal/test/DisjointElementTest.h
index d3ffecfe6588f1055b58b84a1a52c0662427419d..f5601020bed76d13cce378f707a83680c5107eb1 100644
--- a/Framework/Crystal/test/DisjointElementTest.h
+++ b/Framework/Crystal/test/DisjointElementTest.h
@@ -139,8 +139,8 @@ public:
   }
 
   void test_complex() {
-    typedef boost::shared_ptr<DisjointElement> DisjointElement_sptr;
-    typedef std::vector<DisjointElement_sptr> VecDisjointElement;
+    using DisjointElement_sptr = boost::shared_ptr<DisjointElement>;
+    using VecDisjointElement = std::vector<DisjointElement_sptr>;
 
     // Create elements from 0-9
     VecDisjointElement vecElements;
diff --git a/Framework/Crystal/test/HardThresholdBackgroundTest.h b/Framework/Crystal/test/HardThresholdBackgroundTest.h
index 3ba3c728bd0c74cd58939eb77955516fa65ae8cf..5d9566fcb27db74f4636fe95d8df25489e2f0c12 100644
--- a/Framework/Crystal/test/HardThresholdBackgroundTest.h
+++ b/Framework/Crystal/test/HardThresholdBackgroundTest.h
@@ -23,11 +23,11 @@ public:
   void test_isBackground() {
     const double threshold = 1;
     MDHistoWorkspace_sptr ws = makeFakeMDHistoWorkspace(threshold, 1, 1);
-    auto iterator = ws->createIterator(NULL);
+    auto iterator = ws->createIterator(nullptr);
 
     HardThresholdBackground strategy(threshold, Mantid::API::NoNormalization);
 
-    TS_ASSERT(strategy.isBackground(iterator));
+    TS_ASSERT(strategy.isBackground(iterator.get()));
   }
 };
 
diff --git a/Framework/Crystal/test/IntegratePeaksHybridTest.h b/Framework/Crystal/test/IntegratePeaksHybridTest.h
index 693cf2f8bbce0a8bedcc38c6ecdc1f9d00fa817f..97c2a4a92e98da68b93cf5255d36eb0075ca4ae3 100644
--- a/Framework/Crystal/test/IntegratePeaksHybridTest.h
+++ b/Framework/Crystal/test/IntegratePeaksHybridTest.h
@@ -19,8 +19,8 @@ using namespace Mantid::DataObjects;
 using namespace Mantid::API;
 
 namespace {
-typedef boost::tuple<WorkspaceGroup_sptr, IPeaksWorkspace_sptr>
-    AlgorithmOutputs;
+using AlgorithmOutputs =
+    boost::tuple<WorkspaceGroup_sptr, IPeaksWorkspace_sptr>;
 
 // Execute the clustering integration algorithm
 AlgorithmOutputs execute_integration(const MDEventPeaksWSTuple &inputWorkspaces,
diff --git a/Framework/Crystal/test/NormaliseVanadiumTest.h b/Framework/Crystal/test/NormaliseVanadiumTest.h
index d7f35363129105e81afaf32e23964a26d983a717..2cf7ede158b57cf580dcddacb11dc5100096819d 100644
--- a/Framework/Crystal/test/NormaliseVanadiumTest.h
+++ b/Framework/Crystal/test/NormaliseVanadiumTest.h
@@ -12,13 +12,9 @@
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/FacilityHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 #include <cxxtest/TestSuite.h>
-#include <math.h>
+#include <cmath>
+#include <random>
 
 using namespace Mantid;
 using namespace Mantid::Crystal;
@@ -44,27 +40,6 @@ EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents) {
   int numPixels = 10000;
   int numBins = 16;
   double binDelta = 0.10;
-  boost::mt19937 rng;
-  boost::uniform_real<double> u2(0, 1.0); // Random from 0 to 1.0
-  boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>>
-      genUnit(rng, u2);
-  int randomSeed = 1;
-  rng.seed((unsigned int)(randomSeed));
-  size_t nd = 1;
-  // Make a random generator for each dimensions
-  typedef boost::variate_generator<boost::mt19937 &,
-                                   boost::uniform_real<double>> gen_t;
-  gen_t *gens[1];
-  for (size_t d = 0; d < nd; ++d) {
-    double min = -1.;
-    double max = 1.;
-    if (max <= min)
-      throw std::invalid_argument(
-          "UniformParams: min must be < max for all dimensions.");
-    boost::uniform_real<double> u(min, max); // Range
-    gen_t *gen = new gen_t(rng, u);
-    gens[d] = gen;
-  }
 
   EventWorkspace_sptr retVal(new EventWorkspace);
   retVal->initialize(numPixels, 1, 1);
@@ -84,7 +59,8 @@ EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents) {
   retVal->populateInstrumentParameters();
 
   DateAndTime run_start("2010-01-01T00:00:00");
-
+  std::mt19937 rng(1);
+  std::uniform_real_distribution<double> flat(-1.0, 1.0);
   for (int pix = 0; pix < numPixels; pix++) {
     EventList &el = retVal->getSpectrum(pix);
     el.setSpectrumNo(pix);
@@ -102,17 +78,11 @@ EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents) {
                               (pix % 100 - 50.5) * (pix % 100 - 50.5)));
     for (int i = 0; i < r; i++) {
       el += TofEvent(
-          0.75 +
-              binDelta *
-                  (((*gens[0])() + (*gens[0])() + (*gens[0])()) * 2. - 3.),
+          0.75 + binDelta * ((flat(rng) + flat(rng) + flat(rng)) * 2. - 3.),
           run_start + double(i));
     }
   }
 
-  /// Clean up the generators
-  for (size_t d = 0; d < nd; ++d)
-    delete gens[d];
-
   // Set all the histograms at once.
   retVal->setAllX(BinEdges(numBins, LinearGenerator(0.0, binDelta)));
 
@@ -146,11 +116,6 @@ IAlgorithm_sptr createAlgorithm() {
 }
 }
 
-class NormaliseVanadiumImpl : public NormaliseVanadium {
-public:
-  void exec() override { NormaliseVanadium::exec(); };
-};
-
 class NormaliseVanadiumTest : public CxxTest::TestSuite {
 public:
   void test_Init() {
@@ -159,7 +124,7 @@ public:
     TS_ASSERT(alg.isInitialized())
   }
 
-  void do_test_MINITOPAZ() {
+  void test_MINITOPAZ() {
 
     IAlgorithm_sptr alg = createAlgorithm();
     TS_ASSERT_THROWS_NOTHING(alg->execute();)
@@ -172,14 +137,9 @@ public:
     TS_ASSERT(ws);
     if (!ws)
       return;
-    TS_ASSERT_DELTA(ws->y(5050)[5], 7.7142, 0.01);
+    TS_ASSERT_DELTA(ws->y(5050)[5], 17, 0.0001);
     AnalysisDataService::Instance().remove("TOPAZ");
   }
-
-  void test_MINITOPAZ() {
-    for (int i = 0; i < 1; i++)
-      do_test_MINITOPAZ();
-  }
 };
 
 class NormaliseVanadiumTestPerformance : public CxxTest::TestSuite {
diff --git a/Framework/Crystal/test/PeakBackgroundTest.h b/Framework/Crystal/test/PeakBackgroundTest.h
index 7b21d7d9da006754ba5a01247d98886c4a2e125a..4605bc1606738d9a813cc12304c531a78893c931 100644
--- a/Framework/Crystal/test/PeakBackgroundTest.h
+++ b/Framework/Crystal/test/PeakBackgroundTest.h
@@ -48,10 +48,12 @@ public:
   MOCK_CONST_METHOD0(getNormalizedSignalWithMask, signal_t());
   MOCK_CONST_METHOD0(getSignal, signal_t());
   MOCK_CONST_METHOD0(getError, signal_t());
-  MOCK_CONST_METHOD1(getVertexesArray, coord_t *(size_t &numVertices));
+  MOCK_CONST_METHOD1(getVertexesArray,
+                     std::unique_ptr<coord_t[]>(size_t &numVertices));
   MOCK_CONST_METHOD3(getVertexesArray,
-                     coord_t *(size_t &numVertices, const size_t outDimensions,
-                               const bool *maskDim));
+                     std::unique_ptr<coord_t[]>(size_t &numVertices,
+                                                const size_t outDimensions,
+                                                const bool *maskDim));
   MOCK_CONST_METHOD0(getCenter, Mantid::Kernel::VMD());
   MOCK_CONST_METHOD0(getNumEvents, size_t());
   MOCK_CONST_METHOD1(getInnerRunIndex, uint16_t(size_t index));
diff --git a/Framework/Crystal/test/PeakIntegrationTest.h b/Framework/Crystal/test/PeakIntegrationTest.h
index b20f054df2aee8e07d99ab913fb9dfb7ed2b5061..b0556b5d5310ec0052d49a58c811a1511dcad324 100644
--- a/Framework/Crystal/test/PeakIntegrationTest.h
+++ b/Framework/Crystal/test/PeakIntegrationTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataHandling/LoadInstrument.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidDataObjects/WorkspaceCreation.h"
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidKernel/OptionalBool.h"
 #include "MantidKernel/System.h"
@@ -14,14 +15,8 @@
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/FacilityHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
-
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
-
-#include <math.h>
+#include <cmath>
+#include <random>
 
 #include <cxxtest/TestSuite.h>
 
@@ -51,30 +46,11 @@ public:
     int numPixels = 10000;
     int numBins = 16;
     double binDelta = 10.0;
-    boost::mt19937 rng;
-    boost::uniform_real<double> u2(0, 1.0); // Random from 0 to 1.0
-    boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>>
-        genUnit(rng, u2);
-    int randomSeed = 1;
-    rng.seed((unsigned int)(randomSeed));
-    size_t nd = 1;
-    // Make a random generator for each dimensions
-    typedef boost::variate_generator<boost::mt19937 &,
-                                     boost::uniform_real<double>> gen_t;
-    gen_t *gens[1];
-    for (size_t d = 0; d < nd; ++d) {
-      double min = -1.;
-      double max = 1.;
-      if (max <= min)
-        throw std::invalid_argument(
-            "UniformParams: min must be < max for all dimensions.");
-      boost::uniform_real<double> u(min, max); // Range
-      gen_t *gen = new gen_t(rng, u);
-      gens[d] = gen;
-    }
+    std::mt19937 rng(1);
+    std::uniform_real_distribution<double> flat(-1.0, 1.0);
 
-    EventWorkspace_sptr retVal(new EventWorkspace);
-    retVal->initialize(numPixels, 1, 1);
+    EventWorkspace_sptr retVal = create<EventWorkspace>(
+        numPixels, BinEdges(numBins, LinearGenerator(0.0, binDelta)));
 
     // --------- Load the instrument -----------
     LoadInstrument *loadInst = new LoadInstrument();
@@ -109,19 +85,11 @@ public:
                                 (pix % 100 - 50.5) * (pix % 100 - 50.5)));
       for (int i = 0; i < r; i++) {
         el += TofEvent(
-            5844. +
-                10. * (((*gens[0])() + (*gens[0])() + (*gens[0])()) * 2. - 3.),
+            5844. + 10. * ((flat(rng) + flat(rng) + flat(rng)) * 2. - 3.),
             run_start + double(i));
       }
     }
 
-    /// Clean up the generators
-    for (size_t d = 0; d < nd; ++d)
-      delete gens[d];
-
-    // Set all the histograms at once.
-    retVal->setAllX(BinEdges(numBins, LinearGenerator(0.0, binDelta)));
-
     // Some sanity checks
     TS_ASSERT_EQUALS(retVal->getInstrument()->getName(), "MINITOPAZ");
     std::map<int, Geometry::IDetector_const_sptr> dets;
diff --git a/Framework/Crystal/test/PeakStatisticsToolsTest.h b/Framework/Crystal/test/PeakStatisticsToolsTest.h
index 779df462ee03d7bdd77fc92a82f02198f912161c..7f84cfa02c7354b2ac0ac0f503c05bac6a28dfb4 100644
--- a/Framework/Crystal/test/PeakStatisticsToolsTest.h
+++ b/Framework/Crystal/test/PeakStatisticsToolsTest.h
@@ -178,6 +178,30 @@ public:
     TS_ASSERT_EQUALS(cleanIntensities[1], 31.0);
   }
 
+  void test_UniqueReflectionRemoveOutliersWeighted() {
+    UniqueReflection reflection =
+        getReflectionWithPeaks({30.0, 34.0, 32.0, 31.0}, {4.5, 6.5, 10.0, 2.3});
+
+    // standard deviation is 1.70782512765993
+    auto cleanReflection = reflection.removeOutliers(3.0, true);
+    TSM_ASSERT_EQUALS(
+        "UniqueReflection removed outlier although it should not.",
+        cleanReflection.count(), 3);
+
+    cleanReflection = reflection.removeOutliers(2.0, true);
+    TSM_ASSERT_EQUALS(
+        "UniqueReflection removed outlier although it should not.",
+        cleanReflection.count(), 2);
+
+    cleanReflection = reflection.removeOutliers(1.0, true);
+    TSM_ASSERT_EQUALS(
+        "UniqueReflection did not remove outliers although it should have.",
+        cleanReflection.count(), 1);
+
+    std::vector<double> cleanIntensities = cleanReflection.getIntensities();
+    TS_ASSERT_EQUALS(cleanIntensities[0], 32.0);
+  }
+
   void test_UniqueReflectionSetIntensityAndSigma() {
     UniqueReflection reflection =
         getReflectionWithPeaks({30.0, 34.0, 32.0, 31.0}, {4.5, 6.5, 10.0, 2.3});
diff --git a/Framework/Crystal/test/PeaksInRegionTest.h b/Framework/Crystal/test/PeaksInRegionTest.h
index d22b5b8bdb042483b3907830589fbad670c0bade..0d15e62e69ae18807d43e293dfafa9ffa5c3e6af 100644
--- a/Framework/Crystal/test/PeaksInRegionTest.h
+++ b/Framework/Crystal/test/PeaksInRegionTest.h
@@ -19,8 +19,8 @@ Functional Tests
 class PeaksInRegionTest : public CxxTest::TestSuite {
 
 private:
-  typedef boost::tuple<PeaksWorkspace_sptr, std::vector<double>>
-      PeakWorkspaceWithExtents;
+  using PeakWorkspaceWithExtents =
+      boost::tuple<PeaksWorkspace_sptr, std::vector<double>>;
 
   /**
   Helper function. Creates a peaksworkspace with a single peak
diff --git a/Framework/Crystal/test/PredictPeaksTest.h b/Framework/Crystal/test/PredictPeaksTest.h
index ef297ab7108c36d69cc87f019564c751fb405c85..6778889cdc04a831cfb6977e6951db641086f479 100644
--- a/Framework/Crystal/test/PredictPeaksTest.h
+++ b/Framework/Crystal/test/PredictPeaksTest.h
@@ -37,9 +37,9 @@ public:
     PeaksWorkspace_sptr hklPW;
     if (hkls.size() > 0) {
       hklPW = PeaksWorkspace_sptr(new PeaksWorkspace());
-      for (size_t i = 0; i < hkls.size(); i++) {
+      for (const auto &hkl : hkls) {
         Peak p(inst, detid, 1.0);
-        p.setHKL(hkls[i]);
+        p.setHKL(hkl);
         hklPW->addPeak(p);
       }
     }
diff --git a/Framework/Crystal/test/SCDCalibratePanelsTest.h b/Framework/Crystal/test/SCDCalibratePanelsTest.h
index 68b8026d4f6d0a59a632744f00e868dd3b0e4478..3113192c978c7ba6de20ae2428dbcb9e1a8acd58 100644
--- a/Framework/Crystal/test/SCDCalibratePanelsTest.h
+++ b/Framework/Crystal/test/SCDCalibratePanelsTest.h
@@ -17,7 +17,6 @@ using namespace Mantid::DataObjects;
 using namespace std;
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
-using namespace Mantid::Geometry;
 using namespace Mantid::Crystal;
 
 class SCDCalibratePanelsTest : public CxxTest::TestSuite {
diff --git a/Framework/Crystal/test/SaveLauenormTest.h b/Framework/Crystal/test/SaveLauenormTest.h
index a602cb8ade34694297f82529e6cfe034db277a20..ba9b9078b99f88474a3406e865a340bc525dc5f9 100644
--- a/Framework/Crystal/test/SaveLauenormTest.h
+++ b/Framework/Crystal/test/SaveLauenormTest.h
@@ -2,12 +2,14 @@
 #define MANTID_CRYSTAL_SAVELauenormTEST_H_
 
 #include "MantidCrystal/SaveLauenorm.h"
+#include "MantidCrystal/LoadIsawPeaks.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/IDTypes.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include <cxxtest/TestSuite.h>
 #include <fstream>
 #include <Poco/File.h>
@@ -127,6 +129,43 @@ public:
     TS_ASSERT(!Poco::File(outfile3).exists());
     remove(outfile.c_str());
     remove(outfile2.c_str());
+    remove(outfile3.c_str());
+
+    // Now try with lscale format
+    std::string outfile4 = "./LSCALE";
+    LoadIsawPeaks loadPeaks;
+    loadPeaks.initialize();
+    loadPeaks.setPropertyValue("FileName", "Peaks5637.integrate");
+    loadPeaks.setPropertyValue("OutputWorkspace", "abc");
+    loadPeaks.execute();
+    PeaksWorkspace_sptr ows = boost::dynamic_pointer_cast<PeaksWorkspace>(
+        AnalysisDataService::Instance().retrieve("abc"));
+    SaveLauenorm alg4;
+    TS_ASSERT_THROWS_NOTHING(alg4.initialize())
+    TS_ASSERT(alg4.isInitialized())
+    TS_ASSERT_THROWS_NOTHING(alg4.setProperty("InputWorkspace", ows));
+    TS_ASSERT_THROWS_NOTHING(alg4.setPropertyValue("Filename", outfile4));
+    TS_ASSERT_THROWS_NOTHING(alg4.setProperty("LaueScaleFormat", true));
+    TS_ASSERT_THROWS_NOTHING(alg4.setProperty("CrystalSystem", "RHOMBOHEDRAL"));
+    TS_ASSERT_THROWS_NOTHING(alg4.setProperty("Centering", "R"));
+    TS_ASSERT_THROWS_NOTHING(alg4.execute(););
+    TS_ASSERT(alg4.isExecuted());
+    // Get the file
+    outfile4 = alg4.getPropertyValue("Filename") + "001.geasc";
+    TS_ASSERT(Poco::File(outfile4).exists());
+
+    std::ifstream in4(outfile4.c_str());
+    std::string line;
+    if (numPeaksPerBank > 0) {
+      for (int i = 0; i < 7; i++)
+        getline(in4, line);
+      in4 >> line >> d1 >> d2 >> d3 >> d4;
+      TS_ASSERT_EQUALS(d1, 6);
+      TS_ASSERT_EQUALS(d2, 7);
+      TS_ASSERT_EQUALS(d3, 1);
+      TS_ASSERT_EQUALS(d4, 3);
+    }
+    // remove(outfile4.c_str());
   }
 
   /// Test with a few peaks
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h
index 3a4279938f528d0401123112fefbafe1681eaa97..ae69f85c4249a9b65d8ec2b97b4276442896f805 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h
@@ -39,6 +39,9 @@ class DLLExport CalculateChiSquared : public IFittingAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateCostFunction", "Fit"};
+  }
   const std::string summary() const override;
 
 private:
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h
index d66640fd091f0a6c0f0f085ab1f2034cc6d6a28f..958ac2940660bc04f6ff1f432b03613b7a00f993 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h
@@ -42,6 +42,9 @@ class DLLExport CalculateCostFunction : public IFittingAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CalculateChiSquared", "Fit"};
+  }
   const std::string summary() const override;
 
 private:
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h
index 4e7bffa93e4ed0032f30e4c0d36bdd655f2e5216..8366d8e8ccc980a57d687e9133e5a29032a8256b 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h
@@ -37,6 +37,9 @@ class DLLExport EstimateFitParameters : public IFittingAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Fit", "EstimatePeakErrors"};
+  }
   const std::string summary() const override;
 
 private:
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h
index 9337aba270672b8e5d0be8a9fda44a8fbed9d98b..d7f2c396550fd832ea2436dbadb12d93eb352740 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h
@@ -38,6 +38,9 @@ public:
   const std::string summary() const override;
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Fit", "EstimateFitParameters"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h
index 915b3285faaf16451e5783672913d91faeb03785..aef157d8558dc8aa58313d180de2c67f7c4e0396 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h
@@ -38,6 +38,7 @@ class DLLExport EvaluateFunction : public IFittingAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
   const std::string summary() const override;
 
 private:
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h
index a60b8da6de0437f337d657e4fc2cd0f64eb0ca29..028f6d76fee69f5393548e6712dbcea39a46e18d 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h
@@ -103,6 +103,10 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FitGaussian", "UserFunction1D", "PlotPeakByLogValue",
+            "SplineBackground", "EvaluateFunction"};
+  }
 
 private:
   void initConcrete() override;
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h
index c602e18e0f11555dcbe956a1476ff8c7f1b93d42..8b99f2e5e91e722a798461dc074369f8f42cb301 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h
@@ -71,6 +71,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LeBailFit"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Diffraction\\Fitting"; }
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h
index 05466c164ed240319e96168d10217fddabe5bfca..9c73166259e6736e64d6fd46b153faf92bc077c8 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h
@@ -91,6 +91,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateLeBailFitInput", "FitPowderDiffPeaks"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Diffraction\\Fitting"; }
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h
index b628c897ef3d8660f84811d981cdee433aa79350..9b20a8740fa4cdf3ec19700131520308b5bc6c59 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h
@@ -218,7 +218,7 @@ private:
   */
 };
 
-typedef boost::shared_ptr<LeBailFunction> LeBailFunction_sptr;
+using LeBailFunction_sptr = boost::shared_ptr<LeBailFunction>;
 
 } // namespace Algorithms
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h
index 36c402f6e090a7a6353c9ace571b51aebcadbe48..d7ca221d8675bd9d3d39bb27c668d9ce605634c3 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h
@@ -49,6 +49,10 @@ public:
            "input mass value.";
   }
 
+  const std::vector<std::string> seeAlso() const override {
+    return {"MonitorEfficiencyCorUser", "Divide"};
+  }
+
   int version() const override;
   const std::string category() const override;
 
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h
index deaad15eca404f903d653e9e535509651f616a28..9e25bff6a6681079f8790a497d56e127c6e60e93 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h
@@ -69,6 +69,9 @@ public:
   PawleyFit();
   const std::string name() const override { return "PawleyFit"; }
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"PoldiPeakSearch"};
+  }
   const std::string summary() const override;
   const std::string category() const override { return "Diffraction\\Fitting"; }
 
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h
index 659bad57095bce63b4d4965f53521c10bb476bb4..d7425fe118c2dabac5d2896d68e4af328a658c53 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h
@@ -88,6 +88,7 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Optimization"; }
 
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h
index 1c02e46c59ebe5feaaf442c8fc04706ba23ea543..8e06e79bb4b2a1e39b6260b09f37cc874fa7181d 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 3; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"RefinePowderDiffProfileSeq"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Diffraction\\Fitting"; }
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
index c154c4c35aad3f442946f3028571ef836935538c..cb77bfa19f4e59a0c1e8c4121e10ecfb449dcfb1 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h
@@ -47,6 +47,9 @@ public:
   const std::string name() const override { return "SplineBackground"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Fit", "SplineInterpolation", "SplineSmoothing"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Optimization;CorrectionFunctions\\BackgroundCorrections";
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h
index 0d4af58d67a244ad85aff9c680b2435bd2b69027..363fb385aa413e0510c52090c63b1070e2c5826a 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h
@@ -49,6 +49,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Fit", "SplineBackground", "SplineSmoothing"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
index 51ed2dce5c909e38a8ad6b8c417f4e456a3a9125..1a59ab2510e329ed07156852800eb4bc4e22d321 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
@@ -45,6 +45,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Fit", "SplineInterpolation", "SplineBackground"};
+  }
   const std::string category() const override;
   /// Summary of algorithms purpose
   const std::string summary() const override {
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h
index 108ccccdbd7751a2362c65f87786716422bd4c9a..08972a6f98b7928c72494861b87b2cd573129b7c 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h
@@ -57,6 +57,9 @@ public:
     return "Calculates the background due to gamma rays produced when neutrons "
            "are absorbed by shielding.";
   }
+  const std::vector<std::string> seeAlso() const override {
+    return {"VesuvioCorrections"};
+  }
 
   int version() const override;
   const std::string category() const override;
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h
index d3e19adf0d6f131582ed1ab189b83cac1e1ab244..cdd8771b4f4de5b8077a97488bbd7dc76a1f28ad 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h
@@ -4,6 +4,7 @@
 // Includes
 //-----------------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidCurveFitting/MSVesuvioHelpers.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidKernel/V3D.h"
 
@@ -18,13 +19,6 @@ class IObject;
 }
 
 namespace CurveFitting {
-
-namespace MSVesuvioHelper {
-class RandomNumberGenerator;
-struct Simulation;
-struct SimulationWithErrors;
-}
-
 namespace Functions {
 struct ResolutionParams;
 }
@@ -79,8 +73,6 @@ private:
 
 public:
   VesuvioCalculateMS();
-  ~VesuvioCalculateMS() override;
-
   /// @copydoc Algorithm::name
   const std::string name() const override { return "VesuvioCalculateMS"; }
   /// @copydoc Algorithm::version
@@ -95,6 +87,11 @@ public:
            "on a flat plate sample for VESUVIO";
   }
 
+  const std::vector<std::string> seeAlso() const override {
+    return {"MayersSampleCorrection", "MonteCarloAbsorption",
+            "MultipleScatteringCylinderAbsorption"};
+  }
+
 private:
   void init() override;
   void exec() override;
@@ -131,7 +128,7 @@ private:
                     const double e1res) const;
 
   // Member Variables
-  CurveFitting::MSVesuvioHelper::RandomNumberGenerator *
+  std::unique_ptr<CurveFitting::MSVesuvioHelper::RandomVariateGenerator>
       m_randgen; // random number generator
 
   size_t m_acrossIdx, m_upIdx, m_beamIdx; // indices of each direction
@@ -139,7 +136,8 @@ private:
   double m_srcR2;                         // beam penumbra radius (m)
   double m_halfSampleHeight, m_halfSampleWidth, m_halfSampleThick; // (m)
   Geometry::IObject const *m_sampleShape; // sample shape
-  SampleComptonProperties *m_sampleProps; // description of sample properties
+  std::unique_ptr<SampleComptonProperties>
+      m_sampleProps; // description of sample properties
   double m_detHeight, m_detWidth, m_detThick; // (m)
   double m_tmin, m_tmax, m_delt;              // min, max & dt TOF value
   double m_foilRes;                           // resolution in energy of foil
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h
index 8156c721362ce4cbb8dc9bdaf1b6509238cf03ec..52c2db3f26b70e4675111771fbbe7936a27655b2 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h
@@ -97,7 +97,7 @@ class MANTID_CURVEFITTING_DLL AugmentedLagrangianOptimizer {
 
 public:
   /// Function type
-  typedef boost::function<double(const size_t, const double *)> ObjFunction;
+  using ObjFunction = boost::function<double(const size_t, const double *)>;
 
 public:
   /**
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h b/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h
index 5c5f0038e87f5f784d384dc876cdf070e666fb2b..bb65a1d668f1f59c046f20eefc1faf34abb839fb 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h
@@ -11,7 +11,7 @@
 namespace Mantid {
 namespace CurveFitting {
 
-typedef std::complex<double> ComplexType;
+using ComplexType = std::complex<double>;
 class ComplexVector;
 
 /// Struct helping converting complex values
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h
index 9a43f7124b2c296d730b5b42028629db459578df..dea108cfb57b306c25090010ba6e9f3f55fa7a4f 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h
@@ -9,11 +9,11 @@
 namespace Mantid {
 namespace CurveFitting {
 
-typedef FortranMatrix<ComplexMatrix> ComplexFortranMatrix;
-typedef FortranMatrix<GSLMatrix> DoubleFortranMatrix;
-typedef FortranVector<ComplexVector> ComplexFortranVector;
-typedef FortranVector<GSLVector> DoubleFortranVector;
-typedef FortranVector<std::vector<int>> IntFortranVector;
+using ComplexFortranMatrix = FortranMatrix<ComplexMatrix>;
+using DoubleFortranMatrix = FortranMatrix<GSLMatrix>;
+using ComplexFortranVector = FortranVector<ComplexVector>;
+using DoubleFortranVector = FortranVector<GSLVector>;
+using IntFortranVector = FortranVector<std::vector<int>>;
 
 } // namespace CurveFitting
 } // namespace Mantid
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h
index 457fb6c159ae6d7010b80e5b36f75985ebcd6908..bdbf98db9e0cbdbefddc92f635cf977e234a8310 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h
@@ -41,9 +41,9 @@ template <class MatrixClass> class FortranMatrix : public MatrixClass {
   int m_base2;
   /// Typedef the types returned by the base class's operators []. They aren't
   /// necessarily the same as the stored type (double or complex).
-  typedef decltype(
-      std::declval<const MatrixClass>().operator()(0, 0)) ElementConstType;
-  typedef decltype(std::declval<MatrixClass>().operator()(0, 0)) ElementRefType;
+  using ElementConstType =
+      decltype(std::declval<const MatrixClass>().operator()(0, 0));
+  using ElementRefType = decltype(std::declval<MatrixClass>().operator()(0, 0));
 
 public:
   /// Constructor
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h
index 7d6a9a7b1a8b5fb0cccd4c52ad69459b80b8df7f..041ad56f28a7a6e2266dcde179eb67d0fb1b6a76 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h
@@ -7,9 +7,6 @@
 #include "MantidCurveFitting/GSLMatrix.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
 
-#include <boost/random/normal_distribution.hpp>
-#include <boost/random/mersenne_twister.hpp>
-
 namespace Mantid {
 namespace CurveFitting {
 namespace CostFunctions {
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h
index 93136d0d369f57ab8a6d524f712141e859ea5be0..e4421c2258c7440ba56e2f7b7452415945016ea3 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h
@@ -86,7 +86,7 @@ protected:
   double expWidth() const;
 };
 
-typedef boost::shared_ptr<BackToBackExponential> BackToBackExponential_sptr;
+using BackToBackExponential_sptr = boost::shared_ptr<BackToBackExponential>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h
index bc496f54e98cf67546a099ec8a0a25f86637de92..06903f773359a56a1aebbf5044ebd11c98d1162b 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h
@@ -73,7 +73,7 @@ public:
   const std::string category() const override { return "Background"; }
 };
 
-typedef boost::shared_ptr<BackgroundFunction> BackgroundFunction_sptr;
+using BackgroundFunction_sptr = boost::shared_ptr<BackgroundFunction>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h
index 21f5007bd7a6e9f8d76f507a7835fb9bfc4eb6fb..1c980f42ed0ce922c1d4a664d75736709cc462a0 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h
@@ -90,7 +90,7 @@ private:
 
 // typedef boost::shared_ptr<TableWorkspace> TableWorkspace_sptr;
 
-typedef boost::shared_ptr<Bk2BkExpConvPV> Bk2BkExpConvPV_sptr;
+using Bk2BkExpConvPV_sptr = boost::shared_ptr<Bk2BkExpConvPV>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h
index 84ebfa834424dfddce8fbea217f405dca18e4cdd..51be2281977e1666d930cbee87c41ec002f5c669 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h
@@ -18,7 +18,7 @@ namespace CurveFitting {
 namespace Functions {
 
 /// Type of the approximated function
-typedef std::function<double(double)> ChebfunFunctionType;
+using ChebfunFunctionType = std::function<double(double)>;
 
 /**
 
@@ -200,7 +200,7 @@ private:
   static const size_t g_maxNumberPoints;
 };
 
-typedef boost::shared_ptr<ChebfunBase> ChebfunBase_sptr;
+using ChebfunBase_sptr = boost::shared_ptr<ChebfunBase>;
 
 /// Find best fit with highest possible tolerance (to be used with noisy data).
 template <class FunctionType>
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h
index cfa5cadbed39c3ce7b2736f1645eac49e104a971..54e696d7fe171cd986b287982370e9f822c416d0 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h
@@ -70,7 +70,7 @@ private:
   mutable std::valarray<double> m_b;
 };
 
-typedef boost::shared_ptr<Chebyshev> Chebyshev_sptr;
+using Chebyshev_sptr = boost::shared_ptr<Chebyshev>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h
index 4de520dcc24f7cea38106a6f35dbfd54ae0cb74e..614a8948a08641d6e698d6e5394053e8f16bfcde 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h
@@ -115,8 +115,8 @@ private:
   double splineEval(const double x) const;
 };
 
-typedef boost::shared_ptr<CubicSpline> CubicSpline_sptr;
-typedef const boost::shared_ptr<CubicSpline> CubicSpline_const_sptr;
+using CubicSpline_sptr = boost::shared_ptr<CubicSpline>;
+using CubicSpline_const_sptr = const boost::shared_ptr<CubicSpline>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h
index 8b8171dd0804abee38a56da045d77f692eb49796..8b86ec74119f51dca4693a8673ceca46e75794b5 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h
@@ -73,7 +73,7 @@ private:
   double m_bkpos;
 };
 
-typedef boost::shared_ptr<FullprofPolynomial> FullprofPolynomial_sptr;
+using FullprofPolynomial_sptr = boost::shared_ptr<FullprofPolynomial>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h
index ee758caabba09554958b289cac85949c83a7cc1e..ad40dd3f765b700d725960f55726c1d0b0f65dd5 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h
@@ -74,7 +74,7 @@ protected:
   std::string m_profileFunctionCenterParameterName;
 };
 
-typedef boost::shared_ptr<PawleyParameterFunction> PawleyParameterFunction_sptr;
+using PawleyParameterFunction_sptr = boost::shared_ptr<PawleyParameterFunction>;
 
 /** @class PawleyFunction
 
@@ -171,7 +171,7 @@ protected:
   int m_peakRadius;
 };
 
-typedef boost::shared_ptr<PawleyFunction> PawleyFunction_sptr;
+using PawleyFunction_sptr = boost::shared_ptr<PawleyFunction>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h
index 283ea6d945d6803985735b29f86cbf54e6741d79..3e57798ce6767e6b5071afdc49dcac70ce27c073 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h
@@ -68,7 +68,7 @@ private:
   int m_n;
 };
 
-typedef boost::shared_ptr<Polynomial> Polynomial_sptr;
+using Polynomial_sptr = boost::shared_ptr<Polynomial>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h
index cb80ea23af5280e7477ccd825f1057b66c9a5d13..8b3cec7e9714a0d162138a46645632a63752ac0a 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h
@@ -58,7 +58,7 @@ private:
   int m_nlayer, m_nlayer_old;
 };
 
-typedef boost::shared_ptr<ReflectivityMulf> ReflectivityMulf_sptr;
+using ReflectivityMulf_sptr = boost::shared_ptr<ReflectivityMulf>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h
index 8991009a3f26836453506ace0a78a121ed0f0d07..27766fd6de1a5a0166ea9d7215d948ddee82e0a8 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h
@@ -66,8 +66,8 @@ private:
                              double alph1t) const;
 };
 
-typedef boost::shared_ptr<ThermalNeutronBk2BkExpAlpha>
-    ThermalNeutronBk2BkExpAlpha_sptr;
+using ThermalNeutronBk2BkExpAlpha_sptr =
+    boost::shared_ptr<ThermalNeutronBk2BkExpAlpha>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h
index b9d10abd0283ba7f294fc5a46da8afed9858535f..55c3d3d3fd6e3cf4c551714221c560183cb81fe9 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h
@@ -66,8 +66,8 @@ private:
                              double beta1t) const;
 };
 
-typedef boost::shared_ptr<ThermalNeutronBk2BkExpBeta>
-    ThermalNeutronBk2BkExpBeta_sptr;
+using ThermalNeutronBk2BkExpBeta_sptr =
+    boost::shared_ptr<ThermalNeutronBk2BkExpBeta>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h
index 7b268015a3200d9f0cd52da4de4abedd76f62f32..c6cab7ae451a88d1c18ab936d0dac9a7cb7dd95d 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h
@@ -179,8 +179,8 @@ private:
 };
 
 /// Shared pointer to ThermalNeutronBk2BkExpConvPVoigt peak/function
-typedef boost::shared_ptr<ThermalNeutronBk2BkExpConvPVoigt>
-    ThermalNeutronBk2BkExpConvPVoigt_sptr;
+using ThermalNeutronBk2BkExpConvPVoigt_sptr =
+    boost::shared_ptr<ThermalNeutronBk2BkExpConvPVoigt>;
 
 //--- Public inline function --------------------------------------------------
 /** Calculate d = a/sqrt(h**2+k**2+l**2)
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h
index 61847c89230315abdd08af32804885a5986026d0..268e33694b48cedbb41ec79c8f886026b5b7fded 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h
@@ -65,8 +65,8 @@ private:
                              double sig2sq) const;
 };
 
-typedef boost::shared_ptr<ThermalNeutronBk2BkExpSigma>
-    ThermalNeutronBk2BkExpSigma_sptr;
+using ThermalNeutronBk2BkExpSigma_sptr =
+    boost::shared_ptr<ThermalNeutronBk2BkExpSigma>;
 
 } // namespace Functions
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h
index 85c3694e521fb51b717697e387b0d902cdb413fd..224e293bcc77fad898a6367d54cf39773926d842 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h
@@ -81,8 +81,8 @@ private:
   // jacobian);
 };
 
-typedef boost::shared_ptr<ThermalNeutronDtoTOFFunction>
-    ThermalNeutronDtoTOFFunction_sptr;
+using ThermalNeutronDtoTOFFunction_sptr =
+    boost::shared_ptr<ThermalNeutronDtoTOFFunction>;
 
 /// Calcualte TOF from d-spacing value for thermal neutron
 inline double calThermalNeutronTOF(double dh, double dtt1, double dtt1t,
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h
index 5274b319fc81ab123ad40c7acae73363e49f8180..e6478b9b33523bdb70aef1bdf636a43caf16a718 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h
@@ -88,6 +88,7 @@ public:
   const std::string summary() const override {
     return "Fits a histogram from a workspace to a user defined function.";
   }
+  const std::vector<std::string> seeAlso() const override { return {"Fit"}; }
 
 protected:
   /// overwrite base class methods
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h
index 8b4fceaf82f0fc3f1fac0df8d38788dbc1f43436..6c5d8d30ae450fdb0b0d549e88b2244298b78f22 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h
@@ -63,7 +63,7 @@ private:
   Functions::PawleyParameterFunction_sptr m_cellParameters;
 };
 
-typedef boost::shared_ptr<LatticeFunction> LatticeFunction_sptr;
+using LatticeFunction_sptr = boost::shared_ptr<LatticeFunction>;
 
 } // namespace CurveFitting
 } // namespace Mantid
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h b/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h
index 8e105b053445376e4a331338311d634598b2c27a..bd1570276ab583a2f61bf386561ad92f3b00f66f 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h
@@ -1,12 +1,10 @@
 #ifndef MANTID_CURVEFITTING_MSVESUVIOHELPERS_H
 #define MANTID_CURVEFITTING_MSVESUVIOHELPERS_H
 
+#include "MantidKernel/normal_distribution.h"
+#include <random>
 #include <vector>
 
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/normal_distribution.hpp>
-#include <boost/random/uniform_real.hpp>
-
 namespace Mantid {
 namespace CurveFitting {
 namespace MSVesuvioHelper {
@@ -18,21 +16,17 @@ double finalEnergyAuYap(const double randv);
 double finalEnergyUranium(const double randv);
 
 // Ties together random numbers with various probability distributions
-// @todo: Should move to Kernel
-class RandomNumberGenerator {
-  typedef boost::uniform_real<double> uniform_double;
-  typedef boost::normal_distribution<double> gaussian_double;
-
+class RandomVariateGenerator {
 public:
-  RandomNumberGenerator(const int seed);
+  RandomVariateGenerator(const int seed);
   /// Returns a flat random number between 0.0 & 1.0
   double flat();
   /// Returns a random number distributed  by a normal distribution
   double gaussian(const double mean, const double sigma);
 
 private:
-  RandomNumberGenerator();
-  boost::mt19937 m_generator;
+  RandomVariateGenerator();
+  std::mt19937 m_engine;
 };
 
 // Stores counts for each scatter order
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h b/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h
index 5d13fc72a88c4ed89b04c8478ef1a30a05cf1841..a65b4c926944a839a9e45783c76d994423559416 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h
@@ -183,14 +183,14 @@ struct nlls_inform {
 
   ///  the value of the objective function at the best estimate of the solution
   ///   determined by NLLS_solve
-  double obj = HUGE;
+  double obj = std::numeric_limits<float>::max();
 
   ///  the norm of the gradient of the objective function at the best estimate
   ///   of the solution determined by NLLS_solve
-  double norm_g = HUGE;
+  double norm_g = std::numeric_limits<float>::max();
 
   /// the norm of the gradient, scaled by the norm of the residual
-  double scaled_g = HUGE;
+  double scaled_g = std::numeric_limits<float>::max();
 
 }; //  END TYPE nlls_inform
 
diff --git a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
index 2485a0cc1882e1119827512e8f49dd2109663eb1..ac6f649acf397876677ee97beefe226c9fed6d34 100644
--- a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
+++ b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
@@ -10,11 +10,11 @@
 #include "MantidCurveFitting/CostFunctions/CostFuncFitting.h"
 #include "MantidCurveFitting/Functions/ChebfunBase.h"
 #include "MantidKernel/ListValidator.h"
-#include "MantidKernel/MersenneTwister.h"
-#include "MantidKernel/NormalDistribution.h"
+#include "MantidKernel/normal_distribution.h"
 
 #include <map>
 #include <numeric>
+#include <random>
 
 namespace Mantid {
 namespace CurveFitting {
@@ -152,11 +152,11 @@ std::vector<GSLVector>
 runMonteCarlo(CostFunctions::CostFuncFitting &costFunction,
               const std::vector<std::pair<double, double>> &ranges,
               const std::vector<std::unique_ptr<IConstraint>> &constraints,
-              const size_t nSamples, const size_t nOutput, const size_t seed) {
-
-  Kernel::MersenneTwister randGenerator;
+              const size_t nSamples, const size_t nOutput,
+              const unsigned int seed) {
+  std::mt19937 rng;
   if (seed != 0) {
-    randGenerator.setSeed(seed);
+    rng.seed(seed);
   }
   double value = costFunction.val() + getConstraints(constraints);
   auto nParams = costFunction.nParams();
@@ -169,8 +169,8 @@ runMonteCarlo(CostFunctions::CostFuncFitting &costFunction,
   for (size_t it = 0; it < nSamples; ++it) {
     for (size_t i = 0; i < nParams; ++i) {
       const auto &range = ranges[i];
-      auto p = randGenerator.nextValue(range.first, range.second);
-      costFunction.setParameter(i, p);
+      costFunction.setParameter(
+          i, std::uniform_real_distribution<>(range.first, range.second)(rng));
     }
     costFunction.applyTies();
     if (getConstraints(constraints) > 0.0) {
@@ -218,7 +218,7 @@ void runCrossEntropy(
     CostFunctions::CostFuncFitting &costFunction,
     const std::vector<std::pair<double, double>> &ranges,
     const std::vector<std::unique_ptr<IConstraint>> &constraints,
-    size_t nSamples, size_t nSelection, size_t nIterations, size_t seed) {
+    size_t nSamples, size_t nSelection, size_t nIterations, unsigned int seed) {
   // Initialise the normal distribution parameters (mean and sigma for each
   // function parameter).
   std::vector<std::pair<double, double>> distributionParams;
@@ -229,9 +229,9 @@ void runCrossEntropy(
   }
 
   auto nParams = costFunction.nParams();
-  Kernel::NormalDistribution distribution;
+  std::mt19937 rng;
   if (seed != 0) {
-    distribution.setSeed(seed);
+    rng.seed(seed);
   }
   // Sets of function parameters (GSLVector) and corresponding values of the
   // cost function (double)
@@ -251,10 +251,8 @@ void runCrossEntropy(
         paramSet.second.resize(nParams);
       }
       for (size_t i = 0; i < nParams; ++i) {
-        auto mean = distributionParams[i].first;
-        auto sigma = distributionParams[i].second;
-        auto p = distribution.randomValue(mean, sigma);
-        paramSet.second[i] = p;
+        paramSet.second[i] = Kernel::normal_distribution<>(
+            distributionParams[i].first, distributionParams[i].second)(rng);
       }
       // Calculate the cost function with those parameters
       costFunction.setParameters(paramSet.second);
@@ -322,9 +320,8 @@ void EstimateFitParameters::initConcrete() {
   declareProperty("NSamples", 100, "Number of samples.");
   declareProperty("Constraints", "",
                   "Additional constraints on tied parameters.");
-  declareProperty(
-      "Type", "Monte Carlo",
-      "Type of the algorithm: \"Monte Carlo\" or \"Cross Entropy\"");
+  declareProperty("Type", "Monte Carlo",
+                  R"(Type of the algorithm: "Monte Carlo" or "Cross Entropy")");
   declareProperty("NOutputs", 10, "Number of parameter sets to output to "
                                   "OutputWorkspace. Unused if OutputWorkspace "
                                   "isn't set. (Monte Carlo only)");
@@ -406,7 +403,7 @@ void EstimateFitParameters::execConcrete() {
   }
 
   size_t nSamples = static_cast<int>(getProperty("NSamples"));
-  size_t seed = static_cast<int>(getProperty("Seed"));
+  unsigned int seed = static_cast<int>(getProperty("Seed"));
 
   if (getPropertyValue("Type") == "Monte Carlo") {
     int nOutput = getProperty("NOutputs");
@@ -430,8 +427,8 @@ void EstimateFitParameters::execConcrete() {
         if (m_function->isActive(i)) {
           TableRow row = table->appendRow();
           row << m_function->parameterName(i);
-          for (size_t j = 0; j < output.size(); ++j) {
-            row << output[j][ia];
+          for (auto &j : output) {
+            row << j[ia];
           }
           ++ia;
         }
diff --git a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
index 7bfa2e7ea945789adcdf2e91175ec53605e994a8..d435dc2e5a860552a873f3a6381616cfdff1d002 100644
--- a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
+++ b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
@@ -537,7 +537,7 @@ PlotPeakByLogValue::makeNames() const {
   double start = 0;
   double end = 0;
 
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer names(inputList, ";",
                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
   for (const auto &input : names) {
diff --git a/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp b/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
index 032f4748d1a0764e4f556317605b300211e91748..a07084ca021906b3802759fb64cf7f4de504a41d 100644
--- a/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
+++ b/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
@@ -93,22 +93,32 @@ std::map<std::string, std::string> SplineInterpolation::validateInputs() {
   const int derivOrder = getProperty("DerivOrder");
 
   MatrixWorkspace_const_sptr iwsValid = getProperty("WorkspaceToInterpolate");
-  const size_t binsNo = iwsValid->blocksize();
-
-  // The minimum number of points for cubic splines is 3
-  if (binsNo < 2) {
-    result["WorkspaceToInterpolate"] = "Workspace must have minimum 2 points.";
-  } else if (binsNo == 2) {
-    if (!linear) {
-      result["WorkspaceToInterpolate"] =
-          "Workspace has only 2 points, "
-          "you can enable linear interpolation by "
-          "setting the property Linear2Points. Otherwise "
-          "provide a minimum of 3 points.";
-    } else if (derivOrder == 2) {
-      result["DerivOrder"] = "Linear interpolation is requested, hence "
-                             "derivative order can be maximum 1.";
+  if (iwsValid) {
+    try {
+      const size_t binsNo = iwsValid->blocksize();
+
+      // The minimum number of points for cubic splines is 3
+      if (binsNo < 2) {
+        result["WorkspaceToInterpolate"] =
+            "Workspace must have minimum 2 points.";
+      } else if (binsNo == 2) {
+        if (!linear) {
+          result["WorkspaceToInterpolate"] =
+              "Workspace has only 2 points, "
+              "you can enable linear interpolation by "
+              "setting the property Linear2Points. Otherwise "
+              "provide a minimum of 3 points.";
+        } else if (derivOrder == 2) {
+          result["DerivOrder"] = "Linear interpolation is requested, hence "
+                                 "derivative order can be maximum 1.";
+        }
+      }
+    } catch (std::length_error &) {
+      result["WorkspaceToInterpolate"] = "The input workspace does not have "
+                                         "the same number of bins per spectrum";
     }
+  } else {
+    result["WorkspaceToInterpolate"] = "The input is not a MatrixWorkspace";
   }
 
   return result;
diff --git a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateMS.cpp b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateMS.cpp
index 3121c62a16c5d256e3ebbdc5de518537807aa938..b9a5622170e628e286b4d8b38ba5da4c5b64be27 100644
--- a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateMS.cpp
+++ b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateMS.cpp
@@ -1,7 +1,6 @@
 #include "MantidCurveFitting/Algorithms/VesuvioCalculateMS.h"
 // Use helpers for storing detector/resolution parameters
 #include "MantidCurveFitting/Algorithms/ConvertToYSpace.h"
-#include "MantidCurveFitting/MSVesuvioHelpers.h"
 #include "MantidCurveFitting/Functions/VesuvioResolution.h"
 
 #include "MantidAPI/Axis.h"
@@ -21,7 +20,6 @@
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
-#include "MantidKernel/MersenneTwister.h"
 #include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/VectorHelper.h"
 
@@ -57,12 +55,6 @@ VesuvioCalculateMS::VesuvioCalculateMS()
       m_foilRes(-1.0), m_nscatters(0), m_nruns(0), m_nevents(0),
       m_progress(nullptr), m_inputWS() {}
 
-/// Destructor
-VesuvioCalculateMS::~VesuvioCalculateMS() {
-  delete m_randgen;
-  delete m_sampleProps;
-}
-
 /**
  * Initialize the algorithm's properties.
  */
@@ -139,7 +131,8 @@ void VesuvioCalculateMS::exec() {
   MatrixWorkspace_sptr multsc = WorkspaceFactory::Instance().create(m_inputWS);
 
   // Initialize random number generator
-  m_randgen = new CurveFitting::MSVesuvioHelper::RandomNumberGenerator(
+  m_randgen = Kernel::make_unique<
+      CurveFitting::MSVesuvioHelper::RandomVariateGenerator>(
       getProperty("Seed"));
 
   // Setup progress
@@ -230,7 +223,7 @@ void VesuvioCalculateMS::cacheInputs() {
     throw std::invalid_argument(os.str());
   }
   const int natoms = nInputAtomProps / 3;
-  m_sampleProps = new SampleComptonProperties(natoms);
+  m_sampleProps = Kernel::make_unique<SampleComptonProperties>(natoms);
   m_sampleProps->density = getProperty("SampleDensity");
 
   double totalMass(0.0); // total mass in grams
diff --git a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp
index 98ecd9628f8812cfd0bac078b667474144a0a51f..60a8ad16179a2c2d3b75ef3c0b2fcedc22eecc7f 100644
--- a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp
+++ b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp
@@ -9,7 +9,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceProperty.h"
 
-#include "MantidCurveFitting//Constraints/BoundaryConstraint.h"
+#include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
 #include "MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h"
 
@@ -17,17 +17,14 @@
 
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/MersenneTwister.h"
+#include "MantidKernel/normal_distribution.h"
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/normal_distribution.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <boost/version.hpp>
 #include <cmath>
 #include <cstdio>
 #include <cstdlib>
 #include <ctime>
+#include <random>
 
 namespace Mantid {
 namespace CurveFitting {
@@ -355,13 +352,9 @@ void FABADAMinimizer::finalize() {
 * @return :: the step
 */
 double FABADAMinimizer::gaussianStep(const double &jump) {
-  boost::mt19937 mt;
-  mt.seed(123 * (int(m_counter) + 45 * int(jump)) +
-          14 * int(time_t())); // Numbers for the seed
-  boost::normal_distribution<double> distr(0.0, std::abs(jump));
-  boost::variate_generator<boost::mt19937, boost::normal_distribution<double>>
-      step(mt, distr);
-  return step();
+  std::mt19937 rng(123 * (int(m_counter) + 45 * int(jump)) +
+                   14 * int(time_t()));
+  return Kernel::normal_distribution<double>(0.0, std::abs(jump))(rng);
 }
 
 /** If the new point is out of its bounds, it is changed to fit in the bound
@@ -484,10 +477,9 @@ void FABADAMinimizer::algorithmDisplacement(const size_t &parameterIndex,
     double prob = exp((m_chi2 - chi2New) / (2.0 * m_temperature));
 
     // Decide if changing or not
-    boost::mt19937 mt;
-    mt.seed(int(time_t()) + 48 * (int(m_counter) + 76 * int(parameterIndex)));
-    boost::uniform_real<> distr(0.0, 1.0);
-    double p = distr(mt);
+    std::mt19937 rng(int(time_t()) +
+                     48 * (int(m_counter) + 76 * int(parameterIndex)));
+    double p = std::uniform_real_distribution<double>(0.0, 1.0)(rng);
     if (p <= prob) {
       for (size_t j = 0; j < m_nParams; j++) {
         m_chain[j].push_back(newParameters.get(j));
@@ -959,12 +951,12 @@ void FABADAMinimizer::calculateConvChainAndBestParameters(
       auto posBestPar = std::find(reducedChain[j].begin(),
                                   reducedChain[j].end(), bestParameters[j]);
       double varLeft = 0, varRight = 0;
-      for (auto k = reducedChain[j].begin(); k < reducedChain[j].end(); k++) {
+      for (auto k = reducedChain[j].begin(); k < reducedChain[j].end();
+           k += 2) {
         if (k < posBestPar)
           varLeft += (*k - bestParameters[j]) * (*k - bestParameters[j]);
         else if (k > posBestPar)
           varRight += (*k - bestParameters[j]) * (*k - bestParameters[j]);
-        ++k;
       }
       if (posBestPar != reducedChain[j].begin())
         varLeft /= double(posBestPar - reducedChain[j].begin());
diff --git a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
index 2b4c732e7120eec05e4b92c7c63ccbf038b4e4d0..e2d26ec89472206ddd97fa46046a4e075146308c 100644
--- a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
+++ b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp
@@ -1274,10 +1274,10 @@ void solveSubproblem(int n, double radius, double f,
   inform.obj *= pow(scale_c, 2) / scale_h;
   inform.multiplier *= scale_h;
   inform.pole *= scale_h;
-  for (size_t i = 0; i < inform.history.size();
-       ++i) { //      do i = 1, inform.len_history
-    inform.history[i].lambda *= scale_h;
-    inform.history[i].x_norm *= scale_c / scale_h;
+  for (auto &history_item :
+       inform.history) { //      do i = 1, inform.len_history
+    history_item.lambda *= scale_h;
+    history_item.x_norm *= scale_c / scale_h;
   }
 }
 
diff --git a/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp b/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp
index f1af30eea7407b205972ccd4e73adc63fcabba0a..70aed84ab03885f642a0083babf89c4df6f4ccee 100644
--- a/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp
+++ b/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp
@@ -192,10 +192,20 @@ void CrystalFieldMultiSpectrum::setAttribute(const std::string &name,
     }
   } else if (boost::regex_match(name, match, FWHMX_ATTR_REGEX)) {
     auto iSpec = std::stoul(match[1]);
-    m_fwhmX[iSpec].clear();
+    if (m_fwhmX.size() > iSpec) {
+      m_fwhmX[iSpec].clear();
+    } else {
+      throw std::invalid_argument(
+          "Temperatures must be defined before resolution model");
+    }
   } else if (boost::regex_match(name, match, FWHMY_ATTR_REGEX)) {
     auto iSpec = std::stoul(match[1]);
-    m_fwhmY[iSpec].clear();
+    if (m_fwhmY.size() > iSpec) {
+      m_fwhmY[iSpec].clear();
+    } else {
+      throw std::invalid_argument(
+          "Temperatures must be defined before resolution model");
+    }
   }
   FunctionGenerator::setAttribute(name, attr);
 }
diff --git a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp
index d39034cf56511751a6d21003a0ed53c7e360af00..0473c4c344902e5af14ba0c74e046821bb2954cf 100644
--- a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp
+++ b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp
@@ -6,8 +6,6 @@
 #include <algorithm>
 #include <numeric>
 
-#include <boost/random/variate_generator.hpp>
-
 namespace Mantid {
 namespace CurveFitting {
 namespace MSVesuvioHelper {
@@ -353,20 +351,16 @@ double finalEnergyUranium(const double randv) {
 /**
  * Produces random numbers with various probability distributions
  */
-RandomNumberGenerator::RandomNumberGenerator(const int seed) : m_generator() {
-  m_generator.seed(static_cast<boost::mt19937::result_type>(seed));
+RandomVariateGenerator::RandomVariateGenerator(const int seed) : m_engine() {
+  m_engine.seed(static_cast<std::mt19937::result_type>(seed));
 }
 /// Returns a flat random number between 0.0 & 1.0
-double RandomNumberGenerator::flat() {
-  typedef boost::variate_generator<boost::mt19937 &, uniform_double>
-      uniform_generator;
-  return uniform_generator(m_generator, uniform_double(0.0, 1.0))();
+double RandomVariateGenerator::flat() {
+  return std::uniform_real_distribution<>(0.0, 1.0)(m_engine);
 }
-/// Returns a random number distributed  by a normal distribution
-double RandomNumberGenerator::gaussian(const double mean, const double sigma) {
-  typedef boost::variate_generator<boost::mt19937 &, gaussian_double>
-      gauss_generator;
-  return gauss_generator(m_generator, gaussian_double(mean, sigma))();
+/// Returns a random number distributed following a normal distribution
+double RandomVariateGenerator::gaussian(const double mean, const double sigma) {
+  return Kernel::normal_distribution<>(mean, sigma)(m_engine);
 }
 
 //-------------------------------------------------------------------------
diff --git a/Framework/CurveFitting/src/ParameterEstimator.cpp b/Framework/CurveFitting/src/ParameterEstimator.cpp
index a395a5de317fb4500924c94b504ab4166b514856..82b093b48dc646041cdf19c8ad9e8faa8c58a079 100644
--- a/Framework/CurveFitting/src/ParameterEstimator.cpp
+++ b/Framework/CurveFitting/src/ParameterEstimator.cpp
@@ -25,7 +25,7 @@ std::recursive_mutex FUNCTION_MAP_MUTEX;
 }
 
 enum Function { None, Gaussian, Lorentzian, BackToBackExponential };
-typedef std::map<std::string, std::pair<size_t, Function>> FunctionMapType;
+using FunctionMapType = std::map<std::string, std::pair<size_t, Function>>;
 
 //----------------------------------------------------------------------------------------------
 
diff --git a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
index 17ed511e6d0cdc6beec65bc1bb6f69b44c806366..5408948a664951972d3aba5ac0d8bdac55b6847f 100644
--- a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
+++ b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
@@ -39,16 +39,15 @@ public:
     TS_ASSERT(alg.isInitialized())
   }
 
-  // --------------------------------- Success cases
-  // -----------------------------------
+  // -------------------------- Success cases ----------------------------------
 
   void test_exec_with_TOF_input_gives_correct_X_values() {
     using namespace Mantid::API;
 
     auto alg = createAlgorithm();
     double x0(50.0), x1(300.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx,
-                                                                 true, true);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, true, true);
     alg->setProperty("InputWorkspace", testWS);
     alg->setProperty("Mass", 1.0097);
     alg->setProperty("QWorkspace", "ConvertToYSpace_Test_qSpace");
@@ -57,13 +56,13 @@ public:
 
     // Get the y-Space output workspace
     MatrixWorkspace_sptr ySpOutputWs = alg->getProperty("OutputWorkspace");
-    TS_ASSERT(ySpOutputWs != 0)
+    TS_ASSERT(ySpOutputWs != nullptr)
     TS_ASSERT_EQUALS(testWS->getNumberHistograms(),
                      ySpOutputWs->getNumberHistograms());
 
     // Get the q-Space output workspace
     MatrixWorkspace_sptr qSpOutputWs = alg->getProperty("QWorkspace");
-    TS_ASSERT(qSpOutputWs != 0)
+    TS_ASSERT(qSpOutputWs != nullptr)
     TS_ASSERT_EQUALS(testWS->getNumberHistograms(),
                      qSpOutputWs->getNumberHistograms());
 
@@ -79,9 +78,9 @@ public:
     TS_ASSERT_DELTA(-1.670937938, ySpOutX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.99449408, ySpOutX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(-0.01152733, ySpOutY.front(), 1e-08);
-    TS_ASSERT_DELTA(5.56667697, ySpOutY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.35141703, ySpOutY.back(), 1e-08);
+    TS_ASSERT_DELTA(0.0, ySpOutY.front(), 1e-08);
+    TS_ASSERT_DELTA(5.84236492, ySpOutY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(0.0, ySpOutY.back(), 1e-08);
     // E
     TS_ASSERT_DELTA(25.14204252, ySpOutE.front(), 1e-08);
     TS_ASSERT_DELTA(36.99940026, ySpOutE[npts / 2], 1e-08);
@@ -164,7 +163,8 @@ public:
     convertToYSpaceAlg = createAlgorithm();
     double x0(50.0), x1(300.0), dx(0.5);
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
-        1000, x0, x1, dx, true, true);
+        1000, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, true,
+        true);
     convertToYSpaceAlg->setChild(false);
     convertToYSpaceAlg->setProperty("InputWorkspace", testWS);
     convertToYSpaceAlg->setProperty("Mass", 1.0097);
diff --git a/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h b/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
index 0e25179a7808241e5b7a39bfd6c1fd55190e61ca..f6b49071077db138306c80b5d362bb2cea1420e2 100644
--- a/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
+++ b/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
@@ -186,16 +186,14 @@ public:
     alg.setProperty("Seed", 11);
     alg.execute();
     IFunction_sptr fun = alg.getProperty("Function");
-#ifdef _WIN32
     double A = fun->getParameter("A");
     double B = fun->getParameter("B");
     double I = fun->getParameter("I");
     double S = fun->getParameter("S");
-    TS_ASSERT_DELTA(A, 199.3392, 1e-4);
-    TS_ASSERT_DELTA(B, 130.9085, 1e-4);
-    TS_ASSERT_DELTA(I, 3.5418, 1e-4);
-    TS_ASSERT_DELTA(S, 1.4130, 1e-4);
-#endif
+    TS_ASSERT_DELTA(A, 131.2747, 1e-4);
+    TS_ASSERT_DELTA(B, 145.7469, 1e-4);
+    TS_ASSERT_DELTA(I, 3.7114, 1e-4);
+    TS_ASSERT_DELTA(S, 1.5160, 1e-4);
     TS_ASSERT(fun->isFixed(fun->parameterIndex("A")));
     TS_ASSERT(fun->isFixed(fun->parameterIndex("B")));
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("I")));
@@ -222,16 +220,14 @@ public:
     alg.setProperty("Seed", 11);
     alg.execute();
     IFunction_sptr fun = alg.getProperty("Function");
-#ifdef _WIN32
     double A = fun->getParameter("A");
     double B = fun->getParameter("B");
     double I = fun->getParameter("I");
     double S = fun->getParameter("S");
-    TS_ASSERT_DELTA(A, 199.3392, 1e-4);
-    TS_ASSERT_DELTA(B, 130.9085, 1e-4);
-    TS_ASSERT_DELTA(I, 3.5418, 1e-4);
-    TS_ASSERT_DELTA(S, 1.4130, 1e-4);
-#endif
+    TS_ASSERT_DELTA(A, 131.2747, 1e-4);
+    TS_ASSERT_DELTA(B, 145.7469, 1e-4);
+    TS_ASSERT_DELTA(I, 3.7114, 1e-4);
+    TS_ASSERT_DELTA(S, 1.5160, 1e-4);
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("A")));
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("B")));
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("I")));
diff --git a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
index d675c5f0de7097dabcdada4d5d618168c7ca7088..9748b7ac8894a4d329eeda6f60db93575c957564 100644
--- a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
+++ b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
@@ -149,7 +149,6 @@ public:
         TS_ASSERT_DELTA((signal - value) / value, 0.0, 1e-6);
       }
     } while (iter->next());
-    delete iter;
   }
 
   void test_set_workspace_twice() {
diff --git a/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h b/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h
index 0f761eab369d4154d0fe8165e083494d816c32ce..6f560ebd21cb8f079dc833cd9ad27cc63cf1c334 100644
--- a/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h
+++ b/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h
@@ -515,10 +515,10 @@ public:
         1.950190,    1.613562,    1.335208,    1.104734,    0.914043,
         0.756362,    0.000000};
 
-    for (size_t i = 0; i < vecY.size(); ++i) {
+    for (double y : vecY) {
       double e = 1.0;
-      if (vecY[i] > 1.0)
-        e = sqrt(vecY[i]);
+      if (y > 1.0)
+        e = sqrt(y);
       vecE.push_back(e);
     }
 
@@ -687,8 +687,8 @@ public:
     vecy.push_back(0.03096179);
     vece.push_back(0.00105191);
 
-    for (size_t i = 0; i < vecy.size(); ++i)
-      vecy[i] -= 0.02295189;
+    for (double &i : vecy)
+      i -= 0.02295189;
 
     return;
   }
diff --git a/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h b/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h
index ef0f8b8aa540ed75bf1aff9f63b2391b50b97c86..083e2dfd5473f10b9e7695085c4e157c2ebbe8bb 100644
--- a/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h
+++ b/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h
@@ -12,8 +12,8 @@ namespace {
 
 Mantid::API::MatrixWorkspace_sptr
 createTwoSpectrumWorkspace(double x0 = 50, double x1 = 300, double dx = 0.5) {
-  auto twoSpectrum =
-      ComptonProfileTestHelpers::createTestWorkspace(2, x0, x1, dx, true, true);
+  auto twoSpectrum = ComptonProfileTestHelpers::createTestWorkspace(
+      2, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::Full, true, true);
   return twoSpectrum;
 }
 
@@ -60,10 +60,10 @@ public:
     MatrixWorkspace_sptr fittedWS = alg->getProperty("FittedWorkspace");
     MatrixWorkspace_sptr symmetrisedWS =
         alg->getProperty("SymmetrisedWorkspace");
-    TS_ASSERT(outputWS != 0);
-    TS_ASSERT(yspaceWS != 0);
-    TS_ASSERT(fittedWS != 0);
-    TS_ASSERT(symmetrisedWS != 0);
+    TS_ASSERT(outputWS != nullptr);
+    TS_ASSERT(yspaceWS != nullptr);
+    TS_ASSERT(fittedWS != nullptr);
+    TS_ASSERT(symmetrisedWS != nullptr);
 
     // Dimensions
     TS_ASSERT_EQUALS(testWS->getNumberHistograms(),
@@ -92,13 +92,13 @@ public:
     TS_ASSERT_DELTA(175.0, outX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(300.0, outX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(-0.00005081, outY.front(), 1e-08);
-    TS_ASSERT_DELTA(0.00301015, outY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.00000917, outY.back(), 1e-08);
+    TS_ASSERT_DELTA(0.00040504, outY.front(), 1e-08);
+    TS_ASSERT_DELTA(0.00355931, outY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(-0.0001652, outY.back(), 1e-08);
     // E
-    TS_ASSERT_DELTA(0.02000724, outE.front(), 1e-08);
-    TS_ASSERT_DELTA(0.02000724, outE[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(0.02000724, outE.back(), 1e-08);
+    TS_ASSERT_DELTA(0.02030939, outE.front(), 1e-08);
+    TS_ASSERT_DELTA(0.02030939, outE[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(0.02030939, outE.back(), 1e-08);
 
     // ====== Y-space =====
     const auto &ysX = yspaceWS->x(0);
@@ -109,9 +109,9 @@ public:
     TS_ASSERT_DELTA(-1.670937938, ysX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.99449408, ysX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(-0.01152733, ysY.front(), 1e-08);
-    TS_ASSERT_DELTA(5.56667697, ysY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.35141703, ysY.back(), 1e-08);
+    TS_ASSERT_DELTA(-0.20450682, ysY.front(), 1e-08);
+    TS_ASSERT_DELTA(6.48431743, ysY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(2.75992908, ysY.back(), 1e-08);
     // E
     TS_ASSERT_DELTA(25.14204252, ysE.front(), 1e-08);
     TS_ASSERT_DELTA(36.99940026, ysE[npts / 2], 1e-08);
@@ -127,9 +127,9 @@ public:
     TS_ASSERT_DELTA(-1.670937938, fitX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.99449408, fitX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(-0.00556080, fitY.front(), 1e-08);
-    TS_ASSERT_DELTA(6.03793125, fitY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.00656332, fitY.back(), 1e-08);
+    TS_ASSERT_DELTA(-0.00540713, fitY.front(), 1e-08);
+    TS_ASSERT_DELTA(5.94335449, fitY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(-0.00641808, fitY.back(), 1e-08);
     // E
     TS_ASSERT_DELTA(25.14204252, fitE.front(), 1e-08);
     TS_ASSERT_DELTA(36.99940026, fitE[npts / 2], 1e-08);
@@ -145,9 +145,9 @@ public:
     TS_ASSERT_DELTA(-1.670937938, symX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.99449408, symX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(0.23992597, symY.front(), 1e-08);
-    TS_ASSERT_DELTA(6.19840840, symY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.03738811, symY.back(), 1e-08);
+    TS_ASSERT_DELTA(-0.13447607, symY.front(), 1e-08);
+    TS_ASSERT_DELTA(6.39791398, symY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(0.28362702, symY.back(), 1e-08);
     // E
     TS_ASSERT_DELTA(17.78587720, symE.front(), 1e-08);
     TS_ASSERT_DELTA(15.98016067, symE[npts / 2], 1e-08);
@@ -171,10 +171,10 @@ public:
     MatrixWorkspace_sptr fittedWS = alg->getProperty("FittedWorkspace");
     MatrixWorkspace_sptr symmetrisedWS =
         alg->getProperty("SymmetrisedWorkspace");
-    TS_ASSERT(outputWS != 0);
-    TS_ASSERT(yspaceWS != 0);
-    TS_ASSERT(fittedWS != 0);
-    TS_ASSERT(symmetrisedWS != 0);
+    TS_ASSERT(outputWS != nullptr);
+    TS_ASSERT(yspaceWS != nullptr);
+    TS_ASSERT(fittedWS != nullptr);
+    TS_ASSERT(symmetrisedWS != nullptr);
 
     // Dimensions
     TS_ASSERT_EQUALS(testWS->getNumberHistograms(),
@@ -201,13 +201,13 @@ public:
     TS_ASSERT_DELTA(300.0, outX.back(), 1e-08);
     // Y
 
-    TS_ASSERT_DELTA(-0.00000768, outY.front(), 1e-08);
-    TS_ASSERT_DELTA(0.00045496, outY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.00000139, outY.back(), 1e-08);
+    TS_ASSERT_DELTA(0.00006119, outY.front(), 1e-08);
+    TS_ASSERT_DELTA(0.00053774, outY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(-0.00002496, outY.back(), 1e-08);
     // E
-    TS_ASSERT_DELTA(0.00302395, outE.front(), 1e-08);
-    TS_ASSERT_DELTA(0.00302395, outE[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(0.00302395, outE.back(), 1e-08);
+    TS_ASSERT_DELTA(0.00306834, outE.front(), 1e-08);
+    TS_ASSERT_DELTA(0.00306834, outE[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(0.00306834, outE.back(), 1e-08);
 
     // ====== Y-space =====
     const auto &ysX = yspaceWS->x(0);
@@ -220,9 +220,9 @@ public:
     TS_ASSERT_DELTA(0.03651144, ysX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.89050276, ysX.back(), 1e-08);
     // Y
-    TS_ASSERT_DELTA(1.31080438, ysY.front(), 1e-08);
-    TS_ASSERT_DELTA(52.90062150, ysY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(1.70156893, ysY.back(), 1e-08);
+    TS_ASSERT_DELTA(1.04988426, ysY.front(), 1e-08);
+    TS_ASSERT_DELTA(52.62476059, ysY[npts / 2], 1e-08);
+    TS_ASSERT_DELTA(2.04137251, ysY.back(), 1e-08);
     // E
     TS_ASSERT_DELTA(52.17644100, ysE.front(), 1e-08);
     TS_ASSERT_DELTA(71.30383310, ysE[npts / 2], 1e-08);
@@ -238,14 +238,10 @@ public:
     TS_ASSERT_DELTA(0.03651144, fitX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.89050276, fitX.back(), 1e-08);
     // Y
-    std::cerr << std::fixed << std::setprecision(8) << fitY.front() << " "
-              << fitY[npts / 2] << "  " << fitY.back() << "\n";
-    TS_ASSERT_DELTA(-0.03802926, fitY.front(), 1e-08);
-    TS_ASSERT_DELTA(52.21878511, fitY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(-0.04418138, fitY.back(), 1e-08);
+    TS_ASSERT_DELTA(-0.0375677957, fitY.front(), 1e-08);
+    TS_ASSERT_DELTA(52.483339, fitY[npts / 2], 1e-06);
+    TS_ASSERT_DELTA(-0.04348319, fitY.back(), 1e-08);
     // E
-    std::cerr << std::fixed << std::setprecision(8) << fitE.front() << " "
-              << fitE[npts / 2] << "  " << fitE.back() << "\n";
     TS_ASSERT_DELTA(52.17644100, fitE.front(), 1e-08);
     TS_ASSERT_DELTA(71.30383310, fitE[npts / 2], 1e-08);
     TS_ASSERT_DELTA(137.96461559, fitE.back(), 1e-08);
@@ -260,14 +256,10 @@ public:
     TS_ASSERT_DELTA(0.03651144, symX[npts / 2], 1e-08);
     TS_ASSERT_DELTA(17.89050276, symX.back(), 1e-08);
     // Y
-    std::cerr << std::fixed << std::setprecision(8) << symY.front() << " "
-              << symY[npts / 2] << "  " << symY.back() << "\n";
-    TS_ASSERT_DELTA(1.31080438, symY.front(), 1e-08);
-    TS_ASSERT_DELTA(52.90062150, symY[npts / 2], 1e-08);
-    TS_ASSERT_DELTA(0.34709778, symY.back(), 1e-08);
+    TS_ASSERT_DELTA(1.04988426, symY.front(), 1e-08);
+    TS_ASSERT_DELTA(52.624761, symY[npts / 2], 1e-06);
+    TS_ASSERT_DELTA(1.00228928, symY.back(), 1e-08);
     // E
-    std::cerr << std::fixed << std::setprecision(8) << symE.front() << " "
-              << symE[npts / 2] << "  " << symE.back() << "\n";
     TS_ASSERT_DELTA(52.17644100, symE.front(), 1e-08);
     TS_ASSERT_DELTA(71.30383310, symE[npts / 2], 1e-08);
     TS_ASSERT_DELTA(48.83869866, symE.back(), 1e-08);
diff --git a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
index 9c1d7d0d1ed4ad65cd0de9f0784df2667d054f7c..887b222e9af4f88ce50deb2ebc3212eca54c1a6a 100644
--- a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
+++ b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
@@ -33,8 +33,8 @@ using namespace Mantid::CurveFitting::Algorithms;
 using Mantid::HistogramData::BinEdges;
 using Mantid::HistogramData::LinearGenerator;
 
-typedef Mantid::DataObjects::Workspace2D_sptr WS_type;
-typedef Mantid::DataObjects::TableWorkspace_sptr TWS_type;
+using WS_type = Mantid::DataObjects::Workspace2D_sptr;
+using TWS_type = Mantid::DataObjects::TableWorkspace_sptr;
 
 struct Fun {
   double operator()(double, int i) { return double(i + 1); }
@@ -496,10 +496,10 @@ public:
     TS_ASSERT(fits->getNames().size() == 2);
 
     auto wsNames = fits->getNames();
-    for (size_t i = 0; i < wsNames.size(); ++i) {
+    for (const auto &wsName : wsNames) {
       auto fit =
           AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>(
-              wsNames[i]);
+              wsName);
       TS_ASSERT(fit);
       TS_ASSERT(fit->getNumberHistograms() == 5);
     }
diff --git a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
index 233c1a20055e57a6afc44f54949e3f49375657cd..ba013ee91cb938a06b6db4edea8d7a321caa516a 100644
--- a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
+++ b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
@@ -308,9 +308,9 @@ public:
         hkl << hkls[ipk][i];
         cout << hkls[ipk][i] << ", ";
       }
-      for (size_t ipm = 0; ipm < peakparams[ipk].size(); ++ipm) {
-        hkl << peakparams[ipk][ipm];
-        cout << peakparams[ipk][ipm];
+      for (double ipm : peakparams[ipk]) {
+        hkl << ipm;
+        cout << ipm;
       }
       cout << '\n';
     }
@@ -416,10 +416,10 @@ public:
 
     // 2. Add peak parameters' name and values
     map<string, vector<double>>::iterator finditer;
-    for (size_t ipn = 0; ipn < paramnames.size(); ++ipn) {
+    for (const auto &paramname : paramnames) {
       API::TableRow newrow = geomws->appendRow();
-      std::string parname = paramnames[ipn];
-      double parvalue = parameters[paramnames[ipn]];
+      std::string parname = paramname;
+      double parvalue = parameters[paramname];
       newrow << parname << parvalue;
       double parmin = -DBL_MAX;
       double parmax = DBL_MAX;
diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h
index ddc0df117f8a5b8fc41d29290b381be2a33c472f..d391c255273f924fb4ed74f890397fbbdbdee9f0 100644
--- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h
+++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h
@@ -31,8 +31,8 @@ public:
 
     MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace");
     MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace");
-    TS_ASSERT(backgroundWS != 0);
-    TS_ASSERT(correctedWS != 0);
+    TS_ASSERT(backgroundWS != nullptr);
+    TS_ASSERT(correctedWS != nullptr);
     TS_ASSERT(backgroundWS != correctedWS);
 
     // Test some values in the range
@@ -62,15 +62,15 @@ public:
     TS_ASSERT_DELTA(corrE.back(), inE.back(), 1e-08);
 
     const auto &corrY(correctedWS->y(0));
-    TS_ASSERT_DELTA(corrY.front(), -0.00253802, 1e-08);
-    TS_ASSERT_DELTA(corrY[npts / 2], 0.15060372, 1e-08);
-    TS_ASSERT_DELTA(corrY.back(), -0.01696477, 1e-08);
+    TS_ASSERT_DELTA(corrY.front(), 0.0000012042, 1e-08);
+    TS_ASSERT_DELTA(corrY[npts / 2], 0.1580361070, 1e-08);
+    TS_ASSERT_DELTA(corrY.back(), -0.0144493467, 1e-08);
 
     // Background Y values = 0.0
     const auto &backY(backgroundWS->y(0));
-    TS_ASSERT_DELTA(backY.front(), -0.00000138, 1e-08);
-    TS_ASSERT_DELTA(backY[npts / 2], -0.00015056, 1e-08);
-    TS_ASSERT_DELTA(backY.back(), 0.01650629, 1e-08);
+    TS_ASSERT_DELTA(backY.front(), -0.0000012042, 1e-08);
+    TS_ASSERT_DELTA(backY[npts / 2], -0.0001317931, 1e-08);
+    TS_ASSERT_DELTA(backY.back(), 0.0144493467, 1e-08);
   }
 
   void
@@ -81,8 +81,8 @@ public:
 
     MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace");
     MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace");
-    TS_ASSERT(backgroundWS != 0);
-    TS_ASSERT(correctedWS != 0);
+    TS_ASSERT(backgroundWS != nullptr);
+    TS_ASSERT(correctedWS != nullptr);
     TS_ASSERT(backgroundWS != correctedWS);
 
     // Test some values in the range
@@ -125,8 +125,8 @@ public:
 
     MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace");
     MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace");
-    TS_ASSERT(backgroundWS != 0);
-    TS_ASSERT(correctedWS != 0);
+    TS_ASSERT(backgroundWS != nullptr);
+    TS_ASSERT(correctedWS != nullptr);
     TS_ASSERT(backgroundWS != correctedWS);
 
     TS_ASSERT_EQUALS(1, backgroundWS->getNumberHistograms());
@@ -159,15 +159,15 @@ public:
 
     // Corrected values
     const auto &corrY(correctedWS->y(0));
-    TS_ASSERT_DELTA(corrY.front(), -0.00253802, 1e-08);
-    TS_ASSERT_DELTA(corrY[npts / 2], 0.15060372, 1e-08);
-    TS_ASSERT_DELTA(corrY.back(), -0.01696477, 1e-08);
+    TS_ASSERT_DELTA(corrY.front(), 0.0000012042, 1e-08);
+    TS_ASSERT_DELTA(corrY[npts / 2], 0.1580361070, 1e-08);
+    TS_ASSERT_DELTA(corrY.back(), -0.0144493467, 1e-08);
 
     // Background Y values = 0.0
     const auto &backY(backgroundWS->y(0));
-    TS_ASSERT_DELTA(backY.front(), -0.00000138, 1e-08);
-    TS_ASSERT_DELTA(backY[npts / 2], -0.00015056, 1e-08);
-    TS_ASSERT_DELTA(backY.back(), 0.01650629, 1e-08);
+    TS_ASSERT_DELTA(backY.front(), -0.0000012042, 1e-08);
+    TS_ASSERT_DELTA(backY[npts / 2], -0.0001317931, 1e-08);
+    TS_ASSERT_DELTA(backY.back(), 0.0144493467, 1e-08);
   }
 
   //------------------------------------ Error cases
@@ -233,20 +233,21 @@ private:
 
   Mantid::API::MatrixWorkspace_sptr createTestWorkspaceWithFoilChanger() {
     double x0(50.0), x1(300.0), dx(0.5);
-    return ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx, true,
-                                                          true);
+    return ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, true, true);
   }
 
   Mantid::API::MatrixWorkspace_sptr createTestWorkspaceWithNoFoilChanger() {
     double x0(165.0), x1(166.0), dx(0.5);
-    return ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx, false);
+    return ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, false);
   }
 
   Mantid::API::MatrixWorkspace_sptr
   createTwoSpectrumWorkspaceWithFoilChanger() {
     double x0(50.0), x1(300.0), dx(0.5);
     auto singleSpectrum = ComptonProfileTestHelpers::createTestWorkspace(
-        1, x0, x1, dx, true, true);
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, true, true);
     const size_t nhist = 2;
     auto twoSpectrum =
         Mantid::API::WorkspaceFactory::Instance().create(singleSpectrum, nhist);
@@ -268,7 +269,7 @@ public:
     constexpr int nhist = 1;
 
     auto singleSpectrum = ComptonProfileTestHelpers::createTestWorkspace(
-        1, x0, x1, dx, true, true);
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None, true, true);
     auto inWs =
         Mantid::API::WorkspaceFactory::Instance().create(singleSpectrum, nhist);
 
diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
index 5e4bb0d4777fe098e2885eaf528a6fd5e74bd0cd..461a31def4df541b3102dbc2f633e640775e8ccd 100644
--- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
+++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
@@ -57,7 +57,8 @@ createTestWorkspace(const bool detShape = true,
   const double x0(50.0), x1(562.0), dx(1.0);
   const bool singleMassSpec(false), foilChanger(true);
   auto ws2d = ComptonProfileTestHelpers::createTestWorkspace(
-      nhist, x0, x1, dx, singleMassSpec, foilChanger);
+      nhist, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None,
+      singleMassSpec, foilChanger);
 
   if (detShape) {
     // replace instrument with one that has a detector with a shape
@@ -78,7 +79,8 @@ createTestWorkspace(const bool detShape = true,
     if (groupedDets) {
       // Add another detector in the same position as the first
       auto shape = ShapeFactory().createShape(shapeXML);
-      Mantid::Geometry::Detector *det2 = new Detector("det1", 2, shape, NULL);
+      Mantid::Geometry::Detector *det2 =
+          new Detector("det1", 2, shape, nullptr);
       // Setting detectors should normally go via DetectorInfo, but here we need
       // to set a position as we are adding a new detector. In general getPos
       // should not be called as this tries to set the position of the base
@@ -133,13 +135,7 @@ void checkOutputValuesAsExpected(const Mantid::API::IAlgorithm_sptr &alg,
                                  const double expectedMS) {
   using Mantid::API::MatrixWorkspace_sptr;
   const size_t checkIdx = 100;
-// OS X and GCC>=5 seems to do a terrible job with keeping the same precision
-// here.
-#if defined(__clang__) || (__GNUC__ >= 5)
-  const double tolerance(1e-4);
-#else
-  const double tolerance(1e-8);
-#endif
+  const double tolerance(1e-6);
 
   // Values for total scattering
   MatrixWorkspace_sptr totScatter = alg->getProperty("TotalScatteringWS");
@@ -180,28 +176,17 @@ public:
     auto alg = createTestAlgorithm(createFlatPlateSampleWS());
     TS_ASSERT_THROWS_NOTHING(alg->execute());
     TS_ASSERT(alg->isExecuted());
-// seed has different effect in boost version 1.56 and newer
-#if (BOOST_VERSION / 100000) == 1 && (BOOST_VERSION / 100 % 1000) >= 56
-    checkOutputValuesAsExpected(alg, 0.0111204555, 0.0019484356);
-#else
-    checkOutputValuesAsExpected(alg, 0.0099824991, 0.0020558473);
-#endif
+    checkOutputValuesAsExpected(alg, 0.0089444492, 0.0004539721);
   }
 
   void test_exec_with_flat_plate_sample_with_grouped_detectors() {
     auto alg = createTestAlgorithm(createFlatPlateSampleWS(true, true));
     TS_ASSERT_THROWS_NOTHING(alg->execute());
     TS_ASSERT(alg->isExecuted());
-// seed has different effect in boost version 1.56 and newer
-#if (BOOST_VERSION / 100000) == 1 && (BOOST_VERSION / 100 % 1000) >= 56
-    checkOutputValuesAsExpected(alg, 0.0111204555, 0.0019484356);
-#else
-    checkOutputValuesAsExpected(alg, 0.0099824991, 0.0020558473);
-#endif
+    checkOutputValuesAsExpected(alg, 0.0089444492, 0.0004539721);
   }
 
-  //   ------------------------ Failure Cases
-  //   -----------------------------------------
+  // --------------------- Failure Cases --------------------------------
 
   void test_setting_input_workspace_not_in_tof_throws_invalid_argument() {
     VesuvioCalculateMS alg;
diff --git a/Framework/CurveFitting/test/CompositeFunctionTest.h b/Framework/CurveFitting/test/CompositeFunctionTest.h
index 66694429e33242e76eea4c3ea2a45de5e47f6aab..0dfad1276af7dff0a35b73eaf9c3b0503c0c2895 100644
--- a/Framework/CurveFitting/test/CompositeFunctionTest.h
+++ b/Framework/CurveFitting/test/CompositeFunctionTest.h
@@ -33,8 +33,8 @@ using namespace Mantid::CurveFitting::Functions;
 using namespace Mantid::CurveFitting::FuncMinimisers;
 using namespace Mantid::CurveFitting::CostFunctions;
 
-typedef Mantid::DataObjects::Workspace2D_sptr WS_type;
-typedef Mantid::DataObjects::TableWorkspace_sptr TWS_type;
+using WS_type = Mantid::DataObjects::Workspace2D_sptr;
+using TWS_type = Mantid::DataObjects::TableWorkspace_sptr;
 
 class CurveFittingGauss : public IPeakFunction {
 public:
diff --git a/Framework/CurveFitting/test/FortranMatrixTest.h b/Framework/CurveFitting/test/FortranMatrixTest.h
index a217f132c95f3f2441f5fc1f710720e9088fef4a..087bba8ef667229f44b8668b56b0a9e5d47af399 100644
--- a/Framework/CurveFitting/test/FortranMatrixTest.h
+++ b/Framework/CurveFitting/test/FortranMatrixTest.h
@@ -12,8 +12,8 @@ using Mantid::CurveFitting::GSLMatrix;
 using Mantid::CurveFitting::ComplexMatrix;
 using Mantid::CurveFitting::ComplexType;
 
-typedef FortranMatrix<GSLMatrix> DoubleFortranMatrix;
-typedef FortranMatrix<ComplexMatrix> ComplexFortranMatrix;
+using DoubleFortranMatrix = FortranMatrix<GSLMatrix>;
+using ComplexFortranMatrix = FortranMatrix<ComplexMatrix>;
 
 class FortranMatrixTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/CurveFitting/test/FortranVectorTest.h b/Framework/CurveFitting/test/FortranVectorTest.h
index b9c505579184d564377c49b47d0312298b21d7f6..fd4dfb020e9934fbeb3f6ecac4bc100df522dee4 100644
--- a/Framework/CurveFitting/test/FortranVectorTest.h
+++ b/Framework/CurveFitting/test/FortranVectorTest.h
@@ -9,8 +9,8 @@
 
 using Mantid::CurveFitting::FortranVector;
 using Mantid::CurveFitting::ComplexType;
-typedef FortranVector<Mantid::CurveFitting::GSLVector> FortranDoubleVector;
-typedef FortranVector<Mantid::CurveFitting::ComplexVector> FortranComplexVector;
+using FortranDoubleVector = FortranVector<Mantid::CurveFitting::GSLVector>;
+using FortranComplexVector = FortranVector<Mantid::CurveFitting::ComplexVector>;
 
 class FortranVectorTest : public CxxTest::TestSuite {
 public:
@@ -207,7 +207,7 @@ public:
   }
 
   void test_int_array() {
-    typedef FortranVector<std::vector<int>> FortranIntVector;
+    using FortranIntVector = FortranVector<std::vector<int>>;
     FortranIntVector ivec(1, 3);
     ivec(1) = 11;
     ivec(2) = 22;
diff --git a/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h b/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h
index 2333150394447c5346ed148ef300cc60dbb46fc1..db19d23152d705a99b3a5764574534ddf7f72acf 100644
--- a/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h
+++ b/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h
@@ -115,8 +115,7 @@ private:
     ChebfunBase base(n, start, end);
     auto p = base.fit(fun);
     auto x = base.linspace(2 * n);
-    for (size_t i = 0; i < x.size(); ++i) {
-      double xi = x[i];
+    for (double xi : x) {
       TS_ASSERT_DELTA(base.eval(xi, p), fun(xi), 1e-4);
     }
   }
@@ -148,8 +147,7 @@ private:
     std::vector<double> p, a;
     auto base = ChebfunBase::bestFit(start, end, fun, p, a);
     auto x = base->linspace(2 * base->size());
-    for (size_t i = 0; i < x.size(); ++i) {
-      double xi = x[i];
+    for (double xi : x) {
       TS_ASSERT_DELTA(base->eval(xi, p), fun(xi), 1e-14);
     }
     TS_ASSERT_EQUALS(base->size(), expected_n);
@@ -169,8 +167,7 @@ private:
     base->derivative(a, da);
     dp = base->calcP(da);
     auto x = base->linspace(2 * base->size());
-    for (size_t i = 0; i < x.size(); ++i) {
-      double xi = x[i];
+    for (double xi : x) {
       // std::cerr << xi << ' ' << base->eval(xi,dp) - Cos(xi) << '\n';
       TS_ASSERT_DELTA(base->eval(xi, dp), deriv(xi), 1e-13);
     }
@@ -182,8 +179,8 @@ private:
     auto base = ChebfunBase::bestFit(start, end, fun, p, a);
     auto roots = base->roots(a);
     TS_ASSERT_EQUALS(n_roots, roots.size());
-    for (size_t i = 0; i < roots.size(); ++i) {
-      TS_ASSERT_DELTA(base->eval(roots[i], p), 0.0, tol);
+    for (double root : roots) {
+      TS_ASSERT_DELTA(base->eval(root, p), 0.0, tol);
     }
   }
 };
diff --git a/Framework/CurveFitting/test/Functions/ComptonPeakProfileTest.h b/Framework/CurveFitting/test/Functions/ComptonPeakProfileTest.h
index ead30e5efe56094a889f5f40069dde72aea3870a..a104f3dd613a6f0e3946d69280a3e4ad50e50087 100644
--- a/Framework/CurveFitting/test/Functions/ComptonPeakProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/ComptonPeakProfileTest.h
@@ -72,7 +72,8 @@ private:
         boost::make_shared<ComptonPeakProfile>();
     profile->initialize();
     auto paramWS = ComptonProfileTestHelpers::createTestWorkspace(
-        1, 300, 351, 0.5, true, true); // Only using for parameters
+        1, 300, 351, 0.5, ComptonProfileTestHelpers::NoiseType::None, true,
+        true); // Only using for parameters
     profile->setAttributeValue("Mass", 1.0079);
     TS_ASSERT_THROWS_NOTHING(profile->setWorkspace(paramWS));
     profile->setUpForFit();
diff --git a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
index 2022b396ac9af193744371e2a305f6ad92631a3b..1afc6fab41396d7fc114ea4daf747efcd1d049bd 100644
--- a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
+++ b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
@@ -6,19 +6,23 @@
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidIndexing/IndexInfo.h"
-#include "MantidKernel/MersenneTwister.h"
 #include "MantidTypes/SpectrumDefinition.h"
 
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
+#include <random>
+
 // Define helper functions to create test workspaces with appropriate
 // instruments set up
 namespace ComptonProfileTestHelpers {
+enum class NoiseType { None = 0, Full = 1 };
+
 // Forward declare all functions
 static Mantid::API::MatrixWorkspace_sptr
 createTestWorkspace(const size_t nhist, const double x0, const double x1,
-                    const double dx, const bool singleMassSpectrum = false,
+                    const double dx, const NoiseType noise,
+                    const bool singleMassSpectrum = false,
                     const bool addFoilChanger = false);
 static Mantid::Geometry::Instrument_sptr
 createTestInstrumentWithFoilChanger(const Mantid::detid_t id,
@@ -33,44 +37,47 @@ static void addResolutionParameters(const Mantid::API::MatrixWorkspace_sptr &ws,
 static void addFoilResolution(const Mantid::API::MatrixWorkspace_sptr &ws,
                               const std::string &name);
 
-struct ones {
-  double operator()(const double, size_t) {
-    return 1.0;
-  } // don't care about Y values, just use 1.0 everywhere
-};
-
 static Mantid::API::MatrixWorkspace_sptr
 createTestWorkspace(const size_t nhist, const double x0, const double x1,
-                    const double dx, const bool singleMassSpectrum,
-                    const bool addFoilChanger) {
+                    const double dx, const NoiseType noise,
+                    const bool singleMassSpectrum, const bool addFoilChanger) {
   bool isHist(false);
   auto ws2d = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
-      ones(), static_cast<int>(nhist), x0, x1, dx, isHist);
+      [](const double, std::size_t) { return 1.0; }, static_cast<int>(nhist),
+      x0, x1, dx, isHist);
   ws2d->getAxis(0)->setUnit("TOF");
   if (singleMassSpectrum) {
-    const size_t nvalues = ws2d->blocksize();
     // Generate a test mass profile with some noise so any calculated spectrum
     // won't exactly match
     const double peakCentre(164.0), sigmaSq(16 * 16), peakHeight(0.2);
-    const double noise(0.02);
-    Mantid::Kernel::MersenneTwister mt1998(123456);
     for (size_t i = 0; i < nhist; ++i) {
-      for (size_t j = 0; j < nvalues; ++j) {
-        double x = ws2d->dataX(i)[j];
-        double y = peakHeight * exp(-0.5 * pow(x - peakCentre, 2.) / sigmaSq);
-        double r = mt1998.nextValue();
-        if (r > 0.5)
-          y += noise * r;
-        else
-          y -= noise * r;
-        ws2d->dataY(i)[j] = y;
+      auto &dataXi = ws2d->mutableX(i);
+      auto &dataYi = ws2d->mutableY(i);
+      for (auto xit = std::begin(dataXi), yit = std::begin(dataYi);
+           xit != std::end(dataXi); ++xit, ++yit) {
+        *yit = peakHeight *exp(-0.5 * pow(*xit - peakCentre, 2.) / sigmaSq);
+      }
+    }
+    if (noise == NoiseType::Full) {
+      const double meanNoise(0.02);
+      std::mt19937 rng(1);
+      std::uniform_real_distribution<double> flat(0.0, 1.0);
+      for (size_t i = 0; i < nhist; ++i) {
+        auto &dataYi = ws2d->mutableY(i);
+        for (auto &y : dataYi) {
+          const double r(flat(rng));
+          if (r > 0.5)
+            y += r * meanNoise;
+          else
+            y -= r * meanNoise;
+        }
       }
     }
   }
 
   Mantid::detid_t id(1);
   if (addFoilChanger) {
-    double r(0.553), theta(66.5993), phi(138.6);
+    const double r(0.553), theta(66.5993), phi(138.6);
     Mantid::Kernel::V3D detPos;
     detPos.spherical_rad(r, theta * M_PI / 180.0, phi * M_PI / 180.0);
     ws2d->setInstrument(createTestInstrumentWithFoilChanger(id, detPos));
@@ -154,7 +161,7 @@ createTestInstrumentWithNoFoilChanger(const Mantid::detid_t id,
   Detector *det0(nullptr);
   if (!detShapeXML.empty()) {
     auto shape = ShapeFactory().createShape(detShapeXML);
-    det0 = new Detector("det0", id, shape, NULL);
+    det0 = new Detector("det0", id, shape, nullptr);
   } else {
     det0 = new Detector("det0", id, nullptr);
   }
diff --git a/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h b/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
index 77730ea337226725cc8e1b7a496e9b45d1b6496f..0d5c20dabd02b55c4213900e6373ae3c4fb18bc6 100644
--- a/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
+++ b/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
@@ -63,7 +63,8 @@ public:
     IFunction_sptr func =
         createFunctionNoBackground(); // No equality matrix set
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
 
     TS_ASSERT_THROWS_NOTHING(func->setMatrixWorkspace(testWS, 0, x0, x1));
   }
@@ -73,7 +74,8 @@ public:
     using namespace Mantid::API;
     IFunction_sptr func = createFunctionNoBackground();
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0);
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
@@ -95,7 +97,8 @@ public:
     using namespace Mantid::API;
     IFunction_sptr func = createFunctionWithBackground();
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0) *= 1e-06; // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
 
@@ -116,7 +119,8 @@ public:
     using namespace Mantid::API;
     IFunction_sptr func = createFunctionNoBackground();
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0) *= 1e-06; // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
 
@@ -137,7 +141,8 @@ public:
                             "Matrix(1|2)1|-2"); // I_1 = 2I_2
 
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0) *= 1e-06; // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
 
@@ -158,7 +163,8 @@ public:
         createFunctionNoBackground(useTwoIntensityFuncAsFirst);
 
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0) *= 1e-06; // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
 
@@ -176,26 +182,26 @@ public:
   }
 
   void
-  xtest_Iteration_Starting_Resets_Intensity_Parameters_And_Background_Parameters_With_Background_Included() {
+  test_IterStartingResetsIntensityAndBackgroundParsWithBackgroundIncluded() {
     using namespace Mantid::API;
     IFunction_sptr func = createFunctionWithBackground();
     func->setAttributeValue("IntensityConstraints",
                             "Matrix(1|2)1|-2"); // I_1 = 2I_2
 
     double x0(165.0), x1(166.0), dx(0.5);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0) *= 1e-06; // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
 
     func->iterationStarting();
-    //    TS_ASSERT_DELTA(func->getParameter(0),5.0, 1e-10); // width_1
-    //    TS_ASSERT_DELTA(func->getParameter(1),-0.0506748344, 1e-10); // I_1
-    //    TS_ASSERT_DELTA(func->getParameter(2),10.0, 1e-10); //width_2
-    //    TS_ASSERT_DELTA(func->getParameter(3),-0.0253374172, 1e-10); // I_2
-    //    TS_ASSERT_DELTA(func->getParameter(4),-0.0422290287, 1e-10); //
-    //    background A_0
-    //    TS_ASSERT_DELTA(func->getParameter(5),0.00675680781, 1e-10); //
-    //    background A_1
+    TS_ASSERT_DELTA(func->getParameter("f0.Width"), 5.0, 1e-10);
+    const double intensity0(0.42850051);
+    TS_ASSERT_DELTA(func->getParameter("f0.Intensity"), intensity0, 1e-8);
+    TS_ASSERT_DELTA(func->getParameter("f1.Width"), 10.0, 1e-8);
+    TS_ASSERT_DELTA(func->getParameter("f1.Intensity"), 0.5 * intensity0, 1e-8);
+    TS_ASSERT_DELTA(func->getParameter("f2.A0"), 0.35708376, 1e-8);
+    TS_ASSERT_DELTA(func->getParameter("f2.A1"), 0.99989358, 1e-8);
   }
 
 private:
diff --git a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
index 4656d63c7a60cc0013af393e219cae68645a27ad..dc26a88b3b2da18775d65c4ed7968d9d1fbc9762 100644
--- a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
+++ b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
@@ -406,6 +406,16 @@ public:
     }
   }
 
+  void test_multispectrum_malformed_resmod() {
+    std::string fun =
+        "name=CrystalFieldMultiSpectrum,Ion=Ce,FWHMX0=(1,2),FWHMY0=(2,3),"
+        "FWHMX1=(0,1),FWHMY2=(5,6),Temperatures=(44,50),B20=0.37737";
+    auto alg = AlgorithmFactory::Instance().create("EvaluateFunction", -1);
+    alg->initialize();
+    TS_ASSERT_THROWS(alg->setPropertyValue("Function", fun),
+                     std::invalid_argument);
+  }
+
   void test_underdefinded() {
     CrystalFieldMultiSpectrum fun;
     fun.setParameter("B20", 0.37737);
diff --git a/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h b/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
index d226ac07c5a2494dd1da7fc5181a2c0a8f5885df..11c6de7f8f99fd5b53baa7040657e2b51fbdce6e 100644
--- a/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
+++ b/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
@@ -12,11 +12,9 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 #include <cmath>
+#include <random>
 
 #include <cxxtest/TestSuite.h>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/shared_ptr.hpp>
 
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Algorithms;
@@ -417,9 +415,8 @@ private:
 
   /// returns a real value from a uniform distribution
   double random_value(const double &a, const double &b) {
-    boost::mt19937 rng;
-    boost::uniform_real<double> distribution(a, b);
-    return distribution(rng);
+    std::mt19937 rng;
+    return std::uniform_real_distribution<double>(a, b)(rng);
   }
 
   /// save the domain and the values of a function to a nexus file
diff --git a/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h b/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
index 19e1a7589c4f84d7404d01c750c906fcc6b560c9..d38a11a8a931d35c438bd2629eac9aaa4dcff915 100644
--- a/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
@@ -53,7 +53,8 @@ public:
     auto func = createFunctionWithParamsSet();
     double x0(370.0), x1(371.0),
         dx(0.5); // chosen to give put us near the peak for this mass & spectrum
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
diff --git a/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h b/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
index 44b754b1c92f84806c527d03756e2233bf43fccd..416a63059040a99305eb637f294beb88ea6cd6ef 100644
--- a/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
@@ -82,7 +82,8 @@ public:
     auto func = createFunctionWithParamsSet();
     double x0(165.0), x1(166.0),
         dx(0.5); // chosen to give put us near the peak for this mass & spectrum
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
diff --git a/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h b/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
index ad6518d1d2fe3fc56b74c6a0e80f96a8ad869479..4992b92343f1befbf4365d3752ee3efcf8adb4e2 100644
--- a/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
@@ -68,7 +68,8 @@ public:
 
     auto func = createFunctionWithParamsSet();
     double x0(200.0), x1(220.0), dx(10.0);
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
diff --git a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
index acd2ddcd4f044a5c4198e43c6ddb1cb46d45ec57..13ca05b896b37eb05b2c99fb5147e5ac5c897dbe 100644
--- a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
+++ b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
@@ -446,8 +446,8 @@ public:
 
     MersenneTwister mt(1234, 0.0, 1000000.0);
     std::vector<double> bkgdpts(10000);
-    for (auto it = bkgdpts.begin(); it != bkgdpts.end(); it++) {
-      *it = mt.nextValue();
+    for (double &bkgdpt : bkgdpts) {
+      bkgdpt = mt.nextValue();
     }
 
     sbg.initialize();
diff --git a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
index b56e955f424c5a5e0701160caac8caa7dce14e97..1c44aa2d174fbb626e6f79d6088243737f7f05e6 100644
--- a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h
@@ -10,7 +10,7 @@
 #include "MantidCurveFitting/Jacobian.h"
 #include "MantidDataObjects/Workspace2D.h"
 
-typedef Mantid::DataObjects::Workspace2D_sptr WS_type;
+using WS_type = Mantid::DataObjects::Workspace2D_sptr;
 using Mantid::CurveFitting::Functions::ProductFunction;
 using Mantid::CurveFitting::Functions::Gaussian;
 
diff --git a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
index b51bc222d76156deac65f32af781909f9dc87b73..4368e1a703045f9f1b1f41068aeb6bd9bd3309a5 100644
--- a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h
@@ -73,7 +73,7 @@ to check that the results are equal.
     benchmark.addFunction(expFunction);
 
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.0001));
@@ -171,7 +171,7 @@ public:
     benchmark.setParameter("Lifetime", Lifetime);
 
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.1));
@@ -196,7 +196,7 @@ public:
 
   void test_calculate_derivative_throws_nothing() {
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.1));
diff --git a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
index 952f687448f29014ddb238d457a26a08fcadec22..36ee78deb16483bb29106d53ed1ba053513c0082 100644
--- a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
+++ b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h
@@ -75,7 +75,7 @@ to check that the results are equal.
     benchmark.addFunction(expFunction);
 
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.0001));
@@ -169,7 +169,7 @@ public:
     benchmark.setParameter("Lifetime", Lifetime);
 
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.1));
@@ -194,7 +194,7 @@ public:
 
   void test_calculate_derivative_throws_nothing() {
     const size_t nResults = 10;
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble xValues(nResults);
     std::generate(xValues.begin(), xValues.end(),
                   LinearIncrementingAssignment(0, 0.1));
diff --git a/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h b/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h
index f3b4482f107ca3b44b94b2c821a6c9844d008bf4..f2ee2336d6824554d303cb6617232b124090574b 100644
--- a/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h
+++ b/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h
@@ -159,9 +159,9 @@ private:
       }
     }
     auto &xp = cheb.xPoints();
-    for (size_t i = 0; i < xp.size(); ++i) {
+    for (double i : xp) {
       // std::cerr << xp[i] << ' ' << cheb(xp[i]) - fun(xp[i]) << '\n';
-      TS_ASSERT_DELTA(cheb(xp[i]), fun(xp[i]), accur2);
+      TS_ASSERT_DELTA(cheb(i), fun(i), accur2);
     }
   }
 };
diff --git a/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h b/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
index cb856cefc08f34e66087ed037c49f09d0de12fcb..d491354b90a66806d05de12a351298fe3291f1ce 100644
--- a/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
+++ b/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
@@ -34,7 +34,8 @@ public:
     auto func = createFunction();
     double x0(165.0), x1(166.0),
         dx(0.5); // chosen to give put us near the peak for this mass & spectrum
-    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(1, x0, x1, dx);
+    auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
+        1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
diff --git a/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h b/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h
index 2d19fed534771de58497e0ec4c005f3cb98b2f23..843542f9221c9389d16259e0375149175c60d847 100644
--- a/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h
+++ b/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h
@@ -33,10 +33,9 @@ public:
   /* Test that all functions give the expected result.
    */
   void testAllFunctions() {
-    for (auto it = m_expectedResults.begin(); it != m_expectedResults.end();
-         ++it) {
-      const std::string &peakFunctionName = it->first;
-      const std::string &centreParameterName = it->second;
+    for (auto &expectedResult : m_expectedResults) {
+      const std::string &peakFunctionName = expectedResult.first;
+      const std::string &centreParameterName = expectedResult.second;
 
       IPeakFunction_sptr fn = boost::dynamic_pointer_cast<IPeakFunction>(
           FunctionFactory::Instance().createFunction(peakFunctionName));
diff --git a/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h b/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h
index cec758e09c5698897de8fdabc99b512465e886de..7babcbecbfa1a105b2e69811c80ae3f2c6f35f03 100644
--- a/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h
+++ b/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h
@@ -91,12 +91,11 @@ private:
     std::vector<std::string> registeredFunctions =
         FunctionFactory::Instance().getFunctionNames<IPeakFunction>();
 
-    for (auto it = registeredFunctions.begin(); it != registeredFunctions.end();
-         ++it) {
-      if (blackList.count(*it) == 0) {
+    for (auto &registeredFunction : registeredFunctions) {
+      if (blackList.count(registeredFunction) == 0) {
         IPeakFunction_sptr peakFunction =
             boost::dynamic_pointer_cast<IPeakFunction>(
-                FunctionFactory::Instance().createFunction(*it));
+                FunctionFactory::Instance().createFunction(registeredFunction));
 
         if (peakFunction) {
           peakFunctions.push_back(peakFunction);
@@ -110,16 +109,16 @@ private:
   void initializePeakFunctions(const std::vector<IPeakFunction_sptr> &peaks,
                                const ParameterSet &parameters) const {
 
-    for (auto it = peaks.begin(); it != peaks.end(); ++it) {
-      (*it)->setCentre(parameters.center);
+    for (const auto &peak : peaks) {
+      peak->setCentre(parameters.center);
 
       // for Ikeda-Carpenter it's not allowed to set Fwhm
       try {
-        (*it)->setFwhm(parameters.fwhm);
+        peak->setFwhm(parameters.fwhm);
       } catch (std::invalid_argument) {
       }
 
-      (*it)->setHeight(parameters.height);
+      peak->setHeight(parameters.height);
     }
   }
 
@@ -137,8 +136,8 @@ private:
   getIntensities(const std::vector<IPeakFunction_sptr> &peaks) const {
     std::vector<double> intensities;
 
-    for (auto it = peaks.begin(); it != peaks.end(); ++it) {
-      intensities.push_back((*it)->intensity());
+    for (const auto &peak : peaks) {
+      intensities.push_back(peak->intensity());
     }
 
     return intensities;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h b/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h
index c3c49b795f8dd110d21e8837f6ac9e250dbc43b1..e787d32ae909a7e87ba5fcd27eadcce54fc3bbda 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h
@@ -53,6 +53,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventNexus", "LoadEventAndCompress"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Events"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
index 24ef28c000c7270ec4219a341768823e60e37abc..6151c5b35b1c4f6ab56e17cd1c28e76383e9c8df 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection", "SetSampleMaterial", "CopySample"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Sample;"; }
   /// Algorithm's aliases
diff --git a/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h b/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h
index bdddc787c77c81b47076500ee3ddf83e242dbfa5..6d5d06d7600f8dd8ba436477471b7f424c540af5 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "Sample"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h b/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h
index 93ac211c015f4d419989a75264cf351e7176a38c..524f0a5fd0623ba1900bdaa42ecd62d0a90e8b73 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateEmptyTableWorkspace"};
+  }
   /// Category
   const std::string category() const override { return "Utility\\Workspaces"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h b/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h
index 8b8daff910fa329f2cba92de20cadec42ac7b70c..f705e389fffa2d1b135480b97cda3adafaa92cd1 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h
@@ -36,9 +36,9 @@ namespace DataHandling {
   Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 /// Make the code clearer by having this an explicit type
-typedef int PixelType;
+using PixelType = int;
 /// Type for the DAS time of flight (data file)
-typedef int DasTofType;
+using DasTofType = int;
 
 /// Structure that matches the form in the binary event list.
 #pragma pack(push, 4) // Make sure the structure is 8 bytes.
diff --git a/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h b/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h
index dcf95a8715e1b997a5d7ef32d293aeacff53e80d..900a363266946a29cb7ce5ae2765f55c90872134 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h
@@ -43,6 +43,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Load", "CatalogDownloadDataFiles"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h
index f234f05d2a0f9bbcf50bde23dee27a69a858cbb8..69e035ef999ced8ce603ab4aae6bde052e362f84 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h
@@ -40,12 +40,15 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrument", "UpdateScriptRepository"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
 protected:
   // Convenience typedef
-  typedef std::map<std::string, std::string> StringToStringMap;
+  using StringToStringMap = std::map<std::string, std::string>;
 
 private:
   void init() override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h
index 736817697cba0cd670b81facece7e52c69ef3bb8..e7f551b27e82efca7bec961be4fd87dab75718e7 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h
@@ -109,9 +109,9 @@ public:
   virtual bool threadSafe() const;
 };
 
-typedef boost::shared_ptr<EventWorkspaceCollection>
-    EventWorkspaceCollection_sptr;
-typedef std::unique_ptr<EventWorkspaceCollection> EventWorkspaceCollection_uptr;
+using EventWorkspaceCollection_sptr =
+    boost::shared_ptr<EventWorkspaceCollection>;
+using EventWorkspaceCollection_uptr = std::unique_ptr<EventWorkspaceCollection>;
 
 } // namespace DataHandling
 } // namespace Mantid
diff --git a/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h b/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h
index 96a62132aa9d77e688297a25d7d940a5d89af802..3e57037660bfb53a8ac65a6ab59e69f18d27b369 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h
@@ -36,6 +36,9 @@ class DLLExport ExtractMonitorWorkspace : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExtractMonitors"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h b/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h
index 3040fe655c7f0a95369c526baf3ffa3e782caf9c..161bbb543cc64fc9d559ca82b5ac76ff3120c2c8 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h
@@ -41,10 +41,10 @@ namespace DataHandling {
 #undef LOADEVENTPRENEXUS_ALLOW_PARALLEL
 
 /// Make the code clearer by having this an explicit type
-typedef int PixelType;
+using PixelType = int;
 
 /// Type for the DAS time of flight (data file)
-typedef int DasTofType;
+using DasTofType = int;
 
 /// Structure that matches the form in the binary event list.
 #pragma pack(push, 4) // Make sure the structure is 8 bytes.
diff --git a/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h b/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h
index 492bbdf0e1fd0cb7062898be783246fd38bb683d..245ce4500cf6ee3bc7b548da6561a64928b41185 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h
@@ -64,6 +64,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectorsInShape"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Utility\\Instrument"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
index a3ff6210b4ab48afa77d4b8a019e4f9e9d2c34b5..05105829af4c3baa3c7b814f1569f8fbee0edb23 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
@@ -120,6 +120,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SpatialGrouping"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Grouping"; }
 
@@ -149,7 +152,7 @@ private:
 
   /// used to store the lists of WORKSPACE INDICES that will be grouped, the
   /// keys are not used
-  typedef std::map<specnum_t, std::vector<size_t>> storage_map;
+  using storage_map = std::map<specnum_t, std::vector<size_t>>;
 
   /// An estimate of the percentage of the algorithm runtimes that has been
   /// completed
@@ -168,10 +171,11 @@ private:
                  std::vector<int64_t> &unUsedSpec);
   /// gets the list of spectra _index_ _numbers_ from a file of _spectra_
   /// _numbers_
-  void processFile(std::string fname, API::MatrixWorkspace_const_sptr workspace,
+  void processFile(const std::string &fname,
+                   API::MatrixWorkspace_const_sptr workspace,
                    std::vector<int64_t> &unUsedSpec);
   /// gets groupings from XML file
-  void processXMLFile(std::string fname,
+  void processXMLFile(const std::string &fname,
                       API::MatrixWorkspace_const_sptr workspace,
                       std::vector<int64_t> &unUsedSpec);
   void
@@ -183,18 +187,19 @@ private:
                               std::vector<int64_t> &unUsedSpec);
   /// used while reading the file turns the string into an integer number (if
   /// possible), white space and # comments ignored
-  int readInt(std::string line);
+  int readInt(const std::string &line);
 
-  void readFile(spec2index_map &specs2index, std::istream &File,
+  void readFile(const spec2index_map &specs2index, std::istream &File,
                 size_t &lineNum, std::vector<int64_t> &unUsedSpec,
-                bool ignoreGroupNumber);
+                const bool ignoreGroupNumber);
 
   /// used while reading the file reads reads spectra numbers from the string
   /// and returns spectra indexes
-  void readSpectraIndexes(std::string line, spec2index_map &specs2index,
+  void readSpectraIndexes(const std::string &line,
+                          const spec2index_map &specs2index,
                           std::vector<size_t> &output,
                           std::vector<int64_t> &unUsedSpec,
-                          std::string seperator = "#");
+                          const std::string &seperator = "#");
 
   /// Estimate how much what has been read from the input file constitutes
   /// progress for the algorithm
@@ -229,7 +234,7 @@ private:
     /// spectrum will be included in a group, any other
     /// value and it isn't. Spectra numbers should always
     /// be positive so we shouldn't accidientally set a
-    /// spectrum number to the this
+    /// spectrum number to this
     EMPTY_LINE = 1001 - INT_MAX, ///< when reading from the input file this
     /// value means that we found any empty line
     IGNORE_SPACES = Mantid::Kernel::StringTokenizer::TOK_TRIM ///< equal to
diff --git a/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Framework/DataHandling/inc/MantidDataHandling/Load.h
index 7ba6bf16ee67e57967eb0656fd95e6d29e2fe76e..3645c6b4066b2589ee5bc75b37dff89b20c4ec9f 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/Load.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/Load.h
@@ -47,6 +47,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus", "LoadRaw", "LoadBBY"};
+  }
+
   /// Category
   const std::string category() const override { return "DataHandling"; }
   /// Aliases
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h
index a9a2939b46d24658350e13154f1728c545b8853a..e3b60a454d336901dccef17080406539f10b9d98 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h
@@ -24,7 +24,7 @@ namespace DataHandling {
 namespace ANSTO {
 
 /// pointer to the vector of events
-typedef std::vector<Types::Event::TofEvent> *EventVector_pt;
+using EventVector_pt = std::vector<Types::Event::TofEvent> *;
 
 /// helper class to keep track of progress
 class ProgressTracker {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
index db7c394e41301412bb1f427fdc0142cba2925968..961566c7770ab18dd1ae61bf845f5e2ec6757b64 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
@@ -60,6 +60,9 @@ public:
 
   /// The version number
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
   /// The category
   const std::string category() const override { return "DataHandling\\Text"; }
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h
index 1540b860759873d4f5545bf59e60c3ca2206040a..8cbf569c98753fb78ded5af4ad1c72dc9501a8f1 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h
@@ -91,6 +91,9 @@ class DLLExport LoadBBY : public API::IFileLoader<Kernel::FileDescriptor> {
 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 "LoadBBY"; }
   const std::string category() const override { return "DataHandling\\ANSTO"; }
   const std::string summary() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h
index c303d3859e2a3a8927d848979bafea799edfeb85..baf78431397f29ea2cb9b3ba8ca79ef4deb3fb49 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h
@@ -31,9 +31,15 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReadGroupsFromFile",   "CreateDummyCalFile",
+            "CreateCalFileByNames", "AlignDetectors",
+            "DiffractionFocussing", "SaveCalFile",
+            "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles";
+    return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)";
   }
 
   static void getInstrument3WaysInit(Mantid::API::Algorithm *alg);
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h
index fa4a5ec2325ae7d9cca893e0a47a9e0134301ce3..33e161e4fa240fd73a9ea42dd9b388a40f8c827c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h
@@ -72,6 +72,9 @@ class DLLExport LoadCanSAS1D2 : public LoadCanSAS1D {
 public:
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveCanSAS1D"};
+  }
 
 protected:
   /// Overwrites Algorithm method. Extend to create the LoadTransmission flag.
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h
index ca1fb205d813b749cbf6c3520ac1276a90c71dd0..d0e153132618973a26fbc35db60bd16c3718b535 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h
@@ -58,6 +58,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveDaveGrp"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Text;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h
index 6e07009f37938dbf6f2181547a7fef4891eb4593..c628cae276c815a2111d178f50cb49a695825e6a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRaw", "LoadNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Raw"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h
index 0e4c1fc1b845fa0bb058fca1869980e845bcbd0d..5dbe7b6e3c4635cd618f04f7ed9f97266743e08a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveDetectorsGrouping", "GroupDetectors"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Grouping;Transforms\\Grouping";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h
index a2a205d2264f62eeaaae42819d1e47fbbc348e32..a4c87a37ce54fb96327a2a7bbf2d923fbd872d84 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h
@@ -40,6 +40,9 @@ class DLLExport LoadDiffCal : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveDiffCal"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h
index 2165b49239b0e21bf223704cdc6e2edc189d93c4..18caec619c9511396379b3e77f1f492903773715 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h
@@ -71,6 +71,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrument"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h
index 9d167858e4183d7a8c596de394ef7096218e331e..fe1e4f16d4f26e1d410c4d8351a1bed67f36189c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h
@@ -79,6 +79,9 @@ public:
 
   /// Version
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadISISNexus", "LoadEventAndCompress"};
+  }
 
   /// Category
   const std::string category() const override { return "DataHandling\\Nexus"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h
index b02b915af12f0c72026ac7cf99005cc4f6ee5e27..ed3863be5deaf6bb51765386b1bee41cfa806899 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h
@@ -40,10 +40,10 @@ namespace DataHandling {
 #undef LOADEVENTPRENEXUS_ALLOW_PARALLEL
 
 /// Make the code clearer by having this an explicit type
-typedef int PixelType;
+using PixelType = int;
 
 /// Type for the DAS time of flight (data file)
-typedef int DasTofType;
+using DasTofType = int;
 
 /// Structure that matches the form in the binary event list.
 #pragma pack(push, 4) // Make sure the structure is 8 bytes.
@@ -98,6 +98,9 @@ public:
   const std::string name() const override { return "LoadEventPreNexus"; }
   /// Algorithm's version
   int version() const override { return (2); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadPreNexus", "FilterEventsByLogValuePreNexus"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\PreNexus";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
index a699607c6ea99f3b5b3069327d678875af3228a0..a7f8ccbde2ff7ac74e69724fe8657ebb4cec1bd4 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"Load", "SaveFITS"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h b/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h
index 8111a311ed1e1d768fc85bd0a3e8773b9daca656..0c425dac2b6ea0c18bd1c944091368df19c3d7bd 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h
@@ -46,6 +46,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadFullprofFile"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h
index e612508080100a2bb92bb93fd1a929418cfb6905..5cc76649a76dfe9af9401a8524da122144fe1b87 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveGSASInstrumentFile", "LoadGSS", "FixGSASInstrumentFile"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h
index 8512e0db3979701c7bd9159d3c14f0c7218239b3..b19318ba0f9c0cd59cd5243bdadccdb09cb6fad1 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h
@@ -51,6 +51,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadAscii", "SaveGSS", "LoadMultipleGSS"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h
index 0d7413970515722ca6b1feafabea924355b8a2e0..cf96c27b81f0b783e70a1c499613b9fddd3ce387 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h
@@ -41,6 +41,9 @@ class MANTID_DATAHANDLING_DLL LoadILLDiffraction
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   int confidence(Kernel::NexusDescriptor &descriptor) const override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h
index ab552a992cfc4fa8c3796a33d27141aa011305a3..cab355c3535d246857e454dc632f42984b262018 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h
@@ -41,6 +41,9 @@ public:
 
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
 
   const std::string name() const override;
   /// Summary of algorithms purpose
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h
index 000b92adafa4bcb47d0ddc34bf6d0b9ddd95533c..eab4a74e9e8410b5c133e1414a8955f8df97668d 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h
@@ -40,6 +40,9 @@ public:
   const std::string name() const override { return "LoadILLReflectometry"; }
   /// Algorithm's version for identification. @see Algorithm::version
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   /// Algorithm's category for search and find. @see Algorithm::category
   const std::string category() const override {
     return "DataHandling\\Nexus;ILL\\Reflectometry";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h
index cdb68d71b77982d26b91a02fc73b405d92b75d30..1a4f331bd3525209b88f2acff1e6586a821e4f7c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h
@@ -68,6 +68,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   const std::string category() const override;
   /// Returns a confidence value that this algorithm can load a file
   int confidence(Kernel::NexusDescriptor &descriptor) const override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h
index 79ce533b7231260f66c865d192ca6fd5b32e77b8..700a7a9646ae154e22cf66a1c9c5d120dd613b92 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Nexus;ILL\\Direct";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h
index 2954b9871a857df3bbdb390ee345ad5fa9332fcc..85144c3c08a6ef6e04c4cd095642fd9377f5a090 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h
@@ -80,6 +80,9 @@ public:
   const std::string name() const override { return "LoadISISNexus"; }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventNexus", "SaveISISNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
   /// Summary of algorithms purpose
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
index 8649493fe51a914fa262794968c3530701d4b4d2..a0ffc22adc4ca40469c656eece9de2198db1cc6f 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h
@@ -84,6 +84,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrumentFromNexus", "LoadInstrumentFromRaw",
+            "ExportGeometry", "Load"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h
index 5ae9d79ccadf75b74bd8060b018f98020f8f2622..b00f4d6a1480749ac93b2dbc49632166a6a021bc 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h
@@ -84,6 +84,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrument", "Load"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h
index 6185daee8cf7828a3f7135364c29ada2b7483c78..6b5e3d9a8263f1aba05251f61c592aeaa3e0093a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h
@@ -84,6 +84,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrument"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h b/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h
index 321ed71e5270634e29687c535889d46c877b2ff8..10a9d244e5975c899f525b21074a2fc0ffbb163c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveIsawDetCal"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diffraction\\DataHandling;DataHandling\\Isaw";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h b/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h
index 94b541b5c6390ada8e30be62047a8c2225f520cc..075cee128ed15424b081c8b72cdac68e010f5caa 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h
@@ -85,6 +85,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddSampleLog", "LoadNexusLogs"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h
index 3ea1b44215762d6fbcd497382dc2cc7d7233c6a7..593063b1954eaa71f1b81900500c04f888cda7e2 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h
@@ -59,6 +59,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ExportSpectraMask", "LoadMask"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Masking;Transforms\\Masking";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h
index 332df5a22b0016cd35764f93e8791941d58bb1a6..f0511bb6db436d3ae8bc3eeeaeaea62bdc9f6144 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadMcStasNexus", "LoadNexus"};
+  }
   const std::string category() const override;
 
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h
index 7097dddffa08dea6a2d0f7fb328e5bfff12bb0f6..5a7d147d6bd0339eacc366521c6be27740264a15 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h
@@ -40,6 +40,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadMcStas"};
+  }
   const std::string category() const override;
 
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h
index 7f10f57d91103d3b7cef5bb544b60c3618e71f8a..4d638a49e277e0216f65934592fbcd3535d0166a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h
@@ -66,6 +66,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadLog", "LoadLogPropertyTable"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Logs;Muon\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h
index 38f9560f2e97e494d09f6fbb2369e92bb94b90c9..45189d42715cf5efa9e477252b62e1b6fbbacb94 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h
@@ -75,6 +75,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Nexus;Muon\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h
index 0b8fcb6276e877a2552bdc223578e0a28eb1cb59..ad95de64fc8f445d08faeca8ab9a77963db30a4e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h
@@ -52,9 +52,12 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveNXSPE", "LoadSPE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "DataHandling\\Nexus;DataHandling\\SPE;Inelastic\\DataHandling";
+    return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)";
   }
 
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h
index 5b0614563bb51beb4280d990e992d54b1f9dc006..f17a4f2c6fa2b4187768784466259a6f0e883eb3 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadCanSAS1D", "SaveNXcanSAS"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h
index 0f99dc22017cfd36737ac6dc07b31145e45227e6..5f377952ec8f2e9284a76fab50b593dfbe4edf8c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h
@@ -70,6 +70,12 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadMcStasNexus", "LoadNexusMonitors",    "LoadNexusProcessed",
+            "LoadTOFRawNexus", "LoadILLDiffraction",   "LoadILLTOF",
+            "LoadILLIndirect", "LoadILLReflectometry", "LoadILLSANS",
+            "LoadMuonNexus",   "LoadFlexiNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h
index e0bc283b8eeb8e9ca3b70dfb54ea150b67ddf51a..c23d54cc16ef22b4c9a502ec93a816aa951f645a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadLog", "MergeLogs"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Logs;DataHandling\\Nexus";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
index 3ca91b39b598aab2ce94b87c5e9ba46bf3e0ce36..7a98ee10fe4c5aed02c3c3496a998bd21dd65fce 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h
index 7aaec5cdb2335cafa4a4ce82076fb726acf79009..5f44961674654668ca5975027ebb7cdcc042b3fc 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h
@@ -76,6 +76,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h
index 535770755f2b6853a9cfb4ae7123a86dab8c79c6..d74c01e2b0fe4f94a057557bb5b28e6ce6d3c7d9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadAscii"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h
index 698e991deebf19e04ec739982eb0d4ec4e96d6b0..6843aa500b2a295c2993b60b1594f0b0f33d51c2 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h
@@ -76,6 +76,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveParameterFile"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h
index 713214413fa716dcc7f412fb409f67d1997ff514..c2ccb22f0e6a9b86c21a310e84f8d3641bca881b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h
@@ -44,6 +44,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventPreNexus", "LoadPreNexusMonitors", "LoadNexus"};
+  }
   const std::string category() const override;
   void parseRuninfo(const std::string &runinfo, std::string &dataDir,
                     std::vector<std::string> &eventFilenames);
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h
index 664ac56cff3be2472402dcbe9c3e5793661de1c9..25c416c670175c613aaae96a96772e8d65428275 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventPreNexus", "LoadPreNexus"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\PreNexus";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h b/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h
index bc9889a5668d153656425983fee74ec5262fbbd7..406beb41fcb89d548f37dffa809a3b789ed97e11 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h
@@ -48,6 +48,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadBBY"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
index 1c2e33f2bf92d61f34da5d077ec2ed93d19d482c..7e174ea284f909bb4cef8961fb49360dd4b1e11c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveRKH"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Text;SANS\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h
index d72df2b5c523b9239b1b8818ae396582b764ec5d..f2908a5e83b3faa11a62a7f635260e9c3ac45f76 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h
@@ -58,6 +58,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 3; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadVesuvio", "RawFileInfo", "LoadSampleDetailsFromRaw",
+            "LoadRawBin0", "LoadRawSpectrum0"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Raw"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h
index 9fcc52621f67a5b211af7340070d3fe17fcc5a3d..ec86f240489320bb05d9bab9db2b9eeba6c4e645 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h
@@ -78,6 +78,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRawSpectrum0", "LoadRaw"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diagnostics\\Raw;DataHandling\\Raw";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h
index 1be9e313735c4e962436d59405a1103c59c1312f..fdabf955b69ab61e1e33aece0ce9e209593c609b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h
@@ -70,6 +70,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRawBin0", "LoadRaw"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "Diagnostics\\Raw;DataHandling\\Raw";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h
index ad92b109c53204a0b116add9493f3ff8778193b6..300403b5dc899e7e109d94061d88f3d220d52791 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h
@@ -6,9 +6,9 @@
 
 #include <unordered_map>
 
-typedef std::vector<double> Column;
-typedef std::unordered_map<std::string, Column> ColumnMap;
-typedef std::unordered_map<std::string, std::string> AttributeMap;
+using Column = std::vector<double>;
+using ColumnMap = std::unordered_map<std::string, Column>;
+using AttributeMap = std::unordered_map<std::string, std::string>;
 
 namespace Mantid {
 namespace DataHandling {
@@ -51,6 +51,9 @@ public:
   const std::string name() const override;
   const std::string summary() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveSESANS"};
+  }
   const std::string category() const override;
   int confidence(Kernel::FileDescriptor &descriptor) const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h
index 14e8c75257992ecbb7a2b268b8e4b5488b8d8cb0..7bed907b11760ab42e1d21cfc07d79a015a18c52 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h
@@ -55,6 +55,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSINQ", "LoadSINQFile"};
+  }
   const std::string category() const override;
 
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
index 75c104fc42cd0297aeb67e19acee3d2a87221e40..68aa0af8ac915c1d56a746a8f257b3298cd55288 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h
@@ -58,6 +58,9 @@ public:
   }
 
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSpec"};
+  }
   const std::string category() const override { return "DataHandling\\Text"; }
 
   /// Returns a confidence value that this algorithm can load a file
@@ -70,8 +73,8 @@ private:
   /// Allowed values for the cache property
   std::vector<std::string> m_seperator_options;
   std::map<std::string, const char *> m_separatormap; ///<a map of seperators
-  typedef std::pair<std::string, const char *>
-      separator_pair; ///<serparator pair type def
+  using separator_pair =
+      std::pair<std::string, const char *>; ///<serparator pair type def
 };
 
 } // namespace DataHandling
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h
index 4b7893dcd77e74cbfdb6f645ccf357b260fdd31f..29d269c26ff2cf66ebbbab94a4de5781fda6fdf0 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h
@@ -52,6 +52,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveSPE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\SPE;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h
index 99c75422620c4d3108b2d8ffd1a39120b58aa3f4..c898cb038b81404c39f6a8bc4f55934b4c4130e6 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRaw"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Raw;Sample";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
index 8fb12e9d81d24a0db34dad460d3ddfc0b479ae3d..5eb20bb45b7045640719ea44be3546c5fe265bcf 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h
@@ -57,6 +57,9 @@ public:
   }
 
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSNSspec"};
+  }
   const std::string category() const override { return "DataHandling\\Text"; }
 
 private:
@@ -74,8 +77,8 @@ private:
   /// Allowed values for the cache property
   std::vector<std::string> m_seperator_options;
   std::map<std::string, const char *> m_separatormap; ///<a map of seperators
-  typedef std::pair<std::string, const char *>
-      separator_pair; ///<serparator pair type def
+  using separator_pair =
+      std::pair<std::string, const char *>; ///<serparator pair type def
 };
 
 } // namespace DataHandling
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
index 2553c519928802e99de39afe6da5cd38264e9e03..4552c15f71bce422347be74c388fe6a3077c8287 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSpiceAscii", "LoadSpiceXML2DDet"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Text;SANS\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h
index ef02ed6e6c62a6ab30ed878c0bd62c2c137f9099..017f844650daa455d2658db9acba8849ade1274a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h
@@ -37,6 +37,9 @@ class DLLExport LoadSpiceAscii : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSpice2D", "LoadSpiceXML2DDet"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
index 8edc6f39906df380ac4b2646c247b5a8d88ccf29..3129bdbfc31b0e157e7f8db9e3d35a55a5dcffa1 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
@@ -69,6 +69,9 @@ public:
 
   /// Algorithm version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSpice2D"};
+  }
 
   /// Category
   const std::string category() const override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h b/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h
index 7ada633b4f14b74311a77100ea6ccf7dc7293d6d..5f202b0a1168ce50f21c4214448dc5375470d38e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h
@@ -48,6 +48,9 @@ public:
 
   /// The version number
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveTBL"};
+  }
   /// The category
   const std::string category() const override { return "DataHandling\\Text"; }
   /// Returns a confidence value that this algorithm can load a file
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h
index 83db10f28576f6fc2006c9b16f1c81a08ae6ec29..1c104389e45289451ba637865035305921f446b6 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h
@@ -56,6 +56,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h
index 18fe35888b762253db6b58a318d01a4c3e345fa4..9614a977eac8644e3dca33cee932bff7f8cdab51 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h
@@ -36,6 +36,12 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReadGroupsFromFile",   "CreateDummyCalFile",
+            "CreateCalFileByNames", "AlignDetectors",
+            "DiffractionFocussing", "LoadCalFile",
+            "SaveCalFile",          "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Text;Diffraction\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h
index eeb72c9fea0682d8bc75a9dd9b57c3ff71e00040..fd2d0d03475487e154552318140c6de536676c29 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h
@@ -65,6 +65,10 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectorsInShape", "MaskDetectorsIf", "MaskInstrument",
+            "MaskSpectra", "MaskBTP", "MaskAngle", "InvertMask"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Masking"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h
index 533fe235fe9d68dac7f0d8e2b51465b4280a3f23..ea22b9e1b00c65a974af54fc1685993f3e115843 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h
@@ -58,6 +58,9 @@ public:
   const std::string name() const override { return "MaskDetectorsInShape"; };
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors", "FindDetectorsInShape"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "Transforms\\Masking"; }
   /// Summary of algorithms purpose
diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h b/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h
index ee0a2df9cfaa26dbb0ca3d14d1984039e55d7ec0..9c842bfe1abe8fd2016932d61b79d538f5ed9854 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h
@@ -39,6 +39,9 @@ class MANTID_DATAHANDLING_DLL MaskSpectra : public API::DistributedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h b/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h
index 7489b04a7e8a359b7dde29baf04ec701e5cbff51..14b20e692d7b1da98ca056f060ddc47d6f6e9e1b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"AddTimeSeriesLog"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h b/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h
index 7c0c85e460755b12583eaa5e0d1a9d81bb113c92..4783666f48c6e756bdd686ca264fa3c2f59c3580 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h
@@ -48,6 +48,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ResizeRectangularDetector"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h b/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h
index d556d560520c091c50c0d4c94884229628dc55c8..3839dc8a3c53bc6cb558c968b6b2485b724fad49 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h
@@ -71,6 +71,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RotateInstrumentComponent", "SetInstrumentParameter"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h b/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h
index 79b19a27890873c0da1f7bf721d4716532e4a954..0149fb4c9f86da92d3d689b07cbb0f8952a6efff 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h
@@ -94,6 +94,7 @@ const std::string sasProcessName = "name";
 const std::string sasProcessNameValue = "Mantid_generated_NXcanSAS";
 const std::string sasProcessDate = "date";
 const std::string sasProcessTermSvn = "svn";
+const std::string sasProcessTermCan = "can_trans_run";
 const std::string sasProcessTermUserFile = "user_file";
 const std::string sasProcessUserFileInLogs = "UserFile";
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h b/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h
index c2001589b996989261629567a93c2c78591dfe10..dc12118760c15df3145ea3020382394d645366a9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h
@@ -47,6 +47,9 @@ class DLLExport PatchBBY : public API::Algorithm {
 public:
   // description
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadBBY"};
+  }
   const std::string name() const override { return "PatchBBY"; }
   const std::string category() const override { return "DataHandling\\ANSTO"; }
   const std::string summary() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h b/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h
index f2be39a103ef8724dff12ce4d67b54a4202eff85..e73bd721436f460f80f8e6eb6173693baa9af9ba 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h
@@ -71,6 +71,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRaw"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Raw"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h b/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h
index 2e2354bd5df10bbc6e3c6af6dcc83020acab956b..976bccc342fc9ae06a87b549890a1f1ce167777f 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h
@@ -86,6 +86,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RenameLog", "DeleteLog"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h b/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h
index 936ff1012d7a72e11796852f6174f5c7b8fffe15..eeea4eb47e4825c41150739ae8f7114f102ae672 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RemoveLogs", "DeleteLog"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Logs"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h b/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h
index 1b6cb651bd9c7a8c486e18c90a64ec5e30e4f6fc..0bab2f84414356adece559698411e7c3aea38c02 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h
@@ -70,6 +70,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MoveInstrumentComponent", "SetInstrumentParameter"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Instrument";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h b/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h
index 40938148a8f64471ae7cd97ad7f44cb076d4cfda..2eebef20dc0aed8fe8c736521a75252238d44e96 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h
@@ -36,6 +36,9 @@ class DLLExport RotateSource : public API::Algorithm {
 public:
   const std::string name() const override { return "RotateSource"; };
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"RotateInstrumentComponent"};
+  }
   const std::string category() const override {
     return "DataHandling\\Instrument";
   };
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h
index 5cd322be4f189b2b2f01a79de3c335f98e4e34de..c716e3f12edd381f0636f83cdb67fa879062b152 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h
@@ -48,6 +48,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
 
 private:
   /// Return the file extension this algorthm should output.
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
index a78c28d12aaca75edd01d211900fbdc0e949b0a1..899e9eb803b5a25e58d3ae3a4a1a2cafc37e4575 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h
@@ -50,6 +50,12 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadAscii", "SaveANSTOAscii", "SaveCSV", "SaveDiffFittingAscii",
+            "SaveILLCosmosAscii", "SaveReflCustomAscii",
+            "SaveReflThreeColumnAscii", "SaveOpenGenieAscii", "SaveGSS",
+            "SaveFocusedXYE"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Text"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h
index 2e60283a4f5bef14b06484df560475cb96744a48..5fad0d6a2a7b08bdc82c32baee56a4d0551b0576 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h
@@ -93,6 +93,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Text"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h
index 1d99257bd0a93271b922ddc87ed442805dffc037..6e801b78f2fb3810ab605732e76dc44365bf8ce5 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h
@@ -29,9 +29,15 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"ReadGroupsFromFile",   "CreateDummyCalFile",
+            "CreateCalFileByNames", "AlignDetectors",
+            "DiffractionFocussing", "LoadCalFile",
+            "MergeCalFiles"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles";
+    return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)";
   }
 
   void saveCalFile(const std::string &calFileName,
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h
index c1f19c14013495966cfd2e3cc0e2501bd9a64726..de4678a9dcc5258409fe1265203b859f32168b31 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h
@@ -79,6 +79,9 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class DLLExport SaveCanSAS1D2 : public SaveCanSAS1D {
 public:
   int version() const override { return 2; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadCanSAS1D"};
+  }
 
 protected:
   /// Extends the SaveCanSAS1D init method
@@ -92,6 +95,9 @@ protected:
   /// this method creates SAStransmission_spectrum element
   void createSASTransElement(std::string &sasTrans, const std::string &name);
 
+  /// this method creates SASProcess element
+  void createSASProcessElement(std::string &sasProcess);
+
   /// Overwrites writeHeader method
   void writeHeader(const std::string &fileName) override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h
index c7f5b5cae24d6736857e71a28e98e0e31c28aab0..82380bf83671d5b937a8b5990dcc807150d5bfae 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadDaveGrp"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Text;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h
index 52796fc12a701402fd9ba5efcbb6bc2a39288ab4..fecebb64053f9fd31dfa94601ae78dd4d3a94ed1 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadDetectorsGroupingFile", "GroupDetectors"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Grouping;Transforms\\Grouping";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h
index 74c30be7a4a77faaa9f004991df6070d06b403a6..d1ae5a69a2d4a09dec2c9e9ead15404a8de01fb0 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h
@@ -40,6 +40,9 @@ class DLLExport SaveDiffCal : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadDiffCal"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h
index 4b0c21dd82f6ea938e9d3bb761ddc50b5ee76f1a..5b619ca6f592beb1272139a6d7b08a31e6c10d4c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h
@@ -28,6 +28,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"EnggFitPeaks", "SaveAscii"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Text"; }
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h
index ea59057a006e18e0981123edeeebf203d031115c..dff9928d773ec0decab9697eef164f273f1fc018 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h
@@ -37,6 +37,9 @@ public:
   const std::string name() const override final;
 
   int version() const override final;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadFITS", "SaveNXTomo"};
+  }
 
   const std::string category() const override final;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h
index 7da884dc5cc1a1ccb0a96fc34134e3610d61e89f..7d71c4471738acabb41b8c8dc1b0b9902387490a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h
@@ -69,6 +69,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveFullprofResolution", "SaveAscii"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling;DataHandling\\Text";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h
index 5b1fce6e8b82d2f9aa7d95bd8b2d1824ca2553bd..30dbb51d582aab4eec6e69803fc9e0b7aac11c5c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveFocusedXYE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling;DataHandling\\Text";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h
index e4ec6e647f5948d6b4be7fbc8969c60cae1bc667..6ce5acae91daaee3798ca514d25ece15c50da1e5 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h
@@ -50,6 +50,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadGSASInstrumentFile", "SaveGSS"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h
index bc4c870cf2590f143b5a3239e346005ea5050cbf..6c1124c070ba7418e3dde5c0b822e091085830b7 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h
@@ -80,6 +80,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadGSS", "SaveVulcanGSS", "SaveGSASInstrumentFile", "SaveAscii"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling;DataHandling\\Text";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h
index a21a7709ed4efd93a87a099d005f4ee57ec4ea40..598759ad8f13f305d4aa66f4613ab10f8defda91 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
 
 private:
   /// Return the file extension this algorthm should output.
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
index 4c070da9edc4d139633ecc9e8cd16f6220f3f9a9..963c5e9644756c046e50df2721bebc37477ff85e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
@@ -58,6 +58,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveNexusProcessed", "SaveNexus", "LoadNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h b/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h
index 68970bb983a9e8899d05c88884c8a895e8ff0eee..8aab2423c5cdb5e7fa9a9bf5f181d18be52600a9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadIsawDetCal"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Diffraction\\DataHandling;DataHandling\\Isaw";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h b/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h
index d3c06e9be4088c7814bf85ce1544c62c265e98f5..e7ddb70ce273a32e1e6751cdbcf8f075b6b6821c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveMask", "LoadMask"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\Masking;Transforms\\Masking";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h
index 4725bcbaa39836e4205131d74e7e6b6bcef9718b..4e9a4116f28af932d759e6ce80d81cd41660df09 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h
@@ -45,9 +45,12 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNXSPE", "SaveSPE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "DataHandling\\Nexus;DataHandling\\SPE;Inelastic\\DataHandling";
+    return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)";
   }
 
 private:
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h
index 1884a315586647b76bf9a59380176baa9c75eb6e..562a6d86b08b0794b9d27820316aecf4b5fb0752 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h
@@ -60,6 +60,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveNexusProcessed"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h
index 8c9541ef206a4145f8d8a8111c87c5f5bc707d82..62bbbbe7ce345215e67ee5da81baaebdd06b8eb0 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h
@@ -45,6 +45,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveCanSAS1D", "LoadNXcanSAS"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h
index 98d7c344d6f8156a6fadf1a8edcd624bf32c386c..12b09027ad3b96c4c6b9ca5c427f3bcaa059791f 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h
@@ -55,6 +55,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveISISNexus", "SaveNexusPD", "SaveNexusProcessed", "LoadNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h
index 5c3a7f73062e1312319b6dd704927f9055b82fc1..c3e23960fae3b997cb621a41d7d254d344667408 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h
@@ -62,6 +62,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveISISNexus", "SaveNexus", "LoadNexusProcessed"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h
index 7b50c4f01410339e4db9221c765a0549755e1a53..de5947fd4a8350acd682f102b315a57a2efdd424 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h
@@ -26,6 +26,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h b/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h
index 47569287cac9bff72e5914dbb3df21b995a0d39a..b223398d7dd900095de04fa4fe430ec5a8b6bf58 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h
@@ -68,6 +68,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveSPE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\SPE;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h b/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h
index 43f0ee8259d4a78e9003c8cb2ded4a4db1f0be68..ef1455272ccd9b5811039fe395a8e6685e65b702 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h
@@ -34,6 +34,9 @@ class DLLExport SavePDFGui : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveAscii"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h b/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h
index 85a87d9784d41c136f8c67fb91c21bb06b78d0a8..4244b99431ee1084b3c9189900d6f22c16649992 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h
@@ -53,6 +53,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveSPE"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\SPE;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h
index 780ed0bb1e89369ffab0bc94aabbb96e2b9004f0..4f2fe27a23687878136ef64261878d2b6d376544 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h
@@ -44,6 +44,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadParameterFile"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h b/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h
index 846b94d51bd6016993df4691fa36b3be518be6c0..0dbf4c0197ec6a11e94f9a476564698af23a5ea4 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadRKH"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Text"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h
index ddaa6abdaa7645bcb077efd3a4bd06e0b2274479..b4e5d8379127d8ade88dc072c923f8468435178b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h
@@ -48,6 +48,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveReflThreeColumnAscii", "SaveAscii"};
+  }
 
   ///
   void data(std::ofstream &file, const std::vector<double> &XData,
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h
index daa9664c0ee25ff93bf162639907294fa875a909..6bf26dd38800233feba2f3b36066858933b60b69 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h
@@ -50,6 +50,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveReflCustomAscii", "SaveAscii"};
+  }
   /// Algorithm's version for data output overriding a virtual method
   void data(std::ofstream &file, const std::vector<double> &XData,
             bool exportDeltaQ = false) override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h
index 185f10b0cbf4ab9b92e1f3756688d0d1b64a7706..13e4b95071dedfbb69784c162fc50de77e3d7de5 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h
@@ -54,6 +54,9 @@ public:
   const std::string name() const override;
   const std::string summary() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSESANS"};
+  }
   const std::string category() const override;
   std::map<std::string, std::string> validateInputs() override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h
index 1a1dc408346a18a5dc6ca115d98b2e648908dc59..c09ae5d284589e8d83e2fe0402535fd0a95c69d8 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadSPE", "SavePAR", "SavePHX"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "DataHandling\\SPE;Inelastic\\DataHandling";
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h b/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h
index 5f82e9098f8f1ebfa6cf394bd810efc6b2eea2d1..b80c6798d0a973d622ac49a9b397625a18e9bade 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadTBL"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Text"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h
index dc53024f17560f2a559f13761161a489cbe5ebe9..aeed901d4ad9864382e46d6661b4df9e9784d0b7 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h
@@ -60,6 +60,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SaveNexus"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h b/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h
index c947ebbd142c185918db29cd99db11f18095f359..56a10b059668dc34731f29f4a698f5663256f529 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h
@@ -34,6 +34,9 @@ class MANTID_DATAHANDLING_DLL SetBeam final : public API::Algorithm {
 public:
   const std::string name() const override final;
   int version() const override final;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetSample"};
+  }
   const std::string category() const override final;
   const std::string summary() const override final;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
index 6769bd955b1d072b382907e536ddbc38b0c71856..b5a855904ddd1903e67aff6a5caae6adbe9c820f 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h
@@ -40,6 +40,9 @@ class MANTID_DATAHANDLING_DLL SetSample final : public API::Algorithm {
 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"};
+  }
   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 a4e0461fdbeb365bb0973f075337011b1297afab..573251000e4f64cc7ade9521dcc5f4cfd39dd66b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h
@@ -47,6 +47,10 @@ public:
 
   /// Algorithm's version
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AbsorptionCorrection", "CreateSampleShape",
+            "CalculateSampleTransmission"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h b/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h
index 22ac676da171c5e81cc96f8df3e754ef244e93ec..a165dce8bf6f2a09604674b35ac6b9bc5f21596c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h
@@ -34,6 +34,9 @@ class DLLExport SortTableWorkspace : public API::ParallelAlgorithm {
 public:
   const std::string name() const override { return "SortTableWorkspace"; }
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateEmptyTableWorkspace"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h b/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h
index c19f353f5dfac291481bc5bd48e7be90c4823269..13b140d56608c1adafa40fa125e4863b9e35268a 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h
@@ -69,6 +69,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadInstrument"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp b/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp
index f96eed456df8821f50331de4213a29a4f4fd9817..1c0af93b17d0b5e6f11a16a14f3fdba92cf8f2e0 100644
--- a/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp
+++ b/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp
@@ -23,7 +23,7 @@ using namespace Mantid::Kernel;
 using Types::Core::DateAndTime;
 using namespace std;
 
-typedef Mantid::Kernel::StringTokenizer tokenizer;
+using tokenizer = Mantid::Kernel::StringTokenizer;
 
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(CreateChunkingFromInstrument)
diff --git a/Framework/DataHandling/src/CreateSimulationWorkspace.cpp b/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
index 1ee59ace516259cea27a9b5c79f1582bd13f662b..5a64490853fc2e559f2f73cb9469638a0db3c21c 100644
--- a/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
+++ b/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
@@ -288,7 +288,7 @@ void CreateSimulationWorkspace::loadMappingFromISISNXS(
     throw std::runtime_error(
         "Cannot find path to isis_vms_compat. Is the file an ISIS NeXus file?");
   }
-  typedef boost::scoped_ptr<std::vector<int32_t>> NXIntArray;
+  using NXIntArray = boost::scoped_ptr<std::vector<int32_t>>;
 
   nxsFile.openData("NDET");
   NXIntArray ndets(nxsFile.getData<int32_t>());
diff --git a/Framework/DataHandling/src/DetermineChunking.cpp b/Framework/DataHandling/src/DetermineChunking.cpp
index 498f30ba0fec8016756360a6954e6e95759ee448..93b147d699e5bc87814849c9ecc0542901dfa201 100644
--- a/Framework/DataHandling/src/DetermineChunking.cpp
+++ b/Framework/DataHandling/src/DetermineChunking.cpp
@@ -289,7 +289,7 @@ void DetermineChunking::exec() {
 /// set the name of the top level NXentry m_top_entry_name
 std::string DetermineChunking::setTopEntryName(std::string filename) {
   std::string top_entry_name;
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
   try {
     string_map_t::const_iterator it;
     ::NeXus::File file = ::NeXus::File(filename);
diff --git a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
index 28512fcfb87521e8139ce36cab97565884d31613..949e493344830331fb911f180c23cf5c500c5013 100644
--- a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
+++ b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
@@ -52,13 +52,10 @@ using namespace API;
 using namespace DataObjects;
 using namespace Geometry;
 using Types::Core::DateAndTime;
-using boost::posix_time::ptime;
-using boost::posix_time::time_duration;
 using DataObjects::EventList;
 using DataObjects::EventWorkspace;
 using DataObjects::EventWorkspace_sptr;
 using Types::Event::TofEvent;
-using std::cout;
 using std::ifstream;
 using std::runtime_error;
 using std::stringstream;
@@ -910,7 +907,7 @@ void FilterEventsByLogValuePreNexus::procEvents(
   std::vector<DasEvent *> buffers;
 
   /// Pointer to the vector of events
-  typedef std::vector<TofEvent> *EventVector_pt;
+  using EventVector_pt = std::vector<TofEvent> *;
   /// Bare array of arrays of pointers to the EventVectors
   EventVector_pt **eventVectors;
 
@@ -1515,7 +1512,7 @@ void FilterEventsByLogValuePreNexus::filterEvents() {
   std::vector<DasEvent *> buffers;
 
   /// Pointer to the vector of events
-  typedef std::vector<TofEvent> *EventVector_pt;
+  using EventVector_pt = std::vector<TofEvent> *;
   /// Bare array of arrays of pointers to the EventVectors
   EventVector_pt **eventVectors;
 
diff --git a/Framework/DataHandling/src/GenerateGroupingPowder.cpp b/Framework/DataHandling/src/GenerateGroupingPowder.cpp
index 1f421d452bf10e18597a4afb6b07ea90d7c74c6c..b5a0f7b0b655e2a1b80ecacf50acd557b893db72 100644
--- a/Framework/DataHandling/src/GenerateGroupingPowder.cpp
+++ b/Framework/DataHandling/src/GenerateGroupingPowder.cpp
@@ -37,7 +37,7 @@ int GenerateGroupingPowder::version() const { return 1; }
 
 /// Algorithm's category for identification. @see Algorithm::category
 const std::string GenerateGroupingPowder::category() const {
-  return "DataHandling\\Grouping;Transforms\\Grouping;Diffraction\\Utility";
+  return R"(DataHandling\Grouping;Transforms\Grouping;Diffraction\Utility)";
 }
 
 /** Initialize the algorithm's properties.
diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp
index 859a8adf62a4476f11d9e9e3df37b06ee627359b..b7db303c8f73e547c0886a9ed273bf083e94bab5 100644
--- a/Framework/DataHandling/src/GroupDetectors2.cpp
+++ b/Framework/DataHandling/src/GroupDetectors2.cpp
@@ -51,9 +51,9 @@ void translateAdd(const std::string &instructions,
   outSpectra.reserve(spectra.count());
   for (const auto &spectrum : spectra) {
     // add this spectrum to the group we're about to add
-    outSpectra.push_back(boost::lexical_cast<int>(spectrum));
+    outSpectra.emplace_back(boost::lexical_cast<int>(spectrum));
   }
-  outGroups.push_back(std::move(outSpectra));
+  outGroups.emplace_back(std::move(outSpectra));
 }
 
 // A range summation, i.e. "3-6" -> [3+4+5+6]
@@ -74,9 +74,9 @@ void translateSumRange(const std::string &instructions,
   std::vector<int> outSpectra;
   outSpectra.reserve(last - first + 1);
   for (int i = first; i <= last; ++i)
-    outSpectra.push_back(i);
+    outSpectra.emplace_back(i);
   if (!outSpectra.empty())
-    outGroups.push_back(std::move(outSpectra));
+    outGroups.emplace_back(std::move(outSpectra));
 }
 
 // A range insertion, i.e. "3:6" -> [3,4,5,6]
@@ -144,14 +144,14 @@ translateInstructions(const std::string &instructions, unsigned options) {
  * @param axis : The spectra axis of the workspace
  * @param commands : A stringstream to be filled
  */
-void convertGroupsToMapFile(std::vector<std::vector<int>> groups,
-                            const SpectraAxis *axis,
+void convertGroupsToMapFile(const std::vector<std::vector<int>> &groups,
+                            const SpectraAxis &axis,
                             std::stringstream &commands) {
   // The input gives the groups as a vector of a vector of ints. Turn
   // this into a string, just like the contents of a map file.
   commands << groups.size() << "\n";
   for (auto &group : groups) {
-    const int groupId = axis->spectraNo(group[0]);
+    const int groupId = axis.spectraNo(group[0]);
     const int groupSize = static_cast<int>(group.size());
 
     // Comment the output for readability
@@ -165,11 +165,23 @@ void convertGroupsToMapFile(std::vector<std::vector<int>> groups,
     // The input is in 0-indexed workspace ids, but the mapfile syntax expects
     // spectrum ids
     for (size_t j = 0; j < group.size(); ++j) {
-      commands << (j > 0 ? " " : "") << axis->spectraNo(group[j]);
+      commands << (j > 0 ? " " : "") << axis.spectraNo(group[j]);
     }
     commands << "\n";
   }
 }
+
+/**
+ * Replace the vertical axis to by a SpectraAxis.
+ * @param ws a workspace
+ */
+void forceSpectraAxis(MatrixWorkspace &ws) {
+  if (dynamic_cast<SpectraAxis *>(ws.getAxis(1))) {
+    return;
+  }
+  ws.replaceAxis(1, new SpectraAxis(&ws));
+}
+
 } // anonymous namespace
 
 // progress estimates
@@ -322,8 +334,10 @@ void GroupDetectors2::exec() {
 
   outputWS->setIndexInfo(indexInfo);
 
-  g_log.information() << name() << " algorithm has finished\n";
-
+  // Make sure output workspace has spectra axis.
+  // Numeric axis copied from the input workspace would be initialized with
+  // zeros only and contain no information in it.
+  forceSpectraAxis(*outputWS);
   setProperty("OutputWorkspace", outputWS);
 }
 
@@ -393,14 +407,15 @@ void GroupDetectors2::execEvent() {
   // Set all X bins on the output
   outputWS->setAllX(inputWS->binEdges(0));
 
-  g_log.information() << name() << " algorithm has finished\n";
-
+  // Make sure output workspace has spectra axis.
+  // Numeric axis copied from the input workspace would be initialized with
+  // zeros only and contain no information in it.
+  forceSpectraAxis(*outputWS);
   setProperty("OutputWorkspace", outputWS);
 }
 
 /** Make a map containing spectra indexes to group, the indexes could have come
-* from
-*  file, or an array, spectra numbers ...
+*  from a file, or an array, spectra numbers ...
 *  @param workspace :: the user selected input workspace
 *  @param unUsedSpec :: spectra indexes that are not members of any group
 */
@@ -456,11 +471,8 @@ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace,
 
   const std::string instructions = getProperty("GroupingPattern");
   if (!instructions.empty()) {
-    spec2index_map specs2index;
-    const SpectraAxis *axis =
-        dynamic_cast<const SpectraAxis *>(workspace->getAxis(1));
-    if (axis)
-      specs2index = axis->getSpectraIndexMap();
+    const SpectraAxis axis(workspace.get());
+    const auto specs2index = axis.getSpectraIndexMap();
 
     // Translate the instructions into a vector of groups
     auto groups = translateInstructions(instructions, IGNORE_SPACES);
@@ -547,7 +559,7 @@ void GroupDetectors2::getGroups(API::MatrixWorkspace_const_sptr workspace,
 * group (so far)
 *  @throw FileError if there's any problem with the file or its format
 */
-void GroupDetectors2::processFile(std::string fname,
+void GroupDetectors2::processFile(const std::string &fname,
                                   API::MatrixWorkspace_const_sptr workspace,
                                   std::vector<int64_t> &unUsedSpec) {
   // tring to open the file the user told us exists, skip down 20 lines to find
@@ -638,7 +650,7 @@ void GroupDetectors2::processFile(std::string fname,
 * group (so far)
 *  @throw FileError if there's any problem with the file or its format
 */
-void GroupDetectors2::processXMLFile(std::string fname,
+void GroupDetectors2::processXMLFile(const std::string &fname,
                                      API::MatrixWorkspace_const_sptr workspace,
                                      std::vector<int64_t> &unUsedSpec) {
   // 1. Get maps for spectrum No and detector ID
@@ -732,7 +744,7 @@ void GroupDetectors2::processGroupingWorkspace(
     std::vector<int64_t> &unUsedSpec) {
   detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap();
 
-  typedef std::map<size_t, std::set<size_t>> Group2SetMapType;
+  using Group2SetMapType = std::map<size_t, std::set<size_t>>;
   Group2SetMapType group2WSIndexSetmap;
 
   const auto &spectrumInfo = groupWS->spectrumInfo();
@@ -785,7 +797,7 @@ void GroupDetectors2::processMatrixWorkspace(
     std::vector<int64_t> &unUsedSpec) {
   detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap();
 
-  typedef std::map<size_t, std::set<size_t>> Group2SetMapType;
+  using Group2SetMapType = std::map<size_t, std::set<size_t>>;
   Group2SetMapType group2WSIndexSetmap;
 
   const auto &spectrumInfo = groupWS->spectrumInfo();
@@ -838,7 +850,7 @@ void GroupDetectors2::processMatrixWorkspace(
 *  @throw boost::bad_lexical_cast when the string can't be interpreted as an
 * integer
 */
-int GroupDetectors2::readInt(std::string line) {
+int GroupDetectors2::readInt(const std::string &line) {
   // remove comments and white space (TOK_TRIM)
   Mantid::Kernel::StringTokenizer dataComment(
       line, "#", Mantid::Kernel::StringTokenizer::TOK_TRIM);
@@ -880,10 +892,10 @@ int GroupDetectors2::readInt(std::string line) {
 * @param ignoreGroupNumber :: ignore group numbers when numbering spectra
 * @throw invalid_argument if there is any problem with the file
 */
-void GroupDetectors2::readFile(spec2index_map &specs2index, std::istream &File,
-                               size_t &lineNum,
+void GroupDetectors2::readFile(const spec2index_map &specs2index,
+                               std::istream &File, size_t &lineNum,
                                std::vector<int64_t> &unUsedSpec,
-                               bool ignoreGroupNumber) {
+                               const bool ignoreGroupNumber) {
   // go through the rest of the file reading in lists of spectra number to group
   int oldSpectrumNo = 1;
   while (File) {
@@ -946,8 +958,7 @@ void GroupDetectors2::readFile(spec2index_map &specs2index, std::istream &File,
   }
 }
 /** The function expects that the string passed to it contains a series of
-* integers,
-*  ranges specified with a '-' are possible
+*  integers, ranges specified with a '-' are possible
 *  @param line :: a line read from the file, we'll interpret this
 *  @param specs2index :: a map with spectra numbers as indexes and index numbers
 * as values
@@ -958,11 +969,11 @@ void GroupDetectors2::readFile(spec2index_map &specs2index, std::istream &File,
 *  @throw invalid_argument when a number couldn't be found or the number is not
 * in the spectra map
 */
-void GroupDetectors2::readSpectraIndexes(std::string line,
-                                         spec2index_map &specs2index,
+void GroupDetectors2::readSpectraIndexes(const std::string &line,
+                                         const spec2index_map &specs2index,
                                          std::vector<size_t> &output,
                                          std::vector<int64_t> &unUsedSpec,
-                                         std::string seperator) {
+                                         const std::string &seperator) {
   // remove comments and white space
   Mantid::Kernel::StringTokenizer dataComment(line, seperator, IGNORE_SPACES);
   for (const auto &itr : dataComment) {
@@ -1337,7 +1348,7 @@ std::map<std::string, std::string> GroupDetectors2::validateInputs() {
   const std::string pattern = getPropertyValue("GroupingPattern");
 
   boost::regex re(
-      "^\\s*[0-9]+\\s*$|^(\\s*,*[0-9]+(\\s*(,|:|\\+|\\-)\\s*)*[0-9]*)*$");
+      R"(^\s*[0-9]+\s*$|^(\s*,*[0-9]+(\s*(,|:|\+|\-)\s*)*[0-9]*)*$)");
 
   try {
     if (!pattern.empty() && !boost::regex_match(pattern, re)) {
diff --git a/Framework/DataHandling/src/LoadDiffCal.cpp b/Framework/DataHandling/src/LoadDiffCal.cpp
index d4a9929d42162ce62af6035424f32b89817bbef3..398f654ccebe7209d2b2539344b0ae8c84cdc6e8 100644
--- a/Framework/DataHandling/src/LoadDiffCal.cpp
+++ b/Framework/DataHandling/src/LoadDiffCal.cpp
@@ -400,7 +400,12 @@ void LoadDiffCal::exec() {
   try {
     calibrationGroup = file.openGroup("calibration");
   } catch (FileIException &e) {
-    e.printError();
+#if H5_VERSION_GE(1, 8, 13)
+    UNUSED_ARG(e);
+    H5::Exception::printErrorStack();
+#else
+    e.printError(stderr);
+#endif
     throw std::runtime_error("Did not find group \"/calibration\"");
   }
 
diff --git a/Framework/DataHandling/src/LoadEventNexus.cpp b/Framework/DataHandling/src/LoadEventNexus.cpp
index 040c535ac29e4828e7cb0121f742bb649e197691..6a82dc0926f41abb883477baea2d80fb782090ff 100644
--- a/Framework/DataHandling/src/LoadEventNexus.cpp
+++ b/Framework/DataHandling/src/LoadEventNexus.cpp
@@ -22,12 +22,11 @@
 #include "MantidIndexing/IndexInfo.h"
 
 #include <boost/function.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_real.hpp>
 #include <boost/shared_array.hpp>
 #include <boost/shared_ptr.hpp>
 
 #include <functional>
+#include <random>
 
 using Mantid::Types::Core::DateAndTime;
 using Mantid::Types::Event::TofEvent;
@@ -318,7 +317,7 @@ void LoadEventNexus::setTopEntryName() {
     m_top_entry_name = nxentryProperty;
     return;
   }
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
   try {
     string_map_t::const_iterator it;
     // assume we're at the top, otherwise: m_file->openPath("/");
@@ -1143,7 +1142,7 @@ bool LoadEventNexus::hasEventMonitors() {
   try {
     m_file->openPath("/" + m_top_entry_name);
     // Start with the base entry
-    typedef std::map<std::string, std::string> string_map_t;
+    using string_map_t = std::map<std::string, std::string>;
     // Now we want to go through and find the monitors
     string_map_t entries = m_file->getEntries();
     for (string_map_t::const_iterator it = entries.begin(); it != entries.end();
@@ -1418,7 +1417,7 @@ void LoadEventNexus::loadTimeOfFlight(EventWorkspaceCollection_sptr WS,
   m_file->openPath("/");
   m_file->openGroup(entry_name, "NXentry");
 
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
   string_map_t entries = m_file->getEntries();
 
   if (entries.find("detector_1_events") == entries.end()) { // not an ISIS file
@@ -1551,7 +1550,7 @@ void LoadEventNexus::loadTimeOfFlightData(::NeXus::File &file,
   }
 
   // random number generator
-  boost::mt19937 rand_gen;
+  std::mt19937 rng;
 
   // loop over spectra
   for (size_t wi = start_wi; wi < end_wi; ++wi) {
@@ -1581,10 +1580,10 @@ void LoadEventNexus::loadTimeOfFlightData(::NeXus::File &file,
       if (m > 0) { // m events in this bin
         double left = double(tof[i - 1]);
         // spread the events uniformly inside the bin
-        boost::uniform_real<> distribution(left, right);
+        std::uniform_real_distribution<double> flat(left, right);
         std::vector<double> random_numbers(m);
         for (double &random_number : random_numbers) {
-          random_number = distribution(rand_gen);
+          random_number = flat(rng);
         }
         std::sort(random_numbers.begin(), random_numbers.end());
         auto it = random_numbers.begin();
diff --git a/Framework/DataHandling/src/LoadEventPreNexus2.cpp b/Framework/DataHandling/src/LoadEventPreNexus2.cpp
index 8d0b1a657eb365a7c6f970ce9bfa729a04970504..c7fdace12dd00b1f5c3592ae99980093aa617d87 100644
--- a/Framework/DataHandling/src/LoadEventPreNexus2.cpp
+++ b/Framework/DataHandling/src/LoadEventPreNexus2.cpp
@@ -744,7 +744,7 @@ void LoadEventPreNexus2::procEvents(
   std::vector<DasEvent *> buffers;
 
   /// Pointer to the vector of events
-  typedef std::vector<TofEvent> *EventVector_pt;
+  using EventVector_pt = std::vector<TofEvent> *;
   /// Bare array of arrays of pointers to the EventVectors
   EventVector_pt **eventVectors;
 
diff --git a/Framework/DataHandling/src/LoadIDFFromNexus.cpp b/Framework/DataHandling/src/LoadIDFFromNexus.cpp
index 55d92fbeb0f5431d720002820f3c1bd67ed08449..2b8a372117956eefd7061efc6fa5777d6770f1c7 100644
--- a/Framework/DataHandling/src/LoadIDFFromNexus.cpp
+++ b/Framework/DataHandling/src/LoadIDFFromNexus.cpp
@@ -26,7 +26,6 @@ DECLARE_ALGORITHM(LoadIDFFromNexus)
 
 using namespace Kernel;
 using namespace API;
-using Geometry::Instrument;
 using Types::Core::DateAndTime;
 
 /// Empty default constructor
diff --git a/Framework/DataHandling/src/LoadILLDiffraction.cpp b/Framework/DataHandling/src/LoadILLDiffraction.cpp
index 0921cf4c7f71484e52fc822a4bdba99eee163e34..181ef561a500f05cfd95882da5f6b995df8b901d 100644
--- a/Framework/DataHandling/src/LoadILLDiffraction.cpp
+++ b/Framework/DataHandling/src/LoadILLDiffraction.cpp
@@ -752,6 +752,8 @@ void LoadILLDiffraction::setSampleLogs() {
   double lambda = run.getLogAsSingleValue("wavelength");
   double eFixed = WAVE_TO_E / (lambda * lambda);
   run.addLogData(new PropertyWithValue<double>("Ei", eFixed));
+  run.addLogData(new PropertyWithValue<size_t>("NumberOfDetectors",
+                                               m_numberDetectorsActual));
 }
 
 /**
diff --git a/Framework/DataHandling/src/LoadISISNexus2.cpp b/Framework/DataHandling/src/LoadISISNexus2.cpp
index 9f3a54baf0b857cd1f84b789cc2f9cfc01f5e0eb..8aabbd7aa3d6a7db48befe92a26cd1b47ad1ebb4 100644
--- a/Framework/DataHandling/src/LoadISISNexus2.cpp
+++ b/Framework/DataHandling/src/LoadISISNexus2.cpp
@@ -1090,8 +1090,8 @@ void LoadISISNexus2::parseISODateTime(const std::string &datetime_iso,
     time = Poco::DateTimeFormatter::format(datetime_output, "%H:%M:%S",
                                            timezone_diff);
   } catch (Poco::SyntaxException &) {
-    date = "\?\?-\?\?-\?\?\?\?";
-    time = "\?\?:\?\?:\?\?";
+    date = R"(??-??-????)";
+    time = R"(??:??:??)";
     g_log.warning() << "Cannot parse end time from entry in Nexus file.\n";
   }
 }
diff --git a/Framework/DataHandling/src/LoadMask.cpp b/Framework/DataHandling/src/LoadMask.cpp
index ebf95f91f864cee6eb6179d1bb459b8540402b7b..10661889d027f597427d6020d5c0f2dfc6afa5a4 100644
--- a/Framework/DataHandling/src/LoadMask.cpp
+++ b/Framework/DataHandling/src/LoadMask.cpp
@@ -531,9 +531,7 @@ void LoadMask::processMaskOnWorkspaceIndex(bool mask,
   // 3. Set mask
   auto spec0 = maskedSpecID[0];
   auto prev_masks = spec0;
-  for (size_t i = 0; i < maskedSpecID.size(); i++) {
-
-    auto spec2mask = maskedSpecID[i];
+  for (int spec2mask : maskedSpecID) {
 
     s2iter = s2imap.find(spec2mask);
     if (s2iter == s2imap.end()) {
@@ -703,19 +701,18 @@ void LoadMask::convertSpMasksToDetIDs(const API::MatrixWorkspace &sourceWS,
       sourceWS.getDetectorIDToWorkspaceIndexMap(false);
 
   std::multimap<size_t, Mantid::detid_t> spectr2index_map;
-  for (auto it = sourceDetMap.begin(); it != sourceDetMap.end(); it++) {
+  for (auto &it : sourceDetMap) {
     spectr2index_map.insert(
-        std::pair<size_t, Mantid::detid_t>(it->second, it->first));
+        std::pair<size_t, Mantid::detid_t>(it.second, it.first));
   }
   spec2index_map new_map;
-  for (size_t i = 0; i < maskedSpecID.size(); i++) {
+  for (int i : maskedSpecID) {
     // find spectra number from spectra ID for the source workspace
-    const auto itSpec = s2imap.find(maskedSpecID[i]);
+    const auto itSpec = s2imap.find(i);
     if (itSpec == s2imap.end()) {
-      throw std::runtime_error(
-          "Can not find spectra with ID: " +
-          boost::lexical_cast<std::string>(maskedSpecID[i]) +
-          " in the workspace" + sourceWS.getName());
+      throw std::runtime_error("Can not find spectra with ID: " +
+                               boost::lexical_cast<std::string>(i) +
+                               " in the workspace" + sourceWS.getName());
     }
     size_t specN = itSpec->second;
 
diff --git a/Framework/DataHandling/src/LoadNXSPE.cpp b/Framework/DataHandling/src/LoadNXSPE.cpp
index 5379e7ac00e67f6d81c52033a824bb8ba7e5e322..0186d41d008d47fbd601d635bde998e914cac3c7 100644
--- a/Framework/DataHandling/src/LoadNXSPE.cpp
+++ b/Framework/DataHandling/src/LoadNXSPE.cpp
@@ -65,7 +65,7 @@ int LoadNXSPE::identiferConfidence(const std::string &value) {
  */
 int LoadNXSPE::confidence(Kernel::NexusDescriptor &descriptor) const {
   int confidence(0);
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
   try {
     ::NeXus::File file = ::NeXus::File(descriptor.filename());
     string_map_t entries = file.getEntries();
diff --git a/Framework/DataHandling/src/LoadNexusMonitors2.cpp b/Framework/DataHandling/src/LoadNexusMonitors2.cpp
index 790af0f22d51fc32a7cab37b808772a92daa890e..4a899cf5d9dd1c397f36c33389d2463a75b66e99 100644
--- a/Framework/DataHandling/src/LoadNexusMonitors2.cpp
+++ b/Framework/DataHandling/src/LoadNexusMonitors2.cpp
@@ -128,7 +128,7 @@ void LoadNexusMonitors2::exec() {
   ::NeXus::File file(m_filename);
 
   // Start with the base entry
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
   string_map_t::const_iterator it;
   string_map_t entries = file.getEntries();
   for (it = entries.begin(); it != entries.end(); ++it) {
@@ -588,7 +588,7 @@ size_t LoadNexusMonitors2::getMonitorInfo(
     size_t &numHistMon, size_t &numEventMon, size_t &numPeriods,
     std::map<int, std::string> &monitorNumber2Name,
     std::vector<bool> &isEventMonitors) {
-  typedef std::map<std::string, std::string> string_map_t;
+  using string_map_t = std::map<std::string, std::string>;
 
   // Now we want to go through and find the monitors
   string_map_t entries = file.getEntries();
diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp
index 2d3c2bb55a22ad5b2be5b911593ba5c0e74c057b..a8c1164f786fe10729801171bcbbb256a605b3e1 100644
--- a/Framework/DataHandling/src/LoadNexusProcessed.cpp
+++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp
@@ -55,7 +55,7 @@ using Mantid::Types::Event::TofEvent;
 namespace {
 
 // Helper typedef
-typedef boost::shared_array<int> IntArray_shared;
+using IntArray_shared = boost::shared_array<int>;
 
 // Struct to contain spectrum information.
 struct SpectraInfo {
@@ -83,7 +83,7 @@ struct SpectraInfo {
 };
 
 // Helper typdef.
-typedef boost::optional<SpectraInfo> SpectraInfo_optional;
+using SpectraInfo_optional = boost::optional<SpectraInfo>;
 
 /**
 * Extract ALL the detector, spectrum number and workspace index mapping
@@ -1155,6 +1155,14 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
         if (ival != -1)
           peakWS->getPeak(r).setRunNumber(ival);
       }
+    } else if (str == "column_17") {
+      NXInt nxInt = nx_tw.openNXInt(str);
+      nxInt.load();
+
+      for (int r = 0; r < numberPeaks; r++) {
+        int ival = nxInt[r];
+        peakWS->getPeak(r).setPeakNumber(ival);
+      }
     } else if (str == "column_15") {
       NXDouble nxDouble = nx_tw.openNXDouble(str);
       nxDouble.load();
diff --git a/Framework/DataHandling/src/LoadRKH.cpp b/Framework/DataHandling/src/LoadRKH.cpp
index 870343459d7e0438484e9418e371ae8151247673..8a235dfba8bfb4fc4dbe8ac595fcf4d221752de5 100644
--- a/Framework/DataHandling/src/LoadRKH.cpp
+++ b/Framework/DataHandling/src/LoadRKH.cpp
@@ -34,7 +34,7 @@ bool isUnit(const Mantid::Kernel::StringTokenizer &codes) {
   //  5. Close bracket
   std::string input =
       std::accumulate(codes.begin(), codes.end(), std::string(""));
-  std::string reg("^[06][\\w]+\\([/ \\w\\^-]+\\)$");
+  std::string reg(R"(^[06][\w]+\([/ \w\^-]+\)$)");
   boost::regex baseRegex(reg);
   return boost::regex_match(input, baseRegex);
 }
diff --git a/Framework/DataHandling/src/LoadRaw/item_struct.h b/Framework/DataHandling/src/LoadRaw/item_struct.h
index a14028aa556e5e6d43f9841bc85a8d45263ae4dd..aa5ec35f37fe7e7830cddfb2b3d2ba6828c68690 100644
--- a/Framework/DataHandling/src/LoadRaw/item_struct.h
+++ b/Framework/DataHandling/src/LoadRaw/item_struct.h
@@ -23,9 +23,9 @@ public:
   item_struct() : m_items(), m_spec_array(nullptr), m_ndet(0){};
 
 private:
-  typedef std::map<std::string, item_t>
-      items_map_t;             ///<Type def of internal map of named items
-  items_map_t m_items;         ///<internal map of named items
+  using items_map_t =
+      std::map<std::string, item_t>; ///<Type def of internal map of named items
+  items_map_t m_items;               ///<internal map of named items
   unsigned long *m_spec_array; ///< length m_ndet; used for averaging values
   /// with det_average
   long m_ndet; ///<number of detectors
diff --git a/Framework/DataHandling/src/LoadRaw/vms_convert.h b/Framework/DataHandling/src/LoadRaw/vms_convert.h
index eb072664c1549e392a5560f51a24b926120f8679..01ac7726a07cee4eeb2e3336f2641564bf9bcd3b 100644
--- a/Framework/DataHandling/src/LoadRaw/vms_convert.h
+++ b/Framework/DataHandling/src/LoadRaw/vms_convert.h
@@ -9,7 +9,7 @@
 #pragma warning(disable : 4100)
 #endif
 
-typedef int fort_int;
+using fort_int = int;
 
 unsigned short local_to_vax_short(const unsigned short *s);
 unsigned short vax_to_local_short(const unsigned short *s);
diff --git a/Framework/DataHandling/src/LoadSESANS.cpp b/Framework/DataHandling/src/LoadSESANS.cpp
index 05a9716452739d44c41e62d4d6739ae70bb59bc2..3c1927e527546c752fdca5e9de3502f23e9e345f 100644
--- a/Framework/DataHandling/src/LoadSESANS.cpp
+++ b/Framework/DataHandling/src/LoadSESANS.cpp
@@ -103,7 +103,7 @@ int LoadSESANS::confidence(Kernel::FileDescriptor &descriptor) const {
   bool ffvFound = boost::starts_with(line, "FileFormatVersion");
 
   // Next few lines should be key-value pairs
-  boost::regex kvPair("[\\w_]+\\s+[\\w\\d\\.\\-]+(\\s+[\\w\\d\\.\\-\\$]+)*");
+  boost::regex kvPair(R"([\w_]+\s+[\w\d\.\-]+(\s+[\w\d\.\-\$]+)*)");
   int kvPairsFound = 0;
 
   for (int i = 0; i < 3 && !line.empty(); i++) {
@@ -246,7 +246,7 @@ ColumnMap LoadSESANS::consumeData(std::ifstream &infile, std::string &line,
                                  header + "\"",
                        lineNum);
 
-  std::string numberRegex = "(-?\\d+(\\.\\d+)?([Ee][-\\+]?\\d+)?)";
+  std::string numberRegex = R"((-?\d+(\.\d+)?([Ee][-\+]?\d+)?))";
   // static_cast is safe as realistically our file is never going to have enough
   // columns to overflow
   std::string rawRegex = "^\\s*" +
diff --git a/Framework/DataHandling/src/LoadSNSspec.cpp b/Framework/DataHandling/src/LoadSNSspec.cpp
index 77e13b54b1023f8dcad3e31e831daee3db5871c7..af64f65a1a2242c3adab5e07ec5f575143670ca8 100644
--- a/Framework/DataHandling/src/LoadSNSspec.cpp
+++ b/Framework/DataHandling/src/LoadSNSspec.cpp
@@ -33,7 +33,7 @@ int LoadSNSspec::confidence(Kernel::FileDescriptor &descriptor) const {
   int confidence(0);
   size_t axiscols(0), datacols(0);
   std::string str;
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   const std::string sep = " ";
   bool snsspec(false);
 
diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp
index ba2054ea9fd5b72345ba5ad38a7d7abaf6aa8ebc..4573e1d8956b730eb3519e66aa3f7a1ba7e56b7f 100644
--- a/Framework/DataHandling/src/LoadSassena.cpp
+++ b/Framework/DataHandling/src/LoadSassena.cpp
@@ -88,7 +88,7 @@ herr_t LoadSassena::dataSetDouble(const hid_t &h5file,
 
 /* Helper object and function to sort modulus of Q-vectors
  */
-typedef std::pair<double, int> mypair;
+using mypair = std::pair<double, int>;
 bool compare(const mypair &left, const mypair &right) {
   return left.first < right.first;
 }
diff --git a/Framework/DataHandling/src/LoadSpec.cpp b/Framework/DataHandling/src/LoadSpec.cpp
index 540703f58b134deb8024e5f57367de63b04a26ba..b2069c5f0747422b40b2b861c055d5468e1f6a2c 100644
--- a/Framework/DataHandling/src/LoadSpec.cpp
+++ b/Framework/DataHandling/src/LoadSpec.cpp
@@ -134,7 +134,7 @@ size_t LoadSpec::readNumberOfSpectra(std::ifstream &file) const {
 void LoadSpec::readLine(const std::string &line,
                         std::vector<double> &buffer) const {
   if (!line.empty() && line[0] != '#') {
-    typedef Mantid::Kernel::StringTokenizer tokenizer;
+    using tokenizer = Mantid::Kernel::StringTokenizer;
     const std::string sep = " ";
     tokenizer tok(line, sep, Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY);
     for (const auto &beg : tok) {
diff --git a/Framework/DataHandling/src/LoadSpice2D.cpp b/Framework/DataHandling/src/LoadSpice2D.cpp
index d109f4cdc8b8600b8e85953f71b0e5f9523cd081..56fd40b1e19a4d9f5b768605f777ab3ef61b1329 100644
--- a/Framework/DataHandling/src/LoadSpice2D.cpp
+++ b/Framework/DataHandling/src/LoadSpice2D.cpp
@@ -218,7 +218,7 @@ LoadSpice2D::parseDetectorDimensions(const std::string &dims_str) {
 
   std::pair<int, int> dims = std::make_pair(0, 0);
 
-  boost::regex b_re_sig("INT\\d+\\[(\\d+),(\\d+)\\]");
+  boost::regex b_re_sig(R"(INT\d+\[(\d+),(\d+)\])");
   if (boost::regex_match(dims_str, b_re_sig)) {
     boost::match_results<std::string::const_iterator> match;
     boost::regex_search(dims_str, match, b_re_sig);
diff --git a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
index 725bcfd9be168382a783febaeccb9c2f74ebc393..31deaced9856b67e04ad103f9c55d7b65c427df3 100644
--- a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
+++ b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
@@ -669,20 +669,17 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspaceVersion2(
   }     // END-FOR (xml nodes)
 
   // Add the property to output workspace
-  for (std::map<std::string, std::string>::iterator miter = str_log_map.begin();
-       miter != str_log_map.end(); ++miter) {
+  for (auto &log_entry : str_log_map) {
     outws->mutableRun().addProperty(
-        new PropertyWithValue<std::string>(miter->first, miter->second));
+        new PropertyWithValue<std::string>(log_entry.first, log_entry.second));
   }
-  for (std::map<std::string, int>::iterator miter = int_log_map.begin();
-       miter != int_log_map.end(); ++miter) {
+  for (auto &log_entry : int_log_map) {
     outws->mutableRun().addProperty(
-        new PropertyWithValue<int>(miter->first, miter->second));
+        new PropertyWithValue<int>(log_entry.first, log_entry.second));
   }
-  for (std::map<std::string, double>::iterator miter = dbl_log_map.begin();
-       miter != dbl_log_map.end(); ++miter) {
+  for (auto &log_entry : dbl_log_map) {
     outws->mutableRun().addProperty(
-        new PropertyWithValue<double>(miter->first, miter->second));
+        new PropertyWithValue<double>(log_entry.first, log_entry.second));
   }
 
   // Raise exception if no detector node is found
@@ -713,10 +710,10 @@ LoadSpiceXML2DDet::parseDetectorNode(const std::string &detvaluestr,
   // file records data in column major)
   size_t num_empty_line = 0;
   size_t num_weird_line = 0;
-  for (size_t iline = 0; iline < vecLines.size(); ++iline) {
-    if (vecLines[iline].empty())
+  for (auto &vecLine : vecLines) {
+    if (vecLine.empty())
       ++num_empty_line;
-    else if (vecLines[iline].size() < 100)
+    else if (vecLine.size() < 100)
       ++num_weird_line;
   }
   size_t num_pixel_x = vecLines.size() - num_empty_line - num_weird_line;
diff --git a/Framework/DataHandling/src/ParallelEventLoader.cpp b/Framework/DataHandling/src/ParallelEventLoader.cpp
index 90a7522fa793413a633f828dfe2691d64958d9ef..d8c240ba4892d2967bbfcc3aff417746eb93cb06 100644
--- a/Framework/DataHandling/src/ParallelEventLoader.cpp
+++ b/Framework/DataHandling/src/ParallelEventLoader.cpp
@@ -59,11 +59,11 @@ std::vector<int32_t> bankOffsetsSpectrumNumbers(
   const auto &specNums = ws.indexInfo().spectrumNumbers();
   int32_t spectrumIndex{0}; // *global* index
   std::vector<int32_t> bankOffsets(bankNames.size(), 0);
-  for (size_t i = 0; i < specNums.size(); ++i) {
+  for (auto i : specNums) {
     // In contrast to the case of event ID = detector ID we know that any
     // spectrum number has a corresponding event ID, i.e., we do not need
     // special handling for monitors.
-    specnum_t specNum = static_cast<specnum_t>(specNums[i]);
+    specnum_t specNum = static_cast<specnum_t>(i);
     // See comment in bankOffsets regarding this offset computation.
     if (idToBank.count(specNum) == 1) {
       size_t bank = idToBank.at(specNum);
diff --git a/Framework/DataHandling/src/ProcessBankData.cpp b/Framework/DataHandling/src/ProcessBankData.cpp
index 5b93092bf1265be928b3de789fe5dd286536e513..99f74298c62939a9ddb083388346777d798a0c39 100644
--- a/Framework/DataHandling/src/ProcessBankData.cpp
+++ b/Framework/DataHandling/src/ProcessBankData.cpp
@@ -3,7 +3,6 @@
 #include "MantidDataHandling/ProcessBankData.h"
 
 using namespace Mantid::DataObjects;
-using Mantid::Types::Event::TofEvent;
 
 namespace Mantid {
 namespace DataHandling {
diff --git a/Framework/DataHandling/src/SaveAscii2.cpp b/Framework/DataHandling/src/SaveAscii2.cpp
index 55a10b34c34d516607d3aa774885395208c06c75..b8199fa5104ff46dca1ed7e160e0b218275be257 100644
--- a/Framework/DataHandling/src/SaveAscii2.cpp
+++ b/Framework/DataHandling/src/SaveAscii2.cpp
@@ -268,8 +268,8 @@ void SaveAscii2::exec() {
     }
   } else {
     Progress progress(this, 0.0, 1.0, idx.size());
-    for (auto i = idx.begin(); i != idx.end(); ++i) {
-      writeSpectrum(*i, file);
+    for (int i : idx) {
+      writeSpectrum(i, file);
       progress.report();
     }
   }
@@ -357,7 +357,7 @@ void SaveAscii2::populateQMetaData() {
         boost::shared_ptr<const Geometry::IDetector> detector(
             &spectrumInfo.detector(i), NoDeleting());
         efixed = m_ws->getEFixed(detector);
-      } catch (std::runtime_error) {
+      } catch (std::runtime_error &) {
         throw;
       }
     } else {
diff --git a/Framework/DataHandling/src/SaveCanSAS1D2.cpp b/Framework/DataHandling/src/SaveCanSAS1D2.cpp
index ac1eb4afbf971773365b82e66c9ac9fc906ad679..37afe167ba19526caeb8ea397465c528394b790e 100644
--- a/Framework/DataHandling/src/SaveCanSAS1D2.cpp
+++ b/Framework/DataHandling/src/SaveCanSAS1D2.cpp
@@ -9,6 +9,37 @@
 #include "MantidKernel/MantidVersion.h"
 #include "MantidKernel/Unit.h"
 
+namespace {
+void encode(std::string &data) {
+  std::string buffer;
+  buffer.reserve(data.size());
+
+  for (auto &element : data) {
+    switch (element) {
+    case '&':
+      buffer.append("&amp;");
+      break;
+    case '\"':
+      buffer.append("&quot;");
+      break;
+    case '\'':
+      buffer.append("&apos;");
+      break;
+    case '<':
+      buffer.append("&lt;");
+      break;
+    case '>':
+      buffer.append("&gt;");
+      break;
+    default:
+      buffer.push_back(element);
+    }
+  }
+
+  data.swap(buffer);
+}
+}
+
 using namespace Mantid::Kernel;
 using namespace Mantid::Geometry;
 using namespace Mantid::API;
@@ -134,6 +165,77 @@ void SaveCanSAS1D2::createSASRootElement(std::string &rootElem) {
               "http://www.cansas.org/formats/1.1/cansas1d.xsd\"\n\t\t>";
 }
 
+/** This method creates an XML element named "SASprocess"
+ *  @param sasProcess :: string for sasprocess element in the xml
+ */
+void SaveCanSAS1D2::createSASProcessElement(std::string &sasProcess) {
+  sasProcess = "\n\t\t<SASprocess>";
+  // outFile<<sasProcess;
+
+  std::string sasProcname = "\n\t\t\t<name>";
+  sasProcname += "Mantid generated CanSAS1D XML";
+  sasProcname += "</name>";
+  sasProcess += sasProcname;
+
+  time_t rawtime;
+  time(&rawtime);
+
+  char temp[25];
+  strftime(temp, 25, "%d-%b-%Y %H:%M:%S", localtime(&rawtime));
+  std::string sasDate(temp);
+
+  std::string sasProcdate = "\n\t\t\t<date>";
+  sasProcdate += sasDate;
+  sasProcdate += "</date>";
+  sasProcess += sasProcdate;
+
+  std::string sasProcsvn = "\n\t\t\t<term name=\"svn\">";
+  sasProcsvn += MantidVersion::version();
+  sasProcsvn += "</term>";
+  sasProcess += sasProcsvn;
+
+  const API::Run &run = m_workspace->run();
+  std::string user_file;
+  if (run.hasProperty("UserFile")) {
+    user_file = run.getLogData("UserFile")->value();
+  }
+
+  std::string sasProcuserfile = "\n\t\t\t<term name=\"user_file\">";
+  sasProcuserfile += user_file;
+  sasProcuserfile += "</term>";
+  // outFile<<sasProcuserfile;
+  sasProcess += sasProcuserfile;
+
+  // can run number if available
+  if (m_transcan_ws) {
+    if (m_transcan_ws->run().hasProperty("run_number")) {
+      Kernel::Property *logP = m_transcan_ws->run().getLogData("run_number");
+      auto can_run = logP->value();
+      std::string sasProcCanRun = "\n\t\t\t<term name=\"can_trans_run\">";
+      sasProcCanRun += can_run;
+      sasProcCanRun += "</term>";
+      sasProcess += sasProcCanRun;
+    } else {
+      g_log.debug() << "Didn't find RunNumber log in workspace. Writing "
+                       "<Run></Run> to the CANSAS file\n";
+    }
+  }
+
+  // Reduction process note, if available
+  std::string process_xml = getProperty("Process");
+  if (!process_xml.empty()) {
+    std::string processNote = "\n\t\t\t<SASprocessnote>";
+    encode(process_xml);
+    processNote += process_xml;
+    processNote += "</SASprocessnote>";
+    sasProcess += processNote;
+  } else {
+    sasProcess += "\n\t\t\t<SASprocessnote/>";
+  }
+
+  sasProcess += "\n\t\t</SASprocess>";
+}
+
 /** This method creates an XML element named "SAStransmission_spectrum"
  *  @param sasTrans :: string for sasdata element in the xml
  * @param name :: name of the type of spectrum. Two values are acceptable:
diff --git a/Framework/DataHandling/src/SaveFocusedXYE.cpp b/Framework/DataHandling/src/SaveFocusedXYE.cpp
index cd63e3462396de38db1139e1b49ce61caa6cfc5a..2483b0f9725ca409dd2eb221d344f1bc1321e71b 100644
--- a/Framework/DataHandling/src/SaveFocusedXYE.cpp
+++ b/Framework/DataHandling/src/SaveFocusedXYE.cpp
@@ -236,7 +236,8 @@ void SaveFocusedXYE::writeHeaders(
 void SaveFocusedXYE::writeXYEHeaders(
     std::ostream &os,
     Mantid::API::MatrixWorkspace_const_sptr &workspace) const {
-  os << "XYDATA\n";
+  if (m_headerType != TOPAS)
+    os << "XYDATA\n";
   os << m_comment << " File generated by Mantid, "
      << "Instrument " << workspace->getInstrument()->getName() << '\n';
   os << m_comment
diff --git a/Framework/DataHandling/src/SaveFullprofResolution.cpp b/Framework/DataHandling/src/SaveFullprofResolution.cpp
index 0e508d349dcd80f9910cd4bd3486162629a7ee36..550e2701c5c2b5e0903c31991e0804fe27318c8d 100644
--- a/Framework/DataHandling/src/SaveFullprofResolution.cpp
+++ b/Framework/DataHandling/src/SaveFullprofResolution.cpp
@@ -5,8 +5,9 @@
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/BoundedValidator.h"
 
-#include <boost/algorithm/string.hpp>
-#include <Poco/File.h>
+#include "Poco/File.h"
+#include "boost/algorithm/string.hpp"
+#include "boost/math/special_functions/round.hpp"
 
 #include <fstream>
 #include <iomanip>
@@ -192,8 +193,8 @@ void SaveFullprofResolution::parseTableWorkspace() {
     // and BANK matches
     for (size_t i = 1; i < numcols; ++i) {
       if (boost::starts_with(colnames[i], "Value")) {
-        int bankid = static_cast<int>(
-            m_profileTableWS->cell<double>(rowbankindex, i) + 0.5);
+        int bankid = boost::math::iround(
+            m_profileTableWS->cell<double>(rowbankindex, i));
         if (bankid == m_bankID) {
           colindex = static_cast<int>(i);
           break;
diff --git a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
index 84d34e586b1ea21e7adef64aef2d65f6baa5d54a..a33d67c68be5584bf15d57096d663d13bfc5d5b4 100644
--- a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
+++ b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
@@ -67,7 +67,7 @@ private:
   std::vector<int> m_vruns;
 };
 
-typedef boost::shared_ptr<ChopperConfiguration> ChopperConfiguration_sptr;
+using ChopperConfiguration_sptr = boost::shared_ptr<ChopperConfiguration>;
 
 //----------------------------------------------------------------------------------------------
 /** Constructor
diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp
index d9873b66173b423484db55bc7200f53b19edc84e..dd1410209b8a4d931b552b8c9dedadc12d5bf03b 100644
--- a/Framework/DataHandling/src/SaveGSS.cpp
+++ b/Framework/DataHandling/src/SaveGSS.cpp
@@ -442,9 +442,8 @@ void SaveGSS::generateInstrumentHeader(std::stringstream &out,
 
   // write user header first
   if (m_user_specified_gsas_header.size() > 0) {
-    for (auto iter = m_user_specified_gsas_header.begin();
-         iter != m_user_specified_gsas_header.end(); ++iter) {
-      out << *iter << "\n";
+    for (const auto &iter : m_user_specified_gsas_header) {
+      out << iter << "\n";
     }
   }
 
diff --git a/Framework/DataHandling/src/SaveNXSPE.cpp b/Framework/DataHandling/src/SaveNXSPE.cpp
index b76d875c1362a7c0ea925775284ac32bf8b8c835..ae857d46c99b9deac858de68e5d1ba0bec54bef2 100644
--- a/Framework/DataHandling/src/SaveNXSPE.cpp
+++ b/Framework/DataHandling/src/SaveNXSPE.cpp
@@ -194,7 +194,7 @@ void SaveNXSPE::exec() {
   nxFile.closeData();
 
   // let's create some blank arrays in the nexus file
-  typedef std::vector<int64_t> Dimensions;
+  using Dimensions = std::vector<int64_t>;
   Dimensions arrayDims(2);
   arrayDims[0] = nHist;
   arrayDims[1] = nBins;
@@ -221,7 +221,7 @@ void SaveNXSPE::exec() {
   slabSize[1] = nBins;
 
   // Allocate the temporary buffers for the signal and errors
-  typedef boost::scoped_array<double> Buffer;
+  using Buffer = boost::scoped_array<double>;
   const size_t bufferSize(slabSize[0] * slabSize[1]);
   Buffer signalBuffer(new double[bufferSize]);
   Buffer errorBuffer(new double[bufferSize]);
diff --git a/Framework/DataHandling/src/SaveNXcanSAS.cpp b/Framework/DataHandling/src/SaveNXcanSAS.cpp
index 9e24e515ac84ffd2c784ee45fa937edf15891cab..cc5e6b95341f8820e1c14f4783726f35751db2d9 100644
--- a/Framework/DataHandling/src/SaveNXcanSAS.cpp
+++ b/Framework/DataHandling/src/SaveNXcanSAS.cpp
@@ -321,6 +321,45 @@ void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace) {
   }
 }
 
+/**
+ * Add the process information to the NXcanSAS file. This information
+ * about the run number, the Mantid version and the user file (if available)
+ * @param group: the sasEntry
+ * @param workspace: the workspace which is being stored
+ */
+void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace,
+                Mantid::API::MatrixWorkspace_sptr canWorkspace) {
+  // Setup process
+  const std::string sasProcessNameForGroup = sasProcessGroupName;
+  auto process = Mantid::DataHandling::H5Util::createGroupCanSAS(
+      group, sasProcessNameForGroup, nxProcessClassAttr, sasProcessClassAttr);
+
+  // Add name
+  Mantid::DataHandling::H5Util::write(process, sasProcessName,
+                                      sasProcessNameValue);
+
+  // Add creation date of the file
+  auto date = getDate();
+  Mantid::DataHandling::H5Util::write(process, sasProcessDate, date);
+
+  // Add Mantid version
+  const auto version = std::string(MantidVersion::version());
+  Mantid::DataHandling::H5Util::write(process, sasProcessTermSvn, version);
+
+  const auto run = workspace->run();
+  if (run.hasProperty(sasProcessUserFileInLogs)) {
+    auto userFileProperty = run.getProperty(sasProcessUserFileInLogs);
+    auto userFileString = userFileProperty->value();
+    Mantid::DataHandling::H5Util::write(process, sasProcessTermUserFile,
+                                        userFileString);
+  }
+
+  // Add can run number
+  const auto canRun = canWorkspace->getRunNumber();
+  Mantid::DataHandling::H5Util::write(process, sasProcessTermCan,
+                                      std::to_string(canRun));
+}
+
 WorkspaceDimensionality
 getWorkspaceDimensionality(Mantid::API::MatrixWorkspace_sptr workspace) {
   auto numberOfHistograms = workspace->getNumberHistograms();
@@ -814,7 +853,11 @@ void SaveNXcanSAS::exec() {
 
   // Add the process information
   progress.report("Adding process information.");
-  addProcess(sasEntry, workspace);
+  if (transmissionCan) {
+    addProcess(sasEntry, workspace, transmissionCan);
+  } else {
+    addProcess(sasEntry, workspace);
+  }
 
   // Add the transmissions for sample
   if (transmissionSample) {
diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp
index 0cb8b34a0a9e8b393f121771b18e2680ed174698..3d7910b3fd381c8901d114c56d3602fcfa163eb7 100644
--- a/Framework/DataHandling/src/SaveNexusProcessed.cpp
+++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp
@@ -28,7 +28,7 @@ using namespace API;
 using namespace DataObjects;
 using Geometry::Instrument_const_sptr;
 
-typedef NeXus::NexusFileIO::optional_size_t optional_size_t;
+using optional_size_t = NeXus::NexusFileIO::optional_size_t;
 
 // Register the algorithm into the algorithm factory
 DECLARE_ALGORITHM(SaveNexusProcessed)
diff --git a/Framework/DataHandling/src/SetSample.cpp b/Framework/DataHandling/src/SetSample.cpp
index ac802e9549bee96e5d6e400d2a6aedaebf340527..1516b5b66dd604586644c00e1c08a8139b411ec3 100644
--- a/Framework/DataHandling/src/SetSample.cpp
+++ b/Framework/DataHandling/src/SetSample.cpp
@@ -111,11 +111,11 @@ V3D cylBaseCentre(const std::vector<double> &cylCentre, double height,
 std::string axisXML(unsigned axisIdx) {
   switch (axisIdx) {
   case 0:
-    return "<axis x=\"1\" y=\"0\" z=\"0\" />";
+    return R"(<axis x="1" y="0" z="0" />)";
   case 1:
-    return "<axis x=\"0\" y=\"1\" z=\"0\" />";
+    return R"(<axis x="0" y="1" z="0" />)";
   case 2:
-    return "<axis x=\"0\" y=\"0\" z=\"1\" />";
+    return R"(<axis x="0" y="0" z="1" />)";
   default:
     return "";
   }
diff --git a/Framework/DataHandling/test/FindDetectorsInShapeTest.h b/Framework/DataHandling/test/FindDetectorsInShapeTest.h
index e8918c444a31b6449c5ef0624586a2379ae6f508..9334ce32b75d1488a36e4a688b5a657e4a6ba105 100644
--- a/Framework/DataHandling/test/FindDetectorsInShapeTest.h
+++ b/Framework/DataHandling/test/FindDetectorsInShapeTest.h
@@ -22,13 +22,13 @@ public:
 
   void testCuboidMiss() {
     std::string xmlShape = "<cuboid id=\"shape\"> ";
-    xmlShape += "<left-front-bottom-point x=\"0.005\" y=\"-0.1\" z=\"0.0\" /> ";
+    xmlShape += R"(<left-front-bottom-point x="0.005" y="-0.1" z="0.0" /> )";
     xmlShape +=
-        "<left-front-top-point x=\"0.005\" y=\"-0.1\" z=\"0.0001\" />  ";
+        R"(<left-front-top-point x="0.005" y="-0.1" z="0.0001" />  )";
     xmlShape +=
-        "<left-back-bottom-point x=\"-0.005\" y=\"-0.1\" z=\"0.0\" />  ";
+        R"(<left-back-bottom-point x="-0.005" y="-0.1" z="0.0" />  )";
     xmlShape +=
-        "<right-front-bottom-point x=\"0.005\" y=\"0.1\" z=\"0.0\" />  ";
+        R"(<right-front-bottom-point x="0.005" y="0.1" z="0.0" />  )";
     xmlShape += "</cuboid> ";
     xmlShape += "<algebra val=\"shape\" /> ";
 
@@ -55,7 +55,7 @@ public:
   void testSphereMiss() {
     // algebra line is essential
     std::string xmlShape = "<sphere id=\"shape\"> ";
-    xmlShape += "<centre x=\"4.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="4.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -66,7 +66,7 @@ public:
   void testSphereHit() {
     // algebra line is essential
     std::string xmlShape = "<sphere id=\"shape\"> ";
-    xmlShape += "<centre x=\"0.67\"  y=\"0.33\" z=\"1.32\" /> ";
+    xmlShape += R"(<centre x="0.67"  y="0.33" z="1.32" /> )";
     xmlShape += "<radius val=\"0.05\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -77,8 +77,8 @@ public:
   void testCylinderHit() {
     // algebra line is essential
     std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "<height val=\"3\" /> ";
     xmlShape += "</cylinder>";
@@ -90,8 +90,8 @@ public:
   void testInfiniteCylinderHit() {
     // algebra line is essential
     std::string xmlShape = "<infinite-cylinder id=\"shape\"> ";
-    xmlShape += "<centre x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "</infinite-cylinder>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -102,8 +102,8 @@ public:
   void testConeHitNoMonitors() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"-1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="-1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height val=\"4\" /> ";
     xmlShape += "</cone>";
diff --git a/Framework/DataHandling/test/FindDetectorsParTest.h b/Framework/DataHandling/test/FindDetectorsParTest.h
index a55f1b77af5f5109c689be4c7cd7aa3d5d59943a..5d9785001adf4d766333e00ddf5ef9307c461f33 100644
--- a/Framework/DataHandling/test/FindDetectorsParTest.h
+++ b/Framework/DataHandling/test/FindDetectorsParTest.h
@@ -490,8 +490,8 @@ private:
     cont[2] = " 2.     3.   -4.     5.     6.     2";
 
     std::ofstream testFile(fileName);
-    for (size_t i = 0; i < cont.size(); i++) {
-      testFile << cont[i] << '\n';
+    for (const auto &i : cont) {
+      testFile << i << '\n';
     }
     testFile.close();
   }
@@ -503,8 +503,8 @@ private:
     cont[3] = "3.     4.   -5.     6.     7.     3";
 
     std::ofstream testFile(fileName);
-    for (size_t i = 0; i < cont.size(); i++) {
-      testFile << cont[i] << '\n';
+    for (const auto &i : cont) {
+      testFile << i << '\n';
     }
     testFile.close();
   }
@@ -516,8 +516,8 @@ private:
     cont[3] = "10         0     5.000     6.000    7.000    8.0000     3";
 
     std::ofstream testFile(fileName);
-    for (size_t i = 0; i < cont.size(); i++) {
-      testFile << cont[i] << '\n';
+    for (const auto &i : cont) {
+      testFile << i << '\n';
     }
     testFile.close();
   }
@@ -527,8 +527,8 @@ private:
     cont[1] = "10         0     5.000     6.000    7.000    8.0000     1";
 
     std::ofstream testFile(fileName);
-    for (size_t i = 0; i < cont.size(); i++) {
-      testFile << cont[i] << '\n';
+    for (const auto &i : cont) {
+      testFile << i << '\n';
     }
     testFile.close();
   }
diff --git a/Framework/DataHandling/test/GroupDetectors2Test.h b/Framework/DataHandling/test/GroupDetectors2Test.h
index fba67e3bd29e3359be3a0fa5fa696958cff92384..e79ab05dd0d6ca536d31958d8eca481be80965a0 100644
--- a/Framework/DataHandling/test/GroupDetectors2Test.h
+++ b/Framework/DataHandling/test/GroupDetectors2Test.h
@@ -2,18 +2,22 @@
 #define GROUPDETECTORS2TEST_H_
 
 #include "MantidDataHandling/GroupDetectors2.h"
+#include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
-#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/SpectraAxis.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidDataHandling/LoadMuonNexus1.h"
 #include "MantidDataHandling/MaskDetectors.h"
 #include "MantidDataObjects/ScanningWorkspaceBuilder.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidKernel/DateAndTime.h"
@@ -54,13 +58,9 @@ public:
     // This is needed to load in the plugin algorithms (specifically Divide,
     // which is a Child Algorithm of GroupDetectors)
     FrameworkManager::Instance();
-    createTestWorkspace(inputWSName, 0);
-    createTestWorkspace(offsetWSName, 1);
   }
 
-  ~GroupDetectors2Test() override {
-    AnalysisDataService::Instance().remove(inputWSName);
-  }
+  void tearDown() override { AnalysisDataService::Instance().clear(); }
 
   void testSetup() {
     GroupDetectors2 gd;
@@ -68,13 +68,11 @@ public:
     TS_ASSERT_EQUALS(gd.version(), 2);
     TS_ASSERT_THROWS_NOTHING(gd.initialize());
     TS_ASSERT(gd.isInitialized());
-
+    createTestWorkspace(inputWSName, 0);
     gd.setPropertyValue("InputWorkspace", inputWSName);
     gd.setPropertyValue("OutputWorkspace", outputWSNameBase);
     TS_ASSERT_THROWS_NOTHING(gd.execute());
     TS_ASSERT(!gd.isExecuted());
-
-    AnalysisDataService::Instance().remove(outputWSNameBase);
   }
 
   void testAveragingWithNoInstrument() {
@@ -99,6 +97,7 @@ public:
   void testSpectraList() {
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper3.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "Specs");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -124,12 +123,12 @@ public:
     TS_ASSERT(spectrumInfo.hasDetectors(0));
     TS_ASSERT(!spectrumInfo.hasUniqueDetector(0));
     TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
-    AnalysisDataService::Instance().remove(output);
   }
 
   void testIndexList() {
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper3.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "Indices");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -148,7 +147,6 @@ public:
             AnalysisDataService::Instance().retrieve(output));
     TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
     HistogramX tens{10, 11, 12, 13, 14};
-    std::vector<double> ones(NBINS, 1.0);
     TS_ASSERT_EQUALS(outputWS->x(0), tens);
     TS_ASSERT_EQUALS(outputWS->y(0), HistogramY(NBINS, (3 + 4 + 5 + 6)));
     for (int i = 0; i < NBINS; ++i) {
@@ -158,12 +156,12 @@ public:
     const auto &spectrumInfo = outputWS->spectrumInfo();
     TS_ASSERT(spectrumInfo.hasDetectors(0));
     TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
-    AnalysisDataService::Instance().remove(output);
   }
 
   void testGroupingPattern() {
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper3.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "Indices");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -199,6 +197,7 @@ public:
     // Check that the algorithm still works if spectrum numbers are not 1-based
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(offsetWSName, 1);
     grouper3.setPropertyValue("InputWorkspace", offsetWSName);
     std::string output(outputWSNameBase + "Indices");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -217,7 +216,6 @@ public:
             AnalysisDataService::Instance().retrieve(output));
     TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
     HistogramX tens{10, 11, 12, 13, 14};
-    std::vector<double> ones(NBINS, 1.0);
     TS_ASSERT_EQUALS(outputWS->x(0), tens);
     TS_ASSERT_EQUALS(outputWS->y(0), HistogramY(NBINS, (3 + 4 + 5 + 6)));
     for (int i = 0; i < NBINS; ++i) {
@@ -227,13 +225,13 @@ public:
     const auto &spectrumInfo = outputWS->spectrumInfo();
     TS_ASSERT(spectrumInfo.hasDetectors(0));
     TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
-    AnalysisDataService::Instance().remove(output);
   }
 
   void testGroupingPatternOffsetSpectra() {
     // Check that the algorithm still works if spectrum numbers are not 1-based
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(offsetWSName, 1);
     grouper3.setPropertyValue("InputWorkspace", offsetWSName);
     std::string output(outputWSNameBase + "Indices");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -252,7 +250,6 @@ public:
             AnalysisDataService::Instance().retrieve(output));
     TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
     HistogramX tens{10, 11, 12, 13, 14};
-    std::vector<double> ones(NBINS, 1.0);
     TS_ASSERT_EQUALS(outputWS->x(0), tens);
     TS_ASSERT_EQUALS(outputWS->y(0), HistogramY(NBINS, (3 + 4 + 5 + 6)));
     for (int i = 0; i < NBINS; ++i) {
@@ -262,12 +259,12 @@ public:
     const auto &spectrumInfo = outputWS->spectrumInfo();
     TS_ASSERT(spectrumInfo.hasDetectors(0));
     TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
-    AnalysisDataService::Instance().remove(output);
   }
 
   void testDetectorList() {
     GroupDetectors2 grouper3;
     grouper3.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper3.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "Detects");
     grouper3.setPropertyValue("OutputWorkspace", output);
@@ -282,7 +279,6 @@ public:
             AnalysisDataService::Instance().retrieve(output));
     TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
     HistogramX tens{10, 11, 12, 13, 14};
-    std::vector<double> ones(NBINS, 1.0);
     TS_ASSERT_EQUALS(outputWS->x(0), tens);
     TS_ASSERT_EQUALS(outputWS->y(0),
                      HistogramY(NBINS, (3 + 1) + (1 + 1) + (4 + 1) + (0 + 1) +
@@ -295,8 +291,6 @@ public:
     const auto &spectrumInfo = outputWS->spectrumInfo();
     TS_ASSERT(spectrumInfo.hasDetectors(0));
     TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
-
-    AnalysisDataService::Instance().remove(output);
   }
 
   void testFileList() {
@@ -305,6 +299,7 @@ public:
 
     GroupDetectors2 grouper;
     grouper.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "File");
     grouper.setPropertyValue("OutputWorkspace", output);
@@ -369,7 +364,6 @@ public:
     TS_ASSERT(spectrumInfo.hasDetectors(4));
     TS_ASSERT(spectrumInfo.hasUniqueDetector(4));
 
-    AnalysisDataService::Instance().remove(output);
     remove(inputFile.c_str());
   }
 
@@ -379,6 +373,7 @@ public:
 
     GroupDetectors2 grouper;
     grouper.initialize();
+    createTestWorkspace(inputWSName, 0);
     grouper.setPropertyValue("InputWorkspace", inputWSName);
     std::string output(outputWSNameBase + "File");
     grouper.setPropertyValue("OutputWorkspace", output);
@@ -420,8 +415,6 @@ public:
     }
     TS_ASSERT_EQUALS(outputWS->getAxis(1)->spectraNo(2), 3);
     TS_ASSERT_EQUALS(outputWS->getSpectrum(2).getSpectrumNo(), 3);
-
-    AnalysisDataService::Instance().remove(output);
     remove(inputFile.c_str());
   }
 
@@ -470,7 +463,7 @@ public:
     AnalysisDataService::Instance().remove("boevs");
   }
 
-  void testReadingFromXMLCheckDublicateIndex() {
+  void testReadingFromXMLCheckDuplicateIndex() {
     Mantid::DataHandling::LoadMuonNexus1 nxLoad;
     nxLoad.initialize();
 
@@ -587,6 +580,7 @@ public:
   }
 
   void testAverageBehaviour() {
+    createTestWorkspace(inputWSName, 0);
     Mantid::DataHandling::MaskDetectors mask;
     mask.initialize();
     mask.setPropertyValue("Workspace", inputWSName);
@@ -607,9 +601,6 @@ public:
 
     // Result should be 1 + 2  / 2 = 1.5
     TS_ASSERT_EQUALS(output->y(0)[1], 1.5);
-
-    AnalysisDataService::Instance().remove(
-        "GroupDetectors2_testAverageBehaviour_Output");
   }
 
   void testEvents() {
@@ -633,6 +624,7 @@ public:
     alg2.execute();
     TS_ASSERT(alg2.isExecuted());
 
+    TS_ASSERT(AnalysisDataService::Instance().doesExist("GDEventsOut"))
     EventWorkspace_sptr output;
     output = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(
         "GDEventsOut");
@@ -642,7 +634,6 @@ public:
     TS_ASSERT_EQUALS(input->x(0).size(), output->x(0).size());
     TS_ASSERT_DELTA((input->y(2)[0] + input->y(3)[0] + input->y(4)[0]) / 3,
                     output->y(0)[0], 0.00001);
-    AnalysisDataService::Instance().remove("GDEventsOut");
   }
 
   void
@@ -876,6 +867,7 @@ public:
     GroupDetectors2 groupAlg;
     groupAlg.initialize();
     groupAlg.setRethrows(true);
+    createTestWorkspace(inputWSName, 0);
     groupAlg.setPropertyValue("InputWorkspace", inputWSName);
     groupAlg.setPropertyValue("OutputWorkspace", outputWSNameBase);
     groupAlg.setPropertyValue("GroupingPattern", "-1, 0");
@@ -912,8 +904,6 @@ public:
     TS_ASSERT_EQUALS(spectrumDefinitions[1][1].second, 3);
     TS_ASSERT_EQUALS(spectrumDefinitions[1][2].second, 4);
     TS_ASSERT_EQUALS(spectrumDefinitions[1][3].second, 5);
-
-    AnalysisDataService::Instance().remove(outputWSNameBase);
   }
 
   void test_grouping_with_time_indexes_in_event_workspace_throws() {
@@ -936,11 +926,98 @@ public:
                             "EventWorkspaces with detector scans.")
   }
 
+  void test_GroupingPattern_histogram_workspace_without_SpectraAxis_works() {
+    createTestWorkspace(inputWSName, 0);
+    // Use ConvertSpectrumAxis to replace the vertical axis with a
+    // NumericAxis.
+    auto convertAxis =
+        Mantid::API::AlgorithmManager::Instance().createUnmanaged(
+            "ConvertSpectrumAxis");
+    convertAxis->initialize();
+    convertAxis->setChild(true);
+    convertAxis->setRethrows(true);
+    convertAxis->setProperty("InputWorkspace", inputWSName);
+    convertAxis->setProperty("OutputWorkspace", "unused_for_child");
+    convertAxis->setProperty("Target", "Theta");
+    convertAxis->execute();
+    MatrixWorkspace_sptr inputWS = convertAxis->getProperty("OutputWorkspace");
+    GroupDetectors2 group;
+    group.initialize();
+    group.setRethrows(false);
+    TS_ASSERT_THROWS_NOTHING(group.setProperty("InputWorkspace", inputWS))
+    const std::string output(outputWSNameBase + "withoutSpectraAxis");
+    TS_ASSERT_THROWS_NOTHING(group.setPropertyValue("OutputWorkspace", output))
+    TS_ASSERT_THROWS_NOTHING(group.setPropertyValue("GroupingPattern", "2-5"))
+    TS_ASSERT_THROWS_NOTHING(group.execute())
+    TS_ASSERT(group.isExecuted())
+
+    MatrixWorkspace_sptr outputWS =
+        boost::dynamic_pointer_cast<MatrixWorkspace>(
+            AnalysisDataService::Instance().retrieve(output));
+    // The output should have SpectrumAxis.
+    const Axis *axis = outputWS->getAxis(1);
+    TS_ASSERT(dynamic_cast<const Mantid::API::SpectraAxis *>(axis) != nullptr);
+    TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1);
+    const HistogramX tens{10, 11, 12, 13, 14};
+    TS_ASSERT_EQUALS(outputWS->x(0), tens);
+    TS_ASSERT_EQUALS(outputWS->y(0), HistogramY(NBINS, (3 + 4 + 5 + 6)));
+    for (int i = 0; i < NBINS; ++i) {
+      TS_ASSERT_DELTA(outputWS->e(0)[i], std::sqrt(4.0), 0.0001);
+    }
+
+    const auto &spectrumInfo = outputWS->spectrumInfo();
+    TS_ASSERT(spectrumInfo.hasDetectors(0));
+    TS_ASSERT_THROWS_ANYTHING(spectrumInfo.detector(1));
+  }
+
+  void test_GroupingPattern_event_workspace_without_SpectraAxis_works() {
+    const int numBanks{1};
+    const int bankWidthInPixels{3};
+    const bool clearEvents{false};
+    auto ws = WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(
+        numBanks, bankWidthInPixels, clearEvents);
+    // Number of events from WorkspaceCreationHelpers::
+    // createEventWorkspaceWithStartTime, numEvents = 100, eventPatter = 2.
+    const int numEvents{200};
+    auto newAxis = new NumericAxis(ws->getNumberHistograms());
+    for (size_t i = 0; i < newAxis->length(); ++i) {
+      newAxis->setValue(i, static_cast<double>(i + 1));
+    }
+    ws->replaceAxis(1, newAxis);
+    GroupDetectors2 group;
+    TS_ASSERT_THROWS_NOTHING(group.initialize())
+    TS_ASSERT(group.isInitialized());
+    group.setRethrows(true);
+
+    // Set the properties
+    TS_ASSERT_THROWS_NOTHING(group.setProperty("InputWorkspace", ws))
+    TS_ASSERT_THROWS_NOTHING(
+        group.setPropertyValue("OutputWorkspace", "GDEventsOut"))
+    TS_ASSERT_THROWS_NOTHING(group.setPropertyValue("GroupingPattern", "2-4"))
+    TS_ASSERT_THROWS_NOTHING(group.setPropertyValue("Behaviour", "Average"))
+    TS_ASSERT_THROWS_NOTHING(group.setProperty("PreserveEvents", true))
+
+    group.execute();
+    TS_ASSERT(group.isExecuted());
+
+    EventWorkspace_sptr output;
+    output = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(
+        "GDEventsOut");
+    TS_ASSERT(output);
+    const Axis *axis = output->getAxis(1);
+    TS_ASSERT(dynamic_cast<const Mantid::API::SpectraAxis *>(axis) != nullptr);
+    TS_ASSERT_EQUALS(output->getNumberHistograms(), 1);
+    TS_ASSERT_EQUALS(output->getNumberEvents(), 3 * numEvents);
+    TS_ASSERT_EQUALS(ws->x(0).size(), output->x(0).size());
+    TS_ASSERT_DELTA((ws->y(2)[0] + ws->y(3)[0] + ws->y(4)[0]) / 3,
+                    output->y(0)[0], 0.00001);
+  }
+
 private:
   const std::string inputWSName, offsetWSName, outputWSNameBase, inputFile;
   enum constants { NHIST = 6, NBINS = 4 };
 
-  void createTestWorkspace(std::string name, const int offset) {
+  void createTestWorkspace(const std::string &name, const int offset) {
     // Set up a small workspace for testing
     auto space2D = createWorkspace<Workspace2D>(NHIST, NBINS + 1, NBINS);
     space2D->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
@@ -962,6 +1039,8 @@ private:
       instr->add(d);
       instr->markAsDetector(d);
     }
+    ComponentCreationHelper::addSampleToInstrument(instr, V3D{0., 0., 0.});
+    ComponentCreationHelper::addSourceToInstrument(instr, V3D{0., 0., -2.});
     space2D->setInstrument(instr);
 
     // Register the workspace in the data service
@@ -969,6 +1048,7 @@ private:
   }
 
   MatrixWorkspace_sptr createTestScanWorkspace() {
+    createTestWorkspace(inputWSName, 0);
     MatrixWorkspace_sptr inputWS = boost::dynamic_pointer_cast<MatrixWorkspace>(
         AnalysisDataService::Instance().retrieve(inputWSName));
 
diff --git a/Framework/DataHandling/test/LoadCalFileTest.h b/Framework/DataHandling/test/LoadCalFileTest.h
index 2dfcf9897d6eb4cf136a78e634809b34f783e17b..d4724f78271a73fff6c2ea9cddd998c628b22d1d 100644
--- a/Framework/DataHandling/test/LoadCalFileTest.h
+++ b/Framework/DataHandling/test/LoadCalFileTest.h
@@ -125,8 +125,8 @@ public:
   }
 
   void tearDown() override {
-    for (size_t i = 0; i < loadAlgPtrArray.size(); i++) {
-      delete loadAlgPtrArray[i];
+    for (auto &i : loadAlgPtrArray) {
+      delete i;
     }
     loadAlgPtrArray.clear();
 
diff --git a/Framework/DataHandling/test/LoadDetectorInfoTest.h b/Framework/DataHandling/test/LoadDetectorInfoTest.h
index d7fe7bcb642188a80233601fb25a3e8ef1240292..dbdf54376538e206908a62fef20a2471aa7c43db 100644
--- a/Framework/DataHandling/test/LoadDetectorInfoTest.h
+++ b/Framework/DataHandling/test/LoadDetectorInfoTest.h
@@ -69,13 +69,14 @@ void writeSmallDatFile(const std::string &filename) {
           "    w_y         w_z         f_x         f_y         f_z         a_x "
           "        a_y         a_z        det_1       det_2       det_3       "
           "det4\n";
-  for (int i = 0; i < SmallTestDatFile::NDETECTS; ++i) {
-    file << i << "\t" << delta[i] << "\t" << det_l2[i] << "\t" << code[i]
-         << "\t" << det_theta[i] << "\t" << det_phi[i] << "\t" << NOTUSED
-         << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t"
+  for (int detector = 0; detector < SmallTestDatFile::NDETECTS; ++detector) {
+    file << detector << "\t" << delta[detector] << "\t" << det_l2[detector]
+         << "\t" << code[detector] << "\t" << det_theta[detector] << "\t"
+         << det_phi[detector] << "\t" << NOTUSED << "\t" << NOTUSED << "\t"
          << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED
-         << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << pressure[i] << "\t"
-         << wallThick[i] << "\t" << NOTUSED << '\n';
+         << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t"
+         << NOTUSED << "\t" << pressure[detector] << "\t" << wallThick[detector]
+         << "\t" << NOTUSED << '\n';
   }
   file.close();
 }
@@ -301,8 +302,8 @@ public:
 
     // read the parameters from some random detectors, they're parameters are
     // all set to the same thing
-    for (int i = 0; i < NUMRANDOM; ++i) {
-      const size_t detIndex = detInfo.indexOf(DETECTS[i]);
+    for (int detector : DETECTS) {
+      const size_t detIndex = detInfo.indexOf(detector);
 
       const auto &det = detInfo.detector(detIndex);
       Parameter_sptr par = pmap.getRecursive(&det, "TubePressure");
diff --git a/Framework/DataHandling/test/LoadEmptyInstrumentTest.h b/Framework/DataHandling/test/LoadEmptyInstrumentTest.h
index 0520c1e4b6013ddf6d296a82fe9d3a47f9a15644..b69047bccc78c54b60df834933b8105457e747f4 100644
--- a/Framework/DataHandling/test/LoadEmptyInstrumentTest.h
+++ b/Framework/DataHandling/test/LoadEmptyInstrumentTest.h
@@ -180,7 +180,7 @@ public:
     TS_ASSERT_DELTA(param->value<double>(), 32.0, 0.0001);
 
     param = paramMap.get(&det, "boevs");
-    TS_ASSERT(param == NULL);
+    TS_ASSERT(param == nullptr);
 
     param = paramMap.getRecursive(&det, "boevs", "double");
     TS_ASSERT_DELTA(param->value<double>(), 8.0, 0.0001);
@@ -780,7 +780,7 @@ public:
     // And finally demonstrate that the get() method does not perform recursive
     // look-up
     param = paramMap.get(&det1, "tube_pressure2");
-    TS_ASSERT(param == NULL);
+    TS_ASSERT(param == nullptr);
 
     AnalysisDataService::Instance().remove(wsName);
   }
diff --git a/Framework/DataHandling/test/LoadEventNexusTest.h b/Framework/DataHandling/test/LoadEventNexusTest.h
index 5dc3e8407b32d71270e186b3b8d67b879c523b54..c49541b5900776cee35717aad404ea4a01f5126f 100644
--- a/Framework/DataHandling/test/LoadEventNexusTest.h
+++ b/Framework/DataHandling/test/LoadEventNexusTest.h
@@ -295,9 +295,9 @@ public:
 
     double max = events.begin()->tof();
     double min = events.begin()->tof();
-    for (size_t j = 0; j < events.size(); ++j) {
-      max = events[j].tof() > max ? events[j].tof() : max;
-      min = events[j].tof() < min ? events[j].tof() : min;
+    for (auto &event : events) {
+      max = event.tof() > max ? event.tof() : max;
+      min = event.tof() < min ? event.tof() : min;
     }
     TSM_ASSERT("The max TOF in the workspace should be equal to or less than "
                "the filtered cut-off",
diff --git a/Framework/DataHandling/test/LoadEventPreNexus2Test.h b/Framework/DataHandling/test/LoadEventPreNexus2Test.h
index 35bb8cd208d371b6cac8cf526e5f1f8d78e5d6bf..9203e17325b48d9651498fefb8016e2e3a95435e 100644
--- a/Framework/DataHandling/test/LoadEventPreNexus2Test.h
+++ b/Framework/DataHandling/test/LoadEventPreNexus2Test.h
@@ -135,8 +135,8 @@ public:
     Types::Core::DateAndTime start = it->first;
 
     std::vector<TofEvent> events1 = ew->getSpectrum(1000).getEvents();
-    for (size_t i = 0; i < events1.size(); i++) {
-      std::cout << (events1[i].pulseTime() - start) << " sec \n";
+    for (auto &event : events1) {
+      std::cout << (event.pulseTime() - start) << " sec \n";
     }
   }
 
diff --git a/Framework/DataHandling/test/LoadISISNexusTest.h b/Framework/DataHandling/test/LoadISISNexusTest.h
index bd8897282c52686f7f13acf630f4d7e5ca8d20bf..d5a63f9f7abf83d67123591d00d7667b74d9e333 100644
--- a/Framework/DataHandling/test/LoadISISNexusTest.h
+++ b/Framework/DataHandling/test/LoadISISNexusTest.h
@@ -483,8 +483,8 @@ public:
         boost::dynamic_pointer_cast<MatrixWorkspace>(grpWs->getItem(0));
     MatrixWorkspace_sptr ws2 =
         boost::dynamic_pointer_cast<MatrixWorkspace>(grpWs->getItem(1));
-    TS_ASSERT(ws1 != NULL);
-    TS_ASSERT(ws2 != NULL);
+    TS_ASSERT(ws1 != nullptr);
+    TS_ASSERT(ws2 != nullptr);
     // Check that workspace 1 has the correct period data, and no other period
     // log data
     checkPeriodLogData(ws1, 1);
diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h
index 5e5c37231351524e22468611614c418f1af33f8c..d8a6a87974f32d47e3abc5aa1e080d6d60112fae 100644
--- a/Framework/DataHandling/test/LoadInstrumentTest.h
+++ b/Framework/DataHandling/test/LoadInstrumentTest.h
@@ -636,7 +636,7 @@ private:
     // IDFs_for_UNIT_TESTING/HRPD_Parameters_Test4.xml
     Parameter_sptr param = paramMap.getRecursive(&(*comp), par, "fitting");
     TS_ASSERT(param);
-    if (param != 0) {
+    if (param != nullptr) {
       const FitParameter &fitParam4 = param->value<FitParameter>();
       TS_ASSERT(fitParam4.getTie().compare("") == 0);
       TS_ASSERT(fitParam4.getFunction().compare("BackToBackExponential") == 0);
diff --git a/Framework/DataHandling/test/LoadMaskTest.h b/Framework/DataHandling/test/LoadMaskTest.h
index dc3f1db1fcf1b6cf89d2d6c02c941b771a2f7e98..9e10583d305e0f1055004f6d2ff1b81145574182 100644
--- a/Framework/DataHandling/test/LoadMaskTest.h
+++ b/Framework/DataHandling/test/LoadMaskTest.h
@@ -532,8 +532,8 @@ public:
       ss << "</detids>\n";
     }
 
-    for (size_t i = 0; i < banks.size(); i++) {
-      ss << "<component>bank" << banks[i] << "</component>\n";
+    for (int bank : banks) {
+      ss << "<component>bank" << bank << "</component>\n";
     }
 
     // 4. End of file
@@ -552,8 +552,8 @@ public:
     std::stringstream ss;
 
     // 1. Single spectra
-    for (size_t i = 0; i < singlespectra.size(); i++) {
-      ss << singlespectra[i] << " ";
+    for (int i : singlespectra) {
+      ss << i << " ";
     }
     ss << '\n';
 
diff --git a/Framework/DataHandling/test/LoadNexusMonitorsTest.h b/Framework/DataHandling/test/LoadNexusMonitorsTest.h
index 7051fab7658ad221c483f1574a17bbd09a438fb7..b1a87e19a1eb3d00f84184491b0b949dea58fc0c 100644
--- a/Framework/DataHandling/test/LoadNexusMonitorsTest.h
+++ b/Framework/DataHandling/test/LoadNexusMonitorsTest.h
@@ -167,8 +167,8 @@ public:
     // Count output workspaces
     int ws_count = 0;
     auto props = ld1.getProperties();
-    for (auto iter = props.begin(); iter != props.end(); ++iter)
-      if ((*iter)->type() == "Workspace")
+    for (auto &prop : props)
+      if (prop->type() == "Workspace")
         ws_count++;
 
     // Version 1 has an issue that produces additional output workspaces for
@@ -191,8 +191,8 @@ public:
     // Count output workspaces
     ws_count = 0;
     props = ld2.getProperties();
-    for (auto iter = props.begin(); iter != props.end(); ++iter)
-      if ((*iter)->type() == "Workspace")
+    for (auto &prop : props)
+      if (prop->type() == "Workspace")
         ws_count++;
 
     // Version 2 always produces one OutputWorkspace, which may be a group
diff --git a/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Framework/DataHandling/test/LoadNexusProcessedTest.h
index b28faff22c4c5b38d87c0c85244439fbc7cd0e4f..82ee05ae66f2ae5fbe81d2f789c4b89c474e0aab 100644
--- a/Framework/DataHandling/test/LoadNexusProcessedTest.h
+++ b/Framework/DataHandling/test/LoadNexusProcessedTest.h
@@ -280,8 +280,8 @@ public:
     TS_ASSERT_EQUALS(ws->getSpectrum(4).getNumberEvents(), 100);
 
     // Do the comparison algo to check that they really are the same
-    origWS->sortAll(TOF_SORT, NULL);
-    ws->sortAll(TOF_SORT, NULL);
+    origWS->sortAll(TOF_SORT, nullptr);
+    ws->sortAll(TOF_SORT, nullptr);
 
     IAlgorithm_sptr alg2 =
         AlgorithmManager::Instance().createUnmanaged("CompareWorkspaces");
@@ -724,7 +724,7 @@ public:
         "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
     InstrumentDefinitionParser parser(filename, "MINITOPAZ",
                                       Strings::loadFile(filename));
-    auto instrument = parser.parseXML(NULL);
+    auto instrument = parser.parseXML(nullptr);
     peaksTestWS->populateInstrumentParameters();
     peaksTestWS->setInstrument(instrument);
 
@@ -769,7 +769,7 @@ public:
         "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
     InstrumentDefinitionParser parser(filename, "MINITOPAZ",
                                       Strings::loadFile(filename));
-    auto instrument = parser.parseXML(NULL);
+    auto instrument = parser.parseXML(nullptr);
     peaksTestWS->populateInstrumentParameters();
     peaksTestWS->setInstrument(instrument);
 
diff --git a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
index 1f8f61470db0cc871a9f511f1d9233c69666537e..8184605518f67230b83a6e81a990049ed2086ede 100644
--- a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
+++ b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
@@ -150,8 +150,8 @@ public:
 
     // std::cerr << "Count = " << i.use_count();
     boost::shared_ptr<const IComponent> source = i->getSource();
-    TS_ASSERT(source != NULL);
-    if (source != NULL) {
+    TS_ASSERT(source != nullptr);
+    if (source != nullptr) {
       TS_ASSERT_EQUALS(source->getName(), "source");
       TS_ASSERT_DELTA(detectorInfo.sourcePosition().Y(), 0.0, 0.01);
 
diff --git a/Framework/DataHandling/test/LoadTest.h b/Framework/DataHandling/test/LoadTest.h
index 55305d0dbeb8965e9edfa3689682b8a79964d1b3..8ffc38e739f04daa02a1957a8e31871403cd7d4d 100644
--- a/Framework/DataHandling/test/LoadTest.h
+++ b/Framework/DataHandling/test/LoadTest.h
@@ -112,16 +112,16 @@ public:
     const char *loadraw_props[NUMPROPS] = {
         "SpectrumMin", "SpectrumMax", "SpectrumList", "Cache", "LoadLogFiles"};
     // Basic load has no additional loader properties
-    for (size_t i = 0; i < NUMPROPS; ++i) {
-      TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), false);
+    for (auto &loadraw_prop : loadraw_props) {
+      TS_ASSERT_EQUALS(loader.existsProperty(loadraw_prop), false);
     }
     // After setting the file property, the algorithm should have aquired the
     // appropriate properties
     TS_ASSERT_THROWS_NOTHING(
         loader.setPropertyValue("Filename", "IRS38633.raw"));
     // Now
-    for (size_t i = 0; i < NUMPROPS; ++i) {
-      TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), true);
+    for (auto &loadraw_prop : loadraw_props) {
+      TS_ASSERT_EQUALS(loader.existsProperty(loadraw_prop), true);
     }
 
     // Did it find the right loader
diff --git a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
index 91b4f68969c14b4843eac69e56828ca5a79bbd3b..8e7b8951df5cc96a61a3836ae25ed27dc0781b20 100644
--- a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
+++ b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
@@ -28,13 +28,13 @@ public:
 
   void testCuboidMiss() {
     std::string xmlShape = "<cuboid id=\"shape\"> ";
-    xmlShape += "<left-front-bottom-point x=\"0.005\" y=\"-0.1\" z=\"0.0\" /> ";
+    xmlShape += R"(<left-front-bottom-point x="0.005" y="-0.1" z="0.0" /> )";
     xmlShape +=
-        "<left-front-top-point x=\"0.005\" y=\"-0.1\" z=\"0.0001\" />  ";
+        R"(<left-front-top-point x="0.005" y="-0.1" z="0.0001" />  )";
     xmlShape +=
-        "<left-back-bottom-point x=\"-0.005\" y=\"-0.1\" z=\"0.0\" />  ";
+        R"(<left-back-bottom-point x="-0.005" y="-0.1" z="0.0" />  )";
     xmlShape +=
-        "<right-front-bottom-point x=\"0.005\" y=\"0.1\" z=\"0.0\" />  ";
+        R"(<right-front-bottom-point x="0.005" y="0.1" z="0.0" />  )";
     xmlShape += "</cuboid> ";
     xmlShape += "<algebra val=\"shape\" /> ";
 
@@ -44,8 +44,8 @@ public:
   void testConeHitNoMonitors() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"-1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="-1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height val=\"4\" /> ";
     xmlShape += "</cone>";
diff --git a/Framework/DataHandling/test/MaskDetectorsTest.h b/Framework/DataHandling/test/MaskDetectorsTest.h
index a23e6800cf403ec0dc631646f78a6790c550042e..caee36084d2b7066b68d67be6dd327de4fbb36d0 100644
--- a/Framework/DataHandling/test/MaskDetectorsTest.h
+++ b/Framework/DataHandling/test/MaskDetectorsTest.h
@@ -668,7 +668,7 @@ public:
     // Make workspace to act as mask
     const auto numMaskWSSpec = inputWS->getInstrument()->getNumberDetectors();
     auto maskWs = WorkspaceCreationHelper::create2DWorkspaceBinned(
-        static_cast<int>(numMaskWSSpec), 1, 0, 0);
+        static_cast<int>(numMaskWSSpec), 1, 0., 0.);
     maskWs->setInstrument(inputWS->getInstrument());
     for (size_t i = 0; i < maskWs->getNumberHistograms(); ++i) {
       maskWs->mutableY(i)[0] = 1.0;
@@ -736,7 +736,7 @@ public:
     // Make workspace to act as mask
     const auto numMaskWSSpec = inputWS->getInstrument()->getNumberDetectors();
     auto maskWs = WorkspaceCreationHelper::create2DWorkspaceBinned(
-        static_cast<int>(numMaskWSSpec), 1, 0, 0);
+        static_cast<int>(numMaskWSSpec), 1, 0., 0.);
     maskWs->setInstrument(inputWS->getInstrument());
     for (size_t i = 0; i < maskWs->getNumberHistograms(); ++i) {
       maskWs->mutableY(i)[0] = 1.0;
diff --git a/Framework/DataHandling/test/SaveAscii2Test.h b/Framework/DataHandling/test/SaveAscii2Test.h
index c3b86dacfdcae0ec544d1986597514b49bbdb5f2..26ef97cb2da2a6be07adbe308058cf9807dc7a8e 100644
--- a/Framework/DataHandling/test/SaveAscii2Test.h
+++ b/Framework/DataHandling/test/SaveAscii2Test.h
@@ -68,8 +68,8 @@ public:
     std::getline(in, binlines);
 
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 0);
     TS_ASSERT_EQUALS(bins[1], 2);
@@ -78,8 +78,8 @@ public:
     std::getline(in, binlines);
     bins.clear();
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 1.66667);
     TS_ASSERT_EQUALS(bins[1], 8.66667);
@@ -165,8 +165,8 @@ public:
     std::getline(in, binlines);
 
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 0);
     TS_ASSERT_EQUALS(bins[1], 2);
@@ -175,8 +175,8 @@ public:
     std::getline(in, binlines);
     bins.clear();
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 1.66667);
     TS_ASSERT_EQUALS(bins[1], 8.66667);
@@ -589,8 +589,8 @@ public:
     std::getline(in, binlines);
 
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 0);
     TS_ASSERT_EQUALS(bins[1], 4);
@@ -599,8 +599,8 @@ public:
     std::getline(in, binlines);
     bins.clear();
     boost::split(binstr, binlines, boost::is_any_of(","));
-    for (size_t i = 0; i < binstr.size(); i++) {
-      bins.push_back(boost::lexical_cast<double>(binstr.at(i)));
+    for (const auto &i : binstr) {
+      bins.push_back(boost::lexical_cast<double>(i));
     }
     TS_ASSERT_EQUALS(bins[0], 1.66667);
     TS_ASSERT_EQUALS(bins[1], 17.3333);
diff --git a/Framework/DataHandling/test/SaveFocusedXYETest.h b/Framework/DataHandling/test/SaveFocusedXYETest.h
index 89b3e53dc0ea0e41f15d82084f75ccc7534c2f94..0598964d8241375ee226f30b34dd7ca1ef61cb61 100644
--- a/Framework/DataHandling/test/SaveFocusedXYETest.h
+++ b/Framework/DataHandling/test/SaveFocusedXYETest.h
@@ -68,7 +68,7 @@ public:
         "# Data for spectra :0", "TEMP 1 ",
         "# Time-of-flight              Y                 E"};
     size_t lineNumber = 1;
-    while (lineNumber <= MAX_HEADER_LENGTH) {
+    while (lineNumber <= expectedHeader.size()) {
       getline(filestrm, line);
       TS_ASSERT_EQUALS(line, expectedHeader[lineNumber - 1]);
       lineNumber++;
@@ -114,7 +114,7 @@ public:
     while (getline(filestrm, line)) {
       lineNumber++;
       std::istringstream is(line);
-      if (lineNumber <= MAX_HEADER_LENGTH) {
+      if (lineNumber <= expectedHeader.size()) {
         TS_ASSERT_EQUALS(is.str(), expectedHeader[lineNumber - 1]);
         continue;
       }
@@ -145,6 +145,79 @@ public:
     focusfile.remove();
     AnalysisDataService::Instance().remove(resultWS);
   }
+
+  void testHistogramTOPAS() {
+    using namespace Mantid::API;
+    using namespace Mantid::DataObjects;
+    Workspace2D_sptr workspace =
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+    workspace->getAxis(0)->unit() =
+        Mantid::Kernel::UnitFactory::Instance().create("TOF");
+
+    TS_ASSERT_DIFFERS(workspace, boost::shared_ptr<Workspace2D>());
+    std::string resultWS("result");
+    AnalysisDataService::Instance().add(resultWS, workspace);
+
+    Mantid::DataHandling::SaveFocusedXYE saveXYE;
+    TS_ASSERT_THROWS_NOTHING(saveXYE.initialize());
+    TS_ASSERT_EQUALS(saveXYE.isInitialized(), true);
+
+    saveXYE.setPropertyValue("InputWorkspace", resultWS);
+    std::string filename("focussed.test");
+    saveXYE.setPropertyValue("Filename", filename);
+    filename = saveXYE.getPropertyValue("Filename"); // absolute path
+    saveXYE.setProperty("SplitFiles", false);
+    saveXYE.setProperty("Format", "TOPAS");
+
+    TS_ASSERT_THROWS_NOTHING(saveXYE.execute());
+
+    Poco::File focusfile(filename);
+    TS_ASSERT_EQUALS(focusfile.exists(), true);
+
+    std::ifstream filestrm(filename.c_str());
+    std::string line;
+    const std::vector<std::string> expectedHeader{
+        "' File generated by Mantid, Instrument ",
+        "' The X-axis unit is: Time-of-flight, The Y-axis unit is: ",
+        "' Data for spectra :0", "' Spectrum 1 ",
+        "' Time-of-flight              Y                 E"};
+    int bin_no(1);
+    size_t lineNumber = 0;
+    while (getline(filestrm, line)) {
+      lineNumber++;
+      std::istringstream is(line);
+      if (lineNumber <= expectedHeader.size()) {
+        TS_ASSERT_EQUALS(is.str(), expectedHeader[lineNumber - 1]);
+        continue;
+      }
+      double x(0.0), y(0.0), e(0.);
+      is >> x >> y >> e;
+      switch (bin_no) {
+      case 1:
+        TS_ASSERT_DELTA(x, 1.5, m_tol);
+        TS_ASSERT_DELTA(y, 2.0, m_tol);
+        TS_ASSERT_DELTA(e, M_SQRT2, m_tol);
+        break;
+      case 2:
+        TS_ASSERT_DELTA(x, 2.5, m_tol);
+        TS_ASSERT_DELTA(y, 2.0, m_tol);
+        TS_ASSERT_DELTA(e, M_SQRT2, m_tol);
+        break;
+      case 3:
+        TS_ASSERT_DELTA(x, 3.5, m_tol);
+        TS_ASSERT_DELTA(y, 2.0, m_tol);
+        TS_ASSERT_DELTA(e, M_SQRT2, m_tol);
+        break;
+      default:
+        TS_ASSERT(false);
+      }
+      ++bin_no;
+    }
+    filestrm.close();
+    focusfile.remove();
+    AnalysisDataService::Instance().remove(resultWS);
+  }
+
   void testSaveFocusedXYEWorkspaceGroups() {
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
diff --git a/Framework/DataHandling/test/SaveNXSPETest.h b/Framework/DataHandling/test/SaveNXSPETest.h
index 7c8612bdfa2ba60cc21d8f4859fba506e8ec9185..90b8201c198b1ff07b15611379a661e6c6fd865c 100644
--- a/Framework/DataHandling/test/SaveNXSPETest.h
+++ b/Framework/DataHandling/test/SaveNXSPETest.h
@@ -165,9 +165,9 @@ private:
     return inputWS;
   }
 
-  typedef boost::tuple<boost::shared_array<hsize_t>,
-                       boost::shared_array<double>,
-                       boost::shared_array<double>> DataHolder;
+  using DataHolder =
+      boost::tuple<boost::shared_array<hsize_t>, boost::shared_array<double>,
+                   boost::shared_array<double>>;
 
   DataHolder saveAndReloadWorkspace(const MatrixWorkspace_sptr inputWS) {
     SaveNXSPE saver;
diff --git a/Framework/DataHandling/test/SavePHXTest.h b/Framework/DataHandling/test/SavePHXTest.h
index 1bb461aabe3a8507ac48b16e7526a454bdac27fe..e64993177daf4c788af676c2ce12297c76de5f31 100644
--- a/Framework/DataHandling/test/SavePHXTest.h
+++ b/Framework/DataHandling/test/SavePHXTest.h
@@ -139,8 +139,8 @@ public:
         sample_value[0] = (float)spTW->rowCount();
       } else {
         size_t ii = 0;
-        for (size_t i = 0; i < column_name.size(); i++) {
-          sample_value[ii] = (spTW->cell_cast<float>(ic - 1, column_name[i]));
+        for (const auto &i : column_name) {
+          sample_value[ii] = (spTW->cell_cast<float>(ic - 1, i));
           ii++;
           if (ii == 1)
             ii = 2; // scip second column in the file, which contains 0;
diff --git a/Framework/DataHandling/test/SaveParameterFileTest.h b/Framework/DataHandling/test/SaveParameterFileTest.h
index 257cf753d9a7303bc8cac08d275ad435e51b876e..80f8334149072738fcee785d9c82d18ead034b28 100644
--- a/Framework/DataHandling/test/SaveParameterFileTest.h
+++ b/Framework/DataHandling/test/SaveParameterFileTest.h
@@ -136,7 +136,7 @@ public:
         param->value<FitParameter>();
 
     // Info about fitting parameter is in string value, see FitParameter class
-    typedef Mantid::Kernel::StringTokenizer tokenizer;
+    using tokenizer = Mantid::Kernel::StringTokenizer;
     tokenizer values(value, ",", tokenizer::TOK_TRIM);
     TS_ASSERT_EQUALS(fitParam.getFormula(), values[7]);
     TS_ASSERT_EQUALS(fitParam.getFunction(), values[1]);
diff --git a/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h b/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h
index 0dcf3f9b0a5e71676eae0aff8fa13ff53e7aeda4..2d506d17960092863a3b4df9f81ae9149215e74c 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h
@@ -9,7 +9,7 @@
 namespace Mantid {
 namespace DataObjects {
 /// Convenience typedef for a specific matrix type.
-typedef Mantid::Kernel::Matrix<coord_t> AffineMatrixType;
+using AffineMatrixType = Mantid::Kernel::Matrix<coord_t>;
 
 /** Type to wrap an affine matrix and allow serialization via xml.
 *
diff --git a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h
index 9267f1277cabbe5b6c989ba8b90dc626f4a44ac6..0f8f235fdb275558588a57b9c5356c9bc6f362df 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h
@@ -31,8 +31,8 @@ public:
   createTransform(Poco::XML::Element *coordTransElement) const;
   virtual void setSuccessor(CoordTransformAffineParser *other);
   virtual ~CoordTransformAffineParser() = default;
-  typedef boost::shared_ptr<CoordTransformAffineParser>
-      SuccessorType_sptr; ///< successor parser shared ptr typedef
+  using SuccessorType_sptr = boost::shared_ptr<
+      CoordTransformAffineParser>; ///< successor parser shared ptr typedef
 protected:
   SuccessorType_sptr m_successor; ///< successor parser
 private:
diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventList.h b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
index a4ddd64c6897f31624b8936930256408412c3aaa..fa60d100681af04106a7a896d2890b7fd14708ea 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/EventList.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
@@ -17,7 +17,7 @@ class DateAndTime;
 } // namespace Types
 namespace Kernel {
 class SplittingInterval;
-typedef std::vector<SplittingInterval> TimeSplitterType;
+using TimeSplitterType = std::vector<SplittingInterval>;
 class Unit;
 } // namespace Kernel
 namespace DataObjects {
diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h
index de80fb2e826bf385259561486146534621dc93ee..f61a1b1d97c3798c543c4dd06504269c7cce4e94 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h
@@ -162,9 +162,9 @@ private:
 };
 
 /// shared pointer to the EventWorkspace class
-typedef boost::shared_ptr<EventWorkspace> EventWorkspace_sptr;
+using EventWorkspace_sptr = boost::shared_ptr<EventWorkspace>;
 /// shared pointer to a const Workspace2D
-typedef boost::shared_ptr<const EventWorkspace> EventWorkspace_const_sptr;
+using EventWorkspace_const_sptr = boost::shared_ptr<const EventWorkspace>;
 
 } /// namespace DataObjects
 } /// namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/FakeMD.h b/Framework/DataObjects/inc/MantidDataObjects/FakeMD.h
index 0084d7784b0372f120cdbc087b8bd52e3a4ce931..20f46d05e8d60316820a05eff1fac6c703b8ca90 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/FakeMD.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/FakeMD.h
@@ -1,14 +1,12 @@
 #ifndef MANTID_DATAOBJECTS_FAKEMD_H_
 #define MANTID_DATAOBJECTS_FAKEMD_H_
+
 #include <vector>
 
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidDataObjects/DllConfig.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
-
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/variate_generator.hpp>
+#include "MantidKernel/uniform_int_distribution.h"
 
 namespace Mantid {
 namespace DataObjects {
@@ -69,8 +67,8 @@ private:
   const int m_randomSeed;
   const bool m_randomizeSignal;
   mutable std::vector<detid_t> m_detIDs;
-  boost::mt19937 m_randGen;
-  boost::uniform_int<size_t> m_uniformDist;
+  std::mt19937 m_randGen;
+  Kernel::uniform_int_distribution<size_t> m_uniformDist;
 };
 
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h
index 50f21824e37b728e675e138fbd02f1bf5c56bec7..d19fe009f990f775c432bcf843afd65f72f63718 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h
@@ -58,10 +58,10 @@ private:
 };
 
 /// shared pointer to the GroupingWorkspace class
-typedef boost::shared_ptr<GroupingWorkspace> GroupingWorkspace_sptr;
+using GroupingWorkspace_sptr = boost::shared_ptr<GroupingWorkspace>;
 
 /// shared pointer to a const GroupingWorkspace
-typedef boost::shared_ptr<const GroupingWorkspace> GroupingWorkspace_const_sptr;
+using GroupingWorkspace_const_sptr = boost::shared_ptr<const GroupingWorkspace>;
 
 } // namespace Mantid
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h
index d5369975c26e7f9131192524f286f5cd5f51595b..6c3e433311e786144c1f6b47864d111876964dc6 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h
@@ -227,10 +227,10 @@ private:
 
 public:
   /// Typedef for a shared pointer to a MDBox
-  typedef boost::shared_ptr<MDBox<MDE, nd>> sptr;
+  using sptr = boost::shared_ptr<MDBox<MDE, nd>>;
 
   /// Typedef for a vector of the conatined events
-  typedef std::vector<MDE> vec_t;
+  using vec_t = std::vector<MDE>;
 };
 
 #ifndef __INTEL_COMPILER
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h
index 12cee44a4717a8002c617b1648644b0c93406c73..37c91d33fba227ca282c5675c789e692e3e3a069 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h
@@ -158,9 +158,11 @@ public:
   // -------------------------------------------
 
   std::vector<Mantid::Kernel::VMD> getVertexes() const override;
-  coord_t *getVertexesArray(size_t &numVertices) const override;
-  coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions,
-                            const bool *maskDim) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const override;
   void transformDimensions(std::vector<double> &scaling,
                            std::vector<double> &offset) override;
 
@@ -372,7 +374,7 @@ private:
 
 public:
   /// Convenience typedef for a shared pointer to a this type of class
-  typedef boost::shared_ptr<MDBoxBase<MDE, nd>> sptr;
+  using sptr = boost::shared_ptr<MDBoxBase<MDE, nd>>;
 
 }; //(end class MDBoxBase)
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc
index 99c8f9aab90bacfe24b8c71410afc1224a9a89e7..fdd9f3d261ef679450fa86abff786138a750bdae 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc
@@ -1,12 +1,11 @@
 #include "MantidDataObjects/MDBoxBase.h"
 #include "MantidDataObjects/MDEvent.h"
+#include "MantidKernel/make_unique.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/VMD.h"
 #include <boost/make_shared.hpp>
 #include <limits>
 
-//using NeXus::File;
-
 namespace Mantid {
 namespace DataObjects {
 
@@ -135,13 +134,13 @@ TMDE(std::vector<Mantid::Kernel::VMD> MDBoxBase)::getVertexes() const {
  * @param[out] numVertices :: returns the number of vertices in the array.
  * @return the bare array. This should be deleted by the caller!
  * */
-TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices) const {
+TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices) const {
   // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd
   // bits
   numVertices = 1 << nd;
 
   // Allocate the array of the right size
-  auto out = new coord_t[nd * numVertices];
+  auto out = Kernel::make_unique<coord_t[]>(nd * numVertices);
 
   // For each vertex, increase an integeer
   for (size_t i = 0; i < numVertices; ++i) {
@@ -184,7 +183,7 @@ TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices) const {
  *caller!
  * @throw if outDimensions == 0
  * */
-TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices,
+TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices,
                                            const size_t outDimensions,
                                            const bool *maskDim) const {
   if (outDimensions == 0)
@@ -195,7 +194,7 @@ TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices,
   numVertices = (size_t)1 << outDimensions;
 
   // Allocate the array of the right size
-  auto out = new coord_t[outDimensions * numVertices];
+  auto out = Kernel::make_unique<coord_t[]>(outDimensions * numVertices);
 
   // For each vertex, increase an integeer
   for (size_t i = 0; i < numVertices; ++i) {
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h
index a76277444340ca730c60f6349cf37286794f418f..29e4b02904390d216215a057bddfc43f38cb6636 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h
@@ -54,10 +54,12 @@ public:
 
   signal_t getError() const override;
 
-  coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions,
-                            const bool *maskDim) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const override;
 
-  coord_t *getVertexesArray(size_t &numVertices) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const override;
 
   Mantid::Kernel::VMD getCenter() const override;
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc
index d5df20e7669093ba2fdf4b1a20c52b8862f33028..c15a92b207aacc62ef9a9fa2e76131501272dc43 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc
@@ -258,11 +258,11 @@ TMDE(signal_t MDBoxIterator)::getSignal() const {
 TMDE(signal_t MDBoxIterator)::getError() const { return m_current->getError(); }
 
 /// Return a list of vertexes defining the volume pointed to
-TMDE(coord_t *MDBoxIterator)::getVertexesArray(size_t &numVertices) const {
+TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices) const {
   return m_current->getVertexesArray(numVertices);
 }
 
-TMDE(coord_t *MDBoxIterator)::getVertexesArray(size_t &numVertices,
+TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices,
                                                const size_t outDimensions,
                                                const bool *maskDim) const {
   return m_current->getVertexesArray(numVertices, outDimensions, maskDim);
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h
index 2bad03cb31849bf534038eb558f0b49180688af7..5c7f31d9ebab2f70d35d917541d19cd84d359e87 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h
@@ -65,7 +65,7 @@ public:
   static size_t getMaxNumDim() { return size_t(MAX_MD_DIMENSIONS_NUM); }
 
 private:
-  typedef API::IMDNode *(*fpCreateBox)(
+  using fpCreateBox = API::IMDNode *(*)(
       API::BoxController *,
       const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &,
       const uint32_t, const size_t, const size_t);
@@ -75,10 +75,9 @@ private:
 
   // typedef for the class function pointer to the function, which creates MD
   // Workspaces
-  typedef API::IMDEventWorkspace *(*fpCreateMDWS)(
-      const std::string &eventType,
-      const Mantid::API::MDNormalization &preferredNormalization,
-      const Mantid::API::MDNormalization &preferredNormalizationHisto);
+  using fpCreateMDWS = API::IMDEventWorkspace *(*)(
+      const std::string &, const Mantid::API::MDNormalization &,
+      const Mantid::API::MDNormalization &);
   // vector of function pointers to the funcions
   static std::vector<fpCreateMDWS> wsCreatorFP;
 
@@ -425,197 +424,197 @@ private:
 // ------------- Typedefs for MDBox ------------------
 
 /// Typedef for a MDBox with 1 dimension
-typedef MDBox<MDLeanEvent<1>, 1> MDBox1Lean;
+using MDBox1Lean = MDBox<MDLeanEvent<1>, 1>;
 /// Typedef for a MDBox with 2 dimensions
-typedef MDBox<MDLeanEvent<2>, 2> MDBox2Lean;
+using MDBox2Lean = MDBox<MDLeanEvent<2>, 2>;
 /// Typedef for a MDBox with 3 dimensions
-typedef MDBox<MDLeanEvent<3>, 3> MDBox3Lean;
+using MDBox3Lean = MDBox<MDLeanEvent<3>, 3>;
 /// Typedef for a MDBox with 4 dimensions
-typedef MDBox<MDLeanEvent<4>, 4> MDBox4Lean;
+using MDBox4Lean = MDBox<MDLeanEvent<4>, 4>;
 /// Typedef for a MDBox with 5 dimensions
-typedef MDBox<MDLeanEvent<5>, 5> MDBox5Lean;
+using MDBox5Lean = MDBox<MDLeanEvent<5>, 5>;
 /// Typedef for a MDBox with 6 dimensions
-typedef MDBox<MDLeanEvent<6>, 6> MDBox6Lean;
+using MDBox6Lean = MDBox<MDLeanEvent<6>, 6>;
 /// Typedef for a MDBox with 7 dimensions
-typedef MDBox<MDLeanEvent<7>, 7> MDBox7Lean;
+using MDBox7Lean = MDBox<MDLeanEvent<7>, 7>;
 /// Typedef for a MDBox with 8 dimensions
-typedef MDBox<MDLeanEvent<8>, 8> MDBox8Lean;
+using MDBox8Lean = MDBox<MDLeanEvent<8>, 8>;
 /// Typedef for a MDBox with 9 dimensions
-typedef MDBox<MDLeanEvent<9>, 9> MDBox9Lean;
+using MDBox9Lean = MDBox<MDLeanEvent<9>, 9>;
 /// Typedef for a MDBox with 1 dimension
-typedef MDBox<MDEvent<1>, 1> MDBox1;
+using MDBox1 = MDBox<MDEvent<1>, 1>;
 /// Typedef for a MDBox with 2 dimensions
-typedef MDBox<MDEvent<2>, 2> MDBox2;
+using MDBox2 = MDBox<MDEvent<2>, 2>;
 /// Typedef for a MDBox with 3 dimensions
-typedef MDBox<MDEvent<3>, 3> MDBox3;
+using MDBox3 = MDBox<MDEvent<3>, 3>;
 /// Typedef for a MDBox with 4 dimensions
-typedef MDBox<MDEvent<4>, 4> MDBox4;
+using MDBox4 = MDBox<MDEvent<4>, 4>;
 /// Typedef for a MDBox with 5 dimensions
-typedef MDBox<MDEvent<5>, 5> MDBox5;
+using MDBox5 = MDBox<MDEvent<5>, 5>;
 /// Typedef for a MDBox with 6 dimensions
-typedef MDBox<MDEvent<6>, 6> MDBox6;
+using MDBox6 = MDBox<MDEvent<6>, 6>;
 /// Typedef for a MDBox with 7 dimensions
-typedef MDBox<MDEvent<7>, 7> MDBox7;
+using MDBox7 = MDBox<MDEvent<7>, 7>;
 /// Typedef for a MDBox with 8 dimensions
-typedef MDBox<MDEvent<8>, 8> MDBox8;
+using MDBox8 = MDBox<MDEvent<8>, 8>;
 /// Typedef for a MDBox with 9 dimensions
-typedef MDBox<MDEvent<9>, 9> MDBox9;
+using MDBox9 = MDBox<MDEvent<9>, 9>;
 
 // ------------- Typedefs for MDBoxBase ------------------
 
 /// Typedef for a MDBoxBase with 1 dimension
-typedef MDBoxBase<MDLeanEvent<1>, 1> MDBoxBase1Lean;
+using MDBoxBase1Lean = MDBoxBase<MDLeanEvent<1>, 1>;
 /// Typedef for a MDBoxBase with 2 dimensions
-typedef MDBoxBase<MDLeanEvent<2>, 2> MDBoxBase2Lean;
+using MDBoxBase2Lean = MDBoxBase<MDLeanEvent<2>, 2>;
 /// Typedef for a MDBoxBase with 3 dimensions
-typedef MDBoxBase<MDLeanEvent<3>, 3> MDBoxBase3Lean;
+using MDBoxBase3Lean = MDBoxBase<MDLeanEvent<3>, 3>;
 /// Typedef for a MDBoxBase with 4 dimensions
-typedef MDBoxBase<MDLeanEvent<4>, 4> MDBoxBase4Lean;
+using MDBoxBase4Lean = MDBoxBase<MDLeanEvent<4>, 4>;
 /// Typedef for a MDBoxBase with 5 dimensions
-typedef MDBoxBase<MDLeanEvent<5>, 5> MDBoxBase5Lean;
+using MDBoxBase5Lean = MDBoxBase<MDLeanEvent<5>, 5>;
 /// Typedef for a MDBoxBase with 6 dimensions
-typedef MDBoxBase<MDLeanEvent<6>, 6> MDBoxBase6Lean;
+using MDBoxBase6Lean = MDBoxBase<MDLeanEvent<6>, 6>;
 /// Typedef for a MDBoxBase with 7 dimensions
-typedef MDBoxBase<MDLeanEvent<7>, 7> MDBoxBase7Lean;
+using MDBoxBase7Lean = MDBoxBase<MDLeanEvent<7>, 7>;
 /// Typedef for a MDBoxBase with 8 dimensions
-typedef MDBoxBase<MDLeanEvent<8>, 8> MDBoxBase8Lean;
+using MDBoxBase8Lean = MDBoxBase<MDLeanEvent<8>, 8>;
 /// Typedef for a MDBoxBase with 9 dimensions
-typedef MDBoxBase<MDLeanEvent<9>, 9> MDBoxBase9Lean;
+using MDBoxBase9Lean = MDBoxBase<MDLeanEvent<9>, 9>;
 /// Typedef for a MDBoxBase with 1 dimension
-typedef MDBoxBase<MDEvent<1>, 1> MDBoxBase1;
+using MDBoxBase1 = MDBoxBase<MDEvent<1>, 1>;
 /// Typedef for a MDBoxBase with 2 dimensions
-typedef MDBoxBase<MDEvent<2>, 2> MDBoxBase2;
+using MDBoxBase2 = MDBoxBase<MDEvent<2>, 2>;
 /// Typedef for a MDBoxBase with 3 dimensions
-typedef MDBoxBase<MDEvent<3>, 3> MDBoxBase3;
+using MDBoxBase3 = MDBoxBase<MDEvent<3>, 3>;
 /// Typedef for a MDBoxBase with 4 dimensions
-typedef MDBoxBase<MDEvent<4>, 4> MDBoxBase4;
+using MDBoxBase4 = MDBoxBase<MDEvent<4>, 4>;
 /// Typedef for a MDBoxBase with 5 dimensions
-typedef MDBoxBase<MDEvent<5>, 5> MDBoxBase5;
+using MDBoxBase5 = MDBoxBase<MDEvent<5>, 5>;
 /// Typedef for a MDBoxBase with 6 dimensions
-typedef MDBoxBase<MDEvent<6>, 6> MDBoxBase6;
+using MDBoxBase6 = MDBoxBase<MDEvent<6>, 6>;
 /// Typedef for a MDBoxBase with 7 dimensions
-typedef MDBoxBase<MDEvent<7>, 7> MDBoxBase7;
+using MDBoxBase7 = MDBoxBase<MDEvent<7>, 7>;
 /// Typedef for a MDBoxBase with 8 dimensions
-typedef MDBoxBase<MDEvent<8>, 8> MDBoxBase8;
+using MDBoxBase8 = MDBoxBase<MDEvent<8>, 8>;
 /// Typedef for a MDBoxBase with 9 dimensions
-typedef MDBoxBase<MDEvent<9>, 9> MDBoxBase9;
+using MDBoxBase9 = MDBoxBase<MDEvent<9>, 9>;
 
 // ------------- Typedefs for MDGridBox ------------------
 
 /// Typedef for a MDGridBox with 1 dimension
-typedef MDGridBox<MDLeanEvent<1>, 1> MDGridBox1Lean;
+using MDGridBox1Lean = MDGridBox<MDLeanEvent<1>, 1>;
 /// Typedef for a MDGridBox with 2 dimensions
-typedef MDGridBox<MDLeanEvent<2>, 2> MDGridBox2Lean;
+using MDGridBox2Lean = MDGridBox<MDLeanEvent<2>, 2>;
 /// Typedef for a MDGridBox with 3 dimensions
-typedef MDGridBox<MDLeanEvent<3>, 3> MDGridBox3Lean;
+using MDGridBox3Lean = MDGridBox<MDLeanEvent<3>, 3>;
 /// Typedef for a MDGridBox with 4 dimensions
-typedef MDGridBox<MDLeanEvent<4>, 4> MDGridBox4Lean;
+using MDGridBox4Lean = MDGridBox<MDLeanEvent<4>, 4>;
 /// Typedef for a MDGridBox with 5 dimensions
-typedef MDGridBox<MDLeanEvent<5>, 5> MDGridBox5Lean;
+using MDGridBox5Lean = MDGridBox<MDLeanEvent<5>, 5>;
 /// Typedef for a MDGridBox with 6 dimensions
-typedef MDGridBox<MDLeanEvent<6>, 6> MDGridBox6Lean;
+using MDGridBox6Lean = MDGridBox<MDLeanEvent<6>, 6>;
 /// Typedef for a MDGridBox with 7 dimensions
-typedef MDGridBox<MDLeanEvent<7>, 7> MDGridBox7Lean;
+using MDGridBox7Lean = MDGridBox<MDLeanEvent<7>, 7>;
 /// Typedef for a MDGridBox with 8 dimensions
-typedef MDGridBox<MDLeanEvent<8>, 8> MDGridBox8Lean;
+using MDGridBox8Lean = MDGridBox<MDLeanEvent<8>, 8>;
 /// Typedef for a MDGridBox with 9 dimensions
-typedef MDGridBox<MDLeanEvent<9>, 9> MDGridBox9Lean;
+using MDGridBox9Lean = MDGridBox<MDLeanEvent<9>, 9>;
 /// Typedef for a MDGridBox with 1 dimension
-typedef MDGridBox<MDEvent<1>, 1> MDGridBox1;
+using MDGridBox1 = MDGridBox<MDEvent<1>, 1>;
 /// Typedef for a MDGridBox with 2 dimensions
-typedef MDGridBox<MDEvent<2>, 2> MDGridBox2;
+using MDGridBox2 = MDGridBox<MDEvent<2>, 2>;
 /// Typedef for a MDGridBox with 3 dimensions
-typedef MDGridBox<MDEvent<3>, 3> MDGridBox3;
+using MDGridBox3 = MDGridBox<MDEvent<3>, 3>;
 /// Typedef for a MDGridBox with 4 dimensions
-typedef MDGridBox<MDEvent<4>, 4> MDGridBox4;
+using MDGridBox4 = MDGridBox<MDEvent<4>, 4>;
 /// Typedef for a MDGridBox with 5 dimensions
-typedef MDGridBox<MDEvent<5>, 5> MDGridBox5;
+using MDGridBox5 = MDGridBox<MDEvent<5>, 5>;
 /// Typedef for a MDGridBox with 6 dimensions
-typedef MDGridBox<MDEvent<6>, 6> MDGridBox6;
+using MDGridBox6 = MDGridBox<MDEvent<6>, 6>;
 /// Typedef for a MDGridBox with 7 dimensions
-typedef MDGridBox<MDEvent<7>, 7> MDGridBox7;
+using MDGridBox7 = MDGridBox<MDEvent<7>, 7>;
 /// Typedef for a MDGridBox with 8 dimensions
-typedef MDGridBox<MDEvent<8>, 8> MDGridBox8;
+using MDGridBox8 = MDGridBox<MDEvent<8>, 8>;
 /// Typedef for a MDGridBox with 9 dimensions
-typedef MDGridBox<MDEvent<9>, 9> MDGridBox9;
+using MDGridBox9 = MDGridBox<MDEvent<9>, 9>;
 
 // ------------- Typedefs for MDEventWorkspace ------------------
 
 /// Typedef for a MDEventWorkspace with 1 dimension
-typedef MDEventWorkspace<MDLeanEvent<1>, 1> MDEventWorkspace1Lean;
+using MDEventWorkspace1Lean = MDEventWorkspace<MDLeanEvent<1>, 1>;
 /// Typedef for a MDEventWorkspace with 2 dimensions
-typedef MDEventWorkspace<MDLeanEvent<2>, 2> MDEventWorkspace2Lean;
+using MDEventWorkspace2Lean = MDEventWorkspace<MDLeanEvent<2>, 2>;
 /// Typedef for a MDEventWorkspace with 3 dimensions
-typedef MDEventWorkspace<MDLeanEvent<3>, 3> MDEventWorkspace3Lean;
+using MDEventWorkspace3Lean = MDEventWorkspace<MDLeanEvent<3>, 3>;
 /// Typedef for a MDEventWorkspace with 4 dimensions
-typedef MDEventWorkspace<MDLeanEvent<4>, 4> MDEventWorkspace4Lean;
+using MDEventWorkspace4Lean = MDEventWorkspace<MDLeanEvent<4>, 4>;
 /// Typedef for a MDEventWorkspace with 5 dimensions
-typedef MDEventWorkspace<MDLeanEvent<5>, 5> MDEventWorkspace5Lean;
+using MDEventWorkspace5Lean = MDEventWorkspace<MDLeanEvent<5>, 5>;
 /// Typedef for a MDEventWorkspace with 6 dimensions
-typedef MDEventWorkspace<MDLeanEvent<6>, 6> MDEventWorkspace6Lean;
+using MDEventWorkspace6Lean = MDEventWorkspace<MDLeanEvent<6>, 6>;
 /// Typedef for a MDEventWorkspace with 7 dimensions
-typedef MDEventWorkspace<MDLeanEvent<7>, 7> MDEventWorkspace7Lean;
+using MDEventWorkspace7Lean = MDEventWorkspace<MDLeanEvent<7>, 7>;
 /// Typedef for a MDEventWorkspace with 8 dimensions
-typedef MDEventWorkspace<MDLeanEvent<8>, 8> MDEventWorkspace8Lean;
+using MDEventWorkspace8Lean = MDEventWorkspace<MDLeanEvent<8>, 8>;
 /// Typedef for a MDEventWorkspace with 9 dimensions
-typedef MDEventWorkspace<MDLeanEvent<9>, 9> MDEventWorkspace9Lean;
+using MDEventWorkspace9Lean = MDEventWorkspace<MDLeanEvent<9>, 9>;
 /// Typedef for a MDEventWorkspace with 1 dimension
-typedef MDEventWorkspace<MDEvent<1>, 1> MDEventWorkspace1;
+using MDEventWorkspace1 = MDEventWorkspace<MDEvent<1>, 1>;
 /// Typedef for a MDEventWorkspace with 2 dimensions
-typedef MDEventWorkspace<MDEvent<2>, 2> MDEventWorkspace2;
+using MDEventWorkspace2 = MDEventWorkspace<MDEvent<2>, 2>;
 /// Typedef for a MDEventWorkspace with 3 dimensions
-typedef MDEventWorkspace<MDEvent<3>, 3> MDEventWorkspace3;
+using MDEventWorkspace3 = MDEventWorkspace<MDEvent<3>, 3>;
 /// Typedef for a MDEventWorkspace with 4 dimensions
-typedef MDEventWorkspace<MDEvent<4>, 4> MDEventWorkspace4;
+using MDEventWorkspace4 = MDEventWorkspace<MDEvent<4>, 4>;
 /// Typedef for a MDEventWorkspace with 5 dimensions
-typedef MDEventWorkspace<MDEvent<5>, 5> MDEventWorkspace5;
+using MDEventWorkspace5 = MDEventWorkspace<MDEvent<5>, 5>;
 /// Typedef for a MDEventWorkspace with 6 dimensions
-typedef MDEventWorkspace<MDEvent<6>, 6> MDEventWorkspace6;
+using MDEventWorkspace6 = MDEventWorkspace<MDEvent<6>, 6>;
 /// Typedef for a MDEventWorkspace with 7 dimensions
-typedef MDEventWorkspace<MDEvent<7>, 7> MDEventWorkspace7;
+using MDEventWorkspace7 = MDEventWorkspace<MDEvent<7>, 7>;
 /// Typedef for a MDEventWorkspace with 8 dimensions
-typedef MDEventWorkspace<MDEvent<8>, 8> MDEventWorkspace8;
+using MDEventWorkspace8 = MDEventWorkspace<MDEvent<8>, 8>;
 /// Typedef for a MDEventWorkspace with 9 dimensions
-typedef MDEventWorkspace<MDEvent<9>, 9> MDEventWorkspace9;
+using MDEventWorkspace9 = MDEventWorkspace<MDEvent<9>, 9>;
 
 // ------------- Typedefs for MDBin ------------------
 
 /// Typedef for a MDBin with 1 dimension
-typedef MDBin<MDLeanEvent<1>, 1> MDBin1Lean;
+using MDBin1Lean = MDBin<MDLeanEvent<1>, 1>;
 /// Typedef for a MDBin with 2 dimensions
-typedef MDBin<MDLeanEvent<2>, 2> MDBin2Lean;
+using MDBin2Lean = MDBin<MDLeanEvent<2>, 2>;
 /// Typedef for a MDBin with 3 dimensions
-typedef MDBin<MDLeanEvent<3>, 3> MDBin3Lean;
+using MDBin3Lean = MDBin<MDLeanEvent<3>, 3>;
 /// Typedef for a MDBin with 4 dimensions
-typedef MDBin<MDLeanEvent<4>, 4> MDBin4Lean;
+using MDBin4Lean = MDBin<MDLeanEvent<4>, 4>;
 /// Typedef for a MDBin with 5 dimensions
-typedef MDBin<MDLeanEvent<5>, 5> MDBin5Lean;
+using MDBin5Lean = MDBin<MDLeanEvent<5>, 5>;
 /// Typedef for a MDBin with 6 dimensions
-typedef MDBin<MDLeanEvent<6>, 6> MDBin6Lean;
+using MDBin6Lean = MDBin<MDLeanEvent<6>, 6>;
 /// Typedef for a MDBin with 7 dimensions
-typedef MDBin<MDLeanEvent<7>, 7> MDBin7Lean;
+using MDBin7Lean = MDBin<MDLeanEvent<7>, 7>;
 /// Typedef for a MDBin with 8 dimensions
-typedef MDBin<MDLeanEvent<8>, 8> MDBin8Lean;
+using MDBin8Lean = MDBin<MDLeanEvent<8>, 8>;
 /// Typedef for a MDBin with 9 dimensions
-typedef MDBin<MDLeanEvent<9>, 9> MDBin9Lean;
+using MDBin9Lean = MDBin<MDLeanEvent<9>, 9>;
 /// Typedef for a MDBin with 1 dimension
-typedef MDBin<MDEvent<1>, 1> MDBin1;
+using MDBin1 = MDBin<MDEvent<1>, 1>;
 /// Typedef for a MDBin with 2 dimensions
-typedef MDBin<MDEvent<2>, 2> MDBin2;
+using MDBin2 = MDBin<MDEvent<2>, 2>;
 /// Typedef for a MDBin with 3 dimensions
-typedef MDBin<MDEvent<3>, 3> MDBin3;
+using MDBin3 = MDBin<MDEvent<3>, 3>;
 /// Typedef for a MDBin with 4 dimensions
-typedef MDBin<MDEvent<4>, 4> MDBin4;
+using MDBin4 = MDBin<MDEvent<4>, 4>;
 /// Typedef for a MDBin with 5 dimensions
-typedef MDBin<MDEvent<5>, 5> MDBin5;
+using MDBin5 = MDBin<MDEvent<5>, 5>;
 /// Typedef for a MDBin with 6 dimensions
-typedef MDBin<MDEvent<6>, 6> MDBin6;
+using MDBin6 = MDBin<MDEvent<6>, 6>;
 /// Typedef for a MDBin with 7 dimensions
-typedef MDBin<MDEvent<7>, 7> MDBin7;
+using MDBin7 = MDBin<MDEvent<7>, 7>;
 /// Typedef for a MDBin with 8 dimensions
-typedef MDBin<MDEvent<8>, 8> MDBin8;
+using MDBin8 = MDBin<MDEvent<8>, 8>;
 /// Typedef for a MDBin with 9 dimensions
-typedef MDBin<MDEvent<9>, 9> MDBin9;
+using MDBin9 = MDBin<MDEvent<9>, 9>;
 
 /* CODE ABOWE WAS AUTO-GENERATED BY generate_mdevent_declarations.py - DO NOT
  * EDIT! */
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h
index db2057aa2b565f664b72601e634d287fbf1e4fe9..4fd01d327a01cdeae1beb2df8bd28be544b34224 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h
@@ -50,7 +50,7 @@ private:
 
 public:
   /// Type of MDEvent used by the MDEventWorkspace.
-  typedef typename MDEW_SPTR::element_type::MDEventType MDEventType;
+  using MDEventType = typename MDEW_SPTR::element_type::MDEventType;
 
   /**
   Constructor
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
index 92669de6c7df410d226c30e572da8108132af1af..e29bdc73fd90c6f56d1c25699256203692ef1f96 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
@@ -35,9 +35,9 @@ class DLLExport MDEventWorkspace : public API::IMDEventWorkspace {
 
 public:
   /// Typedef for a shared pointer of this kind of event workspace
-  typedef boost::shared_ptr<MDEventWorkspace<MDE, nd>> sptr;
+  using sptr = boost::shared_ptr<MDEventWorkspace<MDE, nd>>;
   /// Typedef to access the MDEventType.
-  typedef MDE MDEventType;
+  using MDEventType = MDE;
 
   MDEventWorkspace(Mantid::API::MDNormalization preferredNormalization =
                        Mantid::API::MDNormalization::VolumeNormalization,
@@ -73,7 +73,7 @@ public:
   uint64_t getNEvents() const override { return getNPoints(); }
 
   /// Creates a new iterator pointing to the first cell (box) in the workspace
-  std::vector<Mantid::API::IMDIterator *> createIterators(
+  std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators(
       size_t suggestedNumCores = 1,
       Mantid::Geometry::MDImplicitFunction *function = nullptr) const override;
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
index 4db8da03a56159193e041a491bd12370ffa2724b..a67a2f30a5994f0942083ef6c2ae06d45b8f4804 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
@@ -239,7 +239,7 @@ TMDE(std::vector<coord_t> MDEventWorkspace)::estimateResolution() const {
  * @param suggestedNumCores :: split iterator over this many cores.
  * @param function :: Optional MDImplicitFunction limiting the iterator
  */
-TMDE(std::vector<Mantid::API::IMDIterator *> MDEventWorkspace)::createIterators(
+TMDE(std::vector<std::unique_ptr<Mantid::API::IMDIterator>> MDEventWorkspace)::createIterators(
     size_t suggestedNumCores,
     Mantid::Geometry::MDImplicitFunction *function) const {
   // Get all the boxes in this workspaces
@@ -261,13 +261,13 @@ TMDE(std::vector<Mantid::API::IMDIterator *> MDEventWorkspace)::createIterators(
     numCores = 1;
 
   // Create one iterator per core, splitting evenly amongst spectra
-  std::vector<API::IMDIterator *> out;
+  std::vector<std::unique_ptr<API::IMDIterator>> out;
   for (size_t i = 0; i < numCores; i++) {
     size_t begin = (i * numElements) / numCores;
     size_t end = ((i + 1) * numElements) / numCores;
     if (end > numElements)
       end = numElements;
-    out.push_back(new MDBoxIterator<MDE, nd>(boxes, begin, end));
+    out.push_back(Kernel::make_unique<MDBoxIterator<MDE, nd>>(boxes, begin, end));
   }
   return out;
 }
@@ -493,7 +493,7 @@ TMDE(Mantid::API::ITableWorkspace_sptr MDEventWorkspace)::makeBoxTable(
   }
 
   // Now sort by ID
-  typedef MDBoxBase<MDE, nd> *ibox_t;
+  using ibox_t = MDBoxBase<MDE, nd> *;
   std::sort(boxes_filtered.begin(), boxes_filtered.end(),
             SortBoxesByID<ibox_t>);
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h
index c45eda990df020fd20351c768b0ef1b43ff42c6c..5d83894a3a3fb2ca93c40957360fa5600141f33d 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h
@@ -205,10 +205,10 @@ public:
 
 public:
   /// Typedef for a shared pointer to a MDGridBox
-  typedef boost::shared_ptr<MDGridBox<MDE, nd>> sptr;
+  using sptr = boost::shared_ptr<MDGridBox<MDE, nd>>;
 
   /// Typedef for a vector of MDBoxBase pointers
-  typedef std::vector<MDBoxBase<MDE, nd> *> boxVector_t;
+  using boxVector_t = std::vector<MDBoxBase<MDE, nd> *>;
 
 private:
   /// Compute the index of the child box for the given event
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
index 5c4839ad64ce17e1010d86d3625d7df3b9dfe366..ae75cdc5c36ca47c59dc25a77dd320d60e2eb16b 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
@@ -78,7 +78,7 @@ public:
   uint64_t getNPoints() const override { return m_length; }
   /// get number of contributed events
   uint64_t getNEvents() const override;
-  std::vector<Mantid::API::IMDIterator *> createIterators(
+  std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators(
       size_t suggestedNumCores = 1,
       Mantid::Geometry::MDImplicitFunction *function = nullptr) const override;
 
@@ -174,7 +174,8 @@ public:
   void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction *function,
                              signal_t signal, signal_t errorSquared);
 
-  coord_t *getVertexesArray(size_t linearIndex, size_t &numVertices) const;
+  std::unique_ptr<coord_t[]> getVertexesArray(size_t linearIndex,
+                                              size_t &numVertices) const;
 
   Kernel::VMD getCenter(size_t linearIndex) const override;
 
@@ -426,7 +427,7 @@ private:
   }
 
   MDHistoWorkspace *doCloneEmpty() const override {
-    return new MDHistoWorkspace(0);
+    return new MDHistoWorkspace(nullptr);
   }
 
   void makeSingleBinWithNaN(std::vector<coord_t> &x, std::vector<signal_t> &y,
@@ -499,10 +500,10 @@ protected:
 };
 
 /// A shared pointer to a MDHistoWorkspace
-typedef boost::shared_ptr<MDHistoWorkspace> MDHistoWorkspace_sptr;
+using MDHistoWorkspace_sptr = boost::shared_ptr<MDHistoWorkspace>;
 
 /// A shared pointer to a const MDHistoWorkspace
-typedef boost::shared_ptr<const MDHistoWorkspace> MDHistoWorkspace_const_sptr;
+using MDHistoWorkspace_const_sptr = boost::shared_ptr<const MDHistoWorkspace>;
 
 } // namespace Mantid
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
index 6ff675621f9fbc430284a96964e4e2d73fa9878d..ea83dda0416fb7edc3038a740e1507965ab30c79 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h
@@ -15,12 +15,12 @@ namespace DataObjects {
 
 // Typedef for a map for mapping width of neighbours (key) to permutations
 // needed in the calcualtion.
-typedef std::map<std::vector<int>, std::vector<int64_t>> PermutationsMap;
+using PermutationsMap = std::map<std::vector<int>, std::vector<int64_t>>;
 // Typedef for extents
-typedef boost::tuple<Mantid::coord_t, Mantid::coord_t>
-    MDExtentPair; // Min/Max pair
+using MDExtentPair =
+    boost::tuple<Mantid::coord_t, Mantid::coord_t>; // Min/Max pair
 // Typedef for vector of extents
-typedef std::vector<MDExtentPair> VecMDExtents;
+using VecMDExtents = std::vector<MDExtentPair>;
 
 /** An implementation of IMDIterator that iterates through
   a MDHistoWorkspace. It treats the bin in the workspace as
@@ -95,10 +95,12 @@ public:
 
   signal_t getError() const override;
 
-  coord_t *getVertexesArray(size_t &numVertices) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices) const override;
 
-  coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions,
-                            const bool *maskDim) const override;
+  std::unique_ptr<coord_t[]>
+  getVertexesArray(size_t &numVertices, const size_t outDimensions,
+                   const bool *maskDim) const override;
 
   Mantid::Kernel::VMD getCenter() const override;
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h
index a71caabb1c74d5592080165ccf1956449922084d..5304998b667cc1097642b9c2a1908b8fb5620ec5 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h
@@ -64,10 +64,10 @@ private:
 };
 
 /// shared pointer to the MaskWorkspace class
-typedef boost::shared_ptr<MaskWorkspace> MaskWorkspace_sptr;
+using MaskWorkspace_sptr = boost::shared_ptr<MaskWorkspace>;
 
 /// shared pointer to a const MaskWorkspace
-typedef boost::shared_ptr<const MaskWorkspace> MaskWorkspace_const_sptr;
+using MaskWorkspace_const_sptr = boost::shared_ptr<const MaskWorkspace>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h
index b3108ad69bb35de929884c8be97edfe8dd98eca9..4b7fcfffa40e612d02f942d8ceef86a7a308dd7f 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h
@@ -48,10 +48,10 @@ private:
 };
 
 /// shared pointer to the OffsetsWorkspace class
-typedef boost::shared_ptr<OffsetsWorkspace> OffsetsWorkspace_sptr;
+using OffsetsWorkspace_sptr = boost::shared_ptr<OffsetsWorkspace>;
 
 /// shared pointer to a const OffsetsWorkspace
-typedef boost::shared_ptr<const OffsetsWorkspace> OffsetsWorkspace_const_sptr;
+using OffsetsWorkspace_const_sptr = boost::shared_ptr<const OffsetsWorkspace>;
 
 } // namespace Mantid
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
index 844c24758c2f33ae2755632c076465b42d2b1717..40ae08376c44336c13162fea741a17cc8f418ab4 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
@@ -86,7 +86,7 @@ public:
   Geometry::Instrument_const_sptr getInstrument() const override;
 
   bool findDetector() override;
-  bool findDetector(const Geometry::InstrumentRayTracer &tracer);
+  bool findDetector(const Geometry::InstrumentRayTracer &tracer) override;
 
   int getRunNumber() const override;
   void setRunNumber(int m_runNumber) override;
@@ -121,6 +121,7 @@ public:
   void setWavelength(double wavelength) override;
   double getWavelength() const override;
   double getScattering() const override;
+  double getAzimuthal() const override;
   double getDSpacing() const override;
   double getTOF() const override;
 
@@ -149,6 +150,8 @@ public:
   int getCol() const override;
   void setRow(int m_row);
   void setCol(int m_col);
+  void setPeakNumber(int m_peakNumber) override;
+  int getPeakNumber() const override;
 
   virtual Mantid::Kernel::V3D getDetPos() const override;
   double getL1() const override;
@@ -242,6 +245,9 @@ private:
   double m_orig_K;
   double m_orig_L;
 
+  // keep peak number
+  int m_peakNumber;
+
   /// List of contributing detectors IDs
   std::set<int> m_detIDs;
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h b/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
index 95384de57acf5f06813959d2f93af4b0a55bce9a..9f4c6beb8171c21b0d6ba2d4b8fec61f8d94c977 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h
@@ -78,7 +78,7 @@ private:
   int m_hklPrec;
 
   /// Type of the row cache value
-  typedef boost::variant<double, int, std::string, Kernel::V3D> CacheValueType;
+  using CacheValueType = boost::variant<double, int, std::string, Kernel::V3D>;
   ///
   mutable std::list<CacheValueType> m_oldRows;
   /// Sets the correct value in the referenced peak.
diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
index da9a6b7730aa76c9d5b517ae90cb798d158c6171..667a43d825a4a12d6bd93c8dc7b0a44c89b9f7a3 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
@@ -79,9 +79,9 @@ private:
   std::vector<double> m_abc_radiiBackgroundOuter;
 };
 
-typedef boost::shared_ptr<PeakShapeEllipsoid> PeakShapeEllipsoid_sptr;
-typedef boost::shared_ptr<const PeakShapeEllipsoid>
-    PeakShapeEllipsoid_const_sptr;
+using PeakShapeEllipsoid_sptr = boost::shared_ptr<PeakShapeEllipsoid>;
+using PeakShapeEllipsoid_const_sptr =
+    boost::shared_ptr<const PeakShapeEllipsoid>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h
index 020b05598dbacb7744147930338a8739b46dcab0..ae24f173e2d5ec4460b490b9da6bc25551ee18bb 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h
@@ -48,9 +48,9 @@ public:
 };
 
 /// Helper typedef
-typedef boost::shared_ptr<PeakShapeFactory> PeakShapeFactory_sptr;
+using PeakShapeFactory_sptr = boost::shared_ptr<PeakShapeFactory>;
 /// Helper typedef
-typedef boost::shared_ptr<const PeakShapeFactory> PeakShapeFactory_const_sptr;
+using PeakShapeFactory_const_sptr = boost::shared_ptr<const PeakShapeFactory>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
index bc2af2cc06c1170d179b4d2329080f1411ac66e2..055b61169a34ca967fae6372ea16b77e06da8415 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
@@ -295,10 +295,10 @@ private:
 };
 
 /// Typedef for a shared pointer to a peaks workspace.
-typedef boost::shared_ptr<PeaksWorkspace> PeaksWorkspace_sptr;
+using PeaksWorkspace_sptr = boost::shared_ptr<PeaksWorkspace>;
 
 /// Typedef for a shared pointer to a const peaks workspace.
-typedef boost::shared_ptr<const PeaksWorkspace> PeaksWorkspace_const_sptr;
+using PeaksWorkspace_const_sptr = boost::shared_ptr<const PeaksWorkspace>;
 }
 }
 #endif
diff --git a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
index 312b03d2be140505fbec6990681199f82efecd71..40f0aa5e3974d6e8564e9811b5bf3b7b039d8969 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h
@@ -97,9 +97,9 @@ private:
 };
 
 /// shared pointer to the RebinnedOutput class
-typedef boost::shared_ptr<RebinnedOutput> RebinnedOutput_sptr;
+using RebinnedOutput_sptr = boost::shared_ptr<RebinnedOutput>;
 /// shared pointer to a const RebinnedOutput
-typedef boost::shared_ptr<const RebinnedOutput> RebinnedOutput_const_sptr;
+using RebinnedOutput_const_sptr = boost::shared_ptr<const RebinnedOutput>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h b/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h
index 9f85163383ed7adda07f94aa7fa831f229c6f1bf..83e5f2cb2e6ea7938905138a61c76fc6b80b2ba2 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h
@@ -123,7 +123,7 @@ MANTID_DATAOBJECTS_DLL DetectorAngularCache
 initAngularCaches(const Mantid::API::MatrixWorkspace *const workspace);
 
 // Helper typedef for scoped pointer of this type.
-typedef boost::shared_ptr<ReflectometryTransform> ReflectometryTransform_sptr;
+using ReflectometryTransform_sptr = boost::shared_ptr<ReflectometryTransform>;
 }
 }
 #endif
diff --git a/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h b/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h
index 8762bb00b73d2c4c997a9833b32e7d4c1f1e39b8..294892336ce9829ca3b688c011a10abe411f7a95 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h
@@ -66,7 +66,7 @@ public:
   bool keepGoing() const override { return false; }
 };
 
-typedef boost::scoped_ptr<SkippingPolicy> SkippingPolicy_scptr;
+using SkippingPolicy_scptr = boost::scoped_ptr<SkippingPolicy>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h
index 651e261f3ce008ab2ee59e6e588eade1e1f4f4e9..4b19d5910323bca8b712261357f364c963397d2f 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h
@@ -89,11 +89,11 @@ protected:
 };
 
 /// shared pointer to the SpecialWorkspace2D class
-typedef boost::shared_ptr<SpecialWorkspace2D> SpecialWorkspace2D_sptr;
+using SpecialWorkspace2D_sptr = boost::shared_ptr<SpecialWorkspace2D>;
 
 /// shared pointer to a const SpecialWorkspace2D
-typedef boost::shared_ptr<const SpecialWorkspace2D>
-    SpecialWorkspace2D_const_sptr;
+using SpecialWorkspace2D_const_sptr =
+    boost::shared_ptr<const SpecialWorkspace2D>;
 
 } // namespace Mantid
 } // namespace DataObjects
diff --git a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h
index ac998ac153f223682d2b9a06fbe4f4bfdb90d764..2821ec983c542fd6d88f44f24e3fe189f6f66853 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h
@@ -81,9 +81,9 @@ private:
   }
 };
 
-typedef boost::shared_ptr<SplittersWorkspace> SplittersWorkspace_sptr;
-typedef boost::shared_ptr<const SplittersWorkspace>
-    SplittersWorkspace_const_sptr;
+using SplittersWorkspace_sptr = boost::shared_ptr<SplittersWorkspace>;
+using SplittersWorkspace_const_sptr =
+    boost::shared_ptr<const SplittersWorkspace>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
index eee53c5d06d2f59a36c2c73ff0dc385975b8b6aa..b6c071a889d0a978f0c9e83a9304405fe9208d8e 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h
@@ -142,9 +142,9 @@ public:
    * @param value :: The value of the element.
    */
   template <typename T> double convertToDouble(const T &value) const {
-    typedef
+    using DoubleType =
         typename std::conditional<std::is_convertible<double, T>::value, T,
-                                  InconvertibleToDoubleType>::type DoubleType;
+                                  InconvertibleToDoubleType>::type;
     return boost::numeric_cast<double, DoubleType>(value);
   }
 
@@ -175,9 +175,9 @@ public:
    * @param value: cast this value
    */
   void fromDouble(size_t i, double value) override {
-    typedef typename std::conditional<std::is_convertible<double, Type>::value,
-                                      Type, InconvertibleToDoubleType>::type
-        DoubleType;
+    using DoubleType =
+        typename std::conditional<std::is_convertible<double, Type>::value,
+                                  Type, InconvertibleToDoubleType>::type;
     m_data[i] =
         static_cast<Type>(boost::numeric_cast<DoubleType, double>(value));
   }
diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
index 20fa71db955e8e044bc21534e52779e5b3cbf711..d893a30fab61e52111de44545f46beb7441a1167 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h
@@ -410,10 +410,13 @@ private:
     }
   };
 
-  typedef std::vector<boost::shared_ptr<API::Column>>::iterator
-      column_it; ///< Column iterator
-  typedef std::vector<boost::shared_ptr<API::Column>>::const_iterator
-      column_const_it; ///< Column const iterator
+  using column_it = std::vector<
+      boost::shared_ptr<API::Column>>::iterator; ///< Column iterator
+
+  ///< Column const iterator
+  using column_const_it =
+      std::vector<boost::shared_ptr<API::Column>>::const_iterator;
+
   /// Shared pointers to the columns.
   std::vector<boost::shared_ptr<API::Column>> m_columns;
   /// row count
@@ -425,10 +428,11 @@ private:
 };
 
 /// Typedef for a shared pointer to \c TableWorkspace
-typedef boost::shared_ptr<TableWorkspace> TableWorkspace_sptr;
+using TableWorkspace_sptr = boost::shared_ptr<TableWorkspace>;
 /// Typedef for a shared pointer to \c const \c TableWorkspace
-typedef boost::shared_ptr<const TableWorkspace> TableWorkspace_const_sptr;
+using TableWorkspace_const_sptr = boost::shared_ptr<const TableWorkspace>;
 
 } // namespace DataObjects
-} // Namespace Mantid
+} // namespace Mantid
+
 #endif /*MANTID_DATAOBJECTS_TABLEWORKSPACE_H_*/
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h
index 7e5a075d581f72a76818c765b7458a7d90a8dddb..4eda3b3d66554cd70a6d4171873087957a6198d0 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h
@@ -118,9 +118,9 @@ private:
 };
 
 /// shared pointer to the Workspace2D class
-typedef boost::shared_ptr<Workspace2D> Workspace2D_sptr;
+using Workspace2D_sptr = boost::shared_ptr<Workspace2D>;
 /// shared pointer to a const Workspace2D
-typedef boost::shared_ptr<const Workspace2D> Workspace2D_const_sptr;
+using Workspace2D_const_sptr = boost::shared_ptr<const Workspace2D>;
 
 } // namespace DataObjects
 } // Namespace Mantid
diff --git a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h
index 343e7f218e1d1cc56fd45ac3aef6a59a5edb8668..539bcd16ab3549eb23a61d55179958a1556f474d 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h
@@ -96,9 +96,9 @@ private:
 };
 
 /// shared pointer to the WorkspaceSingleValue class
-typedef boost::shared_ptr<WorkspaceSingleValue> WorkspaceSingleValue_sptr;
-typedef boost::shared_ptr<const WorkspaceSingleValue>
-    WorkspaceSingleValue_const_sptr;
+using WorkspaceSingleValue_sptr = boost::shared_ptr<WorkspaceSingleValue>;
+using WorkspaceSingleValue_const_sptr =
+    boost::shared_ptr<const WorkspaceSingleValue>;
 
 } // namespace DataObjects
 } // namespace Mantid
diff --git a/Framework/DataObjects/src/AffineMatrixParameterParser.cpp b/Framework/DataObjects/src/AffineMatrixParameterParser.cpp
index 0f60ea75a535a686ffb05d0470ceb90d7c017f6d..bdae316f167643deb6e47d2add542c453ad58cf3 100644
--- a/Framework/DataObjects/src/AffineMatrixParameterParser.cpp
+++ b/Framework/DataObjects/src/AffineMatrixParameterParser.cpp
@@ -17,8 +17,8 @@ AffineMatrixParameter *AffineMatrixParameterParser::createParameter(
         typeName));
   } else {
     // Convenience typedefs
-    typedef std::vector<std::string> VecStrings;
-    typedef std::vector<coord_t> VecDoubles;
+    using VecStrings = std::vector<std::string>;
+    using VecDoubles = std::vector<coord_t>;
 
     std::string sParameterValue =
         parameterElement->getChildElement("Value")->innerText();
diff --git a/Framework/DataObjects/src/CoordTransformAffineParser.cpp b/Framework/DataObjects/src/CoordTransformAffineParser.cpp
index a6acc7ad9ca20f75a128c6b52a296c49be0dd7c5..713e53cf6d294e4f9a69b95158776c7843b8ec2e 100644
--- a/Framework/DataObjects/src/CoordTransformAffineParser.cpp
+++ b/Framework/DataObjects/src/CoordTransformAffineParser.cpp
@@ -20,10 +20,10 @@ Create the transform object.
 */
 Mantid::API::CoordTransform *CoordTransformAffineParser::createTransform(
     Poco::XML::Element *coordTransElement) const {
-  typedef Mantid::API::SingleValueParameterParser<Mantid::API::InDimParameter>
-      InDimParameterParser;
-  typedef Mantid::API::SingleValueParameterParser<Mantid::API::OutDimParameter>
-      OutDimParameterParser;
+  using InDimParameterParser =
+      Mantid::API::SingleValueParameterParser<Mantid::API::InDimParameter>;
+  using OutDimParameterParser =
+      Mantid::API::SingleValueParameterParser<Mantid::API::OutDimParameter>;
   using namespace Poco::XML;
   if ("CoordTransform" != coordTransElement->localName()) {
     std::string message = "This is not a coordinate transform element: " +
diff --git a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp
index 5d2e2c963f33fb63f79dafe137503869cffae514..d5776a7c5ab975b28b5a6bb5d00d28ff5eb82b26 100644
--- a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp
+++ b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp
@@ -17,14 +17,14 @@ Create the transform object.
 Mantid::API::CoordTransform *CoordTransformDistanceParser::createTransform(
     Poco::XML::Element *coordTransElement) const {
   // Typdef the parameter parsers required.
-  typedef Mantid::API::SingleValueParameterParser<Mantid::API::InDimParameter>
-      InDimParameterParser;
-  typedef Mantid::API::SingleValueParameterParser<Mantid::API::OutDimParameter>
-      OutDimParameterParser;
-  typedef Mantid::API::VectorParameterParser<CoordCenterVectorParam>
-      CoordCenterParser;
-  typedef Mantid::API::VectorParameterParser<DimensionsUsedVectorParam>
-      DimsUsedParser;
+  using InDimParameterParser =
+      Mantid::API::SingleValueParameterParser<Mantid::API::InDimParameter>;
+  using OutDimParameterParser =
+      Mantid::API::SingleValueParameterParser<Mantid::API::OutDimParameter>;
+  using CoordCenterParser =
+      Mantid::API::VectorParameterParser<CoordCenterVectorParam>;
+  using DimsUsedParser =
+      Mantid::API::VectorParameterParser<DimensionsUsedVectorParam>;
 
   using namespace Poco::XML;
   if ("CoordTransform" != coordTransElement->localName()) {
diff --git a/Framework/DataObjects/src/FakeMD.cpp b/Framework/DataObjects/src/FakeMD.cpp
index 9de20b32894dd4d4be43151e43f20d2aab49fbb9..353653c1f7ac1d5e61e4e4d0f36c8c94cc545b6e 100644
--- a/Framework/DataObjects/src/FakeMD.cpp
+++ b/Framework/DataObjects/src/FakeMD.cpp
@@ -11,9 +11,6 @@
 #include "MantidKernel/ThreadScheduler.h"
 #include "MantidKernel/Utils.h"
 
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-
 namespace Mantid {
 namespace DataObjects {
 
@@ -66,7 +63,8 @@ void FakeMD::setupDetectorCache(const API::IMDEventWorkspace &workspace) {
     auto inst = workspace.getExperimentInfo(0)->getInstrument();
     m_detIDs = inst->getDetectorIDs(true); // true=skip monitors
     size_t max = m_detIDs.size() - 1;
-    m_uniformDist = boost::uniform_int<size_t>(0, max); // Includes max
+    m_uniformDist =
+        Kernel::uniform_int_distribution<size_t>(0, max); // Includes max
   } catch (std::invalid_argument &) {
   }
 }
@@ -89,11 +87,8 @@ void FakeMD::addFakePeak(typename MDEventWorkspace<MDE, nd>::sptr ws) {
   // Width of the peak
   double desiredRadius = m_peakParams.back();
 
-  boost::mt19937 rng;
-  boost::uniform_real<coord_t> u2(0, 1.0); // Random from 0 to 1.0
-  boost::variate_generator<boost::mt19937 &, boost::uniform_real<coord_t>>
-      genUnit(rng, u2);
-  rng.seed(static_cast<unsigned int>(m_randomSeed));
+  std::mt19937 rng(static_cast<unsigned int>(m_randomSeed));
+  std::uniform_real_distribution<coord_t> flat(0, 1.0);
 
   // Inserter to help choose the correct event type
   auto eventHelper =
@@ -108,7 +103,7 @@ void FakeMD::addFakePeak(typename MDEventWorkspace<MDE, nd>::sptr ws) {
     coord_t centers[nd];
     coord_t radiusSquared = 0;
     for (size_t d = 0; d < nd; d++) {
-      centers[d] = genUnit() - 0.5f; // Distribute around +- the center
+      centers[d] = flat(rng) - 0.5f; // Distribute around +- the center
       radiusSquared += centers[d] * centers[d];
     }
 
@@ -118,7 +113,7 @@ void FakeMD::addFakePeak(typename MDEventWorkspace<MDE, nd>::sptr ws) {
       centers[d] /= radius;
 
     // Now place the point along this radius, scaled with ^1/n for uniformity.
-    coord_t radPos = genUnit();
+    coord_t radPos = flat(rng);
     radPos = static_cast<coord_t>(
         pow(radPos, static_cast<coord_t>(1.0 / static_cast<coord_t>(nd))));
     for (size_t d = 0; d < nd; d++) {
@@ -132,8 +127,8 @@ void FakeMD::addFakePeak(typename MDEventWorkspace<MDE, nd>::sptr ws) {
     float signal = 1.0;
     float errorSquared = 1.0;
     if (m_randomizeSignal) {
-      signal = float(0.5 + genUnit());
-      errorSquared = float(0.5 + genUnit());
+      signal = float(0.5 + flat(rng));
+      errorSquared = float(0.5 + flat(rng));
     }
 
     // Create and add the event.
@@ -227,59 +222,42 @@ void FakeMD::addFakeRandomData(const std::vector<double> &params,
     throw std::invalid_argument(
         " number of distributed events can not be equal to 0");
 
-  boost::mt19937 rng;
-  rng.seed(static_cast<unsigned int>(m_randomSeed));
-
-  // Unit-size randomizer
-  boost::uniform_real<double> u2(0, 1.0); // Random from 0 to 1.0
-  boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>>
-      genUnit(rng, u2);
-
-  // Make a random generator for each dimensions
-  typedef boost::variate_generator<boost::mt19937 &,
-                                   boost::uniform_real<double>> gen_t;
-
   // Inserter to help choose the correct event type
   auto eventHelper =
       MDEventInserter<typename MDEventWorkspace<MDE, nd>::sptr>(ws);
 
-  gen_t *gens[nd];
+  // Array of distributions for each dimension
+  std::mt19937 rng(static_cast<unsigned int>(m_randomSeed));
+  std::array<std::uniform_real_distribution<double>, nd> gens;
   for (size_t d = 0; d < nd; ++d) {
     double min = params[d * 2 + 1];
     double max = params[d * 2 + 2];
     if (max <= min)
       throw std::invalid_argument(
           "UniformParams: min must be < max for all dimensions.");
-
-    boost::uniform_real<double> u(min, max); // Range
-    auto gen = new gen_t(rng, u);
-    gens[d] = gen;
+    gens[d] = std::uniform_real_distribution<double>(min, max);
   }
-
+  // Unit-size randomizer
+  std::uniform_real_distribution<double> flat(0, 1.0); // Random from 0 to 1.0
   // Create all the requested events
   for (size_t i = 0; i < num; ++i) {
     coord_t centers[nd];
     for (size_t d = 0; d < nd; d++) {
-      centers[d] = static_cast<coord_t>(
-          (*gens[d])()); // use a different generator for each dimension
+      centers[d] = static_cast<coord_t>(gens[d](rng));
     }
 
     // Default or randomized error/signal
     float signal = 1.0;
     float errorSquared = 1.0;
     if (m_randomizeSignal) {
-      signal = float(0.5 + genUnit());
-      errorSquared = float(0.5 + genUnit());
+      signal = float(0.5 + flat(rng));
+      errorSquared = float(0.5 + flat(rng));
     }
 
     // Create and add the event.
     eventHelper.insertMDEvent(signal, errorSquared, 0, pickDetectorID(),
                               centers); // 0 = run index
   }
-
-  /// Clean up the generators
-  for (size_t d = 0; d < nd; ++d)
-    delete gens[d];
 }
 
 template <typename MDE, size_t nd>
@@ -363,13 +341,7 @@ detid_t FakeMD::pickDetectorID() {
   if (m_detIDs.empty()) {
     return -1;
   } else {
-    /// A variate generator to combine a random number generator with a
-    /// distribution
-    typedef boost::variate_generator<
-        boost::mt19937 &, boost::uniform_int<size_t>> uniform_generator;
-    uniform_generator uniformRand(m_randGen, m_uniformDist);
-    const size_t randIndex = uniformRand();
-    return m_detIDs[randIndex];
+    return m_detIDs[m_uniformDist(m_randGen)];
   }
 }
 
diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp
index 4bad6f9ee0873660fbc9b21095ea54ce8e5ff5b9..6e9ee3b1a49dbdad84d1246ae4a98979182efdbc 100644
--- a/Framework/DataObjects/src/FractionalRebinning.cpp
+++ b/Framework/DataObjects/src/FractionalRebinning.cpp
@@ -152,9 +152,9 @@ double polyArea(T &v1, T &v2, Ts &&... vertices) {
  * @param yAxis The output data vertical axis
  * @param inputQ The input quadrilateral
  * @param y_start The starting y-axis index
- * @param y_end The starting y-axis index
+ * @param y_end The ending y-axis index
  * @param x_start The starting x-axis index
- * @param x_end The starting x-axis index
+ * @param x_end The ending x-axis index
  * @param areaInfo Output vector of indices and areas of overlapping bins
  */
 void calcTrapezoidYIntersections(
@@ -202,8 +202,8 @@ void calcTrapezoidYIntersections(
   // Step 1 - construct the left/right bin lims on the lines of the y-grid.
   const double NaN = std::numeric_limits<double>::quiet_NaN();
   const double DBL_EPS = std::numeric_limits<double>::epsilon();
-  std::vector<double> leftLim(nx * (ny + 1), NaN);
-  std::vector<double> rightLim(nx * (ny + 1), NaN);
+  std::vector<double> leftLim((nx + 1) * (ny + 1), NaN);
+  std::vector<double> rightLim((nx + 1) * (ny + 1), NaN);
   auto x0_it = xAxis.begin() + x_start;
   auto x1_it = xAxis.begin() + x_end + 1;
   auto y0_it = yAxis.begin() + y_start;
@@ -239,7 +239,7 @@ void calcTrapezoidYIntersections(
       auto right_it = std::upper_bound(x0_it, x1_it, right_val);
       if (right_it != x1_it) {
         rightLim[right_it - x0_it - 1 + yjx] = right_val;
-      } else if (yAxis[yj + y_start] < ur_y) {
+      } else if (yAxis[yj + y_start] < ur_y && nx > 0) {
         right_it = x1_it - 1;
         rightLim[nx - 1 + yjx] = lr_x;
       }
@@ -277,12 +277,15 @@ void calcTrapezoidYIntersections(
         left_it--;
       if (right_it == x1_it)
         right_it--;
-      size_t li = left_it - x0_it - 1;
+      size_t li = (left_it > x0_it) ? (left_it - x0_it - 1) : 0;
+      size_t ri = (right_it > x0_it) ? (right_it - x0_it - 1) : 0;
       leftLim[li + yjx] = (mTop >= 0) ? val : ll_x;
-      rightLim[right_it - x0_it - 1 + yjx] = (mTop >= 0) ? lr_x : val;
-      for (auto x_it = left_it; x_it != right_it; x_it++) {
-        leftLim[li + 1 + yjx] = *x_it;
-        rightLim[li++ + yjx] = *x_it;
+      rightLim[ri + yjx] = (mTop >= 0) ? lr_x : val;
+      if (left_it < right_it && right_it != x1_it) {
+        for (auto x_it = left_it; x_it != right_it; x_it++) {
+          leftLim[li + 1 + yjx] = *x_it;
+          rightLim[li++ + yjx] = *x_it;
+        }
       }
     }
   }
@@ -478,6 +481,8 @@ void calcGeneralIntersections(
 void normaliseOutput(MatrixWorkspace_sptr outputWS,
                      MatrixWorkspace_const_sptr inputWS,
                      boost::shared_ptr<Progress> progress) {
+  const bool removeBinWidth(inputWS->isDistribution() &&
+                            outputWS->id() != "RebinnedOutput");
   for (int64_t i = 0; i < static_cast<int64_t>(outputWS->getNumberHistograms());
        ++i) {
     const auto &outputX = outputWS->x(i);
@@ -487,7 +492,7 @@ void normaliseOutput(MatrixWorkspace_sptr outputWS,
       if (progress)
         progress->report("Calculating errors");
       double eValue = std::sqrt(outputE[j]);
-      if (inputWS->isDistribution()) {
+      if (removeBinWidth) {
         const double binWidth = outputX[j + 1] - outputX[j];
         outputY[j] /= binWidth;
         eValue /= binWidth;
@@ -599,11 +604,15 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ,
 
   // If the input workspace was normalized by the bin width, we need to
   // recover the original Y value, we do it by 'removing' the bin width
+  // Don't do the overlap removal if already RebinnedOutput.
+  // This wreaks havoc on the data.
   double error = inE[j];
-  if (inputWS->isDistribution()) {
+  double inputWeight = 1.;
+  if (inputWS->isDistribution() && !inputRB) {
     const double overlapWidth = inX[j + 1] - inX[j];
     signal *= overlapWidth;
     error *= overlapWidth;
+    inputWeight = overlapWidth;
   }
 
   // The intersection overlap algorithm is relatively costly. The outputQ is
@@ -626,7 +635,6 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ,
 
   // If the input is a RebinnedOutput workspace with frac. area we need
   // to account for the weight of the input bin in the output bin weights
-  double inputWeight = 1.;
   if (inputRB) {
     const auto &inF = inputRB->dataF(i);
     inputWeight = inF[j];
diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp
index 7a9232e17ff28a54448c6285e29f13da33762e64..b350f07c9ea0bada433807b280de03dee8997d5e 100644
--- a/Framework/DataObjects/src/MDBoxFlatTree.cpp
+++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp
@@ -8,7 +8,7 @@
 #include "MantidKernel/Strings.h"
 #include <Poco/File.h>
 
-typedef std::unique_ptr<::NeXus::File> file_holder_type;
+using file_holder_type = std::unique_ptr<::NeXus::File>;
 
 namespace Mantid {
 namespace DataObjects {
diff --git a/Framework/DataObjects/src/MDHistoWorkspace.cpp b/Framework/DataObjects/src/MDHistoWorkspace.cpp
index 0ee1c53816899dad502f6af9bcbc9939187ca45f..d93a75a35536329e5dcba2abe0abe0dcf270616d 100644
--- a/Framework/DataObjects/src/MDHistoWorkspace.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspace.cpp
@@ -1,21 +1,22 @@
+#include "MantidDataObjects/MDHistoWorkspace.h"
+#include "MantidAPI/IMDIterator.h"
+#include "MantidAPI/IMDWorkspace.h"
+#include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h"
+#include "MantidDataObjects/MDHistoWorkspaceIterator.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
+#include "MantidGeometry/MDGeometry/MDDimensionExtents.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
+#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Utils.h"
 #include "MantidKernel/VMD.h"
 #include "MantidKernel/WarningSuppressions.h"
-#include "MantidDataObjects/MDHistoWorkspace.h"
-#include "MantidDataObjects/MDHistoWorkspaceIterator.h"
-#include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h"
-#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
-#include "MantidGeometry/MDGeometry/MDDimensionExtents.h"
-#include <map>
-#include "MantidAPI/IMDWorkspace.h"
-#include "MantidAPI/IMDIterator.h"
-#include <boost/scoped_array.hpp>
+#include "MantidKernel/make_unique.h"
 #include <boost/make_shared.hpp>
 #include <boost/optional.hpp>
+#include <boost/scoped_array.hpp>
 #include <cmath>
+#include <map>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::Geometry;
@@ -303,8 +304,9 @@ void MDHistoWorkspace::applyImplicitFunction(
  * @param[out] numVertices :: returns the number of vertices in the array.
  * @return the bare array. This should be deleted by the caller!
  * */
-coord_t *MDHistoWorkspace::getVertexesArray(size_t linearIndex,
-                                            size_t &numVertices) const {
+std::unique_ptr<coord_t[]>
+MDHistoWorkspace::getVertexesArray(size_t linearIndex,
+                                   size_t &numVertices) const {
   // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd
   // bits
   numVertices = static_cast<size_t>(1)
@@ -319,7 +321,7 @@ coord_t *MDHistoWorkspace::getVertexesArray(size_t linearIndex,
       numDimensions, linearIndex, m_indexMaker, m_indexMax, dimIndexes);
 
   // The output vertexes coordinates
-  auto out = new coord_t[numDimensions * numVertices];
+  auto out = Kernel::make_unique<coord_t[]>(numDimensions * numVertices);
   for (size_t i = 0; i < numVertices; ++i) {
     size_t outIndex = i * numDimensions;
     // Offset the 0th box by the position of this linear index, in each
@@ -421,7 +423,8 @@ size_t MDHistoWorkspace::getLinearIndexAtCoord(const coord_t *coords) const {
  *call.
  * @return MDHistoWorkspaceIterator vector
  */
-std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators(
+std::vector<std::unique_ptr<Mantid::API::IMDIterator>>
+MDHistoWorkspace::createIterators(
     size_t suggestedNumCores,
     Mantid::Geometry::MDImplicitFunction *function) const {
   size_t numCores = suggestedNumCores;
@@ -434,7 +437,7 @@ std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators(
     numCores = 1;
 
   // Create one iterator per core, splitting evenly amongst spectra
-  std::vector<IMDIterator *> out;
+  std::vector<std::unique_ptr<IMDIterator>> out;
   for (size_t i = 0; i < numCores; i++) {
     size_t begin = (i * numElements) / numCores;
     size_t end = ((i + 1) * numElements) / numCores;
@@ -446,8 +449,8 @@ std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators(
     if (function)
       clonedFunction = new Mantid::Geometry::MDImplicitFunction(*function);
 
-    out.push_back(
-        new MDHistoWorkspaceIterator(this, clonedFunction, begin, end));
+    out.push_back(Kernel::make_unique<MDHistoWorkspaceIterator>(
+        this, clonedFunction, begin, end));
   }
   return out;
 }
diff --git a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
index 03277600b8d0619d9ed03d099bf8930f339f51a0..ffc3b2e39ef24328476f619e0d4a7b0470072975 100644
--- a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp
@@ -384,14 +384,16 @@ signal_t MDHistoWorkspaceIterator::getError() const {
 }
 //----------------------------------------------------------------------------------------------
 /// Return a list of vertexes defining the volume pointed to
-coord_t *MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const {
+std::unique_ptr<coord_t[]>
+MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const {
   // The MDHistoWorkspace takes care of this
   return m_ws->getVertexesArray(m_pos, numVertices);
 }
 
-coord_t *MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices,
-                                                    const size_t outDimensions,
-                                                    const bool *maskDim) const {
+std::unique_ptr<coord_t[]>
+MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices,
+                                           const size_t outDimensions,
+                                           const bool *maskDim) const {
   // Do the same thing as is done in the MDBoxBase
   UNUSED_ARG(numVertices);
   UNUSED_ARG(outDimensions);
diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp
index f0607804cd6d7735c60db7e329c1c3fcfcb87c95..a0fbcb21920c6f1b70cd9d041558fe0b3b9a7af9 100644
--- a/Framework/DataObjects/src/Peak.cpp
+++ b/Framework/DataObjects/src/Peak.cpp
@@ -29,7 +29,7 @@ Peak::Peak()
       m_finalEnergy(0.), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
       m_row(-1), m_col(-1), m_orig_H(0), m_orig_K(0), m_orig_L(0),
-      m_peakShape(boost::make_shared<NoShape>()) {
+      m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
 }
 
@@ -49,7 +49,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
@@ -76,7 +76,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(goniometer),
       m_InverseGoniometerMatrix(goniometer), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
@@ -99,7 +99,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID,
     : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
       m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
@@ -121,7 +121,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID,
     : m_H(HKL[0]), m_K(HKL[1]), m_L(HKL[2]), m_intensity(0),
       m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
@@ -145,7 +145,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID,
     : m_H(HKL[0]), m_K(HKL[1]), m_L(HKL[2]), m_intensity(0),
       m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(goniometer),
       m_InverseGoniometerMatrix(goniometer), m_runNumber(0), m_monitorCount(0),
-      m_orig_H(0), m_orig_K(0), m_orig_L(0),
+      m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
@@ -169,7 +169,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, double scattering,
       m_binCount(0), m_GoniometerMatrix(3, 3, true),
       m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0),
       m_row(-1), m_col(-1), m_orig_H(0), m_orig_K(0), m_orig_L(0),
-      m_peakShape(boost::make_shared<NoShape>()) {
+      m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   this->setInstrument(m_inst);
   this->setWavelength(m_Wavelength);
@@ -197,8 +197,9 @@ Peak::Peak(const Peak &other)
       m_row(other.m_row), m_col(other.m_col), sourcePos(other.sourcePos),
       samplePos(other.samplePos), detPos(other.detPos),
       m_orig_H(other.m_orig_H), m_orig_K(other.m_orig_K),
-      m_orig_L(other.m_orig_L), m_detIDs(other.m_detIDs),
-      m_peakShape(other.m_peakShape->clone()), convention(other.convention) {}
+      m_orig_L(other.m_orig_L), m_peakNumber(other.m_peakNumber),
+      m_detIDs(other.m_detIDs), m_peakShape(other.m_peakShape->clone()),
+      convention(other.convention) {}
 
 //----------------------------------------------------------------------------------------------
 /** Constructor making a Peak from IPeak interface
@@ -218,6 +219,7 @@ Peak::Peak(const Geometry::IPeak &ipeak)
       m_runNumber(ipeak.getRunNumber()),
       m_monitorCount(ipeak.getMonitorCount()), m_row(ipeak.getRow()),
       m_col(ipeak.getCol()), m_orig_H(0.), m_orig_K(0.), m_orig_L(0.),
+      m_peakNumber(ipeak.getPeakNumber()),
       m_peakShape(boost::make_shared<NoShape>()) {
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
@@ -422,6 +424,15 @@ double Peak::getScattering() const {
   return detDir.angle(beamDir);
 }
 
+// -------------------------------------------------------------------------------------
+/** Calculate the azimuthal angle of the peak  */
+double Peak::getAzimuthal() const {
+  // The detector is at 2 theta scattering angle
+  V3D detDir = detPos - samplePos;
+
+  return atan2(detDir.Y(), detDir.X());
+}
+
 // -------------------------------------------------------------------------------------
 /** Calculate the d-spacing of the peak, in 1/Angstroms  */
 double Peak::getDSpacing() const {
@@ -628,6 +639,14 @@ bool Peak::findDetector() {
   return findDetector(tracer);
 }
 
+/**
+ * Performs the same algorithm as findDetector() but uses a pre-existing
+ * InstrumentRayTracer object to be able to take adavtange of its caches.
+ * This method should be preferred if findDetector is to be called many times
+ * over the same instrument.
+ * @param tracer A reference to an existing InstrumentRayTracer object.
+ * @return true if the detector ID was found.
+ */
 bool Peak::findDetector(const InstrumentRayTracer &tracer) {
   // Scattered beam direction
   V3D beam = detPos - samplePos;
@@ -870,6 +889,11 @@ int Peak::getRow() const { return m_row; }
  * Returns -1 if it could not find it. */
 int Peak::getCol() const { return m_col; }
 
+// -------------------------------------------------------------------------------------
+/**Returns the unique peak number
+ * Returns -1 if it could not find it. */
+int Peak::getPeakNumber() const { return m_peakNumber; }
+
 // -------------------------------------------------------------------------------------
 /** For RectangularDetectors only, sets the row (y) of the pixel of the
  * detector.
@@ -882,6 +906,13 @@ void Peak::setRow(int m_row) { this->m_row = m_row; }
  * @param m_col :: col value   */
 void Peak::setCol(int m_col) { this->m_col = m_col; }
 
+// -------------------------------------------------------------------------------------
+/** Sets the unique peak number
+ * @param m_peakNumber :: unique peak number value   */
+void Peak::setPeakNumber(int m_peakNumber) {
+  this->m_peakNumber = m_peakNumber;
+}
+
 // -------------------------------------------------------------------------------------
 /** Return the detector position vector */
 Mantid::Kernel::V3D Peak::getDetPos() const { return detPos; }
@@ -933,6 +964,8 @@ double Peak::getValueByColName(const std::string &name_in) const {
     return this->getRow();
   else if (name == "col")
     return this->getCol();
+  else if (name == "peaknumber")
+    return double(this->getPeakNumber());
   else
     throw std::runtime_error(
         "Peak::getValueByColName() unknown column or column is not a number: " +
diff --git a/Framework/DataObjects/src/PeakColumn.cpp b/Framework/DataObjects/src/PeakColumn.cpp
index 57a6634f4b223d96b97b4c53539eb4fbaa38db1d..891e199908ab275e30a2c6c570e9b6ddc761bbf9 100644
--- a/Framework/DataObjects/src/PeakColumn.cpp
+++ b/Framework/DataObjects/src/PeakColumn.cpp
@@ -31,7 +31,7 @@ const std::string typeFromName(const std::string &name) {
   // We should enter the critical section if the map has not been fully filled.
   // Be sure to keep the value tested against in sync with the number of inserts
   // below
-  if (TYPE_INDEX.size() != 17) {
+  if (TYPE_INDEX.size() != 18) {
     PARALLEL_CRITICAL(fill_column_index_map) {
       if (TYPE_INDEX.empty()) // check again inside the critical block
       {
@@ -53,6 +53,7 @@ const std::string typeFromName(const std::string &name) {
         TYPE_INDEX.emplace("Col", "double");
         TYPE_INDEX.emplace("QLab", "V3D");
         TYPE_INDEX.emplace("QSample", "V3D");
+        TYPE_INDEX.emplace("PeakNumber", "int");
         // If adding an entry, be sure to increment the size comparizon in the
         // first line
       }
@@ -152,6 +153,8 @@ void PeakColumn::print(size_t index, std::ostream &s) const {
     s << std::fixed << std::setprecision(m_hklPrec) << peak.getK();
   } else if (m_name == "l") {
     s << std::fixed << std::setprecision(m_hklPrec) << peak.getL();
+  } else if (m_name == "PeakNumber") {
+    s << peak.getPeakNumber();
   } else
     s << peak.getValueByColName(m_name);
   s.flags(fflags);
@@ -291,6 +294,9 @@ const void *PeakColumn::void_pointer(size_t index) const {
   } else if (m_name == "RunNumber") {
     value = peak.getRunNumber();
     return boost::get<int>(&value);
+  } else if (m_name == "PeakNumber") {
+    value = peak.getPeakNumber();
+    return boost::get<int>(&value);
   } else if (m_name == "DetID") {
     value = peak.getDetectorID();
     return boost::get<int>(&value);
diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp
index eab92ec1da6acffa556b7c14a23d8dce15c316f5..a4708efa97b393b349f6880997cf9c5600f87aa5 100644
--- a/Framework/DataObjects/src/PeaksWorkspace.cpp
+++ b/Framework/DataObjects/src/PeaksWorkspace.cpp
@@ -16,6 +16,7 @@
 #include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/Quat.h"
 #include "MantidKernel/Unit.h"
+#include "MantidKernel/UnitConversion.h"
 #include "MantidKernel/V3D.h"
 
 #include <algorithm>
@@ -39,6 +40,8 @@ namespace DataObjects {
 /// Register the workspace as a type
 DECLARE_WORKSPACE(PeaksWorkspace)
 
+Mantid::Kernel::Logger g_log("PeaksWorkspace");
+
 //---------------------------------------------------------------------------------------------
 /** Constructor. Create a table with all the required columns.
  *
@@ -162,8 +165,8 @@ void PeaksWorkspace::removePeaks(std::vector<int> badPeaks) {
       std::remove_if(peaks.begin(), peaks.end(), [&ip, badPeaks](Peak &pk) {
         (void)pk;
         ip++;
-        for (auto ibp = badPeaks.begin(); ibp != badPeaks.end(); ++ibp) {
-          if (*ibp == ip)
+        for (int badPeak : badPeaks) {
+          if (badPeak == ip)
             return true;
         }
         return false;
@@ -278,7 +281,29 @@ PeaksWorkspace::createPeak(const Kernel::V3D &position,
  */
 Peak *PeaksWorkspace::createPeakQSample(const V3D &position) const {
   // Create a peak from QSampleFrame
-  const auto goniometer = run().getGoniometer();
+
+  Geometry::Goniometer goniometer;
+
+  LogManager_const_sptr props = getLogs();
+  if (props->hasProperty("wavelength") || props->hasProperty("energy")) {
+    // Assume constant wavelenth
+    // Calculate Q lab from Q sample and wavelength
+    double wavelength;
+    if (props->hasProperty("energy")) {
+      wavelength = Kernel::UnitConversion::run(
+          "Energy", "Wavelength",
+          props->getPropertyValueAsType<double>("energy"), 0, 0, 0,
+          Kernel::DeltaEMode::Elastic, 0);
+    } else {
+      wavelength = props->getPropertyValueAsType<double>("wavelength");
+    }
+    goniometer.calcFromQSampleAndWavelength(position, wavelength);
+    g_log.information() << "Found goniometer rotation to be "
+                        << goniometer.getEulerAngles()[0]
+                        << " degrees for Q sample = " << position << "\n";
+  } else {
+    goniometer = run().getGoniometer();
+  }
   // create a peak using the qLab frame
   auto peak = new Peak(getInstrument(), position, goniometer.getR());
   // Take the run number from this
@@ -630,6 +655,7 @@ void PeaksWorkspace::initColumns() {
   addPeakColumn("Col");
   addPeakColumn("QLab");
   addPeakColumn("QSample");
+  addPeakColumn("PeakNumber");
 }
 
 //---------------------------------------------------------------------------------------------
@@ -694,6 +720,7 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
   std::vector<double> dSpacing(np);
   std::vector<double> TOF(np);
   std::vector<int> runNumber(np);
+  std::vector<int> peakNumber(np);
   std::vector<double> goniometerMatrix(9 * np);
   std::vector<std::string> shapes(np);
 
@@ -715,6 +742,7 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
     dSpacing[i] = p.getDSpacing();
     TOF[i] = p.getTOF();
     runNumber[i] = p.getRunNumber();
+    peakNumber[i] = p.getPeakNumber();
     {
       Matrix<double> gm = p.getGoniometerMatrix();
       goniometerMatrix[9 * i] = gm[0][0];
@@ -861,6 +889,14 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
   file->putAttr("units", "Not known"); // Units may need changing when known
   file->closeData();
 
+  // Peak Number column
+  file->writeData("column_17", peakNumber);
+  file->openData("column_17");
+  file->putAttr("name", "Peak Number");
+  file->putAttr("interpret_as", specifyInteger);
+  file->putAttr("units", "Not known"); // Units may need changing when known
+  file->closeData();
+
   // Goniometer Matrix Column
   std::vector<int> array_dims;
   array_dims.push_back(static_cast<int>(peaks.size()));
diff --git a/Framework/DataObjects/src/Workspace2D.cpp b/Framework/DataObjects/src/Workspace2D.cpp
index 169ce00da4cd24479f3eaa77e855efe94c98bf03..883abc4fd8576a061122cd9bcdf3b1ad3458c8de 100644
--- a/Framework/DataObjects/src/Workspace2D.cpp
+++ b/Framework/DataObjects/src/Workspace2D.cpp
@@ -107,8 +107,8 @@ void Workspace2D::init(const HistogramData::Histogram &histogram) {
 
   Histogram1D spec(initializedHistogram.xMode(), initializedHistogram.yMode());
   spec.setHistogram(initializedHistogram);
-  for (size_t i = 0; i < data.size(); i++) {
-    data[i] = new Histogram1D(spec);
+  for (auto &i : data) {
+    i = new Histogram1D(spec);
   }
 
   // Add axes that reference the data
diff --git a/Framework/DataObjects/test/EventListTest.h b/Framework/DataObjects/test/EventListTest.h
index 7d1e65d52deba0bf4d57033a8e12843e985d06f5..30b5161f1118f42bbd28559f0c09a25a130fe075 100644
--- a/Framework/DataObjects/test/EventListTest.h
+++ b/Framework/DataObjects/test/EventListTest.h
@@ -1434,7 +1434,7 @@ public:
   void test_convertUnitsViaTof_failures() {
     DummyUnit1 fromUnit;
     DummyUnit2 toUnit;
-    TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(NULL, NULL));
+    TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(nullptr, nullptr));
     // Not initalized
     TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(&fromUnit, &toUnit));
   }
@@ -1826,9 +1826,8 @@ public:
     }
 
     // Clean the pointers
-    for (std::map<int, EventList *>::iterator im = outputs.begin();
-         im != outputs.end(); ++im) {
-      delete im->second;
+    for (auto &output : outputs) {
+      delete output.second;
     }
 
     return;
@@ -1874,9 +1873,8 @@ public:
     }
 
     // Clean the pointers
-    for (std::map<int, EventList *>::iterator im = outputs.begin();
-         im != outputs.end(); ++im) {
-      delete im->second;
+    for (auto &output : outputs) {
+      delete output.second;
     }
 
     return;
@@ -2312,9 +2310,8 @@ public:
     TS_ASSERT_EQUALS(e7->getNumberEvents(), 1);
 
     // Clean the pointers
-    for (std::map<int, EventList *>::iterator im = outputs.begin();
-         im != outputs.end(); ++im) {
-      delete im->second;
+    for (auto &output : outputs) {
+      delete output.second;
     }
 
     return;
@@ -2385,9 +2382,8 @@ public:
     // TS_ASSERT_EQUALS(e7->getNumberEvents(), 1);
 
     // Clean the pointers
-    for (std::map<int, EventList *>::iterator im = outputs.begin();
-         im != outputs.end(); ++im) {
-      delete im->second;
+    for (auto &output : outputs) {
+      delete output.second;
     }
 
     return;
diff --git a/Framework/DataObjects/test/EventWorkspaceTest.h b/Framework/DataObjects/test/EventWorkspaceTest.h
index ff9c4f94fed807a2ae8ed22aa38b431051783bf2..b873a8cbae6d99bf0a0413200db9b725ae144051 100644
--- a/Framework/DataObjects/test/EventWorkspaceTest.h
+++ b/Framework/DataObjects/test/EventWorkspaceTest.h
@@ -691,10 +691,10 @@ public:
     EventWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<EventWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<EventWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -702,9 +702,9 @@ public:
     EventWorkspace_const_sptr wsCastConst;
     EventWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (EventWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (EventWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
@@ -722,10 +722,10 @@ public:
     IEventWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<IEventWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<IEventWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -733,9 +733,9 @@ public:
     IEventWorkspace_const_sptr wsCastConst;
     IEventWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (IEventWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IEventWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
diff --git a/Framework/DataObjects/test/FakeMDTest.h b/Framework/DataObjects/test/FakeMDTest.h
index aa8ce321bca46edbc2ff09defc670717983c2ec0..af7bf383d3cc501964b3dba2f8e995a7dfa64e94 100644
--- a/Framework/DataObjects/test/FakeMDTest.h
+++ b/Framework/DataObjects/test/FakeMDTest.h
@@ -140,8 +140,8 @@ public:
 
     TS_ASSERT_EQUALS(1000, fakeData->getNEvents());
 
-    Mantid::detid_t expectedIDs[10] = {106, 255, 184, 238, 0,
-                                       32,  77,  255, 37,  60};
+    Mantid::detid_t expectedIDs[10] = {37,  235, 140, 72, 255,
+                                       137, 203, 133, 79, 192};
     auto it = fakeData->createIterator();
     size_t counter(0);
     while (counter < 10) {
@@ -150,8 +150,6 @@ public:
       it->next();
       ++counter;
     }
-
-    delete it;
   }
 };
 
diff --git a/Framework/DataObjects/test/GroupingWorkspaceTest.h b/Framework/DataObjects/test/GroupingWorkspaceTest.h
index a2c232cbcf140400301b01a5c558ef81cee8104b..04f7fb02a072eb847871a8ccb539dc5d44789285 100644
--- a/Framework/DataObjects/test/GroupingWorkspaceTest.h
+++ b/Framework/DataObjects/test/GroupingWorkspaceTest.h
@@ -109,10 +109,10 @@ public:
     GroupingWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<GroupingWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<GroupingWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -120,9 +120,9 @@ public:
     GroupingWorkspace_const_sptr wsCastConst;
     GroupingWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (GroupingWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (GroupingWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/MDBinTest.h b/Framework/DataObjects/test/MDBinTest.h
index 451ddc9e0744980a5e384ab9f74b96e31e3fa82e..00eb8ed17b7619648ed4f2ff2e62aff0a278479c 100644
--- a/Framework/DataObjects/test/MDBinTest.h
+++ b/Framework/DataObjects/test/MDBinTest.h
@@ -13,7 +13,7 @@ using namespace Mantid::DataObjects;
 class MDBinTest : public CxxTest::TestSuite {
 public:
   void test_constructor() {
-    typedef MDLeanEvent<3> MDE;
+    using MDE = MDLeanEvent<3>;
     MDBin<MDE, 3> bin;
     for (size_t d = 0; d < 3; d++) {
       TS_ASSERT_EQUALS(bin.m_min[d], -std::numeric_limits<coord_t>::max());
diff --git a/Framework/DataObjects/test/MDBoxBaseTest.h b/Framework/DataObjects/test/MDBoxBaseTest.h
index a5b1c1e0ed8cc4230b99f631817a3bae98df2888..8af6937d8c1c44ea82c15774b33f4d574a83f8fb 100644
--- a/Framework/DataObjects/test/MDBoxBaseTest.h
+++ b/Framework/DataObjects/test/MDBoxBaseTest.h
@@ -161,7 +161,7 @@ public:
   }
 
   void test_extents_constructor() {
-    typedef MDBoxBaseTester<MDLeanEvent<3>, 3> ibox3;
+    using ibox3 = MDBoxBaseTester<MDLeanEvent<3>, 3>;
     std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector;
     TS_ASSERT_THROWS_ANYTHING(ibox3 box(extentsVector));
     extentsVector.resize(3);
@@ -179,7 +179,7 @@ public:
   }
 
   void test_transformDimensions() {
-    typedef MDBoxBaseTester<MDLeanEvent<2>, 2> ibox3;
+    using ibox3 = MDBoxBaseTester<MDLeanEvent<2>, 2>;
     std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extentsVector;
     TS_ASSERT_THROWS_ANYTHING(ibox3 box(extentsVector));
     extentsVector.resize(2);
@@ -326,7 +326,7 @@ public:
     b.setExtents(0, -10.0, 10.0);
     b.setExtents(1, -4.0, 6.0);
     size_t numVertexes = 0;
-    coord_t *v = b.getVertexesArray(numVertexes);
+    auto v = b.getVertexesArray(numVertexes);
     TS_ASSERT_EQUALS(numVertexes, 4);
     TS_ASSERT_EQUALS(v[0], -10.0);
     TS_ASSERT_EQUALS(v[0 + 1], -4.0);
@@ -336,7 +336,6 @@ public:
     TS_ASSERT_EQUALS(v[4 + 1], 6.0);
     TS_ASSERT_EQUALS(v[6], 10.0);
     TS_ASSERT_EQUALS(v[6 + 1], 6.0);
-    delete[] v;
   }
 
   /** Get vertexes as a bare array,
@@ -346,21 +345,18 @@ public:
     b.setExtents(0, -10.0, 10.0);
     b.setExtents(1, -4.0, 6.0);
     size_t numVertexes = 0;
-    coord_t *v;
 
     bool maskDim[2] = {true, false};
-    v = b.getVertexesArray(numVertexes, 1, maskDim);
+    auto v = b.getVertexesArray(numVertexes, 1, maskDim);
     TS_ASSERT_EQUALS(numVertexes, 2);
     TS_ASSERT_EQUALS(v[0], -10.0);
     TS_ASSERT_EQUALS(v[1], 10.0);
-    delete[] v;
 
     bool maskDim2[2] = {false, true};
     v = b.getVertexesArray(numVertexes, 1, maskDim2);
     TS_ASSERT_EQUALS(numVertexes, 2);
     TS_ASSERT_EQUALS(v[0], -4.0);
     TS_ASSERT_EQUALS(v[1], 6.0);
-    delete[] v;
   }
 
   /** Get vertexes as a bare array,
@@ -371,11 +367,10 @@ public:
     b.setExtents(1, -4.0, 6.0);
     b.setExtents(2, -2.0, 8.0);
     size_t numVertexes = 0;
-    coord_t *v;
 
     // 3D projected down to 2D in X/Y
     bool maskDim[3] = {true, true, false};
-    v = b.getVertexesArray(numVertexes, 2, maskDim);
+    auto v = b.getVertexesArray(numVertexes, 2, maskDim);
     TS_ASSERT_EQUALS(numVertexes, 4);
     TS_ASSERT_EQUALS(v[0], -10.0);
     TS_ASSERT_EQUALS(v[0 + 1], -4.0);
@@ -385,7 +380,6 @@ public:
     TS_ASSERT_EQUALS(v[4 + 1], 6.0);
     TS_ASSERT_EQUALS(v[6], 10.0);
     TS_ASSERT_EQUALS(v[6 + 1], 6.0);
-    delete[] v;
 
     // Can't give 0 dimensions.
     TS_ASSERT_THROWS_ANYTHING(v = b.getVertexesArray(numVertexes, 0, maskDim));
@@ -396,7 +390,6 @@ public:
     TS_ASSERT_EQUALS(numVertexes, 2);
     TS_ASSERT_EQUALS(v[0], -4.0);
     TS_ASSERT_EQUALS(v[1], 6.0);
-    delete[] v;
 
     // 3D projected down to 2D in Y/Z
     bool maskDim3[3] = {false, true, true};
@@ -410,7 +403,6 @@ public:
     TS_ASSERT_EQUALS(v[4 + 1], 8.0);
     TS_ASSERT_EQUALS(v[6], 6.0);
     TS_ASSERT_EQUALS(v[6 + 1], 8.0);
-    delete[] v;
   }
 
   void xtest_sortBoxesByFilePos() {
@@ -456,8 +448,7 @@ public:
     b.setExtents(2, -7.0, 7.0);
     for (size_t i = 0; i < 1000000; i++) {
       size_t numVertexes;
-      coord_t *v = b.getVertexesArray(numVertexes);
-      delete[] v;
+      auto v = b.getVertexesArray(numVertexes);
     }
   }
 
@@ -469,8 +460,7 @@ public:
     bool maskDim[3] = {true, true, false};
     for (size_t i = 0; i < 1000000; i++) {
       size_t numVertexes;
-      coord_t *v = b.getVertexesArray(numVertexes, 2, maskDim);
-      delete[] v;
+      auto v = b.getVertexesArray(numVertexes, 2, maskDim);
     }
   }
 
@@ -482,8 +472,7 @@ public:
     b.setExtents(3, -6.0, 6.0);
     for (size_t i = 0; i < 1000000; i++) {
       size_t numVertexes;
-      coord_t *v = b.getVertexesArray(numVertexes);
-      delete[] v;
+      auto v = b.getVertexesArray(numVertexes);
     }
   }
   void test_getVertexesArray_4D_projected_to_3D() {
@@ -495,8 +484,7 @@ public:
     b.setExtents(3, -6.0, 6.0);
     for (size_t i = 0; i < 1000000; i++) {
       size_t numVertexes;
-      coord_t *v = b.getVertexesArray(numVertexes, 3, maskDim);
-      delete[] v;
+      auto v = b.getVertexesArray(numVertexes, 3, maskDim);
     }
   }
 };
diff --git a/Framework/DataObjects/test/MDBoxFlatTreeTest.h b/Framework/DataObjects/test/MDBoxFlatTreeTest.h
index 3b3cfc2c991e4cb323bc2f8e04249bee292a497c..3fcd866ec461a6c02cc4ca9d300e3393dc031ec2 100644
--- a/Framework/DataObjects/test/MDBoxFlatTreeTest.h
+++ b/Framework/DataObjects/test/MDBoxFlatTreeTest.h
@@ -93,8 +93,8 @@ public:
       if (!Boxes[i]->isBox())
         gridIndices.push_back(i);
     }
-    for (size_t i = 0; i < gridIndices.size(); ++i) {
-      delete Boxes[gridIndices[i]];
+    for (auto gridIndex : gridIndices) {
+      delete Boxes[gridIndex];
     }
 
     // Clean up file
diff --git a/Framework/DataObjects/test/MDBoxIteratorTest.h b/Framework/DataObjects/test/MDBoxIteratorTest.h
index 6654f3fcac89a4beadb47edf407d1addc1c41d41..93fc5a6f58966a92d18a7796658c7388fcb74db9 100644
--- a/Framework/DataObjects/test/MDBoxIteratorTest.h
+++ b/Framework/DataObjects/test/MDBoxIteratorTest.h
@@ -26,8 +26,8 @@ using Mantid::Geometry::MDBoxImplicitFunction;
 
 class MDBoxIteratorTest : public CxxTest::TestSuite {
 public:
-  typedef MDGridBox<MDLeanEvent<1>, 1> gbox_t;
-  typedef MDBoxBase<MDLeanEvent<1>, 1> ibox_t;
+  using gbox_t = MDGridBox<MDLeanEvent<1>, 1>;
+  using ibox_t = MDBoxBase<MDLeanEvent<1>, 1>;
 
   //--------------------------------------------------------------------------------------
   /** Make a gridded box with this structure:
@@ -82,8 +82,8 @@ public:
 
   //--------------------------------------------------------------------------------------
   void test_ctor_with_null_box_fails() {
-    typedef MDBoxIterator<MDLeanEvent<1>, 1> boxit_t;
-    TS_ASSERT_THROWS_ANYTHING(new boxit_t(NULL, 10, false););
+    using boxit_t = MDBoxIterator<MDLeanEvent<1>, 1>;
+    TS_ASSERT_THROWS_ANYTHING(new boxit_t(nullptr, 10, false););
   }
 
   //--------------------------------------------------------------------------------------
diff --git a/Framework/DataObjects/test/MDBoxSaveableTest.h b/Framework/DataObjects/test/MDBoxSaveableTest.h
index f2da62d402ac1f361c86ab364f8087c575f1b4ab..fdf5fb46e9bf0a5be5113c9c6275fb618c7f803c 100644
--- a/Framework/DataObjects/test/MDBoxSaveableTest.h
+++ b/Framework/DataObjects/test/MDBoxSaveableTest.h
@@ -254,7 +254,7 @@ public:
     MDBox<MDLeanEvent<3>, 3> *b =
         dynamic_cast<MDBox<MDLeanEvent<3>, 3> *>(gb->getChild(22));
     TSM_ASSERT_EQUALS("Child has 8 events", b->getNPoints(), 8);
-    TSM_ASSERT("The child is also saveabele", b->getISaveable() != NULL);
+    TSM_ASSERT("The child is also saveabele", b->getISaveable() != nullptr);
     if (!b->getISaveable())
       return;
 
@@ -753,7 +753,7 @@ public:
         bin.m_max[d] = 4.0;
         bin.m_signal = 0;
       }
-      c.centerpointBin(bin, NULL);
+      c.centerpointBin(bin, nullptr);
       TS_ASSERT_DELTA(bin.m_signal, 8.0, 1e-4);
       TS_ASSERT_DELTA(bin.m_errorSquared, 8.0, 1e-4);
     }
@@ -795,7 +795,7 @@ public:
    */
   void test_splitAllIfNeeded_fileBacked() {
     using Mantid::DataObjects::BoxControllerNeXusIO;
-    typedef MDLeanEvent<2> MDE;
+    using MDE = MDLeanEvent<2>;
 
     // Create the grid box and make it file-backed.
     MDBoxBase<MDE, 2> *b = MDEventsTestHelper::makeMDGridBox<2>();
@@ -840,14 +840,13 @@ public:
     size_t numOnDisk = 0;
     uint64_t eventsOnDisk = 0;
     uint64_t maxFilePos = 0;
-    for (size_t i = 0; i < boxes.size(); i++) {
-      API::IMDNode *box = boxes[i];
+    for (auto box : boxes) {
       TS_ASSERT_EQUALS(box->getNPoints(), num_repeat);
       auto mdbox = dynamic_cast<MDBox<MDE, 2> *>(box);
       TS_ASSERT(mdbox);
 
       auto pIO = mdbox->getISaveable();
-      TS_ASSERT(pIO != NULL);
+      TS_ASSERT(pIO != nullptr);
       if (!pIO)
         continue;
 
diff --git a/Framework/DataObjects/test/MDBoxTest.h b/Framework/DataObjects/test/MDBoxTest.h
index 2f6391b05381d91097e6bd3e893db0b7c2377dec..ab9b56a8a17f71ba2fa5b3924f94f585e2bf6f0f 100644
--- a/Framework/DataObjects/test/MDBoxTest.h
+++ b/Framework/DataObjects/test/MDBoxTest.h
@@ -365,15 +365,15 @@ public:
   }
 
   void test_sptr() {
-    typedef MDBox<MDLeanEvent<3>, 3> mdbox3;
+    using mdbox3 = MDBox<MDLeanEvent<3>, 3>;
     TS_ASSERT_THROWS_NOTHING(mdbox3::sptr a(new mdbox3(sc.get()));)
   }
 
   void test_bad_splitter() {
     BoxController_sptr sc(new BoxController(4));
     sc->setSplitThreshold(10);
-    typedef MDBox<MDLeanEvent<3>, 3>
-        MACROS_ARE_DUMB; //...since they get confused by commas
+    using MACROS_ARE_DUMB =
+        MDBox<MDLeanEvent<3>, 3>; //...since they get confused by commas
     TS_ASSERT_THROWS(MACROS_ARE_DUMB b3(sc.get()), std::invalid_argument);
   }
 
@@ -407,7 +407,7 @@ public:
     // First, a bin object that holds everything
     MDBin<MDLeanEvent<2>, 2> bin;
     // Perform the centerpoint binning
-    box.centerpointBin(bin, NULL);
+    box.centerpointBin(bin, nullptr);
     // 100 events = 100 weight.
     TS_ASSERT_DELTA(bin.m_signal, 100.0, 1e-4);
     TS_ASSERT_DELTA(bin.m_errorSquared, 150.0, 1e-4);
@@ -419,7 +419,7 @@ public:
     bin.m_max[0] = 6.0;
     bin.m_min[1] = 1.0;
     bin.m_max[1] = 3.0;
-    box.centerpointBin(bin, NULL);
+    box.centerpointBin(bin, nullptr);
     TS_ASSERT_DELTA(bin.m_signal, 4.0, 1e-4);
     TS_ASSERT_DELTA(bin.m_errorSquared, 6.0, 1e-4);
   }
@@ -585,8 +585,8 @@ public:
     coord_t centroid[2] = {0, 0};
     signal_t signal = 0.0;
     b.centroidSphere(sphere, 400., centroid, signal);
-    for (size_t d = 0; d < 2; d++)
-      centroid[d] /= static_cast<coord_t>(signal);
+    for (float &d : centroid)
+      d /= static_cast<coord_t>(signal);
 
     // This should be the weighted centroid
     TS_ASSERT_DELTA(signal, 6.000, 0.001);
@@ -595,11 +595,11 @@ public:
 
     // --- Reset and reduce the radius ------
     signal = 0;
-    for (size_t d = 0; d < 2; d++)
-      centroid[d] = 0.0;
+    for (float &d : centroid)
+      d = 0.0;
     b.centroidSphere(sphere, 16., centroid, signal);
-    for (size_t d = 0; d < 2; d++)
-      centroid[d] /= static_cast<coord_t>(signal);
+    for (float &d : centroid)
+      d /= static_cast<coord_t>(signal);
     // Only one event was contained
     TS_ASSERT_DELTA(signal, 2.000, 0.001);
     TS_ASSERT_DELTA(centroid[0], 2.000, 0.001);
diff --git a/Framework/DataObjects/test/MDEventInserterTest.h b/Framework/DataObjects/test/MDEventInserterTest.h
index 8caccd71a86fde1c0bd54a3a154eb958862ba019..3defd0f380413f0ba67a2f8215e6372df5021846 100644
--- a/Framework/DataObjects/test/MDEventInserterTest.h
+++ b/Framework/DataObjects/test/MDEventInserterTest.h
@@ -52,7 +52,7 @@ public:
   static void destroySuite(MDEventInserterTest *suite) { delete suite; }
 
   void test_add_md_lean_events() {
-    typedef MDEventWorkspace<MDLeanEvent<2>, 2> MDEW_LEAN_2D;
+    using MDEW_LEAN_2D = MDEventWorkspace<MDLeanEvent<2>, 2>;
 
     // Check the type deduction used internally in the MDEventInserter template.
     TS_ASSERT_EQUALS(sizeof(MDEW_LEAN_2D::MDEventType),
@@ -84,7 +84,7 @@ public:
   }
 
   void test_add_md_full_events() {
-    typedef MDEventWorkspace<MDEvent<2>, 2> MDEW_2D;
+    using MDEW_2D = MDEventWorkspace<MDEvent<2>, 2>;
 
     // Check the type deduction used internally in the MDEventInserter template.
     TS_ASSERT_EQUALS(sizeof(MDEW_2D::MDEventType),
diff --git a/Framework/DataObjects/test/MDEventWorkspaceTest.h b/Framework/DataObjects/test/MDEventWorkspaceTest.h
index 72e27f6bb92a454bb14ebb62ff8038403fac0bde..5ca42676adbd47d79724954f75bdd9c5ee00ad04 100644
--- a/Framework/DataObjects/test/MDEventWorkspaceTest.h
+++ b/Framework/DataObjects/test/MDEventWorkspaceTest.h
@@ -19,11 +19,6 @@
 #include "MantidDataObjects/MDLeanEvent.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "PropertyManagerHelper.h"
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 #include <cxxtest/TestSuite.h>
 #include <map>
 #include <memory>
@@ -42,7 +37,7 @@ private:
   /// Helper function to return the number of masked bins in a workspace. TODO:
   /// move helper into test helpers
   size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) {
-    Mantid::API::IMDIterator *it = ws->createIterator(NULL);
+    auto it = ws->createIterator(nullptr);
     size_t numberMasked = 0;
     size_t counter = 0;
     for (; counter < it->getDataSize(); ++counter) {
@@ -51,7 +46,6 @@ private:
       }
       it->next(1); // Doesn't perform skipping on masked, bins, but next() does.
     }
-    delete it;
     return numberMasked;
   }
 
@@ -123,7 +117,7 @@ public:
 
     /*Test that the boxes were deep copied and that their BoxController pointers
      * have been updated too.*/
-    std::vector<API::IMDNode *> originalBoxes(0, NULL);
+    std::vector<API::IMDNode *> originalBoxes(0, nullptr);
     ew3.getBox()->getBoxes(originalBoxes, 10000, false);
 
     std::vector<API::IMDNode *> copiedBoxes;
@@ -238,42 +232,34 @@ public:
   //-------------------------------------------------------------------------------------
   /** Create an IMDIterator */
   void test_createIterator() {
-    MDEventWorkspace3 *ew = new MDEventWorkspace3();
+    auto ew = boost::make_shared<MDEventWorkspace3>();
     BoxController_sptr bc = ew->getBoxController();
     bc->setSplitInto(4);
     ew->splitBox();
-    IMDIterator *it = ew->createIterator();
+    auto it = ew->createIterator();
     TS_ASSERT(it);
     TS_ASSERT_EQUALS(it->getDataSize(), 4 * 4 * 4);
     TS_ASSERT(it->next());
-    delete it;
-    auto *mdfunction = new MDImplicitFunction();
-    it = ew->createIterator(mdfunction);
+    MDImplicitFunction mdfunction;
+    it = ew->createIterator(&mdfunction);
     TS_ASSERT(it);
     TS_ASSERT_EQUALS(it->getDataSize(), 4 * 4 * 4);
     TS_ASSERT(it->next());
-    delete mdfunction;
-    delete it;
-    delete ew;
   }
 
   //-------------------------------------------------------------------------------------
   /** Create several IMDIterators to run them in parallel */
   void test_createIterators() {
-    MDEventWorkspace3 *ew = new MDEventWorkspace3();
+    auto ew = boost::make_shared<MDEventWorkspace3>();
     BoxController_sptr bc = ew->getBoxController();
     bc->setSplitInto(4);
     ew->splitBox();
-    std::vector<IMDIterator *> iterators = ew->createIterators(3);
+    auto iterators = ew->createIterators(3);
     TS_ASSERT_EQUALS(iterators.size(), 3);
 
     TS_ASSERT_EQUALS(iterators[0]->getDataSize(), 21);
     TS_ASSERT_EQUALS(iterators[1]->getDataSize(), 21);
     TS_ASSERT_EQUALS(iterators[2]->getDataSize(), 22);
-
-    for (size_t i = 0; i < 3; ++i)
-      delete iterators[i];
-    delete ew;
   }
 
   //-------------------------------------------------------------------------------------
@@ -379,7 +365,7 @@ public:
     for (size_t i = 0; i < 50; i++) {
       ew->addEvent(ev);
     }
-    ew->splitAllIfNeeded(NULL);
+    ew->splitAllIfNeeded(nullptr);
     ew->refreshCache();
 
     // Create dimension-aligned line through the workspace
@@ -792,10 +778,10 @@ public:
     IMDEventWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<IMDEventWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<IMDEventWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -803,9 +789,9 @@ public:
     IMDEventWorkspace_const_sptr wsCastConst;
     IMDEventWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDEventWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDEventWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
@@ -855,7 +841,7 @@ public:
     std::cout << "Starting Workspace splitting performance test, single "
                  "threaded with " << nBoxes << " events \n";
     Kernel::Timer clock;
-    m_ws->splitAllIfNeeded(NULL);
+    m_ws->splitAllIfNeeded(nullptr);
     std::cout
         << "Finished Workspace splitting performance test, single threaded in "
         << clock.elapsed() << " sec\n";
diff --git a/Framework/DataObjects/test/MDGridBoxTest.h b/Framework/DataObjects/test/MDGridBoxTest.h
index d2e98dbe7adb69e0f9b384ae7a94ad0af9466276..5f35b0ddba6504df986c145a2a48e03fe1962e7b 100644
--- a/Framework/DataObjects/test/MDGridBoxTest.h
+++ b/Framework/DataObjects/test/MDGridBoxTest.h
@@ -21,17 +21,13 @@
 #include "MantidKernel/WarningSuppressions.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include <Poco/File.h>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 #include <cmath>
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
 #include <map>
 #include <memory>
 #include <nexus/NeXusFile.hpp>
+#include <random>
 #include <vector>
 
 using namespace Mantid;
@@ -261,10 +257,10 @@ public:
         new MDGridBox<MDLeanEvent<1>, 1>(*box, newBoxController);
 
     auto boxes = box1->getBoxes();
-    for (size_t i = 0; i < boxes.size(); ++i) {
+    for (auto &box : boxes) {
       TSM_ASSERT_EQUALS(
           "All child boxes should have the same box controller as the parent.",
-          newBoxController, boxes[i]->getBoxController());
+          newBoxController, box->getBoxController());
     }
     delete newBoxController;
     delete box1;
@@ -295,11 +291,10 @@ public:
       TS_ASSERT_EQUALS(g->getChild(i - 2)->getParent(), g);
     }
     // MDGridBox will delete the children that it pulled in but the rest need to
-    // be
-    // taken care of manually
+    // be taken care of manually
     size_t indices[5] = {0, 1, 12, 13, 14};
-    for (size_t i = 0; i < 5; ++i)
-      delete boxes[indices[i]];
+    for (auto index : indices)
+      delete boxes[index];
     delete g;
     delete bcc;
   }
@@ -329,9 +324,9 @@ public:
     // Check the boxes
     std::vector<MDBoxBase<MDLeanEvent<3>, 3> *> boxes = g->getBoxes();
     TS_ASSERT_EQUALS(boxes.size(), 10 * 5 * 2);
-    for (size_t i = 0; i < boxes.size(); i++) {
+    for (auto &boxBase : boxes) {
       MDBox<MDLeanEvent<3>, 3> *box =
-          dynamic_cast<MDBox<MDLeanEvent<3>, 3> *>(boxes[i]);
+          dynamic_cast<MDBox<MDLeanEvent<3>, 3> *>(boxBase);
       TS_ASSERT(box);
     }
     MDBox<MDLeanEvent<3>, 3> *box;
@@ -445,7 +440,7 @@ public:
     }
 
     // You must refresh the cache after adding individual events.
-    superbox->refreshCache(NULL);
+    superbox->refreshCache(nullptr);
     // superbox->refreshCentroid(NULL);
 
     TS_ASSERT_EQUALS(superbox->getNPoints(), 3);
@@ -473,7 +468,7 @@ public:
     }
     TS_ASSERT_EQUALS(superbox->getNPoints(), 3);
 
-    superbox->refreshCache(NULL);
+    superbox->refreshCache(nullptr);
     TS_ASSERT_EQUALS(superbox->getNPoints(), 6);
 
     // Retrieve the 0th grid box
@@ -602,8 +597,8 @@ public:
     parent->getBoxes(boxes, 3, false, function);
     TS_ASSERT_EQUALS(boxes.size(), 54);
     // The boxes extents make sense
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 1.51);
     }
 
     // --- Now leaf-only ---
@@ -611,8 +606,8 @@ public:
     parent->getBoxes(boxes, 3, true, function);
     TS_ASSERT_EQUALS(boxes.size(), 40);
     // The boxes extents make sense
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 1.51);
     }
 
     // Limit by another plane
@@ -622,18 +617,18 @@ public:
     boxes.clear();
     parent->getBoxes(boxes, 3, false, function);
     TS_ASSERT_EQUALS(boxes.size(), 33);
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51);
-      TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 2.99);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 1.51);
+      TS_ASSERT(box->getExtents(0).getMin() <= 2.99);
     }
 
     // Same, leaf only
     boxes.clear();
     parent->getBoxes(boxes, 3, true, function);
     TS_ASSERT_EQUALS(boxes.size(), 24);
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51);
-      TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 2.99);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 1.51);
+      TS_ASSERT(box->getExtents(0).getMin() <= 2.99);
     }
 
     // ----- Infinitely thin plane for an implicit function ------------
@@ -675,11 +670,11 @@ public:
     parent->getBoxes(boxes, 3, false, function);
     TS_ASSERT_EQUALS(boxes.size(), 46);
     // The boxes extents make sense
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 2.00);
-      TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 3.00);
-      TS_ASSERT(boxes[i]->getExtents(1).getMax() >= 2.00);
-      TS_ASSERT(boxes[i]->getExtents(1).getMin() <= 3.00);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 2.00);
+      TS_ASSERT(box->getExtents(0).getMin() <= 3.00);
+      TS_ASSERT(box->getExtents(1).getMax() >= 2.00);
+      TS_ASSERT(box->getExtents(1).getMin() <= 3.00);
     }
 
     // -- Leaf only ---
@@ -690,11 +685,11 @@ public:
         16 + 4 * 4 +
             4); // 16 in the center one + 4x4 at the 4 edges + 4 at the corners
     // The boxes extents make sense
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 2.00);
-      TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 3.00);
-      TS_ASSERT(boxes[i]->getExtents(1).getMax() >= 2.00);
-      TS_ASSERT(boxes[i]->getExtents(1).getMin() <= 3.00);
+    for (auto &box : boxes) {
+      TS_ASSERT(box->getExtents(0).getMax() >= 2.00);
+      TS_ASSERT(box->getExtents(0).getMin() <= 3.00);
+      TS_ASSERT(box->getExtents(1).getMax() >= 2.00);
+      TS_ASSERT(box->getExtents(1).getMin() <= 3.00);
     }
 
     // clean up  behind
@@ -801,7 +796,7 @@ public:
           }
         }
       // You must refresh the cache after adding individual events.
-      box->refreshCache(NULL);
+      box->refreshCache(nullptr);
     }
   }
 
@@ -824,7 +819,7 @@ public:
     size_t numbad = 0;
     TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events););
     // Get the right totals again
-    b->refreshCache(NULL);
+    b->refreshCache(nullptr);
     TS_ASSERT_EQUALS(numbad, 0);
     TS_ASSERT_EQUALS(b->getNPoints(), 100);
     TS_ASSERT_EQUALS(b->getSignal(), 100 * 2.0);
@@ -835,12 +830,12 @@ public:
     // Get all the boxes contained
     std::vector<MDBoxBase<MDLeanEvent<2>, 2> *> boxes = b->getBoxes();
     TS_ASSERT_EQUALS(boxes.size(), 100);
-    for (size_t i = 0; i < boxes.size(); i++) {
-      TS_ASSERT_EQUALS(boxes[i]->getNPoints(), 1);
-      TS_ASSERT_EQUALS(boxes[i]->getSignal(), 2.0);
-      TS_ASSERT_EQUALS(boxes[i]->getErrorSquared(), 2.0);
-      TS_ASSERT_EQUALS(boxes[i]->getSignalNormalized(), 2.0);
-      TS_ASSERT_EQUALS(boxes[i]->getErrorSquaredNormalized(), 2.0);
+    for (auto &box : boxes) {
+      TS_ASSERT_EQUALS(box->getNPoints(), 1);
+      TS_ASSERT_EQUALS(box->getSignal(), 2.0);
+      TS_ASSERT_EQUALS(box->getErrorSquared(), 2.0);
+      TS_ASSERT_EQUALS(box->getSignalNormalized(), 2.0);
+      TS_ASSERT_EQUALS(box->getErrorSquaredNormalized(), 2.0);
     }
 
     // Now try to add bad events (outside bounds)
@@ -851,7 +846,7 @@ public:
         events.push_back(MDLeanEvent<2>(2.0, 2.0, centers));
       }
     // Get the right totals again
-    b->refreshCache(NULL);
+    b->refreshCache(nullptr);
     // All 4 points get rejected
     TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events););
     TS_ASSERT_EQUALS(numbad, 4);
@@ -886,7 +881,7 @@ public:
     TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events));
     TS_ASSERT_EQUALS(numbad, 3);
 
-    b->refreshCache(NULL);
+    b->refreshCache(nullptr);
     TS_ASSERT_EQUALS(b->getNPoints(), 1);
     TS_ASSERT_EQUALS(b->getSignal(), 2.0);
     TS_ASSERT_EQUALS(b->getErrorSquared(), 2.0);
@@ -987,9 +982,9 @@ public:
    * further.
    * */
   void test_splitAllIfNeeded() {
-    typedef MDGridBox<MDLeanEvent<2>, 2> gbox_t;
-    typedef MDBox<MDLeanEvent<2>, 2> box_t;
-    typedef MDBoxBase<MDLeanEvent<2>, 2> ibox_t;
+    using gbox_t = MDGridBox<MDLeanEvent<2>, 2>;
+    using box_t = MDBox<MDLeanEvent<2>, 2>;
+    using ibox_t = MDBoxBase<MDLeanEvent<2>, 2>;
 
     gbox_t *b0 = MDEventsTestHelper::makeMDGridBox<2>();
     b0->getBoxController()->setSplitThreshold(100);
@@ -1006,7 +1001,7 @@ public:
     TS_ASSERT_THROWS_NOTHING(b0->addEvents(events););
 
     // Split into sub-grid boxes
-    TS_ASSERT_THROWS_NOTHING(b0->splitAllIfNeeded(NULL);)
+    TS_ASSERT_THROWS_NOTHING(b0->splitAllIfNeeded(nullptr);)
 
     // Dig recursively into the gridded box hierarchies
     std::vector<ibox_t *> boxes;
@@ -1051,8 +1046,8 @@ public:
    * to use all cores.
    */
   void test_splitAllIfNeeded_usingThreadPool() {
-    typedef MDGridBox<MDLeanEvent<2>, 2> gbox_t;
-    typedef MDBoxBase<MDLeanEvent<2>, 2> ibox_t;
+    using gbox_t = MDGridBox<MDLeanEvent<2>, 2>;
+    using ibox_t = MDBoxBase<MDLeanEvent<2>, 2>;
 
     gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>();
     b->getBoxController()->setSplitThreshold(100);
@@ -1083,8 +1078,7 @@ public:
     // many events
     std::vector<ibox_t *> boxes = b->getBoxes();
     TS_ASSERT_EQUALS(boxes.size(), 100);
-    for (size_t i = 0; i < boxes.size(); i++) {
-      ibox_t *box = boxes[i];
+    for (auto box : boxes) {
       TS_ASSERT_EQUALS(box->getNPoints(), num_repeat);
       TS_ASSERT(dynamic_cast<gbox_t *>(box));
 
@@ -1128,14 +1122,14 @@ public:
 
     MDBin<MDLeanEvent<2>, 2> bin;
     bin = makeMDBin2(minX, maxX, minY, maxY);
-    b->centerpointBin(bin, NULL);
+    b->centerpointBin(bin, nullptr);
     TSM_ASSERT_DELTA(message, bin.m_signal, expectedSignal, 1e-5);
   }
 
   //------------------------------------------------------------------------------------------------
   /** Test binning in orthogonal axes */
   void test_centerpointBin() {
-    typedef MDGridBox<MDLeanEvent<2>, 2> gbox_t;
+    using gbox_t = MDGridBox<MDLeanEvent<2>, 2>;
 
     // 10x10 bins, 2 events per bin, each weight of 1.0
     gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>();
@@ -1405,8 +1399,8 @@ public:
                        signal);
     // Normalized
     if (signal != 0.0) {
-      for (size_t d = 0; d < 2; d++)
-        centroid[d] /= static_cast<coord_t>(signal);
+      for (float &d : centroid)
+        d /= static_cast<coord_t>(signal);
     }
 
     TSM_ASSERT_DELTA(message, signal, 1.0 * numExpected, 1e-5);
@@ -1624,14 +1618,12 @@ public:
     size_t num = 1000000;
     events.clear();
 
-    boost::mt19937 rng;
-    boost::uniform_real<double> u(0, 5.0); // Range
-    boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>> gen(
-        rng, u);
+    std::mt19937 rng;
+    std::uniform_real_distribution<double> flat(0, 5.0);
     for (size_t i = 0; i < num; ++i) {
       double centers[3];
-      for (size_t d = 0; d < 3; d++)
-        centers[d] = gen();
+      for (double &center : centers)
+        center = flat(rng);
       // Create and add the event.
       events.push_back(MDLeanEvent<3>(1.0, 1.0, centers));
     }
@@ -1730,12 +1722,12 @@ public:
     coord_t centroid[3];
     for (size_t i = 0; i < 100; i++) {
       signal = 0;
-      for (size_t d = 0; d < 3; d++)
-        centroid[d] = 0.0;
+      for (float &d : centroid)
+        d = 0.0;
       box3b->centroidSphere(sphere, radius * radius, centroid, signal);
       if (signal != 0.0) {
-        for (size_t d = 0; d < 3; d++)
-          centroid[d] /= static_cast<coord_t>(signal);
+        for (float &d : centroid)
+          d /= static_cast<coord_t>(signal);
       }
     }
 
diff --git a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
index cc63960592dff086b9a55237727bea56a76398b3..6c89feb705d6c7580ea28fc18d145451c2910473 100644
--- a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
+++ b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h
@@ -79,9 +79,8 @@ public:
       TS_ASSERT_DELTA(it->getNormalizedSignal(), double(i) / 1.0, 1e-5);
       TS_ASSERT_DELTA(it->getNormalizedError(), 1.0, 1e-5);
       size_t numVertices;
-      coord_t *vertexes = it->getVertexesArray(numVertices);
+      auto vertexes = it->getVertexesArray(numVertices);
       TS_ASSERT(vertexes);
-      delete[] vertexes;
       TS_ASSERT_EQUALS(it->getNumEvents(), 1);
       TS_ASSERT_EQUALS(it->getInnerDetectorID(0), 0);
       TS_ASSERT_EQUALS(it->getInnerRunIndex(0), 0);
@@ -126,8 +125,7 @@ public:
 
     Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws);
 
-    MDHistoWorkspaceIterator *histoIt =
-        new MDHistoWorkspaceIterator(ws, function);
+    auto histoIt = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function);
 
     TSM_ASSERT_EQUALS("The first index hit should be 5 since that is the first "
                       "unmasked and inside function",
@@ -136,8 +134,6 @@ public:
     TSM_ASSERT_EQUALS("The next index hit should be 7 since that is the next "
                       "unmasked and inside function",
                       7, histoIt->getLinearIndex());
-
-    delete histoIt;
   }
 
   void test_getNormalizedSignal_with_mask() {
@@ -167,8 +163,8 @@ public:
 
     Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws);
 
-    MDHistoWorkspaceIterator *histoIt =
-        dynamic_cast<MDHistoWorkspaceIterator *>(ws->createIterator());
+    auto it = ws->createIterator();
+    auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get());
 
     TSM_ASSERT_EQUALS("Should get the signal value here as data at the iterator"
                       " are unmasked",
@@ -180,8 +176,6 @@ public:
     TSM_ASSERT_EQUALS("Should get the signal value here as data at the iterator"
                       " are unmasked",
                       3.0, histoIt->getNormalizedSignal());
-
-    delete histoIt;
   }
 
   void test_iterator_1D() { do_test_iterator(1, 10); }
@@ -202,7 +196,7 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
     for (size_t i = 0; i < 100; i++)
       ws->setSignalAt(i, double(i));
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function);
     TSM_ASSERT("This iterator is valid at the start.", it->valid());
 
     TS_ASSERT_EQUALS(it->getNormalizedSignal(), 0.);
@@ -225,8 +219,6 @@ public:
     it->next();
     TS_ASSERT_EQUALS(it->getNormalizedSignal(), 30.);
     TS_ASSERT(!it->next());
-
-    delete it;
   }
 
   void test_iterator_2D_implicitFunction_thatExcludesTheStart() {
@@ -239,7 +231,7 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
     for (size_t i = 0; i < 100; i++)
       ws->setSignalAt(i, double(i));
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function);
     TSM_ASSERT("This iterator is valid at the start.", it->valid());
 
     TS_ASSERT_EQUALS(it->getNormalizedSignal(), 4.);
@@ -257,8 +249,6 @@ public:
     TS_ASSERT_EQUALS(it->getNormalizedSignal(), 13.);
     it->next();
     // And so forth....
-
-    delete it;
   }
 
   void test_iterator_2D_implicitFunction_thatExcludesEverything() {
@@ -270,11 +260,9 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
     for (size_t i = 0; i < 100; i++)
       ws->setSignalAt(i, double(i));
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function);
 
     TSM_ASSERT("This iterator is not valid at the start.", !it->valid());
-
-    delete it;
   }
 
   /** Create several parallel iterators */
@@ -286,38 +274,35 @@ public:
       ws->setSignalAt(i, double(i));
 
     // Make 3 iterators
-    std::vector<IMDIterator *> iterators = ws->createIterators(3);
+    auto iterators = ws->createIterators(3);
     TS_ASSERT_EQUALS(iterators.size(), 3);
 
     IMDIterator *it;
 
-    it = iterators[0];
+    it = iterators[0].get();
     TS_ASSERT_DELTA(it->getSignal(), 0.0, 1e-5);
     TS_ASSERT_EQUALS(it->getDataSize(), 33);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 0.5, 1e-5);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 0.5, 1e-5);
 
-    it = iterators[1];
+    it = iterators[1].get();
     TS_ASSERT_DELTA(it->getSignal(), 33.0, 1e-5);
     TS_ASSERT_EQUALS(it->getDataSize(), 33);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 3.5, 1e-5);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 3.5, 1e-5);
 
-    it = iterators[2];
+    it = iterators[2].get();
     TS_ASSERT_DELTA(it->getSignal(), 66.0, 1e-5);
     TS_ASSERT_EQUALS(it->getDataSize(), 34);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 6.5, 1e-5);
     TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 6.5, 1e-5);
-
-    for (size_t i = 0; i < 3; ++i)
-      delete iterators[i];
   }
 
   void test_predictable_steps() {
     MDHistoWorkspace_sptr ws =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
-    MDHistoWorkspaceIterator *histoIt =
-        dynamic_cast<MDHistoWorkspaceIterator *>(ws->createIterator());
+    auto it = ws->createIterator();
+    auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get());
     size_t expected = 0;
     for (size_t i = 0; i < histoIt->getDataSize(); ++i) {
       size_t current = histoIt->getLinearIndex();
@@ -326,7 +311,6 @@ public:
       expected = current + 1;
       histoIt->next();
     }
-    delete histoIt;
   }
 
   void test_skip_masked_detectors() {
@@ -345,8 +329,8 @@ public:
 
     Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws);
 
-    MDHistoWorkspaceIterator *histoIt =
-        dynamic_cast<MDHistoWorkspaceIterator *>(ws_sptr->createIterator());
+    auto it = ws_sptr->createIterator();
+    auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get());
     histoIt->next();
     TSM_ASSERT_EQUALS(
         "The first index hit should be 2 since that is the first unmasked one",
@@ -355,8 +339,6 @@ public:
     TSM_ASSERT_EQUALS(
         "The next index hit should be 5 since that is the next unmasked one", 5,
         histoIt->getLinearIndex());
-
-    delete histoIt;
   }
 
   // template<typename ContainerType, typename ElementType>
@@ -374,7 +356,7 @@ public:
 
     size_t begin = 1;
     size_t end = 5;
-    MDHistoWorkspaceIterator iterator(ws.get(), NULL, begin, end);
+    MDHistoWorkspaceIterator iterator(ws.get(), nullptr, begin, end);
 
     TS_ASSERT(iterator.isWithinBounds(begin));
     TS_ASSERT(iterator.isWithinBounds(end - 1));
@@ -393,7 +375,7 @@ public:
 
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At first position
     /*
@@ -401,7 +383,8 @@ public:
      ^
      |
      */
-    std::vector<size_t> neighbourIndexes = findNeighbourMemberFunction(it);
+    std::vector<size_t> neighbourIndexes =
+        findNeighbourMemberFunction(it.get());
     TS_ASSERT_EQUALS(1, neighbourIndexes.size());
     // should be on edge
     TSM_ASSERT("Neighbour at index 0 is 1",
@@ -414,7 +397,7 @@ public:
          |
          */
     it->next();
-    neighbourIndexes = findNeighbourMemberFunction(it);
+    neighbourIndexes = findNeighbourMemberFunction(it.get());
     TS_ASSERT_EQUALS(2, neighbourIndexes.size());
     // should be on edge
     TSM_ASSERT("Neighbours at index 1 includes 0",
@@ -429,11 +412,9 @@ public:
                                          |
                                          */
     it->jumpTo(9);
-    neighbourIndexes = findNeighbourMemberFunction(it);
+    neighbourIndexes = findNeighbourMemberFunction(it.get());
     TSM_ASSERT("Neighbour at index 9 is 8",
                doesContainIndex(neighbourIndexes, 8));
-
-    delete it;
   }
 
   void test_neighbours_1d_face_touching() {
@@ -462,7 +443,7 @@ public:
      8 - 9 -10 -11
      12-13 -14 -15
      */
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At initial position
     /*
@@ -532,8 +513,6 @@ public:
                doesContainIndex(neighbourIndexes, 11));
     TSM_ASSERT("Neighbour at index 15 is 14",
                doesContainIndex(neighbourIndexes, 14));
-
-    delete it;
   }
 
   void test_neighbours_2d_vertex_touching() {
@@ -548,7 +527,7 @@ public:
      8 - 9 -10 -11
      12-13 -14 -15
      */
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At initial position
     /*
@@ -633,8 +612,6 @@ public:
                doesContainIndex(neighbourIndexes, 11));
     TSM_ASSERT("Neighbour at index 15 is 14",
                doesContainIndex(neighbourIndexes, 14));
-
-    delete it;
   }
 
   void test_neighbours_3d_face_touching() {
@@ -665,7 +642,7 @@ public:
      [60 61 62 63]]]
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // Start at Index = 0
     std::vector<size_t> neighbourIndexes =
@@ -681,9 +658,8 @@ public:
     neighbourIndexes = it->findNeighbourIndexesFaceTouching();
     TS_ASSERT_EQUALS(4, neighbourIndexes.size());
     std::vector<size_t> expected_neighbours = {0, 2, 5, 17};
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
 
     // Move to index 21
@@ -694,9 +670,8 @@ public:
     // Is completely enclosed
     expected_neighbours = {17, 20, 22, 25, 5, 37};
 
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
 
     // Move to index 63. The last index.
@@ -706,12 +681,9 @@ public:
     // Is on edge
     expected_neighbours = {47, 59, 62};
 
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
-
-    delete it;
   }
 
   void test_neighbours_3d_vertex_touching() {
@@ -742,7 +714,7 @@ public:
      [60 61 62 63]]]
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // Start at Index = 0
     std::vector<size_t> neighbourIndexes = it->findNeighbourIndexes();
@@ -762,9 +734,8 @@ public:
     TS_ASSERT_EQUALS(11, neighbourIndexes.size());
     std::vector<size_t> expected_neighbours = {0,  2,  4,  5,  6,  16,
                                                17, 18, 20, 21, 22, 22};
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
 
     // Move to index 21
@@ -776,9 +747,8 @@ public:
     expected_neighbours = {0,  1,  2,  4,  5,  6,  8,  9,  10, 16, 17, 18, 22,
                            20, 24, 25, 26, 32, 33, 34, 37, 38, 36, 41, 40, 42};
 
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
 
     // Move to index 63. The last index.
@@ -788,12 +758,9 @@ public:
     // Is on edge
     expected_neighbours = {42, 43, 46, 47, 58, 59, 62};
 
-    for (auto i = expected_neighbours.begin(); i != expected_neighbours.end();
-         ++i) {
-      TS_ASSERT(doesContainIndex(neighbourIndexes, *i));
+    for (auto &expected_neighbour : expected_neighbours) {
+      TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour));
     }
-
-    delete it;
   }
 
   void test_neighbours_1d_with_width() {
@@ -811,7 +778,7 @@ public:
 
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At first position
     /*
@@ -859,8 +826,6 @@ public:
                doesContainIndex(neighbourIndexes, 8));
     TSM_ASSERT("Neighbours at index 9 includes 7",
                doesContainIndex(neighbourIndexes, 7));
-
-    delete it;
   }
 
   void test_neighbours_2d_vertex_touching_by_width() {
@@ -876,7 +841,7 @@ public:
      8 - 9 -10 -11
      12-13 -14 -15
      */
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At initial position
     /*
@@ -953,8 +918,6 @@ public:
                doesContainIndex(neighbourIndexes, 13));
     TSM_ASSERT("Neighbour at index is 14",
                doesContainIndex(neighbourIndexes, 14));
-
-    delete it;
   }
 
   void test_neighbours_2d_vertex_touching_by_width_vector() {
@@ -973,7 +936,7 @@ public:
      8 - 9 -10 -11
      12-13 -14 -15
      */
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At initial position
     /*
@@ -1038,8 +1001,6 @@ public:
                doesContainIndex(neighbourIndexes, 13));
     TSM_ASSERT("Neighbour at index is 14",
                doesContainIndex(neighbourIndexes, 14));
-
-    delete it;
   }
 
   void test_neighbours_3d_vertex_touching_width() {
@@ -1071,7 +1032,7 @@ public:
      [60 61 62 63]]]
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // Start at Index = 0
     std::vector<size_t> neighbourIndexes =
@@ -1095,8 +1056,6 @@ public:
     TS_ASSERT(doesContainIndex(neighbourIndexes, 24));
     TS_ASSERT(doesContainIndex(neighbourIndexes, 25));
     TS_ASSERT(doesContainIndex(neighbourIndexes, 26));
-
-    delete it;
   }
 
   void test_cache() {
@@ -1110,7 +1069,7 @@ public:
 
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
     TSM_ASSERT_EQUALS("Empty cache expected", 0, it->permutationCacheSize());
     it->findNeighbourIndexesByWidth(3);
     TSM_ASSERT_EQUALS("One cache item expected", 1, it->permutationCacheSize());
@@ -1121,15 +1080,13 @@ public:
     it->findNeighbourIndexesByWidth(5);
     TSM_ASSERT_EQUALS("Two cache entries expected", 2,
                       it->permutationCacheSize());
-
-    delete it;
   }
 
   void test_getBoxExtents_1d() {
     const size_t nd = 1;
     MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(
         1.0 /*signal*/, nd, 3 /*3 bins*/); // Dimension length defaults to 10
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At zeroth position
     VecMDExtents extents = it->getBoxExtents();
@@ -1149,15 +1106,13 @@ public:
     extents = it->getBoxExtents();
     TS_ASSERT_DELTA(extents[0].get<0>(), 10.0 * 2.0 / 3.0, 1e-4);
     TS_ASSERT_DELTA(extents[0].get<1>(), 10.0 * 3.0 / 3.0, 1e-4);
-
-    delete it;
   }
 
   void test_getBoxExtents_3d() {
     MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(
         1.0 /*signal*/, 3 /*nd*/, 4 /*nbins per dim*/, 6 /*max*/,
         1.0 /*error sq*/);
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At zeroth position
     VecMDExtents extents = it->getBoxExtents();
@@ -1181,8 +1136,6 @@ public:
     TS_ASSERT_DELTA(extents[1].get<1>(), 4.0 / 4 * 6.0, 1e-4);
     TS_ASSERT_DELTA(extents[2].get<0>(), 3.0 / 4 * 6.0, 1e-4);
     TS_ASSERT_DELTA(extents[2].get<1>(), 4.0 / 4 * 6.0, 1e-4);
-
-    delete it;
   }
 
   void test_jump_to_nearest_1d() {
@@ -1210,8 +1163,8 @@ public:
 
     */
 
-    MDHistoWorkspaceIterator *itIn = new MDHistoWorkspaceIterator(wsIn);
-    MDHistoWorkspaceIterator *itOut = new MDHistoWorkspaceIterator(wsOut);
+    auto itIn = Kernel::make_unique<MDHistoWorkspaceIterator>(wsIn);
+    auto itOut = Kernel::make_unique<MDHistoWorkspaceIterator>(wsOut);
 
     // First position
     TS_ASSERT_EQUALS(itIn->getLinearIndex(), 0);
@@ -1239,9 +1192,6 @@ public:
     diff = itOut->jumpToNearest(itIn->getCenter());
     TS_ASSERT_EQUALS(itOut->getLinearIndex(), 3); // 10.5 closer to 12 than 8
     TS_ASSERT_DELTA(1.5, diff, 1e-4);
-
-    delete itIn;
-    delete itOut;
   }
 
   void test_neighbours_1d_with_width_including_out_of_bounds() {
@@ -1259,7 +1209,7 @@ public:
 
      */
 
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At first position
     /*
@@ -1348,8 +1298,6 @@ public:
                doesContainIndex(neighbourIndexes, 10)); // Invalid
     TSM_ASSERT("Neighbours include 3",
                doesContainIndex(neighbourIndexes, 11)); // Invalid
-
-    delete it;
   }
 
   void test_neighbours_2d_vertex_touching_by_width_including_out_of_bounds() {
@@ -1366,7 +1314,7 @@ public:
      8 - 9 -10 -11
      12-13 -14 -15
      */
-    MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws);
+    auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws);
 
     // At initial position
     /*
@@ -1451,8 +1399,6 @@ public:
                doesContainIndex(neighbourIndexes, 19)); // Invalid
     TSM_ASSERT("Neighbour at index is 23",
                doesContainIndex(neighbourIndexes, 23)); // Invalid
-
-    delete it;
   }
 };
 
@@ -1479,37 +1425,34 @@ public:
 
   /** ~Two million iterations */
   void test_iterator_3D_signalAndErrorOnly() {
-    MDHistoWorkspaceIterator *it =
-        new MDHistoWorkspaceIterator(ws, new SkipNothing);
+    auto it =
+        Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing);
     do {
       signal_t sig = it->getNormalizedSignal();
       signal_t err = it->getNormalizedError();
       UNUSED_ARG(sig);
       UNUSED_ARG(err);
     } while (it->next());
-    delete it;
   }
 
   /** ~Two million iterations */
   void test_iterator_3D_withGetVertexes() {
-    MDHistoWorkspaceIterator *it =
-        new MDHistoWorkspaceIterator(ws, new SkipNothing);
+    auto it =
+        Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing);
     size_t numVertices;
     do {
       signal_t sig = it->getNormalizedSignal();
       signal_t err = it->getNormalizedError();
-      coord_t *vertexes = it->getVertexesArray(numVertices);
-      delete[] vertexes;
+      auto vertexes = it->getVertexesArray(numVertices);
       UNUSED_ARG(sig);
       UNUSED_ARG(err);
     } while (it->next());
-    delete it;
   }
 
   /** ~Two million iterations */
   void test_iterator_3D_withGetCenter() {
-    MDHistoWorkspaceIterator *it =
-        new MDHistoWorkspaceIterator(ws, new SkipNothing);
+    auto it =
+        Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing);
     do {
       signal_t sig = it->getNormalizedSignal();
       signal_t err = it->getNormalizedError();
@@ -1517,13 +1460,12 @@ public:
       UNUSED_ARG(sig);
       UNUSED_ARG(err);
     } while (it->next());
-    delete it;
   }
 
   /** Use jumpTo() */
   void test_iterator_3D_withGetCenter_usingJumpTo() {
-    MDHistoWorkspaceIterator *it =
-        new MDHistoWorkspaceIterator(ws, new SkipNothing);
+    auto it =
+        Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing);
     int max = int(it->getDataSize());
     for (int i = 0; i < max; i++) {
       it->jumpTo(size_t(i));
@@ -1533,7 +1475,6 @@ public:
       UNUSED_ARG(sig);
       UNUSED_ARG(err);
     }
-    delete it;
   }
 
   void test_masked_get_vertexes_call_throws() {
diff --git a/Framework/DataObjects/test/MDHistoWorkspaceTest.h b/Framework/DataObjects/test/MDHistoWorkspaceTest.h
index b1870ca4b3fd16c8a188d7e47e3968cb0137c4c1..d0de735e34c10ac5d4cf6f248517ab2b1f30577a 100644
--- a/Framework/DataObjects/test/MDHistoWorkspaceTest.h
+++ b/Framework/DataObjects/test/MDHistoWorkspaceTest.h
@@ -33,7 +33,7 @@ private:
   /// Helper function to return the number of masked bins in a workspace. TODO:
   /// move helper into test helpers
   size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) {
-    Mantid::API::IMDIterator *it = ws->createIterator(NULL);
+    auto it = ws->createIterator(nullptr);
     size_t numberMasked = 0;
     size_t counter = 0;
     for (; counter < it->getDataSize(); ++counter) {
@@ -42,7 +42,6 @@ private:
       }
       it->next(1);
     }
-    delete it;
     return numberMasked;
   }
 
@@ -287,16 +286,14 @@ public:
         new MDHistoDimension("X", "x", frame, -10, 10, 5));
     MDHistoWorkspace ws(dimX);
     size_t numVertices;
-    coord_t *v1 = ws.getVertexesArray(0, numVertices);
+    auto v1 = ws.getVertexesArray(0, numVertices);
     TS_ASSERT_EQUALS(numVertices, 2);
     TS_ASSERT_DELTA(v1[0], -10.0, 1e-5);
     TS_ASSERT_DELTA(v1[1], -6.0, 1e-5);
-    delete[] v1;
 
-    coord_t *v2 = ws.getVertexesArray(4, numVertices);
+    auto v2 = ws.getVertexesArray(4, numVertices);
     TS_ASSERT_DELTA(v2[0], 6.0, 1e-5);
     TS_ASSERT_DELTA(v2[1], 10.0, 1e-5);
-    delete[] v2;
   }
 
   //---------------------------------------------------------------------------------------------------
@@ -309,7 +306,7 @@ public:
     MDHistoWorkspace ws(dimX, dimY);
     size_t numVertices, i;
 
-    boost::scoped_array<coord_t> v1(ws.getVertexesArray(0, numVertices));
+    auto v1 = ws.getVertexesArray(0, numVertices);
     TS_ASSERT_EQUALS(numVertices, 4);
     i = 0 * 2;
     TS_ASSERT_DELTA(v1[i + 0], -10.0, 1e-5);
@@ -318,7 +315,7 @@ public:
     TS_ASSERT_DELTA(v1[i + 0], -6.0, 1e-5);
     TS_ASSERT_DELTA(v1[i + 1], -6.0, 1e-5);
     // The opposite corner
-    boost::scoped_array<coord_t> v2(ws.getVertexesArray(24, numVertices));
+    auto v2 = ws.getVertexesArray(24, numVertices);
     i = 0 * 2;
     TS_ASSERT_DELTA(v2[i + 0], 6.0, 1e-5);
     TS_ASSERT_DELTA(v2[i + 1], 6.0, 1e-5);
@@ -339,7 +336,7 @@ public:
     MDHistoWorkspace ws(dimX, dimY, dimZ);
     size_t numVertices, i;
 
-    boost::scoped_array<coord_t> v(ws.getVertexesArray(0, numVertices));
+    auto v = ws.getVertexesArray(0, numVertices);
     TS_ASSERT_EQUALS(numVertices, 8);
     i = 0;
     TS_ASSERT_DELTA(v[i + 0], -10.0, 1e-5);
@@ -413,17 +410,15 @@ public:
     MDHistoDimension_sptr dimZ(
         new MDHistoDimension("Z", "z", frame, -8, 10, 10));
     MDHistoWorkspace ws(dimX, dimY, dimZ);
-    IMDIterator *it = ws.createIterator();
+    auto it = ws.createIterator();
     TS_ASSERT(it);
     MDHistoWorkspaceIterator *hwit =
-        dynamic_cast<MDHistoWorkspaceIterator *>(it);
+        dynamic_cast<MDHistoWorkspaceIterator *>(it.get());
     TS_ASSERT(hwit);
     TS_ASSERT(it->next());
-    delete it;
     boost::scoped_ptr<MDImplicitFunction> mdfunction(new MDImplicitFunction);
     it = ws.createIterator(mdfunction.get());
     TS_ASSERT(it);
-    delete it;
   }
 
   //---------------------------------------------------------------------------------------------------
@@ -1263,10 +1258,10 @@ public:
     IMDHistoWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<IMDHistoWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<IMDHistoWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -1274,9 +1269,9 @@ public:
     IMDHistoWorkspace_const_sptr wsCastConst;
     IMDHistoWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDHistoWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDHistoWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/MaskWorkspaceTest.h b/Framework/DataObjects/test/MaskWorkspaceTest.h
index f32094b5c2b86c788c5b69c6f1480f1f26bee012..275406bef2054746a929cc0c0cc9062e5e620fdc 100644
--- a/Framework/DataObjects/test/MaskWorkspaceTest.h
+++ b/Framework/DataObjects/test/MaskWorkspaceTest.h
@@ -129,10 +129,10 @@ public:
     MaskWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<MaskWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<MaskWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -140,9 +140,9 @@ public:
     MaskWorkspace_const_sptr wsCastConst;
     MaskWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (MaskWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (MaskWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/OffsetsWorkspaceTest.h b/Framework/DataObjects/test/OffsetsWorkspaceTest.h
index c910bbb631d9c58555d04060070ee9ee96549e0f..4bc9a8f60f160e2611e219e909c475465db7cdd0 100644
--- a/Framework/DataObjects/test/OffsetsWorkspaceTest.h
+++ b/Framework/DataObjects/test/OffsetsWorkspaceTest.h
@@ -38,10 +38,10 @@ public:
     OffsetsWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<OffsetsWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<OffsetsWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -49,9 +49,9 @@ public:
     OffsetsWorkspace_const_sptr wsCastConst;
     OffsetsWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (OffsetsWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (OffsetsWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/PeakTest.h b/Framework/DataObjects/test/PeakTest.h
index 9c3404718fc0c726ece72a950c40fd00ab2b4a3c..82ded86e3f99edbae856bffc7c907804babcea2c 100644
--- a/Framework/DataObjects/test/PeakTest.h
+++ b/Framework/DataObjects/test/PeakTest.h
@@ -601,8 +601,7 @@ private:
   void check_Contributing_Detectors(const Peak &peak,
                                     const std::vector<int> &expected) {
     auto peakIDs = peak.getContributingDetIDs();
-    for (auto it = expected.begin(); it != expected.end(); ++it) {
-      const int id = *it;
+    for (int id : expected) {
       TSM_ASSERT_EQUALS("Expected " + boost::lexical_cast<std::string>(id) +
                             " in contribution list",
                         1, peakIDs.count(id))
diff --git a/Framework/DataObjects/test/PeaksWorkspaceTest.h b/Framework/DataObjects/test/PeaksWorkspaceTest.h
index d0299473b002cdf4d5716037d6723c859c497515..929e62a01741eed1318c6fd29cd0632c98755585 100644
--- a/Framework/DataObjects/test/PeaksWorkspaceTest.h
+++ b/Framework/DataObjects/test/PeaksWorkspaceTest.h
@@ -56,7 +56,7 @@ public:
 
   /** Check that the PeaksWorkspace build by buildPW() is correct */
   void checkPW(const PeaksWorkspace &pw) {
-    TS_ASSERT_EQUALS(pw.columnCount(), 17);
+    TS_ASSERT_EQUALS(pw.columnCount(), 18);
     TS_ASSERT_EQUALS(pw.rowCount(), 1);
     TS_ASSERT_EQUALS(pw.getNumberPeaks(), 1);
     if (pw.getNumberPeaks() != 1)
@@ -481,10 +481,10 @@ public:
     PeaksWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<PeaksWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<PeaksWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -492,9 +492,9 @@ public:
     PeaksWorkspace_const_sptr wsCastConst;
     PeaksWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (PeaksWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (PeaksWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
@@ -513,10 +513,10 @@ public:
     IPeaksWorkspace_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<IPeaksWorkspace_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<IPeaksWorkspace_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -524,9 +524,9 @@ public:
     IPeaksWorkspace_const_sptr wsCastConst;
     IPeaksWorkspace_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (IPeaksWorkspace_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IPeaksWorkspace_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 
diff --git a/Framework/DataObjects/test/SpecialWorkspace2DTest.h b/Framework/DataObjects/test/SpecialWorkspace2DTest.h
index 88d2f1608a15dac281f9888c1409ba1b9d225d1f..40825c572ffe4fa33c9ba0c157012e142cc36c36 100644
--- a/Framework/DataObjects/test/SpecialWorkspace2DTest.h
+++ b/Framework/DataObjects/test/SpecialWorkspace2DTest.h
@@ -231,10 +231,10 @@ public:
     SpecialWorkspace2D_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<SpecialWorkspace2D_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<SpecialWorkspace2D_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -242,9 +242,9 @@ public:
     SpecialWorkspace2D_const_sptr wsCastConst;
     SpecialWorkspace2D_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (SpecialWorkspace2D_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (SpecialWorkspace2D_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/Workspace2DTest.h b/Framework/DataObjects/test/Workspace2DTest.h
index 9d3e6ccd6e0db5a7058ccf76f33a8a6210d29348..2f6958be4b372cdc19d8a68f20db20de81353068 100644
--- a/Framework/DataObjects/test/Workspace2DTest.h
+++ b/Framework/DataObjects/test/Workspace2DTest.h
@@ -250,10 +250,10 @@ public:
     Workspace2D_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<Workspace2D_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsNonConst =
                                  manager.getValue<Workspace2D_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -261,9 +261,9 @@ public:
     Workspace2D_const_sptr wsCastConst;
     Workspace2D_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst = (Workspace2D_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (Workspace2D_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/DataObjects/test/WorkspaceIteratorTest.h b/Framework/DataObjects/test/WorkspaceIteratorTest.h
index c218a9078cf54ec9812a3bf1220006c11614c0ca..291ba9adfa008b6a28fce5605cf73ed860062c35 100644
--- a/Framework/DataObjects/test/WorkspaceIteratorTest.h
+++ b/Framework/DataObjects/test/WorkspaceIteratorTest.h
@@ -33,10 +33,10 @@ public:
 
 class WorkspaceIteratorTest : public CxxTest::TestSuite {
 private:
-  typedef boost::shared_ptr<MantidVec> parray;
-  typedef boost::shared_ptr<Workspace2D> W2D;
-  typedef boost::shared_ptr<WorkspaceSingleValue> WSV;
-  typedef boost::shared_ptr<MatrixWorkspace> Wbase;
+  using parray = boost::shared_ptr<MantidVec>;
+  using W2D = boost::shared_ptr<Workspace2D>;
+  using WSV = boost::shared_ptr<WorkspaceSingleValue>;
+  using Wbase = boost::shared_ptr<MatrixWorkspace>;
 
 public:
   void testIteratorWorkspace2DAsBase() {
diff --git a/Framework/DataObjects/test/WorkspaceSingleValueTest.h b/Framework/DataObjects/test/WorkspaceSingleValueTest.h
index facddcc1d3fab004581f258269ebbcd8c2f704e9..015d1a21d20378f6fae393ba12bef57190ed601c 100644
--- a/Framework/DataObjects/test/WorkspaceSingleValueTest.h
+++ b/Framework/DataObjects/test/WorkspaceSingleValueTest.h
@@ -78,10 +78,10 @@ public:
     WorkspaceSingleValue_sptr wsNonConst;
     TS_ASSERT_THROWS_NOTHING(
         wsConst = manager.getValue<WorkspaceSingleValue_const_sptr>(wsName));
-    TS_ASSERT(wsConst != NULL);
+    TS_ASSERT(wsConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(
         wsNonConst = manager.getValue<WorkspaceSingleValue_sptr>(wsName));
-    TS_ASSERT(wsNonConst != NULL);
+    TS_ASSERT(wsNonConst != nullptr);
     TS_ASSERT_EQUALS(wsConst, wsNonConst);
 
     // Check TypedValue can be cast to const_sptr or to sptr
@@ -90,9 +90,9 @@ public:
     WorkspaceSingleValue_sptr wsCastNonConst;
     TS_ASSERT_THROWS_NOTHING(wsCastConst =
                                  (WorkspaceSingleValue_const_sptr)val);
-    TS_ASSERT(wsCastConst != NULL);
+    TS_ASSERT(wsCastConst != nullptr);
     TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (WorkspaceSingleValue_sptr)val);
-    TS_ASSERT(wsCastNonConst != NULL);
+    TS_ASSERT(wsCastNonConst != nullptr);
     TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst);
   }
 };
diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt
index b66dbe21896a5352ff8f1a3f57e3951982d92468..98e664cba7c3395e7f0e8545eb5b8242ea653613 100644
--- a/Framework/Geometry/CMakeLists.txt
+++ b/Framework/Geometry/CMakeLists.txt
@@ -109,16 +109,12 @@ set ( SRC_FILES
 	src/Objects/Rules.cpp
 	src/Objects/ShapeFactory.cpp
 	src/Objects/Track.cpp
-	src/Rendering/BitmapGeometryHandler.cpp
-	src/Rendering/CacheGeometryGenerator.cpp
-	src/Rendering/CacheGeometryHandler.cpp
-	src/Rendering/CacheGeometryRenderer.cpp
 	src/Rendering/GeometryHandler.cpp
-	src/Rendering/GluGeometryHandler.cpp
-	src/Rendering/GluGeometryRenderer.cpp
-	src/Rendering/StructuredGeometryHandler.cpp
+        src/Rendering/RenderingHelpers.cpp
+        src/Rendering/ShapeInfo.cpp
 	src/Rendering/vtkGeometryCacheReader.cpp
 	src/Rendering/vtkGeometryCacheWriter.cpp
+	src/Rendering/GeometryTriangulator.cpp
 	src/Surfaces/Cone.cpp
 	src/Surfaces/Cylinder.cpp
 	src/Surfaces/General.cpp
@@ -132,16 +128,8 @@ set ( SRC_FILES
 	src/Surfaces/Torus.cpp
 )
 
-set ( OPENCASCADE_SRC
-  src/Rendering/OCGeometryGenerator.cpp
-  src/Rendering/OCGeometryHandler.cpp
-  src/Rendering/OCGeometryRenderer.cpp
-)
-
 set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp
   src/Instrument/ObjCompAssembly.cpp
-  src/Rendering/OCGeometryHandler.cpp
-  src/Rendering/OCGeometryRenderer.cpp
 )
 
 set ( INC_FILES
@@ -270,24 +258,17 @@ set ( INC_FILES
 	inc/MantidGeometry/Objects/CSGObject.h
 	inc/MantidGeometry/Objects/IObject.h
 	inc/MantidGeometry/Objects/InstrumentRayTracer.h
-    inc/MantidGeometry/Objects/MeshObject.h
+        inc/MantidGeometry/Objects/MeshObject.h
 	inc/MantidGeometry/Objects/Rules.h
 	inc/MantidGeometry/Objects/ShapeFactory.h
 	inc/MantidGeometry/Objects/Track.h
-	inc/MantidGeometry/Rendering/BitmapGeometryHandler.h
-	inc/MantidGeometry/Rendering/CacheGeometryGenerator.h
-	inc/MantidGeometry/Rendering/CacheGeometryHandler.h
-	inc/MantidGeometry/Rendering/CacheGeometryRenderer.h
 	inc/MantidGeometry/Rendering/GeometryHandler.h
-	inc/MantidGeometry/Rendering/GluGeometryHandler.h
-	inc/MantidGeometry/Rendering/GluGeometryRenderer.h
-	inc/MantidGeometry/Rendering/OCGeometryGenerator.h
-	inc/MantidGeometry/Rendering/OCGeometryHandler.h
-	inc/MantidGeometry/Rendering/OCGeometryRenderer.h
+    	inc/MantidGeometry/Rendering/RenderingHelpers.h
+    	inc/MantidGeometry/Rendering/ShapeInfo.h
 	inc/MantidGeometry/Rendering/OpenGL_Headers.h
-	inc/MantidGeometry/Rendering/StructuredGeometryHandler.h
 	inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h
 	inc/MantidGeometry/Rendering/vtkGeometryCacheWriter.h
+	inc/MantidGeometry/Rendering/GeometryTriangulator.h
 	inc/MantidGeometry/Surfaces/BaseVisit.h
 	inc/MantidGeometry/Surfaces/Cone.h
 	inc/MantidGeometry/Surfaces/Cylinder.h
@@ -410,6 +391,7 @@ set ( TEST_FILES
 	SampleEnvironmentTest.h
 	ScalarUtilsTest.h
 	ShapeFactoryTest.h
+        ShapeInfoTest.h
 	SpaceGroupFactoryTest.h
 	SpaceGroupTest.h
 	SphereTest.h
@@ -446,11 +428,6 @@ if(UNITY_BUILD)
   enable_unity_build(Geometry SRC_FILES SRC_UNITY_IGNORE_FILES 10)
 endif(UNITY_BUILD)
 
-# ===================== Open Cascade ===================
-if (ENABLE_OPENCASCADE)
-  LIST (APPEND SRC_FILES ${OPENCASCADE_SRC} )
-endif ()
-
 # A few defines needed for OpenCascade on the Mac
 if ( APPLE )
   add_definitions ( -DHAVE_IOSTREAM -DHAVE_LIMITS -DHAVE_IOMANIP )
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h
index 82f4460245b4eaa630229fb943acb4af616f1cb5..40e0ebff6cd5b442e526bdc59f837ca621b85270 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h
@@ -13,11 +13,11 @@
 namespace Mantid {
 namespace Geometry {
 
-typedef std::complex<double> StructureFactor;
+using StructureFactor = std::complex<double>;
 
 class BraggScatterer;
 
-typedef boost::shared_ptr<BraggScatterer> BraggScatterer_sptr;
+using BraggScatterer_sptr = boost::shared_ptr<BraggScatterer>;
 
 /**
     @class BraggScatterer
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h
index a9782105dc3dc6b7f1b78931580ca5d323dcc5f9..bc496e93ce61ba6cfe45a41922ac56aefab251ca 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h
@@ -85,8 +85,8 @@ private:
   BraggScattererFactoryImpl();
 };
 
-typedef Mantid::Kernel::SingletonHolder<BraggScattererFactoryImpl>
-    BraggScattererFactory;
+using BraggScattererFactory =
+    Mantid::Kernel::SingletonHolder<BraggScattererFactoryImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h
index b08fbe7e9945c836c2175f47b15c54443597fff9..584133be8207004eadcc72fc57a35ee0752e7597 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h
@@ -72,8 +72,8 @@ protected:
   UnitCell m_cell;
 };
 
-typedef boost::shared_ptr<BraggScattererInCrystalStructure>
-    BraggScattererInCrystalStructure_sptr;
+using BraggScattererInCrystalStructure_sptr =
+    boost::shared_ptr<BraggScattererInCrystalStructure>;
 
 /**
  * Helper class for validating unit cell strings.
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h
index 85c03b85504d7b981875cee0339262179b378bc0..3356098ff91b3974b1320caebd70f9379f127450 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h
@@ -65,8 +65,8 @@ protected:
   std::string m_symbol;
 };
 
-typedef boost::shared_ptr<CenteringGroup> CenteringGroup_sptr;
-typedef boost::shared_ptr<const CenteringGroup> CenteringGroup_const_sptr;
+using CenteringGroup_sptr = boost::shared_ptr<CenteringGroup>;
+using CenteringGroup_const_sptr = boost::shared_ptr<const CenteringGroup>;
 
 /// Helper class to keep this out of the interface of CenteringGroup.
 class MANTID_GEOMETRY_DLL CenteringGroupCreatorImpl {
@@ -94,8 +94,8 @@ private:
   friend struct Mantid::Kernel::CreateUsingNew<CenteringGroupCreatorImpl>;
 };
 
-typedef Mantid::Kernel::SingletonHolder<CenteringGroupCreatorImpl>
-    CenteringGroupCreator;
+using CenteringGroupCreator =
+    Mantid::Kernel::SingletonHolder<CenteringGroupCreatorImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h
index 49d08693628bb905a0a360248cbed277975ab26a..c4317a23dad71dc98e306f4627e51f99d734b2b5 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h
@@ -59,7 +59,7 @@ namespace Geometry {
   */
 class CompositeBraggScatterer;
 
-typedef boost::shared_ptr<CompositeBraggScatterer> CompositeBraggScatterer_sptr;
+using CompositeBraggScatterer_sptr = boost::shared_ptr<CompositeBraggScatterer>;
 
 class MANTID_GEOMETRY_DLL CompositeBraggScatterer : public BraggScatterer {
 public:
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h
index cfa639ec75e0ce63df40a10fb66b2220bb543c04..fe8787ea21207beced875ffdd8b14c4785794ac5 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h
@@ -116,7 +116,7 @@ protected:
   CompositeBraggScatterer_sptr m_scatterers;
 };
 
-typedef boost::shared_ptr<CrystalStructure> CrystalStructure_sptr;
+using CrystalStructure_sptr = boost::shared_ptr<CrystalStructure>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h
index 8c1c07f5923a72c05bbd1913e98570b29c25e20f..991c674c0b072c593747325f91077c8680d71971 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h
@@ -89,8 +89,8 @@ protected:
   generateAllOperations(const SymmetryOperation &operation) const;
 };
 
-typedef boost::shared_ptr<CyclicGroup> CyclicGroup_sptr;
-typedef boost::shared_ptr<const CyclicGroup> CyclicGroup_const_sptr;
+using CyclicGroup_sptr = boost::shared_ptr<CyclicGroup>;
+using CyclicGroup_const_sptr = boost::shared_ptr<const CyclicGroup>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h b/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h
index ec5f164f1407700865448f798a1e48132cff4ea5..459d2f6b27f3c52abd38de87952a483784cc418d 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h
@@ -195,8 +195,8 @@ protected:
   CoordinateSystem m_axisSystem;
 };
 
-typedef boost::shared_ptr<Group> Group_sptr;
-typedef boost::shared_ptr<const Group> Group_const_sptr;
+using Group_sptr = boost::shared_ptr<Group>;
+using Group_const_sptr = boost::shared_ptr<const Group>;
 
 namespace GroupFactory {
 /// Creates a Group sub-class of type T if T has a constructor that takes a
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h
index 04647bd3ee371c0c279704b014ffeb926b984309..f687ff7e9962c0baa86067c7b5fd76fcdd744eb1 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h
@@ -88,7 +88,7 @@ public:
   virtual bool isAllowed(const Kernel::V3D &hkl) const = 0;
 };
 
-typedef boost::shared_ptr<const HKLFilter> HKLFilter_const_sptr;
+using HKLFilter_const_sptr = boost::shared_ptr<const HKLFilter>;
 
 /// Base class for unary logic operations for HKLFilter.
 class MANTID_GEOMETRY_DLL HKLFilterUnaryLogicOperation : public HKLFilter {
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h
index b20d11ccf2f0c219d02657d251d62098597c517a..b3467fdf70924cd0e3b8d1dd283e136899470d3a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h
@@ -143,7 +143,7 @@ public:
     int m_h, m_k, m_l;
     Kernel::V3D m_hkl;
 
-    int m_hMin, m_hMax;
+    int m_hMax;
     int m_kMin, m_kMax;
     int m_lMin, m_lMax;
   };
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
index 9d871cd30587af00314313940c8e484e9b457a6c..f900b5b7cb4b6a464706f3d1e156703e710b9ea1 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
@@ -11,6 +11,7 @@
 
 namespace Mantid {
 namespace Geometry {
+class InstrumentRayTracer;
 
 /** Structure describing a single-crystal peak
  *
@@ -49,6 +50,7 @@ public:
   virtual Mantid::Kernel::V3D getQLabFrame() const = 0;
   virtual Mantid::Kernel::V3D getQSampleFrame() const = 0;
   virtual bool findDetector() = 0;
+  virtual bool findDetector(const InstrumentRayTracer &tracer) = 0;
 
   virtual void setQSampleFrame(const Mantid::Kernel::V3D &QSampleFrame,
                                boost::optional<double> detectorDistance) = 0;
@@ -58,6 +60,7 @@ public:
   virtual void setWavelength(double wavelength) = 0;
   virtual double getWavelength() const = 0;
   virtual double getScattering() const = 0;
+  virtual double getAzimuthal() const = 0;
   virtual double getDSpacing() const = 0;
   virtual double getTOF() const = 0;
 
@@ -76,6 +79,9 @@ public:
   virtual double getBinCount() const = 0;
   virtual void setBinCount(double m_BinCount) = 0;
 
+  virtual int getPeakNumber() const = 0;
+  virtual void setPeakNumber(int m_PeakNumber) = 0;
+
   virtual Mantid::Kernel::Matrix<double> getGoniometerMatrix() const = 0;
   virtual void setGoniometerMatrix(
       const Mantid::Kernel::Matrix<double> &m_GoniometerMatrix) = 0;
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h
index 890bcbbb1f6b86be284805e340923c7e1550006f..a3151c95f1776a1bddbab65488f052b9fe83cd1a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h
@@ -10,8 +10,8 @@ namespace Geometry {
 
 class IsotropicAtomBraggScatterer;
 
-typedef boost::shared_ptr<IsotropicAtomBraggScatterer>
-    IsotropicAtomBraggScatterer_sptr;
+using IsotropicAtomBraggScatterer_sptr =
+    boost::shared_ptr<IsotropicAtomBraggScatterer>;
 
 /** @class IsotropicAtomBraggScatterer
 
@@ -121,8 +121,8 @@ protected:
   std::string m_label;
 };
 
-typedef boost::shared_ptr<IsotropicAtomBraggScatterer>
-    IsotropicAtomBraggScatterer_sptr;
+using IsotropicAtomBraggScatterer_sptr =
+    boost::shared_ptr<IsotropicAtomBraggScatterer>;
 
 class MANTID_GEOMETRY_DLL IsotropicAtomBraggScattererParser {
 public:
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h
index c23c23d963f9659d8310bfb52cd6c1aefd6276b6..bed0e01949726c3bac8bbb3d589800b36383c415 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h
@@ -55,8 +55,8 @@ public:
   virtual ~PeakShape() = default;
 };
 
-typedef boost::shared_ptr<PeakShape> PeakShape_sptr;
-typedef boost::shared_ptr<const PeakShape> PeakShape_const_sptr;
+using PeakShape_sptr = boost::shared_ptr<PeakShape>;
+using PeakShape_const_sptr = boost::shared_ptr<const PeakShape>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h
index a00796790c716258b2db5d1d1d56e791f2ce1cd5..8af664f9342b5efa0120c0ab2d1f4f3640dcd66d 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h
@@ -56,8 +56,8 @@ protected:
 };
 
 /// Typedef for a PeakTransform wrapped in a shared_pointer.
-typedef boost::shared_ptr<PeakTransform> PeakTransform_sptr;
-typedef boost::shared_ptr<const PeakTransform> PeakTransform_const_sptr;
+using PeakTransform_sptr = boost::shared_ptr<PeakTransform>;
+using PeakTransform_const_sptr = boost::shared_ptr<const PeakTransform>;
 
 /**
 @class PeakTransformException
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h
index 17acec02f1bc40dc8aa63964e9ce92158c702423..9cd3c1163b5f2788150b91a508d063dfff5a88bd 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h
@@ -21,7 +21,7 @@ public:
 };
 
 /// Factory Shared Pointer typedef.
-typedef boost::shared_ptr<PeakTransformFactory> PeakTransformFactory_sptr;
+using PeakTransformFactory_sptr = boost::shared_ptr<PeakTransformFactory>;
 }
 }
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h
index 260a392c415611ca1101b1f7bb3dc9725ea4d949..774a1b1eb8eb4642464e0d8f49ae873e59c29b32 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h
@@ -31,7 +31,7 @@ public:
 };
 
 /// Typedef a factory for type of PeaksTransform.
-typedef ConcretePeakTransformFactory<PeakTransformHKL> PeakTransformHKLFactory;
+using PeakTransformHKLFactory = ConcretePeakTransformFactory<PeakTransformHKL>;
 }
 }
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h
index 1cb77266541ca04127cbe481ad8757b6bc261319..ac135a8df02382fee314882973ebf7aa67d3f4a6 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h
@@ -31,8 +31,8 @@ public:
 };
 
 /// Typedef a factory for type of PeaksTransform.
-typedef ConcretePeakTransformFactory<PeakTransformQLab>
-    PeakTransformQLabFactory;
+using PeakTransformQLabFactory =
+    ConcretePeakTransformFactory<PeakTransformQLab>;
 }
 }
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h
index f6e0e2b7bfe749b70551ba79dfdad28bc26afdbf..b2204cf33ff8d8f2bcded40780e9f73ae416629a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h
@@ -31,8 +31,8 @@ public:
 };
 
 /// Typedef a factory for type of PeaksTransform.
-typedef ConcretePeakTransformFactory<PeakTransformQSample>
-    PeakTransformQSampleFactory;
+using PeakTransformQSampleFactory =
+    ConcretePeakTransformFactory<PeakTransformQSample>;
 }
 }
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h
index b7fe36dce4c2bb24d2eafabbee004eb1babcd452..6706bcdb5d0454039543ec5c62cf442257179cb6 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h
@@ -34,7 +34,7 @@ private:
   /// Disabled assigment operator
   PeakTransformSelector &operator=(const PeakTransformSelector &);
   /// Collection of candidate factories.
-  typedef std::set<PeakTransformFactory_sptr> Factories;
+  using Factories = std::set<PeakTransformFactory_sptr>;
   Factories m_candidateFactories;
 };
 }
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
index 0de5373f0a9f423cb7d0ca0e9dfab984425e5010..1d6e64c7cc89ca6643bd4e52fe6363380b8d1ef2 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
@@ -77,7 +77,7 @@ protected:
 };
 
 /// Shared pointer to a PointGroup
-typedef boost::shared_ptr<PointGroup> PointGroup_sptr;
+using PointGroup_sptr = boost::shared_ptr<PointGroup>;
 
 MANTID_GEOMETRY_DLL std::vector<PointGroup_sptr> getAllPointGroups();
 
@@ -107,8 +107,9 @@ struct MANTID_GEOMETRY_DLL CrystalSystemComparator {
                   const PointGroup::CrystalSystem &rhs) const;
 };
 
-typedef std::multimap<PointGroup::CrystalSystem, PointGroup_sptr,
-                      CrystalSystemComparator> PointGroupCrystalSystemMap;
+using PointGroupCrystalSystemMap =
+    std::multimap<PointGroup::CrystalSystem, PointGroup_sptr,
+                  CrystalSystemComparator>;
 
 MANTID_GEOMETRY_DLL PointGroupCrystalSystemMap getPointGroupsByCrystalSystem();
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h
index 6e22e4a622a6bcb1ea75aaec3072cba60d138d72..51f76496811c654433201a3d19e437208bb7cf0a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h
@@ -38,7 +38,7 @@ private:
   PointGroup_sptr m_prototype;
 };
 
-typedef boost::shared_ptr<PointGroupGenerator> PointGroupGenerator_sptr;
+using PointGroupGenerator_sptr = boost::shared_ptr<PointGroupGenerator>;
 
 /**
   @class PointGroupFactory
@@ -120,8 +120,8 @@ private:
   boost::regex m_originChoiceRegex;
 };
 
-typedef Mantid::Kernel::SingletonHolder<PointGroupFactoryImpl>
-    PointGroupFactory;
+using PointGroupFactory =
+    Mantid::Kernel::SingletonHolder<PointGroupFactoryImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h
index 3eb01e35222b08a2e55dc6298bac78ac20214849..aa2a989a57fd01bdc4a727d1e99edd924123dd6c 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h
@@ -168,7 +168,7 @@ public:
 };
 
 /// Shared pointer to a ReflectionCondition
-typedef boost::shared_ptr<ReflectionCondition> ReflectionCondition_sptr;
+using ReflectionCondition_sptr = boost::shared_ptr<ReflectionCondition>;
 
 MANTID_GEOMETRY_DLL std::vector<ReflectionCondition_sptr>
 getAllReflectionConditions();
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h
index 11a16a63a4c4e93cae070d3bef3aaa445639c0d5..26e56434b3d2e349a06c75246680703f3cffaceb 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h
@@ -101,8 +101,8 @@ protected:
 MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &stream,
                                              const SpaceGroup &self);
 
-typedef boost::shared_ptr<SpaceGroup> SpaceGroup_sptr;
-typedef boost::shared_ptr<const SpaceGroup> SpaceGroup_const_sptr;
+using SpaceGroup_sptr = boost::shared_ptr<SpaceGroup>;
+using SpaceGroup_const_sptr = boost::shared_ptr<const SpaceGroup>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h
index 49239db44a40d98a410ccdba3138dbca523d0b1a..536711ebbc5504855b4760a1834c2887238779cf 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h
@@ -61,8 +61,8 @@ private:
   SpaceGroup_const_sptr m_prototype;
 };
 
-typedef boost::shared_ptr<AbstractSpaceGroupGenerator>
-    AbstractSpaceGroupGenerator_sptr;
+using AbstractSpaceGroupGenerator_sptr =
+    boost::shared_ptr<AbstractSpaceGroupGenerator>;
 
 /// Concrete space group generator that uses space group generators as given in
 /// ITA.
@@ -265,8 +265,8 @@ private:
   friend struct Mantid::Kernel::CreateUsingNew<SpaceGroupFactoryImpl>;
 };
 
-typedef Mantid::Kernel::SingletonHolder<SpaceGroupFactoryImpl>
-    SpaceGroupFactory;
+using SpaceGroupFactory =
+    Mantid::Kernel::SingletonHolder<SpaceGroupFactoryImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h
index 0e14ff57b0e26264591f39f1b99b87dbaf1960bc..ca7da50362efaf35e00fa0931fd5e40483424fe3 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h
@@ -59,8 +59,8 @@ protected:
   crystalStructureSetHook(const CrystalStructure &crystalStructure);
 };
 
-typedef boost::shared_ptr<StructureFactorCalculator>
-    StructureFactorCalculator_sptr;
+using StructureFactorCalculator_sptr =
+    boost::shared_ptr<StructureFactorCalculator>;
 
 namespace StructureFactorCalculatorFactory {
 /// Small templated factory function that creates the desired calculator
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h
index cc3a36bb6e017738dc13273ba64a50cb1e8b548a..890695c8f852e5e2d5742624466c9caad3b3110e 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h
@@ -54,8 +54,8 @@ protected:
   CompositeBraggScatterer_sptr m_unitCellScatterers;
 };
 
-typedef boost::shared_ptr<StructureFactorCalculatorSummation>
-    StructureFactorSummation_sptr;
+using StructureFactorSummation_sptr =
+    boost::shared_ptr<StructureFactorCalculatorSummation>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h
index 24f2452565f0629dd5f8f979e8b30921dc897027..1786880dff5fa64e11ec2de89f565d5f733f3f68 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h
@@ -65,7 +65,7 @@ protected:
   std::string m_hmSymbol;
 };
 
-typedef boost::shared_ptr<SymmetryElement> SymmetryElement_sptr;
+using SymmetryElement_sptr = boost::shared_ptr<SymmetryElement>;
 
 /** @class SymmetryElementIdentity
 
@@ -79,7 +79,7 @@ public:
   SymmetryElement_sptr clone() const override;
 };
 
-typedef boost::shared_ptr<SymmetryElementIdentity> SymmetryElementIdentity_sptr;
+using SymmetryElementIdentity_sptr = boost::shared_ptr<SymmetryElementIdentity>;
 
 /** @class SymmetryElementInversion
 
@@ -100,8 +100,8 @@ protected:
   V3R m_inversionPoint;
 };
 
-typedef boost::shared_ptr<SymmetryElementInversion>
-    SymmetryElementInversion_sptr;
+using SymmetryElementInversion_sptr =
+    boost::shared_ptr<SymmetryElementInversion>;
 
 /** @class SymmetryElementTranslation
 
@@ -122,8 +122,8 @@ protected:
   V3R m_translation;
 };
 
-typedef boost::shared_ptr<SymmetryElementTranslation>
-    SymmetryElementTranslation_sptr;
+using SymmetryElementTranslation_sptr =
+    boost::shared_ptr<SymmetryElementTranslation>;
 
 /** @class SymmetryElementWithAxis
 
@@ -150,7 +150,7 @@ protected:
   V3R m_translation;
 };
 
-typedef boost::shared_ptr<SymmetryElementWithAxis> SymmetryElementWithAxis_sptr;
+using SymmetryElementWithAxis_sptr = boost::shared_ptr<SymmetryElementWithAxis>;
 
 /** @class SymmetryElementRotation
 
@@ -183,7 +183,7 @@ protected:
   RotationSense m_rotationSense;
 };
 
-typedef boost::shared_ptr<SymmetryElementRotation> SymmetryElementRotation_sptr;
+using SymmetryElementRotation_sptr = boost::shared_ptr<SymmetryElementRotation>;
 
 /** @class SymmetryElementMirror
 
@@ -203,7 +203,7 @@ public:
   SymmetryElement_sptr clone() const override;
 };
 
-typedef boost::shared_ptr<SymmetryElementMirror> SymmetryElementMirror_sptr;
+using SymmetryElementMirror_sptr = boost::shared_ptr<SymmetryElementMirror>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h
index b0e3c5c1195225f3842ec865b9899757bb1c50da..5da8c6f963ba61599968d376365dd84e54ed3d0c 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h
@@ -41,8 +41,8 @@ public:
   virtual bool canProcess(const SymmetryOperation &operation) const = 0;
 };
 
-typedef boost::shared_ptr<AbstractSymmetryElementGenerator>
-    AbstractSymmetryElementGenerator_sptr;
+using AbstractSymmetryElementGenerator_sptr =
+    boost::shared_ptr<AbstractSymmetryElementGenerator>;
 
 /** @class SymmetryElementIdentityGenerator
 
@@ -258,8 +258,8 @@ private:
   friend struct Mantid::Kernel::CreateUsingNew<SymmetryElementFactoryImpl>;
 };
 
-typedef Mantid::Kernel::SingletonHolder<SymmetryElementFactoryImpl>
-    SymmetryElementFactory;
+using SymmetryElementFactory =
+    Mantid::Kernel::SingletonHolder<SymmetryElementFactoryImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h
index e9fa3cb12dea67dcb9f6ee93cd271cdc4181e53f..03b1d78c0d163472561d654733da789fff10d396 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h
@@ -78,8 +78,8 @@ private:
   SymmetryOperationFactoryImpl();
 };
 
-typedef Mantid::Kernel::SingletonHolder<SymmetryOperationFactoryImpl>
-    SymmetryOperationFactory;
+using SymmetryOperationFactory =
+    Mantid::Kernel::SingletonHolder<SymmetryOperationFactoryImpl>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h b/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h
index 3b794970e9aef4b7179cfe660d2efd80ae4131ae..abd1a45938be3b7fc9937bdc17f1700c267ed9b4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h
@@ -47,7 +47,7 @@ namespace Geometry {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
   */
 
-typedef boost::rational<int> RationalNumber;
+using RationalNumber = boost::rational<int>;
 
 class MANTID_GEOMETRY_DLL V3R {
 public:
diff --git a/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h b/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h
index 63684d264f83d36e6fd96efc9580cc55acf4f58a..bd7af1c70f9a05d17c870a28cee93d5e25c42e0f 100644
--- a/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h
+++ b/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h
@@ -95,9 +95,9 @@ private:
 };
 
 /// Shared pointer to a ICompAssembly
-typedef boost::shared_ptr<ICompAssembly> ICompAssembly_sptr;
+using ICompAssembly_sptr = boost::shared_ptr<ICompAssembly>;
 /// Shared pointer to a const ICompAssembly
-typedef boost::shared_ptr<const ICompAssembly> ICompAssembly_const_sptr;
+using ICompAssembly_const_sptr = boost::shared_ptr<const ICompAssembly>;
 
 } // Namespace Geometry
 } // Namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/IComponent.h b/Framework/Geometry/inc/MantidGeometry/IComponent.h
index 251abc2d4ff4227a31f199e825f3147ad0fad708..25b3bbc9cfa4e8c359ad19bb7366eb8dd44a80df 100644
--- a/Framework/Geometry/inc/MantidGeometry/IComponent.h
+++ b/Framework/Geometry/inc/MantidGeometry/IComponent.h
@@ -25,7 +25,7 @@ class IComponent;
 class ParameterMap;
 
 /// Define a type for a unique component identifier.
-typedef IComponent *ComponentID;
+using ComponentID = IComponent *;
 
 /** @class IComponent
 @brief base class for Geometric IComponent
@@ -186,9 +186,9 @@ public:
 };
 
 /// Typedef of a shared pointer to a IComponent
-typedef boost::shared_ptr<IComponent> IComponent_sptr;
+using IComponent_sptr = boost::shared_ptr<IComponent>;
 /// Typdef of a shared pointer to a const IComponent
-typedef boost::shared_ptr<const IComponent> IComponent_const_sptr;
+using IComponent_const_sptr = boost::shared_ptr<const IComponent>;
 
 } // Namespace Geometry
 
diff --git a/Framework/Geometry/inc/MantidGeometry/IDTypes.h b/Framework/Geometry/inc/MantidGeometry/IDTypes.h
index 45d54a1a702adcb886a21caa1abdaa4089095240..c6d38b6be083f1d5c51005bec42ef140cce85b4b 100644
--- a/Framework/Geometry/inc/MantidGeometry/IDTypes.h
+++ b/Framework/Geometry/inc/MantidGeometry/IDTypes.h
@@ -8,10 +8,10 @@
 namespace Mantid {
 
 /// Typedef for a spectrum Number
-typedef int32_t specnum_t;
+using specnum_t = int32_t;
 
 /// Typedef for a detector ID
-typedef int32_t detid_t;
+using detid_t = int32_t;
 }
 
 #endif // MANTID_GEOMETRY_IDTYPES_H_
diff --git a/Framework/Geometry/inc/MantidGeometry/IDetector.h b/Framework/Geometry/inc/MantidGeometry/IDetector.h
index 078f1870938249be396e5ce3cf5aa9b84ce9ae34..1ad29b9e9598cb76f9003dfb1785a36854109f14 100644
--- a/Framework/Geometry/inc/MantidGeometry/IDetector.h
+++ b/Framework/Geometry/inc/MantidGeometry/IDetector.h
@@ -115,10 +115,10 @@ public:
 };
 
 /// Shared pointer to IDetector
-typedef boost::shared_ptr<Mantid::Geometry::IDetector> IDetector_sptr;
+using IDetector_sptr = boost::shared_ptr<Mantid::Geometry::IDetector>;
 /// Shared pointer to IDetector (const version)
-typedef boost::shared_ptr<const Mantid::Geometry::IDetector>
-    IDetector_const_sptr;
+using IDetector_const_sptr =
+    boost::shared_ptr<const Mantid::Geometry::IDetector>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h b/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h
index 46d8aca207054089a75d37e9681cb6ff1bf13d58..aa4b536864545893707ebc02c8728c9470dc9cac 100644
--- a/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h
+++ b/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h
@@ -34,13 +34,13 @@ namespace Geometry {
 class IDetector;
 
 /// Shared pointer to an IDetector object
-typedef boost::shared_ptr<IDetector> IDetector_sptr;
+using IDetector_sptr = boost::shared_ptr<IDetector>;
 /// Shared pointer to an const IDetector object
-typedef boost::shared_ptr<const IDetector> IDetector_const_sptr;
+using IDetector_const_sptr = boost::shared_ptr<const IDetector>;
 /// unique pointer to an IDetector
-typedef std::unique_ptr<IDetector> IDetector_uptr;
+using IDetector_uptr = std::unique_ptr<IDetector>;
 /// unique pointer to an IDetector (const version)
-typedef std::unique_ptr<const IDetector> IDetector_const_uptr;
+using IDetector_const_uptr = std::unique_ptr<const IDetector>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
index 8cafbd21fb185c191770a08c8fd5c1f40746aa79..2553ed3915c90b2c233b733e2107f1cf0c476dcb 100644
--- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
+++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
@@ -59,6 +59,10 @@ public:
 
   IObjComponent(GeometryHandler *the_handler);
 
+  IObjComponent(const IObjComponent &);
+
+  IObjComponent &operator=(const IObjComponent &rhs);
+
   // Looking to get rid of the first of these constructors in due course (and
   // probably add others)
   ~IObjComponent() override;
@@ -104,11 +108,6 @@ public:
   GeometryHandler *Handle() const { return handle; }
 
 protected:
-  /// Protected copy constructor
-  IObjComponent(const IObjComponent &);
-  /// Assignment operator
-  IObjComponent &operator=(const IObjComponent &);
-
   /// Reset the current geometry handler
   void setGeometryHandler(GeometryHandler *h);
 
@@ -120,9 +119,9 @@ private:
 };
 
 /// Shared pointer to IObjComponent
-typedef boost::shared_ptr<IObjComponent> IObjComponent_sptr;
+using IObjComponent_sptr = boost::shared_ptr<IObjComponent>;
 /// Shared pointer to IObjComponent (const version)
-typedef boost::shared_ptr<const IObjComponent> IObjComponent_const_sptr;
+using IObjComponent_const_sptr = boost::shared_ptr<const IObjComponent>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument.h b/Framework/Geometry/inc/MantidGeometry/Instrument.h
index 82c605c140a23ff1cc65cc325968a5a1055f108e..53d40e5079c7b859128f9cbb621b35fa86b2a1a0 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument.h
@@ -17,7 +17,7 @@
 
 namespace Mantid {
 /// Typedef of a map from detector ID to detector shared pointer.
-typedef std::map<detid_t, Geometry::IDetector_const_sptr> detid2det_map;
+using detid2det_map = std::map<detid_t, Geometry::IDetector_const_sptr>;
 
 namespace Geometry {
 class ComponentInfo;
@@ -26,9 +26,9 @@ class XMLInstrumentParameter;
 class ParameterMap;
 class ReferenceFrame;
 /// Convenience typedef
-typedef std::map<std::pair<std::string, const IComponent *>,
-                 boost::shared_ptr<XMLInstrumentParameter>>
-    InstrumentParameterCache;
+using InstrumentParameterCache =
+    std::map<std::pair<std::string, const IComponent *>,
+             boost::shared_ptr<XMLInstrumentParameter>>;
 
 /**
 Base Instrument Class.
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h
index 41169e9142b421fdae94217c049a5ccdf89664c4..2102997d767235544c750468ea45e82183f55f75 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h
@@ -47,9 +47,9 @@ namespace Geometry {
 class MANTID_GEOMETRY_DLL CompAssembly : public ICompAssembly,
                                          public Component {
 protected:
-  typedef std::vector<IComponent *>::iterator comp_it; ///< Iterator type
-  typedef std::vector<IComponent *>::const_iterator
-      const_comp_it; ///< Const iterator type
+  using comp_it = std::vector<IComponent *>::iterator; ///< Iterator type
+  using const_comp_it =
+      std::vector<IComponent *>::const_iterator; ///< Const iterator type
 
 public:
   /// String description of the type of component
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
index 81ea8c9367e23638109d10c851fac1c57376f4e2..73090822a23a767619d80092bf4994114ac206b6 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h
@@ -5,7 +5,6 @@
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include <boost/shared_ptr.hpp>
-#include <map>
 #include <unordered_map>
 #include <vector>
 
@@ -70,23 +69,24 @@ private:
 
   /// Private copy constructor. Do not make public.
   ComponentInfo(const ComponentInfo &other);
-  template <typename IteratorT>
-  void growBoundingBoxAsRectuangularBank(
-      size_t index, const Geometry::BoundingBox *reference,
-      Geometry::BoundingBox &mutableBB,
-      std::map<size_t, size_t> &mutableDetExclusions,
-      IteratorT &mutableIterator) const;
-  template <typename IteratorT>
+  void
+  growBoundingBoxAsRectuangularBank(size_t index,
+                                    const Geometry::BoundingBox *reference,
+                                    Geometry::BoundingBox &mutableBB) const;
   void growBoundingBoxAsOutline(size_t index,
                                 const Geometry::BoundingBox *reference,
-                                Geometry::BoundingBox &mutableBB,
-                                std::map<size_t, size_t> &mutableDetExclusions,
-                                IteratorT &mutableIterator) const;
-  void growBoundingBoxByDetectors(
-      size_t index, const BoundingBox *reference, BoundingBox &mutableBB,
-      const std::map<size_t, size_t> &detectorExclusions) const;
+                                Geometry::BoundingBox &mutableBB) const;
 
 public:
+  struct QuadrilateralComponent {
+    size_t topLeft;
+    size_t bottomLeft;
+    size_t bottomRight;
+    size_t topRight;
+    size_t nX;
+    size_t nY;
+  };
+
   ComponentInfo(
       std::unique_ptr<Beamline::ComponentInfo> componentInfo,
       boost::shared_ptr<const std::vector<Mantid::Geometry::IComponent *>>
@@ -101,7 +101,10 @@ public:
   std::unique_ptr<ComponentInfo> cloneWithoutDetectorInfo() const;
   std::vector<size_t> detectorsInSubtree(size_t componentIndex) const;
   std::vector<size_t> componentsInSubtree(size_t componentIndex) const;
+  const std::vector<size_t> &children(size_t componentIndex) const;
   size_t size() const;
+  QuadrilateralComponent
+  quadrilateralComponent(const size_t componentIndex) const;
   size_t indexOf(Geometry::IComponent *id) const;
   size_t indexOfAny(const std::string &name) const;
   bool isDetector(const size_t componentIndex) const;
@@ -131,13 +134,15 @@ public:
   const std::string &name(const size_t componentIndex) const;
   void setScaleFactor(const size_t componentIndex,
                       const Kernel::V3D &scaleFactor);
-  size_t root();
+  size_t root() const;
 
   const IComponent *componentID(const size_t componentIndex) const {
     return m_componentIds->operator[](componentIndex);
   }
   bool hasValidShape(const size_t componentIndex) const;
+
   const Geometry::IObject &shape(const size_t componentIndex) const;
+
   double solidAngle(const size_t componentIndex,
                     const Kernel::V3D &observer) const;
   BoundingBox boundingBox(const size_t componentIndex,
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h
index 1ee03f9ba9eb327e1264fc3234da2d7b6e63756b..548dbc62cbbbf5b378c444c7eff232990cda9f16 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h
@@ -43,8 +43,13 @@ public:
   virtual size_t registerComponentAssembly(const ICompAssembly &assembly) = 0;
   virtual size_t registerGenericComponent(const IComponent &component) = 0;
   virtual size_t
+  registerInfiniteComponent(const Mantid::Geometry::IComponent &component) = 0;
+  virtual size_t
   registerGenericObjComponent(const IObjComponent &objComponent) = 0;
+  virtual size_t
+  registerInfiniteObjComponent(const IObjComponent &component) = 0;
   virtual size_t registerDetector(const IDetector &detector) = 0;
+  virtual size_t registerRectangularBank(const ICompAssembly &bank) = 0;
   virtual size_t registerStructuredBank(const ICompAssembly &bank) = 0;
   virtual size_t registerObjComponentAssembly(const ObjCompAssembly &obj) = 0;
   virtual ~ComponentVisitor() {}
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
index bcb6b982222ef878bbc1e4a3242b6f49d80c3693..8717345260c04507e5aea76d936418ef0fdc99b0 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h
@@ -39,7 +39,7 @@ namespace Geometry {
 */
 class MANTID_GEOMETRY_DLL Container final : public IObject {
 public:
-  typedef std::unordered_map<std::string, double> ShapeArgs;
+  using ShapeArgs = std::unordered_map<std::string, double>;
 
   Container();
   Container(IObject_sptr shape);
@@ -103,8 +103,9 @@ public:
     return m_shape->generatePointInObject(rng, activeRegion, i);
   }
 
-  void GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) const override {
+  void GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                     std::vector<Kernel::V3D> &vectors, double &myradius,
+                     double &myheight) const override {
     m_shape->GetObjectGeom(type, vectors, myradius, myheight);
   }
   boost::shared_ptr<GeometryHandler> getGeometryHandler() const override {
@@ -126,9 +127,9 @@ private:
 };
 
 /// Typdef for a shared pointer
-typedef boost::shared_ptr<Container> Container_sptr;
+using Container_sptr = boost::shared_ptr<Container>;
 /// Typdef for a shared pointer to a const object
-typedef boost::shared_ptr<const Container> Container_const_sptr;
+using Container_const_sptr = boost::shared_ptr<const Container>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h
index 21a8388e10360cc075e610c7f6244a191b4d7290..32ab21ebbd60debfcd08597fd6375d1813b4f342 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h
@@ -190,7 +190,7 @@ protected:
   /// The type of collection used for the detectors
   ///          - a map of detector pointers with the detector ID as the key
   // May want to change this to a hash_map in due course
-  typedef std::map<int, IDetector_const_sptr> DetCollection;
+  using DetCollection = std::map<int, IDetector_const_sptr>;
   /// The collection of grouped detectors
   DetCollection m_detectors;
   /** the parameter describes the topology of the detector's group namely if
@@ -263,9 +263,9 @@ private:
 };
 
 /// Typedef for shared pointer
-typedef boost::shared_ptr<DetectorGroup> DetectorGroup_sptr;
+using DetectorGroup_sptr = boost::shared_ptr<DetectorGroup>;
 /// Typedef for shared pointer to a const object
-typedef boost::shared_ptr<const DetectorGroup> DetectorGroup_const_sptr;
+using DetectorGroup_const_sptr = boost::shared_ptr<const DetectorGroup>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Goniometer.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Goniometer.h
index 3a1b47ce8111db2c41327ff230ef805e114ea4f4..7ffbb2626a3298f3df831123776fdfa312a4e250 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Goniometer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Goniometer.h
@@ -91,6 +91,10 @@ public:
   // Set rotation angle for an axis in the units the angle is set (default --
   // degrees)
   void setRotationAngle(size_t axisnumber, double value);
+  // Calculate goniometer for rotation around y-axis for constant wavelength
+  // from Q Sample
+  void calcFromQSampleAndWavelength(const Mantid::Kernel::V3D &Q,
+                                    double wavelength);
   // Get axis object
   const GoniometerAxis &getAxis(size_t axisnumber) const;
   // Get axis object
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h b/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
index 7f066b14efe7b5f4bd57b019f2f589c82b324e85..bcb33a9e17d0cc0e1b95a9638cf33b96dec02e9a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h
@@ -112,8 +112,8 @@ public:
   bool exists() const override { return false; }
 };
 
-typedef boost::shared_ptr<AbstractIDFObject> IDFObject_sptr;
-typedef boost::shared_ptr<const AbstractIDFObject> IDFObject_const_sptr;
+using IDFObject_sptr = boost::shared_ptr<AbstractIDFObject>;
+using IDFObject_const_sptr = boost::shared_ptr<const AbstractIDFObject>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
index ac77820aad5f68c8ae5d649ee6e933cd29df1eb6..ee23596428cf874d6a6de8119b37471117a8db14 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h
@@ -78,6 +78,9 @@ private:
   /// Index of the parent component
   boost::shared_ptr<std::vector<size_t>> m_parentComponentIndices;
 
+  /// Stores instrument tree structure by storing children of all Components
+  boost::shared_ptr<std::vector<std::vector<size_t>>> m_children;
+
   /// Only Assemblies and other NON-detectors yield detector ranges
   boost::shared_ptr<std::vector<std::pair<size_t, size_t>>> m_detectorRanges;
 
@@ -165,9 +168,18 @@ public:
   virtual size_t registerGenericComponent(
       const Mantid::Geometry::IComponent &component) override;
 
+  virtual size_t registerInfiniteComponent(
+      const Mantid::Geometry::IComponent &component) override;
+
   virtual size_t registerGenericObjComponent(
       const Mantid::Geometry::IObjComponent &objComponent) override;
 
+  virtual size_t
+  registerRectangularBank(const Mantid::Geometry::ICompAssembly &bank) override;
+
+  virtual size_t
+  registerInfiniteObjComponent(const IObjComponent &objComponent) override;
+
   virtual size_t
   registerStructuredBank(const Mantid::Geometry::ICompAssembly &bank) override;
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h
index f8e055ce25c91a2566a2eabd6565006ff3d079a9..aaf251206b4e73faaf74a62fb664c1cb225b8682 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h
@@ -45,9 +45,9 @@ namespace Geometry {
 */
 class MANTID_GEOMETRY_DLL ObjCompAssembly : public virtual ICompAssembly,
                                             public virtual ObjComponent {
-  typedef std::vector<ObjComponent *>::iterator comp_it; ///< Iterator type
-  typedef std::vector<ObjComponent *>::const_iterator
-      const_comp_it; ///< Const iterator type
+  using comp_it = std::vector<ObjComponent *>::iterator; ///< Iterator type
+  using const_comp_it =
+      std::vector<ObjComponent *>::const_iterator; ///< Const iterator type
 public:
   /// String description of the type of component
   std::string type() const override { return "ObjCompAssembly"; }
@@ -114,9 +114,9 @@ private:
 };
 
 /// Shared pointer to ObjCompAssembly
-typedef boost::shared_ptr<ObjCompAssembly> ObjCompAssembly_sptr;
+using ObjCompAssembly_sptr = boost::shared_ptr<ObjCompAssembly>;
 /// Shared pointer to ObjCompAssembly (const version)
-typedef boost::shared_ptr<const ObjCompAssembly> ObjCompAssembly_const_sptr;
+using ObjCompAssembly_const_sptr = boost::shared_ptr<const ObjCompAssembly>;
 
 MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &,
                                              const ObjCompAssembly &);
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
index 18c9254403b6c9063fce807f071847450bd9b772..ad07be97ef72c75ccb2d68137bdc79c26a92d144 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
@@ -219,7 +219,7 @@ ParameterType<Type> &ParameterType<Type>::operator=(const Type &value) {
 }
 
 /// Typedef for the shared pointer
-typedef boost::shared_ptr<Parameter> Parameter_sptr;
+using Parameter_sptr = boost::shared_ptr<Parameter>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h
index 68738d6152cc275aea54f45e806d2c4bd3fe2f67..c6fa3fc9bb47a16558b86ae24e2e81e7b18339c1 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h
@@ -67,8 +67,8 @@ private:
   ParameterFactory &operator=(const ParameterFactory &);
 
   /// A typedef for the instantiator
-  typedef Kernel::AbstractInstantiator<Parameter> AbstractFactory;
-  typedef std::map<std::string, std::unique_ptr<AbstractFactory>> FactoryMap;
+  using AbstractFactory = Kernel::AbstractInstantiator<Parameter>;
+  using FactoryMap = std::map<std::string, std::unique_ptr<AbstractFactory>>;
   /// The map holding the registered class names and their instantiators
   static FactoryMap s_map;
 };
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
index 13f7ebc2b72a9c5adfa6f2c200af81dc17306f39..2002187149a50f1250c66fce5ce1f38204cc5711 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
@@ -54,23 +54,23 @@ class Instrument;
   Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 /// Parameter map iterator typedef
-typedef tbb::concurrent_unordered_multimap<
-    ComponentID, boost::shared_ptr<Parameter>>::iterator component_map_it;
-typedef tbb::concurrent_unordered_multimap<
-    ComponentID, boost::shared_ptr<Parameter>>::const_iterator
-    component_map_cit;
+using component_map_it =
+    tbb::concurrent_unordered_multimap<ComponentID,
+                                       boost::shared_ptr<Parameter>>::iterator;
+using component_map_cit = tbb::concurrent_unordered_multimap<
+    ComponentID, boost::shared_ptr<Parameter>>::const_iterator;
 
 class MANTID_GEOMETRY_DLL ParameterMap {
 public:
   /// Parameter map typedef
-  typedef tbb::concurrent_unordered_multimap<ComponentID,
-                                             boost::shared_ptr<Parameter>> pmap;
+  using pmap = tbb::concurrent_unordered_multimap<ComponentID,
+                                                  boost::shared_ptr<Parameter>>;
   /// Parameter map iterator typedef
-  typedef tbb::concurrent_unordered_multimap<
-      ComponentID, boost::shared_ptr<Parameter>>::iterator pmap_it;
+  using pmap_it = tbb::concurrent_unordered_multimap<
+      ComponentID, boost::shared_ptr<Parameter>>::iterator;
   /// Parameter map iterator typedef
-  typedef tbb::concurrent_unordered_multimap<
-      ComponentID, boost::shared_ptr<Parameter>>::const_iterator pmap_cit;
+  using pmap_cit = tbb::concurrent_unordered_multimap<
+      ComponentID, boost::shared_ptr<Parameter>>::const_iterator;
   /// Default constructor
   ParameterMap();
   /// Const constructor
@@ -388,9 +388,9 @@ private:
 };
 
 /// ParameterMap shared pointer typedef
-typedef boost::shared_ptr<ParameterMap> ParameterMap_sptr;
+using ParameterMap_sptr = boost::shared_ptr<ParameterMap>;
 /// ParameterMap constant shared pointer typedef
-typedef boost::shared_ptr<const ParameterMap> ParameterMap_const_sptr;
+using ParameterMap_const_sptr = boost::shared_ptr<const ParameterMap>;
 
 } // Namespace Geometry
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h
index bdf087392e852ca1530531c2a1c1cd806c24d33e..d7b11738945df39b007e1a8726262229cc6c8e41 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h
@@ -211,9 +211,9 @@ private:
 MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &,
                                              const RectangularDetector &);
 
-typedef boost::shared_ptr<RectangularDetector> RectangularDetector_sptr;
-typedef boost::shared_ptr<const RectangularDetector>
-    RectangularDetector_const_sptr;
+using RectangularDetector_sptr = boost::shared_ptr<RectangularDetector>;
+using RectangularDetector_const_sptr =
+    boost::shared_ptr<const RectangularDetector>;
 
 } // Namespace Geometry
 } // Namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h
index aa40ca05e075bea32da9a2ffc09d5d2737cb110d..444e77c69a339476d721c0ba65f072c7d0ab57d8 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h
@@ -79,8 +79,6 @@ public:
   bool isVectorPointingAlongBeam(const Mantid::Kernel::V3D &v) const;
 
 private:
-  /// Common setup
-  void init();
   /// Disabled assignment
   ReferenceFrame &operator=(const ReferenceFrame &);
   /// Pointing up axis
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h
index 428afb7c65761e36d3e093ac43f9727e5c8788b4..7939e9e0707d29c5b10b9c014ce0a99df1502fa2 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h
@@ -64,8 +64,8 @@ public:
   StructuredDetector(const StructuredDetector *base, const ParameterMap *map);
 
   /// Create all the detector pixels of this rectangular detector.
-  void initialize(size_t xPixels, size_t yPixels, const std::vector<double> &x,
-                  const std::vector<double> &y, bool isZBeam, detid_t idStart,
+  void initialize(size_t xPixels, size_t yPixels, std::vector<double> &&x,
+                  std::vector<double> &&y, bool isZBeam, detid_t idStart,
                   bool idFillByFirstY, int idStepByRow, int idStep = 1);
 
   //! Make a clone of the present component
@@ -192,9 +192,9 @@ private:
 MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &,
                                              const StructuredDetector &);
 
-typedef boost::shared_ptr<StructuredDetector> StructuredDetector_sptr;
-typedef boost::shared_ptr<const StructuredDetector>
-    StructuredDetector_const_sptr;
+using StructuredDetector_sptr = boost::shared_ptr<StructuredDetector>;
+using StructuredDetector_const_sptr =
+    boost::shared_ptr<const StructuredDetector>;
 } // namespace Geometry
 } // namespace Mantid
 #endif // STRUCTUREDDETECTOR_H
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h b/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h
index e5272b713fc1561592e7fb981f9079e7de31d209..64ee5ae4b3a01028493e1b96a4d47d3f383d8fbb 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h
@@ -34,13 +34,13 @@ namespace Geometry {
 class Instrument;
 
 /// Shared pointer to an instrument object
-typedef boost::shared_ptr<Instrument> Instrument_sptr;
+using Instrument_sptr = boost::shared_ptr<Instrument>;
 /// Shared pointer to an const instrument object
-typedef boost::shared_ptr<const Instrument> Instrument_const_sptr;
+using Instrument_const_sptr = boost::shared_ptr<const Instrument>;
 /// unique pointer to an instrument
-typedef std::unique_ptr<Instrument> Instrument_uptr;
+using Instrument_uptr = std::unique_ptr<Instrument>;
 /// unique pointer to an instrument (const version)
-typedef std::unique_ptr<const Instrument> Instrument_const_uptr;
+using Instrument_const_uptr = std::unique_ptr<const Instrument>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h
index 49819de15c9650f746d5d5b1ee2cd234e1fb967a..20cae05ac533537add554521c15872db101210f9 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h
@@ -63,8 +63,8 @@ public:
 
 protected:
   std::vector<Mantid::Geometry::MDImplicitFunction_sptr> m_Functions;
-  typedef std::vector<Mantid::Geometry::MDImplicitFunction_sptr>::const_iterator
-      FunctionIterator;
+  using FunctionIterator =
+      std::vector<Mantid::Geometry::MDImplicitFunction_sptr>::const_iterator;
 };
 }
 }
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h
index 5ed0c0e6278b228f647d779c9a3f17e8d06b0f57..0f3980196e75f7c20df96734ac9501dda6b64a62 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h
@@ -117,14 +117,14 @@ public:
 };
 
 /// Shared Pointer for IMDDimension. Frequently used type in framework.
-typedef boost::shared_ptr<IMDDimension> IMDDimension_sptr;
+using IMDDimension_sptr = boost::shared_ptr<IMDDimension>;
 /// Shared Pointer to const IMDDimension. Not strictly necessary since
 /// IMDDimension is pure abstract.
-typedef boost::shared_ptr<const IMDDimension> IMDDimension_const_sptr;
+using IMDDimension_const_sptr = boost::shared_ptr<const IMDDimension>;
 /// Vector of constant shared pointers to IMDDimensions.
-typedef std::vector<IMDDimension_const_sptr> VecIMDDimension_const_sptr;
+using VecIMDDimension_const_sptr = std::vector<IMDDimension_const_sptr>;
 /// Vector of shared pointers to IMDDimensions.
-typedef std::vector<IMDDimension_sptr> VecIMDDimension_sptr;
+using VecIMDDimension_sptr = std::vector<IMDDimension_sptr>;
 }
 }
 #endif
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
index 29152ae5a55ce658b867ce607990faa3ce844ac1..799e5261a66736f0580fb076e8c3a6f97f1cb2a3 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h
@@ -50,10 +50,10 @@ public:
   virtual ~MDFrame() = default;
 };
 
-typedef std::unique_ptr<MDFrame> MDFrame_uptr;
-typedef std::unique_ptr<const MDFrame> MDFrame_const_uptr;
-typedef std::shared_ptr<MDFrame> MDFrame_sptr;
-typedef std::shared_ptr<const MDFrame> MDFrame_const_sptr;
+using MDFrame_uptr = std::unique_ptr<MDFrame>;
+using MDFrame_const_uptr = std::unique_ptr<const MDFrame>;
+using MDFrame_sptr = std::shared_ptr<MDFrame>;
+using MDFrame_const_sptr = std::shared_ptr<const MDFrame>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h
index f702e0e9ce8d435f187a974cdc83529d71ed4bfe..13aa7104ffa0ceb79a8db6dc8eec6be50e320200 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h
@@ -54,7 +54,7 @@ class MANTID_GEOMETRY_DLL MDFrameFactory
                                       MDFrameArgument> {};
 
 /// Helper typedef
-typedef std::unique_ptr<MDFrameFactory> MDFrameFactory_uptr;
+using MDFrameFactory_uptr = std::unique_ptr<MDFrameFactory>;
 
 //-----------------------------------------------------------------------
 // Derived MDFrameFactory declarations
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h
index 40753107697782a78c8c9f7b9ac4e10193e90d34..0b9b680a10ffbf453c8be5eda4943febf6f01b0e 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h
@@ -95,7 +95,7 @@ public:
   bool hasIntegratedTDimension() const;
 
 private:
-  typedef std::vector<IMDDimension_const_sptr> DimensionContainerType;
+  using DimensionContainerType = std::vector<IMDDimension_const_sptr>;
 
   mutable DimensionContainerType m_vecDimensions;
 
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h
index 79e1381b81179c5f14b1a78c30dd96e1783b6e6c..a4b16a6b7c75c0f84a5231dbcf8ee0d0aa64b6ed 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h
@@ -147,10 +147,10 @@ private:
 };
 
 /// Shared pointer to a MDHistoDimension
-typedef boost::shared_ptr<MDHistoDimension> MDHistoDimension_sptr;
+using MDHistoDimension_sptr = boost::shared_ptr<MDHistoDimension>;
 
 /// Shared pointer to a const MDHistoDimension
-typedef boost::shared_ptr<const MDHistoDimension> MDHistoDimension_const_sptr;
+using MDHistoDimension_const_sptr = boost::shared_ptr<const MDHistoDimension>;
 
 } // namespace Mantid
 } // namespace Geometry
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h
index e4fcc69ce53e71eb0571b24f8a84b38fbea9c817..dba705588230c11bfdcf251983113988439836eb 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h
@@ -79,7 +79,7 @@ private:
 };
 
 /// Handy typedef for collection of builders.
-typedef std::vector<MDHistoDimensionBuilder> Vec_MDHistoDimensionBuilder;
+using Vec_MDHistoDimensionBuilder = std::vector<MDHistoDimensionBuilder>;
 }
 }
 
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h
index a94e881bc2b9e0d0642d4caa20808b873650f102..b7c4faf5f4d65e23c12d4a370de1a7d835d3a7bb 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h
@@ -294,7 +294,7 @@ protected:
   size_t m_numPlanes;
 };
 
-typedef boost::shared_ptr<MDImplicitFunction> MDImplicitFunction_sptr;
+using MDImplicitFunction_sptr = boost::shared_ptr<MDImplicitFunction>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h
index 84983b49ca7def7b6f32c650da911c178ffdaf2d..b75542c177f2d7137bfab3867a4e804d6f4a1470 100644
--- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h
+++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h
@@ -40,7 +40,7 @@ namespace Mantid {
  * We can change this in order to compare
  * performance/memory/accuracy requirements.
  */
-typedef float coord_t;
+using coord_t = float;
 
 /// Define indicating that the coord_t type is a float (not double)
 //#undef COORDT_IS_FLOAT
@@ -49,7 +49,7 @@ typedef float coord_t;
 /** Typedef for the signal recorded in a MDBox, etc.
  * Note: MDEvents use 'float' internally to save memory
  */
-typedef double signal_t;
+using signal_t = double;
 
 /** Macro TMDE to make declaring template functions
  * faster. Put this macro before function declarations.
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
index f1b0a16b005f6ddd45e4e73340eec90fe0dcf553..8b808c01926938baf9a7e343784f233ba10e1e46 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
@@ -218,9 +218,9 @@ private:
 };
 
 /// A shared pointer to a BoundingBox
-typedef boost::shared_ptr<BoundingBox> BoundingBox_sptr;
+using BoundingBox_sptr = boost::shared_ptr<BoundingBox>;
 /// A shared pointer to a const BoundingBox
-typedef boost::shared_ptr<const BoundingBox> BoundingBox_const_sptr;
+using BoundingBox_const_sptr = boost::shared_ptr<const BoundingBox>;
 
 /// Print out the bounding box values to a stream.
 MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &os,
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
index f7ee2fe939e0a5205d66827c68cdd9176c10c18b..26b173e33cccbce0548c01dfa1f5fae595633d23 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h
@@ -5,6 +5,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidGeometry/DllConfig.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "MantidGeometry/Objects/IObject.h"
 
 #include "BoundingBox.h"
@@ -22,7 +23,6 @@ class V3D;
 }
 
 namespace Geometry {
-class CacheGeometryHandler;
 class CompGrp;
 class GeometryHandler;
 class Rule;
@@ -83,6 +83,11 @@ public:
     return obj;
   }
 
+  bool isFiniteGeometry() const override { return m_isFiniteGeometry; }
+  void setFiniteGeometryFlag(bool isFinite) override {
+    m_isFiniteGeometry = isFinite;
+  }
+
   /// Return the top rule
   const Rule *topRule() const { return TopRule.get(); }
   void setID(const std::string &id) { m_id = id; }
@@ -191,8 +196,9 @@ public:
   void setVtkGeometryCacheWriter(boost::shared_ptr<vtkGeometryCacheWriter>);
   /// set vtkGeometryCache reader
   void setVtkGeometryCacheReader(boost::shared_ptr<vtkGeometryCacheReader>);
-  void GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) const override;
+  void GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                     std::vector<Kernel::V3D> &vectors, double &myradius,
+                     double &myheight) const override;
   /// Getter for the shape xml
   std::string getShapeXML() const;
 
@@ -252,7 +258,8 @@ private:
   int ObjNum;
   /// Geometry Handle for rendering
   boost::shared_ptr<GeometryHandler> m_handler;
-  friend class CacheGeometryHandler;
+  friend class GeometryHandler;
+  friend class GeometryRenderer;
   /// Is geometry caching enabled?
   bool bGeometryCaching;
   /// a pointer to a class for reading from the geometry cache
@@ -260,17 +267,19 @@ private:
   /// a pointer to a class for writing to the geometry cache
   boost::shared_ptr<vtkGeometryCacheWriter> vtkCacheWriter;
   void updateGeometryHandler();
+  size_t numberOfTriangles() const;
+  size_t numberOfVertices() const;
   /// for solid angle from triangulation
-  int NumberOfTriangles() const;
-  int NumberOfPoints() const;
-  int *getTriangleFaces() const;
-  double *getTriangleVertices() const;
+  const std::vector<uint32_t> &getTriangleFaces() const;
+  const std::vector<double> &getTriangleVertices() const;
   /// original shape xml used to generate this object.
   std::string m_shapeXML;
   /// Optional string identifier
   std::string m_id;
   /// material composition
   std::unique_ptr<Kernel::Material> m_material;
+  /// Whether or not the object geometry is finite
+  bool m_isFiniteGeometry = true;
 
 protected:
   std::vector<const Surface *> m_SurList; ///< Full surfaces (make a map
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
index 24331e8075214d30793df52b286bdd80b10077c7..92f4c32efe2674b687310c71d12767c9e14ab04b 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h
@@ -2,9 +2,10 @@
 #define MANTID_GEOMETRY_IOBJECT_H_
 
 #include "MantidGeometry/DllConfig.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include <boost/shared_ptr.hpp>
-#include <vector>
 #include <map>
+#include <vector>
 
 namespace Mantid {
 
@@ -54,10 +55,13 @@ class vtkGeometryCacheWriter;
  */
 class MANTID_GEOMETRY_DLL IObject {
 public:
+  virtual ~IObject() = default;
   virtual bool isValid(const Kernel::V3D &) const = 0;
   virtual bool isOnSide(const Kernel::V3D &) const = 0;
   virtual int calcValidType(const Kernel::V3D &Pt,
                             const Kernel::V3D &uVec) const = 0;
+  virtual bool isFiniteGeometry() const { return true; }
+  virtual void setFiniteGeometryFlag(bool) {}
   virtual bool hasValidShape() const = 0;
   virtual IObject *clone() const = 0;
   virtual IObject *
@@ -89,9 +93,9 @@ public:
                         const BoundingBox &activeRegion,
                         const size_t) const = 0;
 
-  virtual void GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
+  virtual void GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                             std::vector<Kernel::V3D> &vectors,
                              double &myradius, double &myheight) const = 0;
-
   // Rendering
   virtual void draw() const = 0;
   virtual void initDraw() const = 0;
@@ -103,13 +107,13 @@ public:
 };
 
 /// Typdef for a shared pointer
-typedef boost::shared_ptr<IObject> IObject_sptr;
+using IObject_sptr = boost::shared_ptr<IObject>;
 /// Typdef for a shared pointer to a const object
-typedef boost::shared_ptr<const IObject> IObject_const_sptr;
+using IObject_const_sptr = boost::shared_ptr<const IObject>;
 /// Typdef for a unique pointer
-typedef std::unique_ptr<IObject> IObject_uptr;
+using IObject_uptr = std::unique_ptr<IObject>;
 /// Typdef for a unique pointer to a const object
-typedef std::unique_ptr<const IObject> IObject_const_uptr;
+using IObject_const_uptr = std::unique_ptr<const IObject>;
 
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
index ef45f935d615b8c1caf71394ebf817ca9b51b7fa..ad1110e26bc0d845d771b1c34eab2be7ad2650eb 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
@@ -19,7 +19,7 @@ class IComponent;
 struct Link;
 class Track;
 /// Typedef for object intersections
-typedef Track::LType Links;
+using Links = Track::LType;
 
 /**
 This class is responsible for tracking rays and accumulating a list of objects
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
index ac3cbb67fe3a5387f32bf7573ee8aebeecd8cd1e..d1b0478870289fc0746484d742a508593dea45cd 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/MeshObject.h
@@ -7,6 +7,7 @@
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Objects/IObject.h"
 #include "MantidKernel/Material.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "BoundingBox.h"
 #include <map>
 #include <memory>
@@ -21,7 +22,6 @@ class V3D;
 }
 
 namespace Geometry {
-class CacheGeometryHandler;
 class CompGrp;
 class GeometryHandler;
 class Track;
@@ -139,14 +139,15 @@ public:
   /// Set Geometry Handler
   void setGeometryHandler(boost::shared_ptr<GeometryHandler> h);
 
-  void GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) const override;
+  void GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                     std::vector<Kernel::V3D> &vectors, double &myradius,
+                     double &myheight) const override;
 
   /// Read access to mesh object for rendering
-  int numberOfVertices() const;
-  double *getVertices() const;
-  int numberOfTriangles() const;
-  int *getTriangles() const;
+  size_t numberOfVertices() const;
+  std::vector<double> getVertices() const;
+  size_t numberOfTriangles() const;
+  std::vector<uint32_t> getTriangles() const;
 
   void updateGeometryHandler();
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h
deleted file mode 100644
index a984a0bd4d2f396be10542386b170defcd223f78..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef BITMAPGEOMETRYHANDLER_H
-#define BITMAPGEOMETRYHANDLER_H
-
-#ifndef Q_MOC_RUN
-#include <boost/weak_ptr.hpp>
-#endif
-#include "MantidGeometry/DllConfig.h"
-#include "MantidKernel/Logger.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-namespace Mantid {
-
-namespace Geometry {
-/**
-\class BitmapGeometryHandler
-\brief Handler for geometry objects that are rendered as bitmaps (e.g.
-RectangularDetector), rather than primitives.
-\author Janik Zikovsky
-\date October 2010
-\version 1.0
-
-This class supports drawing RectangularDetector - as a bitmap plotted by openGL
-rather
-than a million individual pixels rendered as cubes.
-A texture will have been created by the RectangularDetectorActor (in MantidPlot)
-and this is what will be mapped.
-
-Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class ObjComponent;
-class CSGObject;
-class MANTID_GEOMETRY_DLL BitmapGeometryHandler : public GeometryHandler {
-private:
-  static Kernel::Logger &PLog; ///< The official logger
-
-  boost::shared_ptr<GeometryHandler> clone() const override;
-
-  /// The RectangularDetector object being plotted.
-  RectangularDetector *m_rectDet;
-
-public:
-  BitmapGeometryHandler(RectangularDetector *comp);
-  BitmapGeometryHandler();
-  //
-  //                      BitmapGeometryHandler(IObjComponent *comp);   ///<
-  //                      Constructor
-  //                      BitmapGeometryHandler(boost::shared_ptr<Object> obj);
-  //                      ///<Constructor
-  //                      BitmapGeometryHandler(Object *obj); ///<Constructor
-  BitmapGeometryHandler *createInstance(
-      IObjComponent *) override; ///< Create an instance of concrete geometry
-  /// handler for ObjComponent
-  BitmapGeometryHandler *createInstance(boost::shared_ptr<CSGObject>)
-      override; ///< Create an instance of concrete geometry handler for Object
-  GeometryHandler *createInstance(CSGObject *)
-      override; ///< Create an instance of concrete geometry handler for Object
-  void Triangulate() override; ///< Triangulate the Object
-  void Render() override;      ///< Render Object or ObjComponent
-  void Initialize()
-      override; ///< Prepare/Initialize Object/ObjComponent to be rendered
-  /// Returns true if the shape can be triangulated
-  bool canTriangulate() override { return false; }
-  /// get the number of triangles
-  int NumberOfTriangles() override { return 0; }
-  /// get the number of points or vertices
-  int NumberOfPoints() override { return 0; }
-  /// Extract the vertices of the triangles
-  double *getTriangleVertices() override { return nullptr; }
-  /// Extract the Faces of the triangles
-  int *getTriangleFaces() override { return nullptr; }
-  /// Sets the geometry cache using the triangulation information provided
-  void setGeometryCache(int noPts, int noFaces, double *pts,
-                        int *faces) override {
-    (void)noPts;
-    (void)noFaces;
-    (void)pts;
-    (void)faces; // Avoid compiler warning
-  };
-  /// return the actual type and points of one of the "standard" objects,
-  /// cuboid/cone/cyl/sphere
-  void GetObjectGeom(int &mytype, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) override {
-    (void)mytype;
-    (void)vectors;
-    (void)myradius;
-    (void)myheight; // Avoid compiler warning
-  };
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h
deleted file mode 100644
index dcdfb1627eb3791e82990f8930c26d2b80dede1a..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef CACHE_GEOMETRYGENERATOR_H
-#define CACHE_GEOMETRYGENERATOR_H
-
-#include "MantidGeometry/DllConfig.h"
-
-namespace Mantid {
-
-namespace Geometry {
-
-/**
-   \class CacheGeometryGenerator
-   \brief Generates geometry using other geometry handlers or keeps the cache of
-   the triangles
-   \author Mr. Srikanth Nagella
-   \date Jan 2009
-   \version 1.0
-
-   This class is an cache for the geometry triangles and if needed generates the
-   triangles using
-   other GeometryHandlers.
-
-   Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class CSGObject;
-class MeshObject;
-
-class MANTID_GEOMETRY_DLL CacheGeometryGenerator {
-private:
-  CSGObject *csgObj;   ///< Input CSGObject
-  MeshObject *meshObj; ///< Input MeshObject
-  int mNoOfVertices;   ///< number of vertices
-  int mNoOfTriangles;  ///< number of triangles
-  double *mPoints;     ///<double array or points
-  int *mFaces;         ///< Integer array of faces
-public:
-  CacheGeometryGenerator(CSGObject *obj);
-  CacheGeometryGenerator(MeshObject *obj);
-  ~CacheGeometryGenerator();
-  /// Generate the trangles
-  void Generate();
-  /// get the number of triangles
-  int getNumberOfTriangles();
-  /// get the number of points
-  int getNumberOfPoints();
-  /// get the triangle vertices
-  double *getTriangleVertices();
-  /// get the triangle faces
-  int *getTriangleFaces();
-  /// Sets the geometry cache using the triangulation information provided
-  void setGeometryCache(int noPts, int noFaces, double *pts, int *faces);
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h
deleted file mode 100644
index 0dcf4a3d9f9eddbf739845620204a27dbde24b5c..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef CACHE_GEOMETRYHANDLER_H
-#define CACHE_GEOMETRYHANDLER_H
-
-#include "MantidGeometry/DllConfig.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-
-namespace Geometry {
-class GeometryHandler;
-class CacheGeometryRenderer;
-class CacheGeometryGenerator;
-class IObjComponent;
-class CSGObject;
-class MeshObject;
-
-/**
-   \class CacheGeometryHandler
-   \brief Place holder for geometry triangulation and rendering with caching
-   triangles.
-   \author Srikanth Nagella
-   \date Jan 2009
-   \version 1.0
-
-   This is an implementation class for handling geometry from cache, if the
-   cache doesn't exist then the
-   triangulation is done using another triangulation handler and store in cache.
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL CacheGeometryHandler : public GeometryHandler {
-private:
-  CacheGeometryRenderer *Renderer; ///< Geometry renderer variable used for
-  /// rendering Object/ObjComponent
-  CacheGeometryGenerator *
-      Triangulator; ///< Geometry generator to triangulate Object
-  void updateGeometryHandler();
-
-public:
-  CacheGeometryHandler(IObjComponent *comp);               ///< Constructor
-  CacheGeometryHandler(boost::shared_ptr<CSGObject> obj);  ///< Constructor
-  CacheGeometryHandler(CSGObject *obj);                    ///< Constructor
-  CacheGeometryHandler(boost::shared_ptr<MeshObject> obj); ///< Constructor
-  CacheGeometryHandler(MeshObject *obj);                   ///< Constructor
-  boost::shared_ptr<GeometryHandler> clone() const override;
-  ~CacheGeometryHandler() override; ///< Destructor
-  GeometryHandler *createInstance(IObjComponent *comp) override;
-  GeometryHandler *createInstance(boost::shared_ptr<CSGObject> obj) override;
-  GeometryHandler *createInstance(CSGObject *obj) override;
-
-  void Triangulate() override;
-  void Render() override;
-  void Initialize() override;
-  bool canTriangulate() override { return true; }
-  int NumberOfTriangles() override;
-  int NumberOfPoints() override;
-  double *getTriangleVertices() override;
-  int *getTriangleFaces() override;
-  /// Sets the geometry cache using the triangulation information provided
-  void setGeometryCache(int noPts, int noFaces, double *pts,
-                        int *faces) override;
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h
deleted file mode 100644
index 708cb3b70b21657ed4746fb4528abdc847f47a15..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef CACHE_GEOMETRYRENDERER_H
-#define CACHE_GEOMETRYRENDERER_H
-
-#include "MantidGeometry/DllConfig.h"
-
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class IObjComponent;
-/**
-   \class CacheGeometryRenderer
-   \brief rendering geometry using opengl from the geometry cache.
-   \author Srikanth Nagella
-   \date Jan 2009
-   \version 1.0
-
-   This is an concrete class for rendering cached geometry using opengl.
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL CacheGeometryRenderer {
-public:
-  /// Render using an object component
-  void Render(IObjComponent *ObjComp) const;
-  /// Render using triangulation information
-  void Render(int noPts, int noFaces, double *points, int *faces) const;
-  /// Initialize using triangulation information
-  void Initialize(int noPts, int noFaces, double *points, int *faces) const;
-  /// Initialize using an object component
-  void Initialize(IObjComponent *ObjComp);
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h
index 055ce4ca74f4614b2e8f9042a1a3e165231344a7..434c3100f1cf49f8a8aa82879997be006e7ffdca 100644
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h
+++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h
@@ -2,118 +2,102 @@
 #define GEOMETRYHANDLER_H
 
 #include "MantidGeometry/DllConfig.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/V3D.h"
 #include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+#include <memory>
 #include <vector>
 
 namespace Mantid {
 
 namespace Geometry {
 class IObjComponent;
-class ObjComponent;
 class CSGObject;
+
 class MeshObject;
+namespace detail {
+class Renderer;
+class GeometryTriangulator;
+}
 
 /**
-   \class GeometryHandler
-   \brief Place holder for geometry triangulation and rendering.
-   \author Srikanth Nagella
-   \date July 2008
-   \version 1.0
+\class GeometryHandler
+\brief Handles rendering of all object Geometry.
+\author Lamar Moore
+\date December 2017
 
-   This is an abstract class for handling geometry primitives.
+Handles the rendering of all geometry types in Mantid.
 
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
+Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+National Laboratory & European Spallation Source
 
-   This file is part of Mantid.
+This file is part of Mantid.
 
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
+Mantid is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
 
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+Mantid is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-   File change history is stored at: <https://github.com/mantidproject/mantid>
+File change history is stored at: <https://github.com/mantidproject/mantid>
 */
 class MANTID_GEOMETRY_DLL GeometryHandler {
 private:
   static Kernel::Logger &PLog; ///< The official logger
 
 protected:
-  IObjComponent *ObjComp; ///< ObjComponent that uses this geometry handler
-  CSGObject *csgObj;      ///< CSG Object that uses this geometry handler
-  MeshObject *meshObj;    ///< Mesh Object that uses this geometry handler
-  bool boolTriangulated;  ///< state of the geometry triangulation
-  bool
-      boolIsInitialized; ///< state of the geometry initialization for rendering
+  std::shared_ptr<detail::ShapeInfo> m_shapeInfo;
+  std::unique_ptr<detail::GeometryTriangulator> m_triangulator;
+  MeshObject *m_meshObj =
+      nullptr; ///< Mesh Object that uses this geometry handler
+  IObjComponent *m_objComp =
+      nullptr; ///< ObjComponent that uses this geometry handler
+  CSGObject *m_csgObj = nullptr; ///< Object that uses this geometry handler
 public:
   GeometryHandler(IObjComponent *comp);               ///< Constructor
-  GeometryHandler(boost::shared_ptr<CSGObject> obj);  ///<Constructor
-  GeometryHandler(CSGObject *obj);                    ///<Constructor
+  GeometryHandler(boost::shared_ptr<CSGObject> obj);  ///< Constructor
+  GeometryHandler(CSGObject *obj);                    ///< Constructor
   GeometryHandler(boost::shared_ptr<MeshObject> obj); ///<Constructor
-  GeometryHandler(MeshObject *obj);                   ///<Constructor
-  virtual boost::shared_ptr<GeometryHandler>
-  clone() const = 0; ///< Virtual copy constructor
-  virtual ~GeometryHandler();
-  virtual GeometryHandler *createInstance(IObjComponent *) = 0; ///< Create an
-  /// instance of
-  /// concrete
-  /// geometry
-  /// handler for
-  /// ObjComponent
-  virtual GeometryHandler *createInstance(
-      boost::shared_ptr<CSGObject>) = 0; ///< Create an instance of
-  /// concrete geometry
-  /// handler for Object
-  virtual GeometryHandler *
-  createInstance(CSGObject *) = 0; ///< Create an instance
-  /// of concrete geometry
-  /// handler for Object
-  virtual void Triangulate() = 0; ///< Triangulate the Object
-  virtual void Render() = 0;      ///< Render Object or ObjComponent
-  virtual void
-  Initialize() = 0; ///< Prepare/Initialize Object/ObjComponent to be rendered
-  /// Returns true if the shape can be triangulated
-  virtual bool canTriangulate() { return false; }
+  GeometryHandler(MeshObject *obj);
+  GeometryHandler(const GeometryHandler &handler);
+  boost::shared_ptr<GeometryHandler> clone() const;
+  ~GeometryHandler();
+  void render() const; ///< Render Object or ObjComponent
+  void
+  initialize() const; ///< Prepare/Initialize Object/ObjComponent to be rendered
+  bool canTriangulate() const { return !(m_triangulator == nullptr); }
   /// get the number of triangles
-  virtual int NumberOfTriangles() { return 0; }
+  size_t numberOfTriangles() const;
   /// get the number of points or vertices
-  virtual int NumberOfPoints() { return 0; }
+  size_t numberOfPoints() const;
+
+  bool hasShapeInfo() const { return !(m_shapeInfo == nullptr); }
+  const detail::ShapeInfo &shapeInfo() const { return *m_shapeInfo; }
   /// Extract the vertices of the triangles
-  virtual double *getTriangleVertices() { return nullptr; }
+  const std::vector<double> &getTriangleVertices() const;
   /// Extract the Faces of the triangles
-  virtual int *getTriangleFaces() { return nullptr; }
+  const std::vector<uint32_t> &getTriangleFaces() const;
   /// Sets the geometry cache using the triangulation information provided
-  virtual void setGeometryCache(int noPts, int noFaces, double *pts,
-                                int *faces) {
-    UNUSED_ARG(noPts);
-    UNUSED_ARG(noFaces);
-    UNUSED_ARG(pts);
-    UNUSED_ARG(faces);
-  };
+  void setGeometryCache(size_t nPts, size_t nFaces, std::vector<double> &&pts,
+                        std::vector<uint32_t> &&faces);
   /// return the actual type and points of one of the "standard" objects,
   /// cuboid/cone/cyl/sphere
-  virtual void GetObjectGeom(int &mytype, std::vector<Kernel::V3D> &vectors,
-                             double &myradius, double &myheight) {
-    UNUSED_ARG(vectors);
-    UNUSED_ARG(myradius);
-    UNUSED_ARG(myheight);
-    // Flag that this is unknown at this point
-    mytype = -1;
-  };
+  void GetObjectGeom(detail::ShapeInfo::GeometryShape &mytype,
+                     std::vector<Kernel::V3D> &vectors, double &myradius,
+                     double &myheight) const;
+  void setShapeInfo(detail::ShapeInfo &&shapeInfo);
 };
 
 } // NAMESPACE Geometry
-
 } // NAMESPACE Mantid
 
 #endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7a6b86a5fc1a74d84d53e9701f90986e96e4c42
--- /dev/null
+++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h
@@ -0,0 +1,94 @@
+#ifndef MANTID_GEOMETRY_SURFACETRIANGULATOR_H_
+#define MANTID_GEOMETRY_SURFACETRIANGULATOR_H_
+
+#include "MantidGeometry/DllConfig.h"
+#include <memory>
+#include <vector>
+
+class TopoDS_Shape;
+
+namespace Mantid {
+namespace Geometry {
+class CSGObject;
+class MeshObject;
+
+namespace detail {
+/** GeometryTriangulator : Triangulates object surfaces. May or may not use
+  opencascade.
+
+  Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class MANTID_GEOMETRY_DLL GeometryTriangulator {
+private:
+  bool m_isTriangulated;
+  size_t m_nFaces;
+  size_t m_nPoints;
+  std::vector<double> m_points;        ///< double array or points
+  std::vector<uint32_t> m_faces;       ///< Integer array of faces
+  const CSGObject *m_csgObj = nullptr; ///< Input Object
+  const MeshObject *m_meshObj = nullptr;
+  void checkTriangulated();
+
+public:
+  GeometryTriangulator(const CSGObject *obj = nullptr);
+  GeometryTriangulator(const MeshObject *obj);
+  GeometryTriangulator(const GeometryTriangulator &) = delete;
+  GeometryTriangulator &operator=(const GeometryTriangulator &) = delete;
+  ~GeometryTriangulator();
+  void triangulate();
+  void generateMesh();
+  void setGeometryCache(size_t nPoints, size_t nFaces,
+                        std::vector<double> &&points,
+                        std::vector<uint32_t> &&faces);
+  /// Return the number of triangle faces
+  size_t numTriangleFaces();
+  /// Return the number of triangle vertices
+  size_t numTriangleVertices();
+  /// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of
+  /// mesh
+  const std::vector<double> &getTriangleVertices();
+  /// get a pointer to the 3x(NumberOFaces) integers describing points forming
+  /// faces (p1,p2,p3)(p4,p5,p6).
+  const std::vector<uint32_t> &getTriangleFaces();
+#ifdef ENABLE_OPENCASCADE
+private:
+  std::unique_ptr<TopoDS_Shape>
+      m_objSurface; ///< Storage for the output surface
+                    /// Analyze the object
+                    /// OpenCascade analysis of object surface
+  void OCAnalyzeObject();
+  size_t numPoints() const;
+  size_t numFaces() const;
+  void setupPoints();
+  void setupFaces();
+
+public:
+  /// Return OpenCascade surface.
+  bool hasOCSurface() const;
+  const TopoDS_Shape &getOCSurface();
+#endif
+};
+} // namespace detail
+} // namespace Geometry
+} // namespace Mantid
+
+#endif /* MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ */
\ No newline at end of file
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h
deleted file mode 100644
index d8497b6cc5d33ea3fa6262df824960e98b49d1f3..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef GLU_GEOMETRYHANDLER_H
-#define GLU_GEOMETRYHANDLER_H
-
-#include "MantidGeometry/DllConfig.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class GeometryHandler;
-class GluGeometryRenderer;
-class IObjComponent;
-class CSGObject;
-/**
-   \class GluGeometryHandler
-   \brief Place holder for geometry triangulation and rendering with special
-   cases of cube, sphere, cone and cylinder.
-   \author Srikanth Nagella
-   \date December 2008
-   \version 1.0
-
-   This is an implementation class for handling geometry without triangulating
-   and using opengl glu methods.
-   This class can render cube, sphere, cone and cylinder.
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL GluGeometryHandler : public GeometryHandler {
-public:
-  /// the type of the geometry eg CUBOID,CYLINDER,CONE,SPHERE
-  enum class GeometryType {
-    NOSHAPE = 0,
-    CUBOID,            ///< CUBOID
-    HEXAHEDRON,        ///< HEXAHEDRON
-    SPHERE,            ///< SPHERE
-    CYLINDER,          ///< CYLINDER
-    CONE,              ///< CONE
-    SEGMENTED_CYLINDER ///< Cylinder with 1 or more segments (along the axis).
-    /// Sizes of segments are important.
-  };
-
-private:
-  static Kernel::Logger &PLog;                   ///< The official logger
-  std::unique_ptr<GluGeometryRenderer> Renderer; ///< Geometry renderer variable
-                                                 /// used for rendering
-  /// Object/ObjComponent
-  std::vector<Kernel::V3D> m_points;
-  double radius; ///<Radius for the sphere, cone and cylinder
-  double height; ///<height for cone and cylinder;
-  GeometryType
-      type; ///< the type of the geometry eg CUBOID,CYLINDER,CONE,SPHERE
-public:
-  GluGeometryHandler(const GluGeometryHandler &other);
-  GluGeometryHandler(IObjComponent *comp);              ///< Constructor
-  GluGeometryHandler(boost::shared_ptr<CSGObject> obj); ///< Constructor
-  GluGeometryHandler(CSGObject *obj);                   ///< Constructor
-  boost::shared_ptr<GeometryHandler> clone() const override;
-  ~GluGeometryHandler() override; ///< Destructor
-  GeometryHandler *createInstance(IObjComponent *comp) override;
-  GeometryHandler *createInstance(boost::shared_ptr<CSGObject> obj) override;
-  GeometryHandler *createInstance(CSGObject *) override;
-  /// sets the geometry handler for a cuboid
-  void setCuboid(const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &,
-                 const Kernel::V3D &);
-  /// sets the geometry handler for a hexahedron
-  void setHexahedron(const Kernel::V3D &, const Kernel::V3D &,
-                     const Kernel::V3D &, const Kernel::V3D &,
-                     const Kernel::V3D &, const Kernel::V3D &,
-                     const Kernel::V3D &, const Kernel::V3D &);
-  /// sets the geometry handler for a cone
-  void setSphere(const Kernel::V3D &, double);
-  /// sets the geometry handler for a cylinder
-  void setCylinder(const Kernel::V3D &, const Kernel::V3D &, double, double);
-  /// sets the geometry handler for a cone
-  void setCone(const Kernel::V3D &, const Kernel::V3D &, double, double);
-  /// sets the geometry handler for a segmented cylinder
-  void setSegmentedCylinder(const Kernel::V3D &, const Kernel::V3D &, double,
-                            double);
-  void Triangulate() override;
-  void Render() override;
-  void Initialize() override;
-  void GetObjectGeom(int &mytype, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) override;
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryRenderer.h
deleted file mode 100644
index 0b0f4b7e2207c34526eece1f2165649e0974e318..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryRenderer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef GLU_GEOMETRYRENDERER_H
-#define GLU_GEOMETRYRENDERER_H
-
-#include "MantidGeometry/DllConfig.h"
-
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class IObjComponent;
-/**
-   \class GluGeometryRenderer
-   \brief rendering geometry using opengl utility library glu.
-   \author Srikanth Nagella
-   \date July 2008
-   \version 1.0
-
-   This is an concrete class for rendering geometry using opengl.
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL GluGeometryRenderer {
-public:
-  /// Renders an object component
-  void Render(IObjComponent *ObjComp) const;
-  /// Renders a Sphere from the input values
-  void RenderSphere(const Kernel::V3D &center, double radius);
-  /// Renders a Cuboid from the input values
-  void RenderCube(const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-                  const Kernel::V3D &Point3, const Kernel::V3D &Point4);
-  /// Renders a Hexahedron from the input values
-  void RenderHexahedron(const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-                        const Kernel::V3D &Point3, const Kernel::V3D &Point4,
-                        const Kernel::V3D &Point5, const Kernel::V3D &Point6,
-                        const Kernel::V3D &Point7, const Kernel::V3D &Point8);
-  /// Renders a Cone from the input values
-  void RenderCone(const Kernel::V3D &center, const Kernel::V3D &axis,
-                  double radius, double height);
-  /// Renders a Cylinder from the input values
-  void RenderCylinder(const Kernel::V3D &center, const Kernel::V3D &axis,
-                      double radius, double height);
-  /// Renders a Segmented Cylinder from the input values
-  void RenderSegmentedCylinder(const Kernel::V3D &center,
-                               const Kernel::V3D &axis, double radius,
-                               double height);
-  /// Creates a sphere from the input values
-  void CreateSphere(const Kernel::V3D &center, double radius);
-  /// Creates a cuboid from the input values
-  void CreateCube(const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-                  const Kernel::V3D &Point3, const Kernel::V3D &Point4);
-  /// Creates a Hexahedron from the input values
-  void CreateHexahedron(const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-                        const Kernel::V3D &Point3, const Kernel::V3D &Point4,
-                        const Kernel::V3D &Point5, const Kernel::V3D &Point6,
-                        const Kernel::V3D &Point7, const Kernel::V3D &Point8);
-  /// Creates a Cone from the input values
-  void CreateCone(const Kernel::V3D &center, const Kernel::V3D &axis,
-                  double radius, double height);
-  /// Creates a cylinder from the input values
-  void CreateCylinder(const Kernel::V3D &center, const Kernel::V3D &axis,
-                      double radius, double height);
-  /// Creates a segmented cylinder from the input values
-  void CreateSegmentedCylinder(const Kernel::V3D &center,
-                               const Kernel::V3D &axis, double radius,
-                               double height);
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h
deleted file mode 100644
index 18020711526b6d6ac5bde9c1a52d4fb03581413a..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef MESH_GEOMETRYGENERATOR_H
-#define MESH_GEOMETRYGENERATOR_H
-
-#include "MantidGeometry/DllConfig.h"
-
-namespace Mantid {
-
-namespace Geometry {
-
-/**
-   This class delivers the triangles of a MeshObject for rendering via
-   the CacheGeometryRenderer.
-
-   Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MeshObject;
-class MANTID_GEOMETRY_DLL MeshGeometryGenerator {
-private:
-  MeshObject *Obj;    ///< Input Object
-  int mNoOfVertices;  ///< number of vertices
-  int mNoOfTriangles; ///< number of triangles
-  double *mPoints;    ///<double array or points
-  int *mFaces;        ///< Integer array of faces
-public:
-  MeshGeometryGenerator(MeshObject *obj);
-  ~MeshGeometryGenerator();
-  /// Generate the trangles
-  void Generate();
-  /// get the number of triangles
-  int getNumberOfTriangles();
-  /// get the number of points
-  int getNumberOfPoints();
-  /// get the triangle vertices
-  double *getTriangleVertices();
-  /// get the triangle faces
-  int *getTriangleFaces();
-  /// Sets the geometry cache using the triangulation information provided
-  void setGeometryCache(int noPts, int noFaces, double *pts, int *faces);
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif MESH_GEOMETRYGENERATOR_H
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h
deleted file mode 100644
index 7433fcc7d2da07f0fa89f49c2b6cbbbb30675f7f..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef OC_GEOMETRYGENERATOR_H
-#define OC_GEOMETRYGENERATOR_H
-
-#include "MantidGeometry/DllConfig.h"
-
-class TopoDS_Shape;
-
-namespace Mantid {
-namespace Geometry {
-class CSGObject;
-class Intersection;
-class Union;
-class SurfPoint;
-class CompGrp;
-class CompObj;
-class BoolValue;
-class Rule;
-class Surface;
-class Cylinder;
-class Sphere;
-class Cone;
-class Plane;
-class Torus;
-
-/**
-   \class OCGeometryGenerator
-   \brief Generates OpenCascade geometry from the ObjComponent
-   \author Mr. Srikanth Nagella
-   \date 4.08.2008
-   \version 1.0
-
-   This class is an OpenCascade geometry generation that takes in input as
-   ObjComponent.
-
-   Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL OCGeometryGenerator {
-private:
-  const CSGObject *Obj;     ///< Input Object
-  TopoDS_Shape *ObjSurface; ///< Storage for the output surface
-  /// Analyze the object
-  void AnalyzeObject();
-
-public:
-  OCGeometryGenerator(const CSGObject *obj);
-  ~OCGeometryGenerator();
-  void Generate();
-  TopoDS_Shape *getObjectSurface();
-  /// return number of triangles in mesh (0 for special shapes)
-  int getNumberOfTriangles();
-  /// return number of points used in mesh (o for special shapes)
-  int getNumberOfPoints();
-  /// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of
-  /// mesh
-  double *getTriangleVertices();
-  /// get a pointer to the 3x(NumberOFaces) integers describing points forming
-  /// faces (p1,p2,p3)(p4,p5,p6).
-  int *getTriangleFaces();
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h
deleted file mode 100644
index b6482ce7e57434e6165312444cb39f9e99be8f4b..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef OC_GEOMETRYHANDLER_H
-#define OC_GEOMETRYHANDLER_H
-
-#include "MantidGeometry/DllConfig.h"
-
-namespace Mantid {
-
-namespace Geometry {
-class GeometryHandler;
-class OCGeometryRenderer;
-class OCGeometryGenerator;
-class IObjComponent;
-class CSGObject;
-/**
-   \class OCGeometryHandler
-   \brief Place holder for OpenCascade library geometry triangulation and
-   rendering.
-   \author Srikanth Nagella
-   \date July 2008
-   \version 1.0
-
-   This is an implementation class for handling geometry using
-   OpenCascade(www.opencascade.org).
-   Unlike the GluGeometryHandler, it can handle more complex shapes.
-   It uses OpenCascade to generate a mesh defining the surface of an Object
-   (shape).
-   This shape is saved along with the instrument definition as a .vtp file (for
-   speed-ups).
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL OCGeometryHandler : public GeometryHandler {
-private:
-  static Kernel::Logger &PLog;  ///< The official logger
-  OCGeometryRenderer *Renderer; ///< Geometry renderer variable used for
-  /// rendering Object/ObjComponent
-  OCGeometryGenerator *
-      Triangulator; ///< Geometry generator to triangulate Object
-public:
-  OCGeometryHandler(IObjComponent *comp);              ///< Constructor
-  OCGeometryHandler(boost::shared_ptr<CSGObject> obj); ///< Constructor
-  OCGeometryHandler(CSGObject *obj);                   ///< Constructor
-  boost::shared_ptr<GeometryHandler>
-  clone() const override;        ///< Virtual copy constructor
-  ~OCGeometryHandler() override; ///< Destructor
-  GeometryHandler *createInstance(IObjComponent *comp) override;
-  GeometryHandler *createInstance(boost::shared_ptr<CSGObject> obj) override;
-  GeometryHandler *createInstance(CSGObject *) override;
-  void Triangulate() override;
-  void Render() override;
-  void Initialize() override;
-  /// Returns true if the shape can be triangulated
-  bool canTriangulate() override { return true; }
-  /// get the number of Triangles
-  int NumberOfTriangles() override;
-  /// get the number of points or vertices
-  int NumberOfPoints() override;
-  /// Extract the vertices of the triangles
-  double *getTriangleVertices() override;
-  /// Extract the Faces of the triangles
-  int *getTriangleFaces() override;
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h
deleted file mode 100644
index a9ab4715e1a4b623ad54ab3be5ce31b228a7d4a3..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef OC_GEOMETRYRENDERER_H
-#define OC_GEOMETRYRENDERER_H
-
-#include "MantidGeometry/DllConfig.h"
-#include "MantidKernel/Logger.h"
-class TopoDS_Shape;
-namespace Mantid {
-
-namespace Geometry {
-class IObjComponent;
-/**
-   \class OCGeometryRenderer
-   \brief rendering geometry primitives of OpenCascade
-   \author Srikanth Nagella
-   \date July 2008
-   \version 1.0
-
-   This is an concrete class for rendering GtsSurface using opengl.
-
-   Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-   This file is part of Mantid.
-
-   Mantid is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   Mantid is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-   File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class MANTID_GEOMETRY_DLL OCGeometryRenderer {
-private:
-  static Kernel::Logger &PLog; ///< The official logger
-  void RenderTopoDS(TopoDS_Shape *ObjSurf);
-
-public:
-  void Render(TopoDS_Shape *ObjSurf);
-  void Render(IObjComponent *ObjComp);
-  void Initialize(TopoDS_Shape *ObjSurf);
-  void Initialize(IObjComponent *ObjComp);
-  void WriteVTK(TopoDS_Shape *out);
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h b/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d266bf6730c5e2350c222d6ce2af51b559c1c0f
--- /dev/null
+++ b/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h
@@ -0,0 +1,40 @@
+#ifndef MANTID_GEOMETRY_RENDERER_H_
+#define MANTID_GEOMETRY_RENDERER_H_
+
+#include "MantidGeometry/DllConfig.h"
+#include "MantidGeometry/Rendering/OpenGL_Headers.h"
+#include <vector>
+
+class TopoDS_Shape;
+
+namespace Mantid {
+namespace Kernel {
+class V3D;
+}
+namespace Geometry {
+class RectangularDetector;
+class StructuredDetector;
+class IObjComponent;
+
+namespace detail {
+class GeometryTriangulator;
+class ShapeInfo;
+} // namespace detail
+
+namespace RenderingHelpers {
+/// Render IObjComponent
+MANTID_GEOMETRY_DLL void renderIObjComponent(const IObjComponent &objComp);
+/// Render Traingulated Surface
+MANTID_GEOMETRY_DLL void
+renderTriangulated(detail::GeometryTriangulator &triangulator);
+/// Renders a sphere, cuboid, hexahedron, cone or cylinder
+MANTID_GEOMETRY_DLL void renderShape(const detail::ShapeInfo &shapeInfo);
+/// Renders a Bitmap (used for rendering RectangularDetector)
+MANTID_GEOMETRY_DLL void renderBitmap(const RectangularDetector &rectDet);
+/// Renders structured geometry (used for rendering StructuredDetector)
+MANTID_GEOMETRY_DLL void renderStructured(const StructuredDetector &structDet);
+} // namespace RenderingHelpers
+} // namespace Geometry
+} // namespace Mantid
+
+#endif /* MANTID_GEOMETRY_RENDERER_H_ */
\ No newline at end of file
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4d0ea6e32214baf01e6a5d28ddd2a38bf56ab1d
--- /dev/null
+++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h
@@ -0,0 +1,94 @@
+#ifndef MANTID_GEOMETRY_SHAPEINFO_H_
+#define MANTID_GEOMETRY_SHAPEINFO_H_
+
+#include "MantidGeometry/DllConfig.h"
+#include <vector>
+
+namespace Mantid {
+namespace Kernel {
+class V3D;
+}
+namespace Geometry {
+class RectangularDetector;
+class StructuredDetector;
+class IObjComponent;
+
+/** ShapeInfo : Stores shape types and information relevant to drawing the
+shape. For cylinders, spheres and cones, height and radius are stored. Points
+are stored in the winding order shown in the IDF here
+http://docs.mantidproject.org/nightly/concepts/HowToDefineGeometricShape.html.
+
+Copyright &copy; 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+National Laboratory & European Spallation Source
+
+This file is part of Mantid.
+
+Mantid is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+Mantid is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+File change history is stored at: <https://github.com/mantidproject/mantid>
+Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+namespace detail {
+class MANTID_GEOMETRY_DLL ShapeInfo {
+public:
+  enum class GeometryShape {
+    NOSHAPE = 0,
+    CUBOID,     ///< CUBOID
+    HEXAHEDRON, ///< HEXAHEDRON
+    SPHERE,     ///< SPHERE
+    CYLINDER,   ///< CYLINDER
+    CONE,       ///< CONE
+  };
+
+private:
+  std::vector<Kernel::V3D> m_points;
+  double m_radius; ///< Radius for the sphere, cone and cylinder
+  double m_height; ///< height for cone and cylinder;
+  GeometryShape m_shape;
+
+public:
+  ShapeInfo();
+  ShapeInfo(const ShapeInfo &) = default;
+  const std::vector<Kernel::V3D> &points() const;
+  double radius() const;
+  double height() const;
+  GeometryShape shape() const;
+
+  void getObjectGeometry(GeometryShape &myshape,
+                         std::vector<Kernel::V3D> &points, double &myradius,
+                         double &myheight) const;
+  /// sets the geometry handler for a cuboid
+  void setCuboid(const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &,
+                 const Kernel::V3D &);
+  /// sets the geometry handler for a hexahedron
+  void setHexahedron(const Kernel::V3D &, const Kernel::V3D &,
+                     const Kernel::V3D &, const Kernel::V3D &,
+                     const Kernel::V3D &, const Kernel::V3D &,
+                     const Kernel::V3D &, const Kernel::V3D &);
+  /// sets the geometry handler for a sphere
+  void setSphere(const Kernel::V3D &center, double radius);
+  /// sets the geometry handler for a cylinder
+  void setCylinder(const Kernel::V3D &center, const Kernel::V3D &axis,
+                   double radius, double height);
+  /// sets the geometry handler for a cone
+  void setCone(const Kernel::V3D &center, const Kernel::V3D &axis,
+               double radius, double height);
+
+  bool operator==(const ShapeInfo &other);
+};
+} // namespace detail
+} // namespace Geometry
+} // namespace Mantid
+
+#endif /* MANTID_GEOMETRY_SHAPEINFO_H_ */
\ No newline at end of file
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h
deleted file mode 100644
index 2985f21c5d5dcc74a2dcba74a9bfd9141b324b10..0000000000000000000000000000000000000000
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef STRUCTUREDGEOMETRYHANDLER_H
-#define STRUCTUREDGEOMETRYHANDLER_H
-
-#ifndef Q_MOC_RUN
-#include <boost/weak_ptr.hpp>
-#endif
-#include "MantidGeometry/DllConfig.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidKernel/Logger.h"
-
-namespace Mantid {
-namespace Geometry {
-/**
-\class StructuredGeometryHandler
-\brief Handler for StructuredDetector geometry objects
-\author Lamar Moore
-\date March 2016
-\version 1.0
-
-This class supports drawing StructuredDetector.
-
-Copyright &copy; 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class ObjComponent;
-class CSGObject;
-class MANTID_GEOMETRY_DLL StructuredGeometryHandler : public GeometryHandler {
-private:
-  static Kernel::Logger &PLog; ///< The official logger
-
-  boost::shared_ptr<GeometryHandler> clone() const override;
-
-  /// The StructuredDetector object being drawn.
-  StructuredDetector *m_Det;
-
-public:
-  StructuredGeometryHandler(StructuredDetector *comp);
-  StructuredGeometryHandler();
-
-  StructuredGeometryHandler *createInstance(
-      IObjComponent *) override; ///< Create an instance of concrete geometry
-                                 /// handler for ObjComponent
-  StructuredGeometryHandler *createInstance(boost::shared_ptr<CSGObject>)
-      override; ///< Create an instance of concrete geometry handler for Object
-  GeometryHandler *createInstance(CSGObject *)
-      override; ///< Create an instance of concrete geometry handler for Object
-  void Triangulate() override; ///< Triangulate the Object
-  void Render() override;      ///< Render Object or ObjComponent
-  void Initialize()
-      override; ///< Prepare/Initialize Object/ObjComponent to be rendered
-                /// Returns true if the shape can be triangulated
-  bool canTriangulate() override { return false; }
-  /// get the number of triangles
-  int NumberOfTriangles() override { return 0; }
-  /// get the number of points or vertices
-  int NumberOfPoints() override { return 0; }
-  /// Extract the vertices of the triangles
-  double *getTriangleVertices() override { return nullptr; }
-  /// Extract the Faces of the triangles
-  int *getTriangleFaces() override { return nullptr; }
-  /// Sets the geometry cache using the triangulation information provided
-  void setGeometryCache(int noPts, int noFaces, double *pts,
-                        int *faces) override {
-    (void)noPts;
-    (void)noFaces;
-    (void)pts;
-    (void)faces; // Avoid compiler warning
-  };
-  /// return the actual type and points of one of the "standard" objects,
-  /// cuboid/cone/cyl/sphere
-  void GetObjectGeom(int &mytype, std::vector<Kernel::V3D> &vectors,
-                     double &myradius, double &myheight) override {
-    (void)mytype;
-    (void)vectors;
-    (void)myradius;
-    (void)myheight; // Avoid compiler warning
-  };
-};
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
-
-#endif // STRUCTUREDGEOMETRYHANDLER_H
\ No newline at end of file
diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h
index bd264ce85ac611f52532896802cbbbc4f7d2d12d..0c3a58e15cf9d6f1d93be3871744b90a19711413 100644
--- a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h
+++ b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h
@@ -53,8 +53,10 @@ private:
   // Private Methods
   void Init();
   Poco::XML::Element *getElementByObjectName(std::string name);
-  void readPoints(Poco::XML::Element *pEle, int *noOfPoints, double **points);
-  void readTriangles(Poco::XML::Element *pEle, int *noOfTriangles, int **faces);
+  void readPoints(Poco::XML::Element *pEle, int noOfPoints,
+                  std::vector<double> &points);
+  void readTriangles(Poco::XML::Element *pEle, int noOfTriangles,
+                     std::vector<uint32_t> &faces);
 
 public:
   vtkGeometryCacheReader(std::string filename);
diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h
index c6b87cc774c405f4ab2d597907e9a67e2ed0cc61..6a2226f1dc0ab5278c4ecb47b6e229a251a8714e 100644
--- a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h
+++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h
@@ -42,8 +42,10 @@ class MANTID_GEOMETRY_DLL SurfaceFactory {
 private:
   // workaround because gcc 4.4 cannot have std::unique_ptr inside a std::map.
   // http://stackoverflow.com/questions/7342703/gcc-4-4-4-5-unique-ptr-not-work-for-unordered-set-unordered-map
-  typedef std::vector<std::pair<std::string, std::unique_ptr<Surface>>>
-      MapType;                 ///< Storage of surface pointers
+
+  ///< Storage of surface pointers.
+  using MapType = std::vector<std::pair<std::string, std::unique_ptr<Surface>>>;
+
   static SurfaceFactory *FOBJ; ///< Effective "this"
 
   MapType SGrid;                  ///< The tally stack
diff --git a/Framework/Geometry/src/Crystal/HKLGenerator.cpp b/Framework/Geometry/src/Crystal/HKLGenerator.cpp
index 9d56c3a2f5dd5fcc96326c4b51852362a6558c03..0979b69dff53f69745f4d2e8b991c44f9d89e1da 100644
--- a/Framework/Geometry/src/Crystal/HKLGenerator.cpp
+++ b/Framework/Geometry/src/Crystal/HKLGenerator.cpp
@@ -62,20 +62,20 @@ V3D HKLGenerator::getEndHKL() const {
 
 /// Default constructor, requirement from boost::iterator_facade
 HKLGenerator::const_iterator::const_iterator()
-    : m_h(0), m_k(0), m_l(0), m_hkl(V3D(0, 0, 0)), m_hMin(0), m_hMax(0),
-      m_kMin(0), m_kMax(0), m_lMin(0), m_lMax(0) {}
+    : m_h(0), m_k(0), m_l(0), m_hkl(V3D(0, 0, 0)), m_hMax(0), m_kMin(0),
+      m_kMax(0), m_lMin(0), m_lMax(0) {}
 
 /// Return an iterator with min = max = current.
 HKLGenerator::const_iterator::const_iterator(const V3D &current)
     : m_h(static_cast<int>(current.X())), m_k(static_cast<int>(current.Y())),
-      m_l(static_cast<int>(current.Z())), m_hkl(current), m_hMin(m_h),
-      m_hMax(m_h), m_kMin(m_k), m_kMax(m_k), m_lMin(m_l), m_lMax(m_l) {}
+      m_l(static_cast<int>(current.Z())), m_hkl(current), m_hMax(m_h),
+      m_kMin(m_k), m_kMax(m_k), m_lMin(m_l), m_lMax(m_l) {}
 
 /// Return an iterator that can move from min to max, with current = min
 HKLGenerator::const_iterator::const_iterator(const V3D &hklMin,
                                              const V3D &hklMax)
     : m_h(static_cast<int>(hklMin.X())), m_k(static_cast<int>(hklMin.Y())),
-      m_l(static_cast<int>(hklMin.Z())), m_hkl(hklMin), m_hMin(m_h),
+      m_l(static_cast<int>(hklMin.Z())), m_hkl(hklMin),
       m_hMax(static_cast<int>(hklMax.X())), m_kMin(m_k),
       m_kMax(static_cast<int>(hklMax.Y())), m_lMin(m_l),
       m_lMax(static_cast<int>(hklMax.Z())) {}
diff --git a/Framework/Geometry/src/Crystal/UnitCell.cpp b/Framework/Geometry/src/Crystal/UnitCell.cpp
index 2e273816e2cf7235a80dc05aa5da698db81acbdf..08077755d176d12974357c4463e946bf365d36fd 100644
--- a/Framework/Geometry/src/Crystal/UnitCell.cpp
+++ b/Framework/Geometry/src/Crystal/UnitCell.cpp
@@ -452,7 +452,13 @@ double UnitCell::recAngle(double h1, double k1, double l1, double h2, double k2,
   double E, ang;
   Q1 = Gstar * Q1;
   E = Q1.scalar_prod(Q2);
-  ang = acos(E / dstar(h1, k1, l1) / dstar(h2, k2, l2));
+  double temp = E / dstar(h1, k1, l1) / dstar(h2, k2, l2);
+  if (temp > 1)
+    ang = 0.;
+  else if (temp < -1)
+    ang = M_PI;
+  else
+    ang = acos(temp);
   if (angleunit == angDegrees)
     return rad2deg * ang;
   else
diff --git a/Framework/Geometry/src/IObjComponent.cpp b/Framework/Geometry/src/IObjComponent.cpp
index a922c367caf7c5d45b5b1d490808e3de6b26e386..8ea7b46480f7e62f58e1c99604d75ca231cbd77c 100644
--- a/Framework/Geometry/src/IObjComponent.cpp
+++ b/Framework/Geometry/src/IObjComponent.cpp
@@ -3,12 +3,12 @@
 //----------------------------------------------------------------------
 #include "MantidGeometry/IObjComponent.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Rendering/CacheGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
 
 namespace Mantid {
 namespace Geometry {
 
-IObjComponent::IObjComponent() { handle = new CacheGeometryHandler(this); }
+IObjComponent::IObjComponent() { handle = new GeometryHandler(this); }
 
 /** Constructor, specifying the GeometryHandler (renderer engine)
  * for this IObjComponent.
@@ -37,12 +37,10 @@ void IObjComponent::setGeometryHandler(GeometryHandler *h) {
 
 /**
  * Copy constructor
- * @param origin :: The object to initialize this with
  */
-IObjComponent::IObjComponent(const IObjComponent &origin) {
-  // Handler contains a pointer to 'this' therefore needs regenerating
-  // with new object
-  handle = origin.handle->createInstance(this);
+IObjComponent::IObjComponent(const IObjComponent &) {
+  // Copy constructor just creates new handle. Copies nothing.
+  handle = new GeometryHandler(this);
 }
 
 /**
@@ -52,10 +50,10 @@ IObjComponent::IObjComponent(const IObjComponent &origin) {
  */
 IObjComponent &IObjComponent::operator=(const IObjComponent &rhs) {
   if (&rhs != this) {
-    handle = rhs.handle->createInstance(this);
+    // Assignment operator copies nothing. Just creates new handle.
+    handle = new GeometryHandler(this);
   }
   return *this;
 }
-
 } // namespace Geometry
 } // namespace Mantid
diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp
index e5692787af4641436aa1a79be11881a92b5122d6..73e92efa2d60b0c8873d31ecf9933b0c07dfc253 100644
--- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp
+++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp
@@ -107,8 +107,46 @@ ComponentInfo::componentsInSubtree(size_t componentIndex) const {
   return m_componentInfo->componentsInSubtree(componentIndex);
 }
 
+const std::vector<size_t> &
+ComponentInfo::children(size_t componentIndex) const {
+  return m_componentInfo->children(componentIndex);
+}
+
 size_t ComponentInfo::size() const { return m_componentInfo->size(); }
 
+ComponentInfo::QuadrilateralComponent
+ComponentInfo::quadrilateralComponent(const size_t componentIndex) const {
+  auto type = componentType(componentIndex);
+  if (!(type == Beamline::ComponentType::Structured ||
+        type == Beamline::ComponentType::Rectangular))
+    throw std::runtime_error("ComponentType is not Structured or Rectangular "
+                             "in ComponentInfo::quadrilateralComponent.");
+
+  QuadrilateralComponent corners;
+  const auto &innerRangeComp = m_componentInfo->children(componentIndex);
+  // nSubComponents, subtract off self hence -1. nSubComponents = number of
+  // horizontal columns.
+  corners.nX = innerRangeComp.size();
+  auto innerRangeDet = m_componentInfo->detectorRangeInSubtree(componentIndex);
+  auto nSubDetectors =
+      std::distance(innerRangeDet.begin(), innerRangeDet.end());
+  corners.nY = nSubDetectors / corners.nX;
+  auto firstComp = innerRangeComp.front();
+  // The ranges contain the parent component as the last index
+  // therefore end() - 2
+  auto lastComp = innerRangeComp.back();
+  corners.bottomLeft =
+      *(m_componentInfo->detectorRangeInSubtree(firstComp).begin());
+  corners.topRight =
+      *(m_componentInfo->detectorRangeInSubtree(lastComp).end() - 1);
+  corners.topLeft =
+      *(m_componentInfo->detectorRangeInSubtree(firstComp).end() - 1);
+  corners.bottomRight =
+      *m_componentInfo->detectorRangeInSubtree(lastComp).begin();
+
+  return corners;
+}
+
 size_t ComponentInfo::indexOf(Geometry::IComponent *id) const {
   return m_compIDToIndex->at(id);
 }
@@ -193,7 +231,7 @@ size_t ComponentInfo::sample() const { return m_componentInfo->sample(); }
 
 double ComponentInfo::l1() const { return m_componentInfo->l1(); }
 
-size_t ComponentInfo::root() { return m_componentInfo->root(); }
+size_t ComponentInfo::root() const { return m_componentInfo->root(); }
 
 void ComponentInfo::setPosition(const size_t componentIndex,
                                 const Kernel::V3D &newPosition) {
@@ -257,39 +295,16 @@ double ComponentInfo::solidAngle(const size_t componentIndex,
  * @param index : Index of the component to get the bounding box for
  * @param reference : Reference bounding box (optional)
  * @param mutableBB : Output bounding box. This will be grown.
- * @param mutableDetExclusions : Output detector exclusions to append to. These
- * are ranges of detector indices that we do NOT need to consider for future
- * bounding box calculations for detectors.
- * @param mutableIterator : Iterator to the next non-detector component.
  */
-template <typename IteratorT>
 void ComponentInfo::growBoundingBoxAsRectuangularBank(
     size_t index, const Geometry::BoundingBox *reference,
-    Geometry::BoundingBox &mutableBB,
-    std::map<size_t, size_t> &mutableDetExclusions,
-    IteratorT &mutableIterator) const {
-  const auto innerRangeComp = m_componentInfo->componentRangeInSubtree(index);
-  const auto innerRangeDet = m_componentInfo->detectorRangeInSubtree(index);
-  // subtract 1 because component ranges includes self
-  auto nSubComponents = innerRangeComp.end() - innerRangeComp.begin() - 1;
-  auto nSubDetectors =
-      std::distance(innerRangeDet.begin(), innerRangeDet.end());
-  auto nY = nSubDetectors / nSubComponents;
-  size_t bottomLeft = *innerRangeDet.begin();
-  size_t topRight = bottomLeft + nSubDetectors - 1;
-  size_t topLeft = bottomLeft + (nY - 1);
-  size_t bottomRight = topRight - (nY - 1);
-
-  mutableBB.grow(componentBoundingBox(bottomLeft, reference));
-  mutableBB.grow(componentBoundingBox(topRight, reference));
-  mutableBB.grow(componentBoundingBox(topLeft, reference));
-  mutableBB.grow(componentBoundingBox(bottomRight, reference));
+    Geometry::BoundingBox &mutableBB) const {
 
-  // Get bounding box for rectangular bank.
-  // Record detector ranges to skip
-  mutableDetExclusions.insert(std::make_pair(bottomLeft, topRight));
-  // Skip all sub components.
-  mutableIterator = innerRangeComp.rend();
+  auto panel = quadrilateralComponent(index);
+  mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference));
+  mutableBB.grow(componentBoundingBox(panel.topRight, reference));
+  mutableBB.grow(componentBoundingBox(panel.topLeft, reference));
+  mutableBB.grow(componentBoundingBox(panel.bottomRight, reference));
 }
 
 /**
@@ -300,62 +315,11 @@ void ComponentInfo::growBoundingBoxAsRectuangularBank(
  * @param index : Index of the component to get the bounding box for
  * @param reference : Reference bounding box (optional)
  * @param mutableBB : Output bounding box. This will be grown.
- * @param mutableDetExclusions : Output detector exclusions to append to. These
- * are ranges of detector indices that we do NOT need to consider for future
- * bounding box calculations for detectors.
- * @param mutableIterator : Iterator to the next non-detector component.
- */
-template <typename IteratorT>
-void ComponentInfo::growBoundingBoxAsOutline(
-    size_t index, const BoundingBox *reference, BoundingBox &mutableBB,
-    std::map<size_t, size_t> &mutableDetExclusions,
-    IteratorT &mutableIterator) const {
-
-  auto rangeDet = m_componentInfo->detectorRangeInSubtree(index);
-  if (!rangeDet.empty()) {
-    auto startIndex = *rangeDet.begin();
-    auto endIndex = *(rangeDet.end() - 1);
-    mutableBB.grow(componentBoundingBox(index, reference));
-    mutableDetExclusions.insert(std::make_pair(startIndex, endIndex));
-  }
-  // No sub components (non detectors) in tube, so just increment iterator
-  mutableIterator++;
-}
-
-/**
- * Grow the bounding box for a component by evaluating all detector bounding
- * boxes for detectors not within any limits described by excusion ranges.
- *
- * Map of exlusion ranges provided as input. There should be no intersection
- * between exclusion ranges, but that should already be guaranteed since
- * detector indices are unique. The key is the beginning of the exclusion range,
- * and therefore we have a guranteed ordering of exclusion ranges.
- *
- * @param index : Index of the component to get the bounding box for
- * @param reference : Reference bounding box.
- * @param mutableBB : Output bounding box. This will be grown.
- * @param detectorExclusions : ranges of detector indices NOT to consider.
  */
-void ComponentInfo::growBoundingBoxByDetectors(
-    size_t index, const BoundingBox *reference, BoundingBox &mutableBB,
-    const std::map<size_t, size_t> &detectorExclusions) const {
-  auto rangeDet = m_componentInfo->detectorRangeInSubtree(index);
-  auto detIt = rangeDet.begin();
-  auto exclIt = detectorExclusions.begin();
-  while (detIt != rangeDet.end()) {
-    auto detIndex = *detIt;
-    if (exclIt != detectorExclusions.end() && detIndex >= exclIt->first &&
-        detIndex <= exclIt->second) {
-      // Move the detector iterator outside the current exclusion
-      detIt += exclIt->second - exclIt->first + 1;
-      // Move the exclusion iterator forward. Do not consider the same exclusion
-      // range again.
-      ++exclIt;
-    } else {
-      mutableBB.grow(componentBoundingBox(*detIt, reference));
-      ++detIt;
-    }
-  }
+void ComponentInfo::growBoundingBoxAsOutline(size_t index,
+                                             const BoundingBox *reference,
+                                             BoundingBox &mutableBB) const {
+  mutableBB.grow(componentBoundingBox(index, reference));
 }
 
 /**
@@ -370,7 +334,8 @@ BoundingBox
 ComponentInfo::componentBoundingBox(const size_t index,
                                     const BoundingBox *reference) const {
   // Check that we have a valid shape here
-  if (!hasValidShape(index)) {
+  if (!hasValidShape(index) ||
+      componentType(index) == Beamline::ComponentType::Infinite) {
     return BoundingBox(); // Return null bounding box
   }
   const auto &s = this->shape(index);
@@ -423,34 +388,29 @@ ComponentInfo::componentBoundingBox(const size_t index,
  */
 BoundingBox ComponentInfo::boundingBox(const size_t componentIndex,
                                        const BoundingBox *reference) const {
-  if (isDetector(componentIndex)) {
+  if (isDetector(componentIndex) ||
+      componentType(componentIndex) == Beamline::ComponentType::Infinite) {
     return componentBoundingBox(componentIndex, reference);
   }
+
   BoundingBox absoluteBB;
-  auto rangeComp = m_componentInfo->componentRangeInSubtree(componentIndex);
-  std::map<size_t, size_t> detExclusions{};
-  auto compIterator = rangeComp.rbegin();
-  while (compIterator != rangeComp.rend()) {
-    const size_t index = *compIterator;
-    const auto compFlag = componentType(index);
-    if (hasSource() && index == source()) {
-      ++compIterator;
-    } else if (compFlag == Beamline::ComponentType::Rectangular) {
-      growBoundingBoxAsRectuangularBank(index, reference, absoluteBB,
-                                        detExclusions, compIterator);
-    } else if (compFlag == Beamline::ComponentType::OutlineComposite) {
-      growBoundingBoxAsOutline(index, reference, absoluteBB, detExclusions,
-                               compIterator);
-    } else {
-      // General case
-      absoluteBB.grow(componentBoundingBox(index, reference));
-      ++compIterator;
+  const auto compFlag = componentType(componentIndex);
+  if (hasSource() && componentIndex == source()) {
+    // Do nothing. Source is not considered part of the beamline for bounding
+    // box calculations.
+  } else if (compFlag == Beamline::ComponentType::Unstructured) {
+    for (const auto &childIndex : this->children(componentIndex)) {
+      absoluteBB.grow(boundingBox(childIndex, reference));
     }
+  } else if (compFlag == Beamline::ComponentType::Rectangular ||
+             compFlag == Beamline::ComponentType::Structured) {
+    growBoundingBoxAsRectuangularBank(componentIndex, reference, absoluteBB);
+  } else if (compFlag == Beamline::ComponentType::OutlineComposite) {
+    growBoundingBoxAsOutline(componentIndex, reference, absoluteBB);
+  } else {
+    // General case
+    absoluteBB.grow(componentBoundingBox(componentIndex, reference));
   }
-
-  // Now deal with bounding boxes for detectors
-  growBoundingBoxByDetectors(componentIndex, reference, absoluteBB,
-                             detExclusions);
   return absoluteBB;
 }
 
diff --git a/Framework/Geometry/src/Instrument/FitParameter.cpp b/Framework/Geometry/src/Instrument/FitParameter.cpp
index 196afb8cadb37f425cffe41e11b6d1f140867774..55be129701de919e302975d99a5f3d1ba30523a0 100644
--- a/Framework/Geometry/src/Instrument/FitParameter.cpp
+++ b/Framework/Geometry/src/Instrument/FitParameter.cpp
@@ -160,7 +160,7 @@ std::ostream &operator<<(std::ostream &os, const FitParameter &f) {
 */
 std::istream &operator>>(std::istream &in, FitParameter &f) {
 
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   std::string str;
   getline(in, str);
 
diff --git a/Framework/Geometry/src/Instrument/Goniometer.cpp b/Framework/Geometry/src/Instrument/Goniometer.cpp
index 3bae3f88603880e33666d42fce6e9d27970da9c9..1002fd2ed07877a088b42ea910ef460aa4520cc9 100644
--- a/Framework/Geometry/src/Instrument/Goniometer.cpp
+++ b/Framework/Geometry/src/Instrument/Goniometer.cpp
@@ -6,6 +6,7 @@
 #include <vector>
 #include <boost/algorithm/string.hpp>
 #include <cstdlib>
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/Logger.h"
 
@@ -178,6 +179,40 @@ void Goniometer::setRotationAngle(size_t axisnumber, double value) {
   recalculateR();
 }
 
+/**Calculate goniometer for rotation around y-asix for constant wavelength from
+ * Q Sample
+ * @param position :: Q Sample position in reciprocal space
+ * @param wavelength :: wavelength
+*/
+void Goniometer::calcFromQSampleAndWavelength(
+    const Mantid::Kernel::V3D &position, double wavelength) {
+  V3D Q(position);
+  if (Kernel::ConfigService::Instance().getString("Q.convention") ==
+      "Crystallography")
+    Q *= -1;
+  double wv = 2.0 * M_PI / wavelength;
+  double norm_q2 = Q.norm2();
+  double theta = acos(1 - norm_q2 / (2 * wv * wv)); // [0, pi]
+  double phi = asin(-Q[1] / wv * sin(theta));       // [-pi/2, pi/2]
+  V3D Q_lab(-wv * sin(theta) * cos(phi), -wv * sin(theta) * sin(phi),
+            wv * (1 - cos(theta)));
+
+  // Solve to find rotation matrix, assuming only rotation around y-axis
+  // A * X = B
+  Matrix<double> A({Q[0], Q[2], Q[2], -Q[0]}, 2, 2);
+  A.Invert();
+  std::vector<double> B{Q_lab[0], Q_lab[2]};
+  std::vector<double> X = A * B;
+  double rot = atan2(X[1], X[0]);
+
+  Matrix<double> goniometer(3, 3, true);
+  goniometer[0][0] = cos(rot);
+  goniometer[0][2] = sin(rot);
+  goniometer[2][0] = -sin(rot);
+  goniometer[2][2] = cos(rot);
+  setR(goniometer);
+}
+
 /// Get GoniometerAxis obfject using motor number
 /// @param axisnumber :: axis number (from 0)
 const GoniometerAxis &Goniometer::getAxis(size_t axisnumber) const {
diff --git a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
index 88776862dc21d3fe9f78c77b8178981638c7ecb1..41e50b977925a30e0e742769615aaf8b4f84a5ca 100644
--- a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
+++ b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
@@ -1587,8 +1587,8 @@ void InstrumentDefinitionParser::createStructuredDetector(
   bool isZBeam =
       m_instrument->getReferenceFrame()->isVectorPointingAlongBeam(zVector);
   // Now, initialize all the pixels in the bank
-  bank->initialize(xpixels, ypixels, xValues, yValues, isZBeam, idstart,
-                   idfillbyfirst_y, idstepbyrow, idstep);
+  bank->initialize(xpixels, ypixels, std::move(xValues), std::move(yValues),
+                   isZBeam, idstart, idfillbyfirst_y, idstepbyrow, idstep);
 
   // Loop through all detectors in the newly created bank and mark those in
   // the instrument.
diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
index daa04a82684604f0229a009008b981d04803c9ff..719d9883b116ce6045efb159cedb1ed541667ab6 100644
--- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
+++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp
@@ -71,6 +71,7 @@ InstrumentVisitor::InstrumentVisitor(
           boost::make_shared<std::vector<size_t>>()),
       m_parentComponentIndices(boost::make_shared<std::vector<size_t>>(
           m_orderedDetectorIds->size(), 0)),
+      m_children(boost::make_shared<std::vector<std::vector<size_t>>>()),
       m_detectorRanges(
           boost::make_shared<std::vector<std::pair<size_t, size_t>>>()),
       m_componentRanges(
@@ -178,6 +179,7 @@ InstrumentVisitor::registerComponentAssembly(const ICompAssembly &assembly) {
   for (const auto &child : children) {
     (*m_parentComponentIndices)[child] = componentIndex;
   }
+  m_children->emplace_back(std::move(children));
   return componentIndex;
 }
 
@@ -205,6 +207,37 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) {
   // Unless this is the root component this parent is not correct and will be
   // updated later in the register call of the parent.
   m_parentComponentIndices->push_back(componentIndex);
+  // Generic components are not assemblies and do not therefore have children.
+  m_children->emplace_back(std::vector<size_t>());
+  return componentIndex;
+}
+
+/**
+* @brief InstrumentVisitor::registerInfiniteComponent
+* @param component : IComponent being visited
+* @return Component index of this component
+*/
+size_t InstrumentVisitor::registerInfiniteComponent(
+    const Mantid::Geometry::IComponent &component) {
+  /*
+  * For a generic leaf component we extend the component ids list, but
+  * the detector indexes entries will of course be empty
+  */
+  m_detectorRanges->emplace_back(
+      std::make_pair(0, 0)); // Represents an empty range
+                             // Record the ID -> index mapping
+  const size_t componentIndex = commonRegistration(component);
+  m_componentType->push_back(Beamline::ComponentType::Infinite);
+
+  const size_t componentStart = m_assemblySortedComponentIndices->size();
+  m_componentRanges->emplace_back(
+      std::make_pair(componentStart, componentStart + 1));
+  m_assemblySortedComponentIndices->push_back(componentIndex);
+  // Unless this is the root component this parent is not correct and will be
+  // updated later in the register call of the parent.
+  m_parentComponentIndices->push_back(componentIndex);
+  // Generic components are not assemblies and do not therefore have children.
+  m_children->emplace_back(std::vector<size_t>());
   return componentIndex;
 }
 
@@ -220,15 +253,39 @@ size_t InstrumentVisitor::registerGenericObjComponent(
   return index;
 }
 
+/**
+* Register a structured bank
+* @param bank : Rectangular Detector
+* @return index assigned
+*/
+size_t InstrumentVisitor::registerRectangularBank(const ICompAssembly &bank) {
+  auto index = registerComponentAssembly(bank);
+  size_t rangesIndex = index - m_orderedDetectorIds->size();
+  (*m_componentType)[rangesIndex] = Beamline::ComponentType::Rectangular;
+  return index;
+}
+
+/**
+* @brief InstrumentVisitor::registerInfiniteObjComponent
+* @param objComponent : IObjComponent being visited
+* @return Component index of this component
+*/
+size_t InstrumentVisitor::registerInfiniteObjComponent(
+    const IObjComponent &objComponent) {
+  auto index = registerInfiniteComponent(objComponent);
+  (*m_shapes)[index] = objComponent.shape();
+  return index;
+}
+
 /**
  * Register a structured bank
- * @param bank : Rectangular Detector
+ * @param bank : Structured Detector
  * @return index assigned
  */
 size_t InstrumentVisitor::registerStructuredBank(const ICompAssembly &bank) {
   auto index = registerComponentAssembly(bank);
   size_t rangesIndex = index - m_orderedDetectorIds->size();
-  (*m_componentType)[rangesIndex] = Beamline::ComponentType::Rectangular;
+  (*m_componentType)[rangesIndex] = Beamline::ComponentType::Structured;
   return index;
 }
 
@@ -335,8 +392,8 @@ InstrumentVisitor::componentInfo() const {
   return Kernel::make_unique<Mantid::Beamline::ComponentInfo>(
       m_assemblySortedDetectorIndices, m_detectorRanges,
       m_assemblySortedComponentIndices, m_componentRanges,
-      m_parentComponentIndices, m_positions, m_rotations, m_scaleFactors,
-      m_componentType, m_names, m_sourceIndex, m_sampleIndex);
+      m_parentComponentIndices, m_children, m_positions, m_rotations,
+      m_scaleFactors, m_componentType, m_names, m_sourceIndex, m_sampleIndex);
 }
 
 std::unique_ptr<Beamline::DetectorInfo>
diff --git a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp
index c53c6a4713ff87bbc8d04c055c1f4c4625f62dad..3f4deaf8030b92ec3672c975aa4162e48dd91a84 100644
--- a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp
+++ b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp
@@ -380,7 +380,7 @@ boost::shared_ptr<IObject> ObjCompAssembly::createOutline() {
 
   // Get information about the shape and size of a detector
   std::string type;
-  int otype;
+  detail::ShapeInfo::GeometryShape otype;
   std::vector<Kernel::V3D> vectors;
   double radius, height;
   boost::shared_ptr<const IObject> obj = group.front()->shape();
@@ -389,9 +389,9 @@ boost::shared_ptr<IObject> ObjCompAssembly::createOutline() {
         "Found ObjComponent without shape");
   }
   obj->GetObjectGeom(otype, vectors, radius, height);
-  if (otype == 1) {
+  if (otype == detail::ShapeInfo::GeometryShape::CUBOID) {
     type = "box";
-  } else if (otype == 4) {
+  } else if (otype == detail::ShapeInfo::GeometryShape::CYLINDER) {
     type = "cylinder";
   } else {
     throw std::runtime_error(
@@ -583,7 +583,7 @@ boost::shared_ptr<IObject> ObjCompAssembly::createOutline() {
       // inverse the vz axis
       vz = vz * (-1);
     }
-    obj_str << "<segmented-cylinder id=\"stick\">";
+    obj_str << "<cylinder id=\"stick\">";
     obj_str << "<centre-of-bottom-base ";
     obj_str << "x=\"" << Cmass.X();
     obj_str << "\" y=\"" << Cmass.Y();
@@ -593,7 +593,7 @@ boost::shared_ptr<IObject> ObjCompAssembly::createOutline() {
             << vz.Z() << "\" /> ";
     obj_str << "<radius val=\"" << radius << "\" />";
     obj_str << "<height val=\"" << hz << "\" />";
-    obj_str << "</segmented-cylinder>";
+    obj_str << "</cylinder>";
   }
 
   if (!obj_str.str().empty()) {
diff --git a/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Framework/Geometry/src/Instrument/ObjComponent.cpp
index f648681ec0870676d4ff272868717e86762615e8..5dcd1e54cf1ade6a8072cc65c8daedcae2fe276e 100644
--- a/Framework/Geometry/src/Instrument/ObjComponent.cpp
+++ b/Framework/Geometry/src/Instrument/ObjComponent.cpp
@@ -1,12 +1,13 @@
 #include "MantidGeometry/Instrument/ObjComponent.h"
-#include "MantidGeometry/Instrument/ComponentVisitor.h"
 #include "MantidGeometry/Instrument/ComponentInfo.h"
-#include "MantidGeometry/Objects/IObject.h"
+#include "MantidGeometry/Instrument/ComponentVisitor.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
+#include "MantidGeometry/Objects/CSGObject.h"
+#include "MantidGeometry/Objects/IObject.h"
 #include "MantidGeometry/Objects/Track.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
 #include <cfloat>
 
 namespace Mantid {
@@ -313,7 +314,7 @@ void ObjComponent::draw() const {
   if (Handle() == nullptr)
     return;
   // Render the ObjComponent and then render the object
-  Handle()->Render();
+  Handle()->render();
 }
 
 /**
@@ -334,7 +335,7 @@ void ObjComponent::initDraw() const {
   // Render the ObjComponent and then render the object
   if (shape() != nullptr)
     shape()->initDraw();
-  Handle()->Initialize();
+  Handle()->initialize();
 }
 
 /**
@@ -342,8 +343,10 @@ void ObjComponent::initDraw() const {
  */
 size_t
 ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const {
-
-  return componentVisitor.registerGenericObjComponent(*this);
+  if (this->shape() != nullptr && this->shape()->isFiniteGeometry())
+    return componentVisitor.registerGenericObjComponent(*this);
+  else
+    return componentVisitor.registerInfiniteObjComponent(*this);
 }
 
 } // namespace Geometry
diff --git a/Framework/Geometry/src/Instrument/RectangularDetector.cpp b/Framework/Geometry/src/Instrument/RectangularDetector.cpp
index 29744ae693e6a62718a193817c225a3a0d248449..95793784ae30a41dea15a699f0fdbfeb99ecd77a 100644
--- a/Framework/Geometry/src/Instrument/RectangularDetector.cpp
+++ b/Framework/Geometry/src/Instrument/RectangularDetector.cpp
@@ -5,15 +5,17 @@
 #include "MantidKernel/Matrix.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Objects/IObject.h"
+#include "MantidGeometry/Objects/CSGObject.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Rendering/BitmapGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
 #include <algorithm>
 #include <ostream>
 #include <stdexcept>
 #include <boost/regex.hpp>
+#include <boost/make_shared.hpp>
 #include "MantidGeometry/Instrument/RectangularDetectorPixel.h"
 
 namespace {
@@ -45,7 +47,7 @@ RectangularDetector::RectangularDetector()
       m_minDetId(0), m_maxDetId(0) {
 
   init();
-  setGeometryHandler(new BitmapGeometryHandler(this));
+  setGeometryHandler(new GeometryHandler(this));
 }
 
 /** Constructor for a parametrized RectangularDetector
@@ -57,7 +59,7 @@ RectangularDetector::RectangularDetector(const RectangularDetector *base,
     : CompAssembly(base, map), IObjComponent(nullptr), m_rectBase(base),
       m_minDetId(0), m_maxDetId(0) {
   init();
-  setGeometryHandler(new BitmapGeometryHandler(this));
+  setGeometryHandler(new GeometryHandler(this));
 }
 
 /** Valued constructor
@@ -75,7 +77,7 @@ RectangularDetector::RectangularDetector(const std::string &n,
       m_minDetId(0), m_maxDetId(0) {
   init();
   this->setName(n);
-  setGeometryHandler(new BitmapGeometryHandler(this));
+  setGeometryHandler(new GeometryHandler(this));
 }
 
 bool RectangularDetector::compareName(const std::string &proposedMatch) {
@@ -673,7 +675,7 @@ void RectangularDetector::draw() const {
   if (Handle() == nullptr)
     return;
   // Render the ObjComponent and then render the object
-  Handle()->Render();
+  Handle()->render();
 }
 
 /**
@@ -696,7 +698,7 @@ void RectangularDetector::initDraw() const {
     return;
   // Render the ObjComponent and then render the object
   // if(shape!=NULL)    shape->initDraw();
-  Handle()->Initialize();
+  Handle()->initialize();
 }
 
 //-------------------------------------------------------------------------------------------------
@@ -732,7 +734,7 @@ const Kernel::Material RectangularDetector::material() const {
 
 size_t RectangularDetector::registerContents(
     ComponentVisitor &componentVisitor) const {
-  return componentVisitor.registerStructuredBank(*this);
+  return componentVisitor.registerRectangularBank(*this);
 }
 
 //-------------------------------------------------------------------------------------------------
diff --git a/Framework/Geometry/src/Instrument/ReferenceFrame.cpp b/Framework/Geometry/src/Instrument/ReferenceFrame.cpp
index a9c128f1280601372253ffe9e4decc9e832c639f..520aafe8cd568d4dcf3573a82f8472a5f67cb6f7 100644
--- a/Framework/Geometry/src/Instrument/ReferenceFrame.cpp
+++ b/Framework/Geometry/src/Instrument/ReferenceFrame.cpp
@@ -6,65 +6,15 @@ using namespace Mantid::Kernel;
 namespace Mantid {
 namespace Geometry {
 
-//----------------------------------------------------------------------------------------------
-/** Constructor
-@param up : pointing up axis
-@param alongBeam : axis pointing along the beam
-@param handedness : Handedness
-@param origin : origin
-*/
-ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam,
-                               Handedness handedness, std::string origin)
-    : m_up(up), m_alongBeam(alongBeam), m_thetaSign(up),
-      m_handedness(handedness), m_origin(origin) {
-  if (up == alongBeam) {
-    throw std::invalid_argument(
-        "Cannot have up direction the same as the beam direction");
-  }
-  init();
-}
-
-//----------------------------------------------------------------------------------------------
-/** Constructor
-@param up : pointing up axis
-@param alongBeam : axis pointing along the beam
-@param thetaSign : axis defining the sign of 2theta
-@param handedness : Handedness
-@param origin : origin
-*/
-ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam,
-                               PointingAlong thetaSign, Handedness handedness,
-                               std::string origin)
-    : m_up(up), m_alongBeam(alongBeam), m_thetaSign(thetaSign),
-      m_handedness(handedness), m_origin(origin) {
-  if (up == alongBeam) {
-    throw std::invalid_argument(
-        "Cannot have up direction the same as the beam direction");
-  }
-  if (thetaSign == alongBeam) {
-    throw std::invalid_argument(
-        "Scattering angle sign axis cannot be the same as the beam direction");
-  }
-  init();
-}
-
-//----------------------------------------------------------------------------------------------
-/** Constructor
-Default constructor
-*/
-ReferenceFrame::ReferenceFrame()
-    : m_up(Y), m_alongBeam(Z), m_handedness(Right), m_origin("source") {
-  init();
-}
-
+namespace {
 /**
-Non-member helper method to convert x y z enumeration directions into proper
-3D vectors.
-@param direction : direction marker
-@return 3D vector
+ * Non-member helper method to convert x y z enumeration directions into proper
+ * 3D vectors.
+ * @param direction : direction marker
+ * @return 3D vector
 */
 V3D directionToVector(const PointingAlong &direction) {
-  Mantid::Kernel::V3D result;
+  V3D result;
   if (direction == X) {
     result = V3D(1, 0, 0);
   } else if (direction == Y) {
@@ -91,9 +41,44 @@ std::string directionToString(const PointingAlong &direction) {
   }
   return result;
 }
+}
+
+/**
+ * Default constructor. up=Y, beam=Z, thetaSign=Y
+ */
+ReferenceFrame::ReferenceFrame() : ReferenceFrame(Y, Z, Y, Right, "source") {}
 
-/// Perform common initalisation steps.
-void ReferenceFrame::init() {
+/** Constructor specifying thetaSign=up
+ * @param up :pointing up axis
+ * @param alongBeam : axis pointing along the beam
+ * @param handedness : Handedness
+ * @param origin : origin
+*/
+ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam,
+                               Handedness handedness, std::string origin)
+    : ReferenceFrame(up, alongBeam, up, handedness, std::move(origin)) {}
+
+/**
+ * Constructor specifying all attributes
+ * @param up : pointing up axis
+ * @param alongBeam : axis pointing along the beam
+ * @param thetaSign : axis defining the sign of 2theta
+ * @param handedness : Handedness
+ * @param origin : origin
+*/
+ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam,
+                               PointingAlong thetaSign, Handedness handedness,
+                               std::string origin)
+    : m_up(up), m_alongBeam(alongBeam), m_thetaSign(thetaSign),
+      m_handedness(handedness), m_origin(std::move(origin)) {
+  if (up == alongBeam) {
+    throw std::invalid_argument(
+        "Cannot have up direction the same as the beam direction");
+  }
+  if (thetaSign == alongBeam) {
+    throw std::invalid_argument(
+        "Scattering angle sign axis cannot be the same as the beam direction");
+  }
   m_vecPointingUp = directionToVector(m_up);
   m_vecPointingAlongBeam = directionToVector(m_alongBeam);
   m_vecThetaSign = directionToVector(m_thetaSign);
diff --git a/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp b/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp
index 36daa0b05ce2cf880542e1dfa96c87b95767daa3..441989fcdca500592b95aacb09da75e7baec7c9a 100644
--- a/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp
+++ b/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp
@@ -50,7 +50,7 @@ namespace Geometry {
 SampleEnvironmentSpec_uptr
 SampleEnvironmentSpecParser::parse(const std::string &name,
                                    std::istream &istr) {
-  typedef AutoPtr<Document> DocumentPtr;
+  using DocumentPtr = AutoPtr<Document>;
 
   InputSource src(istr);
   DOMParser parser;
diff --git a/Framework/Geometry/src/Instrument/StructuredDetector.cpp b/Framework/Geometry/src/Instrument/StructuredDetector.cpp
index ecf96fc36e343086ef31a3f56d01ada46ea13800..40ba6ba2edc487ecfa1cc7e153e17d51035404ac 100644
--- a/Framework/Geometry/src/Instrument/StructuredDetector.cpp
+++ b/Framework/Geometry/src/Instrument/StructuredDetector.cpp
@@ -5,8 +5,7 @@
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Objects/CSGObject.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
-#include "MantidGeometry/Rendering/GluGeometryHandler.h"
-#include "MantidGeometry/Rendering/StructuredGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
 #include "MantidKernel/Matrix.h"
@@ -71,7 +70,7 @@ void StructuredDetector::init() {
   m_idStepByRow = 0;
   m_idStep = 0;
 
-  setGeometryHandler(new StructuredGeometryHandler(this));
+  setGeometryHandler(new GeometryHandler(this));
 }
 
 /** Clone method
@@ -290,8 +289,8 @@ std::vector<double> const &StructuredDetector::getYValues() const {
 *
 */
 void StructuredDetector::initialize(size_t xPixels, size_t yPixels,
-                                    const std::vector<double> &x,
-                                    const std::vector<double> &y, bool isZBeam,
+                                    std::vector<double> &&x,
+                                    std::vector<double> &&y, bool isZBeam,
                                     detid_t idStart, bool idFillByFirstY,
                                     int idStepByRow, int idStep) {
   if (m_map)
@@ -329,8 +328,8 @@ void StructuredDetector::initialize(size_t xPixels, size_t yPixels,
                                 "z-axis aligned beams.");
 
   // Store vertices
-  m_xvalues = x;
-  m_yvalues = y;
+  m_xvalues = std::move(x);
+  m_yvalues = std::move(y);
 
   createDetectors();
 }
@@ -552,7 +551,7 @@ void StructuredDetector::draw() const {
   if (Handle() == nullptr)
     return;
   // Render the ObjComponent and then render the object
-  Handle()->Render();
+  Handle()->render();
 }
 
 /**
@@ -568,7 +567,7 @@ void StructuredDetector::initDraw() const {
   if (Handle() == nullptr)
     return;
 
-  Handle()->Initialize();
+  Handle()->initialize();
 }
 
 /// Returns the shape of the Object
diff --git a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp
index 317b8056141ed8069d1fe0b67c9d93d055672e07..82278e59f50d1cd2d556862aaffc4117df76b434 100644
--- a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp
+++ b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp
@@ -117,8 +117,8 @@ double XMLInstrumentParameter::createParamValue(
   if (!m_logfileID.empty()) {
     // get value from time series
 
-    typedef std::map<std::string, Kernel::Math::StatisticType>
-        StatisticsMapType;
+    using StatisticsMapType =
+        std::map<std::string, Kernel::Math::StatisticType>;
     StatisticsMapType statistics_types;
     statistics_types.emplace("first_value", Kernel::Math::FirstValue);
     statistics_types.emplace("last_value", Kernel::Math::LastValue);
diff --git a/Framework/Geometry/src/Math/BnId.cpp b/Framework/Geometry/src/Math/BnId.cpp
index 84088af001457c25bc1c922dd3fadc196f625473..5c5ae0742ea7a5214d53876fb063c0cee9b0ebc0 100644
--- a/Framework/Geometry/src/Math/BnId.cpp
+++ b/Framework/Geometry/src/Math/BnId.cpp
@@ -110,8 +110,6 @@ int BnId::operator<(const BnId &A) const
 {
   if (A.size != size)
     return size < A.size;
-  std::pair<int, int> cntA(0, 0); // count for A
-  std::pair<int, int> cntT(0, 0); // count for this
   if (Znum != A.Znum)
     return (Znum < A.Znum) ? 1 : 0;
 
@@ -281,9 +279,7 @@ std::pair<int, BnId> BnId::makeCombination(const BnId &A) const
   if (Tnum == A.Tnum)
     return std::pair<int, BnId>(0, BnId());
 
-  int flag(0);                    // numb of diff
-  std::pair<int, int> Tcnt(0, 0); // this counter
-  std::pair<int, int> Acnt(0, 0); // A counter
+  int flag(0); // numb of diff
   auto avc = A.Tval.cbegin();
   std::vector<int>::const_iterator chpt; // change point
   for (auto tvc = Tval.cbegin(); tvc != Tval.cend(); ++tvc, ++avc) {
diff --git a/Framework/Geometry/src/Math/mathSupport.cpp b/Framework/Geometry/src/Math/mathSupport.cpp
index e662bf7f4463135eaef909dfee88ee8867934b33..69ad25b1df9e36983769864dc5cc5b8a7bb62d14 100644
--- a/Framework/Geometry/src/Math/mathSupport.cpp
+++ b/Framework/Geometry/src/Math/mathSupport.cpp
@@ -65,7 +65,7 @@ int solveCubic(const CInputIter Coef, std::complex<double> &AnsA,
 */
 
 {
-  typedef std::complex<double> Cpair;
+  using Cpair = std::complex<double>;
   double q, r; /* solution parameters */
   double termR, discrim;
   double r13;
diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp
index 0d512c6a9402b8b6f6f25646b2df2e71b04aeaee..5d0580b7efe2e57d869265d6196d712483bdb3c2 100644
--- a/Framework/Geometry/src/Objects/CSGObject.cpp
+++ b/Framework/Geometry/src/Objects/CSGObject.cpp
@@ -2,9 +2,8 @@
 
 #include "MantidGeometry/Objects/Rules.h"
 #include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Rendering/CacheGeometryHandler.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Rendering/GluGeometryHandler.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h"
 #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h"
 #include "MantidGeometry/Surfaces/Cone.h"
@@ -27,14 +26,12 @@
 #include <boost/accumulators/statistics/error_of_mean.hpp>
 #include <boost/accumulators/statistics/stats.hpp>
 #include <boost/make_shared.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/ranlux.hpp>
-#include <boost/random/uniform_01.hpp>
 
 #include <array>
 #include <deque>
 #include <iostream>
 #include <stack>
+#include <random>
 
 namespace Mantid {
 namespace Geometry {
@@ -60,7 +57,7 @@ CSGObject::CSGObject(const std::string &shapeXML)
       vtkCacheWriter(boost::shared_ptr<vtkGeometryCacheWriter>()),
       m_shapeXML(shapeXML), m_id(), m_material() // empty by default
 {
-  m_handler = boost::make_shared<CacheGeometryHandler>(this);
+  m_handler = boost::make_shared<GeometryHandler>(this);
 }
 
 /**
@@ -810,7 +807,7 @@ int CSGObject::calcValidType(const Kernel::V3D &point,
 * shape.
 */
 double CSGObject::solidAngle(const Kernel::V3D &observer) const {
-  if (this->NumberOfTriangles() > 30000)
+  if (this->numberOfTriangles() > 30000)
     return rayTraceSolidAngle(observer);
   return triangleSolidAngle(observer);
 }
@@ -1008,28 +1005,25 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const {
 
   // If the object is a simple shape use the special methods
   double height(0.0), radius(0.0);
-  int type(0);
+  detail::ShapeInfo::GeometryShape type;
   std::vector<Mantid::Kernel::V3D> geometry_vectors;
   // Maximum of 4 vectors depending on the type
   geometry_vectors.reserve(4);
   this->GetObjectGeom(type, geometry_vectors, radius, height);
-  int nTri = this->NumberOfTriangles();
+  auto nTri = this->numberOfTriangles();
   // Cylinders are by far the most frequently used
-  GluGeometryHandler::GeometryType gluType =
-      static_cast<GluGeometryHandler::GeometryType>(type);
-
-  switch (gluType) {
-  case GluGeometryHandler::GeometryType::CUBOID:
+  switch (type) {
+  case detail::ShapeInfo::GeometryShape::CUBOID:
     return CuboidSolidAngle(observer, geometry_vectors);
     break;
-  case GluGeometryHandler::GeometryType::SPHERE:
+  case detail::ShapeInfo::GeometryShape::SPHERE:
     return SphereSolidAngle(observer, geometry_vectors, radius);
     break;
-  case GluGeometryHandler::GeometryType::CYLINDER:
+  case detail::ShapeInfo::GeometryShape::CYLINDER:
     return CylinderSolidAngle(observer, geometry_vectors[0],
                               geometry_vectors[1], radius, height);
     break;
-  case GluGeometryHandler::GeometryType::CONE:
+  case detail::ShapeInfo::GeometryShape::CONE:
     return ConeSolidAngle(observer, geometry_vectors[0], geometry_vectors[1],
                           radius, height);
     break;
@@ -1038,10 +1032,10 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const {
     {
       return rayTraceSolidAngle(observer);
     } else { // Compute a generic shape that has been triangulated
-      double *vertices = this->getTriangleVertices();
-      int *faces = this->getTriangleFaces();
+      const auto &vertices = this->getTriangleVertices();
+      const auto &faces = this->getTriangleFaces();
       double sangle(0.0), sneg(0.0);
-      for (int i = 0; i < nTri; i++) {
+      for (size_t i = 0; i < nTri; i++) {
         int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2];
         V3D vp1 =
             V3D(vertices[3 * p1], vertices[3 * p1 + 1], vertices[3 * p1 + 2]);
@@ -1090,7 +1084,7 @@ double CSGObject::triangleSolidAngle(const V3D &observer,
     }
   }
 
-  int nTri = this->NumberOfTriangles();
+  auto nTri = this->numberOfTriangles();
   //
   // If triangulation is not available fall back to ray tracing method, unless
   // object is a standard shape, currently Cuboid or Sphere. Should add Cylinder
@@ -1098,19 +1092,16 @@ double CSGObject::triangleSolidAngle(const V3D &observer,
   //
   if (nTri == 0) {
     double height = 0.0, radius(0.0);
-    int type;
+    detail::ShapeInfo::GeometryShape type;
     std::vector<Kernel::V3D> vectors;
     this->GetObjectGeom(type, vectors, radius, height);
-    GluGeometryHandler::GeometryType gluType =
-        static_cast<GluGeometryHandler::GeometryType>(type);
-
-    switch (gluType) {
-    case GluGeometryHandler::GeometryType::CUBOID:
+    switch (type) {
+    case detail::ShapeInfo::GeometryShape::CUBOID:
       for (auto &vector : vectors)
         vector *= scaleFactor;
       return CuboidSolidAngle(observer, vectors);
       break;
-    case GluGeometryHandler::GeometryType::SPHERE:
+    case detail::ShapeInfo::GeometryShape::SPHERE:
       return SphereSolidAngle(observer, vectors, radius);
       break;
     default:
@@ -1122,10 +1113,10 @@ double CSGObject::triangleSolidAngle(const V3D &observer,
     //
     return rayTraceSolidAngle(observer); // so is this
   }
-  double *vertices = this->getTriangleVertices();
-  int *faces = this->getTriangleFaces();
+  const auto &vertices = this->getTriangleVertices();
+  const auto &faces = this->getTriangleFaces();
   double sangle(0.0), sneg(0.0);
-  for (int i = 0; i < nTri; i++) {
+  for (size_t i = 0; i < nTri; i++) {
     int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2];
     // would be more efficient to pre-multiply the vertices (copy of) by these
     // factors beforehand
@@ -1491,15 +1482,13 @@ double CSGObject::ConeSolidAngle(const V3D &observer,
  * @return The volume.
  */
 double CSGObject::volume() const {
-  int type;
+  detail::ShapeInfo::GeometryShape type;
   double height;
   double radius;
   std::vector<Kernel::V3D> vectors;
   this->GetObjectGeom(type, vectors, radius, height);
-  GluGeometryHandler::GeometryType gluType =
-      static_cast<GluGeometryHandler::GeometryType>(type);
-  switch (gluType) {
-  case GluGeometryHandler::GeometryType::CUBOID: {
+  switch (type) {
+  case detail::ShapeInfo::GeometryShape::CUBOID: {
     // Here, the volume is calculated by the triangular method.
     // We use one of the vertices (vectors[0]) as the reference
     // point.
@@ -1529,9 +1518,9 @@ double CSGObject::volume() const {
     volume += brt.scalar_prod(brb.cross_prod(blb));
     return volume / 6;
   }
-  case GluGeometryHandler::GeometryType::SPHERE:
+  case detail::ShapeInfo::GeometryShape::SPHERE:
     return 4.0 / 3.0 * M_PI * radius * radius * radius;
-  case GluGeometryHandler::GeometryType::CYLINDER:
+  case detail::ShapeInfo::GeometryShape::CYLINDER:
     return M_PI * radius * radius * height;
   default:
     // Fall back to Monte Carlo method.
@@ -1551,7 +1540,7 @@ double CSGObject::monteCarloVolume() const {
   accumulator_set<double, features<tag::mean, tag::error_of<tag::mean>>>
       accumulate;
   // For seeding the single shot runs.
-  boost::random::ranlux48 rnEngine;
+  std::ranlux48 rnEngine;
   // Warm up statistics.
   for (int i = 0; i < 10; ++i) {
     const auto seed = rnEngine();
@@ -1601,15 +1590,14 @@ double CSGObject::singleShotMonteCarloVolume(const int shotSize,
       // the worst case.
       blocksize = shotSize - (threadCount - 1) * blocksize;
     }
-    boost::random::mt19937 rnEngine(
-        static_cast<boost::random::mt19937::result_type>(seed));
+    std::mt19937 rnEngine(static_cast<std::mt19937::result_type>(seed));
     // All threads init their engine with the same seed.
     // We discard the random numbers used by the other threads.
     // This ensures reproducible results independent of the number
     // of threads.
     // We need three random numbers for each iteration.
     rnEngine.discard(currentThreadNum * 3 * blocksize);
-    boost::random::uniform_01<double> rnDistribution;
+    std::uniform_real_distribution<double> rnDistribution(0.0, 1.0);
     int hits = 0;
     for (int i = 0; i < static_cast<int>(blocksize); ++i) {
       double rnd = rnDistribution(rnEngine);
@@ -1717,10 +1705,10 @@ void CSGObject::calcBoundingBoxByRule() {
  */
 void CSGObject::calcBoundingBoxByVertices() {
   // Grab vertex information
-  auto vertCount = this->NumberOfPoints();
-  auto vertArray = this->getTriangleVertices();
+  auto vertCount = this->numberOfVertices();
 
-  if (vertCount && vertArray) {
+  if (vertCount > 0) {
+    const auto &vertArray = this->getTriangleVertices();
     // Unreasonable extents to be overwritten by loop
     constexpr double huge = 1e10;
     double minX, maxX, minY, maxY, minZ, maxZ;
@@ -1728,7 +1716,7 @@ void CSGObject::calcBoundingBoxByVertices() {
     maxX = maxY = maxZ = -huge;
 
     // Loop over all vertices and determine minima and maxima on each axis
-    for (int i = 0; i < vertCount; ++i) {
+    for (size_t i = 0; i < vertCount; ++i) {
       auto vx = vertArray[3 * i + 0];
       auto vy = vertArray[3 * i + 1];
       auto vz = vertArray[3 * i + 2];
@@ -1761,19 +1749,16 @@ void CSGObject::calcBoundingBoxByGeometry() {
   double minX, maxX, minY, maxY, minZ, maxZ;
 
   // Shape geometry data
-  int type(0);
+  detail::ShapeInfo::GeometryShape type;
   std::vector<Kernel::V3D> vectors;
   double radius;
   double height;
 
-  // Will only work for shapes handled by GluGeometryHandler
+  // Will only work for shapes with ShapeInfo
   m_handler->GetObjectGeom(type, vectors, radius, height);
-  GluGeometryHandler::GeometryType gluType =
-      static_cast<GluGeometryHandler::GeometryType>(type);
-
   // Type of shape is given as a simple integer
-  switch (gluType) {
-  case GluGeometryHandler::GeometryType::CUBOID: {
+  switch (type) {
+  case detail::ShapeInfo::GeometryShape::CUBOID: {
     // Points as defined in IDF XML
     auto &lfb = vectors[0]; // Left-Front-Bottom
     auto &lft = vectors[1]; // Left-Front-Top
@@ -1806,7 +1791,7 @@ void CSGObject::calcBoundingBoxByGeometry() {
       maxZ = std::max(maxZ, vector.Z());
     }
   } break;
-  case GluGeometryHandler::GeometryType::HEXAHEDRON: {
+  case detail::ShapeInfo::GeometryShape::HEXAHEDRON: {
     // These will be replaced by more realistic values in the loop below
     minX = minY = minZ = std::numeric_limits<decltype(minZ)>::max();
     maxX = maxY = maxZ = -std::numeric_limits<decltype(maxZ)>::max();
@@ -1821,8 +1806,7 @@ void CSGObject::calcBoundingBoxByGeometry() {
       maxZ = std::max(maxZ, vector.Z());
     }
   } break;
-  case GluGeometryHandler::GeometryType::CYLINDER:
-  case GluGeometryHandler::GeometryType::SEGMENTED_CYLINDER: {
+  case detail::ShapeInfo::GeometryShape::CYLINDER: {
     // Center-point of base and normalized axis based on IDF XML
     auto &base = vectors[0];
     auto &axis = vectors[1];
@@ -1845,7 +1829,7 @@ void CSGObject::calcBoundingBoxByGeometry() {
     maxZ = std::max(base.Z(), top.Z()) + rz;
   } break;
 
-  case GluGeometryHandler::GeometryType::CONE: {
+  case detail::ShapeInfo::GeometryShape::CONE: {
     auto &tip = vectors[0];            // Tip-point of cone
     auto &axis = vectors[1];           // Normalized axis
     auto base = tip + (axis * height); // Center of base
@@ -2072,7 +2056,7 @@ void CSGObject::draw() const {
   if (m_handler == nullptr)
     return;
   // Render the Object
-  m_handler->Render();
+  m_handler->render();
 }
 
 /**
@@ -2084,7 +2068,7 @@ void CSGObject::initDraw() const {
   if (m_handler == nullptr)
     return;
   // Render the Object
-  m_handler->Initialize();
+  m_handler->initialize();
 }
 /**
 * set vtkGeometryCache writer
@@ -2105,8 +2089,8 @@ void CSGObject::setVtkGeometryCacheReader(
 }
 
 /**
-* Returns the geometry handler
-*/
+ * Returns the geometry handler
+ */
 boost::shared_ptr<GeometryHandler> CSGObject::getGeometryHandler() const {
   // Check if the geometry handler is upto dated with the cache, if not then
   // cache it now.
@@ -2137,49 +2121,43 @@ void CSGObject::updateGeometryHandler() {
 
 // Initialize Draw Object
 
-/**
-* get number of triangles
-* @return the number of triangles
-*/
-int CSGObject::NumberOfTriangles() const {
+size_t CSGObject::numberOfTriangles() const {
   if (m_handler == nullptr)
     return 0;
-  return m_handler->NumberOfTriangles();
+  return m_handler->numberOfTriangles();
 }
-
-/**
-* get number of points
-*/
-int CSGObject::NumberOfPoints() const {
+size_t CSGObject::numberOfVertices() const {
   if (m_handler == nullptr)
     return 0;
-  return m_handler->NumberOfPoints();
+  return m_handler->numberOfPoints();
 }
-
 /**
 * get vertices
 */
-double *CSGObject::getTriangleVertices() const {
+const std::vector<double> &CSGObject::getTriangleVertices() const {
+  static const std::vector<double> empty;
   if (m_handler == nullptr)
-    return nullptr;
+    return empty;
   return m_handler->getTriangleVertices();
 }
 
 /**
-* get faces
-*/
-int *CSGObject::getTriangleFaces() const {
+ * get faces
+ */
+const std::vector<uint32_t> &CSGObject::getTriangleFaces() const {
+  static const std::vector<uint32_t> empty;
   if (m_handler == nullptr)
-    return nullptr;
+    return empty;
   return m_handler->getTriangleFaces();
 }
 
 /**
 * get info on standard shapes
 */
-void CSGObject::GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
+void CSGObject::GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                              std::vector<Kernel::V3D> &vectors,
                               double &myradius, double &myheight) const {
-  type = 0;
+  type = detail::ShapeInfo::GeometryShape::NOSHAPE;
   if (m_handler == nullptr)
     return;
   m_handler->GetObjectGeom(type, vectors, myradius, myheight);
diff --git a/Framework/Geometry/src/Objects/MeshObject.cpp b/Framework/Geometry/src/Objects/MeshObject.cpp
index fa4981b8796175f70e6d1a73af30c18431212a2e..5ac26e51f9a63c0030dccb25d4065d904534f505 100644
--- a/Framework/Geometry/src/Objects/MeshObject.cpp
+++ b/Framework/Geometry/src/Objects/MeshObject.cpp
@@ -1,7 +1,5 @@
 #include "MantidGeometry/Objects/MeshObject.h"
-
 #include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Rendering/CacheGeometryHandler.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h"
 #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h"
@@ -45,7 +43,7 @@ void MeshObject::initialize() {
         "Too many vertices (" + std::to_string(m_vertices.size()) +
         "). MeshObject cannot have more than 65535 vertices.");
   }
-  m_handler = boost::make_shared<CacheGeometryHandler>(this);
+  m_handler = boost::make_shared<GeometryHandler>(this);
 }
 
 /**
@@ -567,7 +565,7 @@ void MeshObject::draw() const {
   if (m_handler == nullptr)
     return;
   // Render the Object
-  m_handler->Render();
+  m_handler->render();
 }
 
 /**
@@ -579,7 +577,7 @@ void MeshObject::initDraw() const {
   if (m_handler == nullptr)
     return;
   // Render the Object
-  m_handler->Initialize();
+  m_handler->initialize();
 }
 
 /**
@@ -601,18 +599,16 @@ void MeshObject::updateGeometryHandler() {
 /**
 * Output functions for rendering, may also be used internally
 */
-int MeshObject::numberOfTriangles() const {
-  return static_cast<int>(m_triangles.size() / 3);
-}
+size_t MeshObject::numberOfTriangles() const { return m_triangles.size() / 3; }
 
 /**
 * get faces
 */
-int *MeshObject::getTriangles() const {
-  int *faces = nullptr;
+std::vector<uint32_t> MeshObject::getTriangles() const {
+  std::vector<uint32_t> faces;
   size_t nFaceCorners = m_triangles.size();
   if (nFaceCorners > 0) {
-    faces = new int[static_cast<std::size_t>(nFaceCorners)];
+    faces.resize(static_cast<std::size_t>(nFaceCorners));
     for (size_t i = 0; i < nFaceCorners; ++i) {
       faces[i] = static_cast<int>(m_triangles[i]);
     }
@@ -623,18 +619,18 @@ int *MeshObject::getTriangles() const {
 /**
 * get number of points
 */
-int MeshObject::numberOfVertices() const {
+size_t MeshObject::numberOfVertices() const {
   return static_cast<int>(m_vertices.size());
 }
 
 /**
 * get vertices
 */
-double *MeshObject::getVertices() const {
-  double *points = nullptr;
+std::vector<double> MeshObject::getVertices() const {
+  std::vector<double> points;
   size_t nPoints = m_vertices.size();
   if (nPoints > 0) {
-    points = new double[static_cast<std::size_t>(nPoints) * 3];
+    points.resize(static_cast<std::size_t>(nPoints) * 3);
     for (size_t i = 0; i < nPoints; ++i) {
       V3D pnt = m_vertices[i];
       points[i * 3 + 0] = pnt.X();
@@ -648,12 +644,13 @@ double *MeshObject::getVertices() const {
 /**
 * get info on standard shapes (none for Mesh Object)
 */
-void MeshObject::GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
+void MeshObject::GetObjectGeom(detail::ShapeInfo::GeometryShape &type,
+                               std::vector<Kernel::V3D> &vectors,
                                double &myradius, double &myheight) const {
   // In practice, this outputs type = -1,
   // to indicate not a "standard" object (cuboid/cone/cyl/sphere).
   // Retained for possible future use.
-  type = 0;
+  type = detail::ShapeInfo::GeometryShape::NOSHAPE;
   if (m_handler == nullptr)
     return;
   m_handler->GetObjectGeom(type, vectors, myradius, myheight);
diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp
index 75a8b08636b225d8eb6ce61613a9472713617760..825101d50a73be299e15d451781fabc6d247b2e7 100644
--- a/Framework/Geometry/src/Objects/ShapeFactory.cpp
+++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp
@@ -5,7 +5,8 @@
 #include "MantidGeometry/Instrument/Container.h"
 #include "MantidGeometry/Objects/CSGObject.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
-#include "MantidGeometry/Rendering/GluGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "MantidGeometry/Surfaces/Cone.h"
 #include "MantidGeometry/Surfaces/Cylinder.h"
 #include "MantidGeometry/Surfaces/Plane.h"
@@ -151,20 +152,17 @@ ShapeFactory::createShape(Poco::XML::Element *pElem) {
             numPrimitives++;
           } else if (primitiveName == "infinite-plane") {
             idMatching[idFromUser] = parseInfinitePlane(pE, primitives, l_id);
+            retVal->setFiniteGeometryFlag(false);
             numPrimitives++;
           } else if (primitiveName == "infinite-cylinder") {
             idMatching[idFromUser] =
                 parseInfiniteCylinder(pE, primitives, l_id);
+            retVal->setFiniteGeometryFlag(false);
             numPrimitives++;
           } else if (primitiveName == "cylinder") {
             lastElement = pE;
             idMatching[idFromUser] = parseCylinder(pE, primitives, l_id);
             numPrimitives++;
-          } else if (primitiveName == "segmented-cylinder") {
-            lastElement = pE;
-            idMatching[idFromUser] =
-                parseSegmentedCylinder(pE, primitives, l_id);
-            numPrimitives++;
           } else if (primitiveName == "hollow-cylinder") {
             idMatching[idFromUser] = parseHollowCylinder(pE, primitives, l_id);
             numPrimitives++;
@@ -174,6 +172,7 @@ ShapeFactory::createShape(Poco::XML::Element *pElem) {
             numPrimitives++;
           } else if (primitiveName == "infinite-cone") {
             idMatching[idFromUser] = parseInfiniteCone(pE, primitives, l_id);
+            retVal->setFiniteGeometryFlag(false);
             numPrimitives++;
           } else if (primitiveName == "cone") {
             lastElement = pE;
@@ -1406,12 +1405,14 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf,
   shape->setObject(21, algebra);
   shape->populate(prim);
 
-  auto handler = boost::make_shared<GluGeometryHandler>(shape);
-
+  auto handler = boost::make_shared<GeometryHandler>(shape);
+  detail::ShapeInfo shapeInfo;
   shape->setGeometryHandler(handler);
 
-  handler->setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft,
-                         hex.rft, hex.rbt);
+  shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft,
+                          hex.rft, hex.rbt);
+
+  handler->setShapeInfo(std::move(shapeInfo));
 
   shape->defineBoundingBox(std::max(xrb, xrf), yrf, ZDEPTH, std::min(xlf, xlb),
                            ylb, 0);
@@ -1423,24 +1424,24 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf,
 void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem,
                                          boost::shared_ptr<CSGObject> Obj) {
 
-  auto geomHandler = boost::make_shared<GluGeometryHandler>(Obj);
+  auto geomHandler = boost::make_shared<GeometryHandler>(Obj);
+  detail::ShapeInfo shapeInfo;
   Obj->setGeometryHandler(geomHandler);
 
   if (pElem->tagName() == "cuboid") {
     auto corners = parseCuboid(pElem);
-    geomHandler->setCuboid(corners.lfb, corners.lft, corners.lbb, corners.rfb);
+    shapeInfo.setCuboid(corners.lfb, corners.lft, corners.lbb, corners.rfb);
   } else if (pElem->tagName() == "hexahedron") {
     auto corners = parseHexahedron(pElem);
-    geomHandler->setHexahedron(corners.lbb, corners.lfb, corners.rfb,
-                               corners.rbb, corners.lbt, corners.lft,
-                               corners.rft, corners.rbt);
+    shapeInfo.setHexahedron(corners.lbb, corners.lfb, corners.rfb, corners.rbb,
+                            corners.lbt, corners.lft, corners.rft, corners.rbt);
   } else if (pElem->tagName() == "sphere") {
     Element *pElemCentre = getOptionalShapeElement(pElem, "centre");
     Element *pElemRadius = getShapeElement(pElem, "radius");
     V3D centre;
     if (pElemCentre)
       centre = parsePosition(pElemCentre);
-    geomHandler->setSphere(centre, std::stod(pElemRadius->getAttribute("val")));
+    shapeInfo.setSphere(centre, std::stod(pElemRadius->getAttribute("val")));
   } else if (pElem->tagName() == "cylinder") {
     Element *pElemCentre = getShapeElement(pElem, "centre-of-bottom-base");
     Element *pElemAxis = getShapeElement(pElem, "axis");
@@ -1448,20 +1449,9 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem,
     Element *pElemHeight = getShapeElement(pElem, "height");
     V3D normVec = parsePosition(pElemAxis);
     normVec.normalize();
-    geomHandler->setCylinder(parsePosition(pElemCentre), normVec,
-                             std::stod(pElemRadius->getAttribute("val")),
-                             std::stod(pElemHeight->getAttribute("val")));
-  } else if (pElem->tagName() == "segmented-cylinder") {
-    Element *pElemCentre = getShapeElement(pElem, "centre-of-bottom-base");
-    Element *pElemAxis = getShapeElement(pElem, "axis");
-    Element *pElemRadius = getShapeElement(pElem, "radius");
-    Element *pElemHeight = getShapeElement(pElem, "height");
-    V3D normVec = parsePosition(pElemAxis);
-    normVec.normalize();
-    geomHandler->setSegmentedCylinder(
-        parsePosition(pElemCentre), normVec,
-        std::stod(pElemRadius->getAttribute("val")),
-        std::stod(pElemHeight->getAttribute("val")));
+    shapeInfo.setCylinder(parsePosition(pElemCentre), normVec,
+                          std::stod(pElemRadius->getAttribute("val")),
+                          std::stod(pElemHeight->getAttribute("val")));
   } else if (pElem->tagName() == "cone") {
     Element *pElemTipPoint = getShapeElement(pElem, "tip-point");
     Element *pElemAxis = getShapeElement(pElem, "axis");
@@ -1473,8 +1463,10 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem,
     double height = std::stod(pElemHeight->getAttribute("val"));
     double radius =
         height * tan(M_PI * std::stod(pElemAngle->getAttribute("val")) / 180.0);
-    geomHandler->setCone(parsePosition(pElemTipPoint), normVec, radius, height);
+    shapeInfo.setCone(parsePosition(pElemTipPoint), normVec, radius, height);
   }
+
+  geomHandler->setShapeInfo(std::move(shapeInfo));
 }
 
 } // namespace Geometry
diff --git a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp
deleted file mode 100644
index abf8021c0a6c17fe48166435b595d23afeb12e0e..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "MantidGeometry/Rendering/BitmapGeometryHandler.h"
-#include "MantidGeometry/Rendering/OpenGL_Headers.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-#include <climits>
-#include <iostream>
-
-#include <boost/make_shared.hpp>
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-
-/**
- * @return A shared_ptr to a new copy of this object
- */
-boost::shared_ptr<GeometryHandler> BitmapGeometryHandler::clone() const {
-  return boost::make_shared<BitmapGeometryHandler>(*this);
-}
-
-/// Parameter constructor
-BitmapGeometryHandler::BitmapGeometryHandler(RectangularDetector *comp)
-    : GeometryHandler(dynamic_cast<IObjComponent *>(comp)) {
-  // Save the rectangular detector link for later.
-  m_rectDet = comp;
-}
-
-BitmapGeometryHandler::BitmapGeometryHandler()
-    : GeometryHandler(static_cast<CSGObject *>(nullptr)), m_rectDet(nullptr) {}
-
-///< Create an instance of concrete geometry handler for ObjComponent
-BitmapGeometryHandler *
-BitmapGeometryHandler::createInstance(IObjComponent *comp) {
-  (void)comp;
-  return new BitmapGeometryHandler();
-}
-
-///< Create an instance of concrete geometry handler for Object
-BitmapGeometryHandler *
-BitmapGeometryHandler::createInstance(boost::shared_ptr<CSGObject> obj) {
-  (void)obj;
-  return new BitmapGeometryHandler();
-}
-
-///< Create an instance of concrete geometry handler for Object
-GeometryHandler *BitmapGeometryHandler::createInstance(CSGObject *obj) {
-  (void)obj;
-  return new BitmapGeometryHandler();
-}
-
-//----------------------------------------------------------------------------------------------
-/** Triangulate the Object - this function will not be used.
- *
- */
-void BitmapGeometryHandler::Triangulate() {
-  // std::cout << "BitmapGeometryHandler::Triangulate() called\n";
-}
-
-//----------------------------------------------------------------------------------------------
-///< Render Object or ObjComponent
-void BitmapGeometryHandler::Render() {
-  // std::cout << "BitmapGeometryHandler::Render() called\n";
-  V3D pos;
-
-  // Wait for no error
-  while (glGetError() != GL_NO_ERROR)
-    ;
-
-  // Because texture colours are combined with the geometry colour
-  // make sure the current colour is white
-  glColor3f(1.0f, 1.0f, 1.0f);
-
-  // Nearest-neighbor scaling
-  GLint texParam = GL_NEAREST;
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam);
-
-  glEnable(GL_TEXTURE_2D); // enable texture mapping
-
-  int texx, texy;
-  m_rectDet->getTextureSize(texx, texy);
-  double tex_frac_x = (1.0 * m_rectDet->xpixels()) / (texx);
-  double tex_frac_y = (1.0 * m_rectDet->ypixels()) / (texy);
-
-  // Point to the ID of the texture that was created before - in
-  // RectangularDetectorActor.
-  // int texture_id = m_rectDet->getTextureID();
-  // glBindTexture (GL_TEXTURE_2D, texture_id);
-  // if (glGetError()>0) std::cout << "OpenGL error in glBindTexture \n";
-
-  glBegin(GL_QUADS);
-
-  glTexCoord2f(0.0, 0.0);
-  pos = m_rectDet->getRelativePosAtXY(0, 0);
-  pos += V3D(m_rectDet->xstep() * (-0.5), m_rectDet->ystep() * (-0.5),
-             0.0); // Adjust to account for the size of a pixel
-  glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-             static_cast<GLfloat>(pos.Z()));
-
-  glTexCoord2f(static_cast<GLfloat>(tex_frac_x), 0.0);
-  pos = m_rectDet->getRelativePosAtXY(m_rectDet->xpixels() - 1, 0);
-  pos += V3D(m_rectDet->xstep() * (+0.5), m_rectDet->ystep() * (-0.5),
-             0.0); // Adjust to account for the size of a pixel
-  glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-             static_cast<GLfloat>(pos.Z()));
-
-  glTexCoord2f(static_cast<GLfloat>(tex_frac_x),
-               static_cast<GLfloat>(tex_frac_y));
-  pos = m_rectDet->getRelativePosAtXY(m_rectDet->xpixels() - 1,
-                                      m_rectDet->ypixels() - 1);
-  pos += V3D(m_rectDet->xstep() * (+0.5), m_rectDet->ystep() * (+0.5),
-             0.0); // Adjust to account for the size of a pixel
-  glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-             static_cast<GLfloat>(pos.Z()));
-
-  glTexCoord2f(0.0, static_cast<GLfloat>(tex_frac_y));
-  pos = m_rectDet->getRelativePosAtXY(0, m_rectDet->ypixels() - 1);
-  pos += V3D(m_rectDet->xstep() * (-0.5), m_rectDet->ystep() * (+0.5),
-             0.0); // Adjust to account for the size of a pixel
-  glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-             static_cast<GLfloat>(pos.Z()));
-
-  glEnd();
-  if (glGetError() > 0)
-    std::cout << "OpenGL error in BitmapGeometryHandler::Render \n";
-
-  glDisable(
-      GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary.
-}
-
-//----------------------------------------------------------------------------------------------
-///< Prepare/Initialize Object/ObjComponent to be rendered
-void BitmapGeometryHandler::Initialize() {
-  // std::cout << "BitmapGeometryHandler::Initialize() called\n";
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp
deleted file mode 100644
index efb52d5bb35b62ed15b7d61849f8eaa93b63ef83..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <vector>
-#include <cmath>
-#include "MantidKernel/Matrix.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Objects/MeshObject.h"
-#include "MantidGeometry/Rendering/CacheGeometryGenerator.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-
-#ifdef ENABLE_OPENCASCADE
-#include "MantidGeometry/Rendering/OCGeometryHandler.h"
-#endif
-
-namespace Mantid {
-
-namespace Geometry {
-/**
- * Constructor
- * @param obj :: input CSG object
- */
-CacheGeometryGenerator::CacheGeometryGenerator(CSGObject *obj) : csgObj(obj) {
-  mNoOfVertices = 0;
-  mNoOfTriangles = 0;
-  mFaces = nullptr;
-  mPoints = nullptr;
-  meshObj = nullptr;
-}
-
-/**
-* Constructor
-* @param obj :: input CSG object
-*/
-CacheGeometryGenerator::CacheGeometryGenerator(MeshObject *obj) : meshObj(obj) {
-  mNoOfVertices = 0;
-  mNoOfTriangles = 0;
-  mFaces = nullptr;
-  mPoints = nullptr;
-  csgObj = nullptr;
-}
-
-/**
- * Generate geometry, if there is no cache then it uses OpenCascade to generate
- * surface triangles.
- */
-void CacheGeometryGenerator::Generate() {
-  if (mNoOfVertices <= 0) {
-    if (csgObj != nullptr) {
-// There are no triangles defined to use OpenCascade handler to get them
-#ifdef ENABLE_OPENCASCADE
-      OCGeometryHandler h(csgObj);
-      mNoOfVertices = h.NumberOfPoints();
-      mNoOfTriangles = h.NumberOfTriangles();
-      mPoints = h.getTriangleVertices();
-      mFaces = h.getTriangleFaces();
-#endif
-    } else if (meshObj != nullptr) {
-      // Get triangles from MeshObject
-      mNoOfVertices = meshObj->numberOfVertices();
-      mNoOfTriangles = meshObj->numberOfTriangles();
-      mPoints = meshObj->getVertices();
-      mFaces = meshObj->getTriangles();
-    }
-  }
-}
-
-/**
- * Destroy the surface generated for the object
- */
-CacheGeometryGenerator::~CacheGeometryGenerator() {
-  if (mFaces != nullptr)
-    delete[] mFaces;
-  if (mPoints != nullptr)
-    delete[] mPoints;
-}
-
-int CacheGeometryGenerator::getNumberOfTriangles() { return mNoOfTriangles; }
-
-int CacheGeometryGenerator::getNumberOfPoints() { return mNoOfVertices; }
-
-double *CacheGeometryGenerator::getTriangleVertices() { return mPoints; }
-
-int *CacheGeometryGenerator::getTriangleFaces() { return mFaces; }
-
-/**
-   Sets the geometry cache using the triangulation information provided
-   @param noPts :: the number of points
-   @param noFaces :: the number of faces
-   @param pts :: a double array of the points
-   @param faces :: an int array of the faces
-*/
-void CacheGeometryGenerator::setGeometryCache(int noPts, int noFaces,
-                                              double *pts, int *faces) {
-  if (mPoints != nullptr)
-    delete[] mPoints;
-  if (mFaces != nullptr)
-    delete[] mFaces;
-  mNoOfVertices = noPts;
-  mNoOfTriangles = noFaces;
-  mPoints = pts;
-  mFaces = faces;
-}
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp
deleted file mode 100644
index 88743826dd878985af79428f3df72132b18e97c7..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Objects/MeshObject.h"
-#include "MantidGeometry/Instrument/ObjComponent.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Rendering/CacheGeometryHandler.h"
-#include "MantidGeometry/Rendering/CacheGeometryRenderer.h"
-#include "MantidGeometry/Rendering/CacheGeometryGenerator.h"
-#include "MantidKernel/MultiThreaded.h"
-
-#include <boost/make_shared.hpp>
-
-namespace Mantid {
-namespace Geometry {
-
-CacheGeometryHandler::CacheGeometryHandler(IObjComponent *comp)
-    : GeometryHandler(comp) {
-  Triangulator = nullptr;
-  Renderer = new CacheGeometryRenderer();
-}
-
-CacheGeometryHandler::CacheGeometryHandler(boost::shared_ptr<CSGObject> obj)
-    : GeometryHandler(obj) {
-  Triangulator = new CacheGeometryGenerator(obj.get());
-  Renderer = new CacheGeometryRenderer();
-}
-
-CacheGeometryHandler::CacheGeometryHandler(CSGObject *obj)
-    : GeometryHandler(obj) {
-  Triangulator = new CacheGeometryGenerator(obj);
-  Renderer = new CacheGeometryRenderer();
-}
-
-CacheGeometryHandler::CacheGeometryHandler(boost::shared_ptr<MeshObject> obj)
-    : GeometryHandler(obj) {
-  Triangulator = new CacheGeometryGenerator(obj.get());
-  Renderer = new CacheGeometryRenderer();
-}
-
-CacheGeometryHandler::CacheGeometryHandler(MeshObject *obj)
-    : GeometryHandler(obj) {
-  Triangulator = new CacheGeometryGenerator(obj);
-  Renderer = new CacheGeometryRenderer();
-}
-
-boost::shared_ptr<GeometryHandler> CacheGeometryHandler::clone() const {
-  auto clone = boost::make_shared<CacheGeometryHandler>(*this);
-  clone->Renderer = new CacheGeometryRenderer(*(this->Renderer));
-  if (this->Triangulator)
-    if (meshObj != nullptr) {
-      clone->Triangulator = new CacheGeometryGenerator(this->meshObj);
-    } else {
-      clone->Triangulator = new CacheGeometryGenerator(this->csgObj);
-    }
-  else
-    clone->Triangulator = nullptr;
-  return clone;
-}
-
-CacheGeometryHandler::~CacheGeometryHandler() {
-  if (Triangulator != nullptr)
-    delete Triangulator;
-  if (Renderer != nullptr)
-    delete Renderer;
-}
-
-GeometryHandler *CacheGeometryHandler::createInstance(IObjComponent *comp) {
-  return new CacheGeometryHandler(comp);
-}
-
-GeometryHandler *
-CacheGeometryHandler::createInstance(boost::shared_ptr<CSGObject> obj) {
-  return new CacheGeometryHandler(obj);
-}
-
-GeometryHandler *CacheGeometryHandler::createInstance(CSGObject *obj) {
-  return new CacheGeometryHandler(obj);
-}
-
-void CacheGeometryHandler::Triangulate() {
-  // Check whether Object is triangulated otherwise triangulate
-  PARALLEL_CRITICAL(Triangulate)
-  if ((csgObj != nullptr || meshObj != nullptr) && !boolTriangulated) {
-    Triangulator->Generate();
-    boolTriangulated = true;
-  }
-}
-
-void CacheGeometryHandler::Render() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    Renderer->Render(
-        Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(),
-        Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces());
-  } else if (ObjComp != nullptr) {
-    Renderer->Render(ObjComp);
-  }
-}
-
-void CacheGeometryHandler::Initialize() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    updateGeometryHandler();
-    if (!boolTriangulated)
-      Triangulate();
-    Renderer->Initialize(
-        Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(),
-        Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces());
-  } else if (ObjComp != nullptr) {
-    Renderer->Initialize(ObjComp);
-  }
-}
-
-int CacheGeometryHandler::NumberOfTriangles() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    updateGeometryHandler();
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getNumberOfTriangles();
-  } else {
-    return 0;
-  }
-}
-
-int CacheGeometryHandler::NumberOfPoints() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    updateGeometryHandler();
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getNumberOfPoints();
-  } else {
-    return 0;
-  }
-}
-
-double *CacheGeometryHandler::getTriangleVertices() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    updateGeometryHandler();
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getTriangleVertices();
-  } else {
-    return nullptr;
-  }
-}
-
-int *CacheGeometryHandler::getTriangleFaces() {
-  if (csgObj != nullptr || meshObj != nullptr) {
-    updateGeometryHandler();
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getTriangleFaces();
-  } else {
-    return nullptr;
-  }
-}
-
-void CacheGeometryHandler::updateGeometryHandler() {
-  if (meshObj != nullptr) {
-    meshObj->updateGeometryHandler();
-  } else {
-    csgObj->updateGeometryHandler();
-  }
-}
-
-/**
-Sets the geometry cache using the triangulation information provided
-@param noPts :: the number of points
-@param noFaces :: the number of faces
-@param pts :: a double array of the points
-@param faces :: an int array of the faces
-*/
-void CacheGeometryHandler::setGeometryCache(int noPts, int noFaces, double *pts,
-                                            int *faces) {
-  Triangulator->setGeometryCache(noPts, noFaces, pts, faces);
-  boolTriangulated = true;
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp
deleted file mode 100644
index a34f7e042fb5242dbdcff5b1172e58de57fdbd79..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "MantidGeometry/Rendering/CacheGeometryRenderer.h"
-#include "MantidGeometry/Rendering/OpenGL_Headers.h"
-#include "MantidGeometry/Instrument/ObjComponent.h"
-#include "MantidKernel/Quat.h"
-#include <climits>
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-using Kernel::Quat;
-
-/**
- * Render ObjComponent
- * @param ObjComp :: input to render
- */
-void CacheGeometryRenderer::Render(IObjComponent *ObjComp) const {
-  glPushMatrix();
-  V3D pos = ObjComp->getPos();
-  Quat rot = ObjComp->getRotation();
-  double rotGL[16];
-  rot.GLMatrix(&rotGL[0]);
-  glTranslated(pos[0], pos[1], pos[2]);
-  glMultMatrixd(rotGL);
-  V3D scaleFactor = ObjComp->getScaleFactor();
-  glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  ObjComp->drawObject();
-  glPopMatrix();
-}
-
-void CacheGeometryRenderer::Render(int noPts, int noFaces, double *points,
-                                   int *faces) const {
-  (void)noPts;
-  (void)noFaces;
-  (void)points;
-  (void)faces; // Avoid compiler warning
-  Initialize(noPts, noFaces, points, faces);
-}
-
-void CacheGeometryRenderer::Initialize(int noPts, int noFaces, double *points,
-                                       int *faces) const {
-  (void)noPts; // Avoid compiler warning
-  glBegin(GL_TRIANGLES);
-  V3D normal;
-  for (int i = 0; i < noFaces; i++) {
-    int index1 = faces[i * 3] * 3;
-    int index2 = faces[i * 3 + 1] * 3;
-    int index3 = faces[i * 3 + 2] * 3;
-    // Calculate normal and normalize
-    V3D v1(points[index1], points[index1 + 1], points[index1 + 2]);
-    V3D v2(points[index2], points[index2 + 1], points[index2 + 2]);
-    V3D v3(points[index3], points[index3 + 1], points[index3 + 2]);
-    normal = (v1 - v2).cross_prod(v2 - v3);
-    normal.normalize();
-    glNormal3d(normal[0], normal[1], normal[2]);
-    glVertex3dv(points + index1);
-    glVertex3dv(points + index2);
-    glVertex3dv(points + index3);
-  }
-  glEnd();
-}
-
-void CacheGeometryRenderer::Initialize(IObjComponent *ObjComp) {
-  glPushMatrix();
-  V3D pos = ObjComp->getPos();
-  Quat rot = ObjComp->getRotation();
-  double rotGL[16];
-  rot.GLMatrix(&rotGL[0]);
-  glTranslated(pos[0], pos[1], pos[2]);
-  glMultMatrixd(rotGL);
-  V3D scaleFactor = ObjComp->getScaleFactor();
-  glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  ObjComp->drawObject();
-  glPopMatrix();
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp
index fb32675b9e53b54d1ccc49453a83d9e14b1a4946..51a3f459eae4b7f0c1c66c4d9a46bbe68609c2db 100644
--- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp
+++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp
@@ -1,68 +1,109 @@
 #include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Instrument/RectangularDetector.h"
+#include "MantidGeometry/Objects/CSGObject.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidGeometry/Rendering/GeometryTriangulator.h"
+#include "MantidGeometry/Rendering/RenderingHelpers.h"
+#include <boost/make_shared.hpp>
 
 namespace Mantid {
 namespace Geometry {
+GeometryHandler::GeometryHandler(IObjComponent *comp) : m_objComp(comp) {}
 
-/** Constructor
- *  @param[in] comp
- *  This geometry handler will be ObjComponent's geometry handler
- */
-GeometryHandler::GeometryHandler(IObjComponent *comp) : csgObj() {
-  ObjComp = comp;
-  meshObj = nullptr;
-  boolTriangulated = true;
-  boolIsInitialized = false;
+GeometryHandler::GeometryHandler(boost::shared_ptr<CSGObject> obj)
+    : m_triangulator(new detail::GeometryTriangulator(obj.get())),
+      m_csgObj(obj.get()) {}
+
+GeometryHandler::GeometryHandler(CSGObject *obj)
+    : m_triangulator(new detail::GeometryTriangulator(obj)), m_csgObj(obj) {}
+
+GeometryHandler::GeometryHandler(boost::shared_ptr<MeshObject> obj)
+    : m_triangulator(new detail::GeometryTriangulator(obj.get())),
+      m_meshObj(obj.get()) {}
+
+GeometryHandler::GeometryHandler(MeshObject *obj)
+    : m_triangulator(new detail::GeometryTriangulator(obj)), m_meshObj(obj) {}
+
+GeometryHandler::GeometryHandler(const GeometryHandler &handler) {
+  if (handler.m_csgObj) {
+    m_csgObj = handler.m_csgObj;
+    if (handler.m_triangulator)
+      m_triangulator.reset(new detail::GeometryTriangulator(m_csgObj));
+  }
+  if (handler.m_objComp)
+    m_objComp = handler.m_objComp;
+  if (handler.m_shapeInfo)
+    m_shapeInfo = handler.m_shapeInfo;
 }
 
-/** Constructor
- *  @param[in] obj
- *  This geometry handler will be Object's geometry handler
- */
-GeometryHandler::GeometryHandler(boost::shared_ptr<CSGObject> obj)
-    : csgObj(obj.get()) {
-  ObjComp = nullptr;
-  meshObj = nullptr;
-  boolTriangulated = false;
-  boolIsInitialized = false;
+/// Destructor
+GeometryHandler::~GeometryHandler() {}
+
+boost::shared_ptr<GeometryHandler> GeometryHandler::clone() const {
+  return boost::make_shared<GeometryHandler>(*this);
 }
 
-/** Constructor
- *  @param[in] obj
- *  This geometry handler will be Object's geometry handler
- */
-GeometryHandler::GeometryHandler(CSGObject *obj) : csgObj(obj) {
-  ObjComp = nullptr;
-  meshObj = nullptr;
-  boolTriangulated = false;
-  boolIsInitialized = false;
+void GeometryHandler::render() const {
+  if (m_shapeInfo)
+    RenderingHelpers::renderShape(*m_shapeInfo);
+  else if (m_objComp != nullptr)
+    RenderingHelpers::renderIObjComponent(*m_objComp);
+  else if (canTriangulate())
+    RenderingHelpers::renderTriangulated(*m_triangulator);
 }
 
-/** Constructor
-*  @param[in] obj
-*  This geometry handler will be Object's geometry handler
-*/
-GeometryHandler::GeometryHandler(boost::shared_ptr<MeshObject> obj) : csgObj() {
-  ObjComp = nullptr;
-  meshObj = obj.get();
-  boolTriangulated = false;
-  boolIsInitialized = false;
+void GeometryHandler::initialize() const {
+  if (m_csgObj != nullptr)
+    m_csgObj->updateGeometryHandler();
+  render();
 }
 
-/** Constructor
-*  @param[in] obj
-*  This geometry handler will be Object's geometry handler
-*/
-GeometryHandler::GeometryHandler(MeshObject *obj) : csgObj() {
-  ObjComp = nullptr;
-  meshObj = obj;
-  boolTriangulated = false;
-  boolIsInitialized = false;
+size_t GeometryHandler::numberOfTriangles() const {
+  if (canTriangulate())
+    return m_triangulator->numTriangleFaces();
+  return 0;
 }
 
-/// Destructor
-GeometryHandler::~GeometryHandler() {
-  ObjComp = nullptr;
-  meshObj = nullptr;
+size_t GeometryHandler::numberOfPoints() const {
+  if (canTriangulate())
+    return m_triangulator->numTriangleVertices();
+  return 0;
 }
+
+const std::vector<double> &GeometryHandler::getTriangleVertices() const {
+  static std::vector<double> empty;
+  if (canTriangulate())
+    return m_triangulator->getTriangleVertices();
+  return empty;
+}
+
+const std::vector<uint32_t> &GeometryHandler::getTriangleFaces() const {
+  static std::vector<uint32_t> empty;
+  if (canTriangulate())
+    return m_triangulator->getTriangleFaces();
+  return empty;
+}
+
+void GeometryHandler::setGeometryCache(size_t nPts, size_t nFaces,
+                                       std::vector<double> &&pts,
+                                       std::vector<uint32_t> &&faces) {
+  if (canTriangulate()) {
+    m_triangulator->setGeometryCache(nPts, nFaces, std::move(pts),
+                                     std::move(faces));
+  }
+}
+
+void GeometryHandler::GetObjectGeom(detail::ShapeInfo::GeometryShape &mytype,
+                                    std::vector<Kernel::V3D> &vectors,
+                                    double &myradius, double &myheight) const {
+  mytype = detail::ShapeInfo::GeometryShape::NOSHAPE;
+  if (m_shapeInfo)
+    m_shapeInfo->getObjectGeometry(mytype, vectors, myradius, myheight);
 }
+
+void GeometryHandler::setShapeInfo(detail::ShapeInfo &&shapeInfo) {
+  m_triangulator.reset(nullptr);
+  m_shapeInfo.reset(new detail::ShapeInfo(std::move(shapeInfo)));
 }
+} // namespace Geometry
+} // namespace Mantid
diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec15829f2b8bf75a7cd2667fa788822722b991cc
--- /dev/null
+++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp
@@ -0,0 +1,250 @@
+#include "MantidGeometry/Rendering/GeometryTriangulator.h"
+#include "MantidGeometry/Objects/CSGObject.h"
+#include "MantidGeometry/Objects/MeshObject.h"
+#include "MantidGeometry/Objects/Rules.h"
+#include "MantidKernel/Logger.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include <climits>
+
+#ifdef ENABLE_OPENCASCADE
+// Squash a warning coming out of an OpenCascade header
+#ifdef __INTEL_COMPILER
+#pragma warning disable 191
+#endif
+// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
+// used.
+// Undefine it here before we include the headers to avoid a warning. Older
+// versions
+// also define M_SQRT1_2 so do the same if it is already defined
+#ifdef _MSC_VER
+#undef _USE_MATH_DEFINES
+#ifdef M_SQRT1_2
+#undef M_SQRT1_2
+#endif
+#endif
+
+GCC_DIAG_OFF(conversion)
+// clang-format off
+GCC_DIAG_OFF(cast-qual)
+// clang-format on
+#include <gp_Trsf.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pln.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRep_Tool.hxx>
+#include <Poly_Triangulation.hxx>
+GCC_DIAG_ON(conversion)
+// clang-format off
+GCC_DIAG_ON(cast-qual)
+// clang-format on
+
+#ifdef __INTEL_COMPILER
+#pragma warning enable 191
+#endif
+
+#endif // ENABLE_OPENCASCADE
+
+namespace Mantid {
+namespace Geometry {
+namespace detail {
+namespace {
+/// static logger
+Kernel::Logger g_log("GeometryTriangulator");
+} // namespace
+
+GeometryTriangulator::GeometryTriangulator(const CSGObject *obj)
+    : m_isTriangulated(false), m_nFaces(0), m_nPoints(0), m_csgObj(obj) {
+#ifdef ENABLE_OPENCASCADE
+  m_objSurface = nullptr;
+#endif
+}
+
+GeometryTriangulator::GeometryTriangulator(const MeshObject *obj)
+    : m_isTriangulated(false), m_meshObj(obj) {}
+
+GeometryTriangulator::~GeometryTriangulator() {}
+
+void GeometryTriangulator::triangulate() {
+#ifdef ENABLE_OPENCASCADE
+  if (m_objSurface == nullptr)
+    OCAnalyzeObject();
+#endif
+  if (m_meshObj) {
+    generateMesh();
+    m_nPoints = m_meshObj->numberOfVertices();
+    m_nFaces = m_meshObj->numberOfTriangles();
+    m_points = m_meshObj->getVertices();
+    m_faces = m_meshObj->getTriangles();
+  }
+  m_isTriangulated = true;
+}
+
+void GeometryTriangulator::generateMesh() {
+  /* Placeholder function to replace MeshGeometryGenerator::Generate()*/
+}
+
+#ifdef ENABLE_OPENCASCADE
+bool GeometryTriangulator::hasOCSurface() const {
+  return m_objSurface != nullptr;
+}
+/// Return OpenCascade surface.
+const TopoDS_Shape &GeometryTriangulator::getOCSurface() {
+  checkTriangulated();
+  return *m_objSurface;
+}
+#endif
+
+void GeometryTriangulator::checkTriangulated() {
+  if (m_csgObj != nullptr || m_meshObj != nullptr) {
+    if (!m_isTriangulated) {
+      triangulate();
+    }
+  }
+}
+size_t GeometryTriangulator::numTriangleFaces() {
+  checkTriangulated();
+  return m_nFaces;
+}
+
+size_t GeometryTriangulator::numTriangleVertices() {
+  checkTriangulated();
+  return m_nPoints;
+}
+
+/// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of
+/// mesh
+const std::vector<double> &GeometryTriangulator::getTriangleVertices() {
+  checkTriangulated();
+  return m_points;
+}
+/// get a pointer to the 3x(NumberOFaces) integers describing points forming
+/// faces (p1,p2,p3)(p4,p5,p6).
+const std::vector<uint32_t> &GeometryTriangulator::getTriangleFaces() {
+  checkTriangulated();
+  return m_faces;
+}
+
+#ifdef ENABLE_OPENCASCADE
+void GeometryTriangulator::OCAnalyzeObject() {
+  if (m_csgObj != nullptr) // If object exists
+  {
+    // Get the top rule tree in Obj
+    const Rule *top = m_csgObj->topRule();
+    if (top == nullptr) {
+      m_objSurface.reset(new TopoDS_Shape());
+      return;
+    } else {
+      // Traverse through Rule
+      TopoDS_Shape Result = const_cast<Rule *>(top)->analyze();
+      try {
+        m_objSurface.reset(new TopoDS_Shape(Result));
+        BRepMesh_IncrementalMesh(Result, 0.001);
+      } catch (StdFail_NotDone &) {
+        g_log.error("Cannot build the geometry. Check the geometry definition");
+      }
+    }
+  }
+
+  setupPoints();
+  setupFaces();
+}
+
+size_t GeometryTriangulator::numPoints() const {
+  size_t countVert = 0;
+  if (m_objSurface != nullptr) {
+    TopExp_Explorer Ex;
+    for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
+      TopoDS_Face F = TopoDS::Face(Ex.Current());
+      TopLoc_Location L;
+      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
+      countVert += static_cast<size_t>(facing->NbNodes());
+    }
+  }
+  return countVert;
+}
+
+size_t GeometryTriangulator::numFaces() const {
+  size_t countFace = 0;
+  if (m_objSurface != nullptr) {
+    TopExp_Explorer Ex;
+    for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
+      TopoDS_Face F = TopoDS::Face(Ex.Current());
+      TopLoc_Location L;
+      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
+      countFace += static_cast<size_t>(facing->NbTriangles());
+    }
+  }
+  return countFace;
+}
+
+void GeometryTriangulator::setupPoints() {
+  m_nPoints = numPoints();
+  if (m_nPoints > 0) {
+    size_t index = 0;
+    m_points.resize(m_nPoints * 3);
+    TopExp_Explorer Ex;
+    for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
+      TopoDS_Face F = TopoDS::Face(Ex.Current());
+      TopLoc_Location L;
+      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
+      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
+      tab = facing->Nodes();
+      for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
+        gp_Pnt pnt = tab.Value(i);
+        m_points[index * 3 + 0] = pnt.X();
+        m_points[index * 3 + 1] = pnt.Y();
+        m_points[index * 3 + 2] = pnt.Z();
+        index++;
+      }
+    }
+  }
+}
+
+void GeometryTriangulator::setupFaces() {
+  m_nFaces = numFaces();
+  if (m_nFaces > 0) {
+    m_faces.resize(m_nFaces * 3);
+    TopExp_Explorer Ex;
+    int maxindex = 0;
+    size_t index = 0;
+    for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
+      TopoDS_Face F = TopoDS::Face(Ex.Current());
+      TopLoc_Location L;
+      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
+      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
+      tab = facing->Nodes();
+      Poly_Array1OfTriangle tri(1, facing->NbTriangles());
+      tri = facing->Triangles();
+      for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
+        Poly_Triangle trian = tri.Value(i);
+        Standard_Integer index1, index2, index3;
+        trian.Get(index1, index2, index3);
+        m_faces[index * 3 + 0] = static_cast<uint32_t>(maxindex + index1 - 1);
+        m_faces[index * 3 + 1] = static_cast<uint32_t>(maxindex + index2 - 1);
+        m_faces[index * 3 + 2] = static_cast<uint32_t>(maxindex + index3 - 1);
+        index++;
+      }
+      maxindex += facing->NbNodes();
+    }
+  }
+}
+#endif
+
+void GeometryTriangulator::setGeometryCache(size_t nPoints, size_t nFaces,
+                                            std::vector<double> &&points,
+                                            std::vector<uint32_t> &&faces) {
+  m_nPoints = nPoints;
+  m_nFaces = nFaces;
+  m_points = std::move(points);
+  m_faces = std::move(faces);
+  m_isTriangulated = true;
+}
+} // namespace detail
+} // namespace Geometry
+} // namespace Mantid
diff --git a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp
deleted file mode 100644
index 15ad30496a93c7d7fb3b4f572a40b5aa115941ea..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include "MantidGeometry/Rendering/GluGeometryHandler.h"
-#include "MantidGeometry/Instrument/ObjComponent.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Rendering/GluGeometryRenderer.h"
-#include "MantidKernel/make_unique.h"
-
-#include <boost/make_shared.hpp>
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-
-GluGeometryHandler::GluGeometryHandler(IObjComponent *comp)
-    : GeometryHandler(comp),
-      Renderer(Kernel::make_unique<GluGeometryRenderer>()), radius(0.0),
-      height(0.0), type(GeometryType::NOSHAPE) {}
-
-GluGeometryHandler::GluGeometryHandler(boost::shared_ptr<CSGObject> obj)
-    : GeometryHandler(std::move(obj)),
-      Renderer(Kernel::make_unique<GluGeometryRenderer>()), radius(0.0),
-      height(0.0), type(GeometryType::NOSHAPE) {}
-
-GluGeometryHandler::GluGeometryHandler(CSGObject *obj)
-    : GeometryHandler(obj),
-      Renderer(Kernel::make_unique<GluGeometryRenderer>()), radius(0.0),
-      height(0.0), type(GeometryType::NOSHAPE) {}
-
-GluGeometryHandler::GluGeometryHandler(const GluGeometryHandler &other)
-    : GeometryHandler(other), m_points(other.m_points), radius(other.radius),
-      height(other.height), type(other.type) {
-  this->Renderer = Kernel::make_unique<GluGeometryRenderer>();
-}
-
-boost::shared_ptr<GeometryHandler> GluGeometryHandler::clone() const {
-  return boost::make_shared<GluGeometryHandler>(*this);
-}
-
-GluGeometryHandler::~GluGeometryHandler() = default;
-
-GeometryHandler *GluGeometryHandler::createInstance(IObjComponent *comp) {
-  return new GluGeometryHandler(comp);
-}
-
-GeometryHandler *
-GluGeometryHandler::createInstance(boost::shared_ptr<CSGObject> obj) {
-  return new GluGeometryHandler(obj);
-}
-
-GeometryHandler *GluGeometryHandler::createInstance(CSGObject *obj) {
-  return new GluGeometryHandler(obj);
-}
-
-void GluGeometryHandler::Triangulate() {
-  // Check whether Object is triangulated otherwise triangulate
-  // Doesn't have to do anything because we are not going to triangulate
-  // anything
-}
-
-void GluGeometryHandler::Render() {
-  if (csgObj != nullptr) {
-    switch (type) {
-    case GeometryType::CUBOID:
-      Renderer->RenderCube(m_points[0], m_points[1], m_points[2], m_points[3]);
-      break;
-    case GeometryType::HEXAHEDRON:
-      Renderer->RenderHexahedron(m_points[0], m_points[1], m_points[2],
-                                 m_points[3], m_points[4], m_points[5],
-                                 m_points[6], m_points[7]);
-      break;
-    case GeometryType::SPHERE:
-      Renderer->RenderSphere(m_points[0], radius);
-      break;
-    case GeometryType::CYLINDER:
-      Renderer->RenderCylinder(m_points[0], m_points[1], radius, height);
-      break;
-    case GeometryType::CONE:
-      Renderer->RenderCone(m_points[0], m_points[1], radius, height);
-      break;
-    case GeometryType::SEGMENTED_CYLINDER:
-      Renderer->RenderSegmentedCylinder(m_points[0], m_points[1], radius,
-                                        height);
-      break;
-    case GeometryType::NOSHAPE:
-      break;
-    }
-  } else if (ObjComp != nullptr) {
-    Renderer->Render(ObjComp);
-  }
-}
-
-void GluGeometryHandler::GetObjectGeom(int &mytype,
-                                       std::vector<Kernel::V3D> &vectors,
-                                       double &myradius, double &myheight) {
-  mytype = 0;
-  if (csgObj != nullptr) {
-    mytype = static_cast<int>(type);
-    vectors = m_points;
-    switch (type) {
-    case GeometryType::CUBOID:
-      break;
-    case GeometryType::HEXAHEDRON:
-      break;
-    case GeometryType::SPHERE:
-      myradius = radius;
-      break;
-    default:
-      myradius = radius;
-      myheight = height;
-      break;
-    }
-  }
-}
-
-void GluGeometryHandler::Initialize() {
-  if (csgObj != nullptr) {
-    // There is no initialization or probably call render
-    Render();
-  }
-}
-
-void GluGeometryHandler::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3,
-                                   const V3D &p4) {
-  type = GeometryType::CUBOID;
-  m_points.assign({p1, p2, p3, p4});
-}
-
-void GluGeometryHandler::setHexahedron(const V3D &p1, const V3D &p2,
-                                       const V3D &p3, const V3D &p4,
-                                       const V3D &p5, const V3D &p6,
-                                       const V3D &p7, const V3D &p8) {
-  type = GeometryType::HEXAHEDRON;
-  m_points.assign({p1, p2, p3, p4, p5, p6, p7, p8});
-}
-
-void GluGeometryHandler::setSphere(const V3D &c, double r) {
-  type = GeometryType::SPHERE;
-  m_points.assign({c});
-  radius = r;
-}
-void GluGeometryHandler::setCylinder(const V3D &c, const V3D &a, double r,
-                                     double h) {
-  type = GeometryType::CYLINDER;
-  m_points.assign({c, a});
-  radius = r;
-  height = h;
-}
-void GluGeometryHandler::setCone(const V3D &c, const V3D &a, double r,
-                                 double h) {
-  type = GeometryType::CONE;
-  m_points.assign({c, a});
-  radius = r;
-  height = h;
-}
-void GluGeometryHandler::setSegmentedCylinder(const V3D &c, const V3D &a,
-                                              double r, double h) {
-  type = GeometryType::SEGMENTED_CYLINDER;
-  m_points.assign({c, a});
-  radius = r;
-  height = h;
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp
deleted file mode 100644
index fca52b37921125bb7b8efb42f7a80a6d10a5720e..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-#include "MantidGeometry/Rendering/GluGeometryRenderer.h"
-#include "MantidGeometry/Rendering/OpenGL_Headers.h"
-#include "MantidGeometry/Instrument/ObjComponent.h"
-#include "MantidKernel/Quat.h"
-#include "MantidGeometry/Surfaces/Cylinder.h"
-#include "MantidGeometry/Surfaces/Cone.h"
-#include "MantidGeometry/Surfaces/Sphere.h"
-#include <climits>
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-using Kernel::Quat;
-
-void GluGeometryRenderer::RenderSphere(const V3D &center, double radius) {
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateSphere(center, radius);
-}
-
-void GluGeometryRenderer::RenderCube(const V3D &Point1, const V3D &Point2,
-                                     const V3D &Point3, const V3D &Point4) {
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateCube(Point1, Point2, Point3, Point4);
-}
-
-void GluGeometryRenderer::RenderHexahedron(
-    const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-    const Kernel::V3D &Point3, const Kernel::V3D &Point4,
-    const Kernel::V3D &Point5, const Kernel::V3D &Point6,
-    const Kernel::V3D &Point7, const Kernel::V3D &Point8) {
-
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateHexahedron(Point1, Point2, Point3, Point4, Point5, Point6, Point7,
-                   Point8);
-}
-
-void GluGeometryRenderer::RenderCone(const V3D &center, const V3D &axis,
-                                     double radius, double height) {
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateCone(center, axis, radius, height);
-}
-
-void GluGeometryRenderer::RenderCylinder(const V3D &center, const V3D &axis,
-                                         double radius, double height) {
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateCylinder(center, axis, radius, height);
-}
-
-void GluGeometryRenderer::RenderSegmentedCylinder(const V3D &center,
-                                                  const V3D &axis,
-                                                  double radius,
-                                                  double height) {
-  while (glGetError() != GL_NO_ERROR)
-    ;
-  CreateSegmentedCylinder(center, axis, radius, height);
-}
-
-/**
- * Render ObjComponent
- * @param ObjComp :: input to render
- */
-void GluGeometryRenderer::Render(IObjComponent *ObjComp) const {
-  glPushMatrix();
-  V3D pos = ObjComp->getPos();
-  Quat rot = ObjComp->getRotation();
-  double rotGL[16];
-  rot.GLMatrix(&rotGL[0]);
-  glTranslated(pos[0], pos[1], pos[2]);
-  glMultMatrixd(rotGL);
-  ObjComp->drawObject();
-  glPopMatrix();
-}
-
-/**
- * Creates a GLU Sphere
- * @param center :: center of the sphere
- * @param radius :: radius of the sphere
- */
-void GluGeometryRenderer::CreateSphere(const V3D &center, double radius) {
-  // create glu sphere
-  GLUquadricObj *qobj = gluNewQuadric();
-  gluQuadricDrawStyle(qobj, GLU_FILL);
-  gluQuadricNormals(qobj, GL_SMOOTH);
-  glPushMatrix();
-  glTranslated(center[0], center[1], center[2]);
-  gluSphere(qobj, radius, Geometry::Sphere::g_nslices,
-            Geometry::Sphere::g_nstacks);
-  glPopMatrix();
-  gluDeleteQuadric(qobj);
-}
-
-/**
- * Creates a Cube
- * @param Point1 :: first point of the cube
- * @param Point2 :: second point of the cube
- * @param Point3 :: thrid point of the cube
- * @param Point4 :: fourth point of the cube
- */
-void GluGeometryRenderer::CreateCube(const V3D &Point1, const V3D &Point2,
-                                     const V3D &Point3, const V3D &Point4) {
-  V3D vec0 = Point1;
-  V3D vec1 = Point2 - Point1;
-  V3D vec2 = Point3 - Point1;
-  V3D vec3 = Point4 - Point1;
-  V3D vertex[8];
-  vertex[0] = vec0;
-  vertex[1] = vec0 + vec3;
-  vertex[2] = vec0 + vec3 + vec1;
-  vertex[3] = vec0 + vec1;
-  vertex[4] = vec0 + vec2;
-  vertex[5] = vec0 + vec2 + vec3;
-  vertex[6] = vec0 + vec2 + vec3 + vec1;
-  vertex[7] = vec0 + vec1 + vec2;
-  // int
-  // faceindex[6][4]={{0,1,2,3},{0,3,7,4},{3,2,6,7},{2,1,5,6},{0,4,5,1},{4,7,6,5}};
-  // int
-  // faceindex[6][4]={{0,3,2,1},{0,4,7,3},{3,7,6,2},{2,6,5,1},{0,1,5,4},{4,5,6,7}};
-  int faceindex[6][4] = {
-      {0, 1, 2, 3}, // top
-      {0, 3, 7, 4}, // left
-      {3, 2, 6, 7}, // back
-      {2, 1, 5, 6}, // right
-      {0, 4, 5, 1}, // front
-      {4, 7, 6, 5}, // bottom
-  };
-  V3D normal;
-  // first face
-  glBegin(GL_QUADS);
-  for (auto &row : faceindex) {
-    normal = (vertex[row[0]] - vertex[row[1]])
-                 .cross_prod((vertex[row[0]] - vertex[row[2]]));
-    normal.normalize();
-    glNormal3d(normal[0], normal[1], normal[2]);
-    for (const int ij : row) {
-      if (ij == 0)
-        glTexCoord2i(0, 0);
-      if (ij == 1)
-        glTexCoord2i(1, 0);
-      if (ij == 2)
-        glTexCoord2i(1, 1);
-      if (ij == 3)
-        glTexCoord2i(0, 1);
-      if (ij == 4)
-        glTexCoord2i(0, 0);
-      if (ij == 5)
-        glTexCoord2i(1, 0);
-      if (ij == 6)
-        glTexCoord2i(1, 1);
-      if (ij == 7)
-        glTexCoord2i(0, 1);
-      glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]);
-    }
-  }
-  glEnd();
-}
-
-/**
-* Creates a Hexahedron
-* @param Point1 :: first point of the hexahedron
-* @param Point2 :: second point of the hexahedron
-* @param Point3 :: third point of the hexahedron
-* @param Point4 :: fourth point of the hexahedron
-* @param Point5 :: fifth point of the hexahedron
-* @param Point6 :: sixth point of the hexahedron
-* @param Point7 :: seventh point of the hexahedron
-* @param Point8 :: eigth point of the hexahedron
-*/
-void GluGeometryRenderer::CreateHexahedron(
-    const Kernel::V3D &Point1, const Kernel::V3D &Point2,
-    const Kernel::V3D &Point3, const Kernel::V3D &Point4,
-    const Kernel::V3D &Point5, const Kernel::V3D &Point6,
-    const Kernel::V3D &Point7, const Kernel::V3D &Point8) {
-
-  glBegin(GL_QUADS);
-
-  // bottom
-  glVertex3d(Point1.X(), Point1.Y(), Point1.Z());
-  glVertex3d(Point2.X(), Point2.Y(), Point2.Z());
-  glVertex3d(Point3.X(), Point3.Y(), Point3.Z());
-  glVertex3d(Point4.X(), Point4.Y(), Point4.Z());
-
-  // front
-  glVertex3d(Point2.X(), Point2.Y(), Point2.Z());
-  glVertex3d(Point6.X(), Point6.Y(), Point6.Z());
-  glVertex3d(Point7.X(), Point7.Y(), Point7.Z());
-  glVertex3d(Point3.X(), Point3.Y(), Point3.Z());
-
-  // right
-  glVertex3d(Point3.X(), Point3.Y(), Point3.Z());
-  glVertex3d(Point7.X(), Point7.Y(), Point7.Z());
-  glVertex3d(Point8.X(), Point8.Y(), Point8.Z());
-  glVertex3d(Point4.X(), Point4.Y(), Point4.Z());
-
-  // back
-  glVertex3d(Point4.X(), Point4.Y(), Point4.Z());
-  glVertex3d(Point8.X(), Point8.Y(), Point8.Z());
-  glVertex3d(Point5.X(), Point5.Y(), Point5.Z());
-  glVertex3d(Point1.X(), Point1.Y(), Point1.Z());
-
-  // left
-  glVertex3d(Point1.X(), Point1.Y(), Point1.Z());
-  glVertex3d(Point5.X(), Point5.Y(), Point5.Z());
-  glVertex3d(Point6.X(), Point6.Y(), Point6.Z());
-  glVertex3d(Point2.X(), Point2.Y(), Point2.Z());
-
-  // top
-  glVertex3d(Point5.X(), Point5.Y(), Point5.Z());
-  glVertex3d(Point6.X(), Point6.Y(), Point6.Z());
-  glVertex3d(Point7.X(), Point7.Y(), Point7.Z());
-  glVertex3d(Point8.X(), Point8.Y(), Point8.Z());
-
-  glEnd();
-}
-
-/**
- * Creates a Cone
- * @param center :: center of the cone
- * @param axis ::   axis of the cone
- * @param radius :: radius of the cone
- * @param height :: height of the cone
- */
-void GluGeometryRenderer::CreateCone(const V3D &center, const V3D &axis,
-                                     double radius, double height) {
-  glPushMatrix();
-  GLUquadricObj *qobj = gluNewQuadric();
-  gluQuadricDrawStyle(qobj, GLU_FILL);
-  gluQuadricNormals(qobj, GL_SMOOTH);
-  glTranslated(center[0], center[1], center[2]);
-  GLdouble mat[16];
-  V3D unit(0, 0, 1);
-  Quat rot(unit, axis);
-  rot.GLMatrix(&mat[0]);
-  glMultMatrixd(mat);
-  gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices,
-              Geometry::Cone::g_nstacks);
-  glTranslated(0.0, 0.0, height);
-  gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1);
-  glPopMatrix();
-}
-
-/**
- * Create a Cylinder
- * @param center :: center of the cylinder
- * @param axis ::  axis of the cylinder
- * @param radius :: radius of the cylinder
- * @param height :: height of the cylinder
- */
-void GluGeometryRenderer::CreateCylinder(const V3D &center, const V3D &axis,
-                                         double radius, double height) {
-  GLUquadricObj *qobj = gluNewQuadric();
-  gluQuadricDrawStyle(qobj, GLU_FILL);
-  gluQuadricNormals(qobj, GL_SMOOTH);
-  gluQuadricTexture(qobj, true);
-  glPushMatrix();
-  glTranslated(center[0], center[1], center[2]);
-  GLdouble mat[16];
-  V3D unit(0, 0, 1);
-  Quat rot(unit, axis);
-  rot.GLMatrix(&mat[0]);
-  glMultMatrixd(mat);
-  gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices,
-              Cylinder::g_nstacks);
-  gluQuadricTexture(qobj, false);
-  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
-  glTranslated(0.0, 0.0, height);
-  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
-  glPopMatrix();
-}
-
-void GluGeometryRenderer::CreateSegmentedCylinder(const V3D &center,
-                                                  const V3D &axis,
-                                                  double radius,
-                                                  double height) {
-  GLUquadricObj *qobj = gluNewQuadric();
-  gluQuadricDrawStyle(qobj, GLU_FILL);
-  gluQuadricNormals(qobj, GL_SMOOTH);
-  gluQuadricTexture(qobj, true);
-  glPushMatrix();
-  glTranslated(center[0], center[1], center[2]);
-  GLdouble mat[16];
-  V3D unit(0, 0, 1);
-  Quat rot(unit, axis);
-  rot.GLMatrix(&mat[0]);
-  glMultMatrixd(mat);
-  gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, 1);
-  gluQuadricTexture(qobj, false);
-  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
-  glTranslated(0.0, 0.0, height);
-  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
-  glPopMatrix();
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp
deleted file mode 100644
index e7706d37ac1c4824290cc708e35c440f1a834b57..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <vector>
-#include <cmath>
-#include "MantidKernel/Matrix.h"
-#include "MantidGeometry/Objects/MeshObject.h"
-#include "MantidGeometry/Rendering/MeshGeometryGenerator.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-
-#ifdef ENABLE_OPENCASCADE
-#include "MantidGeometry/Rendering/OCGeometryHandler.h"
-#endif
-
-namespace Mantid {
-
-namespace Geometry {
-/**
- * Constructor
- * @param obj :: input object
- */
-MeshGeometryGenerator::MeshGeometryGenerator(MeshObject *obj) : Obj(obj) {
-  mNoOfVertices = 0;
-  mNoOfTriangles = 0;
-  mFaces = nullptr;
-  mPoints = nullptr;
-}
-
-/**
- * Generate geometry, get triangles from object if not in cache.
- */
-void MeshGeometryGenerator::Generate() {
-  if (mNoOfVertices <= 0) { // Get triangles from object
-  }
-}
-
-/**
- * Destroy the surface generated for the object
- */
-MeshGeometryGenerator::~MeshGeometryGenerator() {
-  if (mFaces != nullptr)
-    delete[] mFaces;
-  if (mPoints != nullptr)
-    delete[] mPoints;
-}
-
-int MeshGeometryGenerator::getNumberOfTriangles() { return mNoOfTriangles; }
-
-int MeshGeometryGenerator::getNumberOfPoints() { return mNoOfVertices; }
-
-double *MeshGeometryGenerator::getTriangleVertices() { return mPoints; }
-
-int *MeshGeometryGenerator::getTriangleFaces() { return mFaces; }
-
-/**
-   Sets the geometry cache using the triangulation information provided
-   @param noPts :: the number of points
-   @param noFaces :: the number of faces
-   @param pts :: a double array of the points
-   @param faces :: an int array of the faces
-*/
-void MeshGeometryGenerator::setGeometryCache(int noPts, int noFaces,
-                                             double *pts, int *faces) {
-  if (mPoints != nullptr)
-    delete[] mPoints;
-  if (mFaces != nullptr)
-    delete[] mFaces;
-  mNoOfVertices = noPts;
-  mNoOfTriangles = noFaces;
-  mPoints = pts;
-  mFaces = faces;
-}
-
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
diff --git a/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp
deleted file mode 100644
index 49b701333b624aabd93a73142688d6f8c5d3e3b2..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "MantidGeometry/Rendering/OCGeometryGenerator.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Surfaces/Quadratic.h"
-#include "MantidGeometry/Surfaces/Sphere.h"
-#include "MantidGeometry/Surfaces/Cylinder.h"
-#include "MantidGeometry/Surfaces/Cone.h"
-#include "MantidGeometry/Surfaces/Plane.h"
-#include "MantidGeometry/Surfaces/Torus.h"
-#include "MantidGeometry/Objects/Rules.h"
-#include "MantidKernel/Logger.h"
-#include "MantidKernel/Matrix.h"
-#include "MantidKernel/Quat.h"
-#include "MantidKernel/V3D.h"
-#include "MantidKernel/WarningSuppressions.h"
-
-#include <climits> // Needed for g++4.4 on Mac with OpenCASCADE 6.3.0
-#include <cmath>
-#include <vector>
-
-// Squash a warning coming out of an OpenCascade header
-#ifdef __INTEL_COMPILER
-#pragma warning disable 191
-#endif
-// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
-// used.
-// Undefine it here before we include the headers to avoid a warning. Older
-// versions
-// also define M_SQRT1_2 so do the same if it is already defined
-#ifdef _MSC_VER
-#undef _USE_MATH_DEFINES
-#ifdef M_SQRT1_2
-#undef M_SQRT1_2
-#endif
-#endif
-
-GCC_DIAG_OFF(conversion)
-// clang-format off
-GCC_DIAG_OFF(cast-qual)
-// clang-format on
-#include <gp_Trsf.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pln.hxx>
-#include <StdFail_NotDone.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Solid.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopExp_Explorer.hxx>
-#include <BRepMesh_IncrementalMesh.hxx>
-#include <BRepAlgoAPI_Fuse.hxx>
-#include <BRepAlgoAPI_Common.hxx>
-#include <BRepAlgoAPI_Cut.hxx>
-#include <BRepPrimAPI_MakeBox.hxx>
-#include <BRepBuilderAPI_Transform.hxx>
-#include <BRep_Tool.hxx>
-#include <Poly_Triangulation.hxx>
-GCC_DIAG_ON(conversion)
-// clang-format off
-GCC_DIAG_ON(cast-qual)
-// clang-format on
-
-#ifdef __INTEL_COMPILER
-#pragma warning enable 191
-#endif
-
-namespace Mantid {
-
-namespace Geometry {
-namespace {
-/// static logger
-Kernel::Logger g_log("OCGeometryGenerator");
-}
-
-/**
-* Constructor
-* @param obj :: input object
-*/
-OCGeometryGenerator::OCGeometryGenerator(const CSGObject *obj) : Obj(obj) {
-  ObjSurface = nullptr;
-}
-
-/**
-* Generate geometry, it uses OpenCascade to generate surface triangles.
-*/
-void OCGeometryGenerator::Generate() {
-  if (ObjSurface == nullptr) {
-    AnalyzeObject();
-  }
-}
-
-/**
-* Destroy the surface generated for the object
-*/
-OCGeometryGenerator::~OCGeometryGenerator() {
-  if (ObjSurface != nullptr) {
-    delete ObjSurface;
-  }
-}
-
-/**
-* Analyzes the rule tree in object and creates a Topology Shape
-*/
-void OCGeometryGenerator::AnalyzeObject() {
-  if (Obj != nullptr) // If object exists
-  {
-    // Get the top rule tree in Obj
-    const Rule *top = Obj->topRule();
-    if (top == nullptr) {
-      ObjSurface = new TopoDS_Shape();
-      return;
-    }
-    // Traverse through Rule
-    TopoDS_Shape Result = const_cast<Rule *>(top)->analyze();
-    try {
-      ObjSurface = new TopoDS_Shape(Result);
-      BRepMesh_IncrementalMesh(Result, 0.001);
-    } catch (StdFail_NotDone &) {
-      g_log.error("Cannot build the geometry. Check the geometry definition");
-    }
-  }
-}
-
-/**
-* Returns the shape generated.
-*/
-TopoDS_Shape *OCGeometryGenerator::getObjectSurface() { return ObjSurface; }
-
-int OCGeometryGenerator::getNumberOfTriangles() {
-  int countFace = 0;
-  if (ObjSurface != nullptr) {
-    TopExp_Explorer Ex;
-    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
-      TopoDS_Face F = TopoDS::Face(Ex.Current());
-      TopLoc_Location L;
-      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-      countFace += facing->NbTriangles();
-    }
-  }
-  return countFace;
-}
-
-int OCGeometryGenerator::getNumberOfPoints() {
-  int countVert = 0;
-  if (ObjSurface != nullptr) {
-    TopExp_Explorer Ex;
-    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
-      TopoDS_Face F = TopoDS::Face(Ex.Current());
-      TopLoc_Location L;
-      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-      countVert += facing->NbNodes();
-    }
-  }
-  return countVert;
-}
-
-double *OCGeometryGenerator::getTriangleVertices() {
-  double *points = nullptr;
-  int nPts = this->getNumberOfPoints();
-  if (nPts > 0) {
-    points = new double[static_cast<std::size_t>(nPts) * 3];
-    int index = 0;
-    TopExp_Explorer Ex;
-    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
-      TopoDS_Face F = TopoDS::Face(Ex.Current());
-      TopLoc_Location L;
-      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
-      tab = facing->Nodes();
-      for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
-        gp_Pnt pnt = tab.Value(i);
-        points[index * 3 + 0] = pnt.X();
-        points[index * 3 + 1] = pnt.Y();
-        points[index * 3 + 2] = pnt.Z();
-        index++;
-      }
-    }
-  }
-  return points;
-}
-
-int *OCGeometryGenerator::getTriangleFaces() {
-  int *faces = nullptr;
-  int nFaces = this->getNumberOfTriangles(); // was Points
-  if (nFaces > 0) {
-    faces = new int[static_cast<std::size_t>(nFaces) * 3];
-    TopExp_Explorer Ex;
-    int maxindex = 0;
-    int index = 0;
-    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
-      TopoDS_Face F = TopoDS::Face(Ex.Current());
-      TopLoc_Location L;
-      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
-      tab = facing->Nodes();
-      Poly_Array1OfTriangle tri(1, facing->NbTriangles());
-      tri = facing->Triangles();
-      for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
-        Poly_Triangle trian = tri.Value(i);
-        Standard_Integer index1, index2, index3;
-        trian.Get(index1, index2, index3);
-        faces[index * 3 + 0] = maxindex + index1 - 1;
-        faces[index * 3 + 1] = maxindex + index2 - 1;
-        faces[index * 3 + 2] = maxindex + index3 - 1;
-        index++;
-      }
-      maxindex += facing->NbNodes();
-    }
-  }
-  return faces;
-}
-} // NAMESPACE Geometry
-
-} // NAMESPACE Mantid
diff --git a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp
deleted file mode 100644
index 821d762c3d8d4884f59e5adafeb4c6e4b3a7f3ba..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Rendering/GeometryHandler.h"
-#include "MantidGeometry/Rendering/OCGeometryHandler.h"
-#include "MantidGeometry/Rendering/OCGeometryGenerator.h"
-#include "MantidGeometry/Rendering/OCGeometryRenderer.h"
-
-#include <boost/make_shared.hpp>
-
-namespace Mantid {
-namespace Geometry {
-OCGeometryHandler::OCGeometryHandler(IObjComponent *comp)
-    : GeometryHandler(comp) {
-  Triangulator = nullptr;
-  Renderer = new OCGeometryRenderer();
-}
-
-OCGeometryHandler::OCGeometryHandler(boost::shared_ptr<CSGObject> obj)
-    : GeometryHandler(obj) {
-  Triangulator = new OCGeometryGenerator(obj.get());
-  Renderer = new OCGeometryRenderer();
-}
-
-OCGeometryHandler::OCGeometryHandler(CSGObject *obj) : GeometryHandler(obj) {
-  Triangulator = new OCGeometryGenerator(obj);
-  Renderer = new OCGeometryRenderer();
-}
-
-boost::shared_ptr<GeometryHandler> OCGeometryHandler::clone() const {
-  auto clone = boost::make_shared<OCGeometryHandler>(*this);
-  clone->Renderer = new OCGeometryRenderer(*(this->Renderer));
-  if (this->Triangulator)
-    clone->Triangulator = new OCGeometryGenerator(this->csgObj);
-  return clone;
-}
-
-OCGeometryHandler::~OCGeometryHandler() {
-  if (Triangulator != nullptr)
-    delete Triangulator;
-  if (Renderer != nullptr)
-    delete Renderer;
-}
-
-GeometryHandler *OCGeometryHandler::createInstance(IObjComponent *comp) {
-  return new OCGeometryHandler(comp);
-}
-
-GeometryHandler *
-OCGeometryHandler::createInstance(boost::shared_ptr<CSGObject> obj) {
-  return new OCGeometryHandler(obj);
-}
-
-GeometryHandler *OCGeometryHandler::createInstance(CSGObject *obj) {
-  return new OCGeometryHandler(obj);
-}
-
-void OCGeometryHandler::Triangulate() {
-  // Check whether Object is triangulated otherwise triangulate
-  if (csgObj != nullptr && !boolTriangulated) {
-    Triangulator->Generate();
-    boolTriangulated = true;
-  }
-}
-
-void OCGeometryHandler::Render() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    Renderer->Render(Triangulator->getObjectSurface());
-  } else if (ObjComp != nullptr) {
-    Renderer->Render(ObjComp);
-  }
-}
-
-void OCGeometryHandler::Initialize() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    Renderer->Initialize(Triangulator->getObjectSurface());
-  } else if (ObjComp != nullptr) {
-    Renderer->Initialize(ObjComp);
-  }
-}
-
-int OCGeometryHandler::NumberOfTriangles() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getNumberOfTriangles();
-  } else {
-    return 0;
-  }
-}
-
-int OCGeometryHandler::NumberOfPoints() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getNumberOfPoints();
-  } else {
-    return 0;
-  }
-}
-
-double *OCGeometryHandler::getTriangleVertices() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getTriangleVertices();
-  } else {
-    return nullptr;
-  }
-}
-
-int *OCGeometryHandler::getTriangleFaces() {
-  if (csgObj != nullptr) {
-    if (!boolTriangulated)
-      Triangulate();
-    return Triangulator->getTriangleFaces();
-  } else {
-    return nullptr;
-  }
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp
deleted file mode 100644
index 1f899f84b1a74f95bd55a70d8ade7a13de4c81bc..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-#include "MantidGeometry/Rendering/OCGeometryRenderer.h"
-#include "MantidGeometry/Rendering/OpenGL_Headers.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidKernel/V3D.h"
-#include "MantidKernel/Quat.h"
-#include "MantidKernel/WarningSuppressions.h"
-#include <climits>
-
-// Squash a warning coming out of an OpenCascade header
-#ifdef __INTEL_COMPILER
-#pragma warning disable 191
-#endif
-// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
-// used.
-// Undefine it here before we include the headers to avoid a warning
-#ifdef _MSC_VER
-#undef _USE_MATH_DEFINES
-#ifdef M_SQRT1_2
-#undef M_SQRT1_2
-#endif
-#endif
-
-GCC_DIAG_OFF(conversion)
-// clang-format off
-GCC_DIAG_OFF(cast-qual)
-// clang-format on
-#include <gp_Pnt.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Face.hxx>
-#include <BRep_Tool.hxx>
-#include <TopExp_Explorer.hxx>
-#include <Poly_Array1OfTriangle.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <Poly_Triangulation.hxx>
-GCC_DIAG_ON(conversion)
-// clang-format off
-GCC_DIAG_ON(cast-qual)
-// clang-format on
-
-#ifdef __INTEL_COMPILER
-#pragma warning enable 191
-#endif
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-using Kernel::Quat;
-
-/**
- * Renders Object surface given as OpenCascade topology shape
- * @param ObjSurf :: object's surface stored in topology shape
- */
-void OCGeometryRenderer::Render(TopoDS_Shape *ObjSurf) { Initialize(ObjSurf); }
-
-/**
- * Render ObjComponent
- * @param ObjComp :: input to render
- */
-void OCGeometryRenderer::Render(IObjComponent *ObjComp) {
-  if (ObjComp == nullptr)
-    return;
-  glPushMatrix();
-  V3D pos = ObjComp->getPos();
-  Quat rot = ObjComp->getRotation();
-  double rotGL[16];
-  rot.GLMatrix(&rotGL[0]);
-  glTranslated(pos[0], pos[1], pos[2]);
-  glMultMatrixd(rotGL);
-  V3D scaleFactor = ObjComp->getScaleFactor();
-  glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  ObjComp->drawObject();
-  glPopMatrix();
-}
-
-/**
- * Initialze the object surface for rendering
- * @param ObjSurf :: input to create display list
- */
-void OCGeometryRenderer::Initialize(TopoDS_Shape *ObjSurf) {
-  glBegin(GL_TRIANGLES);
-  // Here goes the traversing through TopoDS_Shape triangles
-  RenderTopoDS(ObjSurf);
-  glEnd();
-}
-
-/**
- * Initializes creates a display for the input ObjComponent
- * @param ObjComp :: input object component for creating display
- */
-void OCGeometryRenderer::Initialize(IObjComponent *ObjComp) {
-  glPushMatrix();
-  V3D pos = ObjComp->getPos();
-  Quat rot = ObjComp->getRotation();
-  double rotGL[16];
-  rot.GLMatrix(&rotGL[0]);
-  glTranslated(pos[0], pos[1], pos[2]);
-  glMultMatrixd(rotGL);
-  V3D scaleFactor = ObjComp->getScaleFactor();
-  glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  ObjComp->drawObject();
-  glPopMatrix();
-}
-
-/**
- * Renders TopoDS Shape by traversing through the TopoDS_Shape
- */
-void OCGeometryRenderer::RenderTopoDS(TopoDS_Shape *ObjSurf) {
-  if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) {
-    TopExp_Explorer Ex;
-    for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) {
-      TopoDS_Face F = TopoDS::Face(Ex.Current());
-      TopLoc_Location L;
-      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
-      tab = facing->Nodes();
-      Poly_Array1OfTriangle tri(1, facing->NbTriangles());
-      tri = facing->Triangles();
-      for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
-        Poly_Triangle trian = tri.Value(i);
-        Standard_Integer index1, index2, index3;
-        trian.Get(index1, index2, index3);
-        gp_Pnt point1 = tab.Value(index1);
-        gp_Pnt point2 = tab.Value(index2);
-        gp_Pnt point3 = tab.Value(index3);
-        gp_XYZ pt1 = tab.Value(index1).XYZ();
-        gp_XYZ pt2 = tab.Value(index2).XYZ();
-        gp_XYZ pt3 = tab.Value(index3).XYZ();
-
-        gp_XYZ v1 = pt2 - pt1;
-        gp_XYZ v2 = pt3 - pt2;
-
-        gp_XYZ normal = v1 ^ v2;
-        normal.Normalize();
-        glNormal3d(normal.X(), normal.Y(), normal.Z());
-        glVertex3d(point1.X(), point1.Y(), point1.Z());
-        glVertex3d(point2.X(), point2.Y(), point2.Z());
-        glVertex3d(point3.X(), point3.Y(), point3.Z());
-      }
-    }
-  }
-}
-
-/**
- * Writes out a vtk 2.0 file, currently hardcoded to c:\\outputcascade.vtk
- */
-void OCGeometryRenderer::WriteVTK(TopoDS_Shape *out) {
-  FILE *fp = fopen("C:\\outputcascade.vtk", "w+");
-  fprintf(fp, "# vtk DataFile Version 2.0 \nOpenCascade data\nASCII\n");
-  fprintf(fp, "DATASET POLYDATA\n");
-  //			BRepMesh::Mesh(out,0.1);
-  TopExp_Explorer Ex;
-  int countVert = 0;
-  int countFace = 0;
-  for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) {
-    TopoDS_Face F = TopoDS::Face(Ex.Current());
-    TopLoc_Location L;
-    Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-    countVert += facing->NbNodes();
-    countFace += facing->NbTriangles();
-  }
-  fprintf(fp, "POINTS %d float\n", countVert);
-  for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) {
-    TopoDS_Face F = TopoDS::Face(Ex.Current());
-    TopLoc_Location L;
-    Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-    TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
-    tab = facing->Nodes();
-    for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
-      gp_Pnt pnt = tab.Value(i);
-      fprintf(fp, "%f %f %f\n", pnt.X(), pnt.Y(), pnt.Z());
-    }
-  }
-  fprintf(fp, "POLYGONS %d %d\n", countFace, countFace * 4);
-  int maxindex = 0;
-  for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) {
-    TopoDS_Face F = TopoDS::Face(Ex.Current());
-    TopLoc_Location L;
-    Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
-    TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
-    tab = facing->Nodes();
-    Poly_Array1OfTriangle tri(1, facing->NbTriangles());
-    tri = facing->Triangles();
-    for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
-      Poly_Triangle trian = tri.Value(i);
-      Standard_Integer index1, index2, index3;
-      trian.Get(index1, index2, index3);
-      fprintf(fp, "3 %d %d %d\n", maxindex + index1 - 1, maxindex + index2 - 1,
-              maxindex + index3 - 1);
-    }
-    maxindex += facing->NbNodes();
-  }
-  fclose(fp);
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/RenderingHelpers.cpp b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..af230c87276a01f61b3969d0b32097b240b5b1b5
--- /dev/null
+++ b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp
@@ -0,0 +1,330 @@
+#include "MantidGeometry/Rendering/RenderingHelpers.h"
+#include "MantidGeometry/IObjComponent.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Objects/IObject.h"
+#include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryTriangulator.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidGeometry/Surfaces/Cone.h"
+#include "MantidGeometry/Surfaces/Cylinder.h"
+#include "MantidGeometry/Surfaces/Sphere.h"
+#include "MantidKernel/Quat.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include <climits>
+
+#ifdef ENABLE_OPENCASCADE
+// Squash a warning coming out of an OpenCascade header
+#ifdef __INTEL_COMPILER
+#pragma warning disable 191
+#endif
+// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
+// used.
+// Undefine it here before we include the headers to avoid a warning
+#ifdef _MSC_VER
+#undef _USE_MATH_DEFINES
+#ifdef M_SQRT1_2
+#undef M_SQRT1_2
+#endif
+#endif
+
+GCC_DIAG_OFF(conversion)
+// clang-format off
+GCC_DIAG_OFF(cast-qual)
+// clang-format on
+#include <gp_Pnt.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp_Explorer.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <Poly_Triangulation.hxx>
+GCC_DIAG_ON(conversion)
+// clang-format off
+GCC_DIAG_ON(cast-qual)
+// clang-format on
+
+#ifdef __INTEL_COMPILER
+#pragma warning enable 191
+#endif
+#endif
+
+namespace Mantid {
+namespace Geometry {
+using Kernel::Quat;
+using Kernel::V3D;
+
+namespace {
+// Render IObjectComponent
+void render(const IObjComponent &ObjComp) {
+  glPushMatrix();
+  V3D pos = ObjComp.getPos();
+  Quat rot = ObjComp.getRotation();
+  double rotGL[16];
+  rot.GLMatrix(&rotGL[0]);
+  glTranslated(pos[0], pos[1], pos[2]);
+  glMultMatrixd(rotGL);
+  V3D scaleFactor = ObjComp.getScaleFactor();
+  glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
+  ObjComp.drawObject();
+  glPopMatrix();
+}
+
+// Render triangulated surface
+void render(detail::GeometryTriangulator &triangulator) {
+  const auto &faces = triangulator.getTriangleFaces();
+  const auto &points = triangulator.getTriangleVertices();
+  glBegin(GL_TRIANGLES);
+  V3D normal;
+  for (size_t i = 0; i < triangulator.numTriangleFaces(); i++) {
+    auto index2 = static_cast<size_t>(faces[i * 3 + 1] * 3);
+    auto index3 = static_cast<size_t>(faces[i * 3 + 2] * 3);
+    auto index1 = static_cast<size_t>(faces[i * 3] * 3);
+    // Calculate normal and normalize
+    V3D v1(points[index1], points[index1 + 1], points[index1 + 2]);
+    V3D v2(points[index2], points[index2 + 1], points[index2 + 2]);
+    V3D v3(points[index3], points[index3 + 1], points[index3 + 2]);
+    normal = (v1 - v2).cross_prod(v2 - v3);
+    normal.normalize();
+    glNormal3d(normal[0], normal[1], normal[2]);
+    glVertex3dv(&points[index1]);
+    glVertex3dv(&points[index2]);
+    glVertex3dv(&points[index3]);
+  }
+  glEnd();
+}
+
+#ifdef ENABLE_OPENCASCADE
+// Render OpenCascade Shape
+void render(const TopoDS_Shape &ObjSurf) {
+  glBegin(GL_TRIANGLES);
+  if (!ObjSurf.IsNull()) {
+    TopExp_Explorer Ex;
+    for (Ex.Init(ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) {
+      TopoDS_Face F = TopoDS::Face(Ex.Current());
+      TopLoc_Location L;
+      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
+      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
+      tab = facing->Nodes();
+      Poly_Array1OfTriangle tri(1, facing->NbTriangles());
+      tri = facing->Triangles();
+      for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
+        Poly_Triangle trian = tri.Value(i);
+        Standard_Integer index1, index2, index3;
+        trian.Get(index1, index2, index3);
+        gp_Pnt point1 = tab.Value(index1);
+        gp_Pnt point2 = tab.Value(index2);
+        gp_Pnt point3 = tab.Value(index3);
+        gp_XYZ pt1 = tab.Value(index1).XYZ();
+        gp_XYZ pt2 = tab.Value(index2).XYZ();
+        gp_XYZ pt3 = tab.Value(index3).XYZ();
+
+        gp_XYZ v1 = pt2 - pt1;
+        gp_XYZ v2 = pt3 - pt2;
+
+        gp_XYZ normal = v1 ^ v2;
+        normal.Normalize();
+        glNormal3d(normal.X(), normal.Y(), normal.Z());
+        glVertex3d(point1.X(), point1.Y(), point1.Z());
+        glVertex3d(point2.X(), point2.Y(), point2.Z());
+        glVertex3d(point3.X(), point3.Y(), point3.Z());
+      }
+    }
+  }
+  glEnd();
+}
+#endif
+
+void renderSphere(const detail::ShapeInfo &shapeInfo) {
+  // create glu sphere
+  GLUquadricObj *qobj = gluNewQuadric();
+  gluQuadricDrawStyle(qobj, GLU_FILL);
+  gluQuadricNormals(qobj, GL_SMOOTH);
+  glPushMatrix();
+  auto center = shapeInfo.points()[0];
+  glTranslated(center[0], center[1], center[2]);
+  gluSphere(qobj, shapeInfo.radius(), Sphere::g_nslices, Sphere::g_nstacks);
+  glPopMatrix();
+  gluDeleteQuadric(qobj);
+}
+
+void renderCuboid(const detail::ShapeInfo &shapeInfo) {
+  const auto &points = shapeInfo.points();
+  V3D vec0 = points[0];
+  V3D vec1 = points[1] - points[0];
+  V3D vec2 = points[2] - points[0];
+  V3D vec3 = points[3] - points[0];
+  V3D vertex[8];
+  vertex[0] = vec0;
+  vertex[1] = vec0 + vec3;
+  vertex[2] = vec0 + vec3 + vec1;
+  vertex[3] = vec0 + vec1;
+  vertex[4] = vec0 + vec2;
+  vertex[5] = vec0 + vec2 + vec3;
+  vertex[6] = vec0 + vec2 + vec3 + vec1;
+  vertex[7] = vec0 + vec1 + vec2;
+
+  int faceindex[6][4] = {
+      {0, 1, 2, 3}, // top
+      {0, 3, 7, 4}, // left
+      {3, 2, 6, 7}, // back
+      {2, 1, 5, 6}, // right
+      {0, 4, 5, 1}, // front
+      {4, 7, 6, 5}, // bottom
+  };
+  V3D normal;
+  // first face
+  glBegin(GL_QUADS);
+  for (auto &row : faceindex) {
+    normal = (vertex[row[0]] - vertex[row[1]])
+                 .cross_prod((vertex[row[0]] - vertex[row[2]]));
+    normal.normalize();
+    glNormal3d(normal[0], normal[1], normal[2]);
+    for (const int ij : row) {
+      if (ij == 0)
+        glTexCoord2i(0, 0);
+      if (ij == 1)
+        glTexCoord2i(1, 0);
+      if (ij == 2)
+        glTexCoord2i(1, 1);
+      if (ij == 3)
+        glTexCoord2i(0, 1);
+      if (ij == 4)
+        glTexCoord2i(0, 0);
+      if (ij == 5)
+        glTexCoord2i(1, 0);
+      if (ij == 6)
+        glTexCoord2i(1, 1);
+      if (ij == 7)
+        glTexCoord2i(0, 1);
+      glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]);
+    }
+  }
+  glEnd();
+}
+
+void renderHexahedron(const detail::ShapeInfo &shapeInfo) {
+  glBegin(GL_QUADS);
+  const auto &points = shapeInfo.points();
+  // bottom
+  glVertex3d(points[0].X(), points[0].Y(), points[0].Z());
+  glVertex3d(points[1].X(), points[1].Y(), points[1].Z());
+  glVertex3d(points[2].X(), points[2].Y(), points[2].Z());
+  glVertex3d(points[3].X(), points[3].Y(), points[3].Z());
+  // front
+  glVertex3d(points[1].X(), points[1].Y(), points[1].Z());
+  glVertex3d(points[5].X(), points[5].Y(), points[5].Z());
+  glVertex3d(points[6].X(), points[6].Y(), points[6].Z());
+  glVertex3d(points[2].X(), points[2].Y(), points[2].Z());
+  // right
+  glVertex3d(points[2].X(), points[2].Y(), points[2].Z());
+  glVertex3d(points[6].X(), points[6].Y(), points[6].Z());
+  glVertex3d(points[7].X(), points[7].Y(), points[7].Z());
+  glVertex3d(points[3].X(), points[3].Y(), points[3].Z());
+  // back
+  glVertex3d(points[3].X(), points[3].Y(), points[3].Z());
+  glVertex3d(points[7].X(), points[7].Y(), points[7].Z());
+  glVertex3d(points[4].X(), points[4].Y(), points[4].Z());
+  glVertex3d(points[0].X(), points[0].Y(), points[0].Z());
+  // left
+  glVertex3d(points[0].X(), points[0].Y(), points[0].Z());
+  glVertex3d(points[4].X(), points[4].Y(), points[4].Z());
+  glVertex3d(points[5].X(), points[5].Y(), points[5].Z());
+  glVertex3d(points[1].X(), points[1].Y(), points[1].Z());
+  // top
+  glVertex3d(points[4].X(), points[4].Y(), points[4].Z());
+  glVertex3d(points[5].X(), points[5].Y(), points[5].Z());
+  glVertex3d(points[6].X(), points[6].Y(), points[6].Z());
+  glVertex3d(points[7].X(), points[7].Y(), points[7].Z());
+
+  glEnd();
+}
+
+void renderCone(const detail::ShapeInfo &shapeInfo) {
+  glPushMatrix();
+  GLUquadricObj *qobj = gluNewQuadric();
+  gluQuadricDrawStyle(qobj, GLU_FILL);
+  gluQuadricNormals(qobj, GL_SMOOTH);
+  auto center = shapeInfo.points()[0];
+  glTranslated(center[0], center[1], center[2]);
+  GLdouble mat[16];
+  V3D unit(0, 0, 1);
+  auto axis = shapeInfo.points()[1];
+  Quat rot(unit, axis);
+  rot.GLMatrix(&mat[0]);
+  glMultMatrixd(mat);
+  auto radius = shapeInfo.radius();
+  auto height = shapeInfo.height();
+  gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices,
+              Geometry::Cone::g_nstacks);
+  glTranslated(0.0, 0.0, height);
+  gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1);
+  glPopMatrix();
+}
+
+void renderCylinder(const detail::ShapeInfo &shapeInfo) {
+  GLUquadricObj *qobj = gluNewQuadric();
+  gluQuadricDrawStyle(qobj, GLU_FILL);
+  gluQuadricNormals(qobj, GL_SMOOTH);
+  gluQuadricTexture(qobj, true);
+  glPushMatrix();
+  auto center = shapeInfo.points()[0];
+  glTranslated(center[0], center[1], center[2]);
+  GLdouble mat[16];
+  V3D unit(0, 0, 1);
+  auto axis = shapeInfo.points()[1];
+  Quat rot(unit, axis);
+  rot.GLMatrix(&mat[0]);
+  glMultMatrixd(mat);
+  auto radius = shapeInfo.radius();
+  auto height = shapeInfo.height();
+  gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices,
+              Cylinder::g_nstacks);
+  gluQuadricTexture(qobj, false);
+  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
+  glTranslated(0.0, 0.0, height);
+  gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1);
+  glPopMatrix();
+}
+} // namespace
+
+namespace RenderingHelpers {
+void renderIObjComponent(const IObjComponent &objComp) { render(objComp); }
+
+void renderTriangulated(detail::GeometryTriangulator &triangulator) {
+#ifdef ENABLE_OPENCASCADE
+  if (triangulator.hasOCSurface() && !triangulator.getOCSurface().IsNull())
+    render(triangulator.getOCSurface());
+  else
+    render(triangulator);
+#else
+  render(triangulator);
+#endif
+}
+
+void renderShape(const detail::ShapeInfo &shapeInfo) {
+  switch (shapeInfo.shape()) {
+  case detail::ShapeInfo::GeometryShape::CUBOID:
+    renderCuboid(shapeInfo);
+    break;
+  case detail::ShapeInfo::GeometryShape::SPHERE:
+    renderSphere(shapeInfo);
+    break;
+  case detail::ShapeInfo::GeometryShape::HEXAHEDRON:
+    renderHexahedron(shapeInfo);
+    break;
+  case detail::ShapeInfo::GeometryShape::CONE:
+    renderCone(shapeInfo);
+    break;
+  case detail::ShapeInfo::GeometryShape::CYLINDER:
+    renderCylinder(shapeInfo);
+    break;
+  default:
+    return;
+  }
+}
+} // namespace RenderingHelpers
+} // namespace Geometry
+} // namespace Mantid
diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1c6b7ba2c08ab6eda799a2fb790835f91d9fc3b3
--- /dev/null
+++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp
@@ -0,0 +1,74 @@
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidKernel/V3D.h"
+
+namespace Mantid {
+using Kernel::V3D;
+namespace Geometry {
+namespace detail {
+ShapeInfo::ShapeInfo()
+    : m_points(), m_radius(0), m_height(0),
+      m_shape(ShapeInfo::GeometryShape::NOSHAPE) {}
+
+const std::vector<Kernel::V3D> &ShapeInfo::points() const { return m_points; }
+
+double ShapeInfo::radius() const { return m_radius; }
+
+double ShapeInfo::height() const { return m_height; }
+
+ShapeInfo::GeometryShape ShapeInfo::shape() const { return m_shape; }
+
+void ShapeInfo::getObjectGeometry(ShapeInfo::GeometryShape &myshape,
+                                  std::vector<Kernel::V3D> &points,
+                                  double &myradius, double &myheight) const {
+  myshape = m_shape;
+  points = m_points;
+  myradius = m_radius;
+  myheight = m_height;
+}
+
+void ShapeInfo::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3,
+                          const V3D &p4) {
+  m_shape = GeometryShape::CUBOID;
+  m_points.assign({p1, p2, p3, p4});
+  m_radius = 0;
+  m_height = 0;
+}
+
+void ShapeInfo::setHexahedron(const V3D &p1, const V3D &p2, const V3D &p3,
+                              const V3D &p4, const V3D &p5, const V3D &p6,
+                              const V3D &p7, const V3D &p8) {
+  m_shape = GeometryShape::HEXAHEDRON;
+  m_points.assign({p1, p2, p3, p4, p5, p6, p7, p8});
+  m_radius = 0;
+  m_height = 0;
+}
+
+void ShapeInfo::setSphere(const V3D &c, double r) {
+  m_shape = GeometryShape::SPHERE;
+  m_points.assign({c});
+  m_radius = r;
+  m_height = 0;
+}
+
+void ShapeInfo::setCylinder(const V3D &c, const V3D &a, double r, double h) {
+  m_shape = GeometryShape::CYLINDER;
+  m_points.assign({c, a});
+  m_radius = r;
+  m_height = h;
+}
+
+void ShapeInfo::setCone(const V3D &c, const V3D &a, double r, double h) {
+  m_shape = GeometryShape::CONE;
+  m_points.assign({c, a});
+  m_radius = r;
+  m_height = h;
+}
+
+bool ShapeInfo::operator==(const ShapeInfo &other) {
+  return m_shape == other.m_shape && m_height == other.m_height &&
+         m_radius == other.m_radius && m_points == other.m_points;
+}
+
+} // namespace detail
+} // namespace Geometry
+} // namespace Mantid
\ No newline at end of file
diff --git a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp
deleted file mode 100644
index cb756fdfad08f6111bc8625c955574bc15fbdf51..0000000000000000000000000000000000000000
--- a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidGeometry/Rendering/OpenGL_Headers.h"
-#include "MantidGeometry/Rendering/StructuredGeometryHandler.h"
-#include <climits>
-#include <iostream>
-
-#include <boost/make_shared.hpp>
-
-namespace Mantid {
-namespace Geometry {
-using Kernel::V3D;
-
-/**
- * @return A shared_ptr to a new copy of this object
- */
-boost::shared_ptr<GeometryHandler> StructuredGeometryHandler::clone() const {
-  return boost::make_shared<StructuredGeometryHandler>(*this);
-}
-
-/// Parameter constructor
-StructuredGeometryHandler::StructuredGeometryHandler(StructuredDetector *comp)
-    : GeometryHandler(dynamic_cast<IObjComponent *>(comp)) {
-  // Save the structured detector link for later.
-  m_Det = comp;
-}
-
-StructuredGeometryHandler::StructuredGeometryHandler()
-    : GeometryHandler(static_cast<CSGObject *>(nullptr)), m_Det(nullptr) {}
-
-///< Create an instance of concrete geometry handler for ObjComponent
-StructuredGeometryHandler *
-StructuredGeometryHandler::createInstance(IObjComponent *) {
-  return new StructuredGeometryHandler();
-}
-
-///< Create an instance of concrete geometry handler for Object
-StructuredGeometryHandler *
-    StructuredGeometryHandler::createInstance(boost::shared_ptr<CSGObject>) {
-  return new StructuredGeometryHandler();
-}
-
-///< Create an instance of concrete geometry handler for Object
-GeometryHandler *StructuredGeometryHandler::createInstance(CSGObject *) {
-  return new StructuredGeometryHandler();
-}
-
-//----------------------------------------------------------------------------------------------
-/** Triangulate the Object - this function will not be used.
- *
- */
-void StructuredGeometryHandler::Triangulate() {
-  // do nothing
-}
-
-//----------------------------------------------------------------------------------------------
-///< Draw pixels according to StructuredDetector vertices
-void StructuredGeometryHandler::Render() {
-  V3D pos;
-
-  // Wait for no error
-  while (glGetError() != GL_NO_ERROR)
-    ;
-
-  auto xVerts = m_Det->getXValues();
-  auto yVerts = m_Det->getYValues();
-  auto r = m_Det->getR();
-  auto g = m_Det->getG();
-  auto b = m_Det->getB();
-
-  if (xVerts.size() != yVerts.size())
-    return;
-
-  auto w = m_Det->xPixels() + 1;
-  auto h = m_Det->yPixels() + 1;
-
-  glBegin(GL_QUADS);
-
-  for (size_t iy = 0; iy < h - 1; iy++) {
-    for (size_t ix = 0; ix < w - 1; ix++) {
-
-      glColor3ub((GLubyte)r[(iy * (w - 1)) + ix],
-                 (GLubyte)g[(iy * (w - 1)) + ix],
-                 (GLubyte)b[(iy * (w - 1)) + ix]);
-
-      pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0);
-      glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-                 static_cast<GLfloat>(pos.Z()));
-      pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1],
-                0.0);
-      glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-                 static_cast<GLfloat>(pos.Z()));
-      pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0);
-      glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-                 static_cast<GLfloat>(pos.Z()));
-      pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0);
-      glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
-                 static_cast<GLfloat>(pos.Z()));
-    }
-  }
-
-  glEnd();
-
-  if (glGetError() > 0)
-    std::cout << "OpenGL error in StructuredGeometryHandler::Render \n";
-
-  glDisable(
-      GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary.
-}
-
-//----------------------------------------------------------------------------------------------
-///< Prepare/Initialize Object/ObjComponent to be rendered
-void StructuredGeometryHandler::Initialize() {
-  // do nothing
-}
-}
-}
diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp
index a509c8b577b92b1f49a6eaa05ab2e6bbf996e36e..1b770483367e33edc7fba310da1e18134a62b487 100644
--- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp
+++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp
@@ -14,7 +14,6 @@
 #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h"
 
 using Poco::XML::DOMParser;
-using Poco::XML::Document;
 using Poco::XML::Element;
 
 namespace Mantid {
@@ -69,8 +68,8 @@ void vtkGeometryCacheReader::readCacheForObject(IObject *obj) {
   }
   // Read the cache from the element
   int noOfTriangles = 0, noOfPoints = 0;
-  double *Points;
-  int *Faces;
+  std::vector<double> Points;
+  std::vector<uint32_t> Faces;
   std::stringstream buff;
   // Read number of points
   buff << pEle->getAttribute("NumberOfPoints");
@@ -83,15 +82,16 @@ void vtkGeometryCacheReader::readCacheForObject(IObject *obj) {
 
   // Read Points
   Element *pPts = pEle->getChildElement("Points")->getChildElement("DataArray");
-  readPoints(pPts, &noOfPoints, &Points);
+  readPoints(pPts, noOfPoints, Points);
 
   // Read Triangles
   Element *pTris = pEle->getChildElement("Polys")->getChildElement("DataArray");
-  readTriangles(pTris, &noOfTriangles, &Faces);
+  readTriangles(pTris, noOfTriangles, Faces);
 
   // First check whether Object can be written to the file
   boost::shared_ptr<GeometryHandler> handle = obj->getGeometryHandler();
-  handle->setGeometryCache(noOfPoints, noOfTriangles, Points, Faces);
+  handle->setGeometryCache(noOfPoints, noOfTriangles, std::move(Points),
+                           std::move(Faces));
 }
 
 /**
@@ -112,14 +112,15 @@ vtkGeometryCacheReader::getElementByObjectName(std::string name) {
  * Read the points from the element
  */
 void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle,
-                                        int *noOfPoints, double **points) {
+                                        int noOfPoints,
+                                        std::vector<double> &points) {
   if (pEle == nullptr) {
-    *noOfPoints = 0;
+    noOfPoints = 0;
     return;
   }
   // Allocate memory
-  *points = new double[(*noOfPoints) * 3];
-  if (*points == nullptr) // Out of memory
+  points.resize(noOfPoints * 3);
+  if (points.size() != static_cast<size_t>(noOfPoints * 3)) // Out of memory
   {
     g_log.error("Cannot allocate memory for triangle cache of Object ");
     return;
@@ -127,25 +128,26 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle,
   if (pEle->getAttribute("format") == "ascii") { // Read from Ascii
     std::stringstream buf;
     buf << pEle->innerText();
-    for (int i = 0; i < (*noOfPoints) * 3; i++) {
-      buf >> (*points)[i];
+    for (double &point : points) {
+      buf >> point;
     }
-  } else { // Read from binary
   }
+  // Read from binary otherwise
 }
 
 /**
  * Read triangle face indexs
  */
 void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle,
-                                           int *noOfTriangles, int **faces) {
+                                           int noOfTriangles,
+                                           std::vector<uint32_t> &faces) {
   if (pEle == nullptr) {
-    *noOfTriangles = 0;
+    noOfTriangles = 0;
     return;
   }
   // Allocate memory
-  *faces = new int[(*noOfTriangles) * 3];
-  if (*faces == nullptr) // Out of memory
+  faces.resize(noOfTriangles * 3);
+  if (faces.size() != static_cast<size_t>(noOfTriangles * 3)) // Out of memory
   {
     g_log.error("Cannot allocate memory for triangle cache of Object ");
     return;
@@ -153,11 +155,11 @@ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle,
   if (pEle->getAttribute("format") == "ascii") { // Read from Ascii
     std::stringstream buf;
     buf << pEle->innerText();
-    for (int i = 0; i < (*noOfTriangles) * 3; i++) {
-      buf >> (*faces)[i];
+    for (unsigned int &face : faces) {
+      buf >> face;
     }
-  } else { // Read from binary
   }
+  // Read from binary otherwise
 }
 }
 }
diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp
index 8b23a7a86a41c6542f0be32efc49d34f92bcf806..93e1ef29884023f149b2e29b716f4e5cbff261ac 100644
--- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp
+++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp
@@ -85,9 +85,9 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) {
   // get the name of the Object
   int name = obj->getName();
   // get number of point
-  int noPts = handle->NumberOfPoints();
+  auto noPts = handle->numberOfPoints();
   // get number of triangles
-  int noTris = handle->NumberOfTriangles();
+  auto noTris = handle->numberOfTriangles();
   // Add Piece
   AutoPtr<Element> pPiece = mDoc->createElement("Piece");
   // Add attribute name
@@ -110,9 +110,9 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) {
   pPtsDataArray->setAttribute("format", "ascii");
   buf.str("");
   // get the triangles info
-  double *points = handle->getTriangleVertices();
-  int i;
-  for (i = 0; i < noPts * 3; i++) {
+  const auto &points = handle->getTriangleVertices();
+  size_t i;
+  for (i = 0; i < points.size(); i++) {
     buf << points[i] << " ";
   }
   AutoPtr<Text> pPointText = mDoc->createTextNode(buf.str());
@@ -122,13 +122,13 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) {
   AutoPtr<Element> pFaces = mDoc->createElement("Polys");
   AutoPtr<Element> pTrisDataArray = mDoc->createElement("DataArray");
   // add attribute
-  pTrisDataArray->setAttribute("type", "Int32");
+  pTrisDataArray->setAttribute("type", "UInt32");
   pTrisDataArray->setAttribute("Name", "connectivity");
   pTrisDataArray->setAttribute("format", "ascii");
 
   buf.str("");
-  int *faces = handle->getTriangleFaces();
-  for (i = 0; i < noTris * 3; i++) {
+  const auto &faces = handle->getTriangleFaces();
+  for (i = 0; i < faces.size(); i++) {
     buf << faces[i] << " ";
   }
   AutoPtr<Text> pTrisDataText = mDoc->createTextNode(buf.str());
@@ -137,7 +137,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) {
   // set the offsets
   AutoPtr<Element> pTrisOffsetDataArray = mDoc->createElement("DataArray");
   // add attribute
-  pTrisOffsetDataArray->setAttribute("type", "Int32");
+  pTrisOffsetDataArray->setAttribute("type", "UInt32");
   pTrisOffsetDataArray->setAttribute("Name", "offsets");
   pTrisOffsetDataArray->setAttribute("format", "ascii");
   buf.str("");
@@ -164,6 +164,7 @@ void vtkGeometryCacheWriter::write() {
   writer.setOptions(XMLWriter::PRETTY_PRINT);
   std::ofstream file;
   try {
+    g_log.information("Writing Geometry Cache file to " + mFileName);
     file.open(mFileName.c_str(), std::ios::trunc);
     writer.writeNode(file, mDoc);
     file.close();
diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h
index bf96ea743aad6c2c1899aace20da94259610546a..0c9f7bb10e417971079e96b04819fca94ea61924 100644
--- a/Framework/Geometry/test/CSGObjectTest.h
+++ b/Framework/Geometry/test/CSGObjectTest.h
@@ -10,7 +10,9 @@
 #include "MantidGeometry/Surfaces/SurfaceFactory.h"
 #include "MantidGeometry/Objects/Rules.h"
 #include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Rendering/GluGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/Material.h"
@@ -35,6 +37,7 @@
 using namespace Mantid;
 using namespace Geometry;
 using Mantid::Kernel::V3D;
+using detail::ShapeInfo;
 
 namespace {
 // -----------------------------------------------------------------------------
@@ -83,23 +86,22 @@ public:
     auto original_ptr = ComponentCreationHelper::createSphere(1.0);
     auto &original = dynamic_cast<CSGObject &>(*original_ptr);
     original.setID("sp-1");
-    int objType(-1);
+    ShapeInfo::GeometryShape objType;
     double radius(-1.0), height(-1.0);
     std::vector<V3D> pts;
+    auto handler = original.getGeometryHandler();
+    TS_ASSERT(handler->hasShapeInfo());
     original.GetObjectGeom(objType, pts, radius, height);
-    TS_ASSERT_EQUALS(3, objType);
-    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
-        original.getGeometryHandler()));
+    TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType);
 
     CSGObject copy(original);
-    // The copy should be a primitive object with a GluGeometryHandler
-    objType = -1;
+    // The copy should be a primitive object with a GeometryHandler
     copy.GetObjectGeom(objType, pts, radius, height);
 
     TS_ASSERT_EQUALS("sp-1", copy.id());
-    TS_ASSERT_EQUALS(3, objType);
-    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
-        copy.getGeometryHandler()));
+    auto handlerCopy = copy.getGeometryHandler();
+    TS_ASSERT(handlerCopy->hasShapeInfo());
+    TS_ASSERT_EQUALS(handler->shapeInfo(), handlerCopy->shapeInfo());
     TS_ASSERT_EQUALS(copy.getName(), original.getName());
     // Check the string representation is the same
     TS_ASSERT_EQUALS(copy.str(), original.str());
@@ -110,24 +112,24 @@ public:
     auto original_ptr = ComponentCreationHelper::createSphere(1.0);
     auto &original = dynamic_cast<CSGObject &>(*original_ptr);
     original.setID("sp-1");
-    int objType(-1);
+    ShapeInfo::GeometryShape objType;
     double radius(-1.0), height(-1.0);
     std::vector<V3D> pts;
+    auto handler = original.getGeometryHandler();
+    TS_ASSERT(handler->hasShapeInfo());
     original.GetObjectGeom(objType, pts, radius, height);
-    TS_ASSERT_EQUALS(3, objType);
-    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
-        original.getGeometryHandler()));
+    TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType);
 
     CSGObject lhs;  // initialize
     lhs = original; // assign
     // The copy should be a primitive object with a GluGeometryHandler
-    objType = -1;
     lhs.GetObjectGeom(objType, pts, radius, height);
 
     TS_ASSERT_EQUALS("sp-1", lhs.id());
-    TS_ASSERT_EQUALS(3, objType);
-    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
-        lhs.getGeometryHandler()));
+    TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType);
+    auto handlerCopy = lhs.getGeometryHandler();
+    TS_ASSERT(handlerCopy->hasShapeInfo());
+    TS_ASSERT_EQUALS(handlerCopy->shapeInfo(), handler->shapeInfo());
   }
 
   void testCreateUnitCube() {
@@ -793,10 +795,11 @@ public:
   {
     boost::shared_ptr<CSGObject> geom_obj = createSmallCappedCylinder();
     // Want to test triangulation so setup a geometry handler
-    boost::shared_ptr<GluGeometryHandler> h =
-        boost::shared_ptr<GluGeometryHandler>(
-            new GluGeometryHandler(geom_obj.get()));
-    h->setCylinder(V3D(-0.0015, 0.0, 0.0), V3D(1., 0.0, 0.0), 0.005, 0.003);
+    auto h = boost::make_shared<GeometryHandler>(geom_obj);
+    detail::ShapeInfo shapeInfo;
+    shapeInfo.setCylinder(V3D(-0.0015, 0.0, 0.0), V3D(1., 0.0, 0.0), 0.005,
+                          0.003);
+    h->setShapeInfo(std::move(shapeInfo));
     geom_obj->setGeometryHandler(h);
 
     double satol(1e-8); // tolerance for solid angle
@@ -1147,7 +1150,7 @@ public:
 
 private:
   /// Surface type
-  typedef std::map<int, boost::shared_ptr<Surface>> STYPE;
+  using STYPE = std::map<int, boost::shared_ptr<Surface>>;
 
   /// set timeTest true to get time comparisons of soild angle methods
   const static bool timeTest = false;
@@ -1240,7 +1243,7 @@ private:
 
     // PLANE SURFACES:
 
-    typedef std::pair<int, std::string> SCompT;
+    using SCompT = std::pair<int, std::string>;
     std::vector<SCompT> SurfLine;
     if (desired.find("60001") != std::string::npos)
       SurfLine.push_back(SCompT(60001, "px -1"));
@@ -1268,12 +1271,12 @@ private:
       SurfLine.push_back(SCompT(73, "s 0.6 0 0 0.4"));
 
     // Note that the testObject now manages the "new Plane"
-    for (auto vc = SurfLine.cbegin(); vc != SurfLine.cend(); ++vc) {
-      auto A = Geometry::SurfaceFactory::Instance()->processLine(vc->second);
+    for (const auto &vc : SurfLine) {
+      auto A = Geometry::SurfaceFactory::Instance()->processLine(vc.second);
       TSM_ASSERT("Expected a non-null surface from the factory", A);
-      A->setName(vc->first);
-      SMap.insert(STYPE::value_type(vc->first,
-                                    boost::shared_ptr<Surface>(A.release())));
+      A->setName(vc.first);
+      SMap.insert(
+          STYPE::value_type(vc.first, boost::shared_ptr<Surface>(A.release())));
     }
 
     return;
@@ -1441,9 +1444,11 @@ private:
 
     // Explicitly setting the GluGeometryHanler hexahedron allows
     // for the correct bounding box calculation.
-    auto handler = boost::make_shared<GluGeometryHandler>(retVal);
-    handler->setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft,
-                           hex.rft, hex.rbt);
+    auto handler = boost::make_shared<GeometryHandler>(retVal);
+    detail::ShapeInfo shapeInfo;
+    shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt,
+                            hex.lft, hex.rft, hex.rbt);
+    handler->setShapeInfo(std::move(shapeInfo));
     retVal->setGeometryHandler(handler);
 
     retVal->setObject(68, ObjHex);
diff --git a/Framework/Geometry/test/CenteringGroupTest.h b/Framework/Geometry/test/CenteringGroupTest.h
index 16667f7f017bdb7a8e90f539a705be9201534279..8db17e52a86d6f3ccfb7cf88d8cc7fae5b96425b 100644
--- a/Framework/Geometry/test/CenteringGroupTest.h
+++ b/Framework/Geometry/test/CenteringGroupTest.h
@@ -65,10 +65,10 @@ private:
     TSM_ASSERT_EQUALS("Unexpected number of operations for " + symbol,
                       ops.size(), expectedOperations.size());
 
-    for (auto it = expectedOperations.begin(); it != expectedOperations.end();
-         ++it) {
-      TSM_ASSERT("Operation " + (*it).identifier() + " not found in " + symbol,
-                 symOpExistsInCollection(*it, ops));
+    for (const auto &expectedOperation : expectedOperations) {
+      TSM_ASSERT("Operation " + expectedOperation.identifier() +
+                     " not found in " + symbol,
+                 symOpExistsInCollection(expectedOperation, ops));
     }
 
     CenteringGroup_const_sptr centeringGroup =
diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h
index f4282e4ef0fc0a1001fd6ed3fa0f80ed8a4ba124..1bb68e32000b35b7496f878fb80cf1d449d08576 100644
--- a/Framework/Geometry/test/ComponentInfoTest.h
+++ b/Framework/Geometry/test/ComponentInfoTest.h
@@ -107,12 +107,13 @@ std::unique_ptr<Beamline::ComponentInfo> makeSingleBeamlineComponentInfo(
       boost::make_shared<std::vector<Eigen::Vector3d>>(1, scaleFactor);
   auto names = boost::make_shared<std::vector<std::string>>(1);
   using Mantid::Beamline::ComponentType;
-  auto isStructuredBank =
+  auto componentType =
       boost::make_shared<std::vector<ComponentType>>(1, ComponentType::Generic);
+  auto children = boost::make_shared<std::vector<std::vector<size_t>>>(1);
   return Kernel::make_unique<Beamline::ComponentInfo>(
       detectorIndices, detectorRanges, componentIndices, componentRanges,
-      parentIndices, positions, rotations, scaleFactors, isStructuredBank,
-      names, -1, -1);
+      parentIndices, children, positions, rotations, scaleFactors,
+      componentType, names, -1, -1);
 }
 } // namespace
 
@@ -156,10 +157,12 @@ public:
     using Mantid::Beamline::ComponentType;
     auto isRectBank = boost::make_shared<std::vector<ComponentType>>(
         2, ComponentType::Generic);
+    auto children = boost::make_shared<std::vector<std::vector<size_t>>>(
+        1, std::vector<size_t>(1));
     auto internalInfo = Kernel::make_unique<Beamline::ComponentInfo>(
         detectorIndices, detectorRanges, componentIndices, componentRanges,
-        parentIndices, positions, rotations, scaleFactors, isRectBank, names,
-        -1, -1);
+        parentIndices, children, positions, rotations, scaleFactors, isRectBank,
+        names, -1, -1);
     Mantid::Geometry::ObjComponent comp1("component1");
     Mantid::Geometry::ObjComponent comp2("component2");
 
@@ -647,6 +650,47 @@ public:
     TS_ASSERT_EQUALS(infoScan1->position({0 /*detector index*/, 1}),
                      detectorPos);
   }
+
+  void test_throws_if_ComponentType_is_not_Quadrilateral() {
+    auto instrument =
+        ComponentCreationHelper::createTestInstrumentRectangular2(1, 4);
+    auto wrappers = InstrumentVisitor::makeWrappers(*instrument);
+    const auto &componentInfo = std::get<0>(wrappers);
+
+    // find quadrilateral component
+    size_t structuredIndex = componentInfo->root() - 3;
+    // Does not throw for valid index
+    TS_ASSERT_THROWS_NOTHING(
+        componentInfo->quadrilateralComponent(structuredIndex));
+    // Throws for other non quadrilateral component
+    TS_ASSERT_THROWS(
+        componentInfo->quadrilateralComponent(componentInfo->root() - 1),
+        std::runtime_error &);
+    // Throws for root
+    TS_ASSERT_THROWS(
+        componentInfo->quadrilateralComponent(componentInfo->root()),
+        std::runtime_error &);
+    // Throws for detector
+    TS_ASSERT_THROWS(componentInfo->quadrilateralComponent(0),
+                     std::runtime_error &);
+  }
+
+  void test_QuadrilateralComponent_for_single_rectangular_bank() {
+    auto instrument =
+        ComponentCreationHelper::createTestInstrumentRectangular2(1, 4);
+    auto wrappers = InstrumentVisitor::makeWrappers(*instrument);
+    const auto &componentInfo = std::get<0>(wrappers);
+
+    // find quadrilateral component
+    size_t structuredIndex = componentInfo->root() - 3;
+    auto panel = componentInfo->quadrilateralComponent(structuredIndex);
+    TS_ASSERT_EQUALS(panel.nX, 4);
+    TS_ASSERT_EQUALS(panel.nY, 4);
+    TS_ASSERT_EQUALS(panel.bottomLeft, 0);
+    TS_ASSERT_EQUALS(panel.bottomRight, 12);
+    TS_ASSERT_EQUALS(panel.topLeft, 3);
+    TS_ASSERT_EQUALS(panel.topRight, 15);
+  }
 };
 
 #endif /* MANTID_GEOMETRY_COMPONENTINFOTEST_H_ */
diff --git a/Framework/Geometry/test/CompositeBraggScattererTest.h b/Framework/Geometry/test/CompositeBraggScattererTest.h
index cb65396fb3992bd3a025ad5fa056ad3f3e16fc7a..0ca949e61226c8a4b5f7ec3e58cffe7bf2e2b3a8 100644
--- a/Framework/Geometry/test/CompositeBraggScattererTest.h
+++ b/Framework/Geometry/test/CompositeBraggScattererTest.h
@@ -130,9 +130,9 @@ public:
         spaceGroup->getEquivalentPositions(V3D(0.2, 0.3, 0.4));
 
     CompositeBraggScatterer_sptr coll = CompositeBraggScatterer::create();
-    for (auto pos = positions.begin(); pos != positions.end(); ++pos) {
+    for (auto &position : positions) {
       std::ostringstream strm;
-      strm << (*pos);
+      strm << position;
       coll->addScatterer(getInitializedScatterer("Si", strm.str(), 0.01267));
     }
 
diff --git a/Framework/Geometry/test/CrystalStructureTest.h b/Framework/Geometry/test/CrystalStructureTest.h
index 0675a65b79941716912b3905c9df6dc18bcb5665..ccd22be238186667360bad74b1d6dfec6af4e067 100644
--- a/Framework/Geometry/test/CrystalStructureTest.h
+++ b/Framework/Geometry/test/CrystalStructureTest.h
@@ -29,7 +29,7 @@ public:
     m_scatterers->addScatterer(
         BraggScattererFactory::Instance().createScatterer(
             "IsotropicAtomBraggScatterer",
-            "{\"Element\":\"Si\",\"Position\":\"0,0,0\"}"));
+            R"({"Element":"Si","Position":"0,0,0"})"));
   }
 
   void testConstructionSpaceGroup() {
diff --git a/Framework/Geometry/test/GoniometerTest.h b/Framework/Geometry/test/GoniometerTest.h
index 7cfad5d1b3fb4dfaac13bceeaa4b28c1b3f75f3c..afcdf3a9a3a604cb29b4c96ba3e131a8967a1e44 100644
--- a/Framework/Geometry/test/GoniometerTest.h
+++ b/Framework/Geometry/test/GoniometerTest.h
@@ -179,6 +179,56 @@ public:
         }
   }
 
+  void test_calcFromQSampleAndWavelength() {
+    Goniometer G;
+    double wavelength = 2 * M_PI; // k=1
+    DblMatrix R;
+    V3D Q;
+
+    // 0 degree rotation
+    Q = V3D(-1, 0, 1);
+    G.calcFromQSampleAndWavelength(Q, wavelength);
+    R = G.getR();
+    TS_ASSERT_DELTA(R[0][0], 1.0, 0.001);
+    TS_ASSERT_DELTA(R[0][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[0][2], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[1][0], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[1][1], 1.0, 0.001);
+    TS_ASSERT_DELTA(R[1][2], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][0], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][2], 1.0, 0.001);
+
+    // -90 degree rotation
+    Q = V3D(1, 0, 1);
+    G.calcFromQSampleAndWavelength(Q, wavelength);
+    R = G.getR();
+    TS_ASSERT_DELTA(R[0][0], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[0][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[0][2], -1.0, 0.001);
+    TS_ASSERT_DELTA(R[1][0], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[1][1], 1.0, 0.001);
+    TS_ASSERT_DELTA(R[1][2], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][0], 1.0, 0.001);
+    TS_ASSERT_DELTA(R[2][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][2], 0.0, 0.001);
+
+    // 30 degree rotation
+    wavelength = 1.54;
+    Q = V3D(-0.63523489, -0.12302677, -0.29517982);
+    G.calcFromQSampleAndWavelength(Q, wavelength);
+    R = G.getR();
+    TS_ASSERT_DELTA(R[0][0], 0.866, 0.001);
+    TS_ASSERT_DELTA(R[0][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[0][2], 0.5, 0.01);
+    TS_ASSERT_DELTA(R[1][0], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[1][1], 1.0, 0.001);
+    TS_ASSERT_DELTA(R[1][2], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][0], -0.5, 0.01);
+    TS_ASSERT_DELTA(R[2][1], 0.0, 0.001);
+    TS_ASSERT_DELTA(R[2][2], 0.866, 0.001);
+  }
+
   /** Save and load to NXS file */
   void test_nexus() {
     NexusTestHelper th(true);
diff --git a/Framework/Geometry/test/GroupTransformationTest.h b/Framework/Geometry/test/GroupTransformationTest.h
index e583286acb052eadbc62e08dbb1767e9090624d0..8d54c5029f02ff1f7f1f57e89315b74f0933b651 100644
--- a/Framework/Geometry/test/GroupTransformationTest.h
+++ b/Framework/Geometry/test/GroupTransformationTest.h
@@ -51,9 +51,9 @@ public:
      */
     std::unordered_set<std::string> elements;
     std::vector<SymmetryOperation> ops = transformed.getSymmetryOperations();
-    for (auto op = ops.begin(); op != ops.end(); ++op) {
+    for (auto &op : ops) {
       SymmetryElement_sptr el =
-          SymmetryElementFactory::Instance().createSymElement(*op);
+          SymmetryElementFactory::Instance().createSymElement(op);
 
       // Check for identity
       SymmetryElementIdentity_sptr identity =
diff --git a/Framework/Geometry/test/IndexingUtilsTest.h b/Framework/Geometry/test/IndexingUtilsTest.h
index 200bd61e8ec9d09bda9f2c7bc6f25e2f5adc4104..8c28ab07fc5b86e270cd4a97aa8dc897d0864745 100644
--- a/Framework/Geometry/test/IndexingUtilsTest.h
+++ b/Framework/Geometry/test/IndexingUtilsTest.h
@@ -29,8 +29,8 @@ public:
                                {-0.90478, -0.50667, 0.51072},
                                {-0.50387, -0.58561, 0.43502}};
     // Dec 2011: Change convention for Q = 2 pi / wavelength
-    for (size_t i = 0; i < q_vectors.size(); i++)
-      q_vectors[i] *= (2.0 * M_PI);
+    for (auto &q_vector : q_vectors)
+      q_vector *= (2.0 * M_PI);
     return q_vectors;
   }
 
@@ -232,8 +232,8 @@ public:
   void test_Optimize_Direction() {
     std::vector<int> index_values;
     int correct_indices[] = {1, 4, 2, 0, 1, 3, 0, -1, 0, -1, -2, -3};
-    for (size_t i = 0; i < 12; i++) {
-      index_values.push_back(correct_indices[i]);
+    for (int correct_index : correct_indices) {
+      index_values.push_back(correct_index);
     }
 
     std::vector<V3D> q_vectors = getNatroliteQs();
@@ -372,8 +372,8 @@ public:
                             {2.66668320, 5.29605670, 7.9653444}};
 
     std::vector<V3D> directions;
-    for (size_t i = 0; i < 5; i++)
-      directions.emplace_back(vectors[i][0], vectors[i][1], vectors[i][2]);
+    for (auto &vector : vectors)
+      directions.emplace_back(vector[0], vector[1], vector[2]);
 
     double required_tolerance = 0.12;
     size_t a_index = 0;
@@ -410,8 +410,8 @@ public:
                             {2.66668320, 5.29605670, 7.9653444}};
 
     std::vector<V3D> directions;
-    for (size_t i = 0; i < 5; i++)
-      directions.emplace_back(vectors[i][0], vectors[i][1], vectors[i][2]);
+    for (auto &vector : vectors)
+      directions.emplace_back(vector[0], vector[1], vector[2]);
 
     std::vector<V3D> q_vectors = getNatroliteQs();
     double required_tolerance = 0.12;
@@ -756,8 +756,8 @@ public:
     TS_ASSERT_DELTA(direction_list[7].Z(), -0.211325, 1e-5);
 
     double dot_prod;
-    for (size_t i = 0; i < direction_list.size(); i++) {
-      dot_prod = axis.scalar_prod(direction_list[i]);
+    for (const auto &direction : direction_list) {
+      dot_prod = axis.scalar_prod(direction);
       TS_ASSERT_DELTA(dot_prod, 0, 1e-10);
     }
   }
diff --git a/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Framework/Geometry/test/InstrumentDefinitionParserTest.h
index 45a1802fc948a4760c9e874cc8c640f230380777..ea47421b1f6a457f5525f0afa44f86f278406007 100644
--- a/Framework/Geometry/test/InstrumentDefinitionParserTest.h
+++ b/Framework/Geometry/test/InstrumentDefinitionParserTest.h
@@ -891,7 +891,7 @@ public:
 
   void testLocationsNaming() {
     std::string locations =
-        "<locations n-elements=\" 5\" name-count-start=\" 10\" name=\"det\" />";
+        R"(<locations n-elements=" 5" name-count-start=" 10" name="det" />)";
     detid_t numDetectors = 5;
 
     Instrument_sptr instr = loadInstrLocations(locations, numDetectors);
@@ -903,7 +903,7 @@ public:
 
   void testLocationsStaticValues() {
     std::string locations =
-        "<locations n-elements=\"5\" x=\" 1.0\" y=\" 2.0\" z=\" 3.0\" />";
+        R"(<locations n-elements="5" x=" 1.0" y=" 2.0" z=" 3.0" />)";
     detid_t numDetectors = 5;
 
     Instrument_sptr instr = loadInstrLocations(locations, numDetectors);
@@ -986,13 +986,13 @@ public:
 
   void testLocationsInvalidNoElements() {
     std::string locations =
-        "<locations n-elements=\"0\" t=\"0.0\" t-end=\"180.0\" />";
+        R"(<locations n-elements="0" t="0.0" t-end="180.0" />)";
     detid_t numDetectors = 2;
 
     TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true),
                      Exception::InstrumentDefinitionError);
 
-    locations = "<locations n-elements=\"-1\" t=\"0.0\" t-end=\"180.0\" />";
+    locations = R"(<locations n-elements="-1" t="0.0" t-end="180.0" />)";
 
     TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true),
                      Exception::InstrumentDefinitionError);
@@ -1000,28 +1000,28 @@ public:
 
   void testLocationsNotANumber() {
     std::string locations =
-        "<locations n-elements=\"2\" t=\"0.0\" t-end=\"180.x\" />";
+        R"(<locations n-elements="2" t="0.0" t-end="180.x" />)";
     detid_t numDetectors = 2;
 
     TS_ASSERT_THROWS_ANYTHING(
         loadInstrLocations(locations, numDetectors, true));
 
-    locations = "<locations n-elements=\"2\" t=\"0.x\" t-end=\"180.0\" />";
+    locations = R"(<locations n-elements="2" t="0.x" t-end="180.0" />)";
 
     TS_ASSERT_THROWS_ANYTHING(
         loadInstrLocations(locations, numDetectors, true));
 
-    locations = "<locations n-elements=\"x\" t=\"0.0\" t-end=\"180.0\" />";
+    locations = R"(<locations n-elements="x" t="0.0" t-end="180.0" />)";
     TS_ASSERT_THROWS_ANYTHING(
         loadInstrLocations(locations, numDetectors, true));
 
-    locations = "<locations n-elements=\"2\" name-count-start=\"x\"/>";
+    locations = R"(<locations n-elements="2" name-count-start="x"/>)";
     TS_ASSERT_THROWS_ANYTHING(
         loadInstrLocations(locations, numDetectors, true));
   }
 
   void testLocationsNoCorrespondingStartAttr() {
-    std::string locations = "<locations n-elements=\"2\" t-end=\"180.0\" />";
+    std::string locations = R"(<locations n-elements="2" t-end="180.0" />)";
     detid_t numDetectors = 2;
 
     TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true),
diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h
index 3a656cf489f62bec3f39964b3140665e740971bc..dbd6ecf5eec65b0b8c3274f170ba363fae1c086d 100644
--- a/Framework/Geometry/test/InstrumentVisitorTest.h
+++ b/Framework/Geometry/test/InstrumentVisitorTest.h
@@ -244,8 +244,7 @@ public:
   void test_visitor_component_ranges_check() {
     // Create a very basic instrument to visit
     auto visitee = createMinimalInstrument(V3D(0, 0, 0) /*source pos*/,
-                                           V3D(10, 0, 0) /*sample pos*/
-                                           ,
+                                           V3D(10, 0, 0) /*sample pos*/,
                                            V3D(11, 0, 0) /*detector position*/);
 
     InstrumentVisitor visitor(makeParameterized(visitee));
@@ -441,6 +440,57 @@ public:
     TS_ASSERT_EQUALS(detScaling, compInfo->scaleFactor(0));
     TS_ASSERT_EQUALS(instrScaling, compInfo->scaleFactor(compInfo->root()));
   }
+
+  void test_instrumentTreeWithMinimalInstrument() {
+    /** This should produce the following instrument tree
+     *   3
+     * / | \
+     *0  1  2
+     */
+    auto instrument =
+        createMinimalInstrument(V3D(0, 0, 0), V3D(0, 0, 1), V3D(0, 0, 10));
+    auto visitor = InstrumentVisitor(instrument);
+
+    visitor.walkInstrument();
+
+    auto componentInfo = visitor.componentInfo();
+    auto root = componentInfo->root();
+    TS_ASSERT_EQUALS(componentInfo->children(0).size(), 0);
+    TS_ASSERT_EQUALS(componentInfo->children(1).size(), 0);
+    TS_ASSERT_EQUALS(componentInfo->children(2).size(), 0);
+    TS_ASSERT_EQUALS(componentInfo->children(root).size(), 3);
+  }
+
+  void test_instrumentTreeWithComplexInstrument() {
+    /** This should produce the following instrument tree
+     *               16
+     *   /      /      \                \
+     * 14      15       10              13
+     *                /    \          /   \
+     *               8      9      11       12
+     *             /  \   /  \    /  \    /   \
+     *            0    1  2   3  4    5   6    7
+     */
+    auto instrument = createTestInstrumentRectangular2(2, 2);
+    auto visitor = InstrumentVisitor(instrument);
+
+    visitor.walkInstrument();
+
+    auto componentInfo = visitor.componentInfo();
+    auto root = componentInfo->root();
+    for (int i = 0; i < 8; i++)
+      TS_ASSERT_EQUALS(componentInfo->children(i).size(), 0);
+
+    TS_ASSERT_EQUALS(componentInfo->children(root).size(), 4);
+    TS_ASSERT_EQUALS(componentInfo->children(8).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(9).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(11).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(12).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(10).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(13).size(), 2);
+    TS_ASSERT_EQUALS(componentInfo->children(14).size(), 0);
+    TS_ASSERT_EQUALS(componentInfo->children(15).size(), 0);
+  }
 };
 
 class InstrumentVisitorTestPerformance : public CxxTest::TestSuite {
diff --git a/Framework/Geometry/test/MDBoxImplicitFunctionTest.h b/Framework/Geometry/test/MDBoxImplicitFunctionTest.h
index e27544409c8f17e2117c039d93023797d735ae22..38c8ea2c8ffe06af7d6aba5ea39a3636b7ee48f1 100644
--- a/Framework/Geometry/test/MDBoxImplicitFunctionTest.h
+++ b/Framework/Geometry/test/MDBoxImplicitFunctionTest.h
@@ -11,7 +11,7 @@ using namespace Mantid;
 using namespace Mantid::Geometry;
 
 namespace {
-typedef boost::tuple<Mantid::coord_t, Mantid::coord_t> Extent;
+using Extent = boost::tuple<Mantid::coord_t, Mantid::coord_t>;
 }
 
 class MDBoxImplicitFunctionTest : public CxxTest::TestSuite {
diff --git a/Framework/Geometry/test/MDGeometryXMLParserTest.h b/Framework/Geometry/test/MDGeometryXMLParserTest.h
index 00c7187b4343efbd03108803c51eb56fa5d5183d..4137571754c48e63ad505b1766240c72feaae504 100644
--- a/Framework/Geometry/test/MDGeometryXMLParserTest.h
+++ b/Framework/Geometry/test/MDGeometryXMLParserTest.h
@@ -12,7 +12,7 @@ public:
                                   const std::string &yDimensionIdMapping,
                                   const std::string &zDimensionIdMapping,
                                   const std::string &tDimensionIdMapping) {
-    return std::string("<?xml version=\"1.0\" encoding=\"utf-8\"?>") +
+    return std::string(R"(<?xml version="1.0" encoding="utf-8"?>)") +
            "<DimensionSet>" + "<Dimension ID=\"en\">" + "<Name>Energy</Name>" +
            "<UpperBounds>150</UpperBounds>" + "<LowerBounds>0</LowerBounds>" +
            "<NumberOfBins>1</NumberOfBins>" + "</Dimension>" +
diff --git a/Framework/Geometry/test/MatrixVectorPairTest.h b/Framework/Geometry/test/MatrixVectorPairTest.h
index 5cd141103460f439b4e41e561caba443b79a971a..160907e874b469e2d4b5079e3475023c5c74a005 100644
--- a/Framework/Geometry/test/MatrixVectorPairTest.h
+++ b/Framework/Geometry/test/MatrixVectorPairTest.h
@@ -10,7 +10,7 @@
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
 
-typedef MatrixVectorPair<int, V3R> V3RIntPair;
+using V3RIntPair = MatrixVectorPair<int, V3R>;
 
 class MatrixVectorPairTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/Geometry/test/MeshObjectTest.h b/Framework/Geometry/test/MeshObjectTest.h
index 61f176997572f7c6950fd34de3c94f4b7197bb22..65b2c6ac1e6a99fc962a5183011c318caf581cc2 100644
--- a/Framework/Geometry/test/MeshObjectTest.h
+++ b/Framework/Geometry/test/MeshObjectTest.h
@@ -5,7 +5,7 @@
 
 #include "MantidGeometry/Math/Algebra.h"
 #include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Rendering/CacheGeometryHandler.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/Material.h"
diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h
index 5427e27c2623b7e53151e744c159149af3d7485b..168b8db8a002d858eba0ece05e8270c6e9105826 100644
--- a/Framework/Geometry/test/MockObjects.h
+++ b/Framework/Geometry/test/MockObjects.h
@@ -11,6 +11,7 @@
 #include "MantidGeometry/Crystal/IPeak.h"
 #include "MantidGeometry/Crystal/PeakTransform.h"
 #include "MantidGeometry/Crystal/PeakTransformFactory.h"
+#include "MantidGeometry/Objects/InstrumentRayTracer.h"
 #include "MantidKernel/SpecialCoordinateSystem.h"
 #include "MantidKernel/WarningSuppressions.h"
 #include <boost/regex.hpp>
@@ -65,7 +66,9 @@ public:
   MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr());
   MOCK_CONST_METHOD0(getInstrument, Geometry::Instrument_const_sptr());
   MOCK_CONST_METHOD0(getRunNumber, int());
+  MOCK_CONST_METHOD0(getPeakNumber, int());
   MOCK_METHOD1(setRunNumber, void(int m_RunNumber));
+  MOCK_METHOD1(setPeakNumber, void(int m_PeakNumber));
   MOCK_CONST_METHOD0(getMonitorCount, double());
   MOCK_METHOD1(setMonitorCount, void(double m_MonitorCount));
   MOCK_CONST_METHOD0(getH, double());
@@ -80,6 +83,8 @@ public:
   MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
   MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
   MOCK_METHOD0(findDetector, bool());
+  MOCK_METHOD1(findDetector,
+               bool(const Mantid::Geometry::InstrumentRayTracer &tracer));
   MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame,
                                      boost::optional<double> detectorDistance));
   MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame,
@@ -87,6 +92,7 @@ public:
   MOCK_METHOD1(setWavelength, void(double wavelength));
   MOCK_CONST_METHOD0(getWavelength, double());
   MOCK_CONST_METHOD0(getScattering, double());
+  MOCK_CONST_METHOD0(getAzimuthal, double());
   MOCK_CONST_METHOD0(getDSpacing, double());
   MOCK_CONST_METHOD0(getTOF, double());
   MOCK_CONST_METHOD0(getInitialEnergy, double());
diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h
index 4956b67a238a9c07931b3cb2d31e8c9826599f65..1c823495acf779fdadc2989c6e5bb601eda57139 100644
--- a/Framework/Geometry/test/ObjCompAssemblyTest.h
+++ b/Framework/Geometry/test/ObjCompAssemblyTest.h
@@ -337,8 +337,8 @@ public:
     std::stringstream obj_str;
     obj_str << "<cylinder id=\"stick\">";
     obj_str << "<centre-of-bottom-base ";
-    obj_str << "x=\"0\" y=\"0\" z=\"0\" />";
-    obj_str << "<axis x=\"0\" y=\"1\" z=\"0\" /> ";
+    obj_str << R"(x="0" y="0" z="0" />)";
+    obj_str << R"(<axis x="0" y="1" z="0" /> )";
     obj_str << "<radius val=\"0.1\" />";
     obj_str << "<height val=\"0.2\" />";
     obj_str << "</cylinder>";
@@ -359,25 +359,22 @@ public:
     boost::shared_ptr<IObject> shape = bank.createOutline();
     TS_ASSERT(shape);
 
-    int otype;
+    detail::ShapeInfo::GeometryShape otype;
     std::vector<V3D> vectors;
     double radius, height;
     shape->GetObjectGeom(otype, vectors, radius, height);
 
-    TS_ASSERT_EQUALS(otype, 6);
+    TS_ASSERT_EQUALS(otype, detail::ShapeInfo::GeometryShape::CYLINDER);
     TS_ASSERT_EQUALS(radius, 0.1);
     TS_ASSERT_EQUALS(height, 0.6);
   }
 
   void test_fail_CreateOutline_for_wrong_component_type() {
     std::stringstream obj_str;
-    obj_str << "<segmented-cylinder id=\"stick\">";
-    obj_str << "<centre-of-bottom-base ";
-    obj_str << "x=\"0\" y=\"0\" z=\"0\" />";
-    obj_str << "<axis x=\"0\" y=\"1\" z=\"0\" /> ";
+    obj_str << "<sphere id=\"A\">";
+    obj_str << "<centre x=\"4.1\"  y=\"2.1\" z=\"8.1\" />";
     obj_str << "<radius val=\"0.1\" />";
-    obj_str << "<height val=\"0.2\" />";
-    obj_str << "</segmented-cylinder>";
+    obj_str << "</sphere>";
     auto s = Mantid::Geometry::ShapeFactory().createShape(obj_str.str());
 
     ObjCompAssembly bank("BankName");
diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h
index 7710e6233bbcea6b68ab1c83487f32ac45da4fcc..6584f674df8c574f8acada58f18f67ec5496da07 100644
--- a/Framework/Geometry/test/ParObjCompAssemblyTest.h
+++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h
@@ -107,13 +107,12 @@ public:
 
     TS_ASSERT_EQUALS(pcomp.type(), "ObjCompAssembly");
   }
-
   void testCreateOutlineCylinder() {
     std::stringstream obj_str;
     obj_str << "<cylinder id=\"stick\">";
     obj_str << "<centre-of-bottom-base ";
-    obj_str << "x=\"0\" y=\"0\" z=\"0\" />";
-    obj_str << "<axis x=\"0\" y=\"1\" z=\"0\" /> ";
+    obj_str << R"(x="0" y="0" z="0" />)";
+    obj_str << R"(<axis x="0" y="1" z="0" /> )";
     obj_str << "<radius val=\"0.1\" />";
     obj_str << "<height val=\"0.2\" />";
     obj_str << "</cylinder>";
@@ -135,12 +134,12 @@ public:
     boost::shared_ptr<IObject> shape = bank.createOutline();
     TS_ASSERT(shape);
 
-    int otype;
+    detail::ShapeInfo::GeometryShape otype;
     std::vector<V3D> vectors;
     double radius, height;
     shape->GetObjectGeom(otype, vectors, radius, height);
 
-    TS_ASSERT_EQUALS(otype, 6);
+    TS_ASSERT_EQUALS(otype, detail::ShapeInfo::GeometryShape::CYLINDER);
     TS_ASSERT_EQUALS(radius, 0.1);
     TS_ASSERT_EQUALS(height, 0.6);
 
diff --git a/Framework/Geometry/test/ParameterMapTest.h b/Framework/Geometry/test/ParameterMapTest.h
index c9da12fe965cc4daf87ff7f0d5fc1d546f95909c..cac00aafd7ec8ca66623aece35a6bea3c13fd7a1 100644
--- a/Framework/Geometry/test/ParameterMapTest.h
+++ b/Framework/Geometry/test/ParameterMapTest.h
@@ -304,9 +304,9 @@ public:
   test_Replacing_Existing_Parameter_On_A_Copy_Does_Not_Update_Original_Value_Using_AddHelpers_As_Strings() {
     // -- Specialized Helper Functions --
 
-    typedef boost::function<void(ParameterMap *, const IComponent *,
-                                 const std::string &, const std::string &,
-                                 const std::string *const)> AddFuncHelper;
+    using AddFuncHelper = boost::function<void(
+        ParameterMap *, const IComponent *, const std::string &,
+        const std::string &, const std::string *const)>;
 
     // double
     AddFuncHelper faddDouble;
@@ -513,7 +513,7 @@ public:
     Parameter_sptr fetchedValue =
         pmap.getByType(comp.get(), ParameterMap::pDouble());
     TSM_ASSERT("Should not be able to find a double type parameter",
-               fetchedValue == NULL);
+               fetchedValue == nullptr);
   }
 
   void test_lookup_via_type() {
@@ -551,7 +551,7 @@ public:
     // Find it via the component
     Parameter_sptr fetchedValue =
         pmap.getRecursiveByType(component.get(), ParameterMap::pBool());
-    TS_ASSERT(fetchedValue != NULL);
+    TS_ASSERT(fetchedValue != nullptr);
     TS_ASSERT_EQUALS("A", fetchedValue->name());
     TS_ASSERT_EQUALS(ParameterMap::pBool(), fetchedValue->type());
     TS_ASSERT_EQUALS(true, fetchedValue->value<bool>());
@@ -568,7 +568,7 @@ public:
     // Find it via the child
     Parameter_sptr fetchedValue =
         pmap.getRecursiveByType(childComponent.get(), ParameterMap::pBool());
-    TS_ASSERT(fetchedValue != NULL);
+    TS_ASSERT(fetchedValue != nullptr);
     TS_ASSERT_EQUALS("A", fetchedValue->name());
     TS_ASSERT_EQUALS(ParameterMap::pBool(), fetchedValue->type());
     TS_ASSERT_EQUALS(true, fetchedValue->value<bool>());
@@ -589,7 +589,7 @@ public:
     // Find it via the child
     Parameter_sptr fetchedValue =
         pmap.getRecursiveByType(childComponent.get(), ParameterMap::pBool());
-    TS_ASSERT(fetchedValue != NULL);
+    TS_ASSERT(fetchedValue != nullptr);
     TSM_ASSERT_EQUALS(
         "Has not searched through parameters with the correct priority", "A",
         fetchedValue->name());
@@ -639,7 +639,7 @@ private:
                                           const ValueType &newValue) {
     ParameterMap pmap;
     const std::string name = "Parameter";
-    pmap.add<ValueType>(type, m_testInstrument.get(), name, origValue, NULL);
+    pmap.add<ValueType>(type, m_testInstrument.get(), name, origValue, nullptr);
 
     ParameterMap copy(pmap); // invoke copy constructor
 
diff --git a/Framework/Geometry/test/PeakTransformSelectorTest.h b/Framework/Geometry/test/PeakTransformSelectorTest.h
index c2a1f2b76495ddbb217deabfcace31aa487dd8b0..ac3c438324c0cef5912b47b4190c73558a99c5d9 100644
--- a/Framework/Geometry/test/PeakTransformSelectorTest.h
+++ b/Framework/Geometry/test/PeakTransformSelectorTest.h
@@ -31,9 +31,9 @@ private:
     GCC_DIAG_ON_SUGGEST_OVERRIDE
   };
 
-  typedef MockPeakTransformFactoryType<0> MockPeakTransformFactory;
-  typedef MockPeakTransformFactoryType<0> MockPeakTransformFactoryA;
-  typedef MockPeakTransformFactoryType<1> MockPeakTransformFactoryB;
+  using MockPeakTransformFactory = MockPeakTransformFactoryType<0>;
+  using MockPeakTransformFactoryA = MockPeakTransformFactoryType<0>;
+  using MockPeakTransformFactoryB = MockPeakTransformFactoryType<1>;
 
 public:
   void test_Constructor() {
diff --git a/Framework/Geometry/test/PointGroupTest.h b/Framework/Geometry/test/PointGroupTest.h
index 5976f6c135122be341b9dcabf91d0cccbf041fb3..1165941734bb33303285c5758584e801ef92d734 100644
--- a/Framework/Geometry/test/PointGroupTest.h
+++ b/Framework/Geometry/test/PointGroupTest.h
@@ -289,11 +289,11 @@ public:
 
     std::vector<PointGroup_sptr> pointgroups = getAllPointGroups();
 
-    for (size_t i = 0; i < pointgroups.size(); ++i) {
-      TSM_ASSERT_EQUALS(pointgroups[i]->getSymbol() +
+    for (auto &pointgroup : pointgroups) {
+      TSM_ASSERT_EQUALS(pointgroup->getSymbol() +
                             ": Unexpected crystal system.",
-                        pointgroups[i]->crystalSystem(),
-                        crystalSystemsMap[pointgroups[i]->getSymbol()]);
+                        pointgroup->crystalSystem(),
+                        crystalSystemsMap[pointgroup->getSymbol()]);
     }
   }
 
@@ -446,8 +446,8 @@ private:
     t.reset();
     int h = 0;
     for (size_t i = 0; i < 1000; ++i) {
-      for (auto hkl = hkls.begin(); hkl != hkls.end(); ++hkl) {
-        bool eq = pointGroup->isEquivalent(base, *hkl);
+      for (auto &hkl : hkls) {
+        bool eq = pointGroup->isEquivalent(base, hkl);
         if (eq) {
           ++h;
         }
diff --git a/Framework/Geometry/test/ReflectionConditionTest.h b/Framework/Geometry/test/ReflectionConditionTest.h
index c8841ae0fee41586c4868b1a3a63d6d9acdd669d..c34005420456177dbab7700f19808b5b2ad2f4ba 100644
--- a/Framework/Geometry/test/ReflectionConditionTest.h
+++ b/Framework/Geometry/test/ReflectionConditionTest.h
@@ -58,11 +58,11 @@ public:
     centeringSymbols.insert("H");
 
     std::vector<ReflectionCondition_sptr> refs = getAllReflectionConditions();
-    for (auto it = refs.begin(); it != refs.end(); ++it) {
-      TSM_ASSERT_DIFFERS((*it)->getSymbol(),
-                         centeringSymbols.find((*it)->getSymbol()),
+    for (auto &ref : refs) {
+      TSM_ASSERT_DIFFERS(ref->getSymbol(),
+                         centeringSymbols.find(ref->getSymbol()),
                          centeringSymbols.end());
-      centeringSymbols.erase((*it)->getSymbol());
+      centeringSymbols.erase(ref->getSymbol());
     }
 
     // All centering symbols are present if the set is empty.
diff --git a/Framework/Geometry/test/ShapeFactoryTest.h b/Framework/Geometry/test/ShapeFactoryTest.h
index b6335b198e542f5363861a861a17ec73d67e64aa..3cef5552e50838db6c60fb216db279ac01a12516 100644
--- a/Framework/Geometry/test/ShapeFactoryTest.h
+++ b/Framework/Geometry/test/ShapeFactoryTest.h
@@ -23,13 +23,13 @@ class ShapeFactoryTest : public CxxTest::TestSuite {
 public:
   void testCuboid() {
     std::string xmlShape = "<cuboid id=\"shape\"> ";
-    xmlShape += "<left-front-bottom-point x=\"0.005\" y=\"-0.1\" z=\"0.0\" /> ";
+    xmlShape += R"(<left-front-bottom-point x="0.005" y="-0.1" z="0.0" /> )";
     xmlShape +=
-        "<left-front-top-point x=\"0.005\" y=\"-0.1\" z=\"0.0001\" />  ";
+        R"(<left-front-top-point x="0.005" y="-0.1" z="0.0001" />  )";
     xmlShape +=
-        "<left-back-bottom-point x=\"-0.005\" y=\"-0.1\" z=\"0.0\" />  ";
+        R"(<left-back-bottom-point x="-0.005" y="-0.1" z="0.0" />  )";
     xmlShape +=
-        "<right-front-bottom-point x=\"0.005\" y=\"0.1\" z=\"0.0\" />  ";
+        R"(<right-front-bottom-point x="0.005" y="0.1" z="0.0" />  )";
     xmlShape += "</cuboid> ";
     xmlShape += "<algebra val=\"shape\" /> ";
 
@@ -48,8 +48,8 @@ public:
     xmlShape += "<height val=\"0.2\" />";
     xmlShape += "<width val=\"0.1\" />";
     xmlShape += "<depth val=\"0.4\" />";
-    xmlShape += "<centre x=\"1.0\" y=\"1.0\" z=\"1.0\" />";
-    xmlShape += "<axis x=\"1\" y=\"0\" z=\"0\" />"; // Note non-default axis.
+    xmlShape += R"(<centre x="1.0" y="1.0" z="1.0" />)";
+    xmlShape += R"(<axis x="1" y="0" z="0" />)"; // Note non-default axis.
     xmlShape += "</cuboid>";
     xmlShape += "<algebra val=\"some-shape\" />";
 
@@ -80,7 +80,7 @@ public:
     xmlShape += "<height val=\"0.2\" />";
     xmlShape += "<width val=\"0.1\" />";
     xmlShape += "<depth val=\"0.4\" />";
-    xmlShape += "<centre x=\"1.0\" y=\"1.0\" z=\"1.0\" />";
+    xmlShape += R"(<centre x="1.0" y="1.0" z="1.0" />)";
     xmlShape += "</cuboid>";
     xmlShape += "<algebra val=\"some-shape\" />";
 
@@ -111,7 +111,7 @@ public:
     xmlShape += "<height val=\"0.2\" />";
     xmlShape += "<width val=\"0.1\" />";
     xmlShape += "<depth val=\"0.4\" />";
-    xmlShape += "<axis x=\"0\" y=\"0\" z=\"1\" />";
+    xmlShape += R"(<axis x="0" y="0" z="1" />)";
     xmlShape += "</cuboid>";
     xmlShape += "<algebra val=\"some-shape\" />";
 
@@ -139,10 +139,10 @@ public:
   void testRelayShapeXML() {
     // Create a cuboid.
     std::string xmlShape = "<cuboid id=\"shape\"> ";
-    xmlShape += "<left-front-bottom-point x=\"0.005\" y=\"-0.1\" z=\"0.0\"/> ";
-    xmlShape += "<left-front-top-point x=\"0.005\" y=\"-0.1\" z=\"0.0001\"/>  ";
-    xmlShape += "<left-back-bottom-point x=\"-0.005\" y=\"-0.1\" z=\"0.0\"/>  ";
-    xmlShape += "<right-front-bottom-point x=\"0.005\" y=\"0.1\" z=\"0.0\"/>  ";
+    xmlShape += R"(<left-front-bottom-point x="0.005" y="-0.1" z="0.0"/> )";
+    xmlShape += R"(<left-front-top-point x="0.005" y="-0.1" z="0.0001"/>  )";
+    xmlShape += R"(<left-back-bottom-point x="-0.005" y="-0.1" z="0.0"/>  )";
+    xmlShape += R"(<right-front-bottom-point x="0.005" y="0.1" z="0.0"/>  )";
     xmlShape += "</cuboid> ";
     xmlShape += "<algebra val=\"shape\"/> ";
 
@@ -157,14 +157,14 @@ public:
 
   void testHexahedron() {
     std::string xmlShape = "<hexahedron id=\"shape\"> ";
-    xmlShape += "<left-back-bottom-point  x=\"0.0\" y=\"0.0\" z=\"0.0\"  /> ";
-    xmlShape += "<left-front-bottom-point x=\"1.0\" y=\"0.0\" z=\"0.0\"  /> ";
-    xmlShape += "<right-front-bottom-point x=\"1.0\" y=\"1.0\" z=\"0.0\"  /> ";
-    xmlShape += "<right-back-bottom-point  x=\"0.0\" y=\"1.0\" z=\"0.0\"  /> ";
-    xmlShape += "<left-back-top-point  x=\"0.0\" y=\"0.0\" z=\"2.0\"  /> ";
-    xmlShape += "<left-front-top-point  x=\"0.5\" y=\"0.0\" z=\"2.0\"  /> ";
-    xmlShape += "<right-front-top-point  x=\"0.5\" y=\"0.5\" z=\"2.0\"  /> ";
-    xmlShape += "<right-back-top-point  x=\"0.0\" y=\"0.5\" z=\"2.0\"  /> ";
+    xmlShape += R"(<left-back-bottom-point  x="0.0" y="0.0" z="0.0"  /> )";
+    xmlShape += R"(<left-front-bottom-point x="1.0" y="0.0" z="0.0"  /> )";
+    xmlShape += R"(<right-front-bottom-point x="1.0" y="1.0" z="0.0"  /> )";
+    xmlShape += R"(<right-back-bottom-point  x="0.0" y="1.0" z="0.0"  /> )";
+    xmlShape += R"(<left-back-top-point  x="0.0" y="0.0" z="2.0"  /> )";
+    xmlShape += R"(<left-front-top-point  x="0.5" y="0.0" z="2.0"  /> )";
+    xmlShape += R"(<right-front-top-point  x="0.5" y="0.5" z="2.0"  /> )";
+    xmlShape += R"(<right-back-top-point  x="0.0" y="0.5" z="2.0"  /> )";
     xmlShape += "</hexahedron> ";
     xmlShape += "<algebra val=\"shape\" /> ";
 
@@ -180,21 +180,21 @@ public:
   void testHexahedron2() {
     std::string xmlShape = "<hexahedron id=\"shape\"> ";
     xmlShape +=
-        "<left-front-bottom-point x=\"0.0\" y=\"-0.0031\" z=\"-0.037\"  /> ";
+        R"(<left-front-bottom-point x="0.0" y="-0.0031" z="-0.037"  /> )";
     xmlShape +=
-        "<right-front-bottom-point x=\"0.0\" y=\"0.0031\" z=\"-0.037\"  /> ";
+        R"(<right-front-bottom-point x="0.0" y="0.0031" z="-0.037"  /> )";
     xmlShape +=
-        "<left-front-top-point x=\"0.0\" y=\"-0.0104\" z=\"0.037\"  /> ";
+        R"(<left-front-top-point x="0.0" y="-0.0104" z="0.037"  /> )";
     xmlShape +=
-        "<right-front-top-point x=\"0.0\" y=\"0.0104\" z=\"0.037\"  /> ";
+        R"(<right-front-top-point x="0.0" y="0.0104" z="0.037"  /> )";
     xmlShape +=
-        "<left-back-bottom-point x=\"0.005\" y=\"-0.0031\" z=\"-0.037\"  /> ";
+        R"(<left-back-bottom-point x="0.005" y="-0.0031" z="-0.037"  /> )";
     xmlShape +=
-        "<right-back-bottom-point x=\"0.005\" y=\"0.0031\" z=\"-0.037\"  /> ";
+        R"(<right-back-bottom-point x="0.005" y="0.0031" z="-0.037"  /> )";
     xmlShape +=
-        "<left-back-top-point x=\"0.005\" y=\"-0.0104\" z=\"0.037\"  /> ";
+        R"(<left-back-top-point x="0.005" y="-0.0104" z="0.037"  /> )";
     xmlShape +=
-        "<right-back-top-point x=\"0.005\" y=\"0.0104\" z=\"0.037\"  /> ";
+        R"(<right-back-top-point x="0.005" y="0.0104" z="0.037"  /> )";
     xmlShape += "</hexahedron> ";
     xmlShape += "<algebra val=\"shape\" /> ";
 
@@ -209,9 +209,9 @@ public:
 
   void testTaperedGuideDefaults() {
     std::string xmlShape = "<tapered-guide id=\"shape\">";
-    xmlShape += "<aperture-start height=\"2.0\" width=\"2.0\" />";
+    xmlShape += R"(<aperture-start height="2.0" width="2.0" />)";
     xmlShape += "<length val=\"2.0\" />";
-    xmlShape += "<aperture-end height=\"4.0\" width=\"4.0\" />";
+    xmlShape += R"(<aperture-end height="4.0" width="4.0" />)";
     xmlShape += "</tapered-guide>";
     xmlShape += "<algebra val=\"shape\"/>";
 
@@ -242,11 +242,11 @@ public:
 
   void testTaperedGuideDifferentAxisAndCentre() {
     std::string xmlShape = "<tapered-guide id=\"shape\">";
-    xmlShape += "<aperture-start height=\"2.0\" width=\"2.0\" />";
+    xmlShape += R"(<aperture-start height="2.0" width="2.0" />)";
     xmlShape += "<length val=\"2.0\" />";
-    xmlShape += "<aperture-end height=\"4.0\" width=\"4.0\" />";
-    xmlShape += "<centre x=\"0.0\" y=\"0.0\" z=\"1.0\" />";
-    xmlShape += "<axis x=\"1.0\" y=\"0.0\" z=\"0\" />";
+    xmlShape += R"(<aperture-end height="4.0" width="4.0" />)";
+    xmlShape += R"(<centre x="0.0" y="0.0" z="1.0" />)";
+    xmlShape += R"(<axis x="1.0" y="0.0" z="0" />)";
     xmlShape += "</tapered-guide>";
     xmlShape += "<algebra val=\"shape\"/>";
 
@@ -278,7 +278,7 @@ public:
   void testSphere() {
     // algebra line is essential
     std::string xmlShape = "<sphere id=\"shape\"> ";
-    xmlShape += "<centre x=\"4.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="4.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -295,11 +295,11 @@ public:
   void testTwoSpheres() {
     // algebra line is essential
     std::string xmlShape = "<sphere id=\"shape1\"> ";
-    xmlShape += "<centre x=\"4.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="4.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<sphere id=\"shape2\"> ";
-    xmlShape += "<centre x=\"2.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="2.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"shape1 : shape2\" /> ";
@@ -318,11 +318,11 @@ public:
   void testTwoSpheresNoAlgebraString() {
     // algebra line is essential
     std::string xmlShape = "<sphere id=\"shape1\"> ";
-    xmlShape += "<centre x=\"4.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="4.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<sphere id=\"shape2\"> ";
-    xmlShape += "<centre x=\"2.1\"  y=\"2.1\" z=\"8.1\" /> ";
+    xmlShape += R"(<centre x="2.1"  y="2.1" z="8.1" /> )";
     xmlShape += "<radius val=\"3.2\" /> ";
     xmlShape += "</sphere>";
 
@@ -363,8 +363,8 @@ public:
   void testCylinder() {
     // algebra line is essential
     std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "<height val=\"3\" /> ";
     xmlShape += "</cylinder>";
@@ -382,8 +382,8 @@ public:
   void testCylinderNoAlgebraString() {
     // algebra line is essential
     std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "<height val=\"3\" /> ";
     xmlShape += "</cylinder>";
@@ -400,8 +400,8 @@ public:
   void testCylinderTwoAlgebraStrings() {
     // algebra line is essential
     std::string xmlShape = "<cylinder id=\"shape\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre-of-bottom-base x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "<height val=\"3\" /> ";
     xmlShape += "</cylinder>";
@@ -506,8 +506,8 @@ public:
   void testInfiniteCylinder() {
     // algebra line is essential
     std::string xmlShape = "<infinite-cylinder id=\"shape\"> ";
-    xmlShape += "<centre x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<centre x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<radius val=\"0.1\" /> ";
     xmlShape += "</infinite-cylinder>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -524,8 +524,8 @@ public:
   void testCone() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height val=\"4\" /> ";
     xmlShape += "</cone>";
@@ -543,8 +543,8 @@ public:
   void testConeUseDirectStringArgument() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height val=\"4\" /> ";
     xmlShape += "</cone>";
@@ -562,13 +562,13 @@ public:
 
   void testComplement() {
     std::string xmlShape = "<cylinder id=\"stick\"> ";
-    xmlShape += "<centre-of-bottom-base x=\"-0.5\" y=\"0.0\" z=\"0.0\" />";
-    xmlShape += "<axis x=\"1.0\" y=\"0.0\" z=\"0.0\" />";
+    xmlShape += R"(<centre-of-bottom-base x="-0.5" y="0.0" z="0.0" />)";
+    xmlShape += R"(<axis x="1.0" y="0.0" z="0.0" />)";
     xmlShape += "<radius val=\"0.05\" />";
     xmlShape += "<height val=\"1.0\" />";
     xmlShape += "</cylinder>";
     xmlShape += "<sphere id=\"some-sphere\">";
-    xmlShape += "<centre x=\"0.0\"  y=\"0.0\" z=\"0.0\" />";
+    xmlShape += R"(<centre x="0.0"  y="0.0" z="0.0" />)";
     xmlShape += "<radius val=\"0.5\" />";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"some-sphere # stick\" />";
@@ -589,8 +589,8 @@ public:
   void testNoneExistingShape() {
     // algebra line is essential
     std::string xmlShape = "<c5one id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height val=\"4\" /> ";
     xmlShape += "</c5one>";
@@ -604,8 +604,8 @@ public:
   void testTypingErrorInSubElement() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<heeight val=\"4\" /> ";
     xmlShape += "</cone>";
@@ -619,8 +619,8 @@ public:
   void testTypingErrorInAttribute() {
     // algebra line is essential
     std::string xmlShape = "<cone id=\"shape\"> ";
-    xmlShape += "<tip-point x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
-    xmlShape += "<axis x=\"0.0\" y=\"0.0\" z=\"1\" /> ";
+    xmlShape += R"(<tip-point x="0.0" y="0.0" z="0.0" /> )";
+    xmlShape += R"(<axis x="0.0" y="0.0" z="1" /> )";
     xmlShape += "<angle val=\"8.1\" /> ";
     xmlShape += "<height vaal=\"4\" /> ";
     xmlShape += "</cone>";
diff --git a/Framework/Geometry/test/ShapeInfoTest.h b/Framework/Geometry/test/ShapeInfoTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..573a8b5f8394143442be882c2cdbe7de7b8795be
--- /dev/null
+++ b/Framework/Geometry/test/ShapeInfoTest.h
@@ -0,0 +1,138 @@
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidKernel/V3D.h"
+#include <cxxtest/TestSuite.h>
+
+using Mantid::Kernel::V3D;
+using namespace Mantid::Geometry::detail;
+
+class ShapeInfoTest : public CxxTest::TestSuite {
+private:
+  ShapeInfo m_shapeInfo;
+
+public:
+  void testConstructEmptyInitiazesEverythingZero() {
+    TS_ASSERT(m_shapeInfo.points().size() == 0);
+    TS_ASSERT(m_shapeInfo.height() == 0);
+    TS_ASSERT(m_shapeInfo.radius() == 0);
+    TS_ASSERT(m_shapeInfo.shape() == ShapeInfo::GeometryShape::NOSHAPE);
+  }
+
+  void testSetSphere() {
+    V3D center(0, 0, 0);
+    double radius = 10;
+    m_shapeInfo.setSphere(center, radius);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::SPHERE);
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius);
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), 0);
+    TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 1);
+    TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center);
+  }
+
+  void testSetCuboid() {
+    V3D p1(0, 0, 0);
+    V3D p2(0, 0, 1);
+    V3D p3(0, 1, 0);
+    V3D p4(0, 1, 1);
+
+    m_shapeInfo.setCuboid(p1, p2, p3, p4);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CUBOID);
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), 0);
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), 0);
+    TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 4);
+    TS_ASSERT_EQUALS(m_shapeInfo.points(), (std::vector<V3D>{p1, p2, p3, p4}));
+  }
+
+  void testSetHexahedron() {
+    V3D p1(0, 0, 0);
+    V3D p2(0, 0, 1);
+    V3D p3(0, 1, 0);
+    V3D p4(0, 1, 1);
+    V3D p5(1, 0, 0);
+    V3D p6(1, 0, 1);
+    V3D p7(1, 1, 0);
+    V3D p8(1, 1, 1);
+
+    m_shapeInfo.setHexahedron(p1, p2, p3, p4, p5, p6, p7, p8);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::HEXAHEDRON);
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), 0);
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), 0);
+    TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 8);
+    TS_ASSERT_EQUALS(m_shapeInfo.points(),
+                     (std::vector<V3D>{p1, p2, p3, p4, p5, p6, p7, p8}));
+  }
+
+  void testSetCone() {
+    V3D center(0, 0, 0);
+    V3D axis(1, 0, 0);
+    double radius = 10;
+    double height = 5;
+    m_shapeInfo.setCone(center, axis, radius, height);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CONE);
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius);
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), height);
+    TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2);
+    TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center);
+    TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis);
+  }
+
+  void testSetCylinder() {
+    V3D center(0, 0, 0);
+    V3D axis(1, 0, 0);
+    double radius = 10;
+    double height = 5;
+    m_shapeInfo.setCylinder(center, axis, radius, height);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CYLINDER);
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius);
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), height);
+    TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2);
+    TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center);
+    TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis);
+  }
+
+  void testGetObjectGeometry() {
+    V3D center(0, 0, 0);
+    double radius = 10;
+    m_shapeInfo.setSphere(center, radius);
+
+    ShapeInfo::GeometryShape tshape;
+    std::vector<V3D> tpoints;
+    double theight;
+    double tradius;
+
+    m_shapeInfo.getObjectGeometry(tshape, tpoints, tradius, theight);
+    TS_ASSERT_EQUALS(tradius, radius);
+    TS_ASSERT(theight == 0);
+    TS_ASSERT(tpoints.size() == 1);
+    TS_ASSERT_EQUALS(tpoints[0], center);
+    TS_ASSERT_EQUALS(tshape, ShapeInfo::GeometryShape::SPHERE);
+  }
+
+  void testCopyConstructor() {
+    V3D center(0, 2, 1);
+    double radius = 10;
+    m_shapeInfo.setSphere(center, radius);
+
+    ShapeInfo shapeInfoCopy(m_shapeInfo);
+
+    TS_ASSERT_EQUALS(m_shapeInfo.shape(), shapeInfoCopy.shape());
+    TS_ASSERT_EQUALS(m_shapeInfo.radius(), shapeInfoCopy.radius());
+    TS_ASSERT_EQUALS(m_shapeInfo.height(), shapeInfoCopy.height());
+    TS_ASSERT_EQUALS(m_shapeInfo.points(), shapeInfoCopy.points());
+  }
+
+  void testEquality() {
+    V3D center(0, 2, 1);
+    double radius = 10;
+    m_shapeInfo.setSphere(center, radius);
+    ShapeInfo shapeInfo2, shapeInfo3;
+    shapeInfo2.setSphere(center, radius);
+    shapeInfo3.setCuboid(V3D(), V3D(), V3D(), V3D());
+    TS_ASSERT_EQUALS(shapeInfo2, m_shapeInfo);
+    TS_ASSERT_DIFFERS(shapeInfo3, m_shapeInfo);
+  }
+};
diff --git a/Framework/Geometry/test/SpaceGroupTest.h b/Framework/Geometry/test/SpaceGroupTest.h
index 4aa4df38b140568802a7c4095c2ae6f55e64f5d9..363d32d0d38209cac1e440c30d9055b84c1a16b9 100644
--- a/Framework/Geometry/test/SpaceGroupTest.h
+++ b/Framework/Geometry/test/SpaceGroupTest.h
@@ -66,8 +66,8 @@ public:
     SpaceGroup spaceGroup(167, "R-3c", *(group * centering));
 
     std::vector<V3D> byOperator = spaceGroup * V3D(0.3, 0.0, 0.25);
-    for (size_t i = 0; i < byOperator.size(); ++i) {
-      byOperator[i] = getWrappedVector(byOperator[i]);
+    for (auto &i : byOperator) {
+      i = getWrappedVector(i);
     }
     std::sort(byOperator.begin(), byOperator.end());
 
@@ -86,8 +86,8 @@ public:
     SpaceGroup spaceGroup = getSpaceGroupR3m();
 
     std::vector<V3D> byOperator = spaceGroup * V3D(0.5, 0.0, 0.0);
-    for (size_t i = 0; i < byOperator.size(); ++i) {
-      byOperator[i] = getWrappedVector(byOperator[i]);
+    for (auto &i : byOperator) {
+      i = getWrappedVector(i);
     }
     std::sort(byOperator.begin(), byOperator.end());
 
diff --git a/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h
index 80b53703646a26e7945a84974b2d04036b9f3918..6880e34e3dbd69b4ac7b60b16bbe8e75c463f2ec 100644
--- a/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h
+++ b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h
@@ -63,7 +63,7 @@ private:
     CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create();
     scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer(
         "IsotropicAtomBraggScatterer",
-        "{\"Element\":\"Si\",\"Position\":\"0,0,0\",\"U\":\"0.05\"}"));
+        R"({"Element":"Si","Position":"0,0,0","U":"0.05"})"));
 
     CrystalStructure si(
         UnitCell(5.43, 5.43, 5.43),
diff --git a/Framework/Geometry/test/StructuredDetectorTest.h b/Framework/Geometry/test/StructuredDetectorTest.h
index 996d0903d2a8a78885ecf033d1945a2656199c81..e8d10f62026766ece13233ea9a09013eda0eb92f 100644
--- a/Framework/Geometry/test/StructuredDetectorTest.h
+++ b/Framework/Geometry/test/StructuredDetectorTest.h
@@ -125,7 +125,7 @@ public:
     std::vector<double> y{0, 0, 0, 1, 1, 1, 2, 2, 2};
 
     // Initialize with these parameters
-    det->initialize(2, 2, x, y, true, 0, true, 2, 1);
+    det->initialize(2, 2, std::move(x), std::move(y), true, 0, true, 2, 1);
 
     do_test_on(det);
 
@@ -145,10 +145,11 @@ public:
     std::vector<double> x{0, 1, 2, 0, 1, 2, 0, 1, 2};
     std::vector<double> y{0, 0, 0, 1, 1, 1, 2, 2, 2};
 
-    TSM_ASSERT_THROWS("StructuredDetectors created with beams not aligned "
-                      "along the z-axis should fail.",
-                      det->initialize(2, 2, x, y, false, 0, true, 2, 1),
-                      std::invalid_argument);
+    TSM_ASSERT_THROWS(
+        "StructuredDetectors created with beams not aligned "
+        "along the z-axis should fail.",
+        det->initialize(2, 2, std::move(x), std::move(y), false, 0, true, 2, 1),
+        std::invalid_argument);
 
     delete det;
   }
@@ -162,19 +163,27 @@ public:
     std::vector<double> x{0, 1, 2, 0, 1, 2};
     std::vector<double> y{0, 0, 0, 1, 1, 1};
 
+    auto x2 = x;
+    auto y2 = y;
+
     // Initialize with these parameters
-    TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1),
-                     std::invalid_argument);
+    TS_ASSERT_THROWS(
+        det->initialize(2, 2, std::move(x), std::move(y), true, 0, true, 2, 1),
+        std::invalid_argument);
 
-    x.resize(3);
+    x2.resize(3);
+    auto x3 = x2;
+    auto y3 = y2;
 
-    TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1),
+    TS_ASSERT_THROWS(det->initialize(2, 2, std::move(x2), std::move(y2), true,
+                                     0, true, 2, 1),
                      std::invalid_argument);
 
-    x.resize(0);
-    y.resize(0);
+    x3.resize(0);
+    y3.resize(0);
 
-    TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1),
+    TS_ASSERT_THROWS(det->initialize(2, 2, std::move(x3), std::move(y3), true,
+                                     0, true, 2, 1),
                      std::invalid_argument);
 
     delete det;
diff --git a/Framework/Geometry/test/SymmetryOperationFactoryTest.h b/Framework/Geometry/test/SymmetryOperationFactoryTest.h
index 7e425a0df075f45b5d01d453a7bb06c8d9d6e3a7..978514be0baf26e1fa2b51bdc70388fee5b5d357 100644
--- a/Framework/Geometry/test/SymmetryOperationFactoryTest.h
+++ b/Framework/Geometry/test/SymmetryOperationFactoryTest.h
@@ -125,8 +125,8 @@ public:
     // Clear factory
     std::vector<std::string> allSymbols =
         SymmetryOperationFactory::Instance().subscribedSymbols();
-    for (auto it = allSymbols.begin(); it != allSymbols.end(); ++it) {
-      SymmetryOperationFactory::Instance().unsubscribeSymOp(*it);
+    for (auto &symbol : allSymbols) {
+      SymmetryOperationFactory::Instance().unsubscribeSymOp(symbol);
     }
 
     // Subscribe two symmetry operations
@@ -146,8 +146,8 @@ public:
     SymmetryOperationFactory::Instance().unsubscribeSymOp("-x,-y,-z");
 
     // Restore factory
-    for (auto it = allSymbols.begin(); it != allSymbols.end(); ++it) {
-      SymmetryOperationFactory::Instance().subscribeSymOp(*it);
+    for (auto &symbol : allSymbols) {
+      SymmetryOperationFactory::Instance().subscribeSymOp(symbol);
     }
   }
 };
diff --git a/Framework/Geometry/test/SymmetryOperationTest.h b/Framework/Geometry/test/SymmetryOperationTest.h
index 6f7aeccb62afe067fce0a635e60bbe7fa7c4743d..30da4b1aafaecbd9f1fa87a90ba78f860a8d6ad2 100644
--- a/Framework/Geometry/test/SymmetryOperationTest.h
+++ b/Framework/Geometry/test/SymmetryOperationTest.h
@@ -260,7 +260,7 @@ public:
     Mantid::Kernel::IntMatrix randMatrix(3, 3, false);
 
     for (int i = 1; i < 10; ++i) {
-      randMatrix.setRandom(-0, -i, i);
+      randMatrix.setRandom(1, -i, i);
       TS_ASSERT_THROWS(symOp.getOrderFromMatrix(randMatrix),
                        std::runtime_error);
     }
diff --git a/Framework/Geometry/test/UnitCellTest.h b/Framework/Geometry/test/UnitCellTest.h
index 950decf36f6334847ed568b0f8b5abde297836f6..4b512ff034d8603a5aedda54987f075970220f26 100644
--- a/Framework/Geometry/test/UnitCellTest.h
+++ b/Framework/Geometry/test/UnitCellTest.h
@@ -142,6 +142,12 @@ public:
     }
   }
 
+  void testReciprocalAngle0() {
+    UnitCell cell(5.45, 5.45, 5.45);
+    TS_ASSERT_EQUALS(cell.recAngle(0., 4., 0., 0., 4., 0.), 0.);
+    TS_ASSERT_EQUALS(cell.recAngle(0., -4., 0., 0., 4., 0.), 180.);
+  }
+
   void testStrToUnitCell() {
     UnitCell cell(2.0, 4.0, 5.0, 90.0, 100.0, 102.0);
     std::string cellString = unitCellToStr(cell);
diff --git a/Framework/Geometry/test/XMLInstrumentParameterTest.h b/Framework/Geometry/test/XMLInstrumentParameterTest.h
index b2bfe5cd2bf6ae4c945c9c32773ec72ba102fa32..ce2ac3c2ceb95a5e1a26a11d1499569c0e2e08a1 100644
--- a/Framework/Geometry/test/XMLInstrumentParameterTest.h
+++ b/Framework/Geometry/test/XMLInstrumentParameterTest.h
@@ -16,7 +16,7 @@ using namespace Mantid::Kernel;
 
 class XMLInstrumentParameterTest : public CxxTest::TestSuite {
 private:
-  typedef boost::shared_ptr<XMLInstrumentParameter> XMLInstrumentParameter_sptr;
+  using XMLInstrumentParameter_sptr = boost::shared_ptr<XMLInstrumentParameter>;
 
   /**
   Construction logic for the XMLInstrumentParameter type isn't great, so this
diff --git a/Framework/HistogramData/CMakeLists.txt b/Framework/HistogramData/CMakeLists.txt
index a0d9d4b59bce765c95929156f490074bf132301f..7176078f828b9355353e1f620446cd4917ea9650 100644
--- a/Framework/HistogramData/CMakeLists.txt
+++ b/Framework/HistogramData/CMakeLists.txt
@@ -3,6 +3,7 @@ set ( SRC_FILES
 	src/CountStandardDeviations.cpp
 	src/CountVariances.cpp
 	src/Counts.cpp
+	src/EstimatePolynomial.cpp
 	src/Exception.cpp
 	src/Frequencies.cpp
 	src/FrequencyStandardDeviations.cpp
@@ -23,6 +24,7 @@ set ( INC_FILES
 	inc/MantidHistogramData/CountVariances.h
 	inc/MantidHistogramData/Counts.h
 	inc/MantidHistogramData/EValidation.h
+	inc/MantidHistogramData/EstimatePolynomial.h
 	inc/MantidHistogramData/Exception.h
 	inc/MantidHistogramData/FixedLengthVector.h
 	inc/MantidHistogramData/Frequencies.h
@@ -32,8 +34,8 @@ set ( INC_FILES
 	inc/MantidHistogramData/HistogramBuilder.h
 	inc/MantidHistogramData/HistogramDx.h
 	inc/MantidHistogramData/HistogramE.h
-        inc/MantidHistogramData/HistogramItem.h
-        inc/MantidHistogramData/HistogramIterator.h
+	inc/MantidHistogramData/HistogramItem.h
+	inc/MantidHistogramData/HistogramIterator.h
 	inc/MantidHistogramData/HistogramMath.h
 	inc/MantidHistogramData/HistogramX.h
 	inc/MantidHistogramData/HistogramY.h
@@ -46,6 +48,7 @@ set ( INC_FILES
 	inc/MantidHistogramData/PointStandardDeviations.h
 	inc/MantidHistogramData/PointVariances.h
 	inc/MantidHistogramData/Points.h
+	inc/MantidHistogramData/QuadraticGenerator.h
 	inc/MantidHistogramData/Rebin.h
 	inc/MantidHistogramData/Scalable.h
 	inc/MantidHistogramData/Slice.h
@@ -64,6 +67,7 @@ set ( TEST_FILES
 	CountVariancesTest.h
 	CountsTest.h
 	EValidationTest.h
+	EstimatePolynomialTest.h
 	FixedLengthVectorTest.h
 	FrequenciesTest.h
 	FrequencyStandardDeviationsTest.h
@@ -71,7 +75,7 @@ set ( TEST_FILES
 	HistogramBuilderTest.h
 	HistogramDxTest.h
 	HistogramETest.h
-        HistogramIteratorTest.h
+	HistogramIteratorTest.h
 	HistogramMathTest.h
 	HistogramTest.h
 	HistogramXTest.h
@@ -85,6 +89,7 @@ set ( TEST_FILES
 	PointStandardDeviationsTest.h
 	PointVariancesTest.h
 	PointsTest.h
+	QuadraticGeneratorTest.h
 	RebinTest.h
 	ScalableTest.h
 	SliceTest.h
@@ -122,7 +127,7 @@ endif ()
 set_property ( TARGET HistogramData PROPERTY FOLDER "MantidFramework" )
 
 target_include_directories ( HistogramData PUBLIC ${Boost_INCLUDE_DIRS})
-target_link_libraries ( HistogramData LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} 
+target_link_libraries ( HistogramData LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME}
                         ${GSL_LIBRARIES} ${MANTIDLIBS} )
 
 # Add the unit tests directory
diff --git a/Framework/HistogramData/inc/MantidHistogramData/EstimatePolynomial.h b/Framework/HistogramData/inc/MantidHistogramData/EstimatePolynomial.h
new file mode 100644
index 0000000000000000000000000000000000000000..9906f0476e5754d40e1ca1dd65cc0d3c4ad66e4d
--- /dev/null
+++ b/Framework/HistogramData/inc/MantidHistogramData/EstimatePolynomial.h
@@ -0,0 +1,71 @@
+#ifndef MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIAL_H_
+#define MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIAL_H_
+
+#include "MantidHistogramData/DllConfig.h"
+#include "MantidHistogramData/Histogram.h"
+#include <vector>
+
+namespace Mantid {
+namespace HistogramData {
+
+/** EstimatePolynomial : TODO: DESCRIPTION
+
+  Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+
+/**
+ * @brief estimateBackground Estimate a polynomial using Gauss-Markov.
+ *
+ * Uses Gauss-Markov to find the best linear unbiased estimator (BLUE). This
+ * will select the functional
+ * form that has the smallest reduced chisq (divided by degrees of freedom) that
+ * is less than or equal
+ * to the polynomial order requested.
+ * https://en.wikipedia.org/wiki/Gauss%E2%80%93Markov_theorem
+ *
+ * @param order Maximum order of the polynomial to fit
+ * @param i_min Left boundary of window (inclusive)
+ * @param i_max Right boundary of window (exclusive)
+ * @param p_min Left boundary of data in window to skip (inclusive)
+ * @param p_max Right boundary of data in window to skip (exclusive)
+ * @param out_bg0 constant term
+ * @param out_bg1 linear term
+ * @param out_bg2 quadratic term
+ * @param out_chisq_red reduced chisq (chisq normalized by degrees of freedom)
+ */
+MANTID_HISTOGRAMDATA_DLL void
+estimateBackground(const size_t order,
+                   const Mantid::HistogramData::Histogram &histo,
+                   const size_t i_min, const size_t i_max, const size_t p_min,
+                   const size_t p_max, double &out_bg0, double &out_bg1,
+                   double &out_bg2, double &out_chisq_red);
+
+MANTID_HISTOGRAMDATA_DLL void
+estimatePolynomial(const size_t order,
+                   const Mantid::HistogramData::Histogram &histo,
+                   const size_t i_min, const size_t i_max, double &out_bg0,
+                   double &out_bg1, double &out_bg2, double &out_chisq_red);
+
+} // namespace HistogramData
+} // namespace Mantid
+
+#endif /* MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIAL_H_ */
diff --git a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h
index 43c2f53d227fa04a2ff394b4d6289d2b57e34aad..417c30240c68dafa479f4c69b4af110fc6b1bd84 100644
--- a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h
+++ b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h
@@ -169,8 +169,8 @@ public:
   const double &back() const { return m_data.back(); }
 
   // expose typedefs for the iterator types in the underlying container
-  typedef std::vector<double>::iterator iterator;
-  typedef std::vector<double>::const_iterator const_iterator;
+  using iterator = std::vector<double>::iterator;
+  using const_iterator = std::vector<double>::const_iterator;
 };
 
 } // namespace detail
diff --git a/Framework/HistogramData/inc/MantidHistogramData/Histogram.h b/Framework/HistogramData/inc/MantidHistogramData/Histogram.h
index 0b3d1c4ccc5b9a5f2b223599ef9f0a0d947916a4..c1955f6deb725e2cd24ca24f58164aae01c1829f 100644
--- a/Framework/HistogramData/inc/MantidHistogramData/Histogram.h
+++ b/Framework/HistogramData/inc/MantidHistogramData/Histogram.h
@@ -239,7 +239,7 @@ Histogram::setUncertainties(const FrequencyStandardDeviations &e);
   @param y Optional Y data for the Histogram. Can be Counts or Frequencies.
   @param e Optional E data for the Histogram. Can be Variances or
   StandardDeviations for Counts or Frequencies. If not specified or null, the
-  standard deviations will be set as the suare root of the Y data.
+  standard deviations will be set as the square root of the Y data.
   */
 template <class TX, class TY, class TE>
 Histogram::Histogram(const TX &x, const TY &y, const TE &e) {
diff --git a/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h b/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h
index f99d3a7b5860c4a64771631edff0321c23636c1b..7442ee4845fe9b05f8880b3a6ba387173f37fce2 100644
--- a/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h
+++ b/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h
@@ -50,6 +50,10 @@ public:
   template <typename... T> void setE(T &&... data) {
     m_e = Kernel::make_cow<HistogramE>(std::forward<T>(data)...);
   }
+  /// Sets Dx information. Can be a length or actual Dx data.
+  template <typename... T> void setDx(T &&... data) {
+    d_x = Kernel::make_cow<HistogramDx>(std::forward<T>(data)...);
+  }
   void setDistribution(bool isDistribution);
 
   Histogram build() const;
@@ -59,6 +63,7 @@ private:
   Kernel::cow_ptr<HistogramX> m_x{nullptr};
   Kernel::cow_ptr<HistogramY> m_y{nullptr};
   Kernel::cow_ptr<HistogramE> m_e{nullptr};
+  Kernel::cow_ptr<HistogramDx> d_x{nullptr};
 };
 
 } // namespace HistogramData
diff --git a/Framework/HistogramData/inc/MantidHistogramData/Iterable.h b/Framework/HistogramData/inc/MantidHistogramData/Iterable.h
index cdfea120b0605221176976aa7e6833a7ddd2a6a8..864bb4c84f8297d3ae2674930c0eb2da55ff117d 100644
--- a/Framework/HistogramData/inc/MantidHistogramData/Iterable.h
+++ b/Framework/HistogramData/inc/MantidHistogramData/Iterable.h
@@ -86,8 +86,8 @@ public:
   }
 
   // expose typedefs for the iterator types in the underlying container
-  typedef std::vector<double>::iterator iterator;
-  typedef std::vector<double>::const_iterator const_iterator;
+  using iterator = std::vector<double>::iterator;
+  using const_iterator = std::vector<double>::const_iterator;
 
 protected:
   ~Iterable() = default;
diff --git a/Framework/HistogramData/inc/MantidHistogramData/QuadraticGenerator.h b/Framework/HistogramData/inc/MantidHistogramData/QuadraticGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..5db4a94dcac1c7d0914b161674c465445c97c227
--- /dev/null
+++ b/Framework/HistogramData/inc/MantidHistogramData/QuadraticGenerator.h
@@ -0,0 +1,52 @@
+#ifndef MANTID_HISTOGRAMDATA_QUADRATICGENERATOR_H_
+#define MANTID_HISTOGRAMDATA_QUADRATICGENERATOR_H_
+
+#include "MantidHistogramData/DllConfig.h"
+
+namespace Mantid {
+namespace HistogramData {
+
+/** QuadraticGenerator : Makes quadratics
+
+  Copyright &copy; 2016 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class QuadraticGenerator {
+public:
+  QuadraticGenerator(double a0, double a1, double a2)
+      : a0(a0), a1(a1), a2(a2) {}
+
+  double operator()() {
+    const double x = static_cast<double>(count++);
+    return a0 + a1 * x + a2 * x * x;
+  }
+
+private:
+  double a0;
+  double a1;
+  double a2;
+  size_t count{0};
+};
+
+} // namespace HistogramData
+} // namespace Mantid
+
+#endif /* MANTID_HISTOGRAMDATA_QUADRATICGENERATOR_H_ */
diff --git a/Framework/HistogramData/src/EstimatePolynomial.cpp b/Framework/HistogramData/src/EstimatePolynomial.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..753d6b32e79a3878fb0ad581d793d82b09550092
--- /dev/null
+++ b/Framework/HistogramData/src/EstimatePolynomial.cpp
@@ -0,0 +1,253 @@
+#include "MantidHistogramData/EstimatePolynomial.h"
+#include "MantidHistogramData/HistogramY.h"
+#include "MantidHistogramData/Points.h"
+#include <iostream>
+#include <limits>
+#include <sstream>
+#include <stdexcept>
+
+using Mantid::HistogramData::HistogramY;
+using Mantid::HistogramData::Points;
+
+namespace {                    // anonymous
+const double BAD_CHISQ(1.e10); // big invalid value
+const double INVALID_CHISQ(std::numeric_limits<double>::quiet_NaN());
+
+inline void calcFlatParameters(const double sum, const double sumY,
+                               double &bg0) {
+  if (sum != 0.)
+    bg0 = sumY / sum;
+  // otherwise outputs are already 0.
+}
+
+// use Cramer's rule for 2 x 2 matrix
+inline void calcLinearParameters(const double sum, const double sumX,
+                                 const double sumY, const double sumXY,
+                                 const double sumX2, double &bg0, double &bg1) {
+  const double determinant = sum * sumX2 - sumX * sumX;
+  if (determinant != 0) {
+    bg0 = (sumY * sumX2 - sumX * sumXY) / determinant;
+    bg1 = (sum * sumXY - sumY * sumX) / determinant;
+  } // otherwise outputs are already 0.
+}
+
+// use Cramer's rule for 3 x 3 matrix
+// | a b c |
+// | d e f |
+// | g h i |
+// 3 x 3 determinate:  aei+bfg+cdh-ceg-bdi-afh
+inline void calcQuadraticParameters(const double sum, const double sumX,
+                                    const double sumY, const double sumXY,
+                                    const double sumX2, const double sumX2Y,
+                                    const double sumX3, const double sumX4,
+                                    double &bg0, double &bg1, double &bg2) {
+  double determinant = sum * sumX2 * sumX4 + sumX * sumX3 * sumX2 +
+                       sumX2 * sumX * sumX3 - sumX2 * sumX2 * sumX2 -
+                       sumX * sumX * sumX4 - sum * sumX3 * sumX3;
+  if (determinant != 0) {
+    bg0 =
+        (sumY * sumX2 * sumX4 + sumX * sumX3 * sumX2Y + sumX2 * sumXY * sumX3 -
+         sumX2 * sumX2 * sumX2Y - sumX * sumXY * sumX4 - sumY * sumX3 * sumX3) /
+        determinant;
+    bg1 = (sum * sumXY * sumX4 + sumY * sumX3 * sumX2 + sumX2 * sumX * sumX2Y -
+           sumX2 * sumXY * sumX2 - sumY * sumX * sumX4 - sum * sumX3 * sumX2Y) /
+          determinant;
+    bg2 = (sum * sumX2 * sumX2Y + sumX * sumXY * sumX2 + sumY * sumX * sumX3 -
+           sumY * sumX2 * sumX2 - sumX * sumX * sumX2Y - sum * sumXY * sumX3) /
+          determinant;
+  } // otherwise outputs are already 0.
+}
+
+// y = bg0
+struct constant {
+  explicit constant(const double bg0) : bg0(bg0) {}
+
+  double operator()(const double x, const double y) const {
+    (void)x;
+    const double temp = bg0 - y;
+    return temp * temp;
+  }
+
+  double bg0;
+};
+
+// y = bg0 + bg1*x
+struct linear {
+  explicit linear(const double bg0, const double bg1) : bg0(bg0), bg1(bg1) {}
+
+  double operator()(const double x, const double y) const {
+    const double temp = bg0 + bg1 * x - y;
+    return temp * temp;
+  }
+
+  double bg0;
+  double bg1;
+};
+
+// y = bg0 + bg1*x + bg2*x**2
+struct quadratic {
+  explicit quadratic(const double bg0, const double bg1, const double bg2)
+      : bg0(bg0), bg1(bg1), bg2(bg2) {}
+
+  double operator()(const double x, const double y) const {
+    const double temp = bg0 + bg1 * x + bg2 * x * x - y;
+    return temp * temp;
+  }
+
+  double bg0;
+  double bg1;
+  double bg2;
+};
+} // anonymous namespace
+
+namespace Mantid {
+namespace HistogramData {
+
+void estimate(const size_t order, const Points &X, const HistogramY &Y,
+              const size_t i_min, const size_t i_max, const size_t p_min,
+              const size_t p_max, bool haveGap, double &out_bg0,
+              double &out_bg1, double &out_bg2, double &out_chisq_red) {
+  // Validate input
+  if (order > 2)
+    throw std::runtime_error("can only estimate up to order=2");
+  if (i_min >= i_max) {
+    std::stringstream err;
+    err << "i_min (" << i_min << ")cannot be larger or equal to i_max ("
+        << i_max << ")";
+    throw std::runtime_error(err.str());
+  }
+  if (i_max > X.size()) {
+    std::stringstream err;
+    err << "i_max  (" << i_max << ") cannot be larger or equal to size of X "
+        << X.size() << ")";
+    throw std::runtime_error(err.str());
+  }
+  if (haveGap && p_min >= p_max)
+    throw std::runtime_error("p_min cannot larger or equal to p_max");
+  // ignore when p-range is outside of i-range
+
+  // set all output parameters to zero
+  out_bg0 = 0.;
+  out_bg1 = 0.;
+  out_bg2 = 0.;
+  out_chisq_red = INVALID_CHISQ;
+
+  // accumulate sum
+  double sum = 0.0;
+  double sumX = 0.0;
+  double sumY = 0.0;
+  double sumX2 = 0.0;
+  double sumXY = 0.0;
+  double sumX2Y = 0.0;
+  double sumX3 = 0.0;
+  double sumX4 = 0.0;
+  for (size_t i = i_min; i < i_max; ++i) {
+    if (haveGap && i >= p_min && i < p_max)
+      continue;
+    sum += 1.0;
+    sumX += X[i];
+    sumX2 += X[i] * X[i];
+    sumY += Y[i];
+    sumXY += X[i] * Y[i];
+    sumX2Y += X[i] * X[i] * Y[i];
+    sumX3 += X[i] * X[i] * X[i];
+    sumX4 += X[i] * X[i] * X[i] * X[i];
+  }
+
+  if (sum == 0.) {
+    return;
+  }
+
+  // Estimate flat
+  double bg0_flat = 0.;
+  calcFlatParameters(sum, sumY, bg0_flat);
+
+  // Estimate linear
+  double bg0_linear = 0.;
+  double bg1_linear = 0.;
+  calcLinearParameters(sum, sumX, sumY, sumXY, sumX2, bg0_linear, bg1_linear);
+
+  // Estimate quadratic
+  double bg0_quadratic = 0.;
+  double bg1_quadratic = 0.;
+  double bg2_quadratic = 0.;
+  calcQuadraticParameters(sum, sumX, sumY, sumXY, sumX2, sumX2Y, sumX3, sumX4,
+                          bg0_quadratic, bg1_quadratic, bg2_quadratic);
+
+  // Setup to calculate the residuals
+  double chisq_flat = 0.;
+  double chisq_linear = 0.;
+  double chisq_quadratic = 0.;
+  auto residual_flat = constant(bg0_flat);
+  auto residual_linear = linear(bg0_linear, bg1_linear);
+  auto residual_quadratic =
+      quadratic(bg0_quadratic, bg1_quadratic, bg2_quadratic);
+  double num_points = 0.;
+
+  // calculate the chisq - not normalized by the number of points
+  for (size_t i = i_min; i < i_max; ++i) {
+    if (haveGap && i >= p_min && i < p_max)
+      continue;
+
+    num_points += 1.;
+    chisq_flat += residual_flat(X[i], Y[i]);
+    chisq_linear += residual_linear(X[i], Y[i]);
+    chisq_quadratic += residual_quadratic(X[i], Y[i]);
+  }
+
+  // convert to <reduced chisq> = chisq / (<number points> - <number
+  // parameters>)
+  chisq_flat = chisq_flat / (num_points - 1.);
+  chisq_linear = chisq_linear / (num_points - 2.);
+  chisq_quadratic = chisq_quadratic / (num_points - 3.);
+
+  if (order < 2) {
+    chisq_quadratic = BAD_CHISQ;
+    if (order < 1) {
+      chisq_linear = BAD_CHISQ;
+    }
+  }
+
+  // choose the right background function to return
+  // this is written that lower order polynomial wins in the case of a tie
+  if ((chisq_flat <= chisq_linear) && (chisq_flat <= chisq_quadratic)) {
+    out_bg0 = bg0_flat;
+    out_chisq_red = chisq_flat;
+  } else if ((chisq_linear <= chisq_flat) &&
+             (chisq_linear <= chisq_quadratic)) {
+    out_bg0 = bg0_linear;
+    out_bg1 = bg1_linear;
+    out_chisq_red = chisq_linear;
+  } else {
+    out_bg0 = bg0_quadratic;
+    out_bg1 = bg1_quadratic;
+    out_bg2 = bg2_quadratic;
+    out_chisq_red = chisq_quadratic;
+  }
+}
+
+void estimateBackground(const size_t order, const Histogram &histo,
+                        const size_t i_min, const size_t i_max,
+                        const size_t p_min, const size_t p_max, double &out_bg0,
+                        double &out_bg1, double &out_bg2,
+                        double &out_chisq_red) {
+  const auto &X = histo.points();
+  const auto &Y = histo.y();
+
+  // fit with a hole in the middle
+  estimate(order, X, Y, i_min, i_max, p_min, p_max, true, out_bg0, out_bg1,
+           out_bg2, out_chisq_red);
+}
+
+void estimatePolynomial(const size_t order, const Histogram &histo,
+                        const size_t i_min, const size_t i_max, double &out_bg0,
+                        double &out_bg1, double &out_bg2,
+                        double &out_chisq_red) {
+  const auto &X = histo.points();
+  const auto &Y = histo.y();
+  estimate(order, X, Y, i_min, i_max, 0, 0, false, out_bg0, out_bg1, out_bg2,
+           out_chisq_red);
+}
+
+} // namespace HistogramData
+} // namespace Mantid
diff --git a/Framework/HistogramData/src/HistogramBuilder.cpp b/Framework/HistogramData/src/HistogramBuilder.cpp
index 44932841a90525b7cff29dd9a7823077e066c321..6f43a9f72df01ab63eed66be6551c279149e2254 100644
--- a/Framework/HistogramData/src/HistogramBuilder.cpp
+++ b/Framework/HistogramData/src/HistogramBuilder.cpp
@@ -34,6 +34,8 @@ Histogram HistogramBuilder::build() const {
   }
   if (m_e)
     histogram->setSharedE(m_e);
+  if (d_x)
+    histogram->setSharedDx(d_x);
   return *histogram;
 }
 
diff --git a/Framework/HistogramData/test/EstimatePolynomialTest.h b/Framework/HistogramData/test/EstimatePolynomialTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8005e32fcfe7083facf4ce99fa3f15518ec30d7
--- /dev/null
+++ b/Framework/HistogramData/test/EstimatePolynomialTest.h
@@ -0,0 +1,126 @@
+#ifndef MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIALTEST_H_
+#define MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIALTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidHistogramData/EstimatePolynomial.h"
+#include "MantidHistogramData/Histogram.h"
+#include "MantidHistogramData/LinearGenerator.h"
+#include "MantidHistogramData/QuadraticGenerator.h"
+
+using Mantid::HistogramData::estimateBackground;
+using Mantid::HistogramData::estimatePolynomial;
+using Mantid::HistogramData::Counts;
+using Mantid::HistogramData::Histogram;
+using Mantid::HistogramData::LinearGenerator;
+using Mantid::HistogramData::Points;
+using Mantid::HistogramData::QuadraticGenerator;
+
+class EstimatePolynomialTest : 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 EstimatePolynomialTest *createSuite() {
+    return new EstimatePolynomialTest();
+  }
+  static void destroySuite(EstimatePolynomialTest *suite) { delete suite; }
+
+  void test_BadParameters() {
+    Histogram histo(Points{10, LinearGenerator(0., 1.)},
+                    Counts{10, LinearGenerator(10., 0.)});
+
+    double bg0, bg1, bg2, chisq;
+    // bad order
+    TS_ASSERT_THROWS(Mantid::HistogramData::estimatePolynomial(
+                         3, histo, 0, histo.size(), bg0, bg1, bg2, chisq),
+                     std::runtime_error);
+    // bad range i_max < i_min
+    TS_ASSERT_THROWS(estimatePolynomial(2, histo, 1, 0, bg0, bg1, bg2, chisq),
+                     std::runtime_error);
+    // bad range x.size() < i_max
+    TS_ASSERT_THROWS(estimatePolynomial(2, histo, 0, 30, bg0, bg1, bg2, chisq),
+                     std::runtime_error);
+  }
+
+  void test_FlatData() {
+    Histogram histo(Points{10, LinearGenerator(0., 1.)},
+                    Counts{10, LinearGenerator(10., 0.)});
+
+    double bg0, bg1, bg2, chisq;
+    for (size_t order = 0; order < 3;
+         ++order) { // should always return that constant is best
+      estimatePolynomial(order, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+      TS_ASSERT_EQUALS(bg0, 10.);
+      TS_ASSERT_EQUALS(bg1, 0.);
+      TS_ASSERT_EQUALS(bg2, 0.);
+    }
+  }
+
+  void test_LinearData() {
+    Histogram histo(Points{10, LinearGenerator(0., 1.)},
+                    Counts{10, LinearGenerator(0., 12.)});
+
+    double bg0, bg1, bg2, chisq;
+
+    // flat
+    std::cout << "*** *** order=" << 0 << std::endl;
+    estimatePolynomial(0, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_DELTA(bg0, 54., .00001);
+    TS_ASSERT_EQUALS(bg1, 0.);
+    TS_ASSERT_EQUALS(bg2, 0.);
+
+    // linear
+    std::cout << "*** *** order=" << 1 << std::endl;
+    estimatePolynomial(1, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_EQUALS(bg0, 0.);
+    TS_ASSERT_EQUALS(bg1, 12.);
+    TS_ASSERT_EQUALS(bg2, 0.);
+
+    // quadratic
+    std::cout << "*** *** order=" << 2 << std::endl;
+    estimatePolynomial(2, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_EQUALS(bg0, 0.);
+    TS_ASSERT_EQUALS(bg1, 12.);
+    TS_ASSERT_EQUALS(bg2, 0.);
+  }
+
+  void test_QuadraticData() {
+    Histogram histo(Points{10, LinearGenerator(0., 1.)},
+                    Counts{10, QuadraticGenerator(10., 12., -3.)});
+    std::cout << "-> quad: ";
+    for (const auto &val : histo.y())
+      std::cout << val << " ";
+    std::cout << std::endl;
+
+    double bg0, bg1, bg2, chisq;
+
+    // flat
+    std::cout << "*** *** order=" << 0 << std::endl;
+    estimatePolynomial(0, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_DELTA(bg0, -21.5, .00001);
+    TS_ASSERT_EQUALS(bg1, 0.);
+    TS_ASSERT_EQUALS(bg2, 0.);
+
+    // linear
+    std::cout << "*** *** order=" << 1 << std::endl;
+    estimatePolynomial(1, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_DELTA(bg0, 46., .00001);
+    TS_ASSERT_DELTA(bg1, -15., .00001);
+    TS_ASSERT_EQUALS(bg2, 0.);
+
+    // quadratic
+    std::cout << "*** *** order=" << 2 << std::endl;
+    estimatePolynomial(2, histo, 0, histo.size(), bg0, bg1, bg2, chisq);
+    std::cout << "chisq=" << chisq << std::endl;
+    TS_ASSERT_EQUALS(bg0, 10.);
+    TS_ASSERT_EQUALS(bg1, 12.);
+    TS_ASSERT_EQUALS(bg2, -3.);
+  }
+};
+
+#endif /* MANTID_HISTOGRAMDATA_ESTIMATEPOLYNOMIALTEST_H_ */
diff --git a/Framework/HistogramData/test/HistogramBuilderTest.h b/Framework/HistogramData/test/HistogramBuilderTest.h
index f70363696e17a4925bd508244602e1ab4804f984..861825d596b165f68c98afc043f398c17afccfed 100644
--- a/Framework/HistogramData/test/HistogramBuilderTest.h
+++ b/Framework/HistogramData/test/HistogramBuilderTest.h
@@ -39,6 +39,8 @@ public:
     TS_ASSERT_THROWS(builder.build(), std::logic_error);
     builder.setY(6);
     TS_ASSERT_THROWS(builder.build(), std::logic_error);
+    builder.setDx(3);
+    TS_ASSERT_THROWS(builder.build(), std::logic_error);
   }
 
   void test_build_from_size() {
@@ -63,6 +65,31 @@ public:
     TS_ASSERT_EQUALS(hist.xMode(), Histogram::XMode::Points);
     TS_ASSERT_EQUALS(hist.yMode(), Histogram::YMode::Frequencies);
   }
+
+  void test_build_Dx() {
+    HistogramBuilder builder;
+    builder.setX(5);
+    builder.setY(5);
+    builder.setDx(5);
+    const auto hist = builder.build();
+    TS_ASSERT_EQUALS(hist.x().size(), 5);
+    TS_ASSERT_EQUALS(hist.y().size(), 5);
+    TS_ASSERT_EQUALS(hist.e().size(), 5);
+    TS_ASSERT_EQUALS(hist.dx().size(), 5);
+  }
+
+  void test_build_Dx_with_bin_edges() {
+    HistogramBuilder builder;
+    builder.setX(5);
+    builder.setY(4);
+    builder.setDx(4);
+    const auto hist = builder.build();
+    TS_ASSERT_EQUALS(hist.x().size(), 5);
+    TS_ASSERT_EQUALS(hist.y().size(), 4);
+    TS_ASSERT_EQUALS(hist.e().size(), 4);
+    TS_ASSERT_EQUALS(hist.dx().size(), 4);
+    TS_ASSERT_EQUALS(hist.xMode(), Histogram::XMode::BinEdges);
+  }
 };
 
 #endif /* MANTID_HISTOGRAMDATA_HISTOGRAMBUILDERTEST_H_ */
diff --git a/Framework/HistogramData/test/QuadraticGeneratorTest.h b/Framework/HistogramData/test/QuadraticGeneratorTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..f710d92f46c907f962b0130ec74b4b5ea90fd6f7
--- /dev/null
+++ b/Framework/HistogramData/test/QuadraticGeneratorTest.h
@@ -0,0 +1,40 @@
+#ifndef MANTID_HISTOGRAMDATA_QUADRATICGENERATORTEST_H_
+#define MANTID_HISTOGRAMDATA_QUADRATICGENERATORTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidHistogramData/QuadraticGenerator.h"
+
+#include <algorithm>
+
+using Mantid::HistogramData::QuadraticGenerator;
+
+class QuadraticGeneratorTest : 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 QuadraticGeneratorTest *createSuite() {
+    return new QuadraticGeneratorTest();
+  }
+  static void destroySuite(QuadraticGeneratorTest *suite) { delete suite; }
+
+  void test_length0() {
+    std::vector<double> x(0);
+    std::generate_n(x.begin(), 0, QuadraticGenerator(0.1, 0.2, 0.3));
+    TS_ASSERT_EQUALS(x, std::vector<double>(0));
+  }
+
+  void test_length1() {
+    std::vector<double> x(1);
+    std::generate_n(x.begin(), 1, QuadraticGenerator(0.1, 0.2, 0.3));
+    TS_ASSERT_EQUALS(x, std::vector<double>{0.1});
+  }
+
+  void test_length2() {
+    std::vector<double> x(2);
+    std::generate_n(x.begin(), 2, QuadraticGenerator(3, 2, 1));
+    TS_ASSERT_DELTA(x, std::vector<double>({3, 6}), 1e-14);
+  }
+};
+
+#endif /* MANTID_HISTOGRAMDATA_QUADRATICGENERATORTEST_H_ */
diff --git a/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h b/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h
index f26e863bc9cdc5298db0689297b89721e41c7f70..1515f9f8d703a81c848ce202146edbf541c281e9 100644
--- a/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h
+++ b/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h
@@ -60,6 +60,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"DownloadFile", "CatalogGetDataFiles", "CatalogLogin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h b/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h
index c84de8a944c62e77e508ceef05f0879d378eaeb1..e533b041b7425280e1f0bcf5ba6beb06c4d330fc 100644
--- a/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h
+++ b/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h
@@ -57,6 +57,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogDownloadDataFiles", "CatalogGetDataSets", "CatalogLogin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h b/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h
index db6a954318596e7138ac7e92fa79ccfe58c7b9e2..283a9629a47f826915fc9c0030291196f5f8a42b 100644
--- a/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h
+++ b/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h
@@ -57,6 +57,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogGetDataFiles", "CatalogDownloadDataFiles", "CatalogLogin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h b/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h
index 5e042ba5b5ae08a2e1b43e6b223119a3dc5dcfd7..2264f54c27e07c8cae5dc23337701604e09f2704 100644
--- a/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h
+++ b/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h
@@ -53,6 +53,9 @@ public:
   }
   /// Algorithm's version for identification.
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogLogin"};
+  }
   /// Algorithm's category for identification.
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogListInstruments.h b/Framework/ICat/inc/MantidICat/CatalogListInstruments.h
index 8a2e97ed3528e1a459a6e907fc7cad24ff0b1181..38829e19b2892f44cc1de6123b349855bfa29fed 100644
--- a/Framework/ICat/inc/MantidICat/CatalogListInstruments.h
+++ b/Framework/ICat/inc/MantidICat/CatalogListInstruments.h
@@ -48,6 +48,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogListInvestigationTypes"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h b/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h
index 52099cee6752106bc870c4c295691f53502f0ce2..277c03ac35f6cfa3675af15d8b5bc521fa32901e 100644
--- a/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h
+++ b/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h
@@ -50,6 +50,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogListInstruments"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogLogin.h b/Framework/ICat/inc/MantidICat/CatalogLogin.h
index f18ab9298d44e6097c46b36f76b732a5c0178182..f40c9cd77775abfe2e58e2e55ea0313aa9d35af5 100644
--- a/Framework/ICat/inc/MantidICat/CatalogLogin.h
+++ b/Framework/ICat/inc/MantidICat/CatalogLogin.h
@@ -54,6 +54,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogLogout", "CatalogSearch", "CatalogPublish"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogLogout.h b/Framework/ICat/inc/MantidICat/CatalogLogout.h
index c79808c0b3dbeae3b6c994328b14d7e41158469e..b8b48f74d794dc85a19a01075b50d352d2e5da25 100644
--- a/Framework/ICat/inc/MantidICat/CatalogLogout.h
+++ b/Framework/ICat/inc/MantidICat/CatalogLogout.h
@@ -51,6 +51,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogLogin"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h b/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h
index fb3c806dfe2c5193f61eb26430b73f50e66590f5..6ba41b4702f4aa941bb6aefc793893e7d6bcfe35 100644
--- a/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h
+++ b/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h
@@ -57,6 +57,9 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogSearch"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogPublish.h b/Framework/ICat/inc/MantidICat/CatalogPublish.h
index b98865b41caaac3a6e0172c26a14797377cf21c1..6bf0e884522eccb91c09ce60cf1b89675a40fb15 100644
--- a/Framework/ICat/inc/MantidICat/CatalogPublish.h
+++ b/Framework/ICat/inc/MantidICat/CatalogPublish.h
@@ -59,6 +59,9 @@ public:
   }
   /// Algorithm's version for identification.
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogLogin"};
+  }
   /// Algorithm's category for identification.
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/CatalogSearch.h b/Framework/ICat/inc/MantidICat/CatalogSearch.h
index 9e235f557f24013037c11c718870749def9d41cf..d2e9b471c698132370662b4f6bfb4602c9f74a58 100644
--- a/Framework/ICat/inc/MantidICat/CatalogSearch.h
+++ b/Framework/ICat/inc/MantidICat/CatalogSearch.h
@@ -68,6 +68,10 @@ public:
   }
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CatalogMyDataSearch", "CatalogGetDataFiles", "CatalogLogin",
+            "CatalogPublish"};
+  }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\Catalog";
diff --git a/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h b/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h
index 9041bbe85cc052ecc2f070912810bb719c1d9852..3e7c7bb57d7a3ea0d50379d725aff4ef4f65fe46 100644
--- a/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h
+++ b/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h
@@ -146,12 +146,12 @@ public:
 
 #ifndef SOAP_TYPE__QName
 #define SOAP_TYPE__QName (5)
-typedef char *_QName;
+using _QName = char *;
 #endif
 
 #ifndef SOAP_TYPE__XML
 #define SOAP_TYPE__XML (6)
-typedef char *_XML;
+using _XML = char *;
 #endif
 
 /******************************************************************************\
diff --git a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h
index 7a37356b858f1e4063d733d2aaa2da99db7255f0..4147d2a9e1faa31293bfc1958a1ad55c9c983538 100644
--- a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h
+++ b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h
@@ -1254,7 +1254,7 @@ extern const char soap_base64o[], soap_base64i[];
 
 /* gSOAP status/error codes */
 
-typedef soap_int32 soap_status;
+using soap_status = int32_t;
 
 #define SOAP_EOF EOF
 #define SOAP_ERR EOF
@@ -1364,7 +1364,7 @@ typedef soap_int32 soap_status;
 
 /* gSOAP transport, connection, and content encoding modes */
 
-typedef soap_int32 soap_mode;
+using soap_mode = int32_t;
 
 #define SOAP_IO 0x00000003       /* IO mask */
 #define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */
@@ -1621,7 +1621,7 @@ typedef soap_int32 soap_mode;
 
 /* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to
  * distinguish XML entities) */
-typedef soap_int32 soap_wchar;
+using soap_wchar = int32_t;
 
 /* namespace table row */
 struct Namespace {
@@ -1822,7 +1822,7 @@ struct soap_multipart {
   const char *location;             /* MIME Content-Location (optional) */
   const char *description;          /* MIME Content-Description (optional) */
 #ifdef __cplusplus
-  typedef soap_multipart_iterator iterator;
+  using iterator = soap_multipart_iterator;
 #endif
 };
 #endif
@@ -1868,7 +1868,7 @@ struct soap_dom_attribute {
   wchar_t *wide;
   struct soap *soap;
 #ifdef __cplusplus
-  typedef soap_dom_attribute_iterator iterator;
+  using iterator = soap_dom_attribute_iterator;
   struct soap_dom_attribute &set(const char *nstr,
                                  const char *name); /* set namespace and name */
   struct soap_dom_attribute &set(const char *data); /* set data */
@@ -1920,7 +1920,7 @@ struct soap_dom_element {
   char *tail;        /* leading content before end tag */
   struct soap *soap; /* soap context that manages this node */
 #ifdef __cplusplus
-  typedef soap_dom_element_iterator iterator;
+  using iterator = soap_dom_element_iterator;
   struct soap_dom_element &set(const char *nstr, const char *name);
   struct soap_dom_element &set(const char *data);
   struct soap_dom_element &set(void *node, int type);
@@ -2430,7 +2430,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_rand(void);
 #endif
 
 /* soap_traverse() traversal/walker routines take walker function arguments */
-typedef void soap_walker(struct soap *, void *, int, const char *,
+using soap_walker = void(struct soap *, void *, int, const char *,
                          const char *);
 
 SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap);
diff --git a/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h b/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h
index 63eb0cc97f502f6540c59b3b683fe78705ee74fb..55b4342d456fe827320363c9273b4432d161dccc 100644
--- a/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h
+++ b/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h
@@ -11887,12 +11887,12 @@ public:
 
 #ifndef SOAP_TYPE_ICat3__QName
 #define SOAP_TYPE_ICat3__QName (5)
-typedef char *_QName;
+using _QName = char *;
 #endif
 
 #ifndef SOAP_TYPE_ICat3__XML
 #define SOAP_TYPE_ICat3__XML (6)
-typedef char *_XML;
+using _XML = char *;
 #endif
 
 /******************************************************************************\
diff --git a/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h b/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h
index ce57682420fb4596dbbd472734e303263a758aeb..475ab86fb845c4eb10c2f25f6db9cd67a9ac3647 100644
--- a/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h
+++ b/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h
@@ -134,7 +134,7 @@ private:
    */
   template <class T>
   void savetoTableWorkspace(const T *input, Mantid::API::TableRow &t) {
-    if (input != 0) {
+    if (input != nullptr) {
       t << *input;
 
     } else {
diff --git a/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h b/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h
index d033a6828382eaf41f5f3ead53f73041d07f3bfc..8c998ddb6bd80e117698c8b10d0666dca520754e 100644
--- a/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h
+++ b/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h
@@ -3265,12 +3265,12 @@ public:
 
 #ifndef SOAP_TYPE_ICat4__QName
 #define SOAP_TYPE_ICat4__QName (5)
-typedef char *_QName;
+using _QName = char *;
 #endif
 
 #ifndef SOAP_TYPE_ICat4__XML
 #define SOAP_TYPE_ICat4__XML (6)
-typedef char *_XML;
+using _XML = char *;
 #endif
 
 /******************************************************************************\
diff --git a/Framework/ICat/src/GSoap/stdsoap2.cpp b/Framework/ICat/src/GSoap/stdsoap2.cpp
index 140a634526da605309dbb4f955297298c3f0af06..fc03059c4637bf0dacc9e982d79bc24d44fbf45f 100644
--- a/Framework/ICat/src/GSoap/stdsoap2.cpp
+++ b/Framework/ICat/src/GSoap/stdsoap2.cpp
@@ -16101,7 +16101,7 @@ int SOAP_FMAC2 soap_puthttphdr(struct soap *soap, int status, size_t count) {
             sizeof(soap->tmpbuf) - 80) {
       const char *t = strchr(s, ';');
       sprintf(soap->tmpbuf,
-              "multipart/related; charset=utf-8; boundary=\"%s\"; type=\"",
+              R"(multipart/related; charset=utf-8; boundary="%s"; type=")",
               soap->mime.boundary);
       if (t) {
         strncat(soap->tmpbuf, s, t - s);
diff --git a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
index 73db808d8e30b9b5862a6eee40a82f8db8dff220..f7b492201433d49931f8a06ab200c2c218049241 100644
--- a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
+++ b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h
@@ -87,10 +87,10 @@ public:
   IndexInfo(std::vector<IndexType> indices, const IndexInfo &parent);
 
   IndexInfo(const IndexInfo &other);
-  IndexInfo(IndexInfo &&other);
+  IndexInfo(IndexInfo &&other) noexcept;
   ~IndexInfo();
   IndexInfo &operator=(const IndexInfo &other);
-  IndexInfo &operator=(IndexInfo &&other);
+  IndexInfo &operator=(IndexInfo &&other) noexcept;
 
   size_t size() const;
   size_t globalSize() const;
diff --git a/Framework/Indexing/src/IndexInfo.cpp b/Framework/Indexing/src/IndexInfo.cpp
index f226f2136efbbec80bf57e52a2f76e195e9ae0f1..db12c33e2f0ba9273e8a1607d046f09406b3435f 100644
--- a/Framework/Indexing/src/IndexInfo.cpp
+++ b/Framework/Indexing/src/IndexInfo.cpp
@@ -83,17 +83,18 @@ IndexInfo::IndexInfo(const IndexInfo &other)
       m_spectrumDefinitions(other.m_spectrumDefinitions),
       m_spectrumNumberTranslator(other.m_spectrumNumberTranslator) {}
 
-IndexInfo::IndexInfo(IndexInfo &&) = default;
+IndexInfo::IndexInfo(IndexInfo &&) noexcept = default;
 
 // Defined as default in source for forward declaration with std::unique_ptr.
 IndexInfo::~IndexInfo() = default;
 
 IndexInfo &IndexInfo::operator=(const IndexInfo &other) {
   auto copy(other);
-  return *this = std::move(copy);
+  *this = std::move(copy);
+  return *this;
 }
 
-IndexInfo &IndexInfo::operator=(IndexInfo &&) = default;
+IndexInfo &IndexInfo::operator=(IndexInfo &&) noexcept = default;
 
 /// The *local* size, i.e., the number of spectra in this partition.
 size_t IndexInfo::size() const {
diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt
index b1915069fc170b7548808aa76ee50d0778ceadb3..938ea19d10f597994ff2385b2b086752959f26b7 100644
--- a/Framework/Kernel/CMakeLists.txt
+++ b/Framework/Kernel/CMakeLists.txt
@@ -79,7 +79,6 @@ set ( SRC_FILES
 	src/NDRandomNumberGenerator.cpp
 	src/NeutronAtom.cpp
 	src/NexusDescriptor.cpp
-	src/NormalDistribution.cpp
 	src/NullValidator.cpp
 	src/OptionalBool.cpp
 	src/ParaViewVersion.cpp
@@ -248,7 +247,7 @@ set ( INC_FILES
 	inc/MantidKernel/NetworkProxy.h
 	inc/MantidKernel/NeutronAtom.h
 	inc/MantidKernel/NexusDescriptor.h
-	inc/MantidKernel/NormalDistribution.h
+  inc/MantidKernel/normal_distribution.h
 	inc/MantidKernel/NullValidator.h
 	inc/MantidKernel/OptionalBool.h
 	inc/MantidKernel/ParaViewVersion.h
@@ -406,7 +405,6 @@ set ( TEST_FILES
 	NearestNeighboursTest.h
 	NeutronAtomTest.h
 	NexusDescriptorTest.h
-	NormalDistributionTest.h
 	NullValidatorTest.h
 	OptionalBoolTest.h
 	ProgressBaseTest.h
@@ -578,9 +576,9 @@ set ( QT_PLUGINS_DIR "." )
 if ( MAKE_VATES )
   set ( PV_PLUGINS_DIR "./plugins/paraview/qt%V" )
   if ( MSVC )
-    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")
+    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;")
   else()
-    set ( PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/lib;${ParaView_DIR}/lib/site-packages;${ParaView_DIR}/lib/site-packages/vtk")
+    set ( PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/lib;${ParaView_DIR}/lib/site-packages;")
   endif()
 else ()
   set ( PV_PLUGINS_DIR "" )
@@ -673,7 +671,7 @@ install ( TARGETS Kernel ${SYSTEM_PACKAGE_TARGET} DESTINATION ${LIB_DIR} )
 
 # Create the properties file for the installer
 set ( MANTID_ROOT_BUILD ${MANTID_ROOT} )
-if ( APPLE )
+if ( APPLE AND ENABLE_MANTIDPLOT )
   set ( MANTID_ROOT ../.. )
 else ()
   set ( MANTID_ROOT .. )
@@ -691,13 +689,13 @@ set ( FRAMEWORK_PLUGINS_DIR ${MANTID_ROOT}/plugins )
 set ( PYTHONPLUGIN_DIRS "${FRAMEWORK_PLUGINS_DIR}/python" )
 if(MAKE_VATES)
   if (APPLE)
-    set ( PARAVIEW_PYTHON_PATHS "../Libraries;../Python;../Python/vtk")
+    set ( PARAVIEW_PYTHON_PATHS "../Libraries;../Python;")
   elseif (WIN32)
     set ( PV_LIBS "../lib/paraview-${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}" )
-    set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS}/site-packages;${PV_LIBS}/site-packages/vtk" )
+    set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS}/site-packages;" )
   else () #Linux
     set ( PV_LIBS "${CMAKE_INSTALL_PREFIX}/lib/paraview-${PARAVIEW_VERSION}")
-    set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS};${PV_LIBS}/site-packages;${PV_LIBS}/site-packages/vtk")
+    set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS};${PV_LIBS}/site-packages;")
   endif ()
 else ()
     set ( PARAVIEW_PYTHON_PATHS "")
diff --git a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h
index 11e2f98825fe4497c1544b47c3c69096cb4e86cb..dff6a293d751f09a768ce060ca92d8833404bc7a 100644
--- a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h
+++ b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h
@@ -176,8 +176,8 @@ enum ANNbool { ANNfalse = 0, ANNtrue = 1 }; // ANN boolean type (non ANSI C++)
 //		not occur in distance calculation.
 //----------------------------------------------------------------------
 
-typedef double ANNcoord; // coordinate data type
-typedef double ANNdist;  // distance data type
+using ANNcoord = double; // coordinate data type
+using ANNdist = double;  // distance data type
 
 //----------------------------------------------------------------------
 //	ANNidx
@@ -193,7 +193,7 @@ typedef double ANNdist;  // distance data type
 //		It should be distinguishable from any valid array index.
 //----------------------------------------------------------------------
 
-typedef int ANNidx;             // point index
+using ANNidx = int;             // point index
 const ANNidx ANN_NULL_IDX = -1; // a NULL point index
 
 //----------------------------------------------------------------------
@@ -408,10 +408,10 @@ const ANNbool ANN_ALLOW_SELF_MATCH = ANNfalse;
 //		when returning the results of k-nearest neighbor queries.
 //----------------------------------------------------------------------
 
-typedef ANNcoord *ANNpoint;      // a point
-typedef ANNpoint *ANNpointArray; // an array of points
-typedef ANNdist *ANNdistArray;   // an array of distances
-typedef ANNidx *ANNidxArray;     // an array of point indices
+using ANNpoint = ANNcoord *;      // a point
+using ANNpointArray = ANNpoint *; // an array of points
+using ANNdistArray = ANNdist *;   // an array of distances
+using ANNidxArray = ANNidx *;     // an array of point indices
 
 //----------------------------------------------------------------------
 //	Basic point and array utilities:
@@ -766,9 +766,9 @@ const int ANN_N_SHRINK_RULES = 4; // number of shrink rules
 // Some types and objects used by kd-tree functions
 // See src/kd_tree.h and src/kd_tree.cpp for definitions
 //----------------------------------------------------------------------
-class ANNkdStats;              // stats on kd-tree
-class ANNkd_node;              // generic node in a kd-tree
-typedef ANNkd_node *ANNkd_ptr; // pointer to a kd-tree node
+class ANNkdStats;               // stats on kd-tree
+class ANNkd_node;               // generic node in a kd-tree
+using ANNkd_ptr = ANNkd_node *; // pointer to a kd-tree node
 
 class DLL_API ANNkd_tree : public ANNpointSet {
 protected:
diff --git a/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h b/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h
index f5d990c5c51b2caee48d471ec641ab31174da678..0a6b7860f3960a4590d14fe46ddfe9aaf55020c6 100644
--- a/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h
+++ b/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h
@@ -200,6 +200,6 @@ public:
 };
 
 // array of halfspaces
-typedef ANNorthHalfSpace *ANNorthHSArray;
+using ANNorthHSArray = ANNorthHalfSpace *;
 
 #endif
diff --git a/Framework/Kernel/inc/MantidKernel/Cache.h b/Framework/Kernel/inc/MantidKernel/Cache.h
index e403a2bf8a8c96b0907f0465b28d5b2775b407c1..eb6167cad323f8292ddfc9dfcd9dd5370c34b188 100644
--- a/Framework/Kernel/inc/MantidKernel/Cache.h
+++ b/Framework/Kernel/inc/MantidKernel/Cache.h
@@ -167,10 +167,10 @@ private:
   /// internal mutex
   mutable std::mutex m_mutex;
   /// iterator typedef
-  typedef typename std::map<KEYTYPE, VALUETYPE>::iterator CacheMapIterator;
+  using CacheMapIterator = typename std::map<KEYTYPE, VALUETYPE>::iterator;
   /// const_iterator typedef
-  typedef typename std::map<KEYTYPE, VALUETYPE>::const_iterator
-      CacheMapConstIterator;
+  using CacheMapConstIterator =
+      typename std::map<KEYTYPE, VALUETYPE>::const_iterator;
 };
 
 } // namespace Kernel
diff --git a/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Framework/Kernel/inc/MantidKernel/ConfigService.h
index e22ad3433e9a73e908b833728bb9e3d7e3951e8f..1da60b745ee0b73714a2a5b8933d7f58bca17ded 100644
--- a/Framework/Kernel/inc/MantidKernel/ConfigService.h
+++ b/Framework/Kernel/inc/MantidKernel/ConfigService.h
@@ -357,12 +357,12 @@ private:
 
 EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL
     Mantid::Kernel::SingletonHolder<ConfigServiceImpl>;
-typedef Mantid::Kernel::SingletonHolder<ConfigServiceImpl> ConfigService;
+using ConfigService = Mantid::Kernel::SingletonHolder<ConfigServiceImpl>;
 
-typedef Mantid::Kernel::ConfigServiceImpl::ValueChanged
-    ConfigValChangeNotification;
-typedef const Poco::AutoPtr<Mantid::Kernel::ConfigServiceImpl::ValueChanged> &
-    ConfigValChangeNotification_ptr;
+using ConfigValChangeNotification =
+    Mantid::Kernel::ConfigServiceImpl::ValueChanged;
+using ConfigValChangeNotification_ptr =
+    const Poco::AutoPtr<Mantid::Kernel::ConfigServiceImpl::ValueChanged> &;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/DataItem.h b/Framework/Kernel/inc/MantidKernel/DataItem.h
index fd02ec7edaab21fee142de507f7bac540e019a6a..ec3a665f266f1a002a70477299e279a1807ccb22 100644
--- a/Framework/Kernel/inc/MantidKernel/DataItem.h
+++ b/Framework/Kernel/inc/MantidKernel/DataItem.h
@@ -92,9 +92,9 @@ private:
 };
 
 /// Shared pointer to a DataItem
-typedef boost::shared_ptr<DataItem> DataItem_sptr;
+using DataItem_sptr = boost::shared_ptr<DataItem>;
 /// Shared pointer to a const DataItem
-typedef boost::shared_ptr<const DataItem> DataItem_const_sptr;
+using DataItem_const_sptr = boost::shared_ptr<const DataItem>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/DataService.h b/Framework/Kernel/inc/MantidKernel/DataService.h
index c29896cf0470b39b3362f53f97ae3d8fa6728add..788d75a803fabea8d3e68182514e1d01f8c42f09 100644
--- a/Framework/Kernel/inc/MantidKernel/DataService.h
+++ b/Framework/Kernel/inc/MantidKernel/DataService.h
@@ -75,12 +75,12 @@ struct CaseInsensitiveCmp {
 template <typename T> class DLLExport DataService {
 private:
   /// Typedef for the map holding the names of and pointers to the data objects
-  typedef std::map<std::string, boost::shared_ptr<T>, CaseInsensitiveCmp>
-      svcmap;
+  using svcmap =
+      std::map<std::string, boost::shared_ptr<T>, CaseInsensitiveCmp>;
   /// Iterator for the data store map
-  typedef typename svcmap::iterator svc_it;
+  using svc_it = typename svcmap::iterator;
   /// Const iterator for the data store map
-  typedef typename svcmap::const_iterator svc_constit;
+  using svc_constit = typename svcmap::const_iterator;
 
 public:
   /// Class for named object notifications
diff --git a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h
index 638fcaebc9bebb56ea63d656fe4a51a125b88d6c..9322b0a94e0bed1d25b280d652199a329194cc99 100644
--- a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h
+++ b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h
@@ -61,18 +61,17 @@ public:
    * Index 1: Position in the file.
    * Index 2: Size of the free block
    */
-  typedef boost::multi_index::multi_index_container<
-      FreeBlock,
-      boost::multi_index::indexed_by<
-          boost::multi_index::ordered_non_unique<
-              BOOST_MULTI_INDEX_CONST_MEM_FUN(FreeBlock, uint64_t,
-                                              getFilePosition)>,
-          boost::multi_index::ordered_non_unique<
-              BOOST_MULTI_INDEX_CONST_MEM_FUN(FreeBlock, uint64_t, getSize)>>>
-      freeSpace_t;
+  using freeSpace_t = boost::multi_index::multi_index_container<
+      FreeBlock, boost::multi_index::indexed_by<
+                     boost::multi_index::ordered_non_unique<
+                         ::boost::multi_index::const_mem_fun<
+                             FreeBlock, uint64_t, &FreeBlock::getFilePosition>>,
+                     boost::multi_index::ordered_non_unique<
+                         ::boost::multi_index::const_mem_fun<
+                             FreeBlock, uint64_t, &FreeBlock::getSize>>>>;
 
   /// A way to index the free space by their size
-  typedef freeSpace_t::nth_index<1>::type freeSpace_bySize_t;
+  using freeSpace_bySize_t = freeSpace_t::nth_index<1>::type;
 
   DiskBuffer();
   DiskBuffer(uint64_t m_writeBufferSize);
diff --git a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
index 625381c994f7c054914643084697a22da39653a7..84d7d8efd903154c6a730710a12df2739e5beb2f 100644
--- a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
+++ b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
@@ -32,7 +32,7 @@ namespace Kernel {
 //----------------------------------------------------------------------------
 class Logger;
 
-typedef std::less<std::string> CaseSensitiveStringComparator;
+using CaseSensitiveStringComparator = std::less<std::string>;
 
 /** @class DynamicFactory DynamicFactory.h Kernel/DynamicFactory.h
 
@@ -96,7 +96,7 @@ public:
   void disableNotifications() { m_notifyStatus = Disabled; }
 
   /// A typedef for the instantiator
-  typedef AbstractInstantiator<Base> AbstractFactory;
+  using AbstractFactory = AbstractInstantiator<Base>;
   /// Destroys the DynamicFactory and deletes the instantiators for
   /// all registered classes.
   virtual ~DynamicFactory() {
@@ -237,7 +237,7 @@ private:
   }
 
   /// A typedef for the map of registered classes
-  typedef std::map<std::string, AbstractFactory *, Comparator> FactoryMap;
+  using FactoryMap = std::map<std::string, AbstractFactory *, Comparator>;
   /// The map holding the registered class names and their instantiators
   FactoryMap _map;
   /// Flag marking whether we should dispatch notifications
diff --git a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
index a1da07cbd62f8b3170c8136ab46b4ea02ee9656c..a1af17b73ffdf1e1d46f9216b83ec58abef0acd8 100644
--- a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
@@ -131,8 +131,8 @@ private:
   /// this facility
 
   // TODO: remove RemoteJobManager form here (trac ticket #11373)
-  typedef std::map<std::string, boost::shared_ptr<RemoteJobManager>>
-      ComputeResourcesMap;
+  using ComputeResourcesMap =
+      std::map<std::string, boost::shared_ptr<RemoteJobManager>>;
   ComputeResourcesMap m_computeResources; ///< list of compute resources
                                           ///(clusters, etc...) available at
                                           /// this facility
diff --git a/Framework/Kernel/inc/MantidKernel/FunctionTask.h b/Framework/Kernel/inc/MantidKernel/FunctionTask.h
index 64ee250577315dc5488dedb14cb02f9f8280fa34..ad73391beea5ec70b191f949fd7ed75d4a960117 100644
--- a/Framework/Kernel/inc/MantidKernel/FunctionTask.h
+++ b/Framework/Kernel/inc/MantidKernel/FunctionTask.h
@@ -25,7 +25,7 @@ namespace Kernel {
 class DLLExport FunctionTask final : public Task {
 public:
   /// Typedef for a function with no arguments and no return
-  typedef void (*voidFunction)();
+  using voidFunction = void (*)();
   //---------------------------------------------------------------------------------------------
   /** Constructor for a simple void function.
    *
diff --git a/Framework/Kernel/inc/MantidKernel/IValidator.h b/Framework/Kernel/inc/MantidKernel/IValidator.h
index c814d71e84f5cbdecccc797060a6b64df61c8bc8..f1f0aad93984b46b8a0cd25dfffd35bf56360fe3 100644
--- a/Framework/Kernel/inc/MantidKernel/IValidator.h
+++ b/Framework/Kernel/inc/MantidKernel/IValidator.h
@@ -19,7 +19,7 @@ namespace Kernel {
 class IValidator;
 
 /// A shared_ptr to an IValidator
-typedef boost::shared_ptr<IValidator> IValidator_sptr;
+using IValidator_sptr = boost::shared_ptr<IValidator>;
 
 namespace {
 /// Helper object to determine if a type is either a pointer/shared_ptr
diff --git a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
index 85dc0b5de58cf210a3559df30da1dddf9fb52cbe..67f12f60fc93aef099448a60b9bc7e15da04c2e6 100644
--- a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
@@ -90,7 +90,7 @@ private:
 
   /// Typedef for the zeropadding holder, first is starting run-number,
   /// second is file prefix - zero padding pair
-  typedef std::map<unsigned int, std::pair<std::string, int>> ZeroPaddingMap;
+  using ZeroPaddingMap = std::map<unsigned int, std::pair<std::string, int>>;
   /// get the zeropadding part
   int getZeroPadding(ZeroPaddingMap::const_iterator it) const {
     return it->second.second;
diff --git a/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Framework/Kernel/inc/MantidKernel/InternetHelper.h
index 7f6902353e39a7100f3dd7fadde4f282ab773bdb..a7c3835ae2a234000b39a6715779fb481320178c 100644
--- a/Framework/Kernel/inc/MantidKernel/InternetHelper.h
+++ b/Framework/Kernel/inc/MantidKernel/InternetHelper.h
@@ -99,7 +99,7 @@ public:
   virtual ~InternetHelper();
 
   // Convenience typedef
-  typedef std::map<std::string, std::string> StringToStringMap;
+  using StringToStringMap = std::map<std::string, std::string>;
 
   // getters and setters
   void setTimeout(int seconds);
diff --git a/Framework/Kernel/inc/MantidKernel/LibraryManager.h b/Framework/Kernel/inc/MantidKernel/LibraryManager.h
index d8bb2acee8eb13013b4d3e418548c00c9ea76d44..aa308087a3a9c443ae0e753f5a5cc5825c65cd1d 100644
--- a/Framework/Kernel/inc/MantidKernel/LibraryManager.h
+++ b/Framework/Kernel/inc/MantidKernel/LibraryManager.h
@@ -82,7 +82,7 @@ private:
 
 EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL
     Mantid::Kernel::SingletonHolder<LibraryManagerImpl>;
-typedef Mantid::Kernel::SingletonHolder<LibraryManagerImpl> LibraryManager;
+using LibraryManager = Mantid::Kernel::SingletonHolder<LibraryManagerImpl>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h b/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h
index 3bfa68cac7f59a04f0f78a0a596a2c7c343198e1..17e3ac4ca47773e4fe275b6b9cddf5f7aa393f2a 100644
--- a/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h
+++ b/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h
@@ -45,8 +45,8 @@ public:
   LibraryWrapper(const LibraryWrapper &) = delete;
   LibraryWrapper &operator=(const LibraryWrapper &) = delete;
 
-  LibraryWrapper(LibraryWrapper &&src);
-  LibraryWrapper &operator=(LibraryWrapper &&rhs);
+  LibraryWrapper(LibraryWrapper &&src) noexcept;
+  LibraryWrapper &operator=(LibraryWrapper &&rhs) noexcept;
   ~LibraryWrapper();
 
   bool openLibrary(const std::string &filepath);
diff --git a/Framework/Kernel/inc/MantidKernel/ListValidator.h b/Framework/Kernel/inc/MantidKernel/ListValidator.h
index 136cd4e50c9efff307b923d1cee648a64e299050..67408b649129e209fc9a1142fe33b6fc33282875 100644
--- a/Framework/Kernel/inc/MantidKernel/ListValidator.h
+++ b/Framework/Kernel/inc/MantidKernel/ListValidator.h
@@ -196,7 +196,7 @@ protected:
 };
 
 /// ListValidator<std::string> is used heavily
-typedef ListValidator<std::string> StringListValidator;
+using StringListValidator = ListValidator<std::string>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/LogParser.h b/Framework/Kernel/inc/MantidKernel/LogParser.h
index f74caf208127f183bf7bfa95dfc67a024e77c794..ed5175e83598edb14ada260f479a6f93ba67d959 100644
--- a/Framework/Kernel/inc/MantidKernel/LogParser.h
+++ b/Framework/Kernel/inc/MantidKernel/LogParser.h
@@ -107,7 +107,7 @@ private:
 
   /// Typedef for a map of string commands to an enum of strongly typed
   /// commands.
-  typedef std::map<std::string, commands> CommandMap;
+  using CommandMap = std::map<std::string, commands>;
 
   /// TimeSeriesProperty<int> containing data periods. Created by LogParser
   boost::shared_ptr<Kernel::Property> m_periods;
diff --git a/Framework/Kernel/inc/MantidKernel/Logger.h b/Framework/Kernel/inc/MantidKernel/Logger.h
index b13542c7dbc7bf48deab88e11b7f789cc538a597..ed1a37ffe4f48b7e2eb73aab7bd719b9582fe95c 100644
--- a/Framework/Kernel/inc/MantidKernel/Logger.h
+++ b/Framework/Kernel/inc/MantidKernel/Logger.h
@@ -67,7 +67,7 @@ class ThreadSafeLogStream;
 class MANTID_KERNEL_DLL Logger {
 public:
   // Our logger's priority types are the same as POCO's Message's types.
-  typedef Poco::Message::Priority Priority;
+  using Priority = Poco::Message::Priority;
 
   static const std::string *PriorityNames;
 
diff --git a/Framework/Kernel/inc/MantidKernel/MDUnit.h b/Framework/Kernel/inc/MantidKernel/MDUnit.h
index e76bd5eaaf05d0eb0783979b8c728e4bf88f21b1..6b483b5f2794af170798b3f880655195c05a641f 100644
--- a/Framework/Kernel/inc/MantidKernel/MDUnit.h
+++ b/Framework/Kernel/inc/MantidKernel/MDUnit.h
@@ -83,8 +83,8 @@ public:
   LabelUnit *clone() const override;
 };
 
-typedef std::unique_ptr<MDUnit> MDUnit_uptr;
-typedef std::unique_ptr<const MDUnit> MDUnit_const_uptr;
+using MDUnit_uptr = std::unique_ptr<MDUnit>;
+using MDUnit_const_uptr = std::unique_ptr<const MDUnit>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h b/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h
index 5cd8d1726e8c66b90114bc99b3b30f6b329b72ff..10c97e81a4a3e6edc31743e053c1fb9c870ce633 100644
--- a/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h
+++ b/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h
@@ -65,9 +65,9 @@ class MANTID_KERNEL_DLL ReciprocalLatticeUnitFactory : public MDUnitFactory {
   bool canInterpret(const std::string &unitString) const override;
 };
 
-typedef std::unique_ptr<MDUnitFactory> MDUnitFactory_uptr;
+using MDUnitFactory_uptr = std::unique_ptr<MDUnitFactory>;
 
-typedef std::unique_ptr<const MDUnitFactory> MDUnitFactory_const_uptr;
+using MDUnitFactory_const_uptr = std::unique_ptr<const MDUnitFactory>;
 
 /// Convience method. Pre-constructed builder chain.
 MDUnitFactory_uptr MANTID_KERNEL_DLL makeMDUnitFactoryChain();
diff --git a/Framework/Kernel/inc/MantidKernel/MRUList.h b/Framework/Kernel/inc/MantidKernel/MRUList.h
index 34c47702f47157f0a3a5f4302be0fdb2f4f52fa0..33a8dcee1b7bfc12d95c896f0a2c08e29200caab 100644
--- a/Framework/Kernel/inc/MantidKernel/MRUList.h
+++ b/Framework/Kernel/inc/MantidKernel/MRUList.h
@@ -48,16 +48,16 @@ namespace Kernel {
 template <class T> class DLLExport MRUList {
 private:
   /// hideous typedef for the container holding the list
-  typedef typename boost::multi_index::multi_index_container<
+  using item_list = typename boost::multi_index::multi_index_container<
       T *,
       boost::multi_index::indexed_by<
           boost::multi_index::sequenced<>,
-          boost::multi_index::hashed_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN(
-              T, std::uintptr_t, hashIndexFunction)>>> item_list;
+          boost::multi_index::hashed_unique<::boost::multi_index::const_mem_fun<
+              T, std::uintptr_t, &T::hashIndexFunction>>>>;
 
   /// This typedef makes an ordered item list (you access it by the 1st index)
-  typedef typename boost::multi_index::nth_index<item_list, 1>::type
-      ordered_item_list;
+  using ordered_item_list =
+      typename boost::multi_index::nth_index<item_list, 1>::type;
 
   /// The most recently used list
   mutable item_list il;
diff --git a/Framework/Kernel/inc/MantidKernel/Material.h b/Framework/Kernel/inc/MantidKernel/Material.h
index c77bd7991eeb9af2af4776bcc04165ee6820b496..3cf75d93ad12ddd9ff34ac8c02a61cd036002368 100644
--- a/Framework/Kernel/inc/MantidKernel/Material.h
+++ b/Framework/Kernel/inc/MantidKernel/Material.h
@@ -64,7 +64,7 @@ public:
     FormulaUnit(const PhysicalConstants::Atom &atom, const double multiplicity);
   };
 
-  typedef std::vector<FormulaUnit> ChemicalFormula;
+  using ChemicalFormula = std::vector<FormulaUnit>;
 
   static ChemicalFormula parseChemicalFormula(const std::string chemicalSymbol);
 
@@ -193,9 +193,9 @@ private:
 };
 
 /// Typedef for a shared pointer
-typedef boost::shared_ptr<Material> Material_sptr;
+using Material_sptr = boost::shared_ptr<Material>;
 /// Typedef for a shared pointer to a const object
-typedef boost::shared_ptr<const Material> Material_const_sptr;
+using Material_const_sptr = boost::shared_ptr<const Material>;
 }
 }
 
diff --git a/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h b/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h
index 52746165bacfe50f6d565dfea93f8d7dae5a421b..dc5d05f7e2736513f3740b90c2f003b267891dea 100644
--- a/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h
+++ b/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h
@@ -62,7 +62,7 @@ public:
   Material build() const;
 
 private:
-  typedef std::tuple<PhysicalConstants::NeutronAtom, double> Composition;
+  using Composition = std::tuple<PhysicalConstants::NeutronAtom, double>;
 
   bool hasOverrideNeutronProperties() const;
   void overrideNeutronProperties(PhysicalConstants::NeutronAtom &neutron) const;
diff --git a/Framework/Kernel/inc/MantidKernel/Matrix.h b/Framework/Kernel/inc/MantidKernel/Matrix.h
index 0c1661aa17820f2ac3a3153876da168934c48337..13564d466ac0e70d35aa193424d70e8e12f94be8 100644
--- a/Framework/Kernel/inc/MantidKernel/Matrix.h
+++ b/Framework/Kernel/inc/MantidKernel/Matrix.h
@@ -43,7 +43,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 template <typename T> class DLLExport Matrix {
 public:
   /// Enable users to retrieve the element type
-  typedef T value_type;
+  using value_type = T;
 
 private:
   size_t m_numRows;    ///< Number of rows    (x coordinate)
@@ -194,9 +194,9 @@ private:
 // Typedefs
 //-------------------------------------------------------------------------
 /// A matrix of doubles
-typedef Mantid::Kernel::Matrix<double> DblMatrix;
+using DblMatrix = Mantid::Kernel::Matrix<double>;
 /// A matrix of ints
-typedef Mantid::Kernel::Matrix<int> IntMatrix;
+using IntMatrix = Mantid::Kernel::Matrix<int>;
 
 //-------------------------------------------------------------------------
 // Utility methods
diff --git a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
index 2d0a49f831f116645fadf73c29ecf832a4a6a6dc..1fe8149a0f52de02890d80eebffba51067ad4e2a 100644
--- a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
@@ -35,7 +35,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 template <class TYPE = double>
 class MatrixProperty : public PropertyWithValue<Matrix<TYPE>> {
   /// Typedef the held type
-  typedef Kernel::Matrix<TYPE> HeldType;
+  using HeldType = Kernel::Matrix<TYPE>;
 
 public:
   /// Constructor
diff --git a/Framework/Kernel/inc/MantidKernel/MersenneTwister.h b/Framework/Kernel/inc/MantidKernel/MersenneTwister.h
index 8190d349c33bf03aaa8eb7b4c56744e74da47924..8cb36b31331c3d090ab07750de91a000ad9f7ecd 100644
--- a/Framework/Kernel/inc/MantidKernel/MersenneTwister.h
+++ b/Framework/Kernel/inc/MantidKernel/MersenneTwister.h
@@ -6,9 +6,8 @@
 //------------------------------------------------------------------------------
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 
-#ifndef Q_MOC_RUN
-#include <boost/random/mersenne_twister.hpp>
-#endif
+#include <memory>
+#include <random>
 
 namespace Mantid {
 namespace Kernel {
@@ -17,13 +16,6 @@ namespace Kernel {
   generator algorithm as a specialzation of the PseudoRandomNumberGenerator
   interface.
 
-  Further documentation can be found here:
-
-  http://www.boost.org/doc/libs/1_42_0/libs/random/random-generators.html
-
-  @author Martyn Gigg, Tessella plc
-  @date 19/11/2007
-
   Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
   National Laboratory & European Spallation Source
 
@@ -58,8 +50,6 @@ public:
   explicit MersenneTwister(const size_t seedValue);
   /// Construct the generator with an initial seed and range.
   MersenneTwister(const size_t seedValue, const double start, const double end);
-  /// Destructor
-  ~MersenneTwister() override;
 
   MersenneTwister(const MersenneTwister &) = delete;
   MersenneTwister &operator=(const MersenneTwister &) = delete;
@@ -88,17 +78,17 @@ public:
   double max() const override { return m_end; }
 
 private:
-  /// The boost Mersenne Twister generator
-  boost::mt19937 m_generator;
+  /// The engine
+  std::mt19937 m_engine;
   /// Minimum in range
   double m_start;
   /// Maximum in range
   double m_end;
   /// The current seed
-  boost::mt19937::result_type m_currentSeed;
+  std::mt19937::result_type m_seed;
   /// A generator that will take the value when save is requested. Pointer so
   /// that it is only instantiated when required
-  boost::mt19937 *m_savedStateGenerator;
+  std::unique_ptr<std::mt19937> m_savedEngine;
 };
 }
 }
diff --git a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h
index 3ba554a9bdc20a79ad95833c22b574377bc5ff77..e8fa5ef6424ea1dbaab056d0bb356f47653206a9 100644
--- a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h
+++ b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h
@@ -103,9 +103,9 @@ template <int N = 3> class DLLExport NearestNeighbours {
 
 public:
   // typedefs for code brevity
-  typedef Eigen::Matrix<double, N, 1> VectorType;
-  typedef std::vector<std::tuple<VectorType, size_t, double>>
-      NearestNeighbourResults;
+  using VectorType = Eigen::Matrix<double, N, 1>;
+  using NearestNeighbourResults =
+      std::vector<std::tuple<VectorType, size_t, double>>;
 
   /** Create a nearest neighbour search object
    *
diff --git a/Framework/Kernel/inc/MantidKernel/NormalDistribution.h b/Framework/Kernel/inc/MantidKernel/NormalDistribution.h
deleted file mode 100644
index 68a64e707e73d95f8124439902a59f97df79a85d..0000000000000000000000000000000000000000
--- a/Framework/Kernel/inc/MantidKernel/NormalDistribution.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef MANTID_KERNEL_NORMAL_DISTRIBUTION_H_
-#define MANTID_KERNEL_NORMAL_DISTRIBUTION_H_
-
-//------------------------------------------------------------------------------
-// Includes
-//------------------------------------------------------------------------------
-#include "MantidKernel/DllConfig.h"
-#include "MantidKernel/MersenneTwister.h"
-
-#include <boost/random/normal_distribution.hpp>
-
-namespace Mantid {
-namespace Kernel {
-
-/**
-  This implements a generator of normally distributed pseudo-random numbers.
-
-  Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>.
-  Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-class MANTID_KERNEL_DLL NormalDistribution {
-
-public:
-  /// Construct the generator using time stamp for the initial seed.
-  NormalDistribution();
-  /// Construct the generator with initial distribution parameters
-  /// and default seed.
-  NormalDistribution(const double mean, const double sigma);
-  /// Construct the generator with initial distribution parameters and
-  /// a seed value.
-  NormalDistribution(const size_t seedValue, const double mean,
-                     const double sigma);
-
-  NormalDistribution(const NormalDistribution &) = delete;
-  NormalDistribution &operator=(const NormalDistribution &) = delete;
-
-  /// Set the random number seed
-  void setSeed(const size_t seedValue);
-  /// Generate the next random number in the sequence
-  double nextValue();
-  /// Get the mean of the distribution
-  double mean() const { return m_generator.mean(); }
-  /// Get the sigma of the distribution
-  double sigma() const { return m_generator.sigma(); }
-  /// Generate a random number from a distribution with given mean and sigma
-  double randomValue(double argMean, double argSigma);
-
-private:
-  /// The boost Mersenne Twister generator
-  /// (In the future when we have other uniform generators this can be a ref
-  /// to a PseudoRandomNumberGenerator base class and the user can initialize it
-  /// with an implementation of choise)
-  MersenneTwister m_uniform_generator;
-  /// The boost normal distribution generator
-  boost::normal_distribution<double> m_generator;
-};
-}
-}
-
-#endif // MANTID_KERNEL_NORMAL_DISTRIBUTION_H_
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyHelper.h b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h
index 86c67e618ab1572c73a360ccd54f223122af5faf..1fbe4423e46fbfe551d38189c90131e086e59caf 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyHelper.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h
@@ -210,7 +210,7 @@ namespace detail {
 template <typename T>
 void toValue(const std::string &strvalue, std::vector<T> &value,
              std::true_type) {
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer values(strvalue, ",",
                    tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
   value.clear();
@@ -224,7 +224,7 @@ template <typename T>
 void toValue(const std::string &strvalue, std::vector<T> &value,
              std::false_type) {
   // Split up comma-separated properties
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer values(strvalue, ",",
                    tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
 
@@ -263,7 +263,7 @@ template <typename T>
 void toValue(const std::string &strvalue, std::vector<std::vector<T>> &value,
              const std::string &outerDelimiter = ",",
              const std::string &innerDelimiter = "+") {
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer tokens(strvalue, outerDelimiter,
                    tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
 
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyHistory.h b/Framework/Kernel/inc/MantidKernel/PropertyHistory.h
index c45a142bc2bb018b1487c52a81a7c59a76b267a1..9ddcba5d976a37694b892bde6cbb8c7c6a6f2cc1 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyHistory.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyHistory.h
@@ -96,9 +96,9 @@ private:
 };
 
 // typedefs for property history pointers
-typedef boost::shared_ptr<PropertyHistory> PropertyHistory_sptr;
-typedef boost::shared_ptr<const PropertyHistory> PropertyHistory_const_sptr;
-typedef std::vector<PropertyHistory_sptr> PropertyHistories;
+using PropertyHistory_sptr = boost::shared_ptr<PropertyHistory>;
+using PropertyHistory_const_sptr = boost::shared_ptr<const PropertyHistory>;
+using PropertyHistories = std::vector<PropertyHistory_sptr>;
 
 MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &,
                                            const PropertyHistory &);
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManager.h b/Framework/Kernel/inc/MantidKernel/PropertyManager.h
index dc1d192135b813d0691c067fdfd67f937c8090b1..e9b4e33ab162f5b76750d10d78658f397e092f9c 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyManager.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyManager.h
@@ -135,7 +135,7 @@ private:
       const std::unordered_set<std::string> &ignoreProperties);
 
   /// typedef for the map holding the properties
-  typedef std::map<std::string, std::unique_ptr<Property>> PropertyMap;
+  using PropertyMap = std::map<std::string, std::unique_ptr<Property>>;
   /// The properties under management
   PropertyMap m_properties;
   /// Stores the order in which the properties were declared.
@@ -143,7 +143,7 @@ private:
 };
 
 /// Typedef for a shared pointer to a PropertyManager
-typedef boost::shared_ptr<PropertyManager> PropertyManager_sptr;
+using PropertyManager_sptr = boost::shared_ptr<PropertyManager>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h
index f516aec4ccac37d43dd1d9bc1c94205a5986c03c..2a64ff336c201d409c37a6a1da37709299b3c280 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h
@@ -53,8 +53,8 @@ private:
 
 EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL
     Mantid::Kernel::SingletonHolder<PropertyManagerDataServiceImpl>;
-typedef Mantid::Kernel::SingletonHolder<PropertyManagerDataServiceImpl>
-    PropertyManagerDataService;
+using PropertyManagerDataService =
+    Mantid::Kernel::SingletonHolder<PropertyManagerDataServiceImpl>;
 
 } // Namespace Kernel
 } // Namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h
index 04a9a5839d6d94bff0e102691b38592da8e0169d..f71e0094bcb1cd73a2caae9fede94a93c975b2e2 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h
@@ -35,8 +35,8 @@ class MANTID_KERNEL_DLL PropertyManagerProperty final
     : public PropertyWithValue<PropertyManager_sptr> {
 public:
   // Convenience typedefs
-  typedef PropertyWithValue<PropertyManager_sptr> BaseClass;
-  typedef PropertyManager_sptr ValueType;
+  using BaseClass = PropertyWithValue<PropertyManager_sptr>;
+  using ValueType = PropertyManager_sptr;
 
   PropertyManagerProperty(const std::string &name,
                           unsigned int direction = Direction::Input);
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h b/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h
index 1bbe4f8b02892c006e2bdf48740d6fd5d8d33480..a5ba001ece5bf1264b463755dcbb53730178b8e3 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h
@@ -34,13 +34,13 @@ namespace Kernel {
 /// forward declare of Mantid::Kernel::PropertyManager
 class PropertyManager;
 /// shared pointer to Mantid::Kernel::PropertyManager
-typedef boost::shared_ptr<PropertyManager> PropertyManager_sptr;
+using PropertyManager_sptr = boost::shared_ptr<PropertyManager>;
 /// shared pointer to Mantid::Kernel::PropertyManager(const version)
-typedef boost::shared_ptr<const PropertyManager> PropertyManager_const_sptr;
+using PropertyManager_const_sptr = boost::shared_ptr<const PropertyManager>;
 /// unique pointer to Mantid::Kernel::PropertyManager
-typedef std::unique_ptr<PropertyManager> PropertyManager_uptr;
+using PropertyManager_uptr = std::unique_ptr<PropertyManager>;
 /// unique pointer to Mantid::Kernel::PropertyManager (const version)
-typedef std::unique_ptr<const PropertyManager> PropertyManager_const_uptr;
+using PropertyManager_const_uptr = std::unique_ptr<const PropertyManager>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
index 3acb4f61207f414f96d5211800c26997a2ef9030..dee6e74546c51dc221d36eda8086b17318544248 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
@@ -76,7 +76,7 @@ public:
   std::string setDataItem(const boost::shared_ptr<DataItem> data) override;
   PropertyWithValue &operator=(const PropertyWithValue &right);
   PropertyWithValue &operator+=(Property const *right) override;
-  virtual TYPE &operator=(const TYPE &value);
+  virtual PropertyWithValue &operator=(const TYPE &value);
   virtual const TYPE &operator()() const;
   virtual operator const TYPE &() const;
   std::string isValid() const override;
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
index a4902017dbb7104790d56d09cb1a6fcb93393f37..af580021274c2f9dc67441d495ea6158b94fe138 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
@@ -259,7 +259,7 @@ operator+=(Property const *right) {
  *  @return the reference to itself
  */
 template <typename TYPE>
-TYPE &PropertyWithValue<TYPE>::operator=(const TYPE &value) {
+PropertyWithValue<TYPE> &PropertyWithValue<TYPE>::operator=(const TYPE &value) {
   TYPE oldValue = m_value;
   if (std::is_same<TYPE, std::string>::value) {
     std::string valueCopy = toString(value);
@@ -272,10 +272,10 @@ TYPE &PropertyWithValue<TYPE>::operator=(const TYPE &value) {
   }
   std::string problem = this->isValid();
   if (problem.empty()) {
-    return m_value;
+    return *this;
   } else if (problem == "_alias") {
     m_value = getValueForAlias(value);
-    return m_value;
+    return *this;
   } else {
     m_value = oldValue;
     throw std::invalid_argument(problem);
diff --git a/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h b/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h
index 1d028f768176f617e32e36c73793463bfe34a131..64e321d8a22f16cb5607246e01a3bd1afa3b4dfe 100644
--- a/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h
+++ b/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h
@@ -62,7 +62,7 @@ public:
   void generateNextPoint() override;
   // Interface to boost distribution generators
   /// Result (output) value type.
-  typedef double result_type;
+  using result_type = double;
   /// Return the minimum value of the range
   virtual double min() const = 0;
   /// Return the maximum value of the range
diff --git a/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h b/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h
index 534d9b219ae9a015544467244291b5c8f8f9c8ce..69ad397f50f4c4ee09d43f753c3ddb8b7b4418f0 100644
--- a/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h
+++ b/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h
@@ -32,7 +32,7 @@ public:
   // Name/Value pairs for POST data.  Note that the second string might be
   // binary, and might be
   // fairly large.  (If it were a JPG image for example...)
-  typedef std::map<std::string, std::string> PostDataMap;
+  using PostDataMap = std::map<std::string, std::string>;
 
   // Low level HTTP functions - GET, POST, etc...
   // It's up to the various algorithms to know what to do with these functions
diff --git a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
index b4a440788d8aad4d9c8810aab12975dc7fe48123..be71da991e353e60fb5bb30f35b6f3c3e109ac9b 100644
--- a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
+++ b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
@@ -34,7 +34,7 @@ namespace Mantid {
 namespace Kernel {
 
 /// prototype for function passed to atexit()
-typedef void (*atexit_func_t)();
+using atexit_func_t = void (*)();
 
 extern MANTID_KERNEL_DLL void CleanupSingletons();
 extern MANTID_KERNEL_DLL void AddSingleton(atexit_func_t func);
@@ -43,7 +43,7 @@ extern MANTID_KERNEL_DLL void AddSingleton(atexit_func_t func);
 template <typename T> class SingletonHolder {
 public:
   /// Allow users to access to the type returned by Instance()
-  typedef T HeldType;
+  using HeldType = T;
 
   static T &Instance();
 
diff --git a/Framework/Kernel/inc/MantidKernel/Statistics.h b/Framework/Kernel/inc/MantidKernel/Statistics.h
index 0d3cd0a6143d063e3059f095c107f62e20d978de..af8d46e77ee82dc3a290b345a3c6daffef93dbf9 100644
--- a/Framework/Kernel/inc/MantidKernel/Statistics.h
+++ b/Framework/Kernel/inc/MantidKernel/Statistics.h
@@ -93,6 +93,9 @@ Statistics getStatistics(const std::vector<TYPE> &data,
 /// Return the Z score values for a dataset
 template <typename TYPE>
 std::vector<double> getZscore(const std::vector<TYPE> &data);
+template <typename TYPE>
+std::vector<double> getWeightedZscore(const std::vector<TYPE> &data,
+                                      const std::vector<TYPE> &weights);
 /// Return the modified Z score values for a dataset
 template <typename TYPE>
 std::vector<double> getModifiedZscore(const std::vector<TYPE> &data,
diff --git a/Framework/Kernel/inc/MantidKernel/StringTokenizer.h b/Framework/Kernel/inc/MantidKernel/StringTokenizer.h
index a2a039a56d0880ae63645b9d6f8fb1a0c7d22ecc..7bb06f574ea1664e050ead38e907b240435f8af9 100644
--- a/Framework/Kernel/inc/MantidKernel/StringTokenizer.h
+++ b/Framework/Kernel/inc/MantidKernel/StringTokenizer.h
@@ -50,9 +50,9 @@ public:
     TOK_IGNORE_FINAL_EMPTY_TOKEN =
         4 ///< ignore an empty token at the end of the string.
   };
-  typedef std::vector<std::string> TokenVec;
-  typedef std::vector<std::string>::iterator Iterator;
-  typedef std::vector<std::string>::const_iterator ConstIterator;
+  using TokenVec = std::vector<std::string>;
+  using Iterator = std::vector<std::string>::iterator;
+  using ConstIterator = std::vector<std::string>::const_iterator;
   /// Constructs an object from an empty string.
   StringTokenizer() = default;
   /// Constructor requiring a string to tokenize and a string of separators.
diff --git a/Framework/Kernel/inc/MantidKernel/TestChannel.h b/Framework/Kernel/inc/MantidKernel/TestChannel.h
index 24cfa6a0aa01b262623539cc8537850a5a0e307c..8cadb9a7613b3015ba715cf8f19640a03fed1a22 100644
--- a/Framework/Kernel/inc/MantidKernel/TestChannel.h
+++ b/Framework/Kernel/inc/MantidKernel/TestChannel.h
@@ -44,7 +44,7 @@ namespace Mantid {
 
 class MANTID_KERNEL_DLL TestChannel : public Poco::Channel {
 public:
-  typedef std::list<Poco::Message> MsgList;
+  using MsgList = std::list<Poco::Message>;
   void log(const Poco::Message &msg) override;
   MsgList &list();
   void clear();
diff --git a/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h b/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h
index 95fbce921a059cb16da25c156e489e7425cd6231..396e49499d8553b7c97f329af5b5f64bd48e6c7e 100644
--- a/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h
+++ b/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h
@@ -157,9 +157,9 @@ public:
 
 protected:
   /// Map to tasks, sorted by cost
-  typedef std::multimap<double, Task *> InnerMap;
+  using InnerMap = std::multimap<double, Task *>;
   /// Map to maps, sorted by Mutex*
-  typedef std::map<boost::shared_ptr<std::mutex>, InnerMap> SuperMap;
+  using SuperMap = std::map<boost::shared_ptr<std::mutex>, InnerMap>;
 
   /** A super map; first key = a Mutex *
    * Inside it: second key = the cost. */
diff --git a/Framework/Kernel/inc/MantidKernel/TimeSplitter.h b/Framework/Kernel/inc/MantidKernel/TimeSplitter.h
index 53c6af492c4840e18fd678575242091b4ffc8d0a..0e6f664ff496db21c10ce0ed60b6346344810de3 100644
--- a/Framework/Kernel/inc/MantidKernel/TimeSplitter.h
+++ b/Framework/Kernel/inc/MantidKernel/TimeSplitter.h
@@ -53,7 +53,7 @@ private:
  * It is a vector of SplittingInterval classes.
  *
  */
-typedef std::vector<SplittingInterval> TimeSplitterType;
+using TimeSplitterType = std::vector<SplittingInterval>;
 
 // -------------- Operators ---------------------
 MANTID_KERNEL_DLL TimeSplitterType
diff --git a/Framework/Kernel/inc/MantidKernel/TypedValidator.h b/Framework/Kernel/inc/MantidKernel/TypedValidator.h
index eb83c0be3a35a178671b9125d00622f4f1915a62..67279f4ee7da4069847f35391998a2b0fff13d61 100644
--- a/Framework/Kernel/inc/MantidKernel/TypedValidator.h
+++ b/Framework/Kernel/inc/MantidKernel/TypedValidator.h
@@ -78,7 +78,7 @@ template <typename ElementType>
 class DLLExport TypedValidator<boost::shared_ptr<ElementType>>
     : public IValidator {
   /// Shared ptr type
-  typedef boost::shared_ptr<ElementType> ElementType_sptr;
+  using ElementType_sptr = boost::shared_ptr<ElementType>;
 
 protected:
   /// Override this function to check the validity of the type
diff --git a/Framework/Kernel/inc/MantidKernel/Unit.h b/Framework/Kernel/inc/MantidKernel/Unit.h
index b2ee0891898a6e8d1fc1789c5296c8bd3d1a1639..26374a5194af1766743e2afae3e9d9fd3232eaaf 100644
--- a/Framework/Kernel/inc/MantidKernel/Unit.h
+++ b/Framework/Kernel/inc/MantidKernel/Unit.h
@@ -226,23 +226,23 @@ protected:
 private:
   /// A 'quick conversion' requires the constant by which to multiply the input
   /// and the power to which to raise it
-  typedef std::pair<double, double> ConstantAndPower;
+  using ConstantAndPower = std::pair<double, double>;
   /// Lists, for a given starting unit, the units to which a 'quick conversion'
   /// can be made
-  typedef tbb::concurrent_unordered_map<std::string, ConstantAndPower>
-      UnitConversions;
+  using UnitConversions =
+      tbb::concurrent_unordered_map<std::string, ConstantAndPower>;
   /// The possible 'quick conversions' are held in a map with the starting unit
   /// as the key
-  typedef tbb::concurrent_unordered_map<std::string, UnitConversions>
-      ConversionsMap;
+  using ConversionsMap =
+      tbb::concurrent_unordered_map<std::string, UnitConversions>;
   /// The table of possible 'quick conversions'
   static ConversionsMap s_conversionFactors;
 };
 
 /// Shared pointer to the Unit base class
-typedef boost::shared_ptr<Unit> Unit_sptr;
+using Unit_sptr = boost::shared_ptr<Unit>;
 /// Shared pointer to the Unit base class (const version)
-typedef boost::shared_ptr<const Unit> Unit_const_sptr;
+using Unit_const_sptr = boost::shared_ptr<const Unit>;
 
 //----------------------------------------------------------------------
 // Now the concrete units classes
diff --git a/Framework/Kernel/inc/MantidKernel/UnitFactory.h b/Framework/Kernel/inc/MantidKernel/UnitFactory.h
index d8de9c7e8fa7cee1ce9d57baebd04564b0a8dd84..8e4c70e2817bc53418249befc6777e1098f992e5 100644
--- a/Framework/Kernel/inc/MantidKernel/UnitFactory.h
+++ b/Framework/Kernel/inc/MantidKernel/UnitFactory.h
@@ -86,7 +86,7 @@ private:
 EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL
     Mantid::Kernel::SingletonHolder<UnitFactoryImpl>;
 
-typedef SingletonHolder<UnitFactoryImpl> UnitFactory;
+using UnitFactory = SingletonHolder<UnitFactoryImpl>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/UnitLabel.h b/Framework/Kernel/inc/MantidKernel/UnitLabel.h
index 9348e7d16a616c82abc8ef4a360759b9265c64c0..2f4bab8a3163226a6227e73c0e6305a1b6a37fc6 100644
--- a/Framework/Kernel/inc/MantidKernel/UnitLabel.h
+++ b/Framework/Kernel/inc/MantidKernel/UnitLabel.h
@@ -38,11 +38,11 @@ public:
   UnitLabel() = delete;
 
   /// Type that contains a plain-text string
-  typedef std::string AsciiString;
+  using AsciiString = std::string;
   /// Type that can hold a unicode string. This may vary per-platform depending
   /// on the
   /// width of the the built-in std::wstring
-  typedef std::wstring Utf8String;
+  using Utf8String = std::wstring;
 
   /// Constructor giving labels as ascii, unicode, and latex respectively
   UnitLabel(const AsciiString &ascii, const Utf8String &unicode,
diff --git a/Framework/Kernel/inc/MantidKernel/UsageService.h b/Framework/Kernel/inc/MantidKernel/UsageService.h
index e5dc24cfc374b309cffd1f777b530aacb5453f21..aa4090fe6e5ffa7772d0876e73fe02f6c6345cfa 100644
--- a/Framework/Kernel/inc/MantidKernel/UsageService.h
+++ b/Framework/Kernel/inc/MantidKernel/UsageService.h
@@ -147,7 +147,7 @@ private:
 
 EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL
     Mantid::Kernel::SingletonHolder<UsageServiceImpl>;
-typedef Mantid::Kernel::SingletonHolder<UsageServiceImpl> UsageService;
+using UsageService = Mantid::Kernel::SingletonHolder<UsageServiceImpl>;
 
 } // namespace Kernel
 } // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
index 86e92bda36aa213f616c6d0a1bd28e9cc2e8664b..9c9028f6127e1c85b7f32b3dd0333e4bb0e2c22a 100644
--- a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h
@@ -9,7 +9,7 @@
 namespace Mantid {
 namespace Kernel {
 
-typedef boost::optional<std::string> OptionalPath;
+using OptionalPath = boost::optional<std::string>;
 
 class CatalogConfigService {
 public:
diff --git a/Framework/Kernel/inc/MantidKernel/VMD.h b/Framework/Kernel/inc/MantidKernel/VMD.h
index 4cfce09de7a64fb4f59405af31167f6881bb2698..f3e73f0d26c8c6723c18b19003e4c06126ce53e0 100644
--- a/Framework/Kernel/inc/MantidKernel/VMD.h
+++ b/Framework/Kernel/inc/MantidKernel/VMD.h
@@ -98,10 +98,10 @@ protected:
 };
 
 /// Underlying data type for the VMD type
-typedef float VMD_t;
+using VMD_t = float;
 
 /// Define the VMD as using the double or float data type.
-typedef VMDBase<VMD_t> VMD;
+using VMD = VMDBase<VMD_t>;
 
 // Overload operator <<
 MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &,
diff --git a/Framework/Kernel/inc/MantidKernel/VectorHelper.h b/Framework/Kernel/inc/MantidKernel/VectorHelper.h
index c917ab0f7cc756555f6727cffb3f1cc8a1cae37b..45bd4aaa115ea26113a476fc3d0a37b87ce245f2 100644
--- a/Framework/Kernel/inc/MantidKernel/VectorHelper.h
+++ b/Framework/Kernel/inc/MantidKernel/VectorHelper.h
@@ -40,11 +40,10 @@ namespace Kernel {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
 namespace VectorHelper {
-int MANTID_KERNEL_DLL
-createAxisFromRebinParams(const std::vector<double> &params,
-                          std::vector<double> &xnew,
-                          const bool resize_xnew = true,
-                          const bool full_bins_only = false);
+int MANTID_KERNEL_DLL createAxisFromRebinParams(
+    const std::vector<double> &params, std::vector<double> &xnew,
+    const bool resize_xnew = true, const bool full_bins_only = false,
+    const double xMinHint = std::nan(""), const double xMaxHint = std::nan(""));
 
 void MANTID_KERNEL_DLL
 rebin(const std::vector<double> &xold, const std::vector<double> &yold,
diff --git a/Framework/Kernel/inc/MantidKernel/cow_ptr.h b/Framework/Kernel/inc/MantidKernel/cow_ptr.h
index dce5b0dd32b6af1cfbccf7c255bd029a96ebb114..d062271470df69601dc8bfb64b3967f2973964db 100644
--- a/Framework/Kernel/inc/MantidKernel/cow_ptr.h
+++ b/Framework/Kernel/inc/MantidKernel/cow_ptr.h
@@ -56,8 +56,8 @@ namespace Kernel {
 */
 template <typename DataType> class cow_ptr {
 public:
-  typedef boost::shared_ptr<DataType> ptr_type; ///< typedef for the storage
-  typedef DataType value_type;                  ///< typedef for the data type
+  using ptr_type = boost::shared_ptr<DataType>; ///< typedef for the storage
+  using value_type = DataType;                  ///< typedef for the data type
 
 private:
   ptr_type Data; ///< Real object Ptr
@@ -203,10 +203,10 @@ cow_ptr<DataType>::cow_ptr(const ptr_type &resourceSptr) noexcept {
 } // NAMESPACE Kernel
 
 /// typedef for the data storage used in Mantid matrix workspaces
-typedef std::vector<double> MantidVec;
+using MantidVec = std::vector<double>;
 
 /// typedef for the pointer to data storage used in Mantid matrix workspaces
-typedef Kernel::cow_ptr<MantidVec> MantidVecPtr;
+using MantidVecPtr = Kernel::cow_ptr<MantidVec>;
 
 } // NAMESPACE Mantid
 
diff --git a/Framework/Kernel/inc/MantidKernel/normal_distribution.h b/Framework/Kernel/inc/MantidKernel/normal_distribution.h
new file mode 100644
index 0000000000000000000000000000000000000000..54941b602e3c452b9e04d03690f1e7e56c4b87e4
--- /dev/null
+++ b/Framework/Kernel/inc/MantidKernel/normal_distribution.h
@@ -0,0 +1,254 @@
+#ifndef MANTID_KERNEL_NORMAL_DISRIBUTION_H_
+#define MANTID_KERNEL_NORMAL_DISRIBUTION_H_
+/**
+  Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+ */
+#include "MantidKernel/System.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include <ios>
+#include <random>
+
+// Implementation of normal_distribution taken from llvm/libcxx at
+// https://github.com/llvm-mirror/libcxx/blob/661dff0e60093266e7833cbbf5d3809a4f950378/include/random#L497
+//
+// Each of our supported platforms has the header but gcc
+// (https://github.com/gcc-mirror/gcc/blob/da8dff89fa9398f04b107e388cb706517ced9505/libstdc%2B%2B-v3/include/bits/random.tcc#L1783)
+// differs to msvc/clang in which value it caches/returns. This makes writing
+// tests against the implementations much harder. This simply choose the libcxx
+// header as our "standard".
+//
+// Modifications to enable compilation:
+//  * define required macros just for this header
+//  * prefix some structures with std:: now they are not in std:: namespace
+//  * include __save_flags helper class for io formatting
+//  * disabled a maybe-uninitialized warning that would be disabled in the
+//    system header anyway
+
+#ifdef _MSC_VER
+#define INLINE_VISIBILITY __forceinline
+#else
+#define INLINE_VISIBILITY __attribute__((__always_inline__))
+#endif
+
+namespace Mantid {
+namespace Kernel {
+
+template <class _CharT, class _Traits> class __save_flags {
+  typedef std::basic_ios<_CharT, _Traits> __stream_type;
+  typedef typename __stream_type::fmtflags fmtflags;
+
+  __stream_type &__stream_;
+  fmtflags __fmtflags_;
+  _CharT __fill_;
+
+  __save_flags(const __save_flags &);
+  __save_flags &operator=(const __save_flags &);
+
+public:
+  INLINE_VISIBILITY
+  explicit __save_flags(__stream_type &__stream)
+      : __stream_(__stream), __fmtflags_(__stream.flags()),
+        __fill_(__stream.fill()) {}
+  INLINE_VISIBILITY
+  ~__save_flags() {
+    __stream_.flags(__fmtflags_);
+    __stream_.fill(__fill_);
+  }
+};
+
+template <class _RealType = double> class DLLExport normal_distribution {
+public:
+  // types
+  typedef _RealType result_type;
+
+  class DLLExport param_type {
+    result_type __mean_;
+    result_type __stddev_;
+
+  public:
+    typedef normal_distribution distribution_type;
+
+    INLINE_VISIBILITY
+    explicit param_type(result_type __mean = 0, result_type __stddev = 1)
+        : __mean_(__mean), __stddev_(__stddev) {}
+
+    INLINE_VISIBILITY
+    result_type mean() const { return __mean_; }
+    INLINE_VISIBILITY
+    result_type stddev() const { return __stddev_; }
+
+    friend INLINE_VISIBILITY bool operator==(const param_type &__x,
+                                             const param_type &__y) {
+      return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;
+    }
+    friend INLINE_VISIBILITY bool operator!=(const param_type &__x,
+                                             const param_type &__y) {
+      return !(__x == __y);
+    }
+  };
+
+private:
+  param_type __p_;
+  result_type _V_;
+  bool _V_hot_;
+
+public:
+  // constructors and reset functions
+  INLINE_VISIBILITY
+  explicit normal_distribution(result_type __mean = 0, result_type __stddev = 1)
+      : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
+  INLINE_VISIBILITY
+  explicit normal_distribution(const param_type &__p)
+      : __p_(__p), _V_hot_(false) {}
+  INLINE_VISIBILITY
+  void reset() { _V_hot_ = false; }
+
+  // generating functions
+  template <class _URNG> INLINE_VISIBILITY result_type operator()(_URNG &__g) {
+    return (*this)(__g, __p_);
+  }
+  template <class _URNG>
+  result_type operator()(_URNG &__g, const param_type &__p);
+
+  // property functions
+  INLINE_VISIBILITY
+  result_type mean() const { return __p_.mean(); }
+  INLINE_VISIBILITY
+  result_type stddev() const { return __p_.stddev(); }
+
+  INLINE_VISIBILITY
+  param_type param() const { return __p_; }
+  INLINE_VISIBILITY
+  void param(const param_type &__p) { __p_ = __p; }
+
+  INLINE_VISIBILITY
+  result_type min() const {
+    return -std::numeric_limits<result_type>::infinity();
+  }
+  INLINE_VISIBILITY
+  result_type max() const {
+    return std::numeric_limits<result_type>::infinity();
+  }
+
+  friend INLINE_VISIBILITY bool operator==(const normal_distribution &__x,
+                                           const normal_distribution &__y) {
+    return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ &&
+           (!__x._V_hot_ || __x._V_ == __y._V_);
+  }
+  friend INLINE_VISIBILITY bool operator!=(const normal_distribution &__x,
+                                           const normal_distribution &__y) {
+    return !(__x == __y);
+  }
+
+  template <class _CharT, class _Traits, class _RT>
+  friend std::basic_ostream<_CharT, _Traits> &
+  operator<<(std::basic_ostream<_CharT, _Traits> &__os,
+             const normal_distribution<_RT> &__x);
+
+  template <class _CharT, class _Traits, class _RT>
+  friend std::basic_istream<_CharT, _Traits> &
+  operator>>(std::basic_istream<_CharT, _Traits> &__is,
+             normal_distribution<_RT> &__x);
+};
+
+// clang-format off
+#if !defined(__clang__)
+GCC_DIAG_OFF(maybe-uninitialized)
+#endif
+// clang-format on
+template <class _RealType>
+template <class _URNG>
+_RealType normal_distribution<_RealType>::operator()(_URNG &__g,
+                                                     const param_type &__p) {
+  result_type _Up;
+  if (_V_hot_) {
+    _V_hot_ = false;
+    _Up = _V_;
+  } else {
+    std::uniform_real_distribution<result_type> _Uni(-1, 1);
+    result_type __u;
+    result_type __v;
+    result_type __s;
+    do {
+      __u = _Uni(__g);
+      __v = _Uni(__g);
+      __s = __u * __u + __v * __v;
+    } while (__s > 1 || __s == 0);
+    result_type _Fp = std::sqrt(-2 * std::log(__s) / __s);
+    _V_ = __v * _Fp;
+    _V_hot_ = true;
+    _Up = __u * _Fp;
+  }
+  return _Up * __p.stddev() + __p.mean();
+}
+// clang-format off
+#if !defined(__clang__)
+GCC_DIAG_ON(maybe-uninitialized)
+#endif
+// clang-format on
+
+template <class _CharT, class _Traits, class _RT>
+std::basic_ostream<_CharT, _Traits> &
+operator<<(std::basic_ostream<_CharT, _Traits> &__os,
+           const normal_distribution<_RT> &__x) {
+  __save_flags<_CharT, _Traits> __lx(__os);
+  __os.flags(std::ios_base::dec | std::ios_base::left | std::ios_base::fixed |
+             std::ios_base::scientific);
+  _CharT __sp = __os.widen(' ');
+  __os.fill(__sp);
+  __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;
+  if (__x._V_hot_)
+    __os << __sp << __x._V_;
+  return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+std::basic_istream<_CharT, _Traits> &
+operator>>(std::basic_istream<_CharT, _Traits> &__is,
+           normal_distribution<_RT> &__x) {
+  typedef normal_distribution<_RT> _Eng;
+  typedef typename _Eng::result_type result_type;
+  typedef typename _Eng::param_type param_type;
+  __save_flags<_CharT, _Traits> __lx(__is);
+  __is.flags(std::ios_base::dec | std::ios_base::skipws);
+  result_type __mean;
+  result_type __stddev;
+  result_type _Vp = 0;
+  bool _V_hot = false;
+  __is >> __mean >> __stddev >> _V_hot;
+  if (_V_hot)
+    __is >> _Vp;
+  if (!__is.fail()) {
+    __x.param(param_type(__mean, __stddev));
+    __x._V_hot_ = _V_hot;
+    __x._V_ = _Vp;
+  }
+  return __is;
+}
+
+// Clean up macros
+#undef INLINE_VISIBILITY
+
+} // namespace Kernel
+} // namespace Mantid
+
+#endif // MANTID_KERNEL_NORMAL_DISRIBUTION_H_
diff --git a/Framework/Kernel/inc/MantidKernel/uniform_int_distribution.h b/Framework/Kernel/inc/MantidKernel/uniform_int_distribution.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ddd7c77fcf171422b9b87004066c82169841afd
--- /dev/null
+++ b/Framework/Kernel/inc/MantidKernel/uniform_int_distribution.h
@@ -0,0 +1,343 @@
+#ifndef MANTID_KERNEL_UNIFORM_INT_DISRIBUTION_H_
+#define MANTID_KERNEL_UNIFORM_INT_DISRIBUTION_H_
+/**
+  Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+ */
+#include <limits>
+#include <random>
+#include <type_traits>
+
+// Implementation of uniform_int_distribution taken from llvm/libcxx at
+// https://github.com/llvm-mirror/libcxx/blob/master/include/algorithm#L2965
+//
+// Each of our supported platforms has the header but minor differences in the
+// results yield problems consistency of our tests across platorms.
+//
+// Modifications to enable compilation:
+//  * define required macros just for this header
+//  * prefix some structures with std:: now they are not in std:: namespace
+//  * applied clang format
+
+#ifdef _MSC_VER
+#define __CHAR_BIT__ CHAR_BIT
+#define INLINE_VISIBILITY __forceinline
+#else
+#define INLINE_VISIBILITY __attribute__((__always_inline__))
+#endif
+
+namespace Mantid {
+namespace Kernel {
+
+//@cond
+
+// Precondition:  __x != 0
+inline INLINE_VISIBILITY unsigned __clz(unsigned __x) {
+#ifndef _MSC_VER
+  return static_cast<unsigned>(__builtin_clz(__x));
+#else
+  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+  static_assert(sizeof(unsigned long) == 4, "");
+  unsigned long where;
+  // Search from LSB to MSB for first set bit.
+  // Returns zero if no set bit is found.
+  if (_BitScanReverse(&where, __x))
+    return 31 - where;
+  return 32; // Undefined Behavior.
+#endif
+}
+
+inline INLINE_VISIBILITY unsigned long __clz(unsigned long __x) {
+#ifndef _MSC_VER
+  return static_cast<unsigned long>(__builtin_clzl(__x));
+#else
+  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
+  return __clz(static_cast<unsigned>(__x));
+#endif
+}
+
+inline INLINE_VISIBILITY unsigned long long __clz(unsigned long long __x) {
+#ifndef _MSC_VER
+  return static_cast<unsigned long long>(__builtin_clzll(__x));
+#else
+  unsigned long where;
+// BitScanReverse scans from MSB to LSB for first set bit.
+// Returns 0 if no set bit is found.
+#if defined(_LIBCPP_HAS_BITSCAN64)
+  if (_BitScanReverse64(&where, __x))
+    return static_cast<int>(63 - where);
+#else
+  // Scan the high 32 bits.
+  if (_BitScanReverse(&where, static_cast<unsigned long>(__x >> 32)))
+    return 63 - (where + 32); // Create a bit offset from the MSB.
+  // Scan the low 32 bits.
+  if (_BitScanReverse(&where, static_cast<unsigned long>(__x)))
+    return 63 - where;
+#endif
+  return 64; // Undefined Behavior.
+#endif // _MSC_VER
+}
+
+// __independent_bits_engine
+
+template <unsigned long long _Xp, size_t _Rp> struct __log2_imp {
+  static const size_t value = _Xp & ((unsigned long long)(1) << _Rp)
+                                  ? _Rp
+                                  : __log2_imp<_Xp, _Rp - 1>::value;
+};
+
+template <unsigned long long _Xp> struct __log2_imp<_Xp, 0> {
+  static const size_t value = 0;
+};
+
+template <size_t _Rp> struct __log2_imp<0, _Rp> {
+  static const size_t value = _Rp + 1;
+};
+
+template <class _UIntType, _UIntType _Xp> struct __log2 {
+  static const size_t value =
+      __log2_imp<_Xp, sizeof(_UIntType) * __CHAR_BIT__ - 1>::value;
+};
+
+template <class _Engine, class _UIntType> class __independent_bits_engine {
+public:
+  // types
+  typedef _UIntType result_type;
+
+private:
+  typedef typename _Engine::result_type _Engine_result_type;
+  typedef typename std::conditional<
+      sizeof(_Engine_result_type) <= sizeof(result_type), result_type,
+      _Engine_result_type>::type _Working_result_type;
+
+  _Engine &__e_;
+  size_t __w_;
+  size_t __w0_;
+  size_t __n_;
+  size_t __n0_;
+  _Working_result_type __y0_;
+  _Working_result_type __y1_;
+  _Engine_result_type __mask0_;
+  _Engine_result_type __mask1_;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4307)
+#endif
+  static constexpr const _Working_result_type _Rp =
+      _Engine::max() - _Engine::min() + _Working_result_type(1);
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+  static constexpr const size_t __m = __log2<_Working_result_type, _Rp>::value;
+  static constexpr const size_t _WDt =
+      std::numeric_limits<_Working_result_type>::digits;
+  static constexpr const size_t _EDt =
+      std::numeric_limits<_Engine_result_type>::digits;
+
+public:
+  // constructors and seeding functions
+  __independent_bits_engine(_Engine &__e, size_t __w);
+
+  // generating functions
+  result_type operator()() {
+    return __eval(std::integral_constant<bool, _Rp != 0>());
+  }
+
+private:
+  result_type __eval(std::false_type);
+  result_type __eval(std::true_type);
+};
+
+template <class _Engine, class _UIntType>
+__independent_bits_engine<_Engine, _UIntType>::__independent_bits_engine(
+    _Engine &__e, size_t __w)
+    : __e_(__e), __w_(__w) {
+  __n_ = __w_ / __m + (__w_ % __m != 0);
+  __w0_ = __w_ / __n_;
+  if (_Rp == 0)
+    __y0_ = _Rp;
+  else if (__w0_ < _WDt)
+    __y0_ = (_Rp >> __w0_) << __w0_;
+  else
+    __y0_ = 0;
+  if (_Rp - __y0_ > __y0_ / __n_) {
+    ++__n_;
+    __w0_ = __w_ / __n_;
+    if (__w0_ < _WDt)
+      __y0_ = (_Rp >> __w0_) << __w0_;
+    else
+      __y0_ = 0;
+  }
+  __n0_ = __n_ - __w_ % __n_;
+  if (__w0_ < _WDt - 1)
+    __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
+  else
+    __y1_ = 0;
+  __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_)
+                       : _Engine_result_type(0);
+  __mask1_ = __w0_ < _EDt - 1 ? _Engine_result_type(~0) >> (_EDt - (__w0_ + 1))
+                              : _Engine_result_type(~0);
+}
+
+template <class _Engine, class _UIntType>
+inline _UIntType
+    __independent_bits_engine<_Engine, _UIntType>::__eval(std::false_type) {
+  return static_cast<result_type>(__e_() & __mask0_);
+}
+
+template <class _Engine, class _UIntType>
+_UIntType
+    __independent_bits_engine<_Engine, _UIntType>::__eval(std::true_type) {
+  const size_t _WRt = std::numeric_limits<result_type>::digits;
+  result_type _Sp = 0;
+  for (size_t __k = 0; __k < __n0_; ++__k) {
+    _Engine_result_type __u;
+    do {
+      __u = __e_() - _Engine::min();
+    } while (__u >= __y0_);
+    if (__w0_ < _WRt)
+      _Sp <<= __w0_;
+    else
+      _Sp = 0;
+    _Sp += static_cast<result_type>(__u & __mask0_);
+  }
+  for (size_t __k = __n0_; __k < __n_; ++__k) {
+    _Engine_result_type __u;
+    do {
+      __u = __e_() - _Engine::min();
+    } while (__u >= __y1_);
+    if (__w0_ < _WRt - 1)
+      _Sp <<= __w0_ + 1;
+    else
+      _Sp = 0;
+    _Sp += static_cast<result_type>(__u & __mask1_);
+  }
+  return _Sp;
+}
+
+//@endcond
+
+// uniform_int_distribution
+
+template <class _IntType = int> class uniform_int_distribution {
+public:
+  // types
+  typedef _IntType result_type;
+
+  class param_type {
+    result_type __a_;
+    result_type __b_;
+
+  public:
+    typedef uniform_int_distribution distribution_type;
+
+    explicit param_type(
+        result_type __a = 0,
+        result_type __b = std::numeric_limits<result_type>::max())
+        : __a_(__a), __b_(__b) {}
+
+    result_type a() const { return __a_; }
+    result_type b() const { return __b_; }
+
+    friend bool operator==(const param_type &__x, const param_type &__y) {
+      return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;
+    }
+    friend bool operator!=(const param_type &__x, const param_type &__y) {
+      return !(__x == __y);
+    }
+  };
+
+private:
+  param_type __p_;
+
+public:
+  // constructors and reset functions
+  explicit uniform_int_distribution(
+      result_type __a = 0,
+      result_type __b = std::numeric_limits<result_type>::max())
+      : __p_(param_type(__a, __b)) {}
+  explicit uniform_int_distribution(const param_type &__p) : __p_(__p) {}
+  void reset() {}
+
+  // generating functions
+  template <class _URNG> result_type operator()(_URNG &__g) {
+    return (*this)(__g, __p_);
+  }
+  template <class _URNG>
+  result_type operator()(_URNG &__g, const param_type &__p);
+
+  // property functions
+  result_type a() const { return __p_.a(); }
+  result_type b() const { return __p_.b(); }
+
+  param_type param() const { return __p_; }
+  void param(const param_type &__p) { __p_ = __p; }
+
+  result_type min() const { return a(); }
+  result_type max() const { return b(); }
+
+  friend bool operator==(const uniform_int_distribution &__x,
+                         const uniform_int_distribution &__y) {
+    return __x.__p_ == __y.__p_;
+  }
+  friend bool operator!=(const uniform_int_distribution &__x,
+                         const uniform_int_distribution &__y) {
+    return !(__x == __y);
+  }
+};
+
+template <class _IntType>
+template <class _URNG>
+typename uniform_int_distribution<_IntType>::result_type
+    uniform_int_distribution<_IntType>::
+    operator()(_URNG &__g, const param_type &__p) {
+  typedef typename std::conditional<sizeof(result_type) <= sizeof(uint32_t),
+                                    uint32_t, uint64_t>::type _UIntType;
+  const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
+  if (_Rp == 1)
+    return __p.a();
+  const size_t _Dt = std::numeric_limits<_UIntType>::digits;
+  typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
+  if (_Rp == 0)
+    return static_cast<result_type>(_Eng(__g, _Dt)());
+  size_t __w = _Dt - __clz(_Rp) - 1;
+  if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
+    ++__w;
+  _Eng __e(__g, __w);
+  _UIntType __u;
+  do {
+    __u = __e();
+  } while (__u >= _Rp);
+  return static_cast<result_type>(__u + __p.a());
+}
+
+} // namespace Kernel
+} // namespace Mantid
+
+// Clean up macros
+#undef INLINE_VISIBILITY
+#ifdef _MANTID_CHAR_BIT_DEFINED_HERE
+#undef __CHAR_BIT__
+#undef _MANTID_CHAR_BIT_DEFINED_HERE
+#endif
+
+#endif // MANTID_KERNEL_UNIFORM_INT_DISRIBUTION_H_
diff --git a/Framework/Kernel/src/ANN/kd_tree.h b/Framework/Kernel/src/ANN/kd_tree.h
index 93db64f4cf1452452dd2feedcbc0ce2c761aa50a..e47a54f1574b186d2024f1d73ee2ebcbc16e2a2f 100644
--- a/Framework/Kernel/src/ANN/kd_tree.h
+++ b/Framework/Kernel/src/ANN/kd_tree.h
@@ -70,15 +70,9 @@ public:
 //		for building the tree.
 //----------------------------------------------------------------------
 
-typedef void (*ANNkd_splitter)( // splitting routine for kd-trees
-    ANNpointArray pa,           // point array (unaltered)
-    ANNidxArray pidx,           // point indices (permuted on return)
-    const ANNorthRect &bnds,    // bounding rectangle for cell
-    int n,                      // number of points
-    int dim,                    // dimension of space
-    int &cut_dim,               // cutting dimension (returned)
-    ANNcoord &cut_val,          // cutting value (returned)
-    int &n_lo);                 // num of points on low side (returned)
+using ANNkd_splitter = void (*)(ANNpointArray, ANNidxArray, const ANNorthRect &,
+                                int, int, int &, ANNcoord &,
+                                int &); // num of points on low side (returned)
 
 //----------------------------------------------------------------------
 //	Leaf kd-tree node
diff --git a/Framework/Kernel/src/ANN/pr_queue.h b/Framework/Kernel/src/ANN/pr_queue.h
index f25bbad05ba767f675836a2e86ea74dfb8ad44bf..ca53d2ee82b31dc6f4aff12a04f30d144c9885de 100644
--- a/Framework/Kernel/src/ANN/pr_queue.h
+++ b/Framework/Kernel/src/ANN/pr_queue.h
@@ -32,8 +32,8 @@
 //----------------------------------------------------------------------
 //	Basic types.
 //----------------------------------------------------------------------
-typedef void *PQinfo;  // info field is generic pointer
-typedef ANNdist PQkey; // key field is distance
+using PQinfo = void *; // info field is generic pointer
+using PQkey = ANNdist; // key field is distance
 
 //----------------------------------------------------------------------
 //	Priority queue
diff --git a/Framework/Kernel/src/ANN/pr_queue_k.h b/Framework/Kernel/src/ANN/pr_queue_k.h
index ed501d3f185936770e54829764eca07fa07f49f6..8da43d1e0bb99e71e1414bef0fc00f1e0bb626d9 100644
--- a/Framework/Kernel/src/ANN/pr_queue_k.h
+++ b/Framework/Kernel/src/ANN/pr_queue_k.h
@@ -31,8 +31,8 @@
 //----------------------------------------------------------------------
 //	Basic types
 //----------------------------------------------------------------------
-typedef ANNdist PQKkey; // key field is distance
-typedef int PQKinfo;    // info field is int
+using PQKkey = ANNdist; // key field is distance
+using PQKinfo = int;    // info field is int
 
 //----------------------------------------------------------------------
 //	Constants
diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp
index 53385cfa7e4e2200f622af62cf69d2851f8b3946..16a6189f4383f869766cb4a85af77f4091e5493f 100644
--- a/Framework/Kernel/src/ConfigService.cpp
+++ b/Framework/Kernel/src/ConfigService.cpp
@@ -110,7 +110,7 @@ std::vector<std::string> splitPath(const std::string &path) {
 template <typename T> class ConfigServiceImpl::WrappedObject : public T {
 public:
   /// The template type of class that is being wrapped
-  typedef T element_type;
+  using element_type = T;
   /// Simple constructor
   WrappedObject() : T() { m_pPtr = static_cast<T *>(this); }
 
@@ -1774,8 +1774,9 @@ std::string ConfigServiceImpl::getFacilityFilename(const std::string &fName) {
 
   // look through all the possible files
   for (; instrDir != directoryNames.end(); ++instrDir) {
-    std::string filename = (*instrDir) + "Facilities.xml";
-
+    Poco::Path p(*instrDir);
+    p.append("Facilities.xml");
+    std::string filename = p.toString();
     Poco::File fileObj(filename);
     // stop when you find the first one
     if (fileObj.exists())
diff --git a/Framework/Kernel/src/FacilityInfo.cpp b/Framework/Kernel/src/FacilityInfo.cpp
index 52de210b3fade89da921833f9cc8d122805c5e02..519821a771f7cb4d3cda1d77225ab79699cdd621 100644
--- a/Framework/Kernel/src/FacilityInfo.cpp
+++ b/Framework/Kernel/src/FacilityInfo.cpp
@@ -90,7 +90,7 @@ void FacilityInfo::fillExtensions(const Poco::XML::Element *elem) {
     g_log.error("No file extensions defined");
     throw std::runtime_error("No file extensions defined");
   }
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer exts(extsStr, ",",
                  tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
   for (const auto &ext : exts) {
diff --git a/Framework/Kernel/src/Interpolation.cpp b/Framework/Kernel/src/Interpolation.cpp
index 6ff8d02d72ac617fc033e08c229f3d57474ac816..4b866761d461ca2f0b6393de202c7c62272ab880 100644
--- a/Framework/Kernel/src/Interpolation.cpp
+++ b/Framework/Kernel/src/Interpolation.cpp
@@ -174,7 +174,7 @@ std::ostream &operator<<(std::ostream &os, const Interpolation &f) {
 */
 std::istream &operator>>(std::istream &in, Interpolation &f) {
 
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   std::string str;
   getline(in, str);
   tokenizer values(str, ";", tokenizer::TOK_TRIM);
diff --git a/Framework/Kernel/src/LibraryWrapper.cpp b/Framework/Kernel/src/LibraryWrapper.cpp
index 1dca81052b295099d5a968f7e1767918d4725d13..753423937df68ec09d7e0795d972cdbb6e77cb02 100644
--- a/Framework/Kernel/src/LibraryWrapper.cpp
+++ b/Framework/Kernel/src/LibraryWrapper.cpp
@@ -8,13 +8,15 @@ namespace Kernel {
  * Move constructor
  * @param src Constructor from this temporary
  */
-LibraryWrapper::LibraryWrapper(LibraryWrapper &&src) { *this = std::move(src); }
+LibraryWrapper::LibraryWrapper(LibraryWrapper &&src) noexcept {
+  *this = std::move(src);
+}
 
 /**
  * Move assignment
  * @param rhs Temporary object as source of assignment
  */
-LibraryWrapper &LibraryWrapper::operator=(LibraryWrapper &&rhs) {
+LibraryWrapper &LibraryWrapper::operator=(LibraryWrapper &&rhs) noexcept {
   using std::swap;
   swap(m_module, rhs.m_module);
   return *this;
diff --git a/Framework/Kernel/src/MagneticIon.cpp b/Framework/Kernel/src/MagneticIon.cpp
index 72034db1325a4690c968942b5ada92ac0fbd2783..a6a611fd394faf6ad38c2f8eb1bcb231d213da5f 100644
--- a/Framework/Kernel/src/MagneticIon.cpp
+++ b/Framework/Kernel/src/MagneticIon.cpp
@@ -807,7 +807,7 @@ constexpr double j_Au5[3][9] = {
 }
 
 /// Typedef the map type
-typedef std::unordered_map<std::string, MagneticIon> IonIndex;
+using IonIndex = std::unordered_map<std::string, MagneticIon>;
 
 /// Forward decalre intializer
 void createIonLookup(IonIndex &ion_map);
diff --git a/Framework/Kernel/src/Material.cpp b/Framework/Kernel/src/Material.cpp
index 4d81289c1b9499c96f323a4c81a0ebf5dfbec9ce..099e90ab82411b358ea4a5f4f6a08e4ad090fa40 100644
--- a/Framework/Kernel/src/Material.cpp
+++ b/Framework/Kernel/src/Material.cpp
@@ -10,8 +10,8 @@
 namespace Mantid {
 
 namespace Kernel {
-typedef Mantid::Kernel::StringTokenizer tokenizer;
-typedef std::pair<std::string, std::string> str_pair;
+using tokenizer = Mantid::Kernel::StringTokenizer;
+using str_pair = std::pair<std::string, std::string>;
 
 using PhysicalConstants::Atom;
 using PhysicalConstants::getAtom;
diff --git a/Framework/Kernel/src/MaterialBuilder.cpp b/Framework/Kernel/src/MaterialBuilder.cpp
index 9d74c5bc1cffe6db48052d16fe70161f9cb5f40b..1d9113f21b510b1da35a19a4224d75d2625d2f6c 100644
--- a/Framework/Kernel/src/MaterialBuilder.cpp
+++ b/Framework/Kernel/src/MaterialBuilder.cpp
@@ -59,7 +59,7 @@ MaterialBuilder &MaterialBuilder::setFormula(const std::string &formula) {
     throw std::invalid_argument(
         "MaterialBuilder::setFormula() - Empty formula provided.");
   }
-  typedef Material::ChemicalFormula ChemicalFormula;
+  using ChemicalFormula = Material::ChemicalFormula;
   try {
     m_formula = Mantid::Kernel::make_unique<ChemicalFormula>(
         ChemicalFormula(Material::parseChemicalFormula(formula)));
diff --git a/Framework/Kernel/src/MaterialXMLParser.cpp b/Framework/Kernel/src/MaterialXMLParser.cpp
index 1e110f55d4e2f82abe2fd90c8dbffb495f2e697e..f15080f4e8e3bf08b978ed642e7a4a8dd3ab7f6c 100644
--- a/Framework/Kernel/src/MaterialXMLParser.cpp
+++ b/Framework/Kernel/src/MaterialXMLParser.cpp
@@ -51,10 +51,11 @@ const char *ABSORB_ATT = "absorptionxsec";
 
 // Base type to put in a hash
 struct BuilderHandle {
+  virtual ~BuilderHandle() = default;
   virtual void operator()(MaterialBuilder &builder,
                           const std::string &value) const = 0;
 };
-typedef std::unique_ptr<BuilderHandle> BuilderHandle_uptr;
+using BuilderHandle_uptr = std::unique_ptr<BuilderHandle>;
 
 // Pointer to member function on MaterialBuilder
 template <typename ArgType>
@@ -65,8 +66,8 @@ using BuilderMethod = MaterialBuilder &(MaterialBuilder::*)(ArgType);
 template <typename ArgType>
 struct TypedBuilderHandle final : public BuilderHandle {
   // Remove const/reference qualifiers from ArgType
-  typedef typename std::remove_const<
-      typename std::remove_reference<ArgType>::type>::type ValueType;
+  using ValueType = typename std::remove_const<
+      typename std::remove_reference<ArgType>::type>::type;
 
   explicit TypedBuilderHandle(BuilderMethod<ArgType> m)
       : BuilderHandle(), m_method(m) {}
@@ -81,7 +82,7 @@ private:
   BuilderMethod<ArgType> m_method;
 };
 
-typedef std::unordered_map<std::string, BuilderHandle_uptr> Handlers;
+using Handlers = std::unordered_map<std::string, BuilderHandle_uptr>;
 
 // Insert a handle into the given map
 template <typename ArgType>
@@ -148,7 +149,7 @@ void addToBuilder(MaterialBuilder *builder, const std::string &attr,
  */
 Material MaterialXMLParser::parse(std::istream &istr) const {
   using namespace Poco::XML;
-  typedef AutoPtr<Document> DocumentPtr;
+  using DocumentPtr = AutoPtr<Document>;
 
   InputSource src(istr);
   DOMParser parser;
@@ -195,7 +196,7 @@ Material MaterialXMLParser::parse(std::istream &istr) const {
  */
 Material MaterialXMLParser::parse(Poco::XML::Element *element) const {
   using namespace Poco::XML;
-  typedef AutoPtr<NamedNodeMap> NamedNodeMapPtr;
+  using NamedNodeMapPtr = AutoPtr<NamedNodeMap>;
   NamedNodeMapPtr attrs = element->attributes();
   const auto id = attrs->getNamedItem(ID_ATT);
   if (!id || id->nodeValue().empty()) {
diff --git a/Framework/Kernel/src/MersenneTwister.cpp b/Framework/Kernel/src/MersenneTwister.cpp
index 472ee325c5994842ce99ba187ccd78b230b13758..7deeedcfa175b9eb44a7d9697e1cd920d281f0cd 100644
--- a/Framework/Kernel/src/MersenneTwister.cpp
+++ b/Framework/Kernel/src/MersenneTwister.cpp
@@ -2,9 +2,8 @@
 // Includes
 //------------------------------------------------------------------------------
 #include "MantidKernel/MersenneTwister.h"
-
-#include <boost/random/uniform_int_distribution.hpp>
-#include <boost/random/uniform_real_distribution.hpp>
+#include "MantidKernel/make_unique.h"
+#include "MantidKernel/uniform_int_distribution.h"
 
 #include <Poco/Timestamp.h>
 
@@ -44,25 +43,18 @@ MersenneTwister::MersenneTwister(const double start, const double end)
  */
 MersenneTwister::MersenneTwister(const size_t seedValue, const double start,
                                  const double end)
-    : m_generator(), m_start(start), m_end(end), m_currentSeed(),
-      m_savedStateGenerator(nullptr) {
+    : m_engine(), m_start(start), m_end(end), m_seed(), m_savedEngine() {
   setSeed(seedValue);
 }
 
-/// Destructor
-MersenneTwister::~MersenneTwister() { delete m_savedStateGenerator; }
-
 /**
- * (Re-)seed the generator. This clears the current saved state
+ * (Re-)seed the generator. This resets the current saved state
  * @param seedValue :: A seed for the generator
  */
 void MersenneTwister::setSeed(const size_t seedValue) {
-  // Bug in earlier versions of this implementation meant
-  // that a unsigned int could not be past to the seed function
-  m_currentSeed = static_cast<boost::mt19937::result_type>(seedValue);
-  m_generator.seed(m_currentSeed);
-  delete m_savedStateGenerator;
-  m_savedStateGenerator = nullptr;
+  m_seed = static_cast<std::mt19937::result_type>(seedValue);
+  m_engine.seed(m_seed);
+  m_savedEngine = Kernel::make_unique<std::mt19937>(m_engine);
 }
 
 /**
@@ -83,8 +75,7 @@ void MersenneTwister::setRange(const double start, const double end) {
  * @returns The next number in the pseudo-random sequence
  */
 double MersenneTwister::nextValue(double start, double end) {
-  boost::random::uniform_real_distribution<double> dist(start, end);
-  return dist(m_generator);
+  return std::uniform_real_distribution<double>(start, end)(m_engine);
 }
 
 /**
@@ -95,18 +86,17 @@ double MersenneTwister::nextValue(double start, double end) {
  * @return An integer in the defined range
  */
 int MersenneTwister::nextInt(int start, int end) {
-  boost::random::uniform_int_distribution<> dist(start, end);
-  return dist(m_generator);
+  return Mantid::Kernel::uniform_int_distribution<int>(start, end)(m_engine);
 }
 
 /**
  * Resets the generator using the value given at the last call to setSeed
  */
-void MersenneTwister::restart() { setSeed(m_currentSeed); }
+void MersenneTwister::restart() { setSeed(m_seed); }
 
 /// Saves the current state of the generator
 void MersenneTwister::save() {
-  m_savedStateGenerator = new boost::mt19937(m_generator); // Copy the state
+  m_savedEngine = Kernel::make_unique<std::mt19937>(m_engine);
 }
 
 /// Restores the generator to the last saved point, or the beginning if nothing
@@ -115,8 +105,8 @@ void MersenneTwister::restore() {
   // Copy saved to current, still distinct objects so that another restore still
   // brings us
   // back to the originally saved point
-  if (m_savedStateGenerator) {
-    m_generator = boost::mt19937(*m_savedStateGenerator);
+  if (m_savedEngine) {
+    m_engine = std::mt19937(*m_savedEngine);
   } else {
     restart();
   }
diff --git a/Framework/Kernel/src/NetworkProxyOSX.cpp b/Framework/Kernel/src/NetworkProxyOSX.cpp
index ed8e08590703c05e3eb2c077b4d749e5b8cb6dee..1692e4647a5063c7603d05be461588228f366a47 100644
--- a/Framework/Kernel/src/NetworkProxyOSX.cpp
+++ b/Framework/Kernel/src/NetworkProxyOSX.cpp
@@ -43,7 +43,7 @@ enum ProxyType {
 };
 
 /// Typedef Collection of proxy information.
-typedef std::vector<ProxyInfo> ProxyInfoVec;
+using ProxyInfoVec = std::vector<ProxyInfo>;
 
 /**
  * Extract proxy information from a CFDistionaryRef
diff --git a/Framework/Kernel/src/NormalDistribution.cpp b/Framework/Kernel/src/NormalDistribution.cpp
deleted file mode 100644
index e7ff30c4280bd54e798bfbebb1b4b41b55f734f4..0000000000000000000000000000000000000000
--- a/Framework/Kernel/src/NormalDistribution.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//------------------------------------------------------------------------------
-// Includes
-//------------------------------------------------------------------------------
-#include <string>
-#include "MantidKernel/NormalDistribution.h"
-#include "MantidKernel/MersenneTwister.h"
-
-namespace Mantid {
-namespace Kernel {
-
-//------------------------------------------------------------------------------
-// Public member functions
-//------------------------------------------------------------------------------
-
-/// Construct the default generator for standard normal distribution
-/// (mean = 0.0, sigma = 1.0)
-NormalDistribution::NormalDistribution()
-    : m_uniform_generator(), m_generator(0.0, 1.0) {}
-
-/// Construct the generator with initial distribution parameters
-/// and default seed.
-NormalDistribution::NormalDistribution(const double mean, const double sigma)
-    : m_uniform_generator(), m_generator(mean, sigma) {
-  if (sigma <= 0.0) {
-    throw std::runtime_error(
-        "Normal distribution must have positive sigma, given " +
-        std::to_string(sigma));
-  }
-}
-
-/// Construct the generator with initial distribution parameters and
-/// a seed value.
-NormalDistribution::NormalDistribution(const size_t seedValue,
-                                       const double mean, const double sigma)
-    : m_uniform_generator(seedValue), m_generator(mean, sigma) {
-  if (sigma <= 0.0) {
-    throw std::runtime_error(
-        "Normal distribution must have positive sigma, given " +
-        std::to_string(sigma));
-  }
-}
-
-/// Set the random number seed.
-/// @param seedValue :: A seed for the generator.
-void NormalDistribution::setSeed(const size_t seedValue) {
-  m_uniform_generator.setSeed(seedValue);
-}
-
-/// Generate the next random number in the sequence
-double NormalDistribution::nextValue() {
-  return m_generator(m_uniform_generator);
-}
-
-/// Generate a random number from a distribution with given mean and sigma.
-/// @param argMean :: A mean of the distribution.
-/// @param argSigma :: A sigma of the distribution.
-double NormalDistribution::randomValue(double argMean, double argSigma) {
-  boost::normal_distribution<double>::param_type param(argMean, argSigma);
-  return m_generator(m_uniform_generator, param);
-}
-}
-}
diff --git a/Framework/Kernel/src/PropertyManager.cpp b/Framework/Kernel/src/PropertyManager.cpp
index 6cf843553ef294f20ae729d94419aef7b09e056d..ca022354426dfd9850d85dcce8772a932eb13cd8 100644
--- a/Framework/Kernel/src/PropertyManager.cpp
+++ b/Framework/Kernel/src/PropertyManager.cpp
@@ -347,7 +347,7 @@ void PropertyManager::setPropertiesWithSimpleString(
     const std::unordered_set<std::string> &ignoreProperties) {
   ::Json::Value propertyJson;
   // Split up comma-separated properties
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
 
   boost::char_separator<char> sep(";");
   tokenizer propPairs(propertiesString, ";",
diff --git a/Framework/Kernel/src/Statistics.cpp b/Framework/Kernel/src/Statistics.cpp
index a42617046cccd533d475d32bf260448588806edc..42bf89c2a82051612a9fadfc88910831dd9be4cf 100644
--- a/Framework/Kernel/src/Statistics.cpp
+++ b/Framework/Kernel/src/Statistics.cpp
@@ -102,7 +102,43 @@ std::vector<double> getZscore(const vector<TYPE> &data) {
   }
   for (auto it = data.cbegin(); it != data.cend(); ++it) {
     double tmp = static_cast<double>(*it);
-    Zscore.push_back(fabs((tmp - stats.mean) / stats.standard_deviation));
+    Zscore.push_back(fabs((stats.mean - tmp) / stats.standard_deviation));
+  }
+  return Zscore;
+}
+/**
+ * There are enough special cases in determining the Z score where it useful to
+ * put it in a single function.
+ */
+template <typename TYPE>
+std::vector<double> getWeightedZscore(const vector<TYPE> &data,
+                                      const vector<TYPE> &weights) {
+  if (data.size() < 3) {
+    std::vector<double> Zscore(data.size(), 0.);
+    return Zscore;
+  }
+  std::vector<double> Zscore;
+  Statistics stats = getStatistics(data);
+  if (stats.standard_deviation == 0.) {
+    std::vector<double> Zscore(data.size(), 0.);
+    return Zscore;
+  }
+  double sumWeights = 0.0;
+  double sumWeightedData = 0.0;
+  double weightedVariance = 0.0;
+  for (size_t it = 0; it != data.size(); ++it) {
+    sumWeights += static_cast<double>(weights[it]);
+    sumWeightedData += static_cast<double>(weights[it] * data[it]);
+  }
+  double weightedMean = sumWeightedData / sumWeights;
+  for (size_t it = 0; it != data.size(); ++it) {
+    weightedVariance +=
+        std::pow(static_cast<double>(data[it]) - weightedMean, 2) *
+        std::pow(static_cast<double>(weights[it]) / sumWeights, 2);
+  }
+  for (auto it = data.cbegin(); it != data.cend(); ++it) {
+    Zscore.push_back(fabs((static_cast<double>(*it) - weightedMean) /
+                          std::sqrt(weightedVariance)));
   }
   return Zscore;
 }
@@ -406,6 +442,8 @@ std::vector<double> getMomentsAboutMean(const std::vector<TYPE> &x,
   getStatistics<TYPE>(const vector<TYPE> &, const unsigned int);               \
   template MANTID_KERNEL_DLL std::vector<double> getZscore<TYPE>(              \
       const vector<TYPE> &);                                                   \
+  template MANTID_KERNEL_DLL std::vector<double> getWeightedZscore<TYPE>(      \
+      const vector<TYPE> &, const vector<TYPE> &);                             \
   template MANTID_KERNEL_DLL std::vector<double> getModifiedZscore<TYPE>(      \
       const vector<TYPE> &, const bool);                                       \
   template MANTID_KERNEL_DLL std::vector<double> getMomentsAboutOrigin<TYPE>(  \
diff --git a/Framework/Kernel/src/Strings.cpp b/Framework/Kernel/src/Strings.cpp
index a1f1868ee9a7a4d8921e82bc9d8893d7ca29ba62..7798b8f2d86298a046bc2fb1db97c49157736fc3 100644
--- a/Framework/Kernel/src/Strings.cpp
+++ b/Framework/Kernel/src/Strings.cpp
@@ -850,7 +850,7 @@ int setValues(const std::string &Line, const std::vector<int> &Index,
 
   //  mathFunc::crossSort(sIndex,OPt);
 
-  typedef std::vector<int>::const_iterator iVecIter;
+  using iVecIter = std::vector<int>::const_iterator;
   std::vector<int>::const_iterator sc = sIndex.begin();
   std::vector<int>::const_iterator oc = OPt.begin();
   int cnt(0);
@@ -1072,7 +1072,7 @@ int isMember(const std::vector<std::string> &group,
  */
 std::vector<int> parseRange(const std::string &str, const std::string &elemSep,
                             const std::string &rangeSep) {
-  typedef Mantid::Kernel::StringTokenizer Tokenizer;
+  using Tokenizer = Mantid::Kernel::StringTokenizer;
 
   Tokenizer elements;
 
diff --git a/Framework/Kernel/src/UserStringParser.cpp b/Framework/Kernel/src/UserStringParser.cpp
index d365130ca67d07a8bc24b41d4650ada25224e7f2..7c094e615dc22433af8f5b7cd1e71e0337c7f47f 100644
--- a/Framework/Kernel/src/UserStringParser.cpp
+++ b/Framework/Kernel/src/UserStringParser.cpp
@@ -84,7 +84,7 @@ bool UserStringParser::Contains(const std::string &input, char ch) {
   */
 std::vector<std::string>
 UserStringParser::separateComma(const std::string &input) {
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer tokens(input, ",", Mantid::Kernel::StringTokenizer::TOK_TRIM);
   return tokens.asVector();
 }
@@ -142,7 +142,7 @@ void UserStringParser::Tokenize(const std::string &input,
                                 const std::string &delimiter,
                                 unsigned int &start, unsigned int &end,
                                 unsigned int &step) {
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer tokens(input, delimiter);
   // validate the separated tokens
   if (!isValidStepSeparator(input, tokens.asVector())) {
diff --git a/Framework/Kernel/src/VectorHelper.cpp b/Framework/Kernel/src/VectorHelper.cpp
index 199281c7001d7f29413198ce7873792f72dd75f2..4b17ca44e1b8f24c133d172c123bb9fc4b49a829 100644
--- a/Framework/Kernel/src/VectorHelper.cpp
+++ b/Framework/Kernel/src/VectorHelper.cpp
@@ -18,19 +18,37 @@ namespace VectorHelper {
  *,x_n-1,delta_n-1,x_n]
  *  @param[out] xnew   The newly created axis resulting from the input params
  *  @param[in] resize_xnew If false then the xnew vector is NOT resized. Useful
- *if on the number of bins needs determining. (Default=True)
+ *if the number of bins needs determining. (Default=True)
  *  @param[in] full_bins_only If true, bins of the size less than the current
- *step are not included
+ *step are not included. (Default=True)
+ *  @param[in] xMinHint x_1 if params contains only delta_1.
+ *  @param[in] xMaxHint x_2 if params contains only delta_1.
  *  @return The number of bin boundaries in the new axis
  **/
-int DLLExport createAxisFromRebinParams(const std::vector<double> &params,
-                                        std::vector<double> &xnew,
-                                        const bool resize_xnew,
-                                        const bool full_bins_only) {
+int DLLExport
+createAxisFromRebinParams(const std::vector<double> &params,
+                          std::vector<double> &xnew, const bool resize_xnew,
+                          const bool full_bins_only, const double xMinHint,
+                          const double xMaxHint) {
+  std::vector<double> tmp;
+  const std::vector<double> &fullParams =
+      [&params, &tmp, xMinHint, xMaxHint]() {
+        if (params.size() == 1) {
+          if (std::isnan(xMinHint) || std::isnan(xMaxHint)) {
+            throw std::runtime_error("createAxisFromRebinParams: xMinHint and "
+                                     "xMaxHint must be supplied if params "
+                                     "contains only the bin width.");
+          }
+          tmp.resize(3);
+          tmp = {xMinHint, params.front(), xMaxHint};
+          return tmp;
+        }
+        return params;
+      }();
   double xs;
   int ibound(2), istep(1), inew(1);
-  int ibounds = static_cast<int>(
-      params.size()); // highest index in params array containing a bin boundary
+  // highest index in params array containing a bin boundary
+  int ibounds = static_cast<int>(fullParams.size());
   int isteps = ibounds - 1; // highest index in params array containing a step
   xnew.clear();
 
@@ -45,16 +63,16 @@ int DLLExport createAxisFromRebinParams(const std::vector<double> &params,
     lastBinCoef = 1.0;
   }
 
-  double xcurr = params[0];
+  double xcurr = fullParams[0];
   if (resize_xnew)
     xnew.push_back(xcurr);
 
   while ((ibound <= ibounds) && (istep <= isteps)) {
     // if step is negative then it is logarithmic step
-    if (params[istep] >= 0.0)
-      xs = params[istep];
+    if (fullParams[istep] >= 0.0)
+      xs = fullParams[istep];
     else
-      xs = xcurr * fabs(params[istep]);
+      xs = xcurr * fabs(fullParams[istep]);
 
     if (fabs(xs) == 0.0) {
       // Someone gave a 0-sized step! What a dope.
@@ -62,7 +80,7 @@ int DLLExport createAxisFromRebinParams(const std::vector<double> &params,
           "Invalid binning step provided! Can't creating binning axis.");
     }
 
-    if ((xcurr + xs * (1.0 + lastBinCoef)) <= params[ibound]) {
+    if ((xcurr + xs * (1.0 + lastBinCoef)) <= fullParams[ibound]) {
       // If we can still fit current bin _plus_ specified portion of a last bin,
       // continue
       xcurr += xs;
@@ -76,7 +94,7 @@ int DLLExport createAxisFromRebinParams(const std::vector<double> &params,
       else
         // For non full_bins_only, finish by adding as mush as is left from the
         // range
-        xcurr = params[ibound];
+        xcurr = fullParams[ibound];
 
       ibound += 2;
       istep += 2;
@@ -84,14 +102,6 @@ int DLLExport createAxisFromRebinParams(const std::vector<double> &params,
     if (resize_xnew)
       xnew.push_back(xcurr);
     inew++;
-
-    //    if (xnew.size() > 10000000)
-    //    {
-    //      //Max out at 1 million bins
-    //      throw std::runtime_error("Over ten million binning steps created.
-    //      Exiting to avoid infinite loops.");
-    //      return inew;
-    //    }
   }
 
   return inew;
@@ -211,7 +221,7 @@ void rebin(const std::vector<double> &xold, const std::vector<double> &yold,
       }
     } else {
       // non-distribution, just square root final error value
-      typedef double (*pf)(double);
+      using pf = double (*)(double);
       pf uf = std::sqrt;
       std::transform(enew.begin(), enew.end(), enew.begin(), uf);
     }
@@ -322,7 +332,7 @@ void rebinHistogram(const std::vector<double> &xold,
                  // (should be done externally)
   {
     // Now take the root-square of the errors
-    typedef double (*pf)(double);
+    using pf = double (*)(double);
     pf uf = std::sqrt;
     std::transform(enew.begin(), enew.end(), enew.begin(), uf);
   }
@@ -523,7 +533,7 @@ std::vector<NumT> splitStringIntoVector(std::string listString) {
   // Split the string and turn it into a vector.
   std::vector<NumT> values;
 
-  typedef std::vector<std::string> split_vector_type;
+  using split_vector_type = std::vector<std::string>;
   split_vector_type strs;
 
   boost::split(strs, listString, boost::is_any_of(", "));
diff --git a/Framework/Kernel/test/ArrayPropertyTest.h b/Framework/Kernel/test/ArrayPropertyTest.h
index 75408b0d46d6535385a074c232c3dc93cefbb565..f15f1f2ab2e40e36fcb639a7a502672ea30a2313 100644
--- a/Framework/Kernel/test/ArrayPropertyTest.h
+++ b/Framework/Kernel/test/ArrayPropertyTest.h
@@ -242,21 +242,24 @@ public:
     ArrayProperty<int> i("i");
     TS_ASSERT(i.isDefault())
     std::vector<int> ii(3, 4);
-    TS_ASSERT_EQUALS(i = ii, ii)
+    i = ii;
+    TS_ASSERT_EQUALS(i.operator()(), ii);
     TS_ASSERT_EQUALS(i.operator()()[1], 4)
     TS_ASSERT(!i.isDefault())
 
     ArrayProperty<double> d("d");
     TS_ASSERT(d.isDefault())
     std::vector<double> dd(5, 9.99);
-    TS_ASSERT_EQUALS(d = dd, dd)
+    d = dd;
+    TS_ASSERT_EQUALS(d.operator()(), dd);
     TS_ASSERT_EQUALS(d.operator()()[3], 9.99)
     TS_ASSERT(!d.isDefault())
 
     ArrayProperty<std::string> s("s");
     TS_ASSERT(s.isDefault())
     std::vector<std::string> ss(2, "zzz");
-    TS_ASSERT_EQUALS(s = ss, ss)
+    s = ss;
+    TS_ASSERT_EQUALS(s.operator()(), ss)
     TS_ASSERT_EQUALS(s.operator()()[0], "zzz")
     TS_ASSERT(!s.isDefault())
   }
diff --git a/Framework/Kernel/test/BinaryFileTest.h b/Framework/Kernel/test/BinaryFileTest.h
index 11dae6ad287eedf1be473b2a0a727ab43749b20d..b0d5bd2efd60df85c9996c1e58ddaf37c0ef4626 100644
--- a/Framework/Kernel/test/BinaryFileTest.h
+++ b/Framework/Kernel/test/BinaryFileTest.h
@@ -16,9 +16,9 @@ using std::cout;
 
 //==========================================================================================
 /// Make the code clearer by having this an explicit type
-typedef uint32_t PixelType;
+using PixelType = uint32_t;
 /// Type for the DAS time of flight (data file)
-typedef uint32_t DasTofType;
+using DasTofType = uint32_t;
 /// Structure that matches the form in the binary event list.
 struct DasEvent {
   /// Time of flight.
diff --git a/Framework/Kernel/test/CatalogInfoTest.h b/Framework/Kernel/test/CatalogInfoTest.h
index 0eaa2692f5d9b50b48d5dacbac9a2c04f563f6e7..9f8e742c4b0c9c7e7bd8330115cefcdc35608ec9 100644
--- a/Framework/Kernel/test/CatalogInfoTest.h
+++ b/Framework/Kernel/test/CatalogInfoTest.h
@@ -86,7 +86,7 @@ public:
     std::string macPrefixPath =
         "/archive/NDXSANDALS/Instrument/data/cycle_05_3/ALF06716.LOG";
     std::string winPrefixPath =
-        "\\NDXSANDALS\\Instrument\\data\\cycle_05_3\\ALF06716.LOG";
+        R"(\NDXSANDALS\Instrument\data\cycle_05_3\ALF06716.LOG)";
     std::string winDefaultPath = "\\\\isis\\inst$\\Instruments$"
                                  "\\NDXSANDALS\\Instrument\\data\\cycle_05_"
                                  "3\\ALF06716.LOG";
diff --git a/Framework/Kernel/test/ComputeResourceInfoTest.h b/Framework/Kernel/test/ComputeResourceInfoTest.h
index 9e830ad03b034b33d79acf724314b40a4194dd0a..89f745063222fd0417991fc6ae2221a5eb6f6d25 100644
--- a/Framework/Kernel/test/ComputeResourceInfoTest.h
+++ b/Framework/Kernel/test/ComputeResourceInfoTest.h
@@ -211,7 +211,7 @@ private:
                                "<facilities>"
                                "  <facility name=\"" +
                                testFacilityName +
-                               "\" FileExtensions=\".xyz\">" + simpleInstStr +
+                               R"(" FileExtensions=".xyz">)" + simpleInstStr +
                                crStr + "  </facility>"
                                        "</facilities>";
 
diff --git a/Framework/Kernel/test/ConfigServiceTest.h b/Framework/Kernel/test/ConfigServiceTest.h
index bd2f247a1d1eff08e9611e0b2da34383334f0d39..0485fd2b6c03ec15a2bdd0398d9e853e626002aa 100644
--- a/Framework/Kernel/test/ConfigServiceTest.h
+++ b/Framework/Kernel/test/ConfigServiceTest.h
@@ -352,9 +352,9 @@ public:
                      ConfigService::Instance().getInstrumentDirectory());
 
     // check all of the directory entries actually exist
-    for (auto it = directories.begin(); it != directories.end(); ++it) {
-      Poco::File directory(*it);
-      TSM_ASSERT(*it + " does not exist", directory.exists());
+    for (auto &directoryPath : directories) {
+      Poco::File directory(directoryPath);
+      TSM_ASSERT(directoryPath + " does not exist", directory.exists());
     }
   }
 
diff --git a/Framework/Kernel/test/DataServiceTest.h b/Framework/Kernel/test/DataServiceTest.h
index 14b39c910d0b581e8f3859a876634a5ea63a5839..cdd80bae12fbee103df66a38b52a4bdf03d7ed14 100644
--- a/Framework/Kernel/test/DataServiceTest.h
+++ b/Framework/Kernel/test/DataServiceTest.h
@@ -295,8 +295,8 @@ public:
     svc.add("Four", four);
     svc.add("Two", two);
 
-    typedef Mantid::Kernel::DataServiceSort sortedEnum;
-    typedef Mantid::Kernel::DataServiceHidden hiddenEnum;
+    using sortedEnum = Mantid::Kernel::DataServiceSort;
+    using hiddenEnum = Mantid::Kernel::DataServiceHidden;
 
     // First assert that sort does not impact size
     TS_ASSERT_EQUALS(svc.getObjectNames(sortedEnum::Sorted).size(),
diff --git a/Framework/Kernel/test/DiskBufferISaveableTest.h b/Framework/Kernel/test/DiskBufferISaveableTest.h
index 873796a94bce45fc586a0c48295e8e89b71db072..da1a11e73979182cd4d9629178c7b673e2f43a9b 100644
--- a/Framework/Kernel/test/DiskBufferISaveableTest.h
+++ b/Framework/Kernel/test/DiskBufferISaveableTest.h
@@ -90,15 +90,14 @@ public:
   }
 
   void tearDown() override {
-    for (size_t i = 0; i < data.size(); i++) {
-      delete data[i];
-      data[i] = NULL;
+    for (auto &item : data) {
+      delete item;
     }
 
-    for (size_t i = 0; i < bigData.size(); i++) {
-      delete bigData[i];
-      bigData[i] = NULL;
+    for (auto &bigItem : bigData) {
+      delete bigItem;
     }
+
     ISaveableTester::fakeFile = "";
   }
   void testIsaveable() {
@@ -435,9 +434,9 @@ public:
   void test_smallCache_writeBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(3);
-    for (size_t i = 0; i < data.size(); i++) {
-      dbuf.toWrite(data[i]);
-      data[i]->setBusy(false);
+    for (auto &i : data) {
+      dbuf.toWrite(i);
+      i->setBusy(false);
     }
     std::cout << " Elapsed : " << tim << " to load " << num << " into MRU.\n";
   }
@@ -445,13 +444,13 @@ public:
   void test_smallCache_no_writeBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(0);
-    for (size_t i = 0; i < data.size(); i++) {
-      data[i]->setBusy(true); // Items won't do any real saving
+    for (auto &i : data) {
+      i->setBusy(true); // Items won't do any real saving
     }
 
-    for (int i = 0; i < int(data.size()); i++) {
-      dbuf.toWrite(data[i]);
-      data[i]->setBusy(false);
+    for (auto &i : data) {
+      dbuf.toWrite(i);
+      i->setBusy(false);
     }
     std::cout << " Elapsed : " << tim << " to load " << num
               << " into MRU (no write cache).\n";
@@ -460,9 +459,9 @@ public:
   void test_largeCache_writeBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(1000);
-    for (int i = 0; i < int(data.size()); i++) {
-      dbuf.toWrite(data[i]);
-      data[i]->setBusy(false);
+    for (auto &i : data) {
+      dbuf.toWrite(i);
+      i->setBusy(false);
     }
     std::cout << tim << " to load " << num << " into MRU.\n";
   }
@@ -470,9 +469,9 @@ public:
   void test_largeCache_noWriteBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(0);
-    for (int i = 0; i < int(data.size()); i++) {
-      dbuf.toWrite(data[i]);
-      data[i]->setBusy(false);
+    for (auto &i : data) {
+      dbuf.toWrite(i);
+      i->setBusy(false);
     }
     std::cout << " Elapsed : " << tim << " to load " << num
               << " into MRU (no write buffer).\n";
diff --git a/Framework/Kernel/test/DiskBufferTest.h b/Framework/Kernel/test/DiskBufferTest.h
index 426c375731d7603559e2448f15d25f68bc4d2de1..4911bcdaca6a9e6ba3b12ebbf41990182b86b741 100644
--- a/Framework/Kernel/test/DiskBufferTest.h
+++ b/Framework/Kernel/test/DiskBufferTest.h
@@ -115,9 +115,8 @@ public:
   }
 
   void tearDown() override {
-    for (size_t i = 0; i < data.size(); i++) {
-      delete data[i];
-      data[i] = NULL;
+    for (auto &i : data) {
+      delete i;
     }
   }
   void xest_nothing() {
@@ -171,8 +170,8 @@ public:
   ////--------------------------------------------------------------------------------
   ///** Sorts by file position when writing to a file */
   void test_writesOutInFileOrder() {
-    for (size_t i = 0; i < data.size(); i++) {
-      data[i]->setDataChanged();
+    for (auto &i : data) {
+      i->setDataChanged();
     }
     // Room for 2 objects of size 2 in the to-write cache
     DiskBuffer dbuf(2 * 2);
@@ -796,9 +795,9 @@ public:
   void test_withFakeSeeking_withWriteBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(10);
-    for (int i = 0; i < int(dataSeek.size()); i++) {
+    for (auto &i : dataSeek) {
       // Pretend you just loaded the data
-      dataSeek[i]->load(dbuf);
+      i->load(dbuf);
     }
     std::cout << tim << " to load " << dataSeek.size()
               << " into MRU with fake seeking. \n";
@@ -809,9 +808,9 @@ public:
   void test_withFakeSeeking_noWriteBuffer() {
     CPUTimer tim;
     DiskBuffer dbuf(0);
-    for (int i = 0; i < int(dataSeek.size()); i++) {
+    for (auto &i : dataSeek) {
       // Pretend you just loaded the data
-      dataSeek[i]->load(dbuf);
+      i->load(dbuf);
     }
     std::cout << tim << " to load " << dataSeek.size()
               << " into MRU with fake seeking. \n";
@@ -823,10 +822,10 @@ public:
     CPUTimer tim;
     DiskBuffer dbuf(20);
     dbuf.setFileLength(dataSeek.size());
-    for (int i = 0; i < int(dataSeek.size()); i++) {
+    for (auto &i : dataSeek) {
       // Pretend you just loaded the data
-      dataSeek[i]->grow(dbuf, true);
-      dbuf.toWrite(dataSeek[i]);
+      i->grow(dbuf, true);
+      dbuf.toWrite(i);
     }
     std::cout << "About to flush the cache to finish writes.\n";
     dbuf.flushCache();
@@ -840,10 +839,10 @@ public:
   void test_withFakeSeeking_growingData_savingWithoutUsingMRU() {
     CPUTimer tim;
     DiskBuffer dbuf(dataSeek.size());
-    for (int i = 0; i < int(dataSeek.size()); i++) {
+    for (auto &i : dataSeek) {
       // Pretend you just loaded the data
-      dataSeek[i]->grow(dbuf, false);
-      dataSeek[i]->save();
+      i->grow(dbuf, false);
+      i->save();
     }
     std::cout << tim << " to grow " << dataSeek.size()
               << " into MRU with fake seeking. \n";
diff --git a/Framework/Kernel/test/DynamicFactoryTest.h b/Framework/Kernel/test/DynamicFactoryTest.h
index fbbc52509ead89f3e9397817fb1fd4cd12dfb5d2..19d9e912b75988272dc306b4b26909cb44a832ea 100644
--- a/Framework/Kernel/test/DynamicFactoryTest.h
+++ b/Framework/Kernel/test/DynamicFactoryTest.h
@@ -20,7 +20,7 @@ class CaseSensitiveIntFactory
     : public DynamicFactory<int, CaseSensitiveStringComparator> {};
 
 class DynamicFactoryTest : public CxxTest::TestSuite {
-  typedef boost::shared_ptr<int> int_ptr;
+  using int_ptr = boost::shared_ptr<int>;
 
 public:
   // This pair of boilerplate methods prevent the suite being created statically
diff --git a/Framework/Kernel/test/FileDescriptorTest.h b/Framework/Kernel/test/FileDescriptorTest.h
index ec7856f06e13ccb66f81c6e839962836ab23f5be..a3957fa443394a222a4fb7cc9ff5cfa80d57afd6 100644
--- a/Framework/Kernel/test/FileDescriptorTest.h
+++ b/Framework/Kernel/test/FileDescriptorTest.h
@@ -23,14 +23,14 @@ public:
     auto &cfg = Mantid::Kernel::ConfigService::Instance();
     cfg.reset();
     const auto &dataPaths = cfg.getDataSearchDirs();
-    for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) {
-      Poco::Path nxsPath(*it, "CNCS_7860_event.nxs");
+    for (const auto &dataPath : dataPaths) {
+      Poco::Path nxsPath(dataPath, "CNCS_7860_event.nxs");
       if (Poco::File(nxsPath).exists())
         m_testNexusPath = nxsPath.toString();
-      Poco::Path nonNxsPath(*it, "CSP79590.raw");
+      Poco::Path nonNxsPath(dataPath, "CSP79590.raw");
       if (Poco::File(nonNxsPath).exists())
         m_testNonNexusPath = nonNxsPath.toString();
-      Poco::Path asciiPath(*it, "AsciiExample.txt");
+      Poco::Path asciiPath(dataPath, "AsciiExample.txt");
       if (Poco::File(asciiPath).exists())
         m_testAsciiPath = asciiPath.toString();
 
diff --git a/Framework/Kernel/test/FilterChannelTest.h b/Framework/Kernel/test/FilterChannelTest.h
index e59ffadbaa4365cdce7ec6f53552eade2a4d7f3d..e21210140e4e6c84d488d64a719e02a7cf73e9ce 100644
--- a/Framework/Kernel/test/FilterChannelTest.h
+++ b/Framework/Kernel/test/FilterChannelTest.h
@@ -140,7 +140,7 @@ public:
     a.addChannel(tChannel.get());
 
     // create a priority map
-    typedef std::map<unsigned int, std::string> priorityMap;
+    using priorityMap = std::map<unsigned int, std::string>;
     priorityMap pMap;
     pMap.insert(priorityMap::value_type(1, "FATAL"));
     pMap.insert(priorityMap::value_type(2, "CRITICAL"));
diff --git a/Framework/Kernel/test/GlobTest.h b/Framework/Kernel/test/GlobTest.h
index 1908edbff8e531f2dbdb37feb97f9184638593ce..92057289d2f9d4c1d705e1df05b3e285c0eca443 100644
--- a/Framework/Kernel/test/GlobTest.h
+++ b/Framework/Kernel/test/GlobTest.h
@@ -34,9 +34,8 @@ public:
     TS_ASSERT(files.size() > 0);
 
     size_t matches = 0;
-    for (std::set<std::string>::const_iterator f = files.begin();
-         f != files.end(); ++f) {
-      Poco::Path path = *f;
+    for (const auto &file : files) {
+      Poco::Path path = file;
       std::string project = path[path.depth() - 1];
       if (project == "API")
         ++matches;
@@ -96,9 +95,8 @@ public:
     TS_ASSERT(files.size() > 0);
 
     size_t matches = 0;
-    for (std::set<std::string>::const_iterator f = files.begin();
-         f != files.end(); ++f) {
-      Poco::Path path = *f;
+    for (const auto &file : files) {
+      Poco::Path path = file;
       std::string project = path[path.depth() - 1];
       if (project == "API")
         ++matches;
diff --git a/Framework/Kernel/test/IValidatorTest.h b/Framework/Kernel/test/IValidatorTest.h
index 3aac7815d0e25179e2a600e5348db5202d6322dc..8005c39019cc5dfc8d5aa37a9243ac92a9c11208 100644
--- a/Framework/Kernel/test/IValidatorTest.h
+++ b/Framework/Kernel/test/IValidatorTest.h
@@ -25,7 +25,7 @@ public:
 
 private:
   std::string check(const boost::any &value) const override {
-    typedef std::vector<double> HeldType;
+    using HeldType = std::vector<double>;
     const HeldType *dataPtr = boost::any_cast<const HeldType *>(value);
     m_head = dataPtr->data();
     return "";
diff --git a/Framework/Kernel/test/InterpolationTest.h b/Framework/Kernel/test/InterpolationTest.h
index a2ed45e607b1b291938b06922ee96589fb13052d..a54e36bb57ab8a4df5cb2d24e07ad604c0160a65 100644
--- a/Framework/Kernel/test/InterpolationTest.h
+++ b/Framework/Kernel/test/InterpolationTest.h
@@ -206,13 +206,13 @@ public:
     Interpolation interpolationOne;
     interpolationOne.addPoint(200, 2.0);
 
-    for (size_t i = 0; i < m_tableXValues.size(); ++i) {
+    for (double m_tableXValue : m_tableXValues) {
       // When there are zero values in the interpolation, it returns 0.0
-      checkValue(interpolationZero, m_tableXValues[i], 0.0,
+      checkValue(interpolationZero, m_tableXValue, 0.0,
                  "zero interpolation values");
 
       // With one value, it returns this one value for any x.
-      checkValue(interpolationOne, m_tableXValues[i], 2.0,
+      checkValue(interpolationOne, m_tableXValue, 2.0,
                  "one interpolation value");
     }
   }
diff --git a/Framework/Kernel/test/MDAxisValidatorTest.h b/Framework/Kernel/test/MDAxisValidatorTest.h
index df39af877fa123e1cccc3a02a98e13d1be955366..f21d126f0b445614517379fd9a73e20881b4dd75 100644
--- a/Framework/Kernel/test/MDAxisValidatorTest.h
+++ b/Framework/Kernel/test/MDAxisValidatorTest.h
@@ -11,7 +11,7 @@
 #include "boost/make_shared.hpp"
 
 using Mantid::Kernel::MDAxisValidator;
-typedef boost::shared_ptr<MDAxisValidator> MDAxisValidator_sptr;
+using MDAxisValidator_sptr = boost::shared_ptr<MDAxisValidator>;
 
 class MDAxisValidatorTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/Kernel/test/MaterialXMLParserTest.h b/Framework/Kernel/test/MaterialXMLParserTest.h
index 4391ccfd806086a1a22eb03ab3fdf6e6a0082064..f9fc269958bc1266962c2f1ad2421c6796b078c3 100644
--- a/Framework/Kernel/test/MaterialXMLParserTest.h
+++ b/Framework/Kernel/test/MaterialXMLParserTest.h
@@ -30,7 +30,7 @@ public:
   // all of the attributes are handled.
   //----------------------------------------------------------------------------
   void test_Formula_Attribute() {
-    auto mat = parseMaterial("<material id=\"vanadium\" formula=\"V\"/>");
+    auto mat = parseMaterial(R"(<material id="vanadium" formula="V"/>)");
 
     TS_ASSERT_EQUALS("vanadium", mat.name());
     TS_ASSERT_DELTA(0.07223047, mat.numberDensity(), 1e-8);
@@ -38,7 +38,7 @@ public:
 
   void test_AtomicNumber_Attribute() {
     auto mat = parseMaterial(
-        "<material id=\"n\" atomicnumber=\"28\" numberdensity=\"0.12\"/>");
+        R"(<material id="n" atomicnumber="28" numberdensity="0.12"/>)");
 
     TS_ASSERT_DELTA(mat.totalScatterXSection(), 18.5, 0.0001);
     TS_ASSERT_DELTA(mat.absorbXSection(), 4.49, 0.0001);
diff --git a/Framework/Kernel/test/MersenneTwisterTest.h b/Framework/Kernel/test/MersenneTwisterTest.h
index 8e21afa10d0754520dffb090b09100444a638605..4c4084cf3f4a3f661ce1891f1146bf4c88c7acf0 100644
--- a/Framework/Kernel/test/MersenneTwisterTest.h
+++ b/Framework/Kernel/test/MersenneTwisterTest.h
@@ -4,6 +4,8 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/MersenneTwister.h"
 
+#include <iomanip>
+
 using Mantid::Kernel::MersenneTwister;
 
 class MersenneTwisterTest : public CxxTest::TestSuite {
@@ -139,14 +141,15 @@ public:
 
 private:
   void assertSequenceCorrectForSeed_39857239(MersenneTwister &randGen) {
-    double expectedValues[10] = {
-        0.203374452656, 0.597970068222, 0.120683325687,  0.92372657801,
-        0.734524340136, 0.467380537419, 0.0712658402044, 0.204503614921,
-        0.487210249063, 0.885743656661};
+    double expectedValues[10] = {0.597970068269, 0.923726578038, 0.46738053759,
+                                 0.204503614938, 0.885743656775, 0.532315163407,
+                                 0.849185494256, 0.294648804097, 0.435378050559,
+                                 0.222489577528};
     // Check 10 numbers
     for (std::size_t i = 0; i < 10; ++i) {
       TS_ASSERT_DELTA(randGen.nextValue(), expectedValues[i], 1e-12);
     }
+    std::cerr << "\n";
   }
 
   std::vector<double> doNextValueCalls(const unsigned int ncalls,
diff --git a/Framework/Kernel/test/MultiFileNameParserTest.h b/Framework/Kernel/test/MultiFileNameParserTest.h
index 32038147bfbd0fee1d20aa96afe9431743c8c541..d5754a82f95fdaaa0cde3c75068133f213b447f2 100644
--- a/Framework/Kernel/test/MultiFileNameParserTest.h
+++ b/Framework/Kernel/test/MultiFileNameParserTest.h
@@ -19,7 +19,7 @@ public:
   }
   static void destroySuite(MultiFileNameParserTest *suite) { delete suite; }
 
-  typedef std::vector<std::vector<unsigned int>> ParsedRuns;
+  using ParsedRuns = std::vector<std::vector<unsigned int>>;
 
   /////////////////////////////////////////////////////////////////////////////
   // Testing of parseMultiRunString.
diff --git a/Framework/Kernel/test/MutexTest.h b/Framework/Kernel/test/MutexTest.h
index b823f9e03fcf7fcc7dbf9ddc4627497fbcbc202d..e85fac873ccaaf6142eb8cf688133ceac5479e01 100644
--- a/Framework/Kernel/test/MutexTest.h
+++ b/Framework/Kernel/test/MutexTest.h
@@ -24,8 +24,7 @@ void reader() {
   Poco::ScopedReadRWLock lock(_access);
   //  std::cout << "Read launching\n";
   // do work here, without anyone having exclusive access
-  for (size_t i = 0; i < shared_data.size(); i++) {
-    double val = shared_data[i];
+  for (double val : shared_data) {
     UNUSED_ARG(val)
   }
   //  std::cout << "Read finished\n";
@@ -38,8 +37,8 @@ void unconditional_writer() {
   // do work here, with exclusive access
   shared_data.resize(shared_data.size() + 1, 2.345);
   // Dumb thing to slow down the writer
-  for (size_t i = 0; i < shared_data.size(); i++)
-    shared_data[i] = 4.567;
+  for (double &i : shared_data)
+    i = 4.567;
   //  std::cout << "Write finished\n";
 }
 
diff --git a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h
index b2d0230263299a98ce3d470633a6ff3278f2b7f9..197da2111b84e4930f841f7d0568a5d17bb03d41 100644
--- a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h
+++ b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h
@@ -13,7 +13,7 @@ using Mantid::Kernel::NDRandomNumberGenerator;
 
 class NDPseudoRandomNumberGeneratorTest : public CxxTest::TestSuite {
 private:
-  typedef boost::shared_ptr<NDRandomNumberGenerator> NDGenerator_sptr;
+  using NDGenerator_sptr = boost::shared_ptr<NDRandomNumberGenerator>;
 
 public:
   void test_That_Next_Always_Returns_ND_Size_Array() {
@@ -38,8 +38,8 @@ public:
     const double start(2.1), end(3.4);
     NDGenerator_sptr ndRand = createTestGenerator(12345, start, end);
     std::vector<double> firstPoint = ndRand->nextPoint();
-    for (size_t i = 0; i < firstPoint.size(); ++i) {
-      TS_ASSERT(firstPoint[i] >= start && firstPoint[i] <= end);
+    for (double i : firstPoint) {
+      TS_ASSERT(i >= start && i <= end);
     }
   }
 
@@ -63,7 +63,7 @@ private:
   createTestGenerator(const size_t seedValue, const double start = -1.0,
                       const double end = -1.0) {
     using namespace Mantid::Kernel;
-    typedef NDPseudoRandomNumberGenerator<MersenneTwister> NDMersenneTwister;
+    using NDMersenneTwister = NDPseudoRandomNumberGenerator<MersenneTwister>;
     const unsigned int ndims(3);
     if (start > 0.0 && end > 0.0)
       return boost::make_shared<NDMersenneTwister>(ndims, seedValue, start,
diff --git a/Framework/Kernel/test/NexusDescriptorTest.h b/Framework/Kernel/test/NexusDescriptorTest.h
index bf8f89446372d47d4d21960b556bcafc3686766d..0238213b82af62473eaf3d3f791bd9088b895a69 100644
--- a/Framework/Kernel/test/NexusDescriptorTest.h
+++ b/Framework/Kernel/test/NexusDescriptorTest.h
@@ -28,16 +28,16 @@ public:
   NexusDescriptorTest() {
     using Mantid::Kernel::ConfigService;
     auto dataPaths = ConfigService::Instance().getDataSearchDirs();
-    for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) {
-      Poco::Path hdf5Path(*it, "CNCS_7860_event.nxs");
+    for (auto &dataPath : dataPaths) {
+      Poco::Path hdf5Path(dataPath, "CNCS_7860_event.nxs");
       if (Poco::File(hdf5Path).exists())
         m_testHDF5Path = hdf5Path.toString();
 
-      Poco::Path hdf4Path(*it, "argus0026287.nxs");
+      Poco::Path hdf4Path(dataPath, "argus0026287.nxs");
       if (Poco::File(hdf4Path).exists())
         m_testHDF4Path = hdf4Path.toString();
 
-      Poco::Path nonhdf5Path(*it, "CSP79590.raw");
+      Poco::Path nonhdf5Path(dataPath, "CSP79590.raw");
       if (Poco::File(nonhdf5Path).exists())
         m_testNonHDFPath = nonhdf5Path.toString();
 
diff --git a/Framework/Kernel/test/NormalDistributionTest.h b/Framework/Kernel/test/NormalDistributionTest.h
deleted file mode 100644
index 7e06c8d8d2c3d5271615678dcc6bcb261ab24941..0000000000000000000000000000000000000000
--- a/Framework/Kernel/test/NormalDistributionTest.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef NORMALDISTRIBUTIONTEST_H_
-#define NORMALDISTRIBUTIONTEST_H_
-
-#include <cxxtest/TestSuite.h>
-#include "MantidKernel/NormalDistribution.h"
-
-using Mantid::Kernel::NormalDistribution;
-
-class NormalDistributionTest : public CxxTest::TestSuite {
-
-public:
-  void test_That_Object_Construction_Does_Not_Throw() {
-    TS_ASSERT_THROWS_NOTHING(NormalDistribution());
-    TS_ASSERT_THROWS_NOTHING(NormalDistribution(2.0, 1.1));
-    TS_ASSERT_THROWS_NOTHING(NormalDistribution(1, 2.0, 1.1));
-  }
-
-  void test_bad_input() {
-    TS_ASSERT_THROWS(NormalDistribution(1.0, 0.0), std::runtime_error);
-#ifdef NDEBUG
-    // In debug assert in boost code calls abort()
-    TS_ASSERT_THROWS(NormalDistribution(1.0, -1.0), std::runtime_error);
-#endif // NDEBUG
-  }
-
-  void test_standard_normal_distribution() {
-    NormalDistribution norm;
-    norm.setSeed(1);
-    size_t in(0), out(0);
-    for (size_t i = 0; i < 100; ++i) {
-      auto value = norm.nextValue();
-      if (std::fabs(value) < 1.0) {
-        ++in;
-      } else {
-        ++out;
-      }
-    }
-#ifdef _WIN32
-    TS_ASSERT_EQUALS(in, 67);
-    TS_ASSERT_EQUALS(out, 33);
-#else
-    TS_ASSERT_LESS_THAN(out, in);
-#endif
-  }
-
-  void test_normal_distribution() {
-    NormalDistribution norm(30.0, 5.0);
-    norm.setSeed(2);
-    size_t in(0), out(0);
-    for (size_t i = 0; i < 100; ++i) {
-      auto value = (norm.nextValue() - 30.0) / 5.0;
-      if (std::fabs(value) < 1.0) {
-        ++in;
-      } else {
-        ++out;
-      }
-    }
-#ifdef _WIN32
-    TS_ASSERT_EQUALS(in, 58);
-    TS_ASSERT_EQUALS(out, 42);
-#else
-    TS_ASSERT_LESS_THAN(out, in);
-#endif
-  }
-};
-
-#endif // NORMALDISTRIBUTIONTEST_H_
diff --git a/Framework/Kernel/test/PropertyManagerTest.h b/Framework/Kernel/test/PropertyManagerTest.h
index 926c339d284251f7a6f4096eb8f03c40e4cb876d..f23ad6e6fb32f0fb45129722b39af79c3c1778ff 100644
--- a/Framework/Kernel/test/PropertyManagerTest.h
+++ b/Framework/Kernel/test/PropertyManagerTest.h
@@ -90,12 +90,12 @@ public:
     TS_ASSERT_EQUALS(manager.propertyCount(), 3);
 
     const std::vector<Property *> &props = manager.getProperties();
-    for (auto iter = props.begin(); iter != props.end(); ++iter) {
-      Property *prop = *iter;
+    for (auto iter : props) {
+      Property *prop = iter;
       std::string msg = "Property " + prop->name() +
                         " has not been changed to a FilteredTimeSeries";
       auto filteredProp =
-          dynamic_cast<FilteredTimeSeriesProperty<double> *>(*iter);
+          dynamic_cast<FilteredTimeSeriesProperty<double> *>(iter);
       TSM_ASSERT(msg, filteredProp);
     }
 
@@ -248,7 +248,7 @@ public:
     mgr.declareProperty(
         Mantid::Kernel::make_unique<ArrayProperty<double>>("ArrayProp"));
 
-    std::string jsonString = "{\"ArrayProp\":\"10,12,23\"}";
+    std::string jsonString = R"({"ArrayProp":"10,12,23"})";
     TS_ASSERT_THROWS_NOTHING(mgr.setProperties(jsonString));
     TS_ASSERT_EQUALS(mgr.getPropertyValue("ArrayProp"), "10,12,23");
   }
@@ -581,13 +581,13 @@ public:
     TS_ASSERT_EQUALS(d, 23.4);
     TS_ASSERT_EQUALS(i, 22);
 
-    mgr.setPropertiesWithString("{\"double\": 14.0, \"int\":33}");
+    mgr.setPropertiesWithString(R"({"double": 14.0, "int":33})");
     d = mgr.getProperty("double");
     i = mgr.getProperty("int");
     TS_ASSERT_EQUALS(d, 14.0);
     TS_ASSERT_EQUALS(i, 33);
 
-    mgr.setPropertiesWithString("{\"double\": 12.3 ,\"int\":11}", {"int"});
+    mgr.setPropertiesWithString(R"({"double": 12.3 ,"int":11})", {"int"});
     d = mgr.getProperty("double");
     i = mgr.getProperty("int");
     TS_ASSERT_EQUALS(d, 12.3);
diff --git a/Framework/Kernel/test/PropertyWithValueTest.h b/Framework/Kernel/test/PropertyWithValueTest.h
index 7ed65e3847023c815c1b505b7edbceab401f70e6..6f3d65b5a803244f7a01eee9dd024ef9692453a3 100644
--- a/Framework/Kernel/test/PropertyWithValueTest.h
+++ b/Framework/Kernel/test/PropertyWithValueTest.h
@@ -107,8 +107,8 @@ public:
   the size of the property is 2.
   */
   void testSizeOfVectorOfVectorProperty() {
-    typedef std::vector<int> VecInt;
-    typedef std::vector<VecInt> VecVecInt;
+    using VecInt = std::vector<int>;
+    using VecVecInt = std::vector<VecInt>;
     // Test vector value property.
     VecVecInt v;
     v.push_back(VecInt(1, 0));
@@ -690,9 +690,9 @@ public:
     auto values = property.allowedValues();
     auto possibilities = OptionalBool::strToEmumMap();
     TSM_ASSERT_EQUALS("3 states allowed", possibilities.size(), values.size());
-    for (auto it = values.begin(); it != values.end(); ++it) {
+    for (auto &value : values) {
       TSM_ASSERT("value not a known state",
-                 possibilities.find(*it) != possibilities.end());
+                 possibilities.find(value) != possibilities.end());
     }
   }
 
diff --git a/Framework/Kernel/test/SobolSequenceTest.h b/Framework/Kernel/test/SobolSequenceTest.h
index 0a61b278d64888d561761ffea80a79341db9623c..3abe083aa37b85a76633d350505102bf5e311f80 100644
--- a/Framework/Kernel/test/SobolSequenceTest.h
+++ b/Framework/Kernel/test/SobolSequenceTest.h
@@ -87,10 +87,10 @@ private:
         {0.75, 0.25, 0.75, 0.25, 0.75},
         {0.25, 0.75, 0.25, 0.75, 0.25},
     };
-    for (std::size_t i = 0; i < 3; ++i) {
+    for (auto &expectedValue : expectedValues) {
       const std::vector<double> randPoint = randGen.nextPoint();
       for (std::size_t j = 0; j < 5; ++j) {
-        TS_ASSERT_DELTA(randPoint[j], expectedValues[i][j], 1e-12);
+        TS_ASSERT_DELTA(randPoint[j], expectedValue[j], 1e-12);
       }
     }
   }
diff --git a/Framework/Kernel/test/StringTokenizerTest.h b/Framework/Kernel/test/StringTokenizerTest.h
index 4358bb237572be1a5a448db9d7a866a091452343..6aa074d25fb1a1d5b5e2a91d4f5310937f968b31 100644
--- a/Framework/Kernel/test/StringTokenizerTest.h
+++ b/Framework/Kernel/test/StringTokenizerTest.h
@@ -5,6 +5,7 @@
 #include <random>
 #include <array>
 #include "MantidKernel/StringTokenizer.h"
+#include "MantidKernel/uniform_int_distribution.h"
 
 /**
    \class StringTokenizerTest
@@ -165,9 +166,10 @@ class RandomCharacter {
 public:
   RandomCharacter() {
     const size_t maxIndex = (sizeof(m_characterSet) - 1);
-    m_distribution = std::uniform_int_distribution<unsigned>(0, maxIndex);
-  };
-  char operator()() { return m_characterSet[m_distribution(m_generator)]; };
+    m_distribution =
+        Mantid::Kernel::uniform_int_distribution<unsigned>(0, maxIndex);
+  }
+  char operator()() { return m_characterSet[m_distribution(m_generator)]; }
 
 private:
   std::array<char, 62> m_characterSet{
@@ -177,7 +179,7 @@ private:
        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z'}};
   std::mt19937 m_generator;
-  std::uniform_int_distribution<unsigned> m_distribution;
+  Mantid::Kernel::uniform_int_distribution<unsigned> m_distribution;
 };
 
 std::string randomString(size_t length) {
diff --git a/Framework/Kernel/test/ThreadSchedulerTest.h b/Framework/Kernel/test/ThreadSchedulerTest.h
index 587bb4e5707eab9248a568b6f55f6493b4a613fa..60be77fbe9b3aa5bf2eac3cf20051a22c12335b9 100644
--- a/Framework/Kernel/test/ThreadSchedulerTest.h
+++ b/Framework/Kernel/test/ThreadSchedulerTest.h
@@ -87,8 +87,8 @@ public:
 
     // And ThreadScheduler does not delete popped tasks in this way
     TS_ASSERT_EQUALS(ThreadSchedulerTest_numDestructed, 0);
-    for (size_t i = 0; i < 4; i++) {
-      delete tasks[i];
+    for (auto &task : tasks) {
+      delete task;
     }
   }
 
diff --git a/Framework/Kernel/test/UsageServiceTest.h b/Framework/Kernel/test/UsageServiceTest.h
index fbf3fbf4f1b4c26e44e461280e283e3996ae9488..022d88b7c38e1c3e6a1086a81e9747cd76df5300 100644
--- a/Framework/Kernel/test/UsageServiceTest.h
+++ b/Framework/Kernel/test/UsageServiceTest.h
@@ -101,11 +101,11 @@ public:
     }
 
     auto features = root["features"];
-    for (Json::ArrayIndex i = 0; i < features.size(); i++) {
-      std::string name = features[i]["name"].asString();
-      std::string type = features[i]["type"].asString();
-      bool internal = features[i]["internal"].asBool();
-      size_t count = features[i]["count"].asUInt();
+    for (auto &feature : features) {
+      std::string name = feature["name"].asString();
+      std::string type = feature["type"].asString();
+      bool internal = feature["internal"].asBool();
+      size_t count = feature["count"].asUInt();
 
       bool correct = false;
 
diff --git a/Framework/Kernel/test/VectorHelperTest.h b/Framework/Kernel/test/VectorHelperTest.h
index 416a3bf01e5c42adb228767a99900443ee3650e4..c9cae618898da04822f14631c967caaf28fe2b4e 100644
--- a/Framework/Kernel/test/VectorHelperTest.h
+++ b/Framework/Kernel/test/VectorHelperTest.h
@@ -160,6 +160,22 @@ public:
     TS_ASSERT_EQUALS(axis, expectedAxis);
   }
 
+  void test_CreateAxisFromRebinParams_ThrowsIfSingleParamNoHintsProvided() {
+    const std::vector<double> rbParams = {1.0};
+    std::vector<double> axis;
+    TS_ASSERT_THROWS(VectorHelper::createAxisFromRebinParams(rbParams, axis),
+                     const std::runtime_error)
+  }
+
+  void test_CreateAxisFromRebinParams_xMinXMaxHints() {
+    const std::vector<double> rbParams = {1.0};
+    std::vector<double> axis;
+    TS_ASSERT_THROWS_NOTHING(VectorHelper::createAxisFromRebinParams(
+        rbParams, axis, true, true, -5., 3.))
+    const std::vector<double> expectedAxis = {-5, -4, -3, -2, -1, 0, 1, 2, 3};
+    TS_ASSERT_EQUALS(axis, expectedAxis);
+  }
+
   void test_ConvertToBinBoundary_EmptyInputVector() {
     std::vector<double> bin_centers;
     std::vector<double> bin_edges;
diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h
index d776a84d8e57ff70249312c0a19fb0fd777abf43..c9cb0496b4b23823da4079fc323fcac2d0b5def6 100644
--- a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h
+++ b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h
@@ -6,23 +6,14 @@
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 
-#include <mutex>
-
-namespace Poco {
-namespace Net {
-class TCPServer;
-}
-}
-
 namespace Mantid {
 namespace LiveData {
 /**
     Simulates ISIS histogram DAE. It runs continuously until canceled and
-   listens to port 6789 for
-    ISIS DAE commands.
+    listens to port 6789 for ISIS DAE commands.
 
     Copyright &copy; 2008-9 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
+    National Laboratory & European Spallation Source
 
     This file is part of Mantid.
 
@@ -44,9 +35,6 @@ namespace LiveData {
 */
 class FakeISISEventDAE : public API::Algorithm {
 public:
-  FakeISISEventDAE();
-  ~FakeISISEventDAE() override;
-
   /// Algorithm's name for identification overriding a virtual method
   const std::string name() const override { return "FakeISISEventDAE"; }
   /// Algorithm's version for identification overriding a virtual method
@@ -55,6 +43,9 @@ public:
   const std::string category() const override {
     return "DataHandling\\DataAcquisition";
   }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FakeISISHistoDAE"};
+  }
 
   /// Algorithm's summary
   const std::string summary() const override {
@@ -64,10 +55,6 @@ public:
 private:
   void init() override;
   void exec() override;
-  /// Poco TCP server
-  Poco::Net::TCPServer *m_server;
-  /// Mutex
-  std::mutex m_mutex;
 };
 
 } // namespace LiveData
diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h
index 35c4dff7a37d1421b4e80c36b8e028a83417e7da..84c187739b3ef62cf0f3e7736b2cb1d3ef26d2d4 100644
--- a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h
+++ b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h
@@ -5,30 +5,22 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
-#include <mutex>
-
-namespace Poco {
-namespace Net {
-class TCPServer;
-}
-}
 
 namespace Mantid {
 namespace LiveData {
 /**
     Simulates ISIS histogram DAE. It runs continuously until canceled and
-   listens to port 6789 for
-    ISIS DAE commands.
+    listens to port 6789 for ISIS DAE commands.
 
     Data is generated starting at 10000 microseconds Time of flight, and each
-   bin requested covers 100 microseconds.
+    bin requested covers 100 microseconds.
     The algorithm silently defines three additional spectra with numbers
-   NSpectra+1, NSpectra+2 and NSpectra+3 in a
+    NSpectra+1, NSpectra+2 and NSpectra+3 in a
     different time regime (they have different binning to the rest of the
-   spectra).
+    spectra).
 
     Copyright &copy; 2008-9 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
+    National Laboratory & European Spallation Source
 
     This file is part of Mantid.
 
@@ -50,17 +42,17 @@ namespace LiveData {
 */
 class DLLExport FakeISISHistoDAE : public API::Algorithm {
 public:
-  FakeISISHistoDAE();
-  ~FakeISISHistoDAE() override;
-
   /// Algorithm's name for identification overriding a virtual method
-  const std::string name() const override { return "FakeISISHistoDAE"; };
+  const std::string name() const override { return "FakeISISHistoDAE"; }
   /// Algorithm's version for identification overriding a virtual method
-  int version() const override { return 1; };
+  int version() const override { return 1; }
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
     return "DataHandling\\DataAcquisition";
   }
+  const std::vector<std::string> seeAlso() const override {
+    return {"FakeISISEventDAE"};
+  }
   /// Summary of algorithms purpose
   const std::string summary() const override {
     return "Simulates ISIS histogram DAE.";
@@ -70,10 +62,6 @@ private:
   // Implement abstract Algorithm methods
   void init() override;
   void exec() override;
-  /// Poco TCP server
-  Poco::Net::TCPServer *m_server;
-  /// Mutex
-  std::mutex m_mutex;
 };
 
 } // namespace LiveData
diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h
index acc637fc511afcdca02faddc5ff33314f5461b59..c0cd15cf9b7e8f8e91e330e59951b3af64e12c1a 100644
--- a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h
+++ b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h
@@ -12,7 +12,7 @@
 //----------------------------------------------------------------------
 
 struct idc_info;
-typedef struct idc_info *idc_handle_t;
+using idc_handle_t = struct idc_info *;
 
 namespace Mantid {
 //----------------------------------------------------------------------
diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h
index 64e5871e03767950b36618570f19fe7ac5818b0e..d773d374a82a23d3e0bb528461c6ef68fe77e0d9 100644
--- a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h
+++ b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h
@@ -19,13 +19,13 @@
 const long RECV_TIMEOUT = 30;
 // Sleep time in case we need to wait for the data to become available (in
 // milliseconds)
-const long RECV_WAIT = 1;
+const long RECV_WAIT = 10;
 
 //----------------------------------------------------------------------
 // Forward declarations
 //----------------------------------------------------------------------
 struct idc_info;
-typedef struct idc_info *idc_handle_t;
+using idc_handle_t = struct idc_info *;
 
 namespace Mantid {
 namespace LiveData {
@@ -164,6 +164,8 @@ protected:
   void Receive(T &buffer, const std::string &head, const std::string &msg) {
     long timeout = 0;
     while (m_socket.available() < static_cast<int>(sizeof(buffer))) {
+      if (m_stopThread)
+        return;
       Poco::Thread::sleep(RECV_WAIT);
       timeout += RECV_WAIT;
       if (timeout > RECV_TIMEOUT * 1000)
@@ -190,7 +192,7 @@ protected:
   /// Thread that reads events from the DAE in the background
   Poco::Thread m_thread;
   /// background thread checks this periodically.  If true, the thread exits
-  bool m_stopThread;
+  std::atomic<bool> m_stopThread;
   /// Holds on to any exceptions that were thrown in the background thread so
   /// that we
   /// can re-throw them in the forground thread
diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h
index 0b83329afb84bfc383025bc1df4b4ac6646e3359..6104a95cd4860d77c0d21165cca146242ce0d243 100644
--- a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h
+++ b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h
@@ -35,7 +35,7 @@ namespace LiveData {
 */
 class DLLExport IKafkaBroker {
 public:
-  ~IKafkaBroker() = default;
+  virtual ~IKafkaBroker() = default;
 
   virtual std::unique_ptr<IKafkaStreamSubscriber>
   subscribe(std::vector<std::string> topics,
diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h b/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h
index ef4cd6231eaa2bc398f96f17a50bca35317ac0c4..e9410dced555084aef336391bd13fb4811574417 100644
--- a/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h
+++ b/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h
@@ -1,5 +1,5 @@
-#ifndef MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_
-#define MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_
+#ifndef MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_
+#define MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_
 //----------------------------------------------------------------------
 // Includes
 //----------------------------------------------------------------------
@@ -10,6 +10,11 @@
 //----------------------------------------------------------------------
 
 namespace Mantid {
+
+namespace API {
+class IAlgorithm;
+}
+
 namespace LiveData {
 class KafkaEventStreamDecoder;
 
@@ -38,8 +43,7 @@ class KafkaEventStreamDecoder;
  */
 class DLLExport KafkaEventListener : public API::LiveListener {
 public:
-  KafkaEventListener();
-  /// Destructor. Should handle termination of any socket connections.
+  KafkaEventListener() = default;
   ~KafkaEventListener() override = default;
 
   //----------------------------------------------------------------------
@@ -61,6 +65,7 @@ public:
   void start(
       Types::Core::DateAndTime startTime = Types::Core::DateAndTime()) override;
   boost::shared_ptr<API::Workspace> extractData() override;
+  void setAlgorithm(const Mantid::API::IAlgorithm &callingAlgorithm) override;
 
   //----------------------------------------------------------------------
   // State flags
@@ -71,9 +76,10 @@ public:
 
 private:
   std::unique_ptr<KafkaEventStreamDecoder> m_decoder = nullptr;
+  std::string m_instrumentName;
 };
 
 } // namespace LiveData
 } // namespace Mantid
 
-#endif /*MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_*/
+#endif /*MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_*/
diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
index ea02545c2332d07136cc39012b54a7146086ce1c..652b613e8a57e51aaf36b4f6119a002f249d1865 100644
--- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
+++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
@@ -79,7 +79,7 @@ protected:
   bool rxPacket(const ADARA::VariableStringPkt &pkt) override;
   bool rxPacket(const ADARA::DeviceDescriptorPkt &pkt) override;
   bool rxPacket(const ADARA::AnnotationPkt &pkt) override;
-  // virtual bool rxPacket( const ADARA::RunInfoPkt &pkt);
+  bool rxPacket(const ADARA::RunInfoPkt &pkt) override;
 
 private:
   // Workspace initialization needs to happen in 2 steps.  Part 1 must happen
@@ -180,7 +180,8 @@ private:
 
   // maps <device id, variable id> to variable name
   // (variable names are unique, so we don't need to worry about device names.)
-  typedef std::map<std::pair<unsigned, unsigned>, std::string> NameMapType;
+  using NameMapType =
+      std::map<std::pair<unsigned int, unsigned int>, std::string>;
   NameMapType m_nameMap;
 
   // ---------------------------------------------------------------------------
@@ -195,8 +196,8 @@ private:
 
   // Maps the device ID / variable ID pair to the actual packet.  Using a map
   // means we will only keep one packet (the most recent one) for each variable
-  typedef std::map<std::pair<unsigned, unsigned>,
-                   boost::shared_ptr<ADARA::Packet>> VariableMapType;
+  using VariableMapType = std::map<std::pair<unsigned int, unsigned int>,
+                                   boost::shared_ptr<ADARA::Packet>>;
   VariableMapType m_variableMap;
 
   // Process all the variable value packets stored in m_variableMap
diff --git a/Framework/LiveData/src/ISIS/DAE/idc.h b/Framework/LiveData/src/ISIS/DAE/idc.h
index ba5aee984fc0cbcecbd9d17591a51bc13b1db294..442d560fc16a1019a918d49eefa220cfb0668d28 100644
--- a/Framework/LiveData/src/ISIS/DAE/idc.h
+++ b/Framework/LiveData/src/ISIS/DAE/idc.h
@@ -25,12 +25,12 @@
 * holds information about the DAE connection - defined fully in idc.c
 */
 struct idc_info;
-typedef struct idc_info *idc_handle_t;
+using idc_handle_t = struct idc_info *;
 
 /**
  * prototype for error reporting function passed to IDCsetreportfunc()
  */
-typedef void (*idc_error_report_t)(int status, int code, const char *messsage);
+using idc_error_report_t = void (*)(int, int, const char *);
 
 #ifdef __cplusplus
 #include <cstdint>
diff --git a/Framework/LiveData/src/ISIS/DAE/isisds_command.h b/Framework/LiveData/src/ISIS/DAE/isisds_command.h
index 4a9f25406f4b8558558245f9c47045b537f868a4..145e9493c9327dbd47b43097163c239485e9a096 100644
--- a/Framework/LiveData/src/ISIS/DAE/isisds_command.h
+++ b/Framework/LiveData/src/ISIS/DAE/isisds_command.h
@@ -20,8 +20,7 @@
 #ifndef ISISDS_COMMAND_H
 #define ISISDS_COMMAND_H
 
-typedef void (*isisds_error_report_t)(int status, int code,
-                                      const char *messsage);
+using isisds_error_report_t = void (*)(int, int, const char *);
 
 #define ISISDS_PORT 6789
 
diff --git a/Framework/LiveData/src/ISIS/FakeISISEventDAE.cpp b/Framework/LiveData/src/ISIS/FakeISISEventDAE.cpp
index 4e22d55816a660cb0447323e3be79c1c4abd5420..db3a64f7580d06477f101929878997f96dbe5e4b 100644
--- a/Framework/LiveData/src/ISIS/FakeISISEventDAE.cpp
+++ b/Framework/LiveData/src/ISIS/FakeISISEventDAE.cpp
@@ -7,14 +7,9 @@
 #include "MantidKernel/MersenneTwister.h"
 #include "MantidKernel/Timer.h"
 
+#include <Poco/ActiveResult.h>
 #include <Poco/Net/TCPServer.h>
 #include <Poco/Net/StreamSocket.h>
-#include <Poco/ActiveResult.h>
-#include <Poco/Thread.h>
-
-#include <boost/random/uniform_int.hpp>
-
-#include <numeric>
 
 namespace Mantid {
 namespace LiveData {
@@ -147,17 +142,6 @@ public:
 };
 } // end anonymous
 
-/// (Empty) Constructor
-FakeISISEventDAE::FakeISISEventDAE() : m_server(nullptr) {}
-
-/// Destructor
-FakeISISEventDAE::~FakeISISEventDAE() {
-  if (m_server) {
-    m_server->stop();
-    delete m_server;
-  }
-}
-
 /**
 * Declare the algorithm properties
 */
@@ -198,19 +182,18 @@ void FakeISISEventDAE::exec() {
   histoDAE->setProperty("NPeriods", nper);
   histoDAE->setProperty("NSpectra", nspec);
   histoDAE->setProperty("Port", port + 1);
-  Poco::ActiveResult<bool> histoDAEHandle = histoDAE->executeAsync();
+  auto histoDAEHandle = histoDAE->executeAsync();
 
   auto prog = boost::make_shared<Progress>(this, 0.0, 1.0, 100);
   prog->setNotifyStep(0);
   prog->report(0, "Waiting for client");
-  std::lock_guard<std::mutex> lock(m_mutex);
   Poco::Net::ServerSocket socket(static_cast<Poco::UInt16>(port));
   socket.listen();
-  m_server = new Poco::Net::TCPServer(
+  Poco::Net::TCPServer server(
       TestServerConnectionFactory::Ptr(
           new TestServerConnectionFactory(nper, nspec, rate, nevents, prog)),
       socket);
-  m_server->start();
+  server.start();
   // Keep going until you get cancelled
   while (true) {
     try {
@@ -223,19 +206,12 @@ void FakeISISEventDAE::exec() {
     // Sleep for 50 msec
     Poco::Thread::sleep(50);
   }
+  // It's most likely that we got here from a cancel request
+  // so calling prog->report after this point
+  // will generate another CancelException
   histoDAE->cancel();
   histoDAEHandle.wait();
-  if (m_server) {
-    m_server->stop();
-    m_server = nullptr;
-  }
   socket.close();
-
-  prog->report(90, "Closing ISIS event DAE");
-  histoDAE->setLogging(false); // hide the final closedown message to the log it
-                               // is confusing as it is a child alg.
-  histoDAE->cancel();
-  histoDAEHandle.wait();
 }
 
 } // namespace LiveData
diff --git a/Framework/LiveData/src/ISIS/FakeISISHistoDAE.cpp b/Framework/LiveData/src/ISIS/FakeISISHistoDAE.cpp
index bb9b11d2eeaa89eb54ca98966863c3bf395d31c9..bea46be21c0ad16c5abbae6e96493b28a7a01bb6 100644
--- a/Framework/LiveData/src/ISIS/FakeISISHistoDAE.cpp
+++ b/Framework/LiveData/src/ISIS/FakeISISHistoDAE.cpp
@@ -2,11 +2,9 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidLiveData/ISIS/FakeISISHistoDAE.h"
-#include <numeric>
 
 #include <Poco/Net/TCPServer.h>
 #include <Poco/Net/StreamSocket.h>
-#include <Poco/Thread.h>
 
 namespace Mantid {
 namespace LiveData {
@@ -314,17 +312,6 @@ public:
 using namespace Kernel;
 using namespace API;
 
-/// (Empty) Constructor
-FakeISISHistoDAE::FakeISISHistoDAE() : m_server(nullptr) {}
-
-/// Destructor
-FakeISISHistoDAE::~FakeISISHistoDAE() {
-  if (m_server) {
-    m_server->stop();
-    delete m_server;
-  }
-}
-
 /**
  * Declare the algorithm properties
  */
@@ -352,16 +339,15 @@ void FakeISISHistoDAE::exec() {
   int nbins = getProperty("NBins");
   int port = getProperty("Port");
 
-  std::lock_guard<std::mutex> lock(m_mutex);
   Poco::Net::ServerSocket socket(static_cast<Poco::UInt16>(port));
   socket.listen();
 
-  m_server = new Poco::Net::TCPServer(
+  Poco::Net::TCPServer server(
       TestServerConnectionFactory::Ptr(
           new TestServerConnectionFactory(nper, nspec, nbins)),
       socket);
-  m_server->start();
-  // Keep going until you get cancelled
+  server.start();
+  // Keep going until you get cancelled or an error occurs
   while (true) {
     try {
       // Exit if the user presses cancel
@@ -374,10 +360,10 @@ void FakeISISHistoDAE::exec() {
     // Sleep for 50 msec
     Poco::Thread::sleep(50);
   }
-  if (m_server) {
-    m_server->stop();
-    m_server = nullptr;
-  }
+  // It's most likely that we got here from a cancel request
+  // so calling prog->report after this point
+  // will generate another CancelException
+  server.stop();
   socket.close();
 }
 
diff --git a/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp b/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
index ef62b701c44ff04e8463b0294632f56dea03f25f..53c620436f3292a33d09d648cac9145a94bcde34 100644
--- a/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
+++ b/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
@@ -235,6 +235,8 @@ void ISISLiveEventDataListener::run() {
       // get the header with the type of the packet
       Receive(events.head, "Events header",
               "Corrupt stream - you should reconnect.");
+      if (m_stopThread)
+        break;
       if (!(events.head.type == TCPStreamEventHeader::Neutron)) {
         // don't know what to do with it - stop
         throw std::runtime_error("Unknown packet type.");
@@ -244,6 +246,8 @@ void ISISLiveEventDataListener::run() {
       // get the header with the sream size
       Receive(events.head_n, "Neutrons header",
               "Corrupt stream - you should reconnect.");
+      if (m_stopThread)
+        break;
       CollectJunk(events.head_n);
 
       // absolute pulse (frame) time
@@ -282,8 +286,7 @@ void ISISLiveEventDataListener::run() {
       saveEvents(events.data, pulseTime, events.head_n.period);
     }
 
-  } catch (std::runtime_error &
-               e) { // exception handler for generic runtime exceptions
+  } catch (std::runtime_error &e) {
 
     g_log.error() << "Caught a runtime exception.\nException message: "
                   << e.what() << '\n';
@@ -291,8 +294,8 @@ void ISISLiveEventDataListener::run() {
 
     m_backgroundException = boost::make_shared<std::runtime_error>(e);
 
-  } catch (std::invalid_argument &
-               e) { // TimeSeriesProperty (and possibly some other things) can
+  } catch (std::invalid_argument &e) {
+    // TimeSeriesProperty (and possibly some other things) can
     // can throw these errors
     g_log.error()
         << "Caught an invalid argument exception.\nException message: "
@@ -303,7 +306,7 @@ void ISISLiveEventDataListener::run() {
     newMsg += e.what();
     m_backgroundException = boost::make_shared<std::runtime_error>(newMsg);
 
-  } catch (...) { // Default exception handler
+  } catch (...) {
     g_log.error() << "Uncaught exception in ISISLiveEventDataListener network "
                      "read thread.\n";
     m_isConnected = false;
diff --git a/Framework/LiveData/src/Kafka/KafkaEventListener.cpp b/Framework/LiveData/src/Kafka/KafkaEventListener.cpp
index 78fdb58efce7b9ddbeb08cb6469ab5001aa41dff..567a2a883801c81139820eb895db3351835116da 100644
--- a/Framework/LiveData/src/Kafka/KafkaEventListener.cpp
+++ b/Framework/LiveData/src/Kafka/KafkaEventListener.cpp
@@ -1,7 +1,8 @@
 #include "MantidLiveData/Kafka/KafkaEventListener.h"
+#include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/LiveListenerFactory.h"
-#include "MantidLiveData/Kafka/KafkaEventStreamDecoder.h"
 #include "MantidLiveData/Kafka/KafkaBroker.h"
+#include "MantidLiveData/Kafka/KafkaEventStreamDecoder.h"
 #include "MantidLiveData/Kafka/KafkaTopicSubscriber.h"
 
 namespace {
@@ -13,21 +14,32 @@ namespace LiveData {
 
 DECLARE_LISTENER(KafkaEventListener)
 
-KafkaEventListener::KafkaEventListener() {
-  declareProperty("InstrumentName", "");
+void KafkaEventListener::setAlgorithm(
+    const Mantid::API::IAlgorithm &callingAlgorithm) {
+  this->updatePropertyValues(callingAlgorithm);
+  // Get the instrument name from StartLiveData so we can sub to correct topics
+  if (callingAlgorithm.existsProperty("Instrument")) {
+    m_instrumentName = callingAlgorithm.getPropertyValue("Instrument");
+  } else {
+    g_log.error("KafkaEventListener requires Instrument property to be set in "
+                "calling algorithm");
+  }
 }
 
 /// @copydoc ILiveListener::connect
 bool KafkaEventListener::connect(const Poco::Net::SocketAddress &address) {
+  if (m_instrumentName.empty()) {
+    g_log.error(
+        "KafkaEventListener::connect requires a non-empty instrument name");
+  }
   auto broker = std::make_shared<KafkaBroker>(address.toString());
   try {
-    std::string instrumentName = getProperty("InstrumentName");
-    const std::string eventTopic(instrumentName +
+    const std::string eventTopic(m_instrumentName +
                                  KafkaTopicSubscriber::EVENT_TOPIC_SUFFIX),
-        runInfoTopic(instrumentName + KafkaTopicSubscriber::RUN_TOPIC_SUFFIX),
-        spDetInfoTopic(instrumentName +
+        runInfoTopic(m_instrumentName + KafkaTopicSubscriber::RUN_TOPIC_SUFFIX),
+        spDetInfoTopic(m_instrumentName +
                        KafkaTopicSubscriber::DET_SPEC_TOPIC_SUFFIX),
-        sampleEnvTopic(instrumentName +
+        sampleEnvTopic(m_instrumentName +
                        KafkaTopicSubscriber::SAMPLE_ENV_TOPIC_SUFFIX);
     m_decoder = Kernel::make_unique<KafkaEventStreamDecoder>(
         broker, eventTopic, runInfoTopic, spDetInfoTopic, sampleEnvTopic);
diff --git a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
index 5d4de83d092a0a595a3c5c3c1a631786fb98c9c1..1de3cca7717c31050de637311c035331d08e1dc4 100644
--- a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
+++ b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp
@@ -183,7 +183,7 @@ bool KafkaEventStreamDecoder::hasReachedEndOfRun() noexcept {
  */
 API::Workspace_sptr KafkaEventStreamDecoder::extractData() {
   if (m_exception) {
-    throw * m_exception;
+    throw std::runtime_error(*m_exception);
   }
 
   m_extractWaiting = true;
@@ -507,22 +507,21 @@ void KafkaEventStreamDecoder::eventDataFromMessage(const std::string &buffer) {
   const auto &detData = *(eventMsg->detector_id());
   auto nEvents = tofData.size();
 
-  if (eventMsg->facility_specific_data_type() != FacilityData_ISISData) {
-    throw std::runtime_error("KafkaEventStreamDecoder only knows how to "
-                             "deal with ISIS facility specific data");
-  }
-  auto ISISMsg =
-      static_cast<const ISISData *>(eventMsg->facility_specific_data());
-
+  DataObjects::EventWorkspace_sptr periodBuffer;
   std::lock_guard<std::mutex> lock(m_mutex);
-  auto &periodBuffer =
-      *m_localEvents[static_cast<size_t>(ISISMsg->period_number())];
-  auto &mutableRunInfo = periodBuffer.mutableRun();
-  mutableRunInfo.getTimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY)
-      ->addValue(pulseTime, ISISMsg->proton_charge());
+  if (eventMsg->facility_specific_data_type() == FacilityData_ISISData) {
+    auto ISISMsg =
+        static_cast<const ISISData *>(eventMsg->facility_specific_data());
+    periodBuffer = m_localEvents[static_cast<size_t>(ISISMsg->period_number())];
+    auto &mutableRunInfo = periodBuffer->mutableRun();
+    mutableRunInfo.getTimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY)
+        ->addValue(pulseTime, ISISMsg->proton_charge());
+  } else {
+    periodBuffer = m_localEvents[0];
+  }
   for (decltype(nEvents) i = 0; i < nEvents; ++i) {
-    auto &spectrum =
-        periodBuffer.getSpectrum(m_specToIdx[static_cast<int32_t>(detData[i])]);
+    auto &spectrum = periodBuffer->getSpectrum(
+        m_specToIdx[static_cast<int32_t>(detData[i])]);
     spectrum.addEventQuickly(TofEvent(static_cast<double>(tofData[i]) *
                                           1e-3, // nanoseconds to microseconds
                                       pulseTime));
diff --git a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h
index 21c1c3cb91c3382c6809fafc16b31153be09c71e..6ce57b8f32bbb833fa054492dd1d4c15b2f3f6a4 100644
--- a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h
+++ b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h
@@ -100,20 +100,19 @@ namespace flatbuffers {
 // Our default offset / size type, 32bit on purpose on 64bit systems.
 // Also, using a consistent offset type maintains compatibility of serialized
 // offset values between 32bit and 64bit systems.
-typedef uint32_t uoffset_t;
+using uoffset_t = uint32_t;
 
 // Signed offsets for references that can go in both directions.
-typedef int32_t soffset_t;
+using soffset_t = int32_t;
 
 // Offset/index used in v-tables, can be changed to uint8_t in
 // format forks to save a bit of space if desired.
-typedef uint16_t voffset_t;
+using voffset_t = uint16_t;
 
-typedef uintmax_t largest_scalar_t;
+using largest_scalar_t = uintmax_t;
 
 // Pointer to relinquished memory.
-typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>>
-          unique_ptr_t;
+using unique_ptr_t = std::unique_ptr<uint8_t, std::function<void (uint8_t *)> >;
 
 // Wrapper for uoffset_t to allow safe template specialization.
 template<typename T> struct Offset {
@@ -195,14 +194,14 @@ template<typename T> size_t AlignOf() {
 // The typedef is for the convenience of callers of this function
 // (avoiding the need for a trailing return decltype)
 template<typename T> struct IndirectHelper {
-  typedef T return_type;
+  using return_type = T;
   static const size_t element_stride = sizeof(T);
   static return_type Read(const uint8_t *p, uoffset_t i) {
     return EndianScalar((reinterpret_cast<const T *>(p))[i]);
   }
 };
 template<typename T> struct IndirectHelper<Offset<T>> {
-  typedef const T *return_type;
+  using return_type = const T *;
   static const size_t element_stride = sizeof(uoffset_t);
   static return_type Read(const uint8_t *p, uoffset_t i) {
     p += i * sizeof(uoffset_t);
@@ -210,7 +209,7 @@ template<typename T> struct IndirectHelper<Offset<T>> {
   }
 };
 template<typename T> struct IndirectHelper<const T *> {
-  typedef const T *return_type;
+  using return_type = const T *;
   static const size_t element_stride = sizeof(T);
   static return_type Read(const uint8_t *p, uoffset_t i) {
     return reinterpret_cast<const T *>(p + i * sizeof(T));
@@ -226,10 +225,7 @@ struct VectorIterator : public
   const typename IndirectHelper<T>::return_type,
   typename IndirectHelper<T>::return_type > ::type, uoffset_t > {
 
-  typedef std::iterator<std::input_iterator_tag,
-    typename std::conditional<bConst,
-    const typename IndirectHelper<T>::return_type,
-    typename IndirectHelper<T>::return_type>::type, uoffset_t> super_type;
+  using super_type = std::iterator<std::input_iterator_tag, typename std::conditional<bConst, const typename IndirectHelper<T>::return_type, typename IndirectHelper<T>::return_type>::type, uoffset_t>;
 
 public:
   VectorIterator(const uint8_t *data, uoffset_t i) :
@@ -286,15 +282,15 @@ private:
 // Vector::data() assumes the vector elements start after the length field.
 template<typename T> class Vector {
 public:
-  typedef VectorIterator<T, false> iterator;
-  typedef VectorIterator<T, true> const_iterator;
+  using iterator = VectorIterator<T, false>;
+  using const_iterator = VectorIterator<T, true>;
 
   uoffset_t size() const { return EndianScalar(length_); }
 
   // Deprecated: use size(). Here for backwards compatibility.
   uoffset_t Length() const { return size(); }
 
-  typedef typename IndirectHelper<T>::return_type return_type;
+  using return_type = typename IndirectHelper<T>::return_type;
 
   return_type Get(uoffset_t i) const {
     assert(i < size());
@@ -761,11 +757,11 @@ FLATBUFFERS_FINAL_CLASS
     auto vt_use = GetSize();
     // See if we already have generated a vtable with this exact same
     // layout before. If so, make it point to the old one, remove this one.
-    for (auto it = vtables_.begin(); it != vtables_.end(); ++it) {
-      auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*it));
+    for (unsigned int & vtable : vtables_) {
+      auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(vtable));
       auto vt2_size = *vt2;
       if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue;
-      vt_use = *it;
+      vt_use = vtable;
       buf_.pop(GetSize() - vtableoffsetloc);
       break;
     }
diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp
index a5d5c7967d0a757db18a91bcfbe50f3633ca224f..6053943d2a1c83a258b435ae49bdb3e3b9862fb1 100644
--- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp
+++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp
@@ -50,6 +50,10 @@ const std::string PAUSE_PROPERTY("pause");
 const std::string SCAN_PROPERTY("scan_index");
 const std::string PROTON_CHARGE_PROPERTY("proton_charge");
 
+// These are names for some string properties (not time series)
+const std::string RUN_TITLE_PROPERTY("run_title");
+const std::string EXPERIMENT_ID_PROPERTY("experiment_identifier");
+
 // Helper function to get a DateAndTime value from an ADARA packet header
 Mantid::Types::Core::DateAndTime
 timeFromPacket(const ADARA::PacketHeader &hdr) {
@@ -740,9 +744,8 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::RunStatusPkt &pkt) {
     }
 
   } else if (pkt.status() == ADARA::RunStatus::END_RUN) {
-    // Run has ended:  update m_status and set the flag to stop parsing network
-    // packets.  (see comments below for why)
-
+    // Run has ended:  update m_status, set the end time and set the flag
+    // to stop parsing network packets.  (see comments below for why)
     if ((m_status != Running) && (m_status != BeginRun)) {
       // Previous status should have been Running or BeginRun.  Spit out a
       // warning if it's not.  (If it's BeginRun, that's fine.  It just means
@@ -752,6 +755,10 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::RunStatusPkt &pkt) {
     }
     m_status = EndRun;
 
+    // Add the run_end property
+    m_eventBuffer->mutableRun().addProperty(
+        "run_end", timeFromPacket(pkt).toISO8601String());
+
     // Set the flag to make us stop reading from the network.
     // Stopping network reads solves a number of problems:
     // 1) We don't need to manage a second buffer in order to keep the events
@@ -1008,8 +1015,7 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::DeviceDescriptorPkt &pkt) {
 
   // Find the process_variables element
   // Note: for now, I'm ignoring the 'device_name' & 'enumeration' elements
-  // because I don't
-  // think I need them
+  // because I don't think I need them
 
   const Poco::XML::Node *node = deviceNode->firstChild();
   while (node && node->nodeName() != "process_variables") {
@@ -1099,18 +1105,15 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::DeviceDescriptorPkt &pkt) {
               prop->setUnits(pvUnits);
             }
             {
-              // Note: it's possible for us receive device descriptor packets in
-              // the middle
-              // of a run (after the call to initWorkspacePart2), so we really
-              // do need to
-              // the lock the mutex here.
+              // Note: it's possible for us receive device descriptor packets
+              // in the middle of a run (after the call to initWorkspacePart2),
+              // so we really do need to the lock the mutex here.
               std::lock_guard<std::mutex> scopedLock(m_mutex);
               m_eventBuffer->mutableRun().addLogData(prop);
             }
 
             // Add the pv id, device id and pv name to the name map so we can
-            // find the
-            // name when we process the variable value packets
+            // find the name when we process the variable value packets
             m_nameMap[std::make_pair(pkt.devId(), pvIdNum)] = pvName;
           }
         }
@@ -1193,6 +1196,97 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::AnnotationPkt &pkt) {
   return false;
 }
 
+/// Parse a Run Information packet
+
+/// Overrides the default function defined in ADARA::Parser and processes
+/// data from ADARA::RunInfoPkt packets.  Specifically, it looks for the
+/// proposal id and run title and stores those values in properties in the
+/// workspace.
+/// @param pkt The packet to be parsed
+/// @return Returns false if there were no problems.  Returns true if there
+/// was an error and packet parsing should be interrupted
+bool SNSLiveEventDataListener::rxPacket(const ADARA::RunInfoPkt &pkt) {
+
+  // RunInfoPkts are mostly just blocks of XML.
+  Poco::XML::DOMParser parser;
+  Poco::AutoPtr<Poco::XML::Document> doc = parser.parseString(pkt.info());
+  const Poco::XML::Node *runInfoNode = doc->firstChild();
+
+  // The root of the XML should be "runinfo".
+  while (runInfoNode && runInfoNode->nodeName() != "runinfo") {
+    runInfoNode = runInfoNode->nextSibling();
+  }
+
+  if (!runInfoNode) {
+    g_log.error("Run info packet did not contain a 'runinfo' element!!  "
+                "This should never happen!");
+    return false;
+  }
+
+  // The two elements we're looking for (proposal_id and run_title) should
+  // be children of the runInfoNode.  (Note that run_number is also in there,
+  // but we already get that from the RunStatusPkt.)
+  std::string proposalID;
+  std::string runTitle;
+  const Poco::XML::Node *node = runInfoNode->firstChild();
+  while (node) {
+    // iterate through each individual variable...
+    if (node->nodeName() == "proposal_id") {
+      const Poco::XML::Node *textElement = node->firstChild();
+      if (textElement) {
+        proposalID = textElement->nodeValue();
+      }
+    } else if (node->nodeName() == "run_title") {
+      const Poco::XML::Node *textElement = node->firstChild();
+      if (textElement) {
+        runTitle = textElement->nodeValue();
+      }
+    }
+
+    // If we've got everything we need, we can break out of the while loop
+    if (proposalID.length() && runTitle.length()) {
+      break;
+    }
+
+    node = node->nextSibling();
+  }
+
+  if (proposalID.length()) {
+    Property *prop =
+        m_eventBuffer->mutableRun().getProperty(EXPERIMENT_ID_PROPERTY);
+
+    // Sanity check: We're likely to get multiple RunInfo packets in a
+    // run, but the values shouldn't change mid-run...
+    std::string prevPropVal = prop->value();
+    if (prevPropVal.length() && prevPropVal != proposalID) {
+      g_log.error("Proposal ID in the current run info packet has changed!  "
+                  "This shouldn't happen!  (Keeping new ID value.)");
+    }
+    prop->setValue(proposalID);
+  } else {
+    g_log.warning("Run info packet did not contain a proposal ID.  "
+                  "Property will be empty.");
+  }
+
+  if (runTitle.length()) {
+    Property *prop =
+        m_eventBuffer->mutableRun().getProperty(RUN_TITLE_PROPERTY);
+
+    // Sanity check
+    std::string prevPropVal = prop->value();
+    if (prevPropVal.length() && prevPropVal != runTitle) {
+      g_log.error("The run title in the current run info packet has changed!"
+                  "  This shouldn't happen!  (Keeping new title value.)");
+    }
+    prop->setValue(runTitle);
+  } else {
+    g_log.warning("Run info packet did not contain a run title.  "
+                  "Property will be empty.");
+  }
+
+  return false;
+}
+
 /// First part of the workspace initialization
 
 /// Performs various initialization steps that can (and, in some
@@ -1204,10 +1298,8 @@ void SNSLiveEventDataListener::initWorkspacePart1() {
   // down in initWorkspacePart2() when we load the instrument definition.
 
   // We also know we'll need 3 time series properties on the workspace.  Create
-  // them
-  // now. (We may end up adding values to the pause and scan properties before
-  // we
-  // can call initWorkspacePart2().)
+  // them now. (We may end up adding values to the pause and scan properties
+  // before we can call initWorkspacePart2().)
   Property *prop = new TimeSeriesProperty<int>(PAUSE_PROPERTY);
   m_eventBuffer->mutableRun().addLogData(prop);
   prop = new TimeSeriesProperty<int>(SCAN_PROPERTY);
@@ -1215,6 +1307,12 @@ void SNSLiveEventDataListener::initWorkspacePart1() {
   prop = new TimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY);
   prop->setUnits("picoCoulomb");
   m_eventBuffer->mutableRun().addLogData(prop);
+
+  // Same for a couple of other properties (that are not time series)
+  prop = new PropertyWithValue<std::string>(RUN_TITLE_PROPERTY, "");
+  m_eventBuffer->mutableRun().addLogData(prop);
+  prop = new PropertyWithValue<std::string>(EXPERIMENT_ID_PROPERTY, "");
+  m_eventBuffer->mutableRun().addLogData(prop);
 }
 
 /// Second part of the workspace initialization
@@ -1236,8 +1334,8 @@ void SNSLiveEventDataListener::initWorkspacePart2() {
 
   loadInst->execute();
 
-  m_requiredLogs.clear(); // Clear the list.  If we have to initialize the
-                          // workspace again,
+  m_requiredLogs.clear();
+  // Clear the list.  If we have to initialize the workspace again,
   // (at the start of another run, for example), the list will be
   // repopulated when we receive the next geometry packet.
 
@@ -1258,10 +1356,9 @@ void SNSLiveEventDataListener::initWorkspacePart2() {
       true /* bool throwIfMultipleDets */);
 
   // We always want to have at least one value for the the scan index time
-  // series.  We may have
-  // already gotten a scan start packet by the time we get here and therefor
-  // don't need to do
-  // anything.  If not, we need to put a 0 into the time series.
+  // series.  We may have already gotten a scan start packet by the time we
+  // get here and therefor don't need to do anything.  If not, we need to put
+  // a 0 into the time series.
   if (m_eventBuffer->mutableRun()
           .getTimeSeriesProperty<int>(SCAN_PROPERTY)
           ->size() == 0) {
@@ -1297,8 +1394,7 @@ void SNSLiveEventDataListener::initMonitorWorkspace() {
 // NOTE: This function does not lock the mutex!  The calling function must
 // ensure that m_eventBuffer won't change while the function runs (either by
 // locking the mutex, or by the simple fact of never calling it once the
-// workspace
-// has been initialized...)
+// workspace has been initialized...)
 bool SNSLiveEventDataListener::haveRequiredLogs() {
   bool allFound = true;
   Run &run = m_eventBuffer->mutableRun();
diff --git a/Framework/LiveData/test/KafkaEventStreamDecoderTest.h b/Framework/LiveData/test/KafkaEventStreamDecoderTest.h
index a7f1e0e423de383241c072f1f2f194e194019c7b..6a83ccdd50fcf8815e054f1efd6ba00631a2533f 100644
--- a/Framework/LiveData/test/KafkaEventStreamDecoderTest.h
+++ b/Framework/LiveData/test/KafkaEventStreamDecoderTest.h
@@ -54,7 +54,7 @@ public:
   //----------------------------------------------------------------------------
   void test_Single_Period_Event_Stream() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
     using Mantid::API::Workspace_sptr;
     using Mantid::DataObjects::EventWorkspace;
     using namespace Mantid::LiveData;
@@ -92,7 +92,7 @@ public:
 
   void test_Multiple_Period_Event_Stream() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
     using Mantid::API::Workspace_sptr;
     using Mantid::API::WorkspaceGroup;
     using Mantid::DataObjects::EventWorkspace;
@@ -134,7 +134,7 @@ public:
 
   void test_End_Of_Run_Reported_After_Run_Stop_Reached() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
     using Mantid::API::Workspace_sptr;
     using Mantid::DataObjects::EventWorkspace;
     using namespace Mantid::LiveData;
@@ -173,7 +173,7 @@ public:
   void
   test_Get_All_Run_Events_When_Run_Stop_Message_Received_Before_Last_Event_Message() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
     using Mantid::API::Workspace_sptr;
     using Mantid::DataObjects::EventWorkspace;
     using namespace Mantid::LiveData;
@@ -211,7 +211,7 @@ public:
 
   void test_Sample_Log_From_Event_Stream() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
     using Mantid::API::Workspace_sptr;
     using Mantid::DataObjects::EventWorkspace;
     using namespace Mantid::LiveData;
@@ -244,7 +244,7 @@ public:
 
   void test_Empty_Event_Stream_Waits() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
 
     auto mockBroker = std::make_shared<MockKafkaBroker>();
     EXPECT_CALL(*mockBroker, subscribe_(_, _))
@@ -260,12 +260,44 @@ public:
     TS_ASSERT(!decoder->isCapturing());
   }
 
+  void
+  test_No_Exception_When_Event_Message_Without_Facility_Data_Is_Processed() {
+    using namespace ::testing;
+    using namespace KafkaTesting;
+    using Mantid::API::Workspace_sptr;
+    using Mantid::DataObjects::EventWorkspace;
+
+    auto mockBroker = std::make_shared<MockKafkaBroker>();
+    EXPECT_CALL(*mockBroker, subscribe_(_, _))
+        .Times(Exactly(3))
+        .WillOnce(Return(new FakeEventSubscriber))
+        .WillOnce(Return(new FakeRunInfoStreamSubscriber(1)))
+        .WillOnce(Return(new FakeISISSpDetStreamSubscriber));
+    auto decoder = createTestDecoder(mockBroker);
+    startCapturing(*decoder, 2);
+    Workspace_sptr workspace;
+    TS_ASSERT_THROWS_NOTHING(workspace = decoder->extractData());
+    TS_ASSERT_THROWS_NOTHING(decoder->stopCapture());
+    TS_ASSERT(!decoder->isCapturing());
+
+    // Check we did process the event message and extract the events
+    TSM_ASSERT("Expected non-null workspace pointer from extractData()",
+               workspace);
+    auto eventWksp = boost::dynamic_pointer_cast<EventWorkspace>(workspace);
+    TSM_ASSERT(
+        "Expected an EventWorkspace from extractData(). Found something else",
+        eventWksp);
+
+    TSM_ASSERT_EQUALS("Expected 3 events from the event message", 3,
+                      eventWksp->getNumberEvents());
+  }
+
   //----------------------------------------------------------------------------
   // Failure tests
   //----------------------------------------------------------------------------
   void test_Error_In_Stream_Extraction_Throws_Error_On_ExtractData() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
 
     auto mockBroker = std::make_shared<MockKafkaBroker>();
     EXPECT_CALL(*mockBroker, subscribe_(_, _))
@@ -283,7 +315,7 @@ public:
 
   void test_Empty_SpDet_Stream_Throws_Error_On_ExtractData() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
 
     auto mockBroker = std::make_shared<MockKafkaBroker>();
     EXPECT_CALL(*mockBroker, subscribe_(_, _))
@@ -301,7 +333,7 @@ public:
 
   void test_Empty_RunInfo_Stream_Throws_Error_On_ExtractData() {
     using namespace ::testing;
-    using namespace ISISKafkaTesting;
+    using namespace KafkaTesting;
 
     auto mockBroker = std::make_shared<MockKafkaBroker>();
     EXPECT_CALL(*mockBroker, subscribe_(_, _))
diff --git a/Framework/LiveData/test/KafkaTesting.h b/Framework/LiveData/test/KafkaTesting.h
index b8a45780121c74151bbe6263c0e86a4bcf070f2c..01e1d6b342b66878188c23b973e0220b54a98af9 100644
--- a/Framework/LiveData/test/KafkaTesting.h
+++ b/Framework/LiveData/test/KafkaTesting.h
@@ -18,7 +18,7 @@ GCC_DIAG_ON(conversion)
 
 #include <ctime>
 
-namespace ISISKafkaTesting {
+namespace KafkaTesting {
 
 // -----------------------------------------------------------------------------
 // Mock broker to inject fake subscribers
@@ -122,7 +122,7 @@ public:
   }
 };
 
-void fakeReceiveAnEventMessage(std::string *buffer, int32_t nextPeriod) {
+void fakeReceiveAnISISEventMessage(std::string *buffer, int32_t nextPeriod) {
   flatbuffers::FlatBufferBuilder builder;
   std::vector<uint32_t> spec = {5, 4, 3, 2, 1, 2};
   std::vector<uint32_t> tof = {11000, 10000, 9000, 8000, 7000, 6000};
@@ -143,6 +143,22 @@ void fakeReceiveAnEventMessage(std::string *buffer, int32_t nextPeriod) {
                  builder.GetSize());
 }
 
+void fakeReceiveAnEventMessage(std::string *buffer) {
+  flatbuffers::FlatBufferBuilder builder;
+  std::vector<uint32_t> spec = {5, 4, 3};
+  std::vector<uint32_t> tof = {11000, 10000, 9000};
+  uint64_t frameTime = 1;
+
+  auto messageFlatbuf = CreateEventMessage(
+      builder, builder.CreateString("KafkaTesting"), 0, frameTime,
+      builder.CreateVector(tof), builder.CreateVector(spec));
+  FinishEventMessageBuffer(builder, messageFlatbuf);
+
+  // Copy to provided buffer
+  buffer->assign(reinterpret_cast<const char *>(builder.GetBufferPointer()),
+                 builder.GetSize());
+}
+
 void fakeReceiveASampleEnvMessage(std::string *buffer) {
   flatbuffers::FlatBufferBuilder builder;
   // Sample environment log
@@ -206,7 +222,7 @@ public:
                       std::string &topic) override {
     assert(message);
 
-    fakeReceiveAnEventMessage(message, m_nextPeriod);
+    fakeReceiveAnISISEventMessage(message, m_nextPeriod);
     m_nextPeriod = ((m_nextPeriod + 1) % m_nperiods);
 
     UNUSED_ARG(offset);
@@ -236,6 +252,58 @@ private:
   int32_t m_nextPeriod;
 };
 
+// ---------------------------------------------------------------------------------------
+// Fake non-institution-specific event stream to provide event and sample
+// environment data
+// ---------------------------------------------------------------------------------------
+class FakeEventSubscriber : public Mantid::LiveData::IKafkaStreamSubscriber {
+public:
+  void subscribe() override {}
+  void subscribe(int64_t offset) override { UNUSED_ARG(offset) }
+  void consumeMessage(std::string *message, int64_t &offset, int32_t &partition,
+                      std::string &topic) override {
+    assert(message);
+
+    switch (m_nextOffset) {
+    case 0:
+      fakeReceiveARunStartMessage(message, 1000, "2016-08-31T12:07:42",
+                                  "HRPDTEST", 1);
+      break;
+    case 2:
+      fakeReceiveARunStopMessage(message, m_stopTime);
+      break;
+    default:
+      fakeReceiveAnEventMessage(message);
+    }
+    m_nextOffset++;
+
+    UNUSED_ARG(offset);
+    UNUSED_ARG(partition);
+    UNUSED_ARG(topic);
+  }
+  std::unordered_map<std::string, std::vector<int64_t>>
+  getOffsetsForTimestamp(int64_t timestamp) override {
+    UNUSED_ARG(timestamp);
+    return {std::pair<std::string, std::vector<int64_t>>(m_topicName, {1})};
+  }
+  std::unordered_map<std::string, std::vector<int64_t>>
+  getCurrentOffsets() override {
+    std::unordered_map<std::string, std::vector<int64_t>> offsets;
+    return {std::pair<std::string, std::vector<int64_t>>(m_topicName, {1})};
+  }
+  void seek(const std::string &topic, uint32_t partition,
+            int64_t offset) override {
+    UNUSED_ARG(topic);
+    UNUSED_ARG(partition);
+    UNUSED_ARG(offset);
+  }
+
+private:
+  std::string m_topicName = "topic_name";
+  int m_nextOffset = 0;
+  std::string m_stopTime = "2016-08-31T12:07:52";
+};
+
 // -----------------------------------------------------------------------------
 // Fake event stream to provide sample environment data
 // -----------------------------------------------------------------------------
@@ -354,7 +422,7 @@ public:
                                   m_nperiods);
       break;
     default:
-      fakeReceiveAnEventMessage(buffer, 0);
+      fakeReceiveAnISISEventMessage(buffer, 0);
     }
     topic = "topic_name";
     offset = m_nextOffset;
@@ -441,6 +509,6 @@ private:
   // These match the detector numbers in HRPDTEST_Definition.xml
   std::vector<int32_t> m_detid = {1001, 1002, 1100, 901000, 10100};
 };
-} // namespace ISISKafkaTesting
+} // namespace KafkaTesting
 
 #endif // MANTID_LIVEDATA_ISISKAFKAEVENTSTREAMDECODERTESTMOCKS_H_
diff --git a/Framework/LiveData/test/LoadLiveDataTest.h b/Framework/LiveData/test/LoadLiveDataTest.h
index 028cf8db44bba55227d5662481c9cdbf6604a585..a8830030a22f405158b5e3cdb3fdb6c242017c38 100644
--- a/Framework/LiveData/test/LoadLiveDataTest.h
+++ b/Framework/LiveData/test/LoadLiveDataTest.h
@@ -180,8 +180,8 @@ public:
     TS_ASSERT_EQUALS(ws1->getNumberHistograms(), 2);
     double total;
     total = 0;
-    for (auto it = ws1->readY(0).begin(); it != ws1->readY(0).end(); it++)
-      total += *it;
+    for (double yValue : ws1->readY(0))
+      total += yValue;
     TS_ASSERT_DELTA(total, 100.0, 1e-4);
 
     // Next one adds the histograms together
@@ -191,8 +191,8 @@ public:
 
     // The new total signal is 200.0
     total = 0;
-    for (auto it = ws1->readY(0).begin(); it != ws1->readY(0).end(); it++)
-      total += *it;
+    for (double yValue : ws1->readY(0))
+      total += yValue;
     TS_ASSERT_DELTA(total, 200.0, 1e-4);
 
     TSM_ASSERT("Workspace being added stayed the same pointer", ws1 == ws2);
diff --git a/Framework/MDAlgorithms/CMakeLists.txt b/Framework/MDAlgorithms/CMakeLists.txt
index 20b3cfbe911f6b4164ca141a535f12f669ca97f6..f35029deb15a40a29f217bfb3a328d1b448de380 100644
--- a/Framework/MDAlgorithms/CMakeLists.txt
+++ b/Framework/MDAlgorithms/CMakeLists.txt
@@ -1,383 +1,386 @@
 # GLOBs should be replaced with explicit listings
 set ( SRC_FILES
-    # Old TMP convertToMD code prepared for deprecation:
-    # src/CreateMDFitWorkspace.cpp
-    #end TMP
-    src/AccumulateMD.cpp
-    src/AndMD.cpp
-    src/BaseConvertToDiffractionMDWorkspace.cpp
-    src/BinMD.cpp
-    src/BinaryOperationMD.cpp
-    src/BooleanBinaryOperationMD.cpp
-    src/BoxControllerSettingsAlgorithm.cpp
-    src/CalculateCoverageDGS.cpp
-    src/CentroidPeaksMD.cpp
-    src/CentroidPeaksMD2.cpp
-    src/ChangeQConvention.cpp
-    src/CloneMDWorkspace.cpp
-    src/CompactMD.cpp
-    src/CompareMDWorkspaces.cpp
-    src/ConvToMDBase.cpp
-    src/ConvToMDEventsWS.cpp
-    src/ConvToMDHistoWS.cpp
-    src/ConvToMDSelector.cpp
-    src/ConvertCWPDMDToSpectra.cpp
-    src/ConvertCWSDExpToMomentum.cpp
-    src/ConvertCWSDMDtoHKL.cpp
-    src/ConvertMDHistoToMatrixWorkspace.cpp
-    src/ConvertSpiceDataToRealSpace.cpp
-    src/ConvertToDetectorFaceMD.cpp
-    src/ConvertToDiffractionMDWorkspace.cpp
-    src/ConvertToDiffractionMDWorkspace2.cpp
-    src/ConvertToDiffractionMDWorkspace3.cpp
-    src/ConvertToMD.cpp
-    src/ConvertToMDMinMaxGlobal.cpp
-    src/ConvertToMDMinMaxLocal.cpp
-    src/ConvertToMDParent.cpp
-    src/ConvertToReflectometryQ.cpp
-    src/CreateMD.cpp
-    src/CreateMDHistoWorkspace.cpp
-    src/CreateMDWorkspace.cpp
-    src/CutMD.cpp
-    src/DisplayNormalizationSetter.cpp
-    src/DivideMD.cpp
-    src/EqualToMD.cpp
-    src/EvaluateMDFunction.cpp
-    src/ExponentialMD.cpp
-    src/FakeMDEventData.cpp
-    src/FindPeaksMD.cpp
-    src/FitMD.cpp
-    src/GetSpiceDataRawCountsFromMD.cpp
-    src/GreaterThanMD.cpp
-    src/IDynamicRebinning.cpp
-    src/ImportMDEventWorkspace.cpp
-    src/ImportMDHistoWorkspace.cpp
-    src/ImportMDHistoWorkspaceBase.cpp
-    src/Integrate3DEvents.cpp
-    src/IntegrateEllipsoids.cpp
-    src/IntegrateEllipsoidsTwoStep.cpp
-    src/IntegrateFlux.cpp
-    src/IntegrateMDHistoWorkspace.cpp
-    src/IntegratePeaksMD.cpp
-    src/IntegratePeaksMD2.cpp
-    src/IntegratePeaksMDHKL.cpp
-    src/IntegratePeaksCWSD.cpp
-    src/InvalidParameter.cpp
-    src/InvalidParameterParser.cpp
-    src/LessThanMD.cpp
-    src/LoadMD.cpp
-    src/LoadSQW.cpp
-    src/LoadSQW2.cpp
-    src/LogarithmMD.cpp
-    src/MDEventWSWrapper.cpp
-    src/MDNormDirectSC.cpp
-    src/MDNormSCD.cpp
-    src/MDTransfAxisNames.cpp
-    src/MDTransfFactory.cpp
-    src/MDTransfModQ.cpp
-    src/MDTransfNoQ.cpp
-    src/MDTransfQ3D.cpp
-    src/MDWSDescription.cpp
-    src/MDWSTransform.cpp
-    src/MaskMD.cpp
-    src/MergeMD.cpp
-    src/MergeMDFiles.cpp
-    src/MinusMD.cpp
-    src/MultiplyMD.cpp
-    src/NotMD.cpp
-    src/OneStepMDEW.cpp
-    src/OrMD.cpp
-    src/PlusMD.cpp
-    src/PowerMD.cpp
-    src/PreprocessDetectorsToMD.cpp
-    src/Quantification/CachedExperimentInfo.cpp
-    src/Quantification/FitResolutionConvolvedModel.cpp
-    src/Quantification/ForegroundModel.cpp
-    src/Quantification/ForegroundModelFactory.cpp
-    src/Quantification/MDResolutionConvolution.cpp
-    src/Quantification/MDResolutionConvolutionFactory.cpp
-    src/Quantification/Models/MullerAnsatz.cpp
-    src/Quantification/Models/QCoordinate.cpp
-    src/Quantification/Models/Strontium122.cpp
-    src/Quantification/Resolution/ModeratorChopperResolution.cpp
-    src/Quantification/Resolution/TobyFitBMatrix.cpp
-    src/Quantification/Resolution/TobyFitResolutionModel.cpp
-    src/Quantification/Resolution/TobyFitYVector.cpp
-    src/Quantification/ResolutionConvolvedCrossSection.cpp
-    src/Quantification/SimulateResolutionConvolvedModel.cpp
-    src/QueryMDWorkspace.cpp
-    src/ReflectometryTransformKiKf.cpp
-    src/ReflectometryTransformP.cpp
-    src/ReflectometryTransformQxQz.cpp
-    src/ReplicateMD.cpp
-    src/SaveIsawQvector.cpp
-    src/SaveMD.cpp
-    src/SaveMD2.cpp
-    src/SaveZODS.cpp
-    src/SetMDFrame.cpp
-    src/SetMDUsingMask.cpp
-    src/SliceMD.cpp
-    src/SlicingAlgorithm.cpp
-    src/SmoothMD.cpp
-    src/ThresholdMD.cpp
-    src/TransformMD.cpp
-    src/TransposeMD.cpp
-    src/UnaryOperationMD.cpp
-    src/UnitsConversionHelper.cpp
-    src/UserFunctionMD.cpp
-    src/WeightedMeanMD.cpp
-    src/XorMD.cpp
-    )
+	# Old TMP convertToMD code prepared for deprecation:
+	# src/CreateMDFitWorkspace.cpp
+	#end TMP
+	src/AccumulateMD.cpp
+	src/AndMD.cpp
+	src/BaseConvertToDiffractionMDWorkspace.cpp
+	src/BinMD.cpp
+	src/BinaryOperationMD.cpp
+	src/BooleanBinaryOperationMD.cpp
+	src/BoxControllerSettingsAlgorithm.cpp
+	src/CalculateCoverageDGS.cpp
+	src/CentroidPeaksMD.cpp
+	src/CentroidPeaksMD2.cpp
+	src/ChangeQConvention.cpp
+	src/CloneMDWorkspace.cpp
+	src/CompactMD.cpp
+	src/CompareMDWorkspaces.cpp
+	src/ConvToMDBase.cpp
+	src/ConvToMDEventsWS.cpp
+	src/ConvToMDHistoWS.cpp
+	src/ConvToMDSelector.cpp
+	src/ConvertCWPDMDToSpectra.cpp
+	src/ConvertCWSDExpToMomentum.cpp
+	src/ConvertCWSDMDtoHKL.cpp
+	src/ConvertMDHistoToMatrixWorkspace.cpp
+	src/ConvertSpiceDataToRealSpace.cpp
+	src/ConvertToDetectorFaceMD.cpp
+	src/ConvertToDiffractionMDWorkspace.cpp
+	src/ConvertToDiffractionMDWorkspace2.cpp
+	src/ConvertToDiffractionMDWorkspace3.cpp
+	src/ConvertToMD.cpp
+	src/ConvertToMDMinMaxGlobal.cpp
+	src/ConvertToMDMinMaxLocal.cpp
+	src/ConvertToMDParent.cpp
+	src/ConvertToReflectometryQ.cpp
+	src/CreateMD.cpp
+	src/CreateMDHistoWorkspace.cpp
+	src/CreateMDWorkspace.cpp
+	src/CutMD.cpp
+	src/DisplayNormalizationSetter.cpp
+	src/DivideMD.cpp
+	src/EqualToMD.cpp
+	src/EvaluateMDFunction.cpp
+	src/ExponentialMD.cpp
+	src/FakeMDEventData.cpp
+	src/FindPeaksMD.cpp
+	src/FitMD.cpp
+	src/GetSpiceDataRawCountsFromMD.cpp
+	src/GreaterThanMD.cpp
+	src/IDynamicRebinning.cpp
+	src/ImportMDEventWorkspace.cpp
+	src/ImportMDHistoWorkspace.cpp
+	src/ImportMDHistoWorkspaceBase.cpp
+	src/Integrate3DEvents.cpp
+	src/IntegrateEllipsoids.cpp
+	src/IntegrateEllipsoidsTwoStep.cpp
+	src/IntegrateFlux.cpp
+	src/IntegrateMDHistoWorkspace.cpp
+	src/IntegratePeaksCWSD.cpp
+	src/IntegratePeaksMD.cpp
+	src/IntegratePeaksMD2.cpp
+	src/IntegratePeaksMDHKL.cpp
+	src/InvalidParameter.cpp
+	src/InvalidParameterParser.cpp
+	src/LessThanMD.cpp
+	src/LoadDNSSCD.cpp
+	src/LoadMD.cpp
+	src/LoadSQW.cpp
+	src/LoadSQW2.cpp
+	src/LogarithmMD.cpp
+	src/MDEventWSWrapper.cpp
+	src/MDNormDirectSC.cpp
+	src/MDNormSCD.cpp
+	src/MDTransfAxisNames.cpp
+	src/MDTransfFactory.cpp
+	src/MDTransfModQ.cpp
+	src/MDTransfNoQ.cpp
+	src/MDTransfQ3D.cpp
+	src/MDWSDescription.cpp
+	src/MDWSTransform.cpp
+	src/MaskMD.cpp
+	src/MergeMD.cpp
+	src/MergeMDFiles.cpp
+	src/MinusMD.cpp
+	src/MultiplyMD.cpp
+	src/NotMD.cpp
+	src/OneStepMDEW.cpp
+	src/OrMD.cpp
+	src/PlusMD.cpp
+	src/PowerMD.cpp
+	src/PreprocessDetectorsToMD.cpp
+	src/Quantification/CachedExperimentInfo.cpp
+	src/Quantification/FitResolutionConvolvedModel.cpp
+	src/Quantification/ForegroundModel.cpp
+	src/Quantification/ForegroundModelFactory.cpp
+	src/Quantification/MDResolutionConvolution.cpp
+	src/Quantification/MDResolutionConvolutionFactory.cpp
+	src/Quantification/Models/MullerAnsatz.cpp
+	src/Quantification/Models/QCoordinate.cpp
+	src/Quantification/Models/Strontium122.cpp
+	src/Quantification/Resolution/ModeratorChopperResolution.cpp
+	src/Quantification/Resolution/TobyFitBMatrix.cpp
+	src/Quantification/Resolution/TobyFitResolutionModel.cpp
+	src/Quantification/Resolution/TobyFitYVector.cpp
+	src/Quantification/ResolutionConvolvedCrossSection.cpp
+	src/Quantification/SimulateResolutionConvolvedModel.cpp
+	src/QueryMDWorkspace.cpp
+	src/ReflectometryTransformKiKf.cpp
+	src/ReflectometryTransformP.cpp
+	src/ReflectometryTransformQxQz.cpp
+	src/ReplicateMD.cpp
+	src/SaveIsawQvector.cpp
+	src/SaveMD.cpp
+	src/SaveMD2.cpp
+	src/SaveZODS.cpp
+	src/SetMDFrame.cpp
+	src/SetMDUsingMask.cpp
+	src/SliceMD.cpp
+	src/SlicingAlgorithm.cpp
+	src/SmoothMD.cpp
+	src/ThresholdMD.cpp
+	src/TransformMD.cpp
+	src/TransposeMD.cpp
+	src/UnaryOperationMD.cpp
+	src/UnitsConversionHelper.cpp
+	src/UserFunctionMD.cpp
+	src/WeightedMeanMD.cpp
+	src/XorMD.cpp
+)
 
 #set ( SRC_UNITY_IGNORE_FILES src/IDynamicRebinning.cpp
 #)
 
 set ( INC_FILES
-    inc/MantidMDAlgorithms/AccumulateMD.h
-    inc/MantidMDAlgorithms/AndMD.h
-    inc/MantidMDAlgorithms/BaseConvertToDiffractionMDWorkspace.h
-    inc/MantidMDAlgorithms/BinMD.h
-    inc/MantidMDAlgorithms/BinaryOperationMD.h
-    inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h
-    inc/MantidMDAlgorithms/BoxControllerSettingsAlgorithm.h
-    inc/MantidMDAlgorithms/CalculateCoverageDGS.h
-    inc/MantidMDAlgorithms/CentroidPeaksMD.h
-    inc/MantidMDAlgorithms/CentroidPeaksMD2.h
-    inc/MantidMDAlgorithms/ChangeQConvention.h
-    inc/MantidMDAlgorithms/CloneMDWorkspace.h
-    inc/MantidMDAlgorithms/CompactMD.h
-    inc/MantidMDAlgorithms/CompareMDWorkspaces.h
-    inc/MantidMDAlgorithms/ConvToMDBase.h
-    inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h
-    inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h
-    inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h
-    inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h
-    inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
-    inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h
-    inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace.h
-    inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace2.h
-    inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h
-    inc/MantidMDAlgorithms/ConvertToMD.h
-    inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h
-    inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h
-    inc/MantidMDAlgorithms/ConvertToMDParent.h
-    inc/MantidMDAlgorithms/ConvertToReflectometryQ.h
-    inc/MantidMDAlgorithms/CreateMD.h
-    inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h
-    inc/MantidMDAlgorithms/CreateMDWorkspace.h
-    inc/MantidMDAlgorithms/CutMD.h
-    inc/MantidMDAlgorithms/DisplayNormalizationSetter.h
-    inc/MantidMDAlgorithms/DivideMD.h
-    inc/MantidMDAlgorithms/DllConfig.h
-    inc/MantidMDAlgorithms/EqualToMD.h
-    inc/MantidMDAlgorithms/EvaluateMDFunction.h
-    inc/MantidMDAlgorithms/ExponentialMD.h
-    inc/MantidMDAlgorithms/FakeMDEventData.h
-    inc/MantidMDAlgorithms/FindPeaksMD.h
-    inc/MantidMDAlgorithms/FitMD.h
-    inc/MantidMDAlgorithms/GSLFunctions.h
-    inc/MantidMDAlgorithms/GetSpiceDataRawCountsFromMD.h
-    inc/MantidMDAlgorithms/GreaterThanMD.h
-    inc/MantidMDAlgorithms/IDynamicRebinning.h
-    inc/MantidMDAlgorithms/ImportMDEventWorkspace.h
-    inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h
-    inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h
-    inc/MantidMDAlgorithms/Integrate3DEvents.h
-    inc/MantidMDAlgorithms/IntegrateEllipsoids.h
-    inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h
-    inc/MantidMDAlgorithms/IntegrateFlux.h
-    inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h
-    inc/MantidMDAlgorithms/IntegratePeaksMD.h
-    inc/MantidMDAlgorithms/IntegratePeaksMD2.h
-    inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h
-    inc/MantidMDAlgorithms/IntegratePeaksCWSD.h
-    inc/MantidMDAlgorithms/InvalidParameter.h
-    inc/MantidMDAlgorithms/InvalidParameterParser.h
-    inc/MantidMDAlgorithms/LessThanMD.h
-    inc/MantidMDAlgorithms/LoadMD.h
-    inc/MantidMDAlgorithms/LoadSQW.h
-    inc/MantidMDAlgorithms/LoadSQW2.h
-    inc/MantidMDAlgorithms/LogarithmMD.h
-    inc/MantidMDAlgorithms/MDEventWSWrapper.h
-    inc/MantidMDAlgorithms/MDNormDirectSC.h
-    inc/MantidMDAlgorithms/MDNormSCD.h
-    inc/MantidMDAlgorithms/MDTransfAxisNames.h
-    inc/MantidMDAlgorithms/MDTransfFactory.h
-    inc/MantidMDAlgorithms/MDTransfInterface.h
-    inc/MantidMDAlgorithms/MDTransfModQ.h
-    inc/MantidMDAlgorithms/MDTransfNoQ.h
-    inc/MantidMDAlgorithms/MDTransfQ3D.h
-    inc/MantidMDAlgorithms/MDWSDescription.h
-    inc/MantidMDAlgorithms/MDWSTransform.h
-    inc/MantidMDAlgorithms/MaskMD.h
-    inc/MantidMDAlgorithms/MergeMD.h
-    inc/MantidMDAlgorithms/MergeMDFiles.h
-    inc/MantidMDAlgorithms/MinusMD.h
-    inc/MantidMDAlgorithms/MultiplyMD.h
-    inc/MantidMDAlgorithms/NotMD.h
-    inc/MantidMDAlgorithms/OneStepMDEW.h
-    inc/MantidMDAlgorithms/OrMD.h
-    inc/MantidMDAlgorithms/PlusMD.h
-    inc/MantidMDAlgorithms/PowerMD.h
-    inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h
-    inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h
-    inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h
-    inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
-    inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h
-    inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h
-    inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h
-    inc/MantidMDAlgorithms/Quantification/Models/MullerAnsatz.h
-    inc/MantidMDAlgorithms/Quantification/Models/QCoordinate.h
-    inc/MantidMDAlgorithms/Quantification/Models/Strontium122.h
-    inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h
-    inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitBMatrix.h
-    inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h
-    inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h
-    inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h
-    inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
-    inc/MantidMDAlgorithms/QueryMDWorkspace.h
-    inc/MantidMDAlgorithms/ReflectometryTransformKiKf.h
-    inc/MantidMDAlgorithms/ReflectometryTransformP.h
-    inc/MantidMDAlgorithms/ReflectometryTransformQxQz.h
-    inc/MantidMDAlgorithms/ReplicateMD.h
-    inc/MantidMDAlgorithms/SaveIsawQvector.h
-    inc/MantidMDAlgorithms/SaveMD.h
-    inc/MantidMDAlgorithms/SaveMD2.h
-    inc/MantidMDAlgorithms/SaveZODS.h
-    inc/MantidMDAlgorithms/SetMDFrame.h
-    inc/MantidMDAlgorithms/SetMDUsingMask.h
-    inc/MantidMDAlgorithms/SliceMD.h
-    inc/MantidMDAlgorithms/SlicingAlgorithm.h
-    inc/MantidMDAlgorithms/SmoothMD.h
-    inc/MantidMDAlgorithms/ThresholdMD.h
-    inc/MantidMDAlgorithms/TransformMD.h
-    inc/MantidMDAlgorithms/TransposeMD.h
-    inc/MantidMDAlgorithms/UnaryOperationMD.h
-    inc/MantidMDAlgorithms/UnitsConversionHelper.h
-    inc/MantidMDAlgorithms/Vector3DParameter.h
-    inc/MantidMDAlgorithms/Vector3DParameterParser.h
-    inc/MantidMDAlgorithms/WeightedMeanMD.h
-    inc/MantidMDAlgorithms/XorMD.h
-    )
+	inc/MantidMDAlgorithms/AccumulateMD.h
+	inc/MantidMDAlgorithms/AndMD.h
+	inc/MantidMDAlgorithms/BaseConvertToDiffractionMDWorkspace.h
+	inc/MantidMDAlgorithms/BinMD.h
+	inc/MantidMDAlgorithms/BinaryOperationMD.h
+	inc/MantidMDAlgorithms/BooleanBinaryOperationMD.h
+	inc/MantidMDAlgorithms/BoxControllerSettingsAlgorithm.h
+	inc/MantidMDAlgorithms/CalculateCoverageDGS.h
+	inc/MantidMDAlgorithms/CentroidPeaksMD.h
+	inc/MantidMDAlgorithms/CentroidPeaksMD2.h
+	inc/MantidMDAlgorithms/ChangeQConvention.h
+	inc/MantidMDAlgorithms/CloneMDWorkspace.h
+	inc/MantidMDAlgorithms/CompactMD.h
+	inc/MantidMDAlgorithms/CompareMDWorkspaces.h
+	inc/MantidMDAlgorithms/ConvToMDBase.h
+	inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h
+	inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h
+	inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h
+	inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h
+	inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
+	inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h
+	inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace.h
+	inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace2.h
+	inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h
+	inc/MantidMDAlgorithms/ConvertToMD.h
+	inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h
+	inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h
+	inc/MantidMDAlgorithms/ConvertToMDParent.h
+	inc/MantidMDAlgorithms/ConvertToReflectometryQ.h
+	inc/MantidMDAlgorithms/CreateMD.h
+	inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h
+	inc/MantidMDAlgorithms/CreateMDWorkspace.h
+	inc/MantidMDAlgorithms/CutMD.h
+	inc/MantidMDAlgorithms/DisplayNormalizationSetter.h
+	inc/MantidMDAlgorithms/DivideMD.h
+	inc/MantidMDAlgorithms/DllConfig.h
+	inc/MantidMDAlgorithms/EqualToMD.h
+	inc/MantidMDAlgorithms/EvaluateMDFunction.h
+	inc/MantidMDAlgorithms/ExponentialMD.h
+	inc/MantidMDAlgorithms/FakeMDEventData.h
+	inc/MantidMDAlgorithms/FindPeaksMD.h
+	inc/MantidMDAlgorithms/FitMD.h
+	inc/MantidMDAlgorithms/GSLFunctions.h
+	inc/MantidMDAlgorithms/GetSpiceDataRawCountsFromMD.h
+	inc/MantidMDAlgorithms/GreaterThanMD.h
+	inc/MantidMDAlgorithms/IDynamicRebinning.h
+	inc/MantidMDAlgorithms/ImportMDEventWorkspace.h
+	inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h
+	inc/MantidMDAlgorithms/ImportMDHistoWorkspaceBase.h
+	inc/MantidMDAlgorithms/Integrate3DEvents.h
+	inc/MantidMDAlgorithms/IntegrateEllipsoids.h
+	inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h
+	inc/MantidMDAlgorithms/IntegrateFlux.h
+	inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h
+	inc/MantidMDAlgorithms/IntegratePeaksCWSD.h
+	inc/MantidMDAlgorithms/IntegratePeaksMD.h
+	inc/MantidMDAlgorithms/IntegratePeaksMD2.h
+	inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h
+	inc/MantidMDAlgorithms/InvalidParameter.h
+	inc/MantidMDAlgorithms/InvalidParameterParser.h
+	inc/MantidMDAlgorithms/LessThanMD.h
+	inc/MantidMDAlgorithms/LoadDNSSCD.h
+	inc/MantidMDAlgorithms/LoadMD.h
+	inc/MantidMDAlgorithms/LoadSQW.h
+	inc/MantidMDAlgorithms/LoadSQW2.h
+	inc/MantidMDAlgorithms/LogarithmMD.h
+	inc/MantidMDAlgorithms/MDEventWSWrapper.h
+	inc/MantidMDAlgorithms/MDNormDirectSC.h
+	inc/MantidMDAlgorithms/MDNormSCD.h
+	inc/MantidMDAlgorithms/MDTransfAxisNames.h
+	inc/MantidMDAlgorithms/MDTransfFactory.h
+	inc/MantidMDAlgorithms/MDTransfInterface.h
+	inc/MantidMDAlgorithms/MDTransfModQ.h
+	inc/MantidMDAlgorithms/MDTransfNoQ.h
+	inc/MantidMDAlgorithms/MDTransfQ3D.h
+	inc/MantidMDAlgorithms/MDWSDescription.h
+	inc/MantidMDAlgorithms/MDWSTransform.h
+	inc/MantidMDAlgorithms/MaskMD.h
+	inc/MantidMDAlgorithms/MergeMD.h
+	inc/MantidMDAlgorithms/MergeMDFiles.h
+	inc/MantidMDAlgorithms/MinusMD.h
+	inc/MantidMDAlgorithms/MultiplyMD.h
+	inc/MantidMDAlgorithms/NotMD.h
+	inc/MantidMDAlgorithms/OneStepMDEW.h
+	inc/MantidMDAlgorithms/OrMD.h
+	inc/MantidMDAlgorithms/PlusMD.h
+	inc/MantidMDAlgorithms/PowerMD.h
+	inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h
+	inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h
+	inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h
+	inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
+	inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h
+	inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h
+	inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h
+	inc/MantidMDAlgorithms/Quantification/Models/MullerAnsatz.h
+	inc/MantidMDAlgorithms/Quantification/Models/QCoordinate.h
+	inc/MantidMDAlgorithms/Quantification/Models/Strontium122.h
+	inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h
+	inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitBMatrix.h
+	inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h
+	inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h
+	inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h
+	inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
+	inc/MantidMDAlgorithms/QueryMDWorkspace.h
+	inc/MantidMDAlgorithms/ReflectometryTransformKiKf.h
+	inc/MantidMDAlgorithms/ReflectometryTransformP.h
+	inc/MantidMDAlgorithms/ReflectometryTransformQxQz.h
+	inc/MantidMDAlgorithms/ReplicateMD.h
+	inc/MantidMDAlgorithms/SaveIsawQvector.h
+	inc/MantidMDAlgorithms/SaveMD.h
+	inc/MantidMDAlgorithms/SaveMD2.h
+	inc/MantidMDAlgorithms/SaveZODS.h
+	inc/MantidMDAlgorithms/SetMDFrame.h
+	inc/MantidMDAlgorithms/SetMDUsingMask.h
+	inc/MantidMDAlgorithms/SliceMD.h
+	inc/MantidMDAlgorithms/SlicingAlgorithm.h
+	inc/MantidMDAlgorithms/SmoothMD.h
+	inc/MantidMDAlgorithms/ThresholdMD.h
+	inc/MantidMDAlgorithms/TransformMD.h
+	inc/MantidMDAlgorithms/TransposeMD.h
+	inc/MantidMDAlgorithms/UnaryOperationMD.h
+	inc/MantidMDAlgorithms/UnitsConversionHelper.h
+	inc/MantidMDAlgorithms/Vector3DParameter.h
+	inc/MantidMDAlgorithms/Vector3DParameterParser.h
+	inc/MantidMDAlgorithms/WeightedMeanMD.h
+	inc/MantidMDAlgorithms/XorMD.h
+)
 
 # Test files. Other source files required.
 set ( TEST_FILES
-    #
-    # these tests are as they test verify different parts of the CPR algorithms
-    #CreateMDFitWorkspaceTest.h
-    AccumulateMDTest.h
-    AndMDTest.h
-    BooleanBinaryOperationMDTest.h
-    BoxControllerSettingsAlgorithmTest.h
-    CachedExperimentInfoTest.h
-    CalculateCoverageDGSTest.h
-    CentroidPeaksMD2Test.h
-    CentroidPeaksMDTest.h
-    ChangeQConventionTest.h
-    CloneMDWorkspaceTest.h
-    CompactMDTest.h
-    CompareMDWorkspacesTest.h
-    ConvertCWPDMDToSpectraTest.h
-    ConvertCWSDExpToMomentumTest.h
-    ConvertCWSDMDtoHKLTest.h
-    ConvertEventsToMDTest.h
-    ConvertMDHistoToMatrixWorkspaceTest.h
-    ConvertSpiceDataToRealSpaceTest.h
-    ConvertToDetectorFaceMDTest.h
-    ConvertToDiffractionMDWorkspaceTest.h
-    ConvertToDiffractionMDWorkspace2Test.h
-    ConvertToDiffractionMDWorkspace3Test.h
-    ConvertToMDComponentsTest.h
-    ConvertToMDMinMaxGlobalTest.h
-    ConvertToMDMinMaxLocalTest.h
-    ConvertToMDTest.h
-    ConvertToQ3DdETest.h
-    ConvertToReflectometryQTest.h
-    CreateMDHistoWorkspaceTest.h
-    CreateMDTest.h
-    CreateMDWorkspaceTest.h
-    CutMDTest.h
-    DisplayNormalizationSetterTest.h
-    DivideMDTest.h
-    EqualToMDTest.h
-    EvaluateMDFunctionTest.h
-    ExponentialMDTest.h
-    FakeMDEventDataTest.h
-    FindPeaksMDTest.h
-    FitMDTest.h
-    FitResolutionConvolvedModelTest.h
-    ForegroundModelTest.h
-    GetSpiceDataRawCountsFromMDTest.h
-    GreaterThanMDTest.h
-    ImportMDEventWorkspaceTest.h
-    ImportMDHistoWorkspaceTest.h
-    Integrate3DEventsTest.h
-    IntegrateEllipsoidsTest.h
-    IntegrateEllipsoidsTwoStepTest.h
-    IntegrateFluxTest.h
-    IntegrateMDHistoWorkspaceTest.h
-    IntegratePeaksMD2Test.h
-    IntegratePeaksMDHKLTest.h
-    IntegratePeaksMDTest.h
-    IntegratePeaksCWSDTest.h
-    InvalidParameterParserTest.h
-    InvalidParameterTest.h
-    LessThanMDTest.h
-    LoadMDTest.h
-    LoadSQWTest.h
-    LoadSQW2Test.h
-    LogarithmMDTest.h
-    MDEventWSWrapperTest.h
-    MDNormDirectSCTest.h
-    MDNormSCDTest.h
-    MDResolutionConvolutionFactoryTest.h
-    MDTransfAxisNamesTest.h
-    MDTransfFactoryTest.h
-    MDTransfModQTest.h
-    MDTransfQ3DTest.h
-    MDWSDescriptionTest.h
-    MDWSTransfTest.h
-    MaskMDTest.h
-    MergeMDFilesTest.h
-    MergeMDTest.h
-    MinusMDTest.h
-    ModeratorChopperResolutionTest.h
-    MullerAnsatzTest.h
-    MultiplyMDTest.h
-    NotMDTest.h
-    OneStepMDEWTest.h
-    OrMDTest.h
-    PlusMDTest.h
-    PowerMDTest.h
-    PreprocessDetectorsToMDTest.h
-    QueryMDWorkspaceTest.h
-    ReflectometryTransformKiKfTest.h
-    ReflectometryTransformPTest.h
-    ReflectometryTransformQxQzTest.h
-    ReplicateMDTest.h
-    ResolutionConvolvedCrossSectionTest.h
-    SaveIsawQvectorTest.h
-    SaveMD2Test.h
-    SaveMDTest.h
-    SaveZODSTest.h
-    SetMDFrameTest.h
-    SetMDUsingMaskTest.h
-    SimulateResolutionConvolvedModelTest.h
-    SliceMDTest.h
-    SlicingAlgorithmTest.h
-    SmoothMDTest.h
-    Strontium122Test.h
-    ThresholdMDTest.h
-    TobyFitBMatrixTest.h
-    TobyFitResolutionModelTest.h
-    TobyFitYVectorTest.h
-    TransformMDTest.h
-    TransposeMDTest.h
-    UnaryOperationMDTest.h
-    UnitsConversionHelperTest.h
-    WeightedMeanMDTest.h
-    XorMDTest.h
-    )
+	#
+	# these tests are as they test verify different parts of the CPR algorithms
+	#CreateMDFitWorkspaceTest.h
+	AccumulateMDTest.h
+	AndMDTest.h
+	BooleanBinaryOperationMDTest.h
+	BoxControllerSettingsAlgorithmTest.h
+	CachedExperimentInfoTest.h
+	CalculateCoverageDGSTest.h
+	CentroidPeaksMD2Test.h
+	CentroidPeaksMDTest.h
+	ChangeQConventionTest.h
+	CloneMDWorkspaceTest.h
+	CompactMDTest.h
+	CompareMDWorkspacesTest.h
+	ConvertCWPDMDToSpectraTest.h
+	ConvertCWSDExpToMomentumTest.h
+	ConvertCWSDMDtoHKLTest.h
+	ConvertEventsToMDTest.h
+	ConvertMDHistoToMatrixWorkspaceTest.h
+	ConvertSpiceDataToRealSpaceTest.h
+	ConvertToDetectorFaceMDTest.h
+	ConvertToDiffractionMDWorkspace2Test.h
+	ConvertToDiffractionMDWorkspace3Test.h
+	ConvertToDiffractionMDWorkspaceTest.h
+	ConvertToMDComponentsTest.h
+	ConvertToMDMinMaxGlobalTest.h
+	ConvertToMDMinMaxLocalTest.h
+	ConvertToMDTest.h
+	ConvertToQ3DdETest.h
+	ConvertToReflectometryQTest.h
+	CreateMDHistoWorkspaceTest.h
+	CreateMDTest.h
+	CreateMDWorkspaceTest.h
+	CutMDTest.h
+	DisplayNormalizationSetterTest.h
+	DivideMDTest.h
+	EqualToMDTest.h
+	EvaluateMDFunctionTest.h
+	ExponentialMDTest.h
+	FakeMDEventDataTest.h
+	FindPeaksMDTest.h
+	FitMDTest.h
+	FitResolutionConvolvedModelTest.h
+	ForegroundModelTest.h
+	GetSpiceDataRawCountsFromMDTest.h
+	GreaterThanMDTest.h
+	ImportMDEventWorkspaceTest.h
+	ImportMDHistoWorkspaceTest.h
+	Integrate3DEventsTest.h
+	IntegrateEllipsoidsTest.h
+	IntegrateEllipsoidsTwoStepTest.h
+	IntegrateFluxTest.h
+	IntegrateMDHistoWorkspaceTest.h
+	IntegratePeaksCWSDTest.h
+	IntegratePeaksMD2Test.h
+	IntegratePeaksMDHKLTest.h
+	IntegratePeaksMDTest.h
+	InvalidParameterParserTest.h
+	InvalidParameterTest.h
+	LessThanMDTest.h
+	LoadDNSSCDTest.h
+	LoadMDTest.h
+	LoadSQW2Test.h
+	LoadSQWTest.h
+	LogarithmMDTest.h
+	MDEventWSWrapperTest.h
+	MDNormDirectSCTest.h
+	MDNormSCDTest.h
+	MDResolutionConvolutionFactoryTest.h
+	MDTransfAxisNamesTest.h
+	MDTransfFactoryTest.h
+	MDTransfModQTest.h
+	MDTransfQ3DTest.h
+	MDWSDescriptionTest.h
+	MDWSTransfTest.h
+	MaskMDTest.h
+	MergeMDFilesTest.h
+	MergeMDTest.h
+	MinusMDTest.h
+	ModeratorChopperResolutionTest.h
+	MullerAnsatzTest.h
+	MultiplyMDTest.h
+	NotMDTest.h
+	OneStepMDEWTest.h
+	OrMDTest.h
+	PlusMDTest.h
+	PowerMDTest.h
+	PreprocessDetectorsToMDTest.h
+	QueryMDWorkspaceTest.h
+	ReflectometryTransformKiKfTest.h
+	ReflectometryTransformPTest.h
+	ReflectometryTransformQxQzTest.h
+	ReplicateMDTest.h
+	ResolutionConvolvedCrossSectionTest.h
+	SaveIsawQvectorTest.h
+	SaveMD2Test.h
+	SaveMDTest.h
+	SaveZODSTest.h
+	SetMDFrameTest.h
+	SetMDUsingMaskTest.h
+	SimulateResolutionConvolvedModelTest.h
+	SliceMDTest.h
+	SlicingAlgorithmTest.h
+	SmoothMDTest.h
+	Strontium122Test.h
+	ThresholdMDTest.h
+	TobyFitBMatrixTest.h
+	TobyFitResolutionModelTest.h
+	TobyFitYVectorTest.h
+	TransformMDTest.h
+	TransposeMDTest.h
+	UnaryOperationMDTest.h
+	UnitsConversionHelperTest.h
+	WeightedMeanMDTest.h
+	XorMDTest.h
+)
 
 set ( GMOCK_TEST_FILES
     BinaryOperationMDTest.h
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h
index 2763c719ce6ea44486061d2c69be1b738ce93904..cb6bddffcc849d1dc4b65ef57562ca53ac9de890 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h
@@ -88,6 +88,9 @@ class DLLExport AccumulateMD : public API::DataProcessorAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MergeMD"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h
index 8158a03297139e96ff8331d34975869a799c104d..6a2ac1cef7a32b6ae3f2afc180b4b9f151a3d0f5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h
@@ -38,6 +38,9 @@ class DLLExport AndMD : public BooleanBinaryOperationMD {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"XorMD", "OrMD", "NotMD"};
+  }
 
 private:
   void execHistoHisto(
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
index d97ebc5c22f8e5125ca171b68d8a2113e85bef9b..ff47996ac36e6c01a1f5a5d8123ac01f5601f775 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SliceMDHisto", "ProjectMD", "CutMD", "SliceMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Slicing";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
index 29e327cdfe630daa2610568364851292193cd36c..a00c63a3bb4e09b1ccdb9a14aea24ed90f1d8432 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h
@@ -37,6 +37,9 @@ public:
   CalculateCoverageDGS();
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SetGoniometer", "SetUB"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h
index a6239f7da84ac4c21c278bd908675c74144b3bdc..642109658fb8fad5dabb30db38377066b177d1db 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h
@@ -28,6 +28,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 2; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksMD", "CentroidPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "MDAlgorithms\\Peaks"; }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h
index b6de872d91f83fa2673fbb0c06160b52ef94f207..7e39035ac96be9edfd1a51538ddf5a5465ed34fe 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h
@@ -49,7 +49,7 @@ public:
   int version() const override { return 1; };
   /// Algorithm's category for identification
   const std::string category() const override {
-    return "MDAlgorithms\\Utility\\Workspaces;MDAlgorithms\\Creation";
+    return R"(MDAlgorithms\Utility\Workspaces;MDAlgorithms\Creation)";
   }
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h
index eb229efb9da5f02237771569429c1f4ecba45630..4071a31b64841b920b5499ae19d4255c3151fcbf 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h
@@ -62,6 +62,10 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD", "CreateMDHistoWorkspace",
+            "ConvertTableToMatrixWorkspace", "MDHistoToWorkspace2D"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Utility\\Workspaces;MDAlgorithms\\Transforms";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
index f435fb8a2c11e2806ed685e253bd8d508fbfa311..2f0451581b8c0868bc6b6e50387679554d75b691 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
@@ -61,7 +61,7 @@ public:
 
 private:
   /// Typdef for the white-space separated file data type.
-  typedef std::deque<std::string> DataCollectionType;
+  using DataCollectionType = std::deque<std::string>;
 
   /// Initialisation code
   void init() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h
index b59283a4daab9cd06b5944492462487a9e52d1ed..b81698b736a1eb800f1d9bee4ec198d5fc42992d 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h
@@ -48,6 +48,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h
index 15374ecf3f11b4c0d637d055789a35cb90001b4e..55bf4e3230f8e7c7b0579bca86aae8dd7302eb03 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h
@@ -21,6 +21,9 @@ class DLLExport ConvertToDiffractionMDWorkspace3
 public:
   /// Algorithm's version for identification
   int version() const override { return 3; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD", "SetSpecialCoordinates"};
+  }
 
 private:
   void init() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
index 8f7f443248d6b73ff04d2a9b9700807f5b641864..4b3c7bb5c556713e05fad7d6381720da3394e42e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h
@@ -64,6 +64,11 @@ public:
 
   /// Algorithm's version for identification
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToDiffractionMDWorkspace", "ConvertToMDMinMaxGlobal",
+            "ConvertToMDMinMaxLocal", "CreateMDWorkspace",
+            "SetSpecialCoordinates"};
+  }
 
 private:
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h
index 31d9867bcef75fa14e730a1ef298e6c143c90543..018e6ad2c27d13f2d7c3f75cafe13a4c91892566 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h
index 67f1f5a48e8ff0493c19503aeec80cc5068f30d7..7f27270b0dd367762d4042ca3d7410d680435ed5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h
@@ -41,6 +41,9 @@ public:
   }
 
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD"};
+  }
 
 protected: // for testing
   void findMinMaxValues(MDWSDescription &WSDescription,
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h
index b4e4c9dd97a6ee0174a68590933a5c5536c7e8bb..164fe699b78d0da366a16d5b1de323717f5e2366 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertUnits"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h
index a650274c89d82d29ed03c3071fe55d20841d02d8..45dd364aea1a515a8993e65414f83916124303d5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h
@@ -45,6 +45,9 @@ class MANTID_MDALGORITHMS_DLL CreateMD : public API::DataProcessorAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateMDWorkspace"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h
index ec386117d678a907e9995699a385b00bb791f4b0..4908e723d2f6353302b332be2916691aae7884d5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD", "CreateMDWorkspace"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h
index 5b9c8aaa67bb0a0ff90ecf0f9e72c6d6474f0d01..dc8041f778f80fa83079b4926b217b2664ad640a 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h
@@ -36,6 +36,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertToMD", "CreateMDHistoWorkspace", "FakeMDEventData",
+            "CreateMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Creation";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h
index 92aa260c570984e1db299322391c47ed3f00a00c..39adbc42dabc3151a37d8a0e647352a0256ffe79 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h
@@ -42,6 +42,9 @@ class DLLExport CutMD : public API::DataProcessorAlgorithm {
 public:
   const std::string name() const override { return "CutMD"; }
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SliceMDHisto", "ProjectMD", "SliceMD", "BinMD"};
+  }
   const std::string summary() const override {
     return "Slices multidimensional workspaces using input projection "
            "information and binning limits.";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h
index 2c1450dac3bd7693fb33f5dee10d3853fb2ccf9b..d95be8e21932a3b215d6669576b48585fd7cf313 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MinusMD", "MultiplyMD", "PlusMD", "PowerMD"};
+  }
 
 private:
   /// Is the operation commutative?
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h
index 0facbbb05363791d3550f68922a71a7839b8cec1..c6ca87f2652a76f9322c9665a23791b8adbc90df 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h
@@ -37,6 +37,9 @@ class DLLExport EqualToMD : public BooleanBinaryOperationMD {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"GreaterThanMD", "LessThanMD", "NotMD"};
+  }
 
 private:
   void initExtraProperties() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h
index 50bac7d0c1459c4a694b1e615a19f7534544c4e3..3dd3d240522462fdcd5dc941e3933948100483f4 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h
@@ -38,6 +38,9 @@ public:
 
   const std::string name() const override { return "EvaluateMDFunction"; }
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateMDWorkspace", "FakeMDEventData"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h
index 84fa2e1abb447c79b22daf788672a0587e6242df..ed0262ff09af95e769c29c608797801ad636da0e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PowerMD", "LogarithmMD"};
+  }
 
 private:
   /// Check the inputs and throw if the algorithm cannot be run
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h
index acb6ae4924718c9cd735796e25817795f63df340..043e75aea385a69fcbea1edbea847f4ae31269e0 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h
@@ -44,6 +44,9 @@ public:
   }
   /// Algorithm's verion for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateMDWorkspace", "EvaluateMDFunction"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Creation";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
index 6f21dbd40aee83410955893bab59f9f229fc814c..cd8ce88a8d6452b44a9431fb1adb64d383c42471 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h
@@ -36,6 +36,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"FindPeaks"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Optimization\\PeakFinding;MDAlgorithms\\Peaks";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h
index 6df08bee89dd20485fa2860d159dd342dd8e09fc..89d2cbad0a02f9fe5013c52f1bb1c914296aae8f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LessThanMD", "EqualToMD"};
+  }
 
 private:
   bool acceptScalar() const override { return true; }
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h
index b7c7fec64c46db895576d3a8727a91c7c7b2e69b..6d0b420318ad15968f8b77bbd6202163d2e0c2bc 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h
@@ -45,6 +45,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ImportMDHistoWorkspace"};
+  }
   const std::string category() const override;
 
   /// Flag used to indicate the dimension block in the file
@@ -56,7 +59,7 @@ public:
 
 private:
   /// Typdef for the white-space separated file data type.
-  typedef std::deque<std::string> DataCollectionType;
+  using DataCollectionType = std::deque<std::string>;
   /// All read-in data.
   DataCollectionType m_file_data;
   /// Iterator for the dimensionality start position.
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h
index 61acba6d723bc9004de92c1fd1a08505a5ecc0c7..815c78243c8058daef0c71d8431050e3e8f1b528 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ImportMDEventWorkspace"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
index 99a771ecec233b9aa91c1ad1a5a5aaf07475be1a..271c61fca3b24e3ff6a3480a0b94f609179ac9be 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h
@@ -67,9 +67,10 @@ struct IntegrationParameters {
                  <http://doxygen.mantidproject.org>
  */
 
-typedef std::unordered_map<
-    int64_t, std::vector<std::pair<double, Mantid::Kernel::V3D>>> EventListMap;
-typedef std::unordered_map<int64_t, Mantid::Kernel::V3D> PeakQMap;
+using EventListMap =
+    std::unordered_map<int64_t,
+                       std::vector<std::pair<double, Mantid::Kernel::V3D>>>;
+using PeakQMap = std::unordered_map<int64_t, Mantid::Kernel::V3D>;
 
 class DLLExport Integrate3DEvents {
 public:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
index 2a3c8dad79e6566e77c32e5a6cae2b105f549359..aa5f1fca90531229ada789ed93dd44ccd75c9ca2 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
@@ -27,6 +27,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegrateEllipsoidsTwoStep"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h
index 050e00a795a65ace7ee040f77317c6f8097232ab..674f9a3ff44e0f2c6675549ce4b72698a59eed0a 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h
@@ -45,6 +45,9 @@ public:
   const std::string name() const override;
   /// Get the version of this algorithm
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegrateEllipsoids"};
+  }
   /// Get the category of this algorithm
   const std::string category() const override;
   /// Summary of algorithms purpose
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h
index 281667f1de9043327af3f7e6b9fb2848194e5da1..14d481f5ab2c33f8dd541c15cf337106bbf30ec2 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h
@@ -46,6 +46,9 @@ class DLLExport IntegrateFlux : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Integration"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h
index 813e82138b3aaf36caff24de37310e4e446273ba..9901172d10103d0a94fce0cb02b28a17ae23f2ce 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h
@@ -37,6 +37,9 @@ class DLLExport IntegrateMDHistoWorkspace : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SliceMDHisto"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h
index 04360a2a6c4aaa783ce10adaf2cbb5446591945d..5127fef4c8bf538c50e9e643b0c039a7740aae7b 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h
@@ -33,6 +33,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksHybrid", "IntegratePeaksMDHKL", "IntegratePeaksMD",
+            "IntegratePeaksUsingClusters"};
+  }
 
   /// Algorithm's category for identification
   const std::string category() const override { return "MDAlgorithms\\Peaks"; }
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
index eac3242ca28170a61551c24efa86840a8c90e9c6..8da44d60ff9fa98b1aa06d1e5e09e3c9edc229e3 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
@@ -32,6 +32,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 2; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"CentroidPeaksMD", "IntegratePeaksHybrid", "IntegratePeaksMDHKL",
+            "IntegratePeaksUsingClusters", "IntegratePeaksCWSD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "MDAlgorithms\\Peaks"; }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h
index b97d605f74cb6d492c9eaf12735852cff22e0199..a4cabeaf9e37432de291e368e67da632da62adc5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h
@@ -29,6 +29,10 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"IntegratePeaksHybrid", "IntegratePeaksUsingClusters",
+            "IntegratePeaksMD", "IntegratePeaksCWSD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "MDAlgorithms\\Peaks"; }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h
index 0eb6c2c5a8306a5c7d6618834cd5a8e6ff73d358..c478493573c9b175839eb8a5d2e46dc5d9aa106b 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h
@@ -37,6 +37,9 @@ class DLLExport LessThanMD : public BooleanBinaryOperationMD {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"GreaterThanMD", "EqualToMD"};
+  }
 
 private:
   bool acceptScalar() const override { return true; }
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf0b4e0e995c8a7fc571c37a44fcd8dd26886ffb
--- /dev/null
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadDNSSCD.h
@@ -0,0 +1,108 @@
+#ifndef MANTID_MDALGORITHMS_LOADDNSSCD_H_
+#define MANTID_MDALGORITHMS_LOADDNSSCD_H_
+
+#include <vector>
+#include "MantidAPI/DataProcessorAlgorithm.h"
+#include "MantidAPI/IFileLoader.h"
+#include "MantidAPI/IMDEventWorkspace_fwd.h"
+#include "MantidKernel/System.h"
+#include "MantidDataObjects/MDEventWorkspace.h"
+#include "MantidKernel/Matrix.h"
+#include "MantidKernel/V3D.h"
+
+namespace Mantid {
+namespace MDAlgorithms {
+
+/** LoadDNSSCD : Load a list of DNS .d_dat files into a MDEventWorkspace
+
+  @author Marina Ganeva
+  @date 2018-02-15
+
+  Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+  National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+*/
+class DLLExport LoadDNSSCD : public API::IFileLoader<Kernel::FileDescriptor> {
+public:
+  LoadDNSSCD();
+
+  /// Algorithm's name for identification
+  const std::string name() const override { return "LoadDNSSCD"; }
+
+  /// Summary of algorithms purpose
+  const std::string summary() const override {
+    return "Load a list of DNS .d_dat files into a MDEventWorkspace.";
+  }
+
+  /// Algorithm's version for identification
+  int version() const override { return 1; }
+
+  /// Algorithm's category for identification
+  const std::string category() const override {
+    return "MDAlgorithms\\DataHandling";
+  }
+
+  /// Returns a confidence value that this algorithm can load a file
+  int confidence(Kernel::FileDescriptor &descriptor) const override;
+
+private:
+  /// Initialise the properties
+  void init() override;
+  /// Run the algorithm
+  void exec() override;
+
+  /// number of workspace dimensions
+  size_t m_nDims;
+
+  /// type of normalization;
+  std::string m_normtype;
+  /// factor to multiply the error^2 for normalization
+  double m_normfactor;
+
+  /// structure for experimental data
+  struct ExpData {
+    double deterota;
+    double huber;
+    double wavelength;
+    double norm;
+    std::vector<double> signal;
+    std::vector<int> detID;
+  };
+
+  std::vector<ExpData> m_data;
+
+  /// Output IMDEventWorkspace
+  Mantid::API::IMDEventWorkspace_sptr m_OutWS;
+
+  void read_data(const std::string fname,
+                 std::map<std::string, std::string> &str_metadata,
+                 std::map<std::string, double> &num_metadata);
+  void fillOutputWorkspace(double wavelength);
+  API::ITableWorkspace_sptr saveHuber();
+  void loadHuber(API::ITableWorkspace_sptr tws);
+  template <class T>
+  void updateProperties(API::Run &run, std::map<std::string, T> &metadata,
+                        std::string time);
+};
+
+} // namespace MDAlgorithms
+} // namespace Mantid
+
+#endif /* MANTID_MDALGORITHMS_LOADDNSSCD_H_ */
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
index 45a2f6ab84802c5a57be9caf711086a9693029f5..34be74d57520c9f445fd8f040a4f1242dc827914 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
@@ -51,6 +51,7 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override { return {"SaveMD"}; }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\DataHandling";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h
index 34504cb5c9bb5f66cb9eac0ba7ab99989dd51287..b4936899c25fd9bf811c1f3d33765ccbb3a81193 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h
@@ -47,14 +47,17 @@ class DLLExport LoadSQW2 : public API::IFileLoader<Kernel::FileDescriptor> {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNXSPE", "SaveNXSPE"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   int confidence(Kernel::FileDescriptor &descriptor) const override;
 
 private:
   /// Local typedef for
-  typedef DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>
-      SQWWorkspace;
+  using SQWWorkspace =
+      DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>;
 
   void init() override;
   void exec() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h
index b018c748317c156c89f619ff6f4141636c1a9bd6..21ef39b0ec6a7f6757b225c6119cb80a78f34749 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PowerMD", "ExponentialMD"};
+  }
 
 private:
   void initExtraProperties() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h
index f3690c1e134ad408af11ad63746f177ae6122d80..aed554526a034fa674936bc52577a2a3ab78857f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h
@@ -39,7 +39,7 @@ File change history is stored at: <https://github.com/mantidproject/mantid>
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 /// vectors of strings are often used here
-typedef std::vector<std::string> Strings;
+using Strings = std::vector<std::string>;
 
 /// predefenition of the class name
 class MDEventWSWrapper;
@@ -47,13 +47,13 @@ class MDEventWSWrapper;
 // Boost function pointers with multiple arguments
 //        appear not portable to all architectures supported (Fail on MAC)
 /// signature to void templated function
-typedef void (MDEventWSWrapper::*fpVoidMethod)();
+using fpVoidMethod = void (MDEventWSWrapper::*)();
 /// signature for the internal templated function pointer to add data to an
 /// existing workspace
-typedef void (MDEventWSWrapper::*fpAddData)(float *, uint16_t *, uint32_t *,
-                                            coord_t *, size_t) const;
+using fpAddData = void (MDEventWSWrapper::*)(float *, uint16_t *, uint32_t *,
+                                             coord_t *, size_t) const;
 /// signature for the internal templated function pointer to create workspace
-typedef void (MDEventWSWrapper::*fpCreateWS)(const MDWSDescription &mwsd);
+using fpCreateWS = void (MDEventWSWrapper::*)(const MDWSDescription &);
 
 class DLLExport MDEventWSWrapper {
 public:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
index 9e05a140fe0fb07843902ccd82a731cacddc7f9d..8239e46772954ab534e42e4523f88c232dd0c18a 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
@@ -39,6 +39,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MDNormSCD", "MDNormSCDPreprocessIncoherent"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
index 5b18915c2920df28b5675b3151318e5ead64e9d8..749f6007e75b44aafb91075a0778ceb8165a9a11 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
@@ -39,6 +39,9 @@ public:
 
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MDNormSCDPreprocessIncoherent", "MDNormDirectSC"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h
index bfe1777de9836966c00e43a674df35523bf9c337..61bca51533dec393851945a08089bcbb65860672 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h
@@ -110,7 +110,7 @@ private:
 
 /// The specialization of the SingletonHolder class that holds the
 /// MDTransformations Factory
-typedef Kernel::SingletonHolder<MDTransfFactoryImpl> MDTransfFactory;
+using MDTransfFactory = Kernel::SingletonHolder<MDTransfFactoryImpl>;
 
 } // namespace MDAlgorithms
 } // namespace Mantid
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h
index 519e14f6ad93b709a2c645004b2a0c05c7bfe657..e9ff3893a1e0ebdb6b2ccf7fe45ec5320d981811 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h
@@ -236,8 +236,8 @@ public:
       Mantid::API::MatrixWorkspace_sptr underlyingWorkspace) const = 0;
 };
 
-typedef boost::shared_ptr<MDTransfInterface> MDTransf_sptr;
-typedef boost::shared_ptr<const MDTransfInterface> MDTransf_const_sptr;
+using MDTransf_sptr = boost::shared_ptr<MDTransfInterface>;
+using MDTransf_const_sptr = boost::shared_ptr<const MDTransfInterface>;
 
 } // End MDAlgorighms namespace
 } // End Mantid namespace
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h
index e1e0b6a9990575bf5135fb5669612ef530a1daec..cd6106e261fa8a675a0549d47e5ac6ef8f6b0c4e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h
@@ -47,6 +47,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskDetectors"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h
index 8d8155f633557e4c73636f6e6b4c0942aa8462d2..39a0ac1b40109e2923b3b56a864d5c18352c844f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MergeMDFiles", "AccumulateMD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h
index 04860beaa88cf087a6a010bd786ea9b431c44408..cac9e9687137d6888dccc241f36640f32a0af2c1 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h
@@ -54,6 +54,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MergeMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Creation";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h
index 6acb7cb6aeb7bb533654a6b520992ac9498cd304..d6d2baf9733c1bb9cd2ebb87cb2cdaef797141a5 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PlusMD", "MultiplyMD", "DivideMD", "PowerMD"};
+  }
 
 private:
   /// Is the operation commutative?
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h
index 71655bf240945ab79d446b25d67303b9a45b4c71..5f69fcd6861f1c9e530516480b7f4164fcdddc37 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h
@@ -43,6 +43,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MinusMD", "PlusMD", "DivideMD", "PowerMD"};
+  }
 
 private:
   /// Is the operation commutative?
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h
index cffce98eaf441afdad3d93438e3d5ad117126092..c855fbcbcc7b9a2fc590851a9e3da6b6ce0fe014 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AndMD", "OrMD", "XorMD"};
+  }
 
 private:
   /// Check the inputs and throw if the algorithm cannot be run
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h
index 4990ac1658eb82c354639e71c0daffd85747be32..5cbf604ad4153e12855d9a2e1735e853893efd0a 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h
@@ -37,6 +37,9 @@ class DLLExport OrMD : public BooleanBinaryOperationMD {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AndMD", "XorMD", "NotMD"};
+  }
 
 private:
   void execHistoHisto(
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h
index edfd89a6db928b5768f2dc0b29c4d665404c4ded..5a34023e7c2b94bfa4667d0959f359c94e7b110e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h
@@ -47,6 +47,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"MinusMD", "MultiplyMD", "DivideMD", "PowerMD"};
+  }
 
 private:
   /// Is the operation commutative?
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h
index 1f9070f74c14542da6629dfaf52e62ef6b8061e9..f4d1e18e28658ea3083b36c8c2179871fffe22a2 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h
@@ -42,6 +42,10 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"MinusMD", "MultiplyMD",  "DivideMD",
+            "PlusMD",  "LogarithmMD", "ExponentialMD"};
+  }
 
 private:
   void initExtraProperties() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h
index dd236708ec225878d26e2f4ad265ddc15de0c618..e4eb5ed095f23bb5c57a73f764adaaa059572e2d 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h
@@ -35,6 +35,9 @@ public:
     return "Fits a cuts/slices from an MDEventWorkspace using a resolution "
            "function convolved with a foreground model";
   }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SimulateResolutionConvolvedModel"};
+  }
 
   int version() const override;
   const std::string category() const override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
index 8e54a0340f9bd4d407677c8d5bfffcd3efd22c27..23f983d13c2c2ac46f72d6f13d25e6fcf598396f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h
@@ -135,9 +135,9 @@ private:
 };
 
 /// boost::shared_ptr typedef
-typedef boost::shared_ptr<ForegroundModel> ForegroundModel_sptr;
+using ForegroundModel_sptr = boost::shared_ptr<ForegroundModel>;
 /// boost::shared_ptr to const typedef
-typedef boost::shared_ptr<const ForegroundModel> ForegroundModel_const_sptr;
+using ForegroundModel_const_sptr = boost::shared_ptr<const ForegroundModel>;
 }
 }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h
index a54cbd7928f111c7748c00a02242e309bbc1f7b4..e39225d317952d5b17e2525f529ffe35a5a19766 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h
@@ -44,7 +44,7 @@ class MANTID_MDALGORITHMS_DLL ForegroundModelFactoryImpl
     : public Kernel::DynamicFactory<ForegroundModel> {
 private:
   /// Base-class type
-  typedef Kernel::DynamicFactory<ForegroundModel> BaseClass;
+  using BaseClass = Kernel::DynamicFactory<ForegroundModel>;
 
 public:
   /// A create method to ensure the model is initialized properly
@@ -69,8 +69,8 @@ private:
 };
 
 /// Typedef singleton instance to ForegroundFactory
-typedef Kernel::SingletonHolder<ForegroundModelFactoryImpl>
-    ForegroundModelFactory;
+using ForegroundModelFactory =
+    Kernel::SingletonHolder<ForegroundModelFactoryImpl>;
 }
 }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h
index 460fc90faa5b0ca90d99c8ea876cdc648056a729..7f6e826cba433b76ce73012e1d351c1ee596fe46 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h
@@ -42,7 +42,7 @@ class MANTID_MDALGORITHMS_DLL MDResolutionConvolutionFactoryImpl
     : public Kernel::DynamicFactory<MDResolutionConvolution> {
 private:
   /// Base-class type
-  typedef Kernel::DynamicFactory<MDResolutionConvolution> BaseClass;
+  using BaseClass = Kernel::DynamicFactory<MDResolutionConvolution>;
 
 public:
   /// A create method to ensure the type is initialized properly
@@ -70,8 +70,8 @@ private:
 };
 
 /// Typedef singleton instance to MDResolutionConvolutionFactory
-typedef Kernel::SingletonHolder<MDResolutionConvolutionFactoryImpl>
-    MDResolutionConvolutionFactory;
+using MDResolutionConvolutionFactory =
+    Kernel::SingletonHolder<MDResolutionConvolutionFactoryImpl>;
 }
 }
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
index 5925817133cfd3ddecca00330ce169c11031aec6..e068f43de12174fbc94d4474079044fe959c8428 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
@@ -43,7 +43,9 @@ public:
   const std::string summary() const override {
     return "Runs a simulation of a model with a selected resolution function";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"FitResolutionConvolvedModel"};
+  }
   int version() const override;
 
 private:
@@ -66,8 +68,8 @@ private:
   /// The input domain
   boost::shared_ptr<API::FunctionValues> m_calculatedValues;
   /// The output workspace type
-  typedef DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>
-      QOmegaWorkspace;
+  using QOmegaWorkspace =
+      DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>;
 
   /// The output workspace
   boost::shared_ptr<QOmegaWorkspace> m_outputWS;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h
index cf3cb6ce70382f5607d333fcb2567eb5c728fa7a..3c8286f0b3590a12ecaedb29a4cbf4f8b670db2e 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h
@@ -45,6 +45,9 @@ class MANTID_MDALGORITHMS_DLL ReplicateMD : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"CreateMDWorkspace", "MergeMD"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   /// Valdiate the algorithm inputs
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h
index 0f64bd206d0dfb6cb997838cc250aa21f94e8e66..5f20735ef2ea148271bed84c3682acf0a23ab6ca 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 2; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadMD", "SaveZODS"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\DataHandling";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h
index 28aa71218493fcf7534852f01566b083f0ca9665..dc49617eb411f053536547f6a15deeadbe9995b1 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h
@@ -43,6 +43,7 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override { return {"SaveMD"}; }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h
index 9b04faf63ee3940cd3c62b088799cdadcb54401e..4facc974e9e60ef0833c0adb414323b8e49de843 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h
@@ -57,6 +57,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"SliceMDHisto", "ProjectMD", "CutMD", "BinMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Slicing";
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h
index 1b5c16d16e85ff34f21b0e44fe5c4dcedbf68623..4d42b9b57d19b0ce9ae99b58136871971d9f63f6 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h
@@ -46,6 +46,9 @@ class DLLExport SmoothMD : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"ThresholdMD"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h
index 6461f45ade87a92144c4cc1afc92abb8737b1061..46923478f9ed38ac62a3267a7dbc9c8f346ddba0 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h
@@ -39,6 +39,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"SmoothMD"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h
index c697d5e048d3bc29023ca8640e4268d393b7dd66..10479c11f61df25246bc64c86336a1b0e3875d5b 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h
@@ -42,6 +42,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"InvertMDDim"};
+  }
   const std::string category() const override;
 
 private:
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h
index d1a9300c8ba6b18cf152d05d164b6f18cb906cc0..ac5308243e0deca4197beb923cff563946cc66c8 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h
@@ -35,6 +35,9 @@ class MANTID_MDALGORITHMS_DLL TransposeMD : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"Transpose3D", "Transpose"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h
index 61f405f65fe3514949f80a50d592dff6048be162..4846bb102e10000ebb8a40c1fb2b70943a7131f2 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h
@@ -152,7 +152,7 @@ ElemType &Vector3DParameter<Derived, ElemType>::operator[](int index) {
   class classname                                                              \
       : public Mantid::MDAlgorithms::Vector3DParameter<classname, double> {    \
   public:                                                                      \
-    typedef Vector3DParameter<classname, type_> SuperType;                     \
+    using SuperType = Vector3DParameter<classname, type_> SuperType;           \
     static std::string parameterName() { return #classname; }                  \
     classname(type_ a, type_ b, type_ c) : SuperType(a, b, c) {}               \
     classname() : SuperType() {}                                               \
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h
index 6068aa04784d2045c30438aa695b8f4c94650e7d..5e200f69f9e437a097e0aa73199993e088627a48 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version for identification
   int version() const override { return 1; };
+  const std::vector<std::string> seeAlso() const override {
+    return {"WeightedMean"};
+  }
 
 private:
   /// Is the operation commutative?
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h
index 0456fc93eb23e496f0e11b00680e70fa28f61b00..ab39c4cf020bf91824adcd45693a83dd6766f0d9 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h
@@ -37,6 +37,9 @@ class DLLExport XorMD : public BooleanBinaryOperationMD {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"AndMD", "OrMD", "NotMD"};
+  }
 
 private:
   void execHistoHisto(
diff --git a/Framework/MDAlgorithms/src/BinMD.cpp b/Framework/MDAlgorithms/src/BinMD.cpp
index 3346daac0c5044f79ba7a8d9e3128c46d9583457..e1c84d9b869c2a61297aa0ab6aa7f2ecb927fa99 100644
--- a/Framework/MDAlgorithms/src/BinMD.cpp
+++ b/Framework/MDAlgorithms/src/BinMD.cpp
@@ -103,7 +103,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
     // There is a check that the number of events is enough for it to make sense
     // to do all this processing.
     size_t numVertexes = 0;
-    coord_t *vertexes = box->getVertexesArray(numVertexes);
+    auto vertexes = box->getVertexesArray(numVertexes);
 
     // All vertexes have to be within THE SAME BIN = have the same linear index.
     size_t lastLinearIndex = 0;
@@ -111,7 +111,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
 
     for (size_t i = 0; i < numVertexes; i++) {
       // Cache the center of the event (again for speed)
-      const coord_t *inCenter = vertexes + i * nd;
+      const coord_t *inCenter = vertexes.get() + i * nd;
 
       // Now transform to the output dimensions
       m_transform->apply(inCenter, outCenter);
@@ -154,8 +154,6 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin,
         break;
     } // (for each vertex)
 
-    delete[] vertexes;
-
     if (!badOne) {
       // Yes, the entire box is within a single bin
       //        std::cout << "Box at " << box->getExtentsStr() << " is within a
diff --git a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
index 0d15d133c9477ad740b95059894fb8e7f0cb1c98..45f90cf92ef9bf96a3af8da6683508c97c868e43 100644
--- a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
@@ -26,7 +26,7 @@ void BoxControllerSettingsAlgorithm::initBoxControllerProps(
   mustBeMoreThen1->setLower(1);
 
   // Split up comma-separated properties
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  using tokenizer = Mantid::Kernel::StringTokenizer;
   tokenizer values(SplitInto, ",",
                    tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
   std::vector<int> valueVec;
diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
index bb5f39c02881fb552df94c3c27113d14b2f0c118..4383a4134ce670da98313227db19273b574fb414 100644
--- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
+++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
@@ -634,7 +634,7 @@ CalculateCoverageDGS::calculateIntersections(const double theta,
   }
 
   // sort intersections by final momentum
-  typedef std::vector<Mantid::Kernel::VMD>::iterator IterType;
+  using IterType = std::vector<Mantid::Kernel::VMD>::iterator;
   std::stable_sort<IterType, bool (*)(const Mantid::Kernel::VMD &,
                                       const Mantid::Kernel::VMD &)>(
       intersections.begin(), intersections.end(), compareMomentum);
diff --git a/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
index 1b60b9fda5e59c0fb9dab11aec023d49381a0ca7..38e425b77bcac42146d33d31ad284debc62d87c2 100644
--- a/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
+++ b/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
@@ -449,7 +449,7 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws,
                 << sourcepos.Y() << ", " << sourcepos.Z() << "\n";
 
   // Go through all events to find out their positions
-  IMDIterator *mditer = mdws->createIterator();
+  auto mditer = mdws->createIterator();
   bool scancell = true;
   size_t nextindex = 1;
   int currRunIndex = -1;
diff --git a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
index f31c9245fc92fdbd23d90567bec3aff37da71f89..018851c2df615ebdbdb31540be58b52021f420c2 100644
--- a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
+++ b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
@@ -175,7 +175,7 @@ void ConvertCWSDMDtoHKL::exportEvents(
   vec_event_det.resize(numevents);
 
   // Go through to get value
-  IMDIterator *mditer = mdws->createIterator();
+  auto mditer = mdws->createIterator();
   size_t nextindex = 1;
   bool scancell = true;
   size_t currindex = 0;
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
index db50f17dd78eb5ac346d6ed4c38ea09cacc9ebcc..76aa5e8e2b2b60f58c1e62b32acadf1a1f11ce40 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
@@ -125,7 +125,7 @@ void ConvertToDiffractionMDWorkspace::init() {
 }
 
 /// Our MDLeanEvent dimension
-typedef DataObjects::MDLeanEvent<3> MDE;
+using MDE = DataObjects::MDLeanEvent<3>;
 
 /** Convert one spectrum to DataObjects.
  * Depending on options, it uses the histogram view or the
diff --git a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp
index 7a23dca48eabeb2633cf9cfcd9a3547d07535fd0..fd7750cbc9bcfe412a9ddf920f626a4ae194d1e1 100644
--- a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp
@@ -41,7 +41,7 @@ std::vector<std::string> parseNames(const std::string &names_string) {
   // The second part matches anything that doesn't contain a comma
   // NB, the order of the two parts matters
 
-  regex expression("\\[([^\\[]*)\\]|[^,]+");
+  regex expression(R"(\[([^\[]*)\]|[^,]+)");
 
   boost::sregex_token_iterator iter(names_string.begin(), names_string.end(),
                                     expression, 0);
diff --git a/Framework/MDAlgorithms/src/CutMD.cpp b/Framework/MDAlgorithms/src/CutMD.cpp
index 024f5545e9018d291eee051873f1daea1e85938b..b1f6e68ac956659f8d4b52a562df309fd869cd70 100644
--- a/Framework/MDAlgorithms/src/CutMD.cpp
+++ b/Framework/MDAlgorithms/src/CutMD.cpp
@@ -23,7 +23,7 @@ using namespace Mantid::Kernel;
 namespace {
 
 // Typedef to simplify function signatures
-typedef std::pair<double, double> MinMax;
+using MinMax = std::pair<double, double>;
 
 MinMax getDimensionExtents(IMDEventWorkspace_sptr ws, size_t index) {
   if (!ws)
diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp
index a3f838e593896772b38c29592e2d5db4ecef0259..b71032b5f837448c74b838ba9d35c720bdd9bcd2 100644
--- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp
+++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp
@@ -4,6 +4,7 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/Crystal/EdgePixel.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Objects/InstrumentRayTracer.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
@@ -295,30 +296,12 @@ FindPeaksMD::createPeak(const Mantid::Kernel::V3D &Q, const double binCount,
     if (calcGoniometer) {
       // Calculate Q lab from Q sample and wavelength
       double wavelength = getProperty("Wavelength");
-      double wv = 2.0 * M_PI / wavelength;
-      double norm_q2 = Q.norm2();
-      double theta = acos(1 - norm_q2 / (2 * wv * wv));
-      double phi = asin(-Q[1] / wv * sin(theta));
-      V3D Q_lab(-wv * sin(theta) * cos(phi), -wv * sin(theta) * sin(phi),
-                wv * (1 - cos(theta)));
-
-      // Solve to find rotation matrix, assuming only rotation around y-axis
-      // A * X = B
-      Matrix<double> A({Q[0], Q[2], Q[2], -Q[0]}, 2, 2);
-      A.Invert();
-      std::vector<double> B{Q_lab[0], Q_lab[2]};
-      std::vector<double> X = A * B;
-      double rot = atan2(X[1], X[0]);
+      Geometry::Goniometer goniometer;
+      goniometer.calcFromQSampleAndWavelength(Q, wavelength);
       g_log.information() << "Found goniometer rotation to be "
-                          << rot * 180 / M_PI
-                          << " degrees for peak at Q sample = " << Q << "\n";
-
-      Matrix<double> goniometer(3, 3, true);
-      goniometer[0][0] = cos(rot);
-      goniometer[0][2] = sin(rot);
-      goniometer[2][0] = -sin(rot);
-      goniometer[2][2] = cos(rot);
-      p = boost::make_shared<Peak>(inst, Q, goniometer);
+                          << goniometer.getEulerAngles()[0]
+                          << " degrees for Q sample = " << Q << "\n";
+      p = boost::make_shared<Peak>(inst, Q, goniometer.getR());
 
     } else {
       p = boost::make_shared<Peak>(inst, Q, m_goniometer);
@@ -394,7 +377,7 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws) {
     }
     g_log.information() << "Threshold signal density: " << threshold << '\n';
 
-    typedef API::IMDNode *boxPtr;
+    using boxPtr = API::IMDNode *;
     // We will fill this vector with pointers to all the boxes (up to a given
     // depth)
     typename std::vector<API::IMDNode *> boxes;
@@ -404,7 +387,7 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace<MDE, nd>::sptr ws) {
     ws->getBox()->getBoxes(boxes, 1000, true);
 
     // This pair is the <density, ptr to the box>
-    typedef std::pair<double, API::IMDNode *> dens_box;
+    using dens_box = std::pair<double, API::IMDNode *>;
 
     // Map that will sort the boxes by increasing density. The key = density;
     // value = box *.
@@ -586,7 +569,7 @@ void FindPeaksMD::findPeaksHisto(
     peakWS->copyExperimentInfoFrom(ei.get());
 
     // This pair is the <density, box index>
-    typedef std::pair<double, size_t> dens_box;
+    using dens_box = std::pair<double, size_t>;
 
     // Map that will sort the boxes by increasing density. The key = density;
     // value = box index.
@@ -746,6 +729,10 @@ void FindPeaksMD::exec() {
   criteria.push_back(std::pair<std::string, bool>("bincount", false));
   peakWS->sort(criteria);
 
+  for (auto i = 0; i != peakWS->getNumberPeaks(); ++i) {
+    Peak &p = peakWS->getPeak(i);
+    p.setPeakNumber(i + 1);
+  }
   // Save the output
   setProperty("OutputWorkspace", peakWS);
 }
diff --git a/Framework/MDAlgorithms/src/FitMD.cpp b/Framework/MDAlgorithms/src/FitMD.cpp
index e3fbd3f0e296be263b1a1b3c9e714bc69c700ca5..959a88dd53649df7a14d5e36c78862913f0a1c99 100644
--- a/Framework/MDAlgorithms/src/FitMD.cpp
+++ b/Framework/MDAlgorithms/src/FitMD.cpp
@@ -97,7 +97,6 @@ void FitMD::createDomain(boost::shared_ptr<API::FunctionDomain> &domain,
   setParameters();
   auto iterator = m_IMDWorkspace->createIterator();
   const size_t n = iterator->getDataSize();
-  delete iterator;
 
   if (m_count == 0) {
     m_count = n;
@@ -233,7 +232,6 @@ boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace(
     }
     ++resultValueIndex;
   } while (inputIter->next());
-  delete inputIter;
 
   // This splits up all the boxes according to split thresholds and sizes.
   auto threadScheduler = new Kernel::ThreadSchedulerFIFO();
@@ -342,7 +340,6 @@ size_t FitMD::getDomainSize() const {
     throw std::runtime_error("FitMD: workspace wasn't defined");
   auto iterator = m_IMDWorkspace->createIterator();
   size_t n = iterator->getDataSize();
-  delete iterator;
   if (m_count != 0) {
     if (m_startIndex + m_count > n)
       throw std::range_error("FitMD: index is out of range");
diff --git a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
index 6e71b65b7890d31d52484873a2de24ca5e7e6e25..3299118922a09d1e6ec334564cff1ed86e108db4 100644
--- a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
+++ b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
@@ -378,7 +378,7 @@ void GetSpiceDataRawCountsFromMD::getDetCounts(
   vecY.clear();
 
   // Go through all events to find out their positions
-  IMDIterator *mditer = mdws->createIterator();
+  auto mditer = mdws->createIterator();
 
   bool scancell = true;
   size_t nextindex = 1;
@@ -429,8 +429,6 @@ void GetSpiceDataRawCountsFromMD::getDetCounts(
       scancell = false;
     }
   } // ENDOF(while)
-
-  delete (mditer);
 }
 
 //----------------------------------------------------------------------------------------------
@@ -502,7 +500,7 @@ MatrixWorkspace_sptr GetSpiceDataRawCountsFromMD::createOutputWorkspace(
     throw std::runtime_error("Failed to create output matrix workspace.");
 
   // Set data
-  outws->setHistogram(0, Points(std::move(vecX)), Counts(std::move(vecY)));
+  outws->setHistogram(0, Points(vecX), Counts(vecY));
   auto &dataE = outws->mutableE(0);
   std::replace_if(dataE.begin(), dataE.end(),
                   [](double val) { return val < 1.0; }, 1.0);
diff --git a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
index 8a47aa239b576e157512bcf8e802893099935d89..bf3e213f13397d9ecb3a0209eb5913c41ddf0765 100644
--- a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp
@@ -68,7 +68,7 @@ void ImportMDHistoWorkspace::exec() {
   }
 
   // Copy each string present in the file stream into a deque.
-  typedef std::deque<std::string> box_collection;
+  using box_collection = std::deque<std::string>;
   box_collection box_elements;
   std::copy(std::istream_iterator<std::string>(file),
             std::istream_iterator<std::string>(),
diff --git a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp
index 7e516c8f36962a81fe8ce232650ef68b475080e3..301bd111b807cbb7b12dd62067a54bbcf7bbea74 100644
--- a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp
@@ -359,9 +359,8 @@ void IntegrateMDHistoWorkspace::exec() {
     PARALLEL_FOR_NO_WSP_CHECK()
     for (int i = 0; i < int(outIterators.size()); ++i) { // NOLINT
       PARALLEL_START_INTERUPT_REGION
-      boost::scoped_ptr<MDHistoWorkspaceIterator> outIterator(
-          dynamic_cast<MDHistoWorkspaceIterator *>(outIterators[i]));
-
+      auto outIterator =
+          dynamic_cast<MDHistoWorkspaceIterator *>(outIterators[i].get());
       if (!outIterator) {
         throw std::logic_error(
             "Failed to cast iterator to MDHistoWorkspaceIterator");
@@ -386,8 +385,10 @@ void IntegrateMDHistoWorkspace::exec() {
         double sumNEvents = 0;
 
         // Create a thread-local input iterator.
-        boost::scoped_ptr<MDHistoWorkspaceIterator> inIterator(
-            dynamic_cast<MDHistoWorkspaceIterator *>(inWS->createIterator()));
+
+        auto iterator = inWS->createIterator();
+        auto inIterator =
+            dynamic_cast<MDHistoWorkspaceIterator *>(iterator.get());
         if (!inIterator) {
           throw std::runtime_error(
               "Could not convert IMDIterator to a MDHistoWorkspaceIterator");
@@ -401,7 +402,7 @@ void IntegrateMDHistoWorkspace::exec() {
         rather than iterating over the full set of boxes of the input workspace.
         */
         inIterator->jumpToNearest(outIteratorCenter);
-        performWeightedSum(inIterator.get(), box, sumSignal, sumSQErrors,
+        performWeightedSum(inIterator, box, sumSignal, sumSQErrors,
                            sumNEvents); // Use the present position. neighbours
                                         // below exclude the current position.
         // Look at all of the neighbours of our position. We previously
@@ -410,7 +411,7 @@ void IntegrateMDHistoWorkspace::exec() {
             inIterator->findNeighbourIndexesByWidth(widthVector);
         for (auto neighbourIndex : neighbourIndexes) {
           inIterator->jumpTo(neighbourIndex); // Go to that neighbour
-          performWeightedSum(inIterator.get(), box, sumSignal, sumSQErrors,
+          performWeightedSum(inIterator, box, sumSignal, sumSQErrors,
                              sumNEvents);
         }
 
diff --git a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
index 9dccb27505ce3f4606fd5d5c930f316f823469c1..2f71a584d41d85065b887f0136c74f9cfd4c6892 100644
--- a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
+++ b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
@@ -210,7 +210,7 @@ void IntegratePeaksCWSD::simplePeakIntegration(
     throw std::runtime_error("MDEventWorkspace is not defined.");
 
   // Go through to get value
-  API::IMDIterator *mditer = m_inputWS->createIterator();
+  auto mditer = m_inputWS->createIterator();
   size_t nextindex = 1;
   bool scancell = true;
   // size_t currindex = 0;
diff --git a/Framework/MDAlgorithms/src/LoadDNSSCD.cpp b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..43f4dc3c7e0b290264b526f552fcd62938e00d6b
--- /dev/null
+++ b/Framework/MDAlgorithms/src/LoadDNSSCD.cpp
@@ -0,0 +1,606 @@
+#include <map>
+#include <iterator>
+#include <iomanip>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/regex.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/exception_ptr.hpp>
+#include <Poco/DateTime.h>
+#include <Poco/DateTimeFormat.h>
+#include <Poco/DateTimeFormatter.h>
+#include <Poco/DirectoryIterator.h>
+#include <Poco/DateTimeParser.h>
+#include <Poco/Path.h>
+#include <Poco/File.h>
+#include "MantidMDAlgorithms/LoadDNSSCD.h"
+#include "MantidAPI/RegisterFileLoader.h"
+#include "MantidAPI/FileProperty.h"
+#include "MantidAPI/MultipleFileProperty.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/ArrayLengthValidator.h"
+#include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/ListValidator.h"
+#include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidKernel/VectorHelper.h"
+#include "MantidDataObjects/MDEventFactory.h"
+#include "MantidAPI/ExperimentInfo.h"
+#include "MantidAPI/Run.h"
+#include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidGeometry/Crystal/IndexingUtils.h"
+#include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/MDGeometry/HKL.h"
+#include "MantidKernel/UnitLabelTypes.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
+
+#include "MantidMDAlgorithms/MDWSDescription.h"
+#include "MantidMDAlgorithms/MDWSTransform.h"
+#include "MantidDataObjects/MDBoxBase.h"
+#include "MantidDataObjects/MDEventInserter.h"
+
+//========================
+// helper functions
+namespace {
+void eraseSubStr(std::string &str, const std::string &toErase) {
+  // Search for the substring in string
+  size_t pos = str.find(toErase);
+  if (pos != std::string::npos) {
+    // If found then erase it from string
+    str.erase(pos, toErase.length());
+  }
+}
+
+std::string parseTime(std::string &str) {
+  // remove unnecessary symbols
+  eraseSubStr(str, "#");
+  eraseSubStr(str, "start");
+  eraseSubStr(str, "stopped");
+  eraseSubStr(str, "at");
+  auto it = std::find_if(str.begin(), str.end(), [](char ch) {
+    return !std::isspace<char>(ch, std::locale::classic());
+  });
+  str.erase(str.begin(), it);
+  using namespace boost::posix_time;
+  // try to parse as a posix time
+  try {
+    auto time = time_from_string(str);
+    return to_iso_extended_string(time);
+  } catch (std::exception &) {
+    int tzd;
+    Poco::DateTime dt;
+    bool ok = Poco::DateTimeParser::tryParse(str, dt, tzd);
+    if (ok) {
+      auto time = Poco::DateTimeFormatter::format(dt, "%Y-%m-%dT%H:%M:%S");
+      return time;
+    }
+    std::string result("");
+    return result;
+  }
+}
+
+} // anonymous namespace
+//============================
+
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+using namespace Mantid::Geometry;
+
+namespace Mantid {
+namespace MDAlgorithms {
+
+DECLARE_FILELOADER_ALGORITHM(LoadDNSSCD)
+
+//----------------------------------------------------------------------------------------------
+/** Constructor
+*/
+LoadDNSSCD::LoadDNSSCD() : m_nDims(3) {}
+
+/**
+* Return the confidence with with 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 LoadDNSSCD::confidence(Kernel::FileDescriptor &descriptor) const {
+  // DNS data acquisition writes ascii files with .d_dat extension
+  int confidence(0);
+  if ((descriptor.extension() == ".d_dat") && descriptor.isAscii()) {
+    confidence = 80;
+  }
+  return confidence;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Initialize the algorithm's properties.
+ */
+void LoadDNSSCD::init() {
+  std::vector<std::string> exts(1, ".d_dat");
+  declareProperty(Kernel::make_unique<MultipleFileProperty>("Filenames", exts),
+                  "Select one or more DNS SCD .d_dat files to load."
+                  "Files must be measured at the same conditions.");
+
+  declareProperty(make_unique<WorkspaceProperty<IMDEventWorkspace>>(
+                      "OutputWorkspace", "", Direction::Output),
+                  "An output MDEventWorkspace.");
+
+  declareProperty(make_unique<WorkspaceProperty<IMDEventWorkspace>>(
+                      "NormalizationWorkspace", "", Direction::Output),
+                  "An output normalization MDEventWorkspace.");
+
+  const std::vector<std::string> normOptions = {"monitor", "time"};
+  declareProperty("Normalization", "monitor",
+                  boost::make_shared<StringListValidator>(normOptions),
+                  "Algorithm will create a separate normalization workspace. "
+                  "Choose whether it should contain monitor counts or time.");
+
+  auto mustBePositive = boost::make_shared<BoundedValidator<double>>();
+  mustBePositive->setLower(0.0);
+  auto reasonableAngle = boost::make_shared<BoundedValidator<double>>();
+  reasonableAngle->setLower(5.0);
+  reasonableAngle->setUpper(175.0);
+  // clang-format off
+  auto mustBe3D = boost::make_shared<ArrayLengthValidator<double> >(3);
+  auto mustBe2D = boost::make_shared<ArrayLengthValidator<double> >(2);
+  // clang-format on
+  std::vector<double> u0(3, 0), v0(3, 0);
+  u0[0] = 1.;
+  u0[1] = 1.;
+  v0[2] = 1.;
+
+  declareProperty(make_unique<PropertyWithValue<double>>(
+                      "a", 1.0, mustBePositive, Direction::Input),
+                  "Lattice parameter a in Angstrom");
+  declareProperty(make_unique<PropertyWithValue<double>>(
+                      "b", 1.0, mustBePositive, Direction::Input),
+                  "Lattice parameter b in Angstrom");
+  declareProperty(make_unique<PropertyWithValue<double>>(
+                      "c", 1.0, mustBePositive, Direction::Input),
+                  "Lattice parameter c in Angstrom");
+  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),
+                  "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>>(
+                      "OmegaOffset", 0.0,
+                      boost::make_shared<BoundedValidator<double>>(),
+                      Direction::Input),
+                  "Angle in degrees between (HKL1) and the beam axis"
+                  "if the goniometer is at zero.");
+  declareProperty(
+      Kernel::make_unique<ArrayProperty<double>>("HKL1", u0, mustBe3D),
+      "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),
+      "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),
+      "Range (min, max) of scattering angles (2theta, in degrees) to consider. "
+      "Everything out of this range will be cut.");
+
+  declareProperty(
+      Kernel::make_unique<WorkspaceProperty<API::ITableWorkspace>>(
+          "LoadHuberFrom", "", Direction::Input, PropertyMode::Optional),
+      "A table workspace to load a list of raw sample rotation angles. "
+      "Huber angles given in the data files will be ignored.");
+
+  declareProperty(
+      Kernel::make_unique<WorkspaceProperty<API::ITableWorkspace>>(
+          "SaveHuberTo", "", Direction::Output, PropertyMode::Optional),
+      "A workspace name to save a list of raw sample rotation angles.");
+}
+
+//----------------------------------------------------------------------------------------------
+/** Read Huber angles from a given table workspace.
+ */
+
+void LoadDNSSCD::loadHuber(ITableWorkspace_sptr tws) {
+  ColumnVector<double> huber = tws->getVector("Huber(degrees)");
+  // set huber[0] for each run in m_data
+  for (auto &ds : m_data) {
+    ds.huber = huber[0];
+  }
+  // dublicate runs for each huber in the table
+  std::vector<ExpData> old(m_data);
+  for (size_t i = 1; i < huber.size(); ++i) {
+    for (auto &ds : old) {
+      ds.huber = huber[i];
+      m_data.push_back(ds);
+    }
+  }
+}
+
+//----------------------------------------------------------------------------------------------
+/** Save Huber angles to a given table workspace.
+ */
+Mantid::API::ITableWorkspace_sptr LoadDNSSCD::saveHuber() {
+  std::vector<double> huber;
+  for (auto ds : m_data)
+    huber.push_back(ds.huber);
+  // remove dublicates
+  std::sort(huber.begin(), huber.end());
+  huber.erase(unique(huber.begin(), huber.end()), huber.end());
+
+  Mantid::API::ITableWorkspace_sptr huberWS =
+      WorkspaceFactory::Instance().createTable("TableWorkspace");
+  huberWS->addColumn("double", "Huber(degrees)");
+  for (size_t i = 0; i < huber.size(); i++) {
+    huberWS->appendRow();
+    huberWS->cell<double>(i, 0) = huber[i];
+  }
+  return huberWS;
+}
+//----------------------------------------------------------------------------------------------
+/** Execute the algorithm.
+ */
+void LoadDNSSCD::exec() {
+  MultipleFileProperty *multiFileProp =
+      dynamic_cast<MultipleFileProperty *>(getPointerToProperty("Filenames"));
+  if (!multiFileProp) {
+    throw std::logic_error(
+        "Filenames property must have MultipleFileProperty type.");
+  }
+  std::vector<std::string> filenames =
+      VectorHelper::flattenVector(multiFileProp->operator()());
+  if (filenames.empty())
+    throw std::invalid_argument("Must specify at least one filename.");
+
+  // set type of normalization
+  std::string normtype = getProperty("Normalization");
+  if (normtype == "monitor") {
+    m_normtype = "Monitor";
+    m_normfactor = 1.0;
+  } else {
+    m_normtype = "Timer";
+    m_normfactor = 0.0; // error for time should be 0
+  }
+
+  g_log.notice() << "The normalization workspace will contain " << m_normtype
+                 << ".\n";
+
+  ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>();
+  API::Run &run = expinfo->mutableRun();
+  for (auto fname : filenames) {
+    std::map<std::string, std::string> str_metadata;
+    std::map<std::string, double> num_metadata;
+    try {
+      read_data(fname, str_metadata, num_metadata);
+      // if no stop_time, take file_save_time
+      std::string time(str_metadata["stop_time"]);
+      if (time.empty()) {
+        g_log.warning()
+            << "stop_time is empty! File save time will be used instead."
+            << std::endl;
+        time = str_metadata["file_save_time"];
+      }
+      updateProperties<std::string>(run, str_metadata, time);
+      updateProperties<double>(run, num_metadata, time);
+    } catch (...) {
+      g_log.warning() << "Failed to read file " << fname;
+      g_log.warning() << ". This file will be ignored. " << std::endl;
+      g_log.debug() << boost::current_exception_diagnostic_information()
+                    << std::endl;
+    }
+  }
+
+  if (m_data.empty())
+    throw std::runtime_error(
+        "No valid DNS files have been provided. Nothing to load.");
+
+  m_OutWS = MDEventFactory::CreateMDWorkspace(m_nDims, "MDEvent");
+
+  m_OutWS->addExperimentInfo(expinfo);
+
+  // load huber angles from a table workspace if given
+  ITableWorkspace_sptr huberWS = getProperty("LoadHuberFrom");
+  if (huberWS) {
+    g_log.notice() << "Huber angles will be loaded from " << huberWS->getName()
+                   << std::endl;
+    loadHuber(huberWS);
+  }
+
+  // get wavelength
+  TimeSeriesProperty<double> *wlprop =
+      dynamic_cast<TimeSeriesProperty<double> *>(
+          expinfo->run().getProperty("Lambda"));
+  // assume, that lambda is in nm
+  double wavelength =
+      wlprop->minValue() * 10.0; // needed to estimate extents => minValue
+  run.addProperty("wavelength", wavelength);
+  run.getProperty("wavelength")->setUnits("Angstrom");
+
+  fillOutputWorkspace(wavelength);
+
+  std::string saveHuberTableWS = getProperty("SaveHuberTo");
+  if (!saveHuberTableWS.empty()) {
+    Mantid::API::ITableWorkspace_sptr huber_table = saveHuber();
+    setProperty("SaveHuberTo", huber_table);
+  }
+  setProperty("OutputWorkspace", m_OutWS);
+}
+
+//----------------------------------------------------------------------------------------------
+
+template <class T>
+void LoadDNSSCD::updateProperties(API::Run &run,
+                                  std::map<std::string, T> &metadata,
+                                  std::string time) {
+  typename std::map<std::string, T>::iterator it = metadata.begin();
+  while (it != metadata.end()) {
+    TimeSeriesProperty<T> *timeSeries(nullptr);
+    std::string name(it->first);
+    std::string units;
+    // std::regex does not work for rhel7, thus boost
+    boost::regex reg("([-_a-zA-Z]+)\\[(.*)]");
+    boost::smatch match;
+    if (boost::regex_search(name, match, reg) && match.size() > 2) {
+      std::string new_name(match.str(1));
+      units.assign(match.str(2));
+      name = new_name;
+    }
+    if (run.hasProperty(name)) {
+      timeSeries = dynamic_cast<TimeSeriesProperty<T> *>(run.getLogData(name));
+      if (!timeSeries)
+        throw std::invalid_argument(
+            "Log '" + name +
+            "' already exists but the values are a different type.");
+    } else {
+      timeSeries = new TimeSeriesProperty<T>(name);
+      if (!units.empty())
+        timeSeries->setUnits(units);
+      run.addProperty(timeSeries);
+    }
+    timeSeries->addValue(time, it->second);
+    ++it;
+  }
+}
+//----------------------------------------------------------------------------------------------
+/// Create output workspace
+void LoadDNSSCD::fillOutputWorkspace(double wavelength) {
+
+  // dimensions
+  std::vector<std::string> vec_ID(3);
+  vec_ID[0] = "H";
+  vec_ID[1] = "K";
+  vec_ID[2] = "L";
+
+  std::vector<std::string> dimensionNames(3);
+  dimensionNames[0] = "H";
+  dimensionNames[1] = "K";
+  dimensionNames[2] = "L";
+
+  Mantid::Kernel::SpecialCoordinateSystem coordinateSystem =
+      Mantid::Kernel::HKL;
+
+  double a, b, c, alpha, beta, gamma;
+  a = getProperty("a");
+  b = getProperty("b");
+  c = getProperty("c");
+  alpha = getProperty("alpha");
+  beta = getProperty("beta");
+  gamma = getProperty("gamma");
+  std::vector<double> u = getProperty("HKL1");
+  std::vector<double> v = getProperty("HKL2");
+
+  // estimate extents
+  double qmax = 4.0 * M_PI / wavelength;
+  std::vector<double> extentMins = {-qmax * a, -qmax * b, -qmax * c};
+  std::vector<double> extentMaxs = {qmax * a, qmax * b, qmax * c};
+
+  // Get MDFrame of HKL type with RLU
+  auto unitFactory = makeMDUnitFactoryChain();
+  auto unit = unitFactory->create(Units::Symbol::RLU.ascii());
+  Mantid::Geometry::HKL frame(unit);
+
+  // add dimensions
+  for (size_t i = 0; i < m_nDims; ++i) {
+    std::string id = vec_ID[i];
+    std::string name = dimensionNames[i];
+    m_OutWS->addDimension(
+        Geometry::MDHistoDimension_sptr(new Geometry::MDHistoDimension(
+            id, name, frame, static_cast<coord_t>(extentMins[i]),
+            static_cast<coord_t>(extentMaxs[i]), 5)));
+  }
+
+  // Set coordinate system
+  m_OutWS->setCoordinateSystem(coordinateSystem);
+
+  // calculate RUB matrix
+  Mantid::Geometry::OrientedLattice o;
+  o = Mantid::Geometry::OrientedLattice(a, b, c, alpha, beta, gamma);
+  o.setUFromVectors(Mantid::Kernel::V3D(u[0], u[1], u[2]),
+                    Mantid::Kernel::V3D(v[0], v[1], v[2]));
+
+  double omega_offset = getProperty("OmegaOffset");
+  omega_offset *= -1.0 * deg2rad;
+  DblMatrix rotm(3, 3);
+  rotm[0][0] = std::cos(omega_offset);
+  rotm[0][1] = 0.0;
+  rotm[0][2] = std::sin(omega_offset);
+  rotm[1][0] = 0.0;
+  rotm[1][1] = 1.0;
+  rotm[1][2] = 0.0;
+  rotm[2][0] = -std::sin(omega_offset);
+  rotm[2][1] = 0.0;
+  rotm[2][2] = std::cos(omega_offset);
+
+  DblMatrix ub(o.getUB());
+  ub = rotm * ub;
+  o.setUB(ub);
+  DblMatrix ub_inv(ub);
+  // invert the UB matrix
+  ub_inv.Invert();
+
+  // Creates a new instance of the MDEventInserter to output workspace
+  MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 =
+      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_OutWS);
+  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);
+
+  // create a normalization workspace
+  IMDEventWorkspace_sptr normWS = m_OutWS->clone();
+
+  // Creates a new instance of the MDEventInserter to norm workspace
+  MDEventWorkspace<MDEvent<3>, 3>::sptr normws_mdevt_3 =
+      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(normWS);
+  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> norm_inserter(
+      normws_mdevt_3);
+
+  // scattering angle limits
+  std::vector<double> tth_limits = getProperty("TwoThetaLimits");
+  double theta_min = tth_limits[0] * deg2rad / 2.0;
+  double theta_max = tth_limits[1] * deg2rad / 2.0;
+
+  // Go though each element of m_data to convert to MDEvent
+  for (ExpData ds : m_data) {
+    uint16_t runindex = 0;
+    signal_t norm_signal(ds.norm);
+    signal_t norm_error = std::sqrt(m_normfactor * norm_signal);
+    double k = 2.0 / ds.wavelength;
+    for (size_t i = 0; i < ds.detID.size(); i++) {
+      signal_t signal(ds.signal[i]);
+      signal_t error = std::sqrt(signal);
+      detid_t detid(ds.detID[i]);
+      double theta = 0.5 * (ds.detID[i] * 5.0 - ds.deterota) * deg2rad;
+      if ((theta > theta_min) && (theta < theta_max)) {
+        double omega = (ds.huber - ds.deterota) * deg2rad - theta;
+        V3D uphi(-cos(omega), 0, -sin(omega));
+        V3D hphi = uphi * k * sin(theta);
+        V3D hkl = ub_inv * hphi;
+        std::vector<Mantid::coord_t> millerindex(3);
+        millerindex[0] = static_cast<float>(hkl.X());
+        millerindex[1] = static_cast<float>(hkl.Y());
+        millerindex[2] = static_cast<float>(hkl.Z());
+        inserter.insertMDEvent(
+            static_cast<float>(signal), static_cast<float>(error * error),
+            static_cast<uint16_t>(runindex), detid, millerindex.data());
+
+        norm_inserter.insertMDEvent(static_cast<float>(norm_signal),
+                                    static_cast<float>(norm_error * norm_error),
+                                    static_cast<uint16_t>(runindex), detid,
+                                    millerindex.data());
+      }
+    }
+  }
+  setProperty("NormalizationWorkspace", normWS);
+}
+
+void LoadDNSSCD::read_data(const std::string fname,
+                           std::map<std::string, std::string> &str_metadata,
+                           std::map<std::string, double> &num_metadata) {
+  std::ifstream file(fname);
+  std::string line;
+  std::string::size_type n;
+  std::string s;
+  boost::regex reg1("^#\\s+(\\w+):(.*)");
+  boost::regex reg2("^#\\s+((\\w+\\s)+)\\s+(-?\\d+(,\\d+)*(\\.\\d+(e\\d+)?)?)");
+  boost::smatch match;
+  getline(file, line);
+  n = line.find("DNS");
+  if (n == std::string::npos) {
+    throw std::invalid_argument("Not a DNS file");
+  }
+  // get file save time
+  Poco::File pfile(fname);
+  Poco::DateTime lastModified = pfile.getLastModified();
+  std::string wtime(
+      Poco::DateTimeFormatter::format(lastModified, "%Y-%m-%dT%H:%M:%S"));
+  str_metadata.insert(std::make_pair("file_save_time", wtime));
+
+  // get file basename
+  Poco::Path p(fname);
+  str_metadata.insert(std::make_pair("run_number", p.getBaseName()));
+
+  // parse metadata
+  while (getline(file, line)) {
+    n = line.find("Lambda");
+    if (n != std::string::npos) {
+      boost::regex re("[\\s]+");
+      s = line.substr(5);
+      boost::sregex_token_iterator it(s.begin(), s.end(), re, -1);
+      boost::sregex_token_iterator reg_end;
+      getline(file, line);
+      std::string s2 = line.substr(2);
+      boost::sregex_token_iterator it2(s2.begin(), s2.end(), re, -1);
+      for (; (it != reg_end) && (it2 != reg_end); ++it) {
+        std::string token(it->str());
+        if (token.find_first_not_of(' ') == std::string::npos) {
+          ++it2;
+          continue;
+        }
+        if (token == "Mono") {
+          str_metadata.insert(std::make_pair(token, it2->str()));
+        } else {
+          num_metadata.insert(std::make_pair(token, std::stod(it2->str())));
+        }
+        ++it2;
+      }
+    }
+    // parse start and stop time
+    n = line.find("start");
+    if (n != std::string::npos) {
+      str_metadata.insert(std::make_pair("start_time", parseTime(line)));
+      getline(file, line);
+      str_metadata.insert(std::make_pair("stop_time", parseTime(line)));
+      getline(file, line);
+    }
+    if (boost::regex_search(line, match, reg1) && match.size() > 2) {
+      str_metadata.insert(std::make_pair(match.str(1), match.str(2)));
+    }
+    if (boost::regex_search(line, match, reg2) && match.size() > 2) {
+      s = match.str(1);
+      s.erase(std::find_if_not(s.rbegin(), s.rend(), ::isspace).base(),
+              s.end());
+      num_metadata.insert(std::make_pair(s, std::stod(match.str(3))));
+    }
+    n = line.find("DATA");
+    if (n != std::string::npos) {
+      break;
+    }
+  }
+
+  // the algorithm does not work with TOF data for the moment
+  std::map<std::string, double>::const_iterator m =
+      num_metadata.lower_bound("TOF");
+  g_log.debug() << "TOF Channels number: " << m->second << std::endl;
+  if (m->second != 1)
+    throw std::runtime_error(
+        "Algorithm does not support TOF data. TOF Channels number must be 1.");
+
+  ExpData ds;
+  ds.deterota = num_metadata["DeteRota"];
+  ds.huber = num_metadata["Huber"];
+  ds.wavelength = 10.0 * num_metadata["Lambda[nm]"];
+  ds.norm = num_metadata[m_normtype];
+
+  // read data array
+  getline(file, line);
+  int d;
+  double x;
+  while (file) {
+    file >> d >> x;
+    ds.detID.push_back(d);
+    ds.signal.push_back(x);
+  }
+  // DNS PA detector bank has only 24 detectors
+  ds.detID.resize(24);
+  ds.signal.resize(24);
+  m_data.push_back(ds);
+}
+
+} // namespace MDAlgorithms
+} // namespace Mantid
diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp
index d96f7c0f220bb2f9204afe90de54de05db5a6033..f587ebb61e0aa5a0ce34e279ca8199bb5514ba0f 100644
--- a/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -31,7 +31,7 @@
 #include <nexus/NeXusException.hpp>
 #include <vector>
 
-typedef std::unique_ptr<Mantid::API::IBoxControllerIO> file_holder_type;
+using file_holder_type = std::unique_ptr<Mantid::API::IBoxControllerIO>;
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/MDAlgorithms/src/LoadSQW2.cpp b/Framework/MDAlgorithms/src/LoadSQW2.cpp
index 2c278d4e528b7f97c41a4ea0b62f9cdd87c8cefe..434846121ae7440bd3df38689bceb32a6137ceee 100644
--- a/Framework/MDAlgorithms/src/LoadSQW2.cpp
+++ b/Framework/MDAlgorithms/src/LoadSQW2.cpp
@@ -91,7 +91,7 @@ void LoadSQW2::init() {
   using namespace API;
   using Kernel::PropertyWithValue;
   using Kernel::StringListValidator;
-  typedef std::initializer_list<std::string> StringInitializerList;
+  using StringInitializerList = std::initializer_list<std::string>;
 
   // Inputs
   declareProperty(
diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
index 11edab9841fc5cd6411738fa4b2e4dea775ac913..c4ca06ff0f135c8685d780fc9b15bcf749480f03 100644
--- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
+++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
@@ -450,7 +450,7 @@ void MDNormDirectSC::calculateNormalization(
                                PhysicalConstants::meV * 1e-20 /
                                (PhysicalConstants::h * PhysicalConstants::h);
   const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0));
-  typedef Kernel::PropertyWithValue<std::vector<double>> VectorDoubleProperty;
+  using VectorDoubleProperty = Kernel::PropertyWithValue<std::vector<double>>;
   auto *rubwLog =
       dynamic_cast<VectorDoubleProperty *>(exptInfoZero.getLog("RUBW_MATRIX"));
   if (!rubwLog) {
diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp
index 3aab5f50c7085dcb9a1bf1e26ce7802c7ebbeb71..2d4d6ba7423387dc9d7c9cc15da572903cf7252f 100644
--- a/Framework/MDAlgorithms/src/MDNormSCD.cpp
+++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp
@@ -403,7 +403,7 @@ void MDNormSCD::calculateNormalization(
       getProperty("SolidAngleWorkspace");
 
   const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0));
-  typedef Kernel::PropertyWithValue<std::vector<double>> VectorDoubleProperty;
+  using VectorDoubleProperty = Kernel::PropertyWithValue<std::vector<double>>;
   auto *rubwLog =
       dynamic_cast<VectorDoubleProperty *>(exptInfoZero.getLog("RUBW_MATRIX"));
   if (!rubwLog) {
diff --git a/Framework/MDAlgorithms/src/MaskMD.cpp b/Framework/MDAlgorithms/src/MaskMD.cpp
index 72970550e3724315c692e698fa3758290d8cffcd..0487f4e75d7712df2775dd2f905af8a208310ca0 100644
--- a/Framework/MDAlgorithms/src/MaskMD.cpp
+++ b/Framework/MDAlgorithms/src/MaskMD.cpp
@@ -28,7 +28,7 @@ std::vector<std::string> parseDimensionNames(const std::string &names_string) {
   // unless they contain square brackets (so that it only matches inner pairs)
   // The second part matches anything that doesn't contain a comma
   // NB, the order of the two parts matters
-  regex expression("\\[([^\\[]*)\\]|[^,]+");
+  regex expression(R"(\[([^\[]*)\]|[^,]+)");
 
   boost::sregex_token_iterator iter(names_string.begin(), names_string.end(),
                                     expression, 0);
diff --git a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp
index aa4e5a9ef975a526d8567f5020f517fe271e2873..1d4d421642d150d48cbfc6bf9832e2c4f48dda9a 100644
--- a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp
+++ b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp
@@ -521,7 +521,6 @@ void TobyFitResolutionModel::preprocess(
   } while (iterator->next());
   g_log.debug() << "Done preprocessing loop:" << timer.elapsed()
                 << " seconds\n";
-  delete iterator;
 }
 
 /**
@@ -597,7 +596,7 @@ void TobyFitResolutionModel::setupRandomNumberGenerator() {
     else if (m_mcType == 4)
       seed = static_cast<size_t>(Poco::Timestamp().epochMicroseconds());
 
-    typedef NDPseudoRandomNumberGenerator<MersenneTwister> NDMersenneTwister;
+    using NDMersenneTwister = NDPseudoRandomNumberGenerator<MersenneTwister>;
     for (size_t i = 0; i < ngenerators; ++i) {
       m_randomNumbers[i] = new NDMersenneTwister(nrand, seed, 0.0, 1.0);
     }
diff --git a/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp b/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp
index c4efecaad073a109ef52bc2805c45f2a8a3307e5..f757691d623114445676a51759b7aedc66911071 100644
--- a/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp
+++ b/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp
@@ -101,7 +101,7 @@ void ResolutionConvolvedCrossSection::function(
         "Expected FunctionDomainMD in ResolutionConvolvedCrossSection");
   }
 
-  std::vector<API::IMDIterator *> iterators = m_inputWS->createIterators(
+  auto iterators = m_inputWS->createIterators(
       API::FrameworkManager::Instance().getNumOMPThreads());
   const int nthreads = static_cast<int>(iterators.size());
   std::vector<size_t> resultOffsets(nthreads, 0);
@@ -126,7 +126,7 @@ void ResolutionConvolvedCrossSection::function(
   bool exceptionThrown = false; // required for *_PARALLEL_* macros
   PARALLEL_FOR_NO_WSP_CHECK()
   for (int i = 0; i < nthreads; ++i) {
-    API::IMDIterator *boxIterator = iterators[i];
+    auto &boxIterator = iterators[i];
     const size_t resultsOffset = resultOffsets[i];
 
     size_t boxIndex(0);
@@ -141,10 +141,6 @@ void ResolutionConvolvedCrossSection::function(
     } while (boxIterator->next());
   }
   CHECK_PARALLEL_EXCEPTIONS // Not standard macros. See top of file for reason
-
-      for (auto boxIterator : iterators) {
-    delete boxIterator;
-  }
 }
 
 /**
diff --git a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
index 4b5f8a242bfe6f39a36f674524c422631b20ad3a..a008b064c2a8eda56ea21430c67aa680f6290b64 100644
--- a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
@@ -211,7 +211,7 @@ void QueryMDWorkspace::exec() {
   output->getColumn(signalColumnName)->setPlotType(2);
   output->getColumn(errorColumnName)->setPlotType(5);
 
-  IMDIterator *it = input->createIterator();
+  auto it = input->createIterator();
   it->setNormalization(requestedNormalisation);
 
   bool bLimitRows = getProperty("LimitRows");
@@ -251,7 +251,6 @@ void QueryMDWorkspace::exec() {
     rowCounter++;
   }
   setProperty("OutputWorkspace", output);
-  delete it;
 
   //
   IMDEventWorkspace_sptr mdew;
diff --git a/Framework/MDAlgorithms/src/ReplicateMD.cpp b/Framework/MDAlgorithms/src/ReplicateMD.cpp
index 9966a1f2210600af0078ed386607611240c9c20a..70133087d62a33bd88dbe74feb2b7fc25950d9ae 100644
--- a/Framework/MDAlgorithms/src/ReplicateMD.cpp
+++ b/Framework/MDAlgorithms/src/ReplicateMD.cpp
@@ -339,9 +339,6 @@ void ReplicateMD::exec() {
 
   // Create the output workspace from the shape.
   MDHistoWorkspace_sptr outputWS(shapeWS->clone());
-  auto outIt = std::unique_ptr<MDHistoWorkspaceIterator>(
-      dynamic_cast<MDHistoWorkspaceIterator *>(outputWS->createIterator()));
-
   const int nThreads = Mantid::API::FrameworkManager::Instance()
                            .getNumOMPThreads(); // NThreads to Request
 
@@ -352,8 +349,7 @@ void ReplicateMD::exec() {
   for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT
 
     PARALLEL_START_INTERUPT_REGION
-    auto outIt = std::unique_ptr<MDHistoWorkspaceIterator>(
-        dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it]));
+    auto outIt = dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get());
 
     // Iterate over the output workspace
     do {
diff --git a/Framework/MDAlgorithms/src/SaveMD.cpp b/Framework/MDAlgorithms/src/SaveMD.cpp
index d82bd5c0c9632ea845bd9caa5cc364d8e444d5d8..9461c7ac2a76cb36ce72f8a66a1a0178ad06e2ee 100644
--- a/Framework/MDAlgorithms/src/SaveMD.cpp
+++ b/Framework/MDAlgorithms/src/SaveMD.cpp
@@ -17,7 +17,7 @@
 #include "MantidKernel/System.h"
 #include <Poco/File.h>
 
-typedef std::unique_ptr<::NeXus::File> file_holder_type;
+using file_holder_type = std::unique_ptr<::NeXus::File>;
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp
index b9d3f5203375d4cbac0a080ea413814ef3702e75..6f5717415df4da2a482a329c18c93626eb88005d 100644
--- a/Framework/MDAlgorithms/src/SaveMD2.cpp
+++ b/Framework/MDAlgorithms/src/SaveMD2.cpp
@@ -18,7 +18,7 @@
 #include "MantidDataObjects/BoxControllerNeXusIO.h"
 #include "MantidKernel/ConfigService.h"
 
-typedef std::unique_ptr<::NeXus::File> file_holder_type;
+using file_holder_type = std::unique_ptr<::NeXus::File>;
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/MDAlgorithms/src/SmoothMD.cpp b/Framework/MDAlgorithms/src/SmoothMD.cpp
index 2b84722ff26cba35ece324fd945a1bac478106d5..33c3258aded9747a45c0ac00546bfe026edbd6ad 100644
--- a/Framework/MDAlgorithms/src/SmoothMD.cpp
+++ b/Framework/MDAlgorithms/src/SmoothMD.cpp
@@ -30,22 +30,22 @@ using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
 // Typedef for width vector
-typedef std::vector<double> WidthVector;
+using WidthVector = std::vector<double>;
 
 // Typedef for kernel vector
-typedef std::vector<double> KernelVector;
+using KernelVector = std::vector<double>;
 
 // Typedef for an optional md histo workspace
-typedef boost::optional<IMDHistoWorkspace_const_sptr>
-    OptionalIMDHistoWorkspace_const_sptr;
+using OptionalIMDHistoWorkspace_const_sptr =
+    boost::optional<IMDHistoWorkspace_const_sptr>;
 
 // Typedef for a smoothing function
-typedef boost::function<IMDHistoWorkspace_sptr(
+using SmoothFunction = boost::function<IMDHistoWorkspace_sptr(
     IMDHistoWorkspace_const_sptr, const WidthVector &,
-    OptionalIMDHistoWorkspace_const_sptr)> SmoothFunction;
+    OptionalIMDHistoWorkspace_const_sptr)>;
 
 // Typedef for a smoothing function map keyed by name.
-typedef std::map<std::string, SmoothFunction> SmoothFunctionMap;
+using SmoothFunctionMap = std::map<std::string, SmoothFunction>;
 
 namespace {
 
@@ -192,8 +192,8 @@ SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth,
   for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT
 
     PARALLEL_START_INTERUPT_REGION
-    boost::scoped_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it]));
+    auto iterator =
+        dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get());
 
     if (!iterator) {
       throw std::logic_error(
@@ -318,9 +318,8 @@ SmoothMD::gaussianSmooth(IMDHistoWorkspace_const_sptr toSmooth,
     for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT
 
       PARALLEL_START_INTERUPT_REGION
-      boost::scoped_ptr<MDHistoWorkspaceIterator> iterator(
-          dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it]));
-
+      auto iterator =
+          dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get());
       if (!iterator) {
         throw std::logic_error(
             "Failed to cast IMDIterator to MDHistoWorkspaceIterator");
diff --git a/Framework/MDAlgorithms/src/TransposeMD.cpp b/Framework/MDAlgorithms/src/TransposeMD.cpp
index 81cebe92560b7f0a4e36d261734a3fe832ac01e3..6f5d7b219a14653b8aebf2a28cc426b9b36ad8d8 100644
--- a/Framework/MDAlgorithms/src/TransposeMD.cpp
+++ b/Framework/MDAlgorithms/src/TransposeMD.cpp
@@ -132,7 +132,7 @@ void TransposeMD::exec() {
   for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT
 
     PARALLEL_START_INTERUPT_REGION
-    auto inIterator = std::unique_ptr<IMDIterator>(iterators[it]);
+    auto inIterator = iterators[it].get();
     do {
       auto center = inIterator->getCenter();
       const coord_t *incoords = center.getBareArray();
diff --git a/Framework/MDAlgorithms/src/WeightedMeanMD.cpp b/Framework/MDAlgorithms/src/WeightedMeanMD.cpp
index 89f05670921a5a1070bcd2e8754b1cf358b5305c..8f301e9faa4dc5abf88b1b2e10b98eacae6af552 100644
--- a/Framework/MDAlgorithms/src/WeightedMeanMD.cpp
+++ b/Framework/MDAlgorithms/src/WeightedMeanMD.cpp
@@ -28,10 +28,10 @@ void WeightedMeanMD::execHistoHisto(
     Mantid::DataObjects::MDHistoWorkspace_sptr out,
     Mantid::DataObjects::MDHistoWorkspace_const_sptr operand) {
   using DataObjects::MDHistoWorkspaceIterator;
-  MDHistoWorkspaceIterator *lhs_it =
-      dynamic_cast<MDHistoWorkspaceIterator *>(out->createIterator());
-  MDHistoWorkspaceIterator *rhs_it =
-      dynamic_cast<MDHistoWorkspaceIterator *>(operand->createIterator());
+  auto lhs = out->createIterator();
+  auto lhs_it = dynamic_cast<MDHistoWorkspaceIterator *>(lhs.get());
+  auto rhs = operand->createIterator();
+  auto rhs_it = dynamic_cast<MDHistoWorkspaceIterator *>(rhs.get());
 
   if (!lhs_it || !rhs_it) {
     throw std::logic_error("Histo iterators have wrong type.");
@@ -63,9 +63,6 @@ void WeightedMeanMD::execHistoHisto(
     out->setSignalAt(pos, signal);
     out->setErrorSquaredAt(pos, error_sq);
   } while (lhs_it->next() && rhs_it->next());
-
-  delete lhs_it;
-  delete rhs_it;
 }
 
 //----------------------------------------------------------------------------------------------
diff --git a/Framework/MDAlgorithms/test/BinMDTest.h b/Framework/MDAlgorithms/test/BinMDTest.h
index 38d16b0b854d5c275797de94c6b9872e34d4acdf..980e8d0b7b4a9b5e64772d2a4d7352c46caafd9e 100644
--- a/Framework/MDAlgorithms/test/BinMDTest.h
+++ b/Framework/MDAlgorithms/test/BinMDTest.h
@@ -1111,7 +1111,7 @@ public:
   BinMDTestPerformance() {
     in_ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 0);
     in_ws->getBoxController()->setSplitThreshold(2000);
-    in_ws->splitAllIfNeeded(NULL);
+    in_ws->splitAllIfNeeded(nullptr);
     AnalysisDataService::Instance().addOrReplace("BinMDTest_ws", in_ws);
     FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace",
                                       "BinMDTest_ws", "UniformParams",
diff --git a/Framework/MDAlgorithms/test/CentroidPeaksMD2Test.h b/Framework/MDAlgorithms/test/CentroidPeaksMD2Test.h
index 623734fab3eac39bd5d4f4b252a581abaadec2b1..06e5d3b687398c1120c4c7e4e6230385ecd73831 100644
--- a/Framework/MDAlgorithms/test/CentroidPeaksMD2Test.h
+++ b/Framework/MDAlgorithms/test/CentroidPeaksMD2Test.h
@@ -17,11 +17,6 @@
 
 #include <boost/math/distributions/normal.hpp>
 #include <boost/math/special_functions/pow.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/MDAlgorithms/test/CentroidPeaksMDTest.h b/Framework/MDAlgorithms/test/CentroidPeaksMDTest.h
index 4831cc20df05e15629f62b3af8ae75400432ae69..2d0ba871df1066824390f63f15fa5968aef9f9c6 100644
--- a/Framework/MDAlgorithms/test/CentroidPeaksMDTest.h
+++ b/Framework/MDAlgorithms/test/CentroidPeaksMDTest.h
@@ -17,11 +17,6 @@
 
 #include <boost/math/distributions/normal.hpp>
 #include <boost/math/special_functions/pow.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
index 9877a870eddfe7e61d0833a6d7fe69f9efaf572e..64ae9fa681f58d894ee93cfd3537deb93407c028 100644
--- a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
+++ b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
@@ -118,7 +118,7 @@ public:
             AnalysisDataService::Instance().retrieve("QSampleMDEvents"));
     TS_ASSERT(outws);
 
-    IMDIterator *mditer = outws->createIterator();
+    auto mditer = outws->createIterator();
     TS_ASSERT_EQUALS(mditer->getNumEvents(), 7400);
 
     size_t numexpinfo = outws->getNumExperimentInfo();
@@ -157,7 +157,7 @@ public:
             AnalysisDataService::Instance().retrieve("QSampleMDEvents"));
     TS_ASSERT(outws);
 
-    IMDIterator *mditer = outws->createIterator();
+    auto mditer = outws->createIterator();
     TS_ASSERT_EQUALS(mditer->getNumEvents(), 7400);
 
     size_t numexpinfo = outws->getNumExperimentInfo();
diff --git a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
index d01934b1b6b2ab1458063f4f3c8399818292f018..8a762208e6c01fa650e82cf87f7c6ef44d17dfb7 100644
--- a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
+++ b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
@@ -143,7 +143,7 @@ public:
     size_t numevents = mdws->getNEvents();
     TS_ASSERT_EQUALS(numevents, 44 * 61);
 
-    IMDIterator *mditer = mdws->createIterator();
+    auto mditer = mdws->createIterator();
     TS_ASSERT_EQUALS(mditer->getNumEvents(), 44 * 61);
 
     double y0 = mditer->getInnerSignal(0);
@@ -333,7 +333,7 @@ public:
     size_t numevents = mdws->getNEvents();
     TS_ASSERT_EQUALS(numevents, 44 * 61);
 
-    IMDIterator *mditer = mdws->createIterator();
+    auto mditer = mdws->createIterator();
     TS_ASSERT_EQUALS(mditer->getNumEvents(), 44 * 61);
 
     double y0 = mditer->getInnerSignal(0);
diff --git a/Framework/MDAlgorithms/test/ConvertToMDTest.h b/Framework/MDAlgorithms/test/ConvertToMDTest.h
index f57e4376c944aa021724d19dcf412ff86c9d4f71..e92accccc487169cd17f34a450b72cc281651265 100644
--- a/Framework/MDAlgorithms/test/ConvertToMDTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToMDTest.h
@@ -76,7 +76,7 @@ public:
   static ConvertToMDTest *createSuite() { return new ConvertToMDTest(); }
   static void destroySuite(ConvertToMDTest *suite) { delete suite; }
 
-  typedef std::vector<std::string> PropertyAllowedValues;
+  using PropertyAllowedValues = std::vector<std::string>;
 
   void testInit() {
 
diff --git a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
index 5f44b55e93d9b9bb4cd01fa0cca8884624f1492c..449ff78025603b89372dac9fc76002af02a12c22 100644
--- a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
@@ -153,7 +153,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     TS_ASSERT_EQUALS(2, ws->getExperimentInfo(0)->run().getLogData().size());
     // Assert that dimensions should be a general frame
     const auto &frame0 = ws->getDimension(0)->getMDFrame();
@@ -170,7 +170,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     // Assert that dimensions should be a general frame
     const auto &frame0 = ws->getDimension(0)->getMDFrame();
     TSM_ASSERT_EQUALS("Should be a general frame", "KiKf", frame0.name());
@@ -185,7 +185,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     // Assert that dimensions should be a general frame
     const auto &frame0 = ws->getDimension(0)->getMDFrame();
     TSM_ASSERT_EQUALS("Should be a general frame", "P", frame0.name());
@@ -201,7 +201,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     TS_ASSERT_EQUALS(2, ws->run().getLogData().size());
   }
 
@@ -213,7 +213,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     TS_ASSERT_EQUALS(2, ws->run().getLogData().size());
   }
 
@@ -225,7 +225,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
     TS_ASSERT_EQUALS(2, ws->getExperimentInfo(0)->run().getLogData().size());
   }
 
@@ -236,7 +236,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
   }
 
   void test_execute_pipf_2D() {
@@ -246,7 +246,7 @@ public:
     auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
         Mantid::API::AnalysisDataService::Instance().retrieve(
             "OutputTransformedWorkspace"));
-    TS_ASSERT(ws != NULL);
+    TS_ASSERT(ws != nullptr);
   }
 
   void test_box_controller_defaults() {
@@ -342,7 +342,7 @@ public:
     IMDWorkspace_sptr out =
         AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(
             "OutputTransformedWorkspace");
-    TS_ASSERT(out != NULL);
+    TS_ASSERT(out != nullptr);
     TS_ASSERT_EQUALS(out->getNumDims(), 2);
   }
 
@@ -363,7 +363,7 @@ public:
     auto out = AnalysisDataService::Instance()
                    .retrieveWS<Mantid::DataObjects::Workspace2D>(
                        "OutputTransformedWorkspace");
-    TS_ASSERT(out != NULL);
+    TS_ASSERT(out != nullptr);
     TS_ASSERT_EQUALS(out->getNumDims(), 2);
   }
 };
diff --git a/Framework/MDAlgorithms/test/DivideMDTest.h b/Framework/MDAlgorithms/test/DivideMDTest.h
index 611b11c15421192bfe87cac895d7ccf8a322eb27..fdc2633896f0218d7866d4f7eac9e22473ebc362 100644
--- a/Framework/MDAlgorithms/test/DivideMDTest.h
+++ b/Framework/MDAlgorithms/test/DivideMDTest.h
@@ -64,7 +64,7 @@ public:
     TS_ASSERT(ws);
     if (!ws)
       return;
-    IMDIterator *it = ws->createIterator(NULL);
+    auto it = ws->createIterator(nullptr);
     do {
       TS_ASSERT_EQUALS(it->getNumEvents(), 1);
       TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5);
diff --git a/Framework/MDAlgorithms/test/FakeMDEventDataTest.h b/Framework/MDAlgorithms/test/FakeMDEventDataTest.h
index fbb8c4be9ccf660d5174a60dc696d9fd0c684a80..3c31fbcb333abcde2731b13ba16f513a017b651b 100644
--- a/Framework/MDAlgorithms/test/FakeMDEventDataTest.h
+++ b/Framework/MDAlgorithms/test/FakeMDEventDataTest.h
@@ -192,8 +192,8 @@ public:
 
     TS_ASSERT_EQUALS(1000, inWS->getNEvents());
 
-    Mantid::detid_t expectedIDs[10] = {106, 255, 184, 238, 0,
-                                       32,  77,  255, 37,  60};
+    Mantid::detid_t expectedIDs[10] = {37,  235, 140, 72, 255,
+                                       137, 203, 133, 79, 192};
     auto it = inWS->createIterator();
     size_t counter(0);
     while (counter < 10) {
@@ -202,8 +202,6 @@ public:
       it->next();
       ++counter;
     }
-
-    delete it;
   }
 };
 
diff --git a/Framework/MDAlgorithms/test/FitMDTest.h b/Framework/MDAlgorithms/test/FitMDTest.h
index d0f7421baa938e1583f4958a3d6cadc32519b6f9..19d2f93a23b801b6c1a67a0e2fe197b6100c44ae 100644
--- a/Framework/MDAlgorithms/test/FitMDTest.h
+++ b/Framework/MDAlgorithms/test/FitMDTest.h
@@ -36,9 +36,11 @@ public:
   signal_t getNormalizedError() const override;
   signal_t getSignal() const override { return 0; }
   signal_t getError() const override { return 0; }
-  coord_t *getVertexesArray(size_t &) const override { return nullptr; }
-  coord_t *getVertexesArray(size_t &, const size_t,
-                            const bool *) const override {
+  std::unique_ptr<coord_t[]> getVertexesArray(size_t &) const override {
+    return nullptr;
+  }
+  std::unique_ptr<coord_t[]> getVertexesArray(size_t &, const size_t,
+                                              const bool *) const override {
     return nullptr;
   }
   Mantid::Kernel::VMD getCenter() const override;
@@ -69,10 +71,15 @@ public:
 
 class IMDWorkspaceTester : public WorkspaceTester {
 public:
-  std::vector<IMDIterator *>
+  std::vector<std::unique_ptr<IMDIterator>>
   createIterators(size_t,
                   Mantid::Geometry::MDImplicitFunction *) const override {
-    return std::vector<IMDIterator *>(1, new IMDWorkspaceTesterIterator(this));
+
+    std::vector<std::unique_ptr<IMDIterator>> ret;
+    auto ptr = std::unique_ptr<IMDIterator>{
+        Kernel::make_unique<IMDWorkspaceTesterIterator>(this)};
+    ret.push_back(std::move(ptr));
+    return ret;
   }
 };
 
diff --git a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
index 37c2318fa5352feee95277880e293b85f552eb71..17a8ae84fcd21b3770370b35e1e5391a094dbb56 100644
--- a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
@@ -228,7 +228,7 @@ public:
     IMDHistoWorkspace_sptr outWs =
         boost::dynamic_pointer_cast<IMDHistoWorkspace>(
             ADS.retrieve("test_workspace"));
-    TS_ASSERT(outWs != NULL);
+    TS_ASSERT(outWs != nullptr);
 
     // Check the dimensionality
     TS_ASSERT_EQUALS(2, outWs->getNumDims());
@@ -290,7 +290,7 @@ public:
     IMDHistoWorkspace_sptr outWs =
         boost::dynamic_pointer_cast<IMDHistoWorkspace>(
             ADS.retrieve("test_workspace"));
-    TS_ASSERT(outWs != NULL);
+    TS_ASSERT(outWs != nullptr);
 
     // Check the dimensionality
     TS_ASSERT_EQUALS(3, outWs->getNumDims());
diff --git a/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h b/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h
index fab29d9e8a741fd4814e35f6ea18b0edf0cfc66a..fe9bf5388d820f52ec0824178d292da9f6b0a4e5 100644
--- a/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h
+++ b/Framework/MDAlgorithms/test/IntegratePeaksMD2Test.h
@@ -19,12 +19,8 @@
 
 #include <boost/math/distributions/normal.hpp>
 #include <boost/math/special_functions/pow.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 
+#include <random>
 #include <cxxtest/TestSuite.h>
 
 #include <Poco/File.h>
@@ -477,17 +473,15 @@ public:
     Instrument_sptr inst =
         ComponentCreationHelper::createTestInstrumentCylindrical(5);
 
-    boost::mt19937 rng;
-    boost::uniform_real<double> u(-9.0, 9.0); // Random from -9 to 9.0
-    boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>> gen(
-        rng, u);
+    std::mt19937 rng;
+    std::uniform_real_distribution<double> flat(-9.0, 9.0);
 
     peakWS = PeaksWorkspace_sptr(new PeaksWorkspace());
     for (size_t i = 0; i < numPeaks; ++i) {
       // Random peak center
-      double x = gen();
-      double y = gen();
-      double z = gen();
+      double x = flat(rng);
+      double y = flat(rng);
+      double z = flat(rng);
 
       // Make the peak
       IntegratePeaksMD2Test::addPeak(1000, x, y, z, 0.02);
@@ -500,9 +494,6 @@ public:
 
       // Add to peaks workspace
       peakWS->addPeak(Peak(inst, 1, 1.0, V3D(x, y, z)));
-
-      if (i % 100 == 0)
-        std::cout << "Peak " << i << " added\n";
     }
     AnalysisDataService::Instance().add("IntegratePeaksMD2Test_peaks", peakWS);
   }
diff --git a/Framework/MDAlgorithms/test/IntegratePeaksMDHKLTest.h b/Framework/MDAlgorithms/test/IntegratePeaksMDHKLTest.h
index d6046fe697222d64f7b8a1582293d749517c2432..06b499f2dd9288e816b4ed579b81f99465478c79 100644
--- a/Framework/MDAlgorithms/test/IntegratePeaksMDHKLTest.h
+++ b/Framework/MDAlgorithms/test/IntegratePeaksMDHKLTest.h
@@ -17,11 +17,6 @@
 
 #include <boost/math/distributions/normal.hpp>
 #include <boost/math/special_functions/pow.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
 
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h b/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h
index 1fba5a48746e0aad33ed424eb0944d164f3a538d..bc95ba22d2e50c1f460f2785f54659a182054f8b 100644
--- a/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h
+++ b/Framework/MDAlgorithms/test/IntegratePeaksMDTest.h
@@ -18,12 +18,7 @@
 
 #include <boost/math/distributions/normal.hpp>
 #include <boost/math/special_functions/pow.hpp>
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
-
+#include <random>
 #include <cxxtest/TestSuite.h>
 
 #include <Poco/File.h>
@@ -447,17 +442,16 @@ public:
     Instrument_sptr inst =
         ComponentCreationHelper::createTestInstrumentCylindrical(5);
 
-    boost::mt19937 rng;
-    boost::uniform_real<double> u(-9.0, 9.0); // Random from -9 to 9.0
-    boost::variate_generator<boost::mt19937 &, boost::uniform_real<double>> gen(
-        rng, u);
+    std::mt19937 rng;
+    std::uniform_real_distribution<double> flat(-9.0,
+                                                9.0); // Random from -9 to 9.0
 
     peakWS = PeaksWorkspace_sptr(new PeaksWorkspace());
     for (size_t i = 0; i < numPeaks; ++i) {
       // Random peak center
-      double x = gen();
-      double y = gen();
-      double z = gen();
+      double x = flat(rng);
+      double y = flat(rng);
+      double z = flat(rng);
 
       // Make the peak
       IntegratePeaksMDTest::addPeak(1000, x, y, z, 0.02);
@@ -470,9 +464,6 @@ public:
 
       // Add to peaks workspace
       peakWS->addPeak(Peak(inst, 1, 1.0, V3D(x, y, z)));
-
-      if (i % 100 == 0)
-        std::cout << "Peak " << i << " added\n";
     }
     AnalysisDataService::Instance().add("IntegratePeaksMDTest_peaks", peakWS);
   }
diff --git a/Framework/MDAlgorithms/test/LoadDNSSCDTest.h b/Framework/MDAlgorithms/test/LoadDNSSCDTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e2d0b2c31fe30ae03b9eeddb6245804ea92e290
--- /dev/null
+++ b/Framework/MDAlgorithms/test/LoadDNSSCDTest.h
@@ -0,0 +1,707 @@
+#ifndef MANTID_MDALGORITHMS_LOADDNSSCDEWTEST_H_
+#define MANTID_MDALGORITHMS_LOADDNSSCDEWTEST_H_
+
+#include "MantidKernel/Strings.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/IMDIterator.h"
+#include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidDataObjects/MDBox.h"
+#include "MantidDataObjects/MDGridBox.h"
+#include "MantidDataObjects/MDEventFactory.h"
+#include "MantidDataObjects/MDEventWorkspace.h"
+#include "MantidAPI/BoxController.h"
+#include "MantidGeometry/MDGeometry/HKL.h"
+#include "MantidAPI/ExperimentInfo.h"
+#include "MantidAPI/Run.h"
+#include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidMDAlgorithms/LoadDNSSCD.h"
+#include <cxxtest/TestSuite.h>
+
+using namespace Mantid;
+using namespace Mantid::Kernel;
+using namespace Mantid::API;
+using namespace Mantid::DataObjects;
+using namespace Mantid::MDAlgorithms;
+
+class LoadDNSSCDTest : 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 LoadDNSSCDTest *createSuite() { return new LoadDNSSCDTest(); }
+  static void destroySuite(LoadDNSSCDTest *suite) { delete suite; }
+
+  LoadDNSSCDTest() : m_fileName("dn134011vana.d_dat") {}
+
+  void test_Init() {
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+  }
+
+  void test_Name() {
+    LoadDNSSCD alg;
+    TS_ASSERT_EQUALS(alg.name(), "LoadDNSSCD");
+  }
+
+  void test_Metadata() {
+    // test whether the metadata were loaded correctly
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+    TS_ASSERT_EQUALS(iws->getNumExperimentInfo(), 1);
+
+    ExperimentInfo_sptr expinfo = iws->getExperimentInfo(0);
+    auto &run = expinfo->run();
+    double d(1e-05);
+    TS_ASSERT_DELTA(run.getPropertyValueAsType<double>("wavelength"), 4.2, d);
+    TimeSeriesProperty<double> *p =
+        dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Lambda"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.42, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Energy"));
+    TS_ASSERT_DELTA(p->firstValue(), 4.640, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Speed"));
+    TS_ASSERT_DELTA(p->firstValue(), 949.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("DeteRota"));
+    TS_ASSERT_DELTA(p->firstValue(), -8.54, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Huber"));
+    TS_ASSERT_DELTA(p->firstValue(), 79.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(
+        run.getProperty("Flipper_precession"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.970, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(
+        run.getProperty("Flipper_z_compensation"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.400, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("C_a"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("C_b"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.110, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("C_c"));
+    TS_ASSERT_DELTA(p->firstValue(), -0.500, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("C_z"));
+    TS_ASSERT_DELTA(p->firstValue(), 0.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("T1"));
+    TS_ASSERT_DELTA(p->firstValue(), 295.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("T2"));
+    TS_ASSERT_DELTA(p->firstValue(), 296.477, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(
+        run.getProperty("sample_setpoint"));
+    TS_ASSERT_DELTA(p->firstValue(), 295.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Timer"));
+    TS_ASSERT_DELTA(p->firstValue(), 600.0, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(run.getProperty("Monitor"));
+    TS_ASSERT_DELTA(p->firstValue(), 8332872, d);
+    p = dynamic_cast<TimeSeriesProperty<double> *>(
+        run.getProperty("TOF channels"));
+    TS_ASSERT_DELTA(p->firstValue(), 1.0, d);
+    TimeSeriesProperty<std::string> *s =
+        dynamic_cast<TimeSeriesProperty<std::string> *>(
+            run.getProperty("start_time"));
+    TS_ASSERT_EQUALS(s->firstValue(), "2013-04-16T16:11:02");
+    s = dynamic_cast<TimeSeriesProperty<std::string> *>(
+        run.getProperty("stop_time"));
+    TS_ASSERT_EQUALS(s->firstValue(), "2013-04-16T16:21:03");
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
+  void test_DataWSStructure() {
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+
+    TS_ASSERT_EQUALS(iws->getNumDims(), 3);
+    TS_ASSERT_EQUALS(iws->getNPoints(), 24);
+    TS_ASSERT_EQUALS(iws->id(), "MDEventWorkspace<MDEvent,3>");
+
+    // test box controller
+    BoxController_sptr bc = iws->getBoxController();
+    TS_ASSERT(bc);
+    TS_ASSERT_EQUALS(bc->getNumMDBoxes().size(), 6);
+
+    // test dimensions
+    std::vector<std::string> v = {"H", "K", "L"};
+    for (auto i = 0; i < 3; i++) {
+      auto dim = iws->getDimension(i);
+      TS_ASSERT(dim);
+      TS_ASSERT_EQUALS(dim->getName(), v[i]);
+      TS_ASSERT_EQUALS(dim->getNBins(), 5);
+      double d(1.0e-05);
+      TS_ASSERT_DELTA(dim->getMinimum(), -2.991993, d);
+      TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d);
+    }
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
+  void test_DataWS() {
+    // test whether the metadata were loaded correctly
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 4.77));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", -43.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+
+    std::vector<API::IMDNode *> boxes(0, NULL);
+    iws->getBoxes(boxes, 10000, false);
+    TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1);
+    API::IMDNode *box = boxes[0];
+    // there are 24 points in the data file
+    TS_ASSERT_EQUALS(box->getNPoints(), 24);
+    std::vector<coord_t> events;
+    size_t ncols;
+    box->getEventsData(events, ncols);
+    // 7 columns: I, err^2, run_num, det_id, h, k, l
+    TS_ASSERT_EQUALS(ncols, 7);
+    // 7*24 = 168
+    TS_ASSERT_EQUALS(events.size(), 168);
+    // reference vector
+    const std::vector<coord_t> ref = {
+        4366, 4366, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, 31461, 31461,
+        0, 1, -0.15959044f, -0.15959044f, 0.14884006f, 33314, 33314, 0, 2,
+        -0.224231616093f, -0.224231616093f, 0.189927174618f, 32369, 32369, 0, 3,
+        -0.291194311172f, -0.291194311172f, 0.223000198347f, 31851, 31851, 0, 4,
+        -0.359968893923f, -0.359968893923f, 0.247807429194f, 30221, 30221, 0, 5,
+        -0.430031948245f, -0.430031948245f, 0.264160069153f, 26267, 26267, 0, 6,
+        -0.500850251989f, -0.500850251989f, 0.271933664761f, 26788, 26788, 0, 7,
+        -0.571884835101f, -0.571884835101f, 0.27106905426f, 29729, 29729, 0, 8,
+        -0.642595081514f, -0.642595081514f, 0.26157281786f, 30188, 30188, 0, 9,
+        -0.712442843555f, -0.712442843555f, 0.243517227652f, 28116, 28116, 0,
+        10, -0.78089653758f, -0.78089653758f, 0.217039697581f, 30277, 30277, 0,
+        11, -0.847435189645f, -0.847435189645f, 0.182341737639f, 20231, 20231,
+        0, 12, -0.911552400429f, -0.911552400429f, 0.13968742025f, 24538, 24538,
+        0, 13, -0.972760199244f, -0.972760199244f, 0.089401370527f, 16416,
+        16416, 0, 14, -1.03059275778f, -1.03059275778f, 0.0318662956709f, 20225,
+        20225, 0, 15, -1.08460993535f, -1.08460993535f, -0.0324799276578f,
+        19957, 19957, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f,
+        19570, 19570, 0, 17, -1.17958590034f, -1.17958590034f, -0.179598855345f,
+        20743, 20743, 0, 18, -1.21982186332f, -1.21982186332f, -0.261251895832f,
+        22758, 22758, 0, 19, -1.25480229757f, -1.25480229757f, -0.347485278364f,
+        23001, 23001, 0, 20, -1.28426098088f, -1.28426098088f, -0.437642714831f,
+        21836, 21836, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f,
+        23877, 23877, 0, 22, -1.32576003133f, -1.32576003133f, -0.626960497068f,
+        13340, 13340, 0, 23, -1.33748456564f, -1.33748456564f,
+        -0.724680020201f};
+    double d(1.0e-06);
+    for (auto i = 0; i < 168; i++) {
+      TS_ASSERT_DELTA(events[i], ref[i], d);
+    }
+
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
+  void test_NormWSStructure() {
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr nws;
+    TS_ASSERT_THROWS_NOTHING(
+        nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            normWSName));
+    TS_ASSERT(nws);
+
+    TS_ASSERT_EQUALS(nws->getNumDims(), 3);
+    TS_ASSERT_EQUALS(nws->getNPoints(), 24);
+    TS_ASSERT_EQUALS(nws->id(), "MDEventWorkspace<MDEvent,3>");
+
+    // test box controller
+    BoxController_sptr bc = nws->getBoxController();
+    TS_ASSERT(bc);
+    TS_ASSERT_EQUALS(bc->getNumMDBoxes().size(), 6);
+
+    // test dimensions
+    std::vector<std::string> v = {"H", "K", "L"};
+    for (auto i = 0; i < 3; i++) {
+      auto dim = nws->getDimension(i);
+      TS_ASSERT(dim);
+      TS_ASSERT_EQUALS(dim->getName(), v[i]);
+      TS_ASSERT_EQUALS(dim->getNBins(), 5);
+      double d(1.0e-05);
+      TS_ASSERT_DELTA(dim->getMinimum(), -2.991993, d);
+      TS_ASSERT_DELTA(dim->getMaximum(), 2.991993, d);
+    }
+    AnalysisDataService::Instance().remove(normWSName);
+  }
+
+  void test_NormMonitor() {
+    // test whether the metadata were loaded correctly
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 4.77));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", -43.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr nws;
+    TS_ASSERT_THROWS_NOTHING(
+        nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            normWSName));
+    TS_ASSERT(nws);
+
+    std::vector<API::IMDNode *> boxes(0, NULL);
+    nws->getBoxes(boxes, 10000, false);
+    TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1);
+    API::IMDNode *box = boxes[0];
+    // there are 24 points in the data file
+    TS_ASSERT_EQUALS(box->getNPoints(), 24);
+    std::vector<coord_t> events;
+    size_t ncols;
+    box->getEventsData(events, ncols);
+    // 7 columns: I, err^2, run_num, det_id, h, k, l
+    TS_ASSERT_EQUALS(ncols, 7);
+    // 7*24 = 168
+    TS_ASSERT_EQUALS(events.size(), 168);
+    // reference vector
+    const std::vector<coord_t> ref = {
+        8332872, 8332872, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f,
+        8332872, 8332872, 0, 1, -0.15959044f, -0.15959044f, 0.14884006f,
+        8332872, 8332872, 0, 2, -0.224231616093f, -0.224231616093f,
+        0.189927174618f, 8332872, 8332872, 0, 3, -0.291194311172f,
+        -0.291194311172f, 0.223000198347f, 8332872, 8332872, 0, 4,
+        -0.359968893923f, -0.359968893923f, 0.247807429194f, 8332872, 8332872,
+        0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f, 8332872,
+        8332872, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f,
+        8332872, 8332872, 0, 7, -0.571884835101f, -0.571884835101f,
+        0.27106905426f, 8332872, 8332872, 0, 8, -0.642595081514f,
+        -0.642595081514f, 0.26157281786f, 8332872, 8332872, 0, 9,
+        -0.712442843555f, -0.712442843555f, 0.243517227652f, 8332872, 8332872,
+        0, 10, -0.78089653758f, -0.78089653758f, 0.217039697581f, 8332872,
+        8332872, 0, 11, -0.847435189645f, -0.847435189645f, 0.182341737639f,
+        8332872, 8332872, 0, 12, -0.911552400429f, -0.911552400429f,
+        0.13968742025f, 8332872, 8332872, 0, 13, -0.972760199244f,
+        -0.972760199244f, 0.089401370527f, 8332872, 8332872, 0, 14,
+        -1.03059275778f, -1.03059275778f, 0.0318662956709f, 8332872, 8332872, 0,
+        15, -1.08460993535f, -1.08460993535f, -0.0324799276578f, 8332872,
+        8332872, 0, 16, -1.13440062862f, -1.13440062862f, -0.103147585846f,
+        8332872, 8332872, 0, 17, -1.17958590034f, -1.17958590034f,
+        -0.179598855345f, 8332872, 8332872, 0, 18, -1.21982186332f,
+        -1.21982186332f, -0.261251895832f, 8332872, 8332872, 0, 19,
+        -1.25480229757f, -1.25480229757f, -0.347485278364f, 8332872, 8332872, 0,
+        20, -1.28426098088f, -1.28426098088f, -0.437642714831f, 8332872,
+        8332872, 0, 21, -1.30797371487f, -1.30797371487f, -0.531038052704f,
+        8332872, 8332872, 0, 22, -1.32576003133f, -1.32576003133f,
+        -0.626960497068f, 8332872, 8332872, 0, 23, -1.33748456564f,
+        -1.33748456564f, -0.724680020201f};
+    double d(1.0e-06);
+    for (auto i = 0; i < 168; i++) {
+      TS_ASSERT_DELTA(events[i], ref[i], d);
+    }
+
+    AnalysisDataService::Instance().remove(normWSName);
+  }
+
+  void test_NormTime() {
+    // test whether the metadata were loaded correctly
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "time"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 4.77));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", -43.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr nws;
+    TS_ASSERT_THROWS_NOTHING(
+        nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            normWSName));
+    TS_ASSERT(nws);
+
+    std::vector<API::IMDNode *> boxes(0, NULL);
+    nws->getBoxes(boxes, 10000, false);
+    TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1);
+    API::IMDNode *box = boxes[0];
+    // there are 24 points in the data file
+    TS_ASSERT_EQUALS(box->getNPoints(), 24);
+    std::vector<coord_t> events;
+    size_t ncols;
+    box->getEventsData(events, ncols);
+    // 7 columns: I, err^2, run_num, det_id, h, k, l
+    TS_ASSERT_EQUALS(ncols, 7);
+    // 7*24 = 168
+    TS_ASSERT_EQUALS(events.size(), 168);
+    // reference vector
+    const std::vector<coord_t> ref = {
+        600, 0, 0, 0, -0.09776273f, -0.09776273f, 0.10005156f, 600, 0, 0, 1,
+        -0.15959044f, -0.15959044f, 0.14884006f, 600, 0, 0, 2, -0.224231616093f,
+        -0.224231616093f, 0.189927174618f, 600, 0, 0, 3, -0.291194311172f,
+        -0.291194311172f, 0.223000198347f, 600, 0, 0, 4, -0.359968893923f,
+        -0.359968893923f, 0.247807429194f, 600, 0, 0, 5, -0.430031948245f,
+        -0.430031948245f, 0.264160069153f, 600, 0, 0, 6, -0.500850251989f,
+        -0.500850251989f, 0.271933664761f, 600, 0, 0, 7, -0.571884835101f,
+        -0.571884835101f, 0.27106905426f, 600, 0, 0, 8, -0.642595081514f,
+        -0.642595081514f, 0.26157281786f, 600, 0, 0, 9, -0.712442843555f,
+        -0.712442843555f, 0.243517227652f, 600, 0, 0, 10, -0.78089653758f,
+        -0.78089653758f, 0.217039697581f, 600, 0, 0, 11, -0.847435189645f,
+        -0.847435189645f, 0.182341737639f, 600, 0, 0, 12, -0.911552400429f,
+        -0.911552400429f, 0.13968742025f, 600, 0, 0, 13, -0.972760199244f,
+        -0.972760199244f, 0.089401370527f, 600, 0, 0, 14, -1.03059275778f,
+        -1.03059275778f, 0.0318662956709f, 600, 0, 0, 15, -1.08460993535f,
+        -1.08460993535f, -0.0324799276578f, 600, 0, 0, 16, -1.13440062862f,
+        -1.13440062862f, -0.103147585846f, 600, 0, 0, 17, -1.17958590034f,
+        -1.17958590034f, -0.179598855345f, 600, 0, 0, 18, -1.21982186332f,
+        -1.21982186332f, -0.261251895832f, 600, 0, 0, 19, -1.25480229757f,
+        -1.25480229757f, -0.347485278364f, 600, 0, 0, 20, -1.28426098088f,
+        -1.28426098088f, -0.437642714831f, 600, 0, 0, 21, -1.30797371487f,
+        -1.30797371487f, -0.531038052704f, 600, 0, 0, 22, -1.32576003133f,
+        -1.32576003133f, -0.626960497068f, 600, 0, 0, 23, -1.33748456564f,
+        -1.33748456564f, -0.724680020201f};
+    double d(1.0e-06);
+    for (auto i = 0; i < 168; i++) {
+      TS_ASSERT_DELTA(events[i], ref[i], d);
+    }
+
+    AnalysisDataService::Instance().remove(normWSName);
+  }
+
+  void test_SaveHuber() {
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+    std::string tWSName("LoadDNSSCDTest_Huber");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("SaveHuberTo", tWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    ITableWorkspace_sptr tws;
+    TS_ASSERT_THROWS_NOTHING(
+        tws = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
+            tWSName));
+    TS_ASSERT(tws);
+
+    // check that workspace has 1 row and 1 column
+    TS_ASSERT_EQUALS(tws->rowCount(), 1);
+    TS_ASSERT_EQUALS(tws->columnCount(), 1);
+    std::vector<std::string> columnNames = {"Huber(degrees)"};
+    TS_ASSERT_EQUALS(tws->getColumnNames(), columnNames);
+
+    // test the value
+    TS_ASSERT_DELTA(tws->cell<double>(0, 0), 79.0, 1.0e-06);
+    AnalysisDataService::Instance().remove(tWSName);
+  }
+
+  void test_LoadHuber() {
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+    std::string tWSName2("LoadDNSSCDTest_Huber_save");
+    std::string tWSName1("LoadDNSSCDTest_Huber_load");
+
+    // create a test table workspace
+    ITableWorkspace_sptr huberWS =
+        WorkspaceFactory::Instance().createTable("TableWorkspace");
+    huberWS->addColumn("double", "Huber(degrees)");
+    const std::vector<double> vals = {77.0, 92.0, 122.0};
+    auto n = vals.size();
+    for (size_t i = 0; i < n; i++) {
+      huberWS->appendRow();
+      huberWS->cell<double>(i, 0) = vals[i];
+    }
+    AnalysisDataService::Instance().add(tWSName1, huberWS);
+
+    // run the algorithm
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("LoadHuberFrom", tWSName1));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("SaveHuberTo", tWSName2));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+
+    TS_ASSERT_EQUALS(iws->getNumDims(), 3);
+    // data should be replicated for each huber value
+    TS_ASSERT_EQUALS(iws->getNPoints(), 24 * n);
+
+    // Retrieve the table workspace from data service.
+    ITableWorkspace_sptr tws;
+    TS_ASSERT_THROWS_NOTHING(
+        tws = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
+            tWSName2));
+    TS_ASSERT(tws);
+
+    // check that workspace has 1 row and 1 column
+    TS_ASSERT_EQUALS(tws->rowCount(), n);
+    TS_ASSERT_EQUALS(tws->columnCount(), 1);
+    std::vector<std::string> columnNames = {"Huber(degrees)"};
+    TS_ASSERT_EQUALS(tws->getColumnNames(), columnNames);
+
+    // test the values
+    for (size_t i = 0; i < n; i++)
+      TS_ASSERT_DELTA(tws->cell<double>(i, 0), vals[i], 1.0e-06);
+    AnalysisDataService::Instance().remove(tWSName1);
+    AnalysisDataService::Instance().remove(tWSName2);
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
+  void test_2ThetaLimits() {
+    // test whether the scattering angle limits work correctly
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", m_fileName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("a", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("b", 6.84));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("c", 4.77));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("alpha", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("beta", 90.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("gamma", 120.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OmegaOffset", -43.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL1", "1,1,0"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("HKL2", "0,0,1"));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("TwoThetaLimits", "20.0,55.0"));
+    TS_ASSERT_THROWS_NOTHING(alg.execute(););
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+
+    std::vector<API::IMDNode *> boxes(0, NULL);
+    iws->getBoxes(boxes, 10000, false);
+    TSM_ASSERT_EQUALS("Number of boxes", boxes.size(), 1);
+    API::IMDNode *box = boxes[0];
+    // there are 7 points (the rest is outside of 2theta limits)
+    TS_ASSERT_EQUALS(box->getNPoints(), 7);
+    std::vector<coord_t> events;
+    size_t ncols;
+    box->getEventsData(events, ncols);
+    // 7 columns: I, err^2, run_num, det_id, h, k, l
+    TS_ASSERT_EQUALS(ncols, 7);
+    // 7*7 = 49
+    TS_ASSERT_EQUALS(events.size(), 49);
+    // reference vector
+    const std::vector<coord_t> ref = {
+        32369, 32369, 0, 3, -0.291194311172f, -0.291194311172f, 0.223000198347f,
+        31851, 31851, 0, 4, -0.359968893923f, -0.359968893923f, 0.247807429194f,
+        30221, 30221, 0, 5, -0.430031948245f, -0.430031948245f, 0.264160069153f,
+        26267, 26267, 0, 6, -0.500850251989f, -0.500850251989f, 0.271933664761f,
+        26788, 26788, 0, 7, -0.571884835101f, -0.571884835101f, 0.27106905426f,
+        29729, 29729, 0, 8, -0.642595081514f, -0.642595081514f, 0.26157281786f,
+        30188, 30188, 0, 9, -0.712442843555f, -0.712442843555f,
+        0.243517227652f};
+    double d(1.0e-06);
+    for (auto i = 0; i < 49; i++) {
+      TS_ASSERT_DELTA(events[i], ref[i], d);
+    }
+
+    AnalysisDataService::Instance().remove(outWSName);
+
+    // test the normalization workspace as well
+    IMDEventWorkspace_sptr nws;
+    TS_ASSERT_THROWS_NOTHING(
+        nws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            normWSName));
+    TS_ASSERT(nws);
+    // there are 7 points (the rest is outside of 2theta limits)
+    TS_ASSERT_EQUALS(nws->getNPoints(), 7);
+
+    AnalysisDataService::Instance().remove(normWSName);
+  }
+
+  void test_Load2() {
+    // algorithm should load one file and skip the TOF file
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+    std::string filenames = "dn134011vana.d_dat,dnstof.d_dat";
+
+    LoadDNSSCD alg;
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", filenames));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+
+    // algorithm should throw only if no valid files is provided
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    // Retrieve the workspace from data service.
+    IMDEventWorkspace_sptr iws;
+    TS_ASSERT_THROWS_NOTHING(
+        iws = AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>(
+            outWSName));
+    TS_ASSERT(iws);
+
+    TS_ASSERT_EQUALS(iws->getNumDims(), 3);
+    TS_ASSERT_EQUALS(iws->getNPoints(), 24);
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
+  //-------------------- Test failure --------------------------------------
+  void test_failTOF() {
+    // algorithm does not load TOF files
+
+    std::string outWSName("LoadDNSSCDTest_OutputWS");
+    std::string normWSName("LoadDNSSCDTest_OutputWS_norm");
+
+    LoadDNSSCD alg;
+    alg.setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(alg.initialize());
+    TS_ASSERT(alg.isInitialized());
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Filenames", "dnstof.d_dat"));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", outWSName));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("NormalizationWorkspace", normWSName));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("Normalization", "monitor"));
+
+    // algorithm should throw if no valid files is provided
+    TS_ASSERT_THROWS(alg.execute(), std::runtime_error);
+    TS_ASSERT(!alg.isExecuted());
+  }
+
+private:
+  std::string m_fileName;
+};
+
+#endif /* MANTID_MDALGORITHMS_LOADDNSSCDEWEST_H_ */
diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h
index 41cd937c81aa115c12b9a563e54659a04b4215c1..3776ab48fa02a0a8c895d5013a7089d08b4563ff 100644
--- a/Framework/MDAlgorithms/test/LoadMDTest.h
+++ b/Framework/MDAlgorithms/test/LoadMDTest.h
@@ -171,7 +171,7 @@ public:
   template <size_t nd>
   void do_test_exec(bool FileBackEnd, bool deleteWorkspace = true,
                     double memory = 0, bool BoxStructureOnly = false) {
-    typedef MDLeanEvent<nd> MDE;
+    using MDE = MDLeanEvent<nd>;
 
     //------ Start by creating the file
     //----------------------------------------------
@@ -253,8 +253,8 @@ public:
 
       typename std::vector<API::IMDNode *> boxes;
       ws->getBox()->getBoxes(boxes, 1000, false);
-      for (size_t i = 0; i < boxes.size(); i++) {
-        MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
+      for (auto &boxIt : boxes) {
+        MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxIt);
         if (box) {
           TSM_ASSERT("Large box should not be in memory",
                      box->getISaveable()->getDataMemorySize() == 0);
@@ -307,7 +307,7 @@ public:
       ev.setCenter(d, 0.5);
     box->addEvent(ev);
     // CHANGE from AB: 20/01/2013: you have to split to identify changes!
-    box->splitAllIfNeeded(NULL);
+    box->splitAllIfNeeded(nullptr);
 
     // Modify a different box by accessing the events
     MDBox<MDLeanEvent<nd>, nd> *box8 =
diff --git a/Framework/MDAlgorithms/test/LoadSQW2Test.h b/Framework/MDAlgorithms/test/LoadSQW2Test.h
index b7360bdbcc99dac295710de0e6410cd2a6bd4a8b..f54287f8e6f8d7d28a58bc896d0e72e3caab5185 100644
--- a/Framework/MDAlgorithms/test/LoadSQW2Test.h
+++ b/Framework/MDAlgorithms/test/LoadSQW2Test.h
@@ -145,9 +145,9 @@ private:
   enum class DataType { SQW, Cut3D };
 
   struct DimensionProperties {
-    typedef std::array<std::string, 4> StringList;
-    typedef std::array<double, 8> DoubleList;
-    typedef std::array<size_t, 4> SizeTList;
+    using StringList = std::array<std::string, 4>;
+    using DoubleList = std::array<double, 8>;
+    using SizeTList = std::array<size_t, 4>;
     StringList ids, names, units, frameNames;
     DoubleList ulimits;
     SizeTList nbins;
diff --git a/Framework/MDAlgorithms/test/MDTransfModQTest.h b/Framework/MDAlgorithms/test/MDTransfModQTest.h
index 8d4abe7cf82e7fb93914711fd643705b8d906cbd..1178b956b156fa4a78c8e506c55acacce79551c2 100644
--- a/Framework/MDAlgorithms/test/MDTransfModQTest.h
+++ b/Framework/MDAlgorithms/test/MDTransfModQTest.h
@@ -108,8 +108,8 @@ public:
       // the detectors parameters
       MDTransf.calcYDepCoordinates(locCoord, i);
 
-      for (size_t k = 0; k < range.size(); k++) {
-        MDTransf.calcMatrixCoord(range[k], locCoord, signal, errorSq);
+      for (double k : range) {
+        MDTransf.calcMatrixCoord(k, locCoord, signal, errorSq);
         for (size_t j = 0; j < nDims; j++) {
           if (locCoord[j] < minCoord[j])
             minCoord[j] = locCoord[j];
diff --git a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
index cfe87617ea444c234a16e28025bdee3ea56d4565..81f46d2f193900426196cd693d57bf6db14b7fa1 100644
--- a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
+++ b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
@@ -116,8 +116,8 @@ public:
     // testing purposes here
     auto &TwoTheta = const_cast<std::vector<double> &>(
         WSDescr.m_PreprDetTable->getColVector<double>("TwoTheta"));
-    for (size_t i = 0; i < TwoTheta.size(); i++) {
-      TwoTheta[i] = 0;
+    for (double &i : TwoTheta) {
+      i = 0;
     }
 
     TSM_ASSERT_THROWS_NOTHING("should initialize properly: ",
diff --git a/Framework/MDAlgorithms/test/MDWSTransfTest.h b/Framework/MDAlgorithms/test/MDWSTransfTest.h
index ddf5e20a54a424ff579e466a57275dfdf1e7d397..3ca531923c5c42c14f7bba68098f056e900b6d44 100644
--- a/Framework/MDAlgorithms/test/MDWSTransfTest.h
+++ b/Framework/MDAlgorithms/test/MDWSTransfTest.h
@@ -78,7 +78,7 @@ public:
         WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10);
     std::vector<double> minVal(4, -3), maxVal(4, 3);
     TargWSDescription.setMinMax(minVal, maxVal);
-    spws->mutableSample().setOrientedLattice(NULL);
+    spws->mutableSample().setOrientedLattice(nullptr);
 
     TargWSDescription.buildFromMatrixWS(spws, "Q3D", "Direct");
 
diff --git a/Framework/MDAlgorithms/test/MaskMDTest.h b/Framework/MDAlgorithms/test/MaskMDTest.h
index 8cf01437735cad16782ad5bceb4a9676b6a786e7..9539790800664ee9e4d2a8791552107dc3b55cea 100644
--- a/Framework/MDAlgorithms/test/MaskMDTest.h
+++ b/Framework/MDAlgorithms/test/MaskMDTest.h
@@ -37,7 +37,7 @@ private:
     if (!ws)
       return;
 
-    IMDIterator *it = ws->createIterator();
+    auto it = ws->createIterator();
     size_t nMasked = 0;
     for (size_t i = 0; i < it->getDataSize(); ++i) {
       if (it->getIsMasked()) {
diff --git a/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Framework/MDAlgorithms/test/MergeMDFilesTest.h
index b62604f3fb8ccaa6f4a1884afd06fc64c33b2f69..f20739fa83960da1c54e4bbcac27280ab4332df2 100644
--- a/Framework/MDAlgorithms/test/MergeMDFilesTest.h
+++ b/Framework/MDAlgorithms/test/MergeMDFilesTest.h
@@ -102,11 +102,11 @@ public:
     }
 
     // Cleanup generated input files
-    for (size_t i = 0; i < inWorkspaces.size(); i++) {
-      if (inWorkspaces[i]->getBoxController()->isFileBacked()) {
+    for (auto &inWorkspace : inWorkspaces) {
+      if (inWorkspace->getBoxController()->isFileBacked()) {
         std::string fileName =
-            inWorkspaces[i]->getBoxController()->getFileIO()->getFileName();
-        inWorkspaces[i]->clearFileBacked(false);
+            inWorkspace->getBoxController()->getFileIO()->getFileName();
+        inWorkspace->clearFileBacked(false);
         Poco::File(fileName).remove();
       }
     }
diff --git a/Framework/MDAlgorithms/test/MinusMDTest.h b/Framework/MDAlgorithms/test/MinusMDTest.h
index 82ae75c7b7cacc881f963df6da910ee8856d2fbc..8daa5000cbbef30c42a4d4e069318a092bddfc51 100644
--- a/Framework/MDAlgorithms/test/MinusMDTest.h
+++ b/Framework/MDAlgorithms/test/MinusMDTest.h
@@ -105,7 +105,7 @@ public:
       TS_ASSERT_EQUALS(ws->getNPoints(), 10000);
     }
 
-    IMDIterator *it = ws->createIterator();
+    auto it = ws->createIterator();
     if (mask_ws_num == 0) {
       while (it->next()) {
         // Signal of all boxes is zero since they got subtracted
diff --git a/Framework/MDAlgorithms/test/MultiplyMDTest.h b/Framework/MDAlgorithms/test/MultiplyMDTest.h
index 480a3576dff6bfa98ed06d8c863af1724f6d27bc..08725d35da0d6f94f19de65a18a4faade03cfd0d 100644
--- a/Framework/MDAlgorithms/test/MultiplyMDTest.h
+++ b/Framework/MDAlgorithms/test/MultiplyMDTest.h
@@ -63,7 +63,7 @@ public:
     TS_ASSERT(ws);
     if (!ws)
       return;
-    IMDIterator *it = ws->createIterator(NULL);
+    auto it = ws->createIterator(nullptr);
     do {
       TS_ASSERT_EQUALS(it->getNumEvents(), 1);
       TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5);
diff --git a/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h b/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h
index fc1b53032897206a8951c2aa05b782698ab024bc..b5e411b78e56a7510c4b3797bd4c1614f51e0fa2 100644
--- a/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h
@@ -154,7 +154,7 @@ public:
     ITableWorkspace_sptr table =
         AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
 
-    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL);
+    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
     size_t expectedCount =
         3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
     TSM_ASSERT_EQUALS("Four columns expected", expectedCount,
@@ -176,7 +176,7 @@ public:
     ITableWorkspace_sptr table =
         AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
 
-    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL);
+    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
     size_t expectedCount =
         3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
     TSM_ASSERT_EQUALS("Five columns expected", expectedCount,
@@ -199,7 +199,7 @@ public:
     ITableWorkspace_sptr table =
         AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("QueryWS");
 
-    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL);
+    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
     size_t expectedCount =
         3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents
     TSM_ASSERT_EQUALS("Five columns expected", expectedCount,
@@ -253,7 +253,7 @@ public:
     query.execute();
     ITableWorkspace_sptr table = query.getProperty("OutputWorkspace");
 
-    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL);
+    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
     size_t expectedCount =
         3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D
     TSM_ASSERT_EQUALS("Six columns expected", expectedCount,
@@ -292,7 +292,7 @@ public:
     query.execute();
     ITableWorkspace_sptr table = query.getProperty("OutputWorkspace");
 
-    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL);
+    TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr);
     size_t expectedCount =
         3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D
     TSM_ASSERT_EQUALS("Six columns expected", expectedCount,
diff --git a/Framework/MDAlgorithms/test/ReplicateMDTest.h b/Framework/MDAlgorithms/test/ReplicateMDTest.h
index 56b24e96f43f92295ab60e9f6ec816f8597b6f52..68a25f36780b881b47c7d48d55b81ec46aa82802 100644
--- a/Framework/MDAlgorithms/test/ReplicateMDTest.h
+++ b/Framework/MDAlgorithms/test/ReplicateMDTest.h
@@ -77,8 +77,8 @@ MDHistoWorkspace_sptr makeHistoWorkspace(const std::vector<int> &shape,
     // Generate the axis order 0, 1, 2 ... in reverse
     std::vector<int> axes(outWs->getNumDims());
     Decreasing op(outWs->getNumDims());
-    for (auto it = axes.begin(); it != axes.end(); ++it) {
-      *it = static_cast<int>(op());
+    for (int &axis : axes) {
+      axis = static_cast<int>(op());
     }
 
     IAlgorithm *transpose =
diff --git a/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h b/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h
index 03cd21691ed3599ff6b7a178e1e484469b214e8b..497cd15840db79a25a1d1116c639c4e455edac75 100644
--- a/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h
+++ b/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h
@@ -47,7 +47,7 @@ public:
     using namespace Mantid::MDAlgorithms;
     using namespace Mantid::API;
     Mantid::API::IMDWorkspace_sptr testWS = createTestMDWorkspace();
-    Mantid::API::IMDIterator *box = testWS->createIterator();
+    auto box = testWS->createIterator();
     FunctionDomainMD mdDomain(testWS, 0, box->getDataSize());
     FunctionValues output;
 
@@ -55,7 +55,6 @@ public:
     crossSecResolution->setWorkspace(testWS);
     // TODO: Needs a better input workspace
     // TS_ASSERT_THROWS_NOTHING(crossSecResolution->function(mdDomain, output));
-    delete box;
     delete crossSecResolution;
   }
 
diff --git a/Framework/MDAlgorithms/test/SaveMD2Test.h b/Framework/MDAlgorithms/test/SaveMD2Test.h
index 85c4b9e2704648910ab7cdb2ae05d6d314bba571..a91a48586cc6002685ba3488c253266bf56300dd 100644
--- a/Framework/MDAlgorithms/test/SaveMD2Test.h
+++ b/Framework/MDAlgorithms/test/SaveMD2Test.h
@@ -109,7 +109,7 @@ public:
       ev.setCenter(0, double(i) * 0.01 + 0.4);
       ws->addEvent(ev);
     }
-    ws->splitAllIfNeeded(NULL);
+    ws->splitAllIfNeeded(nullptr);
     ws->refreshCache();
     // Manually set the flag that the algo would set
     ws->setFileNeedsUpdating(true);
diff --git a/Framework/MDAlgorithms/test/SaveMDTest.h b/Framework/MDAlgorithms/test/SaveMDTest.h
index a53feb583d2d2207db28d66eba17f118690075ff..aaad74bf8e361ed53febf02492341e57078d3679 100644
--- a/Framework/MDAlgorithms/test/SaveMDTest.h
+++ b/Framework/MDAlgorithms/test/SaveMDTest.h
@@ -114,7 +114,7 @@ public:
       ev.setCenter(0, double(i) * 0.01 + 0.4);
       ws->addEvent(ev);
     }
-    ws->splitAllIfNeeded(NULL);
+    ws->splitAllIfNeeded(nullptr);
     ws->refreshCache();
     // Manually set the flag that the algo would set
     ws->setFileNeedsUpdating(true);
diff --git a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
index 3e736c1d1ca7383cea549b941e39ec25313e29bc..0d558dbcf5f121b919345f2ceedfa9e5197ea267 100644
--- a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
+++ b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h
@@ -332,7 +332,8 @@ public:
   void test_aligned_ImplicitFunction() {
     SlicingAlgorithmImpl *alg = do_createAlignedTransform(
         "Axis0, 2.0,8.0, 6", "Axis1, 2.0,8.0, 3", "Axis2, 2.0,8.0, 3", "");
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(3, 4, 5)));
@@ -681,7 +682,8 @@ public:
     TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, 1.0, 2.6));
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2)));
@@ -738,7 +740,8 @@ public:
     TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, -1.0, 2.6));
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 2)));
@@ -756,8 +759,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234)));
@@ -777,8 +780,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 8);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 1.5, 1.5)));
@@ -796,8 +799,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 8);
     TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 1.5, 1.5)));
@@ -814,8 +817,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234, 456)));
@@ -835,8 +838,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234)));
@@ -854,8 +857,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2)));
@@ -873,8 +876,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5)));
@@ -932,7 +935,8 @@ public:
     TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.));
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(-8.9, -18.9)));
@@ -997,7 +1001,8 @@ public:
     TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.));
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(-18.9, -98.9)));
@@ -1026,8 +1031,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(2., 1.)));
@@ -1048,8 +1053,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 4);
     TS_ASSERT(func->isPointContained(VMD(2., 1., 0.)));
@@ -1072,8 +1077,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 8);
     TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.)));
@@ -1093,8 +1098,8 @@ public:
 
     // The implicit function
     MDImplicitFunction *func(nullptr);
-    TS_ASSERT_THROWS_NOTHING(func =
-                                 alg->getImplicitFunctionForChunk(NULL, NULL));
+    TS_ASSERT_THROWS_NOTHING(
+        func = alg->getImplicitFunctionForChunk(nullptr, nullptr));
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 6);
     TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.)));
@@ -1112,7 +1117,8 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 345)));
@@ -1127,7 +1133,8 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2)));
@@ -1142,7 +1149,8 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     TS_ASSERT(func->isPointContained(VMD(1.5, 1.5)));
@@ -1159,7 +1167,8 @@ public:
     TS_ASSERT_EQUALS(alg->m_bases.size(), 1);
 
     // The implicit function
-    MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL);
+    MDImplicitFunction *func =
+        alg->getImplicitFunctionForChunk(nullptr, nullptr);
     TS_ASSERT(func);
     TS_ASSERT_EQUALS(func->getNumPlanes(), 2);
     VMD point(1);
diff --git a/Framework/MDAlgorithms/test/SmoothMDTest.h b/Framework/MDAlgorithms/test/SmoothMDTest.h
index a2052d8376045c2dfb3ef9161899bc25b42e86cb..1ab8191f72d41b6c94eb0143bbc9f3b83ca6815e 100644
--- a/Framework/MDAlgorithms/test/SmoothMDTest.h
+++ b/Framework/MDAlgorithms/test/SmoothMDTest.h
@@ -14,7 +14,7 @@ using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 
 // Typedef for width vector
-typedef std::vector<double> WidthVector;
+using WidthVector = std::vector<double>;
 
 class SmoothMDTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/MDAlgorithms/test/TobyFitYVectorTest.h b/Framework/MDAlgorithms/test/TobyFitYVectorTest.h
index 249061f556a7b99ba826b27bca9261baa471232a..497046f3e9303c9447cb8ac37c03d744cf8efd5f 100644
--- a/Framework/MDAlgorithms/test/TobyFitYVectorTest.h
+++ b/Framework/MDAlgorithms/test/TobyFitYVectorTest.h
@@ -45,8 +45,8 @@ public:
                             "DetectorArea",  "DetectionTime"};
 
     TobyFitYVector yVector;
-    for (unsigned int i = 0; i < 8; ++i) {
-      yVector.setAttribute(attrs[i], IFunction::Attribute(false));
+    for (auto &attr : attrs) {
+      yVector.setAttribute(attr, IFunction::Attribute(false));
     }
 
     std::vector<double> randNums(yVector.requiredRandomNums(), 0.5);
diff --git a/Framework/MDAlgorithms/test/TransformMDTest.h b/Framework/MDAlgorithms/test/TransformMDTest.h
index 6ecf6571f7be221ac908dbec2880af65d34b7e61..dfa6a35e8ad0910c10fab440ac859b2c663d44ce 100644
--- a/Framework/MDAlgorithms/test/TransformMDTest.h
+++ b/Framework/MDAlgorithms/test/TransformMDTest.h
@@ -64,8 +64,7 @@ public:
     }
     std::vector<API::IMDNode *> boxes;
     ws2->getBox()->getBoxes(boxes, 1000, true);
-    for (size_t i = 0; i < boxes.size(); i++) {
-      API::IMDNode *box = boxes[i];
+    for (auto box : boxes) {
       TSM_ASSERT_LESS_THAN("Box extents was offset", 20.0,
                            box->getExtents(0).getMin());
       // More detailed tests are in MDBox, MDBoxBase and MDGridBox.
diff --git a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
index f2de896a9cfb9a30182bac6679baa788f99a1821..eacd4333e6e1c17ed6cb064d4b5d49e522ec2573 100644
--- a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
+++ b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h
@@ -134,7 +134,7 @@ public:
     MDHistoWorkspace_sptr c =
         boost::dynamic_pointer_cast<MDHistoWorkspace>(ADS.retrieve(outName));
 
-    TS_ASSERT(c != NULL);
+    TS_ASSERT(c != nullptr);
     // Since A and B are equivalent, the mean Signal in C should be the same as
     // both A and B.
     double expectedSignalResults[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
@@ -157,7 +157,7 @@ public:
     MDHistoWorkspace_sptr out;
     out = BinaryOperationMDTestHelper::doTest("WeightedMeanMD", "histo_A",
                                               "histo_B", "out");
-    TS_ASSERT(out != NULL);
+    TS_ASSERT(out != nullptr);
   }
 
   /**
@@ -197,7 +197,7 @@ public:
   /// MatrixWorkspaces (WeightedMean).
   void test_compare_to_matrix_weightedmean() {
     // Create some input data. Signal values as two offset sine waves.
-    typedef std::vector<double> VecDouble;
+    using VecDouble = std::vector<double>;
     VecDouble s1, s2, e1, e2, x;
     double theta_shift = 0.4;
     for (size_t i = 0; i < 40; ++i) {
diff --git a/Framework/Nexus/inc/MantidNexus/NexusClasses.h b/Framework/Nexus/inc/MantidNexus/NexusClasses.h
index 4a49958af93064927bfb836a9d08f9c95cdc997b..f8598304b6c1368384568752eadc03d6aecb962a 100644
--- a/Framework/Nexus/inc/MantidNexus/NexusClasses.h
+++ b/Framework/Nexus/inc/MantidNexus/NexusClasses.h
@@ -471,17 +471,17 @@ private:
 };
 
 /// The integer dataset type
-typedef NXDataSetTyped<int> NXInt;
+using NXInt = NXDataSetTyped<int>;
 /// The float dataset type
-typedef NXDataSetTyped<float> NXFloat;
+using NXFloat = NXDataSetTyped<float>;
 /// The double dataset type
-typedef NXDataSetTyped<double> NXDouble;
+using NXDouble = NXDataSetTyped<double>;
 /// The char dataset type
-typedef NXDataSetTyped<char> NXChar;
+using NXChar = NXDataSetTyped<char>;
 /// The size_t dataset type
-typedef NXDataSetTyped<std::size_t> NXSize;
+using NXSize = NXDataSetTyped<std::size_t>;
 /// The size_t dataset type
-typedef NXDataSetTyped<unsigned int> NXUInt;
+using NXUInt = NXDataSetTyped<unsigned int>;
 
 //-------------------- classes --------------------------//
 
diff --git a/Framework/Nexus/inc/MantidNexus/NexusFileIO.h b/Framework/Nexus/inc/MantidNexus/NexusFileIO.h
index 3995cb08d88b3675a3c7d5a42191ff0d4719dd79..2acac12b0bb74b87dfa5f3a949ac2e11d45f40ed 100644
--- a/Framework/Nexus/inc/MantidNexus/NexusFileIO.h
+++ b/Framework/Nexus/inc/MantidNexus/NexusFileIO.h
@@ -55,7 +55,7 @@ class DLLExport NexusFileIO {
 
 public:
   // Helper typedef
-  typedef boost::optional<size_t> optional_size_t;
+  using optional_size_t = boost::optional<size_t>;
 
   /// Default constructor
   NexusFileIO();
@@ -426,7 +426,7 @@ void NexusFileIO::writeNumericTimeLog(
 }
 
 /// Helper typedef for a shared pointer of a NexusFileIO.
-typedef boost::shared_ptr<NexusFileIO> NexusFileIO_sptr;
+using NexusFileIO_sptr = boost::shared_ptr<NexusFileIO>;
 
 } // namespace NeXus
 } // namespace Mantid
diff --git a/Framework/Parallel/inc/MantidParallel/Status.h b/Framework/Parallel/inc/MantidParallel/Status.h
index adbb5c852be0efdad89126aa8943569e548b364d..965a117cf8c7c473525decf0a28746ae03a45984 100644
--- a/Framework/Parallel/inc/MantidParallel/Status.h
+++ b/Framework/Parallel/inc/MantidParallel/Status.h
@@ -44,7 +44,8 @@ class ThreadingBackend;
 class MANTID_PARALLEL_DLL Status {
 public:
 #ifdef MPI_EXPERIMENTAL
-  Status(const boost::mpi::status &status) : m_status(status) {}
+  Status(const boost::mpi::status &status)
+      : m_status(status), m_threadingBackend{false} {}
 #endif
 
   template <typename T> boost::optional<int> count() const {
@@ -56,12 +57,14 @@ public:
   }
 
 private:
-  Status(const size_t size) : m_size(size), m_threadingBackend(true) {}
+  Status(const size_t size) : m_size(size) {}
 #ifdef MPI_EXPERIMENTAL
   boost::mpi::status m_status;
 #endif
   const size_t m_size{0};
-  const bool m_threadingBackend{false};
+#ifdef MPI_EXPERIMENTAL
+  bool m_threadingBackend{true};
+#endif
   // For accessing constructor based on size.
   friend class detail::ThreadingBackend;
 };
diff --git a/Framework/Parallel/test/EventParserTest.h b/Framework/Parallel/test/EventParserTest.h
index 0dce40044bdbb7e1165d6dc4fc4fdc58fb0154d8..2de672e236ad0e241279aaadd0646c84e86630c5 100644
--- a/Framework/Parallel/test/EventParserTest.h
+++ b/Framework/Parallel/test/EventParserTest.h
@@ -97,7 +97,7 @@ private:
               static_cast<IndexType>(m_bank_offsets[bank] + absolutePixel));
           std::transform(list.cbegin() + prev_end, list.cend(),
                          std::back_inserter(m_event_time_offsets[bank]),
-                         [this](const TofEvent &event) {
+                         [](const TofEvent &event) {
                            return static_cast<TimeOffsetType>(event.tof());
                          });
         }
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h
index 8d65758f0514136057bf964dfa2fc058c5831097..eaa58ae1aeafc4c3fa7d1346bf8415d63240521e 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h
@@ -42,7 +42,7 @@ namespace PythonInterface {
  */
 template <typename BaseAlgorithm>
 class AlgorithmAdapter : public BaseAlgorithm {
-  typedef BaseAlgorithm SuperClass;
+  using SuperClass = BaseAlgorithm;
 
 public:
   /// A constructor that looks like a Python __init__ method
@@ -68,6 +68,8 @@ public:
   const std::string summary() const override;
   /// Returns a category of the algorithm.
   const std::string category() const override;
+  /// Returns seeAlso related algorithms.
+  const std::vector<std::string> seeAlso() const override;
   /// Returns optional documentation URL of the algorithm
   const std::string helpURL() const override;
   /// Allow the isRunning method to be overridden
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h
index aff1c6a9507ca2431c3838f5558181fc7933a5b9..f59da6aa037f7e1a2c662f5368e19d646895127e 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h
@@ -37,9 +37,9 @@ namespace PythonInterface {
  */
 template <typename WorkspaceType> struct WorkspacePropertyExporter {
   /// The export type
-  typedef Mantid::API::WorkspaceProperty<WorkspaceType> TypedWorkspaceProperty;
+  using TypedWorkspaceProperty = Mantid::API::WorkspaceProperty<WorkspaceType>;
   /// Shared pointer to Worksapce type
-  typedef boost::shared_ptr<WorkspaceType> WorkspaceType_sptr;
+  using WorkspaceType_sptr = boost::shared_ptr<WorkspaceType>;
 
   /**
    * Factory function to act as a constructor so that the validator can be
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h
index 268e6219ecbe7c4f0a4dd331760e2bcc09a111a2..db0adf440ddde257d57b1dac7ba17266fedaf8b4 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h
@@ -45,7 +45,7 @@ struct CArrayToNDArray {
     // Round about way of calling the wrapNDArray template function that is
     // defined
     // in the cpp file
-    typedef typename ConversionPolicy::template apply<ElementType> policy;
+    using policy = typename ConversionPolicy::template apply<ElementType>;
     return policy::createFromArray(carray, ndims, dims);
   }
 };
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h
index 85ff6c7942e8da8c8bf66457c3844d6b13442106..08783aaaf85f2a586a25615da7f9aafca4c97c5f 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h
@@ -52,7 +52,7 @@ struct DLLExport MatrixToNDArray {
     const std::pair<size_t, size_t> matrixDims = cmatrix.size();
     Py_intptr_t dims[2] = {static_cast<Py_intptr_t>(matrixDims.first),
                            static_cast<Py_intptr_t>(matrixDims.second)};
-    typedef typename ConversionPolicy::template apply<ElementType> policy;
+    using policy = typename ConversionPolicy::template apply<ElementType>;
     return policy::createFromArray(&(cmatrix[0][0]), 2, dims);
   }
 };
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h
index 0e25b3224b3e5890d4482f468f096a20da5bacfd..80313d2f103e3930b6f4815ef4bb9024e9f4b84c 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h
@@ -48,7 +48,7 @@ struct VectorToNDArray {
    */
   inline PyObject *operator()(const std::vector<ElementType> &cdata) const {
     // Hand off the work to the conversion policy
-    typedef typename ConversionPolicy::template apply<ElementType> policy;
+    using policy = typename ConversionPolicy::template apply<ElementType>;
     return policy::create1D(cdata);
   }
 };
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h
index 7657c6abae07b9949eb29ff68323d94b5bf876cf..0c8b560c2415f4f9562c83f31b3f537901779154 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h
@@ -43,8 +43,8 @@ namespace PythonInterface {
  */
 template <typename SvcType, typename SvcPtrType> struct DataServiceExporter {
   // typedef the type created by boost.python
-  typedef boost::python::class_<SvcType, boost::noncopyable> PythonType;
-  typedef boost::weak_ptr<typename SvcPtrType::element_type> WeakPtr;
+  using PythonType = boost::python::class_<SvcType, boost::noncopyable>;
+  using WeakPtr = boost::weak_ptr<typename SvcPtrType::element_type>;
 
   /**
    * Define the necessary boost.python framework to expor the templated
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h
index 9a3dc8690723b6bf47b6b2bf37042631c9ecd2e7..d926e13c9259f8f133d0a22af2fde61dfadf9476 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h
@@ -73,11 +73,11 @@ template <class ReturnType> struct AsType {
   template <class InputType> struct apply {
     // Deduce if type is correct for policy, needs to be convertible to
     // ReturnType
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         std::is_convertible<InputType, ReturnType>::value,
         AsTypeImpl<ReturnType, InputType>,
         AsType_Requires_New_Type_Automatically_Convertible_To_Original<
-            InputType>>::type type;
+            InputType>>::type;
   };
 };
 
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h
index 173f5a1c319f9ae920ad3a7e52c30f0c737cefe4..1d33ec6e22ba80fe16764fc7aba3f7a7b3472ed9 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h
@@ -88,15 +88,14 @@ template <typename ConversionPolicy> struct MatrixRefToNumpy {
   template <class T> struct apply {
     // Typedef that removes and const or reference qualifiers from the return
     // type
-    typedef typename std::remove_const<
-        typename std::remove_reference<T>::type>::type non_const_type;
+    using non_const_type = typename std::remove_const<
+        typename std::remove_reference<T>::type>::type;
     // MPL compile-time check that T is a reference to a Kernel::Matrix
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         boost::mpl::and_<std::is_reference<T>,
                          is_matrix<non_const_type>>::value,
         MatrixRefToNumpyImpl<non_const_type, ConversionPolicy>,
-        MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type<T>>::type
-        type;
+        MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type<T>>::type;
   };
 };
 
@@ -132,12 +131,12 @@ struct MatrixToNumpy {
   // The boost::python framework calls return_value_policy::apply<T>::type
   template <class T> struct apply {
     // Typedef that removes any const from the type
-    typedef typename std::remove_const<T>::type non_const_type;
+    using non_const_type = typename std::remove_const<T>::type;
     // MPL compile-time check that T is a std::vector
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         is_matrix<non_const_type>::value,
         MatrixRefToNumpyImpl<non_const_type, Converters::Clone>,
-        MatrixToNumpy_Requires_Matrix_Return_By_Value<T>>::type type;
+        MatrixToNumpy_Requires_Matrix_Return_By_Value<T>>::type;
   };
 };
 }
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h
index 0c1070c6745bc56d60af45b8709766d803144d09..fea7b26f85d6d16c95dabd4628d8bd3ac37cdaf7 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h
@@ -72,9 +72,9 @@ struct IsConstSharedPtr<boost::shared_ptr<const T>> : std::true_type {};
 // call to this struct
 template <typename ConstPtrType> struct RemoveConstImpl {
   // Remove the pointer type to leave value type
-  typedef typename std::remove_pointer<ConstPtrType>::type ValueType;
+  using ValueType = typename std::remove_pointer<ConstPtrType>::type;
   // Remove constness
-  typedef typename std::remove_const<ValueType>::type NonConstValueType;
+  using NonConstValueType = typename std::remove_const<ValueType>::type;
 
   inline PyObject *operator()(const ConstPtrType &p) const {
     using namespace boost::python;
@@ -99,10 +99,10 @@ template <typename T> struct RemoveConst_Requires_Pointer_Return_Value {};
 // a check as to whether the return type is valid, if so it forwards the
 // call to this struct
 template <typename ConstSharedPtr> struct RemoveConstSharedPtrImpl {
-  typedef typename ConstSharedPtr::element_type ConstElementType;
-  typedef
-      typename std::remove_const<ConstElementType>::type NonConstElementType;
-  typedef typename boost::shared_ptr<NonConstElementType> NonConstSharedPtr;
+  using ConstElementType = typename ConstSharedPtr::element_type;
+  using NonConstElementType =
+      typename std::remove_const<ConstElementType>::type;
+  using NonConstSharedPtr = typename boost::shared_ptr<NonConstElementType>;
 
   inline PyObject *operator()(const ConstSharedPtr &p) const {
     using namespace boost::python;
@@ -130,9 +130,9 @@ struct RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value {};
 struct RemoveConst {
   template <class T> struct apply {
     // Deduce if type is correct for policy, needs to be a "T*"
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         std::is_pointer<T>::value, RemoveConstImpl<T>,
-        RemoveConst_Requires_Pointer_Return_Value<T>>::type type;
+        RemoveConst_Requires_Pointer_Return_Value<T>>::type;
   };
 };
 
@@ -143,10 +143,10 @@ struct RemoveConstSharedPtr {
   template <class T> struct apply {
     // Deduce if type is correct for policy, needs to be a
     // "boost::shared_ptr<T>"
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         IsConstSharedPtr<T>::value, RemoveConstSharedPtrImpl<T>,
         RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value<
-            T>>::type type;
+            T>>::type;
   };
 };
 
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h
index bed30370d7f01b554afd7e3895c8038f35883c0a..ba9e1d2eff1451d792d429f2d0256e9409f18966 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h
@@ -53,8 +53,8 @@ struct IsSharedPtr<boost::shared_ptr<T>> : boost::true_type {};
  */
 template <typename ArgType> struct ToWeakPtrImpl {
   // Useful types
-  typedef typename ArgType::element_type PointeeType;
-  typedef boost::weak_ptr<PointeeType> WeakPtr;
+  using PointeeType = typename ArgType::element_type;
+  using WeakPtr = boost::weak_ptr<PointeeType>;
 
   inline PyObject *operator()(const ArgType &p) const {
     if (!p)
@@ -80,9 +80,9 @@ template <typename T> struct ToWeakPtr_Requires_Shared_Ptr_Return_Value {};
 struct ToWeakPtr {
   template <class T> struct apply {
     // Deduce if type is correct for policy
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         IsSharedPtr<T>::value, ToWeakPtrImpl<T>,
-        ToWeakPtr_Requires_Shared_Ptr_Return_Value<T>>::type type;
+        ToWeakPtr_Requires_Shared_Ptr_Return_Value<T>>::type;
   };
 };
 
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h
index 829d88da8d5b4b7a5acd32a7c73687f68a51e5f7..7f7cb2046bbd654eed8eb6318cba82bba57699d2 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h
@@ -85,15 +85,14 @@ template <typename ConversionPolicy> struct VectorRefToNumpy {
   // The boost::python framework calls return_value_policy::apply<T>::type
   template <class T> struct apply {
     // Typedef that removes and const or reference qualifiers from the type
-    typedef typename std::remove_const<
-        typename std::remove_reference<T>::type>::type non_const_type;
+    using non_const_type = typename std::remove_const<
+        typename std::remove_reference<T>::type>::type;
     // MPL compile-time check that T is a reference to a std::vector
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         boost::mpl::and_<std::is_reference<T>,
                          is_std_vector<non_const_type>>::value,
         VectorRefToNumpyImpl<non_const_type, ConversionPolicy>,
-        VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type<T>>::type
-        type;
+        VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type<T>>::type;
   };
 };
 
@@ -130,12 +129,12 @@ struct VectorToNumpy {
   // The boost::python framework calls return_value_policy::apply<T>::type
   template <class T> struct apply {
     // Typedef that removes any const from the type
-    typedef typename std::remove_const<T>::type non_const_type;
+    using non_const_type = typename std::remove_const<T>::type;
     // MPL compile-time check that T is a std::vector
-    typedef typename boost::mpl::if_c<
+    using type = typename boost::mpl::if_c<
         is_std_vector<non_const_type>::value,
         VectorRefToNumpyImpl<non_const_type, Converters::Clone>,
-        VectorToNumpy_Requires_StdVector_Return_By_Value<T>>::type type;
+        VectorToNumpy_Requires_StdVector_Return_By_Value<T>>::type;
   };
 };
 }
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
index 3c69a5b0a711e4fd83f79b1a5f6bfb0ed06f1561..9337da3725dd82ef232fc245d6db51b4036498fd 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
@@ -40,8 +40,8 @@ namespace Registry {
  *    - Registers a new PropertyValueHandler for a boost::shared_ptr<T>
  */
 template <typename IType> struct DLLExport RegisterWorkspacePtrToPython {
-  typedef boost::shared_ptr<IType> IType_sptr;
-  typedef boost::weak_ptr<IType> IType_wptr;
+  using IType_sptr = boost::shared_ptr<IType>;
+  using IType_wptr = boost::weak_ptr<IType>;
   /// Constructor
   RegisterWorkspacePtrToPython() {
     using namespace boost::python;
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
index 73b19f29ecb61bfc7622531af52e0925c031bead..b7e517a42b5b97aaff7c3c901076275b813ccdf0 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
@@ -47,7 +47,7 @@ namespace Registry {
 template <typename ValueType, typename Enable = void>
 struct DLLExport TypedPropertyValueHandler : public PropertyValueHandler {
   /// Type required by TypeRegistry framework
-  typedef ValueType HeldType;
+  using HeldType = ValueType;
 
   /**
    * Set function to handle Python -> C++ calls and get the correct type
@@ -101,12 +101,12 @@ struct DLLExport TypedPropertyValueHandler<
     typename std::enable_if<std::is_base_of<API::Workspace, T>::value>::type>
     : public PropertyValueHandler {
   /// Type required by TypeRegistry framework
-  typedef boost::shared_ptr<T> HeldType;
+  using HeldType = boost::shared_ptr<T>;
 
   /// Convenience typedef
-  typedef T PointeeType;
+  using PointeeType = T;
   /// Convenience typedef
-  typedef boost::shared_ptr<T> PropertyValueType;
+  using PropertyValueType = boost::shared_ptr<T>;
 
   /**
    * Set function to handle Python -> C++ calls and get the correct type
diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h
index df59421b31770f4811a76d629a26939e7e4df793..8b6dbfacd1c4c7ea855fc56c82cd344806ce601e 100644
--- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h
+++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h
@@ -83,7 +83,7 @@ std::string toString(const SequenceType &values) {
  */
 template <typename ElementType> struct std_vector_exporter {
   /// A typedef of a vector of template ElementTypes
-  typedef std::vector<ElementType> w_t;
+  using w_t = std::vector<ElementType>;
 
   static std::string to_string(const w_t &values) {
     if (values.empty())
@@ -111,8 +111,8 @@ template <typename ElementType> struct std_vector_exporter {
 // Found this at
 // http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/scitbx/stl/set_wrapper.h?view=log
 template <typename ElementType> struct std_set_exporter {
-  typedef std::set<ElementType> w_t;
-  typedef ElementType e_t;
+  using w_t = std::set<ElementType>;
+  using e_t = ElementType;
 
   static void insert_element(w_t &self, e_t const &x) { self.insert(x); }
 
diff --git a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp
index 804ec003fdf9ea4a816fd23548b0315474b06c5d..96e717d9fe33a4179d54c8a1c6daafeaecbe1e80 100644
--- a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp
@@ -16,7 +16,6 @@ namespace Mantid {
 namespace PythonInterface {
 using Mantid::API::MatrixWorkspace_sptr;
 using Mantid::API::MatrixWorkspace;
-namespace bpl = boost::python;
 
 // ----------------------------------------------------------------------------------------------------------
 namespace {
@@ -38,8 +37,8 @@ PyArrayObject *cloneArray(MatrixWorkspace &workspace, DataField field,
   npy_intp stride(0);
 
   // Find out which function we need to call to access the data
-  typedef const MantidVec &(MatrixWorkspace::*ArrayAccessFn)(const size_t)
-      const;
+  using ArrayAccessFn =
+      const MantidVec &(MatrixWorkspace::*)(const size_t) const;
   ArrayAccessFn dataAccesor;
   /**
    * Can do better than this with a templated object that knows how to access
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp
index 9331a1548ac8c27fc8d9b0c303f3c56535d858d1..d2621202c0deb7c2dd0b539c769be78a4e31201b 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp
@@ -34,30 +34,30 @@ GET_POINTER_SPECIALIZATION(ParallelAlgorithm)
 GET_POINTER_SPECIALIZATION(DistributedAlgorithm)
 
 namespace {
-typedef AlgorithmAdapter<Algorithm> PythonAlgorithm;
-typedef AlgorithmAdapter<SerialAlgorithm> PythonSerialAlgorithm;
-typedef AlgorithmAdapter<ParallelAlgorithm> PythonParallelAlgorithm;
-typedef AlgorithmAdapter<DistributedAlgorithm> PythonDistributedAlgorithm;
+using PythonAlgorithm = AlgorithmAdapter<Algorithm>;
+using PythonSerialAlgorithm = AlgorithmAdapter<SerialAlgorithm>;
+using PythonParallelAlgorithm = AlgorithmAdapter<ParallelAlgorithm>;
+using PythonDistributedAlgorithm = AlgorithmAdapter<DistributedAlgorithm>;
 
 // declarePyAlgProperty(property*,doc)
-typedef void (*declarePropertyType1)(boost::python::object &self,
-                                     Mantid::Kernel::Property *,
-                                     const std::string &);
+using declarePropertyType1 = void (*)(boost::python::object &,
+                                      Mantid::Kernel::Property *,
+                                      const std::string &);
 // declarePyAlgProperty(name, defaultValue, validator, doc, direction)
-typedef void (*declarePropertyType2)(boost::python::object &self,
-                                     const std::string &,
-                                     const boost::python::object &,
-                                     const boost::python::object &,
-                                     const std::string &, const int);
+using declarePropertyType2 = void (*)(boost::python::object &,
+                                      const std::string &,
+                                      const boost::python::object &,
+                                      const boost::python::object &,
+                                      const std::string &, const int);
 // declarePyAlgProperty(name, defaultValue, doc, direction)
-typedef void (*declarePropertyType3)(boost::python::object &self,
-                                     const std::string &,
-                                     const boost::python::object &,
-                                     const std::string &, const int);
+using declarePropertyType3 = void (*)(boost::python::object &,
+                                      const std::string &,
+                                      const boost::python::object &,
+                                      const std::string &, const int);
 // declarePyAlgProperty(name, defaultValue, direction)
-typedef void (*declarePropertyType4)(boost::python::object &self,
-                                     const std::string &,
-                                     const boost::python::object &, const int);
+using declarePropertyType4 = void (*)(boost::python::object &,
+                                      const std::string &,
+                                      const boost::python::object &, const int);
 #ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunknown-pragmas"
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp
index 28de6020d119dc58eeeaab4c1702e483153aecce..3e98413955b21be98e1c7cea0546dc6cdfaf7a49 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp
@@ -14,8 +14,6 @@
 using Mantid::API::AlgorithmHistory;
 using namespace boost::python;
 
-namespace Policies = Mantid::PythonInterface::Policies;
-
 /**
  * Return a Python list of child history objects from the history as this is
  * far easier to work with than a set
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp
index cbf839d44c7e7f9bd8c24b4aee54be1dec83dda2..64689baa89e2365e87e6c1f55a9d35802c96d494 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp
@@ -43,7 +43,7 @@ AlgorithmProperty *createPropertyWithValidator(const std::string &name,
 void export_AlgorithmProperty() {
   // AlgorithmProperty has base PropertyWithValue<boost::shared_ptr<IAlgorithm>>
   // which must be exported
-  typedef boost::shared_ptr<IAlgorithm> HeldType;
+  using HeldType = boost::shared_ptr<IAlgorithm>;
   PropertyWithValueExporter<HeldType>::define("AlgorithmPropertyWithValue");
 
   class_<AlgorithmProperty, bases<PropertyWithValue<HeldType>>,
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
index 229b8b7f9925ff8a4ca91bc36ea3f354e37cef8e..69bb97725cdc805b6e4e5fe9ec3ec711bd7fa1a4 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
@@ -11,8 +11,8 @@ using namespace boost::python;
 GET_POINTER_SPECIALIZATION(AnalysisDataServiceImpl)
 
 void export_AnalysisDataService() {
-  typedef DataServiceExporter<AnalysisDataServiceImpl, Workspace_sptr>
-      ADSExporter;
+  using ADSExporter =
+      DataServiceExporter<AnalysisDataServiceImpl, Workspace_sptr>;
   auto pythonClass = ADSExporter::define("AnalysisDataServiceImpl");
   pythonClass.def("Instance", &AnalysisDataService::Instance,
                   return_value_policy<reference_existing_object>(),
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
index def782865742aeb262db1b2e72dedf4d1d9738a9..c5374df149d54898efae6796d6520cc330101a3f 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp
@@ -27,7 +27,6 @@ using namespace boost::python;
 GET_POINTER_SPECIALIZATION(Axis)
 
 namespace {
-namespace bpl = boost::python;
 
 //------------------------------- Overload macros ---------------------------
 #ifdef __clang__
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
index 1687bd990b1a576357f57e43a7b453f9dad8ba1f..2b17e22dd61246cdda5b989c54b92d9d9cc6b6d3 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
@@ -18,35 +18,35 @@ void export_BinaryOperations() {
   using namespace boost::python;
 
   // Typedefs the various function types
-  typedef IMDWorkspace_sptr (*binary_fn_md_md)(
-      const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &,
-      const std::string &, bool, bool);
-  typedef WorkspaceGroup_sptr (*binary_fn_md_gp)(
-      const IMDWorkspace_sptr, const WorkspaceGroup_sptr, const std::string &,
-      const std::string &, bool, bool);
-  typedef WorkspaceGroup_sptr (*binary_fn_gp_md)(
-      const WorkspaceGroup_sptr, const IMDWorkspace_sptr, const std::string &,
-      const std::string &, bool, bool);
-  typedef WorkspaceGroup_sptr (*binary_fn_gp_gp)(
-      const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, const std::string &,
-      const std::string &, bool, bool);
-
-  typedef IMDHistoWorkspace_sptr (*binary_fn_mh_mh)(
-      const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr,
-      const std::string &, const std::string &, bool, bool);
-
-  typedef IMDWorkspace_sptr (*binary_fn_md_db)(const IMDWorkspace_sptr, double,
-                                               const std::string &,
-                                               const std::string &, bool, bool);
-  typedef IMDHistoWorkspace_sptr (*binary_fn_mh_db)(
-      const IMDHistoWorkspace_sptr, double, const std::string &,
-      const std::string &, bool, bool);
-  typedef WorkspaceGroup_sptr (*binary_fn_gp_db)(
-      const WorkspaceGroup_sptr, double, const std::string &,
-      const std::string &, bool, bool);
+  using binary_fn_md_md = IMDWorkspace_sptr (
+      *)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &,
+         const std::string &, bool, bool);
+  using binary_fn_md_gp = WorkspaceGroup_sptr (
+      *)(const IMDWorkspace_sptr, const WorkspaceGroup_sptr,
+         const std::string &, const std::string &, bool, bool);
+  using binary_fn_gp_md = WorkspaceGroup_sptr (
+      *)(const WorkspaceGroup_sptr, const IMDWorkspace_sptr,
+         const std::string &, const std::string &, bool, bool);
+  using binary_fn_gp_gp = WorkspaceGroup_sptr (
+      *)(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr,
+         const std::string &, const std::string &, bool, bool);
+
+  using binary_fn_mh_mh = IMDHistoWorkspace_sptr (
+      *)(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr,
+         const std::string &, const std::string &, bool, bool);
+
+  using binary_fn_md_db = IMDWorkspace_sptr (
+      *)(const IMDWorkspace_sptr, double, const std::string &,
+         const std::string &, bool, bool);
+  using binary_fn_mh_db = IMDHistoWorkspace_sptr (
+      *)(const IMDHistoWorkspace_sptr, double, const std::string &,
+         const std::string &, bool, bool);
+  using binary_fn_gp_db = WorkspaceGroup_sptr (
+      *)(const WorkspaceGroup_sptr, double, const std::string &,
+         const std::string &, bool, bool);
 
   // Always a return a Workspace_sptr
-  typedef return_value_policy<AsType<Workspace_sptr>> ReturnWorkspaceSptr;
+  using ReturnWorkspaceSptr = return_value_policy<AsType<Workspace_sptr>>;
 
   // Binary operations that return a workspace
   using boost::python::def;
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp
index 9085e895a26f1b8c20773144861667ac42bdb75d..ff4ffee34c9c099eb107747b6d0c76c82807a56a 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp
@@ -1,5 +1,6 @@
-#include "MantidPythonInterface/kernel/GetPointer.h"
 #include "MantidAPI/CompositeFunction.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidPythonInterface/kernel/GetPointer.h"
 #include <boost/python/class.hpp>
 #include <boost/python/overloads.hpp>
 #include <boost/python/register_ptr_to_python.hpp>
@@ -12,19 +13,21 @@ GET_POINTER_SPECIALIZATION(CompositeFunction)
 
 namespace {
 
-typedef double (CompositeFunction::*getParameterType1)(size_t) const;
-typedef double (CompositeFunction::*getParameterType2)(
-    const std::string &) const;
+using getParameterType1 = double (CompositeFunction::*)(size_t) const;
+using getParameterType2 =
+    double (CompositeFunction::*)(const std::string &) const;
 
-typedef void (CompositeFunction::*setParameterType2)(const std::string &,
-                                                     const double &, bool);
+using setParameterType2 = void (CompositeFunction::*)(const std::string &,
+                                                      const double &, bool);
 #ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunknown-pragmas"
 #pragma clang diagnostic ignored "-Wunused-local-typedef"
 #endif
+GCC_DIAG_OFF(conversion)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads,
                                        setParameter, 2, 3)
+GCC_DIAG_ON(conversion)
 #ifdef __clang__
 #pragma clang diagnostic pop
 #endif
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp
index ee7761b2cd9a195be626d043af293db74cc7f22d..98c18f2b2cc5cf47532db3b31c53acc2419c39a2 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp
@@ -11,7 +11,7 @@ using namespace boost::python;
 void export_FunctionProperty() {
   // FuncitonProperty has base PropertyWithValue<boost::shared_ptr<IFunction>>
   // which must be exported
-  typedef boost::shared_ptr<IFunction> HeldType;
+  using HeldType = boost::shared_ptr<IFunction>;
   PropertyWithValueExporter<HeldType>::define("FunctionPropertyWithValue");
 
   class_<FunctionProperty, bases<PropertyWithValue<HeldType>>,
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
index dd2b55e13c98329c3bf3cdb16446963d4e14d73f..c71b84d79039c99a1520dcde4fce3d7fc050ff4f 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
@@ -100,7 +100,7 @@ struct MandatoryFirst {
 
 //----------------------- Property ordering ------------------------------
 /// Vector of property pointers
-typedef std::vector<Property *> PropertyVector;
+using PropertyVector = std::vector<Property *>;
 
 /**
  * Returns the vector of properties ordered by the criteria defined in
@@ -372,7 +372,11 @@ void export_ialgorithm() {
       .def("category", &IAlgorithm::category, arg("self"),
            "Returns the category containing the algorithm")
       .def("categories", &IAlgorithm::categories, arg("self"),
+           return_value_policy<VectorToNumpy>(),
            "Returns the list of categories this algorithm belongs to")
+      .def("seeAlso", &IAlgorithm::seeAlso, arg("self"),
+           return_value_policy<VectorToNumpy>(),
+           "Returns the list of similar algorithms")
       .def("summary", &IAlgorithm::summary, arg("self"),
            "Returns a summary message describing the algorithm")
       .def("helpURL", &IAlgorithm::helpURL, arg("self"),
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
index f9524b3cce55094ac4eea24cb84215b97dd8e56f..886b4303114352fb223dbe4c58ab186e483f98f0 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp
@@ -13,13 +13,12 @@ using Mantid::API::WEIGHTED;
 using Mantid::API::WEIGHTED_NOTIME;
 
 namespace Policies = Mantid::PythonInterface::Policies;
-namespace Converters = Mantid::PythonInterface::Converters;
 using namespace boost::python;
 
 GET_POINTER_SPECIALIZATION(IEventList)
 
 /// return_value_policy for copied numpy array
-typedef return_value_policy<Policies::VectorToNumpy> return_clone_numpy;
+using return_clone_numpy = return_value_policy<Policies::VectorToNumpy>;
 
 void export_IEventList() {
   register_ptr_to_python<IEventList *>();
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp
index 0406931e6735830975e7cd13522739a56909c6a0..7e892d026eede727bcfba7cac687088afa232f49 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp
@@ -42,7 +42,7 @@ PyObject *getCategories(IFunction &self) {
 
 // -- Set property overloads --
 // setProperty(index,value,explicit)
-typedef void (IFunction::*setParameterType1)(size_t, const double &value, bool);
+using setParameterType1 = void (IFunction::*)(size_t, const double &, bool);
 #ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunknown-pragmas"
@@ -54,8 +54,8 @@ GCC_DIAG_OFF(conversion)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads,
                                        setParameter, 2, 3)
 // setProperty(index,value,explicit)
-typedef void (IFunction::*setParameterType2)(const std::string &,
-                                             const double &value, bool);
+using setParameterType2 = void (IFunction::*)(const std::string &,
+                                              const double &, bool);
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads,
                                        setParameter, 2, 3)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(tie_Overloads, tie, 2, 3)
@@ -65,7 +65,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixParameter_Overloads, fixParameter, 1,
                                        2)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fix_Overloads, fix, 1, 2)
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixAll_Overloads, fixAll, 0, 1)
-typedef void (IFunction::*removeTieByName)(const std::string &);
+using removeTieByName = void (IFunction::*)(const std::string &);
 
 GCC_DIAG_ON(conversion)
 #ifdef __clang__
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
index ecd32b1cad97572234669f688083f1bf099cb4dd..10de2206815755e357cc04b60d91f8ed2253708e 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
@@ -48,7 +48,7 @@ void setGoniometerMatrix(IPeak &self, const object &data) {
 
 void export_IPeak() {
   // return_value_policy for read-only numpy array
-  typedef return_value_policy<Policies::MatrixToNumpy> return_copy_to_numpy;
+  using return_copy_to_numpy = return_value_policy<Policies::MatrixToNumpy>;
 
   register_ptr_to_python<IPeak *>();
 
@@ -61,9 +61,16 @@ void export_IPeak() {
            "cache values related to it.")
       .def("getRunNumber", &IPeak::getRunNumber, arg("self"),
            "Return the run number this peak was measured at")
+      .def("getPeakNumber", &IPeak::getPeakNumber, arg("self"),
+           "Return the peak number for this peak")
+      .def("getBankName", &IPeak::getBankName, arg("self"),
+           "Return the bank name for this peak")
       .def("setRunNumber", &IPeak::setRunNumber,
            (arg("self"), arg("run_number")),
            "Set the run number that measured this peak")
+      .def("setPeakNumber", &IPeak::setPeakNumber,
+           (arg("self"), arg("peak_number")),
+           "Set the peak number for this peak")
       .def("getMonitorCount", &IPeak::getMonitorCount, arg("self"),
            "Get the monitor count set for this peak")
       .def("setMonitorCount", &IPeak::setMonitorCount,
@@ -89,7 +96,8 @@ void export_IPeak() {
            ":class:`~mantid.geometry.Goniometer` rotation was NOT taken "
            "out.\n"
            "Note: There is no 2*pi factor used, so \\|Q| = 1/wavelength.")
-      .def("findDetector", &IPeak::findDetector, arg("self"),
+      .def("findDetector", (bool (IPeak::*)()) & IPeak::findDetector,
+           arg("self"),
            "Using the :class:`~mantid.geometry.Instrument` set in the peak, "
            "perform ray tracing to find "
            "the exact :class:`~mantid.geometry.Detector`.")
@@ -125,6 +133,8 @@ void export_IPeak() {
            "Return the incident wavelength")
       .def("getScattering", &IPeak::getScattering, arg("self"),
            "Calculate the scattering angle of the peak")
+      .def("getAzimuthal", &IPeak::getAzimuthal, arg("self"),
+           "Calculate the azimuthal angle of the peak")
       .def("getDSpacing", &IPeak::getDSpacing, arg("self"),
            "Calculate the d-spacing of the peak, in 1/Angstroms")
       .def("getTOF", &IPeak::getTOF, arg("self"),
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
index f23ec4eb88165bda2b79f2158b599f512ecd5c04..38480dd58b8333c362055397a39beafa044a33e0 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
@@ -38,14 +38,15 @@ GET_POINTER_SPECIALIZATION(MatrixWorkspace)
 
 namespace {
 /// Typedef for data access, i.e. dataX,Y,E members
-typedef Mantid::MantidVec &(MatrixWorkspace::*data_modifier)(const std::size_t);
+using data_modifier =
+    Mantid::MantidVec &(MatrixWorkspace::*)(const std::size_t);
 
 /// return_value_policy for read-only numpy array
-typedef return_value_policy<VectorRefToNumpy<WrapReadOnly>>
-    return_readonly_numpy;
+using return_readonly_numpy =
+    return_value_policy<VectorRefToNumpy<WrapReadOnly>>;
 /// return_value_policy for read-write numpy array
-typedef return_value_policy<VectorRefToNumpy<WrapReadWrite>>
-    return_readwrite_numpy;
+using return_readwrite_numpy =
+    return_value_policy<VectorRefToNumpy<WrapReadWrite>>;
 
 //------------------------------- Overload macros ---------------------------
 #ifdef __clang__
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp
index 2ffd86de5fbf9ebdc7be404d06a49bd01c54d620..8bce6bdea86d5e71236eda8f86c2396283508ff9 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp
@@ -17,7 +17,7 @@ using namespace boost::python;
 
 namespace {
 /// The PropertyWithValue type
-typedef std::vector<std::vector<std::string>> HeldType;
+using HeldType = std::vector<std::vector<std::string>>;
 
 /**
  * Converts the value from a MultipleFileProperty to a python object rather than
@@ -71,7 +71,7 @@ createMultipleFileProperty(const std::string &name,
 }
 
 void export_MultipleFileProperty() {
-  typedef PropertyWithValue<HeldType> BaseClass;
+  using BaseClass = PropertyWithValue<HeldType>;
   PropertyWithValueExporter<HeldType>::define(
       "VectorVectorStringPropertyWithValue");
 
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp
index d2ef62e9d76421c213ded80dd4de24de3852ef45..d1e71ee12ce93d2bc6abb3bac99f572c0f59ae6c 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp
@@ -8,11 +8,13 @@ using namespace boost::python;
 
 namespace {
 
-typedef double (ProductFunction::*getParameterType1)(size_t) const;
-typedef double (ProductFunction::*getParameterType2)(const std::string &) const;
+using getParameterType1 = double (ProductFunction::*)(size_t) const;
+using getParameterType2 =
+    double (ProductFunction::*)(const std::string &) const;
+
+using setParameterType2 = void (ProductFunction::*)(const std::string &,
+                                                    const double &, bool);
 
-typedef void (ProductFunction::*setParameterType2)(const std::string &,
-                                                   const double &, bool);
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads,
                                        setParameter, 2, 3)
 }
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp
index 0fcdf9243941c89a46c7a1ce2fe83d1f42884441..3ded562f0ae9cd93aeb91bfc2902b7fa7e3ec651 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp
@@ -73,9 +73,9 @@ void export_WorkspaceFactory() {
 
   const char *createFromScratchDoc =
       "Create a clean new worksapce of the given size.";
-  typedef MatrixWorkspace_sptr (WorkspaceFactoryImpl::*createFromScratchPtr)(
-      const std::string &, const size_t &, const size_t &, const size_t &)
-      const;
+  using createFromScratchPtr = MatrixWorkspace_sptr (
+      WorkspaceFactoryImpl::*)(const std::string &, const size_t &,
+                               const size_t &, const size_t &) const;
 
   class_<WorkspaceFactoryImpl, boost::noncopyable>("WorkspaceFactoryImpl",
                                                    no_init)
diff --git a/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp
index 4540b383f2d40f3f9d2dacfc108faeac3dedcb5a..2ced6615e53bd88474ee155d0c44782e5eaa5ec6 100644
--- a/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp
@@ -22,7 +22,7 @@ using boost::python::extract;
 ExtractWorkspace::ExtractWorkspace(const boost::python::api::object &pyvalue)
     : m_value() {
   // Test for a weak pointer first
-  typedef boost::weak_ptr<Workspace> Workspace_wptr;
+  using Workspace_wptr = boost::weak_ptr<Workspace>;
   extract<Workspace_wptr &> extractWeak(pyvalue);
   if (extractWeak.check()) {
     m_value = extractWeak().lock();
diff --git a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp
index 6d9358d85c22bde259d8e828fe598f2541187999..2c9db0825e8bc623df61a80774bfbf693e78f011 100644
--- a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp
+++ b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp
@@ -3,6 +3,7 @@
 #include "MantidPythonInterface/kernel/Environment/WrapperHelpers.h"
 #include "MantidPythonInterface/kernel/Environment/CallMethod.h"
 #include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h"
+#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"
 #include "MantidAPI/DataProcessorAlgorithm.h"
 #include "MantidAPI/SerialAlgorithm.h"
 #include "MantidAPI/ParallelAlgorithm.h"
@@ -92,6 +93,21 @@ const std::string AlgorithmAdapter<BaseAlgorithm>::category() const {
   return category;
 }
 
+/**
+* Returns seeAlso related algorithms. If not overridden
+* it returns an empty vector of strings
+*/
+template <typename BaseAlgorithm>
+const std::vector<std::string>
+AlgorithmAdapter<BaseAlgorithm>::seeAlso() const {
+  try {
+    auto seeAlsoPyList = callMethod<object>(getSelf(), "seeAlso");
+    return Converters::PySequenceToVector<std::string>(seeAlsoPyList)();
+  } catch (UndefinedAttributeError &) {
+    return {};
+  }
+}
+
 /**
  * Returns the summary of the algorithm. If not overridden
  * it returns defaultSummary
diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp
index b56c86b52a72582f79e025cd3f7d8efa7df91b6e..a28814977f3f3b5448105fbb38e3b243409ac9f7 100644
--- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp
@@ -40,7 +40,7 @@ namespace {
  */
 template <typename MDE, size_t nd>
 void MDEventWorkspaceExportImpl(const char *className) {
-  typedef MDEventWorkspace<MDE, nd> ExportType;
+  using ExportType = MDEventWorkspace<MDE, nd>;
 
   class_<ExportType, bases<IMDEventWorkspace>, boost::noncopyable>(className,
                                                                    no_init);
diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
index a6dabca2af6c0be627465d9150ef31e90a3ef1dd..7987881b15b54e526ba5644ac0d220475da0777e 100644
--- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
+++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
@@ -72,8 +72,8 @@ public:
       const auto &spectrumDefinition = (*spectrumDefinitions)[i];
       std::vector<size_t> detectorIndices;
 
-      for (size_t j = 0; j < spectrumDefinition.size(); ++j) {
-        size_t detectorIndex = spectrumDefinition[j].first;
+      for (const auto &j : spectrumDefinition) {
+        size_t detectorIndex = j.first;
         detectorIndices.emplace_back(std::move(detectorIndex));
       }
 
@@ -133,12 +133,11 @@ public:
       ws.setBinEdges(i, std::move(binEdgeData));
 
       SpectrumDefinition specDef;
-      for (size_t j = 0; j < detectorIndices.size(); ++j) {
-        size_t detectorIndex = detectorIndices[j];
+      for (auto detectorIndex : detectorIndices) {
         specDef.add(detectorIndex);
       }
       spectrumDefinitions.emplace_back(std::move(specDef));
-      spectrumNumbers.emplace_back(std::move(specNum));
+      spectrumNumbers.emplace_back(specNum);
     }
 
     std::string instrumentXML = extract<std::string>(state["instrument_xml"]);
diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp
index 99f9c702f97216cda4c07f1ad073c7d4ecd57d85..696b7904f1be53f8581b24550a3ba50687f4d2f2 100644
--- a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp
+++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp
@@ -42,8 +42,8 @@ void setR(Goniometer &self, const object &data) {
 void export_Goniometer() {
 
   // return_value_policy for read-only numpy array
-  typedef return_value_policy<Policies::MatrixRefToNumpy<
-      Converters::WrapReadOnly>> return_readonly_numpy;
+  using return_readonly_numpy =
+      return_value_policy<Policies::MatrixRefToNumpy<Converters::WrapReadOnly>>;
 
   class_<Goniometer>("Goniometer", init<>(arg("self")))
       .def(init<Goniometer const &>((arg("self"), arg("other"))))
diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp
index 1256ce10fc66ad9dec6b1e4fd4d9c93ea20fa911..be82085147f67fe64a2cd5fa9dc2725631fac778 100644
--- a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp
+++ b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp
@@ -45,8 +45,8 @@ Mantid::Kernel::V3D hklFromQ(OrientedLattice &self, const object &vec) {
 
 void export_OrientedLattice() {
   /// return_value_policy for read-only numpy array
-  typedef return_value_policy<Policies::MatrixRefToNumpy<
-      Converters::WrapReadOnly>> return_readonly_numpy;
+  using return_readonly_numpy =
+      return_value_policy<Policies::MatrixRefToNumpy<Converters::WrapReadOnly>>;
 
   class_<OrientedLattice, bases<UnitCell>>(
       "OrientedLattice",
diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp
index 38682c016d52d687b2f41af37f75da13dce45a09..d8a6c0fb89ee2e190f7f353e413f8a705006c98a 100644
--- a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp
+++ b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp
@@ -67,8 +67,8 @@ void export_UnitCell() {
       .export_values();
 
   /// return_value_policy for read-only numpy array
-  typedef return_value_policy<Policies::MatrixRefToNumpy<
-      Converters::WrapReadOnly>> return_readonly_numpy;
+  using return_readonly_numpy =
+      return_value_policy<Policies::MatrixRefToNumpy<Converters::WrapReadOnly>>;
 
   class_<UnitCell>(
       "UnitCell",
diff --git a/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in b/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in
index fd9cb6edb933387f4e5f9d9192a3be7c719814c0..39e4c870655240527087c65e8c93bfb3453c370e 100644
--- a/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in
+++ b/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in
@@ -10,8 +10,6 @@
 #define PY_ARRAY_UNIQUE_SYMBOL GEOMETRY_ARRAY_API
 #include <numpy/arrayobject.h>
 
-using boost::python::def;
-
 // Forward declare
 @EXPORT_DECLARE@
 
diff --git a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index b7f0589931fca6b907c0ed4b3037ae394ee9a4fd..865b313bab49fc5fcfec36706a0b89ca094b019c 100644
--- a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -179,7 +179,7 @@ copy_files_to_dir ( ${MPISETUP_PY}.py ${CMAKE_CURRENT_BINARY_DIR} ${OUTPUT_DIR}
                     PYTHON_INSTALL_FILES )
 
 # Package version
-if ( WIN32 OR APPLE )
+if ( WIN32 OR (APPLE AND ENABLE_MANTIDPLOT) )
   # NeXus library is in the same place relative to the Python library
   get_filename_component ( NEXUSLIB_FILE ${NEXUSLIB} NAME )
   set ( NEXUSLIB ../../${NEXUSLIB_FILE} )
diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp
index bf501e26a4bc419856aa96a90cc9b3b9c9969542..fb49c9d5934b2a8727b8d2addf5bf723083511d0 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp
@@ -22,6 +22,7 @@ extern template int NDArrayTypeIndex<unsigned long>::typenum;
 extern template int NDArrayTypeIndex<unsigned long long>::typenum;
 extern template int NDArrayTypeIndex<float>::typenum;
 extern template int NDArrayTypeIndex<double>::typenum;
+extern template int NDArrayTypeIndex<Mantid::Types::Core::DateAndTime>::typenum;
 
 namespace Impl {
 /**
diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp
index 17e46c70885598abac82d7128e2787accf168869..539d41c26a28fd1f1c791fb2a19bf2fa4eb9cfc3 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp
@@ -42,7 +42,14 @@ PyArray_Descr *descr_ns() { return func_PyArray_Descr("M8[ns]"); }
 // internal function that handles raw pointer
 boost::shared_ptr<Types::Core::DateAndTime>
 to_dateandtime(const PyObject *datetime) {
+#if __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-qual"
+#endif
   if (!PyArray_IsScalar(datetime, Datetime)) {
+#if __clang__
+#pragma clang diagnostic pop
+#endif
     throw std::runtime_error("Expected datetime64");
   }
 
diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
index 94668f5a1d3fd66fc43bc29e7028c12a7f9e7fd5..2045edd668b047f205790598a7a7c4fa25018775 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp
@@ -27,6 +27,14 @@ extern template int NDArrayTypeIndex<unsigned long>::typenum;
 extern template int NDArrayTypeIndex<unsigned long long>::typenum;
 extern template int NDArrayTypeIndex<float>::typenum;
 extern template int NDArrayTypeIndex<double>::typenum;
+extern template char NDArrayTypeIndex<bool>::typecode;
+extern template char NDArrayTypeIndex<int>::typecode;
+extern template char NDArrayTypeIndex<long>::typecode;
+extern template char NDArrayTypeIndex<long long>::typecode;
+extern template char NDArrayTypeIndex<unsigned int>::typecode;
+extern template char NDArrayTypeIndex<unsigned long>::typecode;
+extern template char NDArrayTypeIndex<unsigned long long>::typecode;
+extern template char NDArrayTypeIndex<double>::typecode;
 }
 
 namespace {
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp
index b27dc7f3d44160a036bf4ff62c26c7359549fa84..365d7a182bcfcd6f803b52e8a2b224fcc27c282d 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp
@@ -24,8 +24,8 @@ using namespace boost::python;
 
 namespace {
 /// return_value_policy for cloned numpy array
-typedef return_value_policy<Policies::VectorRefToNumpy<Converters::Clone>>
-    return_cloned_numpy;
+using return_cloned_numpy =
+    return_value_policy<Policies::VectorRefToNumpy<Converters::Clone>>;
 
 #define EXPORT_ARRAY_PROP(type, prefix)                                        \
   class_<ArrayProperty<type>, bases<PropertyWithValue<std::vector<type>>>,     \
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp
index a6808163eb92b1af6b8efadd9a40d7fd6eea1b77..8ac77740b694cbb1ce838e6462ba6e168ca9ccc2 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp
@@ -7,7 +7,6 @@
 
 using namespace boost::python;
 using Mantid::Kernel::ConfigObserver;
-using Mantid::PythonInterface::Environment::GlobalInterpreterLock;
 using Mantid::PythonInterface::Environment::callMethod;
 
 class ConfigObserverWrapper : public ConfigObserver {
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp
index 112c0c3c08b712806f631f5d79e82daf5d95412f..4e4c3a1bb6f54ca8044304d60f8453caf8eefc7f 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp
@@ -7,7 +7,6 @@
 
 using namespace boost::python;
 using Mantid::Kernel::ConfigPropertyObserver;
-using Mantid::PythonInterface::Environment::GlobalInterpreterLock;
 using Mantid::PythonInterface::Environment::callMethod;
 
 class ConfigPropertyObserverWrapper : public ConfigPropertyObserver {
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp
index 74dba6e8084af5e118d3ca7f8e0af1171be73e6c..28827a4f74c1c376c909db3243cdff0a4127aceb 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp
@@ -24,7 +24,7 @@ void export_Logger() {
   register_ptr_to_python<boost::shared_ptr<Logger>>();
 
   // To distinguish between the overloaded functions
-  typedef void (Logger::*LogLevelFunction)(const std::string &);
+  using LogLevelFunction = void (Logger::*)(const std::string &);
 
   class_<Logger, boost::noncopyable>(
       "Logger", init<std::string>((arg("self"), arg("name"))))
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp
index a95a63d7ba23d87c40e62995998276396ef0acd7..e3edcdc1183cad0465fc58d9ca6bfe75450117d1 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp
@@ -52,7 +52,7 @@ private:
   }
 
 public:
-  typedef OptionalBool HeldType;
+  using HeldType = OptionalBool;
 
   /**
    * Set function to handle Python -> C++ calls and get the correct type
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp
index be80c22864f22bd33dced769f171306b7663d5ad..4149d476e7a3877a50e0c3b01d265ba18da50f6f 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp
@@ -15,7 +15,7 @@ using Mantid::PythonInterface::Registry::createPropertyManager;
 using namespace boost::python;
 
 /// Weak pointer to DataItem typedef
-typedef boost::weak_ptr<PropertyManager> PropertyManager_wptr;
+using PropertyManager_wptr = boost::weak_ptr<PropertyManager>;
 
 namespace {
 /**
@@ -48,8 +48,8 @@ void export_PropertyManagerDataService() {
 
   register_ptr_to_python<PropertyManager_wptr>();
 
-  typedef DataServiceExporter<PropertyManagerDataServiceImpl,
-                              PropertyManager_sptr> PMDExporter;
+  using PMDExporter =
+      DataServiceExporter<PropertyManagerDataServiceImpl, PropertyManager_sptr>;
   auto pmdType = PMDExporter::define("PropertyManagerDataServiceImpl");
 
   pmdType.def("Instance", &PropertyManagerDataService::Instance,
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp
index 2a04f3d761ffc5e8b1154f1e81290b7e8474e278..4f4aa9871ac8f709355021a53c62d31fd239ed12 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp
@@ -29,12 +29,12 @@ createPropertyManagerPropertyWithDict(const std::string &name,
 
 void export_PropertyManagerProperty() {
   // export base class
-  typedef PropertyManager_sptr BaseValueType;
+  using BaseValueType = PropertyManager_sptr;
   PropertyWithValueExporter<BaseValueType>::define(
       "PropertyManagerPropertyWithValue");
 
   // leaf class type
-  typedef PropertyManagerProperty::BaseClass BaseClassType;
+  using BaseClassType = PropertyManagerProperty::BaseClass;
   class_<PropertyManagerProperty, bases<BaseClassType>, boost::noncopyable>(
       "PropertyManagerProperty", no_init)
       .def(init<const std::string &, const unsigned int>(
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp
index f63ae0fca86effc3b1c7ac5f71321f2ff25f63b3..ff875b0733244cf090d75c1c892324f3dddad479 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp
@@ -180,9 +180,9 @@ GCC_DIAG_ON(conversion)
 //============================================
 
 // Function pointer to real implementation of getMoments
-typedef std::vector<double>(*MomentsFunction)(const std::vector<double> &indep,
-                                              const std::vector<double> &depend,
-                                              const int);
+using MomentsFunction = std::vector<double>(*)(const std::vector<double> &,
+                                               const std::vector<double> &,
+                                               const int);
 
 /**
  * The implementation for getMomentsAboutOrigin & getMomentsAboutOriginMean for
@@ -275,7 +275,7 @@ GCC_DIAG_ON(conversion)
 
 void export_Statistics() {
   // typedef std::vector --> numpy array result converter
-  typedef return_value_policy<Policies::VectorToNumpy> ReturnNumpyArray;
+  using ReturnNumpyArray = return_value_policy<Policies::VectorToNumpy>;
 
   // define a new "Statistics" scope so that everything is called as
   // Statistics.getXXX
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp
index 8027b450a63954212624079bed9b825313198e52..86d0f2bb481cec94d3e5ed4f2e7b65c4e60191ad 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp
@@ -7,10 +7,9 @@ using namespace boost::python;
 
 void export_UnitConversion() {
   // Function pointer typedef
-  typedef double (*StringVersion)(
-      const std::string &src, const std::string &dest, const double srcValue,
-      const double l1, const double l2, const double theta,
-      const DeltaEMode::Type emode, const double efixed);
+  using StringVersion = double (
+      *)(const std::string &, const std::string &, const double, const double,
+         const double, const double, const DeltaEMode::Type, const double);
 
   class_<UnitConversion, boost::noncopyable>("UnitConversion", no_init)
       .def("run", (StringVersion)&UnitConversion::run,
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
index 6f3e76a80835f67e7e7312eabc382d5a09456afb..fe450438ced657000e70a620af70125a1f6db39f 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp
@@ -16,7 +16,7 @@ using namespace boost::python;
 namespace {
 boost::shared_ptr<UnitLabel>
 createLabel(const object &ascii, const object &utf8, const object &latex) {
-  typedef UnitLabel::Utf8String::value_type Utf8Char;
+  using Utf8Char = UnitLabel::Utf8String::value_type;
   if (PyUnicode_Check(utf8.ptr())) {
     auto length = PyUnicode_GetSize(utf8.ptr());
     boost::scoped_array<Utf8Char> buffer(new Utf8Char[length]);
diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp
index e59a71bc8174c8cd5ffb8071c6ccd91ccf87a38f..17530ed6d4faaea35ec4c662df9767326c1c3da1 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp
@@ -16,8 +16,8 @@ namespace PythonInterface {
 namespace Registry {
 namespace {
 /// Lookup map type
-typedef std::map<PyTypeObject const *, boost::shared_ptr<PropertyValueHandler>>
-    PyTypeIndex;
+using PyTypeIndex =
+    std::map<const PyTypeObject *, boost::shared_ptr<PropertyValueHandler>>;
 
 /**
  * Initialize lookup map
@@ -26,21 +26,21 @@ void initTypeLookup(PyTypeIndex &index) {
   assert(index.empty());
 
   // Map the Python types to the best match in C++
-  typedef TypedPropertyValueHandler<double> FloatHandler;
+  using FloatHandler = TypedPropertyValueHandler<double>;
   index.emplace(&PyFloat_Type, boost::make_shared<FloatHandler>());
 
-  typedef TypedPropertyValueHandler<bool> BoolHandler;
+  using BoolHandler = TypedPropertyValueHandler<bool>;
   index.emplace(&PyBool_Type, boost::make_shared<BoolHandler>());
 
   // Python 2/3 have an arbitrary-sized long type. The handler
   // will raise an error if the input value overflows a C long
-  typedef TypedPropertyValueHandler<long> IntHandler;
+  using IntHandler = TypedPropertyValueHandler<long>;
   index.emplace(&PyLong_Type, boost::make_shared<IntHandler>());
 
   // In Python 3 all strings are unicode but in Python 2 unicode strings
   // must be explicitly requested. The C++ string handler will accept both
   // but throw and error if the unicode string contains non-ascii characters
-  typedef TypedPropertyValueHandler<std::string> AsciiStrHandler;
+  using AsciiStrHandler = TypedPropertyValueHandler<std::string>;
   // Both versions have unicode objects
   index.emplace(&PyUnicode_Type, boost::make_shared<AsciiStrHandler>());
 
@@ -67,8 +67,8 @@ const PyTypeIndex &getTypeIndex() {
 }
 
 // Lookup map for arrays
-typedef std::map<std::string, boost::shared_ptr<PropertyValueHandler>>
-    PyArrayIndex;
+using PyArrayIndex =
+    std::map<std::string, boost::shared_ptr<PropertyValueHandler>>;
 
 /**
  * Initialize lookup map
@@ -77,18 +77,18 @@ void initArrayLookup(PyArrayIndex &index) {
   assert(index.empty());
 
   // Map the Python array types to the best match in C++
-  typedef SequenceTypeHandler<std::vector<double>> FloatArrayHandler;
+  using FloatArrayHandler = SequenceTypeHandler<std::vector<double>>;
   index.emplace("FloatArray", boost::make_shared<FloatArrayHandler>());
 
-  typedef SequenceTypeHandler<std::vector<std::string>> StringArrayHandler;
+  using StringArrayHandler = SequenceTypeHandler<std::vector<std::string>>;
   index.emplace("StringArray", boost::make_shared<StringArrayHandler>());
 
-  typedef SequenceTypeHandler<std::vector<long>> LongIntArrayHandler;
+  using LongIntArrayHandler = SequenceTypeHandler<std::vector<long>>;
   index.emplace("LongIntArray", boost::make_shared<LongIntArrayHandler>());
 
 #if PY_MAJOR_VERSION < 3
   // Backwards compatible behaviour
-  typedef SequenceTypeHandler<std::vector<int>> IntArrayHandler;
+  using IntArrayHandler = SequenceTypeHandler<std::vector<int>>;
   index.emplace("IntArray", boost::make_shared<IntArrayHandler>());
 #endif
 }
diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp
index 0c6518234b9e8acb8ea81e6149c3b85c541bb63f..fdde2e989b8723d6120d3953f6ed72c1737f826d 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp
@@ -44,7 +44,7 @@ void SequenceTypeHandler<ContainerType>::set(
     Kernel::IPropertyManager *alg, const std::string &name,
     const boost::python::object &value) const {
   using namespace boost::python;
-  typedef typename ContainerType::value_type DestElementType;
+  using DestElementType = typename ContainerType::value_type;
 
   // Current workaround for things that still pass back wrapped vectors...
   if (boost::starts_with(value.ptr()->ob_type->tp_name, "std_vector")) {
@@ -82,7 +82,7 @@ std::unique_ptr<Kernel::Property> SequenceTypeHandler<ContainerType>::create(
     const std::string &name, const boost::python::object &defaultValue,
     const boost::python::object &validator,
     const unsigned int direction) const {
-  typedef typename ContainerType::value_type DestElementType;
+  using DestElementType = typename ContainerType::value_type;
   using Kernel::IValidator;
   using Kernel::PropertyWithValue;
   using boost::python::extract;
diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp
index f111c609993895cff8ae9cfad732222d9f45c0e1..eb9f856cde50767053cea1dabf85be82224e306d 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp
@@ -15,8 +15,8 @@ namespace // <anonymous>
 /// Typedef the map of type_info -> handler objects. We store
 /// boost::python::type_info objects so that they work across DLL boundaries
 /// unlike std::type_info objects
-typedef std::map<const boost::python::type_info,
-                 boost::shared_ptr<PropertyValueHandler>> TypeIDMap;
+using TypeIDMap = std::map<const boost::python::type_info,
+                           boost::shared_ptr<PropertyValueHandler>>;
 
 /**
  * Returns a reference to the static type map
diff --git a/Framework/PythonInterface/mantid/simpleapi.py b/Framework/PythonInterface/mantid/simpleapi.py
index 290fe3d92844c017dde699e8769ac18a1fb9949d..b573512873245c3fcaab9f0477585f68ae3ec009 100644
--- a/Framework/PythonInterface/mantid/simpleapi.py
+++ b/Framework/PythonInterface/mantid/simpleapi.py
@@ -266,6 +266,10 @@ def StartLiveData(*args, **kwargs):
         try:
             if value is None:
                 value = kwargs.pop(name)
+            else:
+                # We don't need the value, but still need to remove from kwargs
+                # so that this property isn't set again later
+                kwargs.pop(name, None)
             algm.setProperty(name, value)
 
         except ValueError as ve:
diff --git a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
index 4faee2742fa410fcdd995eb10eb5940ccb9d4091..11b3ee7637f8cabc129c2b0feac6254c94db330c 100644
--- a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
+++ b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py
@@ -56,6 +56,9 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm):
     def category(self):
         return "Diffraction\\Reduction"
 
+    def seeAlso(self):
+        return [ "AlignAndFocusPowder" ]
+
     def name(self):
         return "AlignAndFocusPowderFromFiles"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/AlignComponents.py b/Framework/PythonInterface/plugins/algorithms/AlignComponents.py
index fda95bd0c683a72d06d32aca40e3f46d5c580070..4232e5c6914054091a8a3dba7037f57bfddc9a5c 100644
--- a/Framework/PythonInterface/plugins/algorithms/AlignComponents.py
+++ b/Framework/PythonInterface/plugins/algorithms/AlignComponents.py
@@ -30,6 +30,9 @@ class AlignComponents(PythonAlgorithm):
         """
         return "Diffraction"
 
+    def seeAlso(self):
+        return [ "GetDetOffsetsMultiPeaks","CalibrateRectangularDetectors" ]
+
     def name(self):
         """
         Mantid required
diff --git a/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py b/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py
index b0579735421a4cb5a149be264165d3507364e59c..9498be25f5c0a8e17afdd4c94cc2d12a024f1171 100644
--- a/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py
+++ b/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py
@@ -1,6 +1,6 @@
 from __future__ import print_function
 
-from mantid.simpleapi import CreateWorkspace, RenameWorkspace
+from mantid.simpleapi import CreateWorkspace, Transpose, Multiply
 from mantid.api import AlgorithmFactory, PropertyMode, PythonAlgorithm, WorkspaceProperty
 from mantid.kernel import Direction
 import numpy as np
@@ -11,6 +11,9 @@ class ApplyDetectorScanEffCorr(PythonAlgorithm):
     def category(self):
         return 'ILL\\Diffraction;Diffraction\\Utility'
 
+    def seeAlso(self):
+        return [ "PowderDiffILLDetEffCorr","LoadILLDiffraction" ]
+
     def name(self):
         return 'ApplyDetectorScanEffCorr'
 
@@ -33,34 +36,18 @@ class ApplyDetectorScanEffCorr(PythonAlgorithm):
 
     def PyExec(self):
         input_ws = self.getProperty("InputWorkspace").value
-        efficiency_workspace = self.getProperty("DetectorEfficiencyWorkspace").value
-
-        y_values = input_ws.extractY()
-        y_values = y_values.reshape(y_values.size)
-        e_values = input_ws.extractE()
-        e_values = e_values.reshape(e_values.size)
-
-        efficiency_values = efficiency_workspace.extractY()
-        efficiency_values = efficiency_values.reshape(efficiency_values.size)
-
-        detector_info = input_ws.detectorInfo()
-        for i in range(detector_info.size()):
-            if detector_info.isMonitor(i):
-                efficiency_values = np.insert(efficiency_values, 0, 1) # add the monitor efficiency
-
-        if (y_values.size % efficiency_values.size) is not 0:
-            raise ValueError('Number of entries in input workspace is not a multiple of number of efficiencies in detector efficiency '
+        eff_ws = self.getProperty("DetectorEfficiencyWorkspace").value
+        transposed = Transpose(InputWorkspace=eff_ws, StoreInADS=False)
+        efficiencies = transposed.extractY().flatten()
+        errors = transposed.extractE().flatten()
+        n_hist = input_ws.getNumberHistograms()
+        if n_hist % efficiencies.size != 0:
+            raise ValueError('Number of histograms in input workspace is not a multiple of number of entries in detector efficiency '
                              'workspace.')
-        number_time_indexes = y_values.size / efficiency_values.size
-
-        full_efficiency_values = np.repeat(efficiency_values, number_time_indexes)
-        y_values *= full_efficiency_values
-        e_values *= full_efficiency_values
-
-        __output_ws = CreateWorkspace(DataX=input_ws.extractX(), DataY=y_values, DataE=e_values, Nspec=y_values.size,
-                                      ParentWorkspace=input_ws)
-
-        RenameWorkspace(__output_ws, self.getPropertyValue("OutputWorkspace"))
-        self.setProperty("OutputWorkspace", __output_ws)
+        n_time_indexes = n_hist / efficiencies.size
+        to_multiply = CreateWorkspace(DataY=np.repeat(efficiencies, n_time_indexes),DataE=np.repeat(errors, n_time_indexes),
+                                      DataX=np.zeros(n_hist), NSpec=n_hist, StoreInADS=False)
+        output = Multiply(LHSWorkspace=input_ws, RHSWorkspace=to_multiply, OutputWorkspace=self.getPropertyValue("OutputWorkspace"))
+        self.setProperty("OutputWorkspace", output)
 
 AlgorithmFactory.subscribe(ApplyDetectorScanEffCorr)
diff --git a/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py b/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py
index 23227fbd37c46a0f850591b206c2e9e709834253..1cc3cc472c2c59d86f4847500b0296b7db23e472 100644
--- a/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py
+++ b/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py
@@ -103,6 +103,9 @@ class BASISDiffraction(DataProcessorAlgorithm):
     def summary(self):
         return "Multiple-file BASIS reduction for diffraction detectors."
 
+    def seeAlso(self):
+        return [ "AlignDetectors","DiffractionFocussing","SNSPowderReduction" ]
+
     def PyInit(self):
         # Input validators
         array_length_three = FloatArrayLengthValidator(3)
diff --git a/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py b/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py
index 3b284a3b6a0b6933922cf7107fdeee5678730864..8a43ed1c89ea2e72b0ea4beba09e8480f8f98ec7 100644
--- a/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py
+++ b/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py
@@ -45,6 +45,9 @@ class BASISReduction311(PythonAlgorithm):
     def category(self):
         return "Inelastic\\Reduction"
 
+    def seeAlso(self):
+        return [ "BASISReduction" ]
+
     def name(self):
         return "BASISReduction311"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py b/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py
index 0c5d8382208ebce34de10cf649e0ee7b5a308b96..41caf00b74322d81bb0a8dee3754a61ae8c8825e 100644
--- a/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py
+++ b/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py
@@ -20,6 +20,9 @@ class CalculateSampleTransmission(PythonAlgorithm):
     def category(self):
         return 'Sample'
 
+    def seeAlso(self):
+        return [ "SetSampleMaterial" ]
+
     def summary(self):
         return 'Calculates the scattering & transmission for a given sample material and size over a given wavelength range.'
 
diff --git a/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py b/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py
index 234a605e8d85102e77e50478bf1e97665a353692..564fec0e0b67f8a90f478403a6fcb3b8e77f0442 100644
--- a/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py
+++ b/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py
@@ -52,6 +52,9 @@ class CalibrateRectangularDetectors(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Calibration"
 
+    def seeAlso(self):
+        return [ "GetDetectorOffsets" ]
+
     def name(self):
         return "CalibrateRectangularDetectors"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py b/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py
index c474b0f71040ac4faf9d36f36e812a6f6c48097d..d9eca9bb05c256f34cf7dc4bf5736c461da14bd5 100644
--- a/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py
+++ b/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py
@@ -14,6 +14,9 @@ class CheckForSampleLogs(PythonAlgorithm):
         """
         return "Utility\\Workspaces"
 
+    def seeAlso(self):
+        return [ "CompareSampleLogs","CopyLogs" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py b/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py
index 6aaabfdf879bd1133bad7308efebbdfed34a3f9c..b6baac7f332d1dcaea763c6e17c7a8abf89ff96c 100644
--- a/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py
+++ b/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py
@@ -17,6 +17,9 @@ class CleanFileCache(PythonAlgorithm):
         """
         return "Workflow\\DataHandling"
 
+    def seeAlso(self):
+        return [ "ClearCache" ]
+
     def name(self):
         """
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py b/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py
index 2a7992709b78dc2850e2be9a4d6a5ac716f16dcf..e6a6bca8c7b5522145bb68acf24914f4966cd528 100644
--- a/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py
+++ b/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py
@@ -25,6 +25,9 @@ class CompareSampleLogs(PythonAlgorithm):
         """
         return "Utility\\Workspaces"
 
+    def seeAlso(self):
+        return [ "CompareWorkspaces","CheckForSampleLogs","CopySample" ]
+
     def name(self):
         """
         Returns name
diff --git a/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py b/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py
index cefc7c15e5474f13345d23d03763eeb6fe562476..869d8b5b149ee6ff472d6f685e75e39bf439faa1 100644
--- a/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py
+++ b/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py
@@ -11,6 +11,9 @@ class ConjoinFiles(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Text"
 
+    def seeAlso(self):
+        return [ "ConjoinWorkspaces" ]
+
     def name(self):
         return "ConjoinFiles"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py b/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py
index cbc4405b21d0297a0b8cbfbf42a9b265b71ce47d..40240565811cb2e853128eb183d60d3107a16a36 100644
--- a/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py
+++ b/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py
@@ -17,6 +17,9 @@ class ConjoinSpectra(PythonAlgorithm):
     def category(self):
         return "Transforms\\Merging"
 
+    def seeAlso(self):
+        return [ "AppendSpectra","ConjoinWorkspaces" ]
+
     def name(self):
         return "ConjoinSpectra"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py b/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py
index 46ce04c74c2d931dcdf220ade2a49e05397d1b13..db4ac9fec84d3be62ca92f10c928c71f71231ae9 100644
--- a/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py
+++ b/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py
@@ -31,6 +31,9 @@ class ConvertSnsRoiFileToMask(api.PythonAlgorithm):
         """
         return "Inelastic\\Utility"
 
+    def seeAlso(self):
+        return [ "MaskDetectors" ]
+
     def name(self):
         """
         Name of the algorithm.
diff --git a/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py b/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py
index f00d6a438e4565c283a6e1ffe8ed4512f60d8786..6ff0279085ada7aabf4df8e2385b241e31ad7fd0 100644
--- a/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py
+++ b/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py
@@ -17,6 +17,9 @@ class CorrectLogTimes(mantid.api.PythonAlgorithm):
         """
         return "DataHandling\\Logs"
 
+    def seeAlso(self):
+        return [ "ChangeLogTime","CreateLogTimeCorrection","ChangePulsetime","ShiftLogTime" ]
+
     def name(self):
         """ Mantid required
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py b/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py
index 8d1d0e831e269e098ceee84acd15b8cbcbbc9f8e..a4e2f8f1f10b4d14cbad8364bc105d821622635f 100644
--- a/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py
+++ b/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py
@@ -21,6 +21,9 @@ class CorrectTOF (PythonAlgorithm):
         """
         return "Workflow\\MLZ\\TOFTOF;Transforms\\Axes"
 
+    def seeAlso(self):
+        return [ "TOFTOFMergeRuns","TOFTOFCropWorkspace" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py b/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py
index 026393dc796de4d5b908e6fdd99121d0216a0c34..39f42a823d35319152a14ee1976cedc32c0d61c2 100644
--- a/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py
+++ b/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py
@@ -16,6 +16,9 @@ class CreateEmptyTableWorkspace(PythonAlgorithm):
     def category(self):
         return 'Utility\\Workspaces'
 
+    def seeAlso(self):
+        return [ "DeleteTableRows","SortTableWorkspace" ]
+
     def PyInit(self):
         # Declare properties
         self.declareProperty(ITableWorkspaceProperty("OutputWorkspace", "", Direction.Output),
diff --git a/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py b/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py
index 579f1cc4802ac39a1904fa9fec880659bc66883d..6585d93e16388b07298c608c0e73c28faa2d9868 100644
--- a/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py
+++ b/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py
@@ -18,6 +18,9 @@ class CreateLeBailFitInput(PythonAlgorithm):
         """
         return "Diffraction\\Fitting;Utility\\Workspaces"
 
+    def seeAlso(self):
+        return [ "LeBailFit" ]
+
     def name(self):
         """
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py b/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py
index 722feb44491177aadcee60bb316158ec6e38180d..c4898987d935dbfd031f8a3892d7a0f06be0d529 100644
--- a/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py
+++ b/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py
@@ -11,6 +11,9 @@ class CropWorkspaceRagged(PythonAlgorithm):
     def category(self):
         return 'Transforms\\Splitting;Workflow'
 
+    def seeAlso(self):
+        return [ "CropWorkspace" ]
+
     def name(self):
         return 'CropWorkspaceRagged'
 
diff --git a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
index 8851d3e351b7a7fe4f70adb7a00c8b9896ca89ea..234be4b2ea84fc21523f827ad89212a4f97ec4bc 100644
--- a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
+++ b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
@@ -29,6 +29,9 @@ class DNSComputeDetEffCorrCoefs(PythonAlgorithm):
         """
         return 'Workflow\\MLZ\\DNS;CorrectionFunctions\\SpecialCorrections'
 
+    def seeAlso(self):
+        return [ "DNSFlippingRatioCorr" ]
+
     def name(self):
         """
         Returns name
diff --git a/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py b/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py
index 26e5b3b713262729936ce5baa2cf4558b4358e2f..d2c237c7e40d23d3386dd8faaa759e52e5be17ae 100644
--- a/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py
+++ b/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py
@@ -32,6 +32,9 @@ class DNSFlippingRatioCorr(PythonAlgorithm):
         """
         return 'Workflow\\MLZ\\DNS;;CorrectionFunctions\\SpecialCorrections'
 
+    def seeAlso(self):
+        return [ "DNSComputeDetEffCorrCoefs" ]
+
     def name(self):
         """
         Returns name
diff --git a/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py b/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py
index 0a98575c21b3d74bb25f6e6a1668dda2c2c08eef..8110e19d9fe1c88dc2e3d88ef38c61a483d270a9 100644
--- a/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py
+++ b/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py
@@ -30,6 +30,9 @@ class DNSMergeRuns(PythonAlgorithm):
         """
         return 'Workflow\\MLZ\\DNS'
 
+    def seeAlso(self):
+        return [ "LoadDNSLegacy" ]
+
     def name(self):
         """
         Returns name
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py b/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py
index 2e8176f65d3fbaf646fbba78e675e5805c93741f..351f905d5cb4285c6752efc0be08516718fc9421 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py
@@ -10,6 +10,9 @@ class EnggCalibrate(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Engineering"
 
+    def seeAlso(self):
+        return [ "EnggCalibrateFull" ]
+
     def name(self):
         return "EnggCalibrate"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py b/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py
index df8ed01c1260745c113ff6c63c2db27f0a5962d0..c3b5e48c07e649baefedeb5bb95e19e54cb41e63 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py
@@ -12,6 +12,9 @@ class EnggCalibrateFull(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Engineering"
 
+    def seeAlso(self):
+        return [ "EnggCalibrate" ]
+
     def name(self):
         return "EnggCalibrateFull"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py b/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py
index fab141ea1d2315f4f22fcfbb62b9860a5c2546a6..5526e2a7cff3942ce226d618bb90da2c7a559df0 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py
@@ -8,6 +8,9 @@ class EnggFitDIFCFromPeaks(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Engineering;Diffraction\\Fitting"
 
+    def seeAlso(self):
+        return [ "EnggFitPeaks","GSASIIRefineFitPeaks","Fit" ]
+
     def name(self):
         return "EnggFitPeaks"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py b/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py
index 2a58c7e58ab454a6067218bd84042ea1be3d45e2..a951a7275f84f4469850226928bd554f1f045a85 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py
@@ -19,6 +19,9 @@ class EnggFitPeaks(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Engineering;Diffraction\\Fitting"
 
+    def seeAlso(self):
+        return [ "EnggFitDIFCFromPeaks","GSASIIRefineFitPeaks","Fit" ]
+
     def name(self):
         return "EnggFitPeaks"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
index 28ecf993a48d5403c04f3ac7fa2bba021ee4fa61..128ab3e76045932c76c146d95a794468ead0df59 100644
--- a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
+++ b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py
@@ -11,6 +11,9 @@ class EnggFocus(PythonAlgorithm):
     def category(self):
         return "Diffraction\\Engineering"
 
+    def seeAlso(self):
+        return [ "AlignDetectors","DiffractionFocussing" ]
+
     def name(self):
         return "EnggFocus"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py b/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py
index 82f6ca11e41d3efaf03e9e8fbd230a16e6de559f..25167d7a36c7a7b9870b5e9d0c371c6b3d3f8e42 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py
@@ -40,6 +40,9 @@ class ExportExperimentLog(PythonAlgorithm):
         """
         return 'DataHandling\\Logs'
 
+    def seeAlso(self):
+        return [ "ExportSampleLogsToCSVFile" ]
+
     def PyInit(self):
         """ Declaration of properties
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py b/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py
index dac0fb3c0d80e405883a551397ff464aec38629e..aca44bbbd2136b978354554146d6e686dff117ec 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py
@@ -46,6 +46,9 @@ class ExportGeometry(PythonAlgorithm):
     def category(self):
         return "Utility\\Instrument"
 
+    def seeAlso(self):
+        return [ "LoadInstrument" ]
+
     def name(self):
         return "ExportGeometry"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py
index be7dd8390cf2485a6eb3d434089d55f1311c5faf..dad5fffe9e8d1573bb7f673e2569204f00d35b1b 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py
@@ -41,6 +41,9 @@ class ExportSampleLogsToCSVFile(PythonAlgorithm):
         """
         return "DataHandling\\Logs"
 
+    def seeAlso(self):
+        return [ "ExportExperimentLog" ]
+
     def name(self):
         """ Algorithm name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
index 69310ca255d518d027b0690d75a58c8ccfc724d7..cc407f5afdd96aedea7c2857c183e09fc80135ba 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
@@ -165,6 +165,9 @@ class ExportSpectraMask(PythonAlgorithm):
         """
         return "DataHandling\\Masking"
 
+    def seeAlso(self):
+        return [ "SaveMask","ExportSpectraMask" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
index 15f1a2fcf4363537084155b84c9d6230cefc5ae0..54e3154eb24bc8add89d2a3d77f4059d4b6c58ce 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
@@ -11,6 +11,9 @@ class ExtractMonitors(DataProcessorAlgorithm):
     def summary(self):
         return 'Separates the monitors and/or detectors into separate workspaces.'
 
+    def seeAlso(self):
+        return [ "ExtractMonitorWorkspace" ]
+
     def PyInit(self):
         self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '',
                                                      direction=Direction.Input),
diff --git a/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py b/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py
index 450554a5dd5f918555a3404dc72c2c4f08779e4c..5089d9fa7cc9a9cae933752dd4429b496f32814a 100644
--- a/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py
+++ b/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py
@@ -12,6 +12,9 @@ class FilterLogByTime(PythonAlgorithm):
     def category(self):
         return "Events\\EventFiltering"
 
+    def seeAlso(self):
+        return [ "FilterByTime","FilterByLogValue" ]
+
     def name(self):
         return "FilterLogByTime"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/FitGaussian.py b/Framework/PythonInterface/plugins/algorithms/FitGaussian.py
index 8777631a52d5228667de2928441f4a64f2f8f22c..fe11460f638beb294ae673481bcef879406234aa 100644
--- a/Framework/PythonInterface/plugins/algorithms/FitGaussian.py
+++ b/Framework/PythonInterface/plugins/algorithms/FitGaussian.py
@@ -11,6 +11,9 @@ class FitGaussian(PythonAlgorithm):
     def category(self):
         return "Optimization"
 
+    def seeAlso(self):
+        return [ "Fit" ]
+
     def PyInit(self):
         # input
         self.declareProperty(MatrixWorkspaceProperty("Workspace", "", Direction.Input),
diff --git a/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py b/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py
index 93aa61dbf9ff9a7f7eeeaf643d1ca636e24c1f67..22db259e49a92c1b3caa9fc846d5fa05bbe63fe3 100644
--- a/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py
+++ b/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py
@@ -40,11 +40,14 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
     PROP_XMIN = "XMin"
 
     LATTICE_TABLE_PARAMS = ["length_a", "length_b", "length_c", "angle_alpha", "angle_beta", "angle_gamma", "volume"]
-    REFINEMENT_METHODS = ["Pawley refinement", "Rietveld refinement", "Peak fitting"]
+    REFINEMENT_METHODS = ["Pawley refinement", "Rietveld refinement"]
 
     def category(self):
         return "Diffraction\\Engineering;Diffraction\\Fitting"
 
+    def seeAlso(self):
+        return [ "LoadGSS","SaveGSS","Fit","EnggFitPeaks" ]
+
     def name(self):
         return "GSASIIRefineFitPeaks"
 
@@ -53,13 +56,22 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
                 "using GSAS-II scriptable API")
 
     def validateInputs(self):
+        errors = {}
+
         x_min = self.getProperty(self.PROP_XMIN)
         x_max = self.getProperty(self.PROP_XMAX)
-
         if not x_max.isDefault and x_max.value <= x_min.value:
-            return {self.PROP_XMAX: "{} must be greater than {}".format(self.PROP_XMAX, self.PROP_XMIN)}
+            errors[self.PROP_XMAX] = "{} must be greater than {}".format(self.PROP_XMAX, self.PROP_XMIN)
+
+        input_ws = self.getProperty(self.PROP_INPUT_WORKSPACE).value
+        input_ws_d = mantid.ConvertUnits(InputWorkspace=input_ws, Target="dSpacing", StoreInADS=False)
+        max_d = max(input_ws_d.readX(0))
+        pawley_dmin = self.getProperty(self.PROP_PAWLEY_DMIN).value
+        if pawley_dmin > max_d:
+            errors[self.PROP_PAWLEY_DMIN] = "{}={} is greater than the max dSpacing value in the input workspace ({})" \
+                                             .format(self.PROP_PAWLEY_DMIN, pawley_dmin, max_d)
 
-        return {}
+        return errors
 
     def PyInit(self):
         self.declareProperty(name=self.PROP_REFINEMENT_METHOD, defaultValue=self.REFINEMENT_METHODS[0],
@@ -80,10 +92,12 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
 
         self.declareProperty(name=self.PROP_XMIN, defaultValue=0.0, direction=Direction.Input,
                              doc="Minimum x value to use for refinement, in the same units as the input workspace. " +
-                                 "Leave blank to refine in the range 0.0 to {}".format(self.PROP_XMAX))
+                                 "Leave blank to refine from the start of the data to {0}. Note, if {1} corresponds to "
+                                 "a greater TOF value than this, then {1} is used".format(self.PROP_XMAX,
+                                                                                          self.PROP_PAWLEY_DMIN))
         self.declareProperty(name=self.PROP_XMAX, defaultValue=0.0, direction=Direction.Input,
                              doc="Maximum x value to use for refinement, in the same units as the input workspace. " +
-                                 "Leave blank to refine in the range {} to the end of the range".format(self.PROP_XMIN))
+                                 "Leave blank to refine in the range {} to the end of the data".format(self.PROP_XMIN))
         self.declareProperty(name=self.PROP_REFINE_SIGMA, defaultValue=False, direction=Direction.Input,
                              doc="Whether to refine the sigma-1 profile coefficient")
         self.declareProperty(name=self.PROP_REFINE_GAMMA, defaultValue=False, direction=Direction.Input,
@@ -110,7 +124,9 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
 
         self.declareProperty(name=self.PROP_PAWLEY_DMIN, defaultValue=1.0, direction=Direction.Input,
                              doc="For Pawley refiment: as defined in GSAS-II, the minimum d-spacing to be used in a "
-                                 "Pawley refinement. Please refer to the GSAS-II documentation for full details.")
+                                 "Pawley refinement. Please refer to the GSAS-II documentation for full details. Note, "
+                                 "if this corresponds to a TOF value less than {0} or the lowest TOF value in the data,"
+                                 " the greatest of the 3 values is used as {0}".format(self.PROP_XMIN))
         self.declareProperty(name=self.PROP_PAWLEY_NEGATIVE_WEIGHT, defaultValue=0.0, direction=Direction.Input,
                              doc="For Pawley refinement: as defined in GSAS-II, the weight for a penalty function "
                                  "applied during a Pawley refinement on resulting negative intensities. "
@@ -124,16 +140,12 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
                                  "printed (not recommended, but can be useful for debugging)")
 
     def PyExec(self):
-        refinement_method = self.getPropertyValue(self.PROP_REFINEMENT_METHOD)
-        if refinement_method == self.REFINEMENT_METHODS[2]:  # Peak fitting
-            raise NotImplementedError("GSAS-II Peak fitting not yet implemented in Mantid")
-
         with self._suppress_stdout():
             gsas_proj = self._initialise_GSAS()
 
             rwp, lattice_params = \
                 self._run_rietveld_pawley_refinement(gsas_proj=gsas_proj,
-                                                     do_pawley=refinement_method == self.REFINEMENT_METHODS[0])
+                                                     do_pawley=self._refinement_method_is_pawley())
 
             self._set_output_properties(lattice_params=lattice_params, rwp=rwp,
                                         fitted_peaks_ws=self._generate_fitted_peaks_ws(gsas_proj),
@@ -150,14 +162,16 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         table.addRow([float(lattice_params[param]) for param in self.LATTICE_TABLE_PARAMS])
         return table
 
-    def _create_refinement_params_dict(self, num_phases):
+    def _create_refinement_params_dict(self, num_phases, pawley_tmin=None):
         basic_refinement = {"set": {"Background": {"no.coeffs": 3, "refine": True},
                                     "Sample Parameters": ["Scale"]}}
 
+        input_ws = self.getProperty(self.PROP_INPUT_WORKSPACE).value
         x_max = self.getProperty(self.PROP_XMAX).value
-        if x_max:
-            x_min = self.getProperty(self.PROP_XMIN).value
-            basic_refinement["set"].update({"Limits": [x_min, x_max]})
+        if not x_max:
+            x_max = max(input_ws.readX(0))
+        x_min = max(pawley_tmin, min(input_ws.readX(0)), self.getProperty(self.PROP_XMIN).value)
+        basic_refinement["set"].update({"Limits": [x_min, x_max]})
 
         scale_refinement = {"set": {"Scale": True},
                             "phases": range(1, num_phases)}
@@ -175,14 +189,17 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
 
         return [basic_refinement, scale_refinement, unit_cell_refinement, profile_coeffs_refinement, {}]
 
+    def _refinement_method_is_pawley(self):
+        return self.getPropertyValue(self.PROP_REFINEMENT_METHOD) == self.REFINEMENT_METHODS[0]
+
     def _extract_spectrum_from_workspace(self):
         """
         Extract a single spectrum from the input workspace. If the input workspace only has one spectrum then just
         return the input workspace
         :return: Single-spectrum workspace
         """
-        ws = self.getPropertyValue(self.PROP_INPUT_WORKSPACE)
-        if mtd[ws].getNumberHistograms > 1:
+        ws = self.getProperty(self.PROP_INPUT_WORKSPACE).value
+        if ws.getNumberHistograms > 1:
             ws_index = self.getPropertyValue(self.PROP_WORKSPACE_INDEX)
             spectrum = mantid.ExtractSpectra(InputWorkspace=ws, StartWorkspaceIndex=ws_index,
                                              EndWorkspaceIndex=ws_index, StoreInADS=False)
@@ -192,7 +209,7 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         return spectrum
 
     def _generate_fitted_peaks_ws(self, gsas_proj):
-        input_ws = self.getPropertyValue(self.PROP_INPUT_WORKSPACE)
+        input_ws = self.getProperty(self.PROP_INPUT_WORKSPACE).value
         fitted_peaks_ws_name = self.getPropertyValue(self.PROP_OUT_FITTED_PEAKS_WS)
         fitted_peaks_ws = mantid.CloneWorkspace(InputWorkspace=input_ws, OutputWorkspace=fitted_peaks_ws_name,
                                                 StoreInADS=False)
@@ -203,6 +220,26 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         fitted_peaks_ws.setY(0, fitted_peaks_y_unmasked)
         return fitted_peaks_ws
 
+    def _generate_pawley_reflections(self, phase):
+        # Note: this is pretty much just copied over from GSASIIphsGUI.UpdatePhaseData.OnPawleyLoad
+        # Once it is possible to do this from GSASIIscriptable, this method should be replaced
+        phase_data = phase.data["General"]  # Parameters corresponding to the 'General' tab in the GSASII GUI
+        cell = phase_data["Cell"][1:7]
+        A = GSASIIlattice.cell2A(cell)
+        space_group = phase_data["SGData"]
+        d_min = phase_data["Pawley dmin"]
+
+        reflections = numpy.array(GSASIIlattice.GenHLaue(d_min, space_group, A))
+
+        peaks = []
+        for h, k, l, d in reflections:
+            forbidden_by_symmetry, multiplicity = GSASIIspc.GenHKLf([h, k, l], space_group)[:2]
+            if not forbidden_by_symmetry:
+                multiplicity *= 2
+                peaks.append([h, k, l, multiplicity, d, True, 100.0, 1.0])
+        GSASIImath.sortArray(peaks, 4, reverse=True)
+        return peaks
+
     def _initialise_GSAS(self):
         """
         Initialise a GSAS project object with a spectrum and an instrument parameter file
@@ -211,7 +248,14 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         gsas_path = self.getPropertyValue(self.PROP_PATH_TO_GSASII)
         sys.path.append(gsas_path)
         try:
+            global GSASII
+            global GSASIIlattice
+            global GSASIIspc
+            global GSASIImath
             import GSASIIscriptable as GSASII
+            import GSASIIlattice
+            import GSASIIspc
+            import GSASIImath
         except ImportError:
             error_msg = "Could not import GSAS-II. Are you sure it's installed at {}?".format(gsas_path)
             logger.error(error_msg)
@@ -247,17 +291,24 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         :return: (R weighted profile, goodness-of-fit coefficient, table containing refined lattice parameters)
         """
         phase_paths = self.getPropertyValue(self.PROP_PATHS_TO_PHASE_FILES).split(",")
-        refinements = self._create_refinement_params_dict(num_phases=len(phase_paths))
-        prog = Progress(self, start=0, end=1, nreports=len(refinements) + 1)
+        pawley_tmin = None
+        if self._refinement_method_is_pawley():
+            pawley_dmin = float(self.getPropertyValue(self.PROP_PAWLEY_DMIN))
+            pawley_tmin = GSASIIlattice.Dsp2pos(Inst=gsas_proj.histogram(0).data["Instrument Parameters"][0],
+                                                dsp=pawley_dmin)
+        refinements = self._create_refinement_params_dict(num_phases=len(phase_paths), pawley_tmin=pawley_tmin)
+        prog = Progress(self, start=0, end=1, nreports=2)
 
         prog.report("Reading phase files")
         for phase_path in phase_paths:
             phase = gsas_proj.add_phase(phasefile=phase_path, histograms=[gsas_proj.histograms()[0]])
             if do_pawley:
                 self._set_pawley_phase_parameters(phase)
+                pawley_reflections = self._generate_pawley_reflections(phase)
+                phase.data["Pawley ref"] = pawley_reflections
 
-        for i, refinement in enumerate(refinements):
-            prog.report("Step {} of refinement recipe".format(i + 1))
+        prog.report("Running {} refinement steps".format(len(refinements)))
+        for refinement in refinements:
             gsas_proj.do_refinements([refinement])
         gsas_proj.save()
 
@@ -299,10 +350,10 @@ class GSASIIRefineFitPeaks(PythonAlgorithm):
         phase_params["doPawley"] = True
 
         pawley_dmin = self.getPropertyValue(self.PROP_PAWLEY_DMIN)
-        phase_params["Pawley dmin"] = pawley_dmin
+        phase_params["Pawley dmin"] = float(pawley_dmin)
 
         pawley_neg_wt = self.getPropertyValue(self.PROP_PAWLEY_NEGATIVE_WEIGHT)
-        phase_params["Pawley neg wt"] = pawley_neg_wt
+        phase_params["Pawley neg wt"] = float(pawley_neg_wt)
 
     @contextmanager
     def _suppress_stdout(self):
diff --git a/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py b/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py
index 6a712c3ec19cd2efaa681b04210a690018dd488f..d0eaa513924ae05d22a466f732f6dc3a304fc0cf 100644
--- a/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py
+++ b/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py
@@ -16,6 +16,9 @@ class GenerateGroupingSNSInelastic(mantid.api.PythonAlgorithm):
         """
         return "Inelastic\\Utility;Transforms\\Grouping"
 
+    def seeAlso(self):
+        return [ "GroupWorkspaces" ]
+
     def name(self):
         """ Mantid required
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py b/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py
index 0ad786a631a52025ddddbd0bc220bacfde4061c2..7c84a9c231b2d62426e0e9ba0cc9cbd29017fe1e 100644
--- a/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py
+++ b/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py
@@ -10,6 +10,9 @@ class GetEiT0atSNS(mantid.api.PythonAlgorithm):
         """
         return "Inelastic\\Ei"
 
+    def seeAlso(self):
+        return [ "GetEi" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py b/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py
index 8e954c53f6964d3ba5314a08747be04859bdd391..f119bb777a707574bde68546b2eeef0c2f6e7683 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py
@@ -15,6 +15,9 @@ class LoadAndMerge(PythonAlgorithm):
     _prefix = ''
     _progress = None
 
+    def seeAlso(self):
+        return [ "Load","MergeRuns" ]
+
     def name(self):
         return "LoadMergeRuns"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadEXED.py b/Framework/PythonInterface/plugins/algorithms/LoadEXED.py
index cc32a7e6cbb70cbe01bbd0836c7924403dcb3b32..8821f9ce1f9ca65c30e912b7470616967ec956c3 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadEXED.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadEXED.py
@@ -24,7 +24,7 @@ class LoadEXED(PythonAlgorithm):
     """
 
     def category(self):
-        return "Inelastic;Diffraction;PythonAlgorithms"
+        return "Inelastic;Diffraction"
 
     def name(self):
         return "LoadEXED"
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py b/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py
index c48ad3107bee394f17529cd313de73a6086c7a1f..a8b82620cbca37ce2526781777e72b34f4fff1e3 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py
@@ -29,6 +29,10 @@ class LoadEmptyVesuvio(PythonAlgorithm):
         return 'DataHandling\\Raw'
 #----------------------------------------------------------------------------------------
 
+    def seeAlso(self):
+        return [ "LoadVesuvio" ]
+
+#----------------------------------------------------------------------------------------
     def PyInit(self):
         self.declareProperty(FileProperty(INST_PAR_PROP, "", action=FileAction.OptionalLoad,
                                           extensions=["dat"]),
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py b/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py
index 86d686206b6401f77efbe073b0119fc6fc73d644..d389ab8868345016f4c89e581dd4f8c487fb0de0 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py
@@ -21,6 +21,9 @@ class LoadFullprofFile(PythonAlgorithm):
         """
         return "Diffraction\\DataHandling"
 
+    def seeAlso(self):
+        return [ "LoadFullprofResolution" ]
+
     def name(self):
         """
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py b/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py
index 22d6f03a55eb33fe8b3b610fd6b1aa729df51a68..2b3cfd8b0dad701e5687e5c1232675c3b22c315c 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py
@@ -18,6 +18,9 @@ class LoadLogPropertyTable(PythonAlgorithm):
         return "Creates a table of Run number against the log values for that run for a range of files.\
          It can use a single log value or a list of log values."
 
+    def seeAlso(self):
+        return [ "LoadLog", "LoadMuonLog" ]
+
     # same concept as built in "CreateLogPropertyTable" but loads its own workspaces and needn't hold all in memory at once
     # select log values to put in table (list)
     # special cases for:
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py b/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py
index a00fb3a26a6a22eabf8178fb3a131461220452c6..cba8e48b6cd5f3b65b77b33a3d9454cae32c26e1 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py
@@ -14,6 +14,9 @@ class LoadMultipleGSS(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Text"
 
+    def seeAlso(self):
+        return [ "LoadGSS" ]
+
     def name(self):
         return "LoadMultipleGSS"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py
index 9166c9e8e4474aeab9e0c541a59c8625aaa32a3e..d452a23ab3aad343a377838f088de2546bab3b2a 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py
@@ -107,6 +107,12 @@ class LoadVesuvio(LoadEmptyVesuvio):
         """ Defines the category the algorithm will be put in the algorithm browser
         """
         return 'DataHandling\\Raw'
+
+#----------------------------------------------------------------------------------------
+
+    def seeAlso(self):
+        return [ "LoadEmptyVesuvio" ,"LoadRaw" ]
+
 #----------------------------------------------------------------------------------------
 
     def PyInit(self):
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py
index 6b965402ea76ccca15964494abb4a29c8251b36d..371d7872146617b6f4b99153d9e79ead2b8f7335 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py
@@ -16,6 +16,9 @@ class LoadVisionElasticBS(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Nexus"
 
+    def seeAlso(self):
+        return [ "LoadVisionElasticEQ","LoadVisionInelastic" ]
+
     def name(self):
         return "LoadVisionElasticBS"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py
index 79b1af0f6ebcd60cf5141da6767fdf711b1a345a..8ce8b6db34ea8b101b84ed8e38430b7cec04ca1b 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py
@@ -16,6 +16,9 @@ class LoadVisionElasticEQ(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Nexus"
 
+    def seeAlso(self):
+        return [ "LoadVisionElasticBS","LoadVisionInelastic" ]
+
     def name(self):
         return "LoadVisionElasticEQ"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py
index fdec94a4f92a39fe258c4e5ff998cc43cf2f6fbc..8fe64569d0796e89a3db72a9d0a8af83a16372bf 100644
--- a/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py
+++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py
@@ -16,6 +16,9 @@ class LoadVisionInelastic(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Nexus"
 
+    def seeAlso(self):
+        return [ "LoadVisionElasticBS","LoadVisionElasticEQ" ]
+
     def name(self):
         return "LoadVisionInelastic"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py
index ef7bf24f40c7622be9f353368d36374c3a4a267e..3b0f9d86b24f3ce77acaa66c9409d3899d2627a1 100644
--- a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py
+++ b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py
@@ -186,7 +186,8 @@ class MRFilterCrossSections(PythonAlgorithm):
                 api.AddSampleLog(Workspace=ws, LogName='cross_section_id',
                                  LogText=pol_state)
 
-            AnalysisDataService.remove(ws_raw_name)
+            if ws_event_data is None:
+                AnalysisDataService.remove(ws_raw_name)
             self.setProperty("CrossSectionWorkspaces", output_wsg)
 
         # If we don't have a splitter table, it might be because we don't have analyzer/polarizer
@@ -196,7 +197,8 @@ class MRFilterCrossSections(PythonAlgorithm):
             self.setProperty("CrossSectionWorkspaces", api.GroupWorkspaces([ws_raw]))
         else:
             api.logger.error("No events remained after filtering")
-            AnalysisDataService.remove(ws_raw_name)
+            if ws_event_data is None:
+                AnalysisDataService.remove(ws_raw_name)
 
     def load_legacy_cross_Sections(self, file_path):
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py
index 596f1e40170905fffde3ea049e0eece8dc0132bc..91be6ae1c855a9b9c1d7ef5292fc746f4f5a6791 100644
--- a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py
@@ -477,29 +477,42 @@ class MagnetismReflectometryReduction(PythonAlgorithm):
         """
         sample_length = self.getProperty("SampleLength").value
 
-        #TODO: Read the slit distances relative to the sample from the logs once
-        # they are available with the new DAS.
-        slits =[[ws.getRun().getProperty("S1HWidth").getStatistics().mean, 2600.],
-                [ws.getRun().getProperty("S2HWidth").getStatistics().mean, 2019.],
-                [ws.getRun().getProperty("S3HWidth").getStatistics().mean, 714.]]
-        theta = ws.getRun().getProperty("two_theta").value/2.0
+        # In newer data files, the slit distances are part of the logs
+        if ws.getRun().hasProperty("S1Distance"):
+            s1_dist = ws.getRun().getProperty("S1Distance").value
+            s2_dist = ws.getRun().getProperty("S2Distance").value
+            s3_dist = ws.getRun().getProperty("S3Distance").value
+        else:
+            s1_dist = -2600.
+            s2_dist = -2019.
+            s3_dist = -714.
+        slits =[[ws.getRun().getProperty("S1HWidth").getStatistics().mean, s1_dist],
+                [ws.getRun().getProperty("S2HWidth").getStatistics().mean, s2_dist],
+                [ws.getRun().getProperty("S3HWidth").getStatistics().mean, s3_dist]]
+        theta = ws.getRun().getProperty("two_theta").value/2.0 * np.pi / 180.0
         res=[]
-        s_width=sample_length*math.sin(theta)
+        s_width=sample_length*np.sin(theta)
         for width, dist in slits:
             # Calculate the maximum opening angle dTheta
             if s_width > 0.:
-                d_theta = math.atan((s_width/2.*(1.+width/s_width))/dist)*2.
+                d_theta = np.arctan((s_width/2.*(1.+width/s_width))/dist)*2.
             else:
-                d_theta = math.atan(width/2./dist)*2.
+                d_theta = np.arctan(width/2./dist)*2.
             # The standard deviation for a uniform angle distribution is delta/sqrt(12)
             res.append(d_theta*0.28867513)
 
-        dq_over_q = min(res) / math.tan(theta)
+        # Wavelength uncertainty
+        lambda_min = ws.getRun().getProperty("lambda_min").value
+        lambda_max = ws.getRun().getProperty("lambda_max").value
+        dq_over_q = min(res) / np.tan(theta)
 
         data_x = ws.dataX(0)
         data_dx = ws.dataDx(0)
+        dwl = (lambda_max - lambda_min) / len(data_x) / np.sqrt(12.0)
         for i in range(len(data_x)):
-            data_dx[i] = data_x[i] * dq_over_q
+            dq_theta = data_x[i] * dq_over_q
+            dq_wl = data_x[i]**2 * dwl / (4.0*np.pi*np.sin(theta))
+            data_dx[i] = np.sqrt(dq_theta**2 + dq_wl**2)
 
         return ws
 
diff --git a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py
index 6fe7e7f90ad2da9ebfb2923685d99b1b0da0b987..5c5805a536903e495f62f09b15502f6c6332cff2 100644
--- a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py
+++ b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py
@@ -15,6 +15,9 @@ class MaskAngle(mantid.api.PythonAlgorithm):
         """
         return "Transforms\\Masking"
 
+    def seeAlso(self):
+        return [ "MaskDetectors" ]
+
     def name(self):
         """ Mantid require
         """
@@ -32,9 +35,12 @@ class MaskAngle(mantid.api.PythonAlgorithm):
         angleValidator=mantid.kernel.FloatBoundedValidator()
         angleValidator.setBounds(0.,180.)
         self.declareProperty(name="MinAngle", defaultValue=0.0, validator=angleValidator,
-                             direction=mantid.kernel.Direction.Input, doc="Angles above StartAngle are going to be masked")
-        self.declareProperty(name="MaxAngle", defaultValue=0.0, validator=angleValidator,
-                             direction=mantid.kernel.Direction.Input, doc="Angles above StartAngle are going to be masked")
+                             direction=mantid.kernel.Direction.Input, doc="Angles above MinAngle are going to be masked")
+        self.declareProperty(name="MaxAngle", defaultValue=180.0, validator=angleValidator,
+                             direction=mantid.kernel.Direction.Input, doc="Angles below MaxAngle are going to be masked")
+        self.declareProperty('Angle', 'TwoTheta',
+                             mantid.kernel.StringListValidator(['TwoTheta', 'Phi']),
+                             'Which angle to use')
         self.declareProperty(mantid.kernel.IntArrayProperty(name="MaskedDetectors", direction=mantid.kernel.Direction.Output),
                              doc="List of detector masked, with scatterin angles between MinAngle and MaxAngle")
 
@@ -56,23 +62,35 @@ class MaskAngle(mantid.api.PythonAlgorithm):
 
     def PyExec(self):
         ws = self.getProperty("Workspace").value
-        ttmin = self.getProperty("MinAngle").value
-        ttmax = self.getProperty("MaxAngle").value
+        ttmin = numpy.radians(self.getProperty("MinAngle").value)
+        ttmax = numpy.radians(self.getProperty("MaxAngle").value)
         if ttmin > ttmax :
             raise ValueError("MinAngle > MaxAngle, please check angle range for masking")
 
+        angle = self.getProperty('Angle').value
+
         detlist=[]
 
         numspec = ws.getNumberHistograms()
-        source=ws.getInstrument().getSource().getPos()
-        sample=ws.getInstrument().getSample().getPos()
         spectrumInfo = ws.spectrumInfo()
-        for i in range(numspec):
-            if not spectrumInfo.isMonitor(i):
-                det = ws.getDetector(i)
-                tt=numpy.degrees(det.getTwoTheta(sample,sample-source))
-                if tt>= ttmin and tt<= ttmax:
-                    detlist.append(det.getID())
+
+        if angle == 'Phi':
+            for i in range(numspec):
+                if not spectrumInfo.isMonitor(i):
+                    det = ws.getDetector(i)
+                    phi=abs(det.getPhi())
+                    if phi>= ttmin and phi<= ttmax:
+                        detlist.append(det.getID())
+        else:
+            source=ws.getInstrument().getSource().getPos()
+            sample=ws.getInstrument().getSample().getPos()
+            beam = sample-source
+            for i in range(numspec):
+                if not spectrumInfo.isMonitor(i):
+                    det = ws.getDetector(i)
+                    tt=det.getTwoTheta(sample,beam)
+                    if tt>= ttmin and tt<= ttmax:
+                        detlist.append(det.getID())
 
         if len(detlist)> 0:
             mantid.simpleapi.MaskDetectors(Workspace=ws,DetectorList=detlist)
diff --git a/Framework/PythonInterface/plugins/algorithms/MaskBTP.py b/Framework/PythonInterface/plugins/algorithms/MaskBTP.py
index 071924945e83957fa3a3cfe554590fd079bee597..e3bdc053705e7602745acecfb71714fe05a3dcef 100644
--- a/Framework/PythonInterface/plugins/algorithms/MaskBTP.py
+++ b/Framework/PythonInterface/plugins/algorithms/MaskBTP.py
@@ -24,6 +24,9 @@ class MaskBTP(mantid.api.PythonAlgorithm):
         """
         return "Transforms\\Masking;Inelastic\\Utility"
 
+    def seeAlso(self):
+        return [ "MaskDetectors","MaskInstrument" ]
+
     def name(self):
         """ Mantid required
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
index 981b8b3d0a470fa1e074d75da1381f2fc734a916..ae736dae55d479c3cfb1a395a131d0099d1bda92 100644
--- a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
+++ b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
@@ -24,6 +24,10 @@ class MaskWorkspaceToCalFile(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Text;Diffraction\\DataHandling;Diffraction\\Masking"
 
+    def seeAlso(self):
+        return [ "ReadGroupsFromFile","CreateDummyCalFile","CreateCalFileByNames",
+                 "AlignDetectors","DiffractionFocussing","LoadCalFile","SaveCalFile","MergeCalFiles" ]
+
     def name(self):
         return "MaskWorkspaceToCalFile"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/Mean.py b/Framework/PythonInterface/plugins/algorithms/Mean.py
index 7b192ce4e894eabcfe54f96da93713d5491a0b0c..59d8b93a16e3789946e7158f5bcd7699c6e20f16 100644
--- a/Framework/PythonInterface/plugins/algorithms/Mean.py
+++ b/Framework/PythonInterface/plugins/algorithms/Mean.py
@@ -13,6 +13,9 @@ class Mean(PythonAlgorithm):
     def category(self):
         return "Arithmetic"
 
+    def seeAlso(self):
+        return [ "MostLikelyMean","WeightedMean","WeightedMeanOfWorkspace" ]
+
     def name(self):
         return "Mean"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py b/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py
index 8c2b116f84f9e6f4cb2583603a41ad3191c259a4..ea0382a6d5898cbc16ccfa4255da245d5fd53259 100644
--- a/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py
+++ b/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py
@@ -9,6 +9,10 @@ class MergeCalFiles(PythonAlgorithm):
     def category(self):
         return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles"
 
+    def seeAlso(self):
+        return [ "ReadGroupsFromFile","CreateDummyCalFile","CreateCalFileByNames",
+                 "AlignDetectors","DiffractionFocussing","LoadCalFile","SaveCalFile" ]
+
     def name(self):
         return "MergeCalFiles"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py b/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py
index 2ede9effc741e6184b06ff5121d5dd75bef57738..28eafd02a7fd473f21be65ea9455ae291cc023e8 100644
--- a/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py
+++ b/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py
@@ -35,6 +35,9 @@ class MuonMaxent(PythonAlgorithm):
     def category(self):
         return "Muon;Arithmetic\\FFT"
 
+    def seeAlso(self):
+        return [ "PhaseQuad","FFT" ]
+
     def PyInit(self):
         self.declareProperty(
             WorkspaceProperty("InputWorkspace",
diff --git a/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py b/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py
index 71ee15fb52ca8821dc1d0c0afd1bb0be207dde87..136152bbcc960359627df6abdf66a212768a79d9 100644
--- a/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py
+++ b/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py
@@ -15,6 +15,9 @@ class PDToGUDRUN(DataProcessorAlgorithm):
     def category(self):
         return "Workflow\\Diffraction"
 
+    def seeAlso(self):
+        return [ "PDToPDFgetN" ]
+
     def name(self):
         return "PDToGUDRUN"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py
index b31a019a7a528ab7baa4324973b78aa31c378542..0e2e6709d0e88e4a3b64e60eb2044b19496127b2 100644
--- a/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py
+++ b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py
@@ -19,6 +19,9 @@ class PDToPDFgetN(DataProcessorAlgorithm):
     def category(self):
         return "Workflow\\Diffraction"
 
+    def seeAlso(self):
+        return [ "PDToGUDRUN" ]
+
     def name(self):
         return "PDToPDFgetN"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py b/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py
index 6d18bd5d01ac181955c3da5428e2481345996947..9f96154d37d3f80b01e452e3edde20a8d62d10c0 100644
--- a/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py
+++ b/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py
@@ -14,6 +14,10 @@ class PearlMCAbsorption(PythonAlgorithm):
     def summary(self):
         return "Loads pre-calculated or measured absorption correction files for Pearl."
 
+    def seeAlso(self):
+        return [ "MonteCarloAbsorption", "MayersSampleCorrection",
+                 "MultipleScatteringCylinderAbsorption", "VesuvioCalculateMS" ]
+
     def PyInit(self):
         # Input file
         self.declareProperty(FileProperty("Filename","", FileAction.Load, ['.out','.dat']), doc="The name of the input file.")
diff --git a/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py b/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py
index da350d1d7d0469b64b7636868b36c55aad38135b..a1207669b60cec5d82fd06e4fa0790d912e69f89 100644
--- a/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py
+++ b/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py
@@ -144,6 +144,9 @@ class PoldiCreatePeaksFromFile(PythonAlgorithm):
     def category(self):
         return "SINQ\\Poldi"
 
+    def seeAlso(self):
+        return [ "PoldiCreatePeaksFromCell" ]
+
     def name(self):
         return "PoldiLoadCrystalData"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/RefLReduction.py b/Framework/PythonInterface/plugins/algorithms/RefLReduction.py
deleted file mode 100644
index a6467a68d83d5d21e9fa6df7d7fa29fc54440c86..0000000000000000000000000000000000000000
--- a/Framework/PythonInterface/plugins/algorithms/RefLReduction.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#pylint: disable=no-init,invalid-name
-from __future__ import (absolute_import, division, print_function)
-from mantid.api import *
-from mantid.simpleapi import *
-from mantid.kernel import *
-
-# import sfCalculator
-import sys
-import os
-sys.path.insert(0,os.path.dirname(__file__))
-import sfCalculator # noqa
-sys.path.pop(0)
-
-
-class RefLReduction(PythonAlgorithm):
-
-    def category(self):
-        return "Reflectometry\\SNS"
-
-    def name(self):
-        return "RefLReduction"
-
-    def version(self):
-        return 1
-
-    def summary(self):
-        return "Liquids Reflectometer (REFL) reduction"
-
-    def PyInit(self):
-        self.declareProperty(IntArrayProperty("RunNumbers"), "List of run numbers to process")
-        self.declareProperty("NormalizationRunNumber", 0, "Run number of the normalization run to use")
-        self.declareProperty(IntArrayProperty("SignalPeakPixelRange"), "Pixel range defining the data peak")
-        self.declareProperty("SubtractSignalBackground", True,
-                             doc='If true, the background will be subtracted from the data peak')
-        self.declareProperty(IntArrayProperty("SignalBackgroundPixelRange", [123, 137],
-                                              IntArrayLengthValidator(2), direction=Direction.Input),
-                             "Pixelrange defining the background. Default:(123,137)")
-        self.declareProperty("NormFlag", True, doc="If true, the data will be normalized")
-        self.declareProperty(IntArrayProperty("NormPeakPixelRange", [127,133],
-                                              IntArrayLengthValidator(2), direction=Direction.Input),
-                             "Pixel range defining the normalization peak")
-        self.declareProperty("SubtractNormBackground", True,
-                             doc="If true, the background will be subtracted from the normalization peak")
-        self.declareProperty(IntArrayProperty("NormBackgroundPixelRange", [127,137],
-                                              IntArrayLengthValidator(2), direction=Direction.Input),
-                             "Pixel range defining the background for the normalization")
-        self.declareProperty("LowResDataAxisPixelRangeFlag", True,
-                             doc="If true, the low resolution direction of the data will be cropped according "+
-                             "to the lowResDataAxisPixelRange property")
-        self.declareProperty(IntArrayProperty("LowResDataAxisPixelRange", [115,210],
-                                              IntArrayLengthValidator(2), direction=Direction.Input),
-                             "Pixel range to use in the low resolution direction of the data")
-        self.declareProperty("LowResNormAxisPixelRangeFlag", True,
-                             doc="If true, the low resolution direction of the normalization run will be cropped "+
-                             "according to the LowResNormAxisPixelRange property")
-        self.declareProperty(IntArrayProperty("LowResNormAxisPixelRange", [115,210],
-                                              IntArrayLengthValidator(2), direction=Direction.Input),
-                             "Pixel range to use in the low resolution direction of the normalizaion run")
-        self.declareProperty(FloatArrayProperty("TOFRange", [9000., 23600.],
-                                                FloatArrayLengthValidator(2), direction=Direction.Input),
-                             "TOF range to use")
-        self.declareProperty("TofRangeFlag", True,
-                             doc="If true, the TOF will be cropped according to the TOF range property")
-        self.declareProperty("QMin", 0.05, doc="Mnimum Q-value")
-        self.declareProperty("QStep", 0.02, doc="Step size in Q. Enter a negative value to get a log scale")
-        self.declareProperty("AngleOffset", 0.0, doc="angle offset (degrees)")
-        self.declareProperty("AngleOffsetError", 0.0, doc="Angle offset error (degrees)")
-        self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace")
-#         self.declareProperty("", True,
-#                              doc="Use Scaling Factor configuration file")
-        self.declareProperty("ScalingFactorFile", "", doc="Scaling factor configuration file")
-        self.declareProperty("SlitsWidthFlag", True,
-                             doc="Looking for perfect match of slits width when using Scaling Factor file")
-        self.declareProperty("IncidentMediumSelected", "", doc="Incident medium used for those runs")
-        self.declareProperty("GeometryCorrectionFlag", False, doc="Use or not the geometry correction")
-
-    #pylint: disable=too-many-locals, too-many-branches
-    def PyExec(self):
-
-        print('-- > starting new Reflectometer Reduction ...')
-
-        from reduction.instruments.reflectometer import wks_utility
-
-        #remove all previous workspaces
-        list_mt = mtd.getObjectNames()
-        for _mt in list_mt:
-            if _mt.find('_scaled') != -1:
-                DeleteWorkspace(_mt)
-            if _mt.find('_reflectivity') != -1:
-                DeleteWorkspace(_mt)
-
-        # retrieve settings from GUI
-        print('-> Retrieving settings from GUI')
-
-        #print 'RunNumbers: '  + str(self.getProperty("RunNumbers").value)
-        #print 'NormalizationRunNumber: ' + str(self.getProperty("NormalizationRunNumber").value)
-        #print 'SignalPeakPixelRange: ' + str(self.getProperty("SignalPeakPixelRange").value)
-        #print 'SubtractSignalBackground: ' + str(self.getProperty("SubtractSignalBackground").value)
-        #print 'SignalBackgroundPixelRange: ' + str(self.getProperty("SignalBackgroundPixelRange").value)
-        #print "NormFlag: " + str(self.getProperty("NormFlag").value)
-        #print "NormPeakPixelRange: " + str(self.getProperty("NormPeakPixelRange").value)
-        #print "NormBackgroundPixelRange: " + str(self.getProperty("NormBackgroundPixelRange").value)
-        #print "SubtractNormBackground: " + str(self.getProperty("SubtractNormBackground").value)
-        #print "LowResDataAxisPixelRangeFlag: " + str(self.getProperty("LowResDataAxisPixelRangeFlag").value)
-        #print "LowResDataAxisPixelRange: " + str(self.getProperty("LowResDataAxisPixelRange").value)
-        #print "LowResNormAxisPixelRangeFlag: " + str(self.getProperty("LowResNormAxisPixelRangeFlag").value)
-        #print "LowResNormAxisPixelRange: " + str(self.getProperty("LowResNormAxisPixelRange").value)
-        #print "TOFRange: " + str(self.getProperty("TOFRange").value)
-        #print "IncidentMediumSelected: " + str(self.getProperty("incidentMediumSelected").value)
-        #print "GeometryCorrectionFlag: " + str(self.getProperty("GeometryCorrectionFlag").value)
-        #print "QMin: " + str(self.getProperty("QMin").value)
-        #print "QStep: " + str(self.getProperty("QStep").value)
-        #print "ScalingFactorFile: " + str(self.getProperty("ScalingFactorFile").value)
-        #print "SlitsWidthFlag: " + str(self.getProperty("SlitsWidthFlag").value)
-        #print "OutputWorkspace: " + str(self.getProperty("OutputWorkspace").value)
-
-        # DATA
-        dataRunNumbers = self.getProperty("RunNumbers").value
-        dataPeakRange = self.getProperty("SignalPeakPixelRange").value
-        dataBackRange = self.getProperty("SignalBackgroundPixelRange").value
-        dataBackFlag = self.getProperty("SubtractSignalBackground").value
-        #Due to the frame effect, it's sometimes necessary to narrow the range
-        #over which we add all the pixels along the low resolution
-        #Parameter
-        dataLowResFlag = self.getProperty("LowResDataAxisPixelRangeFlag")
-        if dataLowResFlag:
-            dataLowResRange = self.getProperty("LowResDataAxisPixelRange").value
-        else:
-            dataLowResRange = [0,maxX-1]
-
-        # NORM
-        normalizationRunNumber = self.getProperty("NormalizationRunNumber").value
-        # normFlag = self.getProperty("NormFlag")
-        normBackRange = self.getProperty("NormBackgroundPixelRange").value
-        normPeakRange = self.getProperty("NormPeakPixelRange").value
-        normBackFlag = self.getProperty("SubtractNormBackground").value
-        #Due to the frame effect, it's sometimes necessary to narrow the range
-        #over which we add all the pixels along the low resolution
-        #Parameter
-        normLowResFlag = self.getProperty("LowResNormAxisPixelRangeFlag")
-        if normLowResFlag:
-            normLowResRange = self.getProperty("LowResNormAxisPixelRange").value
-        else:
-            normLowResRange = [0,maxX-1]
-
-        #GENERAL
-        TOFrangeFlag = self.getProperty("TofRangeFlag")
-        if TOFrangeFlag:
-            TOFrange = self.getProperty("TOFRange").value #microS
-        else:
-            TOFrange = [0, 200000]
-        # TOF binning parameters
-        binTOFrange = [0, 200000]
-        binTOFsteps = 40
-
-        # geometry correction
-        geometryCorrectionFlag = self.getProperty("GeometryCorrectionFlag").value
-
-        qMin = self.getProperty("QMin").value
-        qStep = self.getProperty("QStep").value
-        if qStep > 0: #force logarithmic binning
-            qStep = -qStep
-
-        # angle offset
-        angleOffsetDeg = self.getProperty("AngleOffset").value
-
-        # sfCalculator settings
-        slitsValuePrecision = sfCalculator.PRECISION
-        sfFile = self.getProperty("ScalingFactorFile").value
-
-        incidentMedium = self.getProperty("IncidentMediumSelected").value
-        slitsWidthFlag = self.getProperty("SlitsWidthFlag").value
-        # ==== done retrievin the settings =====
-
-        # ==== start reduction ====
-
-        # work with data
-        # load data
-        ws_event_data = wks_utility.loadNeXus(dataRunNumbers, 'data')
-
-        is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value)
-        print('-> is NeXus taken with new detector geometry: ' + str(is_nexus_detector_rotated_flag))
-
-        ## retrieve general informations
-        # calculate the central pixel (using weighted average)
-        print('-> retrieving general informations')
-        data_central_pixel = wks_utility.getCentralPixel(ws_event_data,
-                                                         dataPeakRange,
-                                                         is_nexus_detector_rotated_flag)
-        # get the distance moderator-detector and sample-detector
-        [dMD, dSD] = wks_utility.getDistances(ws_event_data)
-        # get theta
-        theta = wks_utility.getTheta(ws_event_data, angleOffsetDeg)
-        # get proton charge
-        pc = wks_utility.getProtonCharge(ws_event_data)
-        error_0 = 1. / pc
-
-        # rebin data
-        ws_histo_data = wks_utility.rebinNeXus(ws_event_data,
-                                               [binTOFrange[0], binTOFsteps, binTOFrange[1]],
-                                               'data')
-
-        # get q range
-        q_range = wks_utility.getQrange(ws_histo_data, theta, dMD, qMin, qStep)
-
-        # slit size
-        [first_slit_size, last_slit_size] = wks_utility.getSlitsSize(ws_histo_data)
-
-        # keep only TOF range
-        ws_histo_data = wks_utility.cropTOF(ws_histo_data,
-                                            TOFrange[0],
-                                            TOFrange[1],
-                                            'data')
-
-        # normalize by current proton charge
-        ws_histo_data = wks_utility.normalizeNeXus(ws_histo_data, 'data')
-
-        # integrate over low resolution range
-        [data_tof_axis, data_y_axis, data_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_data,
-                                                                                               dataLowResRange,
-                                                                                               'data',
-                                                                                               is_nexus_detector_rotated_flag)
-
-#        #DEBUG ONLY
-#        wks_utility.ouput_big_ascii_file(
-#'/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_file_after_low_resolution_integration.txt',
-#                                         data_tof_axis,
-#                                         data_y_axis,
-#                                         data_y_error_axis)
-
-        tof_axis = data_tof_axis[0:-1].copy()
-        tof_axis_full = data_tof_axis.copy()
-
-        # data_tof_axis.shape -> (62,)
-        # data_y_axis.shape -> (256,61)
-
-        #substract background
-        [data_y_axis, data_y_error_axis] = wks_utility.substractBackground(tof_axis ,
-                                                                           data_y_axis,
-                                                                           data_y_error_axis,
-                                                                           dataPeakRange,
-                                                                           dataBackFlag,
-                                                                           dataBackRange,
-                                                                           error_0,
-                                                                           'data')
-#        #DEBUG ONLY
-#        wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_file_back_sub_not_integrated.txt',
-#                                         data_tof_axis,
-#                                         data_y_axis,
-#                                         data_y_error_axis)
-
-        # work with normalization
-
-        # load normalization
-        ws_event_norm = wks_utility.loadNeXus(int(normalizationRunNumber), 'normalization')
-
-        # get proton charge
-        pc = wks_utility.getProtonCharge(ws_event_norm)
-        error_0 = 1. / pc
-
-        # rebin normalization
-        ws_histo_norm = wks_utility.rebinNeXus(ws_event_norm,
-                                               [binTOFrange[0], binTOFsteps, binTOFrange[1]],
-                                               'normalization')
-
-        # keep only TOF range
-        ws_histo_norm = wks_utility.cropTOF(ws_histo_norm,
-                                            TOFrange[0],
-                                            TOFrange[1],
-                                            'normalization')
-
-        # normalize by current proton charge
-        ws_histo_norm = wks_utility.normalizeNeXus(ws_histo_norm, 'normalization')
-
-        # integrate over low resolution range
-        [norm_tof_axis, norm_y_axis, norm_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_norm,
-                                                                                               normLowResRange,
-                                                                                               'normalization',
-                                                                                               is_nexus_detector_rotated_flag)
-
-        # substract background
-        [norm_y_axis, norm_y_error_axis] = wks_utility.substractBackground(norm_tof_axis[0:-1],
-                                                                           norm_y_axis,
-                                                                           norm_y_error_axis,
-                                                                           normPeakRange,
-                                                                           normBackFlag,
-                                                                           normBackRange,
-                                                                           error_0,
-                                                                           'normalization')
-
-        [av_norm, av_norm_error] = wks_utility.fullSumWithError(norm_y_axis,
-                                                                norm_y_error_axis)
-
-#        ## DEBUGGING ONLY
-#        wks_utility.ouput_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/norm_file_back_sub_not_integrated.txt',
-#                                     norm_tof_axis,
-#                                     av_norm,
-#                                     av_norm_error)
-
-        [final_data_y_axis, final_data_y_error_axis] = wks_utility.divideDataByNormalization(data_y_axis,
-                                                                                             data_y_error_axis,
-                                                                                             av_norm,
-                                                                                             av_norm_error)
-
-#        #DEBUG ONLY
-#        wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_divided_by_norm_not_integrated.txt',
-#                                         data_tof_axis,
-#                                         final_data_y_axis,
-#                                         final_data_y_error_axis)
-
-        # apply Scaling factor
-        [tof_axis_full, y_axis, y_error_axis, isSFfound] = wks_utility.applyScalingFactor(tof_axis_full,
-                                                                                          final_data_y_axis,
-                                                                                          final_data_y_error_axis,
-                                                                                          incidentMedium,
-                                                                                          sfFile,
-                                                                                          slitsValuePrecision,
-                                                                                          slitsWidthFlag)
-
-#        #DEBUG ONLY
-#        wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/after_applying_scaling_factor.txt',
-#                                         data_tof_axis,
-#                                         y_axis,
-#                                         y_error_axis)
-
-        if geometryCorrectionFlag: # convert To Q with correction
-            [q_axis, y_axis, y_error_axis] = wks_utility.convertToQ(tof_axis_full,
-                                                                    y_axis,
-                                                                    y_error_axis,
-                                                                    peak_range = dataPeakRange,
-                                                                    central_pixel = data_central_pixel,
-                                                                    source_to_detector_distance = dMD,
-                                                                    sample_to_detector_distance = dSD,
-                                                                    theta = theta,
-                                                                    first_slit_size = first_slit_size,
-                                                                    last_slit_size = last_slit_size)
-
-        else: # convert to Q without correction
-
-            [q_axis, y_axis, y_error_axis] = wks_utility.convertToQWithoutCorrection(tof_axis_full,
-                                                                                     y_axis,
-                                                                                     y_error_axis,
-                                                                                     peak_range = dataPeakRange,
-                                                                                     source_to_detector_distance = dMD,
-                                                                                     sample_to_detector_distance = dSD,
-                                                                                     theta = theta,
-                                                                                     first_slit_size = first_slit_size,
-                                                                                     last_slit_size = last_slit_size)
-
-
-#            wks_utility.ouput_big_Q_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/after_conversion_to_q.txt',
-#                                         q_axis,
-#                                         y_axis,
-#                                         y_error_axis)
-
-        # create workspace
-        q_workspace = wks_utility.createQworkspace(q_axis, y_axis, y_error_axis)
-
-        q_rebin = Rebin(InputWorkspace=q_workspace,
-                        Params=q_range,
-                        PreserveEvents=True)
-
-        # keep only the q values that have non zero counts
-        nonzero_q_rebin_wks = wks_utility.cropAxisToOnlyNonzeroElements(q_rebin,
-                                                                        dataPeakRange)
-        # integrate spectra (normal mean) and remove first and last Q value
-        [final_x_axis, final_y_axis, final_error_axis] = wks_utility.integrateOverPeakRange(nonzero_q_rebin_wks, dataPeakRange)
-
-        # cleanup data
-        [final_y_axis, final_y_error_axis] = wks_utility.cleanupData1D(final_y_axis,
-                                                                       final_error_axis)
-
-        # create final workspace
-        import time
-        _time = int(time.time())
-        name_output_ws = self.getPropertyValue("OutputWorkspace")
-        name_output_ws = name_output_ws + '_#' + str(_time) + 'ts'
-        wks_utility.createFinalWorkspace(final_x_axis,
-                                         final_y_axis,
-                                         final_y_error_axis,
-                                         name_output_ws,
-                                         ws_event_data)
-        AddSampleLog(Workspace=name_output_ws,
-                     LogName='isSFfound',
-                     LOgText=str(isSFfound))
-
-        self.setProperty('OutputWorkspace', mtd[name_output_ws])
-
-
-AlgorithmFactory.subscribe(RefLReduction)
diff --git a/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py b/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py
index ce93bb8f87e1ebc8395b44ef0da2ba04efc9d875..b666bdb7bd7400d209d5eab91ef914e856051df2 100644
--- a/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py
+++ b/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py
@@ -40,6 +40,9 @@ class RefinePowderDiffProfileSeq(PythonAlgorithm):
         """
         return "Diffraction\\Fitting"
 
+    def seeAlso(self):
+        return [ "RefinePowderInstrumentParameters" ]
+
     def name(self):
         """ Algorithm name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py b/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py
index 112e1b8d5e58449cce33f746c18a4c84f8209d7b..20bb725b0ae8811e04e4ac775df8ac12e6025ddb 100644
--- a/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py
+++ b/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py
@@ -191,6 +191,9 @@ class RetrieveRunInfo(PythonAlgorithm):
         return "Given a range of run numbers and an output workspace name, will compile a table of info for "+\
                "each run of the instrument you have set as default."
 
+    def seeAlso(self):
+        return [ "CreateLogPropertyTable" ]
+
     def PyInit(self):
         # Declare algorithm properties.
         self.declareProperty(
diff --git a/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py b/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py
index 12684213282bf75396df9f9e05e2731c63043280..325358d88c4fd9b1601bc378b1b18c46d27b223a 100644
--- a/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py
+++ b/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py
@@ -17,6 +17,9 @@ class SANSSubtract(PythonAlgorithm):
         """
         return "SANS"
 
+    def seeAlso(self):
+        return [ "SANSStitch","SANSFitShiftScale" ]
+
     def name(self):
         """
             Return name
diff --git a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
index a2b6d8291abdc9f05912da9a06ba9cc3eb698e93..ba71273be7b3923f10951c05e6fe1d7545ce07dc 100644
--- a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
@@ -138,6 +138,9 @@ class SNSPowderReduction(DistributedDataProcessorAlgorithm):
     def category(self):
         return "Diffraction\\Reduction"
 
+    def seeAlso(self):
+        return [ "DiffractionFocussing","AlignAndFocusPowder" ]
+
     def name(self):
         return "SNSPowderReduction"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py b/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py
index 9d5498c19852cba40952f6e4c5852e788ce98e84..72c096474a36380fc7fac8b3d788d7dd79b2d086 100644
--- a/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py
+++ b/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py
@@ -27,6 +27,9 @@ class SaveNexusPD(mantid.api.PythonAlgorithm):
     def category(self):
         return "DataHandling\\Nexus"
 
+    def seeAlso(self):
+        return [ "SaveNexus" ]
+
     def name(self):
         return "SaveNexusPD"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py
index 6e4a62e6e0c60ec27fb9283e22c3ac24d39b22aa..4cca8b79ae2f6f1249022ffba01b3b0d016123d2 100644
--- a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py
+++ b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py
@@ -15,6 +15,9 @@ class SavePlot1DAsJson(PythonAlgorithm):
         """
         return "DataHandling\\Plots"
 
+    def seeAlso(self):
+        return [ "SavePlot1D","StringToPng" ]
+
     def name(self):
         """
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/SaveReflections.py b/Framework/PythonInterface/plugins/algorithms/SaveReflections.py
index 894549a9f1257577f7741d2aadd00313f310060f..ef5b38c0c31aa45106133041a7d97b830d984033 100644
--- a/Framework/PythonInterface/plugins/algorithms/SaveReflections.py
+++ b/Framework/PythonInterface/plugins/algorithms/SaveReflections.py
@@ -5,7 +5,7 @@ from mantid.simpleapi import SaveHKL
 
 # List of file format names supported by this algorithm
 SUPPORTED_FORMATS = ["Fullprof", "GSAS", "Jana", "SHELX"]
-NUM_PEAKSWS_COLUMNS = 17
+NUM_PEAKSWS_COLUMNS = 18
 
 
 def has_modulated_indexing(workspace):
diff --git a/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py b/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py
index 3b13cc9d5a56599fa1b82ab8dfb34822f228c54b..fbd980e03f80be57024b8a76d018fd246f655ceb 100644
--- a/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py
+++ b/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py
@@ -15,6 +15,9 @@ class SortByQVectors(PythonAlgorithm):
     def category(self):
         return "Transforms\\Merging;Utility\\Sorting"
 
+    def seeAlso(self):
+        return [ "SortDetectors" ]
+
     def name(self):
         return "SortByQVectors"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/SortDetectors.py b/Framework/PythonInterface/plugins/algorithms/SortDetectors.py
index 1a48cb09a4c670cfdf47dca17118d4136a43518c..7951bead58b5b62fd4668a8042af3188ebad0469 100644
--- a/Framework/PythonInterface/plugins/algorithms/SortDetectors.py
+++ b/Framework/PythonInterface/plugins/algorithms/SortDetectors.py
@@ -16,6 +16,9 @@ class SortDetectors(PythonAlgorithm):
         """
         return "Utility\\Sorting"
 
+    def seeAlso(self):
+        return [ "SortByQVectors","SortXAxis" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
index ee803cb59e1246ccd5785d922c4efe1626ebf173..41c8dd04224f554cc2d14ed84e24dd741edff6a2 100644
--- a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
+++ b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py
@@ -1,8 +1,8 @@
 #pylint: disable=no-init,invalid-name
 from __future__ import (absolute_import, division, print_function)
 
-from mantid.api import *
-from mantid.kernel import *
+from mantid.api import AlgorithmFactory, MatrixWorkspaceProperty, PythonAlgorithm
+from mantid.kernel import Direction, StringListValidator
 import numpy as np
 
 
@@ -11,6 +11,9 @@ class SortXAxis(PythonAlgorithm):
     def category(self):
         return "Transforms\\Axes;Utility\\Sorting"
 
+    def seeAlso(self):
+        return [ "SortDetectors" ]
+
     def name(self):
         return "SortXAxis"
 
@@ -22,6 +25,11 @@ class SortXAxis(PythonAlgorithm):
                              doc="Input workspace")
         self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", defaultValue="", direction=Direction.Output),
                              doc="Sorted Output Workspace")
+        self.declareProperty("Ordering",
+                             defaultValue="Ascending",
+                             validator=StringListValidator(["Ascending", "Descending"]),
+                             direction=Direction.Input,
+                             doc="Ascending or descending sorting")
 
     def PyExec(self):
         input_ws = self.getProperty('InputWorkspace').value
@@ -40,9 +48,14 @@ class SortXAxis(PythonAlgorithm):
             y_data = input_ws.readY(i)
             e_data = input_ws.readE(i)
 
-            indexes =  x_data.argsort()
+            indexes = x_data.argsort()
+
+            if self.getPropertyValue("Ordering") == "Descending":
+                self.log().information("Sort descending")
+                indexes = indexes[::-1]
 
             x_ordered = x_data[indexes]
+
             if input_ws.isHistogramData():
                 max_index = np.argmax(indexes)
                 indexes = np.delete(indexes, max_index)
@@ -54,7 +67,12 @@ class SortXAxis(PythonAlgorithm):
             output_ws.setY(i, y_ordered)
             output_ws.setE(i, e_ordered)
 
+            if input_ws.hasDx(i):
+                dx = input_ws.readDx(i)
+                dx_ordered = dx[indexes]
+                output_ws.setDx(i, dx_ordered)
+
         self.setProperty('OutputWorkspace', output_ws)
 
 
-AlgorithmFactory.subscribe(SortXAxis())
+AlgorithmFactory.subscribe(SortXAxis)
diff --git a/Framework/PythonInterface/plugins/algorithms/StringToPng.py b/Framework/PythonInterface/plugins/algorithms/StringToPng.py
index 184ea6cab966f63590d37ebd0daa9571046189d0..0349445489ab5545005e46ee13e6edfb61147898 100644
--- a/Framework/PythonInterface/plugins/algorithms/StringToPng.py
+++ b/Framework/PythonInterface/plugins/algorithms/StringToPng.py
@@ -11,6 +11,9 @@ class StringToPng(mantid.api.PythonAlgorithm):
         """
         return "DataHandling\\Plots"
 
+    def seeAlso(self):
+        return [ "SavePlot1D" ]
+
     def name(self):
         """ Algorithm name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py b/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py
index 51a7993a62ac2b6e96a49ab261bda90aa5deb8ab..538ee9d1433d8ffbb5f61969cccc1b188d3fe6ec 100644
--- a/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py
+++ b/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py
@@ -34,6 +34,9 @@ class SuggestTibCNCS(PythonAlgorithm):
         """
         return "Inelastic\\Utility"
 
+    def seeAlso(self):
+        return [ "SuggestTibHYSPEC" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py b/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py
index e4f653aa559436880c421886bbc7babbbea07e18..b2354db61311346be11d73d167b1c96aa06d5545 100644
--- a/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py
+++ b/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py
@@ -15,6 +15,9 @@ class SuggestTibHYSPEC(PythonAlgorithm):
         """
         return "Inelastic\\Utility"
 
+    def seeAlso(self):
+        return [ "SuggestTibCNCS" ]
+
     def name(self):
         """ Return name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py
index 8c14b944c38ba689f8df1ca52d3f55c40c62cda3..64706916799f9e7d5a55b839a7fe131cd82a5cb2 100644
--- a/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py
+++ b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py
@@ -17,6 +17,9 @@ class TOFTOFCropWorkspace(PythonAlgorithm):
         """
         return "Workflow\\MLZ\\TOFTOF;Transforms\\Splitting"
 
+    def seeAlso(self):
+        return [ "TOFTOFMergeRuns","CorrectTOF" ]
+
     def name(self):
         """ Return summary
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py b/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py
index 56f24da68deb9a40b53b940bb08db0a98ff77a47..69c9e7dd8f50f9bbf749ffdcfd9be9c58c40eb59 100644
--- a/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py
+++ b/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py
@@ -27,6 +27,9 @@ class TOFTOFMergeRuns(PythonAlgorithm):
         """
         return "Workflow\\MLZ\\TOFTOF;Transforms\\Splitting"
 
+    def seeAlso(self):
+        return [ "TOFTOFCropWorkspace","CorrectTOF" ]
+
     def name(self):
         """ Return summary
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py b/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py
index b86164900b2c4e4ba2e45e24faa628887a44db58..e573c87116c61147467fdba24ca0e45cb61aa56d 100644
--- a/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py
+++ b/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py
@@ -13,6 +13,9 @@ class USANSSimulation(PythonAlgorithm):
     def category(self):
         return "SANS"
 
+    def seeAlso(self):
+        return [ "USANSReduction" ]
+
     def name(self):
         return "USANSSimulation"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py
index d523aabcc4c379cef205751e5e1c556cda5f5018..b76c01067cb45042f94f1318a16df98d0e2af3db 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py
@@ -14,6 +14,9 @@ class AddSampleLogMultiple(PythonAlgorithm):
     def summary(self):
         return 'Add multiple sample logs to a workspace'
 
+    def seeAlso(self):
+        return ["AddSampleLog"]
+
     def PyInit(self):
         self.declareProperty(WorkspaceProperty('Workspace', '', direction=Direction.InOut),
                              doc='Workspace to add logs to')
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py
index 00bb6453ebd3e5a73081e4bfc005c05f316f1039..2d82b71a8c4f40ba611ded775af20833f12a5cbb 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py
@@ -51,6 +51,9 @@ class CalculateMonteCarloAbsorption(DataProcessorAlgorithm):
     def category(self):
         return "Workflow\\Inelastic;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS"
 
+    def seeAlso(self):
+        return [ "MonteCarloAbsorption","SimpleShapeMonteCarloAbsorption" ]
+
     def summary(self):
         return "Calculates indirect absorption corrections for a given sample shape, using a MonteCarlo simulation."
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py
index 16123503e88339c030506866320d3c042da87871..bb5a9eb1aae7007c647e90e83022c711caab0fd8 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py
@@ -17,6 +17,9 @@ class ConvertMultipleRunsToSingleCrystalMD(DataProcessorAlgorithm):
     def category(self):
         return "MDAlgorithms\\Creation"
 
+    def seeAlso(self):
+        return [ "ConvertToDiffractionMDWorkspace","ConvertToMD" ]
+
     def name(self):
         return "ConvertMultipleRunsToSingleCrystalMD"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py
index 19fcf7cb2a8532acf807391a63fc395d1d49d058..bc330f9f2e2934a3c54eb8b6eacab91433845671 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py
@@ -42,6 +42,9 @@ class DirectILLApplySelfShielding(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLReduction" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLApplySelfShielding'
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py
index e58103c101edbf72ef3bde629d84ca04a148a641..c60683b544d4d753461a5a1da59a61f1aa754531 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py
@@ -247,6 +247,9 @@ class DirectILLCollectData(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLReduction" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLCollectData'
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py
index bb2a888e8497d667b89560a79e02b7cd9b035513..15482c1bd95f5a552ba24b097df61bebdfe265b7 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py
@@ -309,6 +309,9 @@ class DirectILLDiagnostics(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLReduction" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLDiagnostics'
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py
index 0d719a89e78c75e37331c10c3f79a25aee067d17..a19138f37f62f3d555d5a90ec27c6b396fc00411 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py
@@ -22,6 +22,9 @@ class DirectILLIntegrateVanadium(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLReduction" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLIntegrateVanadium'
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py
index 3d4b7bee8fb559a0726f4569fd8310ef0b1a5b30..235ca49bc041283aa3df735c1a7dd67a849adfd4 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py
@@ -6,8 +6,9 @@ import DirectILL_common as common
 from mantid.api import (AlgorithmFactory, DataProcessorAlgorithm, InstrumentValidator,
                         MatrixWorkspaceProperty, Progress, PropertyMode, WorkspaceProperty, WorkspaceUnitValidator)
 from mantid.kernel import (CompositeValidator, Direction, FloatArrayProperty, StringListValidator)
-from mantid.simpleapi import (BinWidthAtX, CloneWorkspace, ConvertSpectrumAxis, ConvertUnits, CorrectKiKf, DetectorEfficiencyCorUser,
-                              Divide, GroupDetectors, MaskDetectors, Rebin, Scale, SofQWNormalisedPolygon, Transpose)
+from mantid.simpleapi import (BinWidthAtX, CloneWorkspace, ConvertSpectrumAxis, ConvertToDistribution, ConvertUnits, CorrectKiKf,
+                              DetectorEfficiencyCorUser, Divide, GroupDetectors, MaskDetectors, Rebin, Scale, SofQWNormalisedPolygon,
+                              Transpose)
 import math
 import numpy
 import roundinghelper
@@ -169,6 +170,10 @@ class DirectILLReduction(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLApplySelfShielding","DirectILLCollectData",
+                 "DirectILLDiagnostics","DirectILLIntegrateVanadium","DirectILLSelfShielding" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLReduction'
@@ -221,6 +226,9 @@ class DirectILLReduction(DataProcessorAlgorithm):
         mainWS = self._rebinInW(mainWS, wsNames, wsCleanup, report,
                                 subalgLogging)
 
+        # Divide the energy transfer workspace by bin widths.
+        mainWS = self._convertToDistribution(mainWS, wsNames, wsCleanup, subalgLogging)
+
         # Detector efficiency correction.
         progress.report('Correcting detector efficiency')
         mainWS = self._correctByDetectorEfficiency(mainWS, wsNames,
@@ -336,6 +344,17 @@ class DirectILLReduction(DataProcessorAlgorithm):
         wsCleanup.cleanup(mainWS)
         return maskedWS
 
+    def _convertToDistribution(self, mainWS, wsNames, wsCleanup, subalgLogging):
+        """Convert the workspace into a distribution."""
+        distributionWSName = wsNames.withSuffix('as_distribution')
+        distributionWS = CloneWorkspace(InputWorkspace=mainWS,
+                                        OutputWorkspace=distributionWSName,
+                                        EnableLogging=subalgLogging)
+        wsCleanup.cleanup(mainWS)
+        ConvertToDistribution(Workspace=distributionWS,
+                              EnableLogging=subalgLogging)
+        return distributionWS
+
     def _convertTOFToDeltaE(self, mainWS, wsNames, wsCleanup, subalgLogging):
         """Convert the X axis units from time-of-flight to energy transfer."""
         energyConvertedWSName = wsNames.withSuffix('energy_converted')
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py
index 5c1391a418ed55800d7d0b54b5dbc8b70ade9a9f..2609db7937b56b507f20e8690ff070b6279f710f 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py
@@ -21,6 +21,9 @@ class DirectILLSelfShielding(DataProcessorAlgorithm):
         """Return the algorithm's category."""
         return common.CATEGORIES
 
+    def seeAlso(self):
+        return [ "DirectILLReduction" ]
+
     def name(self):
         """Return the algorithm's name."""
         return 'DirectILLSelfShielding'
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
index a80ac5c10bc5b3a4ca56303a94210b6e5ba0141e..86d73568ee12c53b8eb443c00fee0bee0247f0ca 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py
@@ -38,7 +38,10 @@ class ISISIndirectDiffractionReduction(DataProcessorAlgorithm):
     def summary(self):
         return 'Performs a diffraction reduction for a set of raw run files for an ISIS indirect spectrometer'
 
-    # ------------------------------------------------------------------------------
+    def seeAlso(self):
+        return [ "AlignDetectors","DiffractionFocussing","SNSPowderReduction" ]
+
+        # ------------------------------------------------------------------------------
 
     def PyInit(self):
         self.declareProperty(StringArrayProperty(name='InputFiles'),
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py
index 37f75eb8838867cb37ebabd3b0a894885536baf0..fd2a0953387817ec90a9a44a8f9d96a22356b519 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py
@@ -53,6 +53,9 @@ class IndirectILLEnergyTransfer(PythonAlgorithm):
     def summary(self):
         return 'Performs initial energy transfer reduction for ILL indirect geometry data, instrument IN16B.'
 
+    def seeAlso(self):
+        return [ "IndirectILLReductionQENS","IndirectILLReductionFWS" ]
+
     def name(self):
         return "IndirectILLEnergyTransfer"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py
index 35dbafe567681ec70e6cea4fb8d227367cc68508..7ddec145b25dbc38a417e391dbf164c605063746 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py
@@ -39,6 +39,9 @@ class IndirectILLReductionFWS(PythonAlgorithm):
         return 'Performs fixed-window scan (FWS) multiple file reduction (both elastic and inelastic) ' \
                'for ILL indirect geometry data, instrument IN16B.'
 
+    def seeAlso(self):
+        return [ "IndirectILLReductionQENS","IndirectILLEnergyTransfer" ]
+
     def name(self):
         return "IndirectILLReductionFWS"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py
index c6120c518afb9635e3800e1c02540dc090790afd..85b1ab7b4ddb5498a991341eb50b0f4ad0b4fccd 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py
@@ -36,6 +36,9 @@ class IndirectILLReductionQENS(PythonAlgorithm):
         return 'Performs quasi-elastic neutron scattering (QENS) multiple file reduction ' \
                'for ILL indirect geometry data, instrument IN16B.'
 
+    def seeAlso(self):
+        return [ "IndirectILLReductionFWS","IndirectILLEnergyTransfer" ]
+
     def name(self):
         return "IndirectILLReductionQENS"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py
index aee47be349af9b5223b13881c71803f5bc438257..e7fbf7bd15271b38992b0ecad732e23e3f7b8513 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py
@@ -16,7 +16,7 @@ class IndirectSampleChanger(DataProcessorAlgorithm):
     _q1_workspaces = None
 
     def category(self):
-        return "Workflow\\MIDAS;PythonAlgorithms"
+        return "Workflow\\MIDAS"
 
     def summary(self):
         return "Create elastic window scans for sample changer"
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py
index 5a12480428170664ab101048da7e072fa0fedf3a..1d5cd7025e4ae2ab1437d05a621975a623d6d892 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py
@@ -19,6 +19,9 @@ class MDNormSCDPreprocessIncoherent(DataProcessorAlgorithm):
     def category(self):
         return "MDAlgorithms\\Normalisation"
 
+    def seeAlso(self):
+        return [ "MDNormSCD","MDNormDirectSC" ]
+
     def name(self):
         return "MDNormSCDPreprocessIncoherent"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py
index 3f49c6af191eb81326d8c3a2d494997dc4ad7db7..dd4614d029fa8574c7d777dc07432526afcf47f1 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py
@@ -480,6 +480,9 @@ class OSIRISDiffractionReduction(PythonAlgorithm):
     def category(self):
         return 'Diffraction\\Reduction'
 
+    def seeAlso(self):
+        return [ "ISISIndirectDiffractionReduction" ]
+
     def summary(self):
         return "This Python algorithm performs the operations necessary for the reduction of diffraction data " + \
                "from the Osiris instrument at ISIS " + \
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py
index 40f7d7108234edf16bd72c3223e9112ab54fb002..81877ccdcff5835588a1d133faf00d0a0f5bf630 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py
@@ -2,31 +2,69 @@ from __future__ import (absolute_import, division, print_function)
 
 import math
 import numpy as np
+import numpy.ma as ma
 from mantid.kernel import StringListValidator, Direction, IntArrayBoundedValidator, IntArrayProperty, \
     CompositeValidator, IntArrayLengthValidator, IntArrayOrderedPairsValidator, FloatArrayOrderedPairsValidator, \
-    FloatArrayProperty, VisibleWhenProperty, PropertyCriterion
-from mantid.api import PythonAlgorithm, FileProperty, FileAction, Progress, MatrixWorkspaceProperty, PropertyMode
+    FloatArrayProperty, VisibleWhenProperty, PropertyCriterion, IntBoundedValidator
+from mantid.api import PythonAlgorithm, FileProperty, FileAction, Progress, MatrixWorkspaceProperty, PropertyMode, \
+    MultipleFileProperty
 from mantid.simpleapi import *
 
 
+def _crop_bins(ws, bin_min, bin_max, out):
+    """
+        Extracts workspace data in [bin_min, bin_max] for ragged workspace
+    """
+    y = mtd[ws].extractY()
+    e = mtd[ws].extractE()
+    x = mtd[ws].extractX()
+    CreateWorkspace(DataX=x[:,bin_min:bin_max],
+                    DataY=y[:,bin_min:bin_max],
+                    DataE=e[:,bin_min:bin_max],
+                    NSpec=mtd[ws].getNumberHistograms(),
+                    OutputWorkspace=out)
+
+
+def _divide_friendly(ws1, ws2, out):
+    """
+        Divides ws1/ws2 ignoring the difference in x-axis
+    """
+    mtd[ws2].setX(0, mtd[ws1].readX(0))
+    Divide(LHSWorkspace=ws1, RHSWorkspace=ws2, OutputWorkspace=out)
+
+
+def _plus_friendly(ws1, ws2, out):
+    """
+        Sums ws1+ws2 ignoring the difference in x-axis
+    """
+    mtd[ws2].setX(0, mtd[ws1].readX(0))
+    Plus(LHSWorkspace=ws1, RHSWorkspace=ws2, OutputWorkspace=out)
+
+
 class PowderDiffILLDetEffCorr(PythonAlgorithm):
 
     _out_name = None            # the name of the output workspace
-    _input_file = None          # input file (numor), must be a detector scan
+    _input_files = None         # input files (numor), must be detector scans (to list for D2B, to merge for D20)
     _calib_file = None          # file containing previously derived calibration constants
     _progress = None            # progress tracking
     _method = None              # calibration method
     _scan_points = None         # number of scan points (time indices)
     _out_response = None        # the name of the second output workspace with merged response
     _bin_offset = None          # this holds int(scan step / pixel size)
-    _n_det = None               # number of detector pixels (typically 3072)
+    _n_det = None               # number of detector pixels for D20 (=3072)
     _normalise_to = None        # normalisation option
-    _pixel_range = None         # range of the pixels to derive calibration for, e.g. 65,3072
-    _regions_of_interest = None # ROI to normalise to, e.g. 10,50,70,100, typically just one range
-    _interpolate = None         # whether to interpolate 2thetas before taking relative ratios
-    _excluded_ranges = None     # 2theta ranges to exclude when deriving the relative calibration factor
-                                # e.g. -20,0,40,50
+    _pixel_range = None         # range of the pixels to derive calibration for D20, e.g. 65,3072
+    _regions_of_interest = None # ROI to normalise to, e.g. 10,50,70,100, typically just one range, used for D20
+    _interpolate = None         # whether to interpolate 2thetas before taking relative ratios (D20)
+    _excluded_ranges = None     # 2theta ranges to exclude when deriving the calibration factor, e.g. -20,0,40,50
     _live_pixels = None         # holds the list of cells that are not zero counting
+    _derivation_method = ''     # sequential reference (D20) or global reference (D2B)
+    _n_scan_files = None        # number of standard scan files for D2B (~30)
+    _n_scans_per_file = None    # number of scan points in a standard scan for D2B (=25)
+    _n_tubes = None             # number of tubes in D2B (=128)
+    _n_pixels_per_tube = None   # number of pixels per tube in D2B (=128)
+    _n_iterations = None        # number of iterations (=1); used for D2B
+    _pixels_to_trim = None      # number of pixels to trim from top and bottom of tubes for chi2 calculation (D2B)
 
     def _hide(self, name):
         return '__' + self._out_name + '_' + name
@@ -35,14 +73,18 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         return "ILL\\Diffraction;Diffraction\\Reduction;Diffraction\\Calibration"
 
     def summary(self):
-        return "Performs detector efficiency correction calculation for powder diffraction instrument D20 at ILL."
+        return "Performs detector efficiency correction calculation for scanning " \
+               "monochromatic powder diffraction instruments D20 and D2B at ILL."
+
+    def seeAlso(self):
+        return [ "ApplyDetectorScanEffCorr","PowderDiffILLReduction" ]
 
     def name(self):
         return "PowderDiffILLDetEffCorr"
 
     def PyInit(self):
-        self.declareProperty(FileProperty('CalibrationRun', '', action=FileAction.Load, extensions=['nxs']),
-                             doc='File path of calibration run. Must be a detector scan.')
+        self.declareProperty(MultipleFileProperty('CalibrationRun', action=FileAction.Load, extensions=['nxs']),
+                             doc='File path of calibration runs (numors). Must be detector scans.')
 
         self.declareProperty(FileProperty('CalibrationFile', '', action=FileAction.OptionalLoad, extensions=['nxs']),
                              doc='Optional file containing previous calibration constants.')
@@ -50,28 +92,32 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         self.declareProperty(name='CalibrationMethod',
                              defaultValue='Median',
                              validator=StringListValidator(['Median', 'Mean', 'MostLikelyMean']),
-                             doc='The method of how the calibration constant of a '
-                                 'pixel relative to the neighbouring one is derived.')
+                             doc='The method of how the calibration constant of a pixel '
+                                 'is derived from the distribution of ratios.')
+
+        self.declareProperty(name='DerivationMethod', defaultValue='SequentialSummedReference1D',
+                             validator=StringListValidator(['SequentialSummedReference1D', 'GlobalSummedReference2D']),
+                             doc='Choose sequential for D20 (1D detector), global for D2B (2D detector).')
 
         self.declareProperty(name='InterpolateOverlappingAngles', defaultValue=False,
-                             doc='Wheter to interpolate 2theta values for overlapping regions between neighbouring cells.')
+                             doc='Whether to interpolate scattering angle values in overlapping regions (D20 only).')
 
         self.declareProperty(name='NormaliseTo',
                              defaultValue='None',
                              validator=StringListValidator(['None', 'Monitor', 'ROI']),
-                             doc='Normalise to time, monitor or ROI counts before deriving the calibration.')
+                             doc='Normalise to monitor or ROI counts before deriving the calibration.')
 
         thetaRangeValidator = FloatArrayOrderedPairsValidator()
 
         self.declareProperty(FloatArrayProperty(name='ROI', values=[0,100.], validator=thetaRangeValidator),
-                             doc='Regions of interest for normalisation [in scattering angle in degrees].')
+                             doc='Scattering angle regions of interest for normalisation [degrees].')
 
         normaliseToROI = VisibleWhenProperty('NormaliseTo', PropertyCriterion.IsEqualTo, 'ROI')
         self.setPropertySettings('ROI', normaliseToROI)
 
         self.declareProperty(FloatArrayProperty(name='ExcludedRange', values=[], validator=thetaRangeValidator),
-                             doc='2theta regions to exclude from the computation of relative calibration constants '
-                                 '[in scattering angle in degrees]. ')
+                             doc='Scattering angle regions to exclude from the computation of '
+                                 'relative calibration constants; for example, the beam stop [degrees]. ')
 
         pixelRangeValidator = CompositeValidator()
         greaterThanOne = IntArrayBoundedValidator()
@@ -84,19 +130,39 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         pixelRangeValidator.add(orderedPairsValidator)
 
         self.declareProperty(IntArrayProperty(name='PixelRange', values=[1,3072], validator=pixelRangeValidator),
-                             doc='Range of the pixel numbers to compute the calibration factors for. '
-                                 'For the other pixels outside the range, the factor will be set to 1.')
+                             doc='Range of the pixel numbers to compute the calibration factors for (D20 only); '
+                                 'for the other pixels outside the range, the factor will be set to 1.')
 
         self.declareProperty(MatrixWorkspaceProperty('OutputResponseWorkspace', '',
                                                      optional=PropertyMode.Optional, direction=Direction.Output),
-                             doc='Output workspace containing the summed diffraction patterns of all the pixels.')
+                             doc='Output workspace containing the summed diffraction patterns of all the overlapping pixels.')
 
         self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '',
                                                      direction=Direction.Output),
-                             doc='Output workspace containing the detector efficiencies for each pixel.')
+                             doc='Output workspace containing the calibration constants (inverse of efficiency) for each pixel.')
+
+        self.declareProperty(name='NumberOfIterations',
+                             defaultValue=1,
+                             validator=IntBoundedValidator(lower=0, upper=10),
+                             doc='Number of iterations to perform (D2B only): 0 means auto; that is, the '
+                                 'iterations will terminate after reaching some Chi2/NdoF.')
 
     def validateInputs(self):
         issues = dict()
+
+        if self.getPropertyValue("DerivationMethod") == "GlobalSummedReference2D":
+            if self.getProperty("InterpolateOverlappingAngles").value:
+                issues["InterpolateOverlappingAngles"] = "Interpolation option is not supported for global method"
+            if self.getPropertyValue("NormaliseTo") == "ROI":
+                issues["NormaliseTo"] = "ROI normalisation is not supported for global method"
+            method = self.getPropertyValue("CalibrationMethod")
+            if method == "MostLikelyMean" or method == "Mean":
+                issues["CalibrationMethod"] = method + " is not supported for global reference method"
+
+        if self.getPropertyValue("DerivationMethod") == "SequentialSummedReference1D":
+            if self.getProperty("NumberOfIterations").value != 1:
+                issues["NumberOfIterations"] = "NumberOfIterations is not supported for sequential method"
+
         return issues
 
     def _update_reference(self, ws, cropped_ws, ref_ws, factor):
@@ -132,7 +198,8 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
             @param ratio_ws : the name of the ratio workspace
         """
         ConvertToHistogram(InputWorkspace=ratio_ws, OutputWorkspace=ratio_ws)
-        x = mtd[ratio_ws].readX(0)
+        equator = int(mtd[ratio_ws].getNumberHistograms() / 2)
+        x = mtd[ratio_ws].readX(equator)
         xmin = x[0]
         xmax = x[-1]
         for excluded_range in self._excluded_ranges:
@@ -144,13 +211,15 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
                 MaskBins(InputWorkspace=ratio_ws, OutputWorkspace=ratio_ws, XMin=xmin, XMax=xmax)
         ConvertToPointData(InputWorkspace=ratio_ws, OutputWorkspace=ratio_ws)
 
-    def _compute_relative_factor(self, ratio_ws):
+    def _compute_relative_factor_1D(self, ratio_ws):
         """
             Calculates the relative detector efficiency from the workspace containing response ratios.
             Implements mean, median and most likely mean methods.
             @param ratio_ws: input workspace containing response ratios
-            @returns: relative calibration factor
+            @returns: relative calibration factor (scalar)
         """
+        if len(self._excluded_ranges) != 0:
+            self._exclude_ranges(ratio_ws)
         ratios = mtd[ratio_ws].extractY()
         ratios = ratios[np.nonzero(ratios)]
         factor = 1.
@@ -163,6 +232,29 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
                 factor = MostLikelyMean(ratios)
         return factor
 
+    def _compute_relative_factor_2D(self, ratio_ws, tube_index):
+        """
+            Calculates the relative detector efficiency from the workspace containing response ratios.
+            Implements mean, median and most likely mean methods.
+            @param ratio_ws: input workspace containing response ratios
+            @returns: relative calibration factor (1D array, factor per pixel in the tube)
+        """
+        if len(self._excluded_ranges) != 0:
+            self._exclude_ranges(ratio_ws)
+        ratios = mtd[ratio_ws].extractY()
+        if tube_index == 0:
+            ratios=ratios[:,0:-self._n_scans_per_file]
+        elif tube_index == self._n_tubes - 1:
+            ratios=ratios[:,self._n_scans_per_file:]
+        factors = np.ones(ratios.shape[0])
+        ratios = ma.masked_array(ratios, mask=[ratios == 0])
+        ratios = ma.masked_invalid(ratios)
+        if self._method == 'Median':
+            factors = np.array(ma.median(ratios, axis = 1))
+        elif self._method == 'Mean':
+            factors = np.array(ma.mean(ratios, axis = 1))
+        return factors
+
     def _validate_scan(self, scan_ws):
         """
             Ensures that the input workspace corresponds to a detector scan
@@ -175,7 +267,7 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         except RuntimeError:
             is_scanned = True
         if not is_scanned:
-            raise RuntimeError('The input run does not correspond to a detector scan.')
+            raise RuntimeError('The input run is not a detector scan.')
 
     def _reshape(self, raw_ws, ws_2d):
         """
@@ -196,13 +288,28 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         CreateWorkspace(DataX=x_2d, DataY=y_2d, DataE=e_2d, NSpec=self._n_det+1, OutputWorkspace=ws_2d)
         CopyLogs(InputWorkspace=raw_ws, OutputWorkspace=ws_2d)
 
+    def _chi_squared(self, calib_current):
+        """
+            Calculates the termination parameter for automatic iterations for global method (D2B)
+            @param calib_current : the residual calibration map at the current iteration
+            @return : chi2/NdoF
+        """
+        start = self._pixels_to_trim
+        end = self._n_pixels_per_tube - self._pixels_to_trim
+        y = mtd[calib_current].extractY()[:,start:end]
+        diff = (y-1)**2
+        chi2 = np.sum(diff)
+        ndof = (self._n_pixels_per_tube - 2 * self._pixels_to_trim) * self._n_tubes
+        return chi2/ndof
+
     def _set_input_properties(self):
         """
             Sets up the input properties of the algorithm
         """
-        self._input_file = self.getPropertyValue('CalibrationRun')
+        self._input_files = self.getPropertyValue('CalibrationRun')
         self._calib_file = self.getPropertyValue('CalibrationFile')
         self._method = self.getPropertyValue('CalibrationMethod')
+        self._derivation_method = self.getPropertyValue('DerivationMethod')
         self._normalise_to = self.getPropertyValue('NormaliseTo')
         self._regions_of_interest = self.getProperty('ROI').value
         self._excluded_ranges = self.getProperty('ExcludedRange').value
@@ -210,11 +317,12 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         self._pixel_range = self.getProperty('PixelRange').value
         self._out_response = self.getPropertyValue('OutputResponseWorkspace')
         self._out_name = self.getPropertyValue('OutputWorkspace')
+        self._n_iterations = self.getProperty('NumberOfIterations').value
 
-    def _configure(self, raw_ws):
+    def _configure_sequential(self, raw_ws):
         """
-            Configures the fundamental parameters for the algorithm.
-            @param : the name of the raw detector scan workspace
+            Configures the calibration with SequentialSummedReference1D method (D20)
+            @param : the name of the raw detector scan (merged) workspace
         """
         self._scan_points = mtd[raw_ws].getRun().getLogData('ScanSteps').value
         self.log().information('Number of scan steps is: ' + str(self._scan_points))
@@ -236,11 +344,26 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
             n_excluded_ranges = int(len(self._excluded_ranges) / 2)
             self._excluded_ranges = np.split(self._excluded_ranges, n_excluded_ranges)
 
+    def _configure_global(self, raw_ws):
+        """
+            Configures the calibration with GlobalSummedReference2D method (D2B)
+            @param : first raw ws name in the list
+        """
+        inst = mtd[raw_ws].getInstrument()
+        self._n_tubes = inst.getComponentByName('detectors').nelements()
+        self._n_pixels_per_tube = inst.getComponentByName('detectors/tube_1').nelements()
+        self._n_scans_per_file = mtd[raw_ws].getRun().getLogData('ScanSteps').value
+        self._scan_points = self._n_scans_per_file * self._n_scan_files
+        if self._excluded_ranges.any():
+            n_excluded_ranges = int(len(self._excluded_ranges) / 2)
+            self._excluded_ranges = np.split(self._excluded_ranges, n_excluded_ranges)
+
     def _validate_roi(self, ws_2d):
         """
             ROI has to be fully within the aperture of the detector at any time index.
             Example:
             time index : detector span (degrees)
+            ------------------------------------
             first      : -30 -> 120
             last       :  10 -> 160
             ROI can not be wider than [10,120]
@@ -324,9 +447,10 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
                 mtd[constants_ws].dataY(pixel)[0] = 1.
                 mtd[constants_ws].dataE(pixel)[0] = 0.
 
-    def _derive_calibration(self, ws_2d, constants_ws, response_ws):
+    def _derive_calibration_sequential(self, ws_2d, constants_ws, response_ws):
         """
             Computes the relative calibration factors sequentailly for all the pixels.
+            This is the main calculation, the performance is critical
             @param : 2D input workspace
             @param : the output workspace name containing the calibration constants
             @param : the output workspace name containing the combined response
@@ -374,9 +498,7 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
                     RenameWorkspace(InputWorkspace=cloned_ref_ws, OutputWorkspace=cropped_ws)
 
                 Divide(LHSWorkspace=ref_ws, RHSWorkspace=cropped_ws, OutputWorkspace=ratio_ws, EnableLogging=False)
-                if len(self._excluded_ranges) != 0:
-                    self._exclude_ranges(ratio_ws)
-                factor = self._compute_relative_factor(ratio_ws)
+                factor = self._compute_relative_factor_1D(ratio_ws)
                 DeleteWorkspace(ratio_ws)
 
                 if str(factor) == 'nan' or str(factor) == 'inf' or factor == 0.:
@@ -407,31 +529,32 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
         # end of loop over pixels
         DeleteWorkspace(ref_ws)
 
-    def PyExec(self):
-        self._set_input_properties()
-
+    def _process_sequential(self):
+        """
+            Performs the sequential derivation for D20 with the following logic:
+            1. Take first cell as the reference
+            2. Compute the coefficient for the second cell wrt reference
+            3. Scale the response of the second cell with the obtained factor
+            4. Merge the responses of first and second cells and set it as the new reference
+            5. Back to Step 2 for the third pixel and so on...
+        """
         raw_ws = self._hide('raw')
         mon_ws = self._hide('mon')
         ws_2d = self._hide('2d')
         response_ws = self._hide('resp')
         constants_ws = self._hide('constants')
-
-        LoadILLDiffraction(Filename=self._input_file, OutputWorkspace=raw_ws)
-        self._validate_scan(raw_ws)
-        self._configure(raw_ws)
+        calib_ws = self._hide('calib')
 
         ConvertSpectrumAxis(InputWorkspace=raw_ws, OutputWorkspace=raw_ws, Target='SignedTheta', OrderAxis=False)
         self._reshape(raw_ws, ws_2d)
         DeleteWorkspace(raw_ws)
         # extract the monitor spectrum
         ExtractSingleSpectrum(InputWorkspace=ws_2d, WorkspaceIndex=0, OutputWorkspace=mon_ws)
-
         if self._normalise_to == 'Monitor':
             Divide(LHSWorkspace=ws_2d, RHSWorkspace=mon_ws, OutputWorkspace=ws_2d)
         elif self._normalise_to == 'ROI':
             self._validate_roi(ws_2d)
             self._normalise_roi(ws_2d)
-
         DeleteWorkspace(mon_ws)
         # only now crop out the monitor spectrum
         CropWorkspace(InputWorkspace=ws_2d, StartWorkspaceIndex=1, OutputWorkspace=ws_2d)
@@ -439,8 +562,6 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
                              NaNValue=0, NaNError=0, InfinityValue=0, InfinityError=0)
 
         if self._calib_file:
-            calib_ws = self._hide('calib')
-            LoadNexusProcessed(Filename=self._calib_file, OutputWorkspace=calib_ws)
             Multiply(LHSWorkspace=ws_2d, RHSWorkspace=calib_ws, OutputWorkspace=ws_2d)
             DeleteWorkspace(calib_ws)
 
@@ -448,9 +569,187 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm):
             self._prepare_response_workspace(ws_2d, response_ws)
 
         # this is the main calculation
-        self._derive_calibration(ws_2d, constants_ws, response_ws)
+        self._derive_calibration_sequential(ws_2d, constants_ws, response_ws)
         DeleteWorkspace(ws_2d)
         self._perform_absolute_normalisation(constants_ws)
+        mtd[constants_ws].getAxis(1).setUnit('Label').setLabel('Cell #', '')
+        mtd[constants_ws].setYUnitLabel('Calibration constant')
+
+    def _process_global(self):
+        """
+            Performs the global derivation for D2B following the logic:
+            1. SumOverlappingTubes with 2D option to obtain the reference
+            2. Loop over tubes, make ratios wrt reference, obtain constants
+            3. Apply the constants, and iterate over if requested
+        """
+        constants_ws = self._hide('constants')
+        response_ws = self._hide('resp')
+        calib_ws = self._hide('calib')
+        ref_ws = self._hide('ref')
+        numors = []
+        self._progress = Progress(self, start=0.0, end=1.0, nreports=self._n_scan_files)
+
+        for index, numor in enumerate(self._input_files.split(',')):
+            self._progress.report('Pre-processing detector scan '+numor[-9:-3])
+            ws_name = '__raw_'+str(index)
+            numors.append(ws_name)
+            LoadILLDiffraction(Filename=numor, OutputWorkspace=ws_name, DataType="Raw")
+            self._validate_scan(ws_name)
+            if index == 0:
+                if mtd[ws_name].getInstrument().getName() != 'D2B':
+                    raise RuntimeError('Global reference method is not supported for the instrument given')
+                self._configure_global(ws_name)
+            if self._normalise_to == 'Monitor':
+                NormaliseToMonitor(InputWorkspace=ws_name, OutputWorkspace=ws_name, MonitorID=0)
+            ExtractMonitors(InputWorkspace=ws_name, DetectorWorkspace=ws_name)
+            ConvertSpectrumAxis(InputWorkspace=ws_name, OrderAxis=False, Target="SignedTheta", OutputWorkspace=ws_name)
+            if self._calib_file:
+                ApplyDetectorScanEffCorr(InputWorkspace=ws_name, DetectorEfficiencyWorkspace=calib_ws, OutputWorkspace=ws_name)
+
+        if self._calib_file:
+            DeleteWorkspace(calib_ws)
+
+        constants = np.ones([self._n_pixels_per_tube,self._n_tubes])
+        x = np.arange(self._n_tubes)
+        e = np.zeros([self._n_pixels_per_tube,self._n_tubes])
+        CreateWorkspace(DataX=np.tile(x, self._n_pixels_per_tube), DataY=constants, DataE=e,
+                        NSpec=self._n_pixels_per_tube, OutputWorkspace=constants_ws)
+        calib_current = self._hide('current')
+        CloneWorkspace(InputWorkspace=constants_ws, OutputWorkspace=calib_current)
+
+        iteration = 0
+        chi2_ndof = np.inf # set a large number to start with
+        self._pixels_to_trim = 28
+        chi2_ndof_threshold = 1.
+        inst = mtd[numors[0]].getInstrument()
+        if inst.hasParameter('pixels_to_trim'):
+            self._pixels_to_trim = inst.getIntParameter('pixels_to_trim')[0]
+        if inst.hasParameter('chi2_ndof'):
+            chi2_ndof_threshold = inst.getNumberParameter('chi2_ndof')[0]
+
+        while iteration < self._n_iterations or (self._n_iterations == 0 and chi2_ndof > chi2_ndof_threshold):
+            self._progress = Progress(self, start=0.0, end=1.0, nreports=5)
+            self._progress.report('Starting iteration #'+str(iteration))
+            self._derive_calibration_global(numors)
+            Multiply(LHSWorkspace=constants_ws, RHSWorkspace=calib_current, OutputWorkspace=constants_ws)
+            chi2_ndof = self._chi_squared(calib_current)
+            if iteration != 0:
+                self.log().warning('Iteration {0}: Chi2/NdoF={1} (termination criterion: < {2})'.
+                                   format(iteration, chi2_ndof, chi2_ndof_threshold))
+            iteration += 1
+
+        if self._out_response:
+            for index in range(self._n_scan_files):
+                ws_name = '__raw_'+str(index)
+                ApplyDetectorScanEffCorr(InputWorkspace=ws_name, DetectorEfficiencyWorkspace=calib_current, OutputWorkspace=ws_name)
+            SumOverlappingTubes(InputWorkspaces=numors, OutputWorkspace=response_ws, MirrorScatteringAngles=False,
+                                CropNegativeScatteringAngles=False, Normalise=True, OutputType="2DTubes", ScatteringAngleTolerance=1000)
+
+        DeleteWorkspace(ref_ws)
+        DeleteWorkspaces(numors)
+        DeleteWorkspace(calib_current)
+        mtd[constants_ws].getAxis(0).setUnit('Label').setLabel('Tube #', '')
+        mtd[constants_ws].getAxis(1).setUnit('Label').setLabel('Pixel #', '')
+        mtd[constants_ws].setYUnitLabel('Calibration constant')
+
+    def _derive_calibration_global(self, numors):
+        """
+            Derives one iteration of calibration with the global reference method (D2B)
+            This is the main calculation, so the performance is critical
+            @param numors : list of workspace names
+        """
+        y_tubes = []
+        x_tubes = []
+        e_tubes = []
+        calib_current = self._hide('current')
+        ref_ws = self._hide('ref')
+        tubes_group = self._hide('tubes')
+        ratios_group = self._hide('ratios')
+        shape = [self._n_tubes, self._n_pixels_per_tube, self._n_scans_per_file]
+        for i in range(self._n_tubes):
+            y_tubes.append([])
+            x_tubes.append([])
+            e_tubes.append([])
+
+        for index in range(self._n_scan_files):
+            ws_name = '__raw_'+str(index)
+            ApplyDetectorScanEffCorr(InputWorkspace=ws_name, DetectorEfficiencyWorkspace=calib_current, OutputWorkspace=ws_name)
+            y = mtd[ws_name].extractY()
+            e = mtd[ws_name].extractE()
+            x = mtd[ws_name].getAxis(1).extractValues()
+            y_3d = np.reshape(y, shape)
+            x_3d = np.reshape(x, shape)
+            e_3d = np.reshape(e, shape)
+            for tube in range(self._n_tubes):
+                y_tubes[tube].append(y_3d[tube,:,:])
+                x_tubes[tube].append(x_3d[tube,:,:])
+                e_tubes[tube].append(e_3d[tube,:,:])
+
+        self._progress.report('Constructing the global reference')
+        SumOverlappingTubes(InputWorkspaces=numors, OutputWorkspace=ref_ws, MirrorScatteringAngles=False,
+                            CropNegativeScatteringAngles=False, Normalise=True, OutputType="2DTubes", ScatteringAngleTolerance=1000)
+
+        to_group = []
+        self._progress.report('Preparing the tube responses')
+        for tube in range(self._n_tubes):
+            y_tube = np.concatenate(y_tubes[tube], axis=1)
+            x_tube = np.concatenate(x_tubes[tube], axis=1)
+            e_tube = np.concatenate(e_tubes[tube], axis=1)
+            ws_name = "__tube" + str(tube)
+            CreateWorkspace(DataX=x_tube, DataY=y_tube, DataE=e_tube, NSpec=self._n_pixels_per_tube, OutputWorkspace=ws_name)
+            SortXAxis(InputWorkspace=ws_name, OutputWorkspace=ws_name)
+            to_group.append(ws_name)
+        GroupWorkspaces(InputWorkspaces=to_group, OutputWorkspace=tubes_group)
+
+        ratios = []
+        self._progress.report('Constructing response ratios')
+        for tube in reversed(range(self._n_tubes)):
+            itube = self._n_tubes - tube - 1
+            ratio_ws = '__ratio'+str(tube)
+            _crop_bins(ref_ws, itube * self._n_scans_per_file, itube * self._n_scans_per_file + self._scan_points, '__cropped_ref')
+            _divide_friendly('__cropped_ref', '__tube'+str(tube), ratio_ws)
+            ratios.append(ratio_ws)
+            DeleteWorkspace('__cropped_ref')
+        GroupWorkspaces(InputWorkspaces=ratios, OutputWorkspace=ratios_group)
+        DeleteWorkspace(tubes_group)
+
+        self._progress.report('Computing the calibration constants')
+        Transpose(InputWorkspace=calib_current, OutputWorkspace=calib_current)
+        for tube in range(self._n_tubes):
+            coeff = self._compute_relative_factor_2D('__ratio'+str(tube), tube)
+            mtd[calib_current].setY(tube, coeff)
+        Transpose(InputWorkspace=calib_current, OutputWorkspace=calib_current)
+        DeleteWorkspace(ratios_group)
+
+        ReplaceSpecialValues(InputWorkspace=calib_current, OutputWorkspace=calib_current,
+                             NaNValue=1, InfinityValue=1, SmallNumberThreshold=0.00001, SmallNumberValue=1)
+
+    def PyExec(self):
+        self._set_input_properties()
+
+        raw_ws = self._hide('raw')
+        response_ws = self._hide('resp')
+        constants_ws = self._hide('constants')
+        calib_ws = self._hide('calib')
+
+        if self._calib_file:
+            LoadNexusProcessed(Filename=self._calib_file, OutputWorkspace=calib_ws)
+
+        if self._derivation_method == 'SequentialSummedReference1D': # D20
+            self._input_files = self._input_files.replace(',','+')
+            LoadAndMerge(Filename=self._input_files, OutputWorkspace=raw_ws, LoaderName='LoadILLDiffraction')
+            if not mtd[raw_ws].getInstrument().getName().startswith('D20'):
+                DeleteWorkspace(raw_ws)
+                raise RuntimeError('Sequential reference method is not supported for the instrument given')
+            self._validate_scan(raw_ws)
+            self._configure_sequential(raw_ws)
+            self._process_sequential()
+        elif self._derivation_method == 'GlobalSummedReference2D': # D2B
+            self._input_files = self._input_files.replace('+',',')
+            self._n_scan_files = self._input_files.count(',') + 1
+            if self._n_scan_files < 2:
+                raise RuntimeError('At least two overlapping scan files needed for the global method')
+            self._process_global()
 
         # set output workspace[s]
         RenameWorkspace(InputWorkspace=constants_ws, OutputWorkspace=self._out_name)
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py
index 0fd2620d37e01db78dbdb4589a4a63094589ee76..88e50537d399b7223691c349e19f2f8407ef1a39 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py
@@ -2,12 +2,13 @@ from __future__ import (absolute_import, division, print_function)
 
 from mantid.kernel import CompositeValidator, Direction, FloatArrayLengthValidator, FloatArrayOrderedPairsValidator, \
     FloatArrayProperty, StringListValidator
-from mantid.api import DataProcessorAlgorithm, MultipleFileProperty, Progress, WorkspaceGroupProperty
+from mantid.api import DataProcessorAlgorithm, MultipleFileProperty, Progress, WorkspaceGroupProperty, FileProperty, FileAction
 from mantid.simpleapi import *
 
 
 class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
     _progress = None
+    _tolerance = 0.
 
     def category(self):
         return "ILL\\Diffraction;Diffraction\\Reduction"
@@ -15,6 +16,9 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
     def summary(self):
         return 'Performs powder diffraction data reduction for D2B and D20 (when doing a detector scan).'
 
+    def seeAlso(self):
+        return [ "PowderDiffILLReduction" ]
+
     def name(self):
         return "PowderDiffILLDetScanReduction"
 
@@ -40,6 +44,9 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
                              validator=StringListValidator(['None', 'Monitor']),
                              doc='Normalise to monitor, or skip normalisation.')
 
+        self.declareProperty(FileProperty('CalibrationFile', '', action=FileAction.OptionalLoad, extensions=['nxs']),
+                             doc='File containing the detector efficiencies.')
+
         self.declareProperty(name='UseCalibratedData',
                              defaultValue=True,
                              doc='Whether or not to use the calibrated data in the NeXus files.')
@@ -56,6 +63,9 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
                              defaultValue=True,
                              doc='Output a 1D workspace with counts against scattering angle.')
 
+        self.declareProperty(name='CropNegativeScatteringAngles', defaultValue=True,
+                             doc='Whether or not to crop the negative scattering angles.')
+
         self.declareProperty(FloatArrayProperty(name='HeightRange', values=[],
                                                 validator=CompositeValidator([FloatArrayOrderedPairsValidator(),
                                                                               FloatArrayLengthValidator(0, 2)])),
@@ -80,16 +90,32 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
         # We might already have a group, but group just in case
         input_group = GroupWorkspaces(InputWorkspaces=input_workspace)
 
-        instrument_name = input_group[0].getInstrument().getName()
+        instrument = input_group[0].getInstrument()
         supported_instruments = ['D2B', 'D20']
-        if instrument_name not in supported_instruments:
+        if instrument.getName() not in supported_instruments:
             self.log.warning('Running for unsupported instrument, use with caution. Supported instruments are: '
                              + str(supported_instruments))
+        if instrument.getName() == 'D20':
+            if self.getProperty('Output2DTubes').value:
+                raise RuntimeError('Output2DTubes is not supported for D20 (1D detector)')
+            if self.getProperty('Output2D').value:
+                raise RuntimeError('Output2D is not supported for D20 (1D detector)')
+            self._tolerance = 1000.
 
         self._progress.report('Normalising to monitor')
         if self.getPropertyValue('NormaliseTo') == 'Monitor':
             input_group = NormaliseToMonitor(InputWorkspace=input_group, MonitorID=0)
 
+        calib_file = self.getPropertyValue('CalibrationFile')
+        if calib_file:
+            self._progress.report('Applying detector efficiencies')
+            LoadNexusProcessed(Filename=calib_file, OutputWorkspace='__det_eff')
+            for ws in input_group:
+                name = ws.getName()
+                ExtractMonitors(InputWorkspace=name, DetectorWorkspace=name, MonitorWorkspace='__mon')
+                DeleteWorkspace('__mon')
+                ApplyDetectorScanEffCorr(InputWorkspace=name,DetectorEfficiencyWorkspace='__det_eff',OutputWorkspace=name)
+
         height_range = ''
         height_range_prop = self.getProperty('HeightRange').value
         if (len(height_range_prop) == 2):
@@ -98,11 +124,18 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
         output_workspaces = []
         output_workspace_name = self.getPropertyValue('OutputWorkspace')
 
+        mirror_angles = False
+        crop_negative = self.getProperty('CropNegativeScatteringAngles').value
+        if instrument.hasParameter("mirror_scattering_angles"):
+            mirror_angles = instrument.getBoolParameter("mirror_scattering_angles")[0]
+
         self._progress.report('Doing Output2DTubes Option')
         if self.getProperty('Output2DTubes').value:
             output2DTubes = SumOverlappingTubes(InputWorkspaces=input_group,
                                                 OutputType='2DTubes',
                                                 HeightAxis=height_range,
+                                                MirrorScatteringAngles=mirror_angles,
+                                                CropNegativeScatteringAngles=crop_negative,
                                                 OutputWorkspace=output_workspace_name + '_2DTubes')
             output_workspaces.append(output2DTubes)
 
@@ -110,8 +143,9 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
         if self.getProperty('Output2D').value:
             output2D = SumOverlappingTubes(InputWorkspaces=input_group,
                                            OutputType='2D',
-                                           CropNegativeScatteringAngles=True,
                                            HeightAxis=height_range,
+                                           MirrorScatteringAngles=mirror_angles,
+                                           CropNegativeScatteringAngles=crop_negative,
                                            OutputWorkspace = output_workspace_name + '_2D')
             output_workspaces.append(output2D)
 
@@ -119,9 +153,11 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm):
         if self.getProperty('Output1D').value:
             output1D = SumOverlappingTubes(InputWorkspaces=input_group,
                                            OutputType='1D',
-                                           CropNegativeScatteringAngles=True,
                                            HeightAxis=height_range,
-                                           OutputWorkspace=output_workspace_name + '_1D')
+                                           MirrorScatteringAngles=mirror_angles,
+                                           CropNegativeScatteringAngles=crop_negative,
+                                           OutputWorkspace=output_workspace_name + '_1D',
+                                           ScatteringAngleTolerance=self._tolerance)
             output_workspaces.append(output1D)
         DeleteWorkspace('input_group')
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py
index 699ec5e52f0c6cd2c164cb352d00083c32a5cd1b..4930d7631249e3a7c27147832869bb88562a8efd 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py
@@ -36,6 +36,9 @@ class PowderDiffILLReduction(PythonAlgorithm):
     def summary(self):
         return 'Performs powder diffraction data reduction for ILL instrument D20.'
 
+    def seeAlso(self):
+        return [ "PowderDiffILLDetScanReduction","PowderDiffILLDetEffCorr" ]
+
     def name(self):
         return "PowderDiffILLReduction"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py
deleted file mode 100644
index 3c0a7cca5f14647453cd1df661dc500b55b66ad0..0000000000000000000000000000000000000000
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py
+++ /dev/null
@@ -1,229 +0,0 @@
-#pylint: disable=no-init,invalid-name
-from __future__ import (absolute_import, division, print_function)
-
-from mantid.api import *
-from mantid.kernel import *
-from mantid.simpleapi import *
-import os
-import math
-import sys
-
-#pylint: disable=too-few-public-methods
-
-
-class REFLOptions(object):
-    def __init__(self):
-        from reduction_gui.reduction.reflectometer.refl_data_script import DataSets as REFLDataSets
-        from reduction_gui.reduction.reflectometer.refl_data_series import DataSeries
-        self._state = DataSeries(data_class=REFLDataSets)
-
-    def get_state(self):
-        return self._state
-
-
-class REFLReprocess(PythonAlgorithm):
-    """
-        Normalise detector counts by accelerator current and beam spectrum.
-    """
-
-    def category(self):
-        return "Workflow\\REFL"
-
-    def name(self):
-        return "REFLReprocess"
-
-    def summary(self):
-        return "Re-reduce REFL data for an entire experiment using saved parameters"
-
-    def PyInit(self):
-        self.declareProperty("IPTS", '0', "IPTS number to process")
-        self.declareProperty(FileProperty(name="OutputDirectory",defaultValue="",action=FileAction.OptionalDirectory))
-        self.declareProperty("LoadProcessed", False, "If True, data will be loaded instead of being processed")
-        self.declareProperty("Filter", "ts.txt", "String that the reduced data file name must contain")
-
-    def PyExec(self):
-        from reduction_gui.reduction.reflectometer.refl_reduction import REFLReductionScripter
-        ipts = self.getProperty("IPTS").value
-        try:
-            ipts_number = int(ipts)
-            ipts = "IPTS-%s" % ipts_number
-        except:
-            pass
-
-        Logger("REFLReprocess").notice("Processing %s" % ipts)
-
-        # Locate the IPTS directory
-        ipts_dir = "/SNS/REF_L/%s/shared" % ipts
-        if not os.path.isdir(ipts_dir):
-            ipts_dir = ipts
-
-        # Determine the output directory
-        output_dir = self.getProperty("OutputDirectory").value
-        if len(output_dir)==0:
-            output_dir = ipts_dir
-
-        load_only = self.getProperty("LoadProcessed").value
-        if load_only:
-            return self.load_processed(output_dir)
-
-        # Reprocess the data
-        if os.path.isdir(ipts_dir):
-            for item in os.listdir(ipts_dir):
-                if item.endswith('.xml'):
-                    try:
-                        Logger("REFLReprocess").notice("Processing %s" % os.path.join(ipts_dir, item))
-
-                        refl = REFLReductionScripter()
-                        options = REFLOptions()
-                        refl.attach(options)
-                        refl.from_xml(os.path.join(ipts_dir, item))
-                        code = refl.to_script()
-                        exec(code, globals(), locals())
-                        self.stitch_data(os.path.join(ipts_dir, item), output_dir,
-                                         q_min=options.get_state().data_sets[0].q_min,
-                                         q_step=options.get_state().data_sets[0].q_step)
-                    except:
-                        Logger("REFLReprocess").error(str(sys.exc_info()[1]))
-        else:
-            Logger("REFLReprocess").error("%s not a valid directory" % ipts_dir)
-
-    def load_processed(self, output_dir):
-        filter_string = self.getProperty("Filter").value
-        if not os.path.isdir(output_dir):
-            Logger("REFLReprocess").error("%s not a valid directory" % output_dir)
-            return
-
-        for item in os.listdir(output_dir):
-            if item.endswith('.txt') and \
-               (len(filter_string)==0 or item.find(filter_string)>=0):
-                basename, _ = os.path.splitext(item)
-                Load(Filename=os.path.join(output_dir, item), OutputWorkspace=basename)
-                (_name,_ts) = basename.split('_#')
-                CloneWorkspace(InputWorkspace=basename, OutputWorkspace=_name)
-
-    def stitch_data(self, input_file, output_dir, q_min, q_step):
-        from LargeScaleStructures.data_stitching import DataSet, Stitcher#, RangeSelector
-        # Identify the data sets to stitch and order them
-        workspace_list = []
-        _list_name = []
-        _list_ts = []
-        ws_list = AnalysisDataService.getObjectNames()
-        for item in ws_list:
-            if item.endswith('ts'):
-                (_name,_ts) = item.split('_#')
-                _list_name.append(item)
-                _list_ts.append(_ts)
-
-        _name_ts = sorted(zip(_list_ts, _list_name))
-        _ts_sorted, workspace_list = list(zip(*_name_ts))
-
-        # Stitch the data
-        s = Stitcher()
-
-        q_max = 0
-        for item in workspace_list:
-            data = DataSet(item)
-            data.load(True, True)
-            dummy_x_min, x_max = data.get_range()
-            if x_max > q_max:
-                q_max = x_max
-            s.append(data)
-
-        s.set_reference(0)
-        s.compute()
-
-        # Apply the scaling factors
-        for data in s._data_sets:
-            Scale(InputWorkspace=str(data), OutputWorkspace=data._ws_scaled,
-                  Operation="Multiply", Factor=data.get_scale())
-            SaveAscii(InputWorkspace=str(data), Filename=os.path.join(output_dir, '%s.txt' % str(data)))
-
-        output_file = input_file.replace('.xml', '_reprocessed.txt')
-        Logger("REFLReprocess").notice("Saving to %s" % output_file)
-
-        output_ws = _average_y_of_same_x_(q_min, q_step, q_max)
-        SaveAscii(InputWorkspace=output_ws, Filename=output_file)
-
-
-def weightedMean(data_array, error_array):
-    """
-        Code taken out as-is from base_ref_reduction.py
-    """
-    sz = len(data_array)
-
-    # calculate the numerator of mean
-    dataNum = 0
-    for i in range(sz):
-        if not data_array[i] == 0:
-            tmpFactor = float(data_array[i]) / float((pow(error_array[i],2)))
-            dataNum += tmpFactor
-
-    # calculate denominator
-    dataDen = 0
-    for i in range(sz):
-        if not error_array[i] == 0:
-            tmpFactor = 1./float((pow(error_array[i],2)))
-            dataDen += tmpFactor
-
-    if dataDen == 0:
-        mean = 0
-        mean_error = 0
-    else:
-        mean = float(dataNum) / float(dataDen)
-        mean_error = math.sqrt(1/dataDen)
-
-    return [mean, mean_error]
-
-
-def _average_y_of_same_x_(q_min, q_step, q_max=2):
-    """
-
-    Code taken out as-is from base_ref_reduction.py
-
-    2 y values sharing the same x-axis will be average using
-    the weighted mean
-    """
-
-    ws_list = AnalysisDataService.getObjectNames()
-    scaled_ws_list = []
-
-    # Get the list of scaled histos
-    for ws in ws_list:
-        if ws.endswith("_scaled"):
-            scaled_ws_list.append(ws)
-
-    # get binning parameters
-    #_from_q = str(state.data_sets[0].q_min)
-    #_bin_size = str(state.data_sets[0].q_step)
-    #_bin_max = str(2)
-    #binning_parameters = _from_q + ',-' + _bin_size + ',' + _bin_max
-    binning_parameters = "%s,-%s,%s" % (q_min, q_step, q_max)
-
-    # Convert each histo to histograms and rebin to final binning
-    for ws in scaled_ws_list:
-        new_name = "%s_histo" % ws
-        ConvertToHistogram(InputWorkspace=ws, OutputWorkspace=new_name)
-        Rebin(InputWorkspace=new_name, Params=binning_parameters,
-              OutputWorkspace=new_name)
-
-    # Take the first rebinned histo as our output
-    data_y = mtd[scaled_ws_list[0]+'_histo'].dataY(0)
-    data_e = mtd[scaled_ws_list[0]+'_histo'].dataE(0)
-
-    # Add in the other histos, averaging the overlaps
-    for i in range(1, len(scaled_ws_list)):
-        data_y_i = mtd[scaled_ws_list[i]+'_histo'].dataY(0)
-        data_e_i = mtd[scaled_ws_list[i]+'_histo'].dataE(0)
-        for j in range(len(data_y_i)):
-            if data_y[j]>0 and data_y_i[j]>0:
-                [data_y[j], data_e[j]] = weightedMean([data_y[j], data_y_i[j]], [data_e[j], data_e_i[j]])
-            elif (data_y[j] == 0) and (data_y_i[j]>0):
-                data_y[j] = data_y_i[j]
-                data_e[j] = data_e_i[j]
-
-    return scaled_ws_list[0]+'_histo'
-
-#############################################################################################
-
-
-AlgorithmFactory.subscribe(REFLReprocess)
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py
index 8386bd6e2c803e131e73f635cec57a7400f9b548..c113cd2419a09fbbd73436a8f2420f5df1db48d2 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py
@@ -14,6 +14,9 @@ class ReactorSANSResolution(PythonAlgorithm):
     def category(self):
         return "SANS"
 
+    def seeAlso(self):
+        return [ "EQSANSResolution" ]
+
     def name(self):
         return "ReactorSANSResolution"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py
index f1e7aac47404815bd7b5ce6e21500b406ec2d9cb..609eac3ad081ef23f629009f9b63e574280d7f57 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py
@@ -24,6 +24,9 @@ class SavePlot1D(mantid.api.PythonAlgorithm):
         """
         return "DataHandling\\Plots"
 
+    def seeAlso(self):
+        return [ "SavePlot1DAsJson","StringToPng" ]
+
     def name(self):
         """ Algorithm name
         """
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py
index b5b4ff4bd1bab5d1614c78ff308232d461e72e97..cdf13d6bccecbbd9384f4770f1be2c7788f259aa 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py
@@ -20,6 +20,9 @@ class SaveVulcanGSS(PythonAlgorithm):
         """
         return "Workflow\\Diffraction\\DataHandling"
 
+    def seeAlso(self):
+        return [ "SaveGSS" ]
+
     def name(self):
         """ name of algorithm
         """
@@ -368,7 +371,7 @@ class SaveVulcanGSS(PythonAlgorithm):
 
             # property run_start and duration exist
             utctime = numpy.datetime64(run.getProperty('run_start').value)
-            time0 = numpy.datetime64("1990-01-01T0:0:0")
+            time0 = numpy.datetime64("1990-01-01T00:00:00")
             total_nanosecond_start = int((utctime - time0) / numpy.timedelta64(1, 'ns'))
             total_nanosecond_stop = total_nanosecond_start + int(duration*1.0E9)
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py
index 2abf5198c05ebaaffd583e336188bd9ac85d5d28..d3d6ec5964e25cb2e90ab82273062a30f9c9ec5b 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py
@@ -39,6 +39,9 @@ class SimpleShapeMonteCarloAbsorption(DataProcessorAlgorithm):
     def category(self):
         return 'Workflow\\Inelastic;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS'
 
+    def seeAlso(self):
+        return [ "CalculateMonteCarloAbsorption","MonteCarloAbsorption" ]
+
     def summary(self):
         return 'Calculates absorption corrections for a given sample shape.'
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py
index c40af07035c96746cbd7daa3a64dbaf6b2ba27b5..c4862b3d183b265324f17c622608d1baaca999c7 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py
@@ -25,6 +25,9 @@ class SingleCrystalDiffuseReduction(DataProcessorAlgorithm):
     def category(self):
         return "Diffraction\\Reduction"
 
+    def seeAlso(self):
+        return [ "ConvertToMD","MDNormSCD" ]
+
     def name(self):
         return "SingleCrystalDiffuseReduction"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py
index 441becd92311edba49574dc8e107268f0e207c70..9c29136b9a20f471fb3ece14c1c47ff9366971b3 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py
@@ -60,6 +60,9 @@ class TimeSlice(PythonAlgorithm):
     def summary(self):
         return 'Performa an integration on a raw file over a specified time of flight range'
 
+    def seeAlso(self):
+        return [ "Integration" ]
+
     def PyInit(self):
         self.declareProperty(StringArrayProperty(name='InputFiles'),
                              doc='Comma separated list of input files')
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py
index 2258416e97f528d1e4303155b021e7e0102b1d6d..8c1507ddbddcf34b9cc21b594194669abaf9932b 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py
@@ -23,6 +23,9 @@ class USANSReduction(PythonAlgorithm):
     def category(self):
         return "SANS"
 
+    def seeAlso(self):
+        return [ "USANSSimulation" ]
+
     def name(self):
         return "USANSReduction"
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py
index 20bba523daf18b598dda3c7bc13f8d16112e519d..833f14602932d7c0b7b96caa168e4addc8e3e5f3 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py
@@ -25,6 +25,9 @@ class VesuvioDiffractionReduction(DataProcessorAlgorithm):
     def category(self):
         return 'Diffraction\\Reduction'
 
+    def seeAlso(self):
+        return [ "ISISIndirectDiffractionReduction" ]
+
     def summary(self):
         return ('Performs diffraction reduction for VESUVIO. This algorithm is deprecated (April-2017).')
 
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py
new file mode 100644
index 0000000000000000000000000000000000000000..bcce69fe970876b4eef75e20ffd8b5b1fe192ed8
--- /dev/null
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/WANDPowderReduction.py
@@ -0,0 +1,129 @@
+from __future__ import absolute_import, division, print_function
+from mantid.api import (DataProcessorAlgorithm, AlgorithmFactory,
+                        MatrixWorkspaceProperty, PropertyMode)
+from mantid.simpleapi import (ConvertSpectrumAxis, Transpose,
+                              ResampleX, CopyInstrumentParameters,
+                              Divide, DeleteWorkspace, Scale,
+                              MaskAngle, ExtractMask, Minus,
+                              RemoveMaskedSpectra, mtd)
+from mantid.kernel import StringListValidator, Direction, Property
+
+
+class WANDPowderReduction(DataProcessorAlgorithm):
+    temp_workspace_list = ['__data_tmp', '__cal_tmp', '__mask_tmp', '__bkg_tmp']
+
+    def category(self):
+        return "Diffraction\\Reduction"
+
+    def seeAlso(self):
+        return ['LoadWAND','SaveFocusedXYE']
+
+    def summary(self):
+        return 'Performs powder diffraction data reduction for WAND'
+
+    def name(self):
+        return "WANDPowderReduction"
+
+    def validateInputs(self):
+        issues = dict()
+        return issues
+
+    def PyInit(self):
+
+        self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", '',
+                                                     direction=Direction.Input),
+                             doc='The main input workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty("CalibrationWorkspace", '',
+                                                     optional=PropertyMode.Optional,
+                                                     direction=Direction.Input),
+                             doc='The calibration (vandiaum) workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty("BackgroundWorkspace", '',
+                                                     optional=PropertyMode.Optional,
+                                                     direction=Direction.Input),
+                             doc='The background workspace to be subtracted.')
+
+        self.copyProperties('ConvertSpectrumAxis', ['Target', 'EFixed'])
+
+        self.copyProperties('ResampleX', ['XMin', 'XMax', 'NumberBins', 'LogBinning'])
+
+        self.declareProperty('NormaliseBy', 'Monitor', StringListValidator(['None', 'Time', 'Monitor']), "Normalise to monitor or time. ")
+
+        self.declareProperty('MaskAngle', Property.EMPTY_DBL,
+                             "Phi angle above which will be masked. See :ref:`MaskAngle <algm-MaskAngle>` for details.")
+
+        self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "",
+                                                     direction=Direction.Output),
+                             doc="Output Workspace")
+
+    def PyExec(self):
+        data = self.getProperty("InputWorkspace").value
+        cal = self.getProperty("CalibrationWorkspace").value
+        bkg = self.getProperty("BackgroundWorkspace").value
+        target = self.getProperty("Target").value
+        eFixed = self.getProperty("EFixed").value
+        xMin = self.getProperty("XMin").value
+        xMax = self.getProperty("XMax").value
+        numberBins = self.getProperty("NumberBins").value
+        normaliseBy = self.getProperty("NormaliseBy").value
+        maskAngle = self.getProperty("MaskAngle").value
+        outWS = self.getPropertyValue("OutputWorkspace")
+
+        data_scale = 1
+        cal_scale = 1
+        bkg_scale = 1
+
+        if normaliseBy == "Monitor":
+            data_scale = data.run().getProtonCharge()
+        elif normaliseBy == "Time":
+            data_scale = data.run().getLogData('duration').value
+
+        ExtractMask(data, OutputWorkspace='__mask_tmp', EnableLogging=False)
+
+        if maskAngle != Property.EMPTY_DBL:
+            MaskAngle(Workspace='__mask_tmp', MinAngle=maskAngle, Angle='Phi', EnableLogging=False)
+
+        RemoveMaskedSpectra(InputWorkspace=data, MaskedWorkspace='__mask_tmp', OutputWorkspace='__data_tmp', EnableLogging=False)
+        ConvertSpectrumAxis(InputWorkspace='__data_tmp', Target=target, EFixed=eFixed, OutputWorkspace=outWS, EnableLogging=False)
+        Transpose(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False)
+        ResampleX(InputWorkspace=outWS, OutputWorkspace=outWS, XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False)
+
+        if cal is not None:
+            RemoveMaskedSpectra(InputWorkspace=cal, MaskedWorkspace='__mask_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False)
+            CopyInstrumentParameters(data, '__cal_tmp', EnableLogging=False)
+            ConvertSpectrumAxis(InputWorkspace='__cal_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__cal_tmp', EnableLogging=False)
+            Transpose(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False)
+            ResampleX(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins,
+                      EnableLogging=False)
+            Divide(LHSWorkspace=outWS, RHSWorkspace='__cal_tmp', OutputWorkspace=outWS, EnableLogging=False)
+            if normaliseBy == "Monitor":
+                cal_scale = cal.run().getProtonCharge()
+            elif normaliseBy == "Time":
+                cal_scale = cal.run().getLogData('duration').value
+
+        Scale(InputWorkspace=outWS, OutputWorkspace=outWS, Factor=cal_scale/data_scale, EnableLogging=False)
+
+        if bkg is not None:
+            RemoveMaskedSpectra(InputWorkspace=bkg, MaskedWorkspace='__mask_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
+            CopyInstrumentParameters(data, '__bkg_tmp', EnableLogging=False)
+            ConvertSpectrumAxis(InputWorkspace='__bkg_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__bkg_tmp', EnableLogging=False)
+            Transpose(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
+            ResampleX(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins,
+                      EnableLogging=False)
+            if cal is not None:
+                Divide(LHSWorkspace='__bkg_tmp', RHSWorkspace='__cal_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
+            if normaliseBy == "Monitor":
+                bkg_scale = bkg.run().getProtonCharge()
+            elif normaliseBy == "Time":
+                bkg_scale = bkg.run().getLogData('duration').value
+            Scale(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', Factor=cal_scale/bkg_scale, EnableLogging=False)
+            Minus(LHSWorkspace=outWS, RHSWorkspace='__bkg_tmp', OutputWorkspace=outWS, EnableLogging=False)
+
+        self.setProperty("OutputWorkspace", outWS)
+
+        # remove temp workspaces
+        [DeleteWorkspace(ws, EnableLogging=False) for ws in self.temp_workspace_list if mtd.doesExist(ws)]
+
+
+AlgorithmFactory.subscribe(WANDPowderReduction)
diff --git a/Framework/PythonInterface/plugins/algorithms/sfCalculator.py b/Framework/PythonInterface/plugins/algorithms/sfCalculator.py
deleted file mode 100644
index 35e94a2784ed4d08a4cf135e96c4f70304137efb..0000000000000000000000000000000000000000
--- a/Framework/PythonInterface/plugins/algorithms/sfCalculator.py
+++ /dev/null
@@ -1,1441 +0,0 @@
-#pylint: disable=invalid-name,too-many-arguments,too-many-lines,too-many-instance-attributes, too-many-locals,too-many-branches
-from __future__ import (absolute_import, division, print_function)
-from mantid.simpleapi import *
-import numpy as np
-import os.path
-
-PRECISION = 0.020
-
-
-class sfCalculator(object):
-
-    ref_date = '2014-10-01' # when the detector has been rotated
-
-    INDEX = 0
-
-    tof_min = None  #microS
-    tof_max = None  #microS
-
-    #range of x pixel to use in the X integration (we found out that there
-    #is a frame effect that introduces noise)
-    x_pixel_min = 0   #default is 90
-    x_pixel_max = 255 #default is 190  (must be below 256)
-
-    #from,width,to in microS
-    #rebin_parameters = '0,50,200000'
-    rebin_parameters = '0,50,100000'
-
-    #turn on or off the plots
-    bPlot = False
-    bFittingPlot = False
-
-    #size of detector
-    alpha_pixel_nbr = 256
-    beta_pixel_nbr = 304  #will be integrated over this dimension
-
-    #name of numerators and denominators
-    numerator = None #ex: AiD0
-    denominator = None   #ex: AiD1
-
-    y_axis_numerator = None
-    y_axis_error_numerator = None
-    y_axis_denominator = None
-    y_axis_error_denominator = None
-    x_axis = None
-
-    #define the peak region
-    n_peak_pixel_min = 130
-    n_peak_pixel_max = 135
-    d_peak_pixel_min = 130
-    d_peak_pixel_max = 135
-
-    peak_pixel_min = None
-    peak_pixel_max = None
-    back_pixel_min = None
-    back_pixel_max = None
-
-    #define the background range used in the background subtraction
-    n_back_pixel_min = 125
-    n_back_pixel_max = 140
-    d_back_pixel_min = 125
-    d_back_pixel_max = 140
-
-    y_axis_ratio = None
-    y_axis_error_ratio = None
-    x_axis_ratio = None
-
-    is_nexus_detector_rotated_flag = True
-
-    a = None
-    b = None
-    error_a = None
-    error_b = None
-
-    def __init__(self, numerator=None, denominator=None,
-                 tof_range=None):
-
-        print('---> initialize calculation')
-
-        if tof_range is None:
-            self.tof_min = 10000
-            self.tof_max = 21600
-        else:
-            self.tof_min = tof_range[0]
-            self.tof_max = tof_range[1]
-
-        self.numerator = numerator
-        self.denominator = denominator
-
-        self.x_axis_ratio = None
-        self.y_axis_error_ratio = None
-        self.y_axis_ratio = None
-
-    def setNumerator(self, minPeak, maxPeak, minBack, maxBack):
-
-        print('---> set numerator (' + self.numerator + ')')
-
-        if minPeak != 0:
-            self.n_peak_pixel_min = minPeak
-        if maxPeak != 0 :
-            self.n_peak_pixel_max = maxPeak
-        if minBack != 0:
-            self.n_back_pixel_min = minBack
-        if maxBack != 0:
-            self.n_back_pixel_max = maxBack
-
-    def setDenominator(self, minPeak, maxPeak, minBack, maxBack):
-
-        print('---> set denominator (' + self.denominator + ')')
-
-        if minPeak != 0:
-            self.d_peak_pixel_min = minPeak
-        if maxPeak != 0:
-            self.d_peak_pixel_max = maxPeak
-        if minBack != 0:
-            self.d_back_pixel_min = minBack
-        if maxBack != 0:
-            self.d_back_pixel_max = maxBack
-
-    def run(self):
-        """
-        Perform the calculation
-
-        """
-
-        #perform calculation for numerator
-        self._calculateFinalYAxis(bNumerator=True)
-
-#         #DEBUGGING
-#
-#         #output the data to fit to DEBUG
-#         x_axis = self.x_axis_ratio
-#         y_axis = self.y_axis_numerator
-#         y_error_axis = self.y_axis_error_numerator
-#
-#         print 'create sfOutputTest#'
-#         filename = "/SNS/users/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX
-# #        filename = "/home/j35/Desktop/sfOutputTest#%d.txt" % sfCalculator.INDEX
-#         print filename
-#         sfCalculator.INDEX += 1
-#
-#         f=open(filename,'w')
-#
-#         for i in range(len(x_axis)):
-#             f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n");
-#
-#         f.close
-        #END of DEBUGGING
-
-        #perform calculation for denominator
-        self._calculateFinalYAxis(bNumerator=False)
-
-#         #DEBUGGING
-#
-#         #output the data to fit to DEBUG
-#         x_axis = self.x_axis_ratio
-#         y_axis = self.y_axis_denominator
-#         y_error_axis = self.y_axis_error_denominator
-#
-#         print 'create sfOutputTest#'
-#         filename = "/SNS/users/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX
-# #         filename = "/home/j35/Desktop/sfOutputTest#%d.txt" % sfCalculator.INDEX
-#         print filename
-#         sfCalculator.INDEX += 1
-#
-#         f=open(filename,'w')
-#
-#         for i in range(len(x_axis)):
-#             f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n");
-#
-#         f.close
-#         #END of DEBUGGING
-
-        #calculate y_axis of numerator/denominator
-#        self._x_axis_ratio = self._x_axis
-
-        ## code to replace this
-        #self.y_axis_ratio = self.y_axis_numerator / self.y_axis_denominator
-
-        sz = np.size(self.y_axis_numerator)
-        new_y_axis_ratio = np.zeros(sz)
-        for i in range(sz):
-
-            if self.y_axis_denominator[i] == 0:
-                self.y_axis_denominator[i] = 1
-
-#             print i
-#             print self.y_axis_numerator[i]
-#             print self.y_axis_denominator[i]
-#             print
-
-            new_y_axis_ratio[i] = float(self.y_axis_numerator[i]) / float(self.y_axis_denominator[i])
-        self.y_axis_ratio = new_y_axis_ratio
-
-        ## code to replace this
-#         self.y_axis_error_ratio = ((self.y_axis_error_numerator /
-#                                     self.y_axis_numerator) ** 2 +
-#                                     (self.y_axis_error_denominator /
-#                                      self.y_axis_denominator) ** 2)
-#         self.y_axis_error_ratio = np.sqrt(self.y_axis_error_ratio)
-#         self.y_axis_error_ratio *= self.y_axis_ratio
-        new_y_axis_error_ratio = np.zeros(sz)
-        for i in range(sz):
-
-            if self.y_axis_numerator[i] == 0:
-                self.y_axis_numerator[i] = 1
-
-            tmp_value = (float(self.y_axis_error_numerator[i]) / float(self.y_axis_numerator[i])) **2 + \
-                        (float(self.y_axis_error_denominator[i]) / float(self.y_axis_denominator[i])) **2
-            tmp_value = np.sqrt(tmp_value)
-            new_y_axis_error_ratio[i] = self.y_axis_ratio[i]* tmp_value
-        self.y_axis_error_ratio = new_y_axis_error_ratio
-
-    def isNexusTakeAfterRefDate(self, nexus_date):
-        '''
-        This function parses the output.date and returns true if this date is after the ref date
-        '''
-        nexus_date_acquisition = nexus_date.split('T')[0]
-
-        if nexus_date_acquisition > self.ref_date:
-            return True
-        else:
-            return False
-
-    def _calculateFinalYAxis(self, bNumerator=True):
-        """
-        run full calculation for numerator or denominator
-        """
-        if bNumerator is True:
-            filen = self.numerator
-#            _id = self.id_numerator
-            self.peak_pixel_min = self.n_peak_pixel_min
-            self.peak_pixel_max = self.n_peak_pixel_max
-            self.back_pixel_min = self.n_back_pixel_min
-            self.back_pixel_max = self.n_back_pixel_max
-        else:
-            filen = self.denominator
-#            _id = self.id_denominator
-            self.peak_pixel_min = self.d_peak_pixel_min
-            self.peak_pixel_max = self.d_peak_pixel_max
-            self.back_pixel_min = self.d_back_pixel_min
-            self.back_pixel_max = self.d_back_pixel_max
-
-        nexus_file_numerator = filen
-        print('----> loading nexus file: ' + nexus_file_numerator)
-        EventDataWks = LoadEventNexus(Filename=nexus_file_numerator)
-
-        self.is_nexus_detector_rotated_flag = self.isNexusTakeAfterRefDate(EventDataWks.getRun().getProperty('run_start').value)
-
-        if self.is_nexus_detector_rotated_flag:
-            self.alpha_pixel_nbr = 304
-            self.beta_pixel_nbr = 256
-        else:
-            self.alpha_pixel_nbr = 256
-            self.beta_pixel_nbr = 304  #will be integrated over this dimension
-
-        proton_charge = self._getProtonCharge(EventDataWks)
-        print('----> rebinning ')
-        HistoDataWks = Rebin(InputWorkspace=EventDataWks,
-                             Params=self.rebin_parameters)
-
-#        mt2 = mtd['HistoDataWks']
-#        x_axis = mt2.readX(0)[:]
-
-        x_axis = HistoDataWks.readX(0)[:]
-        self.x_axis = x_axis
-
-        OutputWorkspace = self._createIntegratedWorkspace(InputWorkspace=HistoDataWks,
-                                                          proton_charge=proton_charge,
-                                                          from_pixel=self.peak_pixel_min,
-                                                          to_pixel=self.peak_pixel_max)
-
-        DataWks = self._removeBackground(InputWorkspace=OutputWorkspace,
-                                         from_peak=self.peak_pixel_min,
-                                         to_peak=self.peak_pixel_max,
-                                         from_back=self.back_pixel_min,
-                                         to_back=self.back_pixel_max,
-                                         tof_min = self.tof_min,
-                                         tof_max = self.tof_max)
-
-#         print '----> Convert to histogram'
-#         IntegratedDataWks = ConvertToHistogram(InputWorkspace=OutputWorkspace)
-#
-#         print '----> Transpose'
-#         TransposeIntegratedDataWks = Transpose(InputWorkspace=IntegratedDataWks)
-#
-#         print '----> convert to histogram'
-#         TransposeIntegratedDataWks_t = ConvertToHistogram(InputWorkspace=TransposeIntegratedDataWks)
-#
-#         print '----> flat background1'
-#         TransposeHistoFlatDataWks_1 = FlatBackground(InputWorkspace=TransposeIntegratedDataWks_t,
-#                        StartX=self.back_pixel_min,
-#                        EndX=self.peak_pixel_min,
-#                        Mode='Mean',
-#                        OutputMode="Return Background")
-#
-#         print '----> flat background2'
-#         TransposeHistoFlatDataWks_2 = FlatBackground(InputWorkspace=TransposeIntegratedDataWks_t,
-#                        StartX=self.peak_pixel_max,
-#                        EndX=self.back_pixel_max,
-#                        Mode='Mean',
-#                        OutputMode="Return Background")
-#
-#         print '----> transpose flat background 1 -> data1'
-#         DataWks_1 = Transpose(InputWorkspace=TransposeHistoFlatDataWks_1);
-#
-#         print '----> transpose flat background 2 -> data2'
-#         DataWks_2 = Transpose(InputWorkspace=TransposeHistoFlatDataWks_2);
-#
-#         print '----> convert to histogram data2'
-#         DataWks_1 = ConvertToHistogram(InputWorkspace=DataWks_1);
-#
-#         print '----> convert to histogram data1'
-#         DataWks_2 = ConvertToHistogram(InputWorkspace=DataWks_2)
-#
-#         print '----> rebin workspace data1'
-#         DataWks_1 = RebinToWorkspace(WorkspaceToRebin=DataWks_1,
-#                          WorkspacetoMatch=IntegratedDataWks)
-#
-#         print '----> rebin workspace data2'
-#         DataWks_2 = RebinToWorkspace(WorkspaceToRebin=DataWks_2,
-#                          WorkspacetoMatch=IntegratedDataWks)
-#
-#         print '----> weighted mean'
-#         DataWksWeightedMean = WeightedMean(InputWorkspace1=DataWks_1,
-#                      InputWorkspace2=DataWks_2)
-#
-#         print '----> minus'
-#         DataWks = Minus(LHSWorkspace=IntegratedDataWks,
-#               RHSWorkspace=DataWksWeightedMean)
-
-#        if not bNumerator:
-#            import sys
-#            sys.exit("now we are working with denominator")
-
-
-#        mt3 = mtd['DataWks']
-        self._calculateFinalAxis(Workspace=DataWks,
-                                 bNumerator=bNumerator)
-        print('done with _calculateFinalAxis and back in calculatefinalaxis') #REMOVEME
-
-        #cleanup workspaces
-        DeleteWorkspace(EventDataWks)
-        DeleteWorkspace(HistoDataWks)
-#         DeleteWorkspace(IntegratedDataWks)
-#         DeleteWorkspace(TransposeIntegratedDataWks)
-#         DeleteWorkspace(TransposeIntegratedDataWks_t)
-#         DeleteWorkspace(TransposeHistoFlatDataWks_1)
-#         DeleteWorkspace(TransposeHistoFlatDataWks_2)
-        DeleteWorkspace(DataWks)
-
-        print('done with cleaning workspaces in line 247')
-
-    def _calculateFinalAxis(self, Workspace=None, bNumerator=None):
-        """
-        this calculates the final y_axis and y_axis_error of numerator
-        and denominator
-        """
-
-        print('----> calculate final axis')
-        mt = Workspace
-        x_axis = mt.readX(0)[:]
-        self.x_axis = x_axis
-
-        counts_vs_tof = mt.readY(0)[:]
-        counts_vs_tof_error = mt.readE(0)[:]
-
-## this is not use anymore as the integration is done in the previous step
-#         counts_vs_tof = np.zeros(len(x_axis)-1)
-#         counts_vs_tof_error = np.zeros(len(x_axis)-1)
-#
-#         for x in range(self.alpha_pixel_nbr):
-#             counts_vs_tof += mt.readY(x)[:]
-#             counts_vs_tof_error += mt.readE(x)[:] ** 2
-#         counts_vs_tof_error = np.sqrt(counts_vs_tof_error)
-
-#
-#        #for DEBUGGING
-#        #output data into ascii file
-#        f=open('/home/j35/Desktop/myASCII.txt','w')
-#        if (not bNumerator):
-#            f.write(self.denominator + "\n")
-#
-#            for i in range(len(counts_vs_tof)):
-#                f.write(str(x_axis[i]) + "," + str(counts_vs_tof[i]) + "\n")
-#            f.close
-#            import sys
-#            sys.exit("Stop in _calculateFinalAxis")
-##        end of for DEBUGGING #so far, so good !
-
-        index_tof_min = self._getIndex(self.tof_min, x_axis)
-        index_tof_max = self._getIndex(self.tof_max, x_axis)
-
-        if bNumerator is True:
-            self.y_axis_numerator = counts_vs_tof[index_tof_min:index_tof_max].copy()
-            self.y_axis_error_numerator = counts_vs_tof_error[index_tof_min:index_tof_max].copy()
-            self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max].copy()
-        else:
-            self.y_axis_denominator = counts_vs_tof[index_tof_min:index_tof_max].copy()
-            self.y_axis_error_denominator = counts_vs_tof_error[index_tof_min:index_tof_max].copy()
-            self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max].copy()
-
-        print('done with _calculateFinalAxis')
-
-    def _createIntegratedWorkspace(self,
-                                   InputWorkspace=None,
-                                   OutputWorkspace=None,
-                                   proton_charge=None,
-                                   from_pixel=0,
-                                   to_pixel=255):
-        """
-        This creates the integrated workspace over the second pixel range
-        (beta_pixel_nbr here) and
-        returns the new workspace handle
-        """
-
-        print('-----> Create Integrated workspace ')
-        x_axis = InputWorkspace.readX(0)[:]
-        x_size = to_pixel - from_pixel + 1
-        y_axis = np.zeros((self.alpha_pixel_nbr, len(x_axis) - 1))
-        y_error_axis = np.zeros((self.alpha_pixel_nbr, len(x_axis) - 1))
-        y_range = np.arange(x_size) + from_pixel
-
-#        for x in range(self.beta_pixel_nbr):
-#            for y in y_range:
-#                index = int(self.alpha_pixel_nbr * x + y)
-##                y_axis[y, :] += InputWorkspace.readY(index)[:]
-#                y_axis[y, :] += InputWorkspace.readY(index)[:]
-#                y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) *
-#                                        (InputWorkspace.readE(index)[:]))
-
-        if self.is_nexus_detector_rotated_flag:
-            for x in range(256):
-                for y in y_range:
-                    index = int(y+x*304)
-    #                y_axis[y, :] += InputWorkspace.readY(index)[:]
-                    y_axis[y, :] += InputWorkspace.readY(index)[:]
-                    y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) *
-                                           (InputWorkspace.readE(index)[:]))
-
-        else:
-            for x in range(304):
-                for y in y_range:
-                    index = int(y+x*256)
-    #                y_axis[y, :] += InputWorkspace.readY(index)[:]
-                    y_axis[y, :] += InputWorkspace.readY(index)[:]
-                    y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) *
-                                           (InputWorkspace.readE(index)[:]))
-
-#        #DEBUG
-#        f=open('/home/j35/myASCIIfromCode.txt','w')
-#        new_y_axis = np.zeros((len(x_axis)-1))
-#
-#        for y in range(256):
-#            new_y_axis += y_axis[y,:]
-#
-#        for i in range(len(x_axis)-1):
-#            f.write(str(x_axis[i]) + "," + str(new_y_axis[i]) + "\n");
-#        f.close
-#
-#        print sum(new_y_axis)
-#
-#        #END OF DEBUG
-        ## so far, worsk perfectly (tested with portal vs Mantid vs Matlab
-
-        y_axis = y_axis.flatten()
-        y_error_axis = np.sqrt(y_error_axis)
-        #plot_y_error_axis = _y_error_axis #for output testing only
-        #plt.imshow(plot_y_error_axis, aspect='auto', origin='lower')
-        y_error_axis = y_error_axis.flatten()
-
-        #normalization by proton beam
-        y_axis /= (proton_charge * 1e-12)
-        y_error_axis /= (proton_charge * 1e-12)
-
-        OutputWorkspace = CreateWorkspace(DataX=x_axis,
-                                          DataY=y_axis,
-                                          DataE=y_error_axis,
-                                          Nspec=self.alpha_pixel_nbr)
-
-        return OutputWorkspace
-
-    def weighted_mean(self, data, error):
-
-        sz = len(data)
-
-        #calculate numerator
-        dataNum = 0
-        for i in range(sz):
-            if data[i] != 0:
-                tmpFactor = float(data[i]) / (error[i]**2)
-                dataNum += tmpFactor
-
-        #calculate denominator
-        dataDen = 0
-        for i in range(sz):
-            if error[i] != 0:
-                tmpFactor = float(1) / (error[i]**2)
-                dataDen += tmpFactor
-
-        if dataDen == 0:
-            dataDen = 1
-
-        mean = dataNum / dataDen
-        mean_error = np.sqrt(dataDen)
-
-        return (mean, mean_error)
-
-    def removeValueFromArray(self, data, background):
-        # Will remove the background value from each of the data
-        # element (data is an array)
-
-        sz = len(data)
-        new_data = np.zeros(sz)
-        for i in range(sz):
-            new_data[i] = data[i] - background
-
-        return new_data
-
-    def removeValueFromArrayError(self, data_error, background_error):
-        # will calculate the new array of error when removing
-        # a single value from an array
-
-        sz = len(data_error)
-        new_data_error = np.zeros(sz)
-        for i in range(sz):
-            new_data_error[i] = np.sqrt(data_error[i]**2 + background_error**2)
-
-        return new_data_error
-
-    def sumWithError(self, peak, peak_error):
-        # add the array element using their weight and return new error as well
-
-        sz = len(peak)
-        sum_peak = 0
-        sum_peak_error = 0
-        for i in range(sz):
-            sum_peak += peak[i]
-            sum_peak_error += peak_error[i]**2
-
-        sum_peak_error = np.sqrt(sum_peak_error)
-        return [sum_peak, sum_peak_error]
-
-    #pylint: disable=unused-argument
-    def  _removeBackground(self,
-                           InputWorkspace=None,
-                           from_peak= 0,
-                           to_peak=256,
-                           from_back=0,
-                           to_back=256,
-                           tof_min = 0,
-                           tof_max = 200000):
-
-        # retrieve various axis
-        tof_axis = InputWorkspace.readX(0)[:]
-        nbr_tof = len(tof_axis)-1
-
-        # make big array of data
-        if self.is_nexus_detector_rotated_flag:
-            data = np.zeros((304,nbr_tof))
-            error = np.zeros((304,nbr_tof))
-            for x in range(304):
-                data[x,:] = InputWorkspace.readY(x)[:]
-                error[x,:] = InputWorkspace.readE(x)[:]
-
-        else:
-            data = np.zeros((256,nbr_tof))
-            error = np.zeros((256,nbr_tof))
-            for x in range(256):
-                data[x,:] = InputWorkspace.readY(x)[:]
-                error[x,:] = InputWorkspace.readE(x)[:]
-
-        peak_array = np.zeros(nbr_tof)
-        peak_array_error = np.zeros(nbr_tof)
-
-        bMinBack = False
-        bMaxBack = False
-
-        min_back = 0
-        min_back_error = 0
-        max_back = 0
-        max_back_error = 0
-
-        for t in range(nbr_tof-1):
-
-            _y_slice = data[:,t]
-            _y_error_slice = error[:,t]
-
-            _y_slice = _y_slice.flatten()
-            _y_error_slice = _y_error_slice.flatten()
-
-            if from_back < (from_peak-1):
-                range_back_min = _y_slice[from_back : from_peak]
-                range_back_error_min = _y_error_slice[from_back : from_peak]
-                [min_back, min_back_error] = self.weighted_mean(range_back_min, range_back_error_min)
-                bMinBack = True
-
-            if (to_peak+1) < to_back:
-                range_back_max = _y_slice[to_peak+1: to_back+1]
-                range_back_error_max = _y_error_slice[to_peak+1: to_back+1]
-                [max_back, max_back_error] = self.weighted_mean(range_back_max, range_back_error_max)
-                bMaxBack = True
-
-            # if we have a min and max background
-            if bMinBack & bMaxBack:
-                [background, background_error] = self.weighted_mean([min_back,max_back],[min_back_error,max_back_error])
-#
-            # if we don't have a max background, we use min background
-            if not bMaxBack:
-                background = min_back
-                background_error = min_back_error
-#
-            # if we don't have a min background, we use max background
-            if not bMinBack:
-                background = max_back
-                background_error = max_back_error
-
-            tmp_peak = _y_slice[from_peak:to_peak+1]
-            tmp_peak_error = _y_error_slice[from_peak:to_peak+1]
-
-            new_tmp_peak = self.removeValueFromArray(tmp_peak, background)
-            new_tmp_peak_error = self.removeValueFromArrayError(tmp_peak_error, background_error)
-
-            [final_value, final_error] = self.sumWithError(new_tmp_peak, new_tmp_peak_error)
-
-            peak_array[t] = final_value
-            peak_array_error[t] = final_error
-
-        # make new workspace
-        y_axis = peak_array.flatten()
-        y_error_axis = peak_array_error.flatten()
-
-        DataWks = CreateWorkspace(DataX=tof_axis[0:-1],
-                                  DataY=y_axis,
-                                  DataE=y_error_axis,
-                                  Nspec=1)
-
-#         import sys
-#         sys.exit("in _removeBackground... so far, so good!")
-
-        return DataWks
-
-    def _getIndex(self, value, array):
-        """
-        returns the index where the value has been found
-        """
-        return array.searchsorted(value)
-
-    def _getProtonCharge(self, st=None):
-        """
-        Returns the proton charge of the given workspace in picoCoulomb
-        """
-        if st is not None:
-            mt_run = st.getRun()
-            proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value
-            proton_charge = proton_charge_mtd_unit / 2.77777778e-10
-            return proton_charge
-        return None
-
-    def __mul__(self, other):
-        """
-        operator * between two instances of the class
-        """
-
-        product = sfCalculator()
-
-        product.numerator = self.numerator + '*' + other.numerator
-        product.denominator = self.denominator + '*' + other.denominator
-
-        product.x_axis_ratio = self.x_axis_ratio
-
-        ## replace code by
-        #product.y_axis_ratio = self.y_axis_ratio * other.y_axis_ratio
-        sz = len(self.y_axis_ratio)
-        new_y_axis_ratio = np.zeros(sz)
-        for i in range(sz):
-            new_y_axis_ratio[i] = self.y_axis_ratio[i] * other.y_axis_ratio[i]
-        product.y_axis_ratio = new_y_axis_ratio
-
-        ## replace code by
-        #product.y_axis_error_ratio = product.y_axis_ratio * np.sqrt((other.y_axis_error_ratio / other.y_axis_ratio)**2 +\
-        #                             (self.y_axis_error_ratio / self.y_axis_ratio)**2)
-        new_y_axis_error_ratio = np.zeros(sz)
-        for i in range(sz):
-
-            # make sure we don't divide b 0
-            if other.y_axis_ratio[i] == 0:
-                other.y_axis_ratio[i] = 1
-            if self.y_axis_ratio[i] == 0:
-                self.y_axis_ratio[i] = 1
-
-            tmp_product = (other.y_axis_error_ratio[i] / other.y_axis_ratio[i]) ** 2 + \
-                          (self.y_axis_error_ratio[i] / self.y_axis_ratio[i]) ** 2
-            tmp_product = np.sqrt(tmp_product)
-            new_y_axis_error_ratio[i] = tmp_product * product.y_axis_ratio[i]
-        product.y_axis_error_ratio = new_y_axis_error_ratio
-
-        return product
-
-    def fit(self):
-        """
-        This is going to fit the counts_vs_tof with a linear expression and return the a and
-        b coefficients (y=a+bx)
-        """
-
-        DataToFit = CreateWorkspace(DataX=self.x_axis_ratio,
-                                    DataY=self.y_axis_ratio,
-                                    DataE=self.y_axis_error_ratio,
-                                    Nspec=1)
-
-        print('replaceSpecialValues')
-        DataToFit = ReplaceSpecialValues(InputWorkspace=DataToFit,
-                                         NaNValue=0,
-                                         NaNError=0,
-                                         InfinityValue=0,
-                                         InfinityError=0)
-
-#        ResetNegatives(InputWorkspace='DataToFit',
-#                       OutputWorkspace='DataToFit',
-#                       AddMinimum=0)
-
-#         #DEBUG
-#         #output the data to fit to DEBUG
-#         x_axis = DataToFit.readX(0)[:]
-#         y_axis = DataToFit.readY(0)[:]
-#         y_error_axis = DataToFit.readE(0)[:]
-#
-#         print 'create sfOutputTest#'
-#         filename = "/home/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX
-#         print filename
-#         sfCalculator.INDEX += 1
-#
-#         f=open(filename,'w')
-#
-#         for i in range(len(x_axis)):
-#             f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n");
-#
-#         f.close
-#         #END OF DEBUG
-
-        try:
-
-            Fit(InputWorkspace=DataToFit,
-                Function="name=UserFunction, Formula=a+b*x, a=1, b=2",
-                Output='res')
-
-        except:
-
-            xaxis = self.x_axis_ratio
-            sz = len(xaxis)
-            xmin = xaxis[0]
-            xmax = xaxis[sz/2]
-
-            DataToFit = CropWorkspace(InputWorkspace=DataToFit,
-                                      XMin=xmin,
-                                      XMax=xmax)
-
-            Fit(InputWorkspace=DataToFit,
-                Function='name=UserFunction, Formula=a+b*x, a=1, b=2',
-                Output='res')
-
-        res = mtd['res_Parameters']
-
-        self.a = res.cell(0,1)
-        self.b = res.cell(1,1)
-        self.error_a = res.cell(0,2)
-        self.error_b = res.cell(1,2)
-
-#        self.a = res.getDouble("Value", 0)
-#        self.b = res.getDouble("Value", 1)
-#        self.error_a = res.getDouble("Error", 0)
-#        self.error_b = res.getDouble("Error", 1)
-
-
-def plotObject(instance):
-
-#    return
-
-#    print 'a: ' + str(instance.a[-1])
-#    print 'b: ' + str(instance.b[-1])
-
-    figure()
-    errorbar(instance.x_axis_ratio,
-             instance.y_axis_ratio,
-             instance.y_axis_error_ratio,
-             marker='s',
-             mfc='red',
-             linestyle='',
-             label='Exp. data')
-
-    if instance.a is not None:
-        x = linspace(10000, 22000, 100)
-        _label = "%.3f + x*%.2e" % (instance.a, instance.b)
-        plot(x, instance.a + instance.b * x, label=_label)
-
-    xlabel("TOF (microsS)")
-    ylabel("Ratio")
-
-    title(instance.numerator + '/' + instance.denominator)
-    show()
-    legend()
-
-
-def recordSettings(a, b, error_a, error_b, name, instance):
-    """
-    This function will record the various fitting parameters and the
-    name of the ratio
-    """
-    print('--> recoding settings')
-    a.append(instance.a)
-    b.append(instance.b)
-    error_a.append(instance.error_a)
-    error_b.append(instance.error_b)
-    name.append(instance.numerator + '/' + instance.denominator)
-
-
-def variable_value_splitter(variable_value):
-    """
-        This function split the variable that looks like "LambdaRequested:3.75"
-        and returns a dictionnary of the variable name and value
-    """
-
-    _split = variable_value.split('=')
-    variable = _split[0]
-    value = _split[1]
-    return {'variable':variable, 'value':value}
-
-
-def isWithinRange(value1, value2):
-    """
-        This function checks if the two values and return true if their
-        difference is <= PRECISION
-    """
-    diff = abs(float(value1)) - abs(float(value2))
-    if abs(diff) <= PRECISION:
-        return True
-    else:
-        return False
-
-
-def outputFittingParameters(a, b, error_a, error_b,
-                            lambda_requested,
-                            incident_medium,
-                            S1H, S2H,
-                            S1W, S2W,
-                            output_file_name):
-    """
-    Create an ascii file of the various fittings parameters
-    y=a+bx
-    1st column: incident medium
-    2nd column: lambda requested
-    3rd column: S1H value
-    4th column: S2H value
-    5th column: S1W value
-    6th column: S2W value
-    7th column: a
-    7th column: b
-    8th column: error_a
-    9th column: error_b
-    """
-
-    print('--> output fitting parameters')
-
-    bFileExist = False
-    #First we need to check if the file already exist
-    if os.path.isfile(output_file_name):
-        bFileExist = True
-
-    #then if it does, parse the file and check if following infos are
-    #already defined:
-    #  lambda_requested, S1H, S2H, S1W, S2W
-    if bFileExist:
-        f = open(output_file_name, 'r')
-        text = f.readlines()
-#        split_lines = text.split('\n')
-        split_lines = text
-
-        entry_list_to_add = []
-
-        try:
-
-            sz = len(a)
-            for i in range(sz):
-
-                _match = False
-
-                for _line in split_lines:
-                    if _line[0] == '#':
-                        continue
-
-                    _line_split = _line.split(' ')
-                    _incident_medium = variable_value_splitter(_line_split[0])
-
-                    if _incident_medium['value'].strip() == incident_medium.strip():
-                        _lambdaRequested = variable_value_splitter(_line_split[1])
-                        if isWithinRange(_lambdaRequested['value'], lambda_requested):
-                            _s1h = variable_value_splitter(_line_split[2])
-                            if isWithinRange(_s1h['value'], S1H[i]):
-                                _s2h = variable_value_splitter(_line_split[3])
-                                if isWithinRange(_s2h['value'],S2H[i]):
-                                    _s1w = variable_value_splitter(_line_split[4])
-                                    if isWithinRange(_s1w['value'],S1W[i]):
-                                        _s2w = variable_value_splitter(_line_split[5])
-                                        if isWithinRange(_s2w['value'],S2W[i]):
-                                            _match = True
-                                            break
-
-                if not _match:
-                    entry_list_to_add.append(i)
-
-        except:
-            #replace file because this one has the wrong format
-            _content = ['#y=a+bx\n', '#\n',
-                        '#lambdaRequested[Angstroms] S1H[mm] (S2/Si)H[mm] S1W[mm] (S2/Si)W[mm] a b error_a error_b\n', '#\n']
-            sz = len(a)
-            for i in range(sz):
-
-                _line = 'IncidentMedium=' + incident_medium.strip() + ' '
-                _line += 'LambdaRequested=' + str(lambda_requested) + ' '
-
-                _S1H = "{0:.2f}".format(abs(S1H[i]))
-                _S2H = "{0:.2f}".format(abs(S2H[i]))
-                _S1W = "{0:.2f}".format(abs(S1W[i]))
-                _S2W = "{0:.2f}".format(abs(S2W[i]))
-                _a = "{0:}".format(a[i])
-                _b = "{0:}".format(b[i])
-                _error_a = "{0:}".format(float(error_a[i]))
-                _error_b = "{0:}".format(float(error_b[i]))
-
-                _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' '
-                _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' '
-                _line += 'a=' + _a + ' '
-                _line += 'b=' + _b + ' '
-                _line += 'error_a=' + _error_a + ' '
-                _line += 'error_b=' + _error_b + '\n'
-                _content.append(_line)
-
-            f = open(output_file_name, 'w')
-            f.writelines(_content)
-            f.close()
-            return
-
-        _content = []
-        for j in entry_list_to_add:
-
-            _line = 'IncidentMedium=' + incident_medium + ' '
-            _line += 'LambdaRequested=' + str(lambda_requested) + ' '
-
-            _S1H = "{0:.2f}".format(abs(S1H[j]))
-            _S2H = "{0:.2f}".format(abs(S2H[j]))
-            _S1W = "{0:.2f}".format(abs(S1W[j]))
-            _S2W = "{0:.2f}".format(abs(S2W[j]))
-            _a = "{0:}".format(a[j])
-            _b = "{0:}".format(b[j])
-            _error_a = "{0:}".format(float(error_a[j]))
-            _error_b = "{0:}".format(float(error_b[j]))
-
-            _line += 'S1H=' + _S1H + ' ' + 'S2iH=' + _S2H + ' '
-            _line += 'S1W=' + _S1W + ' ' + 'S2iW=' + _S2W + ' '
-            _line += 'a=' + _a + ' '
-            _line += 'b=' + _b + ' '
-            _line += 'error_a=' + _error_a + ' '
-            _line += 'error_b=' + _error_b + '\n'
-            _content.append(_line)
-
-        f = open(output_file_name, 'a')
-        f.writelines(_content)
-        f.close()
-
-    else:
-
-        _content = ['#y=a+bx\n', '#\n',
-                    '#lambdaRequested[Angstroms] S1H[mm] (S2/Si)H[mm] S1W[mm] (S2/Si)W[mm] a b error_a error_b\n', '#\n']
-        sz = len(a)
-        for i in range(sz):
-
-            _line = 'IncidentMedium=' + incident_medium.strip() + ' '
-            _line += 'LambdaRequested=' + str(lambda_requested) + ' '
-
-            _S1H = "{0:.2f}".format(abs(S1H[i]))
-            _S2H = "{0:.2f}".format(abs(S2H[i]))
-            _S1W = "{0:.2f}".format(abs(S1W[i]))
-            _S2W = "{0:.2f}".format(abs(S2W[i]))
-            _a = "{0:}".format(a[i])
-            _b = "{0:}".format(b[i])
-            _error_a = "{0:}".format(float(error_a[i]))
-            _error_b = "{0:}".format(float(error_b[i]))
-
-            _line += 'S1H=' + _S1H + ' ' + 'S2iH=' + _S2H + ' '
-            _line += 'S1W=' + _S1W + ' ' + 'S2iW=' + _S2W + ' '
-            _line += 'a=' + _a + ' '
-            _line += 'b=' + _b + ' '
-            _line += 'error_a=' + _error_a + ' '
-            _line += 'error_b=' + _error_b + '\n'
-            _content.append(_line)
-
-        f = open(output_file_name, 'w')
-        f.writelines(_content)
-        f.close()
-
-
-def createIndividualList(string_list_files):
-    """
-    Using the list_files, will produce a dictionary of the run
-    number and number of attenuator
-    ex:
-        list_files = "1000:0, 1001:1, 1002:1, 1003:2"
-        return {1000:0, 1001:1, 1002:2, 1003:2}
-    """
-    if string_list_files == '':
-        return None
-    first_split = string_list_files.split(',')
-
-    list_runs = []
-    list_attenuator= []
-
-    _nbr_files = len(first_split)
-    for i in range(_nbr_files):
-        _second_split = first_split[i].split(':')
-        list_runs.append(_second_split[0].strip())
-        list_attenuator.append(int(_second_split[1].strip()))
-
-    return {'list_runs':list_runs,
-            'list_attenuator':list_attenuator}
-
-
-def getLambdaValue(mt):
-    """
-    return the lambdaRequest value
-    """
-    mt_run = mt.getRun()
-    _lambda = mt_run.getProperty('LambdaRequest').value
-    return _lambda
-
-
-def getSh(mt, top_tag, bottom_tag):
-    """
-        returns the height and units of the given slits
-    """
-    mt_run = mt.getRun()
-    st = mt_run.getProperty(top_tag).value
-    sb = mt_run.getProperty(bottom_tag).value
-    sh = float(sb[0]) - float(st[0])
-    units = mt_run.getProperty(top_tag).units
-    return sh, units
-
-
-def getSheight(mt, index):
-    """
-        return the DAS hardware slits height of slits # index
-    """
-    mt_run = mt.getRun()
-    if index == '2':
-        try:
-            tag = 'SiVHeight'
-            value = mt_run.getProperty(tag).value
-        except:
-            tag = 'S2VHeight'
-            value = mt_run.getProperty(tag).value
-    else:
-        tag = 'S1VHeight'
-        value = mt_run.getProperty(tag).value
-
-    return value[0]
-
-
-def getS1h(mt=None):
-    """
-        returns the height and units of the slit #1
-    """
-    if mt is not None:
-#        _h, units = getSh(mt, 's1t', 's1b')
-        _h = getSheight(mt, '1')
-        return _h
-    return None
-
-
-def getS2h(mt=None):
-    """
-        returns the height and units of the slit #2
-    """
-    if mt is not None:
-#        _h, units = getSh(mt, 's2t', 's2b')
-        _h = getSheight(mt, '2')
-        return _h
-    return None
-
-
-def getSwidth(mt, index):
-    """
-        returns the width and units of the given index slits
-        defined by the DAS hardware
-    """
-    mt_run = mt.getRun()
-    if index == '2':
-        try:
-            tag = 'SiHWidth'
-            value = mt_run.getProperty(tag).value
-        except:
-            tag = 'S2HWidth'
-            value = mt_run.getProperty(tag).value
-    else:
-        tag = 'S1HWidth'
-        value = mt_run.getProperty(tag).value
-    return value[0]
-
-
-def getSw(mt, left_tag, right_tag):
-    """
-        returns the width and units of the given slits
-    """
-    mt_run = mt.getRun()
-    sl = mt_run.getProperty(left_tag).value
-    sr = mt_run.getProperty(right_tag).value
-    sw = float(sl[0]) - float(sr[0])
-    units = mt_run.getProperty(left_tag).units
-    return sw, units
-
-
-def getS1w(mt=None):
-    """
-        returns the width and units of the slit #1
-    """
-    if mt is not None:
-#        _w, units = getSw(mt, 's1l', 's1r')
-        _w = getSwidth(mt, '1')
-        return _w
-    return None
-
-
-def getS2w(mt=None):
-    """
-        returns the width and units of the slit #2
-    """
-    if mt is not None:
-#        _w, units = getSh(mt, 's2l', 's2r')
-        _w = getSwidth(mt, '2')
-        return _w
-    return None
-
-
-def getSlitsValueAndLambda(full_list_runs,
-                           S1H, S2H,
-                           S1W, S2W, lambdaRequest):
-    """
-    Retrieve the S1H (slit 1 height),
-                 S2H (slit 2 height),
-                 S1W (slit 1 width),
-                 S2W (slit 2 width) and
-                 lambda requested values
-    """
-    _nbr_files = len(full_list_runs)
-    print('> Retrieving Slits and Lambda Requested for each file:')
-    for i in range(_nbr_files):
-        _full_file_name = full_list_runs[i]
-        print('-> ' + _full_file_name)
-        tmpWks = LoadEventNexus(Filename=_full_file_name,
-                                MetaDataOnly='1')
-#        mt1 = mtd['tmpWks']
-        _s1h_value = getS1h(tmpWks)
-        _s2h_value = getS2h(tmpWks)
-        S1H[i] = _s1h_value
-        S2H[i] = _s2h_value
-
-        _s1w_value = getS1w(tmpWks)
-        _s2w_value = getS2w(tmpWks)
-        S1W[i] = _s1w_value
-        S2W[i] = _s2w_value
-
-        _lambda_value = getLambdaValue(tmpWks)
-        lambdaRequest[i] = _lambda_value
-
-
-def isRunsSorted(dummy_list_runs, S1H, S2H):
-    """
-    Make sure the files have been sorted
-    """
-    sz = len(S1H)
-    sTotal = np.zeros(sz)
-    for i in range(sz):
-        sTotal[i] = S1H[i] + S2H[i]
-
-    sorted_sTotal = sorted(sTotal)
-
-    for i in range(len(sTotal)):
-        _left = list(sTotal)[i]
-        _right = sorted_sTotal[i]
-
-        _left_formated = "%2.1f" % _left
-        _right_formated = "%2.1f" % _right
-        if _left_formated != _right_formated:
-            return False
-
-    return True
-
-
-def calculateAndFit(numerator='',
-                    denominator='',
-                    list_peak_back_numerator=None,
-                    list_peak_back_denominator=None,
-                    list_objects=None,
-                    tof_range=None):
-    if list_objects is None:
-        list_objects=[]
-    print('--> running calculate and fit algorithm')
-
-    cal1 = sfCalculator(numerator=numerator,
-                        denominator=denominator,
-                        tof_range=tof_range)
-
-    cal1.setNumerator(minPeak=list_peak_back_numerator[0],
-                      maxPeak=list_peak_back_numerator[1],
-                      minBack=list_peak_back_numerator[2],
-                      maxBack=list_peak_back_numerator[3])
-
-    cal1.setDenominator(minPeak=list_peak_back_denominator[0],
-                        maxPeak=list_peak_back_denominator[1],
-                        minBack=list_peak_back_denominator[2],
-                        maxBack=list_peak_back_denominator[3])
-
-    cal1.run()
-    print('Done with cal1.run()')
-
-    if list_objects != [] and list_objects[-1] is not None:
-        new_cal1 = cal1 * list_objects[-1]
-        new_cal1.fit()
-        return new_cal1
-    else:
-        cal1.fit()
-        return cal1
-
-
-def showhelp():
-    """
-        Here the user will have information about how the command line
-        works
-    """
-    print('sfCalculator help:')
-    print()
-    print('example:')
-    print(' > sfCalculator.calculate(string_runs="55889:0, 55890:1, 55891:1, 55892:2",')
-    print('                          list_')
-
-#if __name__ == '__main__':
-
-
-def calculate(string_runs=None,\
-              #              list_attenuator=None,
-              list_peak_back=None,
-              incident_medium=None,
-              output_file_name=None,
-              tof_range=None):
-    """
-    In this current version, the program will automatically calculates
-    the scaling function for up to, and included, 6 attenuators.
-    A output file will then be produced with the following format:
-        S1H  S2H    a   b   error_a    error_b
-        ....
-        where y=a+bx
-        x axis is in microS
-
-        The string runs has to be specified this way:
-        string_runs = "run#1:nbr_attenuator, run#2:nbr_attenuator...."
-
-        the list_peak_back is specified this way:
-        list_peak_back =
-            [[peak_min_run1, peak_max_run1, back_min_run1, back_max_run1],
-             [peak_min_run2, peak_max_run2, back_min_run2, back_max_run2],
-             [...]]
-
-        output_path = where the scaling factor files will be written
-        tof_range
-
-    """
-
-    list_attenuator = None
-
-    #use default string files if not provided
-    if string_runs is None:
-        #Input from user
-#        list_runs = ['55889', '55890', '55891', '55892', '55893', '55894',
-#                     '55895', '55896', '55897', '55898', '55899', '55900',
-#                     '55901', '55902']
-        list_runs = ['55889', '55890', '55891', '55892', '55893', '55894']
-        nexus_path = '/mnt/hgfs/j35/results/'
-        pre = 'REF_L_'
-        nexus_path_pre = nexus_path + pre
-        post = '_event.nxs'
-
-        for (offset, item) in enumerate(list_runs):
-            list_runs[offset] = nexus_path_pre + item + post
-
-    else:
-        dico = createIndividualList(string_runs)
-        list_runs = dico['list_runs']
-
-        for (offset, item) in enumerate(list_runs):
-            try:
-                _File = FileFinder.findRuns("REF_L%d" %int(item))[0]
-                list_runs[offset] = _File
-            except RuntimeError:
-                msg = "RefLReduction: could not find run %s\n" %item
-                msg += "Add your data folder to your User Data Directories in the File menu"
-                raise RuntimeError(msg)
-
-        list_attenuator = dico['list_attenuator']
-
-    if incident_medium is None:
-        incident_medium = "H20" #default value
-
-    if list_attenuator is None:
-#        list_attenuator = [0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4]
-        list_attenuator = [0, 1, 1, 1, 1, 1]
-
-    if list_peak_back is None:
-        list_peak_back = np.zeros((len(list_runs), 4))   #[peak_min, peak_max, back_min, back_max]
-#        list_peak_back[9, ] = [128, 136, 120, 145]
-#        list_peak_back[11, ] = [125, 140, 115, 150]
-#        list_peak_back[10, ] = [128, 136, 120, 145]
-#        list_peak_back[13, ] = [120, 145, 105, 155]
-#        list_peak_back[12, ] = [125, 140, 115, 150]
-
-    #####
-    #Input file should be as it is here !
-    #####
-
-    #retrieve the S1H and S2H val/units for each NeXus
-    #retrieve the lambdaRequest value (Angstrom)
-    S1H = {}
-    S2H = {}
-    S1W = {}
-    S2W = {}
-    lambdaRequest = {}
-    getSlitsValueAndLambda(list_runs, S1H, S2H, S1W, S2W, lambdaRequest)
-
-    #Make sure all the lambdaRequested are identical within a given range
-    lambdaRequestPrecision = 0.01 #1%
-
-    for i in lambdaRequest:
-        _localValue = float(lambdaRequest[i][0])
-        _localValueRate = lambdaRequestPrecision * _localValue
-        _leftValue = _localValue - _localValueRate
-        _rightValue = _localValue + _localValueRate
-
-        if (_localValue < _leftValue) or (_localValue > _rightValue):
-            raise Exception("lambda requested do not match !")
-
-    #make sure the file are sorted from smaller to bigger openning
-    if isRunsSorted(list_runs, S1H, S2H):
-
-        #initialize record fitting parameters arrays
-        a = []
-        b = []
-        error_a = []
-        error_b = []
-        name = []
-
-        finalS1H = []
-        finalS2H = []
-
-        finalS1W = []
-        finalS2W = []
-
-        #array of True/False flags that will allow us
-        #to rescale the calculation on the first attenuator
-        _first_A = []
-        for dummy_j in range(len(np.unique(list_attenuator))):
-            _first_A.append(True)
-
-        #array of index of first attenuator
-        _index_first_A = []
-        for dummy_j in range(len(np.unique(list_attenuator))):
-            _index_first_A.append(-1)
-
-        index_numerator = -1
-        index_denominator = -1
-
-        list_objects = []
-
-        for i in range(len(list_runs)):
-
-            print('> Working with index: ' + str(i))
-            _attenuator = list_attenuator[i]
-
-            if _attenuator == 0:
-                continue
-            else:
-                if _first_A[_attenuator] is True:
-                    _first_A[_attenuator] = False
-                    _index_first_A[_attenuator] = i
-                    continue
-                else:
-                    index_numerator = i
-                    index_denominator = _index_first_A[_attenuator]
-
-                print('-> numerator  : ' + str(list_runs[index_numerator]))
-                print('-> denominator: ' + str(list_runs[index_denominator]))
-                cal = calculateAndFit(numerator=list_runs[index_numerator],
-                                      denominator=list_runs[index_denominator],
-                                      list_peak_back_numerator=list_peak_back[index_numerator],
-                                      list_peak_back_denominator=list_peak_back[index_denominator],
-                                      list_objects=list_objects,
-                                      tof_range=tof_range)
-                print('-> Done with Calculate and Fit')
-
-                recordSettings(a, b, error_a, error_b, name, cal)
-
-                if i < (len(list_runs) - 1) and list_attenuator[i + 1] == (_attenuator+1):
-                    list_objects.append(cal)
-
-            #record S1H and S2H
-            finalS1H.append(S1H[index_numerator])
-            finalS2H.append(S2H[index_numerator])
-
-            #record S1W and S2W
-            finalS1W.append(S1W[index_numerator])
-            finalS2W.append(S2W[index_numerator])
-
-        #output the fitting parameters in an ascii
-        _lambdaRequest = "{0:.2f}".format(lambdaRequest[0][0])
-
-#        output_pre = 'SFcalculator_lr' + str(_lambdaRequest)
-#        output_ext = '.txt'
-#        output_file = output_path + '/' + output_pre + output_ext
-
-        if (output_file_name is None) or (output_file_name == ''):
-            output_file_name = "RefLsf.cfg"
-
-        outputFittingParameters(a, b, error_a, error_b,
-                                _lambdaRequest,
-                                incident_medium,
-                                finalS1H, finalS2H,
-                                finalS1W, finalS2W,
-                                output_file_name)
-
-        print('Done !')
-
-#    else:
-#        """
-#        sort the files
-#        """
-#        pass
diff --git a/Framework/PythonInterface/plugins/functions/TeixeiraWater.py b/Framework/PythonInterface/plugins/functions/TeixeiraWater.py
index 4c96030e35ff38d73dd7223c7e9cc56bab89c049..b82a46ae9f53ad0a1a05e463608cc6ded6683c09 100644
--- a/Framework/PythonInterface/plugins/functions/TeixeiraWater.py
+++ b/Framework/PythonInterface/plugins/functions/TeixeiraWater.py
@@ -26,10 +26,14 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 from __future__ import (absolute_import, division, print_function)
 import numpy as np
 from mantid.api import IFunction1D, FunctionFactory
+from scipy import constants
 
 
 class TeixeiraWater(IFunction1D):
 
+    planck_constant = constants.Planck / constants.e * 1E15  # meV*psec
+    hbar = planck_constant / (2 * np.pi)  # meV * ps  = ueV * ns
+
     def category(self):
         return "QuasiElastic"
 
@@ -41,25 +45,9 @@ class TeixeiraWater(IFunction1D):
     def function1D(self, xvals):
         tau = self.getParameterValue("Tau")
         length = self.getParameterValue("L")
-        length = length**2
-
-        xvals = np.array(xvals)
-        hwhm = xvals * xvals * length / (tau * (1 + xvals * xvals * length))
-
-        return hwhm
-
-    def functionDeriv1D(self, xvals, jacobian):
-        tau = self.getParameterValue("Tau")
-        length = self.getParameterValue("L")
-        length = length**2
-
-        i = 0
-        for x in xvals:
-            h = x*x*length/(tau*(1+x*x*length))
-            jacobian.set(i,0,-h/tau)
-            jacobian.set(i,1,h*(1.0-h*tau)/length)
-            i += 1
+        q2l2 = np.square(length * np.array(xvals))
+        return (self.hbar/tau) * q2l2 / (6 + q2l2)
 
 
-# Required to have Mantid recognise the new function
+# Required to have Mantid recognise the new function.
 FunctionFactory.subscribe(TeixeiraWater)
diff --git a/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h b/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h
index 0e00aa76c28a056831898990119648479609281f..d389030f288b9c4c95bce357b5b9b48af2406d51 100644
--- a/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h
+++ b/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h
@@ -92,7 +92,7 @@ private:
   template <typename CType> void testCreateArrayProperty(PyObject *pyValue) {
     using namespace boost::python;
     using namespace Mantid::Kernel;
-    typedef std::vector<CType> TypeVec;
+    using TypeVec = std::vector<CType>;
     object pyvalue = object(handle<>(pyValue));
     auto valueProp = createAndCheckPropertyTraits<TypeVec>(
         "TestProperty", pyvalue, Direction::Input);
diff --git a/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h b/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h
index 323e6bea1b4f73504d494808698fc03cde3385e8..3e7c5c17fa292393dfb7588e2e50f9c969652b1f 100644
--- a/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h
+++ b/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h
@@ -11,7 +11,7 @@ using namespace Mantid::PythonInterface::Converters;
 
 class PySequenceToVectorTest : public CxxTest::TestSuite {
 private:
-  typedef PySequenceToVector<double> PySequenceToVectorDouble;
+  using PySequenceToVectorDouble = PySequenceToVector<double>;
 
 public:
   void test_construction_succeeds_with_a_valid_sequence_type() {
@@ -37,7 +37,7 @@ public:
   test_that_trying_to_convert_a_list_of_incompatible_types_throws_error_already_set() {
     // Double->int is not generally safe so should not be allowed
     boost::python::list testlist = createHomogeneousPythonList();
-    typedef PySequenceToVector<int> PySequenceToVectorInt;
+    using PySequenceToVectorInt = PySequenceToVector<int>;
     std::vector<int> cvector;
     TS_ASSERT_THROWS(cvector = PySequenceToVectorInt(testlist)(),
                      boost::python::error_already_set);
diff --git a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py
index 88bc8f31c327e8f7db764bd6c26dbf338b513fef..2ac4ea055a8760748e1ae4e2a990bd58bcb86821 100644
--- a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py
@@ -22,6 +22,7 @@ class AlgorithmTest(unittest.TestCase):
         self.assertEquals(1, len(self._load.categories()))
         self.assertEquals('DataHandling', self._load.categories()[0])
         self.assertEquals('', self._load.helpURL())
+        self.assertEquals(["LoadNexus", "LoadRaw", "LoadBBY"], self._load.seeAlso())
 
     def test_get_unknown_property_raises_error(self):
         self.assertRaises(RuntimeError, self._load.getProperty, "NotAProperty")
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/ApplyDetectorScanEffCorrTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/ApplyDetectorScanEffCorrTest.py
index ac25a60f6a4c9eb8703f428df6c51267c3674973..0a13784999a62f419f6f9925c02b0d08f983f77a 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/ApplyDetectorScanEffCorrTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/ApplyDetectorScanEffCorrTest.py
@@ -2,26 +2,25 @@ from __future__ import (absolute_import, division, print_function)
 
 import unittest
 import numpy as np
-from mantid.simpleapi import ApplyDetectorScanEffCorr, CreateWorkspace, CreateSampleWorkspace
+from mantid.simpleapi import ApplyDetectorScanEffCorr, CreateWorkspace, CreateSampleWorkspace, Transpose
 
 
 class ApplyDetectorScanEffCorrTest(unittest.TestCase):
     def test_non_scanning_case(self):
-        input_ws = CreateSampleWorkspace(NumMonitors=1, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1)
+        input_ws = CreateSampleWorkspace(NumMonitors=0, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1)
 
         calibration_x = np.array([0, 0, 0, 0, 0, 0])
         calibration_y = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
 
-        # Note the monitors are in the wrong place doing the test workspace creation like this - but it does not affect the test.
         calibration_ws = CreateWorkspace(DataX=calibration_x, DataY=calibration_y, Nspec=calibration_y.size)
 
         calibrated_ws = ApplyDetectorScanEffCorr(input_ws, calibration_ws)
-        for i in range(1, 7):
-            self.assertEquals(calibrated_ws.readY(i), input_ws.readY(i) * i)
-            self.assertEquals(calibrated_ws.readE(i), input_ws.readE(i) * i)
+        for i in range(6):
+            self.assertEquals(calibrated_ws.readY(i), input_ws.readY(i) * (i+1))
+            self.assertEquals(calibrated_ws.readE(i), input_ws.readE(i) * (i+1))
 
     def test_simple_scanning_case(self):
-        input_ws = CreateSampleWorkspace(NumMonitors=1, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1, NumScanPoints=2)
+        input_ws = CreateSampleWorkspace(NumMonitors=0, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1, NumScanPoints=2)
 
         calibration_x = np.array([0, 0, 0, 0, 0, 0])
         calibration_y = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
@@ -29,13 +28,14 @@ class ApplyDetectorScanEffCorrTest(unittest.TestCase):
         # Note the monitors are in the wrong place doing the test workspace creation like this - but it does not affect the test.
         calibration_ws = CreateWorkspace(DataX=calibration_x, DataY=calibration_y, Nspec=calibration_y.size)
 
+        expected = np.repeat(calibration_y, 2)
         calibrated_ws = ApplyDetectorScanEffCorr(input_ws, calibration_ws)
-        for i in range(2, 14):
-            self.assertEquals(calibrated_ws.readY(i), input_ws.readY(i) * (i//2))
-            self.assertEquals(calibrated_ws.readE(i), input_ws.readE(i) * (i//2))
+        for i in range(12):
+            self.assertEquals(calibrated_ws.readY(i), input_ws.readY(i) * expected[i])
+            self.assertEquals(calibrated_ws.readE(i), input_ws.readE(i) * expected[i])
 
     def test_mismatched_workspace_size(self):
-        input_ws = CreateSampleWorkspace(NumMonitors=1, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1)
+        input_ws = CreateSampleWorkspace(NumMonitors=0, NumBanks=6, BankPixelWidth=1, XMin=0, XMax=1, BinWidth=1)
 
         calibration_x = np.array([0, 0, 0, 0, 0, 0])
         calibration_y = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
@@ -44,5 +44,22 @@ class ApplyDetectorScanEffCorrTest(unittest.TestCase):
         self.assertRaises(ValueError, ApplyDetectorScanEffCorr, InputWorkspace=input_ws,
                           DetectorEfficiencyWorkspace=calibration_ws, OutputWorkspace='')
 
+    def test_2d_scanning_workspace(self):
+        input_ws = CreateSampleWorkspace(NumMonitors=0, NumBanks=3, BankPixelWidth=2, XMin=0, XMax=5, BinWidth=1, NumScanPoints=7)
+
+        calibration_x = np.array([0,1,2,0,1,2,0,1,2,0,1,2])
+        calibration_y = np.arange(12)
+        calibration_ws = CreateWorkspace(DataX=calibration_x, DataY=calibration_y, Nspec=4)
+        calibrated_ws = ApplyDetectorScanEffCorr(input_ws, calibration_ws)
+
+        tmp = Transpose(calibration_ws)
+        tmp = tmp.extractY().flatten()
+        to_multiply = np.repeat(tmp, 5*7)
+        to_multiply = np.reshape(to_multiply, [7*12,5])
+
+        for det in range(7*12):
+            for bin in range(5):
+                self.assertEquals(calibrated_ws.readY(det)[bin], input_ws.readY(det)[bin] * to_multiply[det][bin])
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py
index 8056afe9f1896b09491af8bd870f903ec67b6f45..e4ac2e594b621860babec0ee6eba3544e25793b7 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py
@@ -21,6 +21,18 @@ class MaskAngleTest(unittest.TestCase):
         DeleteWorkspace(w)
         self.assertTrue(array_equal(masklist,arange(10)+10))
 
+    def testMaskAnglePhi(self):
+        w=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False)
+        AnalysisDataService.add('w',w)
+        masklist = MaskAngle(w,0,45,Angle='Phi')
+        detInfo = w.detectorInfo()
+        for i in arange(w.getNumberHistograms()):
+            if i==0:
+                self.assertTrue(detInfo.isMasked(int(i)))
+            else:
+                self.assertFalse(detInfo.isMasked(int(i)))
+        DeleteWorkspace(w)
+
     def testGroupMaskAngle(self):
         ws1=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False)
         AnalysisDataService.add('ws1',ws1)
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py
index a977957f0ff089d5209a5bd2a47c87b74389a1f8..1310c3fa408e1bb2cfb07246ad1362f2d9e4dd69 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py
@@ -54,7 +54,7 @@ class SaveReflectionsTest(unittest.TestCase):
     def _create_indexed_workspace(self, fractional_peaks, ndim, hklm):
         # Create table with the number of columns we need
         types = ['int', 'long64', 'double', 'double', 'double', 'double',  'double', 'double',
-                 'double', 'double', 'double', 'float', 'str', 'float', 'float', 'V3D', 'V3D']
+                 'double', 'double', 'double', 'float', 'str', 'float', 'float', 'V3D', 'V3D', 'int']
         indexed = CreateEmptyTableWorkspace()
         names = fractional_peaks.getColumnNames()
 
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
index 211ba767192a7a7e8d38e4611af7d7b84ccf2736..9b43e770f953ed20e7eaef4600dd635f58969ac8 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py
@@ -1,16 +1,16 @@
 from __future__ import (absolute_import, division, print_function)
 
 import unittest
-from mantid.kernel import *
-from mantid.api import *
-from mantid.simpleapi import *
+from mantid.simpleapi import AlgorithmManager, CreateWorkspace, DeleteWorkspace, SortXAxis
+
 
 class SortXAxisTest(unittest.TestCase):
 
+
     def test_x_ascending(self):
-        dataX = [1, 2, 3] # In ascending order, so y and e will need to be reversed.
-        dataY = [1, 2, 3]
-        dataE = [1, 2, 3]
+        dataX = [1., 2., 3.] # In ascending order, so y and e will need to be reversed.
+        dataY = [1., 2., 3.]
+        dataE = [1., 2., 3.]
         unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True)
         # Run the algorithm
         sortedws = SortXAxis(InputWorkspace=unsortedws)
@@ -24,11 +24,10 @@ class SortXAxisTest(unittest.TestCase):
         DeleteWorkspace(unsortedws)
         DeleteWorkspace(sortedws)
 
-
     def test_x_descending(self):
-        dataX = [3, 2, 1] # In descending order, so y and e will need to be reversed.
-        dataY = [1, 2, 3]
-        dataE = [1, 2, 3]
+        dataX = [3., 2., 1.] # In descending order, so y and e will need to be reversed.
+        dataY = [1., 2., 3.]
+        dataE = [1., 2., 3.]
         unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True)
         # Run the algorithm
         sortedws = SortXAxis(InputWorkspace=unsortedws)
@@ -45,9 +44,9 @@ class SortXAxisTest(unittest.TestCase):
         DeleteWorkspace(sortedws)
 
     def test_on_multiple_spectrum(self):
-        dataX = [3, 2, 1, 3, 2, 1] # In descending order, so y and e will need to be reversed.
-        dataY = [1, 2, 3, 1, 2, 3]
-        dataE = [1, 2, 3, 1, 2, 3]
+        dataX = [3., 2., 1., 3., 2., 1.] # In descending order, so y and e will need to be reversed.
+        dataY = [1., 2., 3., 1., 2., 3.]
+        dataE = [1., 2., 3., 1., 2., 3.]
         unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True, NSpec=2)
         dataY.reverse()
         dataE.reverse()
@@ -70,11 +69,10 @@ class SortXAxisTest(unittest.TestCase):
         DeleteWorkspace(unsortedws)
         DeleteWorkspace(sortedws)
 
-
     def test_sorts_x_histogram_ascending(self):
-        dataX = [1, 2, 3, 4]
-        dataY = [1, 2, 3]
-        dataE = [1, 2, 3]
+        dataX = [1., 2., 3., 4.]
+        dataY = [1., 2., 3.]
+        dataE = [1., 2., 3.]
         unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=False)
         # Run the algorithm
         sortedws = SortXAxis(InputWorkspace=unsortedws)
@@ -90,9 +88,9 @@ class SortXAxisTest(unittest.TestCase):
         DeleteWorkspace(sortedws)
 
     def test_sorts_x_histogram_descending(self):
-        dataX = [4, 3, 2, 1]
-        dataY = [1, 2, 3]
-        dataE = [1, 2, 3]
+        dataX = [4., 3., 2., 1.]
+        dataY = [1., 2., 3.]
+        dataE = [1., 2., 3.]
         unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=False)
         # Run the algorithm
         sortedws = SortXAxis(InputWorkspace=unsortedws)
@@ -113,9 +111,9 @@ class SortXAxisTest(unittest.TestCase):
         # Create unsorted workspace
         parent = AlgorithmManager.createUnmanaged('Load')
         create_ws_alg = parent.createChildAlgorithm("CreateWorkspace")
-        dataX = [4, 3, 2, 1]
-        dataY = [1, 2, 3]
-        dataE = [1, 2, 3]
+        dataX = [4., 3., 2., 1.]
+        dataY = [1., 2., 3.]
+        dataE = [1., 2., 3.]
         create_ws_alg.setProperty("DataX", dataX)
         create_ws_alg.setProperty("DataY", dataY)
         create_ws_alg.setProperty("DataE", dataE)
@@ -137,5 +135,49 @@ class SortXAxisTest(unittest.TestCase):
         self.assertEqual(dataY, sortedY.tolist())
         self.assertEqual(dataE, sortedE.tolist())
 
+    def test_dx_multiple_spectrum(self):
+        dataX = [3, 2, 1, 3, 2, 1]  # In descending order, so y and e will need to be reversed.
+        dataY = [1, 2, 3, 1, 2, 3]
+        dx = [1, 2, 3, 1, 2, 3]
+        unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, Dx=dx, UnitX='TOF', Distribution=True, NSpec=2)
+        dx.reverse()
+        # Run the algorithm
+        sortedws = SortXAxis(InputWorkspace=unsortedws)
+        # Check the resulting data values for 1st spectrum.
+        sortedDx = sortedws.readDx(0)
+        self.assertEqual(dx[0:3], sortedDx.tolist())
+        # Check the resulting data values for 2nd spectrum.
+        sortedDx = sortedws.readDx(1)
+        self.assertEqual(dx[3:], sortedDx.tolist())
+        DeleteWorkspace(unsortedws)
+        DeleteWorkspace(sortedws)
+
+    def test_dx_histogram_ascending(self):
+        dataX = [1., 2., 3., 4.]
+        dataY = [1., 2., 3.]
+        dx = [1., 2., 3.]
+        unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, Dx=dx, UnitX='TOF', Distribution=False)
+        # Run the algorithm
+        sortedws = SortXAxis(InputWorkspace=unsortedws)
+        sortedDx = sortedws.readDx(0)
+        # Check the resulting data values. Sorting operation should have resulted in no changes
+        self.assertEqual(dx, sortedDx.tolist())
+        DeleteWorkspace(unsortedws)
+        DeleteWorkspace(sortedws)
+
+    def test_sort_descending(self):
+        dataX = [1., 2., 3., 4.]
+        dataY = [1., 2., 3.]
+        unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, UnitX='TOF', Distribution=False)
+        # Run the algorithm
+        sortedws = SortXAxis(InputWorkspace=unsortedws, Ordering="Descending")
+        sortedX = sortedws.readX(0)
+        sortedY = sortedws.readY(0)
+        # Check the resulting data values. Sorting operation should have resulted in no changes
+        self.assertEqual([4., 3., 2., 1.], sortedX.tolist())
+        self.assertEqual([3., 2., 1.], sortedY.tolist())
+        DeleteWorkspace(unsortedws)
+        DeleteWorkspace(sortedws)
+
 if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
+    unittest.main()
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt
index 54f3d588a37a84871b164917bb7cdf8230054f9d..ff23470f34524d01eb6f831da8b461ff05f8fe85 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/CMakeLists.txt
@@ -56,6 +56,7 @@ set ( TEST_PY_FILES
   TOSCABankCorrectionTest.py
   TransformToIqtTest.py
   VesuvioDiffractionReductionTest.py
+  WANDPowderReductionTest.py
 )
 check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} )
 
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
index 98aedfce8148d40eed5cab7e4a0b3f68a3f0a4ab..b334ad1437bbefc68c31b17ab6b6fbd4b870e36f 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/DirectILLReductionTest.py
@@ -78,6 +78,22 @@ class DirectILLReductionTest(unittest.TestCase):
         groupIds = groupedWS.getDetector(0).getDetectorIDs()
         self.assertEqual(collections.Counter(detectorIds), collections.Counter(groupIds))
 
+    def testOutputIsDistribution(self):
+        outWSName = 'outWS'
+        algProperties = {
+            'InputWorkspace': self._TEST_WS_NAME,
+            'OutputWorkspace': outWSName,
+            'OutputSofThetaEnergyWorkspace': 'SofThetaE',
+            'rethrow': True
+        }
+        run_algorithm('DirectILLReduction', **algProperties)
+        self.assertTrue(mtd.doesExist(outWSName))
+        ws = mtd[outWSName]
+        self.assertTrue(ws.isDistribution())
+        self.assertTrue(mtd.doesExist('SofThetaE'))
+        ws = mtd['SofThetaE']
+        self.assertTrue(ws.isDistribution())
+
     def _checkAlgorithmsInHistory(self, ws, *args):
         """Return true if algorithm names listed in *args are found in the
         workspace's history.
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSStitchTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSStitchTest.py
index 53c5fc76a66af2e1cae2f1f5fa0c19083df9eff8..423566183dffa449437dc2a5f12129ee0e3171f5 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSStitchTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSStitchTest.py
@@ -198,7 +198,7 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = [1.5] * 9
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)))
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_strip_special_values(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -267,9 +267,8 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = [0.5] * 9
-
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='can gets subtracted so expect 1 - 0.5 as output signal. Proves the can workspace gets used correctly.')
+        
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_scale_both_without_can(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -315,9 +314,8 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = lab_workspace.readY(0) # We scale and shift to the back (lab) detectors
-
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='All data should be scaled and shifted to the LAB scale=1 shift=-5')
+        
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_scale_both_without_can_with_q_fit_range(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -369,9 +367,8 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = [7497.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 7502, 10.0]  # We scale and shift to the back (lab) detectors
-
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='All data should be scaled and shifted to the LAB scale=1 shift=-5')
+        
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_shift_only_without_can(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -414,9 +411,7 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = lab_workspace.readY(0) # We scale and shift to the back (lab) detectors
-
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='All data should be scaled and shifted to the LAB scale=1 shift=-5')
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_scale_only_without_can(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -460,8 +455,7 @@ class SANSStitchTest(unittest.TestCase):
 
         expected_y_array = lab_workspace.readY(0) # We scale and shift to the back (lab) detectors
 
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='All data should be scaled and shifted to the LAB scale=1 shift=-5')
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_scale_none_with_can_and_q_merge_range_equal(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -508,9 +502,8 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = [0.5] * 5 + [1.5] * 4
-
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='can gets subtracted so expect 1 - 0.5 as output signal. Proves the can workspace gets used correctly.')
+        
+        np.testing.assert_equal(y_array, expected_y_array)
 
     def test_scale_none_with_can_and_q_merge_range(self):
         create_alg = AlgorithmManager.create('CreateWorkspace')
@@ -557,9 +550,158 @@ class SANSStitchTest(unittest.TestCase):
         y_array = out_ws.readY(0)
 
         expected_y_array = [0.5] * 2 + [1.0] * 5 + [1.5] * 2
+                
+        np.testing.assert_equal(y_array, expected_y_array)
+
+    def test_that_merge_range_greater_than_overlap_bounds_set_to_upper_bound(self):
+        # This tests that if a merge_max or merge_min is specified greater than the overlap region of
+        # the HAB and LAB the relevant value is set to the maximum value.
+        create_alg = AlgorithmManager.create('CreateWorkspace')
+        create_alg.setChild(True)
+        create_alg.initialize()
+        create_alg.setProperty('DataX', range(0, 10))
+        create_alg.setProperty('DataY', [1] * 9)
+        create_alg.setProperty('NSpec', 1)
+        create_alg.setProperty('UnitX', 'MomentumTransfer')
+        create_alg.setPropertyValue('OutputWorkspace', 'out_ws')
+        create_alg.execute()
+        single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+        create_alg.setProperty('DataY', [2] * 9)
+        create_alg.execute()
+        single_spectra_input_HAB = create_alg.getProperty('OutputWorkspace').value
+        create_alg.setProperty('DataY', [0.5] * 9)
+        create_alg.execute()
+        smaller_single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+
+        alg = AlgorithmManager.create('SANSStitch')
+        alg.setChild(True)
+        alg.initialize()
+        alg.setProperty('Mode', 'None')
+        alg.setProperty('HABCountsSample', single_spectra_input_HAB)
+        alg.setProperty('LABCountsSample', single_spectra_input)
+        alg.setProperty('HABNormSample', single_spectra_input)
+        alg.setProperty('LABNormSample', single_spectra_input)
+        alg.setProperty('ProcessCan', True)
+        alg.setProperty('HABCountsCan', smaller_single_spectra_input)
+        alg.setProperty('LABCountsCan', smaller_single_spectra_input)
+        alg.setProperty('HABNormCan', single_spectra_input)
+        alg.setProperty('LABNormCan', single_spectra_input)
+        alg.setProperty('OutputWorkspace', 'dummy_name')
+        alg.setProperty('ShiftFactor', 0.0)
+        alg.setProperty('ScaleFactor', 1.0)
+        alg.setProperty('MergeMask', True)
+        alg.setProperty('MergeMin', 50)
+        alg.setProperty('MergeMax', 50)
+        alg.execute()
+        out_ws = alg.getProperty('OutputWorkspace').value
+
+        self.assertTrue(isinstance(out_ws, MatrixWorkspace))
+
+        y_array = out_ws.readY(0)
+
+        expected_y_array = [0.5] * 9
+        np.testing.assert_equal(y_array, expected_y_array)
+
+    def test_that_merge_range_less_than_overlap_bounds_set_to_lower_bound(self):
+        # This tests that if a merge_max or merge_min is specified greater than the overlap region of
+        # the HAB and LAB the relevant value is set to the maximum value.
+        create_alg = AlgorithmManager.create('CreateWorkspace')
+        create_alg.setChild(True)
+        create_alg.initialize()
+        create_alg.setProperty('DataX', range(0, 10))
+        create_alg.setProperty('DataY', [1] * 9)
+        create_alg.setProperty('NSpec', 1)
+        create_alg.setProperty('UnitX', 'MomentumTransfer')
+        create_alg.setPropertyValue('OutputWorkspace', 'out_ws')
+        create_alg.execute()
+        single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+        create_alg.setProperty('DataY', [2] * 9)
+        create_alg.execute()
+        single_spectra_input_HAB = create_alg.getProperty('OutputWorkspace').value
+        create_alg.setProperty('DataY', [0.5] * 9)
+        create_alg.execute()
+        smaller_single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+
+        alg = AlgorithmManager.create('SANSStitch')
+        alg.setChild(True)
+        alg.initialize()
+        alg.setProperty('Mode', 'None')
+        alg.setProperty('HABCountsSample', single_spectra_input_HAB)
+        alg.setProperty('LABCountsSample', single_spectra_input)
+        alg.setProperty('HABNormSample', single_spectra_input)
+        alg.setProperty('LABNormSample', single_spectra_input)
+        alg.setProperty('ProcessCan', True)
+        alg.setProperty('HABCountsCan', smaller_single_spectra_input)
+        alg.setProperty('LABCountsCan', smaller_single_spectra_input)
+        alg.setProperty('HABNormCan', single_spectra_input)
+        alg.setProperty('LABNormCan', single_spectra_input)
+        alg.setProperty('OutputWorkspace', 'dummy_name')
+        alg.setProperty('ShiftFactor', 0.0)
+        alg.setProperty('ScaleFactor', 1.0)
+        alg.setProperty('MergeMask', True)
+        alg.setProperty('MergeMin', 0)
+        alg.setProperty('MergeMax', 0)
+        alg.execute()
+        out_ws = alg.getProperty('OutputWorkspace').value
+
+        self.assertTrue(isinstance(out_ws, MatrixWorkspace))
+
+        y_array = out_ws.readY(0)
 
-        self.assertTrue(all(map(lambda element: element in y_array, expected_y_array)),
-                        msg='can gets subtracted so expect 1 - 0.5 as output signal. Proves the can workspace gets used correctly.')
+        expected_y_array = [1.0] + [1.5] * 8
+        
+        np.testing.assert_equal(y_array, expected_y_array)
+
+    def test_that_zero_merge_range_has_discrete_transition(self):
+            # This tests that if a merge_max or merge_min is specified greater than the overlap region of
+            # the HAB and LAB the relevant value is set to the maximum value.
+            create_alg = AlgorithmManager.create('CreateWorkspace')
+            create_alg.setChild(True)
+            create_alg.initialize()
+            create_alg.setProperty('DataX', range(0, 10))
+            create_alg.setProperty('DataY', [1] * 9)
+            create_alg.setProperty('NSpec', 1)
+            create_alg.setProperty('UnitX', 'MomentumTransfer')
+            create_alg.setPropertyValue('OutputWorkspace', 'out_ws')
+            create_alg.execute()
+            single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+            create_alg.setProperty('DataY', [2] * 9)
+            create_alg.execute()
+            single_spectra_input_HAB = create_alg.getProperty('OutputWorkspace').value
+            create_alg.setProperty('DataY', [0.5] * 9)
+            create_alg.execute()
+            smaller_single_spectra_input = create_alg.getProperty('OutputWorkspace').value
+
+            alg = AlgorithmManager.create('SANSStitch')
+            alg.setChild(True)
+            alg.initialize()
+            alg.setProperty('Mode', 'None')
+            alg.setProperty('HABCountsSample', single_spectra_input_HAB)
+            alg.setProperty('LABCountsSample', single_spectra_input)
+            alg.setProperty('HABNormSample', single_spectra_input)
+            alg.setProperty('LABNormSample', single_spectra_input)
+            alg.setProperty('ProcessCan', True)
+            alg.setProperty('HABCountsCan', smaller_single_spectra_input)
+            alg.setProperty('LABCountsCan', smaller_single_spectra_input)
+            alg.setProperty('HABNormCan', single_spectra_input)
+            alg.setProperty('LABNormCan', single_spectra_input)
+            alg.setProperty('OutputWorkspace', 'dummy_name')
+            alg.setProperty('ShiftFactor', 0.0)
+            alg.setProperty('ScaleFactor', 1.0)
+            alg.setProperty('MergeMask', True)
+            alg.setProperty('MergeMin', 5)
+            alg.setProperty('MergeMax', 5)
+            alg.execute()
+            out_ws = alg.getProperty('OutputWorkspace').value
+
+            self.assertTrue(isinstance(out_ws, MatrixWorkspace))
+
+            y_array = out_ws.readY(0)
+
+            expected_y_array = [0.5] * 5 + [1.5] * 4
+            
+            np.testing.assert_equal(y_array, expected_y_array)
+   
 
     def test_that_can_merge_2D_reduction_when_fitting_set_to_none(self):
         # create an input workspace that has multiple spectra
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/WANDPowderReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/WANDPowderReductionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..210875a1a607575358300b9b231f0fcc2c862848
--- /dev/null
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/WANDPowderReductionTest.py
@@ -0,0 +1,135 @@
+from __future__ import absolute_import, division, print_function
+from mantid.simpleapi import (WANDPowderReduction,
+                              CreateSampleWorkspace, RotateInstrumentComponent,
+                              MoveInstrumentComponent, CloneWorkspace, AddSampleLog)
+from mantid.kernel import V3D
+import unittest
+import numpy as np
+
+
+class WANDPowderReductionTest(unittest.TestCase):
+
+    def _create_workspaces(self):
+        cal=CreateSampleWorkspace(NumBanks=1,BinWidth=20000,PixelSpacing=0.1,BankPixelWidth=100)
+        RotateInstrumentComponent(cal, ComponentName='bank1', X=1, Y=0.5, Z=2, Angle=35)
+        MoveInstrumentComponent(cal, ComponentName='bank1', X=1, Y=1, Z=5)
+        bkg=CloneWorkspace(cal)
+        data=CloneWorkspace(cal)
+        AddSampleLog(cal, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText='200')
+        AddSampleLog(bkg, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText='50')
+        AddSampleLog(data, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText='100')
+        AddSampleLog(cal, LogName="duration", LogType='Number', NumberType='Double', LogText='20')
+        AddSampleLog(bkg, LogName="duration", LogType='Number', NumberType='Double', LogText='5')
+        AddSampleLog(data, LogName="duration", LogType='Number', NumberType='Double', LogText='10')
+
+        def get_cal_counts(n):
+            if n < 5000:
+                return 0.9
+            else:
+                return 1.0
+
+        def get_bkg_counts(n):
+            return 1.5*get_cal_counts(n)
+
+        def get_data_counts(n,twoTheta):
+            tt1=30
+            tt2=45
+            return get_bkg_counts(n)+10*np.exp(-(twoTheta-tt1)**2/1)+20*np.exp(-(twoTheta-tt2)**2/0.2)
+
+        for i in range(cal.getNumberHistograms()):
+            cal.setY(i, [get_cal_counts(i)*2.0])
+            bkg.setY(i, [get_bkg_counts(i)/2.0])
+            twoTheta=data.getInstrument().getDetector(i+10000).getTwoTheta(V3D(0,0,0),V3D(0,0,1))*180/np.pi
+            data.setY(i, [get_data_counts(i,twoTheta)])
+
+        return data, cal, bkg
+
+    def test(self):
+        data, cal, bkg = self._create_workspaces()
+
+        # data normalised by monitor
+        pd_out=WANDPowderReduction(InputWorkspace=data,
+                                   Target='Theta',
+                                   NumberBins=1000)
+
+        x = pd_out.extractX()
+        y = pd_out.extractY()
+
+        self.assertAlmostEqual(x.min(),  8.07086781)
+        self.assertAlmostEqual(x.max(), 50.82973519)
+        self.assertAlmostEqual(y.min(),  0.00328244)
+        self.assertAlmostEqual(y.max(),  4.88908824)
+        self.assertAlmostEqual(x[0,y.argmax()], 45.094311535)
+
+        # data and calibration, limited range
+        pd_out2=WANDPowderReduction(InputWorkspace=data,
+                                    CalibrationWorkspace=cal,
+                                    Target='Theta',
+                                    NumberBins=2000,
+                                    XMin=10,
+                                    XMax=40)
+
+        x = pd_out2.extractX()
+        y = pd_out2.extractY()
+
+        self.assertAlmostEqual(x.min(), 10.0075)
+        self.assertAlmostEqual(x.max(), 39.9925)
+        self.assertAlmostEqual(y.min(),  1.5)
+        self.assertAlmostEqual(y.max(), 12.6107234)
+        self.assertAlmostEqual(x[0,y.argmax()], 30.0025)
+
+        # data, cal and background, normalised by time
+        pd_out3=WANDPowderReduction(InputWorkspace=data,
+                                    CalibrationWorkspace=cal,
+                                    BackgroundWorkspace=bkg,
+                                    Target='Theta',
+                                    NumberBins=1000,
+                                    NormaliseBy='Time')
+
+        x = pd_out3.extractX()
+        y = pd_out3.extractY()
+
+        self.assertAlmostEqual(x.min(), 8.07086781)
+        self.assertAlmostEqual(x.max(), 50.82973519)
+        self.assertAlmostEqual(y.min(),  0)
+        self.assertAlmostEqual(y.max(), 19.97968357)
+        self.assertAlmostEqual(x[0,y.argmax()], 45.008708196)
+
+        # data, cal and background. To d spacing
+        pd_out4=WANDPowderReduction(InputWorkspace=data,
+                                    CalibrationWorkspace=cal,
+                                    BackgroundWorkspace=bkg,
+                                    Target='ElasticDSpacing',
+                                    EFixed=30,
+                                    NumberBins=1000)
+
+        x = pd_out4.extractX()
+        y = pd_out4.extractY()
+
+        self.assertAlmostEqual(x.min(), 1.92800159)
+        self.assertAlmostEqual(x.max(), 11.7586705)
+        self.assertAlmostEqual(y.min(),  0)
+        self.assertAlmostEqual(y.max(), 19.03642005)
+        self.assertAlmostEqual(x[0,y.argmax()], 2.1543333)
+
+        # data, cal and background with mask angle, to Q.
+        pd_out4=WANDPowderReduction(InputWorkspace=data,
+                                    CalibrationWorkspace=cal,
+                                    BackgroundWorkspace=bkg,
+                                    Target='ElasticQ',
+                                    EFixed=30,
+                                    NumberBins=2000,
+                                    MaskAngle=60)
+
+        x = pd_out4.extractX()
+        y = pd_out4.extractY()
+
+        self.assertAlmostEqual(x.min(), 0.53479223)
+        self.assertAlmostEqual(x.max(), 3.21684994)
+        self.assertAlmostEqual(y.min(),  0)
+        self.assertAlmostEqual(y.max(), 19.9948756)
+        self.assertAlmostEqual(x[0,y.argmax()], 2.9122841)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSConvertToQTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSConvertToQTest.py
index 4aa9101962a359dcf6c9923a6b02defc5ee64384..8e82ac329302f4134dd45c130ffed239ed16bb8e 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSConvertToQTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSConvertToQTest.py
@@ -4,10 +4,11 @@ import mantid
 
 from sans.common.general_functions import (create_unmanaged_algorithm)
 from sans.common.constants import EMPTY_NAME
-from sans.common.enums import (SANSFacility, SampleShape, ReductionDimensionality, RangeStepType)
+from sans.common.enums import (SANSFacility, SampleShape, ReductionDimensionality, RangeStepType, SANSInstrument)
 from sans.test_helper.test_director import TestDirector
 from sans.state.convert_to_q import get_convert_to_q_builder
 from sans.state.data import get_data_builder
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 class SANSConvertToQTest(unittest.TestCase):
@@ -35,7 +36,8 @@ class SANSConvertToQTest(unittest.TestCase):
                           use_gravity=False, dim=ReductionDimensionality.OneDim):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_state = data_builder.build()
 
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSScaleTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSScaleTest.py
index e2faa22f796ce63ec8861184dfdb8e090cf0d26f..a671f78df7c6ef951c3c094186e5d272a85f16be 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSScaleTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/sans/SANSScaleTest.py
@@ -5,10 +5,11 @@ import math
 
 from sans.common.general_functions import (create_unmanaged_algorithm)
 from sans.common.constants import EMPTY_NAME
-from sans.common.enums import (SANSFacility, SampleShape)
+from sans.common.enums import (SANSFacility, SampleShape, SANSInstrument)
 from sans.test_helper.test_director import TestDirector
 from sans.state.scale import get_scale_builder
 from sans.state.data import get_data_builder
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 class SANSScaleTest(unittest.TestCase):
@@ -28,11 +29,12 @@ class SANSScaleTest(unittest.TestCase):
     def _get_sample_state(width, height, thickness, shape, scale):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_state = data_builder.build()
 
-        scale_builder = get_scale_builder(data_state)
+        scale_builder = get_scale_builder(data_state, file_information)
         scale_builder.set_scale(scale)
         scale_builder.set_thickness(thickness)
         scale_builder.set_width(width)
diff --git a/Framework/PythonInterface/test/python/plugins/functions/CMakeLists.txt b/Framework/PythonInterface/test/python/plugins/functions/CMakeLists.txt
index f5d4e282347902c1382380703952e710a8e873a2..26b9ae51da26112cb65eba81d5fe04d6e6079a73 100644
--- a/Framework/PythonInterface/test/python/plugins/functions/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/plugins/functions/CMakeLists.txt
@@ -14,6 +14,7 @@ set ( TEST_PY_FILES
   MsdGaussTest.py
   MsdPetersTest.py
   MsdYiTest.py
+  TeixeiraWaterTest.py
 )
 
 check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} )
diff --git a/Framework/PythonInterface/test/python/plugins/functions/TeixeiraWaterTest.py b/Framework/PythonInterface/test/python/plugins/functions/TeixeiraWaterTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..135f8deb54864f84c4331ee303867e2c97ab9465
--- /dev/null
+++ b/Framework/PythonInterface/test/python/plugins/functions/TeixeiraWaterTest.py
@@ -0,0 +1,34 @@
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+import numpy as np
+
+from MsdTestHelper import (is_registered, check_output, do_a_fit)
+
+
+class TeixeiraWaterTest(unittest.TestCase):
+
+    def test_function_has_been_registered(self):
+        status, msg = is_registered("TeixeiraWater")
+        if not status:
+            self.fail(msg)
+
+    def test_function_output(self):
+        input = [0.01, 0.1, 1.0, 10.0]
+        expected = [2.46820217e-05, 2.45907320e-03,
+                    1.79512344e-01, 6.41115514e-01]
+        tolerance = 1.0e-05
+        status, output = check_output("TeixeiraWater", input, expected,
+                                      tolerance, Tau=1.0, L=1.5)
+        if not status:
+            msg = 'Computed output {} from input {} unequal to expected: {}'
+            self.fail(msg.format(*[str(a) for a in (output, input, expected)]))
+
+    def test_do_fit(self):
+        do_a_fit(np.arange(0.1, 2.2, 0.2), 'TeixeiraWater',
+                 guess=dict(Tau=2.0, L=1.0),
+                 target=dict(Tau=1.0, L=3.5), atol=0.01)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
index 4fa0facbe277b4cc6082749a108b25fe239e1208..61e734beea9be664a4eb9a9c21c7889a1b7a578b 100644
--- a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
+++ b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
@@ -54,10 +54,8 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) {
   //===================================
 
   // Function pointers to disambiguate the calls
-  typedef Workspace2D_sptr (*Signature1_2D)(
-      int nHist, int nBins, bool includeMonitors, bool startYNegative);
-  typedef Workspace2D_sptr (*Signature2_2D)(int numBanks, int numPixels,
-                                            int numBins);
+  using Signature1_2D = Workspace2D_sptr (*)(int, int, bool, bool);
+  using Signature2_2D = Workspace2D_sptr (*)(int, int, int);
 
   def("create2DWorkspaceWithFullInstrument",
       reinterpret_cast<Signature1_2D>(&create2DWorkspaceWithFullInstrument),
@@ -90,9 +88,8 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) {
   //===================================
 
   // Typedef for function pointer to disabiguate references
-  typedef MDHistoWorkspace_sptr (*Signature1_MDHisto)(
-      double, size_t, size_t, Mantid::coord_t max, double, std::string name,
-      double);
+  using Signature1_MDHisto = MDHistoWorkspace_sptr (
+      *)(double, size_t, size_t, Mantid::coord_t, double, std::string, double);
 
   def("makeFakeMDHistoWorkspace", (Signature1_MDHisto)&makeFakeMDHistoWorkspace,
       makeFakeMDHistoWorkspace_overloads()
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h
index 3c97fb97f1657fc1bb11b24e03332303029f57bd..e5775dd1d833054d2594e1bdcceffa87b8d4ef1b 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h
@@ -23,8 +23,8 @@
 #include "MantidKernel/System.h"
 
 class JSONValue;
-typedef std::map<std::string, JSONValue> JSONObject;
-typedef std::vector<JSONValue> JSONArray;
+using JSONObject = std::map<std::string, JSONValue>;
+using JSONArray = std::vector<JSONValue>;
 // Note: according to the JSON spec, an array is a type of value.
 // That isn't strictly true in the C++ sense here (ie: JSONArray
 // doesn't inherit from JSONValue), but I think we'll be all right.
diff --git a/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h
index 747c3af568cdf959829aad73fda1ce418c0eecbb..56c48dc08ff1c944c96ab380958580ebb881d5a6 100644
--- a/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h
+++ b/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h
@@ -98,9 +98,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       AbortRemoteJob2 ab;
diff --git a/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h b/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h
index 3bf0389ec81c4b960e18014b834b9147fc187502..5583ee32899f8f8fbe4efe3aa66be25cf41551e3 100644
--- a/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h
+++ b/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h
@@ -96,9 +96,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       AbortRemoteJob ab;
diff --git a/Framework/RemoteAlgorithms/test/Authenticate2Test.h b/Framework/RemoteAlgorithms/test/Authenticate2Test.h
index 8e048de0530b7128e700f292b66230e8c8b12161..3dfb66430a7fce1d0b1849ac5c770dcb839f3c9a 100644
--- a/Framework/RemoteAlgorithms/test/Authenticate2Test.h
+++ b/Framework/RemoteAlgorithms/test/Authenticate2Test.h
@@ -99,9 +99,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       Authenticate2 auth;
diff --git a/Framework/RemoteAlgorithms/test/AuthenticateTest.h b/Framework/RemoteAlgorithms/test/AuthenticateTest.h
index 1014fded63acc6b58605433f2d4ee74496a66c95..f8a074242f205f8ce09c098838000745fbcfe89a 100644
--- a/Framework/RemoteAlgorithms/test/AuthenticateTest.h
+++ b/Framework/RemoteAlgorithms/test/AuthenticateTest.h
@@ -99,9 +99,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       Authenticate auth;
diff --git a/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h
index 41ded2ee0ca38e998febb347d633fb0b0f24604b..9d5dc8c434648c3fd88f6bfb5e014fe6f3ec6ba9 100644
--- a/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h
+++ b/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h
@@ -104,9 +104,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       DownloadRemoteFile2 dl;
diff --git a/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h b/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h
index 4b18bde6ea718f0dcb6d5252a20fc502200487f5..7ecc3244762fe770139e72cec2ab2480527fdd3d 100644
--- a/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h
+++ b/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h
@@ -104,9 +104,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       DownloadRemoteFile dl;
diff --git a/Framework/RemoteAlgorithms/test/Logout2Test.h b/Framework/RemoteAlgorithms/test/Logout2Test.h
index 1b337710d588889ac46546689abd10f05d294314..fc271f6d8ac4913e3a8e47cefbe5159270382d0f 100644
--- a/Framework/RemoteAlgorithms/test/Logout2Test.h
+++ b/Framework/RemoteAlgorithms/test/Logout2Test.h
@@ -72,9 +72,9 @@ public:
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
     // test that job managers are created correctly for different facilities
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       Logout2 lo;
diff --git a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h
index b845d38a2138e95835e521b9d8d43aa1f022f1cf..6ec451c56581c8770b17b03554ee0148576f0832 100644
--- a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h
+++ b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h
@@ -81,9 +81,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const auto facName = testFacility.first;
+      const auto compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryAllRemoteJobs2 qar;
diff --git a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h
index 1d00df8c2c2304a6db57f444661bb43fd10a9c44..da759801f3c9dc1e7defd69c7b643df203f7b7b4 100644
--- a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h
+++ b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h
@@ -81,9 +81,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryAllRemoteJobs qar;
diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h
index 691e371466fea193570a41b4e39972e4c9f38484..3d02988843a9902d9fbf23b3bf8f8ff49cb14dcd 100644
--- a/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h
+++ b/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h
@@ -91,9 +91,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryRemoteFile2 qrf;
diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h b/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h
index 46d71b39742d59c22240ed812dbfd82540854e4d..04427da07913f098b849e41bd1a7e3b8ff116690 100644
--- a/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h
+++ b/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h
@@ -91,9 +91,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryRemoteFile qrf;
diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h
index d8863c6d5d8185b610b615d32f08c4c9b9efc3cb..bd7403c56412350f1fe202b5e21305b6e8a5ed00 100644
--- a/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h
+++ b/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h
@@ -90,9 +90,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryRemoteJob2 qr;
diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h b/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h
index c5d2ea8d43027208ff0e373ef6299b4b83c75cdb..97cd9d135e08eb93b6a68dfe21d9764db1110f68 100644
--- a/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h
+++ b/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h
@@ -88,9 +88,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       QueryRemoteJob qr;
diff --git a/Framework/RemoteAlgorithms/test/SimpleJSONTest.h b/Framework/RemoteAlgorithms/test/SimpleJSONTest.h
index dc3b312fad0a7f977df32627b08c30e4e5dc81cd..749a4f3d640aad5060760baebed28859325d5eb8 100644
--- a/Framework/RemoteAlgorithms/test/SimpleJSONTest.h
+++ b/Framework/RemoteAlgorithms/test/SimpleJSONTest.h
@@ -143,7 +143,7 @@ public:
   void test_JSONObjectExampleServerResponseLonger() {
 
     const std::string longerJsonStr =
-        "{\"v1\": \"[1, a, 3]\",\"" + errName + "\":\"" + errVal + "\"}";
+        R"({"v1": "[1, a, 3]",")" + errName + "\":\"" + errVal + "\"}";
     std::istringstream inputLong(longerJsonStr);
     std::string res;
 
@@ -156,7 +156,7 @@ public:
     TS_ASSERT_EQUALS(true, ol[errName].getValue(res));
     TS_ASSERT_EQUALS(res, errVal);
 
-    const std::string l2JsonStr = "{\"v1\": \"[1, a, 3]\",\"" + errName +
+    const std::string l2JsonStr = R"({"v1": "[1, a, 3]",")" + errName +
                                   "\":\"" + errVal + "\", \"" + versName +
                                   "\": \"" + versVal + "\" }"
                                                        "\"}";
@@ -173,7 +173,7 @@ public:
     TS_ASSERT_EQUALS(res, versVal);
 
     const std::string l3JsonStr = "{ \"" + impName + "\": \"" + impVal +
-                                  "\", \"v1\": \"[1, a, longer str, a4]\",\"" +
+                                  R"(", "v1": "[1, a, longer str, a4]",")" +
                                   errName + "\":\"" + errVal + "\", \"" +
                                   versName + "\": \"" + versVal + "\" }"
                                                                   "\"}";
@@ -201,7 +201,7 @@ public:
     TS_ASSERT_THROWS(initFromStream(jo, istr), JSONParseException);
     TS_ASSERT_THROWS_NOTHING(prettyPrint(jo, out, 0));
 
-    std::string strOK = "{ \"key1\": \"val1\"}";
+    std::string strOK = R"({ "key1": "val1"})";
     std::istringstream istrOK(strOK);
     JSONObject j2;
     TS_ASSERT_THROWS_NOTHING(initFromStream(j2, istrOK));
diff --git a/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h b/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h
index ffadba3eac9497b368bed243e23af70fe6fd1470..f6c86ce31953bffdd1728b190f8632c70fb9b699 100644
--- a/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h
+++ b/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h
@@ -91,9 +91,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       StartRemoteTransaction2 start;
diff --git a/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h b/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h
index 27a2dfa80f567b454b32be0bb9a2c124f14c7586..006b409dfc69eac3637480befba8760e2d1935b8 100644
--- a/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h
+++ b/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h
@@ -91,9 +91,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       StartRemoteTransaction start;
diff --git a/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h b/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h
index 9153fe74d25590f2cd5ea36a57fdd483e379364a..1c3cf78170dea502db28def9f2448060f03ce680 100644
--- a/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h
+++ b/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h
@@ -93,9 +93,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       StopRemoteTransaction2 stop;
diff --git a/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h b/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h
index 75c87b5ddeb152b020bc4c002be2431ededb8b5f..1449876e8363727b357506bf0e68bb2425e4c426 100644
--- a/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h
+++ b/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h
@@ -93,9 +93,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
       StopRemoteTransaction stop;
diff --git a/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h
index 8e1ef644caf37575847e035db1c340c9e53bf87f..edf6b121523379bcc75c4bb8446ec34ca0dafae2 100644
--- a/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h
+++ b/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h
@@ -157,9 +157,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
 
diff --git a/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h b/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h
index 520cb3d0ca86e53f32b3bed0b871ffdac0ba3c2b..cbe9053f8adacb5e5a8dd02aa803bfab73ddaca9 100644
--- a/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h
+++ b/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h
@@ -157,9 +157,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
 
diff --git a/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h
index ebdd6c318fd5564a58715b753bad895f41cc11e3..18a8031f5f8a746cce99dc3ca8f9edc37d841863 100644
--- a/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h
+++ b/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h
@@ -124,9 +124,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
 
diff --git a/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h b/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h
index 2b0f241c2a65d7b6ef7d7925bc8a5726eb0dfdf0..1801ad928e076d38b790737633f711926a4e047f 100644
--- a/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h
+++ b/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h
@@ -124,9 +124,9 @@ public:
 
     const Mantid::Kernel::FacilityInfo &prevFac =
         Mantid::Kernel::ConfigService::Instance().getFacility();
-    for (size_t fi = 0; fi < testFacilities.size(); fi++) {
-      const std::string facName = testFacilities[fi].first;
-      const std::string compName = testFacilities[fi].second;
+    for (auto &testFacility : testFacilities) {
+      const std::string facName = testFacility.first;
+      const std::string compName = testFacility.second;
 
       Mantid::Kernel::ConfigService::Instance().setFacility(facName);
 
diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h
index 72cefdac31cb54024fbba64a9c1839dc6319db50..70e5197ee589c562b6dcfbde01b733d12d3c74d4 100644
--- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h
+++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h
@@ -83,7 +83,7 @@ protected:
   virtual std::string guessJobSubmissionAppName(const std::string &runnablePath,
                                                 const std::string &jobOptions);
 
-  typedef std::map<std::string, std::string> StringToStringMap;
+  using StringToStringMap = std::map<std::string, std::string>;
 
   /// method that deals with the actual HTTP(S) connection (convenient to
   /// mock up all inet messaging)
@@ -114,7 +114,7 @@ protected:
     std::string m_token_str;
   };
 
-  typedef std::pair<std::string, Token> UsernameToken;
+  using UsernameToken = std::pair<std::string, Token>;
 
   // store for username-token pairs
   static std::map<std::string, Token> g_tokenStash;
diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
index 06d9636e3e9d6f006e4de602fa662d69af48f2b5..d01cf35640a20f4ec0d2100b36f8bfa968c457b6 100644
--- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
+++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h
@@ -65,7 +65,7 @@ public:
   // Name/Value pairs for POST data.  Note that the second string might be
   // binary, and might be
   // fairly large.  (If it were a JPG image for example...)
-  typedef std::map<std::string, std::string> PostDataMap;
+  using PostDataMap = std::map<std::string, std::string>;
 
   // Low level HTTP functions - GET, POST, etc...
   // It's up to the various algorithms to know what to do with these functions
diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h
index b7d004d4a556d5a1cccce4205665e7e77fc5f4f4..51ef80c3fb6e025ef8971d8bf0b22361cfd50259 100644
--- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h
+++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h
@@ -21,8 +21,8 @@
 #include <ostream>
 
 class JSONValue;
-typedef std::map<std::string, JSONValue> JSONObject;
-typedef std::vector<JSONValue> JSONArray;
+using JSONObject = std::map<std::string, JSONValue>;
+using JSONArray = std::vector<JSONValue>;
 // Note: according to the JSON spec, an array is a type of value.
 // That isn't strictly true in the C++ sense here (ie: JSONArray
 // doesn't inherit from JSONValue), but I think we'll be all right.
diff --git a/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h b/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h
index ca1f9a7dca3701b33c7fcb486795663546ee69c3..0ac25091d436a8ceab67c47a28b0a397d6d24b55 100644
--- a/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h
+++ b/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h
@@ -54,8 +54,7 @@ class MockMantidAPIStatusNotFoundWithErrMsg
     : public MantidWebServiceAPIJobManager {
 public:
   MockMantidAPIStatusNotFoundWithErrMsg() : MantidWebServiceAPIJobManager() {
-    is.str("{\"foo\": \"err_msg\", \"Err_Msg\"=\"fake error\", \"param\": "
-           "\"1\", }");
+    is.str(R"({"foo": "err_msg", "Err_Msg"="fake error", "param": "1", })");
   }
 
 protected:
diff --git a/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h b/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h
index 1a66516d4862553b424ae4df8997a5e5b108d65d..1fa14856f81fd26cf0e5aeef0baa27d77660c3e6 100644
--- a/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h
+++ b/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h
@@ -44,6 +44,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"TransformMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Transforms";
diff --git a/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h b/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h
index 4efa2af544fbb19a29cf73bfe6f52aa8fdff1d1a..60103f10790e943b1d69f6f3cc42a69485366069 100644
--- a/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h
+++ b/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h
@@ -61,6 +61,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadNexus"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override { return "DataHandling\\Nexus"; }
 
diff --git a/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h b/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h
index 6e0e2bf436196baa7443a909329ffa9200d16188..df1acebf62d6393122c14924bed9d856d8719030 100644
--- a/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h
+++ b/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h
@@ -49,6 +49,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"ConvertMDHistoToMatrixWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Transforms";
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h
index 4344c9b4c3d05159ff4d66eff036ea57184d256d..d4302a395021a624af4292d8a347882fafbdd4b7 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h
@@ -45,6 +45,9 @@ class MANTID_SINQ_DLL PoldiCreatePeaksFromCell : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PoldiCreatePeaksFromFile"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
index f9dc4155e5d1c9ba448bdf111f7c208756a17ffc..e462465b739b7dfd2ca00b491810e81c82c820e6 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
@@ -46,7 +46,7 @@ private:
   double m_width;
 };
 
-typedef boost::shared_ptr<RefinedRange> RefinedRange_sptr;
+using RefinedRange_sptr = boost::shared_ptr<RefinedRange>;
 
 bool MANTID_SINQ_DLL
 operator<(const RefinedRange_sptr &lhs, const RefinedRange_sptr &rhs);
@@ -88,6 +88,9 @@ public:
   }
 
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PoldiFitPeaks2D"};
+  }
   const std::string category() const override;
 
 protected:
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h
index c59149bb3b44f3aa51c5d789bf3c9d9b7ab1a979..f74ce705f7a0a8b64aa270e90686f7404160912b 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h
@@ -56,6 +56,9 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"PoldiFitPeaks1D"};
+  }
   const std::string category() const override;
 
   const std::string summary() const override;
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h
index 92cb4209807804246856e3a675378c7d5c415fbd..d5b0f5f1fc9f35b782509e327d3563084dad603b 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h
@@ -63,7 +63,7 @@ private:
   size_t m_iteration;
 };
 
-typedef boost::shared_ptr<Poldi2DFunction> Poldi2DFunction_sptr;
+using Poldi2DFunction_sptr = boost::shared_ptr<Poldi2DFunction>;
 
 } // namespace SINQ
 } // namespace Mantid
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h
index 56213449295e83197d0461ae9d0deaa399e454b1..be2d9c4873a350c1034f7a4cab44775a880578f0 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h
@@ -60,7 +60,7 @@ protected:
   PoldiAbstractChopper() = default;
 };
 
-typedef boost::shared_ptr<PoldiAbstractChopper> PoldiAbstractChopper_sptr;
+using PoldiAbstractChopper_sptr = boost::shared_ptr<PoldiAbstractChopper>;
 }
 }
 
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h
index f3f0134ca76f099f5518626c5a8ec288f75d1378..fb699ad8839d6dc73a250f649b2f11bf00fe41b4 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h
@@ -66,7 +66,7 @@ protected:
   PoldiAbstractDetector() = default;
 };
 
-typedef boost::shared_ptr<PoldiAbstractDetector> PoldiAbstractDetector_sptr;
+using PoldiAbstractDetector_sptr = boost::shared_ptr<PoldiAbstractDetector>;
 }
 }
 #endif // POLDIABSTRACTDETECTOR_H
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h
index 3e1de9f950516a13cf38119a0de3b76e3a34d0ae..66d3c4b5b42c0dd14eae1ea94f436d439518f377 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h
@@ -45,8 +45,8 @@ public:
                             const std::string &propertyName) const = 0;
 };
 
-typedef boost::shared_ptr<AbstractDoubleValueExtractor>
-    AbstractDoubleValueExtractor_sptr;
+using AbstractDoubleValueExtractor_sptr =
+    boost::shared_ptr<AbstractDoubleValueExtractor>;
 
 class NumberDoubleValueExtractor : public AbstractDoubleValueExtractor {
 public:
@@ -128,7 +128,7 @@ protected:
   static std::map<std::string, AbstractDoubleValueExtractor_sptr> m_extractors;
 };
 
-typedef boost::shared_ptr<PoldiInstrumentAdapter> PoldiInstrumentAdapter_sptr;
+using PoldiInstrumentAdapter_sptr = boost::shared_ptr<PoldiInstrumentAdapter>;
 
 } // namespace Poldi
 } // namespace Mantid
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h
index b8578dda7b6738edd16c3da4432670ee2968533e..eb0672a6c575d8ee67ff563de651d086ce9900a9 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h
@@ -34,7 +34,7 @@ namespace Poldi {
 
 using namespace Geometry;
 
-typedef std::pair<double, double> DoublePair;
+using DoublePair = std::pair<double, double>;
 
 class MockDetector : public PoldiAbstractDetector {
 protected:
@@ -534,7 +534,7 @@ public:
     BraggScatterer_sptr atomSi =
         BraggScattererFactory::Instance().createScatterer(
             "IsotropicAtomBraggScatterer",
-            "{\"Element\":\"Si\",\"Position\":\"0,0,0\",\"U\":\"0.005\"}");
+            R"({"Element":"Si","Position":"0,0,0","U":"0.005"})");
     CompositeBraggScatterer_sptr atoms = CompositeBraggScatterer::create();
     atoms->addScatterer(atomSi);
 
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h
index 850cf66b8b85c0a74925dccf5899577ffd2c2eb7..ae281b626a9b2e4e7ba0f7e3295e605adc4d93e2 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h
@@ -39,7 +39,7 @@ namespace Poldi {
 
 class PoldiPeak;
 
-typedef boost::shared_ptr<PoldiPeak> PoldiPeak_sptr;
+using PoldiPeak_sptr = boost::shared_ptr<PoldiPeak>;
 
 class MANTID_SINQ_DLL PoldiPeak {
 public:
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h
index 16f302e6d9b9a7a2b86ede6031461ec5ee0f1a88..9fae2aeeb67811324b8a49a4c02265fe27ba7c52 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h
@@ -42,7 +42,7 @@ namespace Poldi {
 
 class PoldiPeakCollection;
 
-typedef boost::shared_ptr<PoldiPeakCollection> PoldiPeakCollection_sptr;
+using PoldiPeakCollection_sptr = boost::shared_ptr<PoldiPeakCollection>;
 
 class MANTID_SINQ_DLL PoldiPeakCollection {
 public:
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h
index 4ebd57e8a09dce24c3e9252e9a6d46e3c1af2deb..fd5761a402dba9114172d49f9f2f8b1a77e4ce73 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h
@@ -59,9 +59,9 @@ protected:
   Kernel::Interpolation m_spectrum;
 };
 
-typedef boost::shared_ptr<PoldiSourceSpectrum> PoldiSourceSpectrum_sptr;
-typedef boost::shared_ptr<const PoldiSourceSpectrum>
-    PoldiSourceSpectrum_const_sptr;
+using PoldiSourceSpectrum_sptr = boost::shared_ptr<PoldiSourceSpectrum>;
+using PoldiSourceSpectrum_const_sptr =
+    boost::shared_ptr<const PoldiSourceSpectrum>;
 }
 }
 
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h
index e57e64b294f0e923799632632d601aceaf91b275..c8a1fedf5087251b8e90b5921d4629118f35259f 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h
@@ -97,7 +97,7 @@ struct MANTID_SINQ_DLL Poldi2DHelper {
   int minTOFN;
 };
 
-typedef boost::shared_ptr<Poldi2DHelper> Poldi2DHelper_sptr;
+using Poldi2DHelper_sptr = boost::shared_ptr<Poldi2DHelper>;
 
 class WrapAroundJacobian : public API::Jacobian {
 public:
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h
index 6ca9692d5979a3a1594339733f578fc7f402709c..798d08fb11b2a242eddb0f6857ad83287b06296b 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h
@@ -93,8 +93,8 @@ protected:
   double m_tofFactor;
 };
 
-typedef boost::shared_ptr<const DetectorElementData>
-    DetectorElementData_const_sptr;
+using DetectorElementData_const_sptr =
+    boost::shared_ptr<const DetectorElementData>;
 
 class MANTID_SINQ_DLL PoldiTimeTransformer {
 public:
@@ -128,7 +128,7 @@ protected:
   PoldiSourceSpectrum_const_sptr m_spectrum;
 };
 
-typedef boost::shared_ptr<PoldiTimeTransformer> PoldiTimeTransformer_sptr;
+using PoldiTimeTransformer_sptr = boost::shared_ptr<PoldiTimeTransformer>;
 
 } // namespace Poldi
 } // namespace Mantid
diff --git a/Framework/SINQ/inc/MantidSINQ/ProjectMD.h b/Framework/SINQ/inc/MantidSINQ/ProjectMD.h
index 8fbafa364e7ca8a3c4a6ac6de9214ed2b2826f31..89de58f5554dc26aac719255d189a423e80a6e9a 100644
--- a/Framework/SINQ/inc/MantidSINQ/ProjectMD.h
+++ b/Framework/SINQ/inc/MantidSINQ/ProjectMD.h
@@ -43,6 +43,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"CutMD", "BinMD"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Slicing";
diff --git a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
index 52d9b8611a60b992c547b6fb3254059e52e8d34b..2905071f819c407d921e1a88881a81a5643a182e 100644
--- a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
+++ b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
@@ -52,7 +52,9 @@ public:
   const std::string summary() const override {
     return "SINQ specific MD data reordering";
   }
-
+  const std::vector<std::string> seeAlso() const override {
+    return {"TransposeMD", "Transpose"};
+  }
   /// Algorithm's version
   int version() const override { return (1); }
   /// Algorithm's category for identification
diff --git a/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h b/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h
index 4199b0bf83a9aa9c45837bd853bdb04d1a642384..61f584a5769cee5f099c920bab1a7347421aa7dd 100644
--- a/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h
+++ b/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h
@@ -46,6 +46,9 @@ public:
 
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SliceMD", "IntegrateMDHistoWorkspace"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "MDAlgorithms\\Slicing";
diff --git a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
index e4fd2201eee32641c28a63a02a8a15f51a061978..9fd47f6fd0c2be607cc041f921ecb003aff2f43b 100644
--- a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
+++ b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
@@ -100,8 +100,8 @@ public:
     std::vector<Property *> properties = fitPeaks1D.getProperties();
     std::unordered_set<std::string> names;
 
-    for (size_t i = 0; i < properties.size(); ++i) {
-      names.insert(properties[i]->name());
+    for (auto &property : properties) {
+      names.insert(property->name());
     }
 
     TS_ASSERT_EQUALS(names.count("InputWorkspace"), 1);
diff --git a/Framework/SINQ/test/PoldiFitPeaks1DTest.h b/Framework/SINQ/test/PoldiFitPeaks1DTest.h
index 5fef57ec078c66f53a436b0b1deb7d2812a552b7..e8ff092bb0c1a0535d88eddd36673cabed47ed9c 100644
--- a/Framework/SINQ/test/PoldiFitPeaks1DTest.h
+++ b/Framework/SINQ/test/PoldiFitPeaks1DTest.h
@@ -102,8 +102,8 @@ public:
     std::vector<Property *> properties = fitPeaks1D.getProperties();
     std::unordered_set<std::string> names;
 
-    for (size_t i = 0; i < properties.size(); ++i) {
-      names.insert(properties[i]->name());
+    for (auto &property : properties) {
+      names.insert(property->name());
     }
 
     TS_ASSERT_EQUALS(names.count("InputWorkspace"), 1);
diff --git a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
index b0906c2fa9120d39198de4f436770f27634718fd..302ef9bc8294228df0a9c860c3078b5ae7149a1d 100644
--- a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
+++ b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
@@ -669,9 +669,9 @@ private:
   }
 
   void storeRandomWorkspaces(const std::vector<std::string> &wsNames) {
-    for (auto it = wsNames.begin(); it != wsNames.end(); ++it) {
+    for (const auto &wsName : wsNames) {
       WorkspaceCreationHelper::storeWS(
-          *it, WorkspaceCreationHelper::create1DWorkspaceRand(10, true));
+          wsName, WorkspaceCreationHelper::create1DWorkspaceRand(10, true));
     }
   }
 
@@ -684,8 +684,8 @@ private:
   }
 
   void removeRandomWorkspaces(const std::vector<std::string> &wsNames) {
-    for (auto it = wsNames.begin(); it != wsNames.end(); ++it) {
-      WorkspaceCreationHelper::removeWS(*it);
+    for (const auto &wsName : wsNames) {
+      WorkspaceCreationHelper::removeWS(wsName);
     }
   }
 
diff --git a/Framework/SINQ/test/PoldiInstrumentAdapterTest.h b/Framework/SINQ/test/PoldiInstrumentAdapterTest.h
index aab05fa210ad97fcfc3528731bd058d6ef35a086..46b88a7e51a9970d3825c9e31f806fea6278f8a2 100644
--- a/Framework/SINQ/test/PoldiInstrumentAdapterTest.h
+++ b/Framework/SINQ/test/PoldiInstrumentAdapterTest.h
@@ -195,7 +195,7 @@ public:
     TestablePoldiInstrumentAdapter instrumentAdapter;
 
     // Throw on null-pointer
-    TS_ASSERT_THROWS(instrumentAdapter.getExtractorForProperty(0),
+    TS_ASSERT_THROWS(instrumentAdapter.getExtractorForProperty(nullptr),
                      std::invalid_argument);
     TS_ASSERT_THROWS_NOTHING(instrumentAdapter.getExtractorForProperty(
         m_run.getProperty("chopperspeed_double")));
diff --git a/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Framework/SINQ/test/PoldiPeakCollectionTest.h
index 5f91b3dd074c82498e01c6d166a53d0f2e802f8f..89d64a02f26946d79f46943fe40e4c2893349c45 100644
--- a/Framework/SINQ/test/PoldiPeakCollectionTest.h
+++ b/Framework/SINQ/test/PoldiPeakCollectionTest.h
@@ -390,10 +390,10 @@ private:
 
     BraggScatterer_sptr cs = BraggScattererFactory::Instance().createScatterer(
         "IsotropicAtomBraggScatterer",
-        "{\"Element\":\"Cs\",\"Position\":\"0.5,0.5,0.5\",\"U\":\"0.005\"}");
+        R"({"Element":"Cs","Position":"0.5,0.5,0.5","U":"0.005"})");
     BraggScatterer_sptr cl = BraggScattererFactory::Instance().createScatterer(
         "IsotropicAtomBraggScatterer",
-        "{\"Element\":\"Cl\",\"Position\":\"0,0,0\",\"U\":\"0.005\"}");
+        R"({"Element":"Cl","Position":"0,0,0","U":"0.005"})");
 
     CompositeBraggScatterer_sptr atoms = CompositeBraggScatterer::create();
     atoms->addScatterer(cs);
diff --git a/Framework/SINQ/test/PoldiPeakSearchTest.h b/Framework/SINQ/test/PoldiPeakSearchTest.h
index 6cf85b25ef884598b1f5c60ed4dc6656c536c4fa..b4534d07500df0e93ae8d2996ae5fdf9f91e9da5 100644
--- a/Framework/SINQ/test/PoldiPeakSearchTest.h
+++ b/Framework/SINQ/test/PoldiPeakSearchTest.h
@@ -123,10 +123,9 @@ public:
     std::vector<double> testXData(testYData.size());
 
     double x = 0.0;
-    for (std::vector<double>::iterator iterX = testXData.begin();
-         iterX != testXData.end(); ++iterX) {
+    for (double &iterX : testXData) {
       x += 1.0;
-      *iterX = x;
+      iterX = x;
     }
 
     std::list<std::vector<double>::const_iterator> maxima =
diff --git a/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h b/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
index 4b81bee83471375753259cef513742679b06c1b4..560238d7bfe12a014fa1bfee026910a0cd7e6917 100644
--- a/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
+++ b/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h
@@ -71,7 +71,7 @@ class SCRIPT_DLL_EXPORT ScriptRepositoryImpl : public ScriptRepository {
           auto_update(false), author(""), status(BOTH_UNCHANGED){};
   };
 
-  typedef std::map<std::string, RepositoryEntry> Repository;
+  using Repository = std::map<std::string, RepositoryEntry>;
 
   Repository repo;
 
diff --git a/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h b/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h
index 48098cfef3b48bb063a659262326e7739300c869..d8fe26e372db5718eba173512ecd74a91afe33b7 100644
--- a/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h
+++ b/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h
@@ -363,8 +363,8 @@ public:
     TS_ASSERT_THROWS_NOTHING(list_files = repo->listFiles());
     TS_ASSERT(list_files.size() == 5);
     // check that all the files at the central repository are inside
-    for (int i = 0; i < 5; i++)
-      TSM_ASSERT_THROWS_NOTHING(test_entries[i], repo->info(test_entries[i]));
+    for (auto &test_entry : test_entries)
+      TSM_ASSERT_THROWS_NOTHING(test_entry, repo->info(test_entry));
   }
 
   /**
@@ -478,9 +478,8 @@ public:
     TS_ASSERT_THROWS_NOTHING(list_of_files = repo->listFiles());
 
     std::cout << "After update, the files are: ";
-    for (std::vector<string>::iterator it = list_of_files.begin();
-         it != list_of_files.end(); it++) {
-      std::cout << *it << ", ";
+    for (auto &list_of_file : list_of_files) {
+      std::cout << list_of_file << ", ";
     }
     std::cout << '\n';
     TS_ASSERT(list_of_files.size() == 1);
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h
index 2fe9a1b371f045a1bfe12e3001d0da5a774fd4b5..d3737b45416595937adf2ad63028f7d1a552efbc 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/ComponentCreationHelper.h
@@ -75,6 +75,16 @@ boost::shared_ptr<Mantid::Geometry::CSGObject>
 createCappedCylinder(double radius, double height,
                      const Mantid::Kernel::V3D &baseCentre,
                      const Mantid::Kernel::V3D &axis, const std::string &id);
+
+/// Add a spherical sample at samplePos to given instrument.
+void addSampleToInstrument(Mantid::Geometry::Instrument_sptr &instrument,
+                           const Mantid::Kernel::V3D &samplePos);
+
+/// Add a source with given name and sourcePos to given instrument
+void addSourceToInstrument(Mantid::Geometry::Instrument_sptr &instrument,
+                           const Mantid::Kernel::V3D &sourcePos,
+                           const std::string &name = "moderator");
+
 /**
  * Return the XML for a sphere.
  */
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
index 93b7fab66f124f0b96564db30a313c6768fe378f..b90561823689da025b5094e7896fdae580094042 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
@@ -423,7 +423,7 @@ static void feedMDBox(MDBoxBase<MDLeanEvent<nd>, nd> *box, size_t repeat = 1,
     allDone = Mantid::Kernel::Utils::NestedForLoop::Increment(nd, counters,
                                                               index_max);
   }
-  box->refreshCache(NULL);
+  box->refreshCache(nullptr);
 }
 
 //-------------------------------------------------------------------------------------
@@ -436,7 +436,7 @@ static void feedMDBox(MDBoxBase<MDLeanEvent<nd>, nd> *box, size_t repeat = 1,
 template <size_t nd>
 static void recurseSplit(MDGridBox<MDLeanEvent<nd>, nd> *box,
                          size_t atRecurseLevel, size_t recurseLimit) {
-  typedef std::vector<MDBoxBase<MDLeanEvent<nd>, nd> *> boxVector;
+  using boxVector = std::vector<MDBoxBase<MDLeanEvent<nd>, nd> *>;
   if (atRecurseLevel >= recurseLimit)
     return;
 
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
index b49022e4ae06281ec0d877d17aa5b09efc022b14..b809b285196480bfad27e427ea4cab8e043d3e03 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
@@ -135,10 +135,12 @@ Mantid::DataObjects::Workspace2D_sptr
 create2DWorkspaceWhereYIsWorkspaceIndex(int nhist, int numBoundaries);
 Mantid::DataObjects::Workspace2D_sptr create2DWorkspace123(
     int64_t nHist, int64_t nBins, bool isHist = false,
-    const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>());
+    const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>(),
+    bool hasDx = false);
 Mantid::DataObjects::Workspace2D_sptr create2DWorkspace154(
     int64_t nHist, int64_t nBins, bool isHist = false,
-    const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>());
+    const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>(),
+    bool hasDx = false);
 Mantid::DataObjects::Workspace2D_sptr create2DWorkspaceWithValuesAndXerror(
     int64_t nHist, int64_t nBins, bool isHist, double xVal, double yVal,
     double eVal, double dxVal,
@@ -164,11 +166,12 @@ create2DWorkspaceBinned(int nhist, int numVals, double x0 = 0.0,
  * Filled with Y = 2.0 and E = sqrt(2.0)w
  */
 Mantid::DataObjects::Workspace2D_sptr
-create2DWorkspaceBinned(int nhist, const int numBoundaries,
-                        const double xBoundaries[]);
+create2DWorkspaceNonUniformlyBinned(int nhist, const int numBoundaries,
+                                    const double xBoundaries[],
+                                    bool hasDx = false);
 
-struct returnOne {
-  double operator()(const double, size_t) { return 1; }
+struct ReturnOne {
+  double operator()(const double, std::size_t) { return 1.0; };
 };
 
 /**
@@ -183,11 +186,11 @@ struct returnOne {
  * @param eFunc :: A function to use for the y error values
  * @return The new workspace. The errors are set to 1.0
  */
-template <typename fT, typename gT = returnOne>
+template <typename fT, typename gT = ReturnOne>
 Mantid::DataObjects::Workspace2D_sptr
 create2DWorkspaceFromFunction(fT yFunc, int nSpec, double x0, double x1,
                               double dx, bool isHist = false,
-                              gT eFunc = returnOne()) {
+                              gT eFunc = ReturnOne()) {
   int nX = int((x1 - x0) / dx) + 1;
   int nY = nX - (isHist ? 1 : 0);
   if (nY <= 0)
@@ -228,7 +231,8 @@ void addNoise(Mantid::API::MatrixWorkspace_sptr ws, double noise,
 Mantid::DataObjects::Workspace2D_sptr create2DWorkspaceWithFullInstrument(
     int nhist, int nbins, bool includeMonitors = false,
     bool startYNegative = false, bool isHistogram = true,
-    const std::string &instrumentName = std::string("testInst"));
+    const std::string &instrumentName = std::string("testInst"),
+    bool hasDx = false);
 
 /**
  * Create a workspace as for create2DWorkspaceWithFullInstrument, but including
diff --git a/Framework/TestHelpers/src/ComponentCreationHelper.cpp b/Framework/TestHelpers/src/ComponentCreationHelper.cpp
index 40ba46267c846d6caff6e305e7ab03d6422d0795..61c98fa017e67535757ec2b0d2a2fa61a91cc1db 100644
--- a/Framework/TestHelpers/src/ComponentCreationHelper.cpp
+++ b/Framework/TestHelpers/src/ComponentCreationHelper.cpp
@@ -70,7 +70,7 @@ boost::shared_ptr<CSGObject> createCappedCylinder(double radius, double height,
 }
 
 void addSourceToInstrument(Instrument_sptr &instrument, const V3D &sourcePos,
-                           std::string name = "moderator") {
+                           const std::string &name) {
   ObjComponent *source =
       new ObjComponent(name, IObject_sptr(new CSGObject), instrument.get());
   source->setPos(sourcePos);
diff --git a/Framework/TestHelpers/src/FileComparisonHelper.cpp b/Framework/TestHelpers/src/FileComparisonHelper.cpp
index 95e86c89afdfeabbb311a67536aa12be0a01e93e..9f02a89716f93a68521fcacd312421c6a43d3d0a 100644
--- a/Framework/TestHelpers/src/FileComparisonHelper.cpp
+++ b/Framework/TestHelpers/src/FileComparisonHelper.cpp
@@ -59,7 +59,7 @@ void logDifferenceError(char refChar, char testChar, size_t numNewLines,
   ((outError += "\nTest output:\n") += seenChars) += testChar;
 
   Mantid::Kernel::Logger g_log("FileComparisonHelper");
-  g_log.error(std::move(outError));
+  g_log.error(outError);
 }
 
 } // End of anonymous namespace
diff --git a/Framework/TestHelpers/src/SingleCrystalDiffractionTestHelper.cpp b/Framework/TestHelpers/src/SingleCrystalDiffractionTestHelper.cpp
index 5737b6bc4b5832024260775d6808253c1cd010b0..9b995619a24b9ef40777560f7cc500c57c3a3c90 100644
--- a/Framework/TestHelpers/src/SingleCrystalDiffractionTestHelper.cpp
+++ b/Framework/TestHelpers/src/SingleCrystalDiffractionTestHelper.cpp
@@ -8,6 +8,7 @@
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidKernel/normal_distribution.h"
 #include "MantidKernel/V3D.h"
 #include "MantidTestHelpers/SingleCrystalDiffractionTestHelper.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
@@ -169,9 +170,9 @@ void WorkspaceBuilder::createPeak(const HKLPeakDescriptor &descriptor) {
   const auto tofSigma = std::get<2>(sigmas);
 
   // distributions for beam divergence and TOF broadening
-  std::normal_distribution<> xDist(0, xSigma);
-  std::normal_distribution<> yDist(0, ySigma);
-  std::normal_distribution<> tofDist(tofExact, tofSigma);
+  Kernel::normal_distribution<> xDist(0, xSigma);
+  Kernel::normal_distribution<> yDist(0, ySigma);
+  Kernel::normal_distribution<> tofDist(tofExact, tofSigma);
 
   // add events to the workspace
   for (int i = 0; i < nEvents; ++i) {
diff --git a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
index 4eeb696bb68a4d341934b5b43aa0a4cdd8a1c4ef..f90803a4cd50029c21fc21f821a9b6073e9b8080 100644
--- a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
+++ b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
@@ -30,12 +30,14 @@
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidHistogramData/LinearGenerator.h"
+#include "MantidHistogramData/HistogramDx.h"
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidKernel/MersenneTwister.h"
 #include "MantidKernel/OptionalBool.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/VectorHelper.h"
+#include "MantidKernel/make_cow.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/V3D.h"
 
@@ -195,20 +197,36 @@ Workspace2D_sptr create2DWorkspaceThetaVsTOF(int nHist, int nBins) {
   return outputWS;
 }
 
+/**
+ * @brief create2DWorkspaceWithValues
+ * @param nHist :: Number of spectra
+ * @param nBins :: Number of points (not bin edges!)
+ * @param isHist :: Flag if it is a histogram or point data
+ * @param maskedWorkspaceIndices :: Mask workspace indices
+ * @param xVal :: bin edge or point
+ * @param yVal :: y value
+ * @param eVal :: error values
+ * @param hasDx :: wether workspace has dx values defined (default is false)
+ * @return A workspace filled with nBins bins or points and nHist spectra of the
+ * values yVal and the error eVal as well as Dx values which are copies of the y
+ * values
+ */
 Workspace2D_sptr
 create2DWorkspaceWithValues(int64_t nHist, int64_t nBins, bool isHist,
                             const std::set<int64_t> &maskedWorkspaceIndices,
-                            double xVal, double yVal, double eVal) {
+                            double xVal, double yVal, double eVal,
+                            bool hasDx = false) {
   auto x1 = Kernel::make_cow<HistogramData::HistogramX>(
       isHist ? nBins + 1 : nBins, LinearGenerator(xVal, 1.0));
   Counts y1(nBins, yVal);
   CountStandardDeviations e1(nBins, eVal);
+  auto dx = Kernel::make_cow<HistogramData::HistogramDx>(nBins, yVal);
   auto retVal = boost::make_shared<Workspace2D>();
-  retVal->initialize(nHist, isHist ? nBins + 1 : nBins, nBins);
+  retVal->initialize(nHist, createHisto(isHist, y1, e1));
   for (int i = 0; i < nHist; i++) {
-    retVal->setX(i, x1);
-    retVal->setCounts(i, y1);
-    retVal->setCountStandardDeviations(i, e1);
+    retVal->setSharedX(i, x1);
+    if (hasDx)
+      retVal->setSharedDx(i, dx);
     retVal->getSpectrum(i).setDetectorID(i);
     retVal->getSpectrum(i).setSpectrumNo(i);
   }
@@ -231,16 +249,18 @@ Workspace2D_sptr create2DWorkspaceWithValuesAndXerror(
 
 Workspace2D_sptr
 create2DWorkspace123(int64_t nHist, int64_t nBins, bool isHist,
-                     const std::set<int64_t> &maskedWorkspaceIndices) {
-  return create2DWorkspaceWithValues(nHist, nBins, isHist,
-                                     maskedWorkspaceIndices, 1.0, 2.0, 3.0);
+                     const std::set<int64_t> &maskedWorkspaceIndices,
+                     bool hasDx) {
+  return create2DWorkspaceWithValues(
+      nHist, nBins, isHist, maskedWorkspaceIndices, 1.0, 2.0, 3.0, hasDx);
 }
 
 Workspace2D_sptr
 create2DWorkspace154(int64_t nHist, int64_t nBins, bool isHist,
-                     const std::set<int64_t> &maskedWorkspaceIndices) {
-  return create2DWorkspaceWithValues(nHist, nBins, isHist,
-                                     maskedWorkspaceIndices, 1.0, 5.0, 4.0);
+                     const std::set<int64_t> &maskedWorkspaceIndices,
+                     bool hasDx) {
+  return create2DWorkspaceWithValues(
+      nHist, nBins, isHist, maskedWorkspaceIndices, 1.0, 5.0, 4.0, hasDx);
 }
 
 Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace,
@@ -252,7 +272,7 @@ Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace,
     workspace->setInstrument(instrument);
 
     std::string xmlShape = "<sphere id=\"shape\"> ";
-    xmlShape += "<centre x=\"0.0\"  y=\"0.0\" z=\"0.0\" /> ";
+    xmlShape += R"(<centre x="0.0"  y="0.0" z="0.0" /> )";
     xmlShape += "<radius val=\"0.05\" /> ";
     xmlShape += "</sphere>";
     xmlShape += "<algebra val=\"shape\" /> ";
@@ -303,31 +323,34 @@ Workspace2D_sptr create2DWorkspaceBinned(int nhist, int numVals, double x0,
   Counts y(numVals, 2);
   CountStandardDeviations e(numVals, M_SQRT2);
   auto retVal = boost::make_shared<Workspace2D>();
-  retVal->initialize(nhist, numVals + 1, numVals);
-  for (int i = 0; i < nhist; i++) {
+  retVal->initialize(nhist, createHisto(true, y, e));
+  for (int i = 0; i < nhist; i++)
     retVal->setBinEdges(i, x);
-    retVal->setCounts(i, y);
-    retVal->setCountStandardDeviations(i, e);
-  }
   return retVal;
 }
 
 /** Create a 2D workspace with this many histograms and bins. The bins are
  * assumed to be non-uniform and given by the input array
  * Filled with Y = 2.0 and E = M_SQRT2w
+ * If hasDx is true, all spectra will have dx values, starting from 0.1 and
+ * increased by 0.1 for each bin.
  */
-Workspace2D_sptr create2DWorkspaceBinned(int nhist, const int numBoundaries,
-                                         const double xBoundaries[]) {
+Workspace2D_sptr create2DWorkspaceNonUniformlyBinned(int nhist,
+                                                     const int numBoundaries,
+                                                     const double xBoundaries[],
+                                                     bool hasDx) {
   BinEdges x(xBoundaries, xBoundaries + numBoundaries);
   const int numBins = numBoundaries - 1;
   Counts y(numBins, 2);
   CountStandardDeviations e(numBins, M_SQRT2);
+  auto dx = Kernel::make_cow<HistogramData::HistogramDx>(
+      numBins, LinearGenerator(0.1, .1));
   auto retVal = boost::make_shared<Workspace2D>();
-  retVal->initialize(nhist, numBins + 1, numBins);
+  retVal->initialize(nhist, createHisto(true, y, e));
   for (int i = 0; i < nhist; i++) {
     retVal->setBinEdges(i, x);
-    retVal->setCounts(i, y);
-    retVal->setCountStandardDeviations(i, e);
+    if (hasDx)
+      retVal->setSharedDx(i, dx);
   }
   return retVal;
 }
@@ -360,11 +383,11 @@ void addNoise(Mantid::API::MatrixWorkspace_sptr ws, double noise,
  * from the centre of the
  * previous.
  * Data filled with: Y: 2.0, E: M_SQRT2, X: nbins of width 1 starting at 0
+ * The flag hasDx is responsible for creating dx values or not
  */
-Workspace2D_sptr
-create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors,
-                                    bool startYNegative, bool isHistogram,
-                                    const std::string &instrumentName) {
+Workspace2D_sptr create2DWorkspaceWithFullInstrument(
+    int nhist, int nbins, bool includeMonitors, bool startYNegative,
+    bool isHistogram, const std::string &instrumentName, bool hasDx) {
   if (includeMonitors && nhist < 2) {
     throw std::invalid_argument("Attempting to 2 include monitors for a "
                                 "workspace with fewer than 2 histograms");
@@ -373,9 +396,10 @@ create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors,
   Workspace2D_sptr space;
   if (isHistogram)
     space = create2DWorkspaceBinned(
-        nhist, nbins); // A 1:1 spectra is created by default
+        nhist, nbins, hasDx); // A 1:1 spectra is created by default
   else
-    space = create2DWorkspace123(nhist, nbins, false);
+    space =
+        create2DWorkspace123(nhist, nbins, false, std::set<int64_t>(), hasDx);
   space->setTitle(
       "Test histogram"); // actually adds a property call run_title to the logs
   space->getAxis(0)->setUnit("TOF");
@@ -473,13 +497,12 @@ createEventWorkspaceWithFullInstrument(int numBanks, int numPixels,
   ws->replaceAxis(0, ax0);
 
   // re-assign detector IDs to the rectangular detector
-  int detID = numPixels * numPixels;
-  for (int wi = 0; wi < static_cast<int>(ws->getNumberHistograms()); wi++) {
+  const auto detIds = inst->getDetectorIDs();
+  for (int wi = 0; wi < static_cast<int>(ws->getNumberHistograms()); ++wi) {
     ws->getSpectrum(wi).clearDetectorIDs();
     if (clearEvents)
       ws->getSpectrum(wi).clear(true);
-    ws->getSpectrum(wi).setDetectorID(detID);
-    detID++;
+    ws->getSpectrum(wi).setDetectorID(detIds[wi]);
   }
   return ws;
 }
diff --git a/Framework/Types/src/Core/DateAndTime.cpp b/Framework/Types/src/Core/DateAndTime.cpp
index f421c9b045fbf94df9f6888dac2774d9d3ea4677..c922c025c41c2adfcb8575e889c279a1354b3b0f 100644
--- a/Framework/Types/src/Core/DateAndTime.cpp
+++ b/Framework/Types/src/Core/DateAndTime.cpp
@@ -726,7 +726,7 @@ time_duration DateAndTime::durationFromSeconds(double duration) {
   else if (duration <= std::numeric_limits<int>::min())
     return boost::posix_time::time_duration(boost::posix_time::min_date_time);
 
-  typedef boost::posix_time::time_res_traits::sec_type sec_type;
+  using sec_type = boost::posix_time::time_res_traits::sec_type;
 
 #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
   // Nanosecond resolution
diff --git a/Framework/Types/src/Event/TofEvent.cpp b/Framework/Types/src/Event/TofEvent.cpp
index ce0ee8e761bc2a7153098fc6cf3e392051aea1ee..9e92d192d3a2f2111a6756e05cbb5d2d675de561 100644
--- a/Framework/Types/src/Event/TofEvent.cpp
+++ b/Framework/Types/src/Event/TofEvent.cpp
@@ -4,7 +4,6 @@ using std::ostream;
 
 namespace Mantid {
 namespace Types {
-using Core::DateAndTime;
 namespace Event {
 /** Comparison operator.
  * @param rhs: the other TofEvent to compare.
diff --git a/Framework/Types/test/DateAndTimeTest.h b/Framework/Types/test/DateAndTimeTest.h
index 33f52df1d342e0aa681ac9bf0196a8fb0fa2c15c..91d17bd25ae72467beac1b222a67ee38e94b1f73 100644
--- a/Framework/Types/test/DateAndTimeTest.h
+++ b/Framework/Types/test/DateAndTimeTest.h
@@ -279,7 +279,7 @@ public:
 
   void test_time_t_support() {
     DateAndTime t;
-    std::time_t current = time(NULL);
+    std::time_t current = time(nullptr);
     t.set_from_time_t(current);
     //    if (cur.day() < 28) // Annoying bug at the end of a month
     { TS_ASSERT_EQUALS(current, t.to_time_t()); }
diff --git a/Framework/WorkflowAlgorithms/CMakeLists.txt b/Framework/WorkflowAlgorithms/CMakeLists.txt
index 7bdb72de478154de29dec5ea24968c3423065de9..adbf431c1653738462031a5978e752d5f99ddec3 100644
--- a/Framework/WorkflowAlgorithms/CMakeLists.txt
+++ b/Framework/WorkflowAlgorithms/CMakeLists.txt
@@ -29,7 +29,6 @@ set ( SRC_FILES
 	src/MuonProcess.cpp
 	src/MuonPairAsymmetryCalculator.cpp
 	src/ProcessIndirectFitParameters.cpp
-	src/RefReduction.cpp
 	src/RefRoi.cpp
 	src/SANSBeamFinder.cpp
 	src/SANSBeamFluxCorrection.cpp
@@ -76,7 +75,6 @@ set ( INC_FILES
 	inc/MantidWorkflowAlgorithms/MuonProcess.h
 	inc/MantidWorkflowAlgorithms/MuonPairAsymmetryCalculator.h
 	inc/MantidWorkflowAlgorithms/ProcessIndirectFitParameters.h
-	inc/MantidWorkflowAlgorithms/RefReduction.h
 	inc/MantidWorkflowAlgorithms/RefRoi.h
 	inc/MantidWorkflowAlgorithms/SANSBeamFinder.h
 	inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h
index a5c16c6eb349f0b6b1eb89f28292c4e36866a639..241a2131006c100c080182fb861c0b56b29a91a9 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h
@@ -65,6 +65,9 @@ public:
 
   /// Algorithm's version for identification overriding a virtual method
   int version() const override { return 1; }
+  const std::vector<std::string> seeAlso() const override {
+    return {"AlignAndFocusPowderFromFiles"};
+  }
 
   /// Algorithm's category for identification overriding a virtual method
   const std::string category() const override {
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h
index ce8aaf3dba4de77b153588cdbcd056751365b10f..ec88cb90c0de8360cb9fdb5c9e58e2e13b93c304 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h
@@ -35,6 +35,9 @@ class DLLExport LoadEventAndCompress : public API::DataProcessorAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
+  const std::vector<std::string> seeAlso() const override {
+    return {"LoadEventNexus", "CompressEvents"};
+  }
   const std::string category() const override;
   const std::string summary() const override;
 
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h
deleted file mode 100644
index 749f1f43c9926e449b57caa823947ed6db6a2523..0000000000000000000000000000000000000000
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef MANTID_ALGORITHMS_RefReduction_H_
-#define MANTID_ALGORITHMS_RefReduction_H_
-
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-#include "MantidAPI/Algorithm.h"
-#include "MantidAPI/MatrixWorkspace_fwd.h"
-#include "MantidDataObjects/EventWorkspace.h"
-
-namespace Mantid {
-namespace WorkflowAlgorithms {
-/**
-    Data reduction for reflectometry
-
-    Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-   National Laboratory & European Spallation Source
-
-    This file is part of Mantid.
-
-    Mantid is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 3 of the License, or
-    (at your option) any later version.
-
-    Mantid is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-    File change history is stored at: <https://github.com/mantidproject/mantid>
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-
-class DLLExport RefReduction : public API::Algorithm {
-public:
-  /// Algorithm's name
-  const std::string name() const override { return "RefReduction"; }
-  /// Summary of algorithms purpose
-  const std::string summary() const override {
-    return "Data reduction for reflectometry.";
-  }
-  /// Algorithm's version
-  int version() const override { return (1); }
-  /// Algorithm's category for identification
-  const std::string category() const override {
-    return "Workflow\\Reflectometry";
-  }
-
-private:
-  /// Initialisation code
-  void init() override;
-  /// Execution code
-  void exec() override;
-
-  static const std::string PolStateOffOff;
-  static const std::string PolStateOnOff;
-  static const std::string PolStateOffOn;
-  static const std::string PolStateOnOn;
-  static const std::string PolStateNone;
-
-  static const int NX_PIXELS;
-  static const int NY_PIXELS;
-  static const double PIXEL_SIZE;
-
-  std::string m_output_message;
-
-  API::MatrixWorkspace_sptr processData(const std::string polarization);
-  API::MatrixWorkspace_sptr processNormalization();
-  API::IEventWorkspace_sptr loadData(const std::string dataRun,
-                                     const std::string polarization);
-  double calculateAngleREFM(API::MatrixWorkspace_sptr workspace);
-  double calculateAngleREFL(API::MatrixWorkspace_sptr workspace);
-  API::MatrixWorkspace_sptr subtractBackground(API::MatrixWorkspace_sptr dataWS,
-                                               API::MatrixWorkspace_sptr rawWS,
-                                               int peakMin, int peakMax,
-                                               int bckMin, int bckMax,
-                                               int lowResMin, int lowResMax);
-};
-
-} // namespace Algorithms
-} // namespace Mantid
-
-#endif /*MANTID_ALGORITHMS_RefReduction_H_*/
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h
index 389114be9071f9ee01b1ad30eb3e8c83811ceca6..fd629644542c71120d670d1e110e34c25ec3fbde 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h
@@ -48,6 +48,7 @@ public:
   }
   /// Algorithm's version
   int version() const override { return (1); }
+
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Workflow\\Reflectometry";
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h
index 1c274a53cf641a283bee39b9f7eb3bd1c8c2feeb..3aa3e9b374c52548347f0d8572e08469be745b2b 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h
@@ -24,6 +24,9 @@ public:
   }
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SANSSolidAngleCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Workflow\\SANS\\UsesPropertyManager;"
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h
index a161140b047a7a0a162258da29c3c76e103888b2..9a0fc2d782ef7151617dbb3058c447e6db1c1980 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h
@@ -44,6 +44,9 @@ public:
   }
   /// Algorithm's version
   int version() const override { return (1); }
+  const std::vector<std::string> seeAlso() const override {
+    return {"SANSBeamFluxCorrection"};
+  }
   /// Algorithm's category for identification
   const std::string category() const override {
     return "Workflow\\SANS\\UsesPropertyManager;"
diff --git a/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp b/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp
index 71dc6c39698aa7d5a498a24b87f9f63c2b1dfd48..aa7bf397b5276b3034fe81c3a222c737c0854805 100644
--- a/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp
+++ b/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp
@@ -290,7 +290,7 @@ void DgsDiagnose::exec() {
     diag->execute();
     maskWS = diag->getProperty("OutputWorkspace");
   } else {
-    typedef Mantid::Kernel::StringTokenizer tokenizer;
+    using tokenizer = Mantid::Kernel::StringTokenizer;
     tokenizer tokens(diag_spectra[0], "(,);",
                      Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY);
     for (auto tok_iter = tokens.begin(); tok_iter != tokens.end();) {
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
index ca1966529fef5d90e05ca6d0897d5e8365f43bbb..e5eda43ad15fc2cb8d50564551d0c897411a2d89 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
@@ -231,7 +231,7 @@ void EQSANSLoad::readModeratorPosition(const std::string &line) {
 void EQSANSLoad::readSourceSlitSize(const std::string &line) {
   boost::regex re_key("wheel", boost::regex::icase);
   if (boost::regex_search(line, re_key)) {
-    boost::regex re_sig("([1-8]) wheel[ ]*([1-3])[ \\t]*=[ \\t]*(\\w+)");
+    boost::regex re_sig(R"(([1-8]) wheel[ ]*([1-3])[ \t]*=[ \t]*(\w+))");
     boost::smatch posVec;
     if (boost::regex_search(line, posVec, re_sig)) {
       if (posVec.size() == 4) {
diff --git a/Framework/WorkflowAlgorithms/src/RefReduction.cpp b/Framework/WorkflowAlgorithms/src/RefReduction.cpp
deleted file mode 100644
index 381da79c0b5259b6dec6b98a10f00f51cce364bf..0000000000000000000000000000000000000000
--- a/Framework/WorkflowAlgorithms/src/RefReduction.cpp
+++ /dev/null
@@ -1,817 +0,0 @@
-#include "MantidWorkflowAlgorithms/RefReduction.h"
-#include "MantidAPI/AnalysisDataService.h"
-#include "MantidGeometry/Instrument/DetectorInfo.h"
-#include "MantidAPI/FileFinder.h"
-#include "MantidAPI/MatrixWorkspace.h"
-#include "MantidAPI/Run.h"
-#include "MantidDataObjects/EventWorkspace.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidKernel/ArrayProperty.h"
-#include "MantidKernel/ListValidator.h"
-#include "MantidKernel/TimeSeriesProperty.h"
-#include "MantidKernel/VisibleWhenProperty.h"
-
-#include "Poco/File.h"
-#include "Poco/NumberFormatter.h"
-#include "Poco/String.h"
-#include <algorithm>
-
-namespace Mantid {
-namespace WorkflowAlgorithms {
-
-// Register the algorithm into the AlgorithmFactory
-DECLARE_ALGORITHM(RefReduction)
-
-const std::string RefReduction::PolStateOffOff("entry-Off_Off");
-const std::string RefReduction::PolStateOnOff("entry-On_Off");
-const std::string RefReduction::PolStateOffOn("entry-Off_On");
-const std::string RefReduction::PolStateOnOn("entry-On_On");
-const std::string RefReduction::PolStateNone("entry");
-
-const int RefReduction::NX_PIXELS(304);
-const int RefReduction::NY_PIXELS(256);
-const double RefReduction::PIXEL_SIZE(0.0007);
-
-using namespace Kernel;
-using namespace API;
-using namespace Geometry;
-using namespace DataObjects;
-
-void RefReduction::init() {
-  declareProperty("DataRun", "", "Run number of the data set to be reduced");
-  declareProperty(make_unique<ArrayProperty<int>>("SignalPeakPixelRange"),
-                  "Pixel range for the signal peak");
-
-  declareProperty(
-      "SubtractSignalBackground", false,
-      "If true, the background will be subtracted from the signal peak");
-  declareProperty(make_unique<ArrayProperty<int>>("SignalBackgroundPixelRange"),
-                  "Pixel range for background around the signal peak");
-
-  declareProperty(
-      "CropLowResDataAxis", false,
-      "If true, the low-resolution pixel range will be limited to the"
-      " range given by the LowResDataAxisPixelRange property");
-  declareProperty(make_unique<ArrayProperty<int>>("LowResDataAxisPixelRange"),
-                  "Pixel range for the signal peak in the low-res direction");
-
-  declareProperty("PerformNormalization", true,
-                  "If true, the normalization will be performed");
-  declareProperty("NormalizationRun", "",
-                  "Run number of the normalization data set");
-  declareProperty(make_unique<ArrayProperty<int>>("NormPeakPixelRange"),
-                  "Pixel range for the normalization peak");
-
-  declareProperty("SubtractNormBackground", false,
-                  "It true, the background will be subtracted"
-                  " from the normalization peak");
-  declareProperty(make_unique<ArrayProperty<int>>("NormBackgroundPixelRange"),
-                  "Pixel range for background around the normalization peak");
-
-  declareProperty("CropLowResNormAxis", false,
-                  "If true, the low-resolution pixel range"
-                  " will be limited to be the range given by the "
-                  "LowResNormAxisPixelRange property");
-  declareProperty(
-      make_unique<ArrayProperty<int>>("LowResNormAxisPixelRange"),
-      "Pixel range for the normalization peak in the low-res direction");
-
-  declareProperty("Theta", EMPTY_DBL(),
-                  "Scattering angle (takes precedence over meta data)");
-  declareProperty("TOFMin", EMPTY_DBL(), "Minimum TOF cut");
-  declareProperty("TOFMax", EMPTY_DBL(), "Maximum TOF cut");
-
-  declareProperty("TOFStep", 400.0, "Step size of TOF histogram");
-  declareProperty("NBins", EMPTY_INT(), "Number of bins in TOF histogram "
-                                        "(takes precedence over TOFStep if "
-                                        "given)");
-
-  declareProperty("ReflectivityPixel", EMPTY_DBL());
-  declareProperty("DetectorAngle", EMPTY_DBL());
-  declareProperty("DetectorAngle0", EMPTY_DBL());
-  declareProperty("DirectPixel", EMPTY_DBL());
-  declareProperty("PolarizedData", true, "If true, the algorithm will look for "
-                                         "polarization states in the data set");
-  setPropertySettings(
-      "ReflectivityPixel",
-      make_unique<VisibleWhenProperty>("Instrument", IS_EQUAL_TO, "REF_M"));
-  setPropertySettings("DetectorAngle", make_unique<VisibleWhenProperty>(
-                                           "Instrument", IS_EQUAL_TO, "REF_M"));
-  setPropertySettings(
-      "DetectorAngle0",
-      make_unique<VisibleWhenProperty>("Instrument", IS_EQUAL_TO, "REF_M"));
-  setPropertySettings("DirectPixel", make_unique<VisibleWhenProperty>(
-                                         "Instrument", IS_EQUAL_TO, "REF_M"));
-
-  declareProperty("AngleOffset", EMPTY_DBL(),
-                  "Scattering angle offset in degrees");
-  setPropertySettings("AngleOffset", make_unique<VisibleWhenProperty>(
-                                         "Instrument", IS_EQUAL_TO, "REF_L"));
-
-  std::vector<std::string> instrOptions{"REF_L", "REF_M"};
-  declareProperty("Instrument", "REF_M",
-                  boost::make_shared<StringListValidator>(instrOptions),
-                  "Instrument to reduce for");
-  declareProperty("OutputWorkspacePrefix", "reflectivity",
-                  "Prefix to give the output workspaces");
-  declareProperty("OutputMessage", "", Direction::Output);
-}
-
-/// Execute algorithm
-void RefReduction::exec() {
-  const std::string instrument = getProperty("Instrument");
-  m_output_message = "------ " + instrument + " reduction ------\n";
-
-  // Process each polarization state
-  if (getProperty("PolarizedData")) {
-    processData(PolStateOffOff);
-    processData(PolStateOnOff);
-    processData(PolStateOffOn);
-    processData(PolStateOnOn);
-  } else {
-    processData(PolStateNone);
-  }
-  setPropertyValue("OutputMessage", m_output_message);
-}
-
-MatrixWorkspace_sptr RefReduction::processData(const std::string polarization) {
-  m_output_message += "Processing " + polarization + '\n';
-  const std::string dataRun = getPropertyValue("DataRun");
-  IEventWorkspace_sptr evtWS = loadData(dataRun, polarization);
-  // wrong entry name
-  if (!evtWS)
-    return nullptr;
-
-  MatrixWorkspace_sptr dataWS =
-      boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS);
-  MatrixWorkspace_sptr dataWSTof =
-      boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS);
-
-  // If we have no events, stop here
-  if (evtWS->getNumberEvents() == 0)
-    return dataWS;
-
-  // Get low-res pixel range
-  int low_res_min = 0;
-  int low_res_max = 0;
-  const bool cropLowRes = getProperty("CropLowResDataAxis");
-  const std::vector<int> lowResRange = getProperty("LowResDataAxisPixelRange");
-  if (cropLowRes) {
-    if (lowResRange.size() < 2) {
-      g_log.error() << "LowResDataAxisPixelRange parameter should be a vector "
-                       "of two values\n";
-      throw std::invalid_argument("LowResDataAxisPixelRange parameter should "
-                                  "be a vector of two values");
-    }
-    low_res_min = lowResRange[0];
-    low_res_max = lowResRange[1];
-    m_output_message += "    |Cropping low-res axis: [" +
-                        Poco::NumberFormatter::format(low_res_min) + ", " +
-                        Poco::NumberFormatter::format(low_res_max) + "]\n";
-  }
-
-  // Get peak range
-  const std::vector<int> peakRange = getProperty("SignalPeakPixelRange");
-  if (peakRange.size() < 2) {
-    g_log.error()
-        << "SignalPeakPixelRange parameter should be a vector of two values\n";
-    throw std::invalid_argument(
-        "SignalPeakPixelRange parameter should be a vector of two values");
-  }
-
-  // Get scattering angle in degrees
-  double theta = getProperty("Theta");
-  const std::string instrument = getProperty("Instrument");
-  const bool integrateY = instrument == "REF_M";
-
-  // Get pixel ranges in real pixels
-  int xmin = 0;
-  int xmax = 0;
-  int ymin = 0;
-  int ymax = 0;
-  if (integrateY) {
-    if (isEmpty(theta))
-      theta = calculateAngleREFM(dataWS);
-    if (!cropLowRes)
-      low_res_max = NY_PIXELS - 1;
-    xmin = 0;
-    xmax = NX_PIXELS - 1;
-    ymin = low_res_min;
-    ymax = low_res_max;
-  } else {
-    if (isEmpty(theta))
-      theta = calculateAngleREFL(dataWS);
-    if (!cropLowRes)
-      low_res_max = NX_PIXELS - 1;
-    ymin = 0;
-    ymax = NY_PIXELS - 1;
-    xmin = low_res_min;
-    xmax = low_res_max;
-  }
-  m_output_message += "    |Scattering angle: " +
-                      Poco::NumberFormatter::format(theta, 6) + " deg\n";
-
-  // Subtract background
-  if (getProperty("SubtractSignalBackground")) {
-    // Get background range
-    const std::vector<int> bckRange = getProperty("SignalBackgroundPixelRange");
-    if (bckRange.size() < 2) {
-      g_log.error() << "SignalBackgroundPixelRange parameter should be a "
-                       "vector of two values\n";
-      throw std::invalid_argument("SignalBackgroundPixelRange parameter should "
-                                  "be a vector of two values");
-    }
-
-    IAlgorithm_sptr convAlg =
-        createChildAlgorithm("ConvertToMatrixWorkspace", 0.50, 0.55);
-    convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-    convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
-    convAlg->executeAsChildAlg();
-
-    dataWS =
-        subtractBackground(dataWS, dataWS, peakRange[0], peakRange[1],
-                           bckRange[0], bckRange[1], low_res_min, low_res_max);
-    m_output_message += "    |Subtracted background [" +
-                        Poco::NumberFormatter::format(bckRange[0]) + ", " +
-                        Poco::NumberFormatter::format(bckRange[1]) + "]\n";
-  }
-
-  // Process normalization run
-  if (getProperty("PerformNormalization")) {
-    MatrixWorkspace_sptr normWS = processNormalization();
-    IAlgorithm_sptr rebinAlg =
-        createChildAlgorithm("RebinToWorkspace", 0.50, 0.55);
-    rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToRebin", normWS);
-    rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToMatch", dataWS);
-    rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", normWS);
-    rebinAlg->executeAsChildAlg();
-    normWS = rebinAlg->getProperty("OutputWorkspace");
-
-    IAlgorithm_sptr divAlg = createChildAlgorithm("Divide", 0.55, 0.65);
-    divAlg->setProperty<MatrixWorkspace_sptr>("LHSWorkspace", dataWS);
-    divAlg->setProperty<MatrixWorkspace_sptr>("RHSWorkspace", normWS);
-    divAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
-    divAlg->executeAsChildAlg();
-
-    IAlgorithm_sptr repAlg =
-        createChildAlgorithm("ReplaceSpecialValues", 0.55, 0.65);
-    repAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-    repAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
-    repAlg->setProperty("NaNValue", 0.0);
-    repAlg->setProperty("NaNError", 0.0);
-    repAlg->setProperty("InfinityValue", 0.0);
-    repAlg->setProperty("InfinityError", 0.0);
-    repAlg->executeAsChildAlg();
-    m_output_message += "Normalization completed\n";
-  }
-
-  //    // Integrate over Y
-  //    IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95);
-  //    refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-  //    refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-  //    refAlg->setProperty("NXPixel", NX_PIXELS);
-  //    refAlg->setProperty("NYPixel", NY_PIXELS);
-  //    refAlg->setProperty("YPixelMin", ymin);
-  //    refAlg->setProperty("YPixelMax", ymax);
-  //    refAlg->setProperty("XPixelMin", xmin);
-  //    refAlg->setProperty("XPixelMax", xmax);
-  //    refAlg->setProperty("IntegrateY", integrateY);
-  //    refAlg->setProperty("ScatteringAngle", theta);
-  //    refAlg->executeAsChildAlg();
-  //
-  //    // Convert back to TOF
-  //    IAlgorithm_sptr convAlgToTof = createChildAlgorithm("ConvertUnits",
-  //    0.85, 0.90);
-  //    convAlgToTof->setProperty<MatrixWorkspace_sptr>("InputWorkspace",
-  //    dataWS);
-  //    convAlgToTof->setProperty<MatrixWorkspace_sptr>("OutputWorkspace",
-  //    dataWSTof);
-  //    convAlgToTof->setProperty("Target", "TOF");
-  //    convAlgToTof->executeAsChildAlg();
-  //
-  //    MatrixWorkspace_sptr outputWS2 =
-  //    convAlgToTof->getProperty("OutputWorkspace");
-  //    declareProperty(new WorkspaceProperty<>("OutputWorkspace_jc_" +
-  //    polarization, "TOF_"+polarization, Direction::Output));
-  //    setProperty("OutputWorkspace_jc_" + polarization, outputWS2);
-
-  // integrated over Y and keep in lambda scale
-  IAlgorithm_sptr refAlg1 = createChildAlgorithm("RefRoi", 0.90, 0.95);
-  refAlg1->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-  refAlg1->setProperty("NXPixel", NX_PIXELS);
-  refAlg1->setProperty("NYPixel", NY_PIXELS);
-  refAlg1->setProperty("ConvertToQ", false);
-  refAlg1->setProperty("YPixelMin", ymin);
-  refAlg1->setProperty("YPixelMax", ymax);
-  refAlg1->setProperty("XPixelMin", xmin);
-  refAlg1->setProperty("XPixelMax", xmax);
-  refAlg1->setProperty("IntegrateY", integrateY);
-  refAlg1->setProperty("ScatteringAngle", theta);
-  refAlg1->executeAsChildAlg();
-  MatrixWorkspace_sptr outputWS2 = refAlg1->getProperty("OutputWorkspace");
-  std::string polarizationTranslation(polarization);
-  std::replace(polarizationTranslation.begin(), polarizationTranslation.end(),
-               '-', '_');
-  declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
-      "OutputWorkspace_jc_" + polarizationTranslation, "Lambda_" + polarization,
-      Direction::Output));
-  setProperty("OutputWorkspace_jc_" + polarizationTranslation, outputWS2);
-
-  // Conversion to Q
-  IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95);
-  refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
-  refAlg->setProperty("NXPixel", NX_PIXELS);
-  refAlg->setProperty("NYPixel", NY_PIXELS);
-  refAlg->setProperty("ConvertToQ", true);
-
-  refAlg->setProperty("YPixelMin", ymin);
-  refAlg->setProperty("YPixelMax", ymax);
-  refAlg->setProperty("XPixelMin", xmin);
-  refAlg->setProperty("XPixelMax", xmax);
-  refAlg->setProperty("IntegrateY", integrateY);
-  refAlg->setProperty("ScatteringAngle", theta);
-  refAlg->executeAsChildAlg();
-
-  MatrixWorkspace_sptr output2DWS = refAlg->getProperty("OutputWorkspace");
-  std::vector<int> spectra;
-  for (int i = peakRange[0]; i < peakRange[1] + 1; i++)
-    spectra.push_back(i);
-
-  IAlgorithm_sptr grpAlg = createChildAlgorithm("GroupDetectors", 0.95, 0.99);
-  grpAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", output2DWS);
-  grpAlg->setProperty("SpectraList", spectra);
-  grpAlg->executeAsChildAlg();
-
-  MatrixWorkspace_sptr outputWS = grpAlg->getProperty("OutputWorkspace");
-
-  const std::string prefix = getPropertyValue("OutputWorkspacePrefix");
-  if (polarization == PolStateNone) {
-    declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
-        "OutputWorkspace", prefix, Direction::Output));
-    setProperty("OutputWorkspace", outputWS);
-    declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
-        "OutputWorkspace2D", "2D_" + prefix, Direction::Output));
-    setProperty("OutputWorkspace2D", output2DWS);
-  } else {
-    std::string wsName = prefix + polarization;
-    Poco::replaceInPlace(wsName, "entry", "");
-    declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
-        "OutputWorkspace_" + polarizationTranslation, wsName,
-        Direction::Output));
-    setProperty("OutputWorkspace_" + polarizationTranslation, outputWS);
-    declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
-        "OutputWorkspace2D_" + polarizationTranslation, "2D_" + wsName,
-        Direction::Output));
-    setProperty("OutputWorkspace2D_" + polarizationTranslation, output2DWS);
-  }
-  m_output_message += "Reflectivity calculation completed\n";
-  return outputWS;
-}
-
-MatrixWorkspace_sptr RefReduction::processNormalization() {
-  m_output_message += "Processing normalization\n";
-
-  const std::string normRun = getPropertyValue("NormalizationRun");
-  IEventWorkspace_sptr evtWS = loadData(normRun, PolStateNone);
-  MatrixWorkspace_sptr normWS =
-      boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS);
-
-  const std::vector<int> peakRange = getProperty("NormPeakPixelRange");
-
-  int low_res_min = 0;
-  int low_res_max = 0;
-  int xmin = 0;
-  int xmax = 0;
-  int ymin = 0;
-  int ymax = 0;
-
-  const bool cropLowRes = getProperty("CropLowResNormAxis");
-  const std::vector<int> lowResRange = getProperty("LowResNormAxisPixelRange");
-  if (cropLowRes) {
-    if (lowResRange.size() < 2) {
-      g_log.error() << "LowResNormAxisPixelRange parameter should be a vector "
-                       "of two values\n";
-      throw std::invalid_argument("LowResNormAxisPixelRange parameter should "
-                                  "be a vector of two values");
-    }
-    low_res_min = lowResRange[0];
-    low_res_max = lowResRange[1];
-    m_output_message + "    |Cropping low-res axis: [" +
-        Poco::NumberFormatter::format(low_res_min) + ", " +
-        Poco::NumberFormatter::format(low_res_max) + "]\n";
-  }
-
-  const std::string instrument = getProperty("Instrument");
-  const bool integrateY = instrument == "REF_M";
-  if (integrateY) {
-    if (!cropLowRes)
-      low_res_max = NY_PIXELS - 1;
-    xmin = peakRange[0];
-    xmax = peakRange[1];
-    ymin = low_res_min;
-    ymax = low_res_max;
-  } else {
-    if (!cropLowRes)
-      low_res_max = NX_PIXELS - 1;
-    ymin = peakRange[0];
-    ymax = peakRange[1];
-    xmin = low_res_min;
-    xmax = low_res_max;
-  }
-
-  if (getProperty("SubtractNormBackground")) {
-    // Get background range
-    const std::vector<int> bckRange = getProperty("NormBackgroundPixelRange");
-    if (bckRange.size() < 2) {
-      g_log.error() << "NormBackgroundPixelRange parameter should be a vector "
-                       "of two values\n";
-      throw std::invalid_argument("NormBackgroundPixelRange parameter should "
-                                  "be a vector of two values");
-    }
-
-    IAlgorithm_sptr convAlg =
-        createChildAlgorithm("ConvertToMatrixWorkspace", 0.50, 0.55);
-    convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", normWS);
-    convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", normWS);
-    convAlg->executeAsChildAlg();
-
-    normWS =
-        subtractBackground(normWS, normWS, peakRange[0], peakRange[1],
-                           bckRange[0], bckRange[1], low_res_min, low_res_max);
-    m_output_message += "    |Subtracted background [" +
-                        Poco::NumberFormatter::format(bckRange[0]) + ", " +
-                        Poco::NumberFormatter::format(bckRange[1]) + "]\n";
-  }
-  IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.6, 0.65);
-  refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", normWS);
-  refAlg->setProperty("NXPixel", NX_PIXELS);
-  refAlg->setProperty("NYPixel", NY_PIXELS);
-  refAlg->setProperty("ConvertToQ", false);
-  refAlg->setProperty("SumPixels", true);
-  refAlg->setProperty("NormalizeSum", true);
-  refAlg->setProperty("AverageOverIntegratedAxis", integrateY);
-  refAlg->setProperty("YPixelMin", ymin);
-  refAlg->setProperty("YPixelMax", ymax);
-  refAlg->setProperty("XPixelMin", xmin);
-  refAlg->setProperty("XPixelMax", xmax);
-  refAlg->setProperty("IntegrateY", integrateY);
-  refAlg->executeAsChildAlg();
-
-  MatrixWorkspace_sptr outputNormWS = refAlg->getProperty("OutputWorkspace");
-  return outputNormWS;
-}
-
-IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun,
-                                            const std::string polarization) {
-  const std::string instrument = getProperty("Instrument");
-
-  // Check whether dataRun refers to an existing workspace
-  // Create a good name for the raw workspace
-  std::string ws_name = "__ref_" + dataRun + "-" + polarization + "_raw";
-  IEventWorkspace_sptr rawWS;
-  if (AnalysisDataService::Instance().doesExist(dataRun)) {
-    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(dataRun);
-    g_log.notice() << "Found workspace: " << dataRun << '\n';
-    m_output_message += "    |Input data run is a workspace: " + dataRun + "\n";
-  } else if (AnalysisDataService::Instance().doesExist(ws_name)) {
-    rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(ws_name);
-    g_log.notice() << "Using existing workspace: " << ws_name << '\n';
-    m_output_message +=
-        "    |Found workspace from previous reduction: " + ws_name + "\n";
-  } else {
-    // If we can't find a workspace, find a file to load
-    std::string path = FileFinder::Instance().getFullPath(dataRun);
-
-    if (path.empty() || !Poco::File(path).exists()) {
-      try {
-        std::vector<std::string> paths =
-            FileFinder::Instance().findRuns(instrument + dataRun);
-        path = paths[0];
-      } catch (Exception::NotFoundError &) { /* Pass. We report the missing file
-                                                later. */
-      }
-    }
-
-    if (path.empty() || !Poco::File(path).exists()) {
-      try {
-        std::vector<std::string> paths =
-            FileFinder::Instance().findRuns(dataRun);
-        path = paths[0];
-      } catch (Exception::NotFoundError &) { /* Pass. We report the missing file
-                                                later. */
-      }
-    }
-
-    if (Poco::File(path).exists()) {
-      g_log.notice() << "Found: " << path << '\n';
-      m_output_message += "    |Loading from " + path + "\n";
-      IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2);
-      loadAlg->setProperty("Filename", path);
-      if (polarization != PolStateNone)
-        loadAlg->setProperty("NXentryName", polarization);
-      try {
-        loadAlg->executeAsChildAlg();
-      } catch (...) {
-        g_log.notice() << "Could not load polarization " << polarization;
-        return nullptr;
-      }
-
-      Workspace_sptr temp = loadAlg->getProperty("OutputWorkspace");
-      rawWS = boost::dynamic_pointer_cast<IEventWorkspace>(temp);
-      if (rawWS->getNumberEvents() == 0) {
-        g_log.notice() << "No data in " << polarization << '\n';
-        m_output_message += "    |No data for " + polarization + "\n";
-        return rawWS;
-      }
-
-      // Move the detector to the right position
-      if (instrument == "REF_M") {
-        const auto &detInfo = rawWS->detectorInfo();
-        const size_t detIndex0 = detInfo.indexOf(0);
-        double det_distance = detInfo.position(detIndex0).Z();
-        auto dp = rawWS->run().getTimeSeriesProperty<double>("SampleDetDis");
-        double sdd = dp->getStatistics().mean / 1000.0;
-        IAlgorithm_sptr mvAlg =
-            createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.25);
-        mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", rawWS);
-        mvAlg->setProperty("ComponentName", "detector1");
-        mvAlg->setProperty("Z", sdd - det_distance);
-        mvAlg->setProperty("RelativePosition", true);
-        mvAlg->executeAsChildAlg();
-        g_log.notice() << "Ensuring correct Z position: Correction = "
-                       << Poco::NumberFormatter::format(sdd - det_distance)
-                       << " m\n";
-      }
-      AnalysisDataService::Instance().addOrReplace(ws_name, rawWS);
-    } else {
-      g_log.error() << "Could not find a data file for " << dataRun << '\n';
-      throw std::invalid_argument(
-          "Could not find a data file for the given input");
-    }
-  }
-
-  // Crop TOF as needed and set binning
-  double tofMin = getProperty("TOFMin");
-  double tofMax = getProperty("TOFMax");
-  if (isEmpty(tofMin) || isEmpty(tofMax)) {
-    const auto &x = rawWS->x(0);
-    if (isEmpty(tofMin))
-      tofMin = *std::min_element(x.begin(), x.end());
-    if (isEmpty(tofMax))
-      tofMax = *std::max_element(x.begin(), x.end());
-  }
-
-  int nBins = getProperty("NBins");
-  double tofStep = getProperty("TOFStep");
-  if (!isEmpty(nBins))
-    tofStep = (tofMax - tofMin) / nBins;
-  else
-    nBins = static_cast<int>(floor((tofMax - tofMin) / tofStep));
-
-  std::vector<double> params;
-  params.push_back(tofMin);
-  params.push_back(tofStep);
-  params.push_back(tofMax);
-
-  IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.25, 0.3);
-  rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
-  rebinAlg->setProperty("Params", params);
-  rebinAlg->setProperty("PreserveEvents", true);
-  rebinAlg->executeAsChildAlg();
-  MatrixWorkspace_sptr outputWS = rebinAlg->getProperty("OutputWorkspace");
-  m_output_message += "    |TOF binning: " +
-                      Poco::NumberFormatter::format(tofMin) + " to " +
-                      Poco::NumberFormatter::format(tofMax) + " in steps of " +
-                      Poco::NumberFormatter::format(tofStep) + " microsecs\n";
-
-  // Normalise by current
-  IAlgorithm_sptr normAlg =
-      createChildAlgorithm("NormaliseByCurrent", 0.3, 0.35);
-  normAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
-  normAlg->executeAsChildAlg();
-  outputWS = normAlg->getProperty("OutputWorkspace");
-
-  // Convert to wavelength
-  IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertUnits", 0.35, 0.4);
-  convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
-  convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
-  convAlg->setProperty("Target", "Wavelength");
-  convAlg->executeAsChildAlg();
-
-  // Rebin in wavelength
-  const auto &x = outputWS->x(0);
-  double wlMin = *std::min_element(x.begin(), x.end());
-  double wlMax = *std::max_element(x.begin(), x.end());
-
-  std::vector<double> wl_params;
-  wl_params.push_back(wlMin);
-  wl_params.push_back((wlMax - wlMin) / nBins);
-  wl_params.push_back(wlMax);
-
-  IAlgorithm_sptr rebinAlg2 = createChildAlgorithm("Rebin", 0.25, 0.3);
-  rebinAlg2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS);
-  rebinAlg2->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
-  rebinAlg2->setProperty("Params", wl_params);
-  rebinAlg2->setProperty("PreserveEvents", true);
-  rebinAlg2->executeAsChildAlg();
-
-  IEventWorkspace_sptr outputEvtWS =
-      boost::dynamic_pointer_cast<IEventWorkspace>(outputWS);
-  return outputEvtWS;
-}
-
-double RefReduction::calculateAngleREFM(MatrixWorkspace_sptr workspace) {
-  double dangle = getProperty("DetectorAngle");
-  if (isEmpty(dangle)) {
-    Mantid::Kernel::Property *prop = workspace->run().getProperty("DANGLE");
-    if (!prop)
-      throw std::runtime_error("DetectorAngle property not given as input, and "
-                               "could not find the log entry DANGLE either");
-    Mantid::Kernel::TimeSeriesProperty<double> *dp =
-        dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop);
-    if (!dp)
-      throw std::runtime_error(
-          "The log entry DANGLE could not"
-          "be interpreted as a property of type time series of double");
-    dangle = dp->getStatistics().mean;
-  }
-
-  double dangle0 = getProperty("DetectorAngle0");
-  if (isEmpty(dangle0)) {
-    Mantid::Kernel::Property *prop = workspace->run().getProperty("DANGLE0");
-    if (!prop)
-      throw std::runtime_error("DetectorAngle0 property not given aas input, "
-                               "and could not find the log entry DANGLE0 "
-                               "either");
-    Mantid::Kernel::TimeSeriesProperty<double> *dp =
-        dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop);
-    if (!dp)
-      throw std::runtime_error(
-          "The log entry DANGLE0 could not "
-          "be interpreted as a property of type time series of double values");
-    dangle0 = dp->getStatistics().mean;
-  }
-
-  Mantid::Kernel::Property *prop = workspace->run().getProperty("SampleDetDis");
-  Mantid::Kernel::TimeSeriesProperty<double> *dp =
-      dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop);
-  if (!dp)
-    throw std::runtime_error("SampleDetDis was not a TimeSeriesProperty");
-  const double det_distance = dp->getStatistics().mean / 1000.0;
-
-  double direct_beam_pix = getProperty("DirectPixel");
-  if (isEmpty(direct_beam_pix)) {
-    auto dp = workspace->run().getTimeSeriesProperty<double>("DIRPIX");
-    direct_beam_pix = dp->getStatistics().mean;
-  }
-
-  double ref_pix = getProperty("ReflectivityPixel");
-  if (ref_pix == 0 || isEmpty(ref_pix)) {
-    const std::vector<int> peakRange = getProperty("SignalPeakPixelRange");
-    if (peakRange.size() < 2) {
-      g_log.error() << "SignalPeakPixelRange parameter should be a vector of "
-                       "two values\n";
-      throw std::invalid_argument(
-          "SignalPeakPixelRange parameter should be a vector of two values");
-    }
-    ref_pix = (peakRange[0] + peakRange[1]) / 2.0;
-  }
-
-  double theta =
-      (dangle - dangle0) * M_PI / 180.0 / 2.0 +
-      ((direct_beam_pix - ref_pix) * PIXEL_SIZE) / (2.0 * det_distance);
-
-  return theta * 180.0 / M_PI;
-}
-
-double RefReduction::calculateAngleREFL(MatrixWorkspace_sptr workspace) {
-  auto dp = workspace->run().getTimeSeriesProperty<double>("ths");
-  const double ths = dp->getStatistics().mean;
-
-  dp = workspace->run().getTimeSeriesProperty<double>("tthd");
-  const double tthd = dp->getStatistics().mean;
-
-  double offset = getProperty("AngleOffset");
-  if (isEmpty(offset))
-    offset = 0.0;
-  return tthd - ths + offset;
-}
-
-MatrixWorkspace_sptr RefReduction::subtractBackground(
-    MatrixWorkspace_sptr dataWS, MatrixWorkspace_sptr rawWS, int peakMin,
-    int peakMax, int bckMin, int bckMax, int lowResMin, int lowResMax) {
-  const std::string instrument = getProperty("Instrument");
-  const bool integrateY = instrument == "REF_M";
-
-  int xmin = 0;
-  int xmax = 0;
-  int ymin = 0;
-  int ymax = 0;
-  if (integrateY) {
-    ymin = lowResMin;
-    ymax = lowResMax;
-  } else {
-    xmin = lowResMin;
-    xmax = lowResMax;
-  }
-
-  // Look for overlap with data peak
-  if (bckMin < peakMin && bckMax > peakMax) {
-    // Background on the left
-    if (integrateY) {
-      xmin = bckMin;
-      xmax = peakMin - 1;
-    } else {
-      ymin = bckMin;
-      ymax = peakMin - 1;
-    }
-    IAlgorithm_sptr leftAlg = createChildAlgorithm("RefRoi", 0.6, 0.65);
-    leftAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
-    leftAlg->setProperty("NXPixel", NX_PIXELS);
-    leftAlg->setProperty("NYPixel", NY_PIXELS);
-    leftAlg->setProperty("ConvertToQ", false);
-    leftAlg->setProperty("SumPixels", true);
-    leftAlg->setProperty("NormalizeSum", true);
-    leftAlg->setProperty("AverageOverIntegratedAxis", integrateY);
-    leftAlg->setProperty("YPixelMin", ymin);
-    leftAlg->setProperty("YPixelMax", ymax);
-    leftAlg->setProperty("XPixelMin", xmin);
-    leftAlg->setProperty("XPixelMax", xmax);
-    leftAlg->setProperty("IntegrateY", integrateY);
-    leftAlg->executeAsChildAlg();
-
-    MatrixWorkspace_sptr leftWS = leftAlg->getProperty("OutputWorkspace");
-
-    // Background on the right
-    if (integrateY) {
-      xmin = peakMax + 1;
-      xmax = bckMax;
-    } else {
-      ymin = peakMax + 1;
-      ymax = bckMax;
-    }
-    IAlgorithm_sptr rightAlg = createChildAlgorithm("RefRoi", 0.6, 0.65);
-    rightAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
-    rightAlg->setProperty("NXPixel", NX_PIXELS);
-    rightAlg->setProperty("NYPixel", NY_PIXELS);
-    rightAlg->setProperty("ConvertToQ", false);
-    rightAlg->setProperty("SumPixels", true);
-    rightAlg->setProperty("NormalizeSum", true);
-    rightAlg->setProperty("AverageOverIntegratedAxis", integrateY);
-    rightAlg->setProperty("YPixelMin", ymin);
-    rightAlg->setProperty("YPixelMax", ymax);
-    rightAlg->setProperty("XPixelMin", xmin);
-    rightAlg->setProperty("XPixelMax", xmax);
-    rightAlg->setProperty("IntegrateY", integrateY);
-    rightAlg->executeAsChildAlg();
-
-    MatrixWorkspace_sptr rightWS = rightAlg->getProperty("OutputWorkspace");
-
-    // Average the two sides and subtract from peak
-    dataWS = dataWS - (leftWS + rightWS) / 2.0;
-    return dataWS;
-
-  } else {
-
-    // Check for overlaps
-    if (bckMax > peakMin && bckMax < peakMax) {
-      g_log.notice() << "Background range overlaps with peak\n";
-      bckMax = peakMin - 1;
-    }
-    if (bckMin < peakMax && bckMin > peakMin) {
-      g_log.notice() << "Background range overlaps with peak\n";
-      bckMin = peakMax + 1;
-    }
-
-    if (integrateY) {
-      xmin = bckMin;
-      xmax = bckMax;
-    } else {
-      ymin = bckMin;
-      ymax = bckMax;
-    }
-
-    IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.6, 0.65);
-    refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS);
-    refAlg->setProperty("NXPixel", NX_PIXELS);
-    refAlg->setProperty("NYPixel", NY_PIXELS);
-    refAlg->setProperty("ConvertToQ", false);
-    refAlg->setProperty("SumPixels", true);
-    refAlg->setProperty("NormalizeSum", true);
-    refAlg->setProperty("AverageOverIntegratedAxis", integrateY);
-    refAlg->setProperty("YPixelMin", ymin);
-    refAlg->setProperty("YPixelMax", ymax);
-    refAlg->setProperty("XPixelMin", xmin);
-    refAlg->setProperty("XPixelMax", xmax);
-    refAlg->setProperty("IntegrateY", integrateY);
-    refAlg->executeAsChildAlg();
-
-    MatrixWorkspace_sptr cropWS = refAlg->getProperty("OutputWorkspace");
-
-    dataWS = dataWS - cropWS;
-    return dataWS;
-  }
-}
-
-} // namespace Algorithms
-} // namespace Mantid
diff --git a/Framework/WorkflowAlgorithms/test/ExtractQENSMembersTest.h b/Framework/WorkflowAlgorithms/test/ExtractQENSMembersTest.h
index 044e013d5764b5d0268098caa6e413ccf71c5b01..592fac50c42b58868b2dafc16f4149087169e173 100644
--- a/Framework/WorkflowAlgorithms/test/ExtractQENSMembersTest.h
+++ b/Framework/WorkflowAlgorithms/test/ExtractQENSMembersTest.h
@@ -178,7 +178,7 @@ private:
   createResultWorkspace(const std::vector<std::string> &members,
                         const std::vector<double> &dataX) const {
     MatrixWorkspace_sptr resultWorkspace =
-        WorkspaceCreationHelper::create2DWorkspaceBinned(
+        WorkspaceCreationHelper::create2DWorkspaceNonUniformlyBinned(
             static_cast<int>(members.size()), static_cast<int>(dataX.size()),
             dataX.data());
 
diff --git a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
index 60ba8ec8af9dca4f860780070893f0a65703b4ff..86b61dde7b133862eda4e5d65732a9a20a5fea3d 100644
--- a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
+++ b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
@@ -16,7 +16,7 @@ using Mantid::WorkflowAlgorithms::IMuonAsymmetryCalculator;
 using Mantid::WorkflowAlgorithms::MuonGroupCountsCalculator;
 using Mantid::WorkflowAlgorithms::MuonGroupAsymmetryCalculator;
 using Mantid::WorkflowAlgorithms::MuonPairAsymmetryCalculator;
-typedef std::unique_ptr<IMuonAsymmetryCalculator> IMuonAsymCalc_uptr;
+using IMuonAsymCalc_uptr = std::unique_ptr<IMuonAsymmetryCalculator>;
 
 /**
  * Tests for all classes deriving from IMuonAsymmetryCalculator:
diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt
index 14147fcf7c18fde969c2d50b0897df1be755348e..60cfcede842792ab7832b83c275e891d8792452b 100644
--- a/MantidPlot/CMakeLists.txt
+++ b/MantidPlot/CMakeLists.txt
@@ -740,7 +740,6 @@ copy_files_to_dir ( "${PY_FILES}"
 set( MTDPLOTPY_FILES
   __init__.py
   proxies.py
-  pyplot.py
   qtiplot.py
 )
 copy_files_to_dir ( "${MTDPLOTPY_FILES}"
@@ -893,7 +892,6 @@ set ( MANTIDPLOT_TEST_PY_FILES
     MantidPlotMdiSubWindowTest.py
     MantidPlotTiledWindowTest.py
     MantidPlotInputArgsCheck.py
-    MantidPlotPyplotGeneralTest.py
 )
 
 if ( MAKE_VATES )
diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in
index 03a8e72da8343eeb8bfa6f635ed4962b19e231ff..9653a13085df0d4c937e385c000b5ffcc4b5301a 100755
--- a/MantidPlot/make_package.rb.in
+++ b/MantidPlot/make_package.rb.in
@@ -317,7 +317,8 @@ end
 #Copy over python libraries not included with OSX.
 #currently missing epics
 path = "/Library/Python/2.7/site-packages"
-directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"]
+directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports", "qtawesome", "qtpy",
+               "certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"]
 directories.each do |directory|
   addPythonLibrary("#{path}/#{directory}","Contents/MacOS/")
 end
diff --git a/MantidPlot/mantidplot.py b/MantidPlot/mantidplot.py
index af726851aca867f785646bcbed40dca11e647d8e..c038cd11e64a9c49fcb36b47f01cd46a75ae45d6 100644
--- a/MantidPlot/mantidplot.py
+++ b/MantidPlot/mantidplot.py
@@ -10,8 +10,5 @@ from __future__ import (absolute_import, division,
 import pymantidplot
 from pymantidplot import *
 
-# import pyplot and also bring it into the standard MantidPlot namespace
-import pymantidplot.pyplot
-from pymantidplot.pyplot import *
 # and the old qtiplot stuff
 import pymantidplot.qtiplot
diff --git a/MantidPlot/pymantidplot/pyplot.py b/MantidPlot/pymantidplot/pyplot.py
deleted file mode 100644
index 00d2763ca14fab8b58293ae8ab27a45f77ff58a8..0000000000000000000000000000000000000000
--- a/MantidPlot/pymantidplot/pyplot.py
+++ /dev/null
@@ -1,1598 +0,0 @@
-"""============================================================================
-New Python command line interface for plotting in Mantid (a la matplotlib)
-============================================================================
-
-The idea behind this new module is to provide a simpler, more
-homogeneous command line interface (CLI) to the Mantid plotting
-functionality. This new interface is meant to resemble matplotlib as
-far as possible, and to provide a more manageable, limited number of
-plot options.
-
-The module is at a very early stage of development and provides
-limited functionality. This is very much work in progress at the
-moment. The module is subject to changes and feedback is very much
-welcome!
-
-Simple plots can be created and manipulated with a handul of
-commands. See the following examples.
-
-Plot an array (python list)
----------------------------
-
-.. code-block:: python
-
-    # plot array
-    plot([0.1, 0.3, 0.2, 4])
-    # plot x-y
-    plot([0.1, 0.2, 0.3, 0.4], [1.2, 1.3, 0.2, 0.8])
-
-Plot an array with a different style
-------------------------------------
-
-The plot commands that are described here accept a list of options
-(kwargs) as parameters passed by name. With these options you can
-modify plot properties, such as line styles, colors, axis scale,
-etc. The following example illustrates the use of a few options. You
-can refer to the list of options provided further down in this
-document. In principle, any combination of options is supported, as
-long as it makes sense!
-
-.. code-block:: python
-
-    a = [0.1, 0.3, 0.2, 4]
-    plot(a)
-    import numpy as np
-    y = np.sin(np.linspace(-2.28, 2.28, 1000))
-    plot(y, linestyle='-.', marker='o', color='red')
-
-If you have used the traditional Mantid command line interface in
-Python you will probably remember the plotSpectrum, plotBin and plotMD
-functions. These are supported in this new interface as shown in the
-following examples.
-
-Plot a Mantid workspace
------------------------
-
-You can pass one or more workspaces to the plot function. By default
-it will plot the spectra of the workspace(s), selecting them by the
-indices specified in the second argument. This behavior is similar to
-the plotSpectrum function of the traditional mantidplot module. This is
-a simple example that produces plots of spectra:
-
-.. code-block:: python
-
-    # first, load a workspace. You can do this with a Load command or just from the GUI menus
-    ws = Load("/path/to/MAR11060.raw", OutputWorkspace="foo")
-    # 1 spectrum plot
-    plot(ws, 100)
-    # 3 spectra plot
-    plot(ws, [100, 101, 102])
-
-========================
-Different types of plots
-========================
-
-The plot() function provides a unified interface to different types of
-plots, including specific graphs of spectra, bins, multidimensional
-workspaces, etc. These specific types of plots are explained in the
-next sections. plot() makes a guess as to what tool to use to plot a
-workspace. For example, if you pass an MD workspace it will make an MD
-plot. But you can request a specific type of plot by specifying a
-keyword argument ('tool'). The following tools (or different types of
-plots) are supported:
-
-+------------------------+------------------------------------------------------------+-----------------------+
-| Tool                   | tool= parameter values (all are equivalent aliases)        | Old similar function  |
-+========================+============================================================+=======================+
-| plot spectra (default) | 'plot_spectrum', 'spectrum', 'plot_sp', 'sp'               | plotSpectrum          |
-+------------------------+------------------------------------------------------------+-----------------------+
-| plot bins              | 'plot_bin', 'bin'                                          | plotBin               |
-+------------------------+------------------------------------------------------------+-----------------------+
-| plot MD                | 'plot_md', 'md'                                            | plotMD                |
-+------------------------+------------------------------------------------------------+-----------------------+
-
-The last column of the table lists the functions that produce similar
-plots in the traditional MantidPlot Python plotting interface. For the
-time being this module only supports these types of specific
-plots. Note that the traditional plotting interface of MantidPlot
-provides support for many more specific types of plots. These or
-similar ones will be added in this module in future releases:
-
-* plot2D
-* plot3D
-* plotSlice
-* instrumentWindow
-* waterFallPlot
-* mergePlots
-* stemPlot
-
-Plot spectra using workspace objects and workspace names
---------------------------------------------------------
-
-It is also possible to pass workspace names to plot, as in the
-following example where we plot a few spectra:
-
-.. code-block:: python
-
-    # please make sure that you use the right path and file name
-    mar = Load('/path/to/MAR11060.raw', OutputWorkspace="MAR11060")
-    plot('MAR11060', [10,100,500])
-    plot(mar,[3, 500, 800])
-
-Let's load one more workspace so we can see some examples with list of
-workspaces
-
-.. code-block:: python
-
-    loq=Load('/path/to/LOQ48097.raw', OutputWorkspace="LOQ48097")
-
-The next lines are all equivalent, you can use workspace objects or
-names in the list passed to plot:
-
-.. code-block:: python
-
-    plot([mar, 'LOQ48097'], [800, 900])
-    plot([mar, loq], [800, 900])
-    plot(['MAR11060', loq], [800, 900])
-
-Here, the plot function is making a guess and plotting the spectra of
-these workspaces (instead of the bins or anything else). You can make
-that choice more explicit by specifying the 'tool' argument. In this
-case we use 'plot_spectrum' (which also has shorter aliases:
-'spectrum', or simply 'sp' as listed in the table above):
-
-.. code-block:: python
-
-    plot(['MAR11060', loq], [800, 900], tool='plot_spectrum')
-    plot(['MAR11060', loq], [801, 901], tool='sp')
-
-Alternatively, you can use the plot_spectrum command, which is
-equivalent to the plot command with the keyword argument
-tool='plot_spectrum':
-
-.. code-block:: python
-
-    plot_spectrum(['MAR11060', loq], [800, 900])
-
-Plotting bins
--------------
-
-To plot workspace bins you can use the keyword 'tool' with the value
-'plot_bin' (or equivalent 'bin'), like this:
-
-.. code-block:: python
-
-    ws = Load('/path/to/HRP39182.RAW', OutputWorkspace="HRP39182")
-    plot(ws, [1, 5, 7, 100], tool='plot_bin')
-
-or, alternatively, you can use the plot_bin command:
-
-.. code-block:: python
-
-    plot_bin(ws, [1, 5, 7, 100], linewidth=4, linestyle=':')
-
-Plotting MD workspaces
-----------------------
-
-Similarly, to plot MD workspaces you can use the keyword 'tool' with
-the value 'plot_md' (or 'md' as a short alias), like this:
-
-.. code-block:: python
-
-    simple_md_ws = CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='x,y,z',Units='m,m,m',SplitInto='5',MaxRecursionDepth='20',OutputWorkspace=MDWWorkspaceName)
-    plot(simple_md_ws, tool='plot_md')
-
-or a specific plot_md command:
-
-.. code-block:: python
-
-    plot_md(simple_md_wsws)
-
-For simplicity, these examples use a dummy MD workspace. Please refer
-to the Mantid (http://www.mantidproject.org/MBC_MDWorkspaces) for a
-more real example, which necessarily gets more complicated and data
-intensive.
-
-=========================
-Changing style properties
-=========================
-
-You can modify the style of your plots. For example like this (for a
-full list of options currently supported, see below).
-
-.. code-block:: python
-
-    lines = plot(loq, [100, 104], tool='plot_spectrum', linestyle='-.', marker='*', color='red')
-
-Notice that the plot function returns a list of lines, which
-correspond to the spectra lines. At present the lines have limited
-functionality. Essentially, the data underlying these lines can be
-retrieved as follows:
-
-.. code-block:: python
-
-    lines[0].get_xdata()
-    lines[0].get_ydata()
-
-If you use plot_spectrum, the number of elements in the output lines
-should be equal to the number of bins in the corresponding
-workspace. Conversely, if you use plot_bin, the number of elements in
-the output lines should be equal to the number of spectra in the
-workspace.
-
-To modify the figure, you first need to obtain the figure object
-that represents the figure where the lines are displayed. Once you do
-so you can for example set the title of the figure like this:
-
-.. code-block:: python
-
-    fig = lines[0].figure()
-    fig.suptitle('Example figure title')
-
-Other properties can be modified using different functions, as in
-matplotlib's pyplot. For example:
-
-.. code-block:: python
-
-    title('Test plot of LOQ')
-    xlabel('ToF')
-    ylabel('Counts')
-    ylim(0, 8)
-    xlim(1e3, 4e4)
-    xscale('log')
-    grid('on')
-
-By default, these functions manipulate the current figure (the last or
-most recently shown figure). You can also save the current figure into
-a file like this:
-
-.. code-block:: python
-
-    savefig('example_saved_figure.png')
-
-where the file format is guessed from the file extension. The same
-extensions as in the MantidPlot figure export dialog are supported,
-including jpg, png, tif, ps, and svg.
-
-The usage of these functions very similar to the matlab and/or
-pyplot functions with the same names. The list of functions
-currently supported is provided further below.
-
-Additional options supported as keyword arguments (kwargs):
------------------------------------------------------------
-
-There is a couple of important plot options that are set as keyword
-arguments:
-
-
-+------------+------------------------+
-|Option name | Values supported       |
-+============+========================+
-|error_bars  | True, False (default)  |
-+------------+------------------------+
-|hold        | on, off                |
-+------------+------------------------+
-
-error_bars has the same meaning as in the traditional mantidplot plot
-functions: it defines whether error bars should be added to the
-plots. hold has the same behavior as in matplotlib and pyplot. If the
-value of hold is 'on' in a plot command, the new plot will be drawn on
-top of the current plot window, without clearing it. This makes it
-possible to make plots incrementally.
-
-For example, one can add two spectra from a workspace using the
-following command:
-
-.. code-block:: python
-
-    lines = plot(loq, [100, 102], linestyle='-.', color='red')
-
-But similar results can be obtained by plotting one of the spectra by
-a first command, and then plotting the second spectra in a subsequent
-command with the hold parameter enabled:
-
-.. code-block:: python
-
-    lines = plot(loq, 100, linestyle='-.', color='red')
-    lines = plot(loq, 102, linestyle='-.', color='blue', hold='on')
-
-After the two commands above, any subsequent plot command that passes
-hold='on' as a parameter would add new spectra into the same plot. An
-alternative way of doing this is explained next. Note however that
-using the hold property to combine different types of plots
-(plot_spectrum, plot_bin, etc.) will most likely produce useless
-results.
-
-Multi-plot commands
--------------------
-
-In this version of pyplot there is limited support for multi-plot
-commands (as in pyplot and matlab). For example, you can type commands
-like the following:
-
-.. code-block:: python
-
-    plot(ws, [100, 101], 'r', ws, [200, 201], 'b', tool='plot_spectrum')
-
-This command will plot spectra 100 and 101 in red and spectra 200 and
-201 in blue on the same figure. You can also combine different
-workspaces, for example:
-
-.. code-block:: python
-
-    plot(ws, [100, 101], 'r', mar, [50, 41], 'b', tool='plot_spectrum')
-
-
-Style options supported as keyword arguments
---------------------------------------------
-
-Unless otherwise stated, these options are in principle supported in
-all the plot variants. These options have the same (or as closed as
-possible) meaning as in matplotlib.
-
-+------------+---------------------------------------------------------+
-|Option name | Values supported                                        |
-+============+=========================================================+
-|linewidth   | real values                                             |
-+------------+---------------------------------------------------------+
-|linestyle   | '-', '--', '-.' '.'                                     |
-+------------+---------------------------------------------------------+
-|marker      | None/"None" 'o', 'v', '^', '<', '>', 's', '*',          |
-|            | 'h', '|', '_'                                           |
-+------------+---------------------------------------------------------+
-|color       |  color character or string ('b', 'blue', 'g', 'green',  |
-|            |  'k', 'black', 'y', 'yellow', 'c', 'cyan', 'r', 'red'.  |
-|            |  'm', 'magenta', etc.). RGB colors are not supported at |
-|            |  the moment.                                            |
-+------------+---------------------------------------------------------+
-
-Modifying the plot axes
------------------------
-
-You can modify different properties of the plot axes via functions, as
-seen before. This includes the x and y axis titles, limits and scale
-(linear or logarithmic). For example:
-
-.. code-block:: python
-
-    ylabel('Counts')
-    ylim(0, 8)
-    yscale('log')
-
-An alternative is to use equivalent methods provided by the Figure and
-Axes objects. For this you first need to retrieve the figure and axes
-where a plot (or line) has been shown.
-
-.. code-block:: python
-
-    lines = plot(mar,[3, 500, 800])
-    fig = lines[0].figure()
-    all_ax = fig.axes()    # fig.axes() returns in principle a list
-    ax = all_ax[0]         #  but we only use one axes
-    ax.set_ylabel('Counts')
-    ax.set_xlabel('ToF')
-    ax.set_ylim(0, 8)
-    ax.set_xlim(1e2, 4e4)
-    ax.set_xscale('log')
-
-Functions that modify plot properties
--------------------------------------
-
-Here is a list of the functions supported at the moment. They offer
-the same functionality as their counterparts in matplotlib's
-pyplot.
-
-- title
-- xlabel
-- ylabel
-- ylim
-- xlim
-- axis
-- xscale
-- yscale
-- grid
-- savefig
-
-This is a limited list of functions that should be sufficient for
-basic plots. These functions are presently provided as an example of
-this type of interface, and some of them provide functionality similar
-or equivalent to several of the keyword arguments for plot commands
-detailed in this documentation. Some others produce results equivalent
-to the more object oriented methods described above. For example, the
-function xlabel is equivalent to the method set_xlabel applied on the
-Axes object for the current figure.
-
-This module is by default imported into the standard MantidPlot
-namespace. You can use the functions and classes included here without
-any prefix or adding this module name prefix (pymantidplot.pyplot), as
-in the following example:
-
-.. code-block:: python
-
-    # Two equivalent lines:
-    pymantidplot.pyplot.plot([1, 3, 2])
-    plot([1, 3, 2])
-
-Note that the plot() function of this module has replaced the
-traditional plot() function of MantidPlot which has been moved into a
-package called qtiplot. To use it you can do as follows:
-
-.. code-block:: python
-
-    pymantidplot.qtiplot.plot('MAR11060', [800, 801])
-    # or if you prefer shorter prefixes:
-    import pymantidplot.qtiplot as qtiplt
-    qtiplt.plot('MAR11060', [800, 801])
-
-
-Below is the reference documentation of the classes and functions
-included in this module.
-
-"""
-# Copyright &copy; 2014-2015 ISIS Rutherford Appleton Laboratory, NScD
-# Oak Ridge National Laboratory & European Spallation Source
-#
-# This file is part of Mantid.
-# Mantid is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# Mantid is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# File change history is stored at: <https://github.com/mantidproject/mantid>.
-# Code Documentation is available at: <http://doxygen.mantidproject.org>
-from __future__ import (absolute_import, division,
-                        print_function)
-
-try:
-    import _qti
-except ImportError:
-    raise ImportError('The \'mantidplot\' and \'pymantidplot.pyplot\' modules can only be used from within MantidPlot.')
-
-import numpy as np
-from PyQt4 import Qt, QtGui, QtCore
-from mantid.api import (IMDWorkspace as IMDWorkspace, MatrixWorkspace as MatrixWorkspace, AlgorithmManager as AlgorithmManager, AnalysisDataService as ADS)
-from mantid.api import mtd
-#    return __is_workspace(arg) or (mantid.api.mtd.doesExist(arg) and isinstance(mantid.api.mtd[arg], mantid.api.IMDWorkspace))
-try:
-    from mantid.simpleapi import CreateWorkspace
-except ImportError:
-    def CreateWorkspace(*args, **kwargs):
-        raise RuntimeError("CreateWorkspace function not available")
-
-import mantidplot
-import mantidqtpython
-from six import string_types
-
-class Line2D():
-    """
-    A very minimal replica of matplotlib.Line.Line2D. The true Line2D
-    is a sublcass of matplotlib.artist and provides tons of
-    functionality. At the moment this just provides get_xdata(),
-    get_ydata(), and figure() methods.  It also holds its Graph
-    object and through it it would be possible to provide
-    additional selected functionality. Keep in mind that providing
-    GUI line/plot manipulation functionality would require a proxy
-    for this class.
-    """
-
-    def __init__(self, graph, index, x_data, y_data, fig=None):
-        self._graph = graph
-        self._index = index   # will (may) be needed to change properties of this line
-        self._xdata = x_data
-        self._ydata = y_data
-        self._fig = fig
-
-    def get_xdata(self):
-        return self._xdata
-
-    def get_ydata(self):
-        return self._ydata
-
-    def figure(self):
-        return self._fig
-
-class Axes():
-    """
-    A very minimal replica of matplotlib.axes.Axes. The true Axes is a
-    sublcass of matplotlib.artist and provides tons of functionality.
-    At the moment this just provides a few set methods for properties
-    such as labels and axis limits.
-    """
-
-    """Many plot manipulation functions that are provided in
-    matplolib through Axes objects, for example to manipulate the x/y
-    ticks, are not currently supported. Objects of this class hold
-    their Figure object.  Presently every figure has a single Axes
-    object, and there is no support for multiple axes (as in
-    fig.add_axes() or fix.axes()).
-    """
-
-    def __init__(self, fig, xscale='linear', yscale='linear'):
-        self._fig = fig
-        # state of x and y scale kept here. C++ Graph.isLog() not yet exposed
-        self._xscale = xscale
-        self._yscale = yscale
-
-    def axis(self, lims):
-        """
-        Set the boundaries or limits of the x and y axes
-
-        @param lims :: list or vector specifying min x, max x, min y, max y
-        """
-        l = __last_fig()._graph.activeLayer()
-        if 4 != len(lims):
-            raise ValueError("Error: 4 real values are required for the x and y axes limits")
-        l.setScale(*lims)
-
-    def set_xlabel(self, lbl):
-        """
-        Set the label or title of the x axis
-
-        @param lbl :: x axis lbl
-        """
-        l = self.get_figure()._graph.activeLayer()
-        l.setXTitle(lbl)
-
-    def set_ylabel(self, lbl):
-        """
-        Set the label or title of the y axis
-
-        @param lbl :: y axis lbl
-        """
-        l = self.get_figure()._graph.activeLayer()
-        l.setYTitle(lbl)
-
-    def set_xlim(self, xmin, xmax):
-        """
-        Set the boundaries of the x axis
-
-        @param xmin :: minimum value
-        @param xmax :: maximum value
-        """
-        l = self.get_figure()._graph.activeLayer()
-        l.setAxisScale(2, xmin, xmax)
-
-    def set_ylim(self, ymin, ymax):
-        """
-        Set the boundaries of the y axis
-
-        @param ymin :: minimum value
-        @param ymax :: maximum value
-        """
-        l = self.get_figure()._graph.activeLayer()
-        l.setAxisScale(0, ymin, ymax)
-
-    def set_xscale(self, scale_str):
-        """
-        Set the type of scale of the x axis
-
-        @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale
-        """
-        if 'log' != scale_str and 'linear' != scale_str:
-            raise ValueError("You need to specify either 'log' or 'linear' type of scale for the x axis." )
-
-        l = self.get_figure()._graph.activeLayer()
-        if scale_str == 'log':
-            if 'log' == self._yscale:
-                l.logLogAxes()
-            else:
-                l.logXLinY()
-        elif scale_str == 'linear':
-            if 'log' == self._yscale:
-                l.logYlinX()
-            else:
-                l.linearAxes()
-        self._xscale = scale_str
-
-    def set_yscale(self, scale_str):
-        """
-        Set the type of scale of the y axis
-
-        @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale
-        """
-        if 'log' != scale_str and 'linear' != scale_str:
-            raise ValueError("You need to specify either 'log' or 'linear' type of scale for the y axis." )
-
-        l = self.get_figure()._graph.activeLayer()
-        if scale_str == 'log':
-            if 'log' == self._xscale:
-                l.logLogAxes()
-            else:
-                l.logYlinX()
-        elif scale_str == 'linear':
-            if 'log' == self._xscale:
-                l.logXLinY()
-            else:
-                l.linearAxes()
-        self._yscale = scale_str
-
-    def get_figure(self, ):
-        """
-        Get the figure where this Axes object is included
-
-        Returns :: figure object for the figure that contains this Axes
-        """
-        return self._fig
-
-
-class Figure():
-    """
-    A very minimal replica of matplotlib.figure.Figure. This class is
-    here to support manipulation of multiple figures from the command
-    line.
-    """
-
-    """For the moment this is just a very crude wrapper for Graph
-    (proxy to qti Multilayer), and it is here just to hide (the rather
-    obscure) Graph from users.
-    """
-    # Holds the set of figure ids (integers) as they're being created and/or destroyed
-    __figures = {}
-    # Always increasing seq number, not necessarily the number of figures in the dict
-    __figures_seq = 0
-
-    def __init__(self, num):
-        if isinstance(num, int):
-            # normal matplotlib use, like figure(2)
-            missing = -1
-            fig = Figure.__figures.get(num, missing)
-            if missing == fig:
-                self._graph = Figure.__empty_graph()
-                Figure.__figures[num] = self
-                if num > Figure.__figures_seq:
-                    Figure.__figures_seq = num
-                self._axes = Axes(self)
-            else:
-                if None == fig._graph._getHeldObject():
-                    # has been destroyed!
-                    self._graph = Figure.__empty_graph()
-                    self._axes = Axes(self)
-                else:
-                    self._graph = fig._graph
-                    self._axes = fig._axes
-        elif isinstance(num, mantidplot.proxies.Graph):
-            if None == num._getHeldObject():
-                # deleted Graph!
-                self._graph = Figure.__empty_graph()
-            else:
-                self._graph = num
-            num = Figure.__make_new_fig_number()
-            Figure.__figures[num] = self
-            self._axes = Axes(self)
-        else:
-            raise ValueError("To create a Figure you need to specify a figure number or a Graph object." )
-
-    def suptitle(self, title):
-        """
-        Set a title for the figure
-
-        @param title :: title string
-        """
-        l = self._graph.activeLayer()
-        l.setTitle(title)
-
-    def axes(self):
-        """
-        Obtain the list of axes in this figure.
-
-        Returns :: list of axes. Presently only one Axes object is supported
-                   and this method returns a single object list
-        """
-        return [self._axes]
-
-    def savefig(self, name):
-        """
-        Save current plot into a file. The format is guessed from the file extension (.eps, .png, .jpg, etc.)
-
-        @param name :: file name
-        """
-        if not name:
-            raise ValueError("Error: you need to specify a non-empty file name")
-        l = self._graph.activeLayer()
-        l.export(name);
-
-    @classmethod
-    def fig_seq(cls):
-        """ Helper method, returns the current sequence number for figures"""
-        return cls.__figures_seq
-
-    @classmethod
-    def __make_new_fig_number(cls):
-        """ Helper method, creates and return a new figure number"""
-        num = cls.__figures_seq
-        avail = False
-        while not avail:
-            missing = -1
-            fig = cls.__figures.get(num, missing)
-            if missing == fig:
-                avail = True   # break
-            else:
-                num += 1
-        cls.__figures_seq = num
-        return num
-
-    @staticmethod
-    def __empty_graph():
-        """Helper method, just create a new Graph with an 'empty' plot"""
-        lines = plot([0])
-        return lines._graph
-
-
-def __empty_fig():
-    """Helper function, for the functional interface. Makes a blank/empty figure"""
-    lines = plot([0]) # for the very first figure, this would generate infinite recursion!
-    return Figure(lines[0]._graph)
-
-# TODO/TOTHINK: no 'hold' function support for now. How to handle multi-plots with different types/tools? Does it make sense at all?
-__hold_status = False
-
-__last_shown_fig = None
-
-def __last_fig():
-    """
-        Helper function, especially for the functional interface.
-        Avoid using it inside the plot_spectrum, plot_bin, etc. as there's risk of infinite recursion
-        Returns :: last figure, creating new one if there was none
-    """
-    global __last_shown_fig
-    if not __last_shown_fig:
-        f = __empty_fig()
-        __last_shown_fig = f
-    return __last_shown_fig
-
-def __update_last_shown_fig(g):
-    """
-        Helper function, especially for the functional interface.
-        @param g :: graph object
-        Returns :: new last fig
-    """
-    global __last_shown_fig
-    __last_shown_fig = Figure(g)
-    return __last_shown_fig
-
-def __is_array(arg):
-    """
-        Is the argument a python or numpy list?
-        @param arg :: argument
-
-        Returns :: True if the argument is a python or numpy list
-    """
-    return isinstance(arg, list) or isinstance(arg, np.ndarray)
-
-def __is_array_or_int(arg):
-    """
-        Is the argument a valid workspace index/indices, which is to say:
-        Is the argument an int, or python or numpy list?
-        @param arg :: argument
-
-        Returns :: True if the argument is an integer, or a python or numpy list
-    """
-    return isinstance(arg, int) or __is_array(arg)
-
-
-def __is_registered_workspace_name(arg):
-    """"
-        Check whether the argument passed is the name of a registered workspace
-
-        @param arg :: argument (supposedly a workspace name)
-
-        Returns :: True if arg is a correct workspace name
-    """
-    return (isinstance(arg, string_types) and mtd.doesExist(arg) and isinstance(mtd[arg], IMDWorkspace))
-
-def __is_valid_single_workspace_arg(arg):
-    """"
-        Check whether the argument passed can be used as a workspace input. Note that this differs from
-        __is_workspace() in that workspace names are also accepted. Throws ValueError with informative
-        message if arg is not a valid workspace object or name.
-
-        @param arg :: argument (supposedly one workspace, possibly given by name)
-
-        Returns :: True if arg can be accepted as a workspace
-    """
-    if __is_workspace(arg) or __is_registered_workspace_name(arg):
-        return True
-    else:
-        return False
-
-def __is_valid_workspaces_arg(arg):
-    """"
-        Check whether the argument passed can be used as a workspace(s) input. Note that this differs from
-        __is_workspace() in that lists of workspaces and workspace names are also accepted.
-
-        @param arg :: argument (supposedly one or more workspaces, possibly given by name)
-
-        Returns :: True if arg can be accepted as a workspace or a list of workspaces
-    """
-    if __is_valid_single_workspace_arg(arg):
-        return True
-    else:
-        if 0 == len(arg):
-            return False
-        for name in arg:
-            # name can be a workspace name or a workspace object
-            try:
-                __is_valid_single_workspace_arg(name)
-            except:
-                raise ValueError("This parameter passed in a list of workspaces is not a valid workspace: " + str(name))
-    return True
-
-def __is_data_pair(a, b):
-    """
-        Are the two arguments passed (a and b) a valid data pair for plotting, like in plot(x, y) or
-        plot(ws, [0, 1, 2])?
-        @param a :: first argument passed (supposedly array or workspace(s))
-        @param b :: second argument (supposedly an array of values, or indices)
-
-        Returns :: True if the arguments can be used to plot something is an integer, or a python or numpy list
-    """
-    res = (__is_array(a) and __is_array(b)) or (__is_valid_workspaces_arg(a) and __is_array_or_int(b))
-    return res
-
-def __is_workspace(arg):
-    """
-        Is the argument a Mantid MatrixWorkspace?
-        @param arg :: argument
-
-        Returns :: True if the argument a MatrixWorkspace
-    """
-    return isinstance(arg, MatrixWorkspace)
-
-def __is_array_of_workspaces(arg):
-    """
-        Is the argument a sequence of Mantid MatrixWorkspaces?
-        @param arg :: argument
-
-        Returns :: True if the argument is a sequence of  MatrixWorkspace
-    """
-    return __is_array(arg) and len(arg) > 0 and __is_workspace(arg[0])
-
-
-def __create_workspace(x, y, name="__array_dummy_workspace"):
-    """
-        Create a workspace. Also puts it in the ADS with __ name
-        @param x :: x array
-        @param y :: y array
-        @param name :: workspace name
-
-        Returns :: Workspace
-    """
-    alg = AlgorithmManager.create("CreateWorkspace")
-    alg.setChild(True)
-    alg.initialize()
-    # fake empty workspace (when doing plot([]), cause setProperty needs non-empty data)
-    if [] == x:
-        x = [0]
-    if [] == y:
-        y = [0]
-    alg.setProperty("DataX", x)
-    alg.setProperty("DataY", y)
-    name = name + "_" + str(Figure.fig_seq())
-    alg.setPropertyValue("OutputWorkspace", name)
-    alg.execute()
-    ws = alg.getProperty("OutputWorkspace").value
-    ADS.addOrReplace(name, ws) # Cannot plot a workspace that is not in the ADS
-    return ws
-
-
-def __list_of_lines_from_graph(g, first_line=0):
-    """
-        Produces a python list of line objects, with one object per line plotted on the passed graph
-        Note: at the moment these objects are of class Line2D which is much simpler than matplotlib.lines.Line2D
-        This function should always be part of the process of creating a new figure/graph, and it guarantees
-        that this figure being created is registered as the last shown figure.
-
-        @param g :: graph (with several plot layers = qti Multilayer)
-        @param first_line :: index to start from (useful for hold='on', multi-plots, etc.)
-
-        Returns :: List of line objects
-    """
-    if None == g:
-        raise ValueError("Got empty Graph object, cannot get its lines." )
-    # assume we use a single layer
-    active = g.activeLayer()
-    res = []
-    for i in range(first_line, active.numCurves()):
-        x_data = []
-        y_data = []
-        d = active.curve(i).data()
-        for i in range(0, active.curve(i).data().size()):
-            x_data.append(d.x(i))
-            y_data.append(d.y(i))
-        res.append(Line2D(g, i, x_data, y_data))
-
-    fig = __update_last_shown_fig(g)
-    for lines in res:
-        lines._fig = fig
-
-    return res;
-
-def __matplotlib_defaults(l):
-    """
-        Tries to (approximately) mimic the default plot properties of a pylab.plot()
-        @param l :: layer (plot) from a mantidplot Graph object
-
-        Returns :: nothing, just modifies properties of the layer passed
-    """
-    if None == l:
-        raise ValueError("Got empty Layer object, cannot modify its properties." )
-    l.removeLegend()
-    for i in range(0, l.numCurves()):
-        l.setCurveLineColor(i, __color_char_to_color_idx['b'])
-    l.setTitle(' ')
-    l.setXTitle(' ')
-    l.setYTitle(' ')
-
-__marker_to_plotsymbol = {
-    None: _qti.PlotSymbol.NoSymbol, "None": _qti.PlotSymbol.NoSymbol,
-    'o': _qti.PlotSymbol.Ellipse, 'v': _qti.PlotSymbol.DTriangle, '^': _qti.PlotSymbol.UTriangle,
-    '<': _qti.PlotSymbol.LTriangle, '>': _qti.PlotSymbol.RTriangle, 's': _qti.PlotSymbol.Rect,
-    '*': _qti.PlotSymbol.Star1, 'h': _qti.PlotSymbol.Hexagon, '|': _qti.PlotSymbol.VLine,
-    '_': _qti.PlotSymbol.HLine
-}
-
-"""Contains all the supported line styles"""
-__linestyle_to_qt_penstyle = {
-    '-': QtCore.Qt.SolidLine, '--': QtCore.Qt.DashLine,
-    '-.': QtCore.Qt.DashDotLine, ':': QtCore.Qt.DotLine
-} # other available: Qt.DashDotDotLine, Qt.CustomDashLine
-
-def __apply_linestyle(graph, linestyle, first_line=0):
-    """
-        Sets the linestyle of lines/curves of the active layer of the graph passed
-
-        @param graph :: mantidplot graph (figure)
-        @param linestyle :: linestyle string
-        @param first_line :: index of first line to which the linestyle will apply
-                             (useful when in hold mode / adding lines)
-
-        Returns :: nothing, just modifies the line styles of the active layer of the graph passed
-    """
-    global __linestyle_to_qt_penstyle
-    wrong = 'inexistent'
-    penstyle = __linestyle_to_qt_penstyle.get(linestyle, wrong)
-    if wrong == penstyle:
-        raise ValueError("Wrong linestyle given, unrecognized: " + linestyle)
-    l = graph.activeLayer()
-    for i in range(first_line, l.numCurves()):
-        l.setCurveLineStyle(i, penstyle)
-
-# beware this is not Qt.Qt.color_name (black, etc.)
-__color_char_to_color_idx = {
-    'k': 0, 'r': 1, 'g': 2, 'b': 3, 'c': 4, 'm': 5, 'y': 18,
-    'black': 0, 'red': 1, 'green': 2, 'blue': 3, 'cyan': 4, 'magenta': 5, 'orange': 6,
-    'purple': 7, 'darkGreen': 8, 'darkBlue': 9, 'brown': 10, 'gray': 17, 'yellow': 18
-}
-
-def __apply_line_color(graph, c, first_line=0):
-    """
-        Sets the color of curves of the active layer of the graph passed
-
-        @param graph :: mantidplot graph (figure)
-        @param c :: color string
-        @param first_line :: index of first line to which the color will apply
-                             (useful when in hold mode / adding lines)
-
-        Returns :: nothing, just modifies the line styles of the active layer of the graph passed
-    """
-    inex = 'inexistent'
-    col_idx = __color_char_to_color_idx.get(c, inex)
-    if inex == col_idx:
-        col_idx = QtGui.QColor(c)
-    l = graph.activeLayer()
-    for i in range(first_line, l.numCurves()):
-        l.setCurveLineColor(i, col_idx) # beware this is not Qt.Qt.black, but could be faked with QtGui.QColor("orange")
-
-def __apply_marker(graph, marker, first_line=0):
-    """
-        Sets the marker of curves of the active layer of the graph passed
-
-        @param graph :: mantidplot graph (figure)
-        @param marker :: line marker character
-        @param first_line :: index of first line to which the color will apply
-                             (useful when in hold mode / adding lines)
-
-        Returns :: nothing
-    """
-    wrong = 'inexistent'
-    sym_code = __marker_to_plotsymbol.get(marker, wrong)
-    if wrong == sym_code:
-        raise ValueError("Warning: unrecognized marker: " + str(marker))
-    sym = _qti.PlotSymbol(sym_code, QtGui.QBrush(), QtGui.QPen(), QtCore.QSize(5,5))
-    l = graph.activeLayer()
-    for idx in range(first_line, l.numCurves()):
-        l.setCurveSymbol(idx, sym)
-
-def __is_marker(char):
-    """ Is it a marker character
-        @param char :: suspected marker character coming from a linestyle string
-        Returns :: True if it's a marker character
-    """
-    inex = 'inexistent'
-    m = __marker_to_plotsymbol.get(char, inex)
-    return m != inex
-
-__linestyle_to_qt_penstyle = {
-    '-': QtCore.Qt.SolidLine, '--': QtCore.Qt.DashLine,
-    '-.': QtCore.Qt.DashDotLine, ':': QtCore.Qt.DotLine
-} # other available: Qt.DashDotDotLine, Qt.CustomDashLine
-
-def __is_linestyle(stl, i):
-    """
-        Check if we have a linestyle string in string s at position i
-        @param stl :: input (style) string, for example: '-.g', 'r', ':b'
-        @param i :: index where to start checking in string s
-
-        Returns :: 0 if no linestyle string is identified, length of the string (1 or 2) otherwise
-    """
-    global __linestyle_to_qt_penstyle
-
-    if len(stl) <= i:
-        return 0
-
-    if len(stl) > i+1:
-        if '-' == stl[i+1] or '.' == stl[i+1]:
-            # can check 2 chars
-            wrong = 'inexistent'
-            penstyle = __linestyle_to_qt_penstyle.get(stl[i:i+2], wrong)
-            if wrong != penstyle:
-                return 2
-
-    if '-'==stl[i] or ':'==stl[i]:
-        return 1
-    else:
-        return 0
-
-def __apply_plot_args(graph, first_line, *args):
-    """
-        Applies args, like '-r' etc.
-        @param graph :: a graph (or figure) that can contain multiple layers
-        @param first_line :: first line to which the options will apply (useful when in hold mode / adding lines)
-        @param args :: plot arguments
-
-        Returns :: nothing, just uses kwargs to modify properties of the layer passed
-    """
-    if None==graph or len(args) < 1 or ((),) == args:
-        return
-
-    for a in args:
-        if isinstance(a, string_types):
-            # this will eat characters as they come, without minding much the past/previous characters
-            # users can chain as many modifiers as they wish. It could be modified to be more strict/picky
-            i = 0
-            while i < len(a):
-                linestyle_len = __is_linestyle(a,i)
-                if linestyle_len > 0:
-                    __apply_linestyle(graph, a[i:i+linestyle_len], first_line)
-                    i += linestyle_len
-                elif __is_marker(a[i]):
-                    __apply_marker(graph, a[i:], first_line)
-                    i += 1
-                elif a[i].isalpha():
-                    __apply_line_color(graph, a[i], first_line)
-                    i += 1
-                else:
-                    # TOTHINK - error here? like this? sure? or just a warning?
-                    raise ValueError("Unrecognized character in input string: " + str(a[i]))
-        else:
-            raise ValueError("Expecting style string, but got an unrecognized input parameter: " + str(a) + ", of type: " + str(type(a)))
-
-def __apply_plot_kwargs(graph, first_line=0, **kwargs):
-    """
-        Applies kwargs
-        @param graph :: a graph (or figure) that can contain multiple layers
-
-        Returns :: nothing, just uses kwargs to modify properties of the layer passed
-    """
-    if None==graph or None==kwargs or ((),) == kwargs:
-        return
-
-    for key in kwargs:
-        if 'linestyle' == key:
-            __apply_linestyle(graph, kwargs[key])
-
-        elif 'linewidth' == key:
-            l = graph.activeLayer()
-            for i in range(first_line, l.numCurves()):
-                l.setCurveLineWidth(i, kwargs[key])
-
-        elif 'color' == key:
-            __apply_line_color(graph, kwargs[key], first_line)
-
-        elif 'marker' == key:
-            __apply_marker(graph, kwargs[key], first_line)
-
-def __is_multiplot_command(*args, **kwargs):
-    """
-        Finds out if the passed *args make a valid multi-plot command. At the same time, splits the
-        multi-plot command line into individual plot commands.
-
-        @param args :: curve data and options.
-        @param kwargs :: plot keyword options
-
-        Returns :: tuple: (boolean: whether it is a multiplot command, list of single plot commands as tuples)
-    """
-    # A minimum multi-plot command would be plot(x, y, z, w) or plot(ws1, idx1, ws2, idx2)
-    nargs = len(args)
-    # this will be a list with the sequence of individual plots (a tuples, each describing a single plot)
-    plots_seq = []
-    if nargs < 4:
-        return (False, [])
-    i = 0
-    while i < nargs:
-        a = []
-        b = []
-        style = ''
-        if (nargs-i) >= 3:
-            if __is_data_pair(args[i], args[i+1]):
-                a = args[i]
-                b = args[i+1]
-                i += 2
-            else:
-                return (False, []);
-            # can have style string, but don't get confused with single workspace name strings!
-            if (not __is_registered_workspace_name(args[i])) and isinstance(args[i], string_types):
-                style = args[i]
-                i += 1
-            plots_seq.append((a,b,style))
-
-        elif (nargs-i) >= 2:
-            if __is_data_pair(args[i], args[i+1]):
-                a = args[i]
-                b = args[i+1]
-                i += 2
-            else:
-                return (False, [])
-            plots_seq.append((a, b, ''))
-
-        elif (nargs-i) > 0:
-            raise ValueError("Not plottable. I do not know what to do with this last parameter: " + args[i] + ", of type " + str(type(args)))
-
-    return (i == nargs, plots_seq)
-
-def __process_multiplot_command(plots_seq, **kwargs):
-    """
-        Make one plot at a time when given a multi-plot command.
-
-        @param plots_seq :: list of individual plot parameters
-        @param kwargs :: plot style options
-
-        Returns :: the list of curves included in the plot
-    """
-    lines = []
-    if len(plots_seq) >= 1:
-        if not 'hold' in kwargs:
-            kwargs['hold'] = 'off'
-        lines = plot(*(plots_seq[0]), **kwargs)
-    for i in range(1, len(plots_seq)):
-        kwargs['hold'] = 'on'
-        lines.extend(plot(*(plots_seq[i]), **kwargs))
-    return lines
-
-def __translate_hold_kwarg(**kwargs):
-    """
-    Helper function to translate from hold='on'/'off' kwarg to a True/False value for the
-    mantidplot window and window error_bars
-
-    @param kwargs :: keyword arguments passed to a plot function, this function only cares about hold. Any
-                     value different from 'on' will be considered as 'off'
-
-    Returns :: tuple with a couple of values: True/False value for window, and True/False for clearWindow,
-               to be used with plotSpectrum, plotBin, etc.
-    """
-    # window and clearWindow
-    window_val = None
-    clearWindow_val = False
-    hold_name = 'hold'
-    missing_off = -1
-    str_val = kwargs.get(hold_name, missing_off)
-    if str_val != missing_off and str_val == 'on':
-        if None == __last_shown_fig:
-            window_val = None
-        else:
-            window_val = __last_fig()._graph
-        clearWindow_val = False
-
-    return window_val, clearWindow_val
-
-def __translate_error_bars_kwarg(**kwargs):
-    """
-    Helper function to translate from error_bars=True/False kwarg to a True/False value for the
-    mantidplot error_bars argument
-
-    @param kwargs :: keyword arguments passed to a plot function. This function only cares about 'error_bars'.
-                     Any value different from 'True' will be considered as 'False'
-
-    Returns :: True/False value for error_bars, to be used with plotSpectrum, plotBin, etc.
-
-    """
-    # error_bars param
-    bars_val = False
-    bars_name = 'error_bars'
-    missing_off = -1
-    str_val = kwargs.get(bars_name, missing_off)
-    if str_val != missing_off and str_val == 'True':
-        bars_val = True
-
-    return bars_val
-
-def __translate_distribution_kwarg(**kwargs):
-    """
-    Helper function to translate from distribution=DistributionDefault/DistributionTrue/DistributionFalse kwarg to a
-    mantidplot distribution argument
-
-    @param kwargs :: keyword arguments passed to a plot function. This function only cares about 'distribution'.
-
-    Returns :: DistributionDefault/DistributionTrue/DistributionFalse value for distribution, to be used with plotSpectrum, plotBin, etc.
-
-    """
-    # distribution param
-    distr_val = False
-    distr_name = 'distribution'
-    missing_off = mantidqtpython.MantidQt.DistributionDefault
-    str_val = kwargs.get(distr_name, missing_off)
-    if str_val != missing_off and str_val == 'DistributionTrue':
-        distr_val = mantidqtpython.DistributionTrue
-    elif str_val != missing_off and str_val == 'DistributionFalse':
-        distr_val = mantidqtpython.DistributionFalse
-
-    return distr_val
-
-def __plot_as_workspace(*args, **kwargs):
-    """
-        plot spectrum via qti plotting framework to plot a workspace.
-
-        @param args :: curve data and options.
-        @param kwargs :: plot line options
-
-        Returns :: List of line objects
-    """
-    return plot_spectrum(*args, **kwargs)
-
-def __plot_as_workspaces_list(*args, **kwargs):
-    """
-        Plot a series of workspaces
-        @param args :: curve data and options.
-        @param kwargs :: plot line options
-
-        Returns :: List of line objects
-    """
-    # mantidplot.plotSpectrum can already handle 1 or more input workspaces.
-    return __plot_as_workspace(*args, **kwargs)
-
-
-def __plot_as_array(*args, **kwargs):
-    """
-        Plot from an array
-        @param args :: curve data and options.
-        @param kwargs :: plot line options
-
-        Returns :: the list of curves (1) included in the plot
-    """
-    y = args[0]
-    idx_style = len(args)   # have to guess if we get plot(x,'r'), or plot(x, y, 'r') or no style string
-    if len(args) > 1:
-        if __is_array(args[1]):
-            ws = __create_workspace(y, args[1])
-            idx_style = 2
-        elif isinstance(args[1], string_types):
-            x = list(range(0, len(y), 1)) # 0 to n, incremented by 1.
-            ws = __create_workspace(x, y)
-            # have to assume that args[1] is a style string
-            idx_style = 1
-        else:
-            raise ValueError("Inputs are of type: " + str(type(args)) + ". Not plottable." )
-    else:
-        x = list(range(0, len(y), 1))
-        ws = __create_workspace(x, y)
-
-    lines = __plot_as_workspace(ws, [0], *args[idx_style:], **kwargs)
-    graph = None
-    if len(lines) > 0:
-        graph = lines[0]._graph
-    else:
-        raise Exception("Could not plot a workspace: " + ws)
-    # something to improve: if the C++ Graph class provided a plot1D that doesn't do show(), so that
-    # we could modify properties behind the scene and at the end do the show(). Con: do we really need
-    # to load the qti layer with more methods because of outer layers like here?
-    if 0 == len(kwargs):
-        __matplotlib_defaults(graph.activeLayer())
-    return __list_of_lines_from_graph(graph)
-
-def __plot_with_tool(tool, *args, **kwargs):
-    bin_tool_names = ['plot_bin', 'bin']
-    spectrum_tool_names = ['plot_spectrum', 'plot_sp', 'spectrum', 'sp']
-    md_tool_names = ['plot_md', 'md']
-
-    if len(args) < 2:
-        if tool in bin_tool_names:
-            raise ValueError("To plot bins (using '%s' as tool) you need to give at least two parameters, where the second parameter selects the bins"%tool)
-        elif tool in spectrum_tool_names:
-            raise ValueError("To plot spectra (using '%s' as tool) you need to give at least two parameters, where the second parameter selects the spectrum(a)"%tool)
-
-    if tool in bin_tool_names:
-        return plot_bin(args[0], args[1], *args[2:], **kwargs)
-    elif tool in md_tool_names:
-        return plot_md(args[0], *args[1:], **kwargs)
-    elif tool in spectrum_tool_names:
-        return plot_spectrum(args[0], args[1], *args[2:], **kwargs)
-    # here you would add slice/spectrum/instrument viewer, etc. and maybe you'll want to put them in a dict
-    else:
-        raise ValueError("Unrecognized tool specified: '" + tool + ";. Cannot plot this. ")
-
-def __plot_with_best_guess(*args, **kwargs):
-    y = args[0]
-    if __is_array(y):
-        if __is_array_of_workspaces(y):
-            return __plot_as_workspaces_list(*args, **kwargs)
-        else:
-            return __plot_as_array(*args, **kwargs)
-    else:
-        # mantidplot.plotSpectrum can handle workspace names (strings)
-        return __plot_as_workspace(*args, **kwargs)
-
-def plot_bin(workspaces, indices, *args, **kwargs):
-    """
-    X-Y plot of the bin counts in a workspace.
-
-    Plots one or more bin, selected by indices, using spectra numbers as x-axis and bin counts for
-    each spectrum as y-axis.
-
-    @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted)
-    @param indices :: indices of the bin(s) to plot
-
-    Returns :: the list of curves included in the plot
-    """
-    # Find optional params to plotBin
-    bars_val = __translate_error_bars_kwarg(**kwargs)
-    window_val, clearWindow_val = __translate_hold_kwarg(**kwargs)
-
-    # to change properties on the new lines being added
-    first_line = 0
-    if None != window_val:
-        first_line = window_val.activeLayer().numCurves()
-
-    graph = mantidplot.plotBin(workspaces, indices, error_bars=bars_val, type=-1, window=window_val, clearWindow=clearWindow_val)
-
-    __apply_plot_args(graph, first_line, *args)
-    __apply_plot_kwargs(graph, first_line, **kwargs)
-
-    return __list_of_lines_from_graph(graph, first_line)
-
-
-def plot_md(workspaces, *args, **kwargs):
-    """
-    X-Y plot of an MDWorkspace.
-
-    @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted)
-
-    Returns :: the list of curves included in the plot
-    """
-    # Find optional params to plotBin
-    bars_val = __translate_error_bars_kwarg(**kwargs)
-    window_val, clearWindow_val = __translate_hold_kwarg(**kwargs)
-
-    # to change properties on the new lines being added
-    first_line = 0
-    if None != window_val:
-        first_line = window_val.activeLayer().numCurves()
-
-    graph = mantidplot.plotMD(workspaces, normalization=mantidplot.DEFAULT_MD_NORMALIZATION, error_bars=bars_val, window=window_val, clearWindow=clearWindow_val)
-
-    __apply_plot_args(graph, first_line, *args)
-    __apply_plot_kwargs(graph, first_line, **kwargs)
-
-    return __list_of_lines_from_graph(graph, first_line)
-
-
-def plot_spectrum(workspaces, indices, *args, **kwargs):
-    """X-Y Plot of spectra in a workspace.
-
-    Plots one or more spectra, selected by indices, using bin boundaries as x-axis
-    and the spectra values in each bin as y-axis.
-
-    @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted)
-    @param indices :: indices of the spectra to plot, given as a single integer or a list of integers
-
-    Returns :: the list of curves included in the plot
-
-    """
-    # Find optional params to plotSpectrum
-    bars_val = __translate_error_bars_kwarg(**kwargs)
-    distr_val = __translate_distribution_kwarg(**kwargs)
-    window_val, clearWindow_val = __translate_hold_kwarg(**kwargs)
-
-    # to change properties on the new lines being added
-    first_line = 0
-    if None != window_val:
-        first_line = window_val.activeLayer().numCurves()
-
-    graph = mantidplot.plotSpectrum(workspaces, indices, error_bars=bars_val, type=-1, window=window_val, clearWindow=clearWindow_val)
-
-    __apply_plot_args(graph, first_line, *args)
-    __apply_plot_kwargs(graph, first_line, **kwargs)
-
-    return __list_of_lines_from_graph(graph, first_line)
-
-
-def plot(*args, **kwargs):
-    """
-    Plot the data in various forms depending on what arguments are passed.  Currently supported
-    inputs: arrays (as Python lists or numpy arrays) and workspaces (by name or workspace objects).
-
-    @param args :: curve data and options
-    @param kwargs :: plot line options
-
-    Returns :: the list of curves included in the plot
-
-    args can take different forms depending on what you plot. You can plot:
-
-    * a python list or array (x) for example like this: plot(x)
-
-    * a workspace (ws) for example like this: plot(ws, [100,101])  # this will plot spectra 100 and 101
-
-    * a list of workspaces (ws, ws2, ws3, etc.) for example like this: plot([ws, ws2, ws3], [100,101])
-
-    * workspaces identified by their names: plot(['HRP39182', 'MAR11060.nxs'], [100,101])
-
-    You can also pass matplotlib/pyplot style strings as arguments, for example: plot(x, '-.')
-
-    As keyword arguments (kwargs) you can specify multiple
-    parameters, for example: linewidth, linestyle, marker, color.
-
-    An important keyword argument is tool. At the moment the
-    following values are supported (they have long and short aliases):
-
-    * To plot spectra: 'plot_spectrum' OR 'spectrum' OR 'plot_sp' OR 'sp'  (default for workspaces).
-    * To plot bins: 'plot_bin' OR 'bin'
-    * To do an MD plot: 'plot_md' OR 'md'
-
-    Please see the documentation of this module (use help()) for more details.
-
-    """
-    nargs = len(args)
-    if nargs < 1:
-        raise ValueError("You did not pass any argument. You must provide data to plot.")
-
-    # TOTHINK: should there be an exception if it's plot_md (tool='plot_md')
-    (is_it, plots_seq) = __is_multiplot_command(*args, **kwargs)
-    if is_it:
-        return __process_multiplot_command(plots_seq, **kwargs)
-    elif len(args) > 3:
-        raise ValueError("Could not interpret the arguments passed. You passed more than 3 positional arguments but this does not seem to be a correct multi-plot command. Please check your command and make sure that the workspaces given are correct.")
-
-    # normally guess; exception if e.g. a parameter tool='plot_bin' is given
-    try:
-        tool_val = kwargs['tool']
-        del kwargs['tool']
-        return __plot_with_tool(tool_val, *args, **kwargs)
-    except KeyError:
-        return __plot_with_best_guess(*args, **kwargs)
-
-
-#=============================================================================
-# Functions, for pyplot / old matlab style manipulation of figures
-#=============================================================================
-
-def xlim(xmin, xmax):
-    """
-    Set the boundaries of the x axis
-
-    @param xmin :: minimum value
-    @param xmax :: maximum value
-    """
-    l = __last_fig()._graph.activeLayer()
-    l.setAxisScale(2, xmin, xmax)
-
-def ylim(ymin, ymax):
-    """
-    Set the boundaries of the y axis
-
-    @param ymin :: minimum value
-    @param ymax :: maximum value
-    """
-    l = __last_fig()._graph.activeLayer()
-    l.setAxisScale(0, ymin, ymax)
-
-def xlabel(lbl):
-    """
-    Set the label or title of the x axis
-
-    @param lbl :: x axis lbl
-    """
-    l = __last_fig()._graph.activeLayer()
-    l.setXTitle(lbl)
-
-def ylabel(lbl):
-    """
-    Set the label or title of the y axis
-
-    @param lbl :: y axis lbl
-    """
-    l = __last_fig()._graph.activeLayer()
-    l.setYTitle(lbl)
-
-def title(title):
-    """
-    Set title of the active plot
-
-    @param title :: title string
-    """
-    l = __last_fig()._graph.activeLayer()
-    l.setTitle(title)
-
-def axis(lims):
-    """
-    Set the boundaries or limits of the x and y axes
-
-    @param lims :: list or vector specifying min x, max x, min y, max y
-    """
-    l = __last_fig()._graph.activeLayer()
-    if 4 != len(lims):
-        raise ValueError("Error: 4 real values are required for the x and y axes limits")
-    l.setScale(*lims)
-
-def yscale(scale_str):
-    """
-    Set the type of scale of the y axis
-
-    @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale
-    """
-    ax = __last_fig()._axes
-    ax.set_yscale(scale_str)
-
-def xscale(scale_str):
-    """
-    Set the type of scale of the x axis
-
-    @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale
-    """
-    ax = __last_fig()._axes
-    ax.set_xscale(scale_str)
-
-def grid(opt='on'):
-    """
-    Enable a grid on the active plot (horizontal and vertical)
-
-    @param title :: 'on' to enable
-    """
-    l = __last_fig()._graph.activeLayer()
-    if None == opt or 'on' == opt:
-        l.showGrid()
-    elif 'off' == opt:
-        # TODO is there support for a 'hideGrid' in qti? Apparently not.
-        print("Sorry, hiding/disabling grids is currenlty not supported")
-
-def figure(num=None):
-    """
-    Return Figure object for a new figure or an existing one (if there is any
-    with the number passed as parameter).
-
-    @param num :: figure number (optional). If empty, a new figure is created.
-    """
-    if not num:
-        return __empty_fig()
-    else:
-        if num < 0:
-            raise ValueError("The figure number must be >= 0")
-
-    return Figure(num)
-
-def savefig(name):
-    """
-    Save current plot into a file. The format is guessed from the file extension (.eps, .png, .jpg, etc.)
-
-    @param name :: file name
-    """
-    if not name:
-        raise ValueError("Error: you need to specify a non-empty file name")
-    l = __last_fig()._graph.activeLayer()
-    l.export(name);
diff --git a/MantidPlot/pymantidplot/qtiplot.py b/MantidPlot/pymantidplot/qtiplot.py
index e3848d12bac53e7a198bb6c087e421a9b8f2b033..0c2af7a2968eef770c8d36a72b9041e3b74bb858 100644
--- a/MantidPlot/pymantidplot/qtiplot.py
+++ b/MantidPlot/pymantidplot/qtiplot.py
@@ -19,9 +19,6 @@ from PyQt4 import QtCore
 
 #-----------------------------------------------------------------------------
 # Intercept qtiplot "plot" command and forward to plotSpectrum for a workspace
-#
-# This function has been moved inside qtiplot when pymantidplot.pyplot (which
-# has another plot() function) was imported into the standard MantidPlot namespace
 def plot(source, *args, **kwargs):
     """Create a new plot given a workspace, table or matrix.
 
diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp
index 04133721a85cc01cfca2b1872dec68a8937e2c72..0da334bba9ee7ea4832ed9f94e0929c956004f10 100644
--- a/MantidPlot/src/ApplicationWindow.cpp
+++ b/MantidPlot/src/ApplicationWindow.cpp
@@ -2446,7 +2446,7 @@ Graph3D *ApplicationWindow::dataPlot3D(const QString &caption,
   posX = formula.indexOf("(", pos);
   QString yCol = formula.mid(pos + 1, posX - pos - 1);
 
-  Graph3D *plot = new Graph3D("", this, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr);
   plot->addData(w, xCol, yCol, xl, xr, yl, yr, zl, zr);
   plot->update();
 
@@ -2466,7 +2466,7 @@ Graph3D *ApplicationWindow::newPlot3D() {
 
   QString label = generateUniqueName(tr("Graph"));
 
-  Graph3D *plot = new Graph3D("", this, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr);
   plot->setWindowTitle(label);
   plot->setName(label);
 
@@ -2486,7 +2486,7 @@ Graph3D *ApplicationWindow::plotXYZ(Table *table, const QString &zColName,
 
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
-  Graph3D *plot = new Graph3D("", this, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr);
   QString label = generateUniqueName(tr("Graph"));
   plot->setWindowTitle(label);
   plot->setName(label);
@@ -2531,7 +2531,7 @@ Graph3D *ApplicationWindow::openPlotXYZ(const QString &caption,
   int yCol = w->colIndex(yColName);
   int zCol = w->colIndex(zColName);
 
-  Graph3D *plot = new Graph3D("", this, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr);
   plot->loadData(w, xCol, yCol, zCol, xl, xr, yl, yr, zl, zr);
 
   QString label = caption;
@@ -2584,7 +2584,7 @@ void ApplicationWindow::exportMatrix() {
     return;
 
   ImageExportDialog *ied =
-      new ImageExportDialog(this, m != NULL, d_extended_export_dialog);
+      new ImageExportDialog(this, m != nullptr, d_extended_export_dialog);
   ied->setDirectory(workingDir);
   ied->selectFilter(d_image_export_filter);
   if (ied->exec() != QDialog::Accepted)
@@ -3051,7 +3051,7 @@ void ApplicationWindow::setPreferences(Graph *g) {
  *creates a new empty table
  */
 Table *ApplicationWindow::newTable() {
-  Table *w = new Table(scriptingEnv(), 30, 2, "", this, 0);
+  Table *w = new Table(scriptingEnv(), 30, 2, "", this, nullptr);
   initTable(w, generateUniqueName(tr("Table")));
   w->showNormal();
   return w;
@@ -3061,7 +3061,7 @@ Table *ApplicationWindow::newTable() {
  *used when opening a project file
  */
 Table *ApplicationWindow::newTable(const QString &caption, int r, int c) {
-  Table *w = new Table(scriptingEnv(), r, c, "", this, 0);
+  Table *w = new Table(scriptingEnv(), r, c, "", this, nullptr);
   initTable(w, caption);
   if (w->objectName() != caption) { // the table was renamed
     renamedTables << caption << w->objectName();
@@ -3083,7 +3083,7 @@ bool ApplicationWindow::isDeleteWorkspacePromptEnabled() {
 
 Table *ApplicationWindow::newTable(int r, int c, const QString &name,
                                    const QString &legend) {
-  Table *w = new Table(scriptingEnv(), r, c, legend, this, 0);
+  Table *w = new Table(scriptingEnv(), r, c, legend, this, nullptr);
   initTable(w, name);
   return w;
 }
@@ -3095,7 +3095,7 @@ Table *ApplicationWindow::newTable(const QString &caption, int r, int c,
   if (lst.count() == 2)
     legend = lst[1];
 
-  Table *w = new Table(scriptingEnv(), r, c, legend, this, 0);
+  Table *w = new Table(scriptingEnv(), r, c, legend, this, nullptr);
 
   QStringList rows = text.split("\n", QString::SkipEmptyParts);
   QString rlist = rows[0];
@@ -3117,7 +3117,7 @@ Table *ApplicationWindow::newTable(const QString &caption, int r, int c,
 Table *ApplicationWindow::newHiddenTable(const QString &name,
                                          const QString &label, int r, int c,
                                          const QString &text) {
-  Table *w = new Table(scriptingEnv(), r, c, label, this, 0);
+  Table *w = new Table(scriptingEnv(), r, c, label, this, nullptr);
 
   if (!text.isEmpty()) {
     QStringList rows = text.split("\n", QString::SkipEmptyParts);
@@ -3194,14 +3194,14 @@ Note *ApplicationWindow::newNote(const QString &caption) {
 }
 
 Matrix *ApplicationWindow::newMatrix(int rows, int columns) {
-  Matrix *m = new Matrix(scriptingEnv(), rows, columns, "", this, 0);
+  Matrix *m = new Matrix(scriptingEnv(), rows, columns, "", this, nullptr);
   initMatrix(m, generateUniqueName(tr("Matrix")));
   m->showNormal();
   return m;
 }
 
 Matrix *ApplicationWindow::newMatrix(const QString &caption, int r, int c) {
-  Matrix *w = new Matrix(scriptingEnv(), r, c, "", this, 0);
+  Matrix *w = new Matrix(scriptingEnv(), r, c, "", this, nullptr);
   initMatrix(w, caption);
   if (w->objectName() != caption) // the matrix was renamed
     renamedTables << caption << w->objectName();
@@ -3397,14 +3397,14 @@ ApplicationWindow::matrixToTable(Matrix *m,
 
   Table *w = nullptr;
   if (conversionType == Direct) {
-    w = new Table(scriptingEnv(), rows, cols, "", this, 0);
+    w = new Table(scriptingEnv(), rows, cols, "", this, nullptr);
     for (int i = 0; i < rows; i++) {
       for (int j = 0; j < cols; j++)
         w->setCell(i, j, m->cell(i, j));
     }
   } else if (conversionType == XYZ) {
     int tableRows = rows * cols;
-    w = new Table(scriptingEnv(), tableRows, 3, "", this, 0);
+    w = new Table(scriptingEnv(), tableRows, 3, "", this, nullptr);
     for (int i = 0; i < rows; i++) {
       for (int j = 0; j < cols; j++) {
         int cell = i * cols + j;
@@ -3415,7 +3415,7 @@ ApplicationWindow::matrixToTable(Matrix *m,
     }
   } else if (conversionType == YXZ) {
     int tableRows = rows * cols;
-    w = new Table(scriptingEnv(), tableRows, 3, "", this, 0);
+    w = new Table(scriptingEnv(), tableRows, 3, "", this, nullptr);
     for (int i = 0; i < cols; i++) {
       for (int j = 0; j < rows; j++) {
         int cell = i * rows + j;
@@ -3600,7 +3600,7 @@ Matrix *ApplicationWindow::tableToMatrix(Table *t) {
   int cols = t->numCols();
 
   QString caption = generateUniqueName(tr("Matrix"));
-  Matrix *m = new Matrix(scriptingEnv(), rows, cols, "", this, 0);
+  Matrix *m = new Matrix(scriptingEnv(), rows, cols, "", this, nullptr);
   initMatrix(m, caption);
 
   for (int i = 0; i < rows; i++) {
@@ -5701,7 +5701,7 @@ void ApplicationWindow::exportGraph() {
     return;
 
   ImageExportDialog *ied =
-      new ImageExportDialog(this, plot2D != NULL, d_extended_export_dialog);
+      new ImageExportDialog(this, plot2D != nullptr, d_extended_export_dialog);
   ied->setDirectory(workingDir);
   ied->selectFilter(d_image_export_filter);
   if (ied->exec() != QDialog::Accepted)
@@ -5764,7 +5764,7 @@ void ApplicationWindow::exportLayer() {
     return;
 
   ImageExportDialog *ied =
-      new ImageExportDialog(this, g != NULL, d_extended_export_dialog);
+      new ImageExportDialog(this, g != nullptr, d_extended_export_dialog);
   ied->setDirectory(workingDir);
   ied->selectFilter(d_image_export_filter);
   if (ied->exec() != QDialog::Accepted)
@@ -5837,7 +5837,7 @@ void ApplicationWindow::exportAllGraphs() {
   foreach (MdiSubWindow *w, windows) {
     const std::string windowClassName = w->metaObject()->className();
     if (windowClassName == "MultiLayer") {
-      plot3D = 0;
+      plot3D = nullptr;
       plot2D = dynamic_cast<MultiLayer *>(w);
       if (!plot2D)
         continue;
@@ -5851,7 +5851,7 @@ void ApplicationWindow::exportAllGraphs() {
         continue;
       }
     } else if (windowClassName == "Graph3D") {
-      plot2D = 0;
+      plot2D = nullptr;
       plot3D = dynamic_cast<Graph3D *>(w);
       if (!plot3D)
         continue;
@@ -6137,7 +6137,7 @@ void ApplicationWindow::savetoNexusFile() {
 void ApplicationWindow::loadDataFile() {
   // Ask user for file
   QString fn = QFileDialog::getOpenFileName(
-      0, tr("Mantidplot - Open file to load"),
+      nullptr, tr("Mantidplot - Open file to load"),
       AlgorithmInputHistory::Instance().getPreviousDirectory());
   if (fn != "") {
     loadDataFileByName(fn);
@@ -6438,7 +6438,7 @@ void ApplicationWindow::showTitleDialog() {
 
     Graph *g = ml->activeGraph();
     if (g) {
-      TextDialog *td = new TextDialog(TextDialog::LayerTitle, this, 0);
+      TextDialog *td = new TextDialog(TextDialog::LayerTitle, this, nullptr);
       td->setGraph(g);
       td->exec();
     }
@@ -6462,7 +6462,7 @@ void ApplicationWindow::showAxisTitleDialog() {
   if (!g)
     return;
 
-  TextDialog *td = new TextDialog(TextDialog::AxisTitle, this, 0);
+  TextDialog *td = new TextDialog(TextDialog::AxisTitle, this, nullptr);
   td->setGraph(g);
   td->exec();
 }
@@ -7606,7 +7606,7 @@ void ApplicationWindow::removePoints() {
         this, tr("MantidPlot"), // Mantid
         tr("This will modify the data in the worksheets!\nAre you sure you "
            "want to continue?"),
-        tr("Continue"), tr("Cancel"), 0, 1)) {
+        tr("Continue"), tr("Cancel"), nullptr, 1)) {
     case 0:
       g->setActiveTool(new DataPickerTool(g, this, DataPickerTool::Remove, info,
                                           SLOT(setText(const QString &))));
@@ -7651,7 +7651,7 @@ void ApplicationWindow::movePoints() {
         this, tr("MantidPlot"), // Mantid
         tr("This will modify the data in the worksheets!\nAre you sure you "
            "want to continue?"),
-        tr("Continue"), tr("Cancel"), 0, 1)) {
+        tr("Continue"), tr("Cancel"), nullptr, 1)) {
     case 0:
       if (g) {
         g->setActiveTool(new DataPickerTool(g, this, DataPickerTool::Move, info,
@@ -8345,7 +8345,7 @@ void ApplicationWindow::showTextDialog() {
     if (!l)
       return;
 
-    TextDialog *td = new TextDialog(TextDialog::TextMarker, this, 0);
+    TextDialog *td = new TextDialog(TextDialog::TextMarker, this, nullptr);
     td->setLegendWidget(l);
     td->exec();
   }
@@ -9825,9 +9825,10 @@ void ApplicationWindow::closeEvent(QCloseEvent *ce) {
     delete scriptingWindow;
     scriptingWindow = nullptr;
   }
-  /// Ensure interface python references are cleaned up before the interpreter
-  /// shuts down
+  // Ensure all python references are cleaned up before the interpreter shuts
+  // down
   delete m_iface_script;
+  delete m_interpreterDock;
 
   // Emit a shutting_down() signal that can be caught by
   // independent QMainWindow objects to know when MantidPlot
@@ -10467,7 +10468,7 @@ void ApplicationWindow::chooseHelpFolder() {
   QFileInfo hfi(helpFilePath);
   QString dir = QFileDialog::getExistingDirectory(
       this, tr("Choose the location of the MantidPlot help folder!"),
-      hfi.dir().absolutePath(), 0 /**QFileDialog::ShowDirsOnly*/);
+      hfi.dir().absolutePath(), nullptr /**QFileDialog::ShowDirsOnly*/);
 
   if (!dir.isEmpty()) {
     helpFilePath = dir + "index.html";
@@ -10522,7 +10523,7 @@ void ApplicationWindow::showHelp() {
 void ApplicationWindow::showPlotWizard() {
   QStringList lst = tableNames();
   if (lst.count() > 0) {
-    PlotWizard *pw = new PlotWizard(this, 0);
+    PlotWizard *pw = new PlotWizard(this, nullptr);
     pw->setAttribute(Qt::WA_DeleteOnClose);
     connect(pw, SIGNAL(plot(const QStringList &)), this,
             SLOT(multilayerPlot(const QStringList &)));
@@ -13366,7 +13367,7 @@ Graph3D *ApplicationWindow::openMatrixPlot3D(const QString &caption,
   if (!m)
     return nullptr;
 
-  Graph3D *plot = new Graph3D("", this, 0, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr, nullptr);
   plot->setWindowTitle(caption);
   plot->setName(caption);
   plot->addMatrixData(m, xl, xr, yl, yr, zl, zr);
@@ -13390,7 +13391,7 @@ Graph3D *ApplicationWindow::plot3DMatrix(Matrix *m, int style) {
   QApplication::setOverrideCursor(Qt::WaitCursor);
   QString label = generateUniqueName(tr("Graph"));
 
-  Graph3D *plot = new Graph3D("", this, 0);
+  Graph3D *plot = new Graph3D("", this, nullptr);
   plot->addMatrixData(m);
   plot->customPlotStyle(style);
   customPlot3D(plot);
@@ -14409,7 +14410,7 @@ bool ApplicationWindow::deleteFolder(Folder *f) {
           this, tr("MantidPlot - Delete folder?"), // Mantid
           tr("Delete folder '%1' and all the windows it contains?")
               .arg(f->objectName()),
-          tr("Yes"), tr("No"), 0, 0))
+          tr("Yes"), tr("No"), nullptr, 0))
     return false;
   else {
     Folder *parent = projectFolder();
@@ -14858,7 +14859,8 @@ void ApplicationWindow::showScriptWindow(bool forceVisible, bool quitting) {
     // it doesn't respect the always on top
     // flag, it is treated as a sub window of its parent
     const bool capturePrint = !quitting;
-    scriptingWindow = new ScriptingWindow(scriptingEnv(), capturePrint, NULL);
+    scriptingWindow =
+        new ScriptingWindow(scriptingEnv(), capturePrint, nullptr);
     scriptingWindow->setObjectName("ScriptingWindow");
     scriptingWindow->setAttribute(Qt::WA_DeleteOnClose, false);
     connect(scriptingWindow, SIGNAL(closeMe()), this,
diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp
index c32b03847cb7fed8642ac393bfe6b090f5ef72b4..447d0f7d273a4089499714d3e92cb9534659c6d9 100644
--- a/MantidPlot/src/ConfigDialog.cpp
+++ b/MantidPlot/src/ConfigDialog.cpp
@@ -1277,8 +1277,8 @@ void ConfigDialog::updateSendToTab() {
   }
 }
 
-typedef std::map<std::string, bool> categoriesType;
-typedef QMap<QString, QTreeWidgetItem *> widgetMap;
+using categoriesType = std::map<std::string, bool>;
+using widgetMap = QMap<QString, QTreeWidgetItem *>;
 
 void ConfigDialog::refreshTreeCategories() {
   treeCategories->clear();
@@ -3105,7 +3105,7 @@ void ConfigDialog::chooseTranslationsFolder() {
   QFileInfo tfi(app->d_translations_folder);
   QString dir = QFileDialog::getExistingDirectory(
       this, tr("Choose the location of the MantidPlot translations folder!"),
-      tfi.dir().absolutePath(), 0 /**QFileDialog::ShowDirsOnly*/);
+      tfi.dir().absolutePath(), nullptr /**QFileDialog::ShowDirsOnly*/);
 
   if (!dir.isEmpty()) {
     app->d_translations_folder = dir;
@@ -3130,7 +3130,7 @@ void ConfigDialog::chooseHelpFolder() {
 void ConfigDialog::addPythonScriptsDirs() {
   QString dir = QFileDialog::getExistingDirectory(
       this, tr("Add a python scripts directory"), "",
-      0 /**QFileDialog::ShowDirsOnly*/);
+      nullptr /**QFileDialog::ShowDirsOnly*/);
   if (!dir.isEmpty()) {
     QString dirs = lePythonScriptsDirs->text();
     if (!dirs.isEmpty()) {
@@ -3144,7 +3144,7 @@ void ConfigDialog::addPythonScriptsDirs() {
 void ConfigDialog::addPythonPluginDirs() {
   QString dir = QFileDialog::getExistingDirectory(
       this, tr("Add a python extension directory"), "",
-      0 /**QFileDialog::ShowDirsOnly*/);
+      nullptr /**QFileDialog::ShowDirsOnly*/);
   if (!dir.isEmpty()) {
     QString dirs = lePythonPluginsDirs->text();
     if (!dirs.isEmpty()) {
@@ -3157,7 +3157,7 @@ void ConfigDialog::addPythonPluginDirs() {
 
 void ConfigDialog::addInstrumentDir() {
   QString dir = QFileDialog::getExistingDirectory(
-      this, tr("Select new instrument definition directory"), "", 0);
+      this, tr("Select new instrument definition directory"), "", nullptr);
   if (!dir.isEmpty()) {
     leInstrumentDir->setText(dir);
   }
diff --git a/MantidPlot/src/Fit.h b/MantidPlot/src/Fit.h
index 1c5aa79798eaa27a047e5104b54467d475e110aa..bd6a6bf2efdaf03b5d87d324be1f1c3257585251 100644
--- a/MantidPlot/src/Fit.h
+++ b/MantidPlot/src/Fit.h
@@ -45,11 +45,11 @@ class Fit : public Filter {
   Q_OBJECT
 
 public:
-  typedef double (*fit_function_simplex)(const gsl_vector *, void *);
-  typedef int (*fit_function)(const gsl_vector *, void *, gsl_vector *);
-  typedef int (*fit_function_df)(const gsl_vector *, void *, gsl_matrix *);
-  typedef int (*fit_function_fdf)(const gsl_vector *, void *, gsl_vector *,
-                                  gsl_matrix *);
+  using fit_function_simplex = double (*)(const gsl_vector *, void *);
+  using fit_function = int (*)(const gsl_vector *, void *, gsl_vector *);
+  using fit_function_df = int (*)(const gsl_vector *, void *, gsl_matrix *);
+  using fit_function_fdf = int (*)(const gsl_vector *, void *, gsl_vector *,
+                                   gsl_matrix *);
 
   enum Algorithm {
     ScaledLevenbergMarquardt,
diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp
index 3fd93f5639af75a18628482e21de7547d527f40c..a19870e6eeb2f32cc1610ea8dedbb5271761e2ef 100644
--- a/MantidPlot/src/Graph.cpp
+++ b/MantidPlot/src/Graph.cpp
@@ -3094,7 +3094,7 @@ void Graph::removePie() {
 
   QList<PieLabel *> labels = pieCurve->labelsList();
   foreach (PieLabel *l, labels)
-    l->setPieCurve(0);
+    l->setPieCurve(nullptr);
 
   d_plot->removeCurve(c_keys[0]);
   d_plot->replot();
diff --git a/MantidPlot/src/Graph3D.cpp b/MantidPlot/src/Graph3D.cpp
index 7ca8869de627f224a80a76923587ccca2268d940..7362252c2e05882bacb3a746cddc6edc135747a8 100644
--- a/MantidPlot/src/Graph3D.cpp
+++ b/MantidPlot/src/Graph3D.cpp
@@ -2497,7 +2497,7 @@ MantidQt::API::IProjectSerialisable *
 Graph3D::loadFromProject(const std::string &lines, ApplicationWindow *app,
                          const int fileVersion) {
   Q_UNUSED(fileVersion);
-  auto graph = new Graph3D("", app, "", 0);
+  auto graph = new Graph3D("", app, "", nullptr);
 
   std::vector<std::string> lineVec, valVec;
   boost::split(lineVec, lines, boost::is_any_of("\n"));
diff --git a/MantidPlot/src/Mantid/FitParameterTie.cpp b/MantidPlot/src/Mantid/FitParameterTie.cpp
index 02352d7bb47908bd2f504332f43ce228cc702bb5..d51c05a2719e20af3a1a3b23ed5faa1892044965 100644
--- a/MantidPlot/src/Mantid/FitParameterTie.cpp
+++ b/MantidPlot/src/Mantid/FitParameterTie.cpp
@@ -42,7 +42,7 @@ void FitParameterTie::set(const QString &estr) {
   // rx matches function identifiers in the parameter names and captures the
   // function index:
   // for f12.Sigma rx.cap(1).toInt() returns 12
-  QRegExp rx("\\bf(\\d+)\\.");
+  QRegExp rx(R"(\bf(\d+)\.)");
 
   if (rx.indexIn(parName) < 0) {
     throw std::invalid_argument(
diff --git a/MantidPlot/src/Mantid/InputHistory.h b/MantidPlot/src/Mantid/InputHistory.h
index 23f085ff23e35aa76cb870e2a0f86d1e758410af..e13cd4881663b39853d1c3a7d8fc565d77b477f8 100644
--- a/MantidPlot/src/Mantid/InputHistory.h
+++ b/MantidPlot/src/Mantid/InputHistory.h
@@ -11,7 +11,7 @@
 namespace Mantid {
 namespace API {
 class IAlgorithm;
-typedef boost::shared_ptr<IAlgorithm> IAlgorithm_sptr;
+using IAlgorithm_sptr = boost::shared_ptr<IAlgorithm>;
 }
 }
 
@@ -88,6 +88,6 @@ private:
   QMap<QString, QList<PropertyData>> m_history;
 };
 
-typedef Mantid::Kernel::SingletonHolder<InputHistoryImpl> InputHistory;
+using InputHistory = Mantid::Kernel::SingletonHolder<InputHistoryImpl>;
 
 #endif /* INPUTHISTORY_H */
diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
index 0c0e61b2bae4b589d03dc5bc8728cb1f682d7fc0..07137f9e90df10bb8bae65ab026e62455f14b0b4 100644
--- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
+++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp
@@ -23,7 +23,7 @@ using namespace MantidQt::MantidWidgets;
 InstrumentWindow::InstrumentWindow(const QString &wsName, const QString &label,
                                    ApplicationWindow *parent,
                                    const QString &name)
-    : MdiSubWindow(parent, label, name, 0) {
+    : MdiSubWindow(parent, label, name, nullptr) {
 
   m_instrumentWidget = new InstrumentWidget(wsName, this);
   this->setWidget(m_instrumentWidget);
diff --git a/MantidPlot/src/Mantid/MantidMatrix.cpp b/MantidPlot/src/Mantid/MantidMatrix.cpp
index 76e3aedee0c5ff8c1547195e2dff05212d99e484..bdd87147b94ca635f1fed2168a2ae255af313cd5 100644
--- a/MantidPlot/src/Mantid/MantidMatrix.cpp
+++ b/MantidPlot/src/Mantid/MantidMatrix.cpp
@@ -210,7 +210,7 @@ void MantidMatrix::viewChanged(int index) {
 void MantidMatrix::setup(Mantid::API::MatrixWorkspace_const_sptr ws, int start,
                          int end) {
   if (!ws) {
-    QMessageBox::critical(0, "WorkspaceMatrixModel error",
+    QMessageBox::critical(nullptr, "WorkspaceMatrixModel error",
                           "2D workspace expected.");
     m_rows = 0;
     m_cols = 0;
@@ -468,8 +468,8 @@ void MantidMatrix::setRange(double min, double max) {
 double **MantidMatrix::allocateMatrixData(int rows, int columns) {
   double **data = (double **)malloc(rows * sizeof(double *));
   if (!data) {
-    QMessageBox::critical(0, tr("MantidPlot") + " - " +
-                                 tr("Memory Allocation Error"),
+    QMessageBox::critical(nullptr, tr("MantidPlot") + " - " +
+                                       tr("Memory Allocation Error"),
                           tr("Not enough memory, operation aborted!"));
     return nullptr;
   }
@@ -481,8 +481,8 @@ double **MantidMatrix::allocateMatrixData(int rows, int columns) {
         free(data[j]);
       free(data);
 
-      QMessageBox::critical(0, tr("MantidPlot") + " - " +
-                                   tr("Memory Allocation Error"),
+      QMessageBox::critical(nullptr, tr("MantidPlot") + " - " +
+                                         tr("Memory Allocation Error"),
                             tr("Not enough memory, operation aborted!"));
       return nullptr;
     }
@@ -736,7 +736,7 @@ void MantidMatrix::attachMultilayer(MultiLayer *ml) {
 */
 MultiLayer *MantidMatrix::plotGraph2D(GraphOptions::CurveType type) {
   if (numRows() == 1) {
-    QMessageBox::critical(0, "MantidPlot - Error",
+    QMessageBox::critical(nullptr, "MantidPlot - Error",
                           "Cannot plot a workspace with only one spectrum.");
     return nullptr;
   }
diff --git a/MantidPlot/src/Mantid/MantidMatrix.h b/MantidPlot/src/Mantid/MantidMatrix.h
index 5888ec088c9fc1653b7aeb0f0a4718e08e160188..58203c250bb8499e3dbc0f5161a55f00384df3d1 100644
--- a/MantidPlot/src/Mantid/MantidMatrix.h
+++ b/MantidPlot/src/Mantid/MantidMatrix.h
@@ -333,7 +333,7 @@ private:
 };
 
 /// Typedef for a shared pointer to a MantidMatrix
-typedef QSharedPointer<MantidMatrix> MantidMatrix_sptr;
+using MantidMatrix_sptr = QSharedPointer<MantidMatrix>;
 
 class ProjectData {
 public:
diff --git a/MantidPlot/src/Mantid/MantidTable.cpp b/MantidPlot/src/Mantid/MantidTable.cpp
index 295b08302052dd65f515ce48747fac56e5484fdd..a9a58a128d506051954f8c4765e1459eb7d12988 100644
--- a/MantidPlot/src/Mantid/MantidTable.cpp
+++ b/MantidPlot/src/Mantid/MantidTable.cpp
@@ -35,7 +35,7 @@ MantidTable::MantidTable(ScriptingEnv *env,
                            : static_cast<int>(ws->rowCount()),
             transpose ? static_cast<int>(ws->rowCount() + 1)
                       : static_cast<int>(ws->columnCount()),
-            label, parent, "", 0),
+            label, parent, "", nullptr),
       m_ws(ws), m_wsName(ws->getName()), m_transposed(transpose) {
   d_table->blockResizing(true);
 
diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp
index 1d5dfe006447dad917e90e2804ff83306eb560cd..a67ed40590ca12365844b06f30f9ab1317ab21da 100644
--- a/MantidPlot/src/Mantid/MantidUI.cpp
+++ b/MantidPlot/src/Mantid/MantidUI.cpp
@@ -104,7 +104,6 @@ using namespace Mantid::API;
 using namespace MantidQt::API;
 using namespace MantidQt::MantidWidgets;
 using MantidQt::MantidWidgets::MantidWSIndexDialog;
-using MantidQt::MantidWidgets::MantidTreeWidget;
 using Mantid::Types::Core::DateAndTime;
 using Mantid::Types::Core::time_duration;
 using MantidQt::SliceViewer::SliceViewerWindow;
@@ -214,9 +213,9 @@ MantidUI::MantidUI(ApplicationWindow *aw)
     : m_finishedLoadDAEObserver(*this,
                                 &MantidUI::handleLoadDAEFinishedNotification),
       m_configServiceObserver(*this, &MantidUI::handleConfigServiceUpdate),
-      m_appWindow(aw), m_lastShownInstrumentWin(NULL),
-      m_lastShownSliceViewWin(NULL), m_lastShownSpectrumViewerWin(NULL),
-      m_lastShownColorFillWin(NULL), m_lastShown1DPlotWin(NULL),
+      m_appWindow(aw), m_lastShownInstrumentWin(nullptr),
+      m_lastShownSliceViewWin(nullptr), m_lastShownSpectrumViewerWin(nullptr),
+      m_lastShownColorFillWin(nullptr), m_lastShown1DPlotWin(nullptr),
       m_vatesSubWindow(nullptr)
 //, m_spectrumViewWindow(NULL)
 {
@@ -926,7 +925,7 @@ void MantidUI::showSpectrumViewer() {
       try {
         viewer = new MantidQt::SpectrumView::SpectrumView(m_appWindow);
       } catch (std::runtime_error &e) {
-        m_lastShownSpectrumViewerWin = NULL;
+        m_lastShownSpectrumViewerWin = nullptr;
         g_log.error() << "Could not create spectrum viewer: " << e.what()
                       << "\n";
         throw std::runtime_error(e);
@@ -982,7 +981,7 @@ void MantidUI::showSliceViewer() {
       w = MantidQt::Factory::WidgetFactory::Instance()->createSliceViewerWindow(
           wsName, "");
     } catch (std::runtime_error &e) {
-      m_lastShownSliceViewWin = NULL;
+      m_lastShownSliceViewWin = nullptr;
       g_log.error() << "Could not create slice viewer: " << e.what() << "\n";
       throw std::runtime_error(e);
     }
@@ -1026,7 +1025,7 @@ Show Algorithm History Details in a window .
 void MantidUI::showAlgorithmHistory() {
   QString wsName = getSelectedWorkspaceName();
   Mantid::API::Workspace_const_sptr wsptr = getWorkspace(wsName);
-  if (NULL != wsptr) {
+  if (nullptr != wsptr) {
     // If the workspace has any AlgorithHistory ...
     if (!wsptr->getHistory().empty()) {
       // ... create and display the window.
@@ -1315,8 +1314,8 @@ Table *MantidUI::createDetectorTable(
   const int nrows = indices.empty()
                         ? static_cast<int>(ws->getNumberHistograms())
                         : static_cast<int>(indices.size());
-  Table *t =
-      new Table(appWindow()->scriptingEnv(), nrows, ncols, "", appWindow(), 0);
+  Table *t = new Table(appWindow()->scriptingEnv(), nrows, ncols, "",
+                       appWindow(), nullptr);
   appWindow()->initTable(
       t, appWindow()->generateUniqueName(wsName + "-Detectors-"));
   // Set the column names
@@ -2141,7 +2140,7 @@ void MantidUI::showMantidInstrument(const QString &wsName) {
   InstrumentWindow *insWin = getInstrumentView(wsName);
 
   if (!insWin) {
-    m_lastShownInstrumentWin = NULL;
+    m_lastShownInstrumentWin = nullptr;
     return;
   }
 
@@ -2221,8 +2220,9 @@ void MantidUI::saveProject(bool saved) {
   if (!saved) {
     QString savemsg =
         tr("Save changes to project: <p><b> %1 </b> ?").arg("untitled");
-    int result = QMessageBox::information(appWindow(), tr("MantidPlot"),
-                                          savemsg, tr("Yes"), tr("No"), 0, 2);
+    int result =
+        QMessageBox::information(appWindow(), tr("MantidPlot"), savemsg,
+                                 tr("Yes"), tr("No"), nullptr, 2);
     if (result == 0)
       appWindow()->saveProject();
   }
@@ -2406,7 +2406,7 @@ void MantidUI::importString(const QString &logName, const QString &data,
   }
 
   Table *t = new Table(appWindow()->scriptingEnv(), loglines.size(), 1, "",
-                       appWindow(), 0);
+                       appWindow(), nullptr);
   if (!t)
     return;
   // Have to replace "_" since the legend widget uses them to separate things
@@ -2442,8 +2442,8 @@ void MantidUI::importStrSeriesLog(const QString &logName, const QString &data,
   QStringList loglines = data.split("\n", QString::SkipEmptyParts);
 
   int rowcount(loglines.count());
-  Table *t =
-      new Table(appWindow()->scriptingEnv(), rowcount, 2, "", appWindow(), 0);
+  Table *t = new Table(appWindow()->scriptingEnv(), rowcount, 2, "",
+                       appWindow(), nullptr);
   if (!t)
     return;
   QString label;
@@ -2542,7 +2542,7 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
   int colCount = 2;
 
   Table *t = new Table(appWindow()->scriptingEnv(), rowcount, colCount, "",
-                       appWindow(), 0);
+                       appWindow(), nullptr);
   if (!t)
     return;
   // Have to replace "_" since the legend widget uses them to separate things
@@ -2858,7 +2858,7 @@ Table *MantidUI::createTableFromSpectraList(const QString &tableName,
   bool isHistogram = workspace->isHistogramData();
   int no_cols = static_cast<int>(indexList.size());
   Table *t = new Table(appWindow()->scriptingEnv(), numRows, (1 + c) * no_cols,
-                       "", appWindow(), 0);
+                       "", appWindow(), nullptr);
   appWindow()->initTable(t, appWindow()->generateUniqueName(tableName + "-"));
   // t->askOnCloseEvent(false);
 
@@ -3128,7 +3128,7 @@ MultiLayer *MantidUI::plot1D(const QMultiMap<QString, int> &toPlot,
       return nullptr;
   }
   // Force waterfall option to false if only 1 curve
-  if ((NULL == plotWindow || clearWindow) && toPlot.size() == 1)
+  if ((nullptr == plotWindow || clearWindow) && toPlot.size() == 1)
     waterfallPlot = false;
 
   ScopedOverrideCursor waitCursor;
@@ -3326,7 +3326,7 @@ void MantidUI::drawColorFillPlots(const QStringList &wsNames,
          cit != wsNames.end(); ++cit) {
       const bool hidden = true;
       MultiLayer *plot =
-          this->drawSingleColorFillPlot(*cit, curveType, NULL, hidden);
+          this->drawSingleColorFillPlot(*cit, curveType, nullptr, hidden);
       if (plot)
         plots.append(plot);
     }
@@ -3392,7 +3392,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName,
   ScopedOverrideCursor waitCursor;
 
   bool reusePlots = workspacesDockPlot1To1();
-  if ((!reusePlots && NULL == window) ||
+  if ((!reusePlots && nullptr == window) ||
       (reusePlots && !m_lastShownColorFillWin)) // needs to create a new window
   {
     try {
@@ -3402,7 +3402,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName,
         window->hide();
       }
     } catch (std::runtime_error &e) {
-      m_lastShownColorFillWin = NULL;
+      m_lastShownColorFillWin = nullptr;
       g_log.error() << "Could not create color fill plot: " << e.what() << "\n";
       throw std::runtime_error(e);
     }
@@ -3410,7 +3410,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName,
     m_lastShownColorFillWin = window;
   } else {
     if (nullptr == window) {
-      if (NULL == m_lastShownColorFillWin)
+      if (nullptr == m_lastShownColorFillWin)
         return nullptr;
       window = m_lastShownColorFillWin;
     }
@@ -3737,7 +3737,7 @@ Table *MantidUI::createTableFromBins(
     return nullptr;
 
   Table *t = new Table(appWindow()->scriptingEnv(), numRows,
-                       c * bins.size() + 1, "", appWindow(), 0);
+                       c * bins.size() + 1, "", appWindow(), nullptr);
   appWindow()->initTable(t, appWindow()->generateUniqueName(wsName + "-"));
 
   for (int i = 0; i < bins.size(); i++) {
diff --git a/MantidPlot/src/MdiSubWindow.h b/MantidPlot/src/MdiSubWindow.h
index aca03dc68ef0ff8454d9b5c32395f0f398d19a72..61bf3903eba4fc770e527592df970099e971959b 100644
--- a/MantidPlot/src/MdiSubWindow.h
+++ b/MantidPlot/src/MdiSubWindow.h
@@ -353,7 +353,7 @@ private:
   friend class FloatingWindow;
 };
 
-typedef QList<MdiSubWindow *> MDIWindowList;
+using MDIWindowList = QList<MdiSubWindow *>;
 
 /* Used to register classes into the factory. creates a global object in an
  * anonymous namespace. The object itself does nothing, but the comma operator
diff --git a/MantidPlot/src/PluginFit.cpp b/MantidPlot/src/PluginFit.cpp
index 7b5aae539e18e9501ada0d296fc55e9f98e6eb38..50fd84fa5112ad7ebbcd1a922819af8c47915bc0 100644
--- a/MantidPlot/src/PluginFit.cpp
+++ b/MantidPlot/src/PluginFit.cpp
@@ -161,7 +161,7 @@ bool PluginFit::load(const QString &pluginName) {
   if (!f_eval)
     return false;
 
-  typedef char *(*fitFunc)();
+  using fitFunc = char *(*)();
   ff_union ff;
   ff.ptr = lib.resolve("parameters");
   fitFunc fitFunction = ff.func;
diff --git a/MantidPlot/src/PluginFit.h b/MantidPlot/src/PluginFit.h
index 0253cb40b2e5a6b6a7d20f6261fce7e98ceb0765..ad3c01dcfa8758ca1e86e66879f3b1fb4c54e335 100644
--- a/MantidPlot/src/PluginFit.h
+++ b/MantidPlot/src/PluginFit.h
@@ -48,7 +48,7 @@ public:
 
 private:
   void init();
-  typedef double (*fitFunctionEval)(double, double *);
+  using fitFunctionEval = double (*)(double, double *);
   void calculateFitCurveData(double *X, double *Y) override;
   fitFunctionEval f_eval;
 };
diff --git a/MantidPlot/src/PythonScript.cpp b/MantidPlot/src/PythonScript.cpp
index 9c74de4d8d2e9ac354b4ff485c7c924c48284b85..09d6074ccf515e7207a95dd5ae487552d921ea54 100644
--- a/MantidPlot/src/PythonScript.cpp
+++ b/MantidPlot/src/PythonScript.cpp
@@ -556,7 +556,7 @@ QVariant PythonScript::evaluateImpl() {
     if (pystring) {
       PyObject *asUTF8 =
           PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(pystring),
-                               (int)PyUnicode_GET_DATA_SIZE(pystring), NULL);
+                               (int)PyUnicode_GET_DATA_SIZE(pystring), nullptr);
       Py_DECREF(pystring);
       if (asUTF8) {
         qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8)));
diff --git a/MantidPlot/src/ScriptingEnv.h b/MantidPlot/src/ScriptingEnv.h
index 58544a890615f75207531c22948194645b2c2d48..861d9f8ce08f564523cf887b7c0a49ba3c2fea09 100644
--- a/MantidPlot/src/ScriptingEnv.h
+++ b/MantidPlot/src/ScriptingEnv.h
@@ -169,7 +169,7 @@ public:
   static int numLanguages();
 
 private:
-  typedef ScriptingEnv *(*ScriptingEnvConstructor)(ApplicationWindow *);
+  using ScriptingEnvConstructor = ScriptingEnv *(*)(ApplicationWindow *);
   typedef struct {
     const char *name;
     ScriptingEnvConstructor constructor;
diff --git a/MantidPlot/src/TiledWindow.cpp b/MantidPlot/src/TiledWindow.cpp
index 58d522c6f5b2e4d616a3b89bc86cb8b931a4a236..f7ff58ad82a8d410635d90188dfa81f72aad98f0 100644
--- a/MantidPlot/src/TiledWindow.cpp
+++ b/MantidPlot/src/TiledWindow.cpp
@@ -911,7 +911,7 @@ void TiledWindow::selectRange(int row1, int col1, int row2, int col2) {
 void TiledWindow::removeSelectionTo(TiledWindow::RemoveDestination to) {
   foreach (Tile *tile, m_selection) {
     MdiSubWindow *widget = removeTile(tile);
-    if (widget == NULL) {
+    if (widget == nullptr) {
       throw std::logic_error("TiledWindow: Empty tile is found in slection.");
     }
     sendWidgetTo(widget, to);
diff --git a/MantidPlot/src/WindowFactory.h b/MantidPlot/src/WindowFactory.h
index 7a777ced661bd3b464c4f30511ca91ab298c3f84..46e7c447554a7a40061a0f96ef22cea8834e1ff7 100644
--- a/MantidPlot/src/WindowFactory.h
+++ b/MantidPlot/src/WindowFactory.h
@@ -101,8 +101,8 @@ public:
 
 class WindowFactoryImpl final {
 private:
-  typedef AbstractProjectInstantiator<MantidQt::API::IProjectSerialisable>
-      AbstractFactory;
+  using AbstractFactory =
+      AbstractProjectInstantiator<MantidQt::API::IProjectSerialisable>;
 
 public:
   WindowFactoryImpl();
@@ -173,8 +173,8 @@ private:
   }
 
   /// A typedef for the map of registered classes
-  typedef Mantid::Kernel::CaseInsensitiveMap<std::unique_ptr<AbstractFactory>>
-      FactoryMap;
+  using FactoryMap =
+      Mantid::Kernel::CaseInsensitiveMap<std::unique_ptr<AbstractFactory>>;
   /// The map holding the registered class names and their instantiators
   FactoryMap _map;
 };
@@ -184,7 +184,7 @@ private:
 template class Mantid::Kernel::SingletonHolder<WindowFactoryImpl>;
 #endif /* _WIN32 */
 
-typedef Mantid::Kernel::SingletonHolder<WindowFactoryImpl> WindowFactory;
+using WindowFactory = Mantid::Kernel::SingletonHolder<WindowFactoryImpl>;
 }
 }
 
diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp
index a041ae55b1d52d7ad6f7ea0d2f68337b570bf99c..35df0ddf0183f867f911e48430139b389f3d63d1 100644
--- a/MantidPlot/src/importOPJ.cpp
+++ b/MantidPlot/src/importOPJ.cpp
@@ -501,7 +501,7 @@ bool ImportOPJ::importNotes(const OPJFile &opj) {
   int visible_count = 0;
   for (int n = 0; n < opj.numNotes(); n++) {
     QString name = opj.noteName(n);
-    QRegExp rx("^@\\((\\S+)\\)$");
+    QRegExp rx(R"(^@\((\S+)\)$)");
     if (rx.indexIn(name) == 0)
       name = rx.cap(1);
 
@@ -1175,8 +1175,8 @@ bool ImportOPJ::importGraphs(const OPJFile &opj) {
       vector<text> texts = opj.layerTexts(g, l);
       if (style != GraphOptions::Pie) {
         for (size_t i = 0; i < texts.size(); ++i) {
-          addText(texts[i], graph, 0, layerRect, fFontScaleFactor, fXScale,
-                  fYScale);
+          addText(texts[i], graph, nullptr, layerRect, fFontScaleFactor,
+                  fXScale, fYScale);
         }
       }
 
@@ -1358,8 +1358,8 @@ QString ImportOPJ::parseOriginText(const QString &str) {
 QString ImportOPJ::parseOriginTags(const QString &str) {
   QString line = str;
   // Lookbehind conditions are not supported - so need to reverse string
-  QRegExp rx("\\)[^\\)\\(]*\\((?!\\s*[buig\\+\\-]\\s*\\\\)");
-  QRegExp rxfont("\\)[^\\)\\(]*\\((?![^\\:]*\\:f\\s*\\\\)");
+  QRegExp rx(R"(\)[^\)\(]*\((?!\s*[buig\+\-]\s*\\))");
+  QRegExp rxfont(R"(\)[^\)\(]*\((?![^\:]*\:f\s*\\))");
   QString linerev = strreverse(line);
   QString lBracket = strreverse("&lbracket;");
   QString rBracket = strreverse("&rbracket;");
@@ -1396,10 +1396,10 @@ QString ImportOPJ::parseOriginTags(const QString &str) {
 
   // replace \b(...), \i(...), \u(...), \g(...), \+(...), \-(...), \f:font(...)
   // tags
-  QString rxstr[] = {"\\\\\\s*b\\s*\\(",      "\\\\\\s*i\\s*\\(",
-                     "\\\\\\s*u\\s*\\(",      "\\\\\\s*g\\s*\\(",
-                     "\\\\\\s*\\+\\s*\\(",    "\\\\\\s*\\-\\s*\\(",
-                     "\\\\\\s*f\\:[^\\(]*\\("};
+  QString rxstr[] = {R"(\\\s*b\s*\()",     R"(\\\s*i\s*\()",
+                     R"(\\\s*u\s*\()",     R"(\\\s*g\s*\()",
+                     R"(\\\s*\+\s*\()",    R"(\\\s*\-\s*\()",
+                     R"(\\\s*f\:[^\(]*\()"};
   int postag[] = {0, 0, 0, 0, 0, 0, 0};
   QString ltag[] = {"<b>", "<i>", "<u>", "<font face=Symbol>", "<sup>", "<sub>",
                     "<font face=%1>"};
@@ -1407,7 +1407,7 @@ QString ImportOPJ::parseOriginTags(const QString &str) {
                     "</sup>", "</sub>", "</font>"};
   QRegExp rxtags[7];
   for (int i = 0; i < 7; ++i)
-    rxtags[i].setPattern(rxstr[i] + "[^\\(\\)]*\\)");
+    rxtags[i].setPattern(rxstr[i] + R"([^\(\)]*\))");
 
   bool flag = true;
   while (flag) {
diff --git a/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp b/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp
index 0ebcec2d711dec5d5a9bbae28cbd21f06be1a59b..c599b26d407bc9ebab0f423874f9454a244ce0e1 100644
--- a/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp
+++ b/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp
@@ -605,10 +605,7 @@ void ColorPickerPopup::insertColor(const QColor &col, const QString &text,
 QColor ColorPickerPopup::color(int index) const {
   if (index < 0 || index > (int)items.count() - 1)
     return QColor();
-
-  // cppcheck-suppress cstyleCast
-  ColorPickerPopup *that = (ColorPickerPopup *)this;
-  return that->items.at(index)->color();
+  return this->items.at(index)->color();
 }
 
 /*! \internal
diff --git a/MantidPlot/src/lib/src/TextFormatButtons.cpp b/MantidPlot/src/lib/src/TextFormatButtons.cpp
index 54a29ade87b5615596c8c3eb6c8906dc7c0828f4..12b6dae42efbd09574a79932c0fea5ba1f9a5988 100644
--- a/MantidPlot/src/lib/src/TextFormatButtons.cpp
+++ b/MantidPlot/src/lib/src/TextFormatButtons.cpp
@@ -457,10 +457,10 @@ void TextFormatButtons::addSymbol(const QString &letter) {
     else if (letter == QString(QChar(4 + s)))
       connectedTextEdit->textCursor().insertText("\\int");
     else if (letter == QString(QChar(5 + s)))
-      connectedTextEdit->textCursor().insertText("\\int \\!\\!\\! \\int");
+      connectedTextEdit->textCursor().insertText(R"(\int \!\!\! \int)");
     else if (letter == QString(QChar(6 + s)))
       connectedTextEdit->textCursor().insertText(
-          "\\int \\!\\!\\! \\int \\!\\!\\! \\int");
+          R"(\int \!\!\! \int \!\!\! \int)");
     else if (letter == QString(QChar(7 + s)))
       connectedTextEdit->textCursor().insertText("\\oint");
 
diff --git a/MantidPlot/src/muParserScript.cpp b/MantidPlot/src/muParserScript.cpp
index 93fc202f09074a42fa13a0f1d141335ee6cfaf8b..749d5ad209e6f0edeee2b1029850c1e86340acf1 100644
--- a/MantidPlot/src/muParserScript.cpp
+++ b/MantidPlot/src/muParserScript.cpp
@@ -149,7 +149,7 @@ double muParserScript::col(const QString &arg) {
                                      .toAscii()
                                      .constData());
   if (table->text(row, col).isEmpty())
-    throw new EmptySourceError();
+    throw EmptySourceError();
   else {
     return table->cell(row, col);
   }
@@ -231,7 +231,7 @@ double muParserScript::tablecol(const QString &arg) {
                                      .toAscii()
                                      .constData());
   if (target_table->text(row, col).isEmpty())
-    throw new EmptySourceError();
+    throw EmptySourceError();
   else
     return target_table->cell(row, col);
 }
@@ -254,7 +254,7 @@ double muParserScript::cell(int row, int col) {
                                      .toAscii()
                                      .constData());
   if (matrix->text(row - 1, col - 1).isEmpty())
-    throw new EmptySourceError();
+    throw EmptySourceError();
   else
     return matrix->cell(row - 1, col - 1);
 }
@@ -277,7 +277,7 @@ double muParserScript::tableCell(int col, int row) {
                                      .toAscii()
                                      .constData());
   if (table->text(row - 1, col - 1).isEmpty())
-    throw new EmptySourceError();
+    throw EmptySourceError();
   else
     return table->cell(row - 1, col - 1);
 }
@@ -394,7 +394,7 @@ QString muParserScript::evalSingleLineToString(const QLocale &locale, char f,
   double val = 0.0;
   try {
     val = parser.Eval();
-  } catch (EmptySourceError *) {
+  } catch (EmptySourceError &) {
     return "";
   } catch (ParserError &) {
     return "";
@@ -406,7 +406,7 @@ double muParserScript::evalSingleLine() {
   double val = 0.0;
   try {
     val = parser.Eval();
-  } catch (EmptySourceError *) {
+  } catch (EmptySourceError &) {
     return GSL_NAN;
   } catch (ParserError &) {
     return GSL_NAN;
@@ -467,7 +467,7 @@ bool muParserScript::compileImpl() {
     parser.SetExpr(muCode[0].toAscii().constData());
     try {
       parser.Eval();
-    } catch (EmptySourceError *) {
+    } catch (EmptySourceError &) {
       QApplication::restoreOverrideCursor();
       return false;
     } catch (mu::ParserError &e) {
@@ -492,7 +492,7 @@ QVariant muParserScript::evaluateImpl() {
       parser.SetExpr(i->toAscii().constData());
       val = parser.Eval();
     }
-  } catch (EmptySourceError *) {
+  } catch (EmptySourceError &) {
     return QVariant("");
   } catch (ParserError &e) {
     emit error(e.GetMsg().c_str(), "", 0);
@@ -510,7 +510,7 @@ bool muParserScript::executeImpl() {
       parser.SetExpr(i->toAscii().constData());
       parser.Eval();
     }
-  } catch (EmptySourceError *) {
+  } catch (EmptySourceError &) {
     return true;
   } catch (mu::ParserError &e) {
     emit error(e.GetMsg().c_str(), "", 0);
diff --git a/MantidPlot/src/origin/tree.hh b/MantidPlot/src/origin/tree.hh
index beb1bf1e38e025a92b3816115522c53356452a1d..c036254fb88100cfc64e741de9d0e9d476ce294f 100644
--- a/MantidPlot/src/origin/tree.hh
+++ b/MantidPlot/src/origin/tree.hh
@@ -66,10 +66,10 @@ tree_node_<T>::tree_node_(const T& val)
 template <class T, class tree_node_allocator = std::allocator<tree_node_<T> > >
 class tree {
 	protected:
-		typedef tree_node_<T> tree_node;
+		using tree_node = tree_node_<T>;
 	public:
 		/// Value of the data stored at a node.
-		typedef T value_type;
+		using value_type = T;
 
 		class iterator_base;
 		class pre_order_iterator;
@@ -91,12 +91,12 @@ class tree {
 		class iterator_base {
 #endif
 			public:
-				typedef T                               value_type;
-				typedef T*                              pointer;
-				typedef T&                              reference;
-				typedef size_t                          size_type;
-				typedef ptrdiff_t                       difference_type;
-				typedef std::bidirectional_iterator_tag iterator_category;
+				using value_type = T;
+				using pointer = T *;
+				using reference = T &;
+				using size_type = size_t;
+				using difference_type = ptrdiff_t;
+				using iterator_category = std::bidirectional_iterator_tag;
 
 				iterator_base();
 				iterator_base(tree_node *);
@@ -175,8 +175,8 @@ class tree {
 		};
 
 		/// The default iterator types throughout the tree class.
-		typedef pre_order_iterator            iterator;
-		typedef breadth_first_queued_iterator breadth_first_iterator;
+		using iterator = pre_order_iterator;
+		using breadth_first_iterator = breadth_first_queued_iterator;
 
 		/// Iterator which traverses only the nodes at a given depth from the root.
 		class fixed_depth_iterator : public iterator_base {
@@ -713,7 +713,7 @@ typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_al
 template <class T, class tree_node_allocator>
 typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::begin(const iterator_base& pos) const
 	{
-	assert(pos.node!=0);
+	assert(pos.node!=nullptr);
 	if(pos.node->first_child==nullptr) {
 		return end(pos);
 		}
@@ -764,7 +764,7 @@ template <class T, class tree_node_allocator>
 template <typename iter>
 iter tree<T, tree_node_allocator>::parent(iter position) 
 	{
-	assert(position.node!=0);
+	assert(position.node!=nullptr);
 	return iter(position.node->parent);
 	}
 
@@ -1667,7 +1667,7 @@ template <class T, class tree_node_allocator>
 int tree<T, tree_node_allocator>::depth(const iterator_base& it) 
 	{
 	tree_node* pos=it.node;
-	assert(pos!=0);
+	assert(pos!=nullptr);
 	int ret=0;
 	while(pos->parent!=nullptr) {
 		pos=pos->parent;
@@ -2119,7 +2119,7 @@ tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(const sibli
 template <class T, class tree_node_allocator>
 typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator++()
 	{
-	assert(this->node!=0);
+	assert(this->node!=nullptr);
 	if(!this->skip_current_children_ && this->node->first_child != nullptr) {
 		this->node=this->node->first_child;
 		}
diff --git a/MantidPlot/test/MantidPlotPyplotGeneralTest.py b/MantidPlot/test/MantidPlotPyplotGeneralTest.py
deleted file mode 100644
index 5a89029aa2241dda72474752ce26b311057d815b..0000000000000000000000000000000000000000
--- a/MantidPlot/test/MantidPlotPyplotGeneralTest.py
+++ /dev/null
@@ -1,250 +0,0 @@
-"""General tests for the basic interface of mantidplot.pyplot
-
-Tests correct creation of output lines from plots (with correct
-Figure, Graph, etc. data), and proper handling (exception) of wrong
-input parameters. Tests plotting of normal arrays and workspaces with the following tools ('tool' kwarg): plot_spectrum, plot_bin, plot_
-
-"""
-from __future__ import (absolute_import, division, print_function)
-import mantidplottests
-from mantidplottests import *
-import time
-import numpy as np
-from PyQt4 import QtGui, QtCore
-
-# =============== Create fake workspaces to plot =======================
-X1 = np.linspace(0,10, 100)
-Y1 = 1000*(np.sin(X1)**2) + X1*10
-X1 = np.append(X1, 10.1)
-
-X2 = np.linspace(2,12, 100)
-Y2 = 500*(np.cos(X2/2.)**2) + 20
-X2 = np.append(X2, 12.10)
-
-X = np.append(X1, X2)
-Y = np.append(Y1, Y2)
-E = np.sqrt(Y)
-
-# this one has 2 spectra
-WorkspaceName2D = 'fake ws'
-CreateWorkspace(OutputWorkspace=WorkspaceName2D, DataX=list(X), DataY=list(Y), DataE=list(E), NSpec=2,
-                UnitX="TOF", YUnitLabel="Counts",  WorkspaceTitle="Test/faked data Workspace, 2 spectra")
-
-sec_X3 = np.linspace(2,12, 100)
-sec_Y3 = 200*(np.tan(sec_X3/2.4)**2) + 15
-sec_X3 = np.append(sec_X3, 12.10)
-
-sec_X = np.append(X, sec_X3)
-sec_Y = np.append(Y, sec_Y3)
-sec_E = np.power(sec_Y, 0.6)
-
-# this one has 3 spectra
-SecondWorkspaceName2D = 'another fake ws'
-CreateWorkspace(OutputWorkspace=SecondWorkspaceName2D, DataX=list(sec_X), DataY=list(sec_Y), DataE=list(sec_E), NSpec=3,
-                UnitX="TOF", YUnitLabel="Counts",  WorkspaceTitle="Test/faked data Workspace, 3 spectra")
-
-# plot_md needs an MD workspace with a single non-integrated dimension
-MDWWorkspaceName = 'mdw'
-mdSignal = np.sin(list(range(0,100,1)))
-errInput = mdSignal/20.5
-CreateMDHistoWorkspace(Dimensionality="1", Names='x', Units='m', Extents='0,10', NumberOfBins=len(mdSignal), SignalInput=mdSignal, ErrorInput=errInput, OutputWorkspace=MDWWorkspaceName)
-
-class MantidPlotPyplotGeneralTest(unittest.TestCase):
-
-    def setUp(self):
-        self.g = None
-
-    def tearDown(self):
-        """Clean up by closing the created window """
-        windows = self.g
-        if not self.g:
-            return
-        if type(self.g) != list:
-            windows = [self.g]
-        for window in windows:
-            self.close_win_by_graph(window)
-
-    def close_win_by_graph(self, g):
-        if None != g:
-            g.confirmClose(False)
-            g.close()
-            QtCore.QCoreApplication.processEvents()
-
-    def test_nothing(self):
-        return True
-
-    def check_output_lines(self, lines, expected_len):
-        """ Check that the lines returned by a plot are correctly built """
-        self.assertTrue(expected_len==len(lines))
-        for i in range(0, len(lines)):
-            self.assertTrue(isinstance(lines[i], Line2D))
-            self.assertTrue(isinstance(lines[i].figure(), Figure))
-            self.assertTrue(isinstance(lines[i]._graph, proxies.Graph))
-            self.assertTrue(isinstance(lines[i].figure()._graph, proxies.Graph))
-
-    def close_win(self, lines):
-        """
-        Close a plot window. Use this on your test windows to prevent very likely
-        segfaults at the end of the tests.
-
-        @param lines :: lines object as returned by the plot function
-        """
-        if len(lines) > 0:
-            self.close_win_by_graph(lines[0]._graph)        
-
-    def test_plot_spectrum_ok(self):
-        lines_spec = plot_spectrum(WorkspaceName2D, [0, 1])
-        self.check_output_lines(lines_spec, 2)
-        self.close_win(lines_spec)
-
-        tool_names = ['plot_spectrum', 'plot_sp', 'spectrum', 'sp']
-        for tname in tool_names:
-            lines = plot(WorkspaceName2D, [0, 1], tool=tname)
-            self.check_output_lines(lines, 2)
-            self.close_win(lines)
-
-            if self.assertTrue(len(lines) == len(lines_spec)):
-                for i in range(0, len(lines)):
-                    self.assertEqual(lines[i].get_xdata(), lines_spec[i].get_xdata())
-                    self.assertEqual(lines[i].get_ydata(), lines_spec[i].get_ydata())
-
-    def test_plot_bin_ok(self):
-        lines_bin = plot_bin(WorkspaceName2D, [0, 1, 2])
-        self.check_output_lines(lines_bin, 3)
-        self.close_win(lines_bin)
-
-        tool_names = ['plot_bin', 'bin']
-        for tname in tool_names:
-            lines = plot(WorkspaceName2D, [0, 1, 2], tool=tname)
-            self.check_output_lines(lines, 3)
-            self.close_win(lines)
-
-            if self.assertTrue(len(lines) == len(lines_bin)):
-                for i in range(0, len(lines)):
-                    self.assertEqual(lines[i].get_xdata(), lines2_bin[i].get_xdata())
-                    self.assertEqual(lines[i].get_ydata(), lines2_bin[i].get_ydata())
-
-    def test_lines_get_data(self):
-        y = [0.2, 0.5, 0.1, 0.6]
-        # note this assumes that plot will make a dummy workspace using 0,1,2... as X
-        x = list(range(0, len(y), 1))
-
-        lines = plot(y)
-        self.check_output_lines(lines, 1)
-        # and here also check the values
-        if 1==len(lines):
-            self.assertEqual(lines[0].get_xdata(), x)
-            self.assertEqual(lines[0].get_ydata(), y)
-        self.close_win(lines)
-
-    def test_plot_md_ok(self):
-        lines = plot_md(MDWWorkspaceName)
-        self.assertEqual(len(lines), 1)
-        self.close_win(lines)
-
-        tool_names = ['plot_md', 'md']
-        for tnames in tool_names:
-            lines = plot(MDWWorkspaceName, tool='plot_md')
-            self.assertEqual(len(lines), 1)
-            self.close_win(lines)
-
-        # now see what happens with non-md workspaces
-        self.assertRaises(ValueError, plot, WorkspaceName2D, tool='plot_md')
-
-        self.assertRaises(ValueError, plot_md, WorkspaceName2D)
-
-    def test_plot_array_ok(self):
-        val = []    # empty data, will be replaced with a dummy (0,0) and generate a 'point' line
-        lines = plot(val)
-        self.check_output_lines(lines, 1)
-        self.close_win(lines)
-
-    def test_plot_with_more_functions(self):
-        lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=2, linestyle='--', marker='v')
-        xlim(0, 1)
-        ylim(0, 1)
-        xlabel('X foo label')
-        ylabel('Y bar label')
-        title('baz title')
-        axis([0, 1, 0, 1])
-        grid('off')
-        grid('on')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-    def test_plot_with_style_args(self):
-        # note that these tests also use various aliases for the tool name 'plot_spectrum'
-        # Not adding all the possible combinations here, as this suite is becoming time consuming
-        lines = plot(WorkspaceName2D, [0,1], '--g', tool='plot_spectrum')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-        lines = plot(WorkspaceName2D, [0,1], 'y:>', tool='plot_sp')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-    def test_plot_with_style_args_and_kwargs(self):
-        lines = plot(WorkspaceName2D, [0,1], '-.m', tool='spectrum')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-        lines = plot(WorkspaceName2D, [0,1], 'r-.>', tool='sp')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-    def test_plot_with_kwargs(self):
-        lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=3, linestyle='-.', marker='v')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-        lines = plot(WorkspaceName2D, [0,1], tool='plot_sp', linewidth=3, linestyle='-.', marker='v')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-        lines = plot(SecondWorkspaceName2D, [0,1, 2], tool='sp', linewidth=3, linestyle='-.', marker='v')
-        self.check_output_lines(lines, 3)
-        self.close_win(lines)
-
-    def test_plot_with_none_marker(self):
-        lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linestyle='--', marker=None)
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-        lines = plot(WorkspaceName2D, 0, tool='plot_spectrum', color='y', marker='None')
-        self.check_output_lines(lines, 1)
-        self.close_win(lines)
-
-    def test_wrong_kwargs(self):
-        # funny kwargs should have no big consequences
-        lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=3, linestyle='-.',
-                     marker='v', funny_foo='bar', funny_baz='qux')
-        self.check_output_lines(lines, 2)
-        self.close_win(lines)
-
-    def test_multi_plot_commands(self):
-        lines = plot(WorkspaceName2D, [0,1], SecondWorkspaceName2D, [0, 1, 2])
-        self.check_output_lines(lines, 5)
-        self.close_win(lines)
-
-        lines = plot(WorkspaceName2D, [0,1], SecondWorkspaceName2D, [0, 1, 2])
-        self.check_output_lines(lines, 5)
-        self.close_win(lines)
-
-        # this one mixes up positional and kw args
-        self.assertRaises(ValueError, plot,
-                          WorkspaceName2D, [0,1], WorkspaceName2D, tool='plot_spectrum')
-
-    def test_savefig(self):
-        # save a minimal figure just to check that the file is written
-        import os
-
-        lines = plot([0, 0.5, 0.1])
-        tmp_figname = 'pyplot_tmp_fig_test.png'
-        savefig(tmp_figname)
-        self.close_win(lines)
-
-        self.assertTrue(os.path.exists(tmp_figname))
-        os.remove(tmp_figname)
-
-# Run the unit tests
-mantidplottests.runTests(MantidPlotPyplotGeneralTest)
diff --git a/Testing/Data/SystemTest/ILL/D2B/532008.nxs.md5 b/Testing/Data/SystemTest/ILL/D2B/532008.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..63c8642c0b99b306bc49724f47b688d1beb7c00f
--- /dev/null
+++ b/Testing/Data/SystemTest/ILL/D2B/532008.nxs.md5
@@ -0,0 +1 @@
+d5b95c6cae111b15d8744d23df643306
diff --git a/Testing/Data/SystemTest/ILL/D2B/532009.nxs.md5 b/Testing/Data/SystemTest/ILL/D2B/532009.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..b6052941f3b8cf67596a945d635fa8f312cd6a27
--- /dev/null
+++ b/Testing/Data/SystemTest/ILL/D2B/532009.nxs.md5
@@ -0,0 +1 @@
+161d6e2ac2bde6e04b7fbf801bcc9652
diff --git a/Testing/Data/UnitTest/vulcan_diamond.nxs.md5 b/Testing/Data/UnitTest/vulcan_diamond.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..b7529450e5d9d511a43e13c39a279be21ac53827
--- /dev/null
+++ b/Testing/Data/UnitTest/vulcan_diamond.nxs.md5
@@ -0,0 +1 @@
+14177b391181000b71abae61aa551cef
diff --git a/Testing/SystemTests/tests/analysis/CodeConventions.py b/Testing/SystemTests/tests/analysis/CodeConventions.py
index d0364e1bcaae9354cd6604b39bb83ef9fd9184b7..8b0010b9d0570976f89837db548b5373790fd323 100644
--- a/Testing/SystemTests/tests/analysis/CodeConventions.py
+++ b/Testing/SystemTests/tests/analysis/CodeConventions.py
@@ -23,6 +23,7 @@ ALG_BAD_PARAMS = {
     "EstimateDivergence(v1)":("alpha", "beta0", "beta1"),
     "FindUBUsingLatticeParameters(v1)":("a", "b", "c", "alpha", "beta", "gamma"),
     "IndexSXPeaks(v1)":("a", "b", "c", "alpha", "beta", "gamma", "dTolerance"),
+    "LoadDNSSCD(v1)":("a", "b", "c", "alpha", "beta", "gamma"),
     "ModeratorTzero(v1)":("tolTOF"),
     "MuscatFunc(v1)":("dQ", "dW"),
     "OptimizeCrystalPlacement(v1)":("nPeaks", "nParams", "nIndexed"),
diff --git a/Testing/SystemTests/tests/analysis/GSASIIRefineFitPeaksTest.py b/Testing/SystemTests/tests/analysis/GSASIIRefineFitPeaksTest.py
index da38a43afe3f549764a6da65b7dc799f2218f41b..dff2a45e189a336e8a026ff4a81697796d725e2c 100644
--- a/Testing/SystemTests/tests/analysis/GSASIIRefineFitPeaksTest.py
+++ b/Testing/SystemTests/tests/analysis/GSASIIRefineFitPeaksTest.py
@@ -20,6 +20,7 @@ class _AbstractGSASIIRefineFitPeaksTest(stresstesting.MantidStressTest):
     sigma = None
     lattice_params_table = None
 
+    _FITTED_PEAKS_WS_NAME = "FittedPeaks"
     _LATTICE_PARAM_TBL_NAME = "LatticeParameters"
     _INPUT_WORKSPACE_FILENAME = "focused_bank1_ENGINX00256663.nxs"
     _PHASE_FILENAME_1 = "Fe-gamma.cif"
@@ -36,6 +37,10 @@ class _AbstractGSASIIRefineFitPeaksTest(stresstesting.MantidStressTest):
     def _get_fit_params_reference_filename(self):
         pass
 
+    @abstractmethod
+    def _get_fitted_peaks_reference_filename(self):
+        pass
+
     @abstractmethod
     def _get_gsas_proj_filename(self):
         pass
@@ -85,6 +90,7 @@ class _AbstractGSASIIRefineFitPeaksTest(stresstesting.MantidStressTest):
 
         self.fitted_peaks_ws, self.lattice_params_table, self.rwp, self.sigma, self.gamma = \
             GSASIIRefineFitPeaks(RefinementMethod=self._get_refinement_method(),
+                                 OutputWorkspace=self._FITTED_PEAKS_WS_NAME,
                                  InputWorkspace=self.input_ws,
                                  PhaseInfoFiles=self.phase_file_paths(),
                                  InstrumentFile=self.inst_param_file_path(),
@@ -100,10 +106,10 @@ class _AbstractGSASIIRefineFitPeaksTest(stresstesting.MantidStressTest):
         return True
 
     def validate(self):
-        # TODO: Check fitted_peaks_ws has correct values once we have some data we're sure of
-        self.assertEqual(self.input_ws.getNumberBins(), self.fitted_peaks_ws.getNumberBins())
-        self.assertAlmostEqual(self.rwp, self._get_expected_rwp(), delta=1e-6)
-        return self._LATTICE_PARAM_TBL_NAME, mantid.FileFinder.getFullPath(self._get_fit_params_reference_filename())
+        self.tolerance = 1e-4
+        self.assertAlmostEqual(self.rwp, self._get_expected_rwp(), delta=1e-5)
+        return (self._LATTICE_PARAM_TBL_NAME, mantid.FileFinder.getFullPath(self._get_fit_params_reference_filename()),
+                self._FITTED_PEAKS_WS_NAME, mantid.FileFinder.getFullPath(self._get_fitted_peaks_reference_filename()))
 
 
 class GSASIIRefineFitPeaksRietveldTest(_AbstractGSASIIRefineFitPeaksTest):
@@ -117,6 +123,9 @@ class GSASIIRefineFitPeaksRietveldTest(_AbstractGSASIIRefineFitPeaksTest):
     def _get_fit_params_reference_filename(self):
         return "GSASIIRefineFitPeaksRietveldFitParams.nxs"
 
+    def _get_fitted_peaks_reference_filename(self):
+        return "GSASIIRefineFitPeaksRietveldFittedPeaks.nxs"
+
     def _get_gsas_proj_filename(self):
         return "GSASIIRefineFitPeaksRietveldTest.gpx"
 
@@ -130,11 +139,14 @@ class GSASIIRefineFitPeaksPawleyTest(_AbstractGSASIIRefineFitPeaksTest):
         return not self.path_to_gsas()
 
     def _get_expected_rwp(self):
-        return 74.025863
+        return 24.051622
 
     def _get_fit_params_reference_filename(self):
         return "GSASIIRefineFitPeaksPawleyFitParams.nxs"
 
+    def _get_fitted_peaks_reference_filename(self):
+        return "GSASIIRefineFitPeaksPawleyFittedPeaks.nxs"
+
     def _get_gsas_proj_filename(self):
         return "GSASIIRefineFitPeaksPawleyTest.gpx"
 
diff --git a/Testing/SystemTests/tests/analysis/PowderDiffILLDetScanReductionTest.py b/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py
similarity index 93%
rename from Testing/SystemTests/tests/analysis/PowderDiffILLDetScanReductionTest.py
rename to Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py
index 1740eb86816577a69ad84149c41254340bb3cf99..8c502913d2173a1b7846af31059b3d4afd899403 100644
--- a/Testing/SystemTests/tests/analysis/PowderDiffILLDetScanReductionTest.py
+++ b/Testing/SystemTests/tests/analysis/ILLPowderDiffDetScanReductionTest.py
@@ -5,10 +5,10 @@ from mantid.simpleapi import PowderDiffILLDetScanReduction, \
 from mantid import config
 
 
-class PowderDiffILLDetScanReductionTest(stresstesting.MantidStressTest):
+class ILLPowderDiffDetScanReductionTest(stresstesting.MantidStressTest):
 
     def __init__(self):
-        super(PowderDiffILLDetScanReductionTest, self).__init__()
+        super(ILLPowderDiffDetScanReductionTest, self).__init__()
         self.setUp()
 
     def setUp(self):
@@ -17,7 +17,7 @@ class PowderDiffILLDetScanReductionTest(stresstesting.MantidStressTest):
         config.appendDataSearchSubDir('ILL/D2B/')
 
     def requiredFiles(self):
-        return ["508093.nxs, 508094.nxs, 508095.nxs, D2B_scan_test.nxs"]
+        return ["508093.nxs, 508094.nxs, 508095.nxs"]
 
     def d2b_2d_tubes_test(self):
         ws_2d_tubes = PowderDiffILLDetScanReduction(
@@ -88,4 +88,5 @@ class PowderDiffILLDetScanReductionTest(stresstesting.MantidStressTest):
         GroupWorkspaces([ws_2d_tubes[0], ws_2d[0], ws_1d[0]], OutputWorkspace='grouped_output')
 
     def validate(self):
+        self.tolerance = 0.0001
         return 'grouped_output', 'D2B_scan_test.nxs'
diff --git a/Testing/SystemTests/tests/analysis/ILL_D2B_DetEffCorrTest.py b/Testing/SystemTests/tests/analysis/ILL_D2B_DetEffCorrTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9fe1a0d6bd19ee0132f6e5906d771dd430b3273
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/ILL_D2B_DetEffCorrTest.py
@@ -0,0 +1,36 @@
+from __future__ import (absolute_import, division, print_function)
+
+import stresstesting
+from mantid.simpleapi import PowderDiffILLDetEffCorr, GroupWorkspaces
+from mantid import config, mtd
+
+
+class ILL_D2B_DetEffCorrTest(stresstesting.MantidStressTest):
+
+    def __init__(self):
+        super(ILL_D2B_DetEffCorrTest, self).__init__()
+        self.setUp()
+
+    def setUp(self):
+        config['default.facility'] = 'ILL'
+        config['default.instrument'] = 'D2B'
+        config.appendDataSearchSubDir('ILL/D2B/')
+
+    def requiredFiles(self):
+        return ['532008.nxs', '532009.nxs']
+
+    def tearDown(self):
+        mtd.clear()
+
+    def runTest(self):
+
+        PowderDiffILLDetEffCorr(CalibrationRun='532008,532009',
+                                DerivationMethod='GlobalSummedReference2D',
+                                ExcludedRange=[-5,10],
+                                OutputWorkspace='calib',
+                                OutputResponseWorkspace='response')
+        GroupWorkspaces(InputWorkspaces=['calib','response'], OutputWorkspace='group')
+
+    def validate(self):
+        self.tolerance = 0.01
+        return ['group', 'D2B_DetEffCorr_Ref.nxs']
diff --git a/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py b/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py
index 23bbc3641272677f12024636d9c845740353d5c5..687464ba1d4cad0a7ddeaba17d8b34e899d66ad0 100644
--- a/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py
+++ b/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py
@@ -411,7 +411,7 @@ class JumpTeixeiraTest(JumpFitFunctionTestBase):
     def __init__(self):
         JumpFitFunctionTestBase.__init__(self)
 
-        self._function = 'name=TeixeiraWater,Tau=1.6,L=0.4'
+        self._function = 'name=TeixeiraWater,Tau=1.6,L=0.9'
         self.tolerance = 1e-3
 
     def get_reference_files(self):
diff --git a/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py b/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py
index 2c450b140d6623818cce88c90d6141b395eaa88c..667f45a7aeae19d3e18a4e0779dbdac9df7cd420 100644
--- a/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py
+++ b/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py
@@ -1,21 +1,26 @@
 #pylint: disable=no-init
 import stresstesting
-from mantid.simpleapi import *
+from mantid.simpleapi import LoadEventNexus
 
 
 class ISISLoadingEventData(stresstesting.MantidStressTest):
-    """ There is no event data inside mantid/Test directory.
-        Hence, all the units test that are specific to ISIS
-        when loading EventData should go to here.
+    """Older ISIS event files were actually, effectively, very finely-binned
+    histograms where each "event" was assigned the TOF at the centre of a bin.
+    Attempting to bin this type of data from event mode to histogram mode would
+    then lead to odd effects as you would have clusters of events that were
+    articifically at the "same" time period.
+    For these files Mantid randomizes the TOF from within the bin it was
+    assigned as it loads. Later files have this operation done by the DAE.
     """
 
     def runTest(self):
         ev_ws = LoadEventNexus('LET00006278.nxs')
         # isis_vms_compat/SPB[2]
-        self.assertEqual(ev_ws.sample().getGeometryFlag(), 1, "It does not read correctly the vms compat (check ")
+        self.assertEqual(ev_ws.sample().getGeometryFlag(), 1,
+                         "Geometry flag mimatch. vms_compat block not read correctly")
         # Isis correct the tof using loadTimeOfFlight method.
-        self.assertDelta(   ev_ws.getSpectrum(10).getTofs()[1], 1041.89,0.01,
-                            "The ISIS event correction is incorrect (check LoadEventNexus::loadTimeOfFlight")
+        self.assertDelta(ev_ws.getSpectrum(10).getTofs()[1], 1041.81, 0.01,
+                         "The ISIS event correction is incorrect (check LoadEventNexus::loadTimeOfFlight)")
 
     def validate(self):
         return True
diff --git a/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py b/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
index dca4b3b1cf207287151e4b293622ce8b655131c5..c562424a1903b13cd95d542a7a62f3b04bcf9788 100644
--- a/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
+++ b/Testing/SystemTests/tests/analysis/ISIS_PowderPearlTest.py
@@ -48,7 +48,11 @@ class _CreateVanadiumTest(stresstesting.MantidStressTest):
 
     def runTest(self):
         setup_mantid_paths()
-        run_vanadium_calibration(focus_mode=self.focus_mode)
+        inst_obj = setup_inst_object(tt_mode="tt70", focus_mode="trans")
+        run_vanadium_calibration(inst_obj, focus_mode=self.focus_mode)
+
+        # Make sure that inst settings reverted to the default after create_vanadium
+        self.assertEquals(inst_obj._inst_settings.focus_mode, "trans")
 
     def skipTests(self):
         # Don't actually run this test, as it is a dummy for the focus-mode-specific tests
@@ -107,7 +111,11 @@ class FocusTest(stresstesting.MantidStressTest):
     def runTest(self):
         # Gen vanadium calibration first
         setup_mantid_paths()
-        self.focus_results = run_focus()
+        inst_object = setup_inst_object(tt_mode="tt88", focus_mode="Trans")
+        self.focus_results = run_focus(inst_object, tt_mode="tt70")
+
+        # Make sure that inst settings reverted to the default after focus
+        self.assertEqual(inst_object._inst_settings.tt_mode, "tt88")
 
     def validate(self):
         self.tolerance = 1e-10  # Required for difference in spline data between operating systems
@@ -156,7 +164,11 @@ class CreateCalTest(stresstesting.MantidStressTest):
 
     def runTest(self):
         setup_mantid_paths()
-        self.calibration_results = run_create_cal()
+        inst_object = setup_inst_object(tt_mode="tt88", focus_mode="trans")
+        self.calibration_results = run_create_cal(inst_object, focus_mode="all")
+
+        # Make sure that inst_settings reverted to the default after create_cal
+        self.assertEquals(inst_object._inst_settings.focus_mode, "trans")
 
     def validate(self):
         self.tolerance = 1e-5
@@ -182,22 +194,19 @@ def _gen_required_files():
     return input_files
 
 
-def run_create_cal():
+def run_create_cal(inst_object, focus_mode):
     ceria_run = 98494
-    inst_obj = setup_inst_object(tt_mode="tt88", focus_mode="all")
-    return inst_obj.create_cal(run_number=ceria_run)
+    return inst_object.create_cal(run_number=ceria_run, focus_mode=focus_mode)
 
 
-def run_vanadium_calibration(focus_mode):
+def run_vanadium_calibration(inst_object, focus_mode):
     vanadium_run = 98507  # Choose arbitrary run in the cycle 17_1
 
-    inst_obj = setup_inst_object(tt_mode="tt70", focus_mode=focus_mode)
-
     # Run create vanadium twice to ensure we get two different output splines / files
-    inst_obj.create_vanadium(run_in_cycle=vanadium_run, do_absorb_corrections=True)
+    inst_object.create_vanadium(run_in_cycle=vanadium_run, do_absorb_corrections=True, focus_mode=focus_mode)
 
 
-def run_focus():
+def run_focus(inst_object, tt_mode):
     run_number = 98507
     attenuation_file_name = "PRL112_DC25_10MM_FF.OUT"
 
@@ -208,9 +217,8 @@ def run_focus():
     original_splined_path = os.path.join(input_dir, splined_file_name)
     shutil.copy(original_splined_path, spline_path)
 
-    inst_object = setup_inst_object(tt_mode="tt70", focus_mode="Trans")
     return inst_object.focus(run_number=run_number, vanadium_normalisation=True, do_absorb_corrections=False,
-                             perform_attenuation=True, attenuation_file_path=attenuation_path)
+                             perform_attenuation=True, attenuation_file_path=attenuation_path, tt_mode=tt_mode)
 
 
 def run_focus_with_absorb_corrections():
diff --git a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py b/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py
deleted file mode 100644
index f61dc4634f95d9e9c7c45bbc92b1cf19a361fda8..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# pylint: disable=no-init,invalid-name,attribute-defined-outside-init
-"""
-This system test verifies that OFFSPEC data is processed correctly by
-ReflectometryReductionOneAuto
-"""
-
-import stresstesting
-from mantid.simpleapi import *
-
-
-class OFFSPECReflRedOneAuto(stresstesting.MantidStressTest):
-    def runTest(self):
-        offspec75 = Load("OFFSPEC00027575.raw") #th=0.35
-        offspec76 = Load("OFFSPEC00027576.raw") #th=1.00
-        offspec78 = Load("OFFSPEC00027578.raw") #th=1.70
-        offspec85 = Load("OFFSPEC00027585.raw") #transmission run
-
-        #Process using ReflectometryReductionOneAuto
-        ivq_75, __, __ = ReflectometryReductionOneAuto(offspec75,
-                                                       ThetaIn=0.70,#2*th
-                                                       MomentumTransferStep=1e-3,
-                                                       FirstTransmissionRun=offspec85,
-                                                       Version=1)
-
-        ivq_76, __, __ = ReflectometryReductionOneAuto(offspec76,
-                                                       ThetaIn=2.00,#2*th
-                                                       MomentumTransferStep=1e-3,
-                                                       FirstTransmissionRun=offspec85,
-                                                       Version=1)
-
-        ivq_78, __, __ = ReflectometryReductionOneAuto(offspec78,
-                                                       ThetaIn=3.40,#2*th
-                                                       MomentumTransferStep=1e-3,
-                                                       FirstTransmissionRun=offspec85,
-                                                       Version=1)
-
-        ivq_75_76, __ = Stitch1D(ivq_75, ivq_76, Params="1e-3")
-        #pylint: disable=unused-variable
-        ivq_75_76_78, __ = Stitch1D(ivq_75_76, ivq_78, Params="0,1e-3,0.25")
-        return True
-
-    def validate(self):
-        '''
-        we only wish to check the Q-range in this system test. It is not necessary
-        to check the Instrument definition or Instrument Parameters
-        '''
-        self.disableChecking = ["Instrument"]
-        return ("ivq_75_76_78","OFFSPECReflRedOneAuto_good_v3.nxs")
-
-    def requiredFiles(self):
-        return ["OFFSPEC00027575.raw",
-                "OFFSPEC00027576.raw",
-                "OFFSPEC00027578.raw",
-                "OFFSPEC00027585.raw",
-                "OFFSPECReflRedOneAuto_good_v3.nxs"]
diff --git a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py b/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py
deleted file mode 100644
index b4aaf1e46802965bff96694d9069b9289226984d..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# pylint: disable=no-init, invalid-name, line-too-long, attribute-defined-outside-init
-
-"""
-This system test verifies that OFFSPEC data is processed correctly
-by ReflectometryReductionAutoOne with PolarizationCorrection performed
-as part of the workflow.
-"""
-
-import stresstesting
-from mantid.simpleapi import *
-
-
-class OFFSPECReflRedOneAutoPolarizationCorrection(stresstesting.MantidStressTest):
-    def runTest(self):
-        inputWorkspace = Load("OFFSPEC00033767.nxs")
-        transmissionGroup = Load("OFFSPEC00033772.nxs")
-        #set up our transmission workspace
-        transWorkspace = CreateTransmissionWorkspaceAuto(transmissionGroup,
-                                                         AnalysisMode="MultiDetectorAnalysis",
-                                                         ProcessingInstructions="110-120",
-                                                         WavelengthMin=2.0, WavelengthMax=12.0, Version=1)
-        # set up our efficiency constants
-        CRho=[1]
-        CAlpha=[1]
-        CAp=[1]
-        CPp=[1]
-        #run reflectometryReductionOneAuto
-        __, _IvsLam_polCorr,__ = ReflectometryReductionOneAuto(inputWorkspace, AnalysisMode="MultiDetectorAnalysis",
-                                                               ProcessingInstructions="110-120",
-                                                               FirstTransmissionRun=transWorkspace,
-                                                               ThetaIn="1.2",WavelengthMin=2.0,
-                                                               WavelengthMax=12.0,CorrectionAlgorithm='None',
-                                                               PolarizationAnalysis='PA', MomentumTransferStep=0.1,
-                                                               CPp=CPp,CAp=CAp,CRho=CRho,CAlpha=CAlpha, Version=1)
-        return True
-
-    def validate(self):
-        '''
-        we only wish to check the data from PolarizationCorrection in this system test.
-        It is not necessary to check the Instrument definition or Instrument Parameters
-        '''
-        self.disableChecking = ["Instrument"]
-        return ("_IvsLam_polCorr", "OFFSPECReflRedOneAutoPolarizationCorrection_good_v2.nxs")
-
-    def requiredFiles(self):
-        return ["OFFSPEC00033767.nxs",
-                "OFFSPEC00033772.nxs",
-                "OFFSPECReflRedOneAutoPolarizationCorrection_good_v2.nxs"]
diff --git a/Testing/SystemTests/tests/analysis/REFLReduction.py b/Testing/SystemTests/tests/analysis/REFLReduction.py
deleted file mode 100644
index 695a73a25b62e09ee0979c5f1eb46c5fe32801d7..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/REFLReduction.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#pylint: disable=no-init,attribute-defined-outside-init
-import stresstesting
-from mantid import *
-from mantid.simpleapi import *
-
-
-class REFLReduction(stresstesting.MantidStressTest):
-    def runTest(self):
-        #TODO: The reduction algorithm should not require an absolute path
-        scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg")
-
-        RefLReduction(RunNumbers=[119814],
-                      NormalizationRunNumber=119690,
-                      SignalPeakPixelRange=[154, 166],
-                      SubtractSignalBackground=True,
-                      SignalBackgroundPixelRange=[151, 169],
-                      NormFlag=True,
-                      NormPeakPixelRange=[154, 160],
-                      NormBackgroundPixelRange=[151, 163],
-                      SubtractNormBackground=True,
-                      LowResDataAxisPixelRangeFlag=True,
-                      LowResDataAxisPixelRange=[99, 158],
-                      LowResNormAxisPixelRangeFlag=True,
-                      LowResNormAxisPixelRange=[98, 158],
-                      TOFRange=[29623.0, 42438.0],
-                      IncidentMediumSelected='2InDiamSi',
-                      GeometryCorrectionFlag=False,
-                      QMin=0.005,
-                      QStep=0.01,
-                      AngleOffset=0.009,
-                      AngleOffsetError=0.001,
-                      ScalingFactorFile=scaling_factor_file,
-                      SlitsWidthFlag=True,
-                      OutputWorkspace='reflectivity_119814')
-
-    def validate(self):
-        # Be more tolerant with the output.
-        self.tolerance = 0.0001
-
-        self.disableChecking.append('Instrument')
-        self.disableChecking.append('Sample')
-        self.disableChecking.append('SpectraMap')
-        self.disableChecking.append('Axes')
-        return "reflectivity_119814", 'REFL_119814_combined_data.nxs'
diff --git a/Testing/SystemTests/tests/analysis/REFLWithBackground.py b/Testing/SystemTests/tests/analysis/REFLWithBackground.py
deleted file mode 100644
index 356ebf18a0e156634c43a822901096a0a036bf67..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/REFLWithBackground.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#pylint: disable=no-init,attribute-defined-outside-init
-import stresstesting
-from mantid import *
-from mantid.simpleapi import *
-
-
-class REFLWithBackground(stresstesting.MantidStressTest):
-    def runTest(self):
-        #TODO: The reduction algorithm should not require an absolute path
-        scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg")
-
-        RefLReduction(RunNumbers=[119816],
-                      NormalizationRunNumber=119692,
-                      SignalPeakPixelRange=[155, 165],
-                      SubtractSignalBackground=True,
-                      SignalBackgroundPixelRange=[146, 165],
-                      NormFlag=True,
-                      NormPeakPixelRange=[154, 162],
-                      NormBackgroundPixelRange=[151, 165],
-                      SubtractNormBackground=True,
-                      LowResDataAxisPixelRangeFlag=True,
-                      LowResDataAxisPixelRange=[99, 158],
-                      LowResNormAxisPixelRangeFlag=True,
-                      LowResNormAxisPixelRange=[118, 137],
-                      TOFRange=[9610, 22425],
-                      IncidentMediumSelected='2InDiamSi',
-                      GeometryCorrectionFlag=False,
-                      QMin=0.005,
-                      QStep=0.01,
-                      AngleOffset=0.009,
-                      AngleOffsetError=0.001,
-                      ScalingFactorFile=scaling_factor_file,
-                      SlitsWidthFlag=True,
-                      OutputWorkspace='reflectivity_119816')
-
-    def validate(self):
-        # Be more tolerant with the output.
-        self.tolerance = 0.0001
-
-        self.disableChecking.append('Instrument')
-        self.disableChecking.append('Sample')
-        self.disableChecking.append('SpectraMap')
-        self.disableChecking.append('Axes')
-        return "reflectivity_119816", 'REFL_119816.nxs'
diff --git a/Testing/SystemTests/tests/analysis/REFMReduction.py b/Testing/SystemTests/tests/analysis/REFMReduction.py
deleted file mode 100644
index 0174b83145e1c2d237947c87313d1b2d1f61ccdb..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/REFMReduction.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#pylint: disable=no-init,attribute-defined-outside-init
-import stresstesting
-from mantid import *
-
-from mantid.simpleapi import *
-
-
-class REFMReduction(stresstesting.MantidStressTest):
-    def runTest(self):
-        RefReduction(DataRun=str(9709),
-                     NormalizationRun=str(9684),
-                     SignalPeakPixelRange=[216, 224],
-                     SubtractSignalBackground=True,
-                     SignalBackgroundPixelRange=[172, 197],
-                     PerformNormalization=True,
-                     NormPeakPixelRange=[226, 238],
-                     NormBackgroundPixelRange=[130, 183],
-                     SubtractNormBackground=False,
-                     CropLowResDataAxis=True,
-                     CropLowResNormAxis=False,
-                     LowResDataAxisPixelRange = [86, 159],
-                     NBins=40,
-                     Theta=0.086,
-                     PolarizedData=True,
-                     Instrument="REF_M",
-                     OutputWorkspacePrefix='reflectivity')
-
-    def validate(self):
-        # Be more tolerant with the output, mainly because of the errors.
-        # The following tolerance check the errors up to the third digit.
-        self.tolerance = 0.25
-        self.disableChecking.append('Instrument')
-        self.disableChecking.append('Sample')
-        self.disableChecking.append('SpectraMap')
-        self.disableChecking.append('Axes')
-        return "reflectivity-Off_Off", 'REFMReduction_off_off.nxs'
diff --git a/Testing/SystemTests/tests/analysis/SANSBatchReductionTest.py b/Testing/SystemTests/tests/analysis/SANSBatchReductionTest.py
index fa50ef68a99925cc341bfb8bcf241347c0be1b4e..1bcc521268f9098643e669d290d5201f13c04ed2 100644
--- a/Testing/SystemTests/tests/analysis/SANSBatchReductionTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSBatchReductionTest.py
@@ -10,6 +10,7 @@ from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, ISISReductionMode, OutputMode)
 from sans.common.constants import EMPTY_NAME
 from sans.common.general_functions import create_unmanaged_algorithm
+from sans.common.file_information import SANSFileInformationFactory
 
 
 # -----------------------------------------------
@@ -60,7 +61,10 @@ class SANSBatchReductionTest(unittest.TestCase):
     def test_that_batch_reduction_evaluates_LAB(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -73,7 +77,7 @@ class SANSBatchReductionTest(unittest.TestCase):
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.LAB)
@@ -104,13 +108,16 @@ class SANSBatchReductionTest(unittest.TestCase):
     def test_batch_reduction_on_multiperiod_file(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D0005512")
+
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D0005512")
 
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("MASKSANS2Doptions.091A")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.LAB)
diff --git a/Testing/SystemTests/tests/analysis/SANSBeamCentreFinderCoreTest.py b/Testing/SystemTests/tests/analysis/SANSBeamCentreFinderCoreTest.py
index 0e804a29ca70327c0ccceda3ffb6d277da6f57d5..93ae75e3eb0c5faf8476c5554540a8e216dcb2cb 100644
--- a/Testing/SystemTests/tests/analysis/SANSBeamCentreFinderCoreTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSBeamCentreFinderCoreTest.py
@@ -13,6 +13,7 @@ from sans.common.enums import (DetectorType, DataType, SANSFacility)
 from sans.user_file.state_director import StateDirectorISIS
 from sans.common.constants import EMPTY_NAME
 from sans.common.general_functions import create_unmanaged_algorithm
+from sans.common.file_information import SANSFileInformationFactory
 
 
 # -----------------------------------------------
@@ -139,7 +140,10 @@ class SANSBeamCentreFinderCoreTest(unittest.TestCase):
     def test_that_beam_centre_core_produces_correct_workspaces(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -147,7 +151,7 @@ class SANSBeamCentreFinderCoreTest(unittest.TestCase):
         data_state = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_state)
+        user_file_director = StateDirectorISIS(data_state, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
 
         # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/Testing/SystemTests/tests/analysis/SANSDiagnosticPageTest.py b/Testing/SystemTests/tests/analysis/SANSDiagnosticPageTest.py
index fdf746abf2015e956f1d4194b817d37e74437026..e66b54b735d21feecd6230cdb0d8b6ee0ebdd8a5 100644
--- a/Testing/SystemTests/tests/analysis/SANSDiagnosticPageTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSDiagnosticPageTest.py
@@ -13,6 +13,7 @@ from sans.user_file.state_director import StateDirectorISIS
 from sans.common.constants import EMPTY_NAME
 from sans.common.general_functions import create_unmanaged_algorithm
 from sans.gui_logic.models.diagnostics_page_model import run_integral
+from sans.common.file_information import SANSFileInformationFactory
 
 
 # -----------------------------------------------
@@ -72,13 +73,15 @@ class SANSDiagnosticPageTest(unittest.TestCase):
     def test_that_produces_correct_workspace_for_SANS2D(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_calibration("TUBE_SANS2D_BOTH_31681_25Sept15.nxs")
         data_state = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_state)
+        user_file_director = StateDirectorISIS(data_state, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
 
         # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -104,13 +107,15 @@ class SANSDiagnosticPageTest(unittest.TestCase):
     def test_that_produces_correct_workspace_multiperiod_LARMOR(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("LARMOR00013065")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("LARMOR00013065")
         data_builder.set_calibration("80tubeCalibration_1-05-2015_r3157-3160.nxs")
         data_state = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_state)
+        user_file_director = StateDirectorISIS(data_state, file_information)
         user_file_director.set_user_file("USER_LARMOR_151B_LarmorTeam_80tubes_BenchRot1p4_M4_r3699.txt")
 
         # Construct the final state
diff --git a/Testing/SystemTests/tests/analysis/SANSLoadTest.py b/Testing/SystemTests/tests/analysis/SANSLoadTest.py
index 931ace253e87b295c2df3c5576e91ee69f0b8b6c..154b26f95f78e853e923bf16750aa137cf87f363 100644
--- a/Testing/SystemTests/tests/analysis/SANSLoadTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSLoadTest.py
@@ -17,6 +17,7 @@ from sans.common.constants import (CALIBRATION_WORKSPACE_TAG, SANS_FILE_TAG)
 from sans.test_helper.test_director import TestDirector
 from sans.common.enums import SANSFacility
 from sans.state.data import get_data_builder
+from sans.common.file_information import SANSFileInformationFactory
 
 
 def remove_all_workspaces_from_ads():
@@ -48,9 +49,11 @@ class SANSLoadFactoryTest(unittest.TestCase):
     def test_that_valid_file_information_does_not_raise(self):
         # Arrange
         load_factory = SANSLoadDataFactory()
+        file_information_factory = SANSFileInformationFactory()
 
         ws_name_sample = "SANS2D00022024"
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information = file_information_factory.create_sans_file_information(ws_name_sample)
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter(ws_name_sample)
         data = data_builder.build()
 
@@ -77,7 +80,10 @@ class SANSLoadTest(unittest.TestCase):
                           can_scatter=None, can_trans=None, can_direct=None, calibration=None,
                           sample_scatter_period=None, sample_trans_period=None, sample_direct_period=None,
                           can_scatter_period=None, can_trans_period=None, can_direct_period=None):
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information(sample_scatter)
+
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter(sample_scatter)
 
         # Set the file names
diff --git a/Testing/SystemTests/tests/analysis/SANSMaskWorkspaceTest.py b/Testing/SystemTests/tests/analysis/SANSMaskWorkspaceTest.py
index e13344e5d13db3dffbc24fd082199c5ce5f26e52..3a3090f35db724d3737803b7eefcaa98e3aa4a2a 100644
--- a/Testing/SystemTests/tests/analysis/SANSMaskWorkspaceTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSMaskWorkspaceTest.py
@@ -11,6 +11,7 @@ from sans.common.enums import SANSFacility
 from sans.test_helper.test_director import TestDirector
 from sans.state.data import get_data_builder
 from sans.state.mask import get_mask_builder
+from sans.common.file_information import SANSFileInformationFactory
 
 
 def get_masked_spectrum_numbers(workspace):
@@ -95,7 +96,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_spectra_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
 
@@ -168,7 +171,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_block_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
 
@@ -210,7 +215,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_cross_block_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
 
@@ -264,7 +271,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
         file_name = create_shape_xml_file(shape_xml)
 
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
         mask_builder = get_mask_builder(data_info)
@@ -293,7 +302,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_general_time_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
         mask_builder = get_mask_builder(data_info)
@@ -339,7 +350,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_detector_specific_time_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
         mask_builder = get_mask_builder(data_info)
@@ -379,7 +392,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_angle_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
 
@@ -427,7 +442,9 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
 
     def test_that_beam_stop_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
         mask_builder = get_mask_builder(data_info)
@@ -461,9 +478,49 @@ class SANSMaskWorkspaceTest(unittest.TestCase):
         # Assert
         self._do_assert(workspace, expected_spectra)
 
+    def test_that_beam_stop_masking_is_applied_for_LOQ(self):
+        # Arrange
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("LOQ74044")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
+        data_builder.set_sample_scatter("LOQ74044")
+        data_info = data_builder.build()
+        mask_builder = get_mask_builder(data_info)
+
+        beam_stop_arm_width = .01
+        beam_stop_arm_angle = 180.0
+        beam_stop_arm_pos1 = 0.0
+        beam_stop_arm_pos2 = 0.0
+
+        # Expected_spectra, again the tubes are shifted and that will produce the slightly strange masking
+        expected_spectra = []
+        expected_spectra.extend((7811 + x for x in range(0, 63)))
+        expected_spectra.extend((7939 + x for x in range(0, 63)))
+
+        mask_builder.set_beam_stop_arm_width(beam_stop_arm_width)
+        mask_builder.set_beam_stop_arm_angle(beam_stop_arm_angle)
+        mask_builder.set_beam_stop_arm_pos1(beam_stop_arm_pos1)
+        mask_builder.set_beam_stop_arm_pos2(beam_stop_arm_pos2)
+
+        mask_info = mask_builder.build()
+
+        test_director = TestDirector()
+        test_director.set_states(data_state=data_info, mask_state=mask_info)
+        state = test_director.construct()
+
+        workspace = self._load_workspace(state, move_workspace=False)
+
+        # Act
+        workspace = self._run_mask(state, workspace, "LAB")
+
+        # Assert
+        self._do_assert(workspace, expected_spectra)
+
     def test_that_cylinder_masking_is_applied(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00028827")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00028827")
         data_info = data_builder.build()
         mask_builder = get_mask_builder(data_info)
diff --git a/Testing/SystemTests/tests/analysis/SANSMoveTest.py b/Testing/SystemTests/tests/analysis/SANSMoveTest.py
index 0592d97700c9bb57c2e99460ee394179144af7f3..dc03d813eb54aebcb5637625338a005dd03f944a 100644
--- a/Testing/SystemTests/tests/analysis/SANSMoveTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSMoveTest.py
@@ -16,6 +16,7 @@ from sans.common.enums import (SANSFacility, DetectorType)
 from sans.test_helper.test_director import TestDirector
 from sans.state.move import get_move_builder
 from sans.state.data import get_data_builder
+from sans.common.file_information import SANSFileInformationFactory
 
 
 def load_workspace(file_name):
@@ -67,7 +68,9 @@ class SANSMoveTest(unittest.TestCase):
     @staticmethod
     def _get_simple_state(sample_scatter, lab_x_translation_correction=None, lab_z_translation_correction=None):
         # Set the data
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information(sample_scatter)
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter(sample_scatter)
         data_info = data_builder.build()
 
diff --git a/Testing/SystemTests/tests/analysis/SANSReductionCoreTest.py b/Testing/SystemTests/tests/analysis/SANSReductionCoreTest.py
index 7f63d5befa5ade499a17274795aba721758b7cb9..a9a4537a6459177aa4dd1f3b402548b3157076ab 100644
--- a/Testing/SystemTests/tests/analysis/SANSReductionCoreTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSReductionCoreTest.py
@@ -13,6 +13,7 @@ from sans.common.enums import (DetectorType, DataType, SANSFacility)
 from sans.user_file.state_director import StateDirectorISIS
 from sans.common.constants import EMPTY_NAME
 from sans.common.general_functions import create_unmanaged_algorithm
+from sans.common.file_information import SANSFileInformationFactory
 
 
 # -----------------------------------------------
@@ -131,7 +132,9 @@ class SANSReductionCoreTest(unittest.TestCase):
     def test_that_reduction_core_evaluates_LAB(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -139,7 +142,7 @@ class SANSReductionCoreTest(unittest.TestCase):
         data_state = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_state)
+        user_file_director = StateDirectorISIS(data_state, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
 
         # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/Testing/SystemTests/tests/analysis/SANSSingleReductionTest.py b/Testing/SystemTests/tests/analysis/SANSSingleReductionTest.py
index 4baa83623cd38ef79eee916eaa4a6fe76c64d63b..e7f10a0ef7c6435b2ba59641503cb136cd2669b3 100644
--- a/Testing/SystemTests/tests/analysis/SANSSingleReductionTest.py
+++ b/Testing/SystemTests/tests/analysis/SANSSingleReductionTest.py
@@ -11,6 +11,7 @@ from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, ISISReductionMode, ReductionDimensionality, FitModeForMerge)
 from sans.common.constants import EMPTY_NAME
 from sans.common.general_functions import create_unmanaged_algorithm
+from sans.common.file_information import SANSFileInformationFactory
 
 
 # -----------------------------------------------
@@ -126,7 +127,9 @@ class SANSSingleReductionTest(unittest.TestCase):
     def test_that_single_reduction_evaluates_LAB(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -138,7 +141,7 @@ class SANSSingleReductionTest(unittest.TestCase):
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.LAB)
@@ -178,7 +181,9 @@ class SANSSingleReductionTest(unittest.TestCase):
     def test_that_single_reduction_evaluates_HAB(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -190,7 +195,7 @@ class SANSSingleReductionTest(unittest.TestCase):
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.HAB)
@@ -230,7 +235,9 @@ class SANSSingleReductionTest(unittest.TestCase):
     def test_that_single_reduction_evaluates_merged(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -242,7 +249,7 @@ class SANSSingleReductionTest(unittest.TestCase):
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.Merged)
@@ -293,7 +300,9 @@ class SANSSingleReductionTest(unittest.TestCase):
     def test_that_single_reduction_evaluates_LAB_for_2D_reduction(self):
         # Arrange
         # Build the data information
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information("SANS2D00034484")
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00034484")
         data_builder.set_sample_transmission("SANS2D00034505")
         data_builder.set_sample_direct("SANS2D00034461")
@@ -305,7 +314,7 @@ class SANSSingleReductionTest(unittest.TestCase):
         data_info = data_builder.build()
 
         # Get the rest of the state from the user file
-        user_file_director = StateDirectorISIS(data_info)
+        user_file_director = StateDirectorISIS(data_info, file_information)
         user_file_director.set_user_file("USER_SANS2D_154E_2p4_4m_M3_Xpress_8mm_SampleChanger.txt")
         # Set the reduction mode to LAB
         user_file_director.set_reduction_builder_reduction_mode(ISISReductionMode.LAB)
diff --git a/Testing/SystemTests/tests/analysis/SortHKLTest.py b/Testing/SystemTests/tests/analysis/SortHKLTest.py
index 31618635e17605442fd5c7eaa82794f4b55dc03d..2360e0f09ec889e2e8294a768afc36202ca4e1ab 100644
--- a/Testing/SystemTests/tests/analysis/SortHKLTest.py
+++ b/Testing/SystemTests/tests/analysis/SortHKLTest.py
@@ -116,9 +116,9 @@ class SortHKLTest(HKLStatisticsTestMixin, stresstesting.MantidStressTest):
         centering_name = self._centering_map[space_group[0]]
 
         # pylint: disable=unused-variable
-        sorted_hkls, chi2, statistics = SortHKL(InputWorkspace=reflections,
-                                                PointGroup=point_group_name,
-                                                LatticeCentering=centering_name)
+        sorted_hkls, chi2, statistics, equivInten = SortHKL(InputWorkspace=reflections,
+                                                            PointGroup=point_group_name,
+                                                            LatticeCentering=centering_name)
 
         return statistics.row(0), sorted_hkls
 
diff --git a/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py b/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py
index 43d0db3aa068eafe603bdf17361e06b4926ebb71..38c5654a873ecc7dbdab7a68f28890d9a021929b 100644
--- a/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py
+++ b/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py
@@ -3,7 +3,6 @@
 and that mantid can be imported
 """
 import stresstesting
-import platform
 import numpy as np
 
 from mantid.api import (WorkspaceGroup, MatrixWorkspace)
@@ -14,20 +13,6 @@ from vesuvio.instrument import *
 
 # =====================================Helper Function=================================
 
-def _is_old_boost_version():
-    # It appears that a difference in boost version is causing different
-    # random number generation. As such an OS check is used.
-    # Older boost (earlier than 56): Ubuntu 14.04, RHEL7
-    dist = platform.linux_distribution()
-    if any(dist):
-        if 'Red Hat' in dist[0] and dist[1].startswith('7'):
-            return True
-        if dist[0] == 'Ubuntu' and dist[1] == '14.04':
-            return True
-
-    return False
-
-
 def _make_names_unique(names):
     name_count = dict()
 
@@ -95,7 +80,8 @@ def _equal_within_tolerance(self, expected, actual, tolerance=0.05):
     """
     tolerance_value = expected * tolerance
     abs_difference = abs(expected - actual)
-    self.assertTrue(abs_difference <= abs(tolerance_value))
+    self.assertTrue(abs_difference <= abs(tolerance_value),
+                    msg="abs({:.6f} - {:.6f}) > {:.6f}".format(expected, actual, tolerance))
 
 
 def _get_peak_height_and_index(workspace, ws_index):
@@ -195,12 +181,10 @@ class FitSingleSpectrumNoBackgroundTest(stresstesting.MantidStressTest):
         self.assertAlmostEqual(50.0, fitted_ws.readX(0)[0])
         self.assertAlmostEqual(562.0, fitted_ws.readX(0)[-1])
 
-        index_one_first = -0.013011414483
-        index_one_last = 0.00720741862173
-        index_two_first = 1.12713408816e-05
-        index_two_last = 6.90222280789e-05
-        if _is_old_boost_version():
-            index_one_first = 0.000631295911554
+        index_one_first = 0.000602
+        index_one_last = 0.007207
+        index_two_first = 1.127134e-05
+        index_two_last = 6.902223e-05
 
         _equal_within_tolerance(self, index_one_first, fitted_ws.readY(0)[0])
         _equal_within_tolerance(self, index_one_last, fitted_ws.readY(0)[-1])
@@ -276,12 +260,10 @@ class SingleSpectrumBackground(stresstesting.MantidStressTest):
         self.assertAlmostEqual(50.0, fitted_ws.readX(0)[0])
         self.assertAlmostEqual(562.0, fitted_ws.readX(0)[-1])
 
-        index_one_first = -0.00553133541138
-        index_one_last = 0.00722053823154
-        calc_data_height_expected = 0.13302098172
+        index_one_first = 0.000602
+        index_one_last = 0.007221
+        calc_data_height_expected = 0.133021
         calc_data_bin_expected = 635
-        if _is_old_boost_version():
-            index_one_first = 0.000605572768745
 
         _equal_within_tolerance(self, index_one_first, fitted_ws.readY(0)[0])
         _equal_within_tolerance(self, index_one_last, fitted_ws.readY(0)[-1])
diff --git a/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py b/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py
index a91e3fcfa216bc4efc236abf825bb7d0bc5c2314..44a5dfbc8d7f325ce2511828ea745fca81a4e457 100644
--- a/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py
+++ b/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py
@@ -9,7 +9,6 @@ are configured to find the Vesuvio data
 from __future__ import (absolute_import, division, print_function)
 import stresstesting
 import numpy as np
-import platform
 
 from mantid.api import *
 import mantid.simpleapi as ms
@@ -45,20 +44,6 @@ def tear_down():
             mtd.remove(name)
 
 
-def _is_old_boost_version():
-    # It appears that a difference in boost version is causing different
-    # random number generation. As such an OS check is used.
-    # Older boost (earlier than 56): Ubuntu 14.04, RHEL7
-    dist = platform.linux_distribution()
-    if any(dist):
-        if 'Red Hat' in dist[0] and dist[1].startswith('7'):
-            return True
-        if dist[0] == 'Ubuntu' and dist[1] == '14.04':
-            return True
-
-    return False
-
-
 def _create_algorithm(**kwargs):
     alg = AlgorithmManager.createUnmanaged("VesuvioCorrections")
     alg.initialize()
@@ -178,15 +163,11 @@ class TestGammaAndMsCorrectWorkspaceIndexOne(stresstesting.MantidStressTest):
         # Test Corrections Workspaces
         corrections_wsg = self._algorithm.getProperty("CorrectionWorkspaces").value
         _validate_group_structure(self, corrections_wsg, 3)
-        corrections_gb_peak = 0.013565531122
-        corrections_ts_peak = 0.157937557587
-        corrections_ms_peak = 0.000168789876
-        corrections_ts_bin = 724
-        corrections_ms_bin = 721
-        if _is_old_boost_version():
-            corrections_ms_peak = 0.000230715391301
-            corrections_ts_bin = 722
-            corrections_ms_bin = 367
+        corrections_gb_peak = 0.013566
+        corrections_ts_peak = 0.157938
+        corrections_ms_peak = 0.000212
+        corrections_ts_bin = 726
+        corrections_ms_bin = 709
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(0), corrections_gb_peak, 458)
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, corrections_ts_bin)
@@ -242,10 +223,7 @@ class TestGammaAndMsCorrectWorkspaceIndexTwo(stresstesting.MantidStressTest):
         corrections_gb_peak = 0.010067042262
         corrections_ts_peak = 0.156099834417
         corrections_ms_peak = 0.000224572965
-        correction_ms_bin = 46
-        if _is_old_boost_version():
-            corrections_ms_peak = 0.000217384521001
-            correction_ms_bin = 717
+        correction_ms_bin = 709
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(0), corrections_gb_peak, 457)
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, 724)
@@ -298,15 +276,11 @@ class TestMsCorrectWithContainer(stresstesting.MantidStressTest):
         # Test Corrections Workspaces
         corrections_wsg = self._algorithm.getProperty("CorrectionWorkspaces").value
         _validate_group_structure(self, corrections_wsg, 3)
-        corrections_gb_peak = 0.026998140125
-        corrections_ts_peak = 0.138476364257
-        corrections_ms_peak = 0.000147974497
-        corrections_ts_bin = 724
-        corrections_ms_bin = 721
-        if _is_old_boost_version():
-            corrections_ms_peak = 0.000202286454557
-            corrections_ts_bin = 722
-            corrections_ms_bin = 367
+        corrections_gb_peak = 0.026998
+        corrections_ts_peak = 0.138476
+        corrections_ms_peak = 0.000186
+        corrections_ts_bin = 726
+        corrections_ms_bin = 709
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(0), corrections_gb_peak, 3)
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, corrections_ts_bin)
@@ -360,9 +334,7 @@ class TestGammaAndMsCorrectWithContainer(stresstesting.MantidStressTest):
         corrections_gb_peak = 0.0249370393881
         corrections_ts_peak = 0.0131222459575
         corrections_ms_peak = 0.147875290632
-        corrections_ms_bin = 724
-        if _is_old_boost_version():
-            corrections_ms_bin = 722
+        corrections_ms_bin = 726
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(0), corrections_gb_peak, 3)
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, 458)
@@ -420,9 +392,7 @@ class TestGammaAndMsCorrectWithContainerFixedScaling(stresstesting.MantidStressT
         corrections_gb_peak = 0.045572099871
         corrections_ts_peak = 0.002216628155
         corrections_ms_peak = 0.132649056625
-        corrections_ms_bin = 724
-        if _is_old_boost_version():
-            corrections_ms_bin = 722
+        corrections_ms_bin = 726
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(0), corrections_gb_peak, 3)
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, 458)
@@ -483,16 +453,14 @@ class TestCorrectionsInBackScatteringSpectra(stresstesting.MantidStressTest):
         corrections_wsg = self._algorithm.getProperty("CorrectionWorkspaces").value
         _validate_group_structure(self, corrections_wsg, 3)
         corrections_ts_peak = 0.131359579675
-        # corrections_ms_peak = 0.00117365595751
+        corrections_ms_peak = 0.001551
         corrections_ts_bin  = 701
-        # corrections_ms_bin = 690
-        # if _is_old_boost_version():
-        #    corrections_ms_bin = 691
+        corrections_ms_bin = 48
 
         _validate_matrix_peak_height(self, corrections_wsg.getItem(1), corrections_ts_peak, corrections_ts_bin,
                                      tolerance=0.2, bin_tolerance=5)
-        # _validate_matrix_peak_height(self, corrections_wsg.getItem(2), corrections_ms_peak, corrections_ms_bin,
-        #                              tolerance=0.2, bin_tolerance=5)
+        _validate_matrix_peak_height(self, corrections_wsg.getItem(2), corrections_ms_peak, corrections_ms_bin,
+                                     tolerance=0.2, bin_tolerance=5)
 
         # Test Corrected Workspaces
         corrected_wsg = self._algorithm.getProperty("CorrectedWorkspaces").value
diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..504297da5d23c05a51b89eb2de86f05ef5cae222
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/D2B_DetEffCorr_Ref.nxs.md5
@@ -0,0 +1 @@
+6e114402c861e2129b6c095a083cbd67
diff --git a/Testing/SystemTests/tests/analysis/reference/D2B_scan_test.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/D2B_scan_test.nxs.md5
index 85523cf75a0c8c2d013027436922979b415d23be..64f587253a4513584257f6fda2a56b28970ddb87 100644
--- a/Testing/SystemTests/tests/analysis/reference/D2B_scan_test.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/D2B_scan_test.nxs.md5
@@ -1 +1 @@
-9a20698231398a7b4b1036fdffa97e50
+6726846e1fcd84952bc28ec9e1eee441
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFitParams.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFitParams.nxs.md5
index 481e763db9085eb306ba75eb90a3dbfe8b72a961..de4f61399d2ec2e4b35499bdcef37dc4dc46e4e8 100644
--- a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFitParams.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFitParams.nxs.md5
@@ -1 +1 @@
-1f689b8f4c095fb8fa10145399117407
\ No newline at end of file
+592c91f446b4e5b3bb5716d8daa47515
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFittedPeaks.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFittedPeaks.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..40ef5e388d8ef6094c6d5542e48e14476362e2ec
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyFittedPeaks.nxs.md5
@@ -0,0 +1 @@
+4a6b1694aded2bb62e145970fec6e21b
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyResiduals.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyResiduals.nxs.md5
deleted file mode 100644
index 740e928daa489c2b93c29b2955f60111eb5822d4..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksPawleyResiduals.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-e33700bfde9af8ebc38baddedccff661
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFitParams.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFitParams.nxs.md5
index 9bdd6c49aa834dc16cb086a1e50f449d8ba35e5e..500314e37c4d39ceaad54418c28644e694b81581 100644
--- a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFitParams.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFitParams.nxs.md5
@@ -1 +1 @@
-aff1eb803b8070978dd2ea1df56aae53
\ No newline at end of file
+e9906a68b83017874971da773654253c
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFittedPeaks.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFittedPeaks.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..dab3d00bf30a51db740f2b3bc021821947555d08
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldFittedPeaks.nxs.md5
@@ -0,0 +1 @@
+6c6c3d2b99d7843cd457990f2ff82df9
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldResiduals.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldResiduals.nxs.md5
deleted file mode 100644
index 45a156cb86fb7be3379c483ab4fc1b442d6a8c6f..0000000000000000000000000000000000000000
--- a/Testing/SystemTests/tests/analysis/reference/GSASIIRefineFitPeaksRietveldResiduals.nxs.md5
+++ /dev/null
@@ -1 +0,0 @@
-bb1f5fb90218d031f40fe517c8bf9fad
\ No newline at end of file
diff --git a/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5
index 9013c89cf1e304b51a5d05bb334969a79f1d29c6..49657e6f177c4893c398bd99b6558054c9ddeea6 100644
--- a/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5
@@ -1 +1 @@
-dd9c080b39820e4d84bbf10bfa58e1eb
\ No newline at end of file
+8c1d9d1bf02c71535f369d612eead34f
diff --git a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5
index 309459a3b1c478ef048fa1a80b8d26c0a545a267..e2e298fb93f01e9614ef7e7179e3fb5c7693ca26 100644
--- a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5
@@ -1 +1 @@
-57144b9309c8dbb1232a15c6daa2e904
\ No newline at end of file
+1445797a969c8f96e9ffe402af0dded7
diff --git a/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5
index 795de7fc92365ecb17fcf19e46c5080eddddf72a..118c21b28039f0877356e9d73cf11b0cc0e59ecb 100644
--- a/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5
@@ -1 +1 @@
-bb0346aa19e1bf20cad95cb1c838ea30
\ No newline at end of file
+4485e271ca700f7151193591af67e0f2
diff --git a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5
index 74079775cfa039ecf45d8f2b179315ca03272c8b..15dd6430cabde6b3f4a2d6bd259bbf5e142d8219 100644
--- a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5
@@ -1 +1 @@
-24e66b8ccfde55c58ac97d71d736211d
\ No newline at end of file
+0e367a48dd764b901c9176d37f5bf713
diff --git a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5
index 7966506607d91e3e7274a8fa01a8a5425dcb2bad..4a3b6c8a4078e8aa65e5f85670abc29eb8cd83c5 100644
--- a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5
+++ b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5
@@ -1 +1 @@
-8f7725692c8f287ce01b8648e64e70b2
\ No newline at end of file
+f19753635948066d7ce6a45e58640f6f
diff --git a/buildconfig/CMake/CPackLinuxSetup.cmake b/buildconfig/CMake/CPackLinuxSetup.cmake
index 2451a62301876c487594442e9837ae531da42686..f35b586ec25e460559b5feece5fc45979296a8ec 100644
--- a/buildconfig/CMake/CPackLinuxSetup.cmake
+++ b/buildconfig/CMake/CPackLinuxSetup.cmake
@@ -6,7 +6,7 @@
 string ( TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME )
 
 # define the source generators
-set ( CPACK_SOURCE_GENERATOR TGZ )
+set ( CPACK_SOURCE_GENERATOR "TGZ;TXZ" )
 set ( CPACK_SOURCE_IGNORE_FILES "/\\\\.git*")
 if (CMAKE_BINARY_DIR MATCHES "^${CMAKE_SOURCE_DIR}/.+")
   # In-source build add the binary directory to files to ignore for the tarball
@@ -21,6 +21,7 @@ if ( "${UNIX_DIST}" MATCHES "Ubuntu" )
   find_program (DPKG_CMD dpkg)
   if ( DPKG_CMD )
     set ( CPACK_GENERATOR "DEB" )
+    set ( CPACK_DEBIAN_COMPRESSION_TYPE "xz" )
     execute_process( COMMAND ${DPKG_CMD} --print-architecture
       OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
       OUTPUT_STRIP_TRAILING_WHITESPACE )
@@ -38,6 +39,7 @@ if ( "${UNIX_DIST}" MATCHES "RedHatEnterprise" OR "${UNIX_DIST}" MATCHES "Fedora
     set ( CPACK_GENERATOR "RPM" )
     set ( CPACK_RPM_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}" )
     set ( CPACK_RPM_PACKAGE_URL "http://www.mantidproject.org" )
+    set ( CPACK_RPM_COMPRESSION_TYPE "xz" )
 
     # determine the distribution number
     if(NOT CPACK_RPM_DIST)
diff --git a/buildconfig/CMake/DarwinSetup.cmake b/buildconfig/CMake/DarwinSetup.cmake
index 4fb0b32f8552dee6eefdea1f3a072551b3209225..ddc998caa6d89d66d87683f9a870fd2de8ad2a2e 100644
--- a/buildconfig/CMake/DarwinSetup.cmake
+++ b/buildconfig/CMake/DarwinSetup.cmake
@@ -54,6 +54,18 @@ else ()
   set ( PY_VER 2.7 )
 endif ()
 
+execute_process(COMMAND python${PY_VER}-config --prefix OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if(${PYTHON_VERSION_MAJOR} GREATER 2)
+  execute_process(COMMAND python${PY_VER}-config --abiflags OUTPUT_VARIABLE PY_ABI OUTPUT_STRIP_TRAILING_WHITESPACE)
+else()
+  # --abiflags option not available in python 2
+  set(PY_ABI "")
+endif()
+
+set( PYTHON_LIBRARY "${PYTHON_PREFIX}/lib/libpython${PY_VER}${PY_ABI}.dylib" CACHE FILEPATH "PYTHON_LIBRARY" FORCE )
+set( PYTHON_INCLUDE_DIR "${PYTHON_PREFIX}/include/python${PY_VER}${PY_ABI}" CACHE PATH "PYTHON_INCLUDE_DIR" FORCE )
+
 find_package ( PythonLibs REQUIRED )
 # If found, need to add debug library into libraries variable
 if ( PYTHON_DEBUG_LIBRARIES )
@@ -84,10 +96,18 @@ if ( NOT TARGET mantidpython )
   configure_file ( ${CMAKE_MODULE_PATH}/Packaging/osx/mantidpython_osx ${CMAKE_BINARY_DIR}/mantidpython_osx_install @ONLY )
 endif ()
 
+
+# directives similar to linux for conda framework-only build
+set ( BIN_DIR bin )
+set ( ETC_DIR etc )
+set ( LIB_DIR lib )
+set ( PLUGINS_DIR plugins )
+
+
 ###########################################################################
 # Mac-specific installation setup
 ###########################################################################
-
+if ( ENABLE_MANTIDPLOT )
 set ( CMAKE_INSTALL_PREFIX "" )
 set ( CPACK_PACKAGE_EXECUTABLES MantidPlot )
 set ( INBUNDLE MantidPlot.app/ )
@@ -199,3 +219,4 @@ set ( MACOSX_BUNDLE_ICON_FILE MantidPlot.icns )
 string (REPLACE " " "" CPACK_SYSTEM_NAME ${OSX_CODENAME})
 
 set ( CPACK_GENERATOR DragNDrop )
+endif ()
diff --git a/buildconfig/CMake/Eigen.cmake b/buildconfig/CMake/Eigen.cmake
index 683267ae67db16962b69c3cd1412e0b84eddac1f..160b72e09c62a6533263ca3583622fdd2efe57aa 100644
--- a/buildconfig/CMake/Eigen.cmake
+++ b/buildconfig/CMake/Eigen.cmake
@@ -18,7 +18,7 @@ else()
   # for static libraries, object libraries, and executables without exports.
   cmake_policy(SET CMP0063 "OLD")
 
-  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-eigen )
+  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-eigen )
   execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/extern-eigen )
 
   set(Eigen3_DIR "${CMAKE_BINARY_DIR}/extern-eigen/install/share/eigen3/cmake" CACHE PATH "")
diff --git a/buildconfig/CMake/Eigen.in b/buildconfig/CMake/Eigen.in
index d0081d9aeca5c9b61c335e1aec21de8c392a9a9e..3157b2e2fb98d00c0e8a49a4edb362147573cb87 100644
--- a/buildconfig/CMake/Eigen.in
+++ b/buildconfig/CMake/Eigen.in
@@ -7,6 +7,8 @@ ExternalProject_Add(eigen
   DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/download
   SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/source
   INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern-eigen/install
+  CMAKE_ARGS
+    -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}
   CMAKE_CACHE_ARGS
     -DCMAKE_BUILD_TYPE:STRING=Release
     -DCMAKE_VERBOSE_MAKEFILE:BOOL=OFF
diff --git a/buildconfig/CMake/FindBoostPython.cmake b/buildconfig/CMake/FindBoostPython.cmake
index 939c079d92c271c32e1b3d6e7014c6e72295ba6f..90f15b81591ff0ad04ce2cba04a03faacdd9fd70 100644
--- a/buildconfig/CMake/FindBoostPython.cmake
+++ b/buildconfig/CMake/FindBoostPython.cmake
@@ -11,19 +11,26 @@ else ()
     # Try a known set of suffixes plus a user-defined set
     # Define a cache variable to supply additional suffxies. These are tried first
     set ( BOOST_PYTHON_ADDITIONAL_SUFFIXES "" CACHE STRING "Additional suffixes to try when searching for the boost python3 library. These are prepended to the default list" )
-    set ( _suffixes ${BOOST_PYTHON_ADDITIONAL_SUFFIXES} ${PYTHON_VERSION_MAJOR} -py${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} )
+    set ( _suffixes "${BOOST_PYTHON_ADDITIONAL_SUFFIXES};${PYTHON_VERSION_MAJOR};-py${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR};${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
     foreach ( _suffix ${_suffixes})
       find_package ( Boost COMPONENTS python${_suffix} )
       if ( Boost_FOUND )
         break ()
-      endif()
+      endif ()
     endforeach ()
     if ( NOT Boost_FOUND )
       message ( FATAL_ERROR "Cannot find appropriate boost python version after trying with the "
                 "following library suffixes: ${_suffixes}" )
     endif ()
   else ()
-    # Assumes that the default version is 2
-    find_package ( Boost COMPONENTS python REQUIRED )
+    # Assumes that the default version is 27
+    find_package ( Boost COMPONENTS python )
+    if ( NOT Boost_FOUND )
+      find_package ( Boost COMPONENTS python27 )
+    endif ()
+    if ( NOT Boost_FOUND )
+      message ( FATAL_ERROR "Cannot find appropriate boost python version after trying with the "
+                "following library suffixes: ;27" )
+    endif ()
   endif ()
 endif ()
diff --git a/buildconfig/CMake/FindGitLFS.cmake b/buildconfig/CMake/FindGitLFS.cmake
index 3e57a1b603ef270e3c0aa1ec9c35f10d2c3f81a0..12322655e3d3c2a10b896490ca647efd6bb53eb3 100644
--- a/buildconfig/CMake/FindGitLFS.cmake
+++ b/buildconfig/CMake/FindGitLFS.cmake
@@ -24,7 +24,7 @@ set(gitlfs_names git-lfs )
 
 find_program(GITLFS_EXECUTABLE
   NAMES ${gitlfs_names}
-  PATH_SUFFIXES Git/bin
+  PATH_SUFFIXES Git/bin Git/mingw64/bin
   DOC "git-lfs command line client"
   )
 mark_as_advanced(GITLFS_EXECUTABLE)
diff --git a/buildconfig/CMake/FindSphinx.cmake b/buildconfig/CMake/FindSphinx.cmake
index ddffff3e2e56c679c41886cfd80e795bc0eb5b09..4db68670cd43af51d89107fd272a8e7df962659a 100644
--- a/buildconfig/CMake/FindSphinx.cmake
+++ b/buildconfig/CMake/FindSphinx.cmake
@@ -11,22 +11,14 @@
 # main()
 #=============================================================
 
-
-FIND_FILE(_find_sphinx_py FindSphinx.py PATHS ${CMAKE_MODULE_PATH})
-
-if (version_string)   # chop out the version number
-  string (REGEX REPLACE ".*([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1" SPHINX_VERSION ${version_string})
-endif()
-
+find_file (_find_sphinx_py FindSphinx.py PATHS ${CMAKE_MODULE_PATH})
 
 # import sphinx-build to attempt to get the version
 execute_process (COMMAND ${PYTHON_EXECUTABLE} ${_find_sphinx_py} OUTPUT_VARIABLE sphinx_output
                                                                  RESULT_VARIABLE sphinx_result)
+string (STRIP "${sphinx_output}" sphinx_output)
 
-if (${sphinx_result} STREQUAL "0")# AND version_string)
-  if (version_string)
-    list(GET sphinx_output 0 version_string)
-  endif()
+if (${sphinx_result} STREQUAL "0")
   list(GET sphinx_output 1 SPHINX_PACKAGE_DIR)
 else()
   message(STATUS "failed to run FindSphinx.py returned ${sphinx_result}")
diff --git a/buildconfig/CMake/FindSphinx.py b/buildconfig/CMake/FindSphinx.py
index 3e2ba70b4e354ee931a1cca601e1f98d6284b481..ecb75f60f01bd3bc347be8bf335b02aeb1b0f353 100644
--- a/buildconfig/CMake/FindSphinx.py
+++ b/buildconfig/CMake/FindSphinx.py
@@ -1,2 +1,3 @@
+import os.path as osp
 import sphinx
-print('{0};{1}'.format(sphinx.__version__, sphinx.package_dir))
+print('{0};{1}'.format(sphinx.__version__, osp.dirname(sphinx.__file__)))
diff --git a/buildconfig/CMake/GNUSetup.cmake b/buildconfig/CMake/GNUSetup.cmake
index 22b202ff95bd968e8f420279911d6dada129bcac..05525e7c84173dbb11d0d9173b2f1447064da861 100644
--- a/buildconfig/CMake/GNUSetup.cmake
+++ b/buildconfig/CMake/GNUSetup.cmake
@@ -63,7 +63,7 @@ elseif ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
 endif()
 
 # Add some options for debug build to help the Zoom profiler
-add_compile_options ( $<$<CONFIG:Debug>:-fno-omit-frame-pointer> )
+add_compile_options ( $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:-fno-omit-frame-pointer> )
 
 option(WITH_ASAN "Enable address sanitizer" OFF)
 if(WITH_ASAN)
diff --git a/buildconfig/CMake/GoogleTest.cmake b/buildconfig/CMake/GoogleTest.cmake
index 5c218edcefedbe5951fd949b0512070db8d56ebc..1a23f840e2a7e4d8644a90ea1434830bdd91caed 100644
--- a/buildconfig/CMake/GoogleTest.cmake
+++ b/buildconfig/CMake/GoogleTest.cmake
@@ -21,7 +21,7 @@ else()
   # Download and unpack googletest at configure time
   configure_file(${CMAKE_SOURCE_DIR}/buildconfig/CMake/GoogleTest.in
                  ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt @ONLY)
-  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
+  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} .
                   RESULT_VARIABLE result
                   WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
   if(result)
diff --git a/buildconfig/CMake/GoogleTest.in b/buildconfig/CMake/GoogleTest.in
index 2db620992e6e46d906686238da87c07ad3f50c5b..e37efa6f5bfca2f3074140a7607c69afd960982e 100644
--- a/buildconfig/CMake/GoogleTest.in
+++ b/buildconfig/CMake/GoogleTest.in
@@ -15,6 +15,7 @@ ExternalProject_Add(googletest
   PATCH_COMMAND     "@GIT_EXECUTABLE@" reset --hard ${_tag}
             COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_override.patch"
             COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_static.patch"
+            COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_msvc_cpp11.patch"
   CONFIGURE_COMMAND ""
   BUILD_COMMAND     ""
   INSTALL_COMMAND   ""
diff --git a/buildconfig/CMake/LinuxPackageScripts.cmake b/buildconfig/CMake/LinuxPackageScripts.cmake
index 55686ffbec105b569e18c3698870a4fb6a79e7e9..e917d1320d4564fba81da8f2a0e31fb475365506 100644
--- a/buildconfig/CMake/LinuxPackageScripts.cmake
+++ b/buildconfig/CMake/LinuxPackageScripts.cmake
@@ -136,6 +136,8 @@ endif()
 # .so symlink is only present when a -dev/-devel package is present
 if ( TCMALLOC_FOUND )
   get_filename_component ( TCMALLOC_RUNTIME_LIB ${TCMALLOC_LIBRARIES} REALPATH )
+  # We only want to use the major version number
+  string( REGEX REPLACE "([0-9]+)\.[0-9]+\.[0-9]+$" "\\1" TCMALLOC_RUNTIME_LIB ${TCMALLOC_RUNTIME_LIB} )
 endif ()
 
 # Local dev version
diff --git a/buildconfig/CMake/Packaging/osx/mantidpython_osx b/buildconfig/CMake/Packaging/osx/mantidpython_osx
index dbdbcff3c18c9e501ea5f46cbb037f2f5cca62d6..017e7141cf2195ac5f5fc1ec950e6b9c1a71b922 100755
--- a/buildconfig/CMake/Packaging/osx/mantidpython_osx
+++ b/buildconfig/CMake/Packaging/osx/mantidpython_osx
@@ -26,7 +26,7 @@ fi
 
 if [ -n "$1" ] && [ "$1" = "--classic" ]; then
     shift
-    PROG=$(command -v python@PYTHON_VERSION_MAJOR@.@PYTHON_VERSION_MINOR@)
+    PROG=@PYTHON_EXECUTABLE@
 fi
 
 # Define MANTIDPATH
diff --git a/buildconfig/CMake/Python-xmlrunner.cmake b/buildconfig/CMake/Python-xmlrunner.cmake
index 15c09c1a2d8d9f700e2fc611ab714392813f2153..d5d2e61da95900f1129625941b1e4403c5a9cc61 100644
--- a/buildconfig/CMake/Python-xmlrunner.cmake
+++ b/buildconfig/CMake/Python-xmlrunner.cmake
@@ -14,7 +14,7 @@ else()
   set ( XMLRUNNER_DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/python-xmlrunner-download )
   configure_file(${CMAKE_SOURCE_DIR}/buildconfig/CMake/Python-xmlrunner.in ${XMLRUNNER_DOWNLOAD_DIR}/CMakeLists.txt)
 
-  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${XMLRUNNER_DOWNLOAD_DIR} )
+  execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} . WORKING_DIRECTORY ${XMLRUNNER_DOWNLOAD_DIR} )
   execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${XMLRUNNER_DOWNLOAD_DIR} )
 
   set(PYTHON_XMLRUNNER_DIR "${CMAKE_BINARY_DIR}/python-xmlrunner-src" CACHE PATH "Location of xmlrunner package")
diff --git a/buildconfig/CMake/VersionNumber.cmake b/buildconfig/CMake/VersionNumber.cmake
index 62ba3492a4a8f69f8d050693539e70aa521cd2c8..ad429218ae4cc034c41c629a38778453c12f338f 100644
--- a/buildconfig/CMake/VersionNumber.cmake
+++ b/buildconfig/CMake/VersionNumber.cmake
@@ -1,9 +1,9 @@
 # Set the version number here for MantidVersion and the package filenames
 
 set ( VERSION_MAJOR 3 )
-set ( VERSION_MINOR 11 )
+set ( VERSION_MINOR 12 )
 
 # UNCOMMENT the next 'set' line to 'force' the patch version number to
 # a value (instead of using the count coming out of 'git describe')
 # DO NOT COMMIT THIS TO MASTER UNCOMMENTED, ONLY TO A RELEASE BRANCH
-# set ( VERSION_PATCH 0 )
+#set ( VERSION_PATCH 0 )
diff --git a/buildconfig/CMake/googletest_msvc_cpp11.patch b/buildconfig/CMake/googletest_msvc_cpp11.patch
new file mode 100644
index 0000000000000000000000000000000000000000..339251b3bcb19f54b863abb811b0eaa12c7d3cf9
--- /dev/null
+++ b/buildconfig/CMake/googletest_msvc_cpp11.patch
@@ -0,0 +1,41 @@
+diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
+index 5529ba544..331483e73 100644
+--- a/googletest/include/gtest/internal/gtest-port.h
++++ b/googletest/include/gtest/internal/gtest-port.h
+@@ -325,7 +325,7 @@
+ // -std={c,gnu}++{0x,11} is passed.  The C++11 standard specifies a
+ // value for __cplusplus, and recent versions of clang, gcc, and
+ // probably other compilers set that too in C++11 mode.
+-# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L
++# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L || _MSC_VER >= 1900
+ // Compiling in at least C++11 mode.
+ #  define GTEST_LANG_CXX11 1
+ # else
+@@ -357,12 +357,16 @@
+ #if GTEST_STDLIB_CXX11
+ # define GTEST_HAS_STD_BEGIN_AND_END_ 1
+ # define GTEST_HAS_STD_FORWARD_LIST_ 1
+-# define GTEST_HAS_STD_FUNCTION_ 1
++# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) // works only with VS2015U2 and better
++#   define GTEST_HAS_STD_FUNCTION_ 1
++# endif
+ # define GTEST_HAS_STD_INITIALIZER_LIST_ 1
+ # define GTEST_HAS_STD_MOVE_ 1
+ # define GTEST_HAS_STD_SHARED_PTR_ 1
+ # define GTEST_HAS_STD_TYPE_TRAITS_ 1
+ # define GTEST_HAS_STD_UNIQUE_PTR_ 1
++# define GTEST_HAS_UNORDERED_MAP_ 1
++# define GTEST_HAS_UNORDERED_SET_ 1
+ #endif
+ 
+ // C++11 specifies that <tuple> provides std::tuple.
+@@ -660,7 +664,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
+ // support TR1 tuple.  libc++ only provides std::tuple, in C++11 mode,
+ // and it can be used with some compilers that define __GNUC__.
+ # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \
+-      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600
++      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) \
++      || (_MSC_VER >= 1600 && _MSC_VER < 1900)
+ #  define GTEST_ENV_HAS_TR1_TUPLE_ 1
+ # endif
+ 
diff --git a/buildconfig/Jenkins/buildscript b/buildconfig/Jenkins/buildscript
index ce0f5519f113e149e442e91c0799093d3bb11f97..814eca620ec6dab2214bae1d686912c19132efc1 100755
--- a/buildconfig/Jenkins/buildscript
+++ b/buildconfig/Jenkins/buildscript
@@ -14,7 +14,7 @@ SCRIPT_DIR=$(dirname "$0")
 ###############################################################################
 # System discovery
 ###############################################################################
-if [[ ${NODE_LABELS} == *rhel7* ]] || [[ ${NODE_LABELS} == *centos7* ]]; then
+if [[ ${NODE_LABELS} == *rhel7* ]] || [[ ${NODE_LABELS} == *centos7* ]] || [[ ${NODE_LABELS} == *scilin7* ]]; then
   ON_RHEL7=true
 fi
 if [[ ${NODE_LABELS} == *ubuntu* ]]; then
@@ -25,7 +25,7 @@ if [[ ${NODE_LABELS} == *osx* ]]; then
 fi
 
 ###############################################################################
-# All nodes currently have PARAVIEW_DIR=5.2.0 and PARAVIEW_NEXT_DIR=5.3.0-RC1
+# All nodes currently have PARAVIEW_DIR and PARAVIEW_NEXT_DIR set
 ###############################################################################
 export PARAVIEW_DIR=${PARAVIEW_DIR}
 
@@ -68,18 +68,36 @@ fi
 
 # For pull requests decide on what to build based on changeset and Jenkins
 # parameters.
-BUILDPKG=true
-SYSTEMTESTS=false
+DO_BUILD_CODE=true
+DO_UNITTESTS=true
+DO_DOCTESTS_USER=true
+DO_BUILD_DEVDOCS=true
+DO_BUILD_PKG=true
+DO_SYSTEMTESTS=false
 if [[ ${PRBUILD} == true ]]; then
-  if [[ -n ${BUILD_PACKAGE} ]]; then
-    BUILDPKG=${BUILD_PACKAGE}
+  if ${SCRIPT_DIR}/check_for_changes dev-docs-only || ${SCRIPT_DIR}/check_for_changes user-docs-only; then
+    DO_BUILD_CODE=false
+    DO_UNITTESTS=false
   fi
+  DO_DOCTESTS_USER=false
+  DO_BUILD_DEVDOCS=false
+  DO_BUILD_PKG=${BUILD_PACKAGE:-false}
+  DO_SYSTEMTESTS=false
+
   if [[ ${ON_RHEL7} == true ]]; then
-    if ${SCRIPT_DIR}/check_for_changes docs-gui-only; then
-      SYSTEMTESTS=false
+    # rhel does system testing
+    if ! ${SCRIPT_DIR}/check_for_changes docs-gui-only; then
+      DO_BUILD_PKG=true
+      DO_SYSTEMTESTS=true
+    fi
+  elif [[ ${ON_UBUNTU} == true ]]; then
+    # ubuntu does the docs build
+    if ${SCRIPT_DIR}/check_for_changes dev-docs-only; then
+      DO_BUILD_CODE=false
+      DO_DOCTESTS_USER=false
     else
-      BUILDPKG=true
-      SYSTEMTESTS=true
+      DO_BUILD_CODE=true # code needs to be up to date
+      DO_DOCTESTS_USER=true
     fi
   fi
 fi
@@ -105,6 +123,7 @@ if [[ "$CLEANBUILD" == true ]]; then
 fi
 if [ -d $BUILD_DIR ]; then
   rm -rf ${BUILD_DIR:?}/bin ${BUILD_DIR:?}/ExternalData
+  find ${BUILD_DIR:?} -name 'TEST-*.xml' -delete
   if [[ -n ${CLEAN_EXTERNAL_PROJECTS} && "${CLEAN_EXTERNAL_PROJECTS}" == true ]]; then
       rm -rf $BUILD_DIR/eigen-*
       rm -rf $BUILD_DIR/googletest-*
@@ -183,7 +202,7 @@ fi
 ###############################################################################
 # Packaging options
 ###############################################################################
-if [[ "$BUILDPKG" == true ]]; then
+if [[ ${DO_BUILD_PKG} == true ]]; then
   PACKAGINGVARS="-DPACKAGE_DOCS=ON"
   # Set some variables relating to the linux packages
   if [[ "${ON_MACOS}" == true ]]; then
@@ -266,11 +285,13 @@ fi
 ###############################################################################
 # Build step
 ###############################################################################
-${CMAKE_EXE} --build . -- -j${BUILD_THREADS:?}
-${CMAKE_EXE} --build . --target AllTests -- -j${BUILD_THREADS:?}
+if [[ ${DO_BUILD_CODE} == true ]]; then
+  ${CMAKE_EXE} --build . -- -j${BUILD_THREADS:?}
+  ${CMAKE_EXE} --build . --target AllTests -- -j${BUILD_THREADS:?}
+fi
 
 ###############################################################################
-# static analysis builds stop here
+# Static analysis builds or stop here
 ###############################################################################
 if [[ $USE_CLANG ]] && [[ ${JOB_NAME} == *clang_tidy* ]]; then
   exit 0
@@ -280,30 +301,46 @@ fi
 ###############################################################################
 # Run the unit tests
 ###############################################################################
-# Remove any Mantid.user.properties file
-userprops=~/.mantid/Mantid.user.properties
-rm -f $userprops
-$CTEST_EXE -j${BUILD_THREADS:?} --schedule-random --output-on-failure
+# Prevent race conditions when creating the user config directory
+userconfig_dir=$HOME/.mantid
+rm -fr $userconfig_dir
+mkdir -p $userconfig_dir
+touch $userconfig_dir/Mantid.user.properties
+
+if [[ ${DO_UNITTESTS} == true ]]; then
+  $CTEST_EXE -j${BUILD_THREADS:?} --schedule-random --output-on-failure
+fi
 
 ###############################################################################
-# Run the documentation tests on Ubuntu when doing a pull request build but not for python 3.
+# User Documentation
 ###############################################################################
-if [[ ${ON_UBUNTU} == true ]] && [[ ${PRBUILD} == true ]]; then
+if [[ ${DO_DOCTESTS_USER} == true ]]; then
   # Remove doctrees directory so it forces a full reparse. It seems that
   # without this newly added doctests are not executed
   if [ -d $BUILD_DIR/docs/doctrees ]; then
-    rm -rf $BUILD_DIR/docs/doctrees/*
+    rm -fr $BUILD_DIR/docs/doctrees/*
   fi
   # Build HTML to verify that no referencing errors have crept in.
   ${CMAKE_EXE} --build . --target docs-html
   ${CMAKE_EXE} --build . --target docs-test
 fi
 
+###############################################################################
+# Developer Documentation
+###############################################################################
+# Uncomment this when the dev-docs are ready to build without warnings
+# if [[ ${DO_BUILD_DEVDOCS} == true ]]; then
+#   if [ -d $BUILD_DIR/dev-docs/doctree ]; then
+#     rm -fr $BUILD_DIR/dev-docs/doctree/*
+#   fi
+#   ${CMAKE_EXE} --build . --target dev-docs-html
+# fi
+
 ###############################################################################
 # Create the install kit if required. This includes building the Qt help
 # documentation
 ###############################################################################
-if [[ ${BUILDPKG} == true ]]; then
+if [[ ${DO_BUILD_PKG} == true ]]; then
   # Workaround so that the target can find the properties file
   # CMake doesn't easily allow environment variables on custom targets
   if [[ ${ON_MACOS} == true ]]; then
@@ -328,7 +365,7 @@ fi
 # Run the system tests if required. Run from a package to have at least one
 # Linux checks it install okay
 ###############################################################################
-if [[ ${SYSTEMTESTS} == true ]]; then
+if [[ ${DO_SYSTEMTESTS} == true ]]; then
   if [[ ${PRBUILD} == true ]]; then
     EXTRA_ARGS="--exclude-in-pull-requests" $SCRIPT_DIR/systemtests
   else
diff --git a/buildconfig/Jenkins/buildscript.bat b/buildconfig/Jenkins/buildscript.bat
index 190353049b998d219c7e23b432989b6a18e8b6b6..c25b2032fcc458acfae0db99f589c9bb90a3d7a3 100755
--- a/buildconfig/Jenkins/buildscript.bat
+++ b/buildconfig/Jenkins/buildscript.bat
@@ -28,6 +28,7 @@ set VS_VERSION=14
 :: 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 PARAVIEW_DIR=%PARAVIEW_DIR%
 
@@ -97,8 +98,9 @@ if "!CLEANBUILD!" == "yes" (
 
 if EXIST %BUILD_DIR% (
   rmdir /S /Q %BUILD_DIR%\bin %BUILD_DIR%\ExternalData
+  for /f %%F in ('dir /b /a-d /S "TEST-*.xml"') do del /Q %%F >/nul
   if "!CLEAN_EXTERNAL_PROJECTS!" == "true" (
-    rmdir /S /Q %BUILD_DIR%\eigen-download %BUILD_DIR%\eigen-src
+    rmdir /S /Q %BUILD_DIR%\eigen-prefix
     rmdir /S /Q %BUILD_DIR%\googletest-download %BUILD_DIR%\googletest-src
     rmdir /S /Q %BUILD_DIR%\python-xmlrunner-download %BUILD_DIR%\python-xmlrunner-src
   )
@@ -157,10 +159,14 @@ if ERRORLEVEL 1 exit /B %ERRORLEVEL%
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Run the tests
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:: Remove the user properties file just in case anything polluted it
+:: Remove any user configuration and create a blank user properties file
+:: 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
+rmdir /S /Q %CONFIGDIR%
+mkdir %CONFIGDIR%
+call cmake.exe -E touch %USERPROPS%
 call ctest.exe -C %BUILD_CONFIG% -j%BUILD_THREADS% --schedule-random --output-on-failure
 if ERRORLEVEL 1 exit /B %ERRORLEVEL%
 
diff --git a/buildconfig/Jenkins/check_for_changes b/buildconfig/Jenkins/check_for_changes
index f46e26b59c1d6c09069e7f36cef989e77e8639ef..8c51dc4e6c601dfabcc565f428185f8b2254c5e7 100755
--- a/buildconfig/Jenkins/check_for_changes
+++ b/buildconfig/Jenkins/check_for_changes
@@ -18,33 +18,35 @@ case "$TYPE" in
         exit $(git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.py)
     ;;
     cpp)
-        if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.h)
-        then
-            exit $FOUND
-        fi
-        if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cpp)
-        then
-            exit $FOUND
-        fi
-        if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cxx)
-        then
+        git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.h || exit $FOUND
+        git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cpp || exit $FOUND
+        git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cxx || exit $FOUND
+        git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.tcc || exit $FOUND
+        exit $NOTFOUND
+    ;;
+    # For the -only cases FOUND=1 means that there were other changes besides the case
+    # Note that these checks CANNOT be replaced with "git diff --quiet ... dev-docs" because this only
+    # checks if there were changes in a given directory and not if they are the ONLY changes
+    dev-docs-only)
+        if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^dev-docs/'; then
             exit $FOUND
+        else
+            exit $NOTFOUND
         fi
-        if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.tcc)
-        then
+    ;;
+    user-docs-only)
+        if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/'; then
             exit $FOUND
+        else
+            exit $NOTFOUND
         fi
-        exit $NOTFOUND
     ;;
     docs-gui-only)
-	# FOUND=1 iff changes are limited to docs or GUI only
-	# Find all changed files and grep for required type. -v inverts match so grep=0 means
-	# there are other changes besides this
-	if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^qt/|^MantidPlot/'; then
-	    exit $FOUND
-	else
-	    exit $NOTFOUND
-	fi
+        if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^dev-docs/|^qt/|^MantidPlot/'; then
+            exit $FOUND
+        else
+            exit $NOTFOUND
+        fi
     ;;
     *)
         echo "do not have case for type \"$TYPE\""
diff --git a/buildconfig/Jenkins/dev_site.sh b/buildconfig/Jenkins/dev_site.sh
new file mode 100755
index 0000000000000000000000000000000000000000..85f6bd4682d79189b7e956a2de4befaa742fa060
--- /dev/null
+++ b/buildconfig/Jenkins/dev_site.sh
@@ -0,0 +1,77 @@
+#!/bin/bash -ex
+if [ -z "$BUILD_DIR" ]; then
+ if [ -z "$WORKSPACE" ]; then
+     echo "WORKSPACE not set. Cannot continue"
+     exit 1
+ fi
+
+ BUILD_DIR=$WORKSPACE/build
+ echo "Setting BUILD_DIR to $BUILD_DIR"
+fi
+
+if [ -d $BUILD_DIR ]; then
+  echo "$BUILD_DIR exists"
+else
+  mkdir $BUILD_DIR
+fi
+
+###############################################################################
+# Print out the versions of things we are using
+###############################################################################
+# we use cmake3 on rhel because cmake is too old
+if [ $(command -v cmake3) ]; then
+    CMAKE_EXE=cmake3
+else
+    CMAKE_EXE=cmake
+fi
+${CMAKE_EXE} --version
+
+###############################################################################
+# Generator
+###############################################################################
+if [ "$(command -v ninja)" ]; then
+  CMAKE_GENERATOR="-G Ninja"
+elif [ "$(command -v ninja-build)" ]; then
+  CMAKE_GENERATOR="-G Ninja"
+fi
+##### set up the build directory
+cd $BUILD_DIR
+if [ -e $BUILD_DIR/CMakeCache.txt ]; then
+  ${CMAKE_EXE} .
+else
+  ${CMAKE_EXE} ${CMAKE_GENERATOR} ..
+fi
+
+if [ -d dev-docs/html ]; then
+  echo "Updating existing checkout"
+  cd dev-docs/html
+  git pull --rebase
+  cd -
+else
+  echo "Cloning developer site"
+  git clone git@github.com:mantidproject/developer.git dev-docs/html || exit -1
+  cd dev-docs/html
+  git checkout gh-pages
+  cd -
+fi
+
+##### build the developer site
+${CMAKE_EXE} --build . --target dev-docs-html
+
+cd dev-docs/html
+
+if [ "builder" == "$USER" ]; then
+    echo "Setting username"
+    git config user.name mantid-builder
+    git config user.email "mantid-buildserver@mantidproject.org"
+fi
+
+##### push the results
+if [ $(git diff --quiet) ]; then
+    echo "Committing new site"
+    git add .
+    git commit -m "Automatic update of developer site"
+    git push
+else
+    echo "Nothing has changed"
+fi
diff --git a/buildconfig/Jenkins/jenkins-slave.sh b/buildconfig/Jenkins/jenkins-slave.sh
index 8d94719c1b255951dbd4bd7599dcbd17bbe0f612..4fad34ad8a3fb2684316ccb82d08d51673a63b1b 100755
--- a/buildconfig/Jenkins/jenkins-slave.sh
+++ b/buildconfig/Jenkins/jenkins-slave.sh
@@ -71,17 +71,18 @@ if [ -f ${HOME}/jenkins-linode/${JAR_FILE} ]; then
 elif [ -f ${HOME}/Jenkins/${JAR_FILE} ]; then
   JAR_FILE=${HOME}/Jenkins/${JAR_FILE}
 else
-  JAR_FILE=/tmp/${JAR_FILE}
-  if [ ! -f ${JAR_FILE} ]; then
-    echo "Downloading slave jar file to ${JAR_FILE}"
+  JAR_FILE_TMP=/tmp/${JAR_FILE}
+  if [ ! -f ${JAR_FILE_TMP} ]; then
+    echo "Downloading slave jar file to ${JAR_FILE_TMP}"
     if [ $(command -v curl) ]; then
-      echo "curl -o ${JAR_FILE} ${JENKINS_URL}/jnlpJars/${JAR_FILE}"
-      curl -o ${JAR_FILE} ${JENKINS_URL}/jnlpJars/${JAR_FILE}
+      echo "curl -o ${JAR_FILE_TMP} ${JENKINS_URL}/jnlpJars/${JAR_FILE}"
+      curl -o ${JAR_FILE_TMP} ${JENKINS_URL}/jnlpJars/${JAR_FILE}
     else
       echo "Need curl to download ${JENKINS_URL}/jnlpJars/${JAR_FILE}"
       exit -1
     fi
   fi
+  JAR_FILE=${JAR_FILE_TMP}
 fi
 
 echo "starting ..."
diff --git a/buildconfig/Jenkins/systemtests.bat b/buildconfig/Jenkins/systemtests.bat
index 604142f218ef0cbc723e50abcc1317d5e256293c..8a82854d548a8609a8d1b937a753f58e33da005a 100755
--- a/buildconfig/Jenkins/systemtests.bat
+++ b/buildconfig/Jenkins/systemtests.bat
@@ -68,4 +68,4 @@ set PKGDIR=%WORKSPACE%\build
 :: A completely clean build will not have Mantid installed but will need Python to
 :: run the testing setup scripts. Assume it is in the PATH
 set PYTHON_EXE=python.exe
-%PYTHON_EXE% %WORKSPACE%\Testing\SystemTests\scripts\InstallerTests.py -o -d %PKGDIR%
+%PYTHON_EXE% %WORKSPACE%\Testing\SystemTests\scripts\InstallerTests.py -o -d %PKGDIR% %EXTRA_ARGS%
diff --git a/buildconfig/class_maker.py b/buildconfig/class_maker.py
index e00641cfbc6000dc50a70ec35909b2daaf59b324..5c02dcada8e8c8e333ebff8101e7ee094f1c1257 100755
--- a/buildconfig/class_maker.py
+++ b/buildconfig/class_maker.py
@@ -254,7 +254,7 @@ def write_rst(subproject, classname, filename, args):
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/buildconfig/dev-packages/deb/mantid-developer/ns-control b/buildconfig/dev-packages/deb/mantid-developer/ns-control
index 6ec7b074d4b754c6d0fafeb0a294201cf36f177e..05fcc2fa70cabf17ba18f19fce1c43b3ac1b8979 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.3
+Version: 1.3.4
 Maintainer: Mantid Project <mantid-tech@mantidproject.org>
 Priority: optional
 Architecture: all
@@ -35,6 +35,7 @@ Depends: git,
   qttools5-dev,
   qttools5-dev-tools,
   libqt5webkit5-dev,
+  libqt5x11extras5-dev,
   libqt5scintilla2-dev,
   libpython-dev,
   python-setuptools,
diff --git a/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec b/buildconfig/dev-packages/rpm/mantid-developer/mantid-developer.spec
index 7d0b25f12412ffcd5ac3eac23456e65f7df63306..e470bfbc2f93d87c0dcb25bcd3a39eb8cc4f3f93 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.26
+Version:        1.27
 Release:        1%{?dist}
 Summary:        Meta Package to install dependencies for Mantid Development
 
@@ -19,11 +19,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Requires: clang
 %{?fedora:Requires: cmake-gui}
 %{?rhel:Requires: cmake3-gui}
-%if 0%{?el6}
-Requires: boost157-devel
-%else
 Requires: boost-devel
-%endif
 Requires: doxygen
 Requires: gperftools-devel
 Requires: gperftools-libs
@@ -39,11 +35,7 @@ Requires: muParser-devel
 Requires: mxml-devel
 Requires: nexus >= 4.2
 Requires: nexus-devel >= 4.2
-%if 0%{?el6}
-Requires: ninja
-%else
 Requires: ninja-build
-%endif
 Requires: numpy
 Requires: OCE-devel
 Requires: poco-devel >= 1.4.6
@@ -54,7 +46,6 @@ Requires: python2-QtAwesome
 Requires: python-devel
 Requires: python-setuptools
 Requires: python-ipython >= 1.1
-%{?el6:Conflicts: python-ipython >= 2.0}
 Requires: python-matplotlib
 %{?fedora:Requires: python2-matplotlib-qt4}
 %{?el7:Requires: python-matplotlib-qt4}
@@ -66,11 +57,7 @@ Requires: PyYAML
 Requires: python2-mock
 Requires: qscintilla-devel
 Requires: qt-devel >= 4.6
-%if 0%{?el6}
-Requires: qwt-devel
-%else
 Requires: qwt5-qt4-devel
-%endif
 Requires: qwtplot3d-qt4-devel
 Requires: redhat-lsb
 Requires: rpmdevtools
@@ -81,19 +68,10 @@ Requires: tbb-devel
 Requires: git
 Requires: openssl-devel
 Requires: texlive-latex
-%if 0%{?el6}
-# do nothing
-%else
 Requires: texlive-latex-bin
 Requires: texlive-was
-%endif
 Requires: tex-preview
 Requires: dvipng
-%if 0%{?el6}
-Requires: mantidlibs34-qt-devel
-Requires: mantidlibs34-qtwebkit-devel
-Requires: scl-utils
-%else
 Requires: qt-devel
 Requires: qtwebkit-devel
 Requires: qt5-qtbase-devel
@@ -103,8 +81,9 @@ Requires: qt5-qtsvg
 Requires: qt5-qttools-devel
 Requires: qt5-qttools-libs-designer
 Requires: qt5-qtwebkit-devel
+Requires: qt5-qtx11extras
+Requires: qt5-qtx11extras-devel
 Requires: qscintilla-qt5-devel
-%endif
 Requires: graphviz
 %if %{with_python3}
 Requires: python3-setuptools
@@ -127,7 +106,6 @@ Requires: python3-mock
 Requires: boost-python3-devel
 %endif
 
-
 BuildArch: noarch
 
 %description
@@ -150,6 +128,10 @@ required for Mantid development.
 
 %changelog
 
+* Wed Apr 25 2018 Steven Hahn <hahnse@ornl.gov>
+- Add qt5-qtx11extras
+- remove RHEL6-specific packages
+
 * Mon Jan 22 2018 Martyn Gigg <martyn.gigg@stfc.ac.uk>
 - Added qtawesome
 
diff --git a/buildconfig/windows/command-prompt.bat b/buildconfig/windows/command-prompt.bat
index 0711ebd4c16a7b2c1849b2140fcc2454f484739a..436a79d8ab43427e50e3e1240bf94234579c49ab 100755
--- a/buildconfig/windows/command-prompt.bat
+++ b/buildconfig/windows/command-prompt.bat
@@ -6,5 +6,6 @@
 :: Assume the buildenv.bat script exists and is in the same directory
 call %~dp0buildenv.bat
 set VCVARS=@MSVC_VAR_LOCATION@
+set UseEnv=true
 :: Start command line
-%COMSPEC% /k ""%VCVARS%\vcvarsall.bat"" amd64
+%COMSPEC% /k ""%VCVARS%\vcvarsall.bat"" amd64 @CMAKE_SYSTEM_VERSION@
diff --git a/dev-docs/CMakeLists.txt b/dev-docs/CMakeLists.txt
index 38c441b03eccf42c5135415969b882da37b0558a..a833065f69b1e62c76a95d07425b566e3e8b70a9 100644
--- a/dev-docs/CMakeLists.txt
+++ b/dev-docs/CMakeLists.txt
@@ -6,9 +6,21 @@ set ( BUILDER html )
 set ( OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${BUILDER} )
 set ( DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctree )
 
-add_custom_target ( dev-docs-${BUILDER}
-                   COMMAND python -m sphinx -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR}
-                   COMMENT "Building html developer documentation" )
+# We try to execute Sphinx directly through python -m to avoid problems
+# with the startup scripts on Windows. They are not always reliable
+# as they can have hardcoded paths in them. However, older versions of
+# Sphinx dont't allow python -m execution. Assume
+# we are running on Linux and `sphinx-build` is available in these cases
+if ( EXISTS ${SPHINX_PACKAGE_DIR}/__main__.py )
+  add_custom_target ( dev-docs-${BUILDER}
+                      COMMAND ${PYTHON_EXECUTABLE} -m sphinx -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR}
+                      COMMENT "Building html developer documentation" )
+else ()
+  add_custom_target ( dev-docs-${BUILDER}
+                      COMMAND sphinx-build -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR}
+                      COMMENT "Building html developer documentation" )
+endif ()
+
 # Group within VS and exclude from whole build
 set_target_properties ( dev-docs-html PROPERTIES FOLDER "Documentation"
                        EXCLUDE_FROM_DEFAULT_BUILD 1
diff --git a/dev-docs/source/AutomatedBuildProcess.rst b/dev-docs/source/AutomatedBuildProcess.rst
new file mode 100644
index 0000000000000000000000000000000000000000..09fd38e6887cbc66f51e67e31cda01bd94d9437f
--- /dev/null
+++ b/dev-docs/source/AutomatedBuildProcess.rst
@@ -0,0 +1,70 @@
+===========================
+The Automated Build Process
+===========================
+
+.. contents:: Contents
+   :local:
+
+Summary
+^^^^^^^
+
+If your changes break the master builds in any way, on any platform,
+then it is your responsibility to fix the error immediately!
+
+The Details
+^^^^^^^^^^^
+
+You should follow the :ref:`GitWorkflow`. When you open a
+pull request (or commit to an already open pull request) the automated
+build process will start. There will be a different build for each
+platform/job. A status will appear for each job in the pull request.
+
+The status for each build will be either pending, success or failed.
+
+.. image:: images/BuildStatuses.png
+
+To see the details of a particular build in Jenkins click on Details
+next to the status. To restart a build, if it failed with a spurious
+error not related to your code changes, then you can restart that
+particular build by selecting Rebuild in Jenkins. Then press rebuild
+again on the next screen while not changing any of the parameters. If
+you don't have permission to restart builds in Jenkins you will have
+to ask someone who does.
+
+.. image:: images/RestartBuild.png
+
+Other Notes
+^^^^^^^^^^^
+
+The build will fail if it cannot be cleanly merged with master.
+
+Leeroy will check every 10 minutes for any missed builds, should the
+GitHub hooks fail to activate or the build server was down when the
+pull request was opened.
+
+The pull request builder we are using is called `Leeroy
+<https://github.com/mantidproject/leeroy>`_.
+
+You can find a list of all the pull request Jenkins jobs at `here
+<http://builds.mantidproject.org/view/Pull%20Requests/>`_.
+
+Master Pipeline
+^^^^^^^^^^^^^^^
+
+The `master pipeline <http://builds.mantidproject.org/view/Master%20Pipeline/>`_
+is a series of jobs that periodically run against code on the ``master`` branch.
+Their purpose is to provide reasonable assurance that the code currently in
+``master`` is usable in its current state.
+
+The main tasks carried out by the pipeline are, for each supported platform:
+
+* Build Mantid and installers (``master_clean-PLATFORM``)
+* Run automated testing (``master_clean-PLATFORM``,
+  ``master_systemtests-PLATFORM``, ``master_doctests``)
+* Deploy installers to nightly download locations (``master_deploy``)
+
+The pipeline view in Jenkins shows the order of dependency between these jobs.
+
+The most upstream jobs (i.e. ``master_clean-PLATFORM``) are triggered to start
+at midnight UTC assuming there were changes pushed to the ``master`` branch
+since the last time they ran.
diff --git a/dev-docs/source/BuildingOnOSX.rst b/dev-docs/source/BuildingOnOSX.rst
new file mode 100644
index 0000000000000000000000000000000000000000..092a7724e68576c7bc582729d0ab75b948f64ca7
--- /dev/null
+++ b/dev-docs/source/BuildingOnOSX.rst
@@ -0,0 +1,440 @@
+.. _BuildingOnOSX:
+
+================
+Building on OS X
+================
+
+.. contents::
+  :local:
+
+The following are instructions to build on various versions of OS X:
+
+##################################
+OS X 10.9 using clang and macports
+##################################
+
+*Disclaimer*
+
+This instruction considers that you either use macports or need them for your other development projects. It also 
+considers that you need to compile Mantid by yourself. In other cases please either `download a Mantid dmg package <http://download.mantidproject.org/>`_ or follow the instructions below. Warning: 
+it is not recommended to have both, homebrew and macports installed simultaneously on one mac.
+
+Instruction
+-----------
+1. Install Xcode and macports following the instructions on https://guide.macports.org/chunked/installing.html if needed.
+
+2. Install Mantid prerequisites via ``sudo port install package_name``
+
+3. Things to take care about:
+
+- By default, POCO libraries in macports are missing libCrypto and libNetSSL. If you have the POCO libraries already installed, uninstall them: ``sudo port uninstall poco``, then install as: ``sudo port install poco +ssl``.
+- Install OpenCascade libraries as: ``sudo port install oce -tbb``.
+
+- libNeXus: macports do not contain libNeXus.
+
+  1. Download the source code from the `NeXus developers website <http://download.nexusformat.org/kits/>`_.
+  2. Build and install it:
+   
+     .. code-block:: sh
+
+       % ./configure --prefix=/opt/local
+       % make
+       % sudo make install
+
+      You may need to install additional packages to be able to build libNeXus.
+      
+  3. libNeXus must be recompiled after update of the macports if it's dependencies have been updated. Otherwise it may depend on some non-existent libraries.
+   
+- jsoncpp: ``mantid/Code/Mantid/Framework/DataObjects/src/NoShape.cpp`` line 3 contains: ``#include <jsoncpp/json/json.h>`` but in macports there is no ``jsoncpp`` folder in the ``/opt/local/include``, ``json.h`` is located in ``/opt/local/include/json``. As a temporary solution, you may create a symbolic link:  
+
+  .. code-block:: sh
+
+    % sudo mkdir /opt/local/include/jsoncpp
+    % cd /opt/local/include/jsoncpp
+    % sudo ln -s ../json
+
+4. Run cmake. It may be needed to specify the compiler as well as the path to include files. I use the following cmake options:
+
+.. code-block:: sh
+
+    cmake  -DCMAKE_C_COMPILER=/usr/bin/clang \  
+      -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -G 'Unix Makefiles' \
+      -DCMAKE_PREFIX_PATH=/opt/local \ 
+      -DCMAKE_BUILD_TYPE=Release \ 
+      -DENABLE_CPACK=True \
+      -DPOCO_INCLUDE_DIR=/opt/local/include \
+      -DQWTPLOT3D_INCLUDE_DIR=/opt/local/include/qwtplot3d \
+      -DJSONCPP_INCLUDE_DIR=/opt/local/include \
+      -DOPENCASCADE_INCLUDE_DIR=/opt/local/include/oce \
+      -DPYTHON_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Headers \
+      -DSIP_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Headers \
+      -DPYTHON_NUMPY_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include \
+      -DPYTHON_EXECUTABLE=/opt/local/bin/python \
+      -DPYLINT_EXECUTABLE=/opt/local/bin/pylint-2.7 \
+      -DSPHINX_EXECUTABLE=/opt/local/bin/sphinx-build-2.7 \
+      -DPACKAGE_DOCS=FALSE \
+      -DDOCS_HTML=TRUE \
+      -DPYQT4_PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyQt4 \ 
+      -DSITEPACKAGES_PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages \
+      -DOPENSSL_ROOT_DIR=/opt/local \
+      -DMAKE_VATES=FALSE \
+      -DMACPORTS=TRUE \
+      -DCMAKE_INSTALL_PREFIX=path_where_to_install_mantid  /path_to_repository/mantid/Code/Mantid
+
+5. Pay attention that packaging of the documentation is switched off. I did not manage to build it for the moment.
+6. Build mantid running ``make`` or ``make -j number_of_threads``
+7. You may create the dmg package running the ``make package`` command
+8. You may also install Mantid using the ``make install`` command. *Warning*: if you do not want to install Mantid in /Applications, correct the CMAKE_INSTALL_PREFIX in the ``cmake_install.cmake`` file in your build directory.
+
+Building VATES
+--------------
+Starting from Mantid 3.4, it is possible to build it with VATES support using macports. 
+
+1. Build Paraview using the following instruction: :ref:`BuildingVATES`.
+
+2. Set cmake option ``-DMAKE_VATES=TRUE``
+
+3. Set path to the paraview build directory: ``-DParaView_DIR=/put_your_path_here``
+
+4. Run steps 6-7(8) to build/install Mantid
+
+
+##########################################
+OS X 10.10 and 10.11 using clang and Xcode
+##########################################
+These instructions are from the assumptions of a blank newly installed Mac and want to use the system python. Other python distributions may work but have not been tested. 
+
+1. First install Xcode and then clone the mantid git repository.
+
+- The last version to support OS X Mavericks is Xcode 6.2
+- The last version to support OS X Yosemite is Xcode 7.2.1
+- As of August 1, 2016, our OS X El Capitan build server is running Xcode 7.3.1
+
+2. Install Apple's Command Line tools (without this then /usr/include will not exist)
+
+.. code-block:: sh
+
+         xcode-select --install
+
+2. Install `Homebrew <http://brew.sh>`_. If you already have Homebrew and are upgrading the OS follow the `instructions here <http://ryantvenge.com/2014/09/ruby-homebrea-yosemite/>`_:
+
+.. code-block:: sh
+
+         ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+
+3. Add the necessary 'taps'. The last 4 are to use qt4.
+
+In order to be able to 'tap' the ``mantidproject/mantid`` 'tap' we need to have a couple of packages installed
+
+.. code-block:: sh
+
+        brew install git
+        brew install git-lfs
+
+        brew tap homebrew/science
+        brew tap mantidproject/mantid
+        brew tap caskroom/cask
+        brew tap cartr/qt4
+        brew tap-pin cartr/qt4
+
+5. Install required dependencies (will make a mantid-developer formula soon)
+   If you plan on distributing your application bundle, change ``brew install`` to ``brew install --build-bottle``
+
+.. code-block:: sh
+
+        brew cask install xquartz
+        # mactex is optional, needed for parsing equations in qthelp documentation.
+        brew cask install mactex
+        brew install openssl
+        brew install cmake
+        brew install qt@4 --with-qt3support --build-bottle
+        # sip,pyqt and qscintilla2 bring in homebrew's python if
+        # installed with --build-bottle. And add --build-from-source.
+        brew install sip --build-from-source --without-python3
+        brew install pyqt@4 --build-from-source --without-python3
+        brew install qscintilla2qt4 --build-from-source
+        brew install qt --build-bottle
+        brew install pyqt --build-from-source
+        brew install qscintilla2 --build-from-source --without-python3
+        brew install poco --c++11
+        brew install boost --c++11 
+        # boost-python brings in homebrew's python if installed with --build-bottle.
+        brew install boost-python --c++11 --build-from-source
+        brew install gsl
+        brew install hdf5 --c++11
+        brew install libmxml
+        brew install muparser
+        #Several unit tests fail with NeXus v4.4.2
+        #https://github.com/mantidproject/mantid/issues/17001
+        brew install nexusformat --c++11
+        brew install jsoncpp
+        brew install tbb --c++11
+        brew install opencascade --build-bottle
+        brew install qwt5
+        brew install qwtplot3d
+        brew install google-perftools
+        brew install librdkafka
+
+6. Uninstall homebrew Python that some of the dependencies insist on installing
+
+.. code-block:: sh
+
+        brew uninstall python
+
+6. Optional: for cmake-gui
+
+.. code-block:: sh
+
+        brew cask install cmake
+
+7. Now to install the other python package dependencies:
+
+.. code-block:: sh
+
+        sudo easy_install pip
+        sudo -H pip install sphinx
+        # https://github.com/mantidproject/mantid/issues/13481
+        sudo -H pip install "ipython[notebook]==3.2.1"
+        # qtconsole only required with ipython 4+ 
+        #sudo -H pip install qtconsole
+        sudo -H pip install qtpy
+        sudo -H pip install pygments
+        sudo -H pip install pyzmq
+        sudo -H pip install pycifrw
+        # Version matches Windows/RHEL/Ubuntu (trusty)
+        sudo -H pip install PyYAML==3.10
+        # Version matches Windows/RHEL/Ubuntu (trusty)
+        sudo -H pip install mock==1.0.1
+
+8. Install the theme for sphinx
+
+.. code-block:: sh
+
+        sudo pip install sphinx_bootstrap_theme
+
+9. Install other python dependencies
+
+
+.. code-block:: sh
+
+        sudo pip install psutil
+        brew install h5py
+
+9. Add Homebrew’s site-packages to your python path.
+
+.. code-block:: sh
+
+        mkdir -p ~/Library/Python/2.7/lib/python/site-packages
+        echo '/usr/local/lib/python2.7/site-packages' > ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth
+
+10. Now you need to patch a header in your python!
+
+- If building on the command line with make or ninja.
+
+  .. code-block:: sh
+
+        cd /usr/include/python2.7
+
+  or
+
+  .. code-block:: sh
+
+        cd /System/Library/Frameworks/Python.framework/Headers 
+
+  then
+
+  .. code-block:: sh
+
+        sudo cp pyport.h pyport.h.original
+        sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch
+
+- If building with Xcode on OS X Yosemite 
+
+  .. code-block:: sh
+   
+        cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
+
+
+  then
+
+  .. code-block:: sh
+
+        sudo cp pyport.h pyport.h.original
+        sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch
+
+  **Note**: If Xcode updates for any reason, the patch will be lost.
+
+
+11. Now run CMake and select the Xcode generator with the default native compilers.
+
+12. Now open the project in Xcode (doing this from the command line to ensure the PYTHONPATH is correctly picked up by Xcode).
+
+    .. code-block:: sh
+
+        cd /path/to/my/build/dir
+        open Mantid.xcodeproj
+
+Troubleshooting
+---------------
+1. The main problem that can arise is due to python path issues.  This usually either arises at the CMake or Run from Xcode steps.  It is because the PYTHONPATH is not being picked up.
+2. If you have upgraded to Mavericks (OS X 10.9) from a previous version of OS X with homebrew already installed then you may encounter some issues related to the fact that the default std lib has changed.  The easiest way to avoid this is to remove and then re-install all your formulas.
+3. You may find that if you build the ``MantidPlot`` target then you will get errors when you run, such as *Can't start python* and *Cannot load Curve Fitting Plugins*, this is due to the fact that the MantidPlot target does not contain all the dependencies.  You are best, if you are unsure of the hierarchy, to just use the ALL_BUILD target and then just switch to the MantidPlot target in order to run.
+4. NOTE that you might need to run ``./MantidPlot.app/Contents/MacOS/MantidPlot`` from the ``BUILD-DIR/bin`` (instead of ``open MantidPlot.app`` OR ``./MantidPlot`` from ``BUILD-DIR/bin/MantidPlot.app/Contents/MacOS/``) to get the library paths correct. Otherwise the issues above might show up (at least on OS X 10.11 El Capitan).
+5. Upgrading HDF5 requires also rebuilding nexusformat, h5py, and ParaView.  
+
+
+##########
+OS X 10.12
+##########
+The following instructions setup the build environment for mantid using clang compiler and python provided by the system, and all the other dependencies installed with brew. The drawback is that one has little control over python version and OpenMP will not be found. Make sure you have Qt Creator IDE and optionally cmake (GUI) app installed.
+
+1. Install Xcode from AppStore
+2. Install Xcode command line tools 
+
+.. code-block:: sh
+
+    xcode-select --install
+
+3. Install home-brew package manager
+
+.. code-block:: sh
+
+    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+
+4. Add the necessary 'taps'
+
+In order to be able to 'tap' the `mantidproject/mantid` 'tap' we need to have a couple of packages installed
+
+.. code-block:: sh
+
+    brew install git
+    brew install git-lfs
+
+    brew tap mantidproject/mantid
+    brew tap caskroom/cask
+    brew tap cartr/qt4
+    brew tap-pin cartr/qt4
+
+5. Install the necessary dependencies. Note that some of these will bring brew python with them as dependency.
+
+.. code-block:: sh
+
+    brew cask install xquartz
+    brew cask install mactex
+    brew install openssl
+    brew install cmake
+    brew install ninja --without-test
+    brew install qt@4 --build-bottle
+    brew install sip --build-from-source --without-python
+    brew install pyqt@4 --build-from-source
+    brew install qscintilla2qt4 --build-from-source --without-python
+    brew install qt --build-bottle
+    brew install pyqt --build-from-source
+    brew install qscintilla2 --build-from-source --without-python
+    brew install poco
+    brew install boost --c++11
+    brew install boost-python --c++11 --build-from-source
+    brew install gsl
+    brew install gcc
+    brew install hdf5 --c++11
+    brew install libmxml
+    brew install muparser
+    brew install nexusformat --c++11
+    brew install jsoncpp
+    brew install tbb --c++11
+    brew install opencascade --build-bottle
+    brew install qwt5
+    brew install qwtplot3d
+    brew install google-perftools
+    brew install librdkafka
+
+If, while configuring Mantid, cmake complains that it cannot find sip, uninstall the package by ``brew uninstall --ignore-dependencies sip``, reinstall it using the line above and follow the instructions on how to add Homebrew's site-packages to Python ``sys.path``.
+
+
+6. Uninstall the brew python if it has been previously installed
+
+.. code-block:: sh
+
+    brew uninstall --ignore-dependencies python3
+
+7. Install pip python package manager
+
+.. code-block:: sh
+
+    sudo easy_install pip
+
+8. Install necessary python packages with pip
+
+.. code-block:: sh
+
+    sudo -H pip install sphinx --ignore-installed
+    sudo -H pip install "ipython[notebook]==3.2.1"
+    sudo -H pip install qtpy
+    sudo -H pip install pycifrw
+    sudo -H pip install PyYAML==3.10
+    sudo -H pip install mock==1.0.1
+    sudo pip install sphinx_bootstrap_theme
+    sudo pip install psutil
+    sudo pip install qtawesome
+    sudo pip install "matplotlib>=2.1.2"
+
+9. Install h5py
+
+.. code-block:: sh
+
+    brew install h5py
+
+10. Add Homebrew’s site-packages to your python path.
+
+.. code-block:: sh
+
+    mkdir -p ~/Library/Python/2.7/lib/python/site-packages
+    echo '/usr/local/lib/python2.7/site-packages' > ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth
+
+11. Git clone the mantid repository
+
+12. Disable the system integrity protection (SIP). To do this 
+
+    - restart the computer
+    - before the apple logo appears press `Command+R` to enter the recovery mode
+    - when in recovery mode, go to `Utilities>Terminal` and type
+
+      .. code-block:: sh
+
+        csrutil disable
+   
+    - reboot again
+
+13. Now that SIP is disabled we can do the necessary patch:
+
+.. code-block:: sh
+
+    cd /usr/include/python2.7
+    sudo cp pyport.h pyport.h.original
+    sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch
+
+14. Enable again the system integrity protection by repeating Step 12 and typing this time:
+
+.. code-block:: sh
+
+    csrutil enable
+
+15. Open mantid project from Qt Creator, and you should be able to run cmake and build, given the right environment:
+
+.. code-block:: sh
+
+    CC=/usr/bin/clang
+    CXX=/usr/bin/clang++
+    PATH=/usr/local/bin/:$PATH
+
+Local bin contains the symlink to the brew packages, which have to come first in path, before `/usr/bin`. That's why it is important not to have python or clang (with this setup) in brew.
+    
+
+16. Add to your `.profile`
+
+.. code-block:: sh
+
+    export PYTHONPATH=$BUILDMANTID/bin
+
+
+17. You should now be able to mantid.
diff --git a/dev-docs/source/BuildingVATES.rst b/dev-docs/source/BuildingVATES.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8df1e0e1c999a565500aa9238665aa1888f44d92
--- /dev/null
+++ b/dev-docs/source/BuildingVATES.rst
@@ -0,0 +1,121 @@
+.. _BuildingVATES:
+
+==============
+Building VATES
+==============
+
+.. contents::
+  :local:
+
+What Is the VSI?
+----------------
+
+The VSI stands for VATES Simple Interface. This is best thought of as the way to visualise 3D+ dimensional data in Mantid. Mantid stores n dimensional data in MDWorkspaces, which may be rendered using the ParaView visualisation tools.
+
+How Do I Get the VSI?
+---------------------
+
+The VSI components are part of the Mantid distribution.
+
+ParaView
+--------
+
+The visualisation components for the VSI require the ParaView visualisation platform. However, the CMake option ``MAKE_VATES``, can be used to turn off its use. The patch files used in this section as well as build scripts for Windows & OSX/Linux which automate the steps described below can be found `here <https://github.com/mantidproject/paraview-build>`__.
+
+- Execute the following lines from the command prompt
+
+.. code-block:: sh
+
+  git clone https://gitlab.kitware.com/paraview/paraview.git <Your ParaView source root>
+  cd <Your ParaView source root>
+  git checkout v5.4.0
+  git submodule init
+  git submodule update
+
+The VSI uses a custom data array layout to minimize memory copies. The name and header must be available to ParaView at compile time.
+
+.. code-block:: sh
+
+  mkdir vtkMDHWSignalArray
+  cd  vtkMDHWSignalArray
+  wget https://raw.githubusercontent.com/mantidproject/paraview-build/2b28ebc5fd40ad727ca66772522bf220b834c1f7/vtkMDHWSignalArray/vtkMDHWSignalArray.h
+  SIGNAL_NAME=vtkArrayDispatch_extra_arrays=vtkMDHWSignalArray\<double\>
+  SIGNAL_HEADER=vtkArrayDispatch_extra_headers=<path to vtkMDHWSignalArray.h>
+
+Everyone is encouraged to apply the `additional patchfiles <https://github.com/mantidproject/paraview-build/tree/875fe2a3c800996b75591c8dbe26909b51bdf963/patches>`__ in our buildscript.
+
+Building ParaView
+------------------
+
+This is the visualisation plugins to build and use. This works on Windows/Linux/Mac. Download the source code and build using CMake out of source. You'll need the Qt development libraries, in order to build the GUI and also python. For Windows user, the Third_Party directory contains qmake as well as all the development libraries you should need to build Paraview.
+
+The scripts and cmake cache files used by the build servers are available `here <https://github.com/mantidproject/paraview-build/tree/875fe2a3c800996b75591c8dbe26909b51bdf963>`__.
+
+.. code-block:: sh
+
+  cd <Your paraview source root>
+  mkdir Build
+  cd Build
+
+  cmake -D$SIGNAL_NAME -D$SIGNAL_HEADER -C<path to common.cmake> -C<path to platform specific cache file>  ..
+  cmake --build .
+
+Building the VSI
+----------------
+
+- Get Paraview (see above)
+- Edit the CMake configuration for Mantid
+
+  - Via CMake enable ``MAKE_VATES`` (If editing from the GUI, press ``Configure`` after checking this)
+  - Via CMake set ``ParaView_DIR`` to the directory where paraview has been built.
+- Make Mantid
+
+This should produce the VSI related binaries for Mantid as well as plugins usable by ParaView.
+
+Sample Mantid cmake command
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This build command enables the VSI:
+
+.. code-block:: sh
+
+  cmake -G Ninja  -DCMAKE_BUILD_TYPE=Release -DMAKE_VATES=TRUE -DParaView_DIR=~/Code/paraview/build ../Code/Mantid
+  cmake --build .
+
+Additional Libraries for Paraview/Mantid
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Ubuntu: The package list from :ref:`GettingStarted` contains all the required libraries.
+
+Using Paraview Plugins
+----------------------
+
+This section will be fleshed-out or appear as a separate page in the near future.
+
+- Launch the Paraview GUI
+- Go to Tools -> Manage Plugins and load the MantidParaview... libraries listed above (except for MantidParaViewQtWidgets)
+- There are several reasons why you may get a warning symbol when you try to load the plugins (see troubleshooting)
+- Of those loaded plugins, you may wish to expand them using the (+) tree and assigning them as autoload, so that they are immediately available the next time Paraview is launched.
+- You can now open a sqw file in Paraview.
+- Use the Rebinning Cutter filter to rebin,integrate,rearrange,slice the workspace.
+
+Help
+----
+
+We suggest contacting the core Mantid development team if any problems are experienced.
+
+Troubleshooting
+---------------
+
+- Can't load plugins
+
+  - Have you built both Mantid and Paraview to be either Debug or Release (both the same)?
+  - Do you have the Mantid binaries present and in the right order in the system path (windows)?
+
+- Can't start-up Paraview
+
+  - Try deleting or temporarily renaming the ParaView directory in ``%APPDATA/Roaming%`` Paraview may be crashing as it's trying to autoload plugins that are causing problems.
+
+- Cannot complete the loading of a file
+
+  - Check you have ``MANTIDPATH`` set correctly.
diff --git a/dev-docs/source/BuildingWithCMake.rst b/dev-docs/source/BuildingWithCMake.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e5678263fcfca5cf1855ac5cc2a5e9798995c373
--- /dev/null
+++ b/dev-docs/source/BuildingWithCMake.rst
@@ -0,0 +1,121 @@
+.. _BuildingWithCMake:
+
+===================
+Building with CMake
+===================
+
+.. contents::
+  :local:
+
+CMake is the build system for the entirety of Mantid (Framework, MantidQt & MantidPlot). It is used to generate native build files for your platform, which can be Makefiles (for use with make, nmake or jom) for command line builds or project/solution files for an IDE (e.g. Visual Studio, Eclipse, Qt Creator, XCode).
+
+Environment
+###########
+
+The  :ref:`GettingStarted` page describes how to set up your environment to build Mantid. Follow those instructions and install the Mantid dependencies first.
+
+Also, if you use the Ninja generator then the executable is called ``ninja-build``.
+
+CCache
+######
+
+Mantid's cmake is configure to use the `ccache <https://ccache.samba.org/>`_ tool if it is available. It is highly recommended that this be used on Linux/macOS systems.
+
+For Linux either run either
+
+.. code-block:: sh
+
+  sudo yum install ccache
+
+on Red Hat, or
+
+.. code-block:: sh
+
+  sudo apt-get install ccache
+
+on Ubuntu.
+
+For macOS run:
+
+.. code-block:: sh
+
+  brew install ccache
+
+After it is installed run ``ccache --max-size=20G`` to increase the size of the cache.
+
+If you're build with ``ccache`` exhibits warnings that are not usually present then try setting the ``ccache --set-config=run_second_cpp="true"`` config option (or set ``CCACHE_CPP2=yes`` environment variable on older versions).
+
+Network Drives
+--------------
+
+The default location for the cache directory is ``$HOME/.ccache``. If you're home directory is on a network-mounted drive then the location of this cache be moved to provide the best performance. On newer versions of ``ccache`` run ``ccache --set-config=cache_dir=PATH_TO_CACHE``. Older versions (<3.2) do not allow this and must fall back to setting the ``CCACHE_DIR`` environment variable in your shell profile.
+
+Configuring your build
+######################
+
+CMake encourages the use of 'out of source' builds. This means that all generated files are placed in a separate directory structure to the source files. This separation makes a full clean easier (you just delete everything) and means that you can have different types of build (Release, Debug, different compiler versions, ....) in separate places (N.B. For Visual Studio & XCode, you can still select the type of build from within the IDE).
+
+From the command line
+---------------------
+
+* If wanting an out of source build, create the directory you want to build in and ``cd`` into it.
+* On Windows, you may need to be in a Visual Studio Command Prompt.
+* Run ``cmake /path/to/Mantid``, or to ``/path/to/Mantid/Framework`` if you only want a build of the Framework (typically not recommended, but possible nonetheless). This will generate build files using the default generator for your platform (e.g. Unix Makefiles on Linux).
+* If you want to use a specific generator (run ``cmake --help`` for a list of available generators for your platform), use the ``-G`` option, e.g. ``cmake -G"NMake Makefiles" /path/to/Mantid``.
+* If you want to set the build type (e.g. Release, Debug) you can run cmake with the ``-i`` option or by passing the argument ``-DCMAKE_BUILD_TYPE=Debug`` to cmake. The default is Release.
+* Please note that the executable is called ``cmake3`` on Red Hat 7 / CentOS7.
+
+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).
+* 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).
+* 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.
+
+Data Files Location
+-------------------
+
+Mantid used the CMake ExternalData system for managing testing data. See :ref:`DataFilesForTesting` for further instructions.
+
+With Qt Creator
+---------------
+
+`Qt Creator <http://qt.nokia.com/products/developer-tools/>`_ has some really nice features (it's cross-platform, you can directly open Qt Designer within it, you can highlight a Qt type and go directly to it's help page, it knows about Qt types when debugging....).
+The nice feature in this context is that it has CMake support built in. So you can just open the project by pointing to the main CMakeLists file and then run CMake all within the IDE itself.
+
+Building and working with CMake
+###############################
+
+* You can now start your IDE and point to or import the generated solution/project files or run ``make``, ``nmake`` or ``jom`` to build the whole of Mantid (sub-targets are available - run ``make help`` to see them).
+* '''Visual Studio users''': Use the ``visual-studio.bat`` generated in the build directory to start the IDE. This sets up the environment correctly.
+* You should typically never have to run CMake manually again (unless you want to create a new, separate build) - it will be run automatically if one of the CMake input files changes.
+* It should be rare that you will need to edit the CMake build (``CMakeLists.txt``) files. The most common occurrence will be when you add a new file. This must be added to the corresponding CMakeLists file, e.g. if you add a file to Kernel, edit ``Mantid/Framework/Kernel/CMakeLists.txt`` to add the source, header and test files to the long lists of filepaths at the top of the file.
+* The class maker utility (:ref:`ToolsOverview`) can edit the ``CMakeList.txt`` for you automatically
+* There are similar places in the Qt projects for ui files and files that need moc-ing.
+* If you add a new dependency, that will need to be added (this is less straightforward - do ask for help).
+* Cache variables can be added via the CMake Gui or by running ``ccmake``.
+
+Building the installer package
+##############################
+
+* For Windows only, you first need to install NSIS, available at: http://nsis.sourceforge.net/Download. Ensure that the install directory is added to the PATH. You should be able to type ``makensis /?`` in a command prompt.
+* Run CMake with "ENABLE_CPACK" enabled. If using the GUI you need to click the "Advanced" checkbox to see this option.
+* You will now have a build target called "PACKAGE" available to create the installer package.
+
+Caveats and Known Issues
+########################
+
+* For Visual Studio & XCode, the libraries and executable are put into ``Mantid/bin/Release``, ``Debug``, etc.
+* There is a known issue with using source control with Eclipse on an out of source build. Set the cache variable ``ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT`` to true and CMake will generate a set of 'dummy' project files within the source tree so that you can import that project and use it for source control actions.
+
+Tips
+####
+
+* Running unit test executables directly with the CMake-generated ``Mantid.properties`` file will lead to a bunch of logging output to the console. You are encouraged to use CTest instead, which suppresses this output automatically. Otherwise, adding the line ``logging.channels.consoleChannel.class = NullChannel`` to your Mantid.user.properties file will turn if off.
+* If you have more than one gcc and want to build with a version other than the default (e.g. on RedHat), setting CC & CXX environment variables is one way to make it so.
diff --git a/dev-docs/source/Communication.rst b/dev-docs/source/Communication.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4344a5157a0619472ec79800774afb8f8dcd016f
--- /dev/null
+++ b/dev-docs/source/Communication.rst
@@ -0,0 +1,42 @@
+.. _Communication:
+
+.. toctree::
+   :hidden:
+   
+   DevelopmentTeam
+
+Communication
+==============
+
+How to contact people in the development team
+---------------------------------------------
+
+* :ref:`Development Team <DevelopmentTeam>` Contact Details
+* Developer email list (closed list for developers only) mantid-developers@mantidproject.org
+* `Slack <http://mantid.slack.com/>`__: instant messaging and calls
+
+Support
+-------
+
+* Email Mantid-help@mantidproject.org goes to a short list of developers, who create tickets and assign to others.
+* `Forum <http://forum.mantidproject.org/>`__ with discussions for general and technique help requests
+
+Meetings & other information
+----------------------------
+
+Text
+^^^^
+
+* Informal discussions, and daily status - `Slack <http://mantid.slack.com/>`__
+* Set your picture on `Gravatar <https://secure.gravatar.com/>`__ to get it to appear in github/slack/etc
+
+Video conference
+^^^^^^^^^^^^^^^^
+
+* Mantid Review - Every fortnight update on significant changes & plans
+
+Face to Face
+^^^^^^^^^^^^
+
+* Annual Developer Workshop
+
diff --git a/dev-docs/source/DataFilesForTesting.rst b/dev-docs/source/DataFilesForTesting.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1996d3f19ead2033e654fae036832ce8593b07f5
--- /dev/null
+++ b/dev-docs/source/DataFilesForTesting.rst
@@ -0,0 +1,284 @@
+.. _DataFilesForTesting:
+
+======================
+Data Files for Testing
+======================
+
+.. contents::
+  :local:
+
+Summary
+#######
+
+This page gives an overview of how data files are managed within Mantid.
+
+
+Motivation
+##########
+
+Some unit tests use a small amount of data that is created by the test
+harness and others load data from a file. Take the example of
+``ApplyCalibrationTest``. In its first test, testSimple, it creates a
+workspace with 10 detectors using
+``WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument()``. In
+the second test, testComplex, it reads a file
+**IDFs_for_UNIT_TESTING/MAPS_Definition_Reduced.xml**, which contains
+the definition of a MAPS instrument with the number of detectors reduced
+much to ensure it is read quickly but preserving the other properties of
+this instrument. However, new tests should avoid even loading of this
+nature unless there is a strong justification for doing so.
+
+Main issues:
+
+-  need to store data, mainly for testing, alongside the code
+-  some data needs to be versioned
+-  merging system tests back with main code requires handling large data
+   files
+-  git is bad at handling binary files
+
+Possible solutions:
+
+-  don't have any reference to data in git and force developers to
+   manage the data stored on a file server
+-  extensions to git, e.g.
+   `git-fat <https://github.com/jedbrown/git-fat>`__,
+   `git-annex <https://git-annex.branchable.com/>`__ to deal with large
+   files
+-  CMake's
+   `ExternalData <http://www.kitware.com/source/home/post/107>`__
+
+We have chosen to use CMake as it is already in use as a build system
+and it doesn't involve introducing extra work with git.
+
+
+CMake's External Data
+#####################
+
+.. figure:: images/ExternalDataSchematic.png
+   :alt: Image originated at http://www.kitware.com/source/home/post/107
+   :align: center
+
+   Image originated at http://www.kitware.com/source/home/post/107
+
+Terminology:
+
+-  content - the real data
+-  content link - text file containing a hash (MD5) of the real content.
+   The filename is the filename of the real data plus the ``.md5``
+   extension
+-  object - a file that stores the real data and whose name is the MD5
+   hash of the content
+
+Overview:
+
+-  git does not store any content, it only stores content links
+-  content is stored on a remote server that can be accessed via a
+   ``http`` link
+-  running cmake sets up build rules so that the content is downloaded
+   when dependent projects are built
+
+
+Local Object Store
+##################
+
+CMake does not download content directly but stores the content in a
+*Local Object Store*, whose location is defined by the
+``ExternalData_OBJECT_STORES`` CMake variable. This allows it to share
+content between build trees, especially useful for continuous
+integration servers.
+
+
+Binary Root
+###########
+
+The final step is to create the *real* filename and symbolic link (copy
+on windows) it to the object in the local object store. The location of
+the *real* filenames is controlled by the ``ExternalData_BINARY_ROOT``
+CMake variable and defaults to ``build/ExternalData``.
+
+
+Using Existing Data
+###################
+
+There are two places files may be found:
+
+-  `../mantid/Testing/Data/UnitTest <https://github.com/mantidproject/mantid/tree/master/Testing/Data/UnitTest>`__
+-  `../mantid/instrument/IDFs_for_UNIT_TESTING <https://github.com/mantidproject/mantid/tree/master/instrument/IDFs_for_UNIT_TESTING>`__
+   for test `IDF <IDF>`__ files
+
+
+.. _DataFilesForTesting_AddingANewFile:
+
+Adding A New File(s)
+####################
+
+A helper git command is defined called ``add-test-data``. It would be
+called like this:
+
+.. code-block:: sh
+
+   git add-test-data Testing/Data/UnitTest/INST12345.nxs
+
+This does the following:
+
+-  computes the MD5 hash of the data, e.g.
+   ``d6948514d78db7fe251efb6cce4a9b83``
+-  stores the MD5 hash in a file called
+   ``Testing/Data/UnitTest/INST12345.nxs.md5``
+-  renames the original data file to
+   ``Testing/Data/UnitTest/d6948514d78db7fe251efb6cce4a9b83``
+-  runs ``git add Testing/Data/UnitTest/INST12345.nxs.md5``
+-  tells the user to upload the file(s),
+   ``d6948514d78db7fe251efb6cce4a9b83``, to the remote store (URL:
+   http://198.74.56.37/ftp/external-data/upload)
+-  re-run cmake
+
+Notes:
+
+-  You need to use a shell to add & modify data files under Windows in
+   this way. Not every shell works as described, though `Github for
+   Windows <https://windows.github.com/>`__ shell would allow you to do
+   everything described here step by step without deviations.
+   Unfortunately, MINGW32 shell you have to select to do that is not the
+   most convenient shell under Windows. In addition to that,
+   ``add-test-data`` script is currently broken (at least was on
+   20/11/2015) . This is why I would suggest to use small python script,
+   provided below, which would calculate md5 hash, create the ``.md5``
+   file and rename your test or reference file according to the hash sum
+   calculated. You then have to manually put ``.md5`` file to requested
+   reference data location and add it to Git by usual means. The
+   hash-sum named file should be, as in the case of Unix, placed to the
+   `remote store <http://198.74.56.37/ftp/external-data/upload>`__
+-  Note, that ILL test data should be placed under ``ILL/${INSTRUMENT}``
+   subdirectories (e.g. ``ILL/IN16B``), and should not contain any
+   instrument prefix in the file name.
+
+
+Developer Setup
+###############
+
+**You need cmake 2.8.11+**
+
+To add the ``add-test-data`` command alias to git run
+
+.. code-block:: sh
+
+   git config alias.add-test-data '!bash -c "tools/Development/git/git-add-test-data $*"'
+
+in the git bash shell. The single quotes are important so that bash
+doesn't expand the exclamation mark as a variable.
+
+It is advised that CMake is told where to put the "real" data as the
+default is ``$HOME/MantidExternalData`` on Linux/Mac or
+``C:/MantidExternalData`` on Windows. Over time the store will grow so
+it is recommended that it be placed on a disk with a large amount of
+space. CMake uses the ``MANTID_DATA_STORE`` variable to define where the
+data is stored.
+
+Example cmake command:
+
+Linux/Mac:
+
+.. code-block:: sh
+
+   mkdir -p build
+   cmake -DMANTID_DATA_STORE=/home/mgigg/Data/LocalObjectStore ../Code/Mantid
+
+Windows:
+
+.. code-block:: sh
+
+   mkdir build
+   cmake -DMANTID_DATA_STORE=D:/Data/LocalObjectStore ../Code/Mantid
+
+Setting With Dropbox:
+
+This is for people in the ORNL dropbox share and has the effect of
+reducing external network traffic. There is a
+`gist <http://gist.github.com/peterfpeterson/638490530e37c3d8dba5>`__
+for getting dropbox running on linux.
+
+.. code-block:: sh
+
+   mkdir build
+   cmake -DMANTID_DATA_STORE=/home/mgigg/Dropbox\ \(ORNL\)/MantidExternalData ../Code/Mantid
+
+If you don't want to define the MANTID_DATA_STORE everytime you run
+cmake, you can link the default data store location to the Dropbox one.
+
+.. code-block:: sh
+
+   ln -s ~/Dropbox\ \(ORNL\)/MantidExternalData ~
+
+Proxy Settings
+--------------
+
+If you are sitting behind a proxy server then the shell or Visual studio
+needs to know about the proxy server. You must set the ``http_proxy``
+environment variable to ``http://HOSTNAME:PORT``.
+
+On Windows you go to **Control Panel->System and
+Security->System->Advanced System settings->Environment Variables** and
+click **New...** to add a variable.
+
+On Linux/Mac you will need to set the variable in the shell profile or
+on Linux you can set it system wide in ``/etc/environment``.
+
+Troubleshooting
+---------------
+
+If you find that your tests cannot find the data they require check the
+following gotchas:
+
+-  Check that you have uploaded the original file renamed as a hash to
+   the Mantid file repository
+-  Check that you have re-run CMake in the build directory.
+-  Check that you have removed any user defined data search directories
+   in ~/.mantid
+-  Check that you have rebuilt the test executable you're trying to run
+-  Check that you have rebuilt the SystemTestData target
+
+Python script to produce hash files
+-----------------------------------
+
+.. code::  python
+
+    #!/usr/bin/python
+    import hashlib
+    import os,sys
+
+    def md5sum(filename, blocksize=65536):
+        """Calculate md5 hash sum of a file provided """
+        hash = hashlib.md5()
+        with open(filename, "rb") as f:
+            for block in iter(lambda: f.read(blocksize), b""):
+                hash.update(block)
+        return hash.hexdigest()
+
+    def save_sum(filename,md_sum):
+        """Save hash sum into file with appropriate filename"""
+        md_fname = filename+'.md5'
+        with open(md_fname) as f:
+            f.write(md_sum)
+
+    if __name__ == '__main__':
+
+        if len(sys.argv)<2 or not os.path.isfile(sys.argv[1]):
+            print "Usage: hash_file.py file_name"
+            exit(1)
+
+        filename = sys.argv[1]
+
+        path,fname = os.path.split(filename)
+        hash_sum = md5sum(filename)
+        print "MD SUM FOR FILE: {0} is {1}".format(fname,hash_sum)
+
+       # save hash sum in file with original file name and extension  .md5
+        save_sum(os.path.join(path,fname),hash_sum)
+
+       # Rename hashed file into hash sum name.
+        hash_file = os.path.join(path,hash_sum)
+        if os.path.isfile(hash_file):
+            print "file: {0} already exist".format(hash_sum)
+        else:
+            os.rename(filename,hash_file)
diff --git a/dev-docs/source/DebuggingUnitTests.rst b/dev-docs/source/DebuggingUnitTests.rst
new file mode 100644
index 0000000000000000000000000000000000000000..766582369be813e8634fa174e4e3d6171ad1bcfc
--- /dev/null
+++ b/dev-docs/source/DebuggingUnitTests.rst
@@ -0,0 +1,102 @@
+Debugging Unit Tests
+====================
+
+.. contents::
+  :local:
+
+Using gdb
+---------
+
+Debugging typically requires the test executable to be run directly,
+rather than via ctest (which typically spawns off a separate process to
+run the actual tests). So an example of debugging from the command line
+using gdb would be::
+
+    $ gdb bin/AlgorithmsTest
+    (gdb) r RebinTest
+
+If you do need to run ctest in order to debug - if, for example, a test
+is failing when run in ctest, but not if run directly - then you can
+start the test off and then attach to the actual test executable from
+another terminal (or your IDE). You may need to pause or slow down the
+test using, e.g., the method described for Visual Studio debugging
+below.
+
+If the issue is with a python unit test, the call is slightly more
+complicated::
+
+    $  env PYTHONPATH=$PWD/bin gdb --args python2 /full/path/to/mantid/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py
+    (gdb) run
+
+Within Eclipse
+--------------
+
+#. Go to Run->Debug Configurations
+#. Create a new Debug Configuration. I called mine "DataHandling Test
+   Debug".
+#. For me, it worked best using the "Standard Create Process Launcher"
+   (bottom option on the "Main" tab)
+#. Set the C/C++ application to the path to the test executable, e.g.
+   bin/DataHandlingTest
+#. Under the "Arguments" tab, add the name of the test class you want to
+   debug under "Program arguments", e.g. LoadTest
+
+   #. To only run one test in a class, you can add the particular test
+      to run, e.g. "LoadTest test_exec"
+
+#. Under "Common" you can put the debug config in your "favorites" menu.
+
+You can then run the debugger on this configuration from the Run menu or
+the toolbar.
+
+Within Visual Studio (debugging run method)
+-------------------------------------------
+
+I've found that this method works with Visual Studio Express (which does
+not allow "attach to process").
+
+-  Right-click the test project, e.g. DataObjectsTest.
+-  Select Properties.
+
+   -  Under Debugging -> Command Arguments, type in the test suite and,
+      optionally, single test name. e.g. "EventListTest
+      test_MinusOperator_inPlace_3cases" in the screenshot below.
+
+.. figure:: images/VisualStudioTestDebugProperties.png
+   :alt: VisualStudioTestDebugProperties.png
+
+   VisualStudioTestDebugProperties.png
+
+-  Put a break point somewhere in the test code that will be run.
+-  Select the project and click Debug -> Start Debugging.
+-  Fun test debugging times!
+
+Within Visual Studio (attach to process version)
+------------------------------------------------
+
+The process here is not as straight forward as it is in eclipse. It
+involves a few steps, but it does work!
+
+1. Edit the test to add a pause at the start of the test you are
+interested in. This will make the test wait for keyboard input, all you
+need to do is hit enter, but you can use this delay to attach to the
+debugger to running process.
+
+.. code-block:: c++
+
+  std::string s;
+  std::getline(std::cin, s);
+
+| 2. Run ctest with the appropriate arguments to run the test you are
+  investigating.
+| 3. When the test pauses for input within visual studio select
+  Debug\Attach to Process... |AttachToProcess.png|
+| 4. Select the test executable (e.g. DataHandlingTest.exe) from the
+  list and click attach. Visual studio will change to debug mode.
+| 5. Set any breakpoints you want, go back to the runner.exe window and
+  hit enter to stop the pause. This should then ctach on any breakpoints
+  you have set.
+| 6. VERY IMPORTANT - Clean up when you have done, and do not check in
+  with any paused tests!
+
+.. |AttachToProcess.png| image:: images/AttachToProcess.png
diff --git a/dev-docs/source/DesignDocumentGuides.rst b/dev-docs/source/DesignDocumentGuides.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4b5221765f5ab82bade4e68c3032273f4feabb7d
--- /dev/null
+++ b/dev-docs/source/DesignDocumentGuides.rst
@@ -0,0 +1,121 @@
+.. _DesignDocumentGuidelines:
+
+==========================
+Design Document Guidelines
+==========================
+
+.. contents::
+  :local:
+
+A good design document minimises unexpected complications by addressing
+them before the code is written. A document will provide you, your
+manager and your team with a common vocabulary for talking about the
+project. Writing an effective design document can be tricky in itself
+they often add unnecessary complexity if not done with care. These
+guidelines are to help you generate effective and simple design
+documents.
+
+Before starting, all Mantid design documents must be written in
+`markdown <http://en.wikipedia.org/wiki/Markdown>`__ format with the md
+extension. After approval from the the Mantid Project :ref:`TSC`, they should be stored
+`here <https://github.com/mantidproject/documents/tree/master/Design>`__
+or in one of the subdirectories of that directory. This page covers what
+happens between those points.
+
+Guidelines on Sections
+######################
+
+We want to avoid a prescriptive approach to design document layout.
+Design documents are about communicating design ideas, not a box ticking
+exercise, so developers are expected to use their own professional
+judgement about what goes into them. We are not providing templates for
+this reason. The following are guidelines for writing your design
+document, to help give you some direction.
+
+Motivation
+----------
+
+-  Why does this design document exist?
+-  What is the overview of the problem?
+-  What use cases exist showing the present issue? For example scripting
+   issues.
+-  How does this link in with long-term requirements such as SSC outputs
+-  **This section should be readable by non developers**. Not everyone
+   knows that the ADS stands for the Analysis Data Service and wider
+   stakeholders definitely will not
+
+Dictionary of Terms
+-------------------
+
+Your opportunity to pair abbreviations to longer explanations. This is
+not always necessary in documents where there are no special terms to
+explain. If you need one, a two column table would be sufficient.
+
+Potential Solutions
+-------------------
+
+It is important that you consider a wide range of possible solutions,
+and don't just put forward your favourite. Remember that the design
+document is a way of avoiding mistakes before coding, so spend some time
+considering how several possibilities could be made to work.
+
+For each potential solution, you should probably consider:
+
+-  Keep it brief and high-level at this stage
+-  What would the scope of the changes be?
+-  What are the pros/cons of this solution?
+
+Chosen Solution
+---------------
+
+You should provide logical reasons why you are choosing to adopt
+solution A over solution B, C, D ... As the project grows in size, we
+may need to be able to understand in the future the reasons why certain
+designs have been adopted. If you are unsure which solution would be
+best, you may submit the partially complete design document to the :ref:`TSC` for help. Design
+is itself an iterative process and documents are frequently not accepted
+first time around, so be prepared to make amendments, and don't take it
+personally if corrections are required.
+
+How will we verify the design, what are the use cases that could be used
+to verify the solution?
+
+Implementation Detail
+---------------------
+
+You could merge this section here with the one above if you wish.
+
+-  Use feedback to correct and clarify.
+-  Add more implementation detail. Diagrams are great, but you don't
+   have to use strict UML, and use the appropriate UML diagrams
+   depending upon the solution. Diagrams should help you and readers to
+   understand the solution in a simple way, not make it more
+   complicated.
+-  Could someone else follow the design and implement it? You may not be
+   the one implementing this, and it's even more likely that you will
+   not be the only one maintaining it.
+
+Sign Off
+--------
+
+Design documents help us to manage risk and reduce cost to the project.
+We have had some bad experiences in the past where high-risk changes
+have been made ad-hoc. You must get approval from the :ref:`TSC` before embarking on the work outlined in the
+design document.
+
+Cheat Sheet and Checklist
+#########################
+
+The guidelines above do not need to be strictly followed, but the
+following are necessary:
+
+#. Can non experts understand the motivation for these changes?
+#. Are your design decisions traceable? Does your design document link
+   from requirements through to implementation details in a traceable
+   manner?
+#. Can someone else implement this?
+#. Has the :ref:`TSC` approved the design.
+#. What use cases verify that this design work
+#. Documents must be version controlled and live in a subdirectory of
+   `here <https://github.com/mantidproject/documents/tree/master/Design>`__
+   as a `markdown <http://en.wikipedia.org/wiki/Markdown>`__ document
diff --git a/dev-docs/source/DeveloperAccounts.rst b/dev-docs/source/DeveloperAccounts.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fbdebd33394ba679c7e10241fa524bb3f801aa14
--- /dev/null
+++ b/dev-docs/source/DeveloperAccounts.rst
@@ -0,0 +1,63 @@
+.. _DeveloperAccounts:
+
+==================
+Developer Accounts
+==================
+
+.. contents::
+  :local:
+
+User Names
+----------
+
+Simple, easy to recognise user names are preferred. For example "Nick Draper", or if spaces are not allowed "NickDraper".
+
+Account Creation
+----------------
+
+- Create a **Mantid Wiki** account; follow `this link <https://www.mantidproject.org/Special:RequestAccount>`__.
+- Sign up to the **Mantid Developers** email list; follow `this link <http://lists.mantidproject.org/mailman/listinfo/mantid-developers>`__.
+- Sign up for the **Mantid Slack** channel; follow `this link <https://mantid.slack.com/>`__.
+- If you don't already have one, sign up for a **Github** account; follow `this link <https://github.com/>`__.
+	+ Remember that your username should be easily identifiable.
+	+ Contact one of the "Owners" on `this list <https://github.com/orgs/mantidproject/people?query=role%3Aowner>`__ to add you to the developer team.
+	+ Set up Git on your workstation; see `this guide <https://help.github.com/articles/set-up-git/>`__.
+	+ The Git workflow is described on the :ref:`GitWorkflow` page.
+
+- Consider signing up for **Skype**; follow `this link <https://www.skype.com/>`__.
+- Sign up for a **Gravatar** account; follow `this link <https://en.gravatar.com/>`__.
+
+SNS Git
+-------
+
+If you are based at SNS, in order to be able to ssh out of the lab, you need to do the following:
+
+- Install "Corkscrew" using your package manager.
+- Add the following lines to ~/.ssh/config:
+
+
+.. code:: bash
+
+    ProxyCommand corkscrew snowman.ornl.gov 3128 %h %p
+    Host github.com
+
+Introducing Yourself
+--------------------
+
+- Post a short introduction of yourself to the rest of the team in the General chatroom on Mantid Slack.
+- Add yourself together with your contact details and a photo (selfies are fine) to :ref:`DevelopmentTeam`.
+
+Admin Notes
+-----------
+
+These are notes for account admins on how to add new users.
+
+- **Wiki**
+    + Go to the `special pages index <https://www.mantidproject.org/Special:SpecialPages>`_.
+    + Select Login/Create Account.
+    + Select the Create Account link at the top of the box.
+    + Username should be first name (space) surname.
+    + User will be sent an email to verify.
+
+- **Github**
+	- Add the username provided to the mantid-developers team at `https://github.com/organizations/mantidproject/teams <https://github.com/organizations/mantidproject/teams>`_.
diff --git a/dev-docs/source/DevelopmentAndReleaseCycle.rst b/dev-docs/source/DevelopmentAndReleaseCycle.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9cb8dd18563d54e4a98302647cc565535cf7528c
--- /dev/null
+++ b/dev-docs/source/DevelopmentAndReleaseCycle.rst
@@ -0,0 +1,27 @@
+.. _DevelopmentAndReleaseCycle:
+
+=============================
+Development and Release Cycle
+=============================
+
+Mantid makes 3 point releases per year. The list of current milestones, along with their
+expected release dates, is shown at https://github.com/mantidproject/mantid/milestones. The rough
+structure of the development cycle is shown in the following figure:
+
+.. figure:: images/DevelopmentAndReleaseCycle.png
+   :alt: Development and Release cycle
+
+Each release is divided, roughly, into:
+
+* a 3 month development period where new features and bugfixes are developed
+* a 3 week code freeze where the code is tested and prepared for the next release
+
+  * during the freeze a 2 week beta-test period is given to users to test the upcoming
+    release candidate (deployed in the form of a nightly build).
+
+Feature development occurs on the `master <https://github.com/mantidproject/mantid/tree/master>`__ branch. At the code
+freeze, once all pull requests marked for the release have been merged, a new branch is created for the next release. Fixes
+found during testing are merged to the release branch and the master remains open to changes not destined for this release.
+
+The maintenance period generally overlaps with the tail end of the code freeze. All maintenance tasks occur on the
+master branch and should not disturb the release branch.
diff --git a/dev-docs/source/DevelopmentTeam.rst b/dev-docs/source/DevelopmentTeam.rst
new file mode 100644
index 0000000000000000000000000000000000000000..af0cb984ac13c98c5aad3f6e7259587c416406a6
--- /dev/null
+++ b/dev-docs/source/DevelopmentTeam.rst
@@ -0,0 +1,110 @@
+.. _DevelopmentTeam:
+
+Development Team
+================
+
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Name                       | Location    | Areas of                                                       | Contact                                 |
+|                            |             | Knowledge                                                      | details                                 |
++============================+=============+================================================================+=========================================+
+| Nick Draper(PM)            | RAL, UK     | Project management,                                            | | email: nick.draper@stfc.ac.uk         |
+|                            |             | User Requirements,                                             | | skype: nicholas_draper                |
+| .. image::                 |             | Architectural design,                                          | | phone: +44(0)1235 567212              |
+|    images/NDraper.jpg      |             | Geometry design,                                               |                                         |
+|    :width: 100px           |             | dispute resolution                                             |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Peter Peterson             | ORNL, US    |                                                                | | email: petersonpf@ornl.gov            |
+|                            |             |                                                                | | skype: peterfpeterson                 |
+| .. image::                 |             |                                                                |                                         |
+|    images/PPeterson.jpg    |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Mathieu Doucet             | ORNL, US    | Small angle                                                    | | email: doucetm@ornl.gov               |
+|                            |             | neutron                                                        | | skype: mathieu.doucet                 |
+| .. image::                 |             | scattering                                                     |                                         |
+|    images/MDoucet.jpg      |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Martyn Gigg                | RAL, UK     |                                                                | | email: martyn.gigg@stfc.ac.uk         |
+|                            |             |                                                                | | phone: +44(0)1235 445228              |
+| .. image::                 |             |                                                                |                                         |
+|    images/MGigg.jpg        |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Roman Tolchenov            | RAL, UK     | Curve fitting and optimisation, MantidPlot user interface      | | email: roman.tolchenov@stfc.ac.uk     |
+|                            |             |                                                                | | phone: +44(0)1235 445852              |
+| .. image::                 |             |                                                                |                                         |
+|    images/RTolchenov.jpg   |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Anders                     | RAL, UK     | Instrument and Parameter definitions, Curve fitting and        | | email: anders.markvardsen@stfc.ac.uk  |
+| Markvardsen                |             | optimisation, Muon data reduction and user interface           | | skype: thomas_heldig                  |
+|                            |             |                                                                | | phone: +44(0)1235 445137              |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Karl Palmen                | RAL, UK     |                                                                | | email: karl.palmen@stfc.ac.uk         |
+|                            |             |                                                                | | slack: karl_palmen                    |
+|                            |             |                                                                | | phone: +44(0)1235 445794              |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Owen Arnold                | RAL, UK     | Project Manager for ESS In-Kind team at ISIS. Live Data        | | email: owen.arnold@stfc.ac.uk         |
+|                            |             | Reduction, Visualisation and Instrument Control                | | skype: owen_arnold                    |
+| .. image::                 |             |                                                                | | phone: +44(0)1235 565253              |
+|    images/OArnold.jpg      |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Michael Hart               | RAL, UK     | ESS In-Kind team at ISIS. Live Data Reduction, Visualisation   | | email: michael.hart@stfc.ac.uk        |
+|                            |             | and Instrument Control                                         | | phone: +44(0)1235 445253              |
+|                            |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Lamar Moore                | RAL, UK     | ESS In-Kind team at ISIS. Live Data Reduction, Visualisation   | | email: lamar.moore@stfc.ac.uk         |
+|                            |             | and Instrument Control                                         | | skype: lamar.mantid                   |
+| .. image::                 |             |                                                                | | phone: +44(0)1235 565253              |
+|    images/LMoore.jpg       |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Jean Bilheaux              | ORNL, US    |                                                                | | email: bilheuxjm@ornl.gov             |
+|                            |             |                                                                | | skype: jeanbilheux                    |
+| .. image::                 |             |                                                                | | phone: +1 865-241-6969                |
+|    images/JBilheaux.jpg    |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Andrei Savici              | ORNL, US    | Triple Axis, Inelastic Resolution and Fitting, Single Crystal  | | email: saviciat@ornl.gov              |
+|                            |             | Diffraction and Inelastic                                      | | skype: a_savici                       |
+| .. image::                 |             |                                                                | | phone: +1 917-543-5535                |
+|    images/ASavici.jpg      |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Jose Borreguero            | ORNL, US    | Quasielastic model fitting, MD simulations                     | | email: borreguerojm@ornl.gov          |
+|                            |             |                                                                | | skype: jmborr                         |
+| .. image::                 |             |                                                                | | phone: +1 678 793 6463                |
+|    images/JBorreguero.jpg  |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Vickie Lynch               | ORNL, US    |                                                                | | email: lynchve@ornl.gov               |
+|                            |             |                                                                | | skype: ornlmantid_vickie              |
+| .. image::                 |             |                                                                | | phone: +1 865-574-0623                |
+|    images/VLynch.jpg       |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Wenduo Zhou                | ORNL, US    |                                                                | | email: zhouw@ornl.gov                 |
+|                            |             |                                                                | | skype: wenduozhou                     |
+| .. image::                 |             |                                                                |                                         |
+|    images/WZhou.jpg        |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Ricardo Ferraz Leal        | ORNL, US    | Data reduction for HFIR SANS (BioSANS and GPSANS)              | | email: ferrazlealrm@ornl.gov          |
+|                            |             |                                                                | | skype: ricferrazleal                  |
+| .. image::                 |             |                                                                |                                         |
+|    images/RFerrazLeal.jpg  |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Ross Whitfield             | ORNL, US    |                                                                | email: whitfieldre@ornl.gov             |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Gagik Vardanyan            | ILL, FR     |                                                                | | email: vardanyan@ill.fr               |
+|                            |             |                                                                | | skype: vardanyan_ILL                  |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
+| Gemma Guest                |  RAL, UK    | Large scale structures at ISIS (reflectometry and small angle  | | email: gemma.guest@stfc.ac.uk         |
+|                            |             | neutron scattering)                                            | | skype: live:gemmabguest               |
+| .. image::                 |             |                                                                | | phone: +44(0)1235 394011              |
+|    images/GGuest.png       |             |                                                                |                                         |
+|    :width: 100px           |             |                                                                |                                         |
++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+
diff --git a/dev-docs/source/DoxygenSetup.rst b/dev-docs/source/DoxygenSetup.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0c7f3b2d2104fe1842c126c3a01200bc49ca7808
--- /dev/null
+++ b/dev-docs/source/DoxygenSetup.rst
@@ -0,0 +1,83 @@
+Doxygen Setup
+=============
+
+Unix Console Doxygen Setup
+--------------------------
+
++-----------------+-----------------------------------------------------------------------------------------+
+| | Check for     | You may well already have doxygen installed but is it most likely                       |
+| | doxygen       | in your systems repositories.                                                           |
+|                 | If not, build from source                                                               |
+|                 | `here <http://www.stack.nl/~dimitri/doxygen/download.html#srcbin>`__.                   |
++-----------------+-----------------------------------------------------------------------------------------+
+| Run cmake       | CMake will genereate the doyxgen config file                                            |
+|                 | in ${CMAKE_DIR}/Framework/Doxygen/Mantid.doxyfile                                       |
++-----------------+-----------------------------------------------------------------------------------------+
+| | You're done!  |  -  Type 'make doxygen'                                                                 |
+| | Try!          |  -  This will run doxygen, showing the output in the console. You may                   |
+|                 |     want to pipe warnings to a file to make them easy to read later:                    |
+|                 |     'make  doxygen 2> doxygen_errors.log'                                               |
+|                 |  -  The documentation will go into a subdir doxygen/html of the                         |
+|                 |     directory where cmake was run from.                                                 |
++-----------------+-----------------------------------------------------------------------------------------+
+
+Visual Studio Doxygen Setup
+---------------------------
+
++-----------------+-----------------------------------------------------------------------------------------+
+| Install doxygen | Download the                                                                            |
+| binaries        | `Windows binaries <http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc>`__     |
+|                 | and install them. I'll assume in the following you installed doxygen in                 |
+|                 | c:\program files\doxygen                                                                |
++-----------------+-----------------------------------------------------------------------------------------+
+| Rerun CMake     | Run cmake for the build to ensure that the Mantid.doxyfile is created                   |
++-----------------+-----------------------------------------------------------------------------------------+
+| Add VC++ Tool:  | - Tools\External Tool then click Add                                                    |
+| "DoxyGen"       | - Title: &DoxyGen                                                                       | 
+|                 | - Command: C:\Program Files\Doxygen\bin\doxygen.exe                                     |
+|                 | - Arguments: "$(SolutionDir)\Framework\Doxygen\Mantid.doxyfile" (include the quotes!)   |
+|                 | - Initial Directory: $(SolutionDir)\Build                                               |
+|                 | - Check the "Use output window" box                                                     |
++-----------------+-----------------------------------------------------------------------------------------+
+| Add VC++ Tool:  | - Tools\External Tool then click Add                                                    |
+| "view DoxyGen"  | - Title: &View DoxyGen                                                                  |
+|                 | - Command your favorite browser, e.g. C:\program Files\internet Explorer\iexplore.exe   |
+|                 |   or C:\Program Files (x86)\Google\Chrome\Application\chrome.exe                        |
+|                 | - Arguments: "$(SolutionDir)doxygen\html\index.html"                                    |
+|                 | - Initial Directory: leave empty                                                        |
++-----------------+-----------------------------------------------------------------------------------------+
+| You're done!    | - Choose Tools/DoxyGen from the menu, and watch the magic happen (DoxyGen will log      |
+| Try! "DoxyGen"  |   it's progress and complaints to the output window). Clicking on a warning message     |
+|                 |   will take you to the location in the code of the warning.                             |
+|                 | - Choose Tools/View DoxyGen to explore the documentation.                               |
+|                 | - The "Main Page" is probably rather boring. Click on "Namespaces" in the menu line to  |
+|                 |   browse your classes etc.                                                              |
++-----------------+-----------------------------------------------------------------------------------------+
+
+Eclipse Doxygen Setup
+---------------------
+
++-----------------+-----------------------------------------------------------------------------------------+
+| Check for       | You may well already have doxygen installed, but if not you can install it at the same  |
+| doxygen         | time as the plugin below via the update site                                            |
++-----------------+-----------------------------------------------------------------------------------------+
+| Run cmake       | This will generate the doxygen config file in                                           |
+|                 | ${CMake_DIR}/Framework/Doxygen/Mantid.doxygen                                           |
++-----------------+-----------------------------------------------------------------------------------------+
+| Install Eclipse | - `Eclox <http://eclox.eu/>`_ is a frontend plugin for Eclipse.                         |
+| plugin: "Eclox" | - Install it using the Eclipse Update Manager                                           |
+|                 | - To do this go to Help -> Software Updates...                                          |
+|                 | - Select the 'Available Software' tab then the 'Add Site...' button                     |
+|                 | - Enter `http://download.gna.org/eclox/update` as the location                          |
+|                 | - Eclipse will add the site to the list and you can open the tree to select and install |
+|                 |   Eclox                                                                                 |
++-----------------+-----------------------------------------------------------------------------------------+
+| You're done!    | - You'll now have a 'build doxygen' button in your toolbar (a blue '@')                 |
+| Try!            | - The first time you click it you'll be prompted for the configuration file. Point it   |
+|                 |   at ${CMake_DIR}/Framework/Doxygen/Mantid.doxygen                                      |
+|                 | - This will run doxygen, showing the output in the console and adding warnings symbols  |
+|                 |   on the source files (as for compilation warnings). Hovering over these will show the  |
+|                 |   warning.                                                                              |
+|                 | - The documentation will go into a subdir doxygen/html of the directory where cmake was |
+|                 |   run from.                                                                             |
++-----------------+-----------------------------------------------------------------------------------------+
diff --git a/dev-docs/source/FlowchartCreation.rst b/dev-docs/source/FlowchartCreation.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8b1db35c64aec5b0e6eabb11486d45221222fe25
--- /dev/null
+++ b/dev-docs/source/FlowchartCreation.rst
@@ -0,0 +1,65 @@
+.. _FlowchartCreation:
+
+==================
+Flowchart Creation
+==================
+
+.. contents::
+  :local:
+
+
+The flowchart diagrams are created by writing ``graphviz`` .dot files that describe the diagram in plain text, and placing them into ``docs/source/diagrams``. These can then be rendered in documentation by using the diagram directive in an .rst file: 
+
+.. code-block:: rest
+
+   .. diagram:: AlgorithmName-v1_wkflw.dot
+
+Examples of this can be found in `ReflectometryReductionOne1.rst <https://raw.githubusercontent.com/mantidproject/mantid/master/docs/source/algorithms/ReflectometryReductionOne-v1.rst>`__ and `ReflectometryReductionOneAuto-v1.rst <https://raw.githubusercontent.com/mantidproject/mantid/master/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst>`__.
+
+The .dot format is quite simple¸ but very powerful for describing graphs. The approach we use is to describe all the nodes (shapes) we want first, grouping them into their types, and then defining how they're connected.
+
+To provide a uniform look to all the workflow diagrams, templated keywords are provided which are swapped out with the correct styling options when the documentation is built. They are of the form ``${context}_style``. They're defined by the `diagram directive <https://raw.githubusercontent.com/mantidproject/mantid/master/docs/sphinxext/mantiddoc/directives/diagram.py>`__.
+
+An algorithm that takes one input workspace and scales it by a given parameter/property if it was given, may look like this:
+
+::
+
+   digraph DiagramName {
+   //Comments are inserted in the same way as C++
+   label = "MultiplyByParam Workflow Diagram"
+   $global_style
+
+   subgraph params {
+     //These keywords beginning with $ are replaced with commands to style all the nodes in the subgraph correctly
+     $param_style
+     inputWorkspace  [label="InputWorkspace"]
+     outputWorkspace [label="OutputWorkspace"]
+     coefficient     [label="Coefficient"]
+   }
+
+   subgraph decisions {
+     $decision_style
+     checkCoefficient [label="Was Coefficient\ngiven?"]
+   }
+
+   subgraph algorithms {
+     $algorithm_style
+     scale [label="Scale"]
+   }
+
+   //Define the connections, labelling some of them
+   inputWorkspace   -> checkCoefficient
+   coefficient      -> scale           [label="Factor"]
+   checkCoefficient -> scale           [label="Yes"]
+   checkCoefficient -> outputWorkspace [label="No"]
+   scale            -> outputWorkspace
+   }
+
+While creating the diagrams it's inconvenient to recompile the documentation with each change, so you may want to render the graph manually. This can be achieved on linux or cygwin by running the following command. *You may need to comment out the "$foo_style" lines when manually rendering as they are not valid graphviz syntax* (you can do this on the fly using sed to avoid having to edit the file).
+
+::
+
+   dot -Tpng -o output_image.png input_file.dot                       # render a graph manually
+   sed 's/\$/\/\/$/g' input_file.dot | dot -Tpng -o output_image.png  # excludes $foo_style lines
+
+You can also render them in a web browser using this `online graph renderer <http://www.webgraphviz.com/>`__.
diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e545781ef223e468c3c164d8779d1389ba501806
--- /dev/null
+++ b/dev-docs/source/GUIDesignGuidelines.rst
@@ -0,0 +1,292 @@
+.. _GuiDesignGuidelines:
+
+=====================
+GUI Design Guidelines
+=====================
+
+.. contents::
+   :local:
+
+Summary
+#######
+
+This page describes guidelines that should be followed when
+implementing an interface in MantidPlot. The aim is to encourage a
+consistent approach to developing interfaces.
+
+.. _GuiDesignGuidelinesMVPIntro:
+
+MVP (Model View Presenter)
+##########################
+
+GUIs in Mantid aim to use the MVP pattern. The MVP pattern is a
+generic concept for how to structure GUI code. MVP allows components
+of the GUI to be tested separately and automatically. It also allows
+for greater flexibility. Decoupling the model and view means that if
+the developer wants to experiment with, for example, a different GUI
+toolkit, or a different method of doing their calculations, then it is
+easy and safe to swap out components. A description of each component
+is given below.
+
+To illustrate MVP, a simple example of a calculator GUI has been
+created using Python (the concepts of MVP can be applied to any
+programming language). This example can be found in
+:ref:`MVPCalculatorGUIExample`, and you can run it with
+``python Calculator.py``.
+
+It is good practice to have model, view or presenter (as appropriate)
+at the end of the name for each file (e.g. FFTView, FFTModel,
+FFTPresenter), and each component should be a class in its own
+right. Within the MVP pattern the model and view never exchange any
+information directly.
+
+Model
+-----
+
+The model is where the 'hard sums' take place within GUI. Any Mantid
+algorithms should be run in the model, as well any other calculations
+that may need to be performed.
+
+It is possible that a presenter may have multiple models. For example
+if two GUIs require the same calculation (e.g. mean) but not all
+of the model (one GUI may need standard deviation and the other the
+median), then it would be sensible for there to be three models (with
+the mean model being shared). This prevents code duplication and makes
+maintenance easier.
+
+It is important to note that the values used in the calculations
+should be received from the presenter (more of which below).
+
+.. _GuiDesignGuidelinesMVPView:
+
+View
+----
+
+The view determines the look of the GUI. In passive-view MVP, there
+will generally be very little logic in the view. A view should define
+the following sections:
+
+* The look of the GUI (often this will be defined in a Qt ``.ui`` file
+  instead)
+* **Get** methods to return values from the widgets (text input,
+  checkbox etc)
+* **Set** methods to update the output from the GUI (eg. plot some
+  data, fill in some text boxes)
+
+A view will probably also contain **connections**. A detailed
+explanation of signals and slots can be foud `here
+<http://doc.qt.io/archives/qt-4.8/signalsandslots.html>`_. Briefly, a
+widget may emit **signals**. For example QPushButton emits the signal
+``clicked`` when it is clicked. In order to handle the button being
+clicked, the view will implement a **slot** method. This method does
+whatever we need for a button click. To ensure that this method is
+called whenever the button is clicked, we connect the ``clicked``
+signal of our button to the ``handleButtonClick`` slot of our view.
+
+The view should have a parent - this will be the widget containing
+it. An example of a parent would be a main window containing tabs -
+the children of the main window would be the tabs, and the children of
+the tabs would be the widgets contained within the tabs.
+
+Presenter
+---------
+
+The presenter acts as a 'go-between'. It receives data from the view,
+passes it to the model for processing, receives it back from the model
+and passes it to the view to be displayed to the user. The presenter
+generally should contain relatively simple logic (though it will be
+more complex than the view).
+
+The model and the view are stored as members of the presenter
+class. These should be passed into the presenter at initialisation.
+
+It is important to note that the model and view should have as little
+access as possible to the presenter. Presenter-model communication is
+simple - the presenter generally just calls methods on the
+presenter. Presenter-view communication is slightly more
+involved. There are two ways of doing it:
+
+* **Connections** - the presenter may contain connections as well as
+  the view. You may choose to define custom signals in your view, such
+  as a ``plotRequested`` signal to announce that the user has asked to
+  plot some data, probably by clicking a button. The presenter will
+  need to implement a slot (let's call it ``handlePlotRequested``) to
+  handle this, which gets the relevant data from the model and passes
+  it to the view. We then need to connect the signal to the slot in
+  the presenter's constructor. It is also possible for a signal
+  emitted by a view to be caught in the presenter of a parent view. In
+  order to communicate by connections using Qt in C++ the presenter
+  must inherit from ``QObject``. It's generally considered good
+  practice to avoid having Qt in the presenter, so this method works
+  best for GUIs written in Python (or another language with a more
+  relaxed type system).
+
+  - Note that is good practice to handle all signals in the presenter
+    if you can, even if it is possible to just handle them in the
+    view. This is because by going through the presenter we can unit
+    test the handling of the signals.
+* **Notify** - the presenter may instead allow the view to 'notify'
+  it. This can be achieved by implementing a set of possible
+  notifications (in C++ an enum class works well) and a method
+  ``notify(notification)`` on the presenter. In the above example,
+  ``handlePlotRequested`` is still needed, but now ``notify`` invokes
+  it whenever it is passed a ``plotRequested`` notification. This
+  method requires the view to have a pointer to the presenter, which
+  introduces a circular dependency and leaks information about the
+  presenter to the view. The leak can be resolved by having the
+  presenter implement an interface which exposes **only** the
+  ``notify`` method, and having the view keep a pointer to
+  this.
+
+Doing presenter-view communication with connections is the cleaner of
+the two, so this method should be used unless writing a GUI in
+C++. You'll notice that, in both cases, the view never passes data
+(for example, the input from a text box) directly to the presenter,
+instead it justs tells the presenter that something needs to be
+done. In passive-view MVP the presenter, in handling this, gets any
+data it needs from the view using the view's **get** methods.
+
+Testing MVP Components
+----------------------
+
+MVP allows us to write automated tests for a large amount of the
+GUI. We can write independent tests for the presenter and model, but
+usually not the view (for this reason, the view should be as simple as
+possible, ideally containing no logic at all).
+
+**Mocking** is very useful tool for testing the presenter. Mocking
+allows us to return a predefined result from a method of either the
+view or the model.
+
+It is useful to mock out the model because, providing that we've
+written adequate tests for it, we don't care what the output is in the
+tests for the presenter - we just care that the presenter handles it
+correctly. The model may perform time-consuming calculations, such as
+fitting, so by returning a dummy value from the fitting method we cut
+down the time our tests take to run. We can also potentially change
+how the model works - if the GUI uses an algorithm which undergoes
+some changes, such as applying a different set of corrections, the
+tests for the presenter will be unaffected.
+
+It's useful to mock out the view because we don't want to have to
+manually input data every time the unit tests are run - instead we can
+mock the **get** methods to simulate the user entering data.
+
+Using `GMock
+<https://github.com/google/googletest/blob/master/googlemock/docs/Documentation.md>`_
+in C++, or `unittest.mock
+<https://docs.python.org/3/library/unittest.mock.html>`_ in Python, we
+can set expectations in the unit tests for certain methods to be
+called, and with certain arguments.
+
+Qt Designer
+###########
+
+The layout of all interfaces and reusable widgets should be done by
+using the Qt's `Designer
+<http://qt-project.org/doc/qt-4.8/designer-manual.html>`_ tool. This
+has several advantages:
+
+* immediate visual feedback of what the widget/interface will look
+  like
+* far easier to maintain, e.g. moving a control is a simple drag and
+  drop
+* reduces the amount of hand-written code required
+
+If it is felt that the design must be hand coded then this should be
+discussed with a senior developer.
+
+Reusable Widgets
+################
+
+Many interfaces will require similar functionality. For example, the
+ability to enter a filename string to search for a file along with a
+'Browse' button to select a file from the filesystem. This type of
+behaviour should be captured in a new composite widget that can be
+reused by other components.
+
+The new widget should be placed in the MantidWidgets plugin and a
+wrapper created in the DesignerPlugins plugin so that the new widget
+type can be used from within the Qt Designer.
+
+The current set of reusable items are:
+
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Class Name              | Parent Class  | Abiltity                                                                                                                                                     |
++=========================+===============+==============================================================================================================================================================+
+| AlgorithmSelectorWidget | QWidget       | A text box and tree widget to select an algorithm                                                                                                            |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| CatalogSearch           | QWidget       | An interface interface to the catalog system                                                                                                                 |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| CatalogSelector         | QWidget       | Displays the available catalog services                                                                                                                      |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| CheckBoxHeader          | QHeaderView   | Enables checkboxes to exist in the table header                                                                                                              |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ColorBarWidget          | QWidget       | Show a color bar that can accompany a colored bidimensional plot                                                                                             |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| DataSelector            | MantidWidget  | A box to select if input is from a file or workspace along with the appropriate widget to choose a workspace or file.                                        |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| DisplayCurveFit         | MantidWidget  | A plot to display the results of a curve fitting process                                                                                                     |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| FindReplaceDialog       | QDialog       | A dialog box to find/replace text within a ScriptEditor                                                                                                      |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| FitPropertyBrowser      | QDockWidget   | Specialisation of QPropertyBrowser for defining fitting functions                                                                                            |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| FunctionBrowser         | QWidget       | Provides a wiget to alter the parameters of a function                                                                                                       |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| InstrumentSelector      | QCombobox     | A selection box populated with a list of instruments for the current facility                                                                                |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| LineEditWithClear       | QLineEdit     | A QLineEdit with a button to clear the text                                                                                                                  |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| MessageDisplay          | QWidget       | Display messages from the logging system                                                                                                                     |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| MWRunFiles              | MantidWidget  | Provides a line edit to enter filenames and a browse button to browse the file system                                                                        |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| MWView                  | QWidget       | A colored, bidimensional plot of a matrix workspace                                                                                                          |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ProcessingAlgoWidget    | QWidget       | A composite widget that allows a user to select if a processing step is achieved using an algorithm or a Python script. It also provides a script editor.    |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ScriptEditor            | QsciScintilla | The main script editor widget behind the ScriptWindow                                                                                                        |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| WorkspaceSelector       | QComboBox     | A selection box showing the workspaces currently in Mantid. It can be restricted by type.                                                                    |
++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+Python
+######
+
+Interfaces can also be created in Python using the `PyQt4
+<http://pyqt.sourceforge.net/Docs/PyQt4/>`_ package. The code for the
+interface should be placed in a Python `package
+<https://docs.python.org/2/tutorial/modules.html#packages>`_ under the
+``Code/Mantid/scripts`` directory. It should be named after the interface
+name (without spaces). The code within the package should be
+structured to avoid placing all of the code in a single file,
+i.e. separate files for different classes etc. Sub packages are
+recommended for grouping together logical sets of files.
+
+For the interface to appear from within MantidPlot create a startup
+python file under the ``Code/Mantid/scripts`` directory. Assuming the code
+for the interface is in a directory called foo_app then the startup
+file would look like:
+
+.. code-block:: python
+
+   from foo_app import FooGUI
+
+   app = FooGUI()
+   app.show()
+
+where ``FooGUI`` is the ``MainWindow`` for the interface. Some more
+detailed documentation on creating GUIs in Python can be found at
+:ref:`QtDesignerForPython`.
+
+Designer
+--------
+
+As with the C++ GUI the Qt Designer should be used for layouts of all
+widgets and the main interface. It is recommended that the ``.ui``
+files be placed in a ``ui`` subdirectory of the interface package. To
+generate PyQt code from the UI xml you will need to run the ``pyuic4``
+program that ships with PyQt4. It is also recommended that the output
+file is named, using the ``-o`` argument, ``ui_[widgetname].py`` and
+placed in the ``ui`` subdirectory.
diff --git a/dev-docs/source/GettingStarted.rst b/dev-docs/source/GettingStarted.rst
index bfbbe1927dcd6659d91b26cb9aaa644c0afe7443..68ce6b55d77c981d4645dbe7ebbaf4d12e26b6b1 100644
--- a/dev-docs/source/GettingStarted.rst
+++ b/dev-docs/source/GettingStarted.rst
@@ -1,14 +1,16 @@
-===========================
-Getting Started with Mantid
-===========================
+.. _GettingStarted:
+
+===============
+Getting Started
+===============
 
 .. contents::
   :local:
 
-Prerequisites
-#############
+Environment
+###########
 
-Some intial setup is required before being able to build the code. This is platform
+Some initial setup is required before being able to build the code. This is platform
 specific and described here.
 
 Windows
@@ -18,23 +20,37 @@ 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.
-* `Git <https://git-scm.com/download/win>`_
-* `Git LFS <https://git-lfs.github.com/>`_
 
-  * After installation open Git Bash and run ``git lfs install``
+  * Select a custom install and include at minimum:
+
+    * 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/>`_. After installation open Git Bash and run ``git lfs install``.
 * `CMake <https://cmake.org/download/>`_
-* `MiKTeX <https://miktex.org/download>`_. Instructions are available
-  `here <https://miktex.org/howto/install-miktex>`_.
+* `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
+  * switch to administrator mode
+  * settings -> select "Always install missing packages on-the-fly"
+
 * `NSIS <http://nsis.sourceforge.net/Download>`_ (optional). Used for building packages
 
+`Graphviz <http://graphviz.org/download/>`__ is required to generate the workflow diagrams in the documentation.
+Unfortunately CMake can't find it out of the box and the following steps are required to make this link
+
+* open regedit
+* add a new key ``[HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz]``
+* create a new string value named ``InstallPath`` within this key and set the value
+  to point to the install directory of Graphviz.
+
 Linux
 -----
 
 Red Hat/Cent OS/Fedora
-^^^^^^^^^^^^^^^^^^^^^^
-
-Follow the instructions at http://download.mantidproject.org/redhat.html to add the
+~~~~~~~~~~~~~~~~~~~~~~
+Follow the `Red Hat instructions <http://download.mantidproject.org/redhat.html>`_ to add the
 stable release yum repository and then install the ``mantid-developer`` package:
 
 .. code-block:: sh
@@ -42,9 +58,8 @@ stable release yum repository and then install the ``mantid-developer`` package:
    yum install mantid-developer
 
 Ubuntu
-^^^^^^
-
-Follow the instructions at http://download.mantidproject.org/ubuntu.html to add the
+~~~~~~
+Follow the `Ubuntu instructions <http://download.mantidproject.org/ubuntu.html>`_ to add the
 stable release repository and mantid ppa. Download the latest
 `mantid-developer <https://sourceforge.net/projects/mantid/files/developer>`_
 package and install it:
@@ -56,3 +71,41 @@ package and install it:
 
 where ``X.Y.Z`` should be replaced with the version that was downloaded.
 
+OSX
+---
+The build environment on OS X is described here :ref:`BuildingOnOSX`.
+
+Getting the Mantid code
+############################
+We use `Git`_ as our version control system (VCS). The master copies of our repositories are located at `GitHub <http://github.com/mantidproject>`_. We have a number of repositories, of which the main one (the one containing all the source code for Mantid itself) is called simply `mantid <http://github.com/mantidproject/mantid>`_.
+
+If you are not already set up with Git, you can follow these `instructions <https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup>`_.
+
+If you are at RAL then please run the following commands before cloning the repository:
+
+.. code-block:: sh
+
+    git config --global url.git@github.com:mantidproject.insteadOf http://mantidweb.nd.rl.ac.uk/mirror/git/
+
+This will speed up the clone and intial cmake run considerably.
+
+There are a number of URLs via which the code can be checked out using various protocols. The easiest way to get the one you want is to select the protocol you want on the right side of the `mantid <http://github.com/mantidproject/mantid>`_ repository page on github and copy the url into your clipboard. The way to clone the repository via ssh on the command line, into a directory called Mantid, is:
+
+.. code-block:: sh
+
+    git clone git@github.com:mantidproject/mantid.git
+
+If at RAL now remove the config section above
+
+.. code-block:: sh
+
+    git config --global --unset url.git@github.com:mantidproject
+
+
+Building Mantid
+###############
+See :ref:`BuildingWithCMake` for information about building Mantid.
+
+Building VATES
+##############
+See :ref:`BuildingVATES` for infromation about building VATES.
diff --git a/dev-docs/source/GitWorkflow.rst b/dev-docs/source/GitWorkflow.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8200abc95004486ae13f00a309e4f737c651a958
--- /dev/null
+++ b/dev-docs/source/GitWorkflow.rst
@@ -0,0 +1,186 @@
+.. _GitWorkflow:
+
+===================
+Mantid Git Workflow
+===================
+
+.. contents:: Contents
+   :local:
+
+Summary
+^^^^^^^
+
+This page describes the workflow used in conjunction with `Git
+<http://git-scm.com>`_ and `GitHub <https://www.github.com/>`_ for
+those who have push access to the repository.
+
+Go `here
+<https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf>`__
+for a cheatsheet of Git commands.
+
+Go `here <https://github.com/k88hudson/git-flight-rules>`__ for a
+(fairly) comprehensive guide to solving your various Git problems.
+
+Description
+^^^^^^^^^^^
+
+We follow the `GitHub flow
+<https://guides.github.com/introduction/flow/index.html>`_, using
+branches for new work and pull requests for verifying the work.
+
+The steps for a new piece of work can be summarised as follows:
+
+1. Push up or `create <https://guides.github.com/features/issues>`_ an
+   issue `here <https://github.com/mantidproject/mantid/issues>`__
+2. Create a branch from master, using the naming convention described
+   at :ref:`GitWorkflowPublicPrivateBranches`
+3. Do the work and commit changes to the branch. Push the branch
+   regularly to GitHub to make sure no work is accidentally lost
+4. When you are finished with the work, ensure that all of the unit
+   tests, documentation tests and system tests if necessary pass on
+   your own machine
+5. Open a pull request (:ref:`GitWorkflowPullRequests`)
+   from the `GitHub branches
+   <https://github.com/mantidproject/mantid/branches/>`_ page
+
+   - This will check with the buildservers for cross-platform
+     compatibility
+   - If any issues come up, continue working on your branch and push
+     to GitHub - the pull request will update automatically
+
+.. _GitWorkflowPublicPrivateBranches:
+
+Public and Private Branches
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When naming `public branches
+<http://github.com/mantidproject/mantid/branches>`_ that will be
+pushed to GitHub, please follow the convention of
+``issuenumber_short_description``. This will allow others to discover
+what the branch is for (issue number) and quickly know what is being
+done there (short description). Please remember that public branches
+should not be rebased.
+
+For private branches please follow the convention
+``yourname/issuenumber_short_description``.  You can sync these with
+GitHub (for backup reasons) and rebase. Since the branch name is
+prefixed with your name people will know, by convention, that it is a
+private branch and can be rebased, deleted, etc at the owner's
+whim. Changing a private branch is done by simply renaming the branch
+to drop the prefix.
+
+
+.. _GitWorkflowPullRequests:
+
+Pull Requests
+^^^^^^^^^^^^^
+
+For an general overview of using pull requests on GitHub look `here
+<https://help.github.com/articles/using-pull-requests/>`__.
+
+When creating a pull request you should:
+
+- Ensure that the title succinctly describes the changes so it is easy
+  to read on the overview page
+
+  - The title should **not** contain the issue number
+- `Reference the issue which the pull request is closing  <https://github.com/blog/1506-closing-issues-via-pull-requests>`_, using one of `these <https://help.github.com/articles/closing-issues-via-commit-messages>`_ keywords
+- Ensure the description follows the format described by the `PR
+  template
+  <https://github.com/mantidproject/mantid/blob/master/.github/PULL_REQUEST_TEMPLATE.md>`_
+  on GitHub
+
+A good example is `here <https://github.com/mantidproject/mantid/pull/18713>`__.
+
+Recommended reading: `How to Write the Perfect Pull Request
+<https://github.com/blog/1943-how-to-write-the-perfect-pull-request>`_
+
+Stale Pull Requests
+-------------------
+
+Pull requests that go an extended period of time without any activity
+are considered stale and will be picked up by a (partially) automated
+bot which will notify those that are required to take action in order
+to keep the review process going.
+
+This is also used to notify developers of pull requests that develop
+conflicts with the base branch and that fail continuous integration
+tests, in those two cases the age of the pull request is ignored.
+
+The reasons a pull request may be flagged up currently are:
+
+- Conflicts with base branch
+- Failing CI
+- Last developer has left the Mantid team
+- Nobody has reviewed the PR
+- An assigned reviewer has yet to complete a review
+- A gatekeeper has not second reviewed an approved PR
+- A review from a specific user was requested but that user has yet to complete a review
+- The developer has yet to act on comments left in a review
+
+
+(code for the bot is currently `here
+<https://github.com/DanNixon/mantid_pr_bot>`__)
+
+Code Freeze
+^^^^^^^^^^^
+
+At the start of a *code freeze* before a major release there will be a
+release branch created with the name ``release-vX.Y``, where ``X.Y``
+are the major and minor version numbers, respectively. At this point
+only bugfixes should be applied to this release branch so that it can
+be stabilized for the release. The release branch will be merged to
+``master`` periodically so bugfixes do not need to be separately
+merged to ``master``.
+
+New Branches
+------------
+
+During the code freeze it is important to ensure that a new branch is
+created from the correct base branch depending on the scope of the
+changes:
+
+- ``master``: maintenance fixes, new features. Command: ``git fetch -p && git checkout --no-track -b MYBRANCH_NAME origin/master``
+- ``release-vX.Y``: bugfixes. Command: ``git fetch -p && git checkout --no-track -b MYBRANCH_NAME origin/release-X.Y``
+
+Pull Requests
+-------------
+
+Open pull requests as normal to ask to merge your branch with its
+intended target.
+
+.. image:: images/CodeFreezePR.png
+
+Fixing a PR with an Incorrect Base Branch
+-----------------------------------------
+
+The target branch on GitHub needs to match the base branch used in the
+commands above when the branch was initially created. If the compare
+view shows changes other than your own it is most likely that the base
+branch is incorrect and it needs to be fixed.
+
+As an example consider the scenario where a branch named ``topic`` has
+been based off the ``master`` branch as follows::
+
+   o---o---o---o---o  master
+      |           \
+      |            o---o---o  topic
+       \
+        o---o---o---o---o  release
+
+where we actually want the ``topic`` branch based off ``release``
+instead i.e. ::
+
+   o---o---o---o---o  master
+       \
+        o---o---o---o---o  release
+                                \
+                                 o'---o'---o'  topic
+
+To fix this situation we use the ``rebase`` command, providing the
+``--onto`` option as follows:
+
+.. code-block:: bash
+
+    git fetch
+    git rebase --onto origin/release origin/master topic
diff --git a/dev-docs/source/HandlingXML.rst b/dev-docs/source/HandlingXML.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1f7ad335fe1016250ec1e893f99f799f1e8c6993
--- /dev/null
+++ b/dev-docs/source/HandlingXML.rst
@@ -0,0 +1,85 @@
+Handling XML
+============
+
+This page provides an introduction into reading/writing XML effectively
+within Mantid. In Mantid, we use Poco to handling XML serialisation. A
+useful introductory presentation can be found `here. <http://pocoproject.org/slides/170-XML.pdf>`__
+
+**This page is a work in progress.**
+
+Examples
+--------
+
+Parsing
+~~~~~~~
+
+.. code-block:: cpp
+
+
+    #include <Poco/DOM/Document.h>
+    #include <Poco/DOM/DOMParser.h>
+    #include <Poco/DOM/Element.h>
+
+    Poco::XML::DOMParser pParser;
+    Poco::AutoPtr<Poco::XML::Document> pDoc;
+    try {
+      pDoc = pParser.parseString(cuboidStr);
+    } catch (...) {
+      // Handle the failure as appropriate
+    }
+    // Get pointer to root element
+    Poco::XML::Element *pRootElem = pDoc->documentElement();
+
+Iterating over an element's children
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+    Poco::XML::Element *pRootElem = pDoc->documentElement();
+    //Iterate over every child node (non-recursively)
+    for (Node *pNode = pRootElem->firstChild(); pNode != 0; pNode = pNode->nextSibling()) {
+      auto pElem = dynamic_cast<Poco::XML::Element*>(pNode);
+      if(pElem) {
+        //We can now do something with this element safely
+      }
+    }
+
+Inspecting an element
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+    Poco::XML::Element *pElem;
+
+    //Reasonably quick operations
+    const std::string tag = pElem->tagName(); //for <foo>bar</foo> the tag is 'foo'
+    const std::string value = pElem->innerText(); //for the above example: 'bar'
+    Poco::XML::Node *pNext = pElem->nextSibling();
+    Poco::XML::Node *pPrev = pElem->previousSibling();
+    Poco::XML::Node *pChild = pElem->firstChild(); //avoid lastChild, it's expensive
+
+Avoid NodeList
+--------------
+
+There are numerous functions that return a ``Poco::XML::NodeList``. You
+should avoid using them and the list they return as best you can.
+
+NodeList is a very inefficient container. Its ``item`` method has a cost
+equivalent to the value of ``i`` given to it, and its ``length`` method
+a cost of ``n``, where ``n`` is the number of nodes in the list.
+
+This means that running the following is horrendously slow:
+
+.. code-block:: cpp
+
+    // NEVER DO THIS
+    Poco::AutoPtr<Poco::XML::NodeList> pElems = pElem->getElementsByTagName("foo");
+    for(int i = 0; i < pElems->length(); ++i) { // length costs N, and is called N times (N² cost)
+      Poco::XML::Node* pNode = pElems->item(i); // item costs at least i and is called N times, with i from 0 -> N-1 (N² + N cost)
+    }
+    // NEVER DO THIS
+
+Even if the compiler is smart enough to optimise ``pElems->length()`` to
+a single call, we still have N² + N performance at best. Instead, we
+should **always** use the iteration example given earlier, as that runs
+in N time, instead of N².
diff --git a/dev-docs/source/InstrumentViewer.rst b/dev-docs/source/InstrumentViewer.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bbb9b67200c065742a1471c6cf88fb7c48eb56c1
--- /dev/null
+++ b/dev-docs/source/InstrumentViewer.rst
@@ -0,0 +1,51 @@
+.. _InstrumentViewer:
+
+========================
+Instrument Viewer Widget
+========================
+
+.. contents::
+  :local:
+
+Overview
+--------
+
+Mantid visualisation system allows users to view the geometry of an instrument and also select and query individual detectors.
+An instrument is always shown in the context of a workspace containing data recorded with this instrument.
+The detectors are coloured according to the data in the corresponding spectra of the workspace.
+The user can select individual detectors by clicking on them and request to see the data recorded by this detector as a table or a graph.
+The instrument view also allows users to see close-ups of any component.
+
+.. figure:: images/InstrumentWidget.jpg
+  :align: center
+  :width: 635
+
+Implementation
+--------------
+
+MantidPlot uses :code:`OpenGL` to plot the geometry. :code:`Instrument3DWidget` represents the view window and controls the viewport and the scene.
+The base class for a visual element is :code:`GLObject`. :code:`Actors` and :code:`MantidObject` inherit from it. :code:`Actors` represent the instrument components.
+
+.. figure:: images/InstrumentViewClassDiagram.jpg
+  :align: center
+  :width: 752
+
+Detector Picking
+----------------
+
+Detector picking is a process of selecting a detector in the instrument view by clicking on it.
+When the user clicks the mouse inside the viewport in the picking mode, MantidPlot creates a hidden image of the instrument in which detectors are given colours encoding the detector's index in the instrument tree.
+On the mouse click a colour is read in and decoded back into the index.
+
+Geometry Handlers and Renderers
+-------------------------------
+
+Each object has a geometry handler attached to it.
+The handler is responsible for creating the mesh and rendering the object.
+Handlers have different methods of creating meshes.
+For example, :code:`GluGeometryHandler` can create simple shapes such as spheres and cylinders, :code:`OCGeometryHandler` creates more complex geometries combining simple shapes together.
+:code:`CacheGeometryHandler` reads previously saved geometries from a file.
+
+.. figure:: images/GeometryHandlers.jpg
+  :align: center
+  :width: 793
diff --git a/dev-docs/source/IssueTracking.rst b/dev-docs/source/IssueTracking.rst
new file mode 100644
index 0000000000000000000000000000000000000000..004dd47754f2406b8f1f9430b292b95fc493d5e4
--- /dev/null
+++ b/dev-docs/source/IssueTracking.rst
@@ -0,0 +1,135 @@
+=====================
+Mantid Issue Tracking
+=====================
+
+Mantid uses GitHub issues to track new feature and bugfix
+development. The issue tracker can be found at `GitHub
+<https://github.com/mantidproject/mantid/issues>`_
+
+.. contents:: Contents
+    :local:
+
+Workflow
+^^^^^^^^
+
+Every piece of work starts with an open issue. To find issues that are
+assigned to you see the section
+:ref:`IssueTrackingYourIssues`. How an issue is closed is
+then dependent on its requirements:
+
+- Code changes required: generate a **pull request**
+  (:ref:`GitWorkflowPullRequests`)
+
+  - Make sure the issue is referenced with ``#issue-number``. It will
+    then be closed when the pull request is merged
+- No code changes required: Close the issue, with a comment explaining
+  why the issue should be closed, for example:
+
+  - This is a duplicate of #1234
+  - This works for me, when I try the following steps ....
+  - I've spoken to the author of this issue and it does not happen for
+    them either anymore
+  - Contacted the instrument scientists that raised this issue and it
+    has been solved since version 3.4
+  - After further investigation we are not going to continue with this
+    for the following reasons ... The author of this ticket has been
+    informed.
+  - (If the issue is an **umbrella** issue, indicated by the
+    **Roadmap** label) All points in this issue have been addressed
+    elsewhere (see issues X, Y, Z)
+
+Creating an Issue
+^^^^^^^^^^^^^^^^^
+
+Go `here <https://github.com/mantidproject/mantid/issues/new>`__ to
+create a new issue. Make sure you assign the appropriate labels (see
+:ref:`IssueTrackingLabels`) and milestone.
+
+.. _IssueTrackingLabels:
+
+Labels
+^^^^^^
+
+GitHub allows you to assign various labels to your issues and pull
+requests. Labelling your issues and pull requests adequately will
+ensure that they are picked up by the right people.
+
+Labels fall into several groups: (*please note that 'ticket' is used
+to refer to either an issue or a PR on this page*)
+
+- **Component** - which area of Mantid the ticket concerns. The ticket
+  may be relevant to more than one area. Some commonly used
+  **Component** labels are:
+
+  - **Framework**: tickets relating to Algorithms, Workspaces and
+    SimpleAPI
+  - **GUI** - tickets relating either to the main MantidPlot GUI, or
+    one if its custom interfaces
+  - **Python** - whether the change will be implemented in
+    Python. This is useful for labelling PRs, as branches in which all
+    changes are in Python often don't need to be rebuilt to be tested,
+    so can be picked up more quickly
+- **Group** - you may belong to a group within Mantid, such as the
+  Reflectometry group. Use the corresponding label so that others in
+  your group can easily find your work to review it
+- **Misc** - some of the more common **misc** labels are described
+  below:
+
+  - **Bug** - used for issues or PRs which reference a specific bug in
+    the software (as opposed to a new feature, or general
+    improvements)
+  - **Induction** - if you come across an issue that may be good for a
+    new starter (not too difficult, low risk, the relevant code is
+    comprehensively tested, low(ish) priority) don't hog it for
+    yourself! Put this label on it so that it can be picked up as an
+    introduction to the Mantid codebase
+  - **Roadmap** - useful when planning out a large piece of work - use
+    this to map out the steps you'll need to take along the way. This
+    will usually subsume several smaller issues
+- **Priority**
+
+  - **Priority: High** - use this if your ticket needs picking up
+    right away, for instance if it relates to a bug which affects a
+    large number of users
+- **Patch candidate** - following a release, low-risk tickets with
+  high impact on users will be considered for a follow-up (or *patch*
+  release). If your ticket matches this description, consider
+  labelling it as a patch candidate
+- **Quality** - not all of Mantid is well-written. Use one of these
+  labels if your ticket involves improving the quality of the Mantid
+  codebase (these changes will usually be invisible to users)
+- **State: In Progress** - use this label on a PR if the work in that
+  PR is still ongoing, and you don't want a review yet. **REMEMBER TO
+  REMOVE IT ONCE YOUR WORK IS READY FOR REVIEW**
+
+Filtering Issues
+^^^^^^^^^^^^^^^^
+
+GitHub has a powerful issue filtering system that is described `here
+<https://help.github.com/articles/searching-issues>`__. Below we list
+some common searches that developers will need. It is advised to
+bookmark these URLs.
+
+.. _IssueTrackingYourIssues:
+
+Your Issues
+-----------
+
+You can view the issues assigned to you by visiting the `list of
+issues <https://github.com/mantidproject/mantid/issues>`_, clicking on
+the assignee drop down box and finding your name.
+
+For Review
+----------
+
+These are useful links to view when you are looking to review/test an
+issue or pull request:
+
+- Go `here
+  <https://github.com/mantidproject/mantid/pulls?utf8=%E2%9C%93&q=-author%3AGITHUB-NAME-HERE+is%3Apr+is%3Aopen+-label%3A%22State%3A+In+Progress%22+no%3Aassignee+status%3Asuccess>`__
+  for pull requests that you did not create and no one else is
+  assigned. Please replace GITHUB-NAME-HERE with your GitHub username
+- Go `here
+  <https://github.com/mantidproject/mantid/issues?utf8=%E2%9C%93&q=-assignee%3AGITHUB-NAME-HERE+is%3Aissue+is%3Aopen+label%3A%22State%3A+Review+Required%22+>`__
+  for issues with no code changes to review. Please replace
+  GITHUB-NAME-HERE with your GitHub username
diff --git a/dev-docs/source/JenkinsConfiguration.rst b/dev-docs/source/JenkinsConfiguration.rst
new file mode 100644
index 0000000000000000000000000000000000000000..33280c6a7684bc847a74a37e6a0f9194e7480eaf
--- /dev/null
+++ b/dev-docs/source/JenkinsConfiguration.rst
@@ -0,0 +1,460 @@
+.. _JenkinsConfiguration:
+
+=====================
+Jenkins Configuration
+=====================
+
+.. contents::
+  :local:
+
+Summary
+#######
+
+Mantid uses the `Jenkins <https://jenkins.io/>`__ automation server to
+support the continuous integration requirements of Mantid. This document
+aims to describe the general setup of the system.
+
+Introduction
+############
+
+Jenkins works on a 'master->slave' principle. The master node is
+responsible for orchestrating jobs and managing the slave nodes, where the
+work is actually performed. The master node is located at
+http://builds.mantidproject.org and each facility is responsible for providing
+hardware to act as slaves for the various required configurations.
+
+General Setup
+#############
+
+The master node is set to a fixed TCP port for JNLP slave agents under
+http://builds.mantidproject.org/configureSecurity.
+
+The anonymous jenkins user has the following rights: Overall Read,
+Slave Connect, Job Read, View Read.
+
+Setting up a New Slave
+######################
+
+Machine Setup
+-------------
+
+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`).
+
+Windows
+-------
+
+* Ensure that the location of ``msbuild.exe`` (``C:\Windows\Microsoft.NET\Framework64\v4.0.30319``) is on the ``PATH``
+
+Slave Connection
+^^^^^^^^^^^^^^^^
+
+There are following additional steps required to be able to connect a
+Windows slave using JNLP as a Windows service :
+
+#. Setup the slave on the master node using "New Node" under
+   http://builds.mantidproject.org/computer/. If "New Node" is not visible
+   then you do not have the required permissions - ask an admin for help. It is
+   recommended that you copy from an existing node of a similar type.
+#. Once configured on the master, remote desktop to the slave, open a browser and connect to the webpage of the
+   slave, .e.g. http://builds.mantidproject.org/computer/ornl-pc73896/
+#. Click on the **connect** button to launch the JNLP client.
+#. Once the client is launched, you can select "Install as Windows
+   Service" from the clients menu. If you have a proxy then see the
+   section below for further configuration steps.
+#. Once installed change the recovery behaviour for
+   the service. Do this by right-clicking on the Jenkins
+   service->Properties->Recovery. Change the first, second, subsequent
+   failures to restart the service.
+#. Change the account that the service uses to log on by right-clicking
+   on the Jenkins service->Properties->Log On and enter the details in
+   the builder account
+#. Change the "Startup type:" of the service to be "Automatic (Delayed Start)"
+#. Ensure the msbuild directory is on the ``PATH``
+#. Finally reboot the slave (this is the easiest way for the Jenkins to
+   start trying to reconnect to it)
+
+Note that changes to ``PATH`` require restarting the Jenkins service in
+order to be reflected in the build environment.
+
+Connecting Through a Proxy Server
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It is a little more tricky to windows slaves connected through a
+proxy.To do this you must modify the java arguments that are used to
+start the ``jenkins-slave`` process. Once the "Install as a Windows
+Service" has completed you should
+
+#. Find a directory on the machine such as ``C:\Jenkins``` or whatever
+   was configured in the slave config.
+#. Open the ``jenkins-slave.xml`` file
+#. Edit the tag and add ``-Dhttp.proxyHost=PROXYHOST``
+   ``-Dhttp.proxyPort=PROXYPORT`` to the list
+#. Save the file and restart the service (or machine)
+
+
+Linux
+-----
+
+Install an ssh server.
+
+Install ``ccache``. After installing run ``ccache --max-size=20G`` from the ``builder`` account.
+
+Install a vnc server and from the ``builder`` account run ``vncpasswd`` to set a password on the VNC server. It
+can be any password.
+
+Ensure ``curl`` is installed
+
+Any machines acting as performance test servers will require ``mysqldb`` to be installed.
+
+Ubuntu
+^^^^^^
+
+Configure `automatic security updates <https://help.ubuntu.com/community/AutomaticSecurityUpdates>`__.
+
+Install ``gdebi-core`` package to allow installing ``.deb`` files.
+
+The ``builder`` account must be setup to be able to run ``gdebi`` non-interactively. Use ``visudo`` to add the following
+exception got ``builder``::
+
+    # Allow no password for gdebi
+    builder       ALL=(ALL)NOPASSWD:/usr/bin/gdebi, /usr/bin/dpkg
+    ## Disable tty requirement for gdebi and dpkg command
+    Defaults!/usr/bin/gdebi !requiretty
+    Defaults!/usr/bin/dpkg  !requiretty
+
+Red Hat
+^^^^^^^
+
+The ``builder`` account must be setup to be able to run ``yum`` non-interactively. Use ``visudo`` to add the following
+exception got ``builder``::
+
+    ## Allow no password for yum
+    builder       ALL = NOPASSWD: /usr/bin/yum,/bin/rpm
+    ## Disable tty requirement for yum command
+    Defaults!/bin/rpm       !requiretty
+    Defaults!/usr/bin/yum       !requiretty
+
+Mac OS
+------
+
+Enable `SSH ("Remote Login") and VNC ("Remote Management") <https://apple.stackexchange.com/a/73919>`__.  If you have
+connection issues from a non-OS X client then try adjusting your color depth settings (True Color 32bpp works on Remmina).
+
+Install ``cppcheck`` from brew.
+
+The ``builder`` account must be setup to be able to run ``gdebi`` non-interactively. Use ``visudo`` to add the following
+exception got ``builder``::
+
+
+    # Allow builder to install packages without a password
+    builder  ALL=(ALL)NOPASSWD:/usr/sbin/installer, /bin/rm
+    # Disable tty requirement
+    Defaults!/usr/sbin/installer    !requiretty
+    Defaults!/bin/rm        !requiretty
+
+In order to run the MantidPlot tests, which require a connection to the windowing system, the user that is running the jenkins slave must
+have logged in. This is most easily done by VNC - connect, log in,
+then disconnect. If you see errors such as::
+
+    _RegisterApplication(), FAILED TO establish the default connection to the WindowServer,
+    _CGSDefaultConnection() is NULL.
+
+then no one is logged in to the system.
+
+Linux/Mac Connection Notes
+--------------------------
+
+The jenkins JNLP connections are maintained by a crontab entry. The
+script is in the `mantid repository
+<https://github.com/mantidproject/mantid/blob/master/buildconfig/Jenkins/jenkins-slave.sh>`__.
+
+The comments at the top describe a typical crontab entry for the script. This needs to be manually set for each slave. Ensure the script is
+marked executable after downloading it. Also ensure the entry in the crontab
+has the correct ``PATH`` setting (by default cron uses a reduced ``PATH`` entry). On macOS ``latex`` and ``sysctl``
+should be available.
+
+Post-Connection Setup - All Systems
+-----------------------------------
+
+Ensure the new machine is added to the relevant `ParaView build job <http://builds.mantidproject.org/view/ParaView/>`__ and build
+ParaView. Set the ``PARAVIEW_DIR`` & ``PARAVIEW_NEXT_DIR`` variables
+(it's easiest to just look at the configuration for one of the other
+nodes of a similar type.
+
+Misc Groovy Scripts
+###################
+
+The following is a collection of groovy scripts that can be run either
+at http://builds.mantidproject.org/script (for master node) or on a
+given node, e.g `isis-mantidx3 <http://builds.mantidproject.org/computer/isis-mantidlx3/script>`__.
+You must have admin privileges to run them.
+
+https://github.com/jenkinsci/jenkins-scripts/tree/master/scriptler was helpful for coming up with some of these.
+
+Print the Value of an Environment Variable on All Nodes
+-------------------------------------------------------
+
+.. code-block:: groovy
+
+    import jenkins.model.*
+    import hudson.model.*
+    import hudson.slaves.*
+
+    VARIABLE_NAME = "PARAVIEW_DIR"
+
+    nodes = Jenkins.instance.getNodes()
+    println("Displaying values of " + VARIABLE_NAME + " on all nodes")
+    println()
+    for(node in nodes) {
+      node_props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
+      if(node_props.size() == 1) {
+      env_vars = node_props[0].getEnvVars()
+      if(env_vars.containsKey(VARIABLE_NAME)) {
+      pv_dir = env_vars.get(VARIABLE_NAME, "")
+      } else {
+      pv_dir = VARIABLE_NAME + " not set."
+      }
+      println(node.getDisplayName() + ": " + pv_dir)
+      } else {
+      pv_dir = VARIABLE_NAME + " not set."
+      }
+    }
+
+Update ParaView variables on nodes
+----------------------------------
+
+**After running this script the variables look like they are updated but
+are in fact cached on the slaves so the new values don't take effect
+without disconnecting and forcing each slave to reconnect**
+
+.. code-block:: groovy
+
+    import jenkins.model.*
+    import hudson.model.*
+    import hudson.slaves.*
+
+    VARIABLE_NAME = "PARAVIEW_NEXT_DIR"
+    VERSION = "ParaView-5.1.2"
+
+    jenkins = Jenkins.instance
+    nodes = jenkins.getNodes()
+    println("Displaying values of " + VARIABLE_NAME + " on all nodes")
+    println()
+    for(node in nodes) {
+      node_props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)
+      if(node_props.size() == 1) {
+      env_vars = node_props[0].getEnvVars()
+      if(env_vars.containsKey(VARIABLE_NAME)) {
+        def pv_dir = node.createPath(env_vars.get(VARIABLE_NAME, ""));
+        if(pv_dir) {
+          def pv_build_dir = pv_dir.getParent();
+          def pv_dir_new = pv_build_dir.child(VERSION);
+          println(node.getDisplayName() + ": Updating $VARIABLE_NAME from '" + pv_dir.toString() + "' to '" + pv_dir_new.toString() + "'");
+          env_vars.put(VARIABLE_NAME, pv_dir_new.toString());
+        }
+        else {
+          println(node.getDisplayName() + " has variable set but " + env_vars.get(VARIABLE_NAME, "") + " does not exist");
+        }
+      } else {
+        println(node.getDisplayName() + ": $VARIABLE_NAME " +  "not set.")
+      }
+      } else {
+        println(node.getDisplayName() + ": $VARIABLE_NAME " +  "not set.")
+      }
+    }
+    jenkins.save();
+
+Check existence of ParaView builds
+----------------------------------
+
+.. code-block:: groovy
+
+    import hudson.model.*
+
+    nodes = Jenkins.instance.slaves
+
+    PV_VERSION = "5.1.2"
+
+    for (node in nodes) {
+      FilePath root = node.getRootPath();
+      if(root) {
+        FilePath fp = root.getParent();
+        // assume this is $HOME on osx/linux & drive: on Windows
+        if(fp.toString().startsWith("C:")) {
+          fp = fp.child("Builds")
+        } else {
+          fp = fp.child("build");
+        }
+        fp = fp.child("ParaView-$PV_VERSION");
+        if(!fp.exists()) {
+          println(node.getDisplayName() + " does not have PV 5.1.2")
+        }
+      }
+    }
+
+Remove directories across multiple nodes
+----------------------------------------
+
+It is advised to ensure nothing is running and pause the build queue.
+
+Master Incremental
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: groovy
+
+    import hudson.model.*
+
+    nodes = Jenkins.instance.slaves
+
+    JOBNAME = "master_incremental"
+
+
+    for (node in nodes) {
+      labels = ["osx-10.10-build", "rhel6-build", "rhel7-build", "ubuntu-14.04-build", "ubuntu-16.04-build", "win7"];
+      for (nodeLabel in labels) {
+        FilePath fp = node.createPath(node.getRootPath().toString() + File.separator + "workspace" + File.separator + JOBNAME + File.separator + "label" + File.separator + nodeLabel + File.separator + "build");
+        if(fp!=null && fp.exists()) {
+          println(fp.toString())
+          fp.deleteRecursive()
+        }
+      }
+    }
+
+Pull Requests
+^^^^^^^^^^^^^
+
+.. code-block:: groovy
+
+    import hudson.model.*
+
+    nodes = Jenkins.instance.slaves
+
+    JOB_PREFIX = "pull_requests-"
+    suffixes = ["win7", "osx", "ubuntu", "ubuntu-python3", "rhel7"];
+
+    for (node in nodes) {
+      for (suffix in suffixes) {
+        FilePath fp = node.createPath(node.getRootPath().toString() + File.separator + "workspace" + File.separator + JOB_PREFIX + suffix + File.separator +  "build");
+        if(fp!=null && fp.exists()) {
+          println(fp.toString())
+          fp.deleteRecursive()
+        }
+      }
+    }
+
+Update Branches For Jobs
+------------------------
+
+.. code-block:: groovy
+
+    import hudson.plugins.git.GitSCM
+    import hudson.plugins.git.BranchSpec
+    import static com.google.common.collect.Lists.newArrayList;
+
+    def NEW_BRANCH = "*/release-v3.8"
+
+    // Access to the Hudson Singleton
+    def jenkins = jenkins.model.Jenkins.instance;
+
+    // Retrieve matching jobs
+    def allItems = jenkins.items
+    def chosenJobs = allItems.findAll{job -> job.name =- /release_/};
+
+    println "Updating branch for chosen jobs to $NEW_BRANCH"
+    println ""
+    // Do work
+    chosenJobs.each { job ->
+        def scm = job.scm;
+        if (scm instanceof GitSCM && job.name != "release_nightly_deploy" ) {
+          //def newScm = scm.clone()
+          println "Updating branch for " + job.name
+          scm.branches = newArrayList(new BranchSpec(NEW_BRANCH))
+          println "Branch for " + job.name + ": " + scm.branches
+          println ""
+        }
+    }
+
+List All SCM Urls
+-----------------
+
+.. code-block:: groovy
+
+    import jenkins.model.*;
+    import hudson.model.*;
+    import hudson.tasks.*;
+    import hudson.plugins.git.*;
+    import org.eclipse.jgit.transport.RemoteConfig;
+    import org.eclipse.jgit.transport.URIish;
+
+    for(project in Hudson.instance.items) {
+      scm = project.scm;
+      if (scm instanceof hudson.plugins.git.GitSCM) {
+        for (RemoteConfig cfg : scm.getRepositories()) {
+          for (URIish uri : cfg.getURIs()) {
+            println("SCM " + uri.toString() + " for project " + project);
+          }
+        }
+      }
+    }
+
+Print All Loggers
+-----------------
+
+.. code-block:: groovy
+
+    import java.util.logging.*;
+
+    LogManager.getLogManager().getLoggerNames().each() {
+      println "${it}";
+    }
+
+Run a Process
+-------------
+
+.. code-block:: groovy
+
+    Process p = "cmd /c dir".execute()
+    println "${p.text}"
+
+    // kill process on windows slave
+    Process p = "cmd /c Taskkill /F /IM MantidPlot.exe".execute()
+    println "${p.text}"
+
+Update default values for job parameters
+----------------------------------------
+
+.. code-block:: groovy
+
+    import hudson.model.*
+
+    def SUFFIX_VARIABLE = "PACKAGE_SUFFIX"
+    def NEW_SUFFIX = "nightly"
+
+    // Access to the Hudson Singleton
+    def jenkins = jenkins.model.Jenkins.instance;
+
+    // Retrieve matching jobs
+    def chosenJobs = ["release_clean-rhel7"] //, "release_clean-ubuntu-16.04", "release_clean-ubuntu"]
+
+    println "Updating default package suffix for chosen jobs to ${NEW_SUFFIX}"
+    println ""
+    // Do work
+    chosenJobs.each { jobName ->
+      job = jenkins.getItem(jobName)
+      println(job)
+      paramsDef = job.getAction(ParametersDefinitionProperty)
+      params = paramsDef.getParameterDefinitions()
+      params.each { it ->
+        if(it.getName() == SUFFIX_VARIABLE) {
+          println("Updating default value of '${SUFFIX_VARIABLE}' variable to '${NEW_SUFFIX}'")
+          it.setDefaultValue(NEW_SUFFIX)
+        }
+      }
+
+    }
diff --git a/dev-docs/source/LoadAlgorithmHook.rst b/dev-docs/source/LoadAlgorithmHook.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3c9c0d92504158357c0749d96eb90c16d1dd146b
--- /dev/null
+++ b/dev-docs/source/LoadAlgorithmHook.rst
@@ -0,0 +1,63 @@
+===================
+Load Algorithm Hook
+===================
+
+.. contents::
+  :local:
+
+The Load Algorithm
+##################
+This page describes how to register a new file loading algorithm so that it can be used through
+the general-purpose :ref:`Load <algm-Load>` algorithm.
+The :ref:`Load <algm-Load>` algorithm is a special algorithm as does very little work itself.
+It instead tries to search for the most suitable algorithm for a given file and then uses this
+algorithm as a child to load the file. An algorithm wishing to be included as part of the search
+must register itself slightly differently and not use ``DECLARE_ALGORITHM`` macro.
+
+The process of searching for the correct loader needs to be fairly quick as it will be especially
+noticeable in the GUI if the process takes a long time. To speed up the process the loaders are
+currently split into 2 categories:
+
+- HDF - Currently only HDF4/5
+- NonHDF - The rest
+
+A quick check is performed, using ``HDFDescriptor::isHDF()``, to test whether the file looks like a
+`HDF <http://www.hdfgroup.org/>`__ file.
+If the check succeeds then only the HDF group of loaders are checked, otherwise only the NonHDF group are checked.
+
+Descriptors
+###########
+To avoid the file being opened/closed by each ``confidence`` method, a ``Descriptor`` object is provided.
+The actual ``Descriptor`` class depends on whether the file is a HDF file or not.
+
+HDF
+---
+To register an algorithm as a HDF loader use the IHDFLoader interface as a base class for your algorithm.
+In your cpp file include the ``MantidAPI/RegisterFileLoader.h`` header and use the ``DECLARE_HDF_FILELOADER``
+macro *instead* of the standard ``DECLARE_ALGORITHM`` macro.
+
+The interface requires that the method ``virtual int confidence(Kernel::HDFDescriptor & descriptor) const = 0;``
+be overloaded in the inheriting class. It should use the provided descriptor to check whether the loader is
+able to load the wrapped file and return a confidence level as an integer.
+
+HDFDescriptor
+^^^^^^^^^^^^^
+This provides methods to query characteristics of the current file to avoid repeated accessing of the tree.
+
+Non-HDF
+-------
+To register an algorithm as a Non-HDF loader use the ``IFileLoader`` interface as a base class for your algorithm.
+In your cpp file include the ``MantidAPI/RegisterFileLoader.h`` header and use the ``DECLARE_FILELOADER`` macro
+*instead* of the standard ``DECLARE_ALGORITHM`` macro.
+
+The interface requires that the method ``virtual int confidence(Kernel::FileDescriptor & descriptor) const = 0;``
+be overloaded in the inheriting class. It should use the provided descriptor to check whether the loader is
+able to load the wrapped file and return a confidence level as an integer.
+
+FileDescriptor
+^^^^^^^^^^^^^^
+
+This provides methods to query some characteristics of the current file and also access the open stream to avoid
+repeated opening/closing of the file. *Avoid* closing the stream. The code calling the ``confidence`` method ensures
+that the stream is back at the start of the file before checking the next loader so simply use the stream as
+necessary and leave it as it is.
diff --git a/dev-docs/source/Logging.rst b/dev-docs/source/Logging.rst
new file mode 100644
index 0000000000000000000000000000000000000000..da2fb4b3e1c386bd6e69736bfd1f074351663b53
--- /dev/null
+++ b/dev-docs/source/Logging.rst
@@ -0,0 +1,151 @@
+.. _Logging:
+
+=======
+Logging
+=======
+
+.. contents::
+  :local:
+
+Overview
+--------
+
+The Mantid logging system is a useful tool for garnering more information about the operation of the program.
+It is used to output messages from the framework to a channel, for example a file or the screen.
+Including calls to the logging system in your code can greatly aid in assessing its running - successful or otherwise.
+Logging is provided by the `Mantid::Kernel::Logger <http://doxygen.mantidproject.org/nightly/d2/d78/classMantid_1_1Kernel_1_1Logger.html>`_ class, which is a thin wrapper around the `Poco::Logger <https://pocoproject.org/docs/Poco.Logger.html>`_.
+
+Logging Levels
+--------------
+
+There are 7 log levels supported with increasing priority and decreasing verboseness:
+
++---------------+-----------------------------------------------------------------------------------------------+
+| Level         | Description on what to log                                                                    |
++===============+===============================================================================================+
+| DEBUG         | Anything that may be useful to understand what the code has been doing for debugging purposes.|
+|               | E.g. parameter values, milestones, internal variable values.                                  |
+|               | Log at this level often throughout your code.                                                 |
++---------------+-----------------------------------------------------------------------------------------------+
+| INFORMATION   | Useful information to relay back to the user of the framework.                                |
++---------------+-----------------------------------------------------------------------------------------------+
+| NOTICE        | Really important information that should be displayed to the user, this should be minimal.    |
+|               | Algorithms log at this level when starting/finishing. This is the default logging level.      |
++---------------+-----------------------------------------------------------------------------------------------+
+| WARNING       | Something was wrong but the framework was able to continue despite the problem.               |
++---------------+-----------------------------------------------------------------------------------------------+
+| ERROR         | An error has occurred but the framework is able to handle it and continue.                    |
++---------------+-----------------------------------------------------------------------------------------------+
+| CRITICAL      | An important error has occurred, the framework can continue but it is advisable to restart.   |
++---------------+-----------------------------------------------------------------------------------------------+
+| FATAL         | An unrecoverable error has occurred and the application will terminate.                       |
++---------------+-----------------------------------------------------------------------------------------------+
+
+Configuring the Log Level
+-------------------------
+
+For the logging to work you will need to have configured the logging service. This will occur when you do either of the following:
+
+- Call :code:`FrameworkManager.initialise()`
+- Get a reference to the :code:`ConfigService` singleton
+
+When the framework is initialised, it attempts to read a file called :code:`Mantid.properties` that it assumes will be available in the current working directory.
+This contains among other things the logging configuration. See the :ref:`properties file <mantid:Properties File>` overview for more information.
+
+Here is an example:
+
+.. code-block:: text
+
+  logging.loggers.root.level = debug
+  logging.loggers.root.channel.class = SplitterChannel
+  logging.loggers.root.channel.channel1 = consoleChannel
+  logging.loggers.root.channel.channel2 = fileChannel
+  logging.channels.consoleChannel.class = ConsoleChannel
+  logging.channels.consoleChannel.formatter = f1
+  logging.channels.fileChannel.class = FileChannel
+  logging.channels.fileChannel.path = mantid.log
+  logging.channels.fileChannel.formatter.class = PatternFormatter
+  logging.channels.fileChannel.formatter.pattern = %Y-%m-%d %H:%M:%S,%i [%I] %p %s - %t
+  logging.formatters.f1.class = PatternFormatter
+  logging.formatters.f1.pattern = %s-[%p] %t
+  logging.formatters.f1.times = UTC
+
+This specifies that the logging comments will go to the console as well as a file called :code:`mantid.log`.
+In the example here the level is set to debug, so all the messages will be output.
+In production this will usually be set to information.
+One could also alter the logging level programmatically using :code:`ConfigService`.
+For example, in :code:`python`:
+
+.. code-block:: python
+
+  cfg = ConfigService.Instance()
+  cfg.setConsoleLogLevel(5) # notice
+
+Note, that this affects the current session only; to change the level permanently, one needs to save the configuration to the file.
+
+Usage Example in C++
+--------------------
+
+In the .h:
+
+.. code-block:: cpp
+
+  #include "Logger.h"
+
+  class A
+  {
+  private:
+
+    /// Static reference to the logger class
+    static Logger& g_log;
+  }
+
+In the .cpp:
+
+.. code-block:: cpp
+
+  A::func()
+  {
+    g_log.error("Log message");
+    g_log.information() << "Flightpath found to be " << distance << " metres.\n";
+  }
+
+Usage Example in Python
+-----------------------
+
+Inside the algorithms:
+
+.. code-block:: python
+
+  self.log().information('Number of scan steps is something')
+
+In general:
+
+.. code-block:: python
+
+  from mantid.kernel import logger
+  logger.warning('this is a custom warning')
+
+Tips
+----
+
+- If logging data that takes significant resources to generate the message, use the :code:`is(priority)` function of the logger to check if the message would actually be output:
+
+  .. code-block:: cpp
+
+    if (g_log.is(Logger::PRIO_DEBUG))
+    {
+      // generate message and output to log.
+    }
+
+- If you need to dump binary data, use the dump method of the logger. Note that all dump messages are sent at debug level:
+
+  .. code-block:: cpp
+
+    /// Logs the given message at debug level, followed by the data in buffer.
+    void dump(const std::string& msg, const void* buffer, std::size_t length);
+
+- Note, that logging can slow down code significantly, so avoid overusing it, especially in large and nested loops.
+- In workflow algorithms consider setting an offset to the child algorithm log levels, or disable them completely, otherwise the log output can be too verbose with the low priority levels, such as debug or information.
+- Note, that the *Results Log* widget in MantidPlot offers only five options to show the logs (from debug to error).
+- Note, that too verbose logs when shown in the *Results Log* can slow down and even freeze the MantidPlot GUI for some time. So choose wisely what log level to show.
diff --git a/dev-docs/source/MVPTutorial/AddButton.rst b/dev-docs/source/MVPTutorial/AddButton.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f4a07fbdce9ad2d2ab49b912447d29462e058e96
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/AddButton.rst
@@ -0,0 +1,98 @@
+===============
+Adding a Button
+===============
+
+In this task a GUI is created containing a single button.
+
+The View
+########
+
+The below code creates a QWidget containing a single button. When the
+button is pressed it will print a message to the terminal screen. It
+should be noted that in practice this should be avoided and will be
+discussed in `this section <ReceivingSignalFromView.html>`_.
+
+First we need to import the relevant packages, this includes PyQt.
+
+.. code-block:: python
+
+    from __future__ import (absolute_import,division,print_function)
+    import PyQt4.QtGui  as QtGui
+    import PyQt4.QtCore as QtCore
+
+We then create the View class as a QWidget. Each View will have a
+parent. As a result, the View will automatically be destroyed if the
+parent is destroyed (unless the View has been removed, via docking,
+from the parent).
+
+.. code-block:: python
+
+    class view(QtGui.QWidget):
+
+    def __init__(self, parent=None):
+        super(view, self).__init__(parent)
+
+Next we create a layout and add a button to it
+
+.. code-block:: python
+
+        grid = QtGui.QGridLayout()
+        self.button = QtGui.QPushButton('Hi', self)
+        self.button.setStyleSheet("background-color:lightgrey")
+
+        # connect button to signal
+        self.button.clicked.connect(self.btn_click)
+	# add button to layout
+	grid.addWidget(self.button)
+	# set the layout for the view widget
+	self.setLayout(grid)
+
+The above connect statement means that when the button is pressed, the
+function ``btn_click`` is called:
+
+.. code-block:: python
+
+        def btn_click(self):
+            print("Hello world")
+
+The Main
+########
+
+To run the GUI we need a 'main' module. Assuming that the above has
+all been saved in ``view.py``, the ``main.py`` will contain:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import,division,print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+   
+    import view
+
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self,parent=None):
+            super(demo,self).__init__(parent)
+
+            self.window=QtGui.QMainWindow()
+            my_view = view.view()
+            # set the view for the main window
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+    def qapp():
+        if QtGui.QApplication.instance():
+            _app = QtGui.QApplication.instance()
+	else:
+            _app = QtGui.QApplication(sys.argv)
+	return _app
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
diff --git a/dev-docs/source/MVPTutorial/AddComboBox.rst b/dev-docs/source/MVPTutorial/AddComboBox.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c7162460716359aa17f9c2dfe68f7254b97e3fc9
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/AddComboBox.rst
@@ -0,0 +1,21 @@
+==============
+Add a ComboBox
+==============
+
+A ComboBox is useful when there is a finite list of options that the
+user can choose from. If a line edit was used instead then a typo
+would prevent the GUI from working correctly; a ComboBox prevents this
+possibility.
+
+The following code should be added to the View's ``__init__`` function.
+
+.. code-block:: python
+
+    self.combo = QtGui.QComboBox()
+    options = ["one", "two", "three"]
+    self.combo.addItems(options)
+    grid.addWidget(self.combo)
+
+The first line creates a ComboBox widget. The second line defines the
+options that will be displayed within the ComboBox and the third line
+adds the options to the ComboBox. The last line adds it to the layout.
diff --git a/dev-docs/source/MVPTutorial/AddLabel.rst b/dev-docs/source/MVPTutorial/AddLabel.rst
new file mode 100644
index 0000000000000000000000000000000000000000..da59ee92c3ea79138e852de097325d538324aa53
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/AddLabel.rst
@@ -0,0 +1,19 @@
+==============
+Adding a Label
+==============
+
+In this section we will add a label to the GUI. A label is a text
+display that cannot be edited by the user.
+
+To add a label we need to add three lines to the View. The first
+creates the label widget, the second assigns the label's value (what
+it will display) and the last line adds it to the layout of the view.
+
+.. code-block:: python
+
+    self.label = QtGui.QLabel()
+    self.label.setText("Button")
+    grid.addWidget(self.label)
+
+This code should be added in the View's constructor (ie its
+``__init__`` function).
diff --git a/dev-docs/source/MVPTutorial/AddLineEdit.rst b/dev-docs/source/MVPTutorial/AddLineEdit.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b2c4cbfb978dbacb16ca1bf1b80c9b17705f9d32
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/AddLineEdit.rst
@@ -0,0 +1,23 @@
+==============
+Add a LineEdit
+==============
+
+Sometimes it is necessary for the user to input some information. The
+most versatile way of allowing this is to use a line edit, which
+allows a user to enter arbitrary text. Adding the following code to
+the ``__init__`` function of the View will add a line edit:
+
+.. code-block:: python
+
+   self.text = QtGui.QLineEdit()
+   grid.addWidget(self.text)
+
+It is possible to have a default value within the line edit. It is
+also possible to make it impossible for the user to modify the line
+edit (useful for tables).
+
+Care should be taken before using a line edit as it can give a user
+too much freedom. If you know that the input is an integer then a
+`spin box <AddSpinBox.html>`_ is better. If there is a finite list of
+possible options then a `combo box <AddComboBox.html>`_ would be a
+better choice.
diff --git a/dev-docs/source/MVPTutorial/AddSpinBox.rst b/dev-docs/source/MVPTutorial/AddSpinBox.rst
new file mode 100644
index 0000000000000000000000000000000000000000..86a3abb414f4dc0d0d10f248a4c31e28368465eb
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/AddSpinBox.rst
@@ -0,0 +1,16 @@
+==============
+Add a Spin Box
+==============
+
+A spin box is a useful way to ensure that the user only selects
+integer values. The user can type an integer into the spin box or
+increment the value using the arrows. It is also possible to place
+constraints on the spin box such as a maximum value.
+
+.. code-block:: python
+
+    self.spin = QtGui.QSpinBox()
+    grid.addWidget(self.spin)
+
+To add a spin box to the GUI the above code needs to be added to the
+``__init__`` function of the View.
diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/Calculator.py b/dev-docs/source/MVPTutorial/CalculatorExample/Calculator.py
new file mode 100644
index 0000000000000000000000000000000000000000..143b51351daa0402be809c7e32a862e69f0eeaff
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CalculatorExample/Calculator.py
@@ -0,0 +1,37 @@
+from Presenter import Presenter
+from Model import Model
+from View import View
+
+import PyQt4.QtGui as QtGui
+
+import sys
+
+
+class Demo(QtGui.QMainWindow):
+    """ Wrapper class for setting the main window"""
+    def __init__(self, parent=None):
+        super(Demo, self).__init__(parent)
+
+        self.window = QtGui.QMainWindow()
+        demo_view = View()
+        demo_model = Model()
+        # create presenter
+        self.presenter = Presenter(demo_view, demo_model)
+        # set the view for the main window
+        self.setCentralWidget(demo_view)
+        self.setWindowTitle("MVP Demo")
+
+
+def qapp():
+    if QtGui.QApplication.instance():
+        _app = QtGui.QApplication.instance()
+    else:
+        _app = QtGui.QApplication(sys.argv)
+    return _app
+
+
+if __name__ == "__main__":
+    app = qapp()
+    window = Demo()
+    window.show()
+    app.exec_()
diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/Model.py b/dev-docs/source/MVPTutorial/CalculatorExample/Model.py
new file mode 100644
index 0000000000000000000000000000000000000000..c9c883a022d5f334b82654cfe80e7b23fdb1a8c7
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CalculatorExample/Model.py
@@ -0,0 +1,10 @@
+class Model(object):
+    def __init__(self):
+        self.result = 0
+
+    def calc(self, value1, operation, value2):
+        if operation == "+":
+            self.result = value1 + value2
+        elif operation == "-":
+            self.result = value1 - value2
+        return self.result
diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/Presenter.py b/dev-docs/source/MVPTutorial/CalculatorExample/Presenter.py
new file mode 100644
index 0000000000000000000000000000000000000000..d160d22e3f57b3cb2cfbdde4b1415bb551ef741f
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CalculatorExample/Presenter.py
@@ -0,0 +1,43 @@
+class Presenter(object):
+    # Pass the view and model into the presenter
+    def __init__(self, demo_view, demo_model):
+        self.model = demo_model
+        self.view = demo_view
+
+        # Define the initial view
+        # Note that, in the view, the drop-down could be replaced with a set of
+        # tick boxes and this line would remain unchanged - an advantage of
+        # decoupling the presenter and view
+        self.view.set_options('operations', ['+', '-'])
+        self.view.set_options('display', ['print', 'update', 'print and update'])
+        self.printToScreen = True
+        self.view.hide_display()
+
+        # Connect to the view's custom signals
+        self.view.btnSignal.connect(self.handle_button)
+        self.view.displaySignal.connect(self.display_update)
+
+    # The final two methods handle the signals
+    def display_update(self):
+        display = self.view.get_display()
+        if display == 'update':
+            self.printToScreen = False
+            self.view.show_display()
+        elif display == 'print':
+            self.printToScreen = True
+            self.view.hide_display()
+        else:
+            self.printToScreen = True
+            self.view.show_display()
+
+    def handle_button(self):
+        # Get the values from view
+        value1 = self.view.get_value(0)
+        operation = self.view.get_operation()
+        value2 = self.view.get_value(2)
+        # The model does the hard work for us
+        result = self.model.calc(value1, operation, value2)
+
+        if self.printToScreen:
+            print result
+        self.view.setResult(result)
diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/View.py b/dev-docs/source/MVPTutorial/CalculatorExample/View.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ffd2c4288c1c55b65ababc1a7fac85826c29bf5
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CalculatorExample/View.py
@@ -0,0 +1,91 @@
+import PyQt4.QtGui  as QtGui
+import PyQt4.QtCore as QtCore
+
+
+class View(QtGui.QDialog):
+    # In PyQt signals are the first thing to be defined in a class:
+    displaySignal = QtCore.pyqtSignal()
+    btnSignal = QtCore.pyqtSignal()
+
+    def __init__(self, parent=None):
+        # Call QDialog's constructor
+        super(View, self).__init__(parent)
+
+        # Initialise the widgets for the view (this can also be done from Qt Creator
+        self.table = QtGui.QTableWidget()
+        self.table.setWindowTitle("MVP Demo")
+        self.table.resize(400, 250)
+        self.table.setRowCount(5)
+        self.table.setColumnCount(2)
+        self.table.setHorizontalHeaderLabels(QtCore.QString("name;value;").split(";"))
+
+        # Set display values in the widgets
+        keys = ['value 1', 'operation', 'value 2', 'display', 'result']
+        self.combo = {}
+        self.create_combo_table(1, 1, 'operations')
+        self.create_combo_table(3, 1, 'display')
+        for row in range(len(keys)):
+            self.set_names(keys[row], row)
+
+        # Initialise layout of the widget and add child widgets to it
+        grid = QtGui.QGridLayout()
+        grid.addWidget(self.table)
+
+        self.button = QtGui.QPushButton('Calculate', self)
+        self.button.setStyleSheet("background-color:lightgrey")
+        grid.addWidget(self.button)
+
+        # Connect button click handler method to the button's 'clicked' signal
+        self.button.clicked.connect(self.btn_click)
+        # connect method to handle combo box selection changing to the corresponding signal
+        self.combo['display'].currentIndexChanged.connect(self.display_changed)
+
+        # Set the layout for the view widget
+        self.setLayout(grid)
+
+    # The next two methods handle the signals connected to in the presenter
+    # They emit custom signals that can be caught by a presenter
+    def btn_click(self):
+        self.btnSignal.emit()
+
+    def display_changed(self):
+        self.displaySignal.emit()
+
+    # Populate view
+    def create_combo_table(self, row, col, key):
+        self.combo[key] = QtGui.QComboBox()
+        options = ['test']
+        self.combo[key].addItems(options)
+        self.table.setCellWidget(row, col, self.combo[key])
+
+    # The next 5 methods update the appearance of the view.
+
+    def set_options(self, key, options):
+        self.combo[key].clear()
+        self.combo[key].addItems(options)
+
+    def set_names(self, name, row):
+        text = QtGui.QTableWidgetItem(name)
+        text.setFlags(QtCore.Qt.ItemIsEnabled)
+        self.table.setItem(row, 0, text)
+
+    # Update the view with the result of a calculation
+    def setResult(self, value):
+        self.table.setItem(4, 1, QtGui.QTableWidgetItem(str(value)))
+
+    def hide_display(self):
+        self.table.setRowHidden(4, True)
+
+    def show_display(self):
+        self.table.setRowHidden(4, False)
+
+    # Finally, we have the get methods to allow the presenter to read the user's input
+
+    def get_value(self, row):
+        return float(self.table.item(row, 1).text())
+
+    def get_operation(self):
+        return self.combo['operations'].currentText()
+
+    def get_display(self):
+        return self.combo["display"].currentText()
diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/index.rst b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f54745ec4bd5a4df34733e09af308c1ac57096a8
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst
@@ -0,0 +1,12 @@
+.. _MVPCalculatorGUIExample:
+
+==========================
+MVP Calculator GUI Example
+==========================
+
+See the following files for the calculator GUI described in :ref:`GuiDesignGuidelinesMVPIntro`.
+
+- :download:`Main module <Calculator.py>`
+- :download:`Model.py <Model.py>`
+- :download:`Presenter.py <Presenter.py>`
+- :download:`View.py <View.py>`
diff --git a/dev-docs/source/MVPTutorial/CompleteGUI.rst b/dev-docs/source/MVPTutorial/CompleteGUI.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c3e4ae7d61667851514f40fba3d81be7ff8145da
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/CompleteGUI.rst
@@ -0,0 +1,179 @@
+===========================
+Complete GUI from Exercises
+===========================
+
+Main module
+###########
+
+.. code-block:: python
+
+    from __future__ import (absolute_import,division,print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+
+    import model
+    import masterView
+    import masterPresenter
+
+    
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self, parent=None):
+            super(demo,self).__init__(parent)
+ 
+            data_model = model.DataGenerator()
+            colour_model = model.ColourConvertor()
+
+            self.window = QtGui.QMainWindow()
+
+            my_view = masterView.MasterView(parent=self)
+            self.master_presenter = masterPresenter.MasterPresenter(my_view, data_model, colour_model)
+
+            # set the view for the main window
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+        def qapp():
+            if QtGui.QApplication.instance():
+                _app = QtGui.QApplication.instance()
+	    else:
+		_app = QtGui.QApplication(sys.argv)
+	    return _app
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
+
+which has the addition of the data and colour models being passed to
+the Presenter. This makes it easier for us to replace the Model at a
+later date.
+
+Master View
+###########
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+
+    import view
+    import plotView
+
+    import numpy as np
+
+    class MasterView(QtGui.QWidget):
+
+        def __init__(self, parent=None):
+            super(MasterView, self).__init__(parent)
+
+            grid = QtGui.QVBoxLayout(self)
+            self.plot_view = plotView.PlotView()
+            self.options_view=view.view()
+
+            grid.addWidget(self.plot_view)          
+            grid.addWidget(self.options_view)          
+
+            self.setLayout(grid)
+
+	def getOptionView(self):
+            return self.options_view
+
+	def getPlotView(self):
+            return self.plot_view
+
+Master Presenter
+################
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import model
+    import presenter
+    import plotPresenter
+
+    class MasterPresenter(object):
+
+        def __init__(self, view, data_model, colour_model):
+        self.view = view
+
+        self.data_model = data_model
+        self.colour_model = colour_model
+
+        colours = self.colour_model.getColourSelection()
+
+        self.presenter = presenter.Presenter(self.view.getOptionView(), colours)
+        self.plot_presenter = plotPresenter.PlotPresenter(self.view.getPlotView())
+        # connect statements
+        self.view.getOptionView().plotSignal.connect(self.updatePlot)             
+       
+	# handle signals 
+	def updatePlot(self):
+	    # only care about the colour if the button is pressed
+	    colour, freq,phi = self.presenter.getPlotInfo()
+	    grid_lines = self.presenter.getGridLines()
+ 
+	    self.data_model.genData(freq,phi )
+            x_data = self.data_model.getXData()
+            y_data = self.data_model.getYData()
+ 
+            self.plot_presenter.plot(x_data, y_data, grid_lines, colour)
+
+The signal from the View is caught here and the models are used to create the correct plot.
+
+Plot Presenter
+##############
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    class PlotPresenter(object):
+
+        def __init__(self, view):
+            self.view = view
+
+	def plot(self, x_data, y_data, grid_lines, colour_code):
+            self.view.addData(x_data, y_data, grid_lines, colour_code, "x")
+
+PlotView
+########
+
+Unchanged from `Matplotlib and MVP <Matplotlib.html>`_.
+
+Presenter
+#########
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+
+    class Presenter(object):
+
+        def __init__(self, view, colours):
+            self.view = view
+	    self.view.setColours(colours)
+       
+	def getPlotInfo(self):
+            return str(self.view.getColour()), self.view.getFreq(), self.view.getPhase()
+
+	def getGridLines(self):
+            return self.view.getGridLines()
+
+View
+####
+
+Unchanged from `Model Exercise Solution <ModelExerciseSolution.html>`_.
+
+Model
+#####
+
+Unchanged from `Model Exercise Solution <ModelExerciseSolution.html>`_.
diff --git a/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst
new file mode 100644
index 0000000000000000000000000000000000000000..eed9386f820c81fdfccccef6942af7cc7d52e47c
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst
@@ -0,0 +1,67 @@
+====================================
+Extracting Information from the View
+====================================
+
+The Presenter will need a way to obtain information from the
+View. This can be done by **get** methods, as with normal
+classes. Here is a simple example of how a **get** method for the view can
+be used.
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import PyQt4.QtGui  as QtGui
+    import PyQt4.QtCore as QtCore
+
+
+    class view(QtGui.QWidget):
+
+        doSomethingSignal = QtCore.pyqtSignal()
+
+	def __init__(self, parent=None):
+            super(view, self).__init__(parent)
+
+            self.button = QtGui.QPushButton('Hi', self)
+            self.button.setStyleSheet("background-color:lightgrey")
+            # connect button to signal
+            self.button.clicked.connect(self.btn_click)
+
+            self.label = QtGui.QLabel()
+            self.label.setText("Button")
+
+            # add widgets to layout
+            self.sub_layout = QtGui.QHBoxLayout()
+            self.sub_layout.addWidget(self.label)            
+            self.sub_layout.addWidget(self.button)
+ 
+            grid = QtGui.QVBoxLayout(self)
+            grid.addLayout(self.sub_layout)
+  
+            self.value = QtGui.QLineEdit()
+            grid.addWidget(self.value)  
+
+  
+            # set the layout for the view widget
+            self.setLayout(grid)
+ 
+	#send signals
+	def btn_click(self):
+            print ("hellow from view")
+	    self.doSomethingSignal.emit()
+
+	def getValue(self):
+            return float(self.value.text())
+
+The last function ``getValue`` returns the value of the line
+edit. Since ``text()`` returns a string the output is type cast into a
+float.
+
+The Presenter has the following code added to the ``handleButton`` method:
+
+.. code-block:: python
+
+    value = self.view.getValue()
+    print("Value is "+str(value))
+
+which gets the value from the View and then prints it to the screen.
diff --git a/dev-docs/source/MVPTutorial/Introduction.rst b/dev-docs/source/MVPTutorial/Introduction.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1cca72c91708d41770e909bbe200aa776de6efb8
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Introduction.rst
@@ -0,0 +1,26 @@
+================
+MVP Introduction
+================
+
+The MVP (model, view, presenter) pattern is a set of guidelines for
+creating easy to maintain GUIs (graphical user interfaces). In
+general:
+
+- The View contains the 'look' of the GUI
+- The Model does the 'hard sums' for the GUI (e.g. runs algorithms)
+- The Presenter acts as a go between for the View and Model
+
+It is important to note that the View should be simple (no logic) and
+is usually not tested. The Model can be tested in a similar way to
+other Python tests. The Model and View never communicate with each
+other directly. The Presenter will extract relevant information from
+the View and pass it to the Model. The Presenter may then pass the
+result of the Model to the View. The Presenter will contain the GUI
+logic and is tested using **mocking**.
+
+These are guidelines and do not form a set of rules. It is sometimes
+open to interpretation if some files are classed as a View or a Model
+(this will be discussed in detail later).
+
+A more thorough explanation of MVP can be found at
+:ref:`GuiDesignGuidelinesMVPIntro`.
diff --git a/dev-docs/source/MVPTutorial/Layouts.rst b/dev-docs/source/MVPTutorial/Layouts.rst
new file mode 100644
index 0000000000000000000000000000000000000000..43a1bba04cb2032638c4c7493cfe7e90c15d987e
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Layouts.rst
@@ -0,0 +1,39 @@
+=======
+Layouts
+=======
+
+In the previous task a label was added to the View. However, the label
+appeared below the button. It would be sensible to place the label
+next to the button. This is possible by using **layouts**.
+
+So far we have used the vertical layout (``QtGui.QVBoxLayout``) and we
+will now use the horizontal layout. It is possible to add sub-layouts
+to a layout, which we will do here by adding a horizontal layout to
+the vertical one. The order in which widgets are added to the layout
+will determine their location.
+
+In the View we will replace the ``__init__`` with the following:
+
+.. code-block:: python
+
+    def __init__(self, parent=None):
+        super(view, self).__init__(parent)
+
+	self.button = QtGui.QPushButton('Hi', self)
+	self.button.setStyleSheet("background-color:lightgrey")
+
+	# connect button to signal
+	self.button.clicked.connect(self.btn_click)
+        self.label = QtGui.QLabel()
+        self.label.setText("Button")
+
+	# add widgets to layout
+        self.sub_layout = QtGui.QHBoxLayout()
+        self.sub_layout.addWidget(self.label)
+        self.sub_layout.addWidget(self.button)
+
+        grid = QtGui.QVBoxLayout(self)
+        grid.addLayout(self.sub_layout)
+
+        # set the layout for the view widget
+	self.setLayout(grid)
diff --git a/dev-docs/source/MVPTutorial/Matplotlib.rst b/dev-docs/source/MVPTutorial/Matplotlib.rst
new file mode 100644
index 0000000000000000000000000000000000000000..22972a4f8a83c403fd2c561d9e9517c48ae32514
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Matplotlib.rst
@@ -0,0 +1,73 @@
+==================
+Matplotlib and MVP
+==================
+
+The next step towards the goal of creating a GUI that allows users to
+manipulate a sine wave plot, is to produce the plot itself.
+
+For the purposes of this tutorial it is assumed that the user is
+familiar with Matplotlib, if not see `Matplotlib documentation
+<https://matplotlib.org/users/pyplot_tutorial.html>`_.
+
+The Matplotlib functions could be considered to be a Model or a View
+and there is no correct answer to which. It could be a Model as it
+does something with the data, however it could be considered to be a
+view as (in this case) it is used purely as a visual
+representation. This ambiguity is why MVP is only a pattern and not a
+set of rules. On this occasion it has been decided that it should be a
+View.
+
+This view will exist alongside with the view from the exercise. So we
+will need to call it something different, such as PlotView.
+
+The View has the following imports:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+    import matplotlib.pyplot as plt
+
+    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+
+The fourth line imports Matplotlib and the last line allows it to
+interface with the GUI.
+
+The main class is shown below and contains methods for adding data to
+the plot and creating an empty plot (no data).
+
+.. code-block:: python
+
+    class PlotView(QtGui.QWidget):
+        def __init__(self, parent=None):
+            super(PlotView, self).__init__(parent)
+
+	    self.figure = plt.figure()
+	    grid = QtGui.QVBoxLayout(self)
+	    self.draw() 
+	    self.canvas = self.getWidget()
+	    grid.addWidget(self.canvas)
+	    self.setLayout(grid) 
+
+	def draw(self):
+            ax = self.figure.add_subplot(111)
+	    ax.clear()
+	    ax.set_xlim([0.0, 10.5])
+	    ax.set_ylim([-1.05, 1.05])
+	    ax.set_xlabel("time ($s$)")
+	    ax.set_ylabel("$f(t)$")
+	    return ax
+
+	def getWidget(self):
+            return FigureCanvas(self.figure)
+
+	def addData(self, xvalues, yvalues, colour, marker):
+            ax = self.draw()
+	    ax.plot(xvalues, yvalues, color=colour, marker=marker, linestyle="--") 
+	    self.canvas.draw()
+
+The ``draw`` method creates the plot area without any data. The widget
+is obtained from the ``getWidget`` function. The final method adds
+data to the plot area, the ``self.canvas.draw()`` updates the plot
+area so it will contain the data.
diff --git a/dev-docs/source/MVPTutorial/Mocking.rst b/dev-docs/source/MVPTutorial/Mocking.rst
new file mode 100644
index 0000000000000000000000000000000000000000..631779fc777d6831a48419696f10ddbfc372666e
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Mocking.rst
@@ -0,0 +1,76 @@
+=====================
+Mocking the Presenter
+=====================
+
+The view should be so simple that it does not require
+testing. However, the presenter contains logic and should therefore be
+tested. When testing the presenter we do not want to create the actual
+GUI, instead we just want to ensure that the correct calls are made,
+this is done via mocking see `unittest docs
+<https://docs.python.org/3/library/unittest.mock-examples.html>`_ for
+a detailed discussion. Here we will have a brief discussion of the
+main points.
+
+First are the import statements
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import sys
+    import presenter
+    import view
+
+    import unittest
+    if sys.version_info.major == 3:
+        from unittest import mock
+    else:
+        import mock
+
+A different import is used for ``mock``, depending on whether we're
+using Python 2 or 3.
+
+The test class is then initialised:
+
+.. code-block:: python
+
+    class presenterTest(unittest.TestCase):
+        def setUp(self):
+	    self.view = mock.create_autospec(view.view)
+
+	    # mock view
+	    self.view.doSomethingSignal = mock.Mock()
+	    self.view.btn_click = mock.Mock()
+	    self.view.getValue = mock.Mock(return_value=3.14)
+       
+	    self.presenter = presenter.Presenter(self.view)
+
+``create_autospec`` mocks the class contained within the brackets. We
+then need to explicitly mock the methods using ``mock.Mock``. In
+addtion, when a return value is needed, this is provided in the call
+to ``mock.Mock``.
+
+A test is shown below:
+
+.. code-block:: python
+
+        def test_doSomething(self):
+            self.presenter.handleButton()
+            assert(self.view.getValue.call_count == 1)
+
+We call the ``handleButton`` function and then use ``call_count`` to
+ensure that the method from the View is called the correct number of
+times. This is a more robust method for checking how many times a
+function is called.
+
+There is a ``assert_called_once`` function however this should be
+avoided as it can easily lead to errors. This is because it is
+expected that the function ``assert_called_twice`` exists but it does
+not, however when you run the test it will always pass.
+
+The last bit of code is to execute the tests:
+
+.. code-block:: python
+
+    if __name__ == "__main__":
+        unittest.main()
diff --git a/dev-docs/source/MVPTutorial/MockingExercise.rst b/dev-docs/source/MVPTutorial/MockingExercise.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1770a54c068c818bde111f9bcd4c8da033d74c87
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/MockingExercise.rst
@@ -0,0 +1,11 @@
+================
+Mocking Exercise
+================
+
+In this exercise you will mock the Presenter from the `Presenter
+Exercise <PresenterExercise.html>`_. All of the methods should be
+mocked and the return values should be present only when necessary (on
+this occasion the values do not matter). The ``updatePlot`` function
+should be tested to make sure that it calls the correct methods.
+
+See `here <MockingExerciseSolution.html>`_ for the solution. 
diff --git a/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst
new file mode 100644
index 0000000000000000000000000000000000000000..14f8be65e83fc8d13e15fc7b36a982a4ef1222e9
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst
@@ -0,0 +1,44 @@
+=========================
+Mocking Exercise Solution
+=========================
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import sys
+    import presenter
+    import view
+
+    import unittest
+    if sys.version_info.major == 3:
+        from unittest import mock
+    else:
+        import mock
+
+    class presenterTest(unittest.TestCase):
+        def setUp(self):
+            self.view = mock.create_autospec(view.view)
+
+	    # mock view
+	    self.view.plotSignal = mock.Mock()
+	    self.view.getColour = mock.Mock(return_value="black")
+	    self.view.getGridLines =mock.Mock(return_value=True)
+	    self.view.getFreq =mock.Mock(return_value=3.14)
+	    self.view.getPhase =mock.Mock(return_value=0.56)
+	    self.view.buttonPressed = mock.Mock()
+	    self.view.setTableRow = mock.Mock()
+	    self.view.addWidgetToTable = mock.Mock()
+	    self.view.addITemToTable = mock.Mock()
+
+	    self.presenter = presenter.Presenter(self.view)
+
+        def test_updatePlot(self):
+            self.presenter.updatePlot()
+	    assert(self.view.getColour.call_count == 1)
+	    assert(self.view.getGridLines.call_count == 1)
+	    assert(self.view.getFreq.call_count == 1)
+	    assert(self.view.getPhase.call_count == 1)
+
+    if __name__ == "__main__":
+        unittest.main()
diff --git a/dev-docs/source/MVPTutorial/Model.rst b/dev-docs/source/MVPTutorial/Model.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ea0df87b65c0d2471587feb8503150b35b961cbf
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Model.rst
@@ -0,0 +1,36 @@
+==============
+A Simple Model
+==============
+
+Models are used to do the 'hard sums' within the GUI. It is possible
+to have multiple models within a single presenter, as we will see with
+this example. For this example we have kept the models fairly simple,
+in reality they will be much more complex.
+
+The first model generates the data for the user:
+
+.. code-block:: python
+
+    import numpy as np
+
+    class DataGenerator(object):
+
+        def __init__(self):
+            self.x_data = np.linspace(0.0, 10.0, 100)
+	    self.y_data = []
+ 
+	def genData(self, freq, phi):
+            self.y_data = np.sin(freq * self.x_data + phi)
+
+	def getXData(self):
+	    return self.x_data
+
+	def getYData(self):
+            return self.y_data
+
+The model methods can be split into three types initialisation, a
+calculate button and get methods.
+
+In this case we have a distinct second method. Usually this will be
+placed into its own file, however for simplicity we will contain it
+within the same file as the above code.
diff --git a/dev-docs/source/MVPTutorial/ModelExercise.rst b/dev-docs/source/MVPTutorial/ModelExercise.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c3559b53d9ea1a8c77e8b0452b3bfbb2d25f18b3
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ModelExercise.rst
@@ -0,0 +1,18 @@
+====================
+Model (MVP) Exercise
+====================
+
+In the previous section we did not need to update the View. However,
+the Model contains a dictionary which contains the allowed colour
+options. The GUI should show the same allowed values as the the
+Model. To achieve this you will need to add:
+
+1. A method to the Model for getting the allowed colours
+
+2. A method in the View to update the ComboBox values to match some
+input values
+
+3. In the initialisation of the Presenter get the allowed colours from
+the Model and pass them to the View
+
+See `here <ModelExerciseSolution.html>`_ for the solution. 
diff --git a/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst
new file mode 100644
index 0000000000000000000000000000000000000000..835bec9e2d275f6f43ac8f0710cab937f7c0dc8c
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst
@@ -0,0 +1,33 @@
+=======================
+Model Exercise Solution
+=======================
+
+The Model should now contain the following method in the
+``ColourConvertor`` class:
+
+.. code-block:: python
+
+    def getColourSelection(self):
+        return self.colour_table.keys()
+
+The View should contain the following method:
+
+.. code-block:: python
+
+     def setColours(self,options):
+         self.colours.clear()
+         self.colours.addItems(options)
+
+The Presenter initialisation should now be:
+
+.. code-block:: python
+
+     def __init__(self, view, data_model, colour_model):
+        self.view = view
+        self.data_model = data_model
+        self.colour_model = colour_model
+
+        colours = self.colour_model.getColourSelection()
+        self.view.setColours(colours)
+        # connect statements
+        self.view.plotSignal.connect(self.updatePlot)
diff --git a/dev-docs/source/MVPTutorial/MultipleViews.rst b/dev-docs/source/MVPTutorial/MultipleViews.rst
new file mode 100644
index 0000000000000000000000000000000000000000..115cf9916ace43097508371df0095f1808c9dee2
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/MultipleViews.rst
@@ -0,0 +1,86 @@
+==============
+Multiple Views
+==============
+
+
+It is possible to have an MVP pattern within other MVP patterns. If
+each complete MVP pattern is considered to be a widget then having an
+MVP pattern embedded into another MVP is effectively just adding
+another widget. This can be very useful for creating small versatile
+widgets that may be used in multiple GUIs.
+
+We will combine the View from the exercise and the PlotView from the
+previous section into a single view. To achieve this we will create a
+'master' view:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+
+    import numpy as np
+    import plotView
+    import view
+
+    class MasterView(QtGui.QWidget):
+
+        def __init__(self, parent=None):
+            super(MasterView, self).__init__(parent)
+
+            grid = QtGui.QVBoxLayout(self)
+            self.plot_view = plotView.PlotView(parent=self)
+            x_data = np.linspace(0.0, 10.0, 100)
+            y_data = np.sin(x_data)
+            self.plot_view.addData(x_data, y_data, "b", "x")
+
+            grid.addWidget(self.plot_view)
+
+            self.options_view = view.view(parent=self)
+
+            grid.addWidget(self.options_view)          
+            self.setLayout(grid)
+
+The important thing to note here is that when the PlotView and View
+are created the parent is set to be the masterView.
+
+The main only needs to import the masterView:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+
+    import masterView
+
+
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self, parent=None):
+            super(demo, self).__init__(parent)
+
+            self.window = QtGui.QMainWindow()
+            my_view = masterView.MasterView()
+            # set the view for the main window
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+	def qapp():
+            if QtGui.QApplication.instance():
+                _app = QtGui.QApplication.instance()
+	    else:
+		_app = QtGui.QApplication(sys.argv)
+	    return _app
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
+
diff --git a/dev-docs/source/MVPTutorial/PresenterExercise.rst b/dev-docs/source/MVPTutorial/PresenterExercise.rst
new file mode 100644
index 0000000000000000000000000000000000000000..de947f2237034a7af584a484d8a31eda8905d417
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/PresenterExercise.rst
@@ -0,0 +1,18 @@
+==================
+Presenter Exercise
+==================
+
+In this exercise you will create a Presenter for View.py.
+
+Using the View from the previous exercise (the one which contains a
+table) create a Presenter to handle the button press. When the button
+is pressed the following should be output:
+
+- The line colour
+- If the grid lines are on or off
+- The frequency
+- The phase
+
+The ``main`` module will also need updating to handle these changes.
+
+See `here <PresenterExerciseSolution.html>`_ for the solution. 
diff --git a/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a0cb6caedd2c6f08524f767eb5aa2c322c2aef09
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst
@@ -0,0 +1,149 @@
+===========================
+Presenter Exercise Solution
+===========================
+
+View
+####
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+
+
+    class view(QtGui.QWidget):
+
+        plotSignal = QtCore.pyqtSignal()
+
+	def __init__(self, parent=None):
+            super(view, self).__init__(parent)
+
+            grid = QtGui.QVBoxLayout(self)
+
+            self.table = QtGui.QTableWidget(self)
+            self.table.setRowCount(4)
+            self.table.setColumnCount(2)
+           
+            grid.addWidget(self.table)           
+
+            self.colours = QtGui.QComboBox()
+            options=["Blue", "Green", "Red"]
+            self.colours.addItems(options)
+
+            self.grid_lines= QtGui.QTableWidgetItem()
+            self.grid_lines.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
+            self.grid_lines.setCheckState(QtCore.Qt.Unchecked)
+            self.addItemToTable("Show grid lines", self.grid_lines, 1)
+        
+            self.freq = QtGui.QTableWidgetItem("1.0")
+            self.phi = QtGui.QTableWidgetItem("0.0")
+
+            self.addWidgetToTable("Colour", self.colours, 0)
+            self.addItemToTable("Frequency", self.freq, 2)
+            self.addItemToTable("Phase", self.phi, 3)
+
+            self.plot = QtGui.QPushButton('Add', self)
+            self.plot.setStyleSheet("background-color:lightgrey")
+
+            grid.addWidget(self.plot)           
+
+            self.setLayout(grid)
+
+            self.plot.clicked.connect(self.buttonPressed)
+
+	def getColour(self):
+            return self.colours.currentText()
+  
+	def getGridLines(self):
+            return self.grid_lines.checkState() == QtCore.Qt.Checked
+
+	def getFreq(self):
+            return float(self.freq.text())
+
+	def getPhase(self):
+            return float(self.phi.text())
+
+	def buttonPressed(self):
+            self.plotSignal.emit()
+
+	def setTableRow(self, name, row):
+            text = QtGui.QTableWidgetItem(name)
+            text.setFlags(QtCore.Qt.ItemIsEnabled)
+            col = 0
+            self.table.setItem(row, col, text)
+
+     def addWidgetToTable(self, name, widget, row):
+            self.setTableRow(name, row)
+            col = 1
+            self.table.setCellWidget(row, col, widget)
+
+     def addItemToTable(self, name, widget, row):
+            self.setTableRow(name, row)
+            col = 1
+            self.table.setItem(row, col, widget)
+
+Presenter
+#########
+
+.. code-block:: python
+
+    from __future__ import (absolute_import ,division, print_function)
+
+    class Presenter(object):
+
+        # pass the view and model into the presenter
+	def __init__(self, view):
+            self.view = view
+
+	    self.view.plotSignal.connect(self.updatePlot)             
+       
+	# handle signals 
+	def updatePlot(self):
+            print("The table settings are:")
+	    print("   colour     : " + str(self.view.getColour()))
+	    print("   Grid lines : " + str(self.view.getGridLines()))
+	    print("   Frequency  : " + str(self.view.getFreq()))
+	    print("   Phase      : " + str(self.view.getPhase()))
+
+Main module
+###########
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+
+    import view
+    import presenter
+
+
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self, parent=None):
+            super(demo,self).__init__(parent)
+
+            self.window = QtGui.QMainWindow()
+            my_view = view.view()
+            self.presenter = presenter.Presenter(my_view)
+            # set the view for the main window
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+	def qapp():
+            if QtGui.QApplication.instance():
+                _app = QtGui.QApplication.instance()
+	    else:
+		_app = QtGui.QApplication(sys.argv)
+	    return _app
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
diff --git a/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5a6beb71c3f33e6b276219c6ac27c7f922488fa6
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst
@@ -0,0 +1,123 @@
+================================
+Receiving a signal from the view
+================================
+
+In the `Add Button <AddButton.html>`_ section we had the response to a button press
+within the View. In practice this is not a good implementation. If the
+response was more complicated then it would be difficult to maintain
+the View as it would become extremely long. Furthermore creating the
+look of the GUI is fairly simple and any logic/responses should be
+contained within the Presenter.
+
+In this section we will make a simple Presenter for when a button is
+pressed. First we will start with the View:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+
+
+    class view(QtGui.QWidget):
+
+        doSomethingSignal = QtCore.pyqtSignal()
+
+	def __init__(self, parent=None):
+            super(view, self).__init__(parent)
+
+            self.button = QtGui.QPushButton('Hi', self)
+            self.button.setStyleSheet("background-color:lightgrey")
+            # connect button to signal
+            self.button.clicked.connect(self.btn_click)
+
+            self.label = QtGui.QLabel()
+            self.label.setText("Button")
+
+            # add widgets to layout
+            self.sub_layout = QtGui.QHBoxLayout()
+            self.sub_layout.addWidget(self.label)            
+            self.sub_layout.addWidget(self.button)
+ 
+            grid = QtGui.QVBoxLayout(self)
+            grid.addLayout(self.sub_layout)
+            # set the layout for the view widget
+            self.setLayout(grid)
+ 
+	#send signals
+	def btn_click(self):
+            print ("hellow from view")
+	    self.doSomethingSignal.emit()
+
+The above code has two new additions. The first is the creation of a
+custom signal on line eight. It is also possible to pass objects with
+the signals. The second addition is that ``btn_click`` now emits the
+custom signal and will be caught by the Presenter.
+
+The Presenter is initialised with the View and must be a member of the
+Presenter class. It is therefore possible to change the View by
+passing a different one to the presenter. For example you may want to
+have the widgets in a grid or in a table. The Presenter connects the
+custom signal from the View to its own function (``handleButton``).
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    class Presenter(object):
+
+        # pass the view and model into the presenter
+	def __init__(self, view):
+            self.view = view
+
+	    self.view.doSomethingSignal.connect(self.handleButton)             
+       
+	# handle signals 
+	def handleButton(self):
+            print("hello world, from the presenter")
+
+The main is now:
+
+.. code-block:: python
+
+    from __future__ import (absolute_import, division, print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+    import view
+    import presenter
+
+
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self, parent=None):
+            super(demo, self).__init__(parent)
+
+            self.window = QtGui.QMainWindow()
+            my_view = view.view(self)
+            self.my_presenter = presenter.Presenter(my_view)
+            # set the view for the main window
+
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+	def qapp():
+            if QtGui.QApplication.instance():
+                _app = QtGui.QApplication.instance()
+	    else:
+		_app = QtGui.QApplication(sys.argv)
+	    return _app
+
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
+
+The View and Presenter are both created, but only the Presenter has to
+be a member of the demo class. The View is created to be passed to the
+Presenter and the View could easily be replaced.
diff --git a/dev-docs/source/MVPTutorial/Tables.rst b/dev-docs/source/MVPTutorial/Tables.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d496434b975365fe09dfdc5597a6283ca2284f8a
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/Tables.rst
@@ -0,0 +1,49 @@
+======
+Tables
+======
+
+Tables are useful way to display a set of related options to a
+user. To add a table widget to a GUI the following lines need to be
+added to the ``__init__`` function of the View:
+
+.. code-block:: python
+
+    self.table = QtGui.QTableWidget(self)
+    self.table.setRowCount(2)
+    self.table.setColumnCount(2)
+    grid.addWidget(self.table)
+
+The first line creates the widget. The second and third lines
+determine the size of the table. The fourth line adds it to the
+layout.
+
+To add (non-editable) labels to the table the following code is needed:
+
+.. code-block:: python
+
+    text = QtGui.QTableWidgetItem(("test"))
+    text.setFlags(QtCore.Qt.ItemIsEnabled)
+    row = 0
+    col = 0
+    self.table.setItem(row, col, text)
+
+    row = 1
+    text2 = QtGui.QTableWidgetItem(("another test"))
+    text2.setFlags(QtCore.Qt.ItemIsEnabled)
+    self.table.setItem(row, col, text2)
+
+    row = 0
+    col = 1
+    self.table.setCellWidget(row, col, self.combo)
+    row = 1
+    self.table.setCellWidget(row, col, self.spin)
+
+The first line creates a widget with the label ``test`` and the second
+flag ensures that a user cannot edit the value. The label is added to
+the table with the ``setItem`` function.
+
+A useful feature of tables is that they can contain a widget within
+one of the cells. The last five lines of the above code adds a
+ComboBox and spin box to the table. It is important to note that the
+widgets will now only appear within the table.
+
diff --git a/dev-docs/source/MVPTutorial/ViewExercise1.rst b/dev-docs/source/MVPTutorial/ViewExercise1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d2311e122f03b45fea871d6b5d3eeab735c6de31
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ViewExercise1.rst
@@ -0,0 +1,23 @@
+===============
+View Exercise 1
+===============
+
+A GUI should help a user to easily manipulate the behaviour of the
+code (by changing variables etc.). For example consider creating a
+plot of a sine wave. In this exercise you will create a view which
+contains the options for manipulating the plot.
+
+The GUI should contain a single table and a button for updating the
+plot. The table should include options for:
+
+- Setting the line colour (red, blue, green)
+- Setting the grid lines
+- Entering a frequency
+- Entering a phase shift
+
+The previous sections are not an exhaustive list of possible widgets.
+
+The pages `Matplotlib and MVP <Matplotlib.html>`_ and `MultipleView
+<MultipleViews.html>`_ will be useful for the exercise.
+
+The solution can be found `here <ViewExercise1Solution.html>`_.
diff --git a/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cc17fdfcdf3fe37e224e206f2951e23ae66a822a
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst
@@ -0,0 +1,112 @@
+========================
+View Exercise 1 Solution
+========================
+
+main.py
+#######
+
+.. code-block:: python
+
+    from __future__ import (absolute_import,division,print_function)
+
+    import PyQt4.QtGui as QtGui 
+    import PyQt4.QtCore as QtCore
+
+    import sys
+
+    import view
+
+    """
+    A wrapper class for setting the main window
+    """
+    class demo(QtGui.QMainWindow):
+        def __init__(self,parent=None):
+            super(demo,self).__init__(parent)
+
+            self.window = QtGui.QMainWindow()
+            my_view = view.view()
+
+            # set the view for the main window
+            self.setCentralWidget(my_view)
+            self.setWindowTitle("view tutorial")
+
+	def qapp():
+            if QtGui.QApplication.instance():
+                _app = QtGui.QApplication.instance()
+	    else:
+		_app = QtGui.QApplication(sys.argv)
+	    return _app
+
+    app = qapp()
+    window = demo()
+    window.show()
+    app.exec_()
+
+view.py
+#######
+
+.. code-block:: python
+
+    from __future__ import (absolute_import,division,print_function)
+    import PyQt4.QtGui as QtGui
+    import PyQt4.QtCore as QtCore
+
+
+    class view(QtGui.QWidget):
+
+        def __init__(self, parent=None):
+            super(view, self).__init__(parent)
+
+            grid = QtGui.QVBoxLayout(self)
+
+            self.table = QtGui.QTableWidget(self)
+            self.table.setRowCount(4)
+            self.table.setColumnCount(2)
+            grid.addWidget(self.table)           
+
+            self.colours = QtGui.QComboBox()
+            options = ["Blue", "Green", "Red"]
+            self.colours.addItems(options)
+
+            self.grid_lines = QtGui.QTableWidgetItem()
+            self.grid_lines.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
+            self.grid_lines.setCheckState(QtCore.Qt.Unchecked)
+            self.addItemToTable("Show grid lines", self.grid_lines, 1)
+
+            self.freq = QtGui.QTableWidgetItem("1.0")
+            self.phi = QtGui.QTableWidgetItem("0.0")
+
+            self.addWidgetToTable("Colour", self.colours, 0)
+            self.addItemToTable("Frequency", self.freq, 2)
+            self.addItemToTable("Phase", self.phi, 3)
+
+            self.plot = QtGui.QPushButton('Add', self)
+            self.plot.setStyleSheet("background-color:lightgrey")
+
+            grid.addWidget(self.plot)           
+
+            self.setLayout(grid)
+
+     def setTableRow(self, name, row):
+            text = QtGui.QTableWidgetItem(name)
+            text.setFlags(QtCore.Qt.ItemIsEnabled)
+            col = 0
+            self.table.setItem(row, col, text)
+
+     def addWidgetToTable(self, name, widget, row):
+            self.setTableRow(name,row)
+            col = 1
+            self.table.setCellWidget(row, col, widget)
+
+     def addItemToTable(self, name, widget, row):
+            self.setTableRow(name, row)
+            col = 1
+            self.table.setItem(row, col, widget)
+
+In the above code the following functions have been added to prevent
+repetition of code:
+
+- ``setTableRow`` sets the label for the table row
+- ``addWidgetToTable`` adds a widget to the table
+- ``addItemToTable`` adds an item to the table (needed because the
+  frequency and phase are items and not widgets)
diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a9fcb3795dad870ab39fa9168dad62583bd89919
--- /dev/null
+++ b/dev-docs/source/MVPTutorial/index.rst
@@ -0,0 +1,39 @@
+============
+MVP Tutorial
+============
+
+The following tutorial introduces how to create a Graphical User
+Interface (GUI) using PyQt. Some knowledge of Python is assumed.
+
+The concepts carry over into Qt in C++.
+
+Duration: 6 hours as a hands-on course with exercises. 
+
+.. toctree::
+   :maxdepth: 1
+
+   Introduction
+   AddButton
+   AddLabel
+   Layouts
+   AddLineEdit
+   AddComboBox
+   AddSpinBox
+   Tables
+   ViewExercise1
+   Matplotlib
+   MultipleViews
+   ViewExercise1Solution
+   ReceivingSignalFromView
+   ExtractInfoFromView
+   PresenterExercise
+   PresenterExerciseSolution
+   Mocking
+   MockingExercise
+   MockingExerciseSolution
+   Model
+   ModelExercise
+   ModelExerciseSolution
+   CompleteGUI
+   CalculatorExample/index
+
diff --git a/dev-docs/source/MultiThreadingInAlgorithms.rst b/dev-docs/source/MultiThreadingInAlgorithms.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ec9d6ed5b4a551517b5ca670cd42cf8a315ac871
--- /dev/null
+++ b/dev-docs/source/MultiThreadingInAlgorithms.rst
@@ -0,0 +1,65 @@
+============================
+Multithreading in Algorithms
+============================
+
+Mantid uses `OpenMP <http://openmp.org/wp/about-openmp/>`__ to improve
+performance within algorithms by parallelizing ``for`` loops. A tutorial
+devoted to the technology can be found `here <https://computing.llnl.gov/tutorials/openMP/>`__.
+
+Access to the OpenMP API is via a set of macros defined in
+`MultiThreading.h <https://github.com/mantidproject/mantid/blob/master/Framework/Kernel/inc/MantidKernel/MultiThreaded.h>`__.
+This accomplishes seamless fall-back to single-threaded behaviour for
+compilers that don't have OpenMP available, as well as providing
+protection against multithreading when non-thread-safe workspaces are in use.
+
+The canonical way to use OpenMP in an algorithm loop (typically
+one over the spectra in a workspace) is as follows:
+
+.. code:: cpp
+
+     PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
+     for (int i = 0; i < numSpec; ++i)
+     {
+       PARALLEL_START_INTERUPT_REGION
+
+       // .... algorithm code ....
+
+       PARALLEL_END_INTERUPT_REGION
+     }
+     PARALLEL_CHECK_INTERUPT_REGION
+
+
+The main work is in the first statement, which contains the
+instruction invoking OpenMP, but only if the workspaces given are
+thread-safe. Analogous macros are available for zero, 2 or 3 workspaces.
+Any workspace that is accessed within the loop should be included. There
+is then also a set of slightly verbose interrupt instructions, which
+prevent exceptions escaping from a parallel region (which would
+otherwise cause program termination) - this includes dealing with
+algorithm cancellation.
+
+Ensuring thread-safety
+----------------------
+
+The first rule is this: **Don't write to shared variables.** Or, if you
+do, protect the write with PARALLEL\_CRITICAL or PARALLEL\_ATOMIC calls.
+Note that a write to a workspace data spectrum selected by the loop
+index is not typically a shared write (though see below).
+
+One gotcha comes from the use of copy-on-write pointers to store the
+workspace data. Here's an example:
+
+.. code:: cpp
+
+   // Get references to the x data
+   const auto& xIn = inputWS->x(i);
+   auto& xOut = outputWS->mutableX(i);
+
+This can cause problems in the case where the input and output
+workspaces are the same. Although the call to ``outputWS->x()`` to get a
+reference to the output data may look innocuous, in the case where
+different spectra are pointing to the same underlying data array this
+call will cause the array to be copied, which will invalidate the
+reference obtained to the input data in the previous line. The solution
+is to make sure the non-const calls come before the const ones (in this
+case by reversing the two lines).
diff --git a/dev-docs/source/PatchReleaseChecklist.rst b/dev-docs/source/PatchReleaseChecklist.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b53eb179fe5470e5c7bfd6d4193b1a3d67883205
--- /dev/null
+++ b/dev-docs/source/PatchReleaseChecklist.rst
@@ -0,0 +1,158 @@
+.. _PatchReleaseChecklist:
+
+=======================
+Patch Release Checklist
+=======================
+
+.. contents::
+  :local:
+
+These are the steps involved in performing a Mantid patch release. To
+perform a full release look see :ref:`ReleaseChecklist`.
+
+Request
+#######
+
+*  Anyone may request a patch release, but that request must be intially
+   approved by Project manager (Nick) or one of the team leaders (Pete
+   or Mattieu).
+
+Authorisation
+#############
+
+*  The Project Manager and Team leaders must meet to authorise the patch
+   release.
+*  During the meeting other high value, low impact changes may be
+   considered for inclusion for the release. Any that are to be included
+   must be added to the patch release notes.
+*  The Project Manager will create a new milestone in github, and all
+   tickets to be included must be moved to that milestone.
+*  A developer will be nominated to be the main reviewer and compiler of
+   the patch.
+
+Development
+###########
+
+The patch release will be prepared based off the branch used to
+construct to most recent major point release, e.g. ``release-v3.9``
+would be used for any ``3.9.x`` patches. Changes for the patch should be made using the standard GitHub
+workflow for merging code with ``master``. The issue and pull request should then have the ``PatchCandidate`` label applied to them. These
+commits will then be cherry picked from ``master`` on to the release branch.
+
+Release Branch
+##############
+
+The release branch will currently have its version fixed to exact
+version of the last major/patch release. It is not a requirement but
+advised to unfix the patch number while the patch is being compiled.
+This prevents the nightly builds from generating a collection of packages that have
+exactly the same version. The patch number can be unfixed by commenting the line in
+https://www.github.com/mantidproject/mantid/blob/release-vX.Y/buildconfig/CMake/VersionNumber.cmake#L9, where
+``X.Y`` should be replace with the appropriate numbers.
+
+Release Notes
+-------------
+
+Once the patch version has been unfixed the main reviewer should
+create a skeleton set of patch release notes on the release branch
+using the `python helper tool <https://www.github.com/mantidproject/mantid/blob/master/tools/release_generator/patch.py>`__.
+
+Cherry Picking & Code Review
+----------------------------
+
+It is the job of the main reviewer of the release to review each
+issue/pull request marked ``PatchCandiate`` and decide if the risks of
+the changes are low enough to include in a release that will not
+undergo full beta testing by scientists. If it is acceptable then on the release branch for each pull request:
+
+*  find the list of commit ``SHA1`` values in that pull request
+*  check if any of these commits has altered the release notes for the
+   next major release
+*  if not then pass all commits in the order oldest->newest to
+   ``git cherry-pick -x``
+*  if release notes were modified in a commit on their own then pass all
+   commits except this one in the order oldest->newest to
+   ``git cherry-pick -x``
+*  if a commit has a mixture of code/release note changes then:
+
+   *  pass the list of commits up to but not including this commit to
+      ``git cherry-pick -x``
+   *  now pass this single commit to ``git cherry-pick -x -n`` and it
+      will not make a commit. Remove the major release note changes and
+      commit ``git add``/``git commit``
+   *  if there are any remaining commits after this then pass them to
+      ``git cherry-pick -x`` as before.
+
+*  finally add a commit that updates the patch release notes with this
+   pull request link and description in the table.
+
+Once cherry picked the milestone of the original pull request should be
+updated to the patch milestone.
+
+Nightly Builds
+##############
+
+The `release pipeline <release-pipeline>`_ contains jobs
+that check for changes on the current release branch each night (00:00 GMT).
+Any detected changes will cause a clean build of the code followed by a run
+of the system tests. The Linux clean builds should have the `PACKAGE_SUFFIX` set
+to `nightly` while testing the patch.
+
+These jobs should be checked each morning to confirm that everything is green.
+
+Release Day
+###########
+
+On the day of release a few steps are required:
+
+* update the patch version:
+* navigate to
+  https://www.github.com/mantidproject/mantid/blob/release-X.Y./buildconfig/CMake/VersionNumber.cmake,
+  where ``X`` & ``Y`` are the major and minor release versions
+  respectively.
+* edit the ``VERSION_PATCH`` to the required number for the patch and
+  commit the result.
+* run a manual build of all of the OS jobs under {{
+  site.mantidreleasebuilds }} and when asked for a suffix use an empty
+  string
+* wait for the builds to finish (will take more than 1 cup of
+  tea/coffee/beverage of choice)
+
+While waiting for the builds create a new release on GitHub, using a tag
+of the form ``v.X.Y.Z`` and populate with information from the release
+notes (see a previous version of the format).
+
+Once the builds complete have the development team run unscripted
+testing on the packages generated by the clean release builds. In
+particular the issues intended to be fixed should be tested.
+
+Once the testing has passed:
+
+* Use the manual deploy job at `release pipeline <release-pipeline>`_ to deploy
+  packages and documentation to the public web.
+* The windows binary will **not** be deployed and must be signed by
+  someone at ISIS and uploaded to sourceforge manually
+* Put packages on GitHub
+* RHEL 7 only: Build the suffix-package ``mantidXY`` by running another
+  clean RHEL 7 build from the `release pipeline <release-pipeline>`_ but use the
+  suffix XY, where ``X`` is the major version and ``Y`` is the minor
+  version (currently used at SNS)
+* Have someone at the SNS follow the instructions
+  `here <http://www.mantidproject.org/Fermi_cluster_at_ORNL>`__ to
+  deploy an MPI version of the patch release.
+* Create new DOI using the scripts in the codebase and instructions on
+  :ref:`release checklist <ReleaseChecklist>`.
+* Send an email, including the text of the release notes, to the
+  following lists
+* ``mantid-announce@mantidproject.org``
+* ``mantid-developers@mantidproject.org``
+* ``nobugs@nobugsconference.org``
+* ``news@neutronsources.org``
+* ``neutron@neutronsources.org``
+* Add topic to the news page on the `forum <http://forum.mantidproject.org/>`__
+* Close the release milestone in github
+* Remove the patch candidate tag from pull requests (if not already done)
+
+.. Link definitions
+
+.. _release-pipeline: http://builds.mantidproject.org/view/Release%20Pipeline/
diff --git a/dev-docs/source/ProfilingWithValgrind.rst b/dev-docs/source/ProfilingWithValgrind.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d5e66f6621a95e757cce0fde21432c784f2cd755
--- /dev/null
+++ b/dev-docs/source/ProfilingWithValgrind.rst
@@ -0,0 +1,173 @@
+.. _ProfilingWithValgrind:
+
+Profiling with Valgrind
+=======================
+
+Summary
+-------
+
+Describes how to use the
+`callgrind <http://valgrind.org/docs/manual/cl-manual.html>`__ plugin to
+the `valgrind <http://valgrind.org/>`__ tool set to profile your code.
+
+*Note: Valgrind is a Linux only tool*
+
+Installation
+------------
+
+You will need to install both *valgrind* & the visualizer tool
+*kcachegrind* - both of which should be available in your distribution's
+repositories.
+
+Ubuntu
+~~~~~~
+
+::
+
+    >> apt-get install valgrind kcachegrind 
+
+Red Hat/Fedora
+~~~~~~~~~~~~~~
+
+::
+
+    >> yum install valgrind kcachegrind
+
+Preparation
+-----------
+
+To be most effective valgrind requires that debugging information be
+present in the binaries that are being instrumented, although a full
+debug build is not required. On gcc this means compiling with the *-g*
+flag. For Mantid the recommended setup is to use a separate build with
+the *CMAKE_BUILD_TYPE* set to *RelWithDebInfo*. This provides a good
+balance between performance and availability of debugging information.
+
+Running the Profiler
+--------------------
+
+The profiler can instrument the code in a number of different ways. Some
+of these will be described here. For more detail information see the
+`callgrind manual <http://valgrind.org/docs/manual/cl-manual.html>`__.
+
+During execution the callgrind tool creates many output file named
+*callgrind.output.pid.X*. For this reason it is recommended that each
+profile run be executed from within a separate directory, named with a
+description of the activity. This allows the separate profiled runs to
+be found more easily in the future.
+
+**Beware**: The code will execute many times (factors of 10) slower than
+when not profiling - this is just a consequence of how valgrind
+instruments the code.
+
+Profile a Whole Program Run
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the simplest mode of operation. Simply pass the program
+executable, along with any arguments to the valgrind executable:
+
+::
+
+    >> valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes <executable> [args...]
+
+Profile Selected Portions of the Code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For larger pieces of code it can be quite likely that you wish to
+profile only a selected portion of it. This is possible if you have a
+access to recompile the source code of the binaries to be instrumented
+as valgrind has a C api that can be used talk to the profiler. It uses a
+set of
+`macros <http://valgrind.org/docs/manual/cl-manual.html#cl-manual.clientrequests>`__
+to instruct the profiler what to do when it hits certain points of the
+code.
+
+As an example take a simple main function composed of several function
+calls:
+
+.. code:: cpp
+
+    int main()
+    {
+      foo1();
+      bar1();
+      foo2();
+      foo3();
+    }
+
+To profile only the call to ``bar1()`` then you would do the following
+to the code:
+
+.. code:: cpp
+
+    #include <valgrind/callgrind.h>
+
+    int main()
+    {
+      foo1();
+      CALLGRIND_START_INSTRUMENTATION;
+      CALLGRIND_TOGGLE_COLLECT;
+      bar1();
+      CALLGRIND_TOGGLE_COLLECT;
+      CALLGRIND_STOP_INSTRUMENTATION;
+      foo2();
+      foo3();
+    }
+
+After recompiling the code you would then run the profiler again but
+this time adding the *--instr-atstart=no --collect-atstart=no* flags,
+like so
+
+::
+
+    >> valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes --collect-atstart=no --instr-atstart=no <executable> [args...]
+
+The *--instru-at-start=no* is not strictly necessary but it will speed
+up the code up until the profiling point at the cost of the less
+accuracy about the cache usage. See
+`here <http://valgrind.org/docs/manual/cl-manual.html#opt.instr-atstart>`__
+more details.
+
+Visualisation
+-------------
+
+Callgrind produces a large amount of data about the program's execution.
+It is most easily understood using the *kcachegrind* GUI tool. This
+reads the information produced by callgrind and creates a list of
+function calls along with information on timings of each of the calls
+during the profiled run. If the source code is available it can also
+show the lines of code that relate to the functions being inspected.
+
+.. figure:: images/KCachegrind_MantidPlot.png
+   :alt: Example of KCachegrind display a profile of MantidPlot starting up and closing down
+
+   Example of KCachegrind display a profile of MantidPlot starting up
+   and closing down
+
+By default KCachegrind shows the number of instructions fetched within
+its displays. This can be changed using the drop-down box at the top
+right of the screen. The *Instruction Fetch* and *Cycle Estimation* are
+generally the most widely used and roughly correlate to the amount of
+time spent performing the displayed functions.
+
+Some of the key features display are:
+
+Flat Profile View
+~~~~~~~~~~~~~~~~~
+
+-  Incl. - Sum of itself + all child calls as a percentage of the whole.
+   Programs with little static allocation should have main() at 100%.
+   Units are those selected by the to-right drop-down
+-  Self - Exclusive count spent in the selected function. Units are
+   those selected by the to-right drop-down
+-  Called - Number of times the function was called.
+
+Function Call Detail
+~~~~~~~~~~~~~~~~~~~~
+
+Click on function in flat view to get more detail on the right.
+
+Displays details about the selected function call plus details about all
+child calls it made. The *call graph* tab at the bottom gives a nice
+graphical overview of the relative function cost.
+
diff --git a/dev-docs/source/Python3.rst b/dev-docs/source/Python3.rst
new file mode 100644
index 0000000000000000000000000000000000000000..55fc190b999744cd6a0383b834c8ba4689323200
--- /dev/null
+++ b/dev-docs/source/Python3.rst
@@ -0,0 +1,118 @@
+========
+Python 3
+========
+
+Python 2 has an `end-of-life date set for 2020 <http://legacy.python.org/dev/peps/pep-0373/>`_
+and now that most third-party packages support both 2 and 3 we are starting to think about a
+migration strategy for Mantid.
+
+.. contents::
+  :local:
+
+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.
+
+.. warning::
+   If any of these packages are installed via pip, this could cause conflicts.
+   Install as described here only.
+
+Supporting Python 2 and 3
+#########################
+
+Python 3 introduces many exciting new features. For a full description see the official Python 3
+changes document. For a shorter overview see
+`here <https://asmeurer.github.io/python3-presentation/slides.html#1>`__ or
+`here <http://python3porting.com/differences.html>`__.
+
+Some features of Python 3 have been backported to Python 2.x within the
+`__future__ <https://docs.python.org/2.7/library/__future__.html?highlight=future#module-__future__>`_
+module. These make it easier to write code that is compatible with both versions.
+
+This cheat sheet provides helpful examples of how to write code in a 2/3 compatible manner. Where an
+option is given to use either the `six <https://pythonhosted.org/six/>`_ or
+`future <https://pypi.python.org/pypi/future>`_ (not to be confused with ``__future__``!) modules
+then ``six`` is used.
+
+All new code should be written to be compatible with Python 2 & 3 and as a minimum the first import
+line of the module should be:
+
+.. code-block:: python
+
+   from __future__ import (absolute_import, division, print_function)
+
+It is quite common to also see ``unicode_literals`` in the above import list, however, when running
+under Python 2 ``Boost.Python`` will not automatically convert a Python ``str`` to C++ ``std::string``
+automatically if the string is unicode. When running with Python 3 ``Boost.Python`` will do this
+conversion automatically for unicode strings so this is in fact not a huge issue going forward.
+
+Migrating From Python 2 to 3
+############################
+
+One way to migrate a file from python 2 to 3 is as follows...
+
+.. warning::
+  | To perform the following procedure on windows:
+  | 1. Git Bash or similar will be required.
+  | 2. To run the ``2to3`` script you will need to start the command-prompt.bat in the build directory and run ``%PYTHONHOME%\Scripts\2to3``
+
+Run the following script to run the python 2 to 3 translation tool and rename the file to ``filename.py.bak``
+
+.. code-block:: sh
+
+   2to3 --no-diffs -w filename.py
+   mv filename.py{,.bak};
+
+
+Run **one** of the following commands to append the import statement listed above.
+
+.. code-block:: sh
+
+  awk '/(from|import)/ && !x {print "from __future__ import (absolute_import, division, print_function)\n"; x=1} 1' \
+      filename.py.bak > filename.py
+
+**or**
+
+.. code-block:: sh
+
+  sed -i '0,/^import\|from.*/s/^import\|from.*/from __future__ import (absolute_import, division, print_function)\n&/' filename.py
+
+Check each changed block,
+
+- If any change has replaced ``xrange`` with ``range`` then add ``from six.moves import range``
+  to the imports list
+- If any change has replaced ``ifilterfalse`` with ``filterfalse`` from ``itertools`` then replace a
+  statement like ``from itertools import filterfalse`` with ``from six.moves import filterfalse`` in the
+  imports list. There are more cases like this documented `here <https://pythonhosted.org/six/#module-six.moves>`_.
+- If any change has replaced ``for k, v in knights.iteritems()`` with ``for k, v in knights.items()``
+  then add ``from six import iteritems`` to the import list and update the replacement to
+  ``for k, v in iteritems(knights)``.
+
+In some cases like ``range``, pylint will complain about `Replacing builtin 'range'` or similar.
+Make sure to put the proper ignore statement on that line using ``#pylint: disable=redefined-builtin``.
+
+Check the code still runs as expected in Python 2.
+
+.. note::
+   ``2to3`` will try to keep the type of the objects the same. So, for example ``range(5)`` will
+   become ``list(range(5))``. This is not necessary if you use it just for iteration. Things like
+   ``for i in range(5)`` will work in both versions of Python, you don't need to transform it into a
+   list.
diff --git a/dev-docs/source/PythonVSCppAlgorithms.rst b/dev-docs/source/PythonVSCppAlgorithms.rst
new file mode 100644
index 0000000000000000000000000000000000000000..80993461f751c1366d9e5635f7d0d71bb2cc59e9
--- /dev/null
+++ b/dev-docs/source/PythonVSCppAlgorithms.rst
@@ -0,0 +1,79 @@
+.. _PythonVSCppAlgorithms:
+
+========================
+Python vs C++ Algorithms
+========================
+
+.. contents::
+  :local:
+
+Overview
+--------
+
+Mantid can be extended both with python and C++ algorithms as plug-ins. There are a number of considerations to take into account when deciding which language to choose.
+These are summarised in the table and discussed below. Generally, it is recommended to implement **atomic** operations in C++, and **workflows** in python.
+
+Algorithm Language Comparison
+-----------------------------
+
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| Consideration         | C++                                                                                                    | Python                                                                     |
++=======================+========================================================================================================+============================================================================+
+| **Execution Speed**   | Generally much faster (order of magnitude, and beyond), since compiled.                                | Generally slower. Numpy should be used wherever possible.                  |
+|                       | Lots of optimisations can be made. OpenMP parallelisation for trivial loops (e.g. loops over spectra). | Large loops should be avoided, especially the nested ones.                 |
+|                       |                                                                                                        | Provides no means for trivial parallelisation.                             |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **Creation**          | Generally slower and more complicated, but you do get the advantage of compile-time type checking.     | Generally easier and faster.                                               |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **Workflow**          | Large overhead when setting and getting the properties of child algorithms.                            | Very convenient and concise for workflows thanks to the python SimpleAPI.  |
+|                       | Can quickly grow cumbersome, if many child algorithms have to be run.                                  |                                                                            |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **Testability**       | Easy in C++                                                                                            | Easy in python                                                             |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **API Accessibility** | Full                                                                                                   | Some of the framework functionality is not exposed to python.              |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **User Readability**  | Users are not generally expected to understand C++ code.                                               | Better readability. Power users are expected to understand python code.    |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+| **User Modifiability**| Users can not change C++ algorithms, since they are shipped in the compiled form.                      | Users can play with python algorithms, since they are shipped as source.   |
+|                       |                                                                                                        | It is not advised, of course, do to so, but in case of a spurious result,  |
+|                       |                                                                                                        | they have the opportunity to play with the algorithm before contacting us. |
++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
+
+Multiple Possibilities in Mantid
+--------------------------------
+
+There are many ways to extend Mantid to add new features not present out-of-the-box.
+
+The easiest way to extend Mantid, and possibly the best starting place for any improvements, is a python script. Mantid provides a very high level of scriptable control, including plotting and visualisation as well as the execution of core routines. The scripting manual for Mantid provides an overview of the possibilities offered for scripting, including automatic generation via the graphical user interface for Mantid.
+
+:ref:`Algorithms <Algorithm>` and :ref:`workspaces <Workspace>` are core concepts in Mantid. Generally, an Algorithm does something based on input workspaces, either to create a new one from the results, or to modify the input in-place. One reason to create an Algorithm, is because you have a script containing a well-defined and useful procedure, that you would like to share with a wider audience. It usually requires a low amount of effort to adapt a python script into one or more Python Algorithms.
+
+Core Mantid Algorithms as well as some user defined Algorithms, are generally written in C++. There are a number of advantages to doing this (which are covered later), but also some serious disadvantages. When thinking about writing new functionality against Mantid, C++ does not need to be the default option.
+
+Should I Write a C++ Algorithm?
+-------------------------------
+The main reason to write algorithms in C++ is that you can often significantly reduce the run-time processing time over code written in Python. Looping over large volumes of data tends to be fastest in C++. Mantid also has facilities for running your Algorithm in a multi-threaded context when assembled in C++.
+
+Writing an algorithm in C++ gives you all the advantages associated with a compiled language including compile-time type checking. Some developers find this advantage significant enough to make writing C++ algorithms faster than Python equivalents.
+
+Writing clean Mantid Algorithm code in C++ is sometimes not a good idea. Here are some brief reasons why:
+
+For workflow Algorithms consisting mainly of child-algorithms execution, child-algorithm set-up in C++ can be long-winded and more fragile than Python.
+There are many different ways to do the same thing in C++, and therefore more ways to get it wrong.
+You are responsible for all the heap-allocated memory, as well as other resources you create.
+Our target platforms have different compilers, with different interpretations of the same C++ standard, this can make writing cross-platform code tricky.
+Compiler and linker outputs can be verbose, particularly in the presence of templated code.
+
+Should I Write a Python Algorithm?
+----------------------------------
+Python algorithms are generally easier to put together than those assembled in C++. Because python has a limited dictionary, the barriers to writing effective code are much lower. Furthermore, not all algorithms need to run at the speed of light. For Algorithms that are only fed small volumes of data from small instruments, the user will not notice the difference between it running in half a second in Python or a tenth of a second in C++.
+
+It's more natural to convert a python script into a python Algorithm than directly into a C++ algorithm. In many cases, the algorithm functionality is best assembled by procedural execution of existing algorithms. For this, the python API provides the best means of executing an algorithm in a single line, using well defined, named variables. An algorithm of this nature will take up only a few lines in Python and therefore be very easy to read and maintain.
+
+Python algorithms also benefit from automatic GUI creation when they are registered with Mantid, so they can be used equally well through the command line, or through MantidPlot graphically.
+
+Python algorithms are great for editing and re-registering. Users can tweak existing Python algorithms or generate their own, without the complication of setting up a build environment. They can also more easily be re-issued to fix particular issues than C++ algorithms.
+
+Note for Mantid Developers
+--------------------------
+Developers creating new algorithms in python must still generate unit tests for them. When an algorithm breaks, users do not care what language they are written in. The developer test suites allow you to create the same level of test coverage in python as you would in C++. Developers should also take care to ensure that the test exercises all of the code, as Python provides no compile-time type checking.
diff --git a/dev-docs/source/QtDesignerForPython.rst b/dev-docs/source/QtDesignerForPython.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1ff4b8845df66de76ccf6ba80a9bb5e21ee77587
--- /dev/null
+++ b/dev-docs/source/QtDesignerForPython.rst
@@ -0,0 +1,230 @@
+.. _QtDesignerForPython:
+
+======================
+Qt Designer for Python
+======================
+
+Motivation
+----------
+
+Code for setting up individual widgets and the layout of a view can
+become large and difficult to maintain by hand. It usually easier to
+edit such code using a drag and drop WYSIWYG (What You See Is What You
+Get) editor such as Qt Creator/Designer. However, doing so requires some
+additional actions at build time.
+
+Implementation
+--------------
+
+Qt Creator was not originally designed to work with Python, and it is
+therefore not possible to directly save or export the layout as a
+Python script. Instead you must first save the layout in a ``.ui``
+file and use the ``pyuic4`` tool to convert it to a python script.
+
+Integration With CMake
+----------------------
+
+Running this tool manually for each ui file in the project would
+quickly become infeasible. Fortunately it is easy to integrate this
+with the cmake build using the ``UiToPy`` function defined in
+``buildconfig/CMake/UiToPy.cmake``. This function takes a list of ui
+files and a name to be used for a cmake target. It will produce a
+target with the specified name, which, when built runs the ``pyuic4``
+command on each of the ``.ui`` files to generate a ``.py`` file with a
+``ui_`` prefix in the same directory.
+
+For example the following CMakeLists.txt:
+
+.. code:: cmake
+
+    include(UiToPy)
+    set(UI_FILES
+      sans_data_processor_window.ui
+      settings_diagnostic_tab.ui
+      masking_table.ui
+    )
+
+    UiToPy(UI_FILES CompileUISANSDataProcessorInterface)
+
+Produces a cmake target ``CompileUISANSDataProcessorInterface`` which
+when built runs::
+
+   pyuic4 sans_data_processor_window.ui -o ui_sans_data_processor_window.py
+   pyuic4 settings_diagnostic_tab.ui -o ui_settings_diagnostic_tab.py
+   pyuic4 masking_table.ui -o ui_masking_table.py
+
+The generated target also runs a script wrap_pyui.py which prepends
+``#pylint: skip-file`` to the top of the generated file.
+
+It is worth noting that for the main Mantid repository, in most cases
+``include(UiToPy)`` can be omitted since the majority of Python GUIs
+have their ``.ui`` files under the ``scripts/Interface/ui`` directory
+and so ``scripts/Interface/ui/CMakeLists.txt`` performs this include.
+
+Using the Generated Script
+--------------------------
+
+When following the MVP design pattern as described at
+:ref:`GuiDesignGuidelinesMVPIntro`, the generated file alone is not sufficient
+as a :ref:`GuiDesignGuidelinesMVPView`. Directly accessing the widgets and the
+signals defined on the view from the presenter moves the view
+implementation details into the presenter, which makes it harder to
+change the names and types of widgets used to display the
+information. Instead it is best to create a separate Python file which
+imports the generated one and adds a separate view class which
+inherits from the generated one.
+
+.. code:: python
+
+    import ui_add_runs_page # This imports the file generated by pyuic.
+
+    class AddRunsPage(QtGui.QWidget, ui_add_runs_page.Ui_AddRunsPage):
+       pass
+
+You can then add separate methods to the view for accessing and mutating
+the content of the widgets as well as add any necessary signals which
+form the interface to the view.
+
+.. code:: python
+
+    import ui_add_runs_page # This imports the file generated by pyuic.
+
+    class AddRunsPage(QtGui.QWidget, ui_add_runs_page.Ui_AddRunsPage):
+        outFileChanged = pyqtSignal()
+
+        def __init__(self, parent=None):
+            super(AddRunsPage, self).__init__(parent)
+            self.setupUi(self)
+            self._connect_signals()
+
+        def _connect_signals(self):
+            self.fileNameEdit.editingFinished.connect(self.outFileChanged)
+
+        def out_file_name(self):
+            return self.fileNameEdit.text().encode('utf-8')
+
+Keeping GUIs modular using Widgets
+##################################
+
+.. _motivation-1:
+
+Motivation
+----------
+
+When designing a GUI in QtCreator it is often too easy to end up with
+the entire interface in a single UI file. This can then lead to having a
+single presenter for the entire GUI and sometimes even a single model.
+This makes the UI harder to maintain as a whole and difficult to re-use,
+move and separate out individual sections.
+
+Instead when building a GUI it is sometimes better to separate parts of
+the interface into smaller views and presenters which form a hierarchy
+of widgets. For example the new SANS Run Summation page is in it's own
+UI file and uses two separate widgets - a ``RunSelectorWidget`` and a
+``SummationSettingsWidget``. Although these widgets are not currently
+used in any other interface, they are still isolated from the Run
+Summation tab and could easily be used in another interface should the
+need arise. The code is also better organised and more modular as a
+result of this clean separation.
+
+.. _implementation-1:
+
+Implementation
+--------------
+
+Assuming we start with QtCreator with .ui file open which contains a
+section of an interface which we wish to move to its own widget. We must
+start by creating a new .ui file
+
+1. Go to *File* > *New File Or Project* and select *Qt Designer Form*
+from the list of templates.
+
+.. image:: images/MVPPythonViews/NewForm.png
+
+2. Then select *Widget* from the list of form templates.
+
+.. image:: images/MVPPythonViews/SelectTemplate.png
+
+3. Enter the name for the file and save it to the location containing
+the corresponding CMakeLists.txt
+
+.. image:: images/MVPPythonViews/NewFileName.png
+
+4. Click *Next* and adjust any project management settings as you wish
+before clicking *Finish*.
+
+At this point you should have an empty Widget in the design area.
+
+.. image:: images/MVPPythonViews/SelectFile.png
+
+You can switch between the two ``.ui`` files using the menu in the top left.
+
+5. Next, copy the components you wish to move into the new widget and
+paste them into the new file.
+
+.. image:: images/MVPPythonViews/CopyFromMainUI.png
+
+.. image:: images/MVPPythonViews/PasteIntoWidget.png
+
+6. Make adjustments to the layout and resize behaviour of the widget as
+you see fit.
+
+.. image:: images/MVPPythonViews/AdjustWidgetLayout.png
+
+7. Add the following CMake snippet to your CMakeLists.txt, note that
+you may already have a target for generating the Python files in which
+case you can simply add your new ``.ui`` file to the list of existing
+``.ui`` files.
+
+.. code:: cmake
+
+    set(UI_FILES
+      my_widget.ui
+    )
+
+    UiToPy(UI_FILES CompileUIMyWidget)
+
+Test that this has worked by saving your ``.ui`` file and re-running
+the build, the output should contain a line similar to the following:
+
+``[1/1] Generating scripts/Interface/ui/sans/ui_my_widget.py``
+
+8. Add a separate python file containing the `View <GuiDesignGuidelinesMVPView>`__
+class which extends the generated one.
+
+.. code:: python
+
+    # my_widget.py
+    import ui_my_widget
+
+    class MyWidget(QtGui.QWidget, ui_add_runs_page.Ui_MyWidget):
+       pass
+
+9. Return to the original interface file, delete the components you
+copied across and replace them with a single *Widget* component found in
+the containers section.
+
+.. image:: images/MVPPythonViews/PreReplacedWidget.png
+
+.. image:: images/MVPPythonViews/PostReplacedWidget.png
+
+10. Right click on the newly created widget container and select
+*Promote To...*
+
+.. image:: images/MVPPythonViews/PromoteWidget.png
+
+11. For the *Promoted Class Name* field enter the name of the view
+class. If you are taking the advice given above, this should be the name
+of the class which inherits from the generated
+``ui_my_widget.Ui_MyWidget`` class.
+
+12. For the *Header File* field enter the fully qualified path of the
+python module which contains the class mentioned above.
+
+13. You can leave the *Global Include* box un-ticked. Finish the
+promotion by pressing *Add* and then *Promote*.
+
+.. image:: images/MVPPythonViews/CompletePromote.png
+
+14. Save your ui files, re-run and launch the build to see the finished
+result.
diff --git a/dev-docs/source/ReleaseChecklist.rst b/dev-docs/source/ReleaseChecklist.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ecc77dd277333a1bbf022995dceb8b17eadd3d55
--- /dev/null
+++ b/dev-docs/source/ReleaseChecklist.rst
@@ -0,0 +1,213 @@
+.. _ReleaseChecklist:
+
+=================
+Release Checklist
+=================
+
+.. contents::
+  :local:
+
+These are the steps involved in performing a full Mantid release. To
+request or perform a patch release look at the
+:ref:`patch release checklist <PatchReleaseChecklist>`.
+
+Timeline
+########
+
+Releases are normally planned to occur on a Friday, therefore this
+page will be refer to days assuming that is correct, if the final
+release day is not planned to be Friday then the names of the days
+will have to be changed
+
+Friday, Release-4 weeks
+#######################
+
+**Task Priorities**: Development, Testing, Documentation.
+
+*  Send an email to Mantid-developers reminding developers of the
+   impending release and stating that they have only 5 days left before
+   the code freeze.
+*  Send an email to beta test users explaining the dates for the
+   testing, and stating they will have more detail on the start of the
+   first day.
+*  Invite staff to the release presentation
+
+Friday, Release-3 weeks
+#######################
+
+**Task Priorities**: Final Development until code freeze, Testing,
+Documentation.
+
+Code Freeze
+-----------
+
+*  Send an email to Mantid-developers asking everyone to ensure they
+   have closed their tickets, stating the code freeze is in place, and
+   warning developers that non-blocker tickets will be moved from this
+   release on Monday.
+*  Final Testing afternoon, attempt to drive the pull requests for this
+   milestone down to 0.
+*  Collect all of the completed, fixed tickets for that iteration.
+*  Parse through the list and short list all of the "major points" that
+   may be important to the users.
+
+Monday, Release-2 weeks & 4 days
+################################
+
+**Task Priorities**: Blocker bug fixes, Testing, Release Notes.
+
+Unscripted and Final Testing (technical tasks)
+----------------------------------------------
+
+*  Ensure the
+   `master build and system
+   test <http://builds.mantidproject.org/view/Master%20Builds/>`__
+   jobs have passed for all build environments for this release.
+*  Complete any ticket testing remaining from Friday
+*  Run
+   `open-release-testing <http://builds.mantidproject.org/view/All/job/open-release-testing/>`__
+   to create the release branch and prepare build jobs
+*  Enable and update the release branch name for
+   `merge\_release\_into\_master <http://builds.mantidproject.org/view/All/job/merge_release_into_master/>`__
+*  Check state of all open pull requests for this milestone and update
+   the base branch to the new release branch accordingly.
+*  Create a skeleton set of release notes for the next version
+*  Perform unscripted testing following the instructions described
+   `here <https://www.mantidproject.org/Unscripted_Manual_Testing>`__.
+
+Tuesday, Release- 2 weeks & 3 days
+##################################
+
+**Task Priorities**: Blocker bug fixes, Testing, Release Presentation
+preparation, Release Notes, Next release development.
+
+Beta Test Open
+--------------
+
+*  Before sending an email to users, ensure that the Usage data .zip
+   file containing usage data is up-to-date. This is done by downloading
+   the current .zip from sourceforge, adding any missing files, and
+   resending it.
+*  Send an email to beta test users explaining where to download the
+   installers and how to report issues.
+*  Developers to arrange to meet with their beta testers.
+
+Monday, Release- 4 days
+#######################
+
+**Task Priorities**: Blocker bug fixes, Testing, Release Presentation
+preparation, Release Notes, Next release development.
+
+Beta Test Closes
+----------------
+
+*  At the end of the day email the beta test users thanking them.
+
+Wednesday, Release-2 days
+#########################
+
+**Task Priorities**: Blocker bug fixes, Testing, Release Notes, Next
+release development.
+
+Thursday, Release-1 day
+-----------------------
+
+**Task Priorities**: Blocker bug fixes, Testing, Release Notes, Next
+release development.
+
+Final Code Changes
+------------------
+
+* This is the final day for code changes to the build for blocker
+  tickets
+
+Friday, Release day
+###################
+
+'''Task Priorities''': Blocker bug fixes, Testing, Release Notes, Next
+release development.
+
+Release (technical tasks)
+-------------------------
+
+Once the unscripted testing has passed:
+
+* Check the release notes and remove the "Under Construction" paragraph
+  on the main index page.
+* Disable release deploy jobs by executing
+  `close-release-testing <http://builds.mantidproject.org/view/All/job/close-release-testing>`__
+  job.
+* On the ``release-vX.Y`` branch, update major & minor versions
+  accordingly in ``buildconfig/CMake/VersionNumber.cmake``. Also
+  uncomment ``VERSION_PATCH`` and set it to ``0``.
+* Merge ``release`` branch back to ``master``
+* Comment out patch number on ``master`` branch
+* Draft a `new
+  release <https://github.com/mantidproject/mantid/releases>`__ on
+  GitHub. The new tag should be created based of the release branch in
+  the form ``vX.Y.Z``
+* Hit build on `release kit
+  builds <http://builds.mantidproject.org/view/Release%20Pipeline/>`__
+  and set the ``PACKAGE_SUFFIX`` parameter to an empty string
+* After all of the packages have been smoke tested build the
+  ``release_deploy`` job to put the packages (not windows) on
+  Sourceforge.
+* Kick off the build for ``mantidXY`` on RHEL7 for SNS:
+  http://builds.mantidproject.org/job/release_clean-rhel7/ with suffix
+  ``XY``
+* Make sure someone at ISIS signs the Windows binary and uploads this
+  manually to Sourceforge
+* Set the default package for each OS to the new version
+* Upload packages to GitHub once they are ready and have been checked
+* Publish the page
+* Update the `download <http://download.mantidproject.org>`__ page,
+  following the instructions
+  `here <https://github.com/mantidproject/download.mantidproject.org>`__
+* Publish the draft release on GitHub (this will create the tag too).
+
+Finalise
+========
+
+* Send an email, including the text of the release notes, to the
+  following lists
+* ``mantid-announce@mantidproject.org``
+* ``mantid-developers@mantidproject.org``
+* ``nobugs@nobugsconference.org``
+* ``news@neutronsources.org``
+* ``neutron@neutronsources.org``
+* Create a new item on the forum news
+* Close the release milestone in the issue tracker
+
+Generate DOI (technical tasks)
+------------------------------
+
+This requires that a tag has been created for this release, this is done
+automatically if a new
+`release <https://github.com/mantidproject/mantid/releases>`__ has been
+created on GitHub.
+
+* Make sure that you have updated your local copy of git to grab the
+  new tag. ``git fetch -p``
+* If the script below fails you may need to update the authors list and
+  push the updates to master. Look for ``authors.py`` in the
+  ``tools/DOI`` directory. It does not matter that these are not on the
+  release branch.
+
+``python tools/DOI/doi.py  --username=_____  X.Y.Z``
+
+* Major/minor/patch version numbers must be supplied, as well as a
+  username which can be found in the `Protected
+  Information <http://www.mantidproject.org/Protected_Information>`__
+  section. The script will prompt for the password. Note that only
+  MediaWiki admins have access rights to the page.
+* A corresponding version tag must be present in the Mantid repo.
+
+Next release plan
+-----------------
+
+* Prepare the Next release plan.
+* Gather user descriptions of priority tickets from developers for the
+  next release.
+* Decide on priority maintenance tasks for the next release.
+* Inject Items from the Facility scientific computing strategic plans.
+* Compile to a document and release
diff --git a/dev-docs/source/RemoteJobSubmissionAPI.rst b/dev-docs/source/RemoteJobSubmissionAPI.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c4eaa7d7d66f4989c73f5b90b501b7f76fbfa26f
--- /dev/null
+++ b/dev-docs/source/RemoteJobSubmissionAPI.rst
@@ -0,0 +1,389 @@
+.. _RemoteJobSubmissionAPI:
+
+=========================
+Remote Job Submission API
+=========================
+
+.. contents::
+  :local:
+
+This document describes the web service API that the Mantid Framework uses to submit algorithms to remote compute
+resources. The API is designed to be flexible enough that it can be implemented for just about any compute resource at
+nearly any facility. This document should hopefully contain enough detail for programmers & sysadmins at other
+facilities to implement the API and allow Mantid users to submit jobs to compute resources at those other facilities.
+
+A 'compute resource' may be any computer capable of running the Mantid framework. This could range from a single large
+server, to some sort of Beowulf cluster to machines with specialized hardware such as GPU's or Intel MIC's. The idea is
+that the 'compute resource' will be used to execute tasks that are impractical to run on the user's local workstation.
+
+The reference implementation is the Fermi cluster at the Oak Ridge Spallation Neutron Source (fermi.ornl.gov). Specific
+details of the implementation on Fermi are used as examples throughout this document.
+
+Basic Requirements For API Implementations
+==========================================
+
+The Mantid framework has certain expectations for the API and it's the responsibility of API implementations to meet
+these expectations:
+
+#. The API provides a mechanism for executing python scripts in an environment that includes the Mantid framework. (ie:
+   one where "from mantid.simpleapi import \*" works) (Note: exactly \*how\* this happens is purposely left up to the
+   implementor.)
+#. Scripts are executed in a batch environment - interactive scripts are not supported and scripts must be able to run
+   without input from the user.
+#. No mechanism for passing command line parameters to the python scripts is provided. Things like experiment and run
+   numbers must be hard-coded into the script. (We consider this acceptable because we expect a new script to be
+   auto-generated by MantidPlot for each job.)
+#. Scripts can write output to what is the current working directory when the script starts. These output files will be
+   available for download back to MantidPlot (or wherever) once the script finishes.
+#. Files that were uploaded prior to running the script will be available from the script's working directory.
+#. Authentication is used to prevent individual users from interfering with others' jobs (or even reading their files)
+#. Data from the various API calls is returned in two ways: the standard HTTP status codes (200, 404, 500, etc...) and
+   JSON text in the body. (Note: There's no HTML markup in the output.) In the case of error status codes, the JSON
+   output will contain a field called 'error_msg' who's value is a string describing the error.
+#. Clients should assume that all parts of the URL - including query parameters - are case sensitive. However, servers
+   don't \*have\* to accept URL's with improper case, but may if it makes the code simpler.
+
+Versioning
+==========
+
+A quick Google search shows that versioning web API's is tricky. The technique employed here will be to use a major
+version plus optional extensions.
+
+Between major versions there are no guarantees of backwards or forwards compatibility. Changing the major version is
+essentially starting over from scratch with a clean slate. The major version starts at 1 and will hopefully never
+change.
+
+Backwards-compatible changes are handled by means of optional extensions.
+
+A server must implement all of the functions defined in the base level of the version and a client may assume those
+functions exist. A server is NOT required to implement the extensions (they're optional) and a client may query the
+server to discover which extensions are implemented. (Note that what the server returns is really just a name. It's up
+to the client and server implementers to agree on exactly what that name means and then document it - presumably here in
+this API doc.)
+
+Backwards-incompatible changes to the API are not allowed. That includes the URL itself, the GET or POST variables it
+expects and the JSON that it outputs. If changes are needed, they can be handled through the extension mechanism. For
+example, more GET or POST variables could be accepted by the server, so long as they are not required. An extension
+should be created (and documented here) so that a client may query the server about whether it supports the new
+variables.
+
+Old GET or POST variables cannot be deleted however. This would break clients that expect to use them. If there's a case
+where old varibles no longer make sense, then a completely new URL should be created (and again, documented as an
+extension).
+
+Similar rules apply to the JSON data returned by the API. Extra fields can be added to the JSON returned by a URL, but
+original fields may not be removed.
+
+It's worth noting that it is possible for extensions to be mutually exclusive.
+
+Authentication
+==============
+
+The initial API uses HTTP Basic-Auth name/password combo for authentication. (Other methods may be added via API
+extensions as described above.) Upon successful authentication, a session cookie is created. All other URL's require
+this session cookie.
+
+Because the Basic-Auth scheme does not encrypt the password when it is sent to the server, the use of the HTTPS protocol
+is **STRONGLY** encouraged.
+
+Note that HTTP Basic-Auth is simply the mechanism for passing a username/password combo to the web service. Exactly how
+the web service uses that combo to authenticate (and authorize) a user is not specified by the API. Individual
+implementations are free to do what they like. (For example, the implementation on Fermi checks the username & password
+against an LDAP server.)
+
+Transactions
+============
+
+The API details below mention starting & stopping transactions. It should be noted that in this context, the word
+transaction doesn't really have anything to do with databases. In this context, transactions are a mechanism for the web
+service to associate files with specific jobs. Multiple jobs may be submitted under a given transaction.
+
+Note that the API doesn't specify how this association occurs. That is a detail left up to the individual
+implementation. However, remember the points in the Basic Requirements section above about scripts reading from and
+writing to their current working directory while not allowing other users to see or modify their files. That implies
+that each job will store files in its own directory and will execute scripts from that directory. (This is, in fact, how
+the implementation on Fermi works.)
+
+A user must start a transaction after authenticating, but before transferring files or submitting job scripts. When the
+user's job (or jobs) has finished and the user no longer needs the files associated with the transaction, he or she
+should end the transaction. This will allow the web service to delete the files and recover the disk space.
+
+A Note About File Uploads
+=========================
+
+It is generally assumed that the input files for the submitted python scripts are already available on the compute
+resource (presumably via some kind of network filesystem). Thus, although the API allows for file uploads, this is
+really intended for relatively small support files that a particular script might need. The HTTP protocol really isn't
+intended or suitable for transferring the sort of multi-gigabyte files that are likely to be the inputs for these python
+scripts.
+
+API v1 URL's
+============
+
+General notes:
+
+-  All URL's expect GET requests unless otherwise noted.
+-  The session cookie returned by the authentication URL is required by all other URL's (except for the info URL)
+-  Success is indicated by an HTTP status code in the 200 range. (Typically, 200, but in some cases 201.) Errors are
+   indicated with error codes in the 400 and 500 range.
+-  In the case of errors, the JSON output will include a field named "Err_Msg" whose value is a text string describing
+   the particular error.
+
+
+Information
+-----------
+
++--------------------------------+-------------------------------------------------------------------------------------+
+| Description                    | Returns information about the server including the API version and supported        |
+|                                | extensions.                                                                         |
++--------------------------------+-------------------------------------------------------------------------------------+
+| URL                            | <base_url>/info                                                                     |
++--------------------------------+-------------------------------------------------------------------------------------+
+| Query Parameters               | None                                                                                |
++--------------------------------+-------------------------------------------------------------------------------------+
+| JSON Output                    | API_Version : <integer> API_Extensions : [<extension_1>, <extensions_2>, .... ]     |
+|                                | Implementation_Specific_Post_Variables : [ <variable_1>, <variable_2>, .... ]       |
++--------------------------------+-------------------------------------------------------------------------------------+
+| Notes                          | May be called without first authenticating. The                                     |
+|                                | 'Implementation_Specific_Submit_Variables' field lists the particular POST          |
+|                                | variables that this implementation requires when submitting a job. See the          |
+|                                | 'Job Submission <#Job_Submission>`__ URL.                                           |
++--------------------------------+-------------------------------------------------------------------------------------+
+
+Authentication
+--------------
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Authenticate to the web service.                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/authenticate                                   |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | Username and password are passed in using HTTP Basic      |
+|                                                           | Authentication Returns a session cookie which must be     |
+|                                                           | passed to the other URL's                                 |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+Transactions
+------------
+
+This URL has two forms: one to start a new transaction and the other to end an existing transaction.
+
++-------------------------------------------------+--------------------------------------------------------------------+
+| Description                                     | Start a new transaction                                            |
++-------------------------------------------------+--------------------------------------------------------------------+
+| URL                                             | <base_url>/transaction                                             |
++-------------------------------------------------+--------------------------------------------------------------------+
+| Query Parameters                                | Action=Start                                                       |
++-------------------------------------------------+--------------------------------------------------------------------+
+| JSON Output                                     | TransID : <string>                                                 |
++-------------------------------------------------+--------------------------------------------------------------------+
+| Notes                                           |                                                                    |
++-------------------------------------------------+--------------------------------------------------------------------+
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | End an existing transaction                               |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/transaction                                    |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | Action=Stop TransID=<transaction_id>                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | Once a transaction is stopped, any files associated with  |
+|                                                           | it will no longer be available for download and the       |
+|                                                           | server is free to delete those files.                     |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+File Transfer
+-------------
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Transfer a file from the server back to the client        |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/download                                       |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | TransID=<transaction ID> File=<filename>                  |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               |                                                           |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | <filename> does not include any path information. The     |
+|                                                           | actual directory where the file is stored is chosen by    |
+|                                                           | the web service and hidden from the user                  |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Transfer one or more files from the client up to the      |
+|                                                           | server                                                    |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/upload                                         |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | This is a POST method Multiple files may be submitted     |
+|                                                           | with one call                                             |
+|                                                           | File(s) are submitted as                                  |
+|                                                           | multipart form data (ie: "Content-Type:                   |
+|                                                           | multipart/form-data" header)                              |
+|                                                           | File names should not include                             |
+|                                                           | any directory or path information. (Exactly where the     |
+|                                                           | file is stored is left to the web service to determine.)  |
+|                                                           | The transaction ID must also be                           |
+|                                                           | specified as form data with a field name of "TransID"     |
+|                                                           | On success, returns a "201 - Created" status code         |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+File Listing
+------------
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Return a listing of files associated with the specified   |
+|                                                           | transaction                                               |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/files                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | TransID=<transaction ID>                                  |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | Files : [ <file_1>, <file_2>, ... <file_n> ]              |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | No guarantees are made about the order files are listed   |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+Job Submission
+--------------
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Submit a python script for execution on the compute       |
+|                                                           | resource                                                  |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/submit                                         |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Mandatory POST Variables                                  | TransID : <trans_id>                                      |
+|                                                           | ScriptName : <name_of_python_script>                      |
+|                                                           | <name_of_python_script> : <python code>                   |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Optional POST Variables                                   | JobName : <name>                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Implementation Specific POST Variables                    | NumNodes : <number_of_nodes>                              |
+|                                                           | CoresPerNode: <cores_per_node>                            |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | JobID : <job_id>                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | This is a POST method                                     |
+|                                                           | Request is submitted as multipart form data (ie:          |
+|                                                           | "Content-Type: multipart/form-data" header)               |
+|                                                           | POST variables listed above are individual form data      |
+|                                                           | fields                                                    |
+|                                                           | The content of the "ScriptName" field specifies the name  |
+|                                                           | of the python script. There must be another field with    |
+|                                                           | this name that actually contains the python code. This    |
+|                                                           | allows the web service to keep track of multiple scripts  |
+|                                                           | associated with the same transaction.                     |
+|                                                           | The JobName variable allows the user to specify a name    |
+|                                                           | for a job. The name is included in the output of queries. |
+|                                                           | (Presumably, the user will pick a name that's more        |
+|                                                           | descriptive and easier to remember than the automatically |
+|                                                           | assigned job ID.)                                         |
+|                                                           | The Implementation Specific Post Variables are - like the |
+|                                                           | name says - specific to a particular implementation. They |
+|                                                           | may not be applicable to all implementations and it's     |
+|                                                           | valid for an implementation to ignore those that aren't.  |
+|                                                           | Which variables are required by a specific implementation |
+|                                                           | are listed in the `Information <#Information>`__ URL.     |
+|                                                           | (The two specified above are used by the Fermi            |
+|                                                           | implementation, and would probably be valid for all       |
+|                                                           | compute clusters.)                                        |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+Job Query
+---------
+
+This URL has two forms: one to query a specific job and one to query all of a user's jobs.
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Query all jobs submitted by the user                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/query                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | <job_id> : <job_description_object>                       |
+|                                                           | <job_id> : <job_description_object>                       |
+|                                                           | <job_id> : <job_description_object>                       |
+|                                                           | etc...                                                    |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | See below for a description of the job_description_object |
+|                                                           | The length of time the compute resource will 'remember'   |
+|                                                           | jobs is up to the implementer, but several days should be |
+|                                                           | considered an absolute minimum. (A user should be able to |
+|                                                           | submit a job on Friday and still be able to query it on   |
+|                                                           | Monday morning.)                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Query one specific job submitted by the user              |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/query                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | JobID : <job_id>                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | <job_id> : <job_description_object>                       |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | See below for a description of the job_description_object |
+|                                                           | The length of time the compute resource will 'remember'   |
+|                                                           | jobs is up to the implementer, but several days should be |
+|                                                           | considered an absolute minimum. (A user should be able to |
+|                                                           | submit a job on Friday and still be able to query it on   |
+|                                                           | Monday morning.)                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+The job description object is a JSON object who's fields contain specific information about the job. The fields are:
+
+-  TransID - The transaction ID the job is associated with
+-  JobName - The name that was given to the submit API
+-  ScriptName - The name of the python script that was executed
+-  JobStatus - The execution status of the job. Will be one of: RUNNING, QUEUED, COMPLETED, REMOVED, DEFERRED, IDLE or
+   UNKNOWN
+
+Job Abort
+---------
+
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Description                                               | Abort a previously submitted job. Jobs that are queued    |
+|                                                           | will be dequeued. Jobs that are running will be stopped   |
+|                                                           | immediately. Jobs that have already completed will simply |
+|                                                           | be ignored.                                               |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| URL                                                       | <base_url>/abort                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Query Parameters                                          | JobID : <job_id>                                          |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| JSON Output                                               | None                                                      |
++-----------------------------------------------------------+-----------------------------------------------------------+
+| Notes                                                     | Returns a 400 error code if the job ID does not exist.    |
++-----------------------------------------------------------+-----------------------------------------------------------+
+
+API v1 Extensions
+=================
+
+JOB_DATES
+---------
+
+The JOB_DATES extension adds three fields to the job_description_object that is returned by queries. The fields are
+"SubmitDate", "StartDate" & "CompletionDate" which represent the dates (including time) that the job was first
+submitted, when it started executing and when it stopped (either because it finished or because it was interrupted for
+some reason). The values are ISO8601 strings suitable for importing into a Mantid DateAndTime object.
+
+AUTH_USER_NAME
+--------------
+
+The AUTH_USER_NAME extension adds a single field the the JSON text returned by the 'info' URL. The field name is
+'Authenticated_As' and its value is either the name of the user that's been authenticated, or empty if no authentication
+has taken place yet.
diff --git a/dev-docs/source/RunningTheUnitTests.rst b/dev-docs/source/RunningTheUnitTests.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bb6ebc6c6786f1fd45d6d2bab05120fd907ffa30
--- /dev/null
+++ b/dev-docs/source/RunningTheUnitTests.rst
@@ -0,0 +1,135 @@
+.. _RunningTheUnitTests:
+
+======================
+Running the Unit Tests
+======================
+
+.. contents::
+  :local:
+
+Overview
+########
+
+We use `CTest <http://www.cmake.org/cmake/help/ctest-2-8-docs.html>`__
+for building and running our unit tests. This wraps the underlying
+`cxxtest <cxxtest>`__ or other (e.g. pyunit) test code.
+
+CMake/CTest: Command Line using a makefile generator
+####################################################
+
+The unit tests are currently excluded from the 'all' target. To build
+the all the tests, including the dependent framework code (in all these
+examples in parallel using 8 cores):
+
+.. code-block:: sh
+
+   make -j8 AllTests
+
+To build only one package of tests (and its dependencies):
+
+.. code-block:: sh
+
+   make -j8 KernelTest
+
+To run all the tests:
+
+.. code-block:: sh
+
+   ctest -j8
+
+To build and run all the tests in one shot:
+
+.. code-block:: sh
+
+   make -j8 check
+
+To run a specific test or set of tests (will run all those that match
+the search string):
+
+.. code-block:: sh
+
+   ctest -R KernelTest_TimerTest
+
+So to run all tests in a suite (using a search string):
+
+.. code-block:: sh
+
+   ctest -j8 -R KernelTest
+
+To exclude things from your tests (matches the string as with the -R
+option) - useful for those building the performance tests:
+
+.. code-block:: sh
+
+   ctest -j8 -E Performance
+
+Useful CTest Options
+####################
+
+``ctest -h`` gives the full list of command line arguments. Some useful
+ones to note are:
+
+-  ``--output-on-failure``: displays the log and any stderr output that
+   is otherwise hidden by CTest.
+-  ``--schedule-random``: run the tests in a random order. Useful to
+   weed out accidental dependencies
+-  ``--repeat-until-fail``\ : require each test to run times without
+   failing in order to pass. Useful to try and find random failures
+
+Running Unit Tests Manually
+###########################
+
+Starting in your build folder (e.g. Mantid/Code/debug):
+
+-  Running an entire test suite (e.g. KernelTest):
+
+   .. code-block:: sh
+
+      ctest -j8 -R KernelTest
+      bin/KernelTest
+
+-  Running a specific test class.
+
+   .. code-block:: sh
+
+      ctest -R MyTestClassName
+      bin/KernelTest MyTestClassName
+
+-  Running a specific test.
+
+   .. code-block:: sh
+
+      bin/KernelTest MyTestClassName MySingleTestName``
+
+   -  Not possible with ctest.
+
+Visual Studio/ XCode note
+#########################
+
+In Visual Studio the user can alter the properties of the subset of
+tests (inside the unitTest directory (e.g. AlgorithmTest). In the
+properties box it is possible to specify a specific test to run by
+typing its name in the TargetName box. Then to execute the test, right
+click the subset of tests and select debug and then start new instance.
+
+To run the tests under one of these environments then you will need to
+open a command window and change to the build directory. Once there you
+can run the tests by selecting the configuration;
+
+.. code-block:: sh
+
+   ctest -C Debug -j4
+
+This runs all tests in Debug mode (note that this will NOT build any
+outdated libraries). To select a subset use the ``-R`` option:
+
+.. code-block:: sh
+
+   ctest -C Release -R Kernel -j4
+
+   (-R Kernel), with 4 cores (-j4), in Release mode (-C Release).
+
+Debugging unit tests
+####################
+
+See the instructions `here <DebuggingUnitTests>`__
diff --git a/dev-docs/source/Standards/AlgorithmDocumentation.rst b/dev-docs/source/Standards/AlgorithmDocumentation.rst
new file mode 100644
index 0000000000000000000000000000000000000000..dc03d48a52c5f9caaebd04855dcdf63a71e309f0
--- /dev/null
+++ b/dev-docs/source/Standards/AlgorithmDocumentation.rst
@@ -0,0 +1,194 @@
+.. _AlgorithmDocumentation:
+
+=======================
+Algorithm Documentation
+=======================
+
+.. contents::
+  :local:
+
+Summary
+=======
+
+This page deals with the specifics of how to document an algorithm. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs <DocumentationGuideForDevs.html>`__.
+
+How to Document an Algorithm
+============================
+
+Algorithm documentation is stored in two places.
+
+* The code (.cpp / .h / .py) files: For strings that are needed in the GUI for tooltips etc.
+* The .rst file: For all other documentation, including the algorithm description and `usage examples <AlgorithmUsageExamples.html>`__.
+
+The Code Files
+--------------
+
+The code files hold documentation in two important areas.
+
+The ``summary`` method
+   The summary method should return a string (in plain text) that describes in a short sentence the purpose of the algorithm. This is used to provide a summary in the algorithm dialog box and in the algorithm documentation web page.
+
+In C++: (This example uses the .h file, you could of course implement it in the .cpp file)
+
+.. code-block:: c++
+
+   /// Algorithm's name for identification overriding a virtual method
+   const std::string name() const override { return "Rebin";}
+
+   ///Summary of algorithms purpose
+   const std::string summary() const override {return "Rebins data with new X bin boundaries.";}
+
+Property Descriptions
+---------------------
+
+Each property declaration in the init method of the .cpp file should include a description. This is used as a tooltip, and in the 'properties' table on the algorithm's documentation web page.
+
+.. note::
+
+   The tooltip may only show the description up to the first dot. Be sure that the first sentence in the description gives enough information to understand the purpose of the property.
+
+For example:
+
+.. code-block:: c++
+
+   declareProperty(
+   new WorkspaceProperty<>("InputWorkspace", "", Direction::Input),
+     "Workspace containing the input data");
+   declareProperty(
+   new WorkspaceProperty<>("OutputWorkspace","",Direction::Output),
+     "The name to give the output workspace");
+   declareProperty(
+   new ArrayProperty<double>("Params", boost::make_shared<RebinParamsValidator>()),
+     "A comma separated list of first bin boundary, width, last bin boundary. Optionally "
+     "this can be followed by a comma and more widths and last boundary pairs. "
+     "Optionally this can also be a single number, which is the bin width. "
+     "In this case, the boundary of binning will be determined by minimum and maximum TOF "
+     "values among all events, or previous binning boundary, in case of event Workspace, or "
+     "non-event Workspace, respectively. Negative width values indicate logarithmic binning. ");
+
+Workflow algorithms
+===================
+
+There should be a flow chart for workflow algorithms. See `here <FlowchartCreation.html>`__ on how to make one.
+
+Algorithm Directives
+====================
+
+We have defined several custom directives using the Sphinx extension framework. These are defined to generate the information from an algorithm that is not required to be hand written, i.e the properties table. Each .rst file that is documenting an algorithm should use these directives.
+
+As the **Description** and **Usage** of an algorithm *cannot* be obtained automatically, it must be manually entered. The structure of an algorithm's .rst is:
+
+.. code-block:: rest
+
+   .. algorithm::
+
+   .. summary::
+
+   .. alias::
+
+   .. properties::
+
+   Description
+   -----------
+
+   The description of your algorithm here.
+
+   Usage
+   -----
+
+   A custom usage example.
+
+   .. categories::
+
+   .. sourcelink::
+
+``.. algorithm ::``
+   This directive has several pieces of functionality, which includes:
+
+* A referable link is created for the algorithm. This allows other documentation pages create references to it (e.g. create links to it).
+* Insertion of the page title (which is the name of the algorithm, including the version).
+* Insertion of a screenshot of the algorithm's dialog.
+* Insertion of the Table Of Contents.
+
+``.. summary::``
+   The content of the summary method declared in your algorithm is output as HTML, for example, the following method is used in Rebin: 
+
+.. code-block:: c++
+
+   /// Summary of algorithms purpose
+   const std::string summary() const override {
+      return "Rebins data with new X bin boundaries. For EventWorkspaces, you can very quickly rebin in-place by keeping the same output name and PreserveEvents=true.";
+   }
+
+``.. alias::``
+   This directive obtains aliases from the required ``alias`` method in the algorithm, for example, the following method is used in Rebin: 
+
+.. code-block:: c++
+
+   /// Algorithm's aliases
+   const std::string alias() const override { return "rebin"; }
+
+``.. properties::``
+   As mentioned above, it is *critical* that you include a description for the properties of your algorithm. This directive obtains all of the algorithm's properties (set inside the algorithm's ``init`` method) and outputs in a table format. 
+
+``.. categories::``
+   By default, this directive obtains the categories that were set in the ``categories`` method the algorithm. For example, in Rebin the category method is in the header and contains:
+
+.. code-block:: c++
+
+   /// Algorithm's category for identification
+   const std::string category() const override {return "Transforms\\Rebin";}
+
+When the HTML is generate a categories list is built that contains: Algorithms, Transforms and Rebin.
+
+It is possible to add additional categories by passing the directive arguments, for example, the following would output the above categories, and also `Example`:
+
+.. code-block: rest
+
+   .. categories:: Algorithms, Transforms, Rebin, Example
+
+``..sourcelink ::``
+   This directive adds links to the algorithms source code.
+
+Description
+===========
+
+This section must be manually entered. The description is an extension of the summary, and must contain a detailed overview of the algorithm's functionality. 
+
+Referencing Other Algorithms
+----------------------------
+
+Every algorithm and version has been marked with a tag that can be used to reference it from other documents. If you need to reference the latest version of an algorithm, e.g. DiffractionFocussing, then in Sphinx you type would type
+
+.. code-block:: rest
+
+   :ref:`DiffractionFocussing <algm-DiffractionFocussing>`
+
+If you need to reference a particular version then you would type
+
+.. code-block:: rest
+
+   :ref:`DiffractionFocussing version 2 <algm-DiffractionFocussing-v2>`
+
+where the first part outside the angle brackets defines the link text and the part inside the angle brackets references the tag name. 
+
+Usage
+=====
+
+This section *must* be manually entered. The usage is a 'code' example of the algorithm in use. The `testcode` directive must be used to verify the usage code you entered works correctly. See `here <AlgorithmUsageExamples>`__ for more information on how to write usage examples.
+
+Building the Documentation
+==========================
+
+One can update the documentation for a particular algorithm after changes have been introduced into the corresponding documentation file. Assuming you are in the build directory and want to update the documentation for Rebin:
+
+::
+
+   bin/MantidPlot -xq docs/runsphinx_html.py -R Rebin  # builds HTML documentation
+   bin/MantidPlot -xq docs/runsphinx_qthelp.py -R Rebin  # builds Qt-help documentation
+
+or with vanilla python
+
+::
+
+   python docs/runsphinx_html.py -m $PWD/bin -R Rebin
diff --git a/dev-docs/source/Standards/AlgorithmUsageExamples.rst b/dev-docs/source/Standards/AlgorithmUsageExamples.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3c8ee85ebc3789e7b1a5f89e2d8815f158a3a4d0
--- /dev/null
+++ b/dev-docs/source/Standards/AlgorithmUsageExamples.rst
@@ -0,0 +1,224 @@
+.. _AlgorithmUsageExamples:
+
+========================
+Algorithm Usage Examples
+========================
+
+.. contents::
+  :local:
+
+Introduction
+============
+
+A *usage example* is part of the documentation page of an algorithm.
+
+From a user's point of view, the main purposes of usage examples are:
+
+* Getting started using the algorithm as part of a Python script
+* Understanding the algorithm
+* Showing hints/comments etc. that help understand Mantid Python scripting in general
+
+The usage examples are written in `reStructuredText <http://docutils.sourceforge.net/rst.html>`__, which can be converted to HTML and the code in the usage examples can be tested. The image below demonstrates an example of converting reStructuredText to HTML. 
+
+Guide
+=====
+
+The example below show the proposed way to format an usage example in reStructuredText.
+
+.. code-block:: rest
+
+   Usage
+   -----
+
+   **Example - simple rebin of a histogram workspace:**  
+
+   .. testcode:: ExHistSimple
+
+      # create histogram workspace
+      dataX = [0,1,2,3,4,5,6,7,8,9] # or use dataX=range(0,10) 
+      dataY = [1,1,1,1,1,1,1,1,1] # or use dataY=[1]*9 
+      ws = CreateWorkspace(dataX, dataY)
+      
+      # rebin from min to max with size bin = 2
+      ws = Rebin(ws, 2)   
+      
+      print "The rebinned X values are: " + str(ws.readX(0))  
+      print "The rebinned Y values are: " + str(ws.readY(0)) 
+
+
+   Output:
+
+   .. testoutput:: ExHistSimple
+      
+      The rebinned X values are: [ 0.  2.  4.  6.  8.  9.]
+      The rebinned Y values are: [ 2.  2.  2.  2.  1.]
+
+What is required is:
+
+* Short description explaining the example, formatted as shown above, i.e. using ``**`` to embolden the text.
+* A ``.. testcode::`` section, with a unique 'namespace' name, here ``ExHistSimple``. This 'namespace' is not shown when converted to HTML, but is used in testing the code. This section contains the actual Python code demonstrating a usage of the algorithm. This code block contains commented code, finishing with one or more Python ``print`` lines as shown
+* A ``.. testoutput::`` section. This section must have a matching 'namespace' name to the ``..testcode::`` section. It simply contains a copy of the text that is printed out in the ``..testcode::`` section.
+* Include the "Output:" string above the ``..testoutput::`` directive.
+
+What is optional:
+
+* A ``..testcleanup::`` section. This section must have a matching 'namespace' name to the ``..testcode::`` section. Here, add Python code to do any cleanup of files etc. that were created by the tests. See the notes below for things that are cleaned automatically.
+
+Notes:
+
+* The configuration has a global "testcleanup" implemented which calls ``FrameworkManager::clear()`` to clear algorithms, workspaces & instruments so these are dealt with automatically.
+* There must be a clear blank line before the ``.. testcode::`` and ``.. testoutput`` directives or the test is ignored. As with unit tests you should write a failing test first to ensure it is running.
+
+What is worth keeping in mind is:
+
+* *Assume the user is new to Python*. Consider giving hints to more advanced Python in comments, or introduce a simple example first.
+* Use comments.
+* Use Python ``print`` to output results, which, where possible, helps to understand the algorithm.
+
+A Jenkins job tests that the usage examples are not broken, i.e. that they continue to provide a working demonstration against the current build. It is vital to stress that the purpose of usage testing is *not to replace unit testing* (or system testing). The purpose of usage testing (better described as demonstration examples), is to provide some happy-path examples, which, where this is possible, can assist the user understanding of the Python code. This is very different from the purposes of testing in general, see `here <UnitTestGoodPractice.html>`__.
+
+Additional benefits of usage examples:
+
+* Quick look-up for developers on how to use a certain algorithm in Python scripting
+* Allow the user to test that scripts return expected output in their installed Mantid versions
+* Additional test coverage of Mantid Python API
+
+Using CreateSampleWorkspace and CreateWorkspace
+-----------------------------------------------
+
+There are many ways to create sample workspaces. For example :ref:`CreateMDHistoWorkspace <algm-CreateMDHistoWorkspace>`, :ref:`CreateSampleWorkspace <algm-CreateSampleWorkspace>` and :ref:`CreateWorkspace <algm-CreateWorkspace>`. CreateSampleWorkspace creates a fully defined workspace (either event or histogram) but for creating simple histogram workspace CreateWorkspace may be a better option. Above is shown an example where CreateWorkspace is used. Below is a more complex use of CreateSampleWorkspace:
+
+.. code-block:: rest
+
+   Usage
+   -----
+
+   **Example - Fit a Gaussian to a peak in a spectrum:**
+
+   .. testcode:: ExFitPeak
+
+      # create a workspace with a gaussian peak sitting on top of a linear (here flat) background
+      ws = CreateSampleWorkspace(Function="User Defined", UserDefinedFunction="name=LinearBackground, \
+         A0=0.3;name=Gaussian, PeakCentre=5, Height=10, Sigma=0.7", NumBanks=1, BankPixelWidth=1, XMin=0, XMax=10, BinWidth=0.1)
+
+      # Setup the data to fit:
+      workspaceIndex = 0  # the spectrum with which WorkspaceIndex to fit
+      startX = 1      # specify fitting region 
+      endX = 9      #
+      
+      # Setup the model, here a Gaussian, to fit to data
+      tryCentre = '4'   # A start guess on peak centre
+      sigma = '1'          # A start guess on peak width
+      height = '8'         # A start guess on peak height
+      myFunc = 'name=Gaussian, Height='+height+', PeakCentre='+tryCentre+', Sigma='+sigma
+      # here purposely haven't included a linear background which mean fit will not be spot on
+      # to include a linear background uncomment the line below
+      #myFunc = 'name=LinearBackground, A0=0.3;name=Gaussian, Height='+height+', PeakCentre='+tryCentre+', Sigma='+sigma
+
+      # Do the fitting
+      fitStatus, chiSq, covarianceTable, paramTable, fitWorkspace = Fit(InputWorkspace='ws', \ 
+         WorkspaceIndex=0, StartX = startX, EndX=endX, Output='fit', Function=myFunc)
+
+      print "The fit was: " + fitStatus  
+      print("chi-squared of fit is: %.2f" % chiSq)
+      print("Fitted Height value is: %.2f" % paramTable.column(1)[0])
+      print("Fitted centre value is: %.2f" % paramTable.column(1)[1]) 
+      print("Fitted sigma value is: %.2f" % paramTable.column(1)[2])
+      # fitWorkspace contains the data, the calculated and the difference patterns 
+      print "Number of spectra in fitWorkspace is: " +  str(fitWorkspace.getNumberHistograms())
+      print("The 20th y-value of the calculated pattern: %.4f" % fitWorkspace.readY(1)[19])    
+
+   .. testcleanup:: ExFitPeak
+
+      DeleteWorkspace(ws)
+
+   Output:
+
+   .. testoutput:: ExFitPeak
+
+      The fit was: success
+      chi-squared of fit is: 0.14
+      Fitted Height value is: 9.79
+      Fitted centre value is: 5.05
+      Fitted sigma value is: 0.77
+      Number of spectra in fitWorkspace is: 3
+      The 20th y-value of the calculated pattern: 0.2361
+
+For a more simple use of CreateSampleWorkspace see example below (note if no arguments are given then a histogram workspace is created):
+
+.. code-block:: rest
+
+   Usage
+   -----
+
+   **Example - use option PreserveEvents:**
+
+   .. testcode:: ExEventRebin
+
+      # create some event workspace
+      ws = CreateSampleWorkspace(WorkspaceType="Event")
+
+      print "What type is the workspace before 1st rebin: " + str(type(ws)) 
+      # rebin from min to max with size bin = 2 preserving event workspace (default behaviour)
+      ws = Rebin(ws, 2)   
+      print "What type is the workspace after 1st rebin: " + str(type(ws)) 
+      ws = Rebin(ws, 2, PreserveEvents=False)   
+      print "What type is the workspace after 2nd rebin: " + str(type(ws)) 
+      # note you can also check the type of a workspace using: print isinstance(ws, IEventWorkspace)   
+
+   .. testcleanup:: ExEventRebin
+
+      DeleteWorkspace(ws)
+
+   Output:
+
+   .. testoutput:: ExEventRebin
+
+      What type is the workspace before 1st rebin: <class 'mantid.api._api.IEventWorkspace'>
+      What type is the workspace after 1st rebin: <class 'mantid.api._api.IEventWorkspace'>
+      What type is the workspace after 2nd rebin: <class 'mantid.api._api.MatrixWorkspace'>
+
+When needing to load a data file
+--------------------------------
+
+Instructions to add a new data file to the repository are available `here <DataFilesForTesting.html>`__. Files from the repository will be bundled up into a .zip file, and this .zip made available for download from the Mantid download page.
+
+If you use files you must add the line
+
+.. code-block:: rest
+
+   .. include:: ../usagedata-note.txt
+
+as shown in the example below. This will generate a note to the user explaining how to download the UsageData.
+
+.. code-block:: rest
+
+   Usage
+   -----
+
+   .. include:: ../usagedata-note.txt
+
+   **Example - Load ISIS histogram Nexus file:**
+   (see :ref:`LoadISISNexus <algm-LoadISISNexus>` for more options)   
+
+   .. testcode:: ExLoadISISnexusHist
+
+      # Load ISIS LOQ histogram dataset
+      ws = Load('LOQ49886.nxs') 
+      
+      print "The 1st x-value of the first spectrum is: " + str(ws.readX(0)[0])      
+
+   .. testcleanup:: ExLoadISISnexusHist
+
+      DeleteWorkspace(ws)
+      
+   Output:
+
+   .. testoutput:: ExLoadISISnexusHist
+      
+      The 1st x-value of the first spectrum is: 5.0
+
+Running the Tests
+=================
+
+See `here <DocumentationGuideForDevs.html>`__ for how to run and test the usage examples locally.
diff --git a/dev-docs/source/Standards/CPPStandards.rst b/dev-docs/source/Standards/CPPStandards.rst
new file mode 100644
index 0000000000000000000000000000000000000000..89a81e6236a1b36414f0812b61c0ad6789c411b5
--- /dev/null
+++ b/dev-docs/source/Standards/CPPStandards.rst
@@ -0,0 +1,378 @@
+.. _CppCodingStandards:
+
+====================
+C++ Coding Standards
+====================
+
+.. contents:: Contents
+   :local:
+
+References
+^^^^^^^^^^
+
+- `LLVM Coding standard <http://llvm.org/docs/CodingStandards.html>`__
+- *The C++ Programming Language* (third edition), Bjarne Stroustrup
+- `C++ ANSI Standards <http://www.open-std.org/jtc1/sc22/wg21/>`__
+
+Overview
+^^^^^^^^
+
+Mantid follow the LLVM C++ coding standards and standards on this
+page.  Where these standards overlap the standards on this page take
+precedence.
+
+`This page
+<https://github.com/mantidproject/mantid/wiki/clang-format>`__
+describes a tool that you may find useful for checking your code
+satisfies LLVM whitespace conventions. It's also useful to set up your
+text editor to use `two spaces instead of tabs
+<http://llvm.org/docs/CodingStandards.html#use-spaces-instead-of-tabs>`__.
+
+Files
+^^^^^
+
+- Header files will use the ``.h`` extension.
+- Code body files will use the ``.cpp`` file extension.
+- All ``.cpp`` files must have a corresponding ``.h`` file.
+
+Headers
+^^^^^^^
+
+Header Files
+------------
+
+All header files in a project must have a header comment. In many
+cases this will be included as part of the class header, but any
+header files that do not contain classes must include the same
+information as a file header. The information that must be included
+is:
+
+-  class description
+-  Copyright
+-  GPL license text
+
+Layout of Header File
+---------------------
+
+The contents of the header file should be arranged in the following
+order:
+
+- ``#include`` directives in the following order, where each section shold be
+  sorted alphabetically:
+
+  - Main Module Header
+  - Mantid Headers from the same project
+  - Mantid headers from other projects
+  - 3rd party library headers
+  - System ``#include`` directives
+-  Forward declarations of other classes
+-  Global constants, enumerations & typedefs
+-  Doxygen class description
+-  Class definition:
+
+   -  Public constants, enumerations & types
+   -  Public constructors & destructors
+   -  Public functions & operators
+   -  Protected functions
+   -  Private constants, enumerations & types
+   -  Private functions
+   -  Private variables
+   -  Bodies of inline functions and (for a template class) member
+      functions.
+
+In most cases header files should only contain a single class. The only
+exceptions to this should be for internal utility classes, and extremely
+small highly related classes such as exception classes.
+
+CPP file Headers
+----------------
+
+We will not be including body file headers. The relevant class file
+header in the ``.h`` file will suffice.
+
+Function headers
+----------------
+
+These will follow the style put forward in the `Doxygen documentation
+<http://www.stack.nl/~dimitri/doxygen/docblocks.html>`__.  Headers
+comments must be included above all functions definitions and should
+describe the function, all parameters and returns values as a minimum.
+
+Where a function is declared in the header file and defined in the
+``.cpp`` file the following approach should be taken:
+
+- The header file need only contain documentation for items that do
+  not appear in a ``.cpp`` file (e.g. the class itself, member
+  variables, inlined methods and templated classes). This keeps the
+  header files compact and easier to read. Brief comments can
+  optionally be included (as in the example below).
+
+Example header file function declaration
+
+.. code-block:: c++
+
+    /// Creates an instance of an algorithm
+    IAlgorithm* createAlgorithm(const std::string& algName, const int& version);
+
+Example CPP file function definition
+
+.. code-block:: c++
+
+    /** Creates and initialises an instance of an algorithm
+     *
+     * @param algName The name of the algorithm required
+     * @param version The version of the algorithm
+     * @return A pointer to the created algorithm
+     *
+     * @throw NotFoundError Thrown if algorithm requested is not registered
+     */
+     IAlgorithm* FrameworkManagerImpl::createAlgorithm(const std::string& algName, const int& version) {
+       IAlgorithm* alg = AlgorithmManager::Instance().create(algName,version).get();
+       return alg;
+     }
+
+Naming Conventions
+^^^^^^^^^^^^^^^^^^
+
+Names should be descriptive and meaningful, but not too long (say <20
+characters). This is helped by sensible and consistent (across the
+project) use of abbreviations.
+
+- **Constants** (including static const members): All upper
+  case. Internal words separated by underscore eg: ``ERROR_NO_DATA``
+- **Classes, namespaces, structs, enums (and enum values) and typedefs**:
+  PascalCase (First letter upper case, then lower
+  case. Internal words begin with upper case letter).
+- **Function Names**: function names will be in camelCase (starting
+  with a lower case character and capital for each later word).
+- **Variable Names / Type Prefixes**: variables will be given sensible
+  descriptive names. Type prefixes will not be used. variable names
+  in Mantid are usually camelCase (starting with a lower case
+  character and capital for each later word).
+- **Scope Prefixes**
+   - Static member variables use a ``g_`` prefix.
+   - Non-static member variables use an ``m_`` prefix.
+- **Local variables used as integer loop counters** As an exception,
+  these may use very short names like ``i, j, k, l`` eg. ``for (int
+  i = 0; i < 5; i++)``
+
+Preprocessor
+^^^^^^^^^^^^
+
+1. Use of the pre-processor should be minimised. Constants and type
+   aliases should be declared using ``const`` and ``typedef`` rather
+   than ``#define``, and functions should be used in favour of macros.
+2. ``#include`` statements should use quotes (``""``) for inclusion of
+   Mantid code and angle brackets (``<>``) for system files (this
+   includes headers from ``Third_Party``)
+3. All header files should have guards against repeated inclusion,
+   with the guard flags named consistently. (See `here
+   <https://en.wikipedia.org/wiki/Include_guard>`__ for an
+   explanation)
+4. Header files should only include those other header files within
+   the project that are necessary (e.g. for definition of the base
+   class).  In many cases a forward declaration of the form ``class
+   CPidClientObject;`` is sufficient, and this helps to avoid cyclical
+   inclusions of headers.
+5. It should be possible to compile each header file
+   individually. That is, a file consisting solely of ``#include
+   "header.h"`` should compile without errors. This avoids
+   undocumented interdependencies between headers.
+
+Classes and Namespaces
+^^^^^^^^^^^^^^^^^^^^^^
+
+1. There should be only one class or namespace declared in each header
+   file. This recommendation should only be relaxed where classes are
+   closely tied together.
+2. There should be only one class or namespace defined per body file
+   (unless classes are closely tied as in (1) above). All the
+   definitions for that class/namespace should be in the one file
+   (unless this yields a source file that is unmanageably large).
+3. Data members should be private. Access to data from other classes
+   should only be through protected or public methods (or by
+   ‘friends’, but see item 8). Inside a large class, consider
+   reserving direct access to private data members for a smaller
+   manageable core of member functions.
+4. All constructors for a class must initialise all its member variables
+   that do not have a default constructor (including primitive and
+   pointer types).
+5. All base classes must have a virtual destructor.
+
+   - This may be disregarded only in exceptional circumstances when
+     the overhead of a virtual-table would significantly affect
+     performance. Such a class must not be subclassed, and must be
+     adequately commented to warn other developers against subclassing
+     the class.
+   - In addition, it is recommended that where possible, programming
+     techniques are used to prevent inheritance of classes with a
+     non-virtual destructor. While comments may suffice they can
+     easily be ignored or misunderstood, particularly by inexperienced
+     developers
+
+6. Classes’ constructors and destructors must not call their own virtual
+   member functions, directly or indirectly. (C++ does not resolve such
+   function calls polymorphically.)
+7. Do not define special members functions when they would be
+   identical to those automatically generated by the compiler. Use ``=
+   delete`` to remove invalid compiler-generated versions. Consider
+   following the `rule-of-zero <https://rmf.io/cxx11/rule-of-zero/>`__
+   and writing an additional class for resource management.
+8. The use of ``friend`` should be avoided and its use requires
+   justification. As an exception, overloads of the ``<<`` and ``>>``
+   operators for serialising the class may be declared as ``friend``.
+9. Use of multiple inheritance should be restricted to cases in which
+   the second and subsequent base classes are all interfaces. (An
+   interface in this context is a class consisting only of pure virtual
+   functions.).
+10. Virtual inheritance should only be used when the base class
+    involved is an interface.
+11. Unions and bitfields should only be used where essential for
+    performance, or where required for interfacing with a third party
+    library.
+
+Mantid Namespaces
+-----------------
+
+All Mantid code lives within a minimum of a two tiered namespace. The
+outer namespace for all Mantid code is Mantid, and this is followed by
+a namespace identifying the library that contains the code. Third and
+further level namespaces may be used to section code to further
+improve readability and maintenance.
+
+Functions and Variables
+^^^^^^^^^^^^^^^^^^^^^^^
+
+1. Variables, functions parameters, and function return values must have
+   explicit types (no defaulting to ``int``).
+2. A function declaration should not use ``void`` to indicate an empty
+   parameter list.
+3. Parameters in function prototypes should include names, not just
+   their types. For example, use ``void eraseRange(int nFirst, int
+   nLast);`` rather than ``void eraseRange(int, int);`` as this
+   improves self-documentation.
+4. Non-static member functions should be declared ``const`` if logically
+   they do not alter the state of the class instance.
+5. Simple accessor functions may be inline (e.g. ``inline int
+   getCount() const { return m_nCount;}``). Otherwise, inline
+   functions should be avoided unless essential for performance.
+6. Operators should be overloaded sparingly. Operator overloads should
+   behave in accordance with the semantics of the operator as applied
+   to primitive types, or according to established conventions
+   (e.g. ``<<`` and ``>>`` for serialisation).
+7. ‘Magic numbers’ must not be used in the code. Constants and
+   enumerations must be used instead.
+
+Expressions and Statements
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+1. Integers should not be cast to Booleans. For example, prefer ``if (x
+   != 0)`` rather than ``if(x)``
+2. The new style type casting must be used in place of the old C style
+   type casts. If casting up or down an inheritance hierarchy, use
+   ``dynamic_cast`` (which performs a run-time type check) rather than
+   ``static_cast``.
+3. Function calls with side effects, and the ``++``/``--``/assignment operators,
+   should only be called as a standalone statement rather than embedded
+   inside an expression.
+
+   -  It is permissible, although discouraged, to have a function call
+      with side effects as the right-operand of ``&&`` or ``||``. Any such
+      instances must be commented in detail to alert other developers to
+      the fact that the function is not always called.
+4. ``for`` and ``while`` loops should not use ``break`` and
+   ``continue`` where they can be avoided. Where they are required,
+   comments should draw attention to them as an alternative exit point
+   from the loop.
+5. A ``for`` loop should only have one control variable, and should
+   not modify it in the body.
+6. ``switch`` statements must include a ``default`` clause, even if
+   only to catch errors.
+7. Each ``case`` of a ``switch`` statement must either end with a
+   ``break``/``return``, or contain a clear comment to alert other
+   developers to the fact that execution will fall through to the next
+   case. Multiple ``case`` labels (with no code between them) are,
+   however, permitted for the same block of code.
+8. ``goto`` must be avoided. When there is a need to break out of two
+   or more nested loops in one go, the loops should be moved to a
+   separate function where 'return' can be used instead.
+
+Comments
+^^^^^^^^
+
+1. Sufficient commenting (to the level mandated by this document) of a
+   piece of code must be performed at the same time as the code is
+   written. It must not be put off until the end of development. When
+   code is updated, all relevant comments must be updated as well
+   (including those in the header).
+2. ‘Dead code’ must not be kept in the source code. (‘Dead code’ here
+   means code that has been commented out or unconditionally
+   suppressed in some other way, for example using ``#if 0``
+   preprocessor directives.)
+
+   -  In the (rare) instances that dead code would serve an important
+      documentation purpose for ongoing development, the dead code must
+      be placed in an external location and may be referenced from the
+      ‘live’ source code.
+3. Comments must be indented to the same level as the code to which
+   they refer.
+4. The language used in comments must be professional and to the
+   point.  Flippant or derogatory remarks must be avoided.
+5. The collection of comments in a function must, on its own, be
+   sufficient that a competent C++ developer can pick up the function
+   for subsequent development.
+6. Comments on a single line should use ``//`` rather than ``/* … */``.
+7. No code block should exceed 20 statement lines without a comment of
+   some sort. In general all code should contain 15% comment lines.
+8. The style of the comments is not mandated here. However the following
+   are general recommendations:
+
+   -  Comments should always be used to describe potential “difficult”
+      sections of code utilising, for example, special algorithms
+   -  Comments should be used in particular to explain branch conditions
+      in ``if ... else`` and ``switch { case ...``-like statements
+   - **Comments should be written at a higher level of abstraction
+     than the code to which they pertain, rather than merely
+     restating it**
+
+Error Handling
+^^^^^^^^^^^^^^
+
+The type of error handling needed depends on what the code is
+doing. In daemon / service type of program almost nothing may be
+allowed to cause the process to terminate, whereas in some utility
+programs it may be acceptable to terminate for many error
+conditions. This is a design issue and the strictness of application
+of the following should take into account the use of the code.
+
+1. The developer should identify all errors that can be generated by a
+   function and ensure that they are dealt with appropriately at some
+   point in the system. This may be within the function itself or
+   higher up in the call stack.
+2. All exceptions must be caught and handled properly. (This may
+   include terminating the program cleanly, for instance if no more
+   memory can be allocated.)
+3. Public functions should check their input parameters before using
+   them. This checking may be made using the ``assert()`` macro or
+   similar mechanism, and so only checked in the debug build, in which
+   case comprehensive testing must be performed of the release build.
+4. All error status values returned from a function call must be checked
+   or explicitly ignored. (To explicitly ignore a function call's return
+   value cast it to void, e.g. ``(void) f(a, b);``)
+5. When using ``dynamic_cast`` on a pointer, a check must be made that
+   the result is not ``null`` (i.e. that the cast was successful).
+6. Destructors must not throw any exceptions, directly or indirectly.
+   (Exceptions encountered while calling destructors during stack
+   unwinding from an earlier exception will cause immediate program
+   termination.)
+7. Where the language permits it, and where the occurrence of errors
+   can be identified at coding time (e.g. opening a file), errors
+   should be trapped on an individual basis, rather than using a
+   catch-all error handler.
+8. Error messages displayed to the user must be understandable and
+   informative. They must suggest an action to the user, which will
+   resolve the problem, for example:
+
+   -  No further action is required.
+   -  Check the XYZ input data and then repeat the process.
+   -  Contact the system administrator.
diff --git a/dev-docs/source/Standards/DocumentationGuideForDevs.rst b/dev-docs/source/Standards/DocumentationGuideForDevs.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a022439e85589f6dab17661f6fb862f058d534d2
--- /dev/null
+++ b/dev-docs/source/Standards/DocumentationGuideForDevs.rst
@@ -0,0 +1,249 @@
+.. _DocumentationGuideForDevs:
+
+============================
+Documentation Guide for Devs
+============================
+
+.. contents::
+  :local:
+
+Rationale
+=========
+
+The algorithm documentation approach aims to:
+
+#. Keep .cpp files clean and easy to maintain.
+#. Make the documentation files easier to edit, supporting the use of external editors.
+#. Simplify the Mantid documentation workflow.
+
+To do this we have harmonised most of our documentation workflow to use sphinx, extended a bit by some Mantid custom tag extensions.
+
+Prerequisites
+=============
+
+The documentation build requires:
+
+Sphinx
+------
+
+* `Sphinx <http://www.sphinx-doc.org/en/master/>`__
+* `Sphinx bootstrap theme <https://pypi.python.org/pypi/sphinx-bootstrap-theme/>`__
+
+These are bundled with the Python distrbution on Windows but other platforms will need to install them following the installation instructions `here <https://github.com/mantidproject/mantid/blob/master/docs/README.md>`__. It is recommended that ``pip`` is used over ``easy_install``.
+
+LaTeX
+-----
+
+To view the equations built with the documentation you will need an installation of LaTeX on your system.
+
+Linux
+#####
+
+If you have installed the mantid-develop package then you should have a working latex distribution. If not, use your package manager and search for a suitable candidate, most likely named something like ``texlive``.
+
+MacOS
+#####
+
+See `here <http://tug.org/mactex/>`__ for instructions on installing ``MacTeX``.
+
+Windows
+#######
+
+Download and install ``MikTeX`` from `here <https://miktex.org/download>`__.
+
+During installation there will be a question with a drop-down box relating to installing packages on demand - make sure "Ask first" is selected.
+
+The first build of one of the ``docs-*`` targets after ``MikTeX`` has installed will raise a dialog, similar to this asking you if it is okay to install a package. For developers behind a proxy you will need to click on the "Change" button and enter the proxy information and select a new download location on the set of dialogs that appear before returning back to the main dialog. Check the box saying don't ask again and click install.
+
+reST editors/IDE plugins
+========================
+
+Several free & proprietary editors support syntax-highlighting reST. A list of the most notable ones can be found `here <https://stackoverflow.com/questions/2746692/restructuredtext-tool-support>`__.
+
+Restview
+--------
+
+A really handy tool whilst writing out .rst files is `restview <https://pypi.python.org/pypi/restview>`__ which can be easily installed using ``pip``. It opens a webpage with the rst file processed and refreshes the page automatically whenever the .rst file is saved. This can help you quickly track down that unexpected space or missing newline without having to rebuild the documentation each time. It does not support sphinx directives so links will produce errors on the page which need to be checked by building the documentation using Mantid. The syntax to use it is:
+
+``restview path/to/file.rst``
+
+The reStructuredText File
+=========================
+
+`reStructuredText <http://docutils.sourceforge.net/rst.html>`__ is a markup format and is converted into themed html pages using Sphinx. A primer on reStructuredText can be found here along with a single-page cheat sheet.
+
+The source files are .rst files which are located in the ``docs/source`` directory in the repository. There are various subdirectories based on the type of object being documented, i.e. ``docs/source/algorithms``, ``docs/source/functions``.
+
+The documentation pages is aimed at *users*, not developers, and all information should be targeted for the users. Information for developers should go into doxygen/code-comments in the code or into ``dev-docs``.
+
+Directives
+----------
+
+Sphinx is built on the ``docutils`` package that allows for directives to be inserted in to reST comments. For example:
+
+.. code-block:: rest
+
+    .. warning::
+       This text will show up surrounded by a coloured box.
+
+tells sphinx to treat the the given text differently and flag it so that a user will see it as a warning. The name of the directive is ``warning`` and the ``..`` is a reST comment syntax. The directive name must be followed by ``::`` so that Sphinx process knows it has a directive command and not just plain text. For a list of directives known to Sphinx, see `here <http://www.sphinx-doc.org/en/master/rest.html#directives>`__.
+
+Comments
+--------
+
+If you wish to place comments in the reST file that will not be rendered anywhere then start the line/block with ``..``. See `here <http://sphinx-doc.org/rest.html#comments>`__ for more details.
+
+Algorithms
+----------
+
+The algorithm documentation has a slightly more rigid structure and is described in more detail `here <AlgorithmDocumentation.html>`__ and `here <AlgorithmUsageExamples.html>`__.
+
+Interfaces
+----------
+
+For documenting custom interfaces, it is recommended that you consult `this <InterfaceDocumentation.html>`__  page, which explains how to document them, and which directives may be used in more detail. 
+
+How to define titles, sections etc.
+-----------------------------------
+
+The syntax for headers in restructuredText is the header followed by a line containing symbols such as hyphens. It is possible to use different punctuation to create headers but within the Mantid .rst files we standardize on the characters used as follows:
+
+The title of the page
+   Should be the first header of your .rst file, and generally only occur once. (This is done for you in an algorithm with the ``.. algorithm::`` directive)
+
+.. code-block:: rest
+
+   =============================================
+   Page title (e.g. Workspace) - This outputs H1
+   =============================================
+
+Section headings
+   Sections, such as the description of an algorithm, can be created with the following syntax
+
+.. code-block:: rest
+
+   # Description - This outputs H2
+   -------------------------------
+
+Sub-sections
+   The following is used to create a sub-section of the above section. This must follow after the above to be parsed correctly.
+
+.. code-block:: rest
+
+   Sub-heading - This outputs h3
+   #############################
+
+Sub-sub-sections
+   The following is used to create a sub-header for the sub-heading above. This must also follow after the above header to be parsed correctly.
+
+.. code-block:: rest
+
+   Sub-sub-heading - Outputs h4
+   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Things to Avoid
+===============
+
+If you have weird messages about sphinx warnings that happen on “Console output”, those are coming either from summary functions in algorithms or from parameter descriptions. In these
+
+* *Do not* use ``*`` in parameter names or summary. This yields “Inline emphasis start-string without end-string” warnings.
+* *Do not* use things like ``|Q|``. This yields sphinx error “Undefined substitution referenced”.
+* When using hyperlinks with a label, try to use anonymous hyperlinks (two underscores instead of one) to avoid name clashes. 
+   * ```MD <http://mysite.com/MD1.html>`__`` and ```MD <http://mysite.com/MD2.html>`__`` instead of ```MD <http://mysite.com/MD1.html>`_`` and ```MD <http://mysite.com/MD2.html>`_``. The second on will result in a warning.
+
+Common Warnings and Fixes
+-------------------------
+
+While building the final output, Sphinx will emit warning messages if it things the input restructured text is malformed. This section lists some more common warnings along with suggestions for fixes. 
+
+Explicit markup ends without a blank line; unexpected unindent.
+###############################################################
+
+This is caused by the lack of a blank line between an indented explicit markup block and more unindented text, e.g.
+
+.. code-block:: rest
+
+   .. testcode:: ExHist
+
+      print "This is a test"
+    Output:                         <------------- There should be a blank line above this
+
+    .. testoutput:: ExHist
+
+It can be fixed by having a blank line between the indented block and the unindented text.
+
+Inline interpreted text or phrase reference start-string without end-string
+###########################################################################
+
+This is caused by using one of the `inline markup tags <http://www.sphinx-doc.org/en/master/rest.html#inline-markup>`__, where the text being wrapped splits over multiple lines. In these cases the directive variant of the inline markup should be used. One example is the ``:math:`` tag being spread over multiple lines. The tag ``:math:`` must only be used for inline markup, i.e. when there is no newline in the math string. For multi-line maths markup you must use the ``.. math::`` directive instead. 
+
+.. code-block:: rest
+
+   :math:`\rm U \rm B \left(
+                                \begin{array}{c}
+                                  h_i \\
+                                  k_i \\
+                                  l_i \\
+                                \end{array}
+                               \right) = \rm Q_{gon,i}` (1)
+
+should be written
+
+.. code-block:: rest
+
+   .. math::
+                                                                   <------------------ intentional blank line
+               \rm U \rm B \left(
+                                   \begin{array}{c}
+                                     h_i \\
+                                     k_i \\
+                                     l_i \\
+                                   \end{array}
+                                  \right) = \rm Q_{gon,i} (1)
+                                                                   <------------------ intentional blank line
+
+where there is an explicit blank line after the final line of latex. See `here <http://sphinx-doc.org/ext/math.html>`__ for more information.
+
+image file not readable
+#######################
+
+This indicates the that image referenced by ``.. image::`` or ``.. figure::`` cannot be accessed. Either the image is not there or the reference is incorrect.
+
+Image links in Sphinx are either relative, in which case it is relative to the current document or absolute in which case the path is assumed relative to the root of the source tree (the directory containing the conf.py)
+
+Unknown directive type "foo"
+############################
+
+Sphinx has encountered a line starting with ``.. foo::``, where ``foo`` is expected to be a known directive.
+
+The fix is to correct the name of the directive.
+
+Warnings on console (in the build servers)
+##########################################
+
+These type of errors occur in the summary function and/or in documentation of parameters in the init function. See `Things to Avoid`_.
+
+Running documentation tests locally
+===================================
+
+The usage tests are executed using a driver script, ``runsphinx_doctest.py``, that is generated by CMake in the ``docs`` directory. A top-level target, ``docs-test``, is created for each generator that invokes the script without any arguments and subsequently executes all of the available usage tests.
+
+The driver script has been written to accept additional arguments in order to be able to limit the number of tests that are executed. To run a subset of the available tests, the script must be called manually and supplied with the ``-R TESTREGEX`` argument. The regex is applied to the filename of the document and will match anywhere within the name. The script can be called using either a plain Python interpreter or the MantidPlot executable. If using a plain Python interpreter then you will need to either have your ``PYTHONPATH`` set to find the ``mantid`` module or you can provide the ``-m MANTIDPATH`` option to have the script find the module for you.
+
+It is recommended that the tests are run with MantidPlot as this is the easiest way to be sure that they are being run with the current build copy. As an example, to run any files that have Rebin in the filename you would type (assuming you are in the build directory):
+
+::
+
+   bin/MantidPlot -xq docs/runsphinx_doctest.py -R Rebin
+
+or with vanilla python
+
+::
+
+   python docs/runsphinx_doctest.py -m $PWD/bin -R Rebin
+
+For multi-configuration generators such as Visual Studio or XCode you will need to pick the configuration by choosing the apporiate directory, e.g. for MSVC debug (remembering that the slashes need to be backslash and not forward slash):
+
+::
+
+   bin\Debug\MantidPlot -xq docs\runsphinx_doctest.py -R Rebin
diff --git a/dev-docs/source/Standards/InterfaceDocumentation.rst b/dev-docs/source/Standards/InterfaceDocumentation.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1e49cbb60f01c4148f95f1665f3a1f07918d55f5
--- /dev/null
+++ b/dev-docs/source/Standards/InterfaceDocumentation.rst
@@ -0,0 +1,53 @@
+.. _InterfaceDocumentation:
+
+=======================
+Interface Documentation
+=======================
+
+.. contents::
+  :local:
+
+Summary
+=======
+
+This page deals with the specifics of how to document Custom Interfaces. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs <DocumentationGuideForDevs.html>`__.
+
+The ``interface`` Directive
+===========================
+
+This directive allows you to insert a screenshot of the interface into the documentation. It has one required argument: the name of the interface, as given by the interface's ``name()`` method. Several options, detailed below, may also be provided to further control the behaviour of this directive.
+
+The inserted screenshots are generated automatically when the documentation is being compiled. This is preferable to screenshots taken manually as these will automatically stay up to date. 
+
+Options
+-------
+
+widget
+   You can give the name of a widget in the interface to only take a screenshot of that widget. If not given, a screenshot of the entire interface will be inserted.
+
+align
+   This specifies the alignment to use for the screenshot. Valid settings are *left*, *center*, and *right*. Defaults to *center*.
+
+Examples
+========
+
+This inserts a screenshot of the Muon Analysis interface:
+
+.. code-block:: rest
+
+   .. interface:: Muon Analysis
+
+This inserts a screenshot of the Muon Analysis interface's Grouping Options tab:
+
+.. code-block:: rest
+
+   .. interface:: Muon Analysis
+      :widget: GroupingOptions
+
+This inserts a screenshot of the main table in the ISIS Reflectometry custom interface, aligned to the right:
+
+.. code-block:: rest
+
+   .. interface:: ISIS Reflectometry
+      :widget: viewTable
+      :align: right
diff --git a/dev-docs/source/Standards/Libraries.rst b/dev-docs/source/Standards/Libraries.rst
new file mode 100644
index 0000000000000000000000000000000000000000..391175de080f0403e08b36a239af3187098e9bf1
--- /dev/null
+++ b/dev-docs/source/Standards/Libraries.rst
@@ -0,0 +1,53 @@
+.. _Libraries:
+
+=========
+Libraries
+=========
+
+.. contents:: Contents
+   :local:
+
+Summary
+^^^^^^^
+
+This page describes the preferred libraries used with the Mantid code
+base.
+
+General
+^^^^^^^
+
+- Use libraries from `std <http://en.cppreference.com/w/cpp>`_ where possible.
+- `Boost <http://www.boost.org>`_ header-only libraries are also
+  always available. The following compiled Boost libraries are
+  available:
+
+  - regex
+  - date_time
+  - python
+  - serialization
+  - others required must be discussed with the TSC
+
+- Eigen is used for fast linear algebra calculations
+- Poco is also used for:
+
+  - asynchronous method support
+  - application configuration
+  - logging
+  - path handling (will eventually be replaced by std::filesystem)
+  - networking
+  - XML parsing
+
+Specific Recommendations
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Regex
+-----
+
+Prefer ``boost::regex`` over ``std::regex`` (bugs in ``std::regex``
+until gcc 5 and some platforms still use gcc 4.8)
+
+String Algorithms (chop, ends_with etc)
+---------------------------------------
+
+- Prefer Boost algorithms if possible
+- Some string utilities also exist in ``MantidKernel/Strings.h``
diff --git a/dev-docs/source/Standards/MantidStandards.rst b/dev-docs/source/Standards/MantidStandards.rst
new file mode 100644
index 0000000000000000000000000000000000000000..adfa95c3beecd23abf4a54afb0fd2f2394b5ca90
--- /dev/null
+++ b/dev-docs/source/Standards/MantidStandards.rst
@@ -0,0 +1,119 @@
+================
+Mantid Standards
+================
+
+These standards relate specifically to the implementation of the
+Mantid framework and the MantidPlot application.
+
+.. contents:: Contents
+   :local:
+
+General Notes on Naming
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The items described on this page form part of the public interface to
+Mantid, which means that their names are hard to change once they are
+out in the wild. As naming is one of the most difficult tasks to `do
+well <http://martinfowler.com/bliki/TwoHardThings.html>`_, it is
+important to take time and care when choosing a name. Some guidance on
+naming in a more code-related context can be found `here
+<http://blog.codinghorror.com/i-shall-call-it-somethingmanager/>`_ but
+the advice should still be applicable to naming Mantid concepts.
+
+Algorithms
+^^^^^^^^^^
+
+Standards to follow when implementing an `algorithm
+<http://docs.mantidproject.org/nightly/concepts/Algorithm.html>`_ in
+both C++ and Python.
+
+Naming
+------
+
+Algorithm names start with a capital letter and have a capital letter
+for each new word, with no underscores. Use alphabet and numeric
+characters only. Numbers are only allowed after the first character.
+
+Names should be descriptive but not too long (max 20 chars). If
+possible, avoid abbreviations unless they are common and well
+understood. To avoid a proliferation of different synonyms for
+algorithms that have a common goal, e.g. Create... vs Generate..., we
+standardise on a set of prefixes for common tasks:
+
++-----------------------------------------------------------------------+------------------+--------------------+
+| Task                                                                  | Preferred Prefix | Example            |
++=======================================================================+==================+====================+
+| Creating a new object, e.g. workspace, with exception of file loaders | Create           | CreateMDWorkspace  |
++-----------------------------------------------------------------------+------------------+--------------------+
+| Loading a file                                                        | Load             | LoadMappingTable   |
++-----------------------------------------------------------------------+------------------+--------------------+
+| Applying a value to an existing object, e.g set UB matrix             | Set              | SetUB              |
++-----------------------------------------------------------------------+------------------+--------------------+
+| Retrieve a value, e.g. Ei                                             | Get              | GetDetectorOffsets |
++-----------------------------------------------------------------------+------------------+--------------------+
+| Adding a new item to an existing list                                 | Add              | AddSampleLog       |
++-----------------------------------------------------------------------+------------------+--------------------+
+| Search for something, e.g. peaks                                      | Find             | FindPeaks          |
++-----------------------------------------------------------------------+------------------+--------------------+
+
+Categories
+----------
+
+Plain english using `Title Case
+<http://www.grammar-monster.com/lessons/capital_letters_title_case.htm>`_. Connecting
+words should have lower case first letters. Use alphabet characters
+only, numbers are not allowed, e.g. Muon or SANS.
+
+Properties
+----------
+
+Property names start with a capital letter and have a capital letter
+for each new word, with no underscores. Use alphabet and numeric
+characters only. Numbers are only allowed after the first character.
+
+Wherever possible and unambiguous, the primary input workspace should
+be called ``InputWorkspace`` and the primary output workspace should
+be called ``OutputWorkspace``. An algorithm with a single In/Out
+workspace should name its property ``Workspace``. Certain groups of
+algorithms have other standards to adhere to.
+
+Fit Functions
+^^^^^^^^^^^^^
+
+Standards to following when implementing a fitting function (both C++
+& Python).
+
+Naming
+------
+
+Function names start with a capital letter and have a capital letter
+for each new word, with no underscores. Use alphabet and numeric
+characters only. Numbers are only allowed after the first character.
+
+
+Categories
+----------
+
+Plain english using `Title Case
+<http://www.grammar-monster.com/lessons/capital_letters_title_case.htm>`_. Connecting
+words should have lower case first letters. Numbers are not allowed.
+
+Parameters
+----------
+
+Parameter names must:
+
+- Start with a capital letter
+- Have a capital letter for each new word (e.g. 'InputWorkspace')
+- Use alphanumeric characters only (i.e. cannot contain any of these ``/,._-'\"`` or whitespace)
+- Can contain numbers but only allowed after the first character. 
+
+Notable exceptions to these rules are lattice constants (i.e. a, b, c,
+alpha, beta, gamma).
+
+Workspace Names
+^^^^^^^^^^^^^^^
+
+No firm restrictions. The use of two underscores as a prefix will mark
+the workspace as hidden. It is recommended to use only the alphabet,
+numeric and the underscore characters.
diff --git a/dev-docs/source/Standards/PythonStandards.rst b/dev-docs/source/Standards/PythonStandards.rst
new file mode 100644
index 0000000000000000000000000000000000000000..605cb141fb1b2d304da235dd770f7cac3cdbb2af
--- /dev/null
+++ b/dev-docs/source/Standards/PythonStandards.rst
@@ -0,0 +1,65 @@
+=======================
+Python Coding Standards
+=======================
+
+.. contents:: Contents
+   :local:
+
+Style
+^^^^^
+
+- Unless otherwise specified, follow `PEP 8
+  <https://www.python.org/dev/peps/pep-0008>`_; this means using
+  `snake_case <https://en.wikipedia.org/wiki/Snake_case>`_
+- Use `flake8 <http://flake8.pycqa.org/en/latest>`_ to check
+  for problems in this area. Remember that PEP 8 is only a guide, so
+  respect the style of the surrounding code as a primary goal
+- Always use four spaces for indentation
+- For docstrings please follow `Docstring Conventions PEP 257
+  <https://www.python.org/dev/peps/pep-0257>`_ and document code to
+  aid `sphinx
+  <https://pythonhosted.org/an_example_pypi_project/sphinx.html#full-code-example>`_
+
+None checks
+-----------  
+
+Prefer ``if obj is not None:`` over ``if obj:``. The latter invokes
+``object.__nonzero__`` whereas the former simply compares that obj
+references the same object as ``None``.
+
+Imports
+-------
+
+Imports should be grouped in the following order:
+
+1. stdlib
+2. third party libraries
+3. local modules
+
+Each group should be alphabetically sorted and separate by a newline, e.g.
+
+.. code-block:: python
+
+    import sys
+
+    from qtpy.QtWidgets import QMainWindow
+
+    from mypackage.subpkg import MyClass
+
+Python/Qt
+^^^^^^^^^
+
+Use the `qtpy <https://pypi.python.org/pypi/QtPy>`_ module to hide the
+differences between PyQt versions.  When working with signals, use the
+new style. For naming new custom signals, use the ``sig_`` prefix:
+
+.. code-block:: python
+
+    from qtpy.QtCore import Signal
+    ...
+
+    class MyWidget(...):
+        """Funky new widget"""    
+
+        # Signals
+        sig_run_a_thing_happened = Signal(str, str, str, bool, bool)
diff --git a/dev-docs/source/Standards/UnitTestStandards.rst b/dev-docs/source/Standards/UnitTestStandards.rst
new file mode 100644
index 0000000000000000000000000000000000000000..04c82103bbe978cd21506f636321e904f2834976
--- /dev/null
+++ b/dev-docs/source/Standards/UnitTestStandards.rst
@@ -0,0 +1,25 @@
+.. _UnitTestCodingStandards:
+
+==========================
+Unit Test Coding Standards
+==========================
+
+The code for unit test classes should follow the standards as set out
+in :ref:`CppCodingStandards` with the following differences.
+
+- The file and class name should be of the form ``ClassNameTest``, for
+  example ``WorkspaceTest``, ``LoggerTest``
+- Test classes do not need to be included in a namespace.
+- Test methods within the test classes must start with the word 'test'
+  and then describe the test. For example ``test_readXValues``,
+  ``test_invalidLogString``
+- Other utility methods may be used in test classes but must not start
+  with the word test
+- During debugging Test methods may be disabled by prefixing the
+  method name with 'x'. However if any disabled tests are to be
+  checked in this must be accompanied with comments explaining why the
+  test is disabled and when it may be enabled again.
+- Code headers are not required if the above standards are met as the
+  use of the class will be obvious from the class name and method
+  names.
+
diff --git a/dev-docs/source/Standards/index.rst b/dev-docs/source/Standards/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..20709a3f984ff07e6e82d93b1a044750509481ac
--- /dev/null
+++ b/dev-docs/source/Standards/index.rst
@@ -0,0 +1,44 @@
+.. _Standards:
+
+=========
+Standards
+=========
+
+Coding Standards
+----------------
+
+Coding standards are vital for creating a maintainable and extensible
+system. However in order for them to be effective they have to be
+accepted and supported by the entire development team.
+
+Code produced by code generators is not covered directly by this
+procedure. Programmers must apply the underlying principles of this
+procedure in a sensible manner to code generated automatically.
+
+.. toctree::
+   :maxdepth: 1
+
+   MantidStandards
+   CPPStandards
+   UnitTestStandards
+   PythonStandards
+
+Documentation Standards
+-----------------------
+
+.. toctree::
+   :maxdepth: 1
+
+   DocumentationGuideForDevs
+   AlgorithmDocumentation
+   AlgorithmUsageExamples
+   InterfaceDocumentation
+
+
+Guidelines
+----------
+
+.. toctree::
+   :maxdepth: 1
+
+   Libraries
diff --git a/dev-docs/source/SystemTests.rst b/dev-docs/source/SystemTests.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b0c2cd06dfc388bd7ab2c58d1e803b6531aa5951
--- /dev/null
+++ b/dev-docs/source/SystemTests.rst
@@ -0,0 +1,227 @@
+.. _SystemTests:
+
+============
+System Tests
+============
+
+.. contents::
+  :local:
+
+Overview
+########
+
+System tests are high-level tests, which check that Mantid is able to
+reproduce accepted, standardised results as part of its calculations,
+when executing user stories. The system test suite is written against
+Mantid's Python API.
+
+As part of our nightly-build and nightly-test procedure, Mantid's system
+tests are run as acceptance tests. The nightly-test jobs deploy a
+packaged version of Mantid to the target OS, before executing the system
+tests scripts on that environment.
+
+Writing a Test
+##############
+
+The (python) code for the system tests can be found in the git
+repository at
+`mantidproject/mantid <http://github.com/mantidproject/mantid>`__, under
+the ``Testing/SystemTests`` directory.
+
+Like their 'stress' equivalents (`stress testing <Stress_Tests>`__),
+system tests inherit from the stresstesting.MantidStressTest class. The
+methods that need to be overridden are ``runTest(self)``, where the
+python code that runs the test should be placed, and ``validate(self)``,
+which should simply return a pair of strings: the name of the final
+workspace that results from the ``runTest`` method and the name of a
+nexus file that should be saved in the ReferenceResults sub-directory in
+the repository. The test code itself is likely to be the output of a
+*Save History* command, though it can be any python code. In the
+unlikely case of files being used during a system test, implement the
+method ``requiredFiles`` which should return a list of filenames without
+paths. The file to validate against should be included as well. If any
+of those files are missing the test will be marked as skipped.
+
+The tests should be added to the ``Testing/SystemTests/tests/analysis``,
+with the template result going in the ``reference`` sub-folder. It will
+then be included in the suite of tests from the following night.
+
+Specifying Validation
+---------------------
+
+You may need to inform the System Test Suite about the format of that
+the benchmark workspace you wish to validate against. By default, the
+system tests assume that the second argument returned by the validate
+tuple is the name of a nexus file to validate against. However you can
+override the validateMethod on a test with any one of three options.
+
+-  WorkspaceToNexus (Benchmark workspace is stored as a Nexus file)
+   (default)
+-  WorkspaceToWorkspace (Benchmark workspace is stored as a workspace)
+-  ValidateAscii (Benchmark workspace is stored as an ascii file)
+
+For example:
+
+.. code-block:: python
+
+    def validateMethod(self):
+        return 'WorkspaceToNeXus'
+
+No Workspace Validation
+-----------------------
+
+If the system test does not need comparison/validation against a
+standard workpace, then this step can be skipped. Simply omitting the
+
+.. code-block:: python
+
+   def validate(self):
+
+method from the system test is sufficient.
+
+Skipping tests
+--------------
+
+Tests can be skipped based on arbitrary criteria by implementing the
+``skipTests`` method and returning True if your criteria are met, and
+False otherwise. Examples are the availability of a data file or of
+certain python modules (e.g. for the XML validation tests).
+
+Target Platform Based on Free Memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some tests consume a large amount memory resources, and are therefore
+best executed on hardware where enough memory is available. You can set
+a minimum RAM specification by overriding requiredMemoryMB:
+
+.. code-block:: python
+
+   def requiredMemoryMB(self):
+       return 2000
+
+The above function limits the test to run on a machine where there is at
+least 2GB of free memory.
+
+Target Platform Based on Free Memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some tests require very large files that cannot be placed in the shared
+repository. The ``requiredFiles()`` method returns a list of these files
+so that they test can check that they are all available. If all files
+are not available then the tests are skipped.
+
+.. code-block:: python
+
+   def requiredFiles(self):
+       return ['a.nxs', 'b.nxs']
+
+The above function limits the test to run on a machine that can find the
+files 'a.nxs' & 'b.nxs'
+
+Set the Tolerance
+-----------------
+
+You may specialise the tolerance used by ``CompareWorkspace`` in your
+system test.
+
+.. code-block:: python
+
+   self.tolerance = 0.00000001
+
+Disable Some Checks
+-------------------
+
+You may disable some checks performed by the ``CompareWorkspaces``
+algorithm by appending them to the disableChecking list, which, by
+default, is empty.
+
+.. code-block:: python
+
+   # A list of things not to check when validating
+   self.disableChecking = []
+
+Assertions
+----------
+
+Additional assertions can be used as the basis for your own comparison
+tests. The following assertions are already implemented in the base
+class.
+
+.. code-block:: python
+
+   def assertTrue(self, value, msg=""):
+   def assertEqual(self, value, expected, msg=""):
+   def assertDelta(self, value, expected, delta, msg=""):
+   def assertLessThan(self, value, expected, msg=""):
+   def assertGreaterThan(self, value, expected, msg=""):
+
+Running Tests Locally
+#####################
+
+CMake configures a script file called ``systemtest`` (``systemtest.bat``
+on Windows) in the root of the build directory. This file is the driver
+script to execute the system tests that runs the lower-level
+``Testing/SystemTests/scripts/runSystemTests.py`` script but ensures
+that the environment is set up correctly for that particular build and
+that the required test data has been updated. The script accepts a
+``-h`` option to print out the standard usage information.
+
+Usage differs depending on whether you are using a single-configuration
+generator with CMake, for example Makefiles/Ninja, or a
+multi-configuration generator such as Visual Studio or Xcode.
+
+Visual Studio/Xcode
+-------------------
+
+The user must first open command-prompt from, the build directory. The
+script requires the developer to select the configuration that will be
+used to execute the tests, one of: *Release*, *Debug*, *RelWithDebInfo*
+or 'MinSizeRelease''. Note that the script does not build the code so
+the chosen configuration must have already been built. An example to
+execute all of the tests for the release configuration would be (in the
+command-prompt):
+
+.. code-block:: sh
+
+    > systemtest -C Release
+
+Makefile-like Generators
+------------------------
+
+The script requires no additional arguments as the configuration is
+fixed when running CMake, e.g.
+
+.. code-block:: sh
+
+   cd build
+   systemtest
+
+Selecting Tests To Run
+----------------------
+
+The most important option on the script is the ``-R`` option. This
+restricts the tests that will run to those that match the given regex,
+e.g.
+
+.. code-block:: sh
+
+   cd build
+   systemtest -R SNS
+   # or for msvc/xcode
+   systemtest -C <cfg> -R SNS
+
+would run all of the tests whose name contains SNS.
+
+Adding New Data & References Files
+----------------------------------
+
+The data is managed by CMake's external data system that is described by
+:ref:`DataFilesForTesting`. Please see :ref:`DataFilesForTesting_AddingANewFile` for how to add new
+files.
+
+Best Practice
+#############
+
+-  Always check your test works locally before making it public.
+-  User stories should come from the users themselves where possible.
+-  Take care to set the tolerance to an acceptable level.
diff --git a/dev-docs/source/TSC.rst b/dev-docs/source/TSC.rst
new file mode 100644
index 0000000000000000000000000000000000000000..dcab065a261074c5a96fbfde823d4d495ce5c7e4
--- /dev/null
+++ b/dev-docs/source/TSC.rst
@@ -0,0 +1,13 @@
+.. _TSC:
+
+============================
+Technical Steering Committee
+============================
+
+Please see the `TSC terms <https://github.com/mantidproject/documents/blob/master/Project-Management/TechnicalSteeringCommittee/TSC-Terms.md>`__
+for a description of the aims of this committee including a list of current members.
+
+Contact email: mantid-tech@mantidproject.org
+
+Minutes and reports from Technical Steering Committee meetings can be found
+`here <http://github.com/mantidproject/documents/tree/master/Project-Management/TechnicalSteeringCommittee>`__.
diff --git a/dev-docs/source/TestingUtilities.rst b/dev-docs/source/TestingUtilities.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5f109ed05d074c0a0a159fb286bec3ed61d5bb5d
--- /dev/null
+++ b/dev-docs/source/TestingUtilities.rst
@@ -0,0 +1,50 @@
+.. _TestingUtilities:
+
+=================
+Testing Utilities
+=================
+
+.. contents::
+  :local:
+
+Summary
+#######
+
+This page will provide developers with details of testing utilities, such as helper files, which are
+useful in creating unit tests.
+
+
+Helper Functions
+################
+
+C++
+---
+
+The following helper files have been found in the
+`Mantid/Framework/TestHelpers <http://github.com/mantidproject/mantid/tree/master/Framework/TestHelpers>`__
+package:
+
+-  `BinaryOperationMDTestHelper <http://doxygen.mantidproject.org/d1/d4f/namespaceBinaryOperationMDTestHelper.html>`__
+-  ComponentCreationHelper
+   `ComponentCreationHelper <http://doxygen.mantidproject.org/d8/d8d/namespaceComponentCreationHelper.html>`__
+   This creates instrument components that can then be used in a unit test.
+-  ICatTestHelper
+-  `MDEventsTestHelper <http://doxygen.mantidproject.org/d5/d75/namespaceMantid_1_1MDEvents_1_1MDEventsTestHelper.html>`__
+-  `SANSInstrumentCreationHelper <http://doxygen.mantidproject.org/d9/dbf/classSANSInstrumentCreationHelper.html>`__
+-  `ScopedFileHelper <http://doxygen.mantidproject.org/d7/d7f/classScopedFileHelper_1_1ScopedFile.html#details>`__
+   This creates a file that is automatically deleted when no longer needed.
+-  `WorkspaceCreationHelper <http://doxygen.mantidproject.org/d1/db6/namespaceWorkspaceCreationHelper.html>`__
+   This creates simple workspaces that can be used in a unit test. One of these workspaces has a full instrument.
+
+Python
+------
+
+There are some ``testhelpers`` which are only available in Python, they can
+be found in the ``testhelpers``-package.
+
+-  ``make_decorator`` - A function that returns a decorator for an
+   algorithm without executing it.
+-  ``TemporaryFileHelper`` - A class that creates named temporary files
+   and deletes them automatically when the object is deleted. Basically
+   a thin wrapper around `NamedTemporaryFile <https://docs.python.org/2/library/tempfile.html>`__
+   from the tempfile package.
diff --git a/dev-docs/source/ToolsOverview.rst b/dev-docs/source/ToolsOverview.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1a3ff35b442a32a0fe0c53d93cd61ae43fe8ce64
--- /dev/null
+++ b/dev-docs/source/ToolsOverview.rst
@@ -0,0 +1,161 @@
+.. _ToolsOverview:
+
+==============
+Tools Overview
+==============
+
+Creating classes: class_maker.py
+--------------------------------
+
+**To make it faster to create a new class**. This is a small python
+script located in /buildconfig/. It generates the .cpp, .h and test
+files for a class along with some code stubs. It can also flesh out more
+methods for new Algorithms, using the "--alg" option.
+
+::
+
+    usage: class_maker.py [-h] [--force] [--test] [--alg] SUBPROJECT CLASSNAME
+    Utility to create Mantid class files: header, source and test.
+    positional arguments:
+     SUBPROJECT  The subproject under Framework/; e.g. Kernel
+     CLASSNAME   Name of the class to create
+    optional arguments:
+     -h, --help  show this help message and exit
+     --force     Force overwriting existing files. Use with caution!
+     --test      Create only the test file.
+     --alg       Create an Algorithm stub. This adds some methods common to
+                 algorithms.
+
+Moving/Renaming classes: move_class.py
+--------------------------------------
+
+This python script is located in in /buidconfig/. It will move a class
+from one subproject to another and/or rename the class. Namespaces and
+cmakelists are adjusted. For details, run:
+
+``buildconfig/move_class.py --help``
+
+Deleting a class: delete_class.py
+---------------------------------
+
+This python script is located in in /buildconfig/. It will delete a
+class from one subproject. CMakeList.txt is adjusted. For details, run:
+
+``buildconfig/delete_class.py --help``
+
+Leak checking etc
+-----------------
+
+Linux
+~~~~~
+
+`Memcheck <http://valgrind.org/docs/manual/mc-manual.html>`__
+
+-  Keeps track of allocs/deallocs and reports anything missing at exit.
+-  Slow but thorough
+-  Useful options to run with
+
+``valgrind --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --freelist-vol=500000000 ``\ \ `` [args...]``
+
+Windows
+~~~~~~~
+
+`Visual Leak Detector <https://vld.codeplex.com/releases>`__
+
+#. Setup the additional paths as defined in the readme file
+#. Adjust the configuration file, "C:\Program Files\Visual Leak
+   Detector\vld.ini" to output to both File and debugger by changing the
+   ``ReportTo`` to
+
+``ReportTo = both``
+
+#. Add #include <vld.h> to the system.h file in Kernel
+#. Compile everything in debug
+#. Running unit tests should now create a file memory_leak_report.txt in
+   the test directory.
+#. IMPORTANT remove the #include <vld.ini> before checking in.
+
+Thread checking
+---------------
+
+`Helgrind <http://valgrind.org/docs/manual/hg-manual.html>`__ or  `drd <http://valgrind.org/docs/manual/drd-manual.html>`__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-  Identifies race conditions & dead-locks
+-  Slow but accurate
+-  A pain to get working with OpenMP. GCC must be recompiled to use a different call to create OMP threads or helgrind/drd cannot "see" the thread calls. Use this `script <https://github.com/UCSCSlang/Adversarial-Helgrind/raw/master/drd/scripts/download-and-build-gcc>`__ to recompile the same version off gcc that is onyour system. The script will need editing to change the appropriate variables.
+
+Profiling
+---------
+
+.. _linux-1:
+
+Linux
+~~~~~
+
+`Callgrind/KCachegrind <http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindIndex>`__
+
+-  KCachegrind visualizes callgrind output.
+-  See :ref:`Profiling With Valgrind <ProfilingWithValgrind>` for help on
+   running callgrind
+
+`gperftools <https://github.com/gperftools/gperftools>`__
+
+-  Takes snapshot of run and prints percentage of calls in functions
+
+See here for a list of other tools:
+http://www.pixelbeat.org/programming/profiling/
+
+.. _windows-1:
+
+Windows
+~~~~~~~
+
+`Very Sleepy <http://www.codersnotes.com/sleepy/>`__ (Windows):
+
+-  Start/stop recording of program using a button
+-  Not as detailed or flexible as callgrind
+
+IWYU
+----
+
+`include what you
+use <https://code.google.com/p/include-what-you-use/>`__ (iwyu) is a
+clang-based tool for determining what include statements are needed in
+C/C++ files. Below are instructions for getting it to run with mantid on
+linux which is a filled in version of `this
+bug <https://code.google.com/p/include-what-you-use/issues/detail?id=164>`__.
+
+#. Install the software. The version available from system installs
+   should be fine (e.g. yum or apt-get).
+#. Get a copy of
+   `iwyu_tool.py <https://code.google.com/p/include-what-you-use/source/browse/trunk/iwyu_tool.py>`__
+   which is in the project's repository, but may not be installed if you
+   got it from your operating system locations (e.g. yum).
+#. Run ``cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE``. This will
+   generate an extra file, ``compile_commands.json``, in your build area
+   which has instructions on compiling every file in mantid.
+#. Run :literal:`iwyu_tool.py -p `pwd` 2> iwyu.log` to generate the
+   report of changes redirecting into the file ``iwyu.log``. This will
+   take a long time since it is going through the whole repository. If
+   you want it for a single file, then supply that as an additional
+   argument with full path. Only one file can be supplied at a time.
+#. Run ``fix_includes < iwyu.log`` and compile the results. Depending on
+   how you installed iwyu, the program may be called
+   ``fix_includes.py``. If it doesn't compile, the most likely suspect
+   is that iwyu included a private header. See `iwyu instructions for
+   users <https://code.google.com/p/include-what-you-use/wiki/InstructionsForUsers#How_to_Run>`__
+   for ways to handle this. Generally, they suggest deleting the
+   offending lines.
+#. Check that your build path didn't make it into source files. Since
+   ``compile_commands.json`` has full paths, iwyu will put full paths in
+   the include statements. This will not produce an error on your
+   system, but it will on the build servers. The easiest way to check is
+   to use `the silver
+   searcher <https://github.com/ggreer/the_silver_searcher>`__ to check
+   for your username in your source tree.
+#. Enjoy your success.
+
+**Note:** ``iwyu`` outputs to ``stderr`` and always returns a failure
+status code since it generates no output. The output stream also affects
+``iwyu_tool.py``
diff --git a/dev-docs/source/UnitTestGoodPractice.rst b/dev-docs/source/UnitTestGoodPractice.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4ffc8c672e183fe868f2de0feb252be2c5e12c9e
--- /dev/null
+++ b/dev-docs/source/UnitTestGoodPractice.rst
@@ -0,0 +1,191 @@
+.. _UnitTestGoodPractice:
+
+=======================
+Unit Test Good Practice
+=======================
+
+.. contents::
+  :local:
+
+General Guidance
+################
+
+What to test
+------------
+
+Simply put you should test.
+
+-  Every public member of a class.
+-  That the class can be cast to any of the interfaces or base classes
+   it inherits from.
+-  Any private or protected members.
+
+   -  That aren’t directly covered by a public method test.
+   -  That do any significant processing.
+
+For each method you are testing you should include tests for the
+following:
+
+-  To confirm that the methods meet the requirements associated with
+   them. Thus the test should verify that the function does what it is
+   supposed to do.
+-  To confirm the expected behaviour for boundary and special values.
+-  To confirm that exceptions are thrown when expected.
+
+How to test private or protected members of a class
+---------------------------------------------------
+
+Testing the internals of a class can be considered harmful as it exposes
+the internals of the class, which can arguably be freely changed (so
+long as it does not affect the function of the public interface).
+However there are cases where the internals of a class need unit tests
+either due to complexity or tracking down specific bugs.
+
+In the circumstance where the implementation within the private/protected
+methods of a class is sufficiently complex, such to require dedicated unit
+tests, this code should be moved into a separate class(es).
+
+Protected
+~~~~~~~~~
+
+Within the test library you can add a new testable class that inherits
+from the class you need to test. This class can simply expose any
+protected methods as testable public methods.
+
+Private
+~~~~~~~
+
+There is no ideal way to test a private member of a class as they are
+intentionally hidden from the class interface. There are two options to
+consider in preference order:
+
+#. Change the protection level to protected and follow the approach
+   above.
+#. Declare the test class as a friend, which can access private members.
+
+Good practices for writing tests
+--------------------------------
+
+The following are good practices for writing your unit tests. Many of
+them are standard good coding practices. You will notice that in several
+situations they can clash with each other, in this case common sense
+needs to be applied.
+
+-  Unit tests should test one method only. This allows you to easily
+   identify what failed if the test fails.
+-  Unit tests should not be coupled together, therefore one unit test
+   **CANNOT** rely on another unit test having completed first.
+
+These two often clash, in which case it is often better to compromise on
+the first, and in fact we have relaxed this rule for Mantid (see below).
+
+-  Units tests should use realistic data
+-  Unit tests should use small and simple data sets.
+
+Again these can often conflict.
+
+-  Each test class should be named after the class it is testing (e.g.
+   tests for the ``AlgorithmFactory`` should go in a ``AlgorithmFactoryTest``
+   class).
+-  Each test within a test class should use a descriptive test name,
+   prefixed with test (tests for the ``CreateAlgorithm`` method would be
+   included in ``testCreateAlgorithm``). If there are specific tests for
+   failure situations then these should be added to the end (e.g.
+   ``testCreateAlgorithmNoAlgorithmException``). THE AIM IS THAT FROM THE
+   TEST METHOD NAME ALONE, YOU SHOULD BE ABLE TO IDENTIFY THE PROBLEM.
+
+Other More General Points
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-  Tests should be **fast**, ideally really fast - certainly not more
+   than a few seconds. Unit tests test functionality, performance tests
+   can be used to check stress and timings.
+-  Untestable code is a code-smell, if you can't get the code under test
+   it probably needs refactoring.
+-  Weight your testing to be destructive rather than demonstrative.
+   Destructive tests have a higher efficacy for finding bugs.
+
+Mantid-specific Guidelines
+##########################
+
+-  As noted above, you can assume that individual tests within a cxxtest
+   suite will be run in order.
+-  There must be **no relative paths** (or, more obviously, absolute
+   ones) used in tests as with CMake the code can be build anywhere with
+   respect to the source tree. Make use of the datasearch.directories
+   property (which CMake configures to hold correct paths for a given
+   build).
+-  Ideally, test suites should not have a constructor. If one is
+   required, the following boiler-plate code **must** be inserted in the
+   test class:
+
+   .. code-block:: c++
+
+      static NameOfTest *createSuite() { return new NameOfTest(); }
+      static void destroySuite(NameOfTest *suite) { delete suite; }
+
+   where ``NameOfTest`` is the name of the test class. Without this, the
+   class is turned into a static meaning that the constructor is run at
+   initialisation even if (via an argument) you are not going to run that
+   particular test suite. Also, this can cause problems if running tests in
+   parallel.
+
+-  Be cautious in use of the ``setUp()``and ``tearDown()`` methods. Be aware
+   that if you use these in your suite they will be run before/after
+   **every single** individual test. That's fine if it's the behaviour
+   you really need, but we have found that to be rare - use the
+   constructor or set things up within the test.
+-  To avoid clashes, use unique names for workspaces that will go into
+   the [Analysis Data Service], perhaps by prepending the name of the
+   test suite. Even better, don't put workspaces into the ADS in the
+   first place: for example, an InputWorkspace property can be set via
+   pointer instead of by name.
+-  Clean up the ADS at (or before) the end of the test suite.
+
+Using files in Unit tests
+-------------------------
+
+Files for unit tests bloat our repository and slow down the testing
+process. Therefore unless the prime purpose of the algorithms is to load
+or save a file then you should not use a file in your unit tests.
+
+How do I get a workspace filled with data?
+    Firstly you want to think about how much data you really need, unit
+    tests need to be fast so you don't want too much data.
+    Secondly you should use and extend helper classes (like
+    `1 <https://github.com/mantidproject/mantid/blob/master/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h>`__)
+    to provide the workspaces for you. Keep things as generic as you can
+    and it will help you and others for other tests.
+    More details of this will be provided at `Testing Utilities <TestingUtilities>`__.
+I want a workspace with a valid instrument definition and Spectra-detector map
+    As above use or extend a method in one of the `helper classes <TestingUtilities>`__
+    that actually creates a minimal workspace for you in code - it will
+    only hurt the first time but everyone will benefit.
+    Loading instrument XML files in debug **really** hurts performance;
+    avoid this like the plague.
+What if it **really** needs a file
+    First justify your reasoning with the PM or Lead developer
+    Ensure the file is as small as possible. Perhaps edit the file to
+    only contain 2 spectra
+    Note: this is not the same as just loading 2 spectra from a large
+    file.
+    Do not use a relative path to a file
+    Used the `Scoped
+    File <https://github.com/mantidproject/mantid/blob/master/Framework/TestHelpers/inc/MantidTestHelpers/ScopedFileHelper.h>`__
+    helper, to ensure that resources are cleaned-up in an exception safe
+    manner.
+
+Mocking
+#######
+
+Mocking is a very powerful tool that allows you to simulate components
+in your unit environment and check how your code operates within this
+environment. Mocking allows you to avoid creating Fake objects of any
+kind, and results in fast executing code with a very high test coverage.
+See `Mocking <Mocking>`__ in Mantid to find out what it is and how it
+works.
+
+.. figure:: images/Mocking.png
+   :alt: Object under test using Mocking to isolate the testing.|400px
+
+   Object under test using Mocking to isolate the testing.|400px
diff --git a/dev-docs/source/VisualStudioBuildImpact.rst b/dev-docs/source/VisualStudioBuildImpact.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2d8f5cb11ba74567b2f3c7c0028836c8b8a00025
--- /dev/null
+++ b/dev-docs/source/VisualStudioBuildImpact.rst
@@ -0,0 +1,60 @@
+Visual Studio Build Impact
+==========================
+
+Building Mantid on Visual Studio can take a while, and really tie up the
+computer. This is because Visual Studio starts all of the compilation
+processes at normal priority, so they compete as equals with everything
+you are doing.
+
+So you might think that you can open task manage and reduce the priority
+of all the cl.exe processes, well there can be quite a few, and no it
+won't work for long as these processes are replaced for every file it
+compiles.
+
+What you want to do it hunt down the MSBuild.exe processes and reduce
+the priority of them, there should be the same number as you have
+logical processors. The MSBuild processes spawn all of the compiler and
+linker tasks, an they inherit the priority of the MSBuild process.
+
+Script
+------
+
+Of course if you don't want to do this yourself then you can use this
+script.
+
+::
+
+    Const BELOW_NORMAL = 16384
+     
+    strComputer = "."
+    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
+
+    Set colProcesses = objWMIService.ExecQuery _
+        ("Select * from Win32_Process Where Name = 'MSBuild.exe'")
+    For Each objProcess in colProcesses
+        objProcess.SetPriority(BELOW_NORMAL) 
+    Next
+
+Save it as Reduce_Build_Impact.vbs, and use when things are running like
+a dog!
+
+Monitoring Script
+-----------------
+
+If you don't want to keep running the script for each build, here's one
+that keeps a watch on your system every 5 seconds.
+
+::
+
+    Const BELOW_NORMAL = 16384
+     
+    strComputer = "."
+    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
+    Do While true
+      Set colProcesses = objWMIService.ExecQuery _
+          ("Select * from Win32_Process Where Name = 'MSBuild.exe'")
+      For Each objProcess in colProcesses
+          objProcess.SetPriority(BELOW_NORMAL) 
+      Next
+      WScript.Sleep 5000
+    loop
diff --git a/dev-docs/source/WritingAnAlgorithm.rst b/dev-docs/source/WritingAnAlgorithm.rst
new file mode 100644
index 0000000000000000000000000000000000000000..01f567db695e7c1d265b2c4c3e92f54685dfce65
--- /dev/null
+++ b/dev-docs/source/WritingAnAlgorithm.rst
@@ -0,0 +1,249 @@
+.. _WritingAnAlgorithm:
+
+Writing An Algorithm
+====================
+
+.. contents::
+  :local:
+
+Introduction
+############
+
+Mantid's `plugin <https://www.mantidproject.org/Plugin>`__ architecture has been engineered so that it is easy for a user 
+to write their own algorithm. This page is a primer for the user about to write their first algorithm and assumes no 
+great knowledge of C++. 
+It covers the basics, with links to more advanced options where appropriate. Note if you are looking to add a 
+`plugin <https://www.mantidproject.org/Plugin>`__ fit function rather than an algorithm then see 
+`Writing a Fit Function <https://www.mantidproject.org/Writing_a_Fit_Function>`__. 
+There is special description for the case when you are looking to add a custom `MD conversion plugin <WritingCustomConvertToMDTransformation>`__.
+
+Alternatively, you can implement your algorithm in `Python <https://www.mantidproject.org/Extending_Mantid_With_Python>`__. 
+See `Python Vs C++ Algorithms <https://www.mantidproject.org/Python_Vs_C%2B%2B_Algorithms>`__ for a comparison of Mantid's 
+two programming languages.
+
+All `algorithms <https://www.mantidproject.org/Algorithm>`__ in Mantid `inherit <http://en.wikipedia.org/wiki/Inheritance_(computer_science)>`__ 
+from a base ``Algorithm`` class, which provides the support and services required for running a specific 
+algorithm and greatly simplifies the process of writing a new one.
+
+Getting Started
+###############
+The first step is to create a new directory, with any name of your choice, under your MantidInstall directory
+(on Windows, probably located at ``C:\\MantidInstall``). Alternatively, you can just do everything in the 
+UserAlgorithms directory. The UserAlgorithms directory contains a simple Python script called ``createAlg.py``.
+This can be used to create a new 'empty' algorithm - to create one called 'MyAlg' you should type ``python 
+createAlg.py myAlg category``, where category is an optional argument to set the algorithm's category. 
+To do the same thing 'by hand', create files called ``MyAlg.h`` and ``MyAlg.cpp`` and paste in the following 
+boilerplate C++ code (changing each occurrence of 'MyAlg' to your chosen algorithm name):
+
+**Header file (MyAlg.h)**:
+
+.. code-block:: cpp
+
+    #ifndef MYALG_H_
+    #define MYALG_H_
+    
+    #include "MantidAPI/Algorithm.h"
+    
+    class MyAlg : public Mantid::API::Algorithm
+    {
+    public:
+      /// (Empty) Constructor
+      MyAlg() : Mantid::API::Algorithm() {}
+      /// Virtual destructor
+      virtual ~MyAlg() {}
+      /// Algorithm's name
+      virtual const std::string name() const { return "MyAlg"; }
+      /// Algorithm's version
+      virtual const int version() const { return (1); }
+      /// Algorithm's category for identification
+      virtual const std::string category() const { return "UserDefined"; }
+    
+    private:
+      /// Initialisation code
+      void init();
+      /// Execution code
+      void exec();
+    };
+ 
+    #endif /*MYALG_H_*/
+
+**Source file (MyAlg.cpp)**:
+
+.. code-block:: cpp
+
+    #include "MyAlg.h"
+    
+    // Register the algorithm into the AlgorithmFactory
+    DECLARE_ALGORITHM(MyAlg);
+    
+    void MyAlg::init()
+    {
+    }
+    
+    void MyAlg::exec() 
+    { 
+    }
+
+At this point you will already have something that will compile and run. To do so (on Windows), copy the files 
+``build.bat`` & ``SConstruct`` from ``UserAlgorithms`` into the directory containing your code and execute ``build.bat``. 
+If you then start MantidPlot your algorithm will appear in the list of available algorithms and could be run. 
+But, of course, it won't do anything of interest until you have written some algorithm code...
+
+Coding the Algorithm
+####################
+
+You will see that the algorithm skeletons set up in the last section contain two methods/functions/subroutines
+called ``init`` and ``exec``. It will be no surprise to discover that these will, respectively, contain the code to 
+initialise and execute the algorithm, which goes in the ``.cpp`` file between the curly brackets of each method. 
+Note that these are private methods (i.e. cannot be called directly); an algorithm is run by calling the base 
+class's ``initialize()`` and ``execute()`` methods, which provide additional services such as the validation of properties, 
+fetching workspaces from the ``AnalysisDataService``, handling errors and filling the workspace histories.
+
+Initialization
+--------------
+
+The initialization (init) method is executed by the ``FrameworkManager`` when an algorithm is requested and must
+contain the declaration of the properties required by the algorithm. Atypically, it can also contain other 
+initialization code such as the calculation of constants used by the algorithm, so long as this does not 
+rely on the values of any of the properties.
+
+Calls to the ``declareProperty`` method are used to add a property to this algorithm. See the properties page
+for more information on the types of properties supported and the example algorithms in ``UserAlgorithms`` 
+(especially `PropertyAlgorithm <http://svn.mantidproject.org/mantid/trunk/Code/Mantid/UserAlgorithms/PropertyAlgorithm.cpp>`__
+and `WorkspaceAlgorithm <http://svn.mantidproject.org/mantid/trunk/Code/Mantid/UserAlgorithms/WorkspaceAlgorithm.cpp>`__) 
+for further guidance on how to use them.
+
+For the simple types (integer, double or string), the basic syntax is::
+
+   declareProperty("UniquePropertyName",value);
+
+An optional `validator <https://www.mantidproject.org/Properties#Validators>`__ or 
+`directional argument <https://www.mantidproject.org/Properties#Direction>`__ (input, output or both)
+can also be appended. The syntax for other property types (``WorkspaceProperty`` & ``ArrayProperty``) is more 
+complex - see the `properties <https://www.mantidproject.org/Properties#Direction>`__ page or the 
+example algorithms in `UserAlgorithms <https://www.mantidproject.org/UserAlgorithms>`__ for further details.
+
+Execution
+#########
+
+Fetching properties
+-------------------
+
+Before the data can be processed, the first task is likely to be to fetch the values of the input properties. 
+This uses the ``getProperty`` method as follows::
+
+    TYPE myProperty = getProperty("PropertyName");
+
+where ``TYPE`` is the type of the property (``int``, ``double``, ``std::string``, ``std::vector``...). Note that the 
+value of a ``WorkspaceProperty`` is a `shared pointer <https://www.mantidproject.org/Shared_Pointer>`__
+to the workspace, which is referred to as ``Mantid::API::Workspace_sptr`` or ``Mantid::API::Workspace_const_sptr``. 
+The latter should be used for input workspaces that will not need to be changed in the course of the algorithm.
+
+If a handle is required on the property itself, rather than just its value, then the same method is used as follows::
+
+    Mantid::Kernel::Property* myProperty = getProperty("PropertyName");
+
+This is useful, for example, for checking whether or not an optional property has been set (using Property's 
+``isDefault()`` method).
+
+Creating the output workspace
+-----------------------------
+
+Usually, the result of an algorithm will be stored in another new workspace and the algorithm 
+will need to create that new workspace through a call to the ``WorkspaceFactory``. For the (common) 
+example where the output workspace should be of the same type and size as the input one, the code 
+would read as follows::
+
+   Mantid::API::Workspace_sptr outputWorkspace = Mantid::API::WorkspaceFactory::Instance().create(inputWorkspace);
+
+where ``inputWorkspace`` is a shared pointer to the input workspace.
+
+It is also important to, at some point, set the output workspace property to point at this workspace. 
+This is achieved through a call to the ``setProperty`` method as follows::
+
+  setProperty("OutputWorkspacePropertyName",outputWorkspace);
+
+where ``outputWorkspace`` is a shared pointer to the created output workspace.
+
+Using workspaces
+----------------
+
+The bulk of most algorithms will involve the manipulation of the data contained in workspaces 
+and information on how to interact with these is given `here <https://www.mantidproject.org/Interacting_with_Workspaces>`__. 
+The more advanced user may also want to refer to the full 
+`workspace documentation <http://doxygen.mantidproject.org/nightly/d3/de9/classMantid_1_1API_1_1Workspace.html>`__.
+
+Those familiar with C++ should make use of private methods and data members to break up the execution code into
+more manageable and readable sections.
+
+Further Features
+################
+
+The advanced user is referred to the `full documentation page <http://doxygen.mantidproject.org/nightly/d3/de9/classMantid_1_1API_1_1Workspace.html>`__
+for the ``Algorithm`` base class to explore the full range of methods available for use within an algorithm. 
+A few aspects are highlighted below.
+
+Child Algorithms
+----------------
+
+Algorithms may wish to make use of the functionality of other algorithms as part of their execution. 
+For example, if a units change is required the ``ConvertUnits`` algorithm could be used. Mantid therefore 
+has the concept of a child algorithm and this is accessed through a call to the 
+``createChildAlgorithm`` method as follows::
+
+    Mantid::API::Algorithm_sptr childAlg = createChildAlgorithm("AlgorithmName");
+
+This call will also initialise the algorithm, so the algorithm's properties can then be set and it can be executed::
+
+     childAlg->setPropertyValue("number", 0);
+     childAlg->setProperty<Workspace_sptr>("Workspace",workspacePointer);
+     childAlg->execute();
+
+Logging
+-------
+
+The ``g_log`` object enables access to the `logging <Logging>`__ facilities of Mantid, and is an invaluable 
+tool in understanding the running of your algorithms.
+
+Enhancing asynchronous running
+------------------------------
+
+Any algorithm can be run asynchronously (e.g. by MantidPlot) without modification. However, some features 
+are only enabled if code is added within the ``exec()`` method. ``Algorithm::interruption_point()`` should 
+be called at appropriate intervals so that the algorithm's execution can be interrupted. 
+``Algorithm::progress(double p)`` reports the progress of the algorithm. ``p`` must be between 
+0 (start) and 1 (finish).
+
+Exceptions
+----------
+
+It is fine to throw exceptions in your algorithms in the event of an unrecoverable failure. 
+These will be caught in the base Algorithm class, which will report the failure of the algorithm.
+
+Validation of inputs
+--------------------
+
+`Validators <https://www.mantidproject.org/Properties#Validators>`__ allow you to give feedback 
+to the user if the input of a property is incorrect (for example, typing non-numeric characters 
+in a number field).
+
+For more advanced validation, override the ``Algorithm::validateInputs()`` method. This is a 
+method that returns a map where:
+
+- The key is the name of the property that is in error.
+
+- The value is a string describing the error.
+
+This method allows you to provide validation that depends on several property values at once 
+(something that cannot be done with ``IValidator``). Its default implementation returns an empty map, 
+signifying no errors.
+
+It will be called in dialogs **after** parsing all inputs and setting the properties, but **before** executing. 
+It is also called again in the ``execute()`` call, which will throw if this returns something.
+
+In the MantidPlot GUI, this will set a "star" ``*`` label next to each property that is reporting an error. 
+This makes it easier for users to find where they went wrong.
+
+If your ``validateInputs()`` method validates an input workspace property, bear in mind that the user 
+could provide a ``WorkspaceGroup`` (or an unexpected type of workspace) - when retrieving the property, 
+check that casting it to its intended type succeeded before attempting to use it.
diff --git a/dev-docs/source/WritingCustomConvertToMDTransformation.rst b/dev-docs/source/WritingCustomConvertToMDTransformation.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6267db5a2089ebd5680a5074ea7f286d0e58f29e
--- /dev/null
+++ b/dev-docs/source/WritingCustomConvertToMDTransformation.rst
@@ -0,0 +1,197 @@
+.. _WritingCustomConvertToMDTransformation:
+
+Writing a Custom ConvertToMD Transformation
+===========================================
+
+.. contents::
+  :local:
+
+Introduction
+############
+
+This information is intended for a developer who needs to write a customized
+`ConvertToMD class <http://docs.mantidproject.org/nightly/algorithms/ConvertToMD.html>`__ (plugin). The
+plugin then becomes automatically available to use in the
+`ConvertToMD <http://docs.mantidproject.org/nightly/algorithms/ConvertToMD.html>`__ algorithm and via the
+`Create MD workspaces <http://www.mantidproject.org/Create_MD_Workspace_GUI>`__
+interface to produce multidimensional workspace for further visualization and analysis.
+
+As the MD transformation factory is similar to the `Dynamic Factory <http://www.mantidproject.org/Dynamic_Factory>`__
+used for `converting units <http://docs.mantidproject.org/nightly/concepts/UnitFactory.html>`__, the
+procedure of writing a custom ``ConvertToMD`` transformation is very similar to adding a new unit to use
+with `ConvertUnits <http://docs.mantidproject.org/nightly/algorithms/ConvertUnits.html>`__ algorithm
+or writing a new algorithm to use with Mantid.
+
+The plugin interface deals with the task of converting a generic n-dimensional point of a ``MatrixWorkspace``
+into a generic m-dimensional point of an ``MDWorkspace`` using the necessary parameters.
+
+Examples of such transformations could be a conversion of signal and error at detector num
+at specific time of flight plus log values for temperature and pressure (**The instrument's
+space**: 4 numbers + information about the detector) into 6-D point in the **Physical space
+qx,qy,qz,dE,T,P** (qx,qy,qz -- the components of momentum transfer) or into 3-D point in
+**Physical space \|Q\|,dE,Fugacity** (\|Q\| - modulus of momentum transfer).
+
+Writing a simple custom plugin
+##############################
+
+Summary
+-------
+
+If a single point of a ``MatrixWorkspace`` together with correspondent log files can be converted into a single
+``MDEvent`` (multidimensional point of MD workspace), a simple custom plugin can be written to do this transformation.
+The existing framework in this case deals with all other tasks, namely the iterations over source workspace,
+conversion of the workspace units into the units of the conversion formula, defining the target workspace,
+constructing ``MDEvent`` instances and adding these events to the ``MDWorkspace``.
+
+A ``ConvertToMD`` plugin implements ``MDTransfInterface``, so to write a plugin you must write a class
+which inherits from this interface and register this class with ``MDTransfFactory``. The macro to
+register the class with the factory is similar to the macro used to register an algorithm with
+Mantid or a ``Unit`` class with the Unit conversion factory. The macro is located in ``MDTransfFactory.h``.
+
+The class inheriting from ``MDTransfInterface`` performs two tasks:
+
+- Define the target ``MDWorkspace`` and its dimensions (both the number of dimensions and the dimension units).
+
+- Initialize the transformation and define a formula to transform a single point of input data into output data.
+
+These two tasks are mainly independent, but implemented within a single class to be handled by the single dynamic factory.
+**Note that the functions which define the target MDWorkspace are called before the MDTransfFactory initialize function.**
+The ``initialize`` function accepts the ``MDWorkspace`` description and is expected to fully define all class variables used during
+the transformation from a point of a ``MatrixWorkspace`` into an MD point of a target ``MDWorkspace``.
+
+Workflow
+--------
+This workflow is implemented in the ``ConvertToMD`` algorithm's ``exec()`` function.
+
+#. Select a conversion and obtain additional algorithm parameters from the algorithm interface.
+
+#. Build ``MDWorkspace`` description (call ``MDTransfFactory`` and ask for the conversion plugin parameters).
+
+#. Build new ``MDWorkspace`` on the basis of its description (if new workspace is requested or check if existing workspace is suitable).
+
+#. Initialize the conversion plugin (using ``MDWSDescription``).
+
+#. Run the conversion itself by looping over detectors and their values (use ``MDTransfFactory`` and selected conversion plugin to convert
+   each input point into output MD point).
+
+The ``MDTransformationFactory`` is deployed twice during the conversion. The methods used during each conversion stage are clearly
+specified in ``MDTransformationInterface.h``.
+
+Defining the target workspace
+-----------------------------
+
+This describes steps 1-3 of the workflow.
+
+The input data at this stage are the name of the plugin and the outputs -- the information necessary for the transformation to work
+including the number of output dimensions, units for the selected physical transformation formula, units of the target workspace, etc.
+
+The methods used while defining the workspace should not access or change anything accessed through this pointer of
+the custom plugin. The result of the first stage is a ``MDWSDescription`` class, which can be considered
+as a large XML string that provides a common interface to different data obtained from the algorithm's parameters.
+Any data users want to transfer to the custom plugin can be added to this class, as long as this does not lead to
+excessive memory usage or overhead.
+
+The ``MDWSDescription`` class is copy constructable and assignable and if these operators fail due to the changes
+to the class, custom copy constructor and assignment operators have to be defined.
+
+Doing the transformation
+------------------------
+
+This describes steps 4-5 of the workflow.
+
+The input data at this stage are points of the "Experimental Space", e.g. coordinates of points in the input workspace and
+additional information about these points, e.g. detectors coordinates and log files for values of interest. The output values
+are the vectors of the coordinates of the selected points in the space of interest and (possibly) modified/corrected values of
+the signal and error at this point.
+
+During the second stage of the transformation, the algorithm calculates the multidimensional coordinates of MD points in the
+target workspace, places these coordinates into an MD vector of coordinates and modifies the neutron signal/error if necessary
+(e.g. Lorentz corrections). This stage can be best described by the pseudo-code below. It describes performing the conversion
+over the whole workspace:
+
+.. code-block:: cpp
+
+    /** initialize all internal variables used for transformation of workspace into MD workspace
+      WorkspaceDescription -- the workspace description obtained on the first stage of the transformation */
+    plugin->initialize(WorkspaceDescription);
+    /** calculate generic variables, which are usually placed in logs and do not depend on detectors positions
+       or neutron counts (e.g. temperature) and place these values into proper position in the coordinates vector. */
+    if(!plugin->calcGenericVariables(std::vector<coord_t> &Coord, size_t N_Dimensions))
+        return; // finish if these data are out of range requested
+
+    for(i in array of detectors)
+    {
+         /** Here we calculate all MD coordinates which depend on detectors position only. The plugin also
+         changes the internal plugin values which depend on detector's position e.g. sets up the unit conversion */
+         if(!plugin->calcYDepCoordinates(std::vector<coord_t> &Coord,size_t i))
+             continue;  // skip detector if these data are out of range requested
+
+         /** obtain signal and error, array, corresponding to the i-th detector */
+         spectra[i] = InputWorkspace->getSpectraCorrespondingToTheDetector(size_t i);
+
+         /**Convert units into the units, requested by the plugin */
+         MantidVector X = convertUnits(spectra[i].X_coordinates);
+         for(j in spectra[i])
+         {
+            Signal = spectra[i].Signal[j];
+            Error  = spectra[i].Error[j];
+            /**Calculate remaining MD coordinates and put them into vector of coordinates.
+               Modify Signal and error if the signal and error depends on Coord */
+            plugin->calcMatrixCoordinates(const MantidVec& X, size_t i, size_t j,
+                                          std::vector<coord_t> &Coord, Signal, Error);
+
+            /**Convert Coord signal and error to MD event with coordinate Coord and add the MDEvent to MD workspace*/
+            AddPointToMDWorkspace(Coord,Signal,Error);
+         }
+    }
+
+PreprocessDetectorsToMD with custom plugins
+-------------------------------------------
+
+Unit conversion uses the angular positions and sample-detector distances.
+This information is usually expensive to calculate so it is calculated separately by the
+`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__ algorithm.
+The detector information can be extracted directly from the input workspace, but consider checking the table workspace
+returned by `PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__
+and check if the information is already provided there.
+
+`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__ can also
+be modified to add some additional detector information. This information can then be added to the resulting table workspace
+and used in the custom plugin.
+All currently existing plugins use the information about the detector's positions calculated by
+`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__.
+
+Complex Transformations
+#######################
+
+It is possible that the approach of converting a single point of a ``MatrixWorkspace`` into a single ``MDEvent`` is
+incorrect or inefficient for what is required. In this situation, more complex changes to the conversion framework
+have to be implemented.
+To make the changes one needs to understand the interaction between different classes involved in the conversion.
+
+The class diagram with all main classes involved in the conversion is presented below:
+
+.. figure:: images/ConvertToMDClassDiagram.gif
+   :alt: ConvertToMDClassDiagram.gif
+
+Two factories are involved into the conversion. ``MDTransfFactory`` deals with different formulae to
+transform a single matrix point into an MD point. The other factory (``ConvToMDSelector`` and the algorithm inheriting
+from ``ConvToMDBase``) deal with different kinds of workspaces. There are currently two workspaces that can be transformed
+into an ``MDWorkspace``, namely ``EventWorkspace`` and ``MatrixWorkspace``. ``ConvToMDSelector`` identifies which algorithm to
+deploy based on the input workspace.
+
+If the input workspace has some special properties (e.g. a workspace obtained for an experiment with a rotating crystal,
+which has special units of time of flight with a special time series attached which describe a crystal position),
+the ``ConvToMDSelector`` should be modified to identify such a workspace and an additional class inheriting from
+``ConvToMDBase`` to deal with such workspaces has to be written.
+
+There are two other important classes in the diagram. The first one is ``MDWSDescription``, briefly mentioned above.
+The purpose of this class is to collect all input information from the algorithm interface and transfer this information
+through the common interface in a way convenient for a plugin to use. The user who is writing his own plugin is expected to
+add all the information necessary for the plugin to work to this class.
+
+Another is the ``MDEventWSWrapper``. This class interfaces ``MDEventWorkspace``. The ``MDEventWorkspace`` is templated by number
+of dimensions and the purpose of ``MDEventWSWrapper`` is to provide a unified interface to this workspace regardless of the
+number of workspace dimensions calculated during the run. It uses ``MDEventWorkspace`` methods for which the
+``IMDWorkspace`` interface to the ``MDEventWorkspace`` is not efficient. You do not usually need to modify this class unless
+you are modifying ``MDEventWorkspace`` code.
diff --git a/dev-docs/source/WritingPerformanceTests.rst b/dev-docs/source/WritingPerformanceTests.rst
new file mode 100644
index 0000000000000000000000000000000000000000..951dacca47b8267968cc46fca62c724adae7d6d0
--- /dev/null
+++ b/dev-docs/source/WritingPerformanceTests.rst
@@ -0,0 +1,154 @@
+.. _WritingPerformanceTests:
+
+=========================
+Writing Performance Tests
+=========================
+
+.. contents::
+  :local:
+
+Overview
+########
+
+The point of Performance Tests is to track the performance of a piece of
+code through time, so that it will be easy to pinpoint any change that
+reduced the performance of a particular bit of code. Performance Tests
+will be built and run by a build job, that will track the history of
+timing vs revision. The Jenkins job that runs the performance tests
+sends out an email when the performance of a test is lowered by more
+than a threshold percentage (currently 25%), relative to the average of
+a few previous tests.
+
+How to Write C++ Performance Tests
+##################################
+
+An ideal performance test is neither too fast, nor too slow. The
+precision of timing will be insufficient if the test runs in much less
+than a second; tests that run for several minutes should also be
+avoided.
+
+C++ performance tests are written in the same way as unit tests, and in
+the same file as the unit tests for a particular class, except that you
+will add *Performance* to the end of the name of the test suite. For
+example, in MyAlgorithmTest.h:
+
+.. code-block:: c++
+
+   class MyAlgorithmTest : public CxxTest::TestSuite {
+      // Put in your usual, quick unit tests here
+   };
+
+   class MyAlgorithmTestPerformance : public CxxTest::TestSuite {
+   public:
+      MatrixWorkspace_sptr WS;
+      int numpixels;
+
+      void setUp() {
+         // Put in any code needed to set up your test,
+         // but that should NOT be counted in the execution time.
+      }
+
+      void tearDown() {
+         // Clean-up code, also NOT counted in execution time.
+      }
+
+      void test_slow_performance() {
+         // Put in a unit test that will be slow.
+      }
+   };
+
+Only the presence/absence of the word Performance is used to determine
+if it is a Performance test. As with unit tests, your suite name has to
+match the file name.
+
+You may include ASSERT's in the same way as a unit test to check that
+results are meaningful, but that is unnecessary since these tests are
+for performance, not function. Avoid adding so many assert's that it
+would slow down your test.
+
+Running Performance Tests
+#########################
+
+Performance tests targets are not added by default when running
+cmake/make. To add them as ctest targets, enable them with the flag:
+
+.. code-block:: sh
+
+   cmake -DCXXTEST_ADD_PERFORMANCE=TRUE
+
+After re-building, you can then run performance tests with the command:
+
+.. code-block:: sh
+
+   ctest [-C Release|Debug] -R Performance
+
+And run regular unit tests, excluding the slow performance ones, with:
+
+.. code-block:: sh
+
+   ctest [-C Release|Debug] -E Performance
+
+where the -C option is required for multi-configuration builds like
+Visual Studio & XCode.
+
+The resulting .XML files will contain the detailed timing (of just the
+test portion without setUp/tearDown time).
+
+Note that newly added performance tests will not be registered with
+ctest until cmake has been re-run.
+
+Running tests without ctest
+---------------------------
+
+The tests are still built into every test executable, even if you have
+not set the flag. For example,
+
+.. code-block:: sh
+
+   AlgorithmsTest --help-tests
+
+will list all the available tests. If you run
+
+.. code-block:: sh
+
+   AlgorithmsTest
+
+alone, it will SKIP the Performance Tests. You have to give the name of
+the specific test suite you want to run, e.g,
+
+.. code-block:: sh
+
+   AlgorithmsTest MyAlgorithmPerformanceTest
+
+Best Practice Advice
+####################
+
+-  Performance tests are not System Tests. They should test the code at
+   the same granularity as the unit test suite.
+-  Performance tests are not Unit Tests. There is no need to perform
+   lots of assertions on the test results.
+-  Performance tests should perform enough work such that statistically
+   significant performance differences can be measured.
+-  The performance tests are executed often, so ideally they should
+   typically take 0.2 - 2 seconds to run.
+-  Always perform test set-up outside of the test method. That way your
+   timings will only relate to the target code you wish to measure.
+
+Jobs that monitor performance
+#############################
+
+There is a job in Jenkins (our continuous integration system) that runs
+the performance test suite and generates output that enables us to
+easily monitor timings. The job runs a set of `performance tests on the
+master branch of
+Mantid <http://builds.mantidproject.org/job/master_performancetests2/>`__.
+This job runs on a machine at the ESS, everytime that changes are merged
+into the Mantid master branch, and stores the timing information in a
+database, also generating HTML output via a `set of python
+scripts <https://github.com/mantidproject/mantid/tree/master/Testing/PerformanceTests>`__.
+
+The timing output of these jobs are typically monitored manually on a
+weekly basis to pick up any notable performance degradation. Although
+automatic checking is available within the python scripts, the level of
+instability in the timings meant that it always produced way too many
+false positives to be useful.
diff --git a/dev-docs/source/conf.py b/dev-docs/source/conf.py
index ad87f97943d16c0e7ae6a3662abdb6d491ef5639..cebc195f782d159b2f5746fc5aac0c844752533e 100644
--- a/dev-docs/source/conf.py
+++ b/dev-docs/source/conf.py
@@ -127,9 +127,10 @@ html_theme_options = {
     'navbar_site_name': "Mantid",
     # Add links to the nav bar. Third param of tuple is true to create absolute url.
     'navbar_links': [
-        ("Home", "http://www.mantidproject.org", True),
+        ("Home", "index"),
         ("Download", "http://download.mantidproject.org", True),
-        ("Documentation", "http://www.mantidproject.org/Documentation", True),
+        ("Wiki", "http://www.mantidproject.org", True),
+        ("User Documentation", "http://docs.mantidproject.org", True),
         ("Contact Us", "http://www.mantidproject.org/Contact", True),
     ],
     # Do not show the "Show source" button.
diff --git a/dev-docs/source/images/ASavici.jpg b/dev-docs/source/images/ASavici.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4f52c7a4ad9ef82c313d1c2eed0dc14486318146
Binary files /dev/null and b/dev-docs/source/images/ASavici.jpg differ
diff --git a/dev-docs/source/images/AttachToProcess.png b/dev-docs/source/images/AttachToProcess.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd87f7ae7bab7ef8c594cdd96b02985e68125269
Binary files /dev/null and b/dev-docs/source/images/AttachToProcess.png differ
diff --git a/dev-docs/source/images/BuildStatuses.png b/dev-docs/source/images/BuildStatuses.png
new file mode 100644
index 0000000000000000000000000000000000000000..348fba6f755f9f18891078bbd6053e6d1d126081
Binary files /dev/null and b/dev-docs/source/images/BuildStatuses.png differ
diff --git a/dev-docs/source/images/CodeFreezePR.png b/dev-docs/source/images/CodeFreezePR.png
new file mode 100644
index 0000000000000000000000000000000000000000..610450cfd34335b1c9cae80101d5af16c893405f
Binary files /dev/null and b/dev-docs/source/images/CodeFreezePR.png differ
diff --git a/dev-docs/source/images/ConvertToMDClassDiagram.gif b/dev-docs/source/images/ConvertToMDClassDiagram.gif
new file mode 100644
index 0000000000000000000000000000000000000000..bbce84fddae74cf8a16b6a460ab4660d08168578
Binary files /dev/null and b/dev-docs/source/images/ConvertToMDClassDiagram.gif differ
diff --git a/dev-docs/source/images/DevelopmentAndReleaseCycle.png b/dev-docs/source/images/DevelopmentAndReleaseCycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..e221736354aaf8c81e08fedfceaaeb6a2294be4a
Binary files /dev/null and b/dev-docs/source/images/DevelopmentAndReleaseCycle.png differ
diff --git a/dev-docs/source/images/ExternalDataSchematic.png b/dev-docs/source/images/ExternalDataSchematic.png
new file mode 100644
index 0000000000000000000000000000000000000000..26617234da52eb7f6735ff369eede41a14009f4f
Binary files /dev/null and b/dev-docs/source/images/ExternalDataSchematic.png differ
diff --git a/dev-docs/source/images/GGuest.png b/dev-docs/source/images/GGuest.png
new file mode 100644
index 0000000000000000000000000000000000000000..8098591672d7346279365d52dddef7a4482533d8
Binary files /dev/null and b/dev-docs/source/images/GGuest.png differ
diff --git a/dev-docs/source/images/GeometryHandlers.jpg b/dev-docs/source/images/GeometryHandlers.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a78c0c5de94126ce54e7d04a131ca69587c448b2
Binary files /dev/null and b/dev-docs/source/images/GeometryHandlers.jpg differ
diff --git a/dev-docs/source/images/InstrumentViewClassDiagram.jpg b/dev-docs/source/images/InstrumentViewClassDiagram.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a6e75669282e791bb1f3bb14d0782a23d98b0797
Binary files /dev/null and b/dev-docs/source/images/InstrumentViewClassDiagram.jpg differ
diff --git a/dev-docs/source/images/InstrumentWidget.jpg b/dev-docs/source/images/InstrumentWidget.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..252b96395837cc16ac93ca3a08df53c3bfec7e81
Binary files /dev/null and b/dev-docs/source/images/InstrumentWidget.jpg differ
diff --git a/dev-docs/source/images/JBilheaux.jpg b/dev-docs/source/images/JBilheaux.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..97854cc92f4e2ca4d24e845a28174438a4e65cf5
Binary files /dev/null and b/dev-docs/source/images/JBilheaux.jpg differ
diff --git a/dev-docs/source/images/JBorreguero.jpg b/dev-docs/source/images/JBorreguero.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..432c2ccb5a4b57a2ddd8009e224215033e2e2081
Binary files /dev/null and b/dev-docs/source/images/JBorreguero.jpg differ
diff --git a/dev-docs/source/images/KCachegrind_MantidPlot.png b/dev-docs/source/images/KCachegrind_MantidPlot.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea1be216a8e931906e2e32bc54c531696313876d
Binary files /dev/null and b/dev-docs/source/images/KCachegrind_MantidPlot.png differ
diff --git a/dev-docs/source/images/LMoore.jpg b/dev-docs/source/images/LMoore.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3734e6f2d1c09eecce2041b534303e5ed696f145
Binary files /dev/null and b/dev-docs/source/images/LMoore.jpg differ
diff --git a/dev-docs/source/images/MDoucet.jpg b/dev-docs/source/images/MDoucet.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..58057ed6ec3288ba80ee138d773d10bccc89e888
Binary files /dev/null and b/dev-docs/source/images/MDoucet.jpg differ
diff --git a/dev-docs/source/images/MGigg.jpg b/dev-docs/source/images/MGigg.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..28274291b3ca109fd1820cd3700816c6014c41a1
Binary files /dev/null and b/dev-docs/source/images/MGigg.jpg differ
diff --git a/dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png b/dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8862eabe08ad4b2cc906c6e29a6a80146ed3d03
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/CompletePromote.png b/dev-docs/source/images/MVPPythonViews/CompletePromote.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6d39047ed84736572fbea976b782d68b8e649b1
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/CompletePromote.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png b/dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png
new file mode 100644
index 0000000000000000000000000000000000000000..98d3fadd4a79222fc6a8f99b5158b9521d671522
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/NewFileName.png b/dev-docs/source/images/MVPPythonViews/NewFileName.png
new file mode 100644
index 0000000000000000000000000000000000000000..bec43e4033a4b72563df623c03260550623a0213
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/NewFileName.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/NewForm.png b/dev-docs/source/images/MVPPythonViews/NewForm.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd2794af39b9d32259060204cd346c5afcdf60c0
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/NewForm.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png b/dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png
new file mode 100644
index 0000000000000000000000000000000000000000..06ce203faa1aba7bbc1923372d0520d8a752fb10
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/PostReplacedWidget.png b/dev-docs/source/images/MVPPythonViews/PostReplacedWidget.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc058966ba4b9e0d63d66e25b7cedaad3b61b40c
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/PostReplacedWidget.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/PreReplacedWidget.png b/dev-docs/source/images/MVPPythonViews/PreReplacedWidget.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f19b3cfece59c4bc6082dad3a6d69bbdc7ed48d
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/PreReplacedWidget.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/PromoteWidget.png b/dev-docs/source/images/MVPPythonViews/PromoteWidget.png
new file mode 100644
index 0000000000000000000000000000000000000000..726f34ecffc1f0471021b0ca6b400b7b5084b730
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/PromoteWidget.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/SelectFile.png b/dev-docs/source/images/MVPPythonViews/SelectFile.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1c94cc4650733d8ad0b7484def60b056bd0c8a6
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/SelectFile.png differ
diff --git a/dev-docs/source/images/MVPPythonViews/SelectTemplate.png b/dev-docs/source/images/MVPPythonViews/SelectTemplate.png
new file mode 100644
index 0000000000000000000000000000000000000000..a18465c08c7d01d1a525b59a146dd65d06f7813b
Binary files /dev/null and b/dev-docs/source/images/MVPPythonViews/SelectTemplate.png differ
diff --git a/dev-docs/source/images/Mocking.png b/dev-docs/source/images/Mocking.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec518c080c0b1fc9fb54d108f3eb00d5e3bd2322
Binary files /dev/null and b/dev-docs/source/images/Mocking.png differ
diff --git a/dev-docs/source/images/NDraper.jpg b/dev-docs/source/images/NDraper.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7b1fa3d88134cc1b4bb625cc0c47a9248182ea8c
Binary files /dev/null and b/dev-docs/source/images/NDraper.jpg differ
diff --git a/dev-docs/source/images/OArnold.jpg b/dev-docs/source/images/OArnold.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..efa107d34139fcb79ab2ad5dbdf4abac73ab88e1
Binary files /dev/null and b/dev-docs/source/images/OArnold.jpg differ
diff --git a/dev-docs/source/images/PPeterson.jpg b/dev-docs/source/images/PPeterson.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9d287064d22745d98edb0c81ae224807b4c9a226
Binary files /dev/null and b/dev-docs/source/images/PPeterson.jpg differ
diff --git a/dev-docs/source/images/RFerrazLeal.jpg b/dev-docs/source/images/RFerrazLeal.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b6e8097a1b3e6fc0a93dc89971772d567ed43877
Binary files /dev/null and b/dev-docs/source/images/RFerrazLeal.jpg differ
diff --git a/dev-docs/source/images/RTolchenov.jpg b/dev-docs/source/images/RTolchenov.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..85259769e2b07d0120b40268ac6ea6dfc7950173
Binary files /dev/null and b/dev-docs/source/images/RTolchenov.jpg differ
diff --git a/dev-docs/source/images/RestartBuild.png b/dev-docs/source/images/RestartBuild.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c99976e3b7a86a66e48ef4c57ec22e73ea0a315
Binary files /dev/null and b/dev-docs/source/images/RestartBuild.png differ
diff --git a/dev-docs/source/images/VLynch.jpg b/dev-docs/source/images/VLynch.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e9d29886710360d41a5325ec73266fce2170f1f4
Binary files /dev/null and b/dev-docs/source/images/VLynch.jpg differ
diff --git a/dev-docs/source/images/VisualStudioTestDebugProperties.png b/dev-docs/source/images/VisualStudioTestDebugProperties.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f92b379d8c080b1624f924f3a316c5c91eabf7c
Binary files /dev/null and b/dev-docs/source/images/VisualStudioTestDebugProperties.png differ
diff --git a/dev-docs/source/images/WZhou.jpg b/dev-docs/source/images/WZhou.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..98f98d99f0008f1d78b7df60db4b09cea2844687
Binary files /dev/null and b/dev-docs/source/images/WZhou.jpg differ
diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst
index ebf236f4ac0c7affdda5a1112c1bec7d36493a52..0ac831a84b6a7dc6ddf437dea117753b039ee769 100644
--- a/dev-docs/source/index.rst
+++ b/dev-docs/source/index.rst
@@ -1,17 +1,18 @@
-.. Documentation master file
-   It contains a hidden root toctree directive so that Sphinx
-   has an internal index of all of the pages and doesn't
-   produce a plethora of warnings about most documents not being in
-   a toctree.
-   See http://sphinx-doc.org/tutorial.html#defining-document-structure
-
 .. _contents:
 
 =======================
 Developer Documentation
 =======================
 
-These pages contain the developer documentation for mantid version |release|.
+.. toctree::
+   :hidden:
+
+   DevelopmentTeam
+
+These pages contain the developer documentation for mantid. They are aimed at those who are modifying the
+source code of the project. For user documentation please see :ref:`here <mantid:contents>`.
+
+Meet the :ref:`team <DevelopmentTeam>`.
 
 ======
 Guides
@@ -20,10 +21,157 @@ Guides
 .. toctree::
    :hidden:
 
+   DeveloperAccounts
    GettingStarted
+   BuildingOnOSX
+   BuildingWithCMake
+   BuildingVATES
+   Standards/index
+   DoxygenSetup
+   Python3
+
+:doc:`DeveloperAccounts`
+   Details of the accounts required for developers.
 
 :doc:`GettingStarted`
-   Describes the process of obtaining and building the mantid code base
+   Describes the process of obtaining and building the mantid code base.
+
+:doc:`Standards <Standards/index>`
+   Details of coding and documentation standards for the project. Includes specifics regarding algorithms.
+
+:doc:`DoxygenSetup`
+   Configure a doxygen build locally.
+
+:doc:`Python3`
+   Building with Python 3 (Linux only).
+
+===================
+Development Process
+===================
+
+.. toctree::
+   :hidden:
+
+   DevelopmentAndReleaseCycle
+   Communication
+   IssueTracking
+   GitWorkflow
+   AutomatedBuildProcess
+   JenkinsConfiguration
+   ReleaseChecklist
+   PatchReleaseChecklist
+   TSC
+   DesignDocumentGuides
+
+:doc:`DevelopmentAndReleaseCycle`
+   An overview of the development cycle.
+
+:doc:`Communication`
+   Details various methods of communication used within the team.
+
+:doc:`IssueTracking`
+   Describes how issues are tracked over the project.
+
+:doc:`GitWorkflow`
+   Details the workflow used development with git and GitHub.
+
+:doc:`AutomatedBuildProcess`
+   Details the interaction of pull requests with the Jenkins CI builds.
+
+:doc:`JenkinsConfiguration`
+   Describes the setup of Jenkins system and how to add a new slave.
+
+:doc:`ReleaseChecklist`
+   How to perform a full release of Mantid.
+
+:doc:`PatchReleaseChecklist`
+   How to perform a patch release of Mantid.
+
+:doc:`TSC`
+   Overview of the role of the technical steering committee.
+
+:doc:`DesignDocumentGuides`
+   How to write a good design document.
+
+=====
+Tools
+=====
+
+.. toctree::
+   :hidden:
+
+   ToolsOverview
+   ProfilingWithValgrind
+   FlowchartCreation
+   VisualStudioBuildImpact
+
+:doc:`ToolsOverview`
+   Describes ``class_maker``, ``valgrind`` and related tools.
+
+:doc:`ProfilingWithValgrind`
+   How to use valgrind to profile your code.
+
+:doc:`FlowchartCreation`
+   Describes how to create a flow chart with dot.
+
+:doc:`VisualStudioBuildImpact`
+   Provides a script to reduce the impact of Visual Studio on machine performance.
+
+=======
+Testing
+=======
+
+.. toctree::
+   :hidden:
+
+   RunningTheUnitTests
+   DebuggingUnitTests
+   UnitTestGoodPractice
+   WritingPerformanceTests
+   SystemTests
+   DataFilesForTesting
+   TestingUtilities
+
+:doc:`RunningTheUnitTests`
+   Details on how to run the suite of unit tests.
+
+:doc:`DebuggingUnitTests`
+   Details on how to debug the suite of unit tests.
+
+:doc:`UnitTestGoodPractice`
+   Guidance on writing good unit tests.
+
+:doc:`WritingPerformanceTests`
+   A walk through of how to write a performance test.
+
+:doc:`SystemTests`
+   Guidance on working with the system tests.
+
+:doc:`DataFilesForTesting`
+   How to work with test data files in the mantid repository.
+
+:doc:`TestingUtilities`
+   Helper utlities used for testing.
+
+===============
+GUI Development
+===============
+
+.. toctree::
+   :hidden:
+
+   GUIDesignGuidelines
+   MVPTutorial/index
+   QtDesignerForPython
+
+:doc:`GUIDesignGuidelines`
+   Gives some guidelines to consider when developing a new graphical user interface.
+
+:doc:`MVP Tutorial <MVPTutorial/index>`
+   A hands-on tutorial on how to implement a user GUI using the Model-View-Presenter (MVP) pattern.
+
+:doc:`QtDesignerForPython`
+   Describes how to use the Qt designer to produce GUI views.
 
 ===================
 Component Overviews
@@ -33,5 +181,14 @@ Component Overviews
    :maxdepth: 1
 
    AlgorithmMPISupport
+   HandlingXML
    IndexProperty
+   InstrumentViewer
    ISISSANSReductionBackend
+   LoadAlgorithmHook
+   Logging
+   MultiThreadingInAlgorithms
+   PythonVSCppAlgorithms
+   RemoteJobSubmissionAPI
+   WritingAnAlgorithm
+   WritingCustomConvertToMDTransformation
diff --git a/docs/source/algorithms/Abins-v1.rst b/docs/source/algorithms/Abins-v1.rst
index 65eb426395c5b16ae989a4ed8c51c45494754be9..99c1e7ed0d03979a6d3ace25b51a7f9783c1ec49 100644
--- a/docs/source/algorithms/Abins-v1.rst
+++ b/docs/source/algorithms/Abins-v1.rst
@@ -11,7 +11,7 @@ Contributors:
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AbortRemoteJob-v1.rst b/docs/source/algorithms/AbortRemoteJob-v1.rst
index bf611d704d82c0c9373c098a186649414b952b4d..c921941466f4770e64d1392eb61dc87ae2dc63b1 100644
--- a/docs/source/algorithms/AbortRemoteJob-v1.rst
+++ b/docs/source/algorithms/AbortRemoteJob-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AbortRemoteJob-v2.rst b/docs/source/algorithms/AbortRemoteJob-v2.rst
index 2d1f4dd5d100380da3904e70bbed2483cf4eb81a..460a24c0a6422ec1ab6c8e516ed149edf5938101 100644
--- a/docs/source/algorithms/AbortRemoteJob-v2.rst
+++ b/docs/source/algorithms/AbortRemoteJob-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AbsorptionCorrection-v1.rst b/docs/source/algorithms/AbsorptionCorrection-v1.rst
index 7684c333232d823aead13496e03830cf91216d5a..7ee7e67caee4d354d03e819a4cce0ec017c10e6b 100644
--- a/docs/source/algorithms/AbsorptionCorrection-v1.rst
+++ b/docs/source/algorithms/AbsorptionCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AccumulateMD-v1.rst b/docs/source/algorithms/AccumulateMD-v1.rst
index fdd1a6c4f81dbfbc87dc80a12205d3269f04aaf4..8b8b2ccb4ad2a809b79c3f71ebb2a1bd7a96cf23 100644
--- a/docs/source/algorithms/AccumulateMD-v1.rst
+++ b/docs/source/algorithms/AccumulateMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddLogDerivative-v1.rst b/docs/source/algorithms/AddLogDerivative-v1.rst
index c2880f978ff91702268d2ad8bbe7b11ec5f2cee0..dbb72ea38368f795c4a69d8f7a63812eb2c8d93f 100644
--- a/docs/source/algorithms/AddLogDerivative-v1.rst
+++ b/docs/source/algorithms/AddLogDerivative-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddNote-v1.rst b/docs/source/algorithms/AddNote-v1.rst
index d834faa400586c728ef3d610d0f5906ccc0669d9..c25491208f0209ee1a8ed9da0e178ef17689d1db 100644
--- a/docs/source/algorithms/AddNote-v1.rst
+++ b/docs/source/algorithms/AddNote-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddPeak-v1.rst b/docs/source/algorithms/AddPeak-v1.rst
index 6dae159033cc423eb3875cc317cf424c8d2e07c2..c92fc413894e4054c4d48a3d9131041d3c9373c8 100644
--- a/docs/source/algorithms/AddPeak-v1.rst
+++ b/docs/source/algorithms/AddPeak-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddPeakHKL-v1.rst b/docs/source/algorithms/AddPeakHKL-v1.rst
index ee71dc1ce113de791b6ce776d94910504422d6dc..62ec2126ebf41838569f02fa40670091a0d5ee38 100644
--- a/docs/source/algorithms/AddPeakHKL-v1.rst
+++ b/docs/source/algorithms/AddPeakHKL-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddSampleLog-v1.rst b/docs/source/algorithms/AddSampleLog-v1.rst
index 6cad3c0127071bca753c8aebee4939366f1a0ebb..86bcde338ab550f029561f0cc4ea172f52820bc8 100644
--- a/docs/source/algorithms/AddSampleLog-v1.rst
+++ b/docs/source/algorithms/AddSampleLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddSampleLogMultiple-v1.rst b/docs/source/algorithms/AddSampleLogMultiple-v1.rst
index 0f445b1e1f7e083c475c900b4308af25470d19d6..e736057e43f544bc2cc89c86d78572a40fab4b0f 100644
--- a/docs/source/algorithms/AddSampleLogMultiple-v1.rst
+++ b/docs/source/algorithms/AddSampleLogMultiple-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AddTimeSeriesLog-v1.rst b/docs/source/algorithms/AddTimeSeriesLog-v1.rst
index 1ef19324053249a1c9f31e810ef3d5ac75439022..8e3f3957f609da85cf9522b6b4cbff4ad77eaac4 100644
--- a/docs/source/algorithms/AddTimeSeriesLog-v1.rst
+++ b/docs/source/algorithms/AddTimeSeriesLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AlignAndFocusPowder-v1.rst b/docs/source/algorithms/AlignAndFocusPowder-v1.rst
index 03ec09a13f1abd17d6d774242d6ed10641738218..78db7695af2b10a5ffa871a0234b0b7ff8c63170 100644
--- a/docs/source/algorithms/AlignAndFocusPowder-v1.rst
+++ b/docs/source/algorithms/AlignAndFocusPowder-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst b/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst
index 74130ed6f71434666944ce3df50e4ef4c0b8dada..6449505cca4a6e3f6da923ae925851c75b631105 100644
--- a/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst
+++ b/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AlignComponents-v1.rst b/docs/source/algorithms/AlignComponents-v1.rst
index cc15126ce789e3628d743a7b946873df455f0baa..0507aa62031478c7131c3bdcbe07c4661803be5c 100644
--- a/docs/source/algorithms/AlignComponents-v1.rst
+++ b/docs/source/algorithms/AlignComponents-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AlignDetectors-v1.rst b/docs/source/algorithms/AlignDetectors-v1.rst
index 74b8560ef5d0952a6952ace13da3bb837c452868..ab934df6daa1bc4d28e08337eb471b944d99af8d 100644
--- a/docs/source/algorithms/AlignDetectors-v1.rst
+++ b/docs/source/algorithms/AlignDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AlphaCalc-v1.rst b/docs/source/algorithms/AlphaCalc-v1.rst
index 10bea530d19f43f4cc8a4918ad82c9b07c5649bd..a633b1158953ec4dcde497c47e43886de8a3bc77 100644
--- a/docs/source/algorithms/AlphaCalc-v1.rst
+++ b/docs/source/algorithms/AlphaCalc-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AndMD-v1.rst b/docs/source/algorithms/AndMD-v1.rst
index b0aa22197567e14ea0684fa268154a01b95c0a9d..273bd7896e722d8e8e3323591ebbe8e857191b22 100644
--- a/docs/source/algorithms/AndMD-v1.rst
+++ b/docs/source/algorithms/AndMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst b/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst
index 83068dda4a87aa6b7d612cf2cc5fa03d9523f0d7..fcc7eef89ef35481436f32fb6f57554588827f9d 100644
--- a/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst
+++ b/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst b/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst
index c6dd6717c61197280a0532f3b7370e00bdf85f27..644eae9ddfc15777d6e07eee970d4ad9a98a907f 100644
--- a/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst
+++ b/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AnnularRingAbsorption-v1.rst b/docs/source/algorithms/AnnularRingAbsorption-v1.rst
index 6fcc2deab208f817866d3d8bc3a0a262eaed9def..212b9d069d7b8f4858e2266d0877ad6e7c385f95 100644
--- a/docs/source/algorithms/AnnularRingAbsorption-v1.rst
+++ b/docs/source/algorithms/AnnularRingAbsorption-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AnvredCorrection-v1.rst b/docs/source/algorithms/AnvredCorrection-v1.rst
index ed28378e62730f4e49f05f290cc70dc57f088434..cc95d0cd3aeadb27079877365826133185ebcf43 100644
--- a/docs/source/algorithms/AnvredCorrection-v1.rst
+++ b/docs/source/algorithms/AnvredCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst
index 104ea18c9d3ea3a245d3827d3f967498fc65158c..d7ad2395c19fb2f4fb23ad7ec84147b5214f0a9a 100644
--- a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst
+++ b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AppendSpectra-v1.rst b/docs/source/algorithms/AppendSpectra-v1.rst
index 2ad75355f1a9cc6d77cbfa6f9a6c4305d605a7ee..9a2fa0e1bb8fd6a7f3b406ecd73b8c0e44f576a6 100644
--- a/docs/source/algorithms/AppendSpectra-v1.rst
+++ b/docs/source/algorithms/AppendSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyCalibration-v1.rst b/docs/source/algorithms/ApplyCalibration-v1.rst
index 44f4c7933996d02212a769c755923e6fde13b11e..5f599a50a1d0d1599ac9bdd16b23ece061340167 100644
--- a/docs/source/algorithms/ApplyCalibration-v1.rst
+++ b/docs/source/algorithms/ApplyCalibration-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst b/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst
index 3234aa9f0e9bf83feaae370eb4a85f61ae8434b1..09c864e0d8287fe3a36cc787742fedc41c3c8b5f 100644
--- a/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst
+++ b/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyDetailedBalance-v1.rst b/docs/source/algorithms/ApplyDetailedBalance-v1.rst
index 2b9603ffc68e68aae14b499b5210ef8b26619a0a..4c7e957b96a4a97e6fe019fa35d39c38e09dd605 100644
--- a/docs/source/algorithms/ApplyDetailedBalance-v1.rst
+++ b/docs/source/algorithms/ApplyDetailedBalance-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst b/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst
index e458f48465933ddb46fedd9091667162b6d309dc..f1de79c88979c57d09b545fa3f5b2e78697f78f8 100644
--- a/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst
+++ b/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst
index 3e548a2644c862e5ff2c6407d9c6050274bfb673..fe194338505a992a36790dc66ec5a62f24e526ad 100644
--- a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst
+++ b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst b/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst
index 2d2524e45194389b0da2ba770696e94e4d950bab..0e887cd4626d890de362f7069da55add6c0b39c5 100644
--- a/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst
+++ b/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AsymmetryCalc-v1.rst b/docs/source/algorithms/AsymmetryCalc-v1.rst
index 311e2821e3cc7c8ec61f024f076cfc9997dd3ae2..670fac8573e12f86b9f4843dd214a3276318894c 100644
--- a/docs/source/algorithms/AsymmetryCalc-v1.rst
+++ b/docs/source/algorithms/AsymmetryCalc-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Authenticate-v1.rst b/docs/source/algorithms/Authenticate-v1.rst
index b53f067c18984c784d931380089cd4576781979d..664b7ea7fb280c17b12276276292c1beaeef652a 100644
--- a/docs/source/algorithms/Authenticate-v1.rst
+++ b/docs/source/algorithms/Authenticate-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Authenticate-v2.rst b/docs/source/algorithms/Authenticate-v2.rst
index 785ed8e1011c5dcfaf855414a539cdbde5aae18a..ae46874065e54a33ee5a13cf1b393711c118de79 100644
--- a/docs/source/algorithms/Authenticate-v2.rst
+++ b/docs/source/algorithms/Authenticate-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/AverageLogData-v1.rst b/docs/source/algorithms/AverageLogData-v1.rst
index a987825908e6aad802ff5ff565c38c1aa7764603..bec9ee6bc2daa6400f862797e837657234b79944 100644
--- a/docs/source/algorithms/AverageLogData-v1.rst
+++ b/docs/source/algorithms/AverageLogData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/BASISDiffraction-v1.rst b/docs/source/algorithms/BASISDiffraction-v1.rst
index 4585559694528a4304019013bfac1f4ee2aad102..138a4783f1884e71d92b0203c68ed21f3951bb85 100644
--- a/docs/source/algorithms/BASISDiffraction-v1.rst
+++ b/docs/source/algorithms/BASISDiffraction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -43,7 +43,7 @@ and isotropic scattering to determine instrument efficiency per detector. If
 no vanadium is provided, all detectors are assumed to have the same efficiency
 
 Determine Single Crystal Diffraction
-====================================
+####################################
 
 Creates a diffraction pattern from a set of runs
 implementing a rotational scan of the sample around the vertical axis. The
@@ -52,7 +52,7 @@ corresponding goniometer's rotation should be logged under log name
 angle.
 
 Sample orientation
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 **VectorU**: Vector along k_i, when goniometer is at offset.
 
@@ -60,7 +60,7 @@ Sample orientation
 offset.
 
 Diffraction preferences
-~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^
 
 Most of the scattering occurs in the plane defined by VectorU and VectorV.
 Please choose Uproj and Vproj defining a plane that is as close as possible
diff --git a/docs/source/algorithms/BASISReduction-v1.rst b/docs/source/algorithms/BASISReduction-v1.rst
index 93dc4a8b287f91f860bd693e02ee020b9ce650cb..c0408383ab09ff343e9f02d9b43e60c80dbfcc7e 100644
--- a/docs/source/algorithms/BASISReduction-v1.rst
+++ b/docs/source/algorithms/BASISReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/BASISReduction311-v1.rst b/docs/source/algorithms/BASISReduction311-v1.rst
index 430fb2017b6f7710fa927ced1bebaa18b7039c85..6ca9c90a26815ee27b1598428ad97708ba850505 100644
--- a/docs/source/algorithms/BASISReduction311-v1.rst
+++ b/docs/source/algorithms/BASISReduction311-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -32,7 +32,7 @@ lower boundary the bin with the minimum momentum, the bin width, and the
 upper boundary ofthe bin with the maximum momentum.
 
 Reflection Selector
-===================
+###################
 
 There are typical values for the properties of the 311 reflection:
 
diff --git a/docs/source/algorithms/BayesQuasi-v1.rst b/docs/source/algorithms/BayesQuasi-v1.rst
index 1fd36c075b17cafa2f09f3093a072439da353e19..720e00dc3fa1b4f65dc2c7cf49d826c9f69619e6 100644
--- a/docs/source/algorithms/BayesQuasi-v1.rst
+++ b/docs/source/algorithms/BayesQuasi-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/BayesStretch-v1.rst b/docs/source/algorithms/BayesStretch-v1.rst
index 5fdf7020a3051b7b33e4830ec7c1517856bd9f02..2fe36ac54849d9e73eff3a83c6b9fdef8d951d1b 100644
--- a/docs/source/algorithms/BayesStretch-v1.rst
+++ b/docs/source/algorithms/BayesStretch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst
index 32317820bc9db3d987805174dfe864834bc2dcf5..ffba381cf64a0761fa0ce202118a399b1f79586e 100644
--- a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst
+++ b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -108,13 +108,14 @@ Usage
 Output:
 
 .. testoutput:: Bin2DPowderDiffractionExample
+   :options: +ELLIPSIS, +NORMALIZE_WHITESPACE
 
     Y values without normalization:
-    [[ 278.    0.]
-     [  14.  145.]]
+    [[ ... ...]
+     [  ... ...]]
     Y values with normalization by bin area:
-    [[ 69.5    0.  ]
-     [  3.5   36.25]]
+    [[ ... ...]
+     [ ... ...]]
 
 
 References
diff --git a/docs/source/algorithms/BinMD-v1.rst b/docs/source/algorithms/BinMD-v1.rst
index d55794cbcd476111f9d4678bf0d26b62ed428e7f..dd74733829faea1d70c13d73171ab5d070e177fd 100644
--- a/docs/source/algorithms/BinMD-v1.rst
+++ b/docs/source/algorithms/BinMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/BinWidthAtX-v1.rst b/docs/source/algorithms/BinWidthAtX-v1.rst
index 9d65bc04234a63f50605ce9a74ffa879634c32ec..23434ef27e59a7ac391f18dff1a4b85612309bec 100644
--- a/docs/source/algorithms/BinWidthAtX-v1.rst
+++ b/docs/source/algorithms/BinWidthAtX-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
   
diff --git a/docs/source/algorithms/BinaryOperateMasks-v1.rst b/docs/source/algorithms/BinaryOperateMasks-v1.rst
index c8b284618f9d717db99792b08265fc710c132f4c..e43c307252275c1c8091a8a95666f16cf79dd057 100644
--- a/docs/source/algorithms/BinaryOperateMasks-v1.rst
+++ b/docs/source/algorithms/BinaryOperateMasks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/BroadcastWorkspace-v1.rst b/docs/source/algorithms/BroadcastWorkspace-v1.rst
index ac4e4c529d0a28cc275df56fb9818ca058af1c8a..ca441f47ce6ae9d4b1b830fb0b90ce6ca32191c6 100644
--- a/docs/source/algorithms/BroadcastWorkspace-v1.rst
+++ b/docs/source/algorithms/BroadcastWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalMuonDeadTime-v1.rst b/docs/source/algorithms/CalMuonDeadTime-v1.rst
index 25e721cd2a81a3c2b5edc454728566b926723fcb..b34e67d828711c6c3788fbbb930cd7d4b76e8259 100644
--- a/docs/source/algorithms/CalMuonDeadTime-v1.rst
+++ b/docs/source/algorithms/CalMuonDeadTime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalMuonDetectorPhases-v1.rst b/docs/source/algorithms/CalMuonDetectorPhases-v1.rst
index 45edeb936159eed0eaef0efb0f5932fed0b2a525..833c17388531c6771d4a6413c8c7086be8c7b5a7 100644
--- a/docs/source/algorithms/CalMuonDetectorPhases-v1.rst
+++ b/docs/source/algorithms/CalMuonDetectorPhases-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateChiSquared-v1.rst b/docs/source/algorithms/CalculateChiSquared-v1.rst
index 03ba5e7f4a095c957738d4b764a31cdccd7614c1..e96c3a6b10ef2af55cd50f433b4d741f5c7cd61a 100644
--- a/docs/source/algorithms/CalculateChiSquared-v1.rst
+++ b/docs/source/algorithms/CalculateChiSquared-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -34,7 +34,7 @@ Finally, ChiSquaredWeightedDividedByDOF is
 :math:`\chi_{4}^{2} = \chi_{3}^{2} / DOF`
 
 Parameter errors
-================
+################
 
 Setting the Output property to a non-empty string makes the algorithm explore the surface of the :math:`\chi^{2}`
 around its minimum and estimate the standard deviations for the parameters. The value of the property is a base name
diff --git a/docs/source/algorithms/CalculateCostFunction-v1.rst b/docs/source/algorithms/CalculateCostFunction-v1.rst
index 5bd9729208ffae7a40ed0b370b07cec32e5d58ae..eec1d6353e41fa6bb2ad84caf7467c022d560346 100644
--- a/docs/source/algorithms/CalculateCostFunction-v1.rst
+++ b/docs/source/algorithms/CalculateCostFunction-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateCountRate-v1.rst b/docs/source/algorithms/CalculateCountRate-v1.rst
index acdaee775c530e1c45455cf0ab4a4c6e2cb0a6d5..a52182f29db9c62b7207ee3b9bf2072aaddc6b30 100644
--- a/docs/source/algorithms/CalculateCountRate-v1.rst
+++ b/docs/source/algorithms/CalculateCountRate-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -68,18 +68,19 @@ Usage
         log = LogTest.run().getLogData(log_name)
         print("log {0} contains {1} entries".format(log_name, log.size()))
         print("log starts at {0} and records value: {1}".format(log.firstTime(), log.firstValue()))
-        print("log ends   at {0} and records value: {1}".format(log.lastTime(), log.lastValue()))        
+        print("log ends   at {0} and records value: {1}".format(log.lastTime(), log.lastValue()))
    else:
-       print("{0}".format(rez))        
+       print("{0}".format(rez))
 
    
 .. testoutput:: ExCalcCountRate
+   :options: +ELLIPSIS, +NORMALIZE_WHITESPACE
 
     Initially, Property block_count_rate not found
     The Algorithm produced log: block_count_rate
     log block_count_rate contains 200 entries
-    log starts at 2010-01-01T00:00:09.011891145  and records value: 991.0
-    log ends   at 2010-01-01T00:59:50.996493194  and records value: 1010.0
+    log starts at 2010-01-01T00:00:09... and records value: ...
+    log ends   at 2010-01-01T00:59:50... and records value: ...
  
 .. categories::
 
diff --git a/docs/source/algorithms/CalculateCoverageDGS-v1.rst b/docs/source/algorithms/CalculateCoverageDGS-v1.rst
index 7dad0cf83de44bfbb50d4ef8c9de1c1655135a4b..53b665d420b9598c1717284a7566200452be106d 100644
--- a/docs/source/algorithms/CalculateCoverageDGS-v1.rst
+++ b/docs/source/algorithms/CalculateCoverageDGS-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateDIFC-v1.rst b/docs/source/algorithms/CalculateDIFC-v1.rst
index 6191fad999410a6355d750ef3f6e15b00001f69f..33baf51d2d551928098b12fc655a2e220c2ff025 100644
--- a/docs/source/algorithms/CalculateDIFC-v1.rst
+++ b/docs/source/algorithms/CalculateDIFC-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateEfficiency-v1.rst b/docs/source/algorithms/CalculateEfficiency-v1.rst
index 28cf323f3d29028b7a5805de00c529400d4f0162..7de882a71496a0ef8bd9dc464d2a15916981357f 100644
--- a/docs/source/algorithms/CalculateEfficiency-v1.rst
+++ b/docs/source/algorithms/CalculateEfficiency-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateFlatBackground-v1.rst b/docs/source/algorithms/CalculateFlatBackground-v1.rst
index 10195afcb26a7ef69f092ce3a47ac917002ddd32..5c01a59b2dd41c06b6c121ec4e4b6fb9da2b8af5 100644
--- a/docs/source/algorithms/CalculateFlatBackground-v1.rst
+++ b/docs/source/algorithms/CalculateFlatBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst b/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst
index 5a5e85e049c3d461fc0e73c8a55fa55aef8cbdb1..a9c5d549076647374ccf19db429eb55f83c45af3 100644
--- a/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst
+++ b/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst b/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst
index af7fda4820886fddfe633f98695355ea5ee77d50..21af76b939e588efa5ad98dc686fcfc363038e94 100644
--- a/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst
+++ b/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculatePeaksHKL-v1.rst b/docs/source/algorithms/CalculatePeaksHKL-v1.rst
index 2d18a6150c5521a01b3a468a43c6b076dee53c7f..bbcac2512cf50d45e0f9b95d396a8ae5d0a74ec0 100644
--- a/docs/source/algorithms/CalculatePeaksHKL-v1.rst
+++ b/docs/source/algorithms/CalculatePeaksHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculatePolynomialBackground-v1.rst b/docs/source/algorithms/CalculatePolynomialBackground-v1.rst
index 4887185a85b59e06f4367d95b6008ed308fefab5..06f99fc8f85fb17700587238c3ddab411a72cb47 100644
--- a/docs/source/algorithms/CalculatePolynomialBackground-v1.rst
+++ b/docs/source/algorithms/CalculatePolynomialBackground-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateSampleTransmission-v1.rst b/docs/source/algorithms/CalculateSampleTransmission-v1.rst
index f062723d18ea07c642e1db87734d387198ef9108..b1bef7feac5129f82bfae19654a66e91c1624867 100644
--- a/docs/source/algorithms/CalculateSampleTransmission-v1.rst
+++ b/docs/source/algorithms/CalculateSampleTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateSlits-v1.rst b/docs/source/algorithms/CalculateSlits-v1.rst
index cca529d82fff7bdcfac3c3ae43cf9699ea8f889f..1b2967b0baa9a12b79ca56c2bfad365c806dd17a 100644
--- a/docs/source/algorithms/CalculateSlits-v1.rst
+++ b/docs/source/algorithms/CalculateSlits-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateTransmission-v1.rst b/docs/source/algorithms/CalculateTransmission-v1.rst
index 5bfd0afedd12934588f29ae9690714a27bb6f33f..461cfaa8fd65ffe269560b96820c738bed842d52 100644
--- a/docs/source/algorithms/CalculateTransmission-v1.rst
+++ b/docs/source/algorithms/CalculateTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst b/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst
index 71a50f3095f9e0bed59920c4b0b06a18b8f06090..010fbcf80f9fe7adb32f920b425a8b9c91a08541 100644
--- a/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst
+++ b/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateUMatrix-v1.rst b/docs/source/algorithms/CalculateUMatrix-v1.rst
index f72fc9099416b7a8994a64a9468dfe9705e58111..b729b1be1c66a7060e62840070ad11a5f763185f 100644
--- a/docs/source/algorithms/CalculateUMatrix-v1.rst
+++ b/docs/source/algorithms/CalculateUMatrix-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalculateZscore-v1.rst b/docs/source/algorithms/CalculateZscore-v1.rst
index d444025b3f1aea28b0d79242cf92d3f9a6cb1a92..b422c76d5c65691d9e0f83e8c5040188b7ac5cb1 100644
--- a/docs/source/algorithms/CalculateZscore-v1.rst
+++ b/docs/source/algorithms/CalculateZscore-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst b/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst
index 561db96cb82169c04c844ead79b871a43c949d2d..21b98f4b4200415d96ee1845f5bb4e7d25c2cb95 100644
--- a/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst
+++ b/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst b/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst
index d0ff2cba2be25bed331e54a3cd4e47eefc206d59..462f7007d3e24f76b2b567bbe763a17f4593ed80 100644
--- a/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst
+++ b/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogGetDataFiles-v1.rst b/docs/source/algorithms/CatalogGetDataFiles-v1.rst
index 3688e18d63a69d74fb72e98c973385d3882ba03b..661daf99a694b18d733184885f0bfd014fb9405a 100644
--- a/docs/source/algorithms/CatalogGetDataFiles-v1.rst
+++ b/docs/source/algorithms/CatalogGetDataFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogGetDataSets-v1.rst b/docs/source/algorithms/CatalogGetDataSets-v1.rst
index 6727e74f9f2c5cc7dad5291ccad1cb2291037557..fa5707b91452d9306a5ac36d4a67e12c8cab71b4 100644
--- a/docs/source/algorithms/CatalogGetDataSets-v1.rst
+++ b/docs/source/algorithms/CatalogGetDataSets-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogKeepAlive-v1.rst b/docs/source/algorithms/CatalogKeepAlive-v1.rst
index 755580feafbc57c16d02f5171e49ee2cfe596b80..ec38fc828cabd0d406f1df9040548fbc5b0fec6e 100644
--- a/docs/source/algorithms/CatalogKeepAlive-v1.rst
+++ b/docs/source/algorithms/CatalogKeepAlive-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogListInstruments-v1.rst b/docs/source/algorithms/CatalogListInstruments-v1.rst
index 5fe41febc6db3d8b60eb6321d69be68dc6e6adde..8062a2c02b5043ff9b36f4a6369ccdc50dd79843 100644
--- a/docs/source/algorithms/CatalogListInstruments-v1.rst
+++ b/docs/source/algorithms/CatalogListInstruments-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst b/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst
index 9a265490df931d35d9fe95305af74613d75f588d..85ed1401cedf1cab099522a23ba5fe9aad600239 100644
--- a/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst
+++ b/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogLogin-v1.rst b/docs/source/algorithms/CatalogLogin-v1.rst
index 34693f8be889e9e89fc82f025b24ebf3500445a3..dbcca9fa7e427afb902dddc35e133d23ed4b081c 100644
--- a/docs/source/algorithms/CatalogLogin-v1.rst
+++ b/docs/source/algorithms/CatalogLogin-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogLogout-v1.rst b/docs/source/algorithms/CatalogLogout-v1.rst
index 4c5e02a01cdfae4c14239a230460cd52c5a9554c..9f4b99432b1c79a0a7899f1da9e9bf17dde74adc 100644
--- a/docs/source/algorithms/CatalogLogout-v1.rst
+++ b/docs/source/algorithms/CatalogLogout-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogMyDataSearch-v1.rst b/docs/source/algorithms/CatalogMyDataSearch-v1.rst
index 54a479042e5a1cb3e9b6aaee87cf295b98beefd9..798ae42d16c791eebbdae16362f794ed4f12edd3 100644
--- a/docs/source/algorithms/CatalogMyDataSearch-v1.rst
+++ b/docs/source/algorithms/CatalogMyDataSearch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogPublish-v1.rst b/docs/source/algorithms/CatalogPublish-v1.rst
index 3e17d508178ef9aaf781c0cd4f0601cf8db47edd..d7a82865bcb027a70a8bb9283069e3772e31f0e2 100644
--- a/docs/source/algorithms/CatalogPublish-v1.rst
+++ b/docs/source/algorithms/CatalogPublish-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CatalogSearch-v1.rst b/docs/source/algorithms/CatalogSearch-v1.rst
index a57ff5abfc875f9a55df432366b60277e827598f..955cb0a4cde1931f49a12887533d892fbd8098bd 100644
--- a/docs/source/algorithms/CatalogSearch-v1.rst
+++ b/docs/source/algorithms/CatalogSearch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CentroidPeaks-v1.rst b/docs/source/algorithms/CentroidPeaks-v1.rst
index 29469ed3d93d6ce04ff30f915a1343cec1750737..68797211ba7a250a062817a855c06a656d72f389 100644
--- a/docs/source/algorithms/CentroidPeaks-v1.rst
+++ b/docs/source/algorithms/CentroidPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CentroidPeaksMD-v1.rst b/docs/source/algorithms/CentroidPeaksMD-v1.rst
index e36680d16e927bd77cdac68941edf68619477896..fe919f273ecd1566a3d3325a563b6f67113d4e73 100644
--- a/docs/source/algorithms/CentroidPeaksMD-v1.rst
+++ b/docs/source/algorithms/CentroidPeaksMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CentroidPeaksMD-v2.rst b/docs/source/algorithms/CentroidPeaksMD-v2.rst
index 72f79075cd1e0ad815e6fc50fc931c06cbd520da..98e01b64e9b252f3b0016d85c26517052e2b0e9b 100644
--- a/docs/source/algorithms/CentroidPeaksMD-v2.rst
+++ b/docs/source/algorithms/CentroidPeaksMD-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChangeBinOffset-v1.rst b/docs/source/algorithms/ChangeBinOffset-v1.rst
index 69738abb70a6e1865d9d49209ba111e42b5c7a9e..9ee68e7ee1b52c48906d104047e9a0365e64c8ac 100644
--- a/docs/source/algorithms/ChangeBinOffset-v1.rst
+++ b/docs/source/algorithms/ChangeBinOffset-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChangeLogTime-v1.rst b/docs/source/algorithms/ChangeLogTime-v1.rst
index 9e41dd1a69b69a4ba542f4b287415d50ac1ae798..38f19d3efd0052bc01d35622783e2419aaa1f3d2 100644
--- a/docs/source/algorithms/ChangeLogTime-v1.rst
+++ b/docs/source/algorithms/ChangeLogTime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChangePulsetime-v1.rst b/docs/source/algorithms/ChangePulsetime-v1.rst
index 00cd7903937c1b51f2aed21480a6ae8895d3955b..0ce29e0158ce386e810dc50cb9ecd887b9fb9521 100644
--- a/docs/source/algorithms/ChangePulsetime-v1.rst
+++ b/docs/source/algorithms/ChangePulsetime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChangeQConvention-v1.rst b/docs/source/algorithms/ChangeQConvention-v1.rst
index c76f26b1497a570b278a75c06317a1c9a3217643..bef585d464e0cce34a8e7c3785c7d190331ec699 100644
--- a/docs/source/algorithms/ChangeQConvention-v1.rst
+++ b/docs/source/algorithms/ChangeQConvention-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChangeTimeZero-v1.rst b/docs/source/algorithms/ChangeTimeZero-v1.rst
index 79804c894305842be556d2ad2016a1cb90fe5bc3..bd81c0b1c160b10139233003e20a43c049ad7b92 100644
--- a/docs/source/algorithms/ChangeTimeZero-v1.rst
+++ b/docs/source/algorithms/ChangeTimeZero-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CheckForSampleLogs-v1.rst b/docs/source/algorithms/CheckForSampleLogs-v1.rst
index d97dbd87a671dd6b61752a34935a841edfaf6db8..de24be8a0079e53a6b508f203944406897f05415 100644
--- a/docs/source/algorithms/CheckForSampleLogs-v1.rst
+++ b/docs/source/algorithms/CheckForSampleLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CheckMantidVersion-v1.rst b/docs/source/algorithms/CheckMantidVersion-v1.rst
index bfb5768748c0848e3770a18df662ded253427d8e..595e956309b44895322993a74ecd9dd95df62666 100644
--- a/docs/source/algorithms/CheckMantidVersion-v1.rst
+++ b/docs/source/algorithms/CheckMantidVersion-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CheckWorkspacesMatch-v1.rst b/docs/source/algorithms/CheckWorkspacesMatch-v1.rst
index ce78cc7d3c43aee7545b734914393f7f9fc5458f..34ba2f073a1614ed6559d3df52da86da0567ee49 100644
--- a/docs/source/algorithms/CheckWorkspacesMatch-v1.rst
+++ b/docs/source/algorithms/CheckWorkspacesMatch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ChopData-v1.rst b/docs/source/algorithms/ChopData-v1.rst
index 90ad0f9452199c6af8c14b126096b088619a3d81..07a53ced0fad12ed8fde6c6499f81c982895c14e 100644
--- a/docs/source/algorithms/ChopData-v1.rst
+++ b/docs/source/algorithms/ChopData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CleanFileCache-v1.rst b/docs/source/algorithms/CleanFileCache-v1.rst
index 236e24ec9ec2183470241246b3d759c5ca98f3ba..9e8c2fa0a757b678095873a689284b042d2a54c0 100644
--- a/docs/source/algorithms/CleanFileCache-v1.rst
+++ b/docs/source/algorithms/CleanFileCache-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ClearCache-v1.rst b/docs/source/algorithms/ClearCache-v1.rst
index d630d350ad907c0717edf3f5aaddf66b32a30d19..d4ae041fa314a7358ee1b8ee35721b4a8c32ec69 100644
--- a/docs/source/algorithms/ClearCache-v1.rst
+++ b/docs/source/algorithms/ClearCache-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -20,7 +20,7 @@ Usage
 
 **Example - ClearCache**
 
-.. testcode:: ClearCacheExample
+.. code-block:: python
 
    filesRemoved = ClearCache(DownloadedInstrumentFileCache=True)
 
@@ -32,8 +32,7 @@ Usage
 
 Output:
 
-.. testoutput:: ClearCacheExample
-   :options: +ELLIPSIS
+.. code-block:: python
 
    ... files were removed
 
diff --git a/docs/source/algorithms/ClearInstrumentParameters-v1.rst b/docs/source/algorithms/ClearInstrumentParameters-v1.rst
index 6b46c307eadb43bd2dde479be284783b13abe3ac..221189b6a350a7a9f2dc3ff263317872e02c2bb2 100644
--- a/docs/source/algorithms/ClearInstrumentParameters-v1.rst
+++ b/docs/source/algorithms/ClearInstrumentParameters-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ClearMaskFlag-v1.rst b/docs/source/algorithms/ClearMaskFlag-v1.rst
index a7954af4bf56087bf03c467ee1bfa0471fbdd8a0..d3697d77a46cfd44fa1dbdc16083c7475036a105 100644
--- a/docs/source/algorithms/ClearMaskFlag-v1.rst
+++ b/docs/source/algorithms/ClearMaskFlag-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ClearMaskedSpectra-v1.rst b/docs/source/algorithms/ClearMaskedSpectra-v1.rst
index 8574b039493519022bd0ec47722942f4b3c66b02..13a626fb6cdf37fb8bb16ea546f37ed821615750 100644
--- a/docs/source/algorithms/ClearMaskedSpectra-v1.rst
+++ b/docs/source/algorithms/ClearMaskedSpectra-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ClearUB-v1.rst b/docs/source/algorithms/ClearUB-v1.rst
index f7ddea6d04e6d15f8e44819a9ead3359312aba00..9edefe8e3860ac4e6483c7b5866bd03a904f652f 100644
--- a/docs/source/algorithms/ClearUB-v1.rst
+++ b/docs/source/algorithms/ClearUB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CloneMDWorkspace-v1.rst b/docs/source/algorithms/CloneMDWorkspace-v1.rst
index 3978dd6027783ad63014f92c8a353cdfc231622d..664ba2239bbd940b11d39ed3e44fd3bb7c6a6d82 100644
--- a/docs/source/algorithms/CloneMDWorkspace-v1.rst
+++ b/docs/source/algorithms/CloneMDWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CloneWorkspace-v1.rst b/docs/source/algorithms/CloneWorkspace-v1.rst
index d1b5458f355d7bade5f3fc35e693e3b86f0729c0..51718eba5019a5fd5101dc2cec0d232ab1f24d31 100644
--- a/docs/source/algorithms/CloneWorkspace-v1.rst
+++ b/docs/source/algorithms/CloneWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
index 8c4d91d2c0ca5b263344ef732c8d5426ffdbdf3c..075932fc57e96e1c13963f05b6579ad607a6aef2 100644
--- a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
+++ b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst b/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst
index 1d3bf040e34af59af0b1831ba25a1f4a5fe2eaf1..f3f5534d12f27c82e56302ff53f109afb848666d 100644
--- a/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst
+++ b/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Comment-v1.rst b/docs/source/algorithms/Comment-v1.rst
index aa250230abdf5da9e33eaf2036cb7bb06ab427ab..c592f7a2642e70383d56c3ec4d79aa69f3136fe6 100644
--- a/docs/source/algorithms/Comment-v1.rst
+++ b/docs/source/algorithms/Comment-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CompactMD-v1.rst b/docs/source/algorithms/CompactMD-v1.rst
index b49816bfe2f582d2d2b91954fadd367b19da1302..7eb52c0c5bf932dc588d9602cec3b1f82339cbe4 100644
--- a/docs/source/algorithms/CompactMD-v1.rst
+++ b/docs/source/algorithms/CompactMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CompareMDWorkspaces-v1.rst b/docs/source/algorithms/CompareMDWorkspaces-v1.rst
index f9c5e19a6cfa0e5795ef35b2e65905eef21a7018..6a95360b8497d102d4e9ee9b47fec92a1de2cd6b 100644
--- a/docs/source/algorithms/CompareMDWorkspaces-v1.rst
+++ b/docs/source/algorithms/CompareMDWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CompareSampleLogs-v1.rst b/docs/source/algorithms/CompareSampleLogs-v1.rst
index ce743b9a15440924fd4cb0df944b141f345b4181..6ba35f8a55eab816cc9a685668c00b841419ac9f 100644
--- a/docs/source/algorithms/CompareSampleLogs-v1.rst
+++ b/docs/source/algorithms/CompareSampleLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CompareWorkspaces-v1.rst b/docs/source/algorithms/CompareWorkspaces-v1.rst
index 10b56b5e7f30e19b77005aecf9f3b89522c441b7..edd066552cfe9d90acba1d7a4af214c7ae58226f 100644
--- a/docs/source/algorithms/CompareWorkspaces-v1.rst
+++ b/docs/source/algorithms/CompareWorkspaces-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CompressEvents-v1.rst b/docs/source/algorithms/CompressEvents-v1.rst
index b724fe240454a1a3a68fe6a90f98a937a312616b..31d04b4c265e2f995c8f80969bcdf73b55368e3a 100644
--- a/docs/source/algorithms/CompressEvents-v1.rst
+++ b/docs/source/algorithms/CompressEvents-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -16,7 +16,7 @@ resolution. This switch is made by specifying a
 
 
 Without pulsetime resolution
-============================
+############################
 
 This algorithm starts by sorting the event lists by TOF (or whatever
 the independent axis is) and ignoring the pulsetime. Therefore you may
@@ -43,7 +43,7 @@ changes to its X values (unit conversion for example), you have to use
 your best judgement for the Tolerance value.
 
 With pulsetime resolution
-=========================
+#########################
 
 Similar to the version without pulsetime resolution with a few key differences:
 
diff --git a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst
index 48e59b72e4bc468c1f1749bc7f8158cd272da4fd..0a224767475ad0b3f9fe28c3cfbb367f62aefaab 100644
--- a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst
+++ b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ComputeIncoherentDOS-v1.rst b/docs/source/algorithms/ComputeIncoherentDOS-v1.rst
index e6420dfc9ca66221f19fea17507bfc7c7c9c10ad..5d72a98029f2f4f85fc2aa622dbbc76428b58e91 100644
--- a/docs/source/algorithms/ComputeIncoherentDOS-v1.rst
+++ b/docs/source/algorithms/ComputeIncoherentDOS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ComputeSensitivity-v1.rst b/docs/source/algorithms/ComputeSensitivity-v1.rst
index 4d634d0189281f6bdc5c59d7d8f4ddf19d2e835a..d8a46b16cef52f37f75fd3c66453c3f08858f148 100644
--- a/docs/source/algorithms/ComputeSensitivity-v1.rst
+++ b/docs/source/algorithms/ComputeSensitivity-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConjoinFiles-v1.rst b/docs/source/algorithms/ConjoinFiles-v1.rst
index eb087a5e9ffba3fc4a65f52d574b6bf096dc5cc4..18c5fc1b4423d97617a5b9b18ae85fa36a358d01 100644
--- a/docs/source/algorithms/ConjoinFiles-v1.rst
+++ b/docs/source/algorithms/ConjoinFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConjoinSpectra-v1.rst b/docs/source/algorithms/ConjoinSpectra-v1.rst
index 5d12ae848478f90b9869dab522fc1d958633ee58..1de5a0aff85ac9eab4d1e70c164fa1681114ece7 100644
--- a/docs/source/algorithms/ConjoinSpectra-v1.rst
+++ b/docs/source/algorithms/ConjoinSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConjoinWorkspaces-v1.rst b/docs/source/algorithms/ConjoinWorkspaces-v1.rst
index ab027b06f819905a8b7b1df5e9c098faf4923ba3..a29f7aa4ffa2383a61b53b654098fcd24083c46c 100644
--- a/docs/source/algorithms/ConjoinWorkspaces-v1.rst
+++ b/docs/source/algorithms/ConjoinWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConjoinXRuns-v1.rst b/docs/source/algorithms/ConjoinXRuns-v1.rst
index 28b2c8b7803cd91ccd3505198b3ce595f8cdc69e..72524c195fbf05108da8f62627e89c842481e8e8 100644
--- a/docs/source/algorithms/ConjoinXRuns-v1.rst
+++ b/docs/source/algorithms/ConjoinXRuns-v1.rst
@@ -3,14 +3,14 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
 Description
 -----------
 
-This algorithm joins the input workspaces into a single one by concatenating their spectra. The concatenation is done in the same order as in the input workspaces list. Consider using :ref:`SortXAxis <algm-SortXAxis>` afterwards, if necessary. The instrument and the units are copied from the first workspace. The sample logs are also copied from the first input, but the behaviour can be controlled by the instrument parameter file (IPF), as described in :ref:`MergeRuns <algm-MergeRuns>`. Furthermore, that behaviour can be overriden by providing input to the relevant optional properties of the algorithm.
+This algorithm joins the input workspaces into a single one by concatenating their spectra. The concatenation is done in the same order as in the input workspaces list. Consider using :ref:`SortXAxis <algm-SortXAxis>` afterwards, if necessary. The instrument and the units are copied from the first workspace. The sample logs are also copied from the first input, but the behaviour can be controlled by the instrument parameter file (IPF), as described in :ref:`MergeRuns <algm-MergeRuns>`. Furthermore, that behaviour can be overriden by providing input to the relevant optional properties of the algorithm. This algorithm joins Dx values, if present.
 
 InputWorkspaces
 ---------------
diff --git a/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst b/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst
index fe11f4e7b475e4cc31670e6d5510261a5d076d5b..018ae20ab4a5c5fb45d6d55d996d0b27ae091007 100644
--- a/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst
+++ b/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertAxisByFormula-v1.rst b/docs/source/algorithms/ConvertAxisByFormula-v1.rst
index 60d703e14b4f3d7b46953e690475d648f7b5a745..88cb4d06612375d2cd859aa78442a5e5b6d20fa5 100644
--- a/docs/source/algorithms/ConvertAxisByFormula-v1.rst
+++ b/docs/source/algorithms/ConvertAxisByFormula-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
index a68b94e474bcce4b0d551ea976b2ba561fdf0c9a..39f63591a78b8b7e4e8702dbe27c2d8662d24446 100644
--- a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
+++ b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
index f73282142aa6664a7fd9c12671ba551e60d2db06..b369acddac2ee23d237e905a55effd097eb3293a 100644
--- a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
+++ b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
index a5fe1e7dceaaad46c26502eaad0fc7ac7eeaf641..5d07e1a6b65bb47dd5507a3326c1f000d92f2fd4 100644
--- a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
+++ b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertDiffCal-v1.rst b/docs/source/algorithms/ConvertDiffCal-v1.rst
index 37ddd84ceabd61ee6ef7f7669f2b991b41998ec6..77f2f08a7b6de18083f895388a7cff98dc388b9a 100644
--- a/docs/source/algorithms/ConvertDiffCal-v1.rst
+++ b/docs/source/algorithms/ConvertDiffCal-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertEmptyToTof-v1.rst b/docs/source/algorithms/ConvertEmptyToTof-v1.rst
index 917c8f09d348c5800db4385427c31d3b894eb453..a9f436b2c3db803897c002958a76d87d9814bd3f 100644
--- a/docs/source/algorithms/ConvertEmptyToTof-v1.rst
+++ b/docs/source/algorithms/ConvertEmptyToTof-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertFromDistribution-v1.rst b/docs/source/algorithms/ConvertFromDistribution-v1.rst
index d4254dcd47e71bb53410978083bc3ae9dbc094a3..4e2a20cbf40e689661c0944e66f432ead1d7c0d7 100644
--- a/docs/source/algorithms/ConvertFromDistribution-v1.rst
+++ b/docs/source/algorithms/ConvertFromDistribution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst
index f43815f52678824ea801fdf1ae5fd7674bea2004..20247520553e0c4e1d4bd2ec5a197f9918bd529f 100644
--- a/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst
+++ b/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst b/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst
index 774bc57977458878f675ceb456a7c43bf1b5ab79..f26dd0f573fcfce6bd295204bd98c58b49205b61 100644
--- a/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst
+++ b/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst b/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst
index e3315aae1c95d42c0708877555351f2be0ad91e0..daa157d1a89ad6cc20bb3edfc1ea5197b0e568df 100644
--- a/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst
+++ b/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertSpectrumAxis-v1.rst b/docs/source/algorithms/ConvertSpectrumAxis-v1.rst
index 84599ff4a6562757005ead4435f4463d8534b51e..b9f2664bfdb1c571b39cb1b878af800c72215040 100644
--- a/docs/source/algorithms/ConvertSpectrumAxis-v1.rst
+++ b/docs/source/algorithms/ConvertSpectrumAxis-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst
index 1e79f4ab6e544f016b237721a1cbec0baff85cb2..862d0dae922c3de4a5a58ddb8ade800f56105328 100644
--- a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst
+++ b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst
index ab02f5f03b42a72e0a3738023501bf3349d9e511..7b9e4474db0125b7d8b842f4d5f00ff129682757 100644
--- a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst
+++ b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst
index 8d86b1c18b62f8fe3f238db0898e7405941c1977..cbafc32b82d05596e745dabbb0cc415f17ccded2 100644
--- a/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst
+++ b/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToConstantL2-v1.rst b/docs/source/algorithms/ConvertToConstantL2-v1.rst
index abfa265e0139366892a0708a1852d43674fbc811..34ed360392dbab11717581f9380900f9442a3258 100644
--- a/docs/source/algorithms/ConvertToConstantL2-v1.rst
+++ b/docs/source/algorithms/ConvertToConstantL2-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst b/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst
index 67ceea7278cea2e58213ac2fccc7ed167923c45c..8d14fc3b38c16d7c233dcd4d45cc636679173fbc 100644
--- a/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst
+++ b/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst
index c3733997857aa96776c3576d0731207a9c87297e..75a0bde910a27d60f728198e7ca0b0f946d6772e 100644
--- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst
+++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -106,8 +106,9 @@ Usage
 **Output:**
 
 .. testoutput:: ExConvertToDiffractionMDWorkspace
+   :options: +ELLIPSIS
 
-   Resulting MD workspace has 194783 events and 3 dimensions
+   Resulting MD workspace has 194... events and 3 dimensions
    Workspace Type is:  MDEventWorkspace<MDLeanEvent,3>
 
 .. categories::
diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst
index bd352ee617991140bf6c6605adc8c047c73e76ed..c309bd613dbabe4cdaa7c5db29b80ce1c2cc6161 100644
--- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst
+++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -81,8 +81,9 @@ Usage
 **Output:**
 
 .. testoutput:: ExConvertToDiffractionMDWorkspace
+   :options: +ELLIPSIS
 
-   Resulting MD workspace has 194783 events and 3 dimensions
+   Resulting MD workspace has 1947... events and 3 dimensions
    Workspace Type is:  MDEventWorkspace<MDEvent,3>
 
 
diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst
index 513558ad5e9cd143de006e82eedfe78d33f8f81a..3df0c59439a96fcb025f74ff7714725297a43b82 100644
--- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst
+++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -71,8 +71,9 @@ Usage
 **Output:**
 
 .. testoutput:: ExConvertToDiffractionMDWorkspace
+   :options: +ELLIPSIS
 
-   Resulting MD workspace has 81058 events and 3 dimensions
+   Resulting MD workspace has 81... events and 3 dimensions
    Workspace Type is:  MDEventWorkspace<MDEvent,3>
 
 
diff --git a/docs/source/algorithms/ConvertToDistribution-v1.rst b/docs/source/algorithms/ConvertToDistribution-v1.rst
index d753ba8c5d557e33b1f3d346e94823bbc6390431..d1660ddaf72ff579adb828173b30b028ecc80cdf 100644
--- a/docs/source/algorithms/ConvertToDistribution-v1.rst
+++ b/docs/source/algorithms/ConvertToDistribution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToEventWorkspace-v1.rst b/docs/source/algorithms/ConvertToEventWorkspace-v1.rst
index 15217a14e9ce8d18b937d3c942f87b2264222be7..b5ed0670cba9c61fe7bcb44f113d6d3e984bd4a6 100644
--- a/docs/source/algorithms/ConvertToEventWorkspace-v1.rst
+++ b/docs/source/algorithms/ConvertToEventWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToHistogram-v1.rst b/docs/source/algorithms/ConvertToHistogram-v1.rst
index ba86710722ecba4f09ceb4f5f6fbb87932be2c87..a3a26052713815759fb5978756e29996c5b5dd44 100644
--- a/docs/source/algorithms/ConvertToHistogram-v1.rst
+++ b/docs/source/algorithms/ConvertToHistogram-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToMD-v1.rst b/docs/source/algorithms/ConvertToMD-v1.rst
index e822302682555ca0c97a5d72bf355a8e0497ea79..35b37c45c04ab3534278b2bd2846e498c77d88e5 100644
--- a/docs/source/algorithms/ConvertToMD-v1.rst
+++ b/docs/source/algorithms/ConvertToMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst b/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst
index 974b11cc4ef5eeaaccf0c7c4e0d4260473b4881a..cbb9f6ad6639efb42a8b0bc681806f81a05e3e92 100644
--- a/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst
+++ b/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst
index 8974a0e5da4e7dde0a11ee90a0b79b018407e319..66bf54e4e013d7c439134451618c67febb5ff5f8 100644
--- a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst
+++ b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst
index 3aecaa2f8d8b5f6d63e3077adadbd8b9c64a3cd7..a95ed0e480b1b7b07dc34d1d6baa0c6bbc4e8797 100644
--- a/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst
+++ b/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToPointData-v1.rst b/docs/source/algorithms/ConvertToPointData-v1.rst
index 2eff633e845b951fa22402a418a595fd5b8aace2..b9811d6ab5ecdc4a64ae7cf86b90726e10a7185b 100644
--- a/docs/source/algorithms/ConvertToPointData-v1.rst
+++ b/docs/source/algorithms/ConvertToPointData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst
index f97a14c55836cbb10bdbfb905bd96bda572637aa..a006f9bdc7cd8e690340779f65f05b6384a994fd 100644
--- a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst
+++ b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertToYSpace-v1.rst b/docs/source/algorithms/ConvertToYSpace-v1.rst
index b1cc08cc506cab3c4c983239658cca78869ae515..42981b13a1b13d1b2529545c4cca43210965468d 100644
--- a/docs/source/algorithms/ConvertToYSpace-v1.rst
+++ b/docs/source/algorithms/ConvertToYSpace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertUnits-v1.rst b/docs/source/algorithms/ConvertUnits-v1.rst
index c755f197ba76df381c66d7f5e4a17233b0df78df..1e37613ff86e73b409bc51adcd7ed7f84d62df74 100644
--- a/docs/source/algorithms/ConvertUnits-v1.rst
+++ b/docs/source/algorithms/ConvertUnits-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst b/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst
index fc6e37b0c5370e561651e04b50337d62001ae349..c1c2d5f352359cac7aefc5c15be65363d233be42 100644
--- a/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst
+++ b/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvolutionFitSequential-v1.rst b/docs/source/algorithms/ConvolutionFitSequential-v1.rst
index df1d4afc7319f0d50d05b22674bb44ce0d54fa03..92b2d66d6e97f37b7479596211d8c4c2410edfc0 100644
--- a/docs/source/algorithms/ConvolutionFitSequential-v1.rst
+++ b/docs/source/algorithms/ConvolutionFitSequential-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ConvolveWorkspaces-v1.rst b/docs/source/algorithms/ConvolveWorkspaces-v1.rst
index fd67dcf082c47e52312259bbd36bf501aa01ab73..2ead5bc04637464fa81b2a764494379aaee627bf 100644
--- a/docs/source/algorithms/ConvolveWorkspaces-v1.rst
+++ b/docs/source/algorithms/ConvolveWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CopyDetectorMapping-v1.rst b/docs/source/algorithms/CopyDetectorMapping-v1.rst
index d03fe81b0830c1d62f01dd790b2a8629a1e93b94..f8b034681c936e9323cfd16f132ebe36f7be8731 100644
--- a/docs/source/algorithms/CopyDetectorMapping-v1.rst
+++ b/docs/source/algorithms/CopyDetectorMapping-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CopyInstrumentParameters-v1.rst b/docs/source/algorithms/CopyInstrumentParameters-v1.rst
index 434ea4a7f72753798383b815d21b518af0a6d017..678de4f69682c3bb894a3bdb5eed3a841ab8e2dd 100644
--- a/docs/source/algorithms/CopyInstrumentParameters-v1.rst
+++ b/docs/source/algorithms/CopyInstrumentParameters-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CopyLogs-v1.rst b/docs/source/algorithms/CopyLogs-v1.rst
index a9cb195add6e4379c7e242eae5ebcdf34ccd625b..a003eee7564c12f178f4775912e99fae6979edde 100644
--- a/docs/source/algorithms/CopyLogs-v1.rst
+++ b/docs/source/algorithms/CopyLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CopySample-v1.rst b/docs/source/algorithms/CopySample-v1.rst
index b86987f43c51bd514437e9ad831f972f473db7db..dd7c0c87dcdfc33397838220e88224856586fc9c 100644
--- a/docs/source/algorithms/CopySample-v1.rst
+++ b/docs/source/algorithms/CopySample-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorelliCrossCorrelate-v1.rst b/docs/source/algorithms/CorelliCrossCorrelate-v1.rst
index daec61b383639a1c2dca468418dcee019f805c3e..0f4905988f9a98d536fd6ebb6a510bed080ff47d 100644
--- a/docs/source/algorithms/CorelliCrossCorrelate-v1.rst
+++ b/docs/source/algorithms/CorelliCrossCorrelate-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorrectKiKf-v1.rst b/docs/source/algorithms/CorrectKiKf-v1.rst
index ec0daa197c7b7fb55e51b59a81a1c331cf1f55d0..77c39bb6e766dd6d29ce85d852e4917d18c75d8f 100644
--- a/docs/source/algorithms/CorrectKiKf-v1.rst
+++ b/docs/source/algorithms/CorrectKiKf-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorrectLogTimes-v1.rst b/docs/source/algorithms/CorrectLogTimes-v1.rst
index 12bb2c85c6ce55d8dc84de877a9405100f94e859..f460a676355e08aca54eb9f0c727c58d3c863d30 100644
--- a/docs/source/algorithms/CorrectLogTimes-v1.rst
+++ b/docs/source/algorithms/CorrectLogTimes-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorrectTOF-v1.rst b/docs/source/algorithms/CorrectTOF-v1.rst
index 9fe776bc90b585a1b305be7ce25ad30ccb1f442f..16eb68c6f1a366cb226436f92b27a49680b9daba 100644
--- a/docs/source/algorithms/CorrectTOF-v1.rst
+++ b/docs/source/algorithms/CorrectTOF-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorrectTOFAxis-v1.rst b/docs/source/algorithms/CorrectTOFAxis-v1.rst
index edebd7f668b1af564fdf09871d4ae1f04efb1100..92464f500e6803c096f8e52e582578786b753278 100644
--- a/docs/source/algorithms/CorrectTOFAxis-v1.rst
+++ b/docs/source/algorithms/CorrectTOFAxis-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CorrectToFile-v1.rst b/docs/source/algorithms/CorrectToFile-v1.rst
index 08d0ec0525bbd3d5b2e349d0700d26c1b3407fe6..75b1473c8889bb9dc4c767515efbd309484eb26c 100644
--- a/docs/source/algorithms/CorrectToFile-v1.rst
+++ b/docs/source/algorithms/CorrectToFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CountReflections-v1.rst b/docs/source/algorithms/CountReflections-v1.rst
index 5d404ab75c48be0b50faf0b9c57177744d127593..764b1c8fa2627c81a6ab49caa37da7e932f0e556 100644
--- a/docs/source/algorithms/CountReflections-v1.rst
+++ b/docs/source/algorithms/CountReflections-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateCacheFilename-v1.rst b/docs/source/algorithms/CreateCacheFilename-v1.rst
index 4f292a710662190be49346aef372da7d639c3295..c27b7b290bcdab9244d9fa899946a7d798b3602b 100644
--- a/docs/source/algorithms/CreateCacheFilename-v1.rst
+++ b/docs/source/algorithms/CreateCacheFilename-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateCalFileByNames-v1.rst b/docs/source/algorithms/CreateCalFileByNames-v1.rst
index 35952daf80fc12cdbb4ce8f2bcc6a82ecb28dbd6..d1dce35d1bdef230a7ddb53c964c63e7255094ea 100644
--- a/docs/source/algorithms/CreateCalFileByNames-v1.rst
+++ b/docs/source/algorithms/CreateCalFileByNames-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateChopperModel-v1.rst b/docs/source/algorithms/CreateChopperModel-v1.rst
index 0494f9b68c45e02bc5e7a92fe34bec1cd6910136..441734571edb4ddbd45ae0a47bee28dcad596e8f 100644
--- a/docs/source/algorithms/CreateChopperModel-v1.rst
+++ b/docs/source/algorithms/CreateChopperModel-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst b/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst
index 3486c253d892a28e6318ad8992a3de44bcc1f093..d457ce06b8c8fc4b497b6af1a205148d20fc74c5 100644
--- a/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst
+++ b/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateDummyCalFile-v1.rst b/docs/source/algorithms/CreateDummyCalFile-v1.rst
index 385ce99d981219c76c4115157081d56b550ba7dd..9f9f592fde7c6de93ae8eb2eed19dc2c58ba46dd 100644
--- a/docs/source/algorithms/CreateDummyCalFile-v1.rst
+++ b/docs/source/algorithms/CreateDummyCalFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateEPP-v1.rst b/docs/source/algorithms/CreateEPP-v1.rst
index 43a4b5f9bb2e8e0b26cfb30fceebf229b5dc1c0a..c450dbf8c90607628450b1a02f1551f8c8f65100 100644
--- a/docs/source/algorithms/CreateEPP-v1.rst
+++ b/docs/source/algorithms/CreateEPP-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst b/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst
index 73e10d17ab6b47705d6c977af2f33b57bcb4b9a7..1f04900be24ff18923bb89178c83a722d60abd3d 100644
--- a/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst b/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst
index 6dc23cbb88b83863486f52c5e14ac90ca19dafc5..b2802e224aa01b66752eff5d0df3e1df06f1d7d8 100644
--- a/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
index c472673786b026cfb187f4bdfbb430348ee0ace0..b8926c91a7ac7594b3d5442b6242f0b5fff600ab 100644
--- a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateLeBailFitInput-v1.rst b/docs/source/algorithms/CreateLeBailFitInput-v1.rst
index c39b0896524ecd098e98e0e7787df18e103df2ea..e9c4749f8a6ff18ee876bce9836ea45ab4783a2e 100644
--- a/docs/source/algorithms/CreateLeBailFitInput-v1.rst
+++ b/docs/source/algorithms/CreateLeBailFitInput-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateLogPropertyTable-v1.rst b/docs/source/algorithms/CreateLogPropertyTable-v1.rst
index ec6bb4ceac7f54525652827e02acfcb62e0f5f17..6cddc1a741bbbc8b7ecd8b016bb5693a2bbef9d5 100644
--- a/docs/source/algorithms/CreateLogPropertyTable-v1.rst
+++ b/docs/source/algorithms/CreateLogPropertyTable-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst
index 1208abebe3d129655b0829ca4685ffeef1b25179..dffd463ccc5519947f24035d44710cd44118d50c 100644
--- a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst
+++ b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateMD-v1.rst b/docs/source/algorithms/CreateMD-v1.rst
index c995b084e3d1421e2e5a59a8702bda21df4ca037..826181d4ad5dbae947d779cc78d5f33b49eb326b 100644
--- a/docs/source/algorithms/CreateMD-v1.rst
+++ b/docs/source/algorithms/CreateMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst b/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst
index f7d5b533368f7c5d10eb60aa2d8a2e187fca716f..1fb31629c1a805c9b1479781fefa954aba6c1e85 100644
--- a/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateMDWorkspace-v1.rst b/docs/source/algorithms/CreateMDWorkspace-v1.rst
index 01682818c6820c79086ffe8902b6a2f5bfd1f574..c39280179d65d6d7d92a02a0a5ca6288dee6dc14 100644
--- a/docs/source/algorithms/CreateMDWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateMDWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateModeratorModel-v1.rst b/docs/source/algorithms/CreateModeratorModel-v1.rst
index b6419df33d868dc23924942913cbf38b894afae0..e5aef2c96b89fd2bbd239ea032532b9c71d061b5 100644
--- a/docs/source/algorithms/CreateModeratorModel-v1.rst
+++ b/docs/source/algorithms/CreateModeratorModel-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreatePSDBleedMask-v1.rst b/docs/source/algorithms/CreatePSDBleedMask-v1.rst
index 632ba9484bdf2159af3bc6ac269aab318bd2110f..9b680d7c3c040f941bbc30d9c3aa77f65796d1ee 100644
--- a/docs/source/algorithms/CreatePSDBleedMask-v1.rst
+++ b/docs/source/algorithms/CreatePSDBleedMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreatePeaksWorkspace-v1.rst b/docs/source/algorithms/CreatePeaksWorkspace-v1.rst
index 7538196ffafb22be8a937f64597a68167ef47d94..573908fc5547183b724831433d47ef038994f24b 100644
--- a/docs/source/algorithms/CreatePeaksWorkspace-v1.rst
+++ b/docs/source/algorithms/CreatePeaksWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateSampleShape-v1.rst b/docs/source/algorithms/CreateSampleShape-v1.rst
index e5ba9aff3f6b762f2e6bbba9e4de51ff3291f35a..d4de5dbd5bf095c3e6a624a6dbf0607e8d0ed7b9 100644
--- a/docs/source/algorithms/CreateSampleShape-v1.rst
+++ b/docs/source/algorithms/CreateSampleShape-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateSampleWorkspace-v1.rst b/docs/source/algorithms/CreateSampleWorkspace-v1.rst
index 3fd42ca473a1bf7148f76410acbdf24853e43cb0..088a661ce73ae44f711343fb99f382db15915c68 100644
--- a/docs/source/algorithms/CreateSampleWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateSampleWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -37,7 +37,7 @@ important set Random to false or uncheck the box.
   values should be set to a range symmetrical around x=0.
 
 Instrument
-~~~~~~~~~~
+##########
 
 The instrument created by CreateSample workspace is very simple and looks like
 this.
@@ -48,7 +48,7 @@ this.
 
 The sample is placed at the origin.  The source is seperated from the sample in
 the negative direction by the value you specify in "SourceDistanceFromSample".
-The instrument has "NumBanks" detector banks, each bank is moved down the X axis
+The instrument has "NumBanks" detector banks, each bank is moved down the Z axis
 by "BankDistanceFromSample" from the sample or the previous bank.
 
 Each bank is a square rectangular bank comprising of "BankPixelWidth" pixels in
diff --git a/docs/source/algorithms/CreateSimulationWorkspace-v1.rst b/docs/source/algorithms/CreateSimulationWorkspace-v1.rst
index 2f3bb5ede9ad1017ebd33666fd7eafd09c0ef85f..3d072e2884030396624a7b1ec492eb4f702d180d 100644
--- a/docs/source/algorithms/CreateSimulationWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateSimulationWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst b/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst
index cdab8c58d7191b9ea4c70eeccc8b691d941ce7fc..a45cae2192a29c358e2f4cf3b600e86fcc5cd49b 100644
--- a/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst b/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst
index d4a051e996461cfab9a62d525fa024b75d47d0b1..fc581c9a254bd023e73cf5d41a39733ac7bff604 100644
--- a/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst b/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst
index 395469e382fa7b6396de8e487b21ebaffe39ef15..b4bc5f1ffcda580efbf0f0026afade20586d0c86 100644
--- a/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst
+++ b/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst
index 57ac9a3c13c05db89ff50dc2fa306a8e4fe84744..f9e6e8527b401596085fd4c54ef9ed3523e9586b 100644
--- a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst
+++ b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst
index b599275fa98342e6a31ab4d8369a3640976d947e..7eee0bc60f82df327e5ff2d93c986b5123e73dd9 100644
--- a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst
+++ b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateUserDefinedBackground-v1.rst b/docs/source/algorithms/CreateUserDefinedBackground-v1.rst
index 3e9ee3da1275e95400169c0d3701699df946bf69..3ad76d3d2f851d0265bf6fe1651221e5103b66e9 100644
--- a/docs/source/algorithms/CreateUserDefinedBackground-v1.rst
+++ b/docs/source/algorithms/CreateUserDefinedBackground-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CreateWorkspace-v1.rst b/docs/source/algorithms/CreateWorkspace-v1.rst
index 253adc45156b444a2a36c1ff03aa300614c6a8a9..afdc4acb2435e7e5c701bec58ed30456964180e4 100644
--- a/docs/source/algorithms/CreateWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -10,14 +10,15 @@ Description
 -----------
 
 This algorithm constructs a :ref:`MatrixWorkspace <MatrixWorkspace>`
-when passed a vector for each of the X, Y, and E data values. The unit
-for the X Axis can optionally be specified as any of the units in the
+when passed a vector for each of the X, Y and optionally E and Dx values.
+The E values of the output workspace will be zero if not provided.
+The unit for the X Axis can optionally be specified as any of the units in the
 Mantid `Unit Factory <http://www.mantidproject.org/Units>`__ (see `the
 list of units currently available
 <http://www.mantidproject.org/Units>`__).  Multiple spectra may be
 created by supplying the NSpec Property (integer, default 1). When
 this is provided the vectors are split into equal-sized spectra (all
-X, Y, E values must still be in a single vector for input).
+X, Y, E, Dx values must still be in a single vector for input).
 
 When you use the input property ParentWorkspace, the new workspace is
 created with the same instrument (including its parameters), sample
@@ -57,10 +58,17 @@ Usage
 
      dataX = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
      dataY = [1,2,3,4,5,6,7,8,9,10,11,12]
+
+     # The workspace will be named "dataWS1", error values will be zero.
+     dataWS1 = CreateWorkspace(DataX=dataX, DataY=dataY, NSpec=4, UnitX="Wavelength")
+
+     # Create a workspace containing the following error values:
      dataE = [1,2,3,4,5,6,7,8,9,10,11,12]
-     
-     # The workspace will be named "dataWS"
-     dataWS = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4,UnitX="Wavelength")
+     dataWS2 = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4, UnitX="Wavelength")
+
+     # Create a workspace containing Dx values:
+     dX = [1,2,3,4,5,6,7,8,9,10,11,12]
+     dataWS3 = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4, UnitX="Wavelength", Dx=dX)
 
 .. categories::
 
diff --git a/docs/source/algorithms/CropToComponent-v1.rst b/docs/source/algorithms/CropToComponent-v1.rst
index dd58e21b903daecfda47dbbec548d84d997de739..c4513c0e53e7984ac01461b95d226d9e3f1e6004 100644
--- a/docs/source/algorithms/CropToComponent-v1.rst
+++ b/docs/source/algorithms/CropToComponent-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CropWorkspace-v1.rst b/docs/source/algorithms/CropWorkspace-v1.rst
index 7723bed4a499edeb4fcb81e1da4f29f78b73ec75..e99c98173566da67dfadde8145c7593c5e08f83d 100644
--- a/docs/source/algorithms/CropWorkspace-v1.rst
+++ b/docs/source/algorithms/CropWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CropWorkspaceRagged-v1.rst b/docs/source/algorithms/CropWorkspaceRagged-v1.rst
index 85ce724eecdf70f34dc838af7ec6026998ff3706..f09113db9c80f8ce1ba29382617f6c431752fb8d 100644
--- a/docs/source/algorithms/CropWorkspaceRagged-v1.rst
+++ b/docs/source/algorithms/CropWorkspaceRagged-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CrossCorrelate-v1.rst b/docs/source/algorithms/CrossCorrelate-v1.rst
index cfd7452b8dc7aa1830ab09ee8817daa96d7b23eb..870f9b7398f7fe55747ecd46742ac6e4670b348f 100644
--- a/docs/source/algorithms/CrossCorrelate-v1.rst
+++ b/docs/source/algorithms/CrossCorrelate-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CrystalFieldEnergies-v1.rst b/docs/source/algorithms/CrystalFieldEnergies-v1.rst
index cf102a0f030c99b473faf6398231c0a3658f7337..9750f4703ab85d24dda130151ec53b26b2618177 100644
--- a/docs/source/algorithms/CrystalFieldEnergies-v1.rst
+++ b/docs/source/algorithms/CrystalFieldEnergies-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -21,30 +21,30 @@ The algorithm calculates the crystal field energies and wave functions. The exam
       en, wf, ham = energies(1,  B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544)
       
       # a list of crystal field energies
-      print('energies:\n{}'.format(en))
+      print('energies:\n{}'.format(en[2:]))
       # a complex-valued matrix with wave functions
       print('wave functions:\n{}'.format(wf))
       # a complex-valued matrix with the Hamiltonian
       print('Hamiltonian:\n{}'.format(ham))
 
 .. testoutput::
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
      energies:
-     [  0.00000000e+00   4.97379915e-14   2.93261118e+01   2.93261118e+01
-        4.43412485e+01   4.43412485e+01]
+     [ 29.32611185  29.32611185  44.3412485   44.3412485 ]
      wave functions:
-     [[ -6.93889390e-17+0.j  -3.38877312e-01+0.j   6.80756336e-01+0.j
-        -6.25169857e-01+0.j   1.74683643e-01+0.j  -1.95256823e-02+0.j]
-      [  5.42213428e-01+0.j  -7.97569062e-17+0.j  -2.33045938e-01+0.j
-        -2.53767032e-01+0.j   8.51307403e-02+0.j   7.61609638e-01+0.j]
-      [  5.55111512e-17+0.j   7.68873700e-01+0.j   1.21082286e-01+0.j
-        -1.11195433e-01+0.j   6.14081735e-01+0.j  -6.86404558e-02+0.j]
-      [ -7.68873700e-01+0.j   6.77450070e-17+0.j   1.11195433e-01+0.j
-         1.21082286e-01+0.j   6.86404558e-02+0.j   6.14081735e-01+0.j]
-      [ -5.55111512e-17+0.j  -5.42213428e-01+0.j  -2.53767032e-01+0.j
-         2.33045938e-01+0.j   7.61609638e-01+0.j  -8.51307403e-02+0.j]
-      [  3.38877312e-01+0.j  -2.36325596e-17+0.j   6.25169857e-01+0.j
-         6.80756336e-01+0.j   1.95256823e-02+0.j   1.74683643e-01+0.j]]
+     [[ ...  ...   ...
+        ...  ...   ...]
+      [ ...  ...   ...
+        ...  ...   ...]
+      [ ...  ...   ...
+        ...  ...   ...]
+      [ ...  ...   ...
+        ...  ...   ...]
+      [ ...  ...   ...
+        ...  ...   ...]
+      [ ...  ...   ...
+        ...  ...   ...]]
      Hamiltonian:
      [[  1.86648000+0.j   0.00000000+0.j   9.27182972+0.j   0.00000000+0.j
         -3.36590841+0.j   0.00000000+0.j]
diff --git a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst
index 8b5b26683731a737ad4f26c1d4a02ada33cd63f2..3bf69ee0e9bb222480be19c4ae2b6dcc96329989 100644
--- a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst
+++ b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CutMD-v1.rst b/docs/source/algorithms/CutMD-v1.rst
index 7c77511cbc1199e97c023231229cbcc71867c1f1..ee98fac154f646c824904ad91b6c1a63db495960 100644
--- a/docs/source/algorithms/CutMD-v1.rst
+++ b/docs/source/algorithms/CutMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -22,19 +22,19 @@ is that the same number of output workspaces are also given so that CutMD knows
 what to call each output workspace created.
 
 MDEventWorkspaces
-~~~~~~~~~~~~~~~~~~~
+#################
 
 For input of type :ref:`MDEventWorkspace <MDWorkspace>` the algorithm uses :ref:`algm-BinMD` or
 :ref:`algm-SliceMD` to achieve the binning of the data. The choice of child
 algorithm used for slicing in this case is controlled by the NoPix option. 
 
 MDHistoWorkspaces
-~~~~~~~~~~~~~~~~~~~
+#################
 
 If the input is an :ref:`MDHistoWorkspace <MDHistoWorkspace>` :ref:`algm-BinMD` and :ref:`algm-SliceMD` are not made available as they needto get hold of the original MDEvents associated with an :ref:`MDEventWorkspace <MDWorkspace>` in order to perform the rebinning. As this information is missing from the MDHistoWorkspace images, those operations are forbidden. Instead, a limited subset of the operations are allowed, and are performed via :ref:`algm-IntegrateMDHistoWorkspace`. In this case, the Projection and NoPix properties are ignored. See :ref:`algm-IntegrateMDHistoWorkspace` for how the binning parameters are used.
 
 Projection Binning
-~~~~~~~~~~~~~~~~~~
+##################
 
 The 'PnBin' property, where n is between 1 and 5, is used to specify the binning for the nth dimension of the output workspace.
 The dimension will be truncated to have extents 'minimum' and 'maximum', with 'stepsize' specifying the size of the bins inbetween.
@@ -64,7 +64,7 @@ For ease of use, when using the python interface only, the 'PBins' keyword can b
 PBins accepts a tuple, or list, of PnBins parameters. The position in the list determines the dimension it corresponds to. See the Usage_ examples below.
 
 Creating Projections
-~~~~~~~~~~~~~~~~~~~~
+####################
 
 Projections are used by CutMD to transform the multidimensional data prior to
 cutting it. Projections are provided to CutMD in the form of a :ref:`TableWorkspace <Table Workspaces>`.
@@ -124,7 +124,7 @@ call the created workspace:
    CutMD(..., Projection=proj.createWorkspace(), ...)
 
 Workflow
-~~~~~~~~
+########
 
 .. diagram:: CutMD-v1_wkflw.dot
 
diff --git a/docs/source/algorithms/CylinderAbsorption-v1.rst b/docs/source/algorithms/CylinderAbsorption-v1.rst
index 8de3994299d12ae6a81078f00505c0956b0956f3..a45bd481bab5cc5833400f7e2972e9377b8b2f98 100644
--- a/docs/source/algorithms/CylinderAbsorption-v1.rst
+++ b/docs/source/algorithms/CylinderAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst b/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst
index fdc45aeb0b045aa0fcb88dc27766ebdb26a1a7c5..f800ad52d144ba53c1c778fd4ee70bf170bc4718 100644
--- a/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst
+++ b/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst b/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst
index 70c207d35afe88f1e7052e5e2184431a07c1c05e..5d3dd875ebdfceeeb03987b7805eab200789f0e0 100644
--- a/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst
+++ b/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst b/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst
index 438f785749e0f19ba84182699065993067f9a08f..612a739a34cfcd4cedec8d783a703276974e69f7 100644
--- a/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst
+++ b/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DNSMergeRuns-v1.rst b/docs/source/algorithms/DNSMergeRuns-v1.rst
index 5221c1f2fea61f1e424f3a5868bec6ea6c1cf5b5..98aa84115fb4846cd7ec8ae60773f7c76d65ec8f 100644
--- a/docs/source/algorithms/DNSMergeRuns-v1.rst
+++ b/docs/source/algorithms/DNSMergeRuns-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DPDFreduction-v1.rst b/docs/source/algorithms/DPDFreduction-v1.rst
index 2c7841286a782df6902e756072e79c659485ce65..9785ef62655fba2566065dccae43f75da3b68a04 100644
--- a/docs/source/algorithms/DPDFreduction-v1.rst
+++ b/docs/source/algorithms/DPDFreduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DSFinterp-v1.rst b/docs/source/algorithms/DSFinterp-v1.rst
index e91143ecbb9512dec5046ba19a3104f090d372e9..cb029a2f452a608e86952d87e6e4117b28e9ec8c 100644
--- a/docs/source/algorithms/DSFinterp-v1.rst
+++ b/docs/source/algorithms/DSFinterp-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DakotaChiSquared-v1.rst b/docs/source/algorithms/DakotaChiSquared-v1.rst
index dd934df4d38f40b99e99da4985a949244f8ecf9b..633f76d8ea0887d92b3c5d1e3d1f66728de6f925 100644
--- a/docs/source/algorithms/DakotaChiSquared-v1.rst
+++ b/docs/source/algorithms/DakotaChiSquared-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DefineGaugeVolume-v1.rst b/docs/source/algorithms/DefineGaugeVolume-v1.rst
index f3ed5b24a46cee53a32a5f1f8daf3aee6d02f082..ac27a86068ba4fb7e57a5e5288c423d78a9f9725 100644
--- a/docs/source/algorithms/DefineGaugeVolume-v1.rst
+++ b/docs/source/algorithms/DefineGaugeVolume-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DeleteLog-v1.rst b/docs/source/algorithms/DeleteLog-v1.rst
index 6b5a99beb9b46b33cf68db554e41772bba0d75f8..2809ddcab41845ed8923bd0171e649a2dd61534b 100644
--- a/docs/source/algorithms/DeleteLog-v1.rst
+++ b/docs/source/algorithms/DeleteLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DeleteTableRows-v1.rst b/docs/source/algorithms/DeleteTableRows-v1.rst
index bf2abca08f477ab6985655530196f0556609aa0a..0bd251222d43013b031b8b3036d04312c15a6dde 100644
--- a/docs/source/algorithms/DeleteTableRows-v1.rst
+++ b/docs/source/algorithms/DeleteTableRows-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DeleteWorkspace-v1.rst b/docs/source/algorithms/DeleteWorkspace-v1.rst
index 4f9263dc2265b95bd1bd9c091934e29e0a0e4a0f..5c041cde4e1ce35eeaf111f737634b6f34bce99e 100644
--- a/docs/source/algorithms/DeleteWorkspace-v1.rst
+++ b/docs/source/algorithms/DeleteWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DeleteWorkspaces-v1.rst b/docs/source/algorithms/DeleteWorkspaces-v1.rst
index e7284d9ffeef1e88d743a132007af022782b6b05..0c51ae0d55c5806800cb881d3c7d5c99e30c8480 100644
--- a/docs/source/algorithms/DeleteWorkspaces-v1.rst
+++ b/docs/source/algorithms/DeleteWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DeltaPDF3D-v1.rst b/docs/source/algorithms/DeltaPDF3D-v1.rst
index bf8f9572f97e428d69ace20159f61b6e1c12a62b..8469c064d83b8c715f39d25a859f8e2ec1c2bb91 100644
--- a/docs/source/algorithms/DeltaPDF3D-v1.rst
+++ b/docs/source/algorithms/DeltaPDF3D-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetectorDiagnostic-v1.rst b/docs/source/algorithms/DetectorDiagnostic-v1.rst
index 9404c8d50f14f139bf599febe406742fe92f7688..ac630bf0fcd3729f65a0c7e9d1c4ff201f28396e 100644
--- a/docs/source/algorithms/DetectorDiagnostic-v1.rst
+++ b/docs/source/algorithms/DetectorDiagnostic-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst
index 6fb7716cad4769efdca481ccb074410ffb349829..339a831e674bf3c287e07a094344b21ce5a0ac45 100644
--- a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst
+++ b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst b/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst
index 4f35ff53463775cffaf812e626f6d9eb3d1a14b9..2039b8cb1f1b369058c4bc3c48faa710c1077b0e 100644
--- a/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst
+++ b/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst b/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst
index e6ba5d1f11161f941e53d419147c079d665d7b81..8a21005e672d40a95e2bbd50d1dc9ce2fa613dd0 100644
--- a/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst
+++ b/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetectorFloodWeighting-v1.rst b/docs/source/algorithms/DetectorFloodWeighting-v1.rst
index 062a0fa633277e425f4ef57d8dc4dea982624fd7..35f13ab8f53b9ef8135240a6b61dbb0acad3ae32 100644
--- a/docs/source/algorithms/DetectorFloodWeighting-v1.rst
+++ b/docs/source/algorithms/DetectorFloodWeighting-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DetermineChunking-v1.rst b/docs/source/algorithms/DetermineChunking-v1.rst
index b7b5c49d77d77668cb8b26c8ab977567005d5094..adc7319c2c7260585bed7a3f733dec8cbc9e0105 100644
--- a/docs/source/algorithms/DetermineChunking-v1.rst
+++ b/docs/source/algorithms/DetermineChunking-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst
index cf8ade09d03a29b7f12b41fae554b050eb2b4bfd..1b11f02914b57f8e12a1abad61492b3a6309db22 100644
--- a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst
+++ b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst
index 7d319df7841690cf051e18b6fbe0f6cd6bea5bbc..392c82d4ac4e0c89e912d7d376cbf5638ef116aa 100644
--- a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst
+++ b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsDiagnose-v1.rst b/docs/source/algorithms/DgsDiagnose-v1.rst
index 027400ea8ceeec872c8e9a31471a9c0d4b888560..e5670303700227e8a1426fcd017d8667bebc9d92 100644
--- a/docs/source/algorithms/DgsDiagnose-v1.rst
+++ b/docs/source/algorithms/DgsDiagnose-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsPreprocessData-v1.rst b/docs/source/algorithms/DgsPreprocessData-v1.rst
index 8a6bafdf2087a2a19a6f43c80c96038e6cabf364..5a8946e19eb69cdadce0be3813c75a2e0dba1231 100644
--- a/docs/source/algorithms/DgsPreprocessData-v1.rst
+++ b/docs/source/algorithms/DgsPreprocessData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst
index 5431253860620c5fd1c978a999c977ee51501a47..d64d655e8f4676c82db01c5c90bb032a5985e0e9 100644
--- a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst
+++ b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsReduction-v1.rst b/docs/source/algorithms/DgsReduction-v1.rst
index 0c4d1378c9e2e92338ff308f464812650c847d84..bb33cb66ae5763043df3b75ed2f5843f5bfa40f6 100644
--- a/docs/source/algorithms/DgsReduction-v1.rst
+++ b/docs/source/algorithms/DgsReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DgsRemap-v1.rst b/docs/source/algorithms/DgsRemap-v1.rst
index de6578e7a544fbde064e28d54e1316306bf4932d..aab6dcabeef0ff60777fca85a721648dbd360ec7 100644
--- a/docs/source/algorithms/DgsRemap-v1.rst
+++ b/docs/source/algorithms/DgsRemap-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst b/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst
index 38eb213b99c53c5dc98d26745122b339edc2be0d..2e32649c61cd4305bdd3bbd4470f7feedfc28209 100644
--- a/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst
+++ b/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst b/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst
index 2d780d5c8235dbe819631fe8129b3d8d14bde27e..3ad86a09a962bb6c8292dd99f6001499859f490d 100644
--- a/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst
+++ b/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -37,9 +37,10 @@ Usage
 Output:
 
 .. testoutput:: ExDiffractionEventCalibrateDetectors
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
-    Peak in dSpace 2.69077317913
-    Peak from calibration 2.68342207235
+    Peak in dSpace 2.6...
+    Peak from calibration 2.6...
 
 
 .. categories::
diff --git a/docs/source/algorithms/DiffractionFocussing-v1.rst b/docs/source/algorithms/DiffractionFocussing-v1.rst
index 8f5b311be9a5e2a759dbb559992c509c3b78abf1..f828f72e7db9480d047ccf30258e9ce38d06dd74 100644
--- a/docs/source/algorithms/DiffractionFocussing-v1.rst
+++ b/docs/source/algorithms/DiffractionFocussing-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DiffractionFocussing-v2.rst b/docs/source/algorithms/DiffractionFocussing-v2.rst
index 70b7718cc5963360519dfed1f1af314bf15eb873..52509fe68413ec16e61f39f3d4477889eec95400 100644
--- a/docs/source/algorithms/DiffractionFocussing-v2.rst
+++ b/docs/source/algorithms/DiffractionFocussing-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst
index 2db0d942e6fbdc95d0986a0a76492c6468014536..3da05ab45e00be5a4c6be52ab32d4dbfeb2abf97 100644
--- a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst
+++ b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -126,7 +126,7 @@ Output:
 .. testoutput:: FakeIN4Example
 
     Elastic peak maximum before corrections: 26.7
-    After empty container subtraction and absorption corrections: 48.0
+    After empty container subtraction and absorption corrections: 51.5
 
 .. categories::
 
diff --git a/docs/source/algorithms/DirectILLCollectData-v1.rst b/docs/source/algorithms/DirectILLCollectData-v1.rst
index 7054fc45a80bbd70eb314df3b60b4c37b8d6e048..63f171037e5e636028ce3b3676a1278d22f0fcf9 100644
--- a/docs/source/algorithms/DirectILLCollectData-v1.rst
+++ b/docs/source/algorithms/DirectILLCollectData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DirectILLDiagnostics-v1.rst b/docs/source/algorithms/DirectILLDiagnostics-v1.rst
index 8201ca8e4d28002b176fa35ba33a30fcfc0aa623..116a1cbd1c029a2814a5ba594e4cadb242aeca81 100644
--- a/docs/source/algorithms/DirectILLDiagnostics-v1.rst
+++ b/docs/source/algorithms/DirectILLDiagnostics-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst
index b96cba3937ddf1acc3c88ca473fd1f018d3d014a..e5b620a4f35b658f1449a59425bc6c0255f315f0 100644
--- a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst
+++ b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DirectILLReduction-v1.rst b/docs/source/algorithms/DirectILLReduction-v1.rst
index f43b36417cd06d9c727fab25e60c6f5e2b85f105..41ac4fad906f450f758e34e4c0083d93f5e3a754 100644
--- a/docs/source/algorithms/DirectILLReduction-v1.rst
+++ b/docs/source/algorithms/DirectILLReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DirectILLSelfShielding-v1.rst b/docs/source/algorithms/DirectILLSelfShielding-v1.rst
index 6fe5566b416aa1b8434e5a72c1e2c16c1e147721..19f7c866da4e44d9c8fbc98ed030c2e0ea07909a 100644
--- a/docs/source/algorithms/DirectILLSelfShielding-v1.rst
+++ b/docs/source/algorithms/DirectILLSelfShielding-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -106,10 +106,11 @@ Usage
 Output:
 
 .. testoutput:: FakeIN4Example
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
     Absoprtion corrections factors for detector 1
-    Short final wavelengths: 0.4047
-    Long final wavelengths:  0.2267
+    Short final wavelengths: 0.4...
+    Long final wavelengths:  0.2...
 
 .. categories::
 
diff --git a/docs/source/algorithms/Divide-v1.rst b/docs/source/algorithms/Divide-v1.rst
index 1a4cc08943045e22bdbdb18ce62bb77298b876ef..02147daae8f404e081e1aa8c9d974767bb446e4a 100644
--- a/docs/source/algorithms/Divide-v1.rst
+++ b/docs/source/algorithms/Divide-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DivideMD-v1.rst b/docs/source/algorithms/DivideMD-v1.rst
index 258ee5dc796b76f22122b176e0756823d0e97070..96f9264388244a3528bf896dab31cc30a530c38c 100644
--- a/docs/source/algorithms/DivideMD-v1.rst
+++ b/docs/source/algorithms/DivideMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DownloadFile-v1.rst b/docs/source/algorithms/DownloadFile-v1.rst
index 85d30aae197700fda30f3aecd30154ef3d2afcdb..cdb152d68626f5c0b5f90b4caa96fa4a2e4982ec 100644
--- a/docs/source/algorithms/DownloadFile-v1.rst
+++ b/docs/source/algorithms/DownloadFile-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DownloadInstrument-v1.rst b/docs/source/algorithms/DownloadInstrument-v1.rst
index 979d7d67152c0c37815b178a65c748fe8912e514..198d5a3d4861075cf03119eaa36cb67915038fa5 100644
--- a/docs/source/algorithms/DownloadInstrument-v1.rst
+++ b/docs/source/algorithms/DownloadInstrument-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DownloadRemoteFile-v1.rst b/docs/source/algorithms/DownloadRemoteFile-v1.rst
index baafb5ea5c99109b97878fd8f2045e2bb84c8eef..5ad4690b16938e5ed362abe4983cb12047b3679d 100644
--- a/docs/source/algorithms/DownloadRemoteFile-v1.rst
+++ b/docs/source/algorithms/DownloadRemoteFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/DownloadRemoteFile-v2.rst b/docs/source/algorithms/DownloadRemoteFile-v2.rst
index 11687fb4cf839a14bab989081118bd65b5a0b2d0..12dede5c008f07ccfaec57e449247d275b3666c8 100644
--- a/docs/source/algorithms/DownloadRemoteFile-v2.rst
+++ b/docs/source/algorithms/DownloadRemoteFile-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst b/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst
index e6f083dbe8d52e5ddc08a1e68fbc1112ebca43e7..f83a4eeea4e5203caee2a21270febf85b24c0989 100644
--- a/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst
+++ b/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst
index 4e7f412815c4fffe355225b48c34a7cb62ee0c30..e371b8e32b3f368e87d53fd71b3e13108c8f83d1 100644
--- a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst
+++ b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst
index 2be799e69f6850b7ef2060e84b3dc5c6b4664a24..9a4c6b31f2fb603bde6b6c7bf95e9822714d5190 100644
--- a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst
+++ b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst b/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst
index 21cbc6fb083e9ce708aee73ca9db2ca6b55fe86d..7400110992a6c079b5e6d2078db8f4b13d52eaad 100644
--- a/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst
+++ b/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSLoad-v1.rst b/docs/source/algorithms/EQSANSLoad-v1.rst
index 755d3e89472e2172d17927f83bc670d8d9478515..545dac3422e99aebfa9de4d1d589f734e40f2f8d 100644
--- a/docs/source/algorithms/EQSANSLoad-v1.rst
+++ b/docs/source/algorithms/EQSANSLoad-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSMonitorTOF-v1.rst b/docs/source/algorithms/EQSANSMonitorTOF-v1.rst
index 3c87c117223b94da7cc7bea02d12d5893e7aa3f7..8c1cdcc1f0c0850fb312a0658cd2c38a43c34eec 100644
--- a/docs/source/algorithms/EQSANSMonitorTOF-v1.rst
+++ b/docs/source/algorithms/EQSANSMonitorTOF-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSNormalise-v1.rst b/docs/source/algorithms/EQSANSNormalise-v1.rst
index 698fd88ac8a5a9e107f05671eb54e0d14b56ed1a..b54294e0ecde79754983fe595d49d3204eaefcb3 100644
--- a/docs/source/algorithms/EQSANSNormalise-v1.rst
+++ b/docs/source/algorithms/EQSANSNormalise-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst b/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst
index b33bf402a501750cc5a477dc43b2d78fd41758e0..fbcf407733c3d04dee7c17bbe9dab71bc3fbea13 100644
--- a/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst
+++ b/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSQ2D-v1.rst b/docs/source/algorithms/EQSANSQ2D-v1.rst
index ce876f73c0327ef61c0257534d2be3d3a2f37415..5c90e3e9ecc69bb23285434ff93fede712fc3a93 100644
--- a/docs/source/algorithms/EQSANSQ2D-v1.rst
+++ b/docs/source/algorithms/EQSANSQ2D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSResolution-v1.rst b/docs/source/algorithms/EQSANSResolution-v1.rst
index 2bdcc43d8cd8ae67a49ce2fe5f817f2fa95da6d0..8fa588e49a042a91ecc01aa804f20331145975da 100644
--- a/docs/source/algorithms/EQSANSResolution-v1.rst
+++ b/docs/source/algorithms/EQSANSResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EQSANSTofStructure-v1.rst b/docs/source/algorithms/EQSANSTofStructure-v1.rst
index 1316f72372d633707aacb7d64f4ba6b5bb4fbc1b..5e7db7dcb46e27fddcdacdf9907dd7a8d3795d63 100644
--- a/docs/source/algorithms/EQSANSTofStructure-v1.rst
+++ b/docs/source/algorithms/EQSANSTofStructure-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EditInstrumentGeometry-v1.rst b/docs/source/algorithms/EditInstrumentGeometry-v1.rst
index 5526e52a64036ce9dc515f581aef62e64f00c69c..8773eb259d3ce5c66308b97d90a8dde4d7848d50 100644
--- a/docs/source/algorithms/EditInstrumentGeometry-v1.rst
+++ b/docs/source/algorithms/EditInstrumentGeometry-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ElasticWindow-v1.rst b/docs/source/algorithms/ElasticWindow-v1.rst
index 636cfe3af37ff318cd386db8c360e96bec01723e..ca1f05c38ac00b34893c207d1f9eb26e327b7376 100644
--- a/docs/source/algorithms/ElasticWindow-v1.rst
+++ b/docs/source/algorithms/ElasticWindow-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ElasticWindowMultiple-v1.rst b/docs/source/algorithms/ElasticWindowMultiple-v1.rst
index a953d30b052b9e5ad24f6c70de145f781e1cf8a4..bbfbc8f62fc09aed441d15bec8f4c9d455097dae 100644
--- a/docs/source/algorithms/ElasticWindowMultiple-v1.rst
+++ b/docs/source/algorithms/ElasticWindowMultiple-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnergyWindowScan-v1.rst b/docs/source/algorithms/EnergyWindowScan-v1.rst
index 71f91e40b69d0c259fc8d92d59d314645c44edd2..c21ce61a4f4f2ec0a55cf5c52e8173222a1cbc49 100644
--- a/docs/source/algorithms/EnergyWindowScan-v1.rst
+++ b/docs/source/algorithms/EnergyWindowScan-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggCalibrate-v1.rst b/docs/source/algorithms/EnggCalibrate-v1.rst
index 0375eb44e530f5f8bd9b0391cdb4a4ca40bbb7aa..0327a8c1d60ad0134c6ef5d28389fe6f80dadbc1 100644
--- a/docs/source/algorithms/EnggCalibrate-v1.rst
+++ b/docs/source/algorithms/EnggCalibrate-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggCalibrateFull-v1.rst b/docs/source/algorithms/EnggCalibrateFull-v1.rst
index 5cac4656139d49d652d774abe2bda0d914e327c9..ee01751308a8004a02cb8f6c263a5ae161984768 100644
--- a/docs/source/algorithms/EnggCalibrateFull-v1.rst
+++ b/docs/source/algorithms/EnggCalibrateFull-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst b/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst
index 7a3f1c2a8f31cf96d68054c8d44202f3a0f64c46..0faff5d7519df1963ccdac5b49896362c077cd30 100644
--- a/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst
+++ b/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggFitPeaks-v1.rst b/docs/source/algorithms/EnggFitPeaks-v1.rst
index 011bc6802ced80ffbd0f2d65ce19f949cf5f68b8..b94994f858a4545391caacd06b6ba1d2974e3711 100644
--- a/docs/source/algorithms/EnggFitPeaks-v1.rst
+++ b/docs/source/algorithms/EnggFitPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggFocus-v1.rst b/docs/source/algorithms/EnggFocus-v1.rst
index 12f2f1dd1206e2e076c91ed875e15d60ac8a0483..6883341f7be4c13ac2379ee697208f4699712b86 100644
--- a/docs/source/algorithms/EnggFocus-v1.rst
+++ b/docs/source/algorithms/EnggFocus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EnggVanadiumCorrections-v1.rst b/docs/source/algorithms/EnggVanadiumCorrections-v1.rst
index f980ed5fb93fc602d76cec4cd7ca88e8b92555e8..d1eae6232446e697bc04983337a48f6a19f1958a 100644
--- a/docs/source/algorithms/EnggVanadiumCorrections-v1.rst
+++ b/docs/source/algorithms/EnggVanadiumCorrections-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EqualToMD-v1.rst b/docs/source/algorithms/EqualToMD-v1.rst
index 847c6031f09bd62409b31bf9c089ced4b1d6aec3..1a59830e967de373ce14295b5cea3eb65f000cdc 100644
--- a/docs/source/algorithms/EqualToMD-v1.rst
+++ b/docs/source/algorithms/EqualToMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EstimateDivergence-v1.rst b/docs/source/algorithms/EstimateDivergence-v1.rst
index c7da06299303ad1c51fe162825860cbd66b0d02a..7d370fec154b3fdc8aa8cc52bd7bfdc73fab15f8 100644
--- a/docs/source/algorithms/EstimateDivergence-v1.rst
+++ b/docs/source/algorithms/EstimateDivergence-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EstimateFitParameters-v1.rst b/docs/source/algorithms/EstimateFitParameters-v1.rst
index 0d5f6b186e1de93ece9831834810e6477c50ed2f..6a4c58ed6eca43fc58f910ede21cb1ed22c728f8 100644
--- a/docs/source/algorithms/EstimateFitParameters-v1.rst
+++ b/docs/source/algorithms/EstimateFitParameters-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst b/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst
index 7480c94af69078cd8d7908d3ef92249fa22d393e..ce63f658d1ec03d6405f99191d7196d90001883a 100644
--- a/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst
+++ b/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EstimatePeakErrors-v1.rst b/docs/source/algorithms/EstimatePeakErrors-v1.rst
index f4783163738d039bc7cddf7f2b1fefa457fc435a..d8d424fca78f076955d8c86a33a80d6ccf23260b 100644
--- a/docs/source/algorithms/EstimatePeakErrors-v1.rst
+++ b/docs/source/algorithms/EstimatePeakErrors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
index e65e13f905c71ac70724acbad8c163c1727efb76..ec5daa91322c2033a096b8d471b36914b1be6b75 100644
--- a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
+++ b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EvaluateFunction-v1.rst b/docs/source/algorithms/EvaluateFunction-v1.rst
index 74ff2c7d9ca629132f73beffd5d68492ffa7477c..41aa5710e3682d2e93f2398023081ad276736f6c 100644
--- a/docs/source/algorithms/EvaluateFunction-v1.rst
+++ b/docs/source/algorithms/EvaluateFunction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/EvaluateMDFunction-v1.rst b/docs/source/algorithms/EvaluateMDFunction-v1.rst
index 91f8acc66df3cb1d45a660e0486936a87771518f..0c0d2d28586002f8aa4957ca218bc5deabf65c59 100644
--- a/docs/source/algorithms/EvaluateMDFunction-v1.rst
+++ b/docs/source/algorithms/EvaluateMDFunction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst
index 431f6369d1d361c47c7acbe5a7851bf742aa1b4b..78612391ca1fa4705607cff6a41b85fe32f19292 100644
--- a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst
+++ b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExampleSaveAscii-v1.rst b/docs/source/algorithms/ExampleSaveAscii-v1.rst
index 6f061321b8261b5104ba7bf3ca29a51143508816..4236bf38c2683f7ac897282fa7d451486281f321 100644
--- a/docs/source/algorithms/ExampleSaveAscii-v1.rst
+++ b/docs/source/algorithms/ExampleSaveAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Exponential-v1.rst b/docs/source/algorithms/Exponential-v1.rst
index a08913dde2c45e787ff609f3842336a866672cf6..46d725e7142e7d5e21dc516ceefa20ca2a68839f 100644
--- a/docs/source/algorithms/Exponential-v1.rst
+++ b/docs/source/algorithms/Exponential-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExponentialCorrection-v1.rst b/docs/source/algorithms/ExponentialCorrection-v1.rst
index 369f24d942c622bb0e75c2faedf55bed283146e8..c060e683940133ef3480f93deafc3d3193f8ca21 100644
--- a/docs/source/algorithms/ExponentialCorrection-v1.rst
+++ b/docs/source/algorithms/ExponentialCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExponentialMD-v1.rst b/docs/source/algorithms/ExponentialMD-v1.rst
index 2076609d36e4e3b8d68f910cc143184d7ccbcc60..6207ef6a5ed964737aeb8761f791d9ea41909b87 100644
--- a/docs/source/algorithms/ExponentialMD-v1.rst
+++ b/docs/source/algorithms/ExponentialMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExportExperimentLog-v1.rst b/docs/source/algorithms/ExportExperimentLog-v1.rst
index 25967655bf6a061dfae2a0dd00b2164fdf93478a..19be177823c599db598e6a58c0d6a1bb5fabae0e 100644
--- a/docs/source/algorithms/ExportExperimentLog-v1.rst
+++ b/docs/source/algorithms/ExportExperimentLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExportGeometry-v1.rst b/docs/source/algorithms/ExportGeometry-v1.rst
index 53878c8d80451e9faf099d99d59f4f39441a3d10..1318b1a78527ee8a9c5ad6b3d9836e303ad0c11e 100644
--- a/docs/source/algorithms/ExportGeometry-v1.rst
+++ b/docs/source/algorithms/ExportGeometry-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst
index 51d77cd96ff035ec9e82455dfb20da82cc152221..085c78f0e285edac366f336693663985c2356ec8 100644
--- a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst
+++ b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -15,7 +15,7 @@ The header for the sample log csv file can also
 be created by this algorithm in a seperate *header* file. 
 
 CSV File format
-===============
+###############
 
 Sample logs are written to a csv file.   
 A tab separates any two adjacent values. 
@@ -35,7 +35,7 @@ Here is the definition for the columns.
    *SampleLogNames*
 
 Header file
-===========
+###########
 
 A sample log header file can be generated optionally.  
 It contains theree lines described as below. 
@@ -46,7 +46,7 @@ It contains theree lines described as below.
    Usually it is the column names in the .csv file
 
 Time Zone
-=========
+#########
 
 The time stamps of sample logs are recorded as UTC time in SNS.
 Some users wants to see the exported sample log as the neutron facility's local time.
diff --git a/docs/source/algorithms/ExportSpectraMask-v1.rst b/docs/source/algorithms/ExportSpectraMask-v1.rst
index 92b65de4497b03674b20339ace2d1e3d58599b64..5bf6179e0cb1337de30222f62a264c0709b0f295 100644
--- a/docs/source/algorithms/ExportSpectraMask-v1.rst
+++ b/docs/source/algorithms/ExportSpectraMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst
index 3434bd092b51eb7281cfd14cf0ca1da8205cb83f..139228477de64cf180388fb5e03cda600e9f86e3 100644
--- a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst
+++ b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst
index 7d75cd5a0624cdeb8ea37030c4294d5cdfdf0c9e..d87dd5f5888b8913878be7e2afecbd89c82967a0 100644
--- a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst
+++ b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractMask-v1.rst b/docs/source/algorithms/ExtractMask-v1.rst
index 2a9dfa07dfac906df5e3650e46669658598dd59d..1f13ca0e28b5f4324f99ae8718128bbd45487917 100644
--- a/docs/source/algorithms/ExtractMask-v1.rst
+++ b/docs/source/algorithms/ExtractMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -18,6 +18,8 @@ new MatrixWorkspace with a single X bin where:
 The spectra containing 0 are also marked as masked and the instrument
 link is preserved so that the instrument view functions correctly.
 
+A list of masked detector IDs is also output. Note this contains the detector IDs which 
+are masked rather than the index or spectrum number. 
 
 Usage
 -----
@@ -29,11 +31,11 @@ Usage
     #create a workspace with a 3*3 pixel detector
     bankPixelWidth = 3
     ws = CreateSampleWorkspace(NumBanks=1,BankPixelWidth=bankPixelWidth)
-    
+
     #Mask out every other detector
     MaskDetectors(ws,WorkspaceIndexList=range(0,bankPixelWidth*bankPixelWidth,2))
 
-    wsMask = ExtractMask(ws)
+    wsMask, maskList = ExtractMask(ws)
 
     #This mask can then be applied to another workspace
     ws2 = CreateSampleWorkspace(NumBanks=1,BankPixelWidth=bankPixelWidth)
@@ -43,6 +45,9 @@ Usage
     print("n ws    ws2")
     for i in range (ws.getNumberHistograms()):
         print("%i %-5s %s" % (i, ws.getDetector(i).isMasked(), ws2.getDetector(i).isMasked()))
+        
+    print("\nMasked detector IDs")
+    print(maskList)
 
 Output:
 
@@ -59,6 +64,9 @@ Output:
     6 True  True
     7 False False
     8 True  True
+    
+    Masked detector IDs
+    [ 9 11 13 15 17]
 
 .. categories::
 
diff --git a/docs/source/algorithms/ExtractMaskToTable-v1.rst b/docs/source/algorithms/ExtractMaskToTable-v1.rst
index 35251f1b572874413e799e90af46c554a7b6a83e..7dab04928908856782234f3b1b61830017ee38f7 100644
--- a/docs/source/algorithms/ExtractMaskToTable-v1.rst
+++ b/docs/source/algorithms/ExtractMaskToTable-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst b/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst
index 0185717cdffeccf2a6d527dbcf3d703b218591ef..626c243bbb2a3bb7b2bdda0152799e2cf1bdfdbf 100644
--- a/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst
+++ b/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractMonitors-v1.rst b/docs/source/algorithms/ExtractMonitors-v1.rst
index 6b758461ae92904339b815e67ce7c3b9cb3d398e..d1c180bec8b1691bcb79e57668911241d41b7081 100644
--- a/docs/source/algorithms/ExtractMonitors-v1.rst
+++ b/docs/source/algorithms/ExtractMonitors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractQENSMembers-v1.rst b/docs/source/algorithms/ExtractQENSMembers-v1.rst
index 67f9613c6ccf9b8afb749945b2fc6561ba7cc04c..8ea5b640408287fb97c886c03ab21660a17d0bd2 100644
--- a/docs/source/algorithms/ExtractQENSMembers-v1.rst
+++ b/docs/source/algorithms/ExtractQENSMembers-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractSingleSpectrum-v1.rst b/docs/source/algorithms/ExtractSingleSpectrum-v1.rst
index 624dd7889b1ec0eb6a587521b328d5cf40778567..3dfb14755c4c932ffa1c177b44805eb5bb943487 100644
--- a/docs/source/algorithms/ExtractSingleSpectrum-v1.rst
+++ b/docs/source/algorithms/ExtractSingleSpectrum-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractSpectra-v1.rst b/docs/source/algorithms/ExtractSpectra-v1.rst
index 094704b06f804cbef7d0deb2064261ef2d1dfbc4..361a05673b8bcf94b8df086084771b77dbdea467 100644
--- a/docs/source/algorithms/ExtractSpectra-v1.rst
+++ b/docs/source/algorithms/ExtractSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst b/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst
index 3d3a3ca9fc00f457a62d89d611c36f860fc92e05..439e06812cbdaf33af27d9f5cea0a9c1d857587d 100644
--- a/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst
+++ b/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FFT-v1.rst b/docs/source/algorithms/FFT-v1.rst
index 23d8d392f4b37f2c901b3baa7ef116ef2dc1ba47..467c249b81709bd7fc9cc4239181355756d2683b 100644
--- a/docs/source/algorithms/FFT-v1.rst
+++ b/docs/source/algorithms/FFT-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FFTDerivative-v1.rst b/docs/source/algorithms/FFTDerivative-v1.rst
index fd926b6bbf5d8d5dacc2ff393c9e0c04d83ac61b..4e15e3737e21a10ceb0ee9e77a6ef49a1e9ab5ac 100644
--- a/docs/source/algorithms/FFTDerivative-v1.rst
+++ b/docs/source/algorithms/FFTDerivative-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FFTSmooth-v1.rst b/docs/source/algorithms/FFTSmooth-v1.rst
index 244a668c3db3d2311931b7e808e09ddbed4db73b..277c3e01e7862fb6ea2ef7e889ea42edf87a0ad2 100644
--- a/docs/source/algorithms/FFTSmooth-v1.rst
+++ b/docs/source/algorithms/FFTSmooth-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FFTSmooth-v2.rst b/docs/source/algorithms/FFTSmooth-v2.rst
index 1bef23441fa9d1c2c1f63958f524f23b54dbade3..9b44faa260f1261c08a17e50e22f8639a4bf7215 100644
--- a/docs/source/algorithms/FFTSmooth-v2.rst
+++ b/docs/source/algorithms/FFTSmooth-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FakeISISEventDAE-v1.rst b/docs/source/algorithms/FakeISISEventDAE-v1.rst
index dd8ccf50f955d24ba2ed4df6e515f024f5588696..34a928799ebb54bbf152812ac52ac01efaa304aa 100644
--- a/docs/source/algorithms/FakeISISEventDAE-v1.rst
+++ b/docs/source/algorithms/FakeISISEventDAE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -25,7 +25,11 @@ Usage
 
 **Example:**
 
-.. testcode:: exFakeISISEventDAE
+.. This test is currently hanging on macOS as the MonitorLiveData algorithm
+   is taking a long time to cancel
+.. .. testcode:: exFakeISISEventDAE
+
+.. code-block:: python
 
     from threading import Thread
     import time
@@ -42,20 +46,22 @@ Usage
     def captureLive():
         ConfigService.setFacility("TEST_LIVE")
 
-        # start a Live data listener updating every second, that rebins the data
-        # and replaces the results each time with those of the last second.
-        StartLiveData(Instrument='ISIS_Event', OutputWorkspace='wsOut', UpdateEvery=1,
-                      ProcessingAlgorithm='Rebin', ProcessingProperties='Params=10000,1000,20000;PreserveEvents=1',
-                      AccumulationMethod='Add', PreserveEvents=True)
-
-        # give it a couple of seconds before stopping it
-        time.sleep(2)
-
-        # This will cancel both algorithms
-        # you can do the same in the GUI
-        # by clicking on the details button on the bottom right
-        AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
-        AlgorithmManager.newestInstanceOf("FakeISISEventDAE").cancel()
+        try:
+            # start a Live data listener updating every second, that rebins the data
+            # and replaces the results each time with those of the last second.
+            StartLiveData(Instrument='ISIS_Event', OutputWorkspace='wsOut', UpdateEvery=1,
+                          ProcessingAlgorithm='Rebin', ProcessingProperties='Params=10000,1000,20000;PreserveEvents=1',
+                          AccumulationMethod='Add', PreserveEvents=True)
+
+            # give it a couple of seconds before stopping it
+            time.sleep(2)
+        finally:
+            # This will cancel both algorithms
+            # you can do the same in the GUI
+            # by clicking on the details button on the bottom right
+            AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
+            AlgorithmManager.newestInstanceOf("FakeISISEventDAE").cancel()
+            time.sleep(1)
     #--------------------------------------------------------------------------------------------------
 
     oldFacility = ConfigService.getFacility().name()
diff --git a/docs/source/algorithms/FakeISISHistoDAE-v1.rst b/docs/source/algorithms/FakeISISHistoDAE-v1.rst
index 64be954cbced56b98848eb8a87ce33e02bcb82c4..6cbe8c7711f5fc23fe8da78f72c276a675f400d0 100644
--- a/docs/source/algorithms/FakeISISHistoDAE-v1.rst
+++ b/docs/source/algorithms/FakeISISHistoDAE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -36,20 +36,21 @@ Usage
     def captureLive():
         ConfigService.setFacility("TEST_LIVE")
 
-        # start a Live data listener updating every second, that rebins the data
-        # and replaces the results each time with those of the last second.
-        StartLiveData(Instrument='ISIS_Histogram', OutputWorkspace='wsOut', UpdateEvery=1,
-                      AccumulationMethod='Replace')
-
-        # give it a couple of seconds before stopping it
-        time.sleep(2)
-
-        # This will cancel both algorithms
-        # you can do the same in the GUI
-        # by clicking on the details button on the bottom right
-        AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
-        AlgorithmManager.newestInstanceOf("FakeISISHistoDAE").cancel()
-        time.sleep(1) # give them time to cancel
+        try:
+            # start a Live data listener updating every second, that rebins the data
+            # and replaces the results each time with those of the last second.
+            StartLiveData(Instrument='ISIS_Histogram', OutputWorkspace='wsOut', UpdateEvery=1,
+                          AccumulationMethod='Replace')
+
+            # give it a couple of seconds before stopping it
+            time.sleep(2)
+        finally:
+            # This will cancel both algorithms
+            # you can do the same in the GUI
+            # by clicking on the details button on the bottom right
+            AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
+            AlgorithmManager.newestInstanceOf("FakeISISHistoDAE").cancel()
+            time.sleep(1)
     #--------------------------------------------------------------------------------------------------
 
     oldFacility = ConfigService.getFacility().name()
diff --git a/docs/source/algorithms/FakeMDEventData-v1.rst b/docs/source/algorithms/FakeMDEventData-v1.rst
index 2566749755edc5d75e9b5844c2ccfde93edaceb5..ecc8148bcba0d910239c2f614f4c0d70d8226665 100644
--- a/docs/source/algorithms/FakeMDEventData-v1.rst
+++ b/docs/source/algorithms/FakeMDEventData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FilterBadPulses-v1.rst b/docs/source/algorithms/FilterBadPulses-v1.rst
index d90b34fa8d438906d3e10522207b9a0263198d43..b98e55478c0c8cefc901bd27987f778b71d3bbf7 100644
--- a/docs/source/algorithms/FilterBadPulses-v1.rst
+++ b/docs/source/algorithms/FilterBadPulses-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FilterByLogValue-v1.rst b/docs/source/algorithms/FilterByLogValue-v1.rst
index 757d3077511bcb83499f5f4d800867303b258a91..6579b1d95d58e25908e113772d61d9159450c7be 100644
--- a/docs/source/algorithms/FilterByLogValue-v1.rst
+++ b/docs/source/algorithms/FilterByLogValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -108,8 +108,8 @@ Output:
 
 .. testoutput:: FilterByLogValue
 
-   The unfiltered workspace ws has 1900 events and a peak value of 257.00
-   The filtered workspace wsOut has 950 events and a peak value of 131.00
+   The unfiltered workspace ws has 1900 events and a peak value of 2...
+   The filtered workspace wsOut has 950 events and a peak value of 1...
 
 
 .. categories::
diff --git a/docs/source/algorithms/FilterByTime-v1.rst b/docs/source/algorithms/FilterByTime-v1.rst
index 075d9cd6d4ce2e367808a47ee1f900a669ce9949..9cd99c8e2e5aeba027438486202f27c4c3a05ea8 100644
--- a/docs/source/algorithms/FilterByTime-v1.rst
+++ b/docs/source/algorithms/FilterByTime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -60,10 +60,11 @@ Usage
 Output:
 
 .. testoutput:: ExFilter
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
-    The number of events within the relative Filter: 950
-    The number of events within the Aboslute Filter: 315
-    Compared to the number in the unfiltered workspace: 1900
+    The number of events within the relative Filter: 95...
+    The number of events within the Aboslute Filter: 3...
+    Compared to the number in the unfiltered workspace: 190...
 
 
 .. categories::
diff --git a/docs/source/algorithms/FilterByXValue-v1.rst b/docs/source/algorithms/FilterByXValue-v1.rst
index 120a8e3626f171b84ddb5bc0c03d463722563edb..c1331f3d01fabfdcaa8a54fb1e41dfc78e6c5755 100644
--- a/docs/source/algorithms/FilterByXValue-v1.rst
+++ b/docs/source/algorithms/FilterByXValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -52,9 +52,10 @@ Output:
 Output:
 
 .. testoutput:: ExFilterWavelengthByMinMax
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
     1900 events before filtering
-    1118 events after filtering
+    11... events after filtering
 
 
 .. categories::
diff --git a/docs/source/algorithms/FilterEvents-v1.rst b/docs/source/algorithms/FilterEvents-v1.rst
index 40f20b1ae091a316562937393a1c068720f258ee..3697e881b78c2552e5f2c8ebb64cd4b1baa6a620 100644
--- a/docs/source/algorithms/FilterEvents-v1.rst
+++ b/docs/source/algorithms/FilterEvents-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -100,6 +100,17 @@ name ended with '\_unfiltered'.
 If input property 'OutputWorkspaceIndexedFrom1' is set to True, then
 this workspace shall not be outputed.
 
+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``.
+
 Difference from FilterByLogValue
 ################################
 
diff --git a/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst b/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst
index f561ec03ba6462196d994dfd9949370d738e7b61..38dad32fd64bcd66ecaade737f301460331cc7bd 100644
--- a/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst
+++ b/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FilterLogByTime-v1.rst b/docs/source/algorithms/FilterLogByTime-v1.rst
index 3a59a1ecd3255866ba099938b67ccfe01ece06b2..cc472181d1f8c353b4cf916a8ac75e60f74974f8 100644
--- a/docs/source/algorithms/FilterLogByTime-v1.rst
+++ b/docs/source/algorithms/FilterLogByTime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FilterPeaks-v1.rst b/docs/source/algorithms/FilterPeaks-v1.rst
index 0e2c5e8510f26806ba88a884e7eb2ceb913f6ce7..60b68602faa47c04ffdac867fb9f27f66f8831c5 100644
--- a/docs/source/algorithms/FilterPeaks-v1.rst
+++ b/docs/source/algorithms/FilterPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindCenterOfMassPosition-v1.rst b/docs/source/algorithms/FindCenterOfMassPosition-v1.rst
index 089aeba786c3e2a72c6e84e647f42645ee3cdaab..d3ce89a051092bfdc88adc68e4f4b5d32f36270a 100644
--- a/docs/source/algorithms/FindCenterOfMassPosition-v1.rst
+++ b/docs/source/algorithms/FindCenterOfMassPosition-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindCenterOfMassPosition-v2.rst b/docs/source/algorithms/FindCenterOfMassPosition-v2.rst
index 6e52fe5e4c59b50f61134e4523a07ecc2afcf5a2..807494f5f19438330e642fcccdf2a3bb63a71205 100644
--- a/docs/source/algorithms/FindCenterOfMassPosition-v2.rst
+++ b/docs/source/algorithms/FindCenterOfMassPosition-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindClusterFaces-v1.rst b/docs/source/algorithms/FindClusterFaces-v1.rst
index e9dc29408f41256c10c615ae87aebb124827b2dc..2aaab72b277ce334707245e4a86d825fe2f349a0 100644
--- a/docs/source/algorithms/FindClusterFaces-v1.rst
+++ b/docs/source/algorithms/FindClusterFaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindDeadDetectors-v1.rst b/docs/source/algorithms/FindDeadDetectors-v1.rst
index 9b2e143ec19b91b48ffa75831c27e5123b134215..61183a433f719809ecfd64c905f3f1a901282ebd 100644
--- a/docs/source/algorithms/FindDeadDetectors-v1.rst
+++ b/docs/source/algorithms/FindDeadDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindDetectorsInShape-v1.rst b/docs/source/algorithms/FindDetectorsInShape-v1.rst
index 396988effb94fd4de0137525dea4c93b7dcee0d9..6a5e7072d7bc754b4ec96ac841dfa411eb76243a 100644
--- a/docs/source/algorithms/FindDetectorsInShape-v1.rst
+++ b/docs/source/algorithms/FindDetectorsInShape-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst b/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst
index 1533d25ddaa87184d675276c7e50a26a80bfea0f..3b4d4cbeeaddfabc5cc4909fd39efe19f8515169 100644
--- a/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst
+++ b/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindDetectorsPar-v1.rst b/docs/source/algorithms/FindDetectorsPar-v1.rst
index 4ba2c875bdd5863d42d4eda7583d62568de4e826..26102ba80274f1ed6dbbb4c1c7bb1be2ee663c47 100644
--- a/docs/source/algorithms/FindDetectorsPar-v1.rst
+++ b/docs/source/algorithms/FindDetectorsPar-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindEPP-v1.rst b/docs/source/algorithms/FindEPP-v1.rst
index e3e3334e8964df233a9422a44d2b2ce58bfaa89a..689deffb32291925359773af8d27a8914f60cc1f 100644
--- a/docs/source/algorithms/FindEPP-v1.rst
+++ b/docs/source/algorithms/FindEPP-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindEPP-v2.rst b/docs/source/algorithms/FindEPP-v2.rst
index 5d21c8caf27c5c1e12403f093a1c978c26dfca50..6d9bf273840e450aea7ff311e6fb0f4e8f9b880e 100644
--- a/docs/source/algorithms/FindEPP-v2.rst
+++ b/docs/source/algorithms/FindEPP-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindPeakBackground-v1.rst b/docs/source/algorithms/FindPeakBackground-v1.rst
index 74a0ba5dbc1ecad94b04ff36568381c3d47b9d79..13fe933f2bec15837591eb6a41fad34e994f92be 100644
--- a/docs/source/algorithms/FindPeakBackground-v1.rst
+++ b/docs/source/algorithms/FindPeakBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindPeaks-v1.rst b/docs/source/algorithms/FindPeaks-v1.rst
index 065598ee6f040f4cf8f65089ab4161cbe6f5a245..7e0ca332f4876b2813bd9398f3a2da7756aa12fe 100644
--- a/docs/source/algorithms/FindPeaks-v1.rst
+++ b/docs/source/algorithms/FindPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindPeaksMD-v1.rst b/docs/source/algorithms/FindPeaksMD-v1.rst
index 5d799903afdfd42609c4a6b9845cc40d800a103d..48f18985df86a044e7c1f615d2ce8d490ad3e582 100644
--- a/docs/source/algorithms/FindPeaksMD-v1.rst
+++ b/docs/source/algorithms/FindPeaksMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -85,6 +85,8 @@ First calculate the :math:`\textbf{Q}_{lab}` using
 
 .. math:: \phi = \sin^{-1}(-\textbf{Q}_{sample}^y \sin(\theta)/k)
 
+where :math:`\theta` is from 0 to :math:`\pi` and  :math:`\phi` is from :math:`-\pi/2` to :math:`\pi/2`. This means that it will assume your detector position is on the left of the beam even it it's not.
+
 Now you have :math:`\theta`, :math:`\phi` and k you can get :math:`\textbf{Q}_{lab}` using (1).
 
 We need to now solve :math:`G \textbf{Q}_{sample} =
@@ -145,24 +147,24 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp
 
    def print_tableWS(pTWS,nRows):
        ''' Method to print part of the table workspace '''
-       tab_names=pTWS.keys();
-       
+       tab_names=pTWS.keys()
+       row = ""
        for name in tab_names:
            if len(name)>8:
-              name= name[0:8];
-           print("| {0:8} ".format(name))
-       print("|\n")
-   
-       for i in xrange(0,nRows):
+              name= name[:8]
+           row += "| {:8} ".format(name)
+       print(row + "|")
+ 
+       for i in range(nRows):
+           row = ""
            for name in tab_names:
                  col = pTWS.column(name);
                  data2pr=col[i]
                  if type(data2pr) is float:
-                      print("| {0:>8.2f} ".format(data2pr))
+                     row += "| {:8.1f} ".format(data2pr)
                  else:
-                     print("| {0:>8} ".format(data2pr))
-           print("|\n")
-       
+                     row += "| {:8} ".format(str(data2pr))
+           print(row + "|")
     
    # load test workspace
    Load(Filename=r'TOPAZ_3132_event.nxs',OutputWorkspace='TOPAZ_3132_event',LoadMonitors='1')
@@ -183,17 +185,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp
 
    #.. testoutput:: exFindPeaksMD
 
-   | RunNumbe  | DetID     | h         | k         | l         | Waveleng  | Energy    | TOF       | DSpacing  | Intens    | SigInt    | BinCount  | BankName  | Row       | Col       | QLab      | QSample   |
-   |     3132  |  1124984  |     0.00  |     0.00  |     0.00  |     3.10  |     8.49  | 14482.29  |     2.02  |     0.00  |     0.00  |  1668.00  |   bank17  |   120.00  |    42.00  | [1.57771,1.21779,2.37854]  | [2.99396,0.815958,0.00317344]  |
-   |     3132  |  1156753  |     0.00  |     0.00  |     0.00  |     2.08  |    18.82  |  9725.74  |     1.30  |     0.00  |     0.00  |  1060.00  |   bank17  |   145.00  |   166.00  | [2.48964,1.45725,3.88666]  | [4.52618,1.71025,0.129461]  |
-   |     3132  |  1141777  |     0.00  |     0.00  |     0.00  |     1.71  |    28.09  |  7963.17  |     1.05  |     0.00  |     0.00  |    96.00  |   bank17  |    17.00  |   108.00  | [2.60836,2.31423,4.86391]  | [5.69122,1.79492,-0.452799]  |
-   |     3132  |  1125241  |     0.00  |     0.00  |     0.00  |     1.55  |    33.86  |  7252.16  |     1.01  |     0.00  |     0.00  |    83.00  |   bank17  |   121.00  |    43.00  | [3.15504,2.42573,4.75121]  | [5.97829,1.63473,0.0118744]  |
-   |     3132  |  1170598  |     0.00  |     0.00  |     0.00  |     1.55  |    34.12  |  7224.59  |     0.95  |     0.00  |     0.00  |    73.00  |   bank17  |   166.00  |   220.00  | [3.43363,1.70178,5.39301]  | [6.07726,2.59962,0.281759]  |
-   |     3132  |  1214951  |     0.00  |     0.00  |     0.00  |     1.89  |    22.79  |  8839.55  |     1.68  |     0.00  |     0.00  |   719.00  |   bank18  |   231.00  |   137.00  | [2.73683,1.43808,2.11574]  | [3.5786,0.470838,1.00329]  |
-   |     3132  |  1207827  |     0.00  |     0.00  |     0.00  |     1.71  |    27.89  |  7991.70  |     1.32  |     0.00  |     0.00  |   447.00  |   bank18  |    19.00  |   110.00  | [2.80324,2.29519,3.09134]  | [4.71517,0.554412,0.37714]  |
-   |     3132  |  1232949  |     0.00  |     0.00  |     0.00  |     1.24  |    53.28  |  5782.14  |     0.93  |     0.00  |     0.00  |    45.00  |   bank18  |    53.00  |   208.00  | [4.29033,2.63319,4.46168]  | [6.52658,1.27985,1.00646]  |
-   |     3132  |  1189484  |     0.00  |     0.00  |     0.00  |     1.14  |    63.42  |  5299.28  |     0.96  |     0.00  |     0.00  |    31.00  |   bank18  |   108.00  |    38.00  | [4.02414,3.39659,3.83664]  | [6.4679,0.298896,0.726133]  |
-   |     3132  |  1218337  |     0.00  |     0.00  |     0.00  |     1.01  |    79.81  |  4724.05  |     0.77  |     0.00  |     0.00  |    15.00  |   bank18  |    33.00  |   151.00  | [4.96622,3.61607,5.32554]  | [7.99244,1.19363,0.892655]  |
+   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  | PeakNumb |
+   | 3132     | 1124984  |      0.0 |      0.0 |      0.0 |      3.1 |      8.5 |  14482.3 |      2.0 |      0.0 |      0.0 |   1668.0 | bank17   |    120.0 |     42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1        |
+   | 3132     | 1156753  |      0.0 |      0.0 |      0.0 |      2.1 |     18.8 |   9725.7 |      1.3 |      0.0 |      0.0 |   1060.0 | bank17   |    145.0 |    166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2        |
+   | 3132     | 1141777  |      0.0 |      0.0 |      0.0 |      1.7 |     28.1 |   7963.2 |      1.0 |      0.0 |      0.0 |     96.0 | bank17   |     17.0 |    108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3        |
+   | 3132     | 1125241  |      0.0 |      0.0 |      0.0 |      1.6 |     33.9 |   7252.2 |      1.0 |      0.0 |      0.0 |     83.0 | bank17   |    121.0 |     43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4        |
+   | 3132     | 1170598  |      0.0 |      0.0 |      0.0 |      1.5 |     34.1 |   7224.6 |      0.9 |      0.0 |      0.0 |     73.0 | bank17   |    166.0 |    220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5        |
+   | 3132     | 1214951  |      0.0 |      0.0 |      0.0 |      1.9 |     22.8 |   8839.5 |      1.7 |      0.0 |      0.0 |    719.0 | bank18   |    231.0 |    137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6        |
+   | 3132     | 1207827  |      0.0 |      0.0 |      0.0 |      1.7 |     27.9 |   7991.7 |      1.3 |      0.0 |      0.0 |    447.0 | bank18   |     19.0 |    110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7        |
+   | 3132     | 1232949  |      0.0 |      0.0 |      0.0 |      1.2 |     53.3 |   5782.1 |      0.9 |      0.0 |      0.0 |     45.0 | bank18   |     53.0 |    208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8        |
+   | 3132     | 1189484  |      0.0 |      0.0 |      0.0 |      1.1 |     63.4 |   5299.3 |      1.0 |      0.0 |      0.0 |     31.0 | bank18   |    108.0 |     38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9        |
+   | 3132     | 1218337  |      0.0 |      0.0 |      0.0 |      1.0 |     79.8 |   4724.1 |      0.8 |      0.0 |      0.0 |     15.0 | bank18   |     33.0 |    151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10       |
 
 
 .. categories::
diff --git a/docs/source/algorithms/FindReflectometryLines-v1.rst b/docs/source/algorithms/FindReflectometryLines-v1.rst
index 8658801e013f42af57adff0cd8459122cc7a49d6..959852929a21a44864e08f5f17c460e0f6be10e5 100644
--- a/docs/source/algorithms/FindReflectometryLines-v1.rst
+++ b/docs/source/algorithms/FindReflectometryLines-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindSXPeaks-v1.rst b/docs/source/algorithms/FindSXPeaks-v1.rst
index 91f6a7d0cf04248351e12b6d9deda8bb2eb96600..231ad55bb22e0eefa0e60063e5cdf11de690da27 100644
--- a/docs/source/algorithms/FindSXPeaks-v1.rst
+++ b/docs/source/algorithms/FindSXPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindUBUsingFFT-v1.rst b/docs/source/algorithms/FindUBUsingFFT-v1.rst
index d28fab4eba2815da1da1886b43ed2f50f9d6d36f..20db2c2cc337dc49873c24e6a4ff67383ec2ec98 100644
--- a/docs/source/algorithms/FindUBUsingFFT-v1.rst
+++ b/docs/source/algorithms/FindUBUsingFFT-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst b/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst
index f642030ababeffc07362f34a5a34a6a2dfd102f5..ca033741902560dd1b180c1c887b7e978e5e317e 100644
--- a/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst
+++ b/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst b/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst
index 1d8012832fd618895f8a1b5083108474958f5960..bdf33137bce63442ec0d9e770fa227572eefff87 100644
--- a/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst
+++ b/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst b/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst
index e3c3fac4117d740d2ab13ac8a5dd2ed1b5da4e23..f49ad16a667dc2133f00f94658320b661c35d813 100644
--- a/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst
+++ b/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Fit-v1.rst b/docs/source/algorithms/Fit-v1.rst
index 035b0430a80232ed73337d74293b2f047bc5ea8f..1b2237850be5f6cbf32cfa300463e224f585a726 100644
--- a/docs/source/algorithms/Fit-v1.rst
+++ b/docs/source/algorithms/Fit-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FitGaussian-v1.rst b/docs/source/algorithms/FitGaussian-v1.rst
index 779dd6ba6da4a9b2722b8665f41849e7fad85a1d..c6f36f47c7496eb5c14e9d951c260575a8aca6d6 100644
--- a/docs/source/algorithms/FitGaussian-v1.rst
+++ b/docs/source/algorithms/FitGaussian-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FitPeak-v1.rst b/docs/source/algorithms/FitPeak-v1.rst
index 0149c2ebf09b15df50917f656e824f3b5454131e..47a93d71844c2e5bc701033a6e5a8460e177eec7 100644
--- a/docs/source/algorithms/FitPeak-v1.rst
+++ b/docs/source/algorithms/FitPeak-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FitPeaks-v1.rst b/docs/source/algorithms/FitPeaks-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b59accc45922ec19f654fdda0c5a4335bf566b96
--- /dev/null
+++ b/docs/source/algorithms/FitPeaks-v1.rst
@@ -0,0 +1,435 @@
+.. algorithm::
+
+.. summary::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm fits a set of specified peaks in a set of specified spectra in a :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>`,
+returning a list of the successfully fitted peaks along with
+optional output for fitting information.
+
+The list of candidate peaks found is passed to a fitting routine and
+those that are successfully fitted are kept and returned in the output
+workspace (and logged at information level). The output
+:class:`TableWorkspace <mantid.api.ITableWorkspace>`
+contains the following columns,
+which reflect the fact that the peak has been fitted to a Gaussian atop
+a linear background: spectrum, centre, width, height,
+backgroundintercept & backgroundslope.
+
+Assumption
+##########
+
+It is assumed that the values of peaks' profile parameters, such as peak width,
+are somehow correlated within a single spectrum.
+Therefore, the fitted profile parameters values of a peak should be good starting values
+to fit the peaks adjacent to this peak.
+
+Required pre-knowledge
+######################
+
+The following information are required.
+
+* Assumed position of each peak
+* Peak profile function
+* Background type (flat or linear)
+* Starting values of peak parameters
+
+For better results
+==================
+
+* Peak fit window: this is an option
+
+  a. specified by user
+  b. figured out by :ref:`FindPeakBackground <algm-FindPeakBackground>`, first moments and second moments (NEED TO FIND OUT THE ALGORITHM)
+  c. if the workspace is in unit dSpacing and :math:`\Delta d/d`
+
+* Peak position tolerance: there could be three cases for how the peak position tolerance is specified.
+
+  a. specified by user
+  b. defined by peak windows
+  c. half distance to the neighboring peak (if not (a) and not (b))
+  d. whole range of X-axis (if there is one and only one peak in a spectrum)
+
+
+
+Description of algorithm
+########################
+
+For each spectrum, it is assumed that there are N peaks to fit.
+The fitting starts from either the peak at the smallest X value or the largest X values depending on the
+user's input.
+The first peak will be fit with the starting value provided by the user.
+except background and peak center, which will be determiend by *observation*.
+
+Background
+##########
+
+Linear background is used for fitting peaks.  The background parameters
+will be estimated via *observation*.
+
+Estimation of values of peak profiles
+#####################################
+
+Peak intensity and peak center are estimated by observing the maximum value within peak fit window.
+
+Subalgorithms used
+##################
+
+``FitPeaks`` uses the :ref:`Fit <algm-Fit>` algorithm to fit each single peak.
+``FitPeaks`` uses the :ref:`FindPeakBackground <algm-FindPeakBackground>` algorithm to estimate the background of each peak.
+
+
+Inputs
+======
+
+The inputs tends to be general enough for various use cases.
+
+
+Limitations on Partial Spectra
+##############################
+
+* For partial spectra peak fitting, the spectra must be consecutive.
+
+
+Peak positions
+##############
+
+One of only one of the following will be taken.
+
+* A :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>`
+
+  * Number of spectra shall be the same as the number of spectra of the workspace containing peaks to fit for.  Or the number of spectra is the same as the number of spectra of the input workspace.
+  * X value is the index of the peak.
+  * Y value is the position of the peaks to fit.
+  * Peak centers are stored in ``m_peakCenterWorkspace``.
+  * Spectra can be a subset of all spectra because ``FitPeaks`` can work on partial spectra.
+
+* An array of double as the positions of the peaks to fit.
+
+  * Peak centers are stored in ``m_peakCenters``
+
+
+**Peaks' positions must be given in ascending order**
+
+Parameter ``FitFromRight`` deontes start fits from right most peak rather than left most peak.
+
+
+
+Fit Window
+##########
+
+There are two input parameters that are associated with fitting window.
+
+* FitWindowBoundaryList
+* FitPeakWindowWorkspace
+
+
+If FitWindows is defined, then a peak's range to fit (i.e., x-min and
+x-max) is confined by this window.
+
+If FitWindows is defined, starting peak centres are NOT user's input,
+but found by highest value within peak window. (Is this correct???)
+
+
+Further down the road, here are the fitting setup that can be affected.
+
+* Peak positions are uniform among all spectra
+
+  - Peak window information will be retrieved from **m_peakWindowVector**
+
+* Peak positions are different among spectra.
+
+  - Peak windown information will be retrieved from **m_peakWindowWorkspace**
+
+
+Tolerance on Fitting Peaks Positions
+####################################
+
+Tolerance will be always checked!
+
+* Uniform tolerance
+
+* Non-uniform tolerance
+
+* Case 2, 3 and 4
+
+
+Algorithm Configurations
+########################
+
+* Peak profile starting value will be given as
+
+  - an array ``PeakParameterValues`` such that the starting values are uniform among all spectra.
+  - a table (workspace) ``PeakParameterValueTable`` such that the starting values are not necessary same among all spectra.
+
+
+Calculation of starting value of peak profile and background parameters
+-----------------------------------------------------------------------
+
+``FitPeaks`` supports estimating peak parameter names as starting values.
+
+
+Workflow
+########
+
+1. Call :ref:`FindPeakBackground <algm-FindPeakBackground>` to estimate the background of peak with a numerical approach.
+
+   * Some tests have made to show that most time :ref:`FindPeakBackground <algm-FindPeakBackground>` failed to do a valid estimation.  Therefore this feature is temporarily disabled.
+
+2. If :ref:`FindPeakBackground <algm-FindPeakBackground>` fails, *estimate-peak-background* will be used for simple approximation.
+
+3. Estimate the peak parameter, *estimate-peak-parameter*, by using the estimated peak background obtained in either step 1 or step 2.
+
+4. Estimate the peak range, which is used to constrain the peak position in fitting, by using the left *FWHM* and right *FWHM* from step 3.
+
+Estimate background
+###################
+
+*Estimate-peak-background* takes *peak fit window* for pre-knowledge, and calculate *a* and *b* in the linear background function.
+
+The algorithm is
+1. Find the left and right *N* points respectively, average both *x* and *y* value
+2. Use :math:`(\bar{x}_1, \bar{y}_1)` and :math:`(\bar{x}_2, \bar{y}_2)` to calculate *a* and *b* in :math:`y = a\cdot x + b`
+
+Estimate peak parameters
+########################
+
+*Estimate-peak-parameters* requires background parameters being estimated.
+
+Here is the approach to estimate the peak parameters
+
+1. Remove background.
+
+2. Find maximum Y value as the *observed* peak center and peak height :math:`H_{obs}`.
+
+3. Check peak height with user-specified minimum height and peak center that must be at least more than 3 data points away from the boundary of fit window.
+
+4. Find the left and right *FWHM* by searching :math:`x_i` and :math:`x_{i+1}` such that :math:`H_{obs}` is between :math:`y_i` and :math:`y_{i+1}`.
+
+
+Estimate peak range
+===================
+
+*Estimate-peak-range* requires inputs including expected peak center, fit window and estimated right and left FWHM.
+It will output the left and right boundary of the peak such that the background can be fit by excluding the peak.
+
+1. Peak range is defined as :math:`x_0 \pm 6 \cdot w`, where *w* is half of FWHM for either left or right half of peak.
+
+2. Check the number of background points out of peak range at the left and right side respectively.
+   It is required to have at least 3 background points at either side, i.e., :math:`min(3, \frac{i_{x0} - i_{min}}{6})` for left side.
+
+
+
+Fit peak with high background
+#############################
+
+Step 1
+======
+
+Reduce the background by finding a linear function :math:`B_i = a\cdot x_i + b`,
+such that :math:`\sum_i (Y_i - B_i)` is minimum while any :math:`Y_i - B_i` is non-negative.
+
+This approach is good for any background close to linear within the fit window.
+
+Step 2
+======
+
+With the background reduced in step 1, it will be more reliable to estimate the peak's FWHM via *observation*.
+
+Step 3
+======
+Fit peak... ...........
+
+Step 3
+======
+
+Get the peak range (by *estimate-peak-range*) and fit the background with *FitMultiDomain* to fit background.
+
+Step 4
+======
+
+Remove the background and fit peak!
+
+
+Outputs
+-------
+
+Algorithm ``FitPeaks`` is designed for various purposes including but not limited to vanadium peak striping and fitting diamond peaks to calibrate detectors' positions.
+On the other hand, due to the complexity in peak fitting, users prefer to check the fitting results.
+Therefore, ``FitPeaks`` supports various fexible and informative outputs.
+
+OutputWorkspace
+###############
+
+It is a :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>` containing the peak positions expected and fitted.
+
+* The output workspace has *N* spectra corresponding to the spectra that are specified by user via ``MinimumWorkspaceIndex`` and ``MaximumWorkspaceIndex``.
+* If there are *m* peaks that are required to fit for, then each spectrum in the output workspace has *m* data points.
+* In each spectrum, *x(i)* is the expected position of *i-th* peak; *y(i)* is the fitted position of *i-th* peak; and *e(i)* is the cost from fitting.
+* There are several cases that the fitting could fail.  A negative peak position *y(i)* combined with *e(i)* equal to *DBL_MAX* denote such failure.
+* Cause of fitting failure is denoted by different negative value of *y(i)*
+  - -1: empty spectrum
+  - -2: spectrum with too few counts
+  - -3: peak is low
+  - -4: TODO : find out the answer
+  - -5: TODO : find out the answer
+
+
+
+It is a TableWorkspace containing peak parameters.
+According to user's specication, it will contain one parameter, i.e., peak position, or all parameters.
+
+The order of the peaks will be exactly the sequence of peaks as the order of the given positions of peaks.
+
+
+FittingCostWorkspace
+####################
+
+It is a :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>` recording the cost of each peak that is fitted.
+It is in the exactly same order as the given positions of peaks to fit.
+Its X values store the fitted peak positions and Y values are for :math:`\chi^2`.
+
+If a peak's fitting is bad, then the peak position will be its proposed peak position,
+while its :math:`\chi^2` shall be some special value.
+
+
+FittedPeaksWorkspace
+####################
+
+It is an optional output :py:obj:`MatrixWorkspace <mantid.api.MatrixWorkspace>`.
+
+For each spectrum, in each fit window, the Y values will be replaced by the calcualted peak and background value.
+If fitting is bad, then only background is calculated.
+
+
+
+Usage
+-----
+
+**Example - Find a single peak:**
+
+.. testcode:: ExFindPeakSingle
+
+  ws = CreateSampleWorkspace(Function="User Defined",
+                             UserDefinedFunction="name=LinearBackground, A0=0.3;name=Gaussian, PeakCentre=5, Height=10, Sigma=0.7",
+                             NumBanks=1, BankPixelWidth=1, XMin=0, XMax=10, BinWidth=0.1)
+
+  FitPeaks(InputWorkspace='ws', PeakCenters='5.1', FitWindowBoundaryList='0,10', OutputPeakParametersWorkspace='fitted_params',
+           BackgroundType='Linear', FittedPeaksWorkspace='fitted', OutputWorkspace='peakpositions')
+
+  peakposws = mtd['peakpositions']
+  param_ws = mtd['fitted_params']
+  row = param_ws.row(0)
+
+  # output
+  print ('Fitted peak position: {0:.5f}'.format(peakposws.readY(0)[0]))
+  print ("Peak 0  Centre: {0:.5f}, width: {1:.5f}, height: {2:.5f}".format(row["PeakCentre"], row["Sigma"], row["Height"]))
+
+  # clean up workspaces
+  DeleteWorkspace(Workspace='fitted')
+  DeleteWorkspace(Workspace='fitted_params')
+  DeleteWorkspace(Workspace='ws')
+  DeleteWorkspace(Workspace='peakpositions')
+
+
+
+Output:
+
+.. testoutput:: ExFindPeakSingle
+
+   Fitted peak position: 5.05000
+   Peak 0  Centre: 5.05000, width: 0.70000, height: 10.00000
+
+
+**Example - Fit peaks on high background (vanadium):**
+
+.. testcode:: ExFitVanadiumPeaks
+
+  # load a 4 spectra workspace
+  ws = Load("PG3_733.nxs")
+
+  van_peak_centers = "0.5044,0.5191,0.5350,0.5526,0.5936,0.6178,0.6453,0.6768,0.7134,0.7566,0.8089,0.8737,0.9571,1.0701,1.2356,1.5133,2.1401"
+  FitPeaks(InputWorkspace=ws, StartWorkspaceIndex=0, StopWorkspaceIndex=3,PeakCenters=van_peak_centers,
+             FitFromRight=True,HighBackground=True,
+             BackgroundType='Quadratic',
+             PeakWidthPercent=0.008,
+             OutputWorkspace='PG3_733_peak_positions',OutputPeakParametersWorkspace='PG3_733_peak_params',
+             FittedPeaksWorkspace='PG3_733_fitted_peaks')
+
+  PG3_733_peak_positions = mtd["PG3_733_peak_positions"]
+  ep0 = PG3_733_peak_positions.readX(0)[-1]
+  ep1 = PG3_733_peak_positions.readX(0)[-2]
+  ep2 = PG3_733_peak_positions.readX(0)[-3]
+  fp0 = PG3_733_peak_positions.readY(0)[-1]
+  fp1 = PG3_733_peak_positions.readY(0)[-2]
+  fp2 = PG3_733_peak_positions.readY(0)[-3]
+
+  # print data
+  print ('Spectrum 1: Expected right most 3 peaks at {0:.7f}, {1:.7f}, {2:.7f}'.format(ep0, ep1, ep2))
+  print ('Spectrum 1: Found    right most 3 peaks at {0:.7f}, {1:.7f}, {2:.7f}'.format(fp0, fp1, fp2))
+
+  # delete workspaces
+  DeleteWorkspace(Workspace='PG3_733_peak_positions')
+  DeleteWorkspace(Workspace='PG3_733_fitted_peaks')
+  DeleteWorkspace(Workspace='PG3_733_peak_params')
+  DeleteWorkspace(Workspace='ws')
+
+
+Output:
+
+.. testoutput::  ExFitVanadiumPeaks
+
+  Spectrum 1: Expected right most 3 peaks at 2.1401000, 1.5133000, 1.2356000
+  Spectrum 1: Found    right most 3 peaks at 2.1483553, 1.5188663, 1.2401992
+
+
+**Example - Fit back-to-back exponential peaks (Vulcan diamond):**
+
+.. testcode:: ExFitVulcanPeaks
+
+  # load data
+  Load(Filename="vulcan_diamond.nxs", OutputWorkspace="diamond_3peaks")
+
+  FitPeaks(InputWorkspace="diamond_3peaks", StartWorkspaceIndex=0, StopWorkspaceIndex=5,
+         PeakCenters="0.6867, 0.728299, 0.89198, 1.0758",
+         PeakFunction="BackToBackExponential", BackgroundType="Linear",
+         FitWindowBoundaryList="0.67, 0.709, 0.71, 0.76, 0.87, 0.92, 1.05, 1.1",
+         PeakParameterNames="I, A, B, X0, S",
+         PeakParameterValues="2.5e+06, 5400, 1700, 1.07, 0.000355",
+         FitFromRight=True,
+         HighBackground=False,
+         OutputWorkspace="diamond_peaks_centers",
+         OutputPeakParametersWorkspace="PeakParametersWS2",
+         FittedPeaksWorkspace="FittedPeaksWS2")
+
+  fitted_peak_pos_ws = mtd['diamond_peaks_centers']
+
+  # print result
+  for ws_index in range(0, 1):
+      print ('Spectrum {0}:'.format(ws_index+1))
+      for peak_index in range(2, 4):
+          exp_pos = fitted_peak_pos_ws.readX(ws_index)[peak_index]
+          fit_pos = fitted_peak_pos_ws.readY(ws_index)[peak_index]
+          print ('Expected @ {0:.3f}  Fitted @ {1:.3f}'.format(exp_pos, fit_pos))
+
+  # clean
+  DeleteWorkspace(Workspace='diamond_3peaks')
+  DeleteWorkspace(Workspace='diamond_peaks_centers')
+  DeleteWorkspace(Workspace='FittedPeaksWS2')
+  DeleteWorkspace(Workspace='PeakParametersWS2')
+
+Output:
+
+.. testoutput:: ExFitVulcanPeaks
+
+  Spectrum 1:
+  Expected @ 0.892  Fitted @ 0.892
+  Expected @ 1.076  Fitted @ 1.075
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/FitPowderDiffPeaks-v1.rst b/docs/source/algorithms/FitPowderDiffPeaks-v1.rst
index 04796e007eb77eb7145ee504c60c915852133e7b..ce7ec4115642e46324a8509c57b2e9b14c0df893 100644
--- a/docs/source/algorithms/FitPowderDiffPeaks-v1.rst
+++ b/docs/source/algorithms/FitPowderDiffPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst b/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst
index 2d8770ff4f101fb34cd88a979eaf9a4c54557db7..992e88294ed18d4f215129779bf38d1f775473a2 100644
--- a/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst
+++ b/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FixGSASInstrumentFile-v1.rst b/docs/source/algorithms/FixGSASInstrumentFile-v1.rst
index fe76a35484bf0a99a8867c5ccd939d4079039eb1..e7c62fd3c165f466f271aba30523ec63743c6e2c 100644
--- a/docs/source/algorithms/FixGSASInstrumentFile-v1.rst
+++ b/docs/source/algorithms/FixGSASInstrumentFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FlatPlateAbsorption-v1.rst b/docs/source/algorithms/FlatPlateAbsorption-v1.rst
index 1ef508555216b7e32a86d944769184d155394b61..b7807180e3d3f46d57cf663de6053bab7464d382 100644
--- a/docs/source/algorithms/FlatPlateAbsorption-v1.rst
+++ b/docs/source/algorithms/FlatPlateAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst b/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
index 1cf5a9118b4df6a334ef118db7892e2ae66674cc..fe854b26b83f4ce8550c166061bd526ff3e77f3d 100644
--- a/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
+++ b/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst b/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst
index 638d651e1f2e066429942664a376598cbf07fb35..93a2bc9c4c0f15ea566a2bb9eee1bca121febcbb 100644
--- a/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst
+++ b/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -118,7 +118,7 @@ Usage
    # You would normally generate the focused file using the Engg GUI or,
    # alternatively, with commands like these:
    #
-   # wks = Load('ENGINX00256663-256675')
+   # ws_to_focus = Load('ENGINX00256663-256675')
    # wks_ceria = Load('ENGINX00255924')
    # wks_vana = Load('ENGINX00254854')
    # # Using default expected peaks for Ceria
@@ -127,50 +127,53 @@ Usage
    # SaveNexus(InputWorkspace=wks_focused, Filename='focused_bank1_ENGINX00256663.nxs')
    #
    wks = Load('focused_bank1_ENGINX00256663.nxs')
-   peaks, residuals, lattice_params = \
+   peaks, lattice_params, rwp, sigma, gamma = \
        GSASIIRefineFitPeaks(InputWorkspace=wks,
-                            RefinementMethod="PawleyRefinement",
+                            RefinementMethod="Pawley refinement",
                             InstrumentFile='template_ENGINX_241391_236516_North_bank.prm',
-                            PhaseInfoFile='FE_ALPHA.cif',
-                            PathToGSASII='/home/user/gsas',
-                            SaveGSASIIProjectFile='example_gsas2_project.gpx')
-   print "Goodness of fit coefficient: {0:.5f}".format(residuals.row(0)["GoF"])
-   print "Weighted profile R-factor (Rwp): {0:.5f}".format(residuals.row(0)["Rwp"])
-   print ("Lattice parameters, a: {a}, b: {b}, c: {c}, alpha: {alpha}, beta: {beta}, gamma: {gamma}, "
-          "Volume: {volume:.3f}".format(**lattice_params.row(0)))
+                            PhaseInfoFiles='Fe-alpha.cif,Fe-gamma.cif',
+                            PathToGSASII='/home/user/g2conda/GSASII',
+                            RefineSigma=True,
+                            RefineGamma=True,
+                            SaveGSASIIProjectFile='example_gsas2_project.gpx',
+                            OutputWorkspace="FittedPeaks")
+   print("Weighted profile R-factor (Rwp): {0:.5f}".format(rwp))
+   print("Lattice parameters, a: {a}, b: {b}, c: {c}, alpha: {alpha}, beta: {beta}, gamma: {gamma}, "
+         "Volume: {volume:.3f}".format(**lattice_params.row(0)))
+   print("Sigma={}, Gamma={}".format(sigma, gamma))
 
 Output:
 
 .. code-block:: none
 
-    Goodness of fit coefficient: 3.57847
     Weighted profile R-factor (Rwp): 77.75515
     Lattice parameters, a: 2.8665, b: 2.8665, c: 2.8665, alpha: 90.0, beta: 90.0, gamma: 90.0, Volume: 23.554
+    Sigma=81.0939, Gamma=0.1855
 
 **Example - Rietveld refinement of lattice parameters from a diffraction spectrum**
 
 .. code-block:: python
 
    wks=Load('focused_bank1_ENGINX00256663.nxs')
-   peaks, residuals, lattice_params = \
+   peaks, lattice_params, rwp, sigma, gamma = \
        GSASIIRefineFitPeaks(InputWorkspace=wks,
                             RefinementMethod='Rietveld refinement',
                             InstrumentFile='template_ENGINX_241391_236516_North_bank.prm',
-                            PhaseInfoFile='FE_ALPHA.cif',
-                            PathToGSASII='/home/user/gsas',
+                            PhaseInfoFiles='Fe-alpha.cif,Fe-gamma.cif',
+                            PathToGSASII='/home/user/g2conda/GSASII',
                             SaveGSASIIProjectFile='example_gsas2_project.gpx',
-   print "Goodness of fit coefficient: {0:.5f}".format(residuals.row(0)["GoF"]))
-   print "Weighted profile R-factor (Rwp): {0:.5f}".format(residuals.row(0)["Rwp"])
-   print ("Lattice parameters, a: {a}, b: {b}, c: {c}, alpha: {alpha}, beta: {beta}, gamma: {gamma}, "
-          "Volume: {volume:.3f}".format(**lattice_params.row(0)))
+   print("Weighted profile R-factor (Rwp): {0:.5f}".format(rwp))
+   print("Lattice parameters, a: {a}, b: {b}, c: {c}, alpha: {alpha}, beta: {beta}, gamma: {gamma}, "
+         "Volume: {volume:.3f}".format(**lattice_params.row(0)))
+   print("Sigma={}, Gamma={}".format(sigma, gamma))
 
 Output:
 
 .. code-block:: none
 
-    Goodness of fit coefficient: 3.57776
     Weighted profile R-factor (Rwp): 77.75499
     Lattice parameters, a: 2.8665, b: 2.8665, c: 2.8665, alpha: 90.0, beta: 90.0, gamma: 90.0, Volume: 23.554
+    Sigma=81.0939, Gamma=0.1855
 
 .. categories::
 
diff --git a/docs/source/algorithms/GatherWorkspaces-v1.rst b/docs/source/algorithms/GatherWorkspaces-v1.rst
index 3e58b64aef50be660ed550ac2195a2e57d776df3..cdcd8907366c5bde3f6956f12fbec6387e41f131 100644
--- a/docs/source/algorithms/GatherWorkspaces-v1.rst
+++ b/docs/source/algorithms/GatherWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GeneralisedSecondDifference-v1.rst b/docs/source/algorithms/GeneralisedSecondDifference-v1.rst
index 8d9c9a05ee1936c0fd7682305689b6445dfef879..94359793ffba5a2e51dce897d24fc25840f9c0b5 100644
--- a/docs/source/algorithms/GeneralisedSecondDifference-v1.rst
+++ b/docs/source/algorithms/GeneralisedSecondDifference-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GenerateEventsFilter-v1.rst b/docs/source/algorithms/GenerateEventsFilter-v1.rst
index f08d70e464ced94ca3b8b878f085c92d370233a2..3bd3a0ede0018a5de42d7b73bb8bec6e9873ad78 100644
--- a/docs/source/algorithms/GenerateEventsFilter-v1.rst
+++ b/docs/source/algorithms/GenerateEventsFilter-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -95,12 +95,12 @@ Generate event filters by time
 ##############################
 
 Event filters can be created by defining start time, stop time and time intervals. 
-The three input properties for them are *StartTime*, *StopTime* and *TimeInterval*, 
+The three input properties for them are ``StartTime``, ``StopTime`` and ``TimeInterval``, 
 respectively. 
 
-*TimeInterval* accepts an array of doubles.  
+``TimeInterval`` accepts an array of doubles.  
 If the array size is zero, then there will be one and only splitter will be 
-created from *StartTime* and *StopTime*.  
+created from ``StartTime`` and ``StopTime``.  
 If the size of the array is one, then all event splitters will have the same duration
 of time. 
 In general if the array is composed as :math:`t_1, t_2, \cdots, t_n`, 
@@ -115,7 +115,7 @@ Unit of time
 ============
 
 There are three types of units that are supported for time. 
-They are second, nanosecond and percentage of duration from *StartTime* to *StopTime*. 
+They are second, nanosecond and percentage of duration from ``StartTime`` to ``StopTime``. 
 
 .. _filterbylogv-GenerateEventFilter-ref:
 
@@ -158,19 +158,25 @@ Algorithm Parameters and Examples
 Here are the introductions to some important parameters (i.e., algorithm's properties). 
 
 
-Parameter: *Centre*
-###################
+Parameter: ``Centre``
+#####################
 
-The input Boolean parameter *centre* is for filtering by log value(s).
-If option *centre* is taken, then for each interval,
+The input Boolean parameter ``centre`` is for filtering by log value(s).
+If option ``centre`` is taken, then for each interval,
 
 -  starting time = log\_time - tolerance\_time;
 -  stopping time = log\_time - tolerance\_time;
 
 It is a shift to left.
 
-Parameter: *MinimumLogValue*, *MaximumLogValue*, *LogValueTolerance* and *LogValueInterval*
-###########################################################################################
+Parameter: ``FastLog``
+######################
+
+When ``FastLog`` is set to True, a :ref:`MatrixWorkspace <MatrixWorkspace>` will be used to store the event
+splitters, which is more appropriate for fast changing logs. (see above for details).
+
+Parameter: ``MinimumLogValue``, ``MaximumLogValue``, ``LogValueTolerance`` and ``LogValueInterval``
+###################################################################################################
 
 These four parameters are used to determine the log value intervals for
 filtering events.
@@ -191,11 +197,11 @@ Integer value log
 
 It is a little bit different for sample log recorded with integer. 
 
-- *MinimumLogValue* and *MaximumLogValue* can be same such that only entries with exacly the same log value 
+- ``MinimumLogValue`` and ``MaximumLogValue`` can be same such that only entries with exacly the same log value 
   will be considered;
-- If *LogValueInterval* is not give (i.e., default value is used), then any log enetry with log value
-  larger and equal to *MinimumLogValue* and smaller and equal to *MaximumLogValue* will be considered. 
-  Be noticed that in the same case for double value log, log entry with value equal to *MaximumLogValue*
+- If ``LogValueInterval`` is not give (i.e., default value is used), then any log enetry with log value
+  larger and equal to ``MinimumLogValue`` and smaller and equal to ``MaximumLogValue`` will be considered. 
+  Be noticed that in the same case for double value log, log entry with value equal to ``MaximumLogValue``
   will be excluded. 
 
 
diff --git a/docs/source/algorithms/GenerateGroupingPowder-v1.rst b/docs/source/algorithms/GenerateGroupingPowder-v1.rst
index 1e60ca05e6fb269f36e9f8f5e4bdde3f83446079..fd0bf506a2b35230c172b8e7751a676cfc9a42f8 100644
--- a/docs/source/algorithms/GenerateGroupingPowder-v1.rst
+++ b/docs/source/algorithms/GenerateGroupingPowder-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst b/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst
index be4e371ec3fb747c6348267006df75d8e68325de..9247cc1f73f6e535422e685ec37063c0abd9c35f 100644
--- a/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst
+++ b/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GenerateIPythonNotebook-v1.rst b/docs/source/algorithms/GenerateIPythonNotebook-v1.rst
index 5f5d2f6066e18af71b2664c0fd42ad69243a63b1..fe434664c108c08d82ebbe1257404dd31aba4a65 100644
--- a/docs/source/algorithms/GenerateIPythonNotebook-v1.rst
+++ b/docs/source/algorithms/GenerateIPythonNotebook-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GeneratePeaks-v1.rst b/docs/source/algorithms/GeneratePeaks-v1.rst
index ba3f9dd6a809c533e655a4b0fe8e7149637f771e..bd8e69b466f4b2762b3d68bfb1e67de27d79823c 100644
--- a/docs/source/algorithms/GeneratePeaks-v1.rst
+++ b/docs/source/algorithms/GeneratePeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GeneratePythonScript-v1.rst b/docs/source/algorithms/GeneratePythonScript-v1.rst
index 120ec60cc48b46ec9f72d05bc7a5e6a037dac4c5..d4e7b1958f7d00c8d2ac53a046103ea049896196 100644
--- a/docs/source/algorithms/GeneratePythonScript-v1.rst
+++ b/docs/source/algorithms/GeneratePythonScript-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetAllEi-v1.rst b/docs/source/algorithms/GetAllEi-v1.rst
index ac64d4a3fbe58b2fcf1c320705e3f4a3a6495ac3..b5585acaaea5895352c2cd63becf03da933b5a78 100644
--- a/docs/source/algorithms/GetAllEi-v1.rst
+++ b/docs/source/algorithms/GetAllEi-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst
index 2f15f722ff0dd012c15ed2ee40b8ae6d9cd68693..cf7c75e13ccfbc30b61cf18453b9aaf1c5087171 100644
--- a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst
+++ b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetDetectorOffsets-v1.rst b/docs/source/algorithms/GetDetectorOffsets-v1.rst
index c7e6cbc02259548f7799f7cc5be25fdbee46d78c..79b10bfde4d548e5b3bfc2973e6e2feb25f88566 100644
--- a/docs/source/algorithms/GetDetectorOffsets-v1.rst
+++ b/docs/source/algorithms/GetDetectorOffsets-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetEi-v1.rst b/docs/source/algorithms/GetEi-v1.rst
index f6f69d097d0931201f6322117c223c39016a5c08..d977599197ed9f01011bd0e9d2cf323bd5042590 100644
--- a/docs/source/algorithms/GetEi-v1.rst
+++ b/docs/source/algorithms/GetEi-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetEi-v2.rst b/docs/source/algorithms/GetEi-v2.rst
index d9e7061a00fe41af20230ae73ca278416ae36de1..f18f493f4797b3fb3cfb1c1da1f36741f2c6f160 100644
--- a/docs/source/algorithms/GetEi-v2.rst
+++ b/docs/source/algorithms/GetEi-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetEiMonDet-v1.rst b/docs/source/algorithms/GetEiMonDet-v1.rst
index 163093133aac7412ca5a750156e7f37e4e2fdb6c..3e4934fb1d4c7ea2aab5e2d3705ce4fc8693cd85 100644
--- a/docs/source/algorithms/GetEiMonDet-v1.rst
+++ b/docs/source/algorithms/GetEiMonDet-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetEiMonDet-v2.rst b/docs/source/algorithms/GetEiMonDet-v2.rst
index bb8169cd3504a97622cd41eb3159d07d034363cd..da019e1c2b05b5bf7d846b403ab192d4ab36a792 100644
--- a/docs/source/algorithms/GetEiMonDet-v2.rst
+++ b/docs/source/algorithms/GetEiMonDet-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetEiT0atSNS-v1.rst b/docs/source/algorithms/GetEiT0atSNS-v1.rst
index 94e0a89f2fc6e899e16244e45fb11adc088e5781..d3872c02d6d9451e1fea3045f55deef7d6547924 100644
--- a/docs/source/algorithms/GetEiT0atSNS-v1.rst
+++ b/docs/source/algorithms/GetEiT0atSNS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetIPTS-v1.rst b/docs/source/algorithms/GetIPTS-v1.rst
index 67d94d2baef30e172f2f3e5614af9d0199d81a44..88ba39f2e3aba72c98785be7e5b04341deae50fc 100644
--- a/docs/source/algorithms/GetIPTS-v1.rst
+++ b/docs/source/algorithms/GetIPTS-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetQsInQENSData-v1.rst b/docs/source/algorithms/GetQsInQENSData-v1.rst
index 62c6fd51566abb9181124a7a524f05725bd08ddb..f29900f1ce81ef50bae6e23ed7665ba4254670a5 100644
--- a/docs/source/algorithms/GetQsInQENSData-v1.rst
+++ b/docs/source/algorithms/GetQsInQENSData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst b/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst
index 640c995a9225d995a20bffc6a9d3fe599103a419..b9f6afae76083fcc16702d32a75840620e9443d2 100644
--- a/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst
+++ b/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst b/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst
index 7cad594900fe8238abf09acdf71f3b3cf0bed021..bd1c6e92217cb9f70c199ff4fc3c2ad51a08af46 100644
--- a/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst
+++ b/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst b/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst
index 55f0eef6c72dc80e4c804c886cee14be1baab96d..c13a7586e6cb430b0e92ad1b968444e94807b9f3 100644
--- a/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst
+++ b/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GreaterThanMD-v1.rst b/docs/source/algorithms/GreaterThanMD-v1.rst
index 1b4bfccb9239c108ef0355484b01f022c9d23d04..1cc76e43f7ee832398a202967bc65abdddbf17cc 100644
--- a/docs/source/algorithms/GreaterThanMD-v1.rst
+++ b/docs/source/algorithms/GreaterThanMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GroupDetectors-v1.rst b/docs/source/algorithms/GroupDetectors-v1.rst
index 1cb598e2ca4d95285a95b12b3d4d4b774046d0a7..248238931e76446716d42aa4c144e4515cef79d3 100644
--- a/docs/source/algorithms/GroupDetectors-v1.rst
+++ b/docs/source/algorithms/GroupDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/GroupDetectors-v2.rst b/docs/source/algorithms/GroupDetectors-v2.rst
index f2cb66ff129ca9afd684e9c767f298a7b22e94a4..af0f35dda4aacbad868f3c0dcc8cf8195f809c56 100644
--- a/docs/source/algorithms/GroupDetectors-v2.rst
+++ b/docs/source/algorithms/GroupDetectors-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -116,6 +116,16 @@ workspace indices. This can be achieved with the following operators:
 One could combine these operations, for example :literal:`10+12,13:89` would
 list the sum of 10 and 12 followed by 13 to 89.
 
+Vertical Axis on Output
+#######################
+
+The OutputWorkspace of this algorithm will always have spectrum numbers as the
+vertical axis, independent of the vertical axis units in InputWorkspace. This
+is because after grouping, the vertical axis can have meaningless values and
+generally, there is not enough information available to rebuild the axis. The
+vertical axis can be manually restored afterwards by e.g.
+:ref:`ConvertSpectrumAxis <algm-ConvertSpectrumAxis>`.
+
 Previous Versions
 -----------------
 
diff --git a/docs/source/algorithms/GroupWorkspaces-v1.rst b/docs/source/algorithms/GroupWorkspaces-v1.rst
index 08bc6389d67d1f94afeb82b91620d9cc026281c5..28ea510b27ea25fa4c0d04e718df638fd0b9c169 100644
--- a/docs/source/algorithms/GroupWorkspaces-v1.rst
+++ b/docs/source/algorithms/GroupWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst b/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst
index 1fa07f3cabb735527478f8635962705286271e78..cb4a74af464ef18d737c31e87084071e68627f72 100644
--- a/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst
+++ b/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HFIRLoad-v1.rst b/docs/source/algorithms/HFIRLoad-v1.rst
index 8e54f84b8a5a53da61a28a277ee68bbac48cc2a5..ed9733f4b43df287070828118adffd384656fad9 100644
--- a/docs/source/algorithms/HFIRLoad-v1.rst
+++ b/docs/source/algorithms/HFIRLoad-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HFIRSANSNormalise-v1.rst b/docs/source/algorithms/HFIRSANSNormalise-v1.rst
index 600633def4b162d84204040485d67f254249b259..019999cebd5c2c94b6b1aa95cfdde99e5d89d14e 100644
--- a/docs/source/algorithms/HFIRSANSNormalise-v1.rst
+++ b/docs/source/algorithms/HFIRSANSNormalise-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HFIRSANSReduction-v1.rst b/docs/source/algorithms/HFIRSANSReduction-v1.rst
index 76fc0da3670304bd68d1bb4ffad9a3f789cded0b..1e332d172849de8b3879482a9066462317b05bd6 100644
--- a/docs/source/algorithms/HFIRSANSReduction-v1.rst
+++ b/docs/source/algorithms/HFIRSANSReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst b/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst
index 95be4bc13f0191c17953013149aa92619ce59d46..845656a7c5c6da6f60d712574e2662714374c5e1 100644
--- a/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst
+++ b/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HasUB-v1.rst b/docs/source/algorithms/HasUB-v1.rst
index 8c3a702a195209c004f50d81d33306100fd3597a..ed71dd485a21944db88f134dbd113b37f975e205 100644
--- a/docs/source/algorithms/HasUB-v1.rst
+++ b/docs/source/algorithms/HasUB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/He3TubeEfficiency-v1.rst b/docs/source/algorithms/He3TubeEfficiency-v1.rst
index 7d941a22e8d5e31ce433fe5dced68abbcc79e133..945e7a90023f2b45e7ca3e04292319cbb5c441f5 100644
--- a/docs/source/algorithms/He3TubeEfficiency-v1.rst
+++ b/docs/source/algorithms/He3TubeEfficiency-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/HyspecScharpfCorrection-v1.rst b/docs/source/algorithms/HyspecScharpfCorrection-v1.rst
index dff4da2f7ebdbc2bd781e5d2f629a935976257f1..1ca4fb5fe2fcb8138841a90302e8ab04bda4f3e9 100644
--- a/docs/source/algorithms/HyspecScharpfCorrection-v1.rst
+++ b/docs/source/algorithms/HyspecScharpfCorrection-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IQTransform-v1.rst b/docs/source/algorithms/IQTransform-v1.rst
index c4979f152cfe617dd7b10a859d78db259b863bf2..e761d70aec645974c2066e2488d172456f3641f1 100644
--- a/docs/source/algorithms/IQTransform-v1.rst
+++ b/docs/source/algorithms/IQTransform-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst b/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst
index ce585d201e532b76c79f7981059107b2151fef56..83fffd29bd1312dea0ae9c4407576a1dd5ebcd31 100644
--- a/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst
+++ b/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst b/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst
index 5780800c69ef56131ec589fd7fa769608ff6e03b..2947a546a332080cd5e9b2189f3285a03be31566 100644
--- a/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst
+++ b/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst b/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst
index dbe3eea3d273ded58d3c258ce2938553190e764e..1291957226a09384bb262c5d52913e0768a92ced 100644
--- a/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst
+++ b/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ImportMDEventWorkspace-v1.rst b/docs/source/algorithms/ImportMDEventWorkspace-v1.rst
index 56876d7e7d711abd485b7e8efcaec045ea7bd263..3f052d10474b47d467da80e92fc32e3234fcc102 100644
--- a/docs/source/algorithms/ImportMDEventWorkspace-v1.rst
+++ b/docs/source/algorithms/ImportMDEventWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst b/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst
index 91d96eedf71b17b085b83e4722314522e9e5d2f8..fba81f8dc3e8e3cc7139eceec0a666690de491f7 100644
--- a/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst
+++ b/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndexPeaks-v1.rst b/docs/source/algorithms/IndexPeaks-v1.rst
index c67aa21333a4218a471191546354b069a1c5014e..bd66a8b1827bdcb9ad79c78a4270421d85802bc6 100644
--- a/docs/source/algorithms/IndexPeaks-v1.rst
+++ b/docs/source/algorithms/IndexPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndexSXPeaks-v1.rst b/docs/source/algorithms/IndexSXPeaks-v1.rst
index 497e71748a6e61f758220a856f5ff0883f22c093..189b1aee4184d36296a7f1ba8b1567c8d3b88f54 100644
--- a/docs/source/algorithms/IndexSXPeaks-v1.rst
+++ b/docs/source/algorithms/IndexSXPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst b/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst
index 3db9123cf879302eb8bf1bb3a1e7ad7c25e5f4d0..c9ca3327bab800297f6a4eaaeed0ff62dcd33690 100644
--- a/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst
+++ b/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst b/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst
index 77c89e34e5ca352f4a22a95c1bdb1260c3fa4746..b10c28f09301a31fd5f57972a57f630b93e5bc3f 100644
--- a/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst
+++ b/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectCalibration-v1.rst b/docs/source/algorithms/IndirectCalibration-v1.rst
index cd1184579b0aca891c101a1cfa28edf60d730c8d..ada37e779c378cb18e2236640ce6afb859eb1472 100644
--- a/docs/source/algorithms/IndirectCalibration-v1.rst
+++ b/docs/source/algorithms/IndirectCalibration-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst
index e5973db26b9f39f564ee034ff8b6bd349780b625..9b3c2289fac553cced6af8586407bf83941a76bb 100644
--- a/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst
+++ b/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst b/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst
index a32f50957cafdce41e50f6b2613d012901b6c424..25d58f1fbc47780d8cc5dfce1194ef6f75fa9ec7 100644
--- a/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst
+++ b/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectDiffScan-v1.rst b/docs/source/algorithms/IndirectDiffScan-v1.rst
index d5358ad998dbd07094fb29b1daeac48ec584c428..ef8386c49ac4db447b90c22780d221b17ad4c635 100644
--- a/docs/source/algorithms/IndirectDiffScan-v1.rst
+++ b/docs/source/algorithms/IndirectDiffScan-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst
index 844b49e9abdc8ef7d7b492572ac5a70c743d4387..e9c662cb20fc0df10f4cc2a96eb8ca028f62804e 100644
--- a/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst
+++ b/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst b/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst
index f5cd723fcbaa3e8bf202c3ac183d56a3f4cb7d97..cf8d8dd6ca52c9786c06fb376f93198409c3752b 100644
--- a/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst
+++ b/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst b/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst
index 1044f48fc7ce54337c23030666b876fd5cfc6b05..d94b96d4c93b47fdbdffeee8a14b717323274113 100644
--- a/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst
+++ b/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectILLReductionFWS-v1.rst b/docs/source/algorithms/IndirectILLReductionFWS-v1.rst
index 48e65b1f07a8c831766f3df5f7c2770cb5767257..94543460dbcacccfd18e08138af1c805ac42c3fa 100644
--- a/docs/source/algorithms/IndirectILLReductionFWS-v1.rst
+++ b/docs/source/algorithms/IndirectILLReductionFWS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectILLReductionQENS-v1.rst b/docs/source/algorithms/IndirectILLReductionQENS-v1.rst
index a0d6bb85580083446c8320e7c43f3bd544d18386..5910b816835020f5d5a48cfa627cea5191dc5348 100644
--- a/docs/source/algorithms/IndirectILLReductionQENS-v1.rst
+++ b/docs/source/algorithms/IndirectILLReductionQENS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -13,7 +13,7 @@ Performs a multiple-file QENS (Quasi-Elastic Neutron Scattering) data reduction
 It uses internally the :ref:`IndirectILLEnergyTransfer <algm-IndirectILLEnergyTransfer>` algorithm.
 
 Multiple File Reduction
-~~~~~~~~~~~~~~~~~~~~~~~
+#######################
 
 The algorithm is capable of running over multiple files.  Run property
 needs to be specified following the syntax in :py:obj:`MultipleFileProperty <mantid.api.MultipleFileProperty>`.
@@ -24,7 +24,7 @@ ignored.  Use **Added Range** and **Added Stepped Range** instead (see
 ``CalibrationRun``, ``CalibrationBackgroundRun`` and ``AlignmentRun`` all the runs will be automatically summed.
 
 Unmirror Options
-~~~~~~~~~~~~~~~~
+################
 
 **IN16B** can record data with mirror sense, where the spectra for the acceleration and
 deceleration phase of the Doppler drive are recorded separately, or without.
@@ -62,7 +62,7 @@ Options 5 and 7 require the ``AlignmentRun`` (vanadium) to determine the peak po
 Note, that both detector calibration and background subtraction are performed wing-by-wing, i.e. unmirroring is the very final step.
 
 Vanadium Calibration
-~~~~~~~~~~~~~~~~~~~~
+####################
 
 Integration range can be specified to integrate over spectra in ``CalibrationRun``. Note, that before integration, the spectra will be
 centered at 0-energy transfer (see Unmirror Option 6 above) for the calibration run.
diff --git a/docs/source/algorithms/IndirectQuickRun-v1.rst b/docs/source/algorithms/IndirectQuickRun-v1.rst
index d8f19257054f719e61470117ac25c7cc9ce371d9..93e79b5bfcb92d175094a3359aba9e30a033e113 100644
--- a/docs/source/algorithms/IndirectQuickRun-v1.rst
+++ b/docs/source/algorithms/IndirectQuickRun-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectResolution-v1.rst b/docs/source/algorithms/IndirectResolution-v1.rst
index 539852f2fcd792d747ae636ac9f23f24f320e030..07249bd02737d9ad16ec5b8b7ceaf2242c1c31e8 100644
--- a/docs/source/algorithms/IndirectResolution-v1.rst
+++ b/docs/source/algorithms/IndirectResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectSampleChanger-v1.rst b/docs/source/algorithms/IndirectSampleChanger-v1.rst
index c0f87a6e65ce49caf6cd15d173d61e95d7a1d8fa..93907aaa537e615e105a89557ea85a7d5eff8c6e 100644
--- a/docs/source/algorithms/IndirectSampleChanger-v1.rst
+++ b/docs/source/algorithms/IndirectSampleChanger-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectTransmission-v1.rst b/docs/source/algorithms/IndirectTransmission-v1.rst
index 142920a7bd86a7e7b7fc0f7d36dbd2b545fe44de..eeafe31920a0601fb99798469439f5f27379c6c2 100644
--- a/docs/source/algorithms/IndirectTransmission-v1.rst
+++ b/docs/source/algorithms/IndirectTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst b/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst
index 68f881ad280232832103aa13e50284853311770c..9f9361a03eb342c2ae753d0c5d5a34610f8afc8b 100644
--- a/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst
+++ b/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegrateByComponent-v1.rst b/docs/source/algorithms/IntegrateByComponent-v1.rst
index d961ed53eeecc636349676ecb0fdac4272342dfd..f2460e09aac2a246aa905165b8efd0dbe52450b9 100644
--- a/docs/source/algorithms/IntegrateByComponent-v1.rst
+++ b/docs/source/algorithms/IntegrateByComponent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegrateEPP-v1.rst b/docs/source/algorithms/IntegrateEPP-v1.rst
index fdcbce9792eebddb012875c61286676ebea8d04e..2e2c65a53e45120e1869e51e8963f7b7c5ae7984 100644
--- a/docs/source/algorithms/IntegrateEPP-v1.rst
+++ b/docs/source/algorithms/IntegrateEPP-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/docs/source/algorithms/IntegrateEllipsoids-v1.rst
index 8e34678c0ef8b2de0c91117d3a9df3536548d810..23b4caf1dabcb745cb863f338efea5efc52b76f7 100644
--- a/docs/source/algorithms/IntegrateEllipsoids-v1.rst
+++ b/docs/source/algorithms/IntegrateEllipsoids-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -273,17 +273,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp
 .. code-block:: python
    :linenos:
 
-   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  |
-   | 3132     | 1124984  |     -2.0 |     -1.0 |      2.0 |      3.1 |      8.5 |  14482.3 |      2.0 | 120486.0 |    375.8 |   1668.0 | bank17   |    120.0 |     42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] |
-   | 3132     | 1156753  |     -3.0 |     -2.0 |      3.0 |      2.1 |     18.8 |   9725.7 |      1.3 | 149543.0 |    393.0 |   1060.0 | bank17   |    145.0 |    166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] |
-   | 3132     | 1141777  |     -4.0 |     -2.0 |      3.0 |      1.7 |     28.1 |   7963.2 |      1.0 |   8744.0 |    106.3 |     96.0 | bank17   |     17.0 |    108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] |
-   | 3132     | 1125241  |     -4.0 |     -2.0 |      4.0 |      1.6 |     33.9 |   7252.2 |      1.0 |  19740.0 |    146.2 |     83.0 | bank17   |    121.0 |     43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] |
-   | 3132     | 1170598  |     -4.0 |     -3.0 |      4.0 |      1.5 |     34.1 |   7224.6 |      0.9 |  15914.0 |    131.4 |     73.0 | bank17   |    166.0 |    220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] |
-   | 3132     | 1214951  |     -2.0 |     -1.0 |      4.0 |      1.9 |     22.8 |   8839.5 |      1.7 | 121852.0 |    352.9 |    719.0 | bank18   |    231.0 |    137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] |
-   | 3132     | 1207827  |     -3.0 |     -1.0 |      4.0 |      1.7 |     27.9 |   7991.7 |      1.3 |  64593.0 |    257.7 |    447.0 | bank18   |     19.0 |    110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] |
-   | 3132     | 1232949  |     -4.0 |     -2.0 |      6.0 |      1.2 |     53.3 |   5782.1 |      0.9 |  18247.0 |    139.3 |     45.0 | bank18   |     53.0 |    208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] |
-   | 3132     | 1189484  |     -4.0 |     -1.0 |      6.0 |      1.1 |     63.4 |   5299.3 |      1.0 |  13512.0 |    120.7 |     31.0 | bank18   |    108.0 |     38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] |
-   | 3132     | 1218337  |     -5.0 |     -2.0 |      7.0 |      1.0 |     79.8 |   4724.1 |      0.8 |   7411.0 |     88.3 |     15.0 | bank18   |     33.0 |    151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] |
+   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  | PeakNumb |
+   | 3132     | 1124984  |     -2.0 |     -1.0 |      2.0 |      3.1 |      8.5 |  14482.3 |      2.0 | 120486.0 |    375.8 |   1668.0 | bank17   |    120.0 |     42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1        |
+   | 3132     | 1156753  |     -3.0 |     -2.0 |      3.0 |      2.1 |     18.8 |   9725.7 |      1.3 | 149543.0 |    393.0 |   1060.0 | bank17   |    145.0 |    166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2        |
+   | 3132     | 1141777  |     -4.0 |     -2.0 |      3.0 |      1.7 |     28.1 |   7963.2 |      1.0 |   8744.0 |    106.3 |     96.0 | bank17   |     17.0 |    108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3        |
+   | 3132     | 1125241  |     -4.0 |     -2.0 |      4.0 |      1.6 |     33.9 |   7252.2 |      1.0 |  19740.0 |    146.2 |     83.0 | bank17   |    121.0 |     43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4        |
+   | 3132     | 1170598  |     -4.0 |     -3.0 |      4.0 |      1.5 |     34.1 |   7224.6 |      0.9 |  15914.0 |    131.4 |     73.0 | bank17   |    166.0 |    220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5        |
+   | 3132     | 1214951  |     -2.0 |     -1.0 |      4.0 |      1.9 |     22.8 |   8839.5 |      1.7 | 121852.0 |    352.9 |    719.0 | bank18   |    231.0 |    137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6        |
+   | 3132     | 1207827  |     -3.0 |     -1.0 |      4.0 |      1.7 |     27.9 |   7991.7 |      1.3 |  64593.0 |    257.7 |    447.0 | bank18   |     19.0 |    110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7        |
+   | 3132     | 1232949  |     -4.0 |     -2.0 |      6.0 |      1.2 |     53.3 |   5782.1 |      0.9 |  18247.0 |    139.3 |     45.0 | bank18   |     53.0 |    208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8        |
+   | 3132     | 1189484  |     -4.0 |     -1.0 |      6.0 |      1.1 |     63.4 |   5299.3 |      1.0 |  13512.0 |    120.7 |     31.0 | bank18   |    108.0 |     38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9        |
+   | 3132     | 1218337  |     -5.0 |     -2.0 |      7.0 |      1.0 |     79.8 |   4724.1 |      0.8 |   7411.0 |     88.3 |     15.0 | bank18   |     33.0 |    151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10       |
 
 .. categories::
 
diff --git a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst
index 8b7af21beb57ba2a1710e343000c62cecbbf9a0c..3104a0cd27efdaac11e77ab48f90d29ff561f65a 100644
--- a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst
+++ b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -315,17 +315,17 @@ availible in `Mantid system tests repository
 .. code-block:: python
    :linenos:
 
-   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  |
-   | 3132     | 1124984  |     -2.0 |     -1.0 |      2.0 |      3.1 |      8.5 |  14482.3 |      2.0 | 120486.0 |    375.8 |   1668.0 | bank17   |    120.0 |     42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] |
-   | 3132     | 1156753  |     -3.0 |     -2.0 |      3.0 |      2.1 |     18.8 |   9725.7 |      1.3 | 149543.0 |    393.0 |   1060.0 | bank17   |    145.0 |    166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] |
-   | 3132     | 1141777  |     -4.0 |     -2.0 |      3.0 |      1.7 |     28.1 |   7963.2 |      1.0 |   8744.0 |    106.3 |     96.0 | bank17   |     17.0 |    108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] |
-   | 3132     | 1125241  |     -4.0 |     -2.0 |      4.0 |      1.6 |     33.9 |   7252.2 |      1.0 |  19740.0 |    146.2 |     83.0 | bank17   |    121.0 |     43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] |
-   | 3132     | 1170598  |     -4.0 |     -3.0 |      4.0 |      1.5 |     34.1 |   7224.6 |      0.9 |  15914.0 |    131.4 |     73.0 | bank17   |    166.0 |    220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] |
-   | 3132     | 1214951  |     -2.0 |     -1.0 |      4.0 |      1.9 |     22.8 |   8839.5 |      1.7 | 121852.0 |    352.9 |    719.0 | bank18   |    231.0 |    137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] |
-   | 3132     | 1207827  |     -3.0 |     -1.0 |      4.0 |      1.7 |     27.9 |   7991.7 |      1.3 |  64593.0 |    257.7 |    447.0 | bank18   |     19.0 |    110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] |
-   | 3132     | 1232949  |     -4.0 |     -2.0 |      6.0 |      1.2 |     53.3 |   5782.1 |      0.9 |  18247.0 |    139.3 |     45.0 | bank18   |     53.0 |    208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] |
-   | 3132     | 1189484  |     -4.0 |     -1.0 |      6.0 |      1.1 |     63.4 |   5299.3 |      1.0 |  13512.0 |    120.7 |     31.0 | bank18   |    108.0 |     38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] |
-   | 3132     | 1218337  |     -5.0 |     -2.0 |      7.0 |      1.0 |     79.8 |   4724.1 |      0.8 |   7411.0 |     88.3 |     15.0 | bank18   |     33.0 |    151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] |
+   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  | PeakNumb |
+   | 3132     | 1124984  |     -2.0 |     -1.0 |      2.0 |      3.1 |      8.5 |  14482.3 |      2.0 | 120486.0 |    375.8 |   1668.0 | bank17   |    120.0 |     42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1        |
+   | 3132     | 1156753  |     -3.0 |     -2.0 |      3.0 |      2.1 |     18.8 |   9725.7 |      1.3 | 149543.0 |    393.0 |   1060.0 | bank17   |    145.0 |    166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2        |
+   | 3132     | 1141777  |     -4.0 |     -2.0 |      3.0 |      1.7 |     28.1 |   7963.2 |      1.0 |   8744.0 |    106.3 |     96.0 | bank17   |     17.0 |    108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3        |
+   | 3132     | 1125241  |     -4.0 |     -2.0 |      4.0 |      1.6 |     33.9 |   7252.2 |      1.0 |  19740.0 |    146.2 |     83.0 | bank17   |    121.0 |     43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4        |
+   | 3132     | 1170598  |     -4.0 |     -3.0 |      4.0 |      1.5 |     34.1 |   7224.6 |      0.9 |  15914.0 |    131.4 |     73.0 | bank17   |    166.0 |    220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5        |
+   | 3132     | 1214951  |     -2.0 |     -1.0 |      4.0 |      1.9 |     22.8 |   8839.5 |      1.7 | 121852.0 |    352.9 |    719.0 | bank18   |    231.0 |    137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6        |
+   | 3132     | 1207827  |     -3.0 |     -1.0 |      4.0 |      1.7 |     27.9 |   7991.7 |      1.3 |  64593.0 |    257.7 |    447.0 | bank18   |     19.0 |    110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7        |
+   | 3132     | 1232949  |     -4.0 |     -2.0 |      6.0 |      1.2 |     53.3 |   5782.1 |      0.9 |  18247.0 |    139.3 |     45.0 | bank18   |     53.0 |    208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8        |
+   | 3132     | 1189484  |     -4.0 |     -1.0 |      6.0 |      1.1 |     63.4 |   5299.3 |      1.0 |  13512.0 |    120.7 |     31.0 | bank18   |    108.0 |     38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9        |
+   | 3132     | 1218337  |     -5.0 |     -2.0 |      7.0 |      1.0 |     79.8 |   4724.1 |      0.8 |   7411.0 |     88.3 |     15.0 | bank18   |     33.0 |    151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10       |
 
 .. categories::
 
diff --git a/docs/source/algorithms/IntegrateFlux-v1.rst b/docs/source/algorithms/IntegrateFlux-v1.rst
index 04161a2ddd77d2ee7622a0abc4aa61d7e49569b8..6bda273ccce0ba637d54c9a5e2de6d7e9fdd5439 100644
--- a/docs/source/algorithms/IntegrateFlux-v1.rst
+++ b/docs/source/algorithms/IntegrateFlux-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst b/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst
index 0f27858c11c22d17176c407784559a28771e0f04..40bd6a3c80b4e2ae817a8ef751c88d7b6fd4db8c 100644
--- a/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst
+++ b/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -13,12 +13,12 @@ Description
 Provides limited integration of a :ref:`MDHistoWorkspace <MDHistoWorkspace>` in n-dimensions. Integration is always axis-aligned. Dimensions can only be integrated out, but no finer rebinning is permitted. Dimensions that do not require further rebinning will be left intact provided that the the binning parameters for those dimensions are not specified. For dimensions that are integrated, limits should be provided to give the range of the data to keep.
 
 Binning
-~~~~~~~
+#######
 
 The *P1Bin* corresponds to the first dimension of the MDHistoWorkspace, *P2Bin* to the second and so on. *P1Bin=[-1, 1]* indicates that we will integrate this dimension between -1 and 1. *P1Bins=[]* indicates that the shape of this dimension should be unchanged from the input. *P1Bins=[-1,0,1]* is a special case, the zero indicates that the same bin width as the input dimension would be used, but the minimum and maximum will also be used to crop the dimension. In this latter form, the limits may be expanded to ensure that there is no partial bins in the non-integrated dimension (see warning messages).
 
 Weights 
-~~~~~~~
+#######
 
 The algorithm works by creating the *OutputWorkspace* in the correct shape. Each bin in the OutputWorkspace is treated in turn. For each bin in the OutputWorkspace, we find those bins in the *InputWorkspace* that overlap and therefore could contribute to the OutputBin. For any contributing bin, we calculate the fraction overlap and treat this a weighting factor. For each contributing bin *Signal*, and :math:`Error^{2}`, and *Number of Events* values are extracted and multiplied by the  weight. These values are summed for all contributing input bins before being assigned to the corresponding output bin. For plotting the *OutputWorkspace*, it is important to select the Number of Events normalization option to correctly account for the weights.
 
diff --git a/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst b/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst
index 7c95e0d49fd254afc3d78c176f74644e114a0f97..b328a21255eafbcc45d32a892aeac6093e5611d6 100644
--- a/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst
+++ b/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst
index 1f32f37597ac06b82db6462f2236ab9427007177..b6ec410b2a028573ee0353738140573bb8969feb 100644
--- a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst
+++ b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst
index 23444e0a196c496364e40ee30a7d489fc732efaf..6c76bddc5fb763d81adf1c2c60569d1bd425eb61 100644
--- a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst
+++ b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegratePeaksMD-v1.rst b/docs/source/algorithms/IntegratePeaksMD-v1.rst
index b0fb9c10c7579bf2aef89a03d71a94d589cd94c4..6e728bd8f1bbc83f25bd8417f8118ebc62bad272 100644
--- a/docs/source/algorithms/IntegratePeaksMD-v1.rst
+++ b/docs/source/algorithms/IntegratePeaksMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegratePeaksMD-v2.rst b/docs/source/algorithms/IntegratePeaksMD-v2.rst
index 9e159ed56c3bcc660a1742df507526975c2b0ba0..76b3bf4f930e09126a47f2847cdb83b4630200f9 100644
--- a/docs/source/algorithms/IntegratePeaksMD-v2.rst
+++ b/docs/source/algorithms/IntegratePeaksMD-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -236,17 +236,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp
    :linenos:
 
 
-   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  |
-   | 3132     | 1168209  |      0.0 |      0.0 |      0.0 |      1.1 |     66.9 |   5158.0 |      0.7 |   2160.9 |     32.3 |   1326.0 | bank17   |     81.0 |    211.0 | [4.42961,2.81707,7.86314] | [8.75838,3.55459,-0.205083] |
-   | 3132     | 1124983  |      0.0 |      0.0 |      0.0 |      1.6 |     33.9 |   7250.6 |      1.0 |   1990.0 |     14.4 |   1060.0 | bank17   |    119.0 |     42.0 | [3.14813,2.43563,4.75389] | [5.9822,1.62965,0.00130101] |
-   | 3132     | 1141521  |      0.0 |      0.0 |      0.0 |      1.7 |     28.1 |   7959.1 |      1.0 |    644.6 |      7.3 |   1034.0 | bank17   |     17.0 |    107.0 | [2.60893,2.31831,4.86248] | [5.69311,1.79103,-0.453311] |
-   | 3132     | 1125238  |      0.0 |      0.0 |      0.0 |      3.1 |      8.4 |  14518.9 |      2.0 |    750.5 |      2.2 |    880.0 | bank17   |    118.0 |     43.0 | [1.57116,1.21649,2.37775] | [2.98926,0.816337,-0.00161709] |
-   | 3132     | 1170852  |      0.0 |      0.0 |      0.0 |      1.6 |     34.0 |   7235.3 |      1.0 |   1826.4 |     14.7 |    762.0 | bank17   |    164.0 |    221.0 | [3.4229,1.70246,5.39532] | [6.0734,2.6008,0.271523] |
-   | 3132     | 1156497  |      0.0 |      0.0 |      0.0 |      2.1 |     18.9 |   9718.2 |      1.3 |   5137.6 |     13.4 |    518.0 | bank17   |    145.0 |    165.0 | [2.49117,1.46093,3.88649] | [4.5291,1.70753,0.129446] |
-   | 3132     | 1207828  |      0.0 |      0.0 |      0.0 |      1.7 |     27.9 |   7989.1 |      1.3 |   3233.6 |     12.7 |   1024.0 | bank18   |     20.0 |    110.0 | [2.80538,2.29342,3.08833] | [4.71342,0.553533,0.380727] |
-   | 3132     | 1218593  |      0.0 |      0.0 |      0.0 |      1.0 |     79.6 |   4729.3 |      0.8 |   3018.1 |     35.4 |    756.0 | bank18   |     33.0 |    152.0 | [4.96533,3.60693,5.32436] | [7.98578,1.19927,0.895763] |
-   | 3132     | 1232694  |      0.0 |      0.0 |      0.0 |      1.2 |     53.4 |   5772.9 |      0.9 |   3464.5 |     25.9 |    631.0 | bank18   |     54.0 |    207.0 | [4.29539,2.63813,4.45945] | [6.53086,1.27477,1.00974] |
-   | 3132     | 1200023  |      0.0 |      0.0 |      0.0 |      0.7 |    159.1 |   3345.1 |      0.6 |   3796.1 |     71.1 |    509.0 | bank18   |    151.0 |     79.0 | [6.75629,4.8092,5.93224] | [10.0166,0.773518,1.74245] |
+   | RunNumbe | DetID    | h        | k        | l        | Waveleng | Energy   | TOF      | DSpacing | Intens   | SigInt   | BinCount | BankName | Row      | Col      | QLab     | QSample  | PeakNumb |
+   | 3132     | 1168209  |      0.0 |      0.0 |      0.0 |      1.1 |     66.9 |   5158.0 |      0.7 |   2160.9 |     32.3 |   1326.0 | bank17   |     81.0 |    211.0 | [4.42961,2.81707,7.86314] | [8.75838,3.55459,-0.205083] | 1        |
+   | 3132     | 1124983  |      0.0 |      0.0 |      0.0 |      1.6 |     33.9 |   7250.6 |      1.0 |   1990.0 |     14.4 |   1060.0 | bank17   |    119.0 |     42.0 | [3.14813,2.43563,4.75389] | [5.9822,1.62965,0.00130101] | 2        |
+   | 3132     | 1141521  |      0.0 |      0.0 |      0.0 |      1.7 |     28.1 |   7959.1 |      1.0 |    644.6 |      7.3 |   1034.0 | bank17   |     17.0 |    107.0 | [2.60893,2.31831,4.86248] | [5.69311,1.79103,-0.453311] | 3        |
+   | 3132     | 1125238  |      0.0 |      0.0 |      0.0 |      3.1 |      8.4 |  14518.9 |      2.0 |    750.5 |      2.2 |    880.0 | bank17   |    118.0 |     43.0 | [1.57116,1.21649,2.37775] | [2.98926,0.816337,-0.00161709] | 4        |
+   | 3132     | 1170852  |      0.0 |      0.0 |      0.0 |      1.6 |     34.0 |   7235.3 |      1.0 |   1826.4 |     14.7 |    762.0 | bank17   |    164.0 |    221.0 | [3.4229,1.70246,5.39532] | [6.0734,2.6008,0.271523] | 5        |
+   | 3132     | 1156497  |      0.0 |      0.0 |      0.0 |      2.1 |     18.9 |   9718.2 |      1.3 |   5137.6 |     13.4 |    518.0 | bank17   |    145.0 |    165.0 | [2.49117,1.46093,3.88649] | [4.5291,1.70753,0.129446] | 6        |
+   | 3132     | 1207828  |      0.0 |      0.0 |      0.0 |      1.7 |     27.9 |   7989.1 |      1.3 |   3233.6 |     12.7 |   1024.0 | bank18   |     20.0 |    110.0 | [2.80538,2.29342,3.08833] | [4.71342,0.553533,0.380727] | 7        |
+   | 3132     | 1218593  |      0.0 |      0.0 |      0.0 |      1.0 |     79.6 |   4729.3 |      0.8 |   3018.1 |     35.4 |    756.0 | bank18   |     33.0 |    152.0 | [4.96533,3.60693,5.32436] | [7.98578,1.19927,0.895763] | 8        |
+   | 3132     | 1232694  |      0.0 |      0.0 |      0.0 |      1.2 |     53.4 |   5772.9 |      0.9 |   3464.5 |     25.9 |    631.0 | bank18   |     54.0 |    207.0 | [4.29539,2.63813,4.45945] | [6.53086,1.27477,1.00974] | 9        |
+   | 3132     | 1200023  |      0.0 |      0.0 |      0.0 |      0.7 |    159.1 |   3345.1 |      0.6 |   3796.1 |     71.1 |    509.0 | bank18   |    151.0 |     79.0 | [6.75629,4.8092,5.93224] | [10.0166,0.773518,1.74245] | 10       |
 
 .. categories::
 
diff --git a/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst b/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst
index af9d3208f2e54f5022ba86cf61473130b0210735..fecbb7bbb719d16e2d4216ab3916038101396bb5 100644
--- a/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst
+++ b/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst
index a57d879043f2b69bf2df86e768dfe0112da0a8cf..ed9b40a93dfab992a86676389c6d29bf01bbdff0 100644
--- a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst
+++ b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Integration-v1.rst b/docs/source/algorithms/Integration-v1.rst
index 5a98e9bc9d2ad84ce6bb324203ecedfc0ebadba7..254e64df5340ff2b091cbedea9644c905a29c3b2 100644
--- a/docs/source/algorithms/Integration-v1.rst
+++ b/docs/source/algorithms/Integration-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/InterpolatingRebin-v1.rst b/docs/source/algorithms/InterpolatingRebin-v1.rst
index 6749b30292b8033bd4e5faee80b62f16731f308b..41e9ec068aef6f11fa249d6a626ef1eb984f955a 100644
--- a/docs/source/algorithms/InterpolatingRebin-v1.rst
+++ b/docs/source/algorithms/InterpolatingRebin-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/InvertMDDim-v1.rst b/docs/source/algorithms/InvertMDDim-v1.rst
index eeb1dc83f562cc364d722b526a881032100e5c07..e007c5c9601e78b55d3feb10c2d0b91357cda2b1 100644
--- a/docs/source/algorithms/InvertMDDim-v1.rst
+++ b/docs/source/algorithms/InvertMDDim-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/InvertMask-v1.rst b/docs/source/algorithms/InvertMask-v1.rst
index 15441ddfb17d42d5cb83001dd66387941cc16a7b..4f4d8ce2bdd06fc602f9643726deb9a3b5291eec 100644
--- a/docs/source/algorithms/InvertMask-v1.rst
+++ b/docs/source/algorithms/InvertMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IqtFitMultiple-v1.rst b/docs/source/algorithms/IqtFitMultiple-v1.rst
index 8f13a394d0da598edb33ea2465700c347b7ecf50..6bbba0c5f27ff1c8446bb75ce5156d7664b1d3ed 100644
--- a/docs/source/algorithms/IqtFitMultiple-v1.rst
+++ b/docs/source/algorithms/IqtFitMultiple-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/IqtFitSequential-v1.rst b/docs/source/algorithms/IqtFitSequential-v1.rst
index 437d53abcade0041e4f629473999788cdaf6a206..6c62230170af024a48ab16f8f35e80b56d6f88c6 100644
--- a/docs/source/algorithms/IqtFitSequential-v1.rst
+++ b/docs/source/algorithms/IqtFitSequential-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRAutoReduction-v1.rst b/docs/source/algorithms/LRAutoReduction-v1.rst
index 0ec12ae2ef3f6bb7bb31c32e48357a651e9f3ef1..7f8726567c2a45d9c0d22cb4e96bc1377b7fba56 100644
--- a/docs/source/algorithms/LRAutoReduction-v1.rst
+++ b/docs/source/algorithms/LRAutoReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRDirectBeamSort-v1.rst b/docs/source/algorithms/LRDirectBeamSort-v1.rst
index 1fa9d3863959e77d94a321add929fd29f35dbb81..4b93e8c847fe1d7a82c2d85911687443979496bf 100644
--- a/docs/source/algorithms/LRDirectBeamSort-v1.rst
+++ b/docs/source/algorithms/LRDirectBeamSort-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRPeakSelection-v1.rst b/docs/source/algorithms/LRPeakSelection-v1.rst
index c295738b6f502dd6fa58f24de7417a44b428dbdf..ec3e442da68859ee7cca61fa9b0535dbcafcc5cd 100644
--- a/docs/source/algorithms/LRPeakSelection-v1.rst
+++ b/docs/source/algorithms/LRPeakSelection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRPrimaryFraction-v1.rst b/docs/source/algorithms/LRPrimaryFraction-v1.rst
index a3e47703b88593bd43a69d87d6ac5fbe4844d714..793948ac21b98faf9995606bb0eb2208994312b2 100644
--- a/docs/source/algorithms/LRPrimaryFraction-v1.rst
+++ b/docs/source/algorithms/LRPrimaryFraction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRReflectivityOutput-v1.rst b/docs/source/algorithms/LRReflectivityOutput-v1.rst
index dd826d0041a663301f254b4b339fe993016c6f98..ace259c22d1eb0a28aafbdcd419cf6c2892dcb51 100644
--- a/docs/source/algorithms/LRReflectivityOutput-v1.rst
+++ b/docs/source/algorithms/LRReflectivityOutput-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRScalingFactors-v1.rst b/docs/source/algorithms/LRScalingFactors-v1.rst
index cb585ea707839ab5d06a79ba982e9a57c82e72a3..7b7f19534b2cbb9363d7155d1d8b220d37dc18f4 100644
--- a/docs/source/algorithms/LRScalingFactors-v1.rst
+++ b/docs/source/algorithms/LRScalingFactors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LRSubtractAverageBackground-v1.rst b/docs/source/algorithms/LRSubtractAverageBackground-v1.rst
index 920fb7fb011eab48506b2b7c804015edbfea27ab..dc380f3d0abace9c48bc6fd17861063c5e3c6a2e 100644
--- a/docs/source/algorithms/LRSubtractAverageBackground-v1.rst
+++ b/docs/source/algorithms/LRSubtractAverageBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LeBailFit-v1.rst b/docs/source/algorithms/LeBailFit-v1.rst
index f99d6824839303df92fad52ea081cb9e9ffb6f9a..3cdafc2c9414113a285dc76b6e1e8566fb6074fa 100644
--- a/docs/source/algorithms/LeBailFit-v1.rst
+++ b/docs/source/algorithms/LeBailFit-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LessThanMD-v1.rst b/docs/source/algorithms/LessThanMD-v1.rst
index 380bfbe88460262f45768b8b6d6abcb3e71826f4..d23afd077e2b25efece34b3f8fe70bf3e7812d6b 100644
--- a/docs/source/algorithms/LessThanMD-v1.rst
+++ b/docs/source/algorithms/LessThanMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LineProfile-v1.rst b/docs/source/algorithms/LineProfile-v1.rst
index 7e6b73a9aca1ad2ccff13147ba3c6b6b319feb92..001d49a0dba6449aaa75ec66a294d533aec72d75 100644
--- a/docs/source/algorithms/LineProfile-v1.rst
+++ b/docs/source/algorithms/LineProfile-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst b/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst
index 16639389fddf38c2aeb8814b4f02ba2934cfeba8..ffe35a7ac0d4046e27175213c5868f4672da1004 100644
--- a/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst
+++ b/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Load-v1.rst b/docs/source/algorithms/Load-v1.rst
index 02ca814359891da88cf0cfa6ab549c8a83671d64..6dc2e87c125d99b908a2b7d4b9c2c63ec92dd057 100644
--- a/docs/source/algorithms/Load-v1.rst
+++ b/docs/source/algorithms/Load-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadAndMerge-v1.rst b/docs/source/algorithms/LoadAndMerge-v1.rst
index 04ca1ab664c1fe6b17658adcfde51f84d4739cf5..bbc42f59fdd0a3d46db8295b7b3eff4be4cb9ee1 100644
--- a/docs/source/algorithms/LoadAndMerge-v1.rst
+++ b/docs/source/algorithms/LoadAndMerge-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadAscii-v1.rst b/docs/source/algorithms/LoadAscii-v1.rst
index 9b7b2851204595b87be161be12e67181076caec1..46fe9904a6dd075b0e52dade0e07b1de1c10fe3e 100644
--- a/docs/source/algorithms/LoadAscii-v1.rst
+++ b/docs/source/algorithms/LoadAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadAscii-v2.rst b/docs/source/algorithms/LoadAscii-v2.rst
index 7060d3037ee685d90e7ea1bee8d866eac8ffe85f..7420d024b0730e3b85b8321ef7a3354be5168c83 100644
--- a/docs/source/algorithms/LoadAscii-v2.rst
+++ b/docs/source/algorithms/LoadAscii-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadBBY-v1.rst b/docs/source/algorithms/LoadBBY-v1.rst
index 09d00219fd584d34075b6446fec96d185d76f8a0..7774d651ad4524ba5611bf33065f0feb2b52d0fe 100644
--- a/docs/source/algorithms/LoadBBY-v1.rst
+++ b/docs/source/algorithms/LoadBBY-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadCIF-v1.rst b/docs/source/algorithms/LoadCIF-v1.rst
index b92996f733fa468f0e077df1a9606bbcc7cede3b..7dd4c61516cda4b186ab36857131343e9e60858a 100644
--- a/docs/source/algorithms/LoadCIF-v1.rst
+++ b/docs/source/algorithms/LoadCIF-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadCalFile-v1.rst b/docs/source/algorithms/LoadCalFile-v1.rst
index 66e8c0a0fad29d143fe48114afff5ba62cec1167..d96a583b525319f3b1c25067dcc13cc3edf58961 100644
--- a/docs/source/algorithms/LoadCalFile-v1.rst
+++ b/docs/source/algorithms/LoadCalFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadCanSAS1D-v1.rst b/docs/source/algorithms/LoadCanSAS1D-v1.rst
index 67c40d640db338f87a223f57ffd4bab200b581f1..827e5ec4d7b919900764fb2a7ae9dbe2609152e2 100644
--- a/docs/source/algorithms/LoadCanSAS1D-v1.rst
+++ b/docs/source/algorithms/LoadCanSAS1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadCanSAS1D-v2.rst b/docs/source/algorithms/LoadCanSAS1D-v2.rst
index 70e703c0341f1da497db8359bebed3d484083ebd..94946cae452207dd0816d6b3ad698d8be7ff10c0 100644
--- a/docs/source/algorithms/LoadCanSAS1D-v2.rst
+++ b/docs/source/algorithms/LoadCanSAS1D-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadDNSLegacy-v1.rst b/docs/source/algorithms/LoadDNSLegacy-v1.rst
index 4d55aa05bff60a1f7597cf004d8b957efd5b2d80..3096529d6988007540dafbcdcfb171846a9ab235 100644
--- a/docs/source/algorithms/LoadDNSLegacy-v1.rst
+++ b/docs/source/algorithms/LoadDNSLegacy-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -57,15 +57,15 @@ This algorithm only supports DNS instrument in its configuration with one detect
 Usage
 -----
 
-**Example - Load a DNS legacy .d_dat file:**
+**Example - Load DNS legacy .d_dat files:**
 
 .. code-block:: python
 
    # data file.
-   datafile = 'dn134011vana.d_dat'
+   datafiles = 'dn134011vana.d_dat,dnstof.d_dat'
 
    # Load dataset
-   ws = LoadDNSLegacy(datafile, Normalization='monitor')
+   ws = LoadDNSLegacy(datafiles, Normalization='monitor')
 
    print("This workspace has {} dimensions and has {} histograms.".format(ws.getNumDims(), ws.getNumberHistograms()))
 
diff --git a/docs/source/algorithms/LoadDNSSCD-v1.rst b/docs/source/algorithms/LoadDNSSCD-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d3b24caaf87f879236a4aa96b3150f23a7673dff
--- /dev/null
+++ b/docs/source/algorithms/LoadDNSSCD-v1.rst
@@ -0,0 +1,221 @@
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+.. warning::
+
+   This algorithm does not perform any consistency check of the input data. It is the users responsibility to choose a physically reasonable dataset.
+
+This algorithm loads a list  of DNS `.d_dat` data files into a `MDEventWorkspace <http://www.mantidproject.org/MDEventWorkspace>`_. If the algorithm fails to process a file, this file will be ignored. In this case the algorithm produces a warning and continues to process further files. Only if no valid files are provided, the algorithm terminates with an error message.
+
+This algorithm is meant to replace the :ref:`algm-LoadDNSLegacy` for single crystal diffraction data.
+
+**Output**
+
+As a result, two workspaces are created:
+
+- `OutputWorkspace` contains the raw neutron counts.
+
+- `NormalizationWorkspace` contains the choosen normalization data (either monitor counts or experiment duration time).
+
+Both workspaces have :math:`(H,K,L)` dimensions. The metadata are loaded into time series sample logs.
+
+.. note::
+
+   For the further data reduction :ref:`algm-BinMD` should be used to bin the data.
+
+Restrictions
+------------
+
+- This algorithm only supports the *DNS* instrument in its configuration with one detector bank (polarisation analysis).
+
+- This algorithm does not support DNS TOF mode data. It is meant only for single crystal diffraction experiments with 1 TOF channel.
+
+
+Data replication
+________________
+
+For standard data (vanadium, NiCr, background) the sample rotation angle is assumed to be not important. These data are typically measured only for one sample rotation angle. The algorithm can replicate these data for the same sample rotation angles as a single crystal sample has been measured. For this purpose optional input fields *SaveHuberTo* and *LoadHuberFrom* can be used.
+
+- *SaveHuberTo* should contain a name of the `TableWorkspace <http://www.mantidproject.org/TableWorkspace>`_ where sample rotation angles (Huber) read from the data files will be saved. If the specified workspace exists, it will be overwritten.
+
+- *LoadHuberFrom* should contain a name of the `TableWorkspace <http://www.mantidproject.org/TableWorkspace>`_. The workspace must exist and contain one column with the name *Huber(degrees)*, where the sample rotation angles are specified.
+
+.. note::
+
+   If *LoadHuberFrom* option is applied, sample rotation angles in the data files will be ignored. Only sample rotation angles from the table will be considered.
+
+Usage
+-----
+
+**Example 1 - Load a DNS .d_dat file to MDEventWorkspace:**
+
+.. testcode:: LoadDNSSCDEx1
+
+   # data file.
+   filename = "dn134011vana.d_dat"
+
+   # lattice parameters
+   a = 5.0855
+   b = 5.0855
+   c = 14.0191
+   omega_offset = 225.0
+   hkl1="1,0,0"
+   hkl2="0,0,1"
+   alpha=90.0
+   beta=90.0
+   gamma=120.0
+
+   # load data to MDEventWorkspace
+   ws, ws_norm, huber_ws = LoadDNSSCD(FileNames=filename, NormalizationWorkspace='ws_norm',
+                                      Normalization='monitor', a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma,
+                                      OmegaOffset=omega_offset, HKL1=hkl1, HKL2=hkl2, SaveHuberTo='huber_ws')
+
+   # print output workspace information
+   print("Output Workspace Type is:  {}".format(ws.id()))
+   print("It has {0} events and {1} dimensions:".format(ws.getNEvents(), ws.getNumDims()))
+   for i in range(ws.getNumDims()):
+       dimension = ws.getDimension(i)
+       print("Dimension {0} has name: {1}, id: {2}, Range: {3:.2f} to {4:.2f} {5}".format(i,
+             dimension.getDimensionId(),
+             dimension.name,
+             dimension.getMinimum(),
+             dimension.getMaximum(),
+             dimension.getUnits()))
+
+   # print information about the table workspace
+   print ("TableWorkspace '{0}' has {1} row in the column '{2}'.".format(huber_ws.getName(),
+                                                                         huber_ws.rowCount(),
+                                                                         huber_ws.getColumnNames()[0]))
+   print("It contains sample rotation angle {} degrees".format(huber_ws.cell(0, 0)))
+
+**Output:**
+
+.. testoutput:: LoadDNSSCDEx1
+
+    Output Workspace Type is:  MDEventWorkspace<MDEvent,3>
+    It has 24 events and 3 dimensions:
+    Dimension 0 has name: H, id: H, Range: -15.22 to 15.22 r.l.u
+    Dimension 1 has name: K, id: K, Range: -15.22 to 15.22 r.l.u
+    Dimension 2 has name: L, id: L, Range: -41.95 to 41.95 r.l.u
+    TableWorkspace 'huber_ws' has 1 row in the column 'Huber(degrees)'.
+    It contains sample rotation angle 79.0 degrees
+
+
+**Example 2 - Specify scattering angle limits:**
+
+.. testcode:: LoadDNSSCDEx2
+
+   # data file.
+   filename = "dn134011vana.d_dat"
+
+   # lattice parameters
+   a = 5.0855
+   b = 5.0855
+   c = 14.0191
+   omega_offset = 225.0
+   hkl1="1,0,0"
+   hkl2="0,0,1"
+   alpha=90.0
+   beta=90.0
+   gamma=120.0
+
+   # scattering angle limits, degrees
+   tth_limits = "20,70"
+
+   # load data to MDEventWorkspace
+   ws, ws_norm, huber_ws = LoadDNSSCD(FileNames=filename, NormalizationWorkspace='ws_norm',
+                                      Normalization='monitor', a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma,
+                                      OmegaOffset=omega_offset, HKL1=hkl1, HKL2=hkl2, TwoThetaLimits=tth_limits)
+
+   # print output workspace information
+   print("Output Workspace Type is:  {}".format(ws.id()))
+   print("It has {0} events and {1} dimensions.".format(ws.getNEvents(), ws.getNumDims()))
+
+   # print normalization workspace information
+   print("Normalization Workspace Type is:  {}".format(ws_norm.id()))
+   print("It has {0} events and {1} dimensions.".format(ws_norm.getNEvents(), ws_norm.getNumDims()))
+
+**Output:**
+
+.. testoutput:: LoadDNSSCDEx2
+
+    Output Workspace Type is:  MDEventWorkspace<MDEvent,3>
+    It has 10 events and 3 dimensions.
+    Normalization Workspace Type is:  MDEventWorkspace<MDEvent,3>
+    It has 10 events and 3 dimensions.
+
+**Example 3 - Load sample rotation angles from the table**
+
+.. testcode:: LoadDNSSCDEx3
+
+   # data file.
+   filename = "dn134011vana.d_dat"
+
+   # construct table workspace with 10 raw sample rotation angles from 70 to 170 degrees
+   table = CreateEmptyTableWorkspace()
+   table.addColumn( "double", "Huber(degrees)")
+   for huber in range(70, 170, 10):
+       table.addRow([huber])
+
+   # lattice parameters
+   a = 5.0855
+   b = 5.0855
+   c = 14.0191
+   omega_offset = 225.0
+   hkl1="1,0,0"
+   hkl2="0,0,1"
+   alpha=90.0
+   beta=90.0
+   gamma=120.0
+
+   # load data to MDEventWorkspace
+   ws, ws_norm, huber_ws = LoadDNSSCD(FileNames=filename, NormalizationWorkspace='ws_norm',
+                                      Normalization='monitor', a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma,
+                                      OmegaOffset=omega_offset, HKL1=hkl1, HKL2=hkl2, LoadHuberFrom=table)
+
+   # print output workspace information
+   print("Output Workspace Type is:  {}".format(ws.id()))
+   print("It has {0} events and {1} dimensions.".format(ws.getNEvents(), ws.getNumDims()))
+
+   # setting for the BinMD algorithm
+   bvec0 = '[100],unit,1,0,0'
+   bvec1 = '[001],unit,0,0,1'
+   bvec2 = '[010],unit,0,1,0'
+   extents = '-2,1.5,-0.2,6.1,-10,10'
+   bins = '10,10,1'
+   # bin the data
+   data_raw = BinMD(ws, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1,
+                    BasisVector2=bvec2, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0')
+   # bin normalization
+   data_norm = BinMD(ws_norm, AxisAligned='0', BasisVector0=bvec0, BasisVector1=bvec1,
+                     BasisVector2=bvec2, OutputExtents=extents, OutputBins=bins, NormalizeBasisVectors='0')
+   # normalize data
+   data = data_raw/data_norm
+
+   # print reduced workspace information
+   print("Reduced Workspace Type is:  {}".format(data.id()))
+   print("It has {} dimensions.".format(data.getNumDims()))
+   s =  data.getSignalArray()
+   print("Signal at some points: {0:.4f}, {1:.4f}, {2:.4f}".format(s[7,1][0], s[7,2][0], s[7,3][0]))
+
+**Output:**
+
+.. testoutput:: LoadDNSSCDEx3
+
+    Output Workspace Type is:  MDEventWorkspace<MDEvent,3>
+    It has 240 events and 3 dimensions.
+    Reduced Workspace Type is:  MDHistoWorkspace
+    It has 3 dimensions.
+    Signal at some points: 0.0035, 0.0033, 0.0035
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/LoadDaveGrp-v1.rst b/docs/source/algorithms/LoadDaveGrp-v1.rst
index 355da06a843b22dff39958e513742c74f15634d7..bb13d04d66c49e6112033b9f3c3d3e80d75c1274 100644
--- a/docs/source/algorithms/LoadDaveGrp-v1.rst
+++ b/docs/source/algorithms/LoadDaveGrp-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadDetectorInfo-v1.rst b/docs/source/algorithms/LoadDetectorInfo-v1.rst
index 7a3545e0dbc3692d839cd81f8fd1301b50b39d0e..7fff57ebb66989bc47fdd0d1dcf8dc22717c39b3 100644
--- a/docs/source/algorithms/LoadDetectorInfo-v1.rst
+++ b/docs/source/algorithms/LoadDetectorInfo-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst b/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst
index 8481ea8e301a8bd25d541ecc25cd6d0d8c1360a2..d318557d986556b9c0301112af84ce4a4b519179 100644
--- a/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst
+++ b/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadDiffCal-v1.rst b/docs/source/algorithms/LoadDiffCal-v1.rst
index b2fc5741c14f477db64a9448b854942d964f2c0f..b83edb746f3c50eabb14214c02a9cefb89d9382e 100644
--- a/docs/source/algorithms/LoadDiffCal-v1.rst
+++ b/docs/source/algorithms/LoadDiffCal-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadDspacemap-v1.rst b/docs/source/algorithms/LoadDspacemap-v1.rst
index e92564e49306d7c18ce070a75b8c46419a5dcd8d..e00b75625777b19dad573c985a8bed21e1021ae9 100644
--- a/docs/source/algorithms/LoadDspacemap-v1.rst
+++ b/docs/source/algorithms/LoadDspacemap-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEXED-v1.rst b/docs/source/algorithms/LoadEXED-v1.rst
index 4682fdb07fff285b061d7fc8e20f3c4ad4fa45c9..3aa844d1bb85a8dbb07a4d9197cd3e81454e9455 100644
--- a/docs/source/algorithms/LoadEXED-v1.rst
+++ b/docs/source/algorithms/LoadEXED-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEmptyInstrument-v1.rst b/docs/source/algorithms/LoadEmptyInstrument-v1.rst
index 16d294756665094af1b521aa5c898372dbf25dd4..7044a542d27cb1dcadd1cb104aa9a92e8bc0b960 100644
--- a/docs/source/algorithms/LoadEmptyInstrument-v1.rst
+++ b/docs/source/algorithms/LoadEmptyInstrument-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEmptyVesuvio-v1.rst b/docs/source/algorithms/LoadEmptyVesuvio-v1.rst
index 4b8909997c656e4f6edb6d2b687cda35d1792e4d..795ddea4ad7f57b309f4393d983532f1fd11d22f 100644
--- a/docs/source/algorithms/LoadEmptyVesuvio-v1.rst
+++ b/docs/source/algorithms/LoadEmptyVesuvio-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEventAndCompress-v1.rst b/docs/source/algorithms/LoadEventAndCompress-v1.rst
index 7af29968e94db749312f7569e3f4fd1e49982942..12e7da3307134294f2c7905128c0842d30a3767f 100644
--- a/docs/source/algorithms/LoadEventAndCompress-v1.rst
+++ b/docs/source/algorithms/LoadEventAndCompress-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEventNexus-v1.rst b/docs/source/algorithms/LoadEventNexus-v1.rst
index 06ac964a6a818309ed40b669963214946d75cc88..1fdbd426fdc52c80b0da7d18888d7a8b958cbe4c 100644
--- a/docs/source/algorithms/LoadEventNexus-v1.rst
+++ b/docs/source/algorithms/LoadEventNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadEventPreNexus-v2.rst b/docs/source/algorithms/LoadEventPreNexus-v2.rst
index 9a27afe7943ba7331e02fe686873fda4db32e287..9cbbe010eff450594adc0cecd15a1348543dd1b6 100644
--- a/docs/source/algorithms/LoadEventPreNexus-v2.rst
+++ b/docs/source/algorithms/LoadEventPreNexus-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadFITS-v1.rst b/docs/source/algorithms/LoadFITS-v1.rst
index fc1b672d2f38c163dcf33fe41a9a8bad84725117..fbd48295ac5629612eb315ada358532e86da05ab 100644
--- a/docs/source/algorithms/LoadFITS-v1.rst
+++ b/docs/source/algorithms/LoadFITS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadFlexiNexus-v1.rst b/docs/source/algorithms/LoadFlexiNexus-v1.rst
index 4dede92da8dc8fb4c687f0d5cbf9e7d82251e76a..061164de428831e118e6c3c40248e875c9b78f64 100644
--- a/docs/source/algorithms/LoadFlexiNexus-v1.rst
+++ b/docs/source/algorithms/LoadFlexiNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadFullprofFile-v1.rst b/docs/source/algorithms/LoadFullprofFile-v1.rst
index a3954d7bb30a1c66a783d819a7bceed0d10e4d78..1bd0a740c3078bc549c9a87b8af819b00638b14e 100644
--- a/docs/source/algorithms/LoadFullprofFile-v1.rst
+++ b/docs/source/algorithms/LoadFullprofFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadFullprofResolution-v1.rst b/docs/source/algorithms/LoadFullprofResolution-v1.rst
index 36fbfebb1853808425f5859f02e208ede61d5170..53081fe10c8362fa2074181b0bb3eb7cc41efbc7 100644
--- a/docs/source/algorithms/LoadFullprofResolution-v1.rst
+++ b/docs/source/algorithms/LoadFullprofResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst b/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst
index 6d26c479f30c8664791c93c56d44fd37c80496e5..c42932baaeb0e165d5247594d8173032d7fcf782 100644
--- a/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst
+++ b/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadGSS-v1.rst b/docs/source/algorithms/LoadGSS-v1.rst
index 9b2162be7288a664bb0b528c3c2639e08df6226c..025cc510df9b9e3cab741ac3475add2873f1dbb5 100644
--- a/docs/source/algorithms/LoadGSS-v1.rst
+++ b/docs/source/algorithms/LoadGSS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadHKL-v1.rst b/docs/source/algorithms/LoadHKL-v1.rst
index e772121e42ef831f577b8fe3d1330c38838da71d..6222531baef2c1a9d2b811a0d35fc6a28fb930f6 100644
--- a/docs/source/algorithms/LoadHKL-v1.rst
+++ b/docs/source/algorithms/LoadHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -12,7 +12,7 @@ Description
 Loads an ASCII .hkl file to a PeaksWorkspace.
 
 HKL File Format
-***************
+###############
         
 File has same format that works successfully in GSAS and SHELX from
 ISAW:
diff --git a/docs/source/algorithms/LoadIDFFromNexus-v1.rst b/docs/source/algorithms/LoadIDFFromNexus-v1.rst
index 09fdf94e69b07be1128a2e8ba76fd97d3509ee8a..b707b491405544426fb57c46772b698bdafc47c8 100644
--- a/docs/source/algorithms/LoadIDFFromNexus-v1.rst
+++ b/docs/source/algorithms/LoadIDFFromNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLDiffraction-v1.rst b/docs/source/algorithms/LoadILLDiffraction-v1.rst
index 95c3221834d56955edf989dd43e1b4144201c138..eae3c9c3926e2adaf2897c8d9564e0bd817739ae 100644
--- a/docs/source/algorithms/LoadILLDiffraction-v1.rst
+++ b/docs/source/algorithms/LoadILLDiffraction-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLIndirect-v2.rst b/docs/source/algorithms/LoadILLIndirect-v2.rst
index 9b4b44df190e152de1991ff7619e31ba9c133fcb..43721433616b205ff47b536ddabcba6b3eb52c2c 100644
--- a/docs/source/algorithms/LoadILLIndirect-v2.rst
+++ b/docs/source/algorithms/LoadILLIndirect-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst b/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst
index 02ff134d610ba9e88567f09018f6c3ed0e51ea4c..60cfcc5cf33ef137cc639d363261b1ee0feeeaa6 100644
--- a/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst
+++ b/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLReflectometry-v1.rst b/docs/source/algorithms/LoadILLReflectometry-v1.rst
index f3cf3ad31e7e992487ed7025d53357164b7204d7..c43ab4f05bad7bde0ec577739f6a3942cd24b005 100644
--- a/docs/source/algorithms/LoadILLReflectometry-v1.rst
+++ b/docs/source/algorithms/LoadILLReflectometry-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLSANS-v1.rst b/docs/source/algorithms/LoadILLSANS-v1.rst
index c0accafcb7fa7cb8de2799bf68ff36679f085f02..2e51a0ba86041c5c1e30130b975b62377398d1fe 100644
--- a/docs/source/algorithms/LoadILLSANS-v1.rst
+++ b/docs/source/algorithms/LoadILLSANS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadILLTOF-v2.rst b/docs/source/algorithms/LoadILLTOF-v2.rst
index 6cac270c17417b2c09d1e5247e8d312a1c133171..fb36d146be60859c09fa5c1700b62f48a56f4fdb 100644
--- a/docs/source/algorithms/LoadILLTOF-v2.rst
+++ b/docs/source/algorithms/LoadILLTOF-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadISISNexus-v2.rst b/docs/source/algorithms/LoadISISNexus-v2.rst
index 92d8cbe22f7651c15394ab25b85512fc50c4bc1a..051bafc40f6fb71f649166eb737e9124199b0549 100644
--- a/docs/source/algorithms/LoadISISNexus-v2.rst
+++ b/docs/source/algorithms/LoadISISNexus-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadInstrument-v1.rst b/docs/source/algorithms/LoadInstrument-v1.rst
index 9bb17050731bffe22d3823c82e5c9024e3575b4b..742ede74498275023f8e003273898033fa8aac3e 100644
--- a/docs/source/algorithms/LoadInstrument-v1.rst
+++ b/docs/source/algorithms/LoadInstrument-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst
index c7d47ac3c0dfad7a7fc63af18f044e41c373329c..d41423e0f7dbffef4e9e4201d4129d0750648b24 100644
--- a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst
+++ b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst b/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst
index 8468aa33fd589d28daaec47a12c6dcc1bbddc35f..10277281419d3e77d88e045a192e0217021063bc 100644
--- a/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst
+++ b/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadIsawDetCal-v1.rst b/docs/source/algorithms/LoadIsawDetCal-v1.rst
index 39dc33620d67e532766bb20401c05af859199c7f..65adcc7bab0a3d41975c817824003a5745f25617 100644
--- a/docs/source/algorithms/LoadIsawDetCal-v1.rst
+++ b/docs/source/algorithms/LoadIsawDetCal-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadIsawPeaks-v1.rst b/docs/source/algorithms/LoadIsawPeaks-v1.rst
index 8a27cedbe85a0aa9257a6b05d58e1670467c1992..754710cc55813662ec70c9812ec83bcaafc2d5a4 100644
--- a/docs/source/algorithms/LoadIsawPeaks-v1.rst
+++ b/docs/source/algorithms/LoadIsawPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadIsawSpectrum-v1.rst b/docs/source/algorithms/LoadIsawSpectrum-v1.rst
index aa2b05caee8d5307bff2fc9701e262512aee2a0e..a5fb42498577004698042e635f7a1efb7f209c7f 100644
--- a/docs/source/algorithms/LoadIsawSpectrum-v1.rst
+++ b/docs/source/algorithms/LoadIsawSpectrum-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadIsawUB-v1.rst b/docs/source/algorithms/LoadIsawUB-v1.rst
index d0565e842f035db0ec880a8900c04fc2f3c590a1..1112f519484bebccb2868fd1a2719398760090eb 100644
--- a/docs/source/algorithms/LoadIsawUB-v1.rst
+++ b/docs/source/algorithms/LoadIsawUB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadLLB-v1.rst b/docs/source/algorithms/LoadLLB-v1.rst
index 7fb60a344b96d74bc585631d9eae6779460b1d68..6bf029c5a06fd62487bee05f8bc73245e06430c0 100644
--- a/docs/source/algorithms/LoadLLB-v1.rst
+++ b/docs/source/algorithms/LoadLLB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadLamp-v1.rst b/docs/source/algorithms/LoadLamp-v1.rst
index d551753ff7acd498ed992429bdfa945d016d0afc..ebcef6ad50a2b0d063f231d3ece4d63f05fb2f07 100644
--- a/docs/source/algorithms/LoadLamp-v1.rst
+++ b/docs/source/algorithms/LoadLamp-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadLiveData-v1.rst b/docs/source/algorithms/LoadLiveData-v1.rst
index 2f0be8557dd26e817cda3fe00cd38dfe2d473912..a8224c0e971bd8fd3be3efefff12f1d70e29b88e 100644
--- a/docs/source/algorithms/LoadLiveData-v1.rst
+++ b/docs/source/algorithms/LoadLiveData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadLog-v1.rst b/docs/source/algorithms/LoadLog-v1.rst
index 79315d77c3eb6517e3f4a67bb0b9fa209f35585d..9dd0160c66b2d40150611781cdd6687c45801d13 100644
--- a/docs/source/algorithms/LoadLog-v1.rst
+++ b/docs/source/algorithms/LoadLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadLogPropertyTable-v1.rst b/docs/source/algorithms/LoadLogPropertyTable-v1.rst
index 11c227f673f9c4b77ff35d149fe79c646a7a1779..f34dde7c6825fd6aba017333a143b24b8c8bafcb 100644
--- a/docs/source/algorithms/LoadLogPropertyTable-v1.rst
+++ b/docs/source/algorithms/LoadLogPropertyTable-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMD-v1.rst b/docs/source/algorithms/LoadMD-v1.rst
index add4525edef8561436c64d27e127cd32af6ef1e6..377dd78987e872706cf0902081af6d6f2df98cbd 100644
--- a/docs/source/algorithms/LoadMD-v1.rst
+++ b/docs/source/algorithms/LoadMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMLZ-v1.rst b/docs/source/algorithms/LoadMLZ-v1.rst
index fcbb25c2efcf5ba4317a293a98555b0d2ccdfc9e..8efb00dbc4965ab958380542cbc0c06465459100 100644
--- a/docs/source/algorithms/LoadMLZ-v1.rst
+++ b/docs/source/algorithms/LoadMLZ-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMappingTable-v1.rst b/docs/source/algorithms/LoadMappingTable-v1.rst
index 694ade0b83684376795afe447911254f8dc4356d..f485e532664cb26cea628849b513f90c7b4b4cce 100644
--- a/docs/source/algorithms/LoadMappingTable-v1.rst
+++ b/docs/source/algorithms/LoadMappingTable-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMask-v1.rst b/docs/source/algorithms/LoadMask-v1.rst
index 223fcea04d39d5eedc140a1ffab1cc96a1680b56..572b110ace935d58f20eddc01a99acc5cfabbad6 100644
--- a/docs/source/algorithms/LoadMask-v1.rst
+++ b/docs/source/algorithms/LoadMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMcStas-v1.rst b/docs/source/algorithms/LoadMcStas-v1.rst
index b042f4d774288dba5ef71bd809c769b6d89506ae..3039803b2e52d6f50755e57f2a06055225fd4e83 100644
--- a/docs/source/algorithms/LoadMcStas-v1.rst
+++ b/docs/source/algorithms/LoadMcStas-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMcStasNexus-v1.rst b/docs/source/algorithms/LoadMcStasNexus-v1.rst
index 230d0405dbb00b6d96de72c484c0aa061ec68332..02422e3aa859489f523927b9e5968985a7b204b2 100644
--- a/docs/source/algorithms/LoadMcStasNexus-v1.rst
+++ b/docs/source/algorithms/LoadMcStasNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMultipleGSS-v1.rst b/docs/source/algorithms/LoadMultipleGSS-v1.rst
index 7aab060dd3dba7da955429ccface9c08c2aaebdb..4e3caa68595bd4daa472eec2639d8dddac292904 100644
--- a/docs/source/algorithms/LoadMultipleGSS-v1.rst
+++ b/docs/source/algorithms/LoadMultipleGSS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMuonLog-v1.rst b/docs/source/algorithms/LoadMuonLog-v1.rst
index e089716be96ffee53040448a177733541157da79..b9116c5c531aa0d6846cb9813222df03af3201d3 100644
--- a/docs/source/algorithms/LoadMuonLog-v1.rst
+++ b/docs/source/algorithms/LoadMuonLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMuonNexus-v1.rst b/docs/source/algorithms/LoadMuonNexus-v1.rst
index a798064a45b7b0e4d99320c925c7b47f8a3c10ab..489c79d9e7227ed572ece03e34ab94d22028fea6 100644
--- a/docs/source/algorithms/LoadMuonNexus-v1.rst
+++ b/docs/source/algorithms/LoadMuonNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadMuonNexus-v2.rst b/docs/source/algorithms/LoadMuonNexus-v2.rst
index a36ba6e4689a095cc188658eb058fb731396bce5..81fbbc40660a93f4d082691190b7d4849b9f2a50 100644
--- a/docs/source/algorithms/LoadMuonNexus-v2.rst
+++ b/docs/source/algorithms/LoadMuonNexus-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst b/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst
index 8d06bedd116cf74939206059b3e3517497eb5657..588dbb4aedd0aca309e72b6accfedb5d1ffbf134 100644
--- a/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst
+++ b/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst
index 72179b710986f3f4db9baace501499f93733ecf7..3c7b6c43857e3dfdc80e2c42ef3cc3e5356d232d 100644
--- a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst
+++ b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst b/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst
index 033966b156f5afd856c0c3829a500b2f01b9f59c..619825c4b5fe3bb8c6aef229d065d73422f97135 100644
--- a/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst
+++ b/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNXSPE-v1.rst b/docs/source/algorithms/LoadNXSPE-v1.rst
index 97930210ae72d5261b839d527c36ccc73adebe1a..3837d2d616c03742ee53ef5e6eb042c1a7a0e32e 100644
--- a/docs/source/algorithms/LoadNXSPE-v1.rst
+++ b/docs/source/algorithms/LoadNXSPE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNXcanSAS-v1.rst b/docs/source/algorithms/LoadNXcanSAS-v1.rst
index 8da99f48766344a65dba8f38608f5f75f83770a7..b0264acbbc72cded736b6df93a42539cd8f63556 100644
--- a/docs/source/algorithms/LoadNXcanSAS-v1.rst
+++ b/docs/source/algorithms/LoadNXcanSAS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNexus-v1.rst b/docs/source/algorithms/LoadNexus-v1.rst
index 5ab2681bb8c65331654d6a3d28a718cc3a151de3..3a943ba388b9d22d25ab8820c5a8a60f0f2b8f7a 100644
--- a/docs/source/algorithms/LoadNexus-v1.rst
+++ b/docs/source/algorithms/LoadNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNexusLogs-v1.rst b/docs/source/algorithms/LoadNexusLogs-v1.rst
index fd20fc6c67360449fa595f7da27ab8d18cc681bf..b04d523dd59b99555f00d16aff5f1c6eb686bf92 100644
--- a/docs/source/algorithms/LoadNexusLogs-v1.rst
+++ b/docs/source/algorithms/LoadNexusLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNexusMonitors-v1.rst b/docs/source/algorithms/LoadNexusMonitors-v1.rst
index 8e8a3f6dfa259103c2e7516ede37a0e2a6c45bed..1108b568428a219d137b7c113e8c48a777d50336 100644
--- a/docs/source/algorithms/LoadNexusMonitors-v1.rst
+++ b/docs/source/algorithms/LoadNexusMonitors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadNexusMonitors-v2.rst b/docs/source/algorithms/LoadNexusMonitors-v2.rst
index 9a6fda08a2f8e8c5dd5d487a349f14f59217d8b3..d115c204cc94e705f047b4f61b08147643d5ef2a 100644
--- a/docs/source/algorithms/LoadNexusMonitors-v2.rst
+++ b/docs/source/algorithms/LoadNexusMonitors-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -24,7 +24,7 @@ workspace. As a side-effect of the fix, the contained individual
 workspaces for each of the periods are named slightly differently.
 
 Event monitor and histogram monitor
-===================================
+###################################
 
 There are two types of monitors, event monitors and histograms monitors.
 Both of them are of class *NXmonitor* in NeXus file.
@@ -39,14 +39,14 @@ Both of them are of class *NXmonitor* in NeXus file.
    * period_index
 
 ISIS event monitor
-==================
+##################
 
 ISIS monitor of event mode may contain entry *data*.  In this case,
 the monitor of event mode can be loaded in histogram mode.
 
 
 Load NeXus file containing both event monitor and histogram monitor
-===================================================================
+###################################################################
 
 There are a few use cases to load monitor's data if the NeXus file has coexisting
 event monitors and histogram monitors.
diff --git a/docs/source/algorithms/LoadNexusProcessed-v1.rst b/docs/source/algorithms/LoadNexusProcessed-v1.rst
index d807be0ba03ed7892201de228c000218dd96036f..4ee1808037b1917e7cc2caef3821765d6dd1ae00 100644
--- a/docs/source/algorithms/LoadNexusProcessed-v1.rst
+++ b/docs/source/algorithms/LoadNexusProcessed-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadPDFgetNFile-v1.rst b/docs/source/algorithms/LoadPDFgetNFile-v1.rst
index fa232ab4999bab2023aa4f9ee5b6faed2e2d2db2..227fe09f03debc98c66c5d356e753b55160b024e 100644
--- a/docs/source/algorithms/LoadPDFgetNFile-v1.rst
+++ b/docs/source/algorithms/LoadPDFgetNFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadParameterFile-v1.rst b/docs/source/algorithms/LoadParameterFile-v1.rst
index fda8e1da56297b9ac58ec2b82dcbd8f2d4ad2c29..17836f3b9ca98828829cf2e5c8f5251345be4c56 100644
--- a/docs/source/algorithms/LoadParameterFile-v1.rst
+++ b/docs/source/algorithms/LoadParameterFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadPreNexus-v1.rst b/docs/source/algorithms/LoadPreNexus-v1.rst
index b78e915c4ee570ec048ea63a4e0a2264cd143d34..23c4a16fe12cf396ca204f930d70aecfbc82371d 100644
--- a/docs/source/algorithms/LoadPreNexus-v1.rst
+++ b/docs/source/algorithms/LoadPreNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadPreNexusLive-v1.rst b/docs/source/algorithms/LoadPreNexusLive-v1.rst
index 674c3b5a99d9ea0fefa350fb1cefb4904d4eaa7d..5e5ee7183892142183a78b72d5125b8c69fabdb5 100644
--- a/docs/source/algorithms/LoadPreNexusLive-v1.rst
+++ b/docs/source/algorithms/LoadPreNexusLive-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadPreNexusMonitors-v1.rst b/docs/source/algorithms/LoadPreNexusMonitors-v1.rst
index 4f45a04ca08fb7602824e37b7c0c3c8f18d78632..80292f10472c16cc2316c2900381a5fdd50276d4 100644
--- a/docs/source/algorithms/LoadPreNexusMonitors-v1.rst
+++ b/docs/source/algorithms/LoadPreNexusMonitors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadQKK-v1.rst b/docs/source/algorithms/LoadQKK-v1.rst
index 92721016f794a8c96550dfbbab70137c22fc3dcf..9942142869c3c96757a0cfaeedcd11367a2170ba 100644
--- a/docs/source/algorithms/LoadQKK-v1.rst
+++ b/docs/source/algorithms/LoadQKK-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadRKH-v1.rst b/docs/source/algorithms/LoadRKH-v1.rst
index 08d8e4c84aeff3b2965044686cbefbf823d575cf..ad8cbce7608f37c52e4791f641c74989750fb8a4 100644
--- a/docs/source/algorithms/LoadRKH-v1.rst
+++ b/docs/source/algorithms/LoadRKH-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadRaw-v3.rst b/docs/source/algorithms/LoadRaw-v3.rst
index 4a67346b1de281decacb0786fc5ed0f551872be6..7ccd96f0ad8d505f3b17aadee5889e1f6bc59c80 100644
--- a/docs/source/algorithms/LoadRaw-v3.rst
+++ b/docs/source/algorithms/LoadRaw-v3.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadRawBin0-v1.rst b/docs/source/algorithms/LoadRawBin0-v1.rst
index ac383e40ef00c66c35b8823e828f89a16dfad398..277cfb7f18be6b135978260cce2a8a6f99552260 100644
--- a/docs/source/algorithms/LoadRawBin0-v1.rst
+++ b/docs/source/algorithms/LoadRawBin0-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadRawSpectrum0-v1.rst b/docs/source/algorithms/LoadRawSpectrum0-v1.rst
index 93003f14ec466cb65b08e21e83bcf88578677809..6ec923a6a9208822a26684cbfca420319dde819e 100644
--- a/docs/source/algorithms/LoadRawSpectrum0-v1.rst
+++ b/docs/source/algorithms/LoadRawSpectrum0-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSESANS-v1.rst b/docs/source/algorithms/LoadSESANS-v1.rst
index eb1ca8b16b0d595cb68cf676ce1680efb65c63a5..6d6126ae6029ab4afbb949786b845d2f6d6fe55c 100644
--- a/docs/source/algorithms/LoadSESANS-v1.rst
+++ b/docs/source/algorithms/LoadSESANS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSINQ-v1.rst b/docs/source/algorithms/LoadSINQ-v1.rst
index 87fbda9bf56c58e87b599f04210077a0f7efb957..9fb18dd5a80d6b08d2e7954733d385dc262e17bf 100644
--- a/docs/source/algorithms/LoadSINQ-v1.rst
+++ b/docs/source/algorithms/LoadSINQ-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSINQFile-v1.rst b/docs/source/algorithms/LoadSINQFile-v1.rst
index 44fce4dd38fbdacdcfb7f0fac8b2823cc4c07e1e..773de1cbf46bf1de95d03da056a93ca72c3cea4c 100644
--- a/docs/source/algorithms/LoadSINQFile-v1.rst
+++ b/docs/source/algorithms/LoadSINQFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSINQFocus-v1.rst b/docs/source/algorithms/LoadSINQFocus-v1.rst
index c9693e0b067244a31d2accb9686b9da2b0de0884..91edd2507ee9f53d87c0eda72410892918033fd4 100644
--- a/docs/source/algorithms/LoadSINQFocus-v1.rst
+++ b/docs/source/algorithms/LoadSINQFocus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSNSspec-v1.rst b/docs/source/algorithms/LoadSNSspec-v1.rst
index 1f5ccfbd558a3883efbf9ad48148ea189b8094cf..0d356d3874df51cfbb56b9b4edaaa5d39a6d19de 100644
--- a/docs/source/algorithms/LoadSNSspec-v1.rst
+++ b/docs/source/algorithms/LoadSNSspec-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSPE-v1.rst b/docs/source/algorithms/LoadSPE-v1.rst
index cd8acb3fcbab83a6c1bb001a62ba8273797dc860..3f3a7f8595c1c8c6067caee8d831c59968e7e8ca 100644
--- a/docs/source/algorithms/LoadSPE-v1.rst
+++ b/docs/source/algorithms/LoadSPE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSQW-v1.rst b/docs/source/algorithms/LoadSQW-v1.rst
index 2420f3498c19dd5bb0266a521e15edffdcd112b6..c2ef22d9fcdd2cf878f02435839373f9a179a723 100644
--- a/docs/source/algorithms/LoadSQW-v1.rst
+++ b/docs/source/algorithms/LoadSQW-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSQW-v2.rst b/docs/source/algorithms/LoadSQW-v2.rst
index f0a40db3c265b1ac1e858550a7968703693c6add..6651f7cef591125bf4be092c8fed50068969bc6e 100644
--- a/docs/source/algorithms/LoadSQW-v2.rst
+++ b/docs/source/algorithms/LoadSQW-v2.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst b/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst
index 2b92c0b7005dbc1ab7b671e7c6e7e30d30cacf65..9f5f4aea40c4b832c8e2bc30955a680e13cfb23c 100644
--- a/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst
+++ b/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSassena-v1.rst b/docs/source/algorithms/LoadSassena-v1.rst
index 0680ea202de148432432798afba5d5e5048cc9e5..a8978dffa8b0c5d13975ecc17d1119bd69132d4f 100644
--- a/docs/source/algorithms/LoadSassena-v1.rst
+++ b/docs/source/algorithms/LoadSassena-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSpec-v1.rst b/docs/source/algorithms/LoadSpec-v1.rst
index b37969d58cf7ec25653300ca8972574a4db4a0e4..d846c9b0693688878d938ace0647341d95daa01f 100644
--- a/docs/source/algorithms/LoadSpec-v1.rst
+++ b/docs/source/algorithms/LoadSpec-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSpice2D-v1.rst b/docs/source/algorithms/LoadSpice2D-v1.rst
index 857c87654c0c654c7be88e6ab2e5f30a16608888..d5d607ffefa86da266ad296e44a59b424aa223b7 100644
--- a/docs/source/algorithms/LoadSpice2D-v1.rst
+++ b/docs/source/algorithms/LoadSpice2D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSpiceAscii-v1.rst b/docs/source/algorithms/LoadSpiceAscii-v1.rst
index 93662c3b27203045c4e341728568139c4f079539..6bb9f483ea142b3685530b110d4024815b19ee97 100644
--- a/docs/source/algorithms/LoadSpiceAscii-v1.rst
+++ b/docs/source/algorithms/LoadSpiceAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
index 05c83f510107ec310106c991f10128ae8dc6cc08..64f4f0d70bce32af7fcd4dbd86fcc0723c21f6d4 100644
--- a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
+++ b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadSwans-v1.rst b/docs/source/algorithms/LoadSwans-v1.rst
index 4f288ccee204435944d98587fdba67a6c3f96fcc..839f640e4e345ec90d8d684b05fed5e95ae8a6fa 100644
--- a/docs/source/algorithms/LoadSwans-v1.rst
+++ b/docs/source/algorithms/LoadSwans-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadTBL-v1.rst b/docs/source/algorithms/LoadTBL-v1.rst
index d0f355b638dfb575c882b291b10ca3ae0d247318..9951cb77d57fa9a9225c3c66aedc38ed2c524dc9 100644
--- a/docs/source/algorithms/LoadTBL-v1.rst
+++ b/docs/source/algorithms/LoadTBL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadTOFRawNexus-v1.rst b/docs/source/algorithms/LoadTOFRawNexus-v1.rst
index c9709cb383d334d9abccaf9e3a9b63863da29478..bc902c6f2fb2fdf43bb516607c8d1d2960e2643c 100644
--- a/docs/source/algorithms/LoadTOFRawNexus-v1.rst
+++ b/docs/source/algorithms/LoadTOFRawNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVTK-v1.rst b/docs/source/algorithms/LoadVTK-v1.rst
index 1ab52491815d4a7e7297e9da16e12f37c37b1d57..d047f11c134ac535cf5cbdd1e6d3408cf1071eae 100644
--- a/docs/source/algorithms/LoadVTK-v1.rst
+++ b/docs/source/algorithms/LoadVTK-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVesuvio-v1.rst b/docs/source/algorithms/LoadVesuvio-v1.rst
index 9adc889a649ba374b84f8c904aaee834e0774cd0..a9953c686f4087755e0b2ce811ae55038e3e9c9a 100644
--- a/docs/source/algorithms/LoadVesuvio-v1.rst
+++ b/docs/source/algorithms/LoadVesuvio-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVisionElasticBS-v1.rst b/docs/source/algorithms/LoadVisionElasticBS-v1.rst
index 2767b3a719dc8e57f337fb01b8a9f113d4c9c63a..0ee9821ec31cd109d9a5c0d6397e8594629dfdbe 100644
--- a/docs/source/algorithms/LoadVisionElasticBS-v1.rst
+++ b/docs/source/algorithms/LoadVisionElasticBS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVisionElasticEQ-v1.rst b/docs/source/algorithms/LoadVisionElasticEQ-v1.rst
index bb175164fc2167a97e8a8010e7c49a7ee2f9b2d0..f7b468e473750dce149be42d1c5953b14896cdb1 100644
--- a/docs/source/algorithms/LoadVisionElasticEQ-v1.rst
+++ b/docs/source/algorithms/LoadVisionElasticEQ-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVisionInelastic-v1.rst b/docs/source/algorithms/LoadVisionInelastic-v1.rst
index 30a39cdd2ce7dbacfce520fa089089cb3ad81805..0d063c9125c3cdd7a6844e201ba1442fbdae7b0e 100644
--- a/docs/source/algorithms/LoadVisionInelastic-v1.rst
+++ b/docs/source/algorithms/LoadVisionInelastic-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LoadVulcanCalFile-v1.rst b/docs/source/algorithms/LoadVulcanCalFile-v1.rst
index 0a10aab6597bf773a8f5be3bef663e4a0b51e0da..993e081745b9cd6a08c4b355d2c80540564c7d71 100644
--- a/docs/source/algorithms/LoadVulcanCalFile-v1.rst
+++ b/docs/source/algorithms/LoadVulcanCalFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -17,7 +17,7 @@ By this algorithm, Vulcan's calibration file can be converted to
 the standard calibration file for SNSPowderReduction.
 
 Detector offset file
-====================
+####################
 
 There are :math:`62500` (:math:`50\times 1250`) rows in the offset file.
 In each row, the first value is the pixel ID; and the second is inner-module offset.
@@ -35,14 +35,14 @@ from 0.
 - Line :math:`1250\times M_i + 1249`: pixel ID, inter bank correction
 
 Bad pixel file
-==============
+##############
 
 In bad pixel file, each line contains one and only one integer
 corresponding to the detector ID of a bad pixel.
 The bad pixels will be masked in the output MaskWorkspace.
 
 Conversion from offset in TOF to d-spacing
-==========================================
+##########################################
 
 With VULCAN's offsets in TOF, the calibration is done as the following.
 
diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst
index 8d075bc5ef6b73265e34edeeffd2673eb6e00750..d5cd3e1a2dbc0a7cd61aa62aab096fd4120f3e58 100644
--- a/docs/source/algorithms/LoadWAND-v1.rst
+++ b/docs/source/algorithms/LoadWAND-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Logarithm-v1.rst b/docs/source/algorithms/Logarithm-v1.rst
index f73ddf933f3756df35825266d255e2d75aefb3cb..b4293fb2fd1e69c9ed255bd5ee2239edc7d049ed 100644
--- a/docs/source/algorithms/Logarithm-v1.rst
+++ b/docs/source/algorithms/Logarithm-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LogarithmMD-v1.rst b/docs/source/algorithms/LogarithmMD-v1.rst
index 8e569665a65d53f9410ef3ceb32b2f7d46dd022b..5164eabb2421e3a39b3ec1e588e08d56a54351bb 100644
--- a/docs/source/algorithms/LogarithmMD-v1.rst
+++ b/docs/source/algorithms/LogarithmMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/LorentzCorrection-v1.rst b/docs/source/algorithms/LorentzCorrection-v1.rst
index 509cdbc732430d80b4da324404cd923af2eff451..abd1e94191e3bce596416cc75735fb860cb63309 100644
--- a/docs/source/algorithms/LorentzCorrection-v1.rst
+++ b/docs/source/algorithms/LorentzCorrection-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst b/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst
index 90c4d1cd41dbb2bb614b234301d766c88a90171e..45ee32e6b9f2ab1b9941b9681f7a3fa7f55156db 100644
--- a/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst
+++ b/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MDNormDirectSC-v1.rst b/docs/source/algorithms/MDNormDirectSC-v1.rst
index c47842c280d16b3d020a126de16f25bd3c62e7c8..353dbdbe8a1ec881188b6b50e6605215dd215b6c 100644
--- a/docs/source/algorithms/MDNormDirectSC-v1.rst
+++ b/docs/source/algorithms/MDNormDirectSC-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MDNormSCD-v1.rst b/docs/source/algorithms/MDNormSCD-v1.rst
index c54e1efe10ca7662f4993ed4a7daedfda3e37720..f99be5cb7590ac502352c0d609bd6a4e21d35747 100644
--- a/docs/source/algorithms/MDNormSCD-v1.rst
+++ b/docs/source/algorithms/MDNormSCD-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst b/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst
index 221ddcfbb61381e7774e830f049ac35f36515b93..3b0bc08dc90eb8ff11c100c27042eca7cbc1e345 100644
--- a/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst
+++ b/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MRFilterCrossSections-v1.rst b/docs/source/algorithms/MRFilterCrossSections-v1.rst
index 3f214516448c32fed01d5710937b452fe6c6f4cf..75c7202df0c12d517394254512e116cc66bcd87f 100644
--- a/docs/source/algorithms/MRFilterCrossSections-v1.rst
+++ b/docs/source/algorithms/MRFilterCrossSections-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MRInspectData-v1.rst b/docs/source/algorithms/MRInspectData-v1.rst
index 657aab1595c72ef952b4dbfd92869a1768de6fc5..6fbd4f2e54af68fc4791736c125d6d710fe3211a 100644
--- a/docs/source/algorithms/MRInspectData-v1.rst
+++ b/docs/source/algorithms/MRInspectData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MSDFit-v1.rst b/docs/source/algorithms/MSDFit-v1.rst
index 96907467e77dcab04ba8fc4dbfcaa37cddd6b06a..f7b51e2cda468e30da3ebfe74171c9a69af73817 100644
--- a/docs/source/algorithms/MSDFit-v1.rst
+++ b/docs/source/algorithms/MSDFit-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MagFormFactorCorrection-v1.rst b/docs/source/algorithms/MagFormFactorCorrection-v1.rst
index 3e27e3937902cb3d934154e8f080bda2db50dca7..608b9cac232b04222c57e08cc959796e3f1c2005 100644
--- a/docs/source/algorithms/MagFormFactorCorrection-v1.rst
+++ b/docs/source/algorithms/MagFormFactorCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskAngle-v1.rst b/docs/source/algorithms/MaskAngle-v1.rst
index 5f9590342acbae50c7c3b200635aaaf7e8c1a826..f981b9458f741ca8fc2bfd8d84f1814ea31bbb93 100644
--- a/docs/source/algorithms/MaskAngle-v1.rst
+++ b/docs/source/algorithms/MaskAngle-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -14,11 +14,15 @@ Algorithm to mask detectors with scattering angles in a given interval
 set, all detectors are going to be masked Returns a list of detectors
 that were masked
 
+When masking the phi angle the absolute value of phi is used.
+
 Usage
 -----
 
 .. include:: ../usagedata-note.txt
 
+**Two theta example**
+
 .. testcode:: MaskAngle
 
     #Load a workspace
@@ -53,6 +57,42 @@ The instrument view would look like:
 .. figure:: /images/MaskAngle.png
    :alt: MaskAngle.png    
 
+**Phi example**
+
+.. testcode:: MaskAngle_phi
+
+    #Load a workspace
+    ws = Load("CNCS_7860")
+
+    #Do the masking for direct beam
+    mask = MaskAngle(ws, MinAngle=30, MaxAngle=150, Angle='Phi')
+    print("The algorithm has masked {} detectors".format(mask.size))
+
+    #to test check a couple of detectors
+    inst = ws.getInstrument()
+    print("Is the minimum element in the mask list (detector {}) masked?  {}".format(mask.min(), inst.getDetector(int(mask.min())).isMasked()))
+    print("Is the maximum element in the mask list (detector {}) masked?  {}".format(mask.max(), inst.getDetector(int(mask.max())).isMasked()))
+    print("Is a detector outside the list masked (for example detector 100)?  {}".format(inst.getDetector(100).isMasked()  ))
+
+.. testcleanup:: MaskAngle_phi
+
+   DeleteWorkspace(ws)
+
+Output:
+
+.. testoutput:: MaskAngle_phi
+
+    The algorithm has masked 6348 detectors
+    Is the minimum element in the mask list (detector 29568) masked?  True
+    Is the maximum element in the mask list (detector 44287) masked?  True
+    Is a detector outside the list masked (for example detector 100)?  False
+
+
+The instrument view would look like:
+
+.. figure:: /images/MaskAngle_phi.png
+   :alt: MaskAngle_phi.png
+
 .. categories::
 
 .. sourcelink::
diff --git a/docs/source/algorithms/MaskBTP-v1.rst b/docs/source/algorithms/MaskBTP-v1.rst
index 611797be603c41b44e8c415b218a8d80e7e0c63f..bde4c6c2f856966cf65bc6563dc51f9205fbd862 100644
--- a/docs/source/algorithms/MaskBTP-v1.rst
+++ b/docs/source/algorithms/MaskBTP-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskBins-v1.rst b/docs/source/algorithms/MaskBins-v1.rst
index cbdeb1a00b168973176d157458e8f37584b84ef1..9af7cb8ee3d93bbd0a202b3c4117463d89ef675b 100644
--- a/docs/source/algorithms/MaskBins-v1.rst
+++ b/docs/source/algorithms/MaskBins-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskBinsFromTable-v1.rst b/docs/source/algorithms/MaskBinsFromTable-v1.rst
index 8ee464a6408329a145244fd543b6e02776d924d3..a83f9e89e420931f413553051e660544f62d57df 100644
--- a/docs/source/algorithms/MaskBinsFromTable-v1.rst
+++ b/docs/source/algorithms/MaskBinsFromTable-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskDetectors-v1.rst b/docs/source/algorithms/MaskDetectors-v1.rst
index b22bb7a85abaaa4d2c0aaba94ebfa121c7b33047..47ffae9c3c34f0e6f58f24db823fcb0c1ff59e40 100644
--- a/docs/source/algorithms/MaskDetectors-v1.rst
+++ b/docs/source/algorithms/MaskDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskDetectorsIf-v1.rst b/docs/source/algorithms/MaskDetectorsIf-v1.rst
index 276b40f34ea95c0e63690b257950703c01236c7c..a70292d2d40068dc2b5e49a96dc3515fa445c047 100644
--- a/docs/source/algorithms/MaskDetectorsIf-v1.rst
+++ b/docs/source/algorithms/MaskDetectorsIf-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskDetectorsInShape-v1.rst b/docs/source/algorithms/MaskDetectorsInShape-v1.rst
index 109d854381ef70e012b9f698bd7d8081d3a2f907..8dbcc0d049aa490e16097340ad405de634d2bc7a 100644
--- a/docs/source/algorithms/MaskDetectorsInShape-v1.rst
+++ b/docs/source/algorithms/MaskDetectorsInShape-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskInstrument-v1.rst b/docs/source/algorithms/MaskInstrument-v1.rst
index 5fbf728786696e7b6c46fb64d96627b8b36ebc92..b15ca47878119ffd12f1d6e5e3b8d841420c56cb 100644
--- a/docs/source/algorithms/MaskInstrument-v1.rst
+++ b/docs/source/algorithms/MaskInstrument-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskMD-v1.rst b/docs/source/algorithms/MaskMD-v1.rst
index d3b5086665f44b3918f1f64d588860e98c005ca8..6bb22cb9da5b3e85f950d6c97b1af4f45c0344f0 100644
--- a/docs/source/algorithms/MaskMD-v1.rst
+++ b/docs/source/algorithms/MaskMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskPeaksWorkspace-v1.rst b/docs/source/algorithms/MaskPeaksWorkspace-v1.rst
index b771d01ddbdb419d0b66dc532d7263a45207f140..5040e4f1f20d484fee859c619e6946778c15a0a9 100644
--- a/docs/source/algorithms/MaskPeaksWorkspace-v1.rst
+++ b/docs/source/algorithms/MaskPeaksWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskSpectra-v1.rst b/docs/source/algorithms/MaskSpectra-v1.rst
index d7f8ada91ec7eed36203b641f51b6a8a9e102269..b234da9e4ff63d6662a941a90b2237d146271e33 100644
--- a/docs/source/algorithms/MaskSpectra-v1.rst
+++ b/docs/source/algorithms/MaskSpectra-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst b/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst
index 11682c79abf521c4259af2e7dbe58c24efa3af55..74dd984691c807406e4f7505ea5d832d1731e5c3 100644
--- a/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst
+++ b/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MatchPeaks-v1.rst b/docs/source/algorithms/MatchPeaks-v1.rst
index d245e56808a2ec73e8a70150585a6f12fd854249..c1fe7f9c15d024be1e79eede1d5829b6431d731b 100644
--- a/docs/source/algorithms/MatchPeaks-v1.rst
+++ b/docs/source/algorithms/MatchPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Max-v1.rst b/docs/source/algorithms/Max-v1.rst
index e0b69bbb7ef3c54122b7b8222d36a1b05454e3c6..3cf69b9415d430eae2e991dc943a062ef69ef7b7 100644
--- a/docs/source/algorithms/Max-v1.rst
+++ b/docs/source/algorithms/Max-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MaxEnt-v1.rst b/docs/source/algorithms/MaxEnt-v1.rst
index 1db090ec069ee32f3adc7059734f0099093cff3f..f3d4a78544dfbcc309cd0793b14dd88362c0375c 100644
--- a/docs/source/algorithms/MaxEnt-v1.rst
+++ b/docs/source/algorithms/MaxEnt-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -100,33 +100,33 @@ the output workspaces whether the algorithm was evolving towards the correct sol
 On the other hand, the user must always check the validity of the solution by inspecting *EvolChi* and *EvolAngle*,
 whose values will be set to zero once the true maximum entropy solution is found.
 
-.. table:: Table 1. Output workspaces for a real input workspace with M histograms and N bins
+.. table:: Table 1. Output workspaces for a real input workspace with M histograms and N bins, taking J iterations.
 
     +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
     | Workspace         | Number of histograms         | Number of bins | Description                                                                                                                                                                                                                                                                                                        |
     +===================+==============================+================+====================================================================================================================================================================================================================================================================================================================+
-    | EvolChi           | M                            | MaxIterations  | Evolution of :math:`\chi^2` until the solution is found. Then all values are set to zero.                                                                                                                                                                                                                          |
+    | EvolChi           | M                            | J              | For spectrum :math:`k` in the input workspace, evolution of :math:`\chi^2` until the solution is found                                                                                                                                                                                                             |
     +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | EvolAngle         | M                            | MaxIterations  | Evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found. Then all values are set to zero.                                                                                                                                                                           |
+    | EvolAngle         | M                            | J              | For spectrum :math:`k` in the input workspace, evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found                                                                                                                                                              |
     +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | ReconstructedImage| 2M                           | N              | For spectrum :math:`s` in the input workspace, the reconstructed image is stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part)                                                                                                                                                                 |
+    | ReconstructedImage| 2M                           | N              | For spectrum :math:`k` in the input workspace, the reconstructed image is stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part)                                                                                                                                                                 |
     +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | ReconstructedData | 2M                           | N              | For spectrum :math:`s` in the input workspace, the reconstructed data are stored in spectrum :math:`s` (real part) and :math:`s+M` (imaginary part). Note that although the input is real, the imaginary part is recorded for debugging purposes, it should be zero for all data points.                           |
+    | ReconstructedData | 2M                           | N              | For spectrum :math:`k` in the input workspace, the reconstructed data are stored in spectrum :math:`k` (real part) and :math:`k+M` (imaginary part). Note that although the input is real, the imaginary part is recorded for debugging purposes, it should be zero for all data points.                           |
     +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
-.. table:: Table 2. Output workspaces for a complex input workspace with 2M histograms and N bins.
+.. table:: Table 2. Output workspaces for a complex input workspace with 2M histograms and N bins, taking J iterations.
 
-    +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | Workspace         | Number of histograms         | Number of bins | Description                                                                                                                                                |
-    +===================+==============================+================+============================================================================================================================================================+
-    | EvolChi           | M                            | MaxIterations  | Evolution of :math:`\chi^2` until the solution is found. Then all values are set to zero.                                                                  |
-    +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | EvolAngle         | M                            | MaxIterations  | Evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found. Then all values are set to zero.                   |
-    +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | ReconstructedImage| 2M                           | :math:`N`      | For spectrum :math:`(s, s+M)` in the input workspace, the reconstructed image is stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part)  |
-    +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
-    | ReconstructedData | 2M                           | :math:`N`      | For spectrum :math:`(s, s+M)` in the input workspace, the reconstructed data are stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part)  |
-    +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
+    +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+    | Workspace         | Number of histograms         | Number of bins | Description                                                                                                                                                  |
+    +===================+==============================+================+==============================================================================================================================================================+
+    | EvolChi           | M                            | J              | For spectrum :math:`(k, k+M)` in the input workspace, evolution of :math:`\chi^2` until the solution is found                                                |
+    +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+    | EvolAngle         | M                            | J              | For spectrum :math:`(k, k+M)` in the input workspace, evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found |
+    +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+    | ReconstructedImage| 2M                           | :math:`N`      | For spectrum :math:`(k, k+M)` in the input workspace, the reconstructed image is stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part)    |
+    +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+    | ReconstructedData | 2M                           | :math:`N`      | For spectrum :math:`(k, k+M)` in the input workspace, the reconstructed data are stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part)    |
+    +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 Usage
 -----
@@ -174,13 +174,14 @@ and the reconstructed image, i.e. Fourier transform (right).
 Output:
 
 .. testoutput:: ExFourierCoeffs
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    First  reconstructed coefficient: 0.847
    Second reconstructed coefficient: 0.846
    Third  reconstructed coefficient: 0.846
    Fourth reconstructed coefficient: 0.896
    Fifth  reconstructed coefficient: 0.896
-   Number of iterations: 3495
+   Number of iterations: ...
 
 .. figure:: ../images/MaxEntFourierCoefficients.png
    :align: center
@@ -223,13 +224,14 @@ and :ref:`algm-FFT` (right).
 Output:
 
 .. testoutput:: ExMUSR00022725
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    Image at -1.359: 0.100
    Image at 0.000: 0.009
    Image at 1.359: 0.100
    Negative background 0.006431
    Positive background 0.006431
-   Number of iterations: 22
+   Number of iterations: ...
 .. figure:: ../images/MaxEntMUSR00022725.png
    :align: center
 
@@ -258,6 +260,7 @@ and its imaginary part (right).
 Output:
 
 .. testoutput:: ExEMU00020884
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    Image (real part) at -1.389: -0.063
    Image (real part) at  0.000:  0.035
@@ -265,7 +268,7 @@ Output:
    Image (imaginary part) at -1.389: -0.277
    Image (imaginary part) at  0.000:  0.000
    Image (imaginary part) at  1.389:  0.277
-   Number of iterations: 33
+   Number of iterations: ...
 
 
 .. figure:: ../images/MaxEntMUSR00020884.png
@@ -304,11 +307,12 @@ the original and reconstructed data (left), and the reconstructed image (right).
 Output:
 
 .. testoutput:: ExRealImage
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    Image (real part) at 0.318: 0.000
    Image (real part) at 0.477: 5.862
    Image (real part) at 0.637: 0.000
-   Number of iterations: 20000
+   Number of iterations: ...
 
 .. figure:: ../images/MaxEntComplexData.png
    :align: center
@@ -359,12 +363,13 @@ image in order to obtain smooth results).
 Output:
 
 .. testoutput:: ExRealPosImage
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    Image at 0.318: 0.000 (PositiveImage=False), 0.000 (PositiveImage=True)
    Image at 0.477: 5.862 (PositiveImage=False), 5.913 (PositiveImage=True)
    Image at 0.637: 0.000 (PositiveImage=False), 0.000 (PositiveImage=True)
-   Number of iterations: 20000
-   Number of iterations: 11
+   Number of iterations: ...
+   Number of iterations: ...
 
 .. figure:: ../images/MaxEntPositiveImage.png
    :align: center
@@ -380,6 +385,76 @@ where the first one refers to the real part of the entropy and the second one to
 about the image is available, as trying to reconstruct images that are inherently complex discarding the imaginary part will prevent the algorithm
 from converging. If the image is known to be real this property can be safely set to *False*.
 
+Complex Data
+------------
+If the input property "ComplexData* is set to *True*, the algorithm will assume complex data for the calculations with all the
+real parts listed before all the imaginary parts. This means that if you have workspaces where the imaginary part immediately
+follow the real part, such workspaces cannot be combined by using the :ref:`algm-AppendSpectra` algorithm because the resulting
+output will not order the real and imaginary parts corrected as needed for this algorithm. The following usage example
+shows how to combine two workspaces with complex data.
+
+.. testcode:: ExComplexData
+
+   from math import pi, sin, cos
+   from random import random, seed
+   seed(0)
+   # Create complex data for a workspace
+   X = []
+   YRe = []
+   YIm = []
+   E = []
+   N = 200
+   w = 3
+   for i in range(0,N):
+       x = 2*pi*i/N
+       X.append(x)
+       YRe.append(cos(w*x)+(random()-0.5)*0.3)
+       YIm.append(sin(w*x)+(random()-0.5)*0.3)
+       E.append(0.1)
+
+   seed(0)
+   # Create complex data for a second workspace
+   X2 = []
+   YRe2 = []
+   YIm2 = []
+   E2 = []
+   N2 = 200
+   w2 = 4
+   for i in range(0,N2):
+       x = 2*pi*i/N2
+       X2.append(x)
+       YRe2.append(cos(w2*x)+(random()-0.5)*0.3)
+       YIm2.append(sin(w2*x)+(random()-0.5)*0.3)
+       E2.append(0.5)
+
+   # Create two workspaces of one spectrum each    
+   CreateWorkspace(OutputWorkspace='ws1',DataX=X+X,DataY=YRe+YIm,DataE=E+E,NSpec=2)
+   evolChiP, evolAngleP, imageP, dataP = MaxEnt(InputWorkspace='ws1', ComplexData=True, A=0.001, PositiveImage=True)
+
+   print ("Number of iterations dataset1 separate: "+str( len(evolAngleP.readX(0))))
+
+   CreateWorkspace(OutputWorkspace='ws2',DataX=X2+X2,DataY=YRe2+YIm2,DataE=E2+E2,NSpec=2)
+   evolChiP2, evolAngleP2, imageP2, dataP2 = MaxEnt(InputWorkspace='ws2', ComplexData=True, A=0.001, PositiveImage=True)
+
+   print ("Number of iterations dataset2 separate: "+str( len(evolAngleP2.readX(0))))
+
+   # Combine the two workspaces
+   CreateWorkspace(OutputWorkspace='wsCombined',DataX=X+X2+X+X2,DataY=YRe+YRe2+YIm+YIm2,DataE=E+E2+E+E2,NSpec=4)
+   evolChiC, evolAngleC, imageC, dataC = MaxEnt(InputWorkspace='wsCombined', ComplexData=True, A=0.001, PositiveImage=True)
+
+   print ("Number of iterations dataset1 combined: "+str( len(evolAngleC.readX(0))))
+   print ("Number of iterations dataset2 combined: "+str( len(evolAngleC.readX(1))))
+
+Output:
+
+.. testoutput:: ExComplexData
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
+
+   Number of iterations dataset1 separate: ...
+   Number of iterations dataset2 separate: ...
+   Number of iterations dataset1 combined: ...
+   Number of iterations dataset2 combined: ...
+
 
 Increasing the number of points in the image
 --------------------------------------------
@@ -410,11 +485,12 @@ from the default 1.0; the dataset contains 270 data points and here set to be sl
 Output:
 
 .. testoutput:: ExResolutionFactor
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
    Image at 0.000: 0.035 (ResolutionFactor=1)
    Image at 0.000: 0.068 (ResolutionFactor=2)
-   Number of iterations: 33
-   Number of iterations: 20
+   Number of iterations: ...
+   Number of iterations: ...
 
 .. figure:: ../images/MaxEntResolutionFactor.png
    :align: center
@@ -441,11 +517,12 @@ a zoom into the region :math:`0.82 < x < 1.44` and :math:`-0.187 < y < 0.004`.
 Output:
 
 .. testoutput:: ExResolutionFactor2
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
-   Number of iterations: 41
-   Number of iterations: 20
-   Number of iterations: 24
-   Number of iterations: 32
+   Number of iterations: ...
+   Number of iterations: ...
+   Number of iterations: ...
+   Number of iterations: ...
 
 .. figure:: ../images/MaxEntResolutionFactor2.png
    :align: center
diff --git a/docs/source/algorithms/MaxMin-v1.rst b/docs/source/algorithms/MaxMin-v1.rst
index 39961f5687b66d27a5ebd42b149f35befe94a8f1..8e335fd3a1d28ff9a30b0e06d08800df78a1cccf 100644
--- a/docs/source/algorithms/MaxMin-v1.rst
+++ b/docs/source/algorithms/MaxMin-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MayersSampleCorrection-v1.rst b/docs/source/algorithms/MayersSampleCorrection-v1.rst
index 7a1c489f2931f95fae92b4cbf00401bafa2a1f81..a2163c2834e517e45edbe5ff8950af581f1be8ab 100644
--- a/docs/source/algorithms/MayersSampleCorrection-v1.rst
+++ b/docs/source/algorithms/MayersSampleCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Mean-v1.rst b/docs/source/algorithms/Mean-v1.rst
index b73567b1784a9e52869896cf12e379842c96e573..d3452b87f5a38c5a2d766c8612812e9fcb8c3d13 100644
--- a/docs/source/algorithms/Mean-v1.rst
+++ b/docs/source/algorithms/Mean-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MedianBinWidth-v1.rst b/docs/source/algorithms/MedianBinWidth-v1.rst
index 9198e8ed0c9b507b8a6509ab0575949bc4d69cba..6d51bb1690a65f3bcc11ea29c4e1eeba95fca33a 100644
--- a/docs/source/algorithms/MedianBinWidth-v1.rst
+++ b/docs/source/algorithms/MedianBinWidth-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
   
diff --git a/docs/source/algorithms/MedianDetectorTest-v1.rst b/docs/source/algorithms/MedianDetectorTest-v1.rst
index a995af4766ef20f42f8d89d522e3e191bf958d9b..dd467de839cedef559755656b5e0387f408f64f8 100644
--- a/docs/source/algorithms/MedianDetectorTest-v1.rst
+++ b/docs/source/algorithms/MedianDetectorTest-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MergeCalFiles-v1.rst b/docs/source/algorithms/MergeCalFiles-v1.rst
index 9a41a8f9224aecaae0a590e2173d1d7017d6084a..410472900e81c105747a32b66d31ef1301326b83 100644
--- a/docs/source/algorithms/MergeCalFiles-v1.rst
+++ b/docs/source/algorithms/MergeCalFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MergeLogs-v1.rst b/docs/source/algorithms/MergeLogs-v1.rst
index e4b257a2df5fbcfb861a121ff6ba0eb95fce38f5..f10702f4eacd077be486ce3fb61b4f10afa0159c 100644
--- a/docs/source/algorithms/MergeLogs-v1.rst
+++ b/docs/source/algorithms/MergeLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MergeMD-v1.rst b/docs/source/algorithms/MergeMD-v1.rst
index 2acf36e1fe878fadbe335dfefc90d4afb2f6292f..263470105bb4ecde08f70364601597bbd8928d45 100644
--- a/docs/source/algorithms/MergeMD-v1.rst
+++ b/docs/source/algorithms/MergeMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MergeMDFiles-v1.rst b/docs/source/algorithms/MergeMDFiles-v1.rst
index bbb7fa66d1c2640f696ea9266fcb6ccea523c42d..eb383fc1db543579fdea4e7856ee16222a226271 100644
--- a/docs/source/algorithms/MergeMDFiles-v1.rst
+++ b/docs/source/algorithms/MergeMDFiles-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MergeRuns-v1.rst b/docs/source/algorithms/MergeRuns-v1.rst
index 1ff0fbaf6a39249cd8bf972cf52eb01827488a87..1c41b77e816dcf0184a116e3d3cb247225e80e79 100644
--- a/docs/source/algorithms/MergeRuns-v1.rst
+++ b/docs/source/algorithms/MergeRuns-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Min-v1.rst b/docs/source/algorithms/Min-v1.rst
index 04328af539f7771ec46934f099f71bd55f42876a..d36da60edf2659484acc62bd0e0104ab65852bf3 100644
--- a/docs/source/algorithms/Min-v1.rst
+++ b/docs/source/algorithms/Min-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Minus-v1.rst b/docs/source/algorithms/Minus-v1.rst
index 27d3ff7dc7fd72ff1c10e599c70f6c80e628e4ab..77c371c156a2b3f3f7f02a5d82cceec0891695ee 100644
--- a/docs/source/algorithms/Minus-v1.rst
+++ b/docs/source/algorithms/Minus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MinusMD-v1.rst b/docs/source/algorithms/MinusMD-v1.rst
index df468c762969a6875724fa5dd33bd8514f130960..d55bb27197c815d7db7a2c80f3a75f991a36a876 100644
--- a/docs/source/algorithms/MinusMD-v1.rst
+++ b/docs/source/algorithms/MinusMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ModeratorTzero-v1.rst b/docs/source/algorithms/ModeratorTzero-v1.rst
index 7ec77175e2a9ac8db63bd5432e34339a919318f9..b03a405bd4bcc0966eb7e20ad4f85f2cff1f42eb 100644
--- a/docs/source/algorithms/ModeratorTzero-v1.rst
+++ b/docs/source/algorithms/ModeratorTzero-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst
index f2352550059403f6aa2f313cc15fededbc0a41f8..7684fa4be21885922fa16171e24075d5d9fabce3 100644
--- a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst
+++ b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst
index 58aef3d2ae23e4938044711b203dbd9da31410da..0df84923b53e80c8ee7397a411676493f1e32254 100644
--- a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst
+++ b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MolDyn-v1.rst b/docs/source/algorithms/MolDyn-v1.rst
index c29281247027363568e038e75c510a95534e1b73..c776859164ccb880f1594c67d4f017679e4b1a39 100644
--- a/docs/source/algorithms/MolDyn-v1.rst
+++ b/docs/source/algorithms/MolDyn-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst b/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst
index 0c96ec724c1d1acfa91bab72f0e558a816e5edcc..bbf858a58c912bf2b36ce5d8fe2904945958199d 100644
--- a/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst
+++ b/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MonitorLiveData-v1.rst b/docs/source/algorithms/MonitorLiveData-v1.rst
index cb3401f0a2f30263d61f66253ccab0c88f424b2e..7545e2311437dec9e0f595b21ba4557eebf116ae 100644
--- a/docs/source/algorithms/MonitorLiveData-v1.rst
+++ b/docs/source/algorithms/MonitorLiveData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MonteCarloAbsorption-v1.rst b/docs/source/algorithms/MonteCarloAbsorption-v1.rst
index eb8ae7c7effa96ff03a016651a62da20e8d4b950..bdc1e59726fbe4131bebfa236e3e1e535d0df518 100644
--- a/docs/source/algorithms/MonteCarloAbsorption-v1.rst
+++ b/docs/source/algorithms/MonteCarloAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MostLikelyMean-v1.rst b/docs/source/algorithms/MostLikelyMean-v1.rst
index 0573e797c957c37533b9555ab8fb8af7ea40dc6f..122cc8d600bda7c4512b4635232a2dfdf0e08fe5 100644
--- a/docs/source/algorithms/MostLikelyMean-v1.rst
+++ b/docs/source/algorithms/MostLikelyMean-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MoveInstrumentComponent-v1.rst b/docs/source/algorithms/MoveInstrumentComponent-v1.rst
index 579eca2db371c6903bfb701ea2092d0da0c954bb..7202f866af8470412f3be8603ab9b4738a301d62 100644
--- a/docs/source/algorithms/MoveInstrumentComponent-v1.rst
+++ b/docs/source/algorithms/MoveInstrumentComponent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst b/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst
index 8ba34d07e087a113f0bbc3aa19e87538c15bdb94..bcb4b1ce649ed5156a2e90269f241aec0551b587 100644
--- a/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst
+++ b/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Multiply-v1.rst b/docs/source/algorithms/Multiply-v1.rst
index b8eb73ac9f9e53b0902a85c4f9df9b2cec7795f6..06f738f55e7d5ee7bbefa0f8d73eb1dbebe4e909 100644
--- a/docs/source/algorithms/Multiply-v1.rst
+++ b/docs/source/algorithms/Multiply-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MultiplyMD-v1.rst b/docs/source/algorithms/MultiplyMD-v1.rst
index ab23a28de8f3206f73c804abba911459bcb8975f..e63c67fa070d268fdbf754b845c62b57d8eff965 100644
--- a/docs/source/algorithms/MultiplyMD-v1.rst
+++ b/docs/source/algorithms/MultiplyMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MultiplyRange-v1.rst b/docs/source/algorithms/MultiplyRange-v1.rst
index fe72fcb0080c2408bf2421e54cbce970bb7d2b65..284891de161d4c4372225cf8a58b110dade59a1f 100644
--- a/docs/source/algorithms/MultiplyRange-v1.rst
+++ b/docs/source/algorithms/MultiplyRange-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuonGroupDetectors-v1.rst b/docs/source/algorithms/MuonGroupDetectors-v1.rst
index dcf6a7d1d765a0f8a7e414772b3afa21c46dfea1..9a9549927230556ead1bf9139426cc06237fa1aa 100644
--- a/docs/source/algorithms/MuonGroupDetectors-v1.rst
+++ b/docs/source/algorithms/MuonGroupDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuonMaxent-v1.rst b/docs/source/algorithms/MuonMaxent-v1.rst
index 5ea956f2d0d6eefaf68d3e59fb4a539aa6d68c56..c85399b6a5e87a2ac4d20536ea82f73d9c726f67 100644
--- a/docs/source/algorithms/MuonMaxent-v1.rst
+++ b/docs/source/algorithms/MuonMaxent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuonProcess-v1.rst b/docs/source/algorithms/MuonProcess-v1.rst
index 460e2348cfd2e1ada5e070dee427da5b10c6babf..f24b88fc76d1fbd1803c538be2b92c5075f9a2c0 100644
--- a/docs/source/algorithms/MuonProcess-v1.rst
+++ b/docs/source/algorithms/MuonProcess-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuscatData-v1.rst b/docs/source/algorithms/MuscatData-v1.rst
index 810162435cd4e2bbb04812cd345f478e17c261d8..e6a500e1efe644120b3b2d3dd25970bfca6595b4 100644
--- a/docs/source/algorithms/MuscatData-v1.rst
+++ b/docs/source/algorithms/MuscatData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuscatFunc-v1.rst b/docs/source/algorithms/MuscatFunc-v1.rst
index 3c0bd184bd6183b027ad9aca4bc3cb5f5c8a9f3d..921e759ba69a9b953532f403a1b1fc2776813ad7 100644
--- a/docs/source/algorithms/MuscatFunc-v1.rst
+++ b/docs/source/algorithms/MuscatFunc-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/MuscatSofQW-v1.rst b/docs/source/algorithms/MuscatSofQW-v1.rst
index 692b2bb76c7eaaeb7aabb787ff70d4a955536919..3442b17a9d2f8db60e692454527d01d159660f17 100644
--- a/docs/source/algorithms/MuscatSofQW-v1.rst
+++ b/docs/source/algorithms/MuscatSofQW-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NMoldyn4Interpolation-v1.rst b/docs/source/algorithms/NMoldyn4Interpolation-v1.rst
index 6209957c9c0dd207260d1e56a70b27cb52b3ebee..ff3d0a10409913a938145e1f7f944f4c22d72f34 100644
--- a/docs/source/algorithms/NMoldyn4Interpolation-v1.rst
+++ b/docs/source/algorithms/NMoldyn4Interpolation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NRCalculateSlitResolution-v1.rst b/docs/source/algorithms/NRCalculateSlitResolution-v1.rst
index bdd830f369c35ee35ef6af028d065c6bb5ed052b..1f729b8c20ced64dce0d2b712f7aa49c8cce1a62 100644
--- a/docs/source/algorithms/NRCalculateSlitResolution-v1.rst
+++ b/docs/source/algorithms/NRCalculateSlitResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -17,7 +17,7 @@ using the theta log name provided.
 The effective inverse of this algorithm is :ref:`algm-CalculateSlits`.
 
 Beam Divergence
-***************
+###############
 
 .. figure:: ../images/collimation_diagram.png
    :scale: 50 %
diff --git a/docs/source/algorithms/NexusTester-v1.rst b/docs/source/algorithms/NexusTester-v1.rst
index 6314e9a18afc2eaa2694b0696ce88a0934dea449..e2bac7eed2c2d9788a166401b6ff9ae650efc090 100644
--- a/docs/source/algorithms/NexusTester-v1.rst
+++ b/docs/source/algorithms/NexusTester-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseByCurrent-v1.rst b/docs/source/algorithms/NormaliseByCurrent-v1.rst
index ad9fbc58e87251e0fa5ff0a85b098a997b5d7833..b306fee5c54159625f1000e28e7e3f47e14af27e 100644
--- a/docs/source/algorithms/NormaliseByCurrent-v1.rst
+++ b/docs/source/algorithms/NormaliseByCurrent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseByDetector-v1.rst b/docs/source/algorithms/NormaliseByDetector-v1.rst
index a9d4792005530a0e4bbcdc2cfe64d265fe28fb35..b7d8f7d19c444bfe9769827fca0974bc332e1edc 100644
--- a/docs/source/algorithms/NormaliseByDetector-v1.rst
+++ b/docs/source/algorithms/NormaliseByDetector-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseByPeakArea-v1.rst b/docs/source/algorithms/NormaliseByPeakArea-v1.rst
index fb3e25279aeddd584f1a0cfb7ae3c89c4766b9f9..b11b2e9f47137084ca5381f962a2f8b69e5d42b3 100644
--- a/docs/source/algorithms/NormaliseByPeakArea-v1.rst
+++ b/docs/source/algorithms/NormaliseByPeakArea-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseByThickness-v1.rst b/docs/source/algorithms/NormaliseByThickness-v1.rst
index 437f5584ca7c451946eb66d8420a50b666d862cb..362f9dff526d75f221b59c6df21894d06dde68be 100644
--- a/docs/source/algorithms/NormaliseByThickness-v1.rst
+++ b/docs/source/algorithms/NormaliseByThickness-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseSpectra-v1.rst b/docs/source/algorithms/NormaliseSpectra-v1.rst
index d7e428c066435768ca84bae1a9401c48a9d23468..ef9b534a1f3044040f1761190726d10c1b7afcc9 100644
--- a/docs/source/algorithms/NormaliseSpectra-v1.rst
+++ b/docs/source/algorithms/NormaliseSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseToMonitor-v1.rst b/docs/source/algorithms/NormaliseToMonitor-v1.rst
index 520ea336220f699f86a6e843f472952ba5049163..79df1957337b68e9a6f6889356150a413b795155 100644
--- a/docs/source/algorithms/NormaliseToMonitor-v1.rst
+++ b/docs/source/algorithms/NormaliseToMonitor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseToUnity-v1.rst b/docs/source/algorithms/NormaliseToUnity-v1.rst
index 059fe586a0999153986feb5a61ff5a4639a896bf..637da1324fc2018911e493a8e14d5f7879ef4363 100644
--- a/docs/source/algorithms/NormaliseToUnity-v1.rst
+++ b/docs/source/algorithms/NormaliseToUnity-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NormaliseVanadium-v1.rst b/docs/source/algorithms/NormaliseVanadium-v1.rst
index 4bf7490ef3640e25d72011a04b6cb546874a8fef..c441ac08356614ef3a523a4e4de6dcd3e5896fa6 100644
--- a/docs/source/algorithms/NormaliseVanadium-v1.rst
+++ b/docs/source/algorithms/NormaliseVanadium-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/NotMD-v1.rst b/docs/source/algorithms/NotMD-v1.rst
index 3c87a3ee903972bee6221fd9f61e02c47d1531e6..49026f56f05e787af35643e2a67d2905430e3f99 100644
--- a/docs/source/algorithms/NotMD-v1.rst
+++ b/docs/source/algorithms/NotMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst b/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst
index 87bf5b6dc369d097dea3b1e95c6ac002e6be133e..c9bc8716db237f1cc4f9298635cfb9c38cde544c 100644
--- a/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst
+++ b/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OneMinusExponentialCor-v1.rst b/docs/source/algorithms/OneMinusExponentialCor-v1.rst
index a35ca4c96320fc16fc5c2d5cc51384ed7f0d25de..c82a12a31969d596a7fb5744ca9a6d061e53e1b4 100644
--- a/docs/source/algorithms/OneMinusExponentialCor-v1.rst
+++ b/docs/source/algorithms/OneMinusExponentialCor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OneStepMDEW-v1.rst b/docs/source/algorithms/OneStepMDEW-v1.rst
index ab2b0dc463fb5ad401df978b8c38e94bfdd0bf6b..dc1664119db75a31a79b519a58c319d74a401472 100644
--- a/docs/source/algorithms/OneStepMDEW-v1.rst
+++ b/docs/source/algorithms/OneStepMDEW-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
index 712f492abf243fa83468c31d8c48a98d42ce2a02..d4527d6fdbfba4fe4c41c28e33c416768f54787e 100644
--- a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
+++ b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst b/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst
index fb3a18d2d23c9753442f432370756fab1ccdb558..d3badd33dc0f915ea7c334956de5d5e469dea904 100644
--- a/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst
+++ b/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/OrMD-v1.rst b/docs/source/algorithms/OrMD-v1.rst
index 6c32609d1c5cfd80b950828afba64d899152dce0..5731f041fcfa1bd2d38032e2a64245131df55bfc 100644
--- a/docs/source/algorithms/OrMD-v1.rst
+++ b/docs/source/algorithms/OrMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PDCalibration-v1.rst b/docs/source/algorithms/PDCalibration-v1.rst
index a916066df11347145cdb677c11f9fce550873713..fbaecc83cab2100881063b7e9c67af23324cde2b 100644
--- a/docs/source/algorithms/PDCalibration-v1.rst
+++ b/docs/source/algorithms/PDCalibration-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst
index d34d55bc56009072b62e9a89f0343b7cf8d12140..3bbf4814847a6404574a59735e923a5c76ce37b7 100644
--- a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst
+++ b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PDFFourierTransform-v1.rst b/docs/source/algorithms/PDFFourierTransform-v1.rst
index e1ab0936bfd4d201b9efc06ce15b4e96e2e533a1..de892da208fd3652c62e6f89c070fe929689410a 100644
--- a/docs/source/algorithms/PDFFourierTransform-v1.rst
+++ b/docs/source/algorithms/PDFFourierTransform-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -32,7 +32,7 @@ Output Options
 --------------
 
 **G(r)**
-'''''''''
+########
 
 .. raw:: html
 
@@ -84,7 +84,7 @@ otherwise
 
 
 **g(r)**
-''''''''
+########
 
 .. raw:: html
 
@@ -111,7 +111,7 @@ transforms to
 
 
 **RDF(r)**
-''''''''''
+##########
 
 .. raw:: html
 
diff --git a/docs/source/algorithms/PDLoadCharacterizations-v1.rst b/docs/source/algorithms/PDLoadCharacterizations-v1.rst
index 6fb3ad6727cc22c5f88899c336f9cd7651a399c5..48454d9e29068557729d8e4c6f0cb92a3475b81c 100644
--- a/docs/source/algorithms/PDLoadCharacterizations-v1.rst
+++ b/docs/source/algorithms/PDLoadCharacterizations-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PDToGUDRUN-v1.rst b/docs/source/algorithms/PDToGUDRUN-v1.rst
index 5f242e390a5d59a6a40d4a7433ccd64255d12fc5..1090a979c2e46ac0c63e984c5b40879c7dc4c1a0 100644
--- a/docs/source/algorithms/PDToGUDRUN-v1.rst
+++ b/docs/source/algorithms/PDToGUDRUN-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PDToPDFgetN-v1.rst b/docs/source/algorithms/PDToPDFgetN-v1.rst
index f37aae644e29dee983a0c7e1ab829a772546b5a4..52236db5af28db3533cc0b4442538f9149cf6edd 100644
--- a/docs/source/algorithms/PDToPDFgetN-v1.rst
+++ b/docs/source/algorithms/PDToPDFgetN-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PaddingAndApodization-v1.rst b/docs/source/algorithms/PaddingAndApodization-v1.rst
index a2a6dd46e16eef89178a4aae65e588424af214c2..365c47df7536082d55d39e1a1bc5170f3b35d1a3 100644
--- a/docs/source/algorithms/PaddingAndApodization-v1.rst
+++ b/docs/source/algorithms/PaddingAndApodization-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Pause-v1.rst b/docs/source/algorithms/Pause-v1.rst
index 3608265c5ab15ceb0f2ef93cbdeb3eb352424094..b8d05479ccd3a441d4f626226ca2315c051ed2b9 100644
--- a/docs/source/algorithms/Pause-v1.rst
+++ b/docs/source/algorithms/Pause-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PawleyFit-v1.rst b/docs/source/algorithms/PawleyFit-v1.rst
index 2d595ce71e36b1d5d8f4801b24d7cd0e5b2248c7..0304af84e3304d3865fe41d09439a52c8e2fe103 100644
--- a/docs/source/algorithms/PawleyFit-v1.rst
+++ b/docs/source/algorithms/PawleyFit-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PeakIntegration-v1.rst b/docs/source/algorithms/PeakIntegration-v1.rst
index 5883750d5d06cea702d89fe46fe3a59556c6db89..10f147f712bbb0d901d35b80b73da81e0f9b1073 100644
--- a/docs/source/algorithms/PeakIntegration-v1.rst
+++ b/docs/source/algorithms/PeakIntegration-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst
index 3c2dfb61ec141539943007b225c7ce1bacf823f7..5bbcab8f5fefc6b06b3a35fca7f5f2fa07567113 100644
--- a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst
+++ b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PeaksInRegion-v1.rst b/docs/source/algorithms/PeaksInRegion-v1.rst
index d31f554b61c8fcc59fd6d0d4341b0551a2fd25ed..416e628b74479109c896766a328d7936dc50e628 100644
--- a/docs/source/algorithms/PeaksInRegion-v1.rst
+++ b/docs/source/algorithms/PeaksInRegion-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PeaksOnSurface-v1.rst b/docs/source/algorithms/PeaksOnSurface-v1.rst
index 2120e70924cc30974d541d4fd1654970672f421a..9863d8155b84dd38bd66f84c057621039f1ba83b 100644
--- a/docs/source/algorithms/PeaksOnSurface-v1.rst
+++ b/docs/source/algorithms/PeaksOnSurface-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PearlMCAbsorption-v1.rst b/docs/source/algorithms/PearlMCAbsorption-v1.rst
index 98d3162d44126348119401fcc5a4358e84b62283..160bb9d855fe6698a0bc373d7f1a76dc3ace2936 100644
--- a/docs/source/algorithms/PearlMCAbsorption-v1.rst
+++ b/docs/source/algorithms/PearlMCAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PerformIndexOperations-v1.rst b/docs/source/algorithms/PerformIndexOperations-v1.rst
index 8884f4c92dd4a072e7596e16fdf01b46fe6ae982..cc43e6c55990a5df181c39f2d91a33eb4d0bb9b7 100644
--- a/docs/source/algorithms/PerformIndexOperations-v1.rst
+++ b/docs/source/algorithms/PerformIndexOperations-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PhaseQuad-v1.rst b/docs/source/algorithms/PhaseQuad-v1.rst
index 30f6d6da89ecb6bfaaaed11826ccfe8ae8e9b2c5..90ed1e0970868f0a3f92f29394f8e40532acdf84 100644
--- a/docs/source/algorithms/PhaseQuad-v1.rst
+++ b/docs/source/algorithms/PhaseQuad-v1.rst
@@ -16,7 +16,7 @@ the dataset using the algorithm :ref:`algm-RRFMuon`. Both algorithms are fully d
 by T.M. Riseman and J.H. Brewer [Hyp. Int., 65, (1990), 1107].
 
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst b/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst
index bcdd84cedb0f572a9197683c2a27158e2aefd9c9..5f73a567df13c9fffd5c638bd1015d93667a5f7d 100644
--- a/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst
+++ b/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PlotPeakByLogValue-v1.rst b/docs/source/algorithms/PlotPeakByLogValue-v1.rst
index 2abc311e9edcd62cf5adcbc398e0b0b3d52b5215..aaa63fab9c676456901c90181d54fdc13e284435 100644
--- a/docs/source/algorithms/PlotPeakByLogValue-v1.rst
+++ b/docs/source/algorithms/PlotPeakByLogValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Plus-v1.rst b/docs/source/algorithms/Plus-v1.rst
index ae8542c8964a4bea6378a872c4a0ceabad1dc68b..0e5ccdcf98eb0c71e97cbbd3815f6b47dfc02c3d 100644
--- a/docs/source/algorithms/Plus-v1.rst
+++ b/docs/source/algorithms/Plus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PlusMD-v1.rst b/docs/source/algorithms/PlusMD-v1.rst
index b61fe857e8bb352348bc8d485e9607d9b29eaeae..652d6a4f8b25871046c2dc629fcd72c0d71e862c 100644
--- a/docs/source/algorithms/PlusMD-v1.rst
+++ b/docs/source/algorithms/PlusMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PointByPointVCorrection-v1.rst b/docs/source/algorithms/PointByPointVCorrection-v1.rst
index 8cd77e9b2d9129797379113446c2942b2d917d60..9b5887582ea1204c3e96894ee458b7b139d6776a 100644
--- a/docs/source/algorithms/PointByPointVCorrection-v1.rst
+++ b/docs/source/algorithms/PointByPointVCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoissonErrors-v1.rst b/docs/source/algorithms/PoissonErrors-v1.rst
index ff71601af0216fb910ace03932b3b515157f2bda..e2afcc45783ca8e5a581861d87344bc57f7edb1c 100644
--- a/docs/source/algorithms/PoissonErrors-v1.rst
+++ b/docs/source/algorithms/PoissonErrors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PolarizationCorrection-v1.rst b/docs/source/algorithms/PolarizationCorrection-v1.rst
index f3ad00bdb846ab297a5984dd3c8d1ff922a14004..c42f2de3d7fec485a9e788ea88186a38b37e00d4 100644
--- a/docs/source/algorithms/PolarizationCorrection-v1.rst
+++ b/docs/source/algorithms/PolarizationCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst b/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst
index 6768e8f5fdd09bbcc4a2a7c1fb4a63c2224cc9bd..a34480a2307b1035f6ee503f4b5b352f272d11bd 100644
--- a/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst
+++ b/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst b/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst
index db4d53d023643f1509e39640ba992acc1263319e..4e7d1efd056eb3ed5e872bb9771b909e339ff5b7 100644
--- a/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst
+++ b/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiAutoCorrelation-v5.rst b/docs/source/algorithms/PoldiAutoCorrelation-v5.rst
index 06d1a4746d6ce6343dde224b860e3c26879be2d2..fab4797afc75a89d9c25694c8b96f9e53bfc02c6 100644
--- a/docs/source/algorithms/PoldiAutoCorrelation-v5.rst
+++ b/docs/source/algorithms/PoldiAutoCorrelation-v5.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst b/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst
index 474852eb1f01b2eeb3ef66087403bf74180b5fba..949ea1c1e2e2912e61ca4d1d6058dc3e34a6d70f 100644
--- a/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst
+++ b/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst b/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst
index 5ed11c6b4027641d31c3bac02db335057d8f42d4..12f8f906cb00f488bf8f59cd7d4a146389d90df3 100644
--- a/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst
+++ b/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiDataAnalysis-v1.rst b/docs/source/algorithms/PoldiDataAnalysis-v1.rst
index 2ba86f8a52a3dd948256c1a25f170e46f6d52cbb..b3a40781d215c7948f8c41118a722103c40c809f 100644
--- a/docs/source/algorithms/PoldiDataAnalysis-v1.rst
+++ b/docs/source/algorithms/PoldiDataAnalysis-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiFitPeaks1D-v1.rst b/docs/source/algorithms/PoldiFitPeaks1D-v1.rst
index 97f082a76b1c826705698cccf3c7ed6bd9b33807..3043e2daef16bedcaa82e21008407af089d670fc 100644
--- a/docs/source/algorithms/PoldiFitPeaks1D-v1.rst
+++ b/docs/source/algorithms/PoldiFitPeaks1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiFitPeaks1D-v2.rst b/docs/source/algorithms/PoldiFitPeaks1D-v2.rst
index 3bc77b32254857fb891e5f045efd1c4597e2f71f..dabc74f453f0b9c9a7168ae3fdab679f0e8e9e98 100644
--- a/docs/source/algorithms/PoldiFitPeaks1D-v2.rst
+++ b/docs/source/algorithms/PoldiFitPeaks1D-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiFitPeaks2D-v1.rst b/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
index d2cc1729a4a97e2b5e98487120210a3781a9981c..ebff26e15814f83851b7416b6034ac969d5791b1 100644
--- a/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
+++ b/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst b/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst
index 615f830636cfd36e78bc6036e02efe370e34bdea..7557517576c76f649a74a2153ca876b50b0ef132 100644
--- a/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst
+++ b/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiLoadRuns-v1.rst b/docs/source/algorithms/PoldiLoadRuns-v1.rst
index 8fb355dd2a0bb064b8adef8c3777624ce43d9d03..c2a82a3ce75a4529586238b284ac734e4bdc64b7 100644
--- a/docs/source/algorithms/PoldiLoadRuns-v1.rst
+++ b/docs/source/algorithms/PoldiLoadRuns-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiMerge-v1.rst b/docs/source/algorithms/PoldiMerge-v1.rst
index 43efce97d054a3ab99b2019153a08f71d244f009..f1bb1e512c8c9930409a90d2c8bc31ed75f01d10 100644
--- a/docs/source/algorithms/PoldiMerge-v1.rst
+++ b/docs/source/algorithms/PoldiMerge-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiPeakSearch-v1.rst b/docs/source/algorithms/PoldiPeakSearch-v1.rst
index e5f4a535f6bb696860f300eeaf971ebae78383df..6051f20db58db298ad7dfc0518f281072bc0fe95 100644
--- a/docs/source/algorithms/PoldiPeakSearch-v1.rst
+++ b/docs/source/algorithms/PoldiPeakSearch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiPeakSummary-v1.rst b/docs/source/algorithms/PoldiPeakSummary-v1.rst
index 058e6408ae5ff383617be56d2c01aa8cbb9f3b51..dda2634eabd862fb9c53094d702229055aa08f7e 100644
--- a/docs/source/algorithms/PoldiPeakSummary-v1.rst
+++ b/docs/source/algorithms/PoldiPeakSummary-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PoldiTruncateData-v1.rst b/docs/source/algorithms/PoldiTruncateData-v1.rst
index a8ad7c8454f5d0c96ad688bd26c9afb7b6ec47e8..3b29df5d33dc699d8794f970eee454f3bb82ac68 100644
--- a/docs/source/algorithms/PoldiTruncateData-v1.rst
+++ b/docs/source/algorithms/PoldiTruncateData-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PolynomialCorrection-v1.rst b/docs/source/algorithms/PolynomialCorrection-v1.rst
index 379471ffb8679d7b2a5f97bf445932a1ca863fc4..00c0a3a00004586038b2e846a3696246f0e3f37e 100644
--- a/docs/source/algorithms/PolynomialCorrection-v1.rst
+++ b/docs/source/algorithms/PolynomialCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst b/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst
index 972a9b365e3083ef18a9dee3164b213c25db5e46..bb2ecc3d790da6bb3c330ab31f427a3ab0a70956 100644
--- a/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst
+++ b/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst
@@ -2,91 +2,205 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
 Description
 -----------
 
-This algorithm calculates the detector efficiency corrections for the instrument D20 at the ILL.
+This algorithm calculates the detector efficiency corrections for scanning monochromatic powder diffractometers D20 and D2B at ILL.
+Detector scan in this context stands for a set of discrete rotations of the detector around the sample in the horizontal (scattering) plane.
+The general philosophy is based on the fact that different detector cells pass through the same spatial coordinates during the scan.
+Under the assumption that at a certain coordinate all the detectors should measure the same counts, one could derive relative inter-calibration between the cells.
+The input to the algorithm is a set of detector scan acquisitions recorded for vanadium sample.
+However, **no assumption** that vanadium response has to be flat and isotropic, is made.
+That is, the geometrical effects, off-plane self-attenuation effects, and the small Bragg peaks in the vanadium data are well taken into account.
+The output is a map of calibration constants that have to be applied multiplicatively to the sample data; that is, the calibration constant is the inverse of the relative detector efficiency.
 
-It performs as follows:
+DerivationMethod
+----------------
 
-1. Takes the first cell response as a function of scattering angle as a reference
+There are two strategies to derive the efficiencies, as follows:
 
-2. Takes the second cell, and divides the reference to the second cell response in the overlapping region in terms of scattering angle. This results in the array of relative response ratios.
+  - **SequentialSummedReference1D** (referred hereafter as the **D20** method) must be used for D20, which is a 1D detector with solid rectangular panels.
 
-3. Uses one of the 3 suggested options to compute the relative calibration factor from the array of relative response ratios. This factor is saved in the output as the calibration factor for the second cell.
+    1. Takes the first cell response as a function of scattering angle (during the scan) as a reference
 
-4. The response of the second cell is scaled up with that factor, and then merged (in the overlapping region) with the reference using :ref:`WeightedMean <algm-WeightedMean>`.
+    2. Takes the second cell and divides the reference to the second cell response in the overlapping region in terms of scattering angle. This results in an array of relative response ratios.
 
-5. Repeat from Step 2 for the next cell and so on until the last cell.
+    3. Uses one of the 3 calibration methods (see below) to compute the relative calibration factor from the array of relative response ratios. This factor is saved in the output as the calibration factor for the second cell.
 
-For the zero-counting cells, the calibration factor cannot be computed, and it will be set to 1. Cells are treated as zero-counting, if they count zero more than 80% of time.
+    4. The response of the second cell is scaled up with that factor, and then merged (in the overlapping region) with the reference using :ref:`WeightedMean <algm-WeightedMean>`. This results in a new reference.
 
-After the calibration factors are computed for all the cells, they are divided by the median of all the factors (excluding the zero counting cells),
-in order to absolutely normalise the calibration curve.
+    5. Repeat from Step 2 for the next cell using the updated reference and so on until the last cell.
 
-Input
------
 
-The input must be a single **detector-scan** run in `.nxs` format produced for vanadium.
+    For the zero-counting cells, the calibration factor cannot be computed, hence they will be set to 1. Cells are treated as zero-counting if they count zero more than 80% of time.
 
-Optionally the previously derived calibration file can be seeded, and the algorithm will then compute the residual calibration factors on top of that.
+    After the calibration factors are computed for all the cells, they are divided by the median of all the factors (excluding the zero-counting cells),
+    in order to absolutely normalize the calibration curve.
 
-Method
-------
 
-You can choose the method of how the relative calibration factor is extracted from the relative response ratios (Step 3).
-It can be the Median (default), Mean or :ref:`MostLikelyMean <algm-MostLikelyMean>`.
+  - **GlobalSummedReference2D** (referred hereafter as the **D2B** method) must be used for D2B, which is a 2D detector composed of PSD tubes that are placed at some distance from each other, hence the detector has gaps between the tubes.
 
-Excluded range
+    1. Averages the responses of all the pixels at a certain height level using :ref:`SumOverlappingTubes <algm-SumOverlappingTubes>`. This results in a global reference, which is a 2D matrix of averaged counts.
+
+    2. For each tube, constructs the ratio of the global reference wrt the tube response in the overlapping region; this results in arrays of relative response ratios for each pixel in that tube.
+
+    3. Takes the median of the response ratios as calibration constant for the given pixel in the given tube.
+
+    4. Optionally, if iterations are requested (see below), it applies the calibration of the first run to the input, and repeats from Step 1.
+
+
+    As mentioned, the calibration constants are computed pixel by pixel; no grouping of pixels inside the tubes is done.
+
+CalibrationMethod
+-----------------
+
+When relative response ratios are constructed for a given pixel, the algorithm offers 3 ways to get the calibration factor out: median (default), mean and :ref:`MostLikelyMean <algm-MostLikelyMean>`.
+For the **D2B** case, for the moment only median is supported, as the convergence of the other methods through the iterations is currently under investigation.
+
+CalibrationRun
 --------------
 
-Provide ranges in scattering angle in degrees, to exclude non-desired regions, e.g. the beam stop.
-Multiple regions can be set, **-20,0,10,20** will exclude **[-20,0]** and **[10,20]**.
-This exclusion will happen at Step 3.
+The input must be a set of **detector-scan** numors in **.nxs** format produced for vanadium.
 
-Pixel range
------------
+CalibrationFile
+---------------
+
+Optionally a previously derived calibration file (e.g. the output of this algorithm saved with :ref:`SaveNexusProcessed <algm-SaveNexusProcessed>`) can be provided.
+In this case this calibration will be applied first, and then the algorithm will compute residual calibration factors on top of that.
+
+ExcludedRange
+-------------
+
+Provide ranges in scattering angle in degrees (in equatorial plane) to exclude non-desired regions, e.g. the beam stop.
+In principle, multiple regions can be set, **-20,0,10,20** will exclude **[-20,0]** and **[10,20]**.
+The exclusion happens at Step 3 for both of the derivation methods, before computing the calibration factor out of the relative response ratios.
+
+PixelRange
+----------
 
 Provide the range of detector cells to compute the calibration factors for.
 For the rest of the cells, the factor will be set to 1.
+This is used for **D20** only, and by default the factors will be computed for all the cells.
 
-Output
-------
+NormaliseTo
+-----------
 
-Output will be a single-column workspace containing the calibration factors for each cell. This should be normally saved with
-:ref:`SaveNexusProcessed <algm-SaveNexusProcessed>` to be later used in :ref:`PowderDiffILLReduction <algm-PowderDiffILLReduction>`.
+The input data can be optionally normalised to monitor counts or region-of-interest (ROI, for **D20** only) counts.
 
-Optionally, the full absolute response resulted from the combination of the data for all the cells (see Step 4 above) can also be output.
+ROI
+---
 
-Workflow
---------
+Regions of scattering angle in degrees (in equatorial plane), where the counts are summed, and the data is normalised to the sum. Relevant only for **D20**.
 
-.. diagram:: PowderDiffILLDetEffCorr-v1_wkflw.dot
+OutputWorkspace
+---------------
 
-Related Algorithms
+For **D20**, the output is a single-column workspace containing the calibration factors for each cell.
+For **D2B**, it is a 2D workspace (x axis is the tube index, spectrum axis is the pixel index in the tube).
+The output should be normally saved with
+:ref:`SaveNexusProcessed <algm-SaveNexusProcessed>` to be later used in :ref:`PowderDiffILLReduction <algm-PowderDiffILLReduction>` and :ref:`PowderDiffILLDetScanReduction <algm-PowderDiffILLDetScanReduction>`.
+
+OutputResponseWorkspace
+-----------------------
+
+Optionally, the merged response of the cells taking into account the newly derived calibration can be output. This is a 1D spectrum for **D20** and 2D workspace for **D2B**.
+
+NumberOfIterations
 ------------------
 
-:ref:`PowderDiffILLReduction <algm-PowderDiffILLReduction>` performs the data reduction.
+This is used for **D2B** only.
+For **D20** there is no need for iterations, since a single shot derivation is already convergent; that is, the residual calibration factors are identical to unity.
+
+This specifies how many times the calibration has to be derived (see Step 4 above for **D2B** method):
+
+  - 1 by default: The calibration will be derived only once (single-shot) and no iteration will be performed. Typically this gives reasonably good result already.
 
-Usage
------
+  - User specified positive integer: Iterations will be performed as many times as requested. It is not advised to iterate too much, since after local convergence it may start to diverge again; hence there is a hard limit of 10.
 
-**Example - PowderDiffILLDetEffCorr**
+  - 0 stands for auto: Iterations will be run automatically until the termination criteria is satisfied. Termination criteria is:
+
+      .. math:: \chi^2/NdoF = \frac{\sum_{i,j}(c_{ij} - 1)ˆ2}{N_{tubes} * N_{pixels_per_tube}} < t
+
+      where :math:`c_{ij}` is the residual calibration factor for tube *i* and pixel *j*, :math:`t` is the threshold defined in :ref:`Instrument Parameter File (IPF)<InstrumentParameterFile>` as *chi2_ndof*.
+
+      The top and bottom parts of the tubes are excluded from this calculation. How many pixels exactly are excluded is again defined in :ref:`IPF <InstrumentParameterFile>` as *pixels_to_trim*.
+
+      Currently, for **D2B**, *pixels_to_trim=28* and *t=1%*. With this settings iterations typically terminate after the first one, i. e. one run and one iteration give results already convergent within 1%.
+
+      This has to be interpreted as: the residual calibration is close enough to unity, so further iterations will not change the calibration much.
+
+      However, this criterion does not prevent from divergence in all the cases.
+      It can happen that for a given pixel the residual calibration factor (albeit close to unity) is always on the same side (i.e. always above 1 or below 1); this will cause the absolute calibration to gradually diverge with iterations.
+      Anyways, the method implemented does not provide enough precision to resolve residual calibration better than in the percent range.
+      Hence, care must be taken when using the iterations.
+      It is not recommended to use more than 2 iterations.
+
+Limitations
+-----------
+
+For **D2B** it is assumed that the tubes and pixels pass through the exact same positions during the scan.
+That is, the tubes have to be aligned vertically and horizontally and the gap between each pair of neighboring tubes must be integer multiple of the scan step.
+
+D20 Workflow
+------------
+
+.. diagram:: PowderDiffILLDetEffCorr-v1_D20_wkflw.dot
+
+.. include:: ../usagedata-note.txt
+
+**Example - D20**
 
 .. code-block:: python
 
-   calib = PowderDiffILLDetEffCorr(CalibrationRun='967076', OutputWorkspace='constants')
-   print("Reduced workspace contains {0} constants, one for each cell.".format(calib.getNumberHistograms()))
+   import matplotlib.pyplot as plt
+   from mantid import plots
+   from mantid.simpleapi import PowderDiffILLDetEffCorr
+   PowderDiffILLDetEffCorr(CalibrationRun='967076.nxs', DerivationMethod='SequentialSummedReference1D', OutputWorkspace='calib')
+   Transpose(InputWorkspace='calib', OutputWorkspace='calib')
+   fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
+   ax.plot(mtd['calib'],'-')
+   ax.set_xlabel('Pixel #')
+   ax.set_ylabel('Calibration constant')
+   fig.show()
+
+.. figure:: /images/D20_calib.png
+  :align: center
+  :width: 600
+
+D2B Workflow
+------------
+
+.. diagram:: PowderDiffILLDetEffCorr-v1_D2B_wkflw.dot
 
-Output:
+**Example - D2B**
 
 .. code-block:: python
 
-   Reduced workspace contains 3072 constants, one for each cell.
+   import matplotlib.pyplot as plt
+   from mantid import plots
+   from mantid.simpleapi import PowderDiffILLDetEffCorr
+   PowderDiffILLDetEffCorr(CalibrationRun='532008,532009', DerivationMethod='GlobalSummedReference2D', OutputWorkspace='calib')
+   fig, ax = plt.subplots(subplot_kw={'projection':'mantid'})
+   c = ax.pcolormesh(mtd['calib'], vmin=0.8, vmax=1.2)
+   ax.set_xlabel('Tube #')
+   ax.set_ylabel('Pixel #')
+   cbar = fig.colorbar(c)
+   cbar.set_label('Calibration constant')
+   fig.show()
+
+.. figure:: /images/D2B_calib.png
+  :align: center
+  :width: 600
+
+Related Algorithms
+------------------
+
+:ref:`PowderDiffILLReduction <algm-PowderDiffILLReduction>` performs the data reduction.
+:ref:`PowderDiffILLDetScanReduction <algm-PowderDiffILLDetScanReduction>` performs the data reduction for detector scans.
 
 .. categories::
 
diff --git a/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst b/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst
index 3012609bb5c4617cb351d3690e3950f38d258788..78114e0436400435861d458811c9c24a6de5b180 100644
--- a/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst
+++ b/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -85,7 +85,7 @@ Output:
 
 .. testoutput:: ExPowderDiffDetScanILLReduction
 
-    '2DTubes' output workspace has 128 diffractograms having 3250 bins each
+    '2DTubes' output workspace has 128 diffractograms having 3025 bins each
     '2D' output workspace has 128 diffractograms having 3025 bins each
     '1D' output workspace has 1 diffractograms having 3025 bins each
 
diff --git a/docs/source/algorithms/PowderDiffILLReduction-v1.rst b/docs/source/algorithms/PowderDiffILLReduction-v1.rst
index e176f63b647db61eaddc81d5c8fdd8df5f16a816..0aa17c738a05214690b6c58ab2f5dc5d86c82d2f 100644
--- a/docs/source/algorithms/PowderDiffILLReduction-v1.rst
+++ b/docs/source/algorithms/PowderDiffILLReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Power-v1.rst b/docs/source/algorithms/Power-v1.rst
index e265fc3f8be84a8347d048d6d91784d4703139f2..a5e2355783b9c3eb195ba61545c5d07ea9ce6efd 100644
--- a/docs/source/algorithms/Power-v1.rst
+++ b/docs/source/algorithms/Power-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PowerLawCorrection-v1.rst b/docs/source/algorithms/PowerLawCorrection-v1.rst
index 2c0a331cae57f8b3d6ed481d3a557c0957ad97be..2c6b4295d7825d2e7ba0529ee65072152a5d7119 100644
--- a/docs/source/algorithms/PowerLawCorrection-v1.rst
+++ b/docs/source/algorithms/PowerLawCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PowerMD-v1.rst b/docs/source/algorithms/PowerMD-v1.rst
index d9c9235dab872c6412438aa3433df5713be6ff41..cd3de950833ac5c9ae31aaeea911c9883bd0f7df 100644
--- a/docs/source/algorithms/PowerMD-v1.rst
+++ b/docs/source/algorithms/PowerMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PredictFractionalPeaks-v1.rst b/docs/source/algorithms/PredictFractionalPeaks-v1.rst
index 17cfee191374187b73d37f6e92888fdb09b5894a..665c80a9dd9f98bb2a023d894c25b77d3a9ea370 100644
--- a/docs/source/algorithms/PredictFractionalPeaks-v1.rst
+++ b/docs/source/algorithms/PredictFractionalPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PredictPeaks-v1.rst b/docs/source/algorithms/PredictPeaks-v1.rst
index e75114f7be9ce3133f7732344ecab1c23f43678b..e49f377c0b0048fa76cc52e59343ef6fb90f66d9 100644
--- a/docs/source/algorithms/PredictPeaks-v1.rst
+++ b/docs/source/algorithms/PredictPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst
index c33bc2138e4d7ce9464757784e578c24630af3e1..d1827a3046c21205f532febdb7cd5969b0ef233b 100644
--- a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst
+++ b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ProcessBackground-v1.rst b/docs/source/algorithms/ProcessBackground-v1.rst
index fbaa512aa399c9a5f6b063c2f8d5eafbd1a3e116..3a9dfe1486cdb747446a2a001d23744357841de5 100644
--- a/docs/source/algorithms/ProcessBackground-v1.rst
+++ b/docs/source/algorithms/ProcessBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst b/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst
index 9dac5faff4735b488d47d2c595be99d79141a514..3b6dae49d1a00170f593bc9495f43764286fd652 100644
--- a/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst
+++ b/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ProjectMD-v1.rst b/docs/source/algorithms/ProjectMD-v1.rst
index 81ca4aadbbca0d041832f738bd262a001359989f..926a93f09d8e0da81f42222ab8b02c53beeb5a35 100644
--- a/docs/source/algorithms/ProjectMD-v1.rst
+++ b/docs/source/algorithms/ProjectMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Q1D-v2.rst b/docs/source/algorithms/Q1D-v2.rst
index 58211b2be981940a13afbccc5a7cbe9441093831..758cfa7e89f58f7d1e447d2b318752840064eb83 100644
--- a/docs/source/algorithms/Q1D-v2.rst
+++ b/docs/source/algorithms/Q1D-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Q1DWeighted-v1.rst b/docs/source/algorithms/Q1DWeighted-v1.rst
index dc9a32533cbed0a43ab5372c2c46d3ed2d61cd76..a378348812a801a47c0880eb246d50fd3fa95b4d 100644
--- a/docs/source/algorithms/Q1DWeighted-v1.rst
+++ b/docs/source/algorithms/Q1DWeighted-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryAllRemoteJobs-v1.rst b/docs/source/algorithms/QueryAllRemoteJobs-v1.rst
index cd0d0d952d010bf4e7ea4a6a8e78c8ae43e17926..e5fbcdff86d2c81f0f7a447d1a6ffb222cc67f40 100644
--- a/docs/source/algorithms/QueryAllRemoteJobs-v1.rst
+++ b/docs/source/algorithms/QueryAllRemoteJobs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryAllRemoteJobs-v2.rst b/docs/source/algorithms/QueryAllRemoteJobs-v2.rst
index 2f8f0e272da67c5c367d92ff395e85c092a3f2a8..927d6d70c5418c4869583cd70676fc3730e661a1 100644
--- a/docs/source/algorithms/QueryAllRemoteJobs-v2.rst
+++ b/docs/source/algorithms/QueryAllRemoteJobs-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryMDWorkspace-v1.rst b/docs/source/algorithms/QueryMDWorkspace-v1.rst
index a7e8b512695ea3707eda3645cad4aee03cf63079..5f44c2e97ae5778fa7b2d9f4acb2f776702b083a 100644
--- a/docs/source/algorithms/QueryMDWorkspace-v1.rst
+++ b/docs/source/algorithms/QueryMDWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryRemoteFile-v1.rst b/docs/source/algorithms/QueryRemoteFile-v1.rst
index 91c5b712556f01ceac9e4734a98af0e7b1f7ba7e..4c53fe1220510f384334d8e1f1cdd4aa77e42e39 100644
--- a/docs/source/algorithms/QueryRemoteFile-v1.rst
+++ b/docs/source/algorithms/QueryRemoteFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryRemoteFile-v2.rst b/docs/source/algorithms/QueryRemoteFile-v2.rst
index 41764288088b944962e46a178fcd4db77214b487..67173a6687cfeb45d978029bec1d9252573213be 100644
--- a/docs/source/algorithms/QueryRemoteFile-v2.rst
+++ b/docs/source/algorithms/QueryRemoteFile-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryRemoteJob-v1.rst b/docs/source/algorithms/QueryRemoteJob-v1.rst
index b8d7c1be07c403c3c6f4c8ea61b6179b6de8ceda..44f6aa6fd59452b1cd874682488fd908b4218e4a 100644
--- a/docs/source/algorithms/QueryRemoteJob-v1.rst
+++ b/docs/source/algorithms/QueryRemoteJob-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/QueryRemoteJob-v2.rst b/docs/source/algorithms/QueryRemoteJob-v2.rst
index 8f017f8c4a23713c51f8e6e14541f1ed7c791cd3..f52dac82412591eca1ff142c2d1ad7ea8bb2cbfb 100644
--- a/docs/source/algorithms/QueryRemoteJob-v2.rst
+++ b/docs/source/algorithms/QueryRemoteJob-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Qxy-v1.rst b/docs/source/algorithms/Qxy-v1.rst
index 7a191f7970c4ba8532c049e839b82c8b1252de83..378fff955ddc5c7cae8401b905c3a1558c8d81fb 100644
--- a/docs/source/algorithms/Qxy-v1.rst
+++ b/docs/source/algorithms/Qxy-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/REFLReprocess-v1.rst b/docs/source/algorithms/REFLReprocess-v1.rst
deleted file mode 100644
index 3862660e27418e3f17329aa6509e6e5da795d639..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/REFLReprocess-v1.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-Re-reduce REFL data for an entire experiment using saved parameters
-
-.. categories::
-
-.. sourcelink::
diff --git a/docs/source/algorithms/RRFMuon-v1.rst b/docs/source/algorithms/RRFMuon-v1.rst
index be04df98f4f03dc0ce66a070f6dd4357a7bad4da..1ad5d6074e5cffeb9d7b617664538d40d8813dfc 100644
--- a/docs/source/algorithms/RRFMuon-v1.rst
+++ b/docs/source/algorithms/RRFMuon-v1.rst
@@ -14,7 +14,7 @@ This algorithm is frequently run after making a phase quadrature transformation
 article by T.M. Riseman and J.H. Brewer [Hyp. Int., 65, (1990), 1107].
 
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RadiusSum-v1.rst b/docs/source/algorithms/RadiusSum-v1.rst
index 36b1513aa96dae57be3cfa04bb2f9291e1c69eea..9242f12d3d3c5584daec19316f9eb0278878e51b 100644
--- a/docs/source/algorithms/RadiusSum-v1.rst
+++ b/docs/source/algorithms/RadiusSum-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RawFileInfo-v1.rst b/docs/source/algorithms/RawFileInfo-v1.rst
index 48166101012aa1df5a191f1f4a24db585fe1c643..1d9a6904b32553d66d3b779e83b61d518f23a767 100644
--- a/docs/source/algorithms/RawFileInfo-v1.rst
+++ b/docs/source/algorithms/RawFileInfo-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RayTracerTester-v1.rst b/docs/source/algorithms/RayTracerTester-v1.rst
index 251ee405ed56d618367a25d0f2caaa1036cba587..9e3bbdcdb92b3133e795447a8384e7df8e606d1d 100644
--- a/docs/source/algorithms/RayTracerTester-v1.rst
+++ b/docs/source/algorithms/RayTracerTester-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ReactorSANSResolution-v1.rst b/docs/source/algorithms/ReactorSANSResolution-v1.rst
index d8e589d65dbe3125bd813c4fe594f77ad6e2ecd6..905752dda9f867080ef0ea58efdeaf3c59d8824d 100644
--- a/docs/source/algorithms/ReactorSANSResolution-v1.rst
+++ b/docs/source/algorithms/ReactorSANSResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ReadGroupsFromFile-v1.rst b/docs/source/algorithms/ReadGroupsFromFile-v1.rst
index ed1bf892686434b51b4bfe3d21f2ec907a0e9c21..1b67b1337acd1c1c36d3798c82fb9583892d5f6a 100644
--- a/docs/source/algorithms/ReadGroupsFromFile-v1.rst
+++ b/docs/source/algorithms/ReadGroupsFromFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RealFFT-v1.rst b/docs/source/algorithms/RealFFT-v1.rst
index f0da140e26ff8103e05294bd0dbca6ebb83d0c8c..65b63330ddc9784079b832a36bf754a077be142f 100644
--- a/docs/source/algorithms/RealFFT-v1.rst
+++ b/docs/source/algorithms/RealFFT-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Rebin-v1.rst b/docs/source/algorithms/Rebin-v1.rst
index 593accdcd915f07846aeb10ed543e60e5c786b4c..1da69119acfdeb25ff8b5ff0bb88a2e912f6b0fb 100644
--- a/docs/source/algorithms/Rebin-v1.rst
+++ b/docs/source/algorithms/Rebin-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -14,11 +14,11 @@ defines new boundaries in intervals :math:`x_i-x_{i+1}\,`. Positive
 :math:`\Delta x_i\,` make constant width bins, whilst negative ones
 create logarithmic binning using the formula
 :math:`x(j+1)=x(j)(1+|\Delta x_i|)\,`
-
+ 
 This algorithms is useful both in data reduction, but also in remapping
 :ref:`ragged workspace <Ragged_Workspace>` to a regular set of bin
 boundaries.
-
+ 
 Unless the FullBinsOnly option is enabled, the bin immediately before
 the specified boundaries :math:`x_2`, :math:`x_3`, ... :math:`x_i` is
 likely to have a different width from its neighbours because there can
@@ -136,7 +136,7 @@ Output:
    The 2nd and 3rd rebinned X values are: [ 1.5   2.25]
 
 **Example - custom two regions rebinning:**
-
+ 
 .. testcode:: ExHistCustom
 
    # create histogram workspace
diff --git a/docs/source/algorithms/Rebin2D-v1.rst b/docs/source/algorithms/Rebin2D-v1.rst
index d9efd20d2ac63482ece4e919113ffa384152e62f..dda2cdb3205dd0beb75d97adf3cdb69925504170 100644
--- a/docs/source/algorithms/Rebin2D-v1.rst
+++ b/docs/source/algorithms/Rebin2D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RebinByPulseTimes-v1.rst b/docs/source/algorithms/RebinByPulseTimes-v1.rst
index 827d09ab25d198a0385bd9d971e0c65b899e54e0..7ace4e765283fcbcf6b6fc0a181f69027ddb481a 100644
--- a/docs/source/algorithms/RebinByPulseTimes-v1.rst
+++ b/docs/source/algorithms/RebinByPulseTimes-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RebinByTimeAtSample-v1.rst b/docs/source/algorithms/RebinByTimeAtSample-v1.rst
index 166f073353ab8224ace2c198eba9e573f545847c..e01c41d77981870eaba1d318542bed58e0fc9ae1 100644
--- a/docs/source/algorithms/RebinByTimeAtSample-v1.rst
+++ b/docs/source/algorithms/RebinByTimeAtSample-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RebinToWorkspace-v1.rst b/docs/source/algorithms/RebinToWorkspace-v1.rst
index 400aa5a5559d1f5c42a355fa468427044249d35b..fd20ffff3a8728e8cf12bb58960b6f72979d46b1 100644
--- a/docs/source/algorithms/RebinToWorkspace-v1.rst
+++ b/docs/source/algorithms/RebinToWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -13,7 +13,7 @@ Takes an input workspace and alters the binning so that all it's spectra
 match that of the **first spectrum** of the second workspace. This
 algorithm simply builds a parameter list that is passed to the
 :ref:`algm-Rebin` algorithm, which actually does the work.
-
+ 
 .. categories::
 
 .. sourcelink::
diff --git a/docs/source/algorithms/Rebunch-v1.rst b/docs/source/algorithms/Rebunch-v1.rst
index 6113649edc2e18379ee758b254e3a2736fd0531a..87dc9446d42e4aacc64a4e23e4f244f06d5ce9e5 100644
--- a/docs/source/algorithms/Rebunch-v1.rst
+++ b/docs/source/algorithms/Rebunch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RecordPythonScript-v1.rst b/docs/source/algorithms/RecordPythonScript-v1.rst
index b4b3c921b02d5b890f973b5c4f57b06e21d21a23..b095e41acf56b9ffbe3e963c7b8865732d9bc1e8 100644
--- a/docs/source/algorithms/RecordPythonScript-v1.rst
+++ b/docs/source/algorithms/RecordPythonScript-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RefLReduction-v1.rst b/docs/source/algorithms/RefLReduction-v1.rst
deleted file mode 100644
index 9a878fdd9b1fe048f9bf82dc3652f0f5d57f34a2..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/RefLReduction-v1.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-Liquids Reflectometer (REFL) reduction
-
-.. categories::
-
-.. sourcelink::
diff --git a/docs/source/algorithms/RefReduction-v1.rst b/docs/source/algorithms/RefReduction-v1.rst
deleted file mode 100644
index 80dc19fc12e561f50c24dc3167dca157c1721745..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/RefReduction-v1.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-Reflectivity reduction workflow. This workflow algorithm computes the
-specular and off-specular reflectivity for both REFM and REFL
-instruments.
-
-.. categories::
-
-.. sourcelink::
diff --git a/docs/source/algorithms/RefRoi-v1.rst b/docs/source/algorithms/RefRoi-v1.rst
index 857c87654c0c654c7be88e6ab2e5f30a16608888..d5d607ffefa86da266ad296e44a59b424aa223b7 100644
--- a/docs/source/algorithms/RefRoi-v1.rst
+++ b/docs/source/algorithms/RefRoi-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst b/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst
index 187da08e14329ba1d184fdcf33b9b60cdda28cd7..a296eb204bac65b65d86b24b2ce3f3244712cb91 100644
--- a/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst
+++ b/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst b/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst
index dabb9a3335045d2417880a298ba8780e801e4bce..db10e6fa19aed7c023e26adeb9bd0f5b3420ea23 100644
--- a/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst
+++ b/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -19,7 +19,7 @@ FitPowderDiffPeaks().
 
 
 Introduction
-============
+############
 
 In order to do Rietveld refinement to experimental data, the diffractometer’s profile should be calibrated by the standards, such as LaB6 or Ni, 
 with known crystal structure and lattice parameters.  
@@ -45,8 +45,8 @@ Final Time-of-flight is calculated as:
 
 .. math:: TOF = n_{cross} TOF_e + (1-n_{cross}) TOF_t
 
-Formular for calculating :math:`A(d)`, :math:`B(d)`, :math:`\sigma(d)` and :math:`\gamma(d)`
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Formula for calculating :math:`A(d)`, :math:`B(d)`, :math:`\sigma(d)` and :math:`\gamma(d)`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 :math:`\alpha(d)`:
 
@@ -104,7 +104,7 @@ where
 
 
 Break down the problem
-======================
+######################
 
 If we can do the single peak fitting on each single diffraction peak in a certain range, 
 then we can divide the optimization problem into 4 sub problems for :math:`X_0`, :math:`A`,
@@ -136,13 +136,13 @@ with constraint:
 The coefficients in this function are strongly correlated to each other.
 
 Current Implementation
-======================
+######################
 
 Only the parameters of the function for :math:`X_0` are fitted in 
 present implementation. 
 
 Refinement Algorithm
-====================
+####################
 
 Two refinement algorithms, DirectFit and MonteCarlo, are provided.
 
@@ -171,7 +171,7 @@ In future, constaint will be considered.
 
 
 How to use algorithm with other algorithms
-==========================================
+##########################################
 
 This algorithm is designed to work with other algorithms to do Le Bail
 fit. The introduction can be found in the wiki page of
diff --git a/docs/source/algorithms/ReflectometryMomentumTransfer-v1.rst b/docs/source/algorithms/ReflectometryMomentumTransfer-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ff7d1f6cc57a6e1a3f45926967c3bb872e7d1f21
--- /dev/null
+++ b/docs/source/algorithms/ReflectometryMomentumTransfer-v1.rst
@@ -0,0 +1,117 @@
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm converts a reflectivity workspace from wavelength to momentum transfer :math:`Q_{z}` and calculates the :math:`Q_{z}` resolution. The resolution is added as the Dx (X Errors) field in the output workspace.
+
+The two additional input workspaces, *ReflectedBeamWorkspace* and *DirectBeamWorkspace* are the raw reflected and direct beam workspaces before foreground summation. They are needed for the resolution calculation.
+
+The instruments of all three input workspaces are expected contain two components representing the two slits in the beam before the sample. The names of these components are given to the algorithm as the *Slit1Name* and *Slit2Name* properties. The slit openings (width or height depending on reflectometer setup) should be written in the sample logs (units 'm' or 'mm'). The log enties are named by *Slit1SizeSampleLog* and *Slit2SizeSampleLog*.
+
+The *Polarized* property should be used to indicate whether *InputWorkspace* is part of a polarization analysis dataset.
+
+The *SummationType* property reflects the type of foreground summation used to obtain the reflectivity workspace.
+
+Conversion to momentum transfer
+###############################
+
+The unit conversion from wavelength to :math:`Q_{z}` is done by :ref:`ConvertUnits <algm-ConvertUnits>`.
+
+:math:`Q_{z}` resolution
+########################
+
+The resolution calculation follows the procedure described in [#Gutfreund]_.
+
+Usage
+-----
+
+.. include:: ../usagedata-note.txt
+
+**Example - ReflectometryMomentumTransfer**
+
+.. testcode:: ReflectometryMomentumTransferExample
+
+   # Load data.
+   reflectedWS = LoadILLReflectometry('ILL/D17/317370.nxs', XUnit='TimeOfFlight')
+   ConvertToDistribution(reflectedWS)
+   directWS = LoadILLReflectometry('ILL/D17/317369.nxs', XUnit='TimeOfFlight')
+   ConvertToDistribution(directWS)
+
+   # Extract some instrument parameters.
+   chopperPairDistance = 1e-2 * reflectedWS.run().getProperty('Distance.ChopperGap').value
+   chopperSpeed = reflectedWS.run().getProperty('VirtualChopper.chopper1_speed_average').value
+   chopper1Phase = reflectedWS.run().getProperty('VirtualChopper.chopper1_phase_average').value
+   chopper2Phase = reflectedWS.run().getProperty('VirtualChopper.chopper2_phase_average').value
+   openoffset = reflectedWS.run().getProperty('VirtualChopper.open_offset').value
+
+   # Normalize to time.
+   duration = reflectedWS.run().getProperty('duration').value
+   reflectedWS /= duration
+   duration = directWS.run().getProperty('duration').value
+   directWS /= duration
+
+   # Calculate reflectivity.
+   refForeground = SumSpectra(reflectedWS, 198, 209)
+   dirForeground = SumSpectra(directWS, 190, 210)
+   refForeground = RebinToWorkspace(WorkspaceToRebin=refForeground, WorkspaceToMatch=dirForeground)
+   R = refForeground / dirForeground
+
+   # Convert TOF to wavelength, crop.
+   R = ConvertUnits(R, 'Wavelength')
+   R = CropWorkspace(R, XMin=4.3, XMax=14.0, StoreInADS=False)
+   n = reflectedWS.getNumberHistograms()
+   reflectedWS = ConvertUnits(reflectedWS, 'Wavelength')
+   reflectedWS = CropWorkspaceRagged(reflectedWS, XMin=n*[4.3], XMax=n*[14.0], StoreInADS=False)
+   directWS = ConvertUnits(directWS, 'Wavelength')
+   directWS = CropWorkspaceRagged(directWS, XMin=n*[4.3], XMax=n*[14.0])
+
+   outws = ReflectometryMomentumTransfer(
+       R,
+       reflectedWS,
+       directWS,
+       ReflectedForeground=[198, 209],
+       DirectForeground=[190, 210],
+       SummationType='SumInLambda',
+       Polarized=False,
+       PixelSize=0.001195,
+       DetectorResolution=0.0022,
+       ChopperRadius=0.36,
+       ChopperSpeed=chopperSpeed,
+       ChopperOpening=45. - (chopper2Phase - chopper1Phase) - openoffset,
+       ChopperPairDistance=chopperPairDistance,
+       Slit1Name='slit2',
+       Slit1SizeSampleLog='VirtualSlitAxis.s2w_actual_width',
+       Slit2Name='slit3',
+       Slit2SizeSampleLog='VirtualSlitAxis.s3w_actual_width',
+       TOFChannelWidth=57.
+   )
+
+   qs = outws.readX(0)
+   dqs = outws.readDx(0)
+   print('First refectivity point Qz = {:.4f} +- {:.4f} A-1'.format(qs[0], dqs[0]))
+   print('and last Qz = {:.4f} +- {:.4f} A-1'.format(qs[-1], dqs[-1]))
+
+Output:
+
+.. testoutput:: ReflectometryMomentumTransferExample
+
+   First refectivity point Qz = 0.0118 +- 0.0001 A-1
+   and last Qz = 0.0381 +- 0.0005 A-1
+
+References
+----------
+
+.. [#Gutfreund] P. Gutfreund, T. Saerbeck, M. A. Gonzalez, E. Pellegrini, M. Laver, C. Dewhurst, R. Cubitt,
+             `arXiv:1710.04139  <https://arxiv.org/abs/1710.04139>`_ **\[physics.ins-det\]**
+
+.. categories::
+
+.. sourcelink::
+
diff --git a/docs/source/algorithms/ReflectometryReductionOne-v1.rst b/docs/source/algorithms/ReflectometryReductionOne-v1.rst
deleted file mode 100644
index a39a841536b2974ca73aa2ee1859678d6339f721..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/ReflectometryReductionOne-v1.rst
+++ /dev/null
@@ -1,248 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-Reduces a single TOF reflectometry run into a mod Q vs I/I0 workspace.
-Performs transmission corrections. Handles both point detector and
-multidetector cases. The algorithm can correct detector locations based
-on an input theta value.
-
-Historically the work performed by this algorithm was known as the Quick
-script.
-
-If :literal:`MonitorBackgroundWavelengthMin` and
-:literal:`MonitorBackgroundWavelengthMax` are both set to :literal:`0`, then
-background normalization will not be performed on the monitors.
-
-The properties of this algorithm should be manually selected by the user. If you
-wish to use the default values (found in the Instrument Defintion File) for the
-properties of this algorithm, you may want to consider using
-:ref:`algm-ReflectometryReductionOneAuto`.
-
-:ref:`algm-ReflectometryReductionOneAuto` also performs extra processing steps
-such as Background subtraction and :ref:`algm-PolarizationCorrection`. If you
-want to know how these processing steps are used, please refer to the
-:ref:`algm-ReflectometryReductionOneAuto` documentation.
-
-High-Level Workflow
--------------------
-
-The diagram below displays a high-level version of the algorithm workflow,
-illustrating the main steps taking place in the ReflectometryReductionOne
-algorithm. These individual steps are described in more detail in the next
-sections.
-
-.. diagram:: ReflectometryReductionOne_HighLvl-v1_wkflw.dot
-
-Low-Level Workflow
-------------------
-
-Conversion to Wavelength
-########################
-
-The following diagram describes the steps taken in converting the input
-workspace into units of wavelength and dividing its constituent detectors by
-monitors.
-
-.. diagram:: ReflectometryReductionOne_ConvertToWavelength-v1_wkflw.dot
-
-The default analysis mode is *PointDetectorAnalysis*. For PointAnalysisMode the
-analysis can be roughly reduced to IvsLam = DetectorWS / sum(I0) /
-TransmissionWS / sum(I0). For MultiDetectorAnalysis the analysis can be roughly
-reduced to IvsLam = DetectorWS / RegionOfDirectBeamWS / sum(I0) / TransmissionWS
-/ sum(I0).
-
-Transmission Correction
-#######################
-
-This diagram shows how the resultant workspace of the previous step is corrected
-by either by provided transmission runs or by a specific correction algorithm.
-
-.. diagram:: ReflectometryReductionOne_TransmissionCorrection-v1_wkflw.dot
-
-Transmission correction is a normalization step, which may be applied to both
-*PointDetectorAnalysis* and *MultiDetectorAnalysis* reduction.
-
-Transmission runs are expected to be in TOF. The spectra numbers in the
-Transmission run workspaces must be the same as those in the Input Run
-workspace. If two Transmission runs are provided then the Stitching
-parameters associated with the transmission runs will also be required.
-If a single Transmission run is provided, then no stitching parameters
-will be needed.
-
-The normalization by tranmission run(s) is optional.
-
-The input workspace provided to the workflow in this instance is the original
-:literal:`InputWorkspace` after conversion to wavelength and normalization by
-monitors, as shown in the previous :literal:`Conversion To Wavelength` diagram.
-
-The output workspace given is not the output to the whole algorithm. Rather it
-will serve as the input workspace to the :literal:`Polynomial Correction`
-workflow, where further steps will be applied to it.
-
-Polynomial Correction
-=====================
-
-If no Transmission runs are provided, then polynomial correction can be
-performed instead. Polynomial correction is enabled by setting the
-:literal:`CorrectionAlgorithm` property. If set to
-:literal:`PolynomialCorrection` it runs the :ref:`algm-PolynomialCorrection`
-algorithm, with this algorithms :literal:`Polynomial` property used as its
-:literal:`Coefficients` property.
-
-If the :literal:`CorrectionAlgorithm` property is set to
-:literal:`ExponentialCorrection`, then the :Ref:`algm-ExponentialCorrection`
-algorithm is used, with C0 and C1 taken from the :literal:`C0` and :literal:`C1`
-properties.
-
-Detector Position Correction
-############################
-
-The diagram below describes how the input workspace is then corrected by
-detector positions after transmission correction.
-
-.. diagram:: ReflectometryReductionOne_CorrectDetectorPositions-v1_wkflw.dot
-
-Detector Position Correction is used for when the position of the detector
-is not aligned with the reflected beamline. The correction algorithm used is
-:ref:`algm-SpecularReflectionPositionCorrect-v1` which is a purely vertical
-position correction.
-
-The detector positions in this process are corrected in terms of
-:literal:`ThetaIn`. In general, the detector posistions should always be
-corrected unless the :literal:`InputWorkspace` already has the detectors in the
-right positions. This can be achieved by running
-:literal:`MoveInstrumentComponent` before :literal:`ReflectometryReductionOne`.
-
-Convert To Momentum Transfer (Q)
-################################
-
-The last diagram describes the steps involved in converting the input workspace
-from units of wavelength into momentum transfer (Q).
-
-.. diagram:: ReflectometryReductionOne_ConvertToMomentum-v1_wkflw.dot
-
-ReflectometryReductionOne contains 2 post-processing options that will be
-applied to the IvsQ workspace. These two options are `Rebin` and `Scale`.
-
-Rebinning
-=========
-
-To Rebin your IvsQ workspace you will have to provide values for the following
-properties: `MomentumTransferMinimum`, `MomentumTransferStep` and
-`MomentumTransferMaximum`. These values will be appended to each other to form
-your :ref:`algm-Rebin` Params. These values correspond to your `MinimumExtent`,
-`BinWidth` and `MaximumExtent` respectively.
-
-If you provide a positive `MomentumTransferStep` value then the algorithm will
-automatically negate this value which will allow for Logarithmic Rebinning.
-Alternatively, a negative `MomentumTransferStep` will result in Linear
-Rebinning. More details about the Rebinning process can be found in the
-documentation for :ref:`algm-Rebin`.
-
-If no values are provided for `MomentumTransferMinimum` and
-`MomentumTransferMaximum` then the algorithm will attempt to calculate these
-values by using the equations below:
-
-    :math:`Q_{min} = 2 \, k \, sin \, \theta = \frac{4 \pi sin \theta}{\lambda_{max}}`
-
-    :math:`Q_{max} = 2 \, k \, sin \, \theta = \frac{4 \pi sin \theta}{\lambda_{min}}`
-
-Where :math:`\lambda_{min}` is the minimum extent of the `IvsLambda` Workspace
-and :math:`\lambda_{max}` is the maximum extent of the `IvsLambda` Workspace.
-
-If you have not provided a value for `MomentumTransferStep` then the algorithm
-will use :ref:`algm-NRCalculateSlitResolution` to calculate this value for you.
-
-Scaling
-=======
-
-To apply a scaling to the IvsQ workspace that has been produced by the
-reduction, you will need to provide a value for the `ScaleFactor` property in
-the algorithm. The default for this value is 1.0 and thus no scaling is applied
-to the workspace. The scaling of the IvsQ workspace is performed in-place by the
-:ref:`algm-Scale` algorithm and your IvsQ workspace will be set to the product
-of this algorithm.
-
-Source Rotation
-===============
-
-In the workflow diagram above, after we produce the IvsLambda workspace, it may
-be necessary to rotate the position of the source to match the value of
-ThetaOut (:math:`\theta_f`).
-
-Below we see the typical experimental setup for a Reflectometry instrument. The
-source direction (Beam vector) is along the horizon. This setup is defined in
-the Instrument Defintion File and this instrument setup will be attached to any
-workspaces associated with that instrument. When we pass the IvsLambda workspace
-to :ref:`algm-ConvertUnits` to produce an IvsQ workspace,
-:ref:`algm-ConvertUnits` will assume that :math:`2\theta` is the angle between
-the Beam vector and the sample-to-detector vector. When we have the typical
-setup seen below, :math:`2\theta` will be exactly half the value we wish it to
-be.
-
-.. figure:: /images/CurrentExperimentSetupForReflectometry.png
-    :width: 650px
-    :height: 250px
-    :align: center
-
-We rotate the position of the Source (and therefore the Beam vector) in the
-Instrument Defintion associated with the IvsLambda workspace until the condition
-:math:`\theta_i = \theta_f` is satisfied. This will achieve the desired result
-for :math:`2\theta` (see below for rotated source diagram). After
-:ref:`algm-ConvertUnits` has produced our IvsQ workspace, we will rotate the
-position of the source back to its original position so that the experimental
-setup remains unchanged for other algorithms that may need to manipulate/use it.
-
-.. figure:: /images/RotatedExperimentSetupForReflectometry.png
-    :width: 650px
-    :height: 250px
-    :align: center
-
-
-Processing Instructions
-#######################
-
-These enable a grouping pattern on workspace indices to yield only the detectors of interest. It allows usage of the operators :literal:`,:+-` to specify or exclude specific indices or to add
-spectra together. See :literal:`Grouping Pattern` from :Ref:`algm-GroupDetectors` for further details on their usage.
-
-Usage
------
-
-**Example - Reduce a Run**
-
-.. testcode:: ExReflRedOneSimple
-
-   run = Load(Filename='INTER00013460.nxs')
-   # Basic reduction with no transmission run
-   IvsQ, IvsLam, thetaOut = ReflectometryReductionOne(InputWorkspace=run, ThetaIn=0.7, I0MonitorIndex=2, ProcessingInstructions='3:4',
-   WavelengthMin=1.0, WavelengthMax=17.0,
-   MonitorBackgroundWavelengthMin=15.0, MonitorBackgroundWavelengthMax=17.0,
-   MonitorIntegrationWavelengthMin=4.0, MonitorIntegrationWavelengthMax=10.0, Version=1)
-
-   print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-	  IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3]))
-   print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-          IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3]))
-   print("Theta out is the same as theta in: {}".format(thetaOut))
-
-
-Output:
-
-.. testoutput:: ExReflRedOneSimple
-
-   The first four IvsLam Y values are: [ 0.0000e+00, 0.0000e+00, 7.8118e-07, 1.9346e-06 ]
-   The first four IvsQ Y values are: [ 1.3845e-03, 1.9717e-03, 2.7579e-03, 4.1467e-03 ]
-   Theta out is the same as theta in: 0.7
-
-
-.. categories::
-
-.. sourcelink::
diff --git a/docs/source/algorithms/ReflectometryReductionOne-v2.rst b/docs/source/algorithms/ReflectometryReductionOne-v2.rst
index aa317703b2667e5494131d063a3da99d72b4cee5..fe6b4df8b6b40b36b7d15060df9f2c6a27ab2142 100644
--- a/docs/source/algorithms/ReflectometryReductionOne-v2.rst
+++ b/docs/source/algorithms/ReflectometryReductionOne-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -254,10 +254,10 @@ Output:
 
 .. testoutput:: ExReflRedOneTrans
 
-   0.4592
+   0.4597
    0.4654
-   0.7278
-   1.0305
+   0.7203
+   1.0512
 
 .. categories::
 
diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst
deleted file mode 100644
index de816114e3f2feb392fa4ff9da17df161f9764eb..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst
+++ /dev/null
@@ -1,166 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-Facade over :ref:`algm-ReflectometryReductionOne`.
-
-Pulls numeric parameters out of the instrument parameters where possible. You can override any of these automatically applied defaults by providing your own value for the input.
-
-See :ref:`algm-ReflectometryReductionOne` for more information on the wrapped algorithm.
-
-ProcessingInstructions
-######################
-
-If ProcessingInstructions is not set its value is inferred from other properties:
-
-* If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart = PointDetectorStop then the spectrum specified by PointDetectorStart is used.
-* If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart ≠ PointDetectorStop then the sum of the spectra from PointDetectorStart to PointDetectorStop is used.
-* If AnalysisMode = MultiDetectorAnalaysis then all of the spectra from MultiDetectorStart onwards are used.
-
-Note, the ProcessingInstructions are workspace indicies, not detector IDs. The first few workspaces may correspond to monitors, rather than detectors of interest.
-For the syntax of this property, see :ref:`algm-GroupDetectors`.
-
-Workflow for WorkspaceGroups
-############################
-
-If a WorkspaceGroup is provided to ReflectometryReductionOneAuto, it will follow the steps shown in the diagram below to produce its output.
-
-.. diagram:: ReflectometryReductionOneAuto-v1-Groups_wkflw.dot
-
-Workflow for Polarization Correction
-####################################
-
-If polarization correction is enabled, it is performed as an additional step once the main processing has completed.
-The following diagram shows how the :ref:`algm-PolarizationCorrection` algorithm is used.
-
-.. diagram:: ReflectometryReductionOneAuto-v1-PolarizationCorrection_wkflw.dot
-
-Polynomial Correction
-#####################
-
-If no Transmission runs are provided, then polynomial correction can be
-performed instead. Polynomial correction is enabled by setting the
-:literal:`CorrectionAlgorithm` property.
-
-If set to :literal:`AutoDetect`, it looks at the instrument
-parameters for the :literal:`correction` parameter. If it is set to
-:literal:`polynomial`, then polynomial correction is performed using the
-:ref:`algm-PolynomialCorrection` algorithm, with the polynomial string taken
-from the instrument's :literal:`polynomial` parameter. If the
-:literal:`correction` parameter is set to :literal:`exponential` instead, then
-the :Ref:`algm-ExponentialCorrection` algorithm is used, with C0 and C1 taken
-from the instrument parameters, :literal:`C0` and :literal:`C1`.
-
-These can be specified manually by setting the :literal:`CorrectionAlgorithm`,
-:literal:`Polynomial`, :literal:`C0`, and :literal:`C1` properties accordingly.
-
-Usage
------
-
-**Example - Reduce a Run**
-
-.. testcode:: ExReflRedOneAutoSimple
-
-    run = Load(Filename='INTER00013460.nxs')
-    # Basic reduction with no transmission run
-    IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, Version=1)
-
-    print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-  	   IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3]))
-    print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-	   IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3]))
-    print("Theta out is the same as theta in: {}".format(thetaOut))
-
-Output:
-
-.. testoutput:: ExReflRedOneAutoSimple
-
-    The first four IvsLam Y values are: [ 5.3860e-06, 9.3330e-06, 6.9796e-06, 6.5687e-06 ]
-    The first four IvsQ Y values are: [ 1.3648e-03, 1.9490e-03, 2.7277e-03, 4.0995e-03 ]
-    Theta out is the same as theta in: 0.7
-
-**Example - Reduce a Run with a transmission run**
-
-.. testcode:: ExReflRedOneAutoTrans
-
-    run = Load(Filename='INTER00013460.nxs')
-    trans = Load(Filename='INTER00013463.nxs')
-    # Basic reduction with a transmission run
-    IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, FirstTransmissionRun=trans, ThetaIn=0.7, Version=1)
-
-    print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-  	   IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3]))
-    print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-	   IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3]))
-    print("Theta out is the same as theta in: {}".format(thetaOut))
-
-Output:
-
-.. testoutput:: ExReflRedOneAutoTrans
-
-    The first four IvsLam Y values are: [ 3.2705e-05, 5.5450e-05, 3.9630e-05, 3.5770e-05 ]
-    The first four IvsQ Y values are: [ 9.3930e-01, 1.3251e+00, 1.2766e+00, 1.1977e+00 ]
-    Theta out is the same as theta in: 0.7
-
-**Example - Reduce a Run overloading default parameters**
-
-.. testcode:: ExReflRedOneAutoOverload
-
-    run = Load(Filename='INTER00013460.nxs')
-    # Reduction overriding the default values for MonitorBackgroundWavelengthMin and MonitorBackgroundWavelengthMax which would otherwise be retirieved from the workspace
-    IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, MonitorBackgroundWavelengthMin=0.0, MonitorBackgroundWavelengthMax=1.0, Version=1)
-
-    print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-  	   IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3]))
-    print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format(
-	   IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3]))
-    print("Theta out is the same as theta in: {}".format(thetaOut))
-
-Output:
-
-.. testoutput:: ExReflRedOneAutoOverload
-
-    The first four IvsLam Y values are: [ 5.3868e-06, 9.3344e-06, 6.9807e-06, 6.5696e-06 ]
-    The first four IvsQ Y values are: [ 1.3650e-03, 1.9493e-03, 2.7281e-03, 4.1001e-03 ]
-    Theta out is the same as theta in: 0.7
-
-**Example - Polynomial correction**
-
-.. testcode:: ExReflRedOneAutoPoly
-
-    run = Load(Filename='INTER00013460.nxs')
-    # Set up some paramters, allowing the algorithm to automatically detect the correction to use
-    SetInstrumentParameter(run, "correction", Value="polynomial")
-    SetInstrumentParameter(run, "polynomial", Value="0,0.5,1,2,3")
-
-    IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, Version=1)
-
-    def findByName(histories, name):
-        return next(x for x in histories if x.name() == name)
-
-    # Find the PolynomialCorrection entry in the workspace's history
-    algHist = IvsLam.getHistory()
-    refRedOneAutoHist = findByName(algHist.getAlgorithmHistories(), "ReflectometryReductionOneAuto")
-    refRedOneHist = findByName(refRedOneAutoHist.getChildHistories(), "ReflectometryReductionOne")
-    polyCorHist = findByName(refRedOneHist.getChildHistories(), "PolynomialCorrection")
-
-    coefProp = findByName(polyCorHist.getProperties(), "Coefficients")
-
-    print("Coefficients: '{}'".format(coefProp.value()))
-
-Output:
-
-.. testoutput:: ExReflRedOneAutoPoly
-
-    Coefficients: '0,0.5,1,2,3'
-
-.. categories::
-
-.. sourcelink::
diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst
index 2bb6d64880052340b85f7d877f04c954f744278d..4258f0d63cb608753b0818403fce8e1ca991567d 100644
--- a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst
+++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -43,7 +43,7 @@ The rest of the input properties are not inferred from the parameter file, and m
 property that allows users to specify a region of direct beam that will be used to normalize
 the detector signal. The region of direct beam is specified by workspace indices. For instance, :literal:`RegionOfDirectBeam='2-3'`
 means that spectra with workspace indices :literal:`2` and :literal:`3` will be summed and the resulting
-workspace will be used as the direct beam workspace. 
+workspace will be used as the direct beam workspace.
 
 Transmission corrections can be optionally applied by providing either one or
 two transmission runs or polynomial corrections. Polynomial correction is enabled by setting the
@@ -198,10 +198,10 @@ Output:
 
     0.00441
     0.00462
-    0.64241
-    0.41453
+    0.64231
+    0.41456
     0.51029
-    0.52240
+    0.52241
 
 .. categories::
 
diff --git a/docs/source/algorithms/Regroup-v1.rst b/docs/source/algorithms/Regroup-v1.rst
index 0a3cf86c5396df7c4b80957efdd0e0b093d3549e..daf32889ffcb4f835552c1dba037990f9c9738d7 100644
--- a/docs/source/algorithms/Regroup-v1.rst
+++ b/docs/source/algorithms/Regroup-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveBackground-v1.rst b/docs/source/algorithms/RemoveBackground-v1.rst
index 87dd338d4d989631b31abb37a640ef084cd658c0..219fcc121190caadb6b6abcd0b77dd46d8a58beb 100644
--- a/docs/source/algorithms/RemoveBackground-v1.rst
+++ b/docs/source/algorithms/RemoveBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -215,25 +215,25 @@ Usage
     | x sampl  | x result | S sample | S no bg  | Err samp | Err no_bg|
     |     -20.0|     -20.0|    1.0000|    -0.959|     1.000|     1.008|
     |     -18.0|     -18.0|    2.0000|    -0.101|     1.414|     1.420|
-    |     -16.0|     -16.0|    3.0000|     0.740|     1.732|     1.738|
+    |     -16.0|     -16.0|    4.0000|     1.740|     2.000|     2.005|
     |     -14.0|     -14.0|    1.0000|    -1.441|     1.000|     1.012|
-    |     -12.0|     -12.0|    5.0000|     2.353|     2.236|     2.242|
-    |     -10.0|     -10.0|    2.0000|    -0.885|     1.414|     1.426|
+    |     -12.0|     -12.0|    3.0000|     0.353|     1.732|     1.740|
+    |     -10.0|     -10.0|    3.0000|     0.115|     1.732|     1.742|
     |      -8.0|      -8.0|    5.0000|     1.841|     2.236|     2.245|
-    |      -6.0|      -6.0|    2.0000|    -1.481|     1.414|     1.431|
+    |      -6.0|      -6.0|    4.0000|     0.519|     2.000|     2.012|
     |      -4.0|      -4.0|    4.0000|     0.139|     2.000|     2.015|
     |      -2.0|      -2.0|    3.0000|    -1.315|     1.732|     1.753|
-    |       0.0|       0.0|    6.0000|     1.133|     2.449|     2.469|
+    |       0.0|       0.0|    4.0000|    -0.867|     2.000|     2.024|
     |       2.0|       2.0|    7.0000|     1.454|     2.646|     2.669|
-    |       4.0|       4.0|    5.0000|    -1.400|     2.236|     2.272|
-    |       6.0|       6.0|    7.0000|    -0.499|     2.646|     2.688|
-    |       8.0|       8.0|    9.0000|     0.047|     3.000|     3.053|
+    |       4.0|       4.0|    6.0000|    -0.400|     2.449|     2.483|
+    |       6.0|       6.0|    8.0000|     0.501|     2.828|     2.868|
+    |       8.0|       8.0|    8.0000|    -0.953|     2.828|     2.885|
     |      10.0|      10.0|   11.0000|     0.054|     3.317|     3.388|
-    |      12.0|      12.0|   16.0000|     2.190|     4.000|     4.094|
-    |      14.0|      14.0|   16.0000|    -2.188|     4.000|     4.162|
-    |      16.0|      16.0|   26.0000|     0.490|     5.099|     5.348|
-    |      18.0|      18.0|   39.0000|    -0.581|     6.245|     6.728|
- 
+    |      12.0|      12.0|   13.0000|    -0.810|     3.606|     3.710|
+    |      14.0|      14.0|   20.0000|     1.812|     4.472|     4.618|
+    |      16.0|      16.0|   25.0000|    -0.510|     5.000|     5.254|
+    |      18.0|      18.0|   37.0000|    -2.581|     6.083|     6.578|
+
 .. categories::
 
 .. sourcelink::
diff --git a/docs/source/algorithms/RemoveBins-v1.rst b/docs/source/algorithms/RemoveBins-v1.rst
index ec8d56cea2f4838ec3b07035a7d201e136bf3b2b..4953808f4a3ad6f89b56bf31fa27032b363360c2 100644
--- a/docs/source/algorithms/RemoveBins-v1.rst
+++ b/docs/source/algorithms/RemoveBins-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveExpDecay-v1.rst b/docs/source/algorithms/RemoveExpDecay-v1.rst
index 97985ff7e3a27d8c79c0676470717b224753fbf6..4edaffbf4f45bf1bd6a4d6cc4387e8ceb8a45b43 100644
--- a/docs/source/algorithms/RemoveExpDecay-v1.rst
+++ b/docs/source/algorithms/RemoveExpDecay-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveLogs-v1.rst b/docs/source/algorithms/RemoveLogs-v1.rst
index de038a5308a374a5f19152170e56af453b902470..4944a4e094e55849e413d13d305911cd19dd847d 100644
--- a/docs/source/algorithms/RemoveLogs-v1.rst
+++ b/docs/source/algorithms/RemoveLogs-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveLowResTOF-v1.rst b/docs/source/algorithms/RemoveLowResTOF-v1.rst
index 9b4d0bdaafe5b0dccdb55dd878b53340d74b6f73..34a1c2c83c21000025d814bd65a2f95ef0940d65 100644
--- a/docs/source/algorithms/RemoveLowResTOF-v1.rst
+++ b/docs/source/algorithms/RemoveLowResTOF-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveMaskedSpectra-v1.rst b/docs/source/algorithms/RemoveMaskedSpectra-v1.rst
index eae7f4c961ca3ad2b743ec7a7d32310dbcb1dd9c..cb92f814c2db35077e4fc1631f241b5d029fcc99 100644
--- a/docs/source/algorithms/RemoveMaskedSpectra-v1.rst
+++ b/docs/source/algorithms/RemoveMaskedSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemovePromptPulse-v1.rst b/docs/source/algorithms/RemovePromptPulse-v1.rst
index 8f41765299f5d1051d215c37f6da139af32b0be2..172346cc8a6578fb4abadcabfb8fdae7108fa62d 100644
--- a/docs/source/algorithms/RemovePromptPulse-v1.rst
+++ b/docs/source/algorithms/RemovePromptPulse-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst
index 0c29f28a6d7884a1f0b85e035f0124c18790d431..afe1bcfe38d33e0917af9933dae402094769b6fe 100644
--- a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst
+++ b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RenameLog-v1.rst b/docs/source/algorithms/RenameLog-v1.rst
index 192fb28465e323512696c48e01b5cf80017a861b..83e74bcee0f7ff96b9aeead13d2228998c97bb42 100644
--- a/docs/source/algorithms/RenameLog-v1.rst
+++ b/docs/source/algorithms/RenameLog-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RenameWorkspace-v1.rst b/docs/source/algorithms/RenameWorkspace-v1.rst
index 0eeb092d51ce407fb223de2bc0527dedb3ac2549..c5d6e2d95e22849caab515882e7ea3478c10317c 100644
--- a/docs/source/algorithms/RenameWorkspace-v1.rst
+++ b/docs/source/algorithms/RenameWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RenameWorkspaces-v1.rst b/docs/source/algorithms/RenameWorkspaces-v1.rst
index 002feebc6e77d26f6d9e77eafd8580cefa955555..c1fc0899d85cfc4f49769cbf187bf70aa497414d 100644
--- a/docs/source/algorithms/RenameWorkspaces-v1.rst
+++ b/docs/source/algorithms/RenameWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ReplaceSpecialValues-v1.rst b/docs/source/algorithms/ReplaceSpecialValues-v1.rst
index d2015400deaf9e238bb13e902e38210fc6e4ed09..596da224c831c3f3afc0878baedf9d77a1aa7338 100644
--- a/docs/source/algorithms/ReplaceSpecialValues-v1.rst
+++ b/docs/source/algorithms/ReplaceSpecialValues-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ReplicateMD-v1.rst b/docs/source/algorithms/ReplicateMD-v1.rst
index ff6ac463e020cb8f13e143f22db32cdeafa82714..46b5d35df5be0e6335508dc7e649430109a843b5 100644
--- a/docs/source/algorithms/ReplicateMD-v1.rst
+++ b/docs/source/algorithms/ReplicateMD-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ResNorm-v1.rst b/docs/source/algorithms/ResNorm-v1.rst
index f611b50a596e8c5e703f36ca30c52ec2a65cf9d1..22d14ef8272e71d66803acab8e07bd7e37045652 100644
--- a/docs/source/algorithms/ResNorm-v1.rst
+++ b/docs/source/algorithms/ResNorm-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ResNorm-v2.rst b/docs/source/algorithms/ResNorm-v2.rst
index baa4ed715c282a51af242ecb6f0aab73bc6e6912..fc31d42f50819190480450dbe462a923671183f4 100644
--- a/docs/source/algorithms/ResNorm-v2.rst
+++ b/docs/source/algorithms/ResNorm-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ResampleX-v1.rst b/docs/source/algorithms/ResampleX-v1.rst
index 96b4bbf0c952550b6afb780c66ad182ae7e24193..eb4766d503d56f4690ec6ac1937d86cb813c97a7 100644
--- a/docs/source/algorithms/ResampleX-v1.rst
+++ b/docs/source/algorithms/ResampleX-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ResetNegatives-v1.rst b/docs/source/algorithms/ResetNegatives-v1.rst
index df5ea7243cd50554d91eacc3ec1722fc23d9086b..f026d6ba210d144c16b2ece9b13e0b80cc66e1b2 100644
--- a/docs/source/algorithms/ResetNegatives-v1.rst
+++ b/docs/source/algorithms/ResetNegatives-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ResizeRectangularDetector-v1.rst b/docs/source/algorithms/ResizeRectangularDetector-v1.rst
index 12a4ea95279462099b6e65ff8cc6baf7dfb13d1c..57bcc563f8e6f7ec81e96785e5b5e4fc4690e73e 100644
--- a/docs/source/algorithms/ResizeRectangularDetector-v1.rst
+++ b/docs/source/algorithms/ResizeRectangularDetector-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RetrieveRunInfo-v1.rst b/docs/source/algorithms/RetrieveRunInfo-v1.rst
index 74efd6c926c4347380cdf53ed88fdf2a5c0d9337..a15c206b9eb9dcae0549999fbb144b4d36ca72d7 100644
--- a/docs/source/algorithms/RetrieveRunInfo-v1.rst
+++ b/docs/source/algorithms/RetrieveRunInfo-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RingProfile-v1.rst b/docs/source/algorithms/RingProfile-v1.rst
index 565d0a4f98ae925f55682111c109e10ab3f91d90..6128ab0c3d49d747f8149b12574ada228be49bd1 100644
--- a/docs/source/algorithms/RingProfile-v1.rst
+++ b/docs/source/algorithms/RingProfile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RotateInstrumentComponent-v1.rst b/docs/source/algorithms/RotateInstrumentComponent-v1.rst
index ec0fba77cb83db0e26ca9ef723181b015f78b8e4..10b3d82729e5a7bd199a7c0d001b448b8345c30e 100644
--- a/docs/source/algorithms/RotateInstrumentComponent-v1.rst
+++ b/docs/source/algorithms/RotateInstrumentComponent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RotateSource-v1.rst b/docs/source/algorithms/RotateSource-v1.rst
index a076165b66242322cdf663c744f54b1734fa2c49..3c4fd67043668efaf05672e7591f4154c6cc735f 100644
--- a/docs/source/algorithms/RotateSource-v1.rst
+++ b/docs/source/algorithms/RotateSource-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/RunPythonScript-v1.rst b/docs/source/algorithms/RunPythonScript-v1.rst
index 3ef644b912c8a202c172c737be8505b57580888e..82c50218b7d9125ed68b74dd95ab34bb71ea588a 100644
--- a/docs/source/algorithms/RunPythonScript-v1.rst
+++ b/docs/source/algorithms/RunPythonScript-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSAbsoluteScale-v1.rst b/docs/source/algorithms/SANSAbsoluteScale-v1.rst
index 8f639082cdb5709eca542e668a00f1cd62b796d0..dfb8782b7d0bef92589442ecf5668dbe213832d7 100644
--- a/docs/source/algorithms/SANSAbsoluteScale-v1.rst
+++ b/docs/source/algorithms/SANSAbsoluteScale-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst b/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst
index 351c5c2bc179e2886681cfcf654adff935736fcd..d42709129706e39201f9effece408bc326f02f01 100644
--- a/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst
+++ b/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSBeamFinder-v1.rst b/docs/source/algorithms/SANSBeamFinder-v1.rst
index 336706fff43f7304aa711b76bc32d3dd995d283f..985aaac9c556170a6731798515f409edca6a151d 100644
--- a/docs/source/algorithms/SANSBeamFinder-v1.rst
+++ b/docs/source/algorithms/SANSBeamFinder-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst b/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst
index 28f5a224afd08f4faa4cbb02e8fa76aec149ab9f..89fa891a0efc74e983d71c0fb282e90106679d19 100644
--- a/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst
+++ b/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst b/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst
index f5ec4f3ea21189d46b90c06e1ee0f065f4df4be9..7ca608d099c251d4ae109d356d3e2e546ad8d823 100644
--- a/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst
+++ b/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSCalculateTransmission-v1.rst b/docs/source/algorithms/SANSCalculateTransmission-v1.rst
index 680e22aa1a6282936bfa9854bee92e304836846a..a2a195773ab6875e6ecc9a7a9198692ed194e897 100644
--- a/docs/source/algorithms/SANSCalculateTransmission-v1.rst
+++ b/docs/source/algorithms/SANSCalculateTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSConvertToQ-v1.rst b/docs/source/algorithms/SANSConvertToQ-v1.rst
index ae5eaf71e1d9a01b663ecd1191b7ebf0530937c6..50f3a9cb382dfd35efb80265dd939364a2a3966b 100644
--- a/docs/source/algorithms/SANSConvertToQ-v1.rst
+++ b/docs/source/algorithms/SANSConvertToQ-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSConvertToWavelength-v1.rst b/docs/source/algorithms/SANSConvertToWavelength-v1.rst
index e1809d3c9ead04bfe71e1976d43dd34a1b821849..8983cd04e78e4dbf9c347bf58d7431ab486d90c8 100644
--- a/docs/source/algorithms/SANSConvertToWavelength-v1.rst
+++ b/docs/source/algorithms/SANSConvertToWavelength-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst b/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst
index 3dc3f2e2dad2263774072c71bb729037a63abc05..e4e63b6faf3dd1a7a4cc92c9f320b514e94be2a3 100644
--- a/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst
+++ b/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst b/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst
index d002ddc8f2b1cb6a7fc42930c25e309733ac52e4..5f44dc352006f555c87b01c1c34ee61e01fe462c 100644
--- a/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst
+++ b/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst b/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst
index 8e7a78335a976f6b86b820708e10ce8766577597..361a34ed1b9bd0f06838d442bc06cbb750049987 100644
--- a/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst
+++ b/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSCrop-v1.rst b/docs/source/algorithms/SANSCrop-v1.rst
index 340047d864844ae6308053849a92d1c5169c9de2..f85e7c495262bb5bbf113019287f54ec52a82eda 100644
--- a/docs/source/algorithms/SANSCrop-v1.rst
+++ b/docs/source/algorithms/SANSCrop-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst
index e047601d93a1e7a8d788f44a9086971ad25d4cbd..44245466bb056f4b1efb6dccad0ccca4dae1d509 100644
--- a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst
+++ b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst b/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst
index 9e860bf4b112570a6b21757b9d2c1f36081f67c5..dd4b153d066ebd8b52844afca84ad3cdbf01c396 100644
--- a/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst
+++ b/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSFitShiftScale-v1.rst b/docs/source/algorithms/SANSFitShiftScale-v1.rst
index 63dbabb1a39d8b5b63edb2d94bacfaf19f87702f..9456909f7fa01bca8772c8744a74a6fbf6169405 100644
--- a/docs/source/algorithms/SANSFitShiftScale-v1.rst
+++ b/docs/source/algorithms/SANSFitShiftScale-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSLoad-v1.rst b/docs/source/algorithms/SANSLoad-v1.rst
index 1ce6490e87c835ff8159f36d00d5bc778efba538..67dffa65f4c93a739b04f2c239fa1a641510bd8e 100644
--- a/docs/source/algorithms/SANSLoad-v1.rst
+++ b/docs/source/algorithms/SANSLoad-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSMask-v1.rst b/docs/source/algorithms/SANSMask-v1.rst
index 54678ab58066c2228921c440bd8b6ec2d31ffcbf..1456c2085b483517d815a8814a459d0ab0b16ac7 100644
--- a/docs/source/algorithms/SANSMask-v1.rst
+++ b/docs/source/algorithms/SANSMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSMaskWorkspace-v1.rst b/docs/source/algorithms/SANSMaskWorkspace-v1.rst
index 8ab90994988c0d48995a5022478c53d38399ad79..910cf7f13423d4a757b73461e42e0e11932688a8 100644
--- a/docs/source/algorithms/SANSMaskWorkspace-v1.rst
+++ b/docs/source/algorithms/SANSMaskWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSMove-v1.rst b/docs/source/algorithms/SANSMove-v1.rst
index f9961d61393e7c0e11e16eb4fa67420f8a14fa2d..9fd885cd2fbb6dde110987965c2d52d97422b604 100644
--- a/docs/source/algorithms/SANSMove-v1.rst
+++ b/docs/source/algorithms/SANSMove-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst b/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst
index 1ae60263d7abb455e1c319b2152f72e618f4678b..6428517cdce5f14ddff7e271ec641c4c82aa67cf 100644
--- a/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst
+++ b/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSReduction-v1.rst b/docs/source/algorithms/SANSReduction-v1.rst
index 572972a1d9729257766f2ca59ba113f9ad1e4bf8..b971806dd524ed6c8c8ef8bc487b2044eac097aa 100644
--- a/docs/source/algorithms/SANSReduction-v1.rst
+++ b/docs/source/algorithms/SANSReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSSave-v1.rst b/docs/source/algorithms/SANSSave-v1.rst
index 2c2cd936453e71d2143c9cd083f54a247c858688..3bb80b67177feb04ea435e91290576e7f7a1f48f 100644
--- a/docs/source/algorithms/SANSSave-v1.rst
+++ b/docs/source/algorithms/SANSSave-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSScale-v1.rst b/docs/source/algorithms/SANSScale-v1.rst
index d02b6ea156e3a4226c96e3a82cee4e0e9126a5bf..461a0fe494038b13a01b5c4089542f1851faa4af 100644
--- a/docs/source/algorithms/SANSScale-v1.rst
+++ b/docs/source/algorithms/SANSScale-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSSensitivityCorrection-v1.rst b/docs/source/algorithms/SANSSensitivityCorrection-v1.rst
index 0281a60b75eccb30f66a8a62a78a88b810acd21d..9b9381673ca60278e0260eab212564bc7f6e460f 100644
--- a/docs/source/algorithms/SANSSensitivityCorrection-v1.rst
+++ b/docs/source/algorithms/SANSSensitivityCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSSliceEvent-v1.rst b/docs/source/algorithms/SANSSliceEvent-v1.rst
index 3016309f4a6cbe39ab0c7be9738f0c6d980528df..77aad4d01d187986bed772ace25177d1cea50f73 100644
--- a/docs/source/algorithms/SANSSliceEvent-v1.rst
+++ b/docs/source/algorithms/SANSSliceEvent-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst b/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst
index 2cd96afadf8f21489dc0cdb860cefe6cf3162598..ad5c4cebaa0d801cd7177d1c5584aae8e36ddd2e 100644
--- a/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst
+++ b/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSStitch-v1.rst b/docs/source/algorithms/SANSStitch-v1.rst
index 938dd4683f8a5cd80210999d4f7effe6a0a11b23..9b20f09d4412a5f503bc02f60cb7622bd3d6d272 100644
--- a/docs/source/algorithms/SANSStitch-v1.rst
+++ b/docs/source/algorithms/SANSStitch-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSSubtract-v1.rst b/docs/source/algorithms/SANSSubtract-v1.rst
index b74a65c7042ff7726a6905826e3951a40b242d38..22674d01c9c4767a15f566cdded483fa81ee050d 100644
--- a/docs/source/algorithms/SANSSubtract-v1.rst
+++ b/docs/source/algorithms/SANSSubtract-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SANSWideAngleCorrection-v1.rst b/docs/source/algorithms/SANSWideAngleCorrection-v1.rst
index b3e6aac35bd809d66458ec5290a5c6412da4fd72..f2fd5aa11cdad04d2235637a7298f26b2519b5e0 100644
--- a/docs/source/algorithms/SANSWideAngleCorrection-v1.rst
+++ b/docs/source/algorithms/SANSWideAngleCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SCDCalibratePanels-v1.rst b/docs/source/algorithms/SCDCalibratePanels-v1.rst
index 43dac886c2461c010316d36bec457da1facaccf4..c07c43128af31621d822eed17e6197bfcbb5863f 100644
--- a/docs/source/algorithms/SCDCalibratePanels-v1.rst
+++ b/docs/source/algorithms/SCDCalibratePanels-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -37,7 +37,7 @@ The panels and packs' parameters are optimized in parallel.
 An option is available to adjust the panel widths and heights for Rectangular Detectors in a second iteration with all the other parameters fixed.
 
 OUTPUT workspaces and files:
-============================
+############################
 
 1) The results are saved to an ISAW-like DetCal file and optionally in an xml
    file that can be used with the :ref:`LoadParameterFile <algm-LoadParameterFile>` algorithm.
diff --git a/docs/source/algorithms/SNAPReduce-v1.rst b/docs/source/algorithms/SNAPReduce-v1.rst
index 7d79a441b31246feba4be7aa23ab6d68e65f3a07..3923b00263443a2feb5cd289db53dad3897287bc 100644
--- a/docs/source/algorithms/SNAPReduce-v1.rst
+++ b/docs/source/algorithms/SNAPReduce-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SNSPowderReduction-v1.rst b/docs/source/algorithms/SNSPowderReduction-v1.rst
index c4cfe68c4f843ba76fa891c33c0561a7372607ed..5ce240037e53fe715998e25108ce92923d6c756d 100644
--- a/docs/source/algorithms/SNSPowderReduction-v1.rst
+++ b/docs/source/algorithms/SNSPowderReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SassenaFFT-v1.rst b/docs/source/algorithms/SassenaFFT-v1.rst
index edcc923c834273e77e3020d5cf62ebf541c68889..910dcc900dfb4ae363b1d8a9031fbdc136009515 100644
--- a/docs/source/algorithms/SassenaFFT-v1.rst
+++ b/docs/source/algorithms/SassenaFFT-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveANSTOAscii-v1.rst b/docs/source/algorithms/SaveANSTOAscii-v1.rst
index 3f7e6cf70bb7034cd7cec4f62b91e14d97a7d6f7..b56cc467146ef84f35ca2319af374cc6067fb187 100644
--- a/docs/source/algorithms/SaveANSTOAscii-v1.rst
+++ b/docs/source/algorithms/SaveANSTOAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveAscii-v1.rst b/docs/source/algorithms/SaveAscii-v1.rst
index c7c417429d5c5ff11d8c2e1ff5195e2612d96348..2aa848631a306eaa4a2fcbb544e883bb742d22f7 100644
--- a/docs/source/algorithms/SaveAscii-v1.rst
+++ b/docs/source/algorithms/SaveAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveAscii-v2.rst b/docs/source/algorithms/SaveAscii-v2.rst
index a03c8dc8ffeaa666e2635a5cbf39a0efa063a718..a35e60f03bf289130b86ec3e87ce427584b81e71 100644
--- a/docs/source/algorithms/SaveAscii-v2.rst
+++ b/docs/source/algorithms/SaveAscii-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveCSV-v1.rst b/docs/source/algorithms/SaveCSV-v1.rst
index 627b3ca39867c205293d3cdb3348505487ecf2ba..43c7a7253f02a5842d408d5b1e94e71823eba75a 100644
--- a/docs/source/algorithms/SaveCSV-v1.rst
+++ b/docs/source/algorithms/SaveCSV-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveCalFile-v1.rst b/docs/source/algorithms/SaveCalFile-v1.rst
index e2e9171111bedd74aef6a602065c1ba4a6bfbf1e..5efebfccc2b97f5ec4e369422d12f647ad04a8e0 100644
--- a/docs/source/algorithms/SaveCalFile-v1.rst
+++ b/docs/source/algorithms/SaveCalFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveCanSAS1D-v1.rst b/docs/source/algorithms/SaveCanSAS1D-v1.rst
index e13fe9d5b5a3b51123f940ad6bb235a4b73f0550..016d4daafd22645023f0cfb207f19d24d9c45608 100644
--- a/docs/source/algorithms/SaveCanSAS1D-v1.rst
+++ b/docs/source/algorithms/SaveCanSAS1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveCanSAS1D-v2.rst b/docs/source/algorithms/SaveCanSAS1D-v2.rst
index e704f271dc33bff89348da252643b4c5f077407e..ed4ff014e3bb53d3c7e92d9bb1f40391cf782fb4 100644
--- a/docs/source/algorithms/SaveCanSAS1D-v2.rst
+++ b/docs/source/algorithms/SaveCanSAS1D-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveDaveGrp-v1.rst b/docs/source/algorithms/SaveDaveGrp-v1.rst
index a2267c636e00347f40723b1b66dacda2ff40067c..40ce0af178b2e78ef9ad8a1cb1cef9e2feb17381 100644
--- a/docs/source/algorithms/SaveDaveGrp-v1.rst
+++ b/docs/source/algorithms/SaveDaveGrp-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveDetectorsGrouping-v1.rst b/docs/source/algorithms/SaveDetectorsGrouping-v1.rst
index 5f356aca0f5c49dc66806023b2fbc2c1a89f8e9a..221ec51d2efd096f2ed9ac2c517a268bc06b736d 100644
--- a/docs/source/algorithms/SaveDetectorsGrouping-v1.rst
+++ b/docs/source/algorithms/SaveDetectorsGrouping-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveDiffCal-v1.rst b/docs/source/algorithms/SaveDiffCal-v1.rst
index fa6f577ccbee2fda17d92538d9a919a33210893d..a2ebc766f3da895fc275607b4940ac513be865b1 100644
--- a/docs/source/algorithms/SaveDiffCal-v1.rst
+++ b/docs/source/algorithms/SaveDiffCal-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveDiffFittingAscii-v1.rst b/docs/source/algorithms/SaveDiffFittingAscii-v1.rst
index 969d9245746f2c2debd61237d08ba1ac8400d45e..5997581c202f7559dffbe88d28ee17b8047d2821 100644
--- a/docs/source/algorithms/SaveDiffFittingAscii-v1.rst
+++ b/docs/source/algorithms/SaveDiffFittingAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveDspacemap-v1.rst b/docs/source/algorithms/SaveDspacemap-v1.rst
index 2ff397771fb27149fcbbcb3942d1d05300a72337..d49f557541d14a42800075307e6cef0b2f4f8a16 100644
--- a/docs/source/algorithms/SaveDspacemap-v1.rst
+++ b/docs/source/algorithms/SaveDspacemap-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveFITS-v1.rst b/docs/source/algorithms/SaveFITS-v1.rst
index 9ab62318637c39ac24c96c0f9864f78ecd65e64e..54337346cabd8059ccfd2d73be5fa56c417ec390 100644
--- a/docs/source/algorithms/SaveFITS-v1.rst
+++ b/docs/source/algorithms/SaveFITS-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveFocusedXYE-v1.rst b/docs/source/algorithms/SaveFocusedXYE-v1.rst
index 53a1c4186d35f31ba612daa4260091bf7629be99..d654cdfac33fdc9460d49b87f0ca3927d4450b4e 100644
--- a/docs/source/algorithms/SaveFocusedXYE-v1.rst
+++ b/docs/source/algorithms/SaveFocusedXYE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveFullprofResolution-v1.rst b/docs/source/algorithms/SaveFullprofResolution-v1.rst
index 621a9cc84bc86d2519290c2fec722ee3bd8d3cc9..5f4203d5af4dd7954abaa2b018120edf134764a1 100644
--- a/docs/source/algorithms/SaveFullprofResolution-v1.rst
+++ b/docs/source/algorithms/SaveFullprofResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst b/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst
index f2690b6d6e39a72d8ca68dc90c61e86bf4a0910a..1b44511f1ab418ea2c6eeb388e2b7104e5d7feeb 100644
--- a/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst
+++ b/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveGSS-v1.rst b/docs/source/algorithms/SaveGSS-v1.rst
index b94f8acfcaa2bfe24b2954433c9f11b2b11cbd90..c6d2a2c0f8deb8710a184c42dba34026918c0952 100644
--- a/docs/source/algorithms/SaveGSS-v1.rst
+++ b/docs/source/algorithms/SaveGSS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveHKL-v1.rst b/docs/source/algorithms/SaveHKL-v1.rst
index c2cc616f34603206472fb58ec6b245e4948d635f..c293e2eee2c6b547001263ec8879604591efb8b2 100644
--- a/docs/source/algorithms/SaveHKL-v1.rst
+++ b/docs/source/algorithms/SaveHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveILLCosmosAscii-v1.rst b/docs/source/algorithms/SaveILLCosmosAscii-v1.rst
index 41d27f23b358a6e912d28cdbe8e2b5d1e31d9d80..8864a170eecbcbf802bfd1620d782b8f81c265b2 100644
--- a/docs/source/algorithms/SaveILLCosmosAscii-v1.rst
+++ b/docs/source/algorithms/SaveILLCosmosAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveISISNexus-v1.rst b/docs/source/algorithms/SaveISISNexus-v1.rst
index 484ceecba5da998638867a8e526a8afae042dc6b..0454c04852281dda1ed8aee460c63c29d99ea95e 100644
--- a/docs/source/algorithms/SaveISISNexus-v1.rst
+++ b/docs/source/algorithms/SaveISISNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveIsawDetCal-v1.rst b/docs/source/algorithms/SaveIsawDetCal-v1.rst
index 39cb1d6e763b51478f9bf072758c3f7153267e58..c88fbe530795f7ef7ba906295311f93526715f5c 100644
--- a/docs/source/algorithms/SaveIsawDetCal-v1.rst
+++ b/docs/source/algorithms/SaveIsawDetCal-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveIsawPeaks-v1.rst b/docs/source/algorithms/SaveIsawPeaks-v1.rst
index 64357cacb45512080061310691fad12bc0b32acd..212ba072dea963c2c3053a65bcd2a77328ec152e 100644
--- a/docs/source/algorithms/SaveIsawPeaks-v1.rst
+++ b/docs/source/algorithms/SaveIsawPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -30,6 +30,8 @@ Usage
   # Add two peaks to the peaks workspace
   AddPeak( pws, ws, TOF=100, DetectorID=101, Height=1 )
   AddPeak( pws, ws, TOF=200, DetectorID=102, Height=2 )
+  peak = pws.getPeak(1).setPeakNumber(2)
+  peak = pws.getPeak(2).setPeakNumber(3)
 
   # Save the peaks workspace to a file in the user's home directory
   isawPeaksFilePath = os.path.expanduser('~/MantidUsageExample_ISawFile.peaks')
diff --git a/docs/source/algorithms/SaveIsawQvector-v1.rst b/docs/source/algorithms/SaveIsawQvector-v1.rst
index be2e824c08ebd3b9e359736f60be9f661d934968..eb32744a5039bf4db8af6390b40933a399f5f8b4 100644
--- a/docs/source/algorithms/SaveIsawQvector-v1.rst
+++ b/docs/source/algorithms/SaveIsawQvector-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveIsawUB-v1.rst b/docs/source/algorithms/SaveIsawUB-v1.rst
index 11415c868c8459349cf7a559ab093c9368889c98..f364b22c295bff273c3f7ad87705bd84aa20e21a 100644
--- a/docs/source/algorithms/SaveIsawUB-v1.rst
+++ b/docs/source/algorithms/SaveIsawUB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveLauenorm-v1.rst b/docs/source/algorithms/SaveLauenorm-v1.rst
index 0ab304c56215c4616a6ac8c7de53e01953a5b927..862f9533d373fc92babe686213b55c6fbdce75fd 100644
--- a/docs/source/algorithms/SaveLauenorm-v1.rst
+++ b/docs/source/algorithms/SaveLauenorm-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveMD-v1.rst b/docs/source/algorithms/SaveMD-v1.rst
index e0ff00e221e22f83350229d5ba6c20e91aa151f6..ebda8ebaca76901e59dcaabf0d02fb87c26fdae7 100644
--- a/docs/source/algorithms/SaveMD-v1.rst
+++ b/docs/source/algorithms/SaveMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveMD-v2.rst b/docs/source/algorithms/SaveMD-v2.rst
index baf9a2f931ad27af951dafbe49c12b979bb47aa2..443ec2b3c5d4b538994f78df7df64f178dc6c52c 100644
--- a/docs/source/algorithms/SaveMD-v2.rst
+++ b/docs/source/algorithms/SaveMD-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst b/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst
index 19c90a8f3286a0679fdd0575c4739bcc063ce5db..83ff41c6bb5ea928c34337e248c6cf336451ec66 100644
--- a/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst
+++ b/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveMask-v1.rst b/docs/source/algorithms/SaveMask-v1.rst
index c94eb79e3ea6c47a79e47819eed3a920ca491ac3..8dcb04c173361cb635d7a56942c43be6c2ff941d 100644
--- a/docs/source/algorithms/SaveMask-v1.rst
+++ b/docs/source/algorithms/SaveMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNISTDAT-v1.rst b/docs/source/algorithms/SaveNISTDAT-v1.rst
index e9d30acff91cd6266b6a7c79dbd0b086600acdbb..7019a91dea78eef485dd6b39a54c3f8a2926a363 100644
--- a/docs/source/algorithms/SaveNISTDAT-v1.rst
+++ b/docs/source/algorithms/SaveNISTDAT-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNXSPE-v1.rst b/docs/source/algorithms/SaveNXSPE-v1.rst
index 61dcc9d20b3e998928066bf282fd6a8ef1fc7d57..c51ff193f95038d14d4e17d3c39a3d203db4875c 100644
--- a/docs/source/algorithms/SaveNXSPE-v1.rst
+++ b/docs/source/algorithms/SaveNXSPE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNXTomo-v1.rst b/docs/source/algorithms/SaveNXTomo-v1.rst
index 495f186f21cc0f4ad54e533177a688c690279d15..9c0ac61c0894720279c7d5cb87b533b2b244d5e5 100644
--- a/docs/source/algorithms/SaveNXTomo-v1.rst
+++ b/docs/source/algorithms/SaveNXTomo-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNXcanSAS-v1.rst b/docs/source/algorithms/SaveNXcanSAS-v1.rst
index 90a9535c6b23ed7eb2c6717d575d18ddd4aef06b..426c54d924169e25e682573ef110fcd3065ed6a6 100644
--- a/docs/source/algorithms/SaveNXcanSAS-v1.rst
+++ b/docs/source/algorithms/SaveNXcanSAS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNexus-v1.rst b/docs/source/algorithms/SaveNexus-v1.rst
index dd22495bd16685e41a92d91df0af6d4c053480a9..f9f19ce382bae0f1223639219615f9791977b705 100644
--- a/docs/source/algorithms/SaveNexus-v1.rst
+++ b/docs/source/algorithms/SaveNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNexusPD-v1.rst b/docs/source/algorithms/SaveNexusPD-v1.rst
index 2b18441beaf09055e4c5d19b2fdffbb4c2837d12..475405a9e571cde8ff003789bdb3582e318b7aee 100644
--- a/docs/source/algorithms/SaveNexusPD-v1.rst
+++ b/docs/source/algorithms/SaveNexusPD-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveNexusProcessed-v1.rst b/docs/source/algorithms/SaveNexusProcessed-v1.rst
index c0ee69902031bbc457d9a1c8c0765419740c0176..3f22356ced7371f7aa8236855b28422eca91d0ca 100644
--- a/docs/source/algorithms/SaveNexusProcessed-v1.rst
+++ b/docs/source/algorithms/SaveNexusProcessed-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveOpenGenieAscii-v1.rst b/docs/source/algorithms/SaveOpenGenieAscii-v1.rst
index 6d853c65781094c251a7a84a15c1fdab9de5ccd4..b0c021f2d7e34549484a207f492ccc9d57d0bc9d 100644
--- a/docs/source/algorithms/SaveOpenGenieAscii-v1.rst
+++ b/docs/source/algorithms/SaveOpenGenieAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SavePAR-v1.rst b/docs/source/algorithms/SavePAR-v1.rst
index 11274afe87b080bb80871a809851c2dbd15ce11f..78db4aa3108e0eefb62ffbc86170731967cb55e9 100644
--- a/docs/source/algorithms/SavePAR-v1.rst
+++ b/docs/source/algorithms/SavePAR-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SavePDFGui-v1.rst b/docs/source/algorithms/SavePDFGui-v1.rst
index 1b964b46487f3c36a715f61bcb99ea421ad64142..92352598e21e3f2abbb308ce4161a5fac7aa3d78 100644
--- a/docs/source/algorithms/SavePDFGui-v1.rst
+++ b/docs/source/algorithms/SavePDFGui-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SavePHX-v1.rst b/docs/source/algorithms/SavePHX-v1.rst
index 49ff0e73bb50dc739b1bebdef2662441fcd1b8df..09d5003a03a2f3eaef5a0ba78ec8c6ea9078fe64 100644
--- a/docs/source/algorithms/SavePHX-v1.rst
+++ b/docs/source/algorithms/SavePHX-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveParameterFile-v1.rst b/docs/source/algorithms/SaveParameterFile-v1.rst
index 3903cf34bd7a16d0ba5cf6deda24c5a531b89320..be2795351b61f3b294a849809b23a673523f4e20 100644
--- a/docs/source/algorithms/SaveParameterFile-v1.rst
+++ b/docs/source/algorithms/SaveParameterFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SavePlot1D-v1.rst b/docs/source/algorithms/SavePlot1D-v1.rst
index b5f9ad78c892a5caeb320cdd1fab6f4f90f99009..b29f32c4187ff9e3b61cd9cafd0ed54dfa1c4955 100644
--- a/docs/source/algorithms/SavePlot1D-v1.rst
+++ b/docs/source/algorithms/SavePlot1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SavePlot1DAsJson-v1.rst b/docs/source/algorithms/SavePlot1DAsJson-v1.rst
index 85bb7a8d062628aad864fac2e7a84bdde2c6c871..414c7e478f73259d89c96d64b5619dc9b8b0f6c0 100644
--- a/docs/source/algorithms/SavePlot1DAsJson-v1.rst
+++ b/docs/source/algorithms/SavePlot1DAsJson-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveRKH-v1.rst b/docs/source/algorithms/SaveRKH-v1.rst
index 30cb6726492170822fa491b4b5cd1885b91ebbf9..26c0ecdedb800d07dabe0bcb2abd06dee61c771e 100644
--- a/docs/source/algorithms/SaveRKH-v1.rst
+++ b/docs/source/algorithms/SaveRKH-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveReflCustomAscii-v1.rst b/docs/source/algorithms/SaveReflCustomAscii-v1.rst
index 96a531afc3f8a967ad360f0e20eb7cedef9a009c..81d9b39b96f726559e3f513b1bffa73eaafc1832 100644
--- a/docs/source/algorithms/SaveReflCustomAscii-v1.rst
+++ b/docs/source/algorithms/SaveReflCustomAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst b/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst
index 842b71090339f8b9de0e0ffc4896bb7edb31cf8b..7f25d60b8e4b2bf92f31909fe185414dc19088aa 100644
--- a/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst
+++ b/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveReflections-v1.rst b/docs/source/algorithms/SaveReflections-v1.rst
index f1578a110c7d542030997734367493085de0bac3..f4a9755cce75829c3533ac2ed54b952d747147f8 100644
--- a/docs/source/algorithms/SaveReflections-v1.rst
+++ b/docs/source/algorithms/SaveReflections-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveSESANS-v1.rst b/docs/source/algorithms/SaveSESANS-v1.rst
index 1d53164654ea5f9149407877b87f9f877eee6d8e..96b4819c112d9dfa4c73a25d8e77e546440450cf 100644
--- a/docs/source/algorithms/SaveSESANS-v1.rst
+++ b/docs/source/algorithms/SaveSESANS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveSPE-v1.rst b/docs/source/algorithms/SaveSPE-v1.rst
index 7cd4c44a9a0ae37a9a82ceef75f42e37b5d65722..fa29314aa71ff87dc2b396aa8894763d3bee1317 100644
--- a/docs/source/algorithms/SaveSPE-v1.rst
+++ b/docs/source/algorithms/SaveSPE-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveTBL-v1.rst b/docs/source/algorithms/SaveTBL-v1.rst
index f17c7d9eb7038df9ca541be9c15b0955ea8f9174..822c57f3c4aa91ba3f2dc75f4af44027d111db77 100644
--- a/docs/source/algorithms/SaveTBL-v1.rst
+++ b/docs/source/algorithms/SaveTBL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst b/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst
index eb6f5f53a27a2a6b5ab7e93bb718e6c3e72b9bf2..fb5c24ebd953b9c7d4b3af2be8a548bdc596744e 100644
--- a/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst
+++ b/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveVTK-v1.rst b/docs/source/algorithms/SaveVTK-v1.rst
index b0bc1962e20bdd43df82d7b7936faa62fd8ea864..9e4f3cbd409f20212ef041ecf25a5514c8df843e 100644
--- a/docs/source/algorithms/SaveVTK-v1.rst
+++ b/docs/source/algorithms/SaveVTK-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveVulcanGSS-v1.rst b/docs/source/algorithms/SaveVulcanGSS-v1.rst
index 02dad60760f689d4e78d3d59566ab810ab687726..db8f998453dab9c762a0742e56e96eead3a661ae 100644
--- a/docs/source/algorithms/SaveVulcanGSS-v1.rst
+++ b/docs/source/algorithms/SaveVulcanGSS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveYDA-v1.rst b/docs/source/algorithms/SaveYDA-v1.rst
index fd7e62d45193cfc2f61c29ac5a2c2d8acae6c542..a0c122544fcccab02d9e49cbb89b06ac190c245f 100644
--- a/docs/source/algorithms/SaveYDA-v1.rst
+++ b/docs/source/algorithms/SaveYDA-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SaveZODS-v1.rst b/docs/source/algorithms/SaveZODS-v1.rst
index a8eae4a0181688ad77f8c175e4617be41fed8388..b18e507c8860f33fd7006d1ecf473f9890a387e1 100644
--- a/docs/source/algorithms/SaveZODS-v1.rst
+++ b/docs/source/algorithms/SaveZODS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Scale-v1.rst b/docs/source/algorithms/Scale-v1.rst
index 2e9d12029745e2979a56e4d32b7b949f14f2ea59..0afc60473c318a61728dcec33044308bb6563562 100644
--- a/docs/source/algorithms/Scale-v1.rst
+++ b/docs/source/algorithms/Scale-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ScaleX-v1.rst b/docs/source/algorithms/ScaleX-v1.rst
index 443e864f69d7fd363d1359d3ad42d90ca915adbd..f73d22db3ed7f1fea30294cf14762a85675cf486 100644
--- a/docs/source/algorithms/ScaleX-v1.rst
+++ b/docs/source/algorithms/ScaleX-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Segfault-v1.rst b/docs/source/algorithms/Segfault-v1.rst
index 46d811401c311966fbb79473f19908782f5efb07..200d83f64c61299c76915e823836b3902c2debce 100644
--- a/docs/source/algorithms/Segfault-v1.rst
+++ b/docs/source/algorithms/Segfault-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SelectCellOfType-v1.rst b/docs/source/algorithms/SelectCellOfType-v1.rst
index 76a02f6b4385a7a5767c6a99eb8a4f0e593a087e..a0e36580cd47c9537940d6a8e2d55d03f2570225 100644
--- a/docs/source/algorithms/SelectCellOfType-v1.rst
+++ b/docs/source/algorithms/SelectCellOfType-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SelectCellWithForm-v1.rst b/docs/source/algorithms/SelectCellWithForm-v1.rst
index b85608ad3f82ae42b1c2e6432be9eccbdf4e4d8d..67219f6beb948b8e6b47d4061c815bc28559262a 100644
--- a/docs/source/algorithms/SelectCellWithForm-v1.rst
+++ b/docs/source/algorithms/SelectCellWithForm-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst b/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst
index 6207b7c559184f2d95b20721450d3748eb479851..905a432444466bec9bd6bcb5100c7aa64dc57654 100644
--- a/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst
+++ b/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetBeam-v1.rst b/docs/source/algorithms/SetBeam-v1.rst
index 6bafc93088ea781003cb3c8b2d24bedb31ae59ae..87cecd620e57aacd4b5d4f74c7695b4b1f01cd19 100644
--- a/docs/source/algorithms/SetBeam-v1.rst
+++ b/docs/source/algorithms/SetBeam-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetDetScale-v1.rst b/docs/source/algorithms/SetDetScale-v1.rst
index ca1a0e36a8a171faa0a228f24b3be63ea184c4e4..466cf165cef160a6cc78160ca354b83530b1f443 100644
--- a/docs/source/algorithms/SetDetScale-v1.rst
+++ b/docs/source/algorithms/SetDetScale-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetGoniometer-v1.rst b/docs/source/algorithms/SetGoniometer-v1.rst
index d8c47595fe3f1c1e5f7f539c2f2f9447a4583401..c13b71b14b8fd688fe093ff4e56ccb730163ed17 100644
--- a/docs/source/algorithms/SetGoniometer-v1.rst
+++ b/docs/source/algorithms/SetGoniometer-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetInstrumentParameter-v1.rst b/docs/source/algorithms/SetInstrumentParameter-v1.rst
index 07d3193ca4b258637101ec9eb7309f2be74969e2..b3280db781ee8ce758293fbe953307fe521fd939 100644
--- a/docs/source/algorithms/SetInstrumentParameter-v1.rst
+++ b/docs/source/algorithms/SetInstrumentParameter-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetMDFrame-v1.rst b/docs/source/algorithms/SetMDFrame-v1.rst
index a53653f95fe6e26bce51802cebd99fdf085e9f42..c722fcadd94d7a619c1835679d0029dcc0c8a579 100644
--- a/docs/source/algorithms/SetMDFrame-v1.rst
+++ b/docs/source/algorithms/SetMDFrame-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetMDUsingMask-v1.rst b/docs/source/algorithms/SetMDUsingMask-v1.rst
index 1c82ef7a0380cf25081f53770b69e2249071cdb7..97519a88c55391af015280a07e72957b1945d345 100644
--- a/docs/source/algorithms/SetMDUsingMask-v1.rst
+++ b/docs/source/algorithms/SetMDUsingMask-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetSample-v1.rst b/docs/source/algorithms/SetSample-v1.rst
index 50ed6a778b96239baec77b6b280ef78d8be794d2..9d7e6155da66eb0e672a2ef70814f158eb7807e6 100644
--- a/docs/source/algorithms/SetSample-v1.rst
+++ b/docs/source/algorithms/SetSample-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetSampleMaterial-v1.rst b/docs/source/algorithms/SetSampleMaterial-v1.rst
index 35cc486ecacbd1c620dbfeb5c6f09b28b759a306..af4760a9cb00987720ecc38ef96cf7fc48686085 100644
--- a/docs/source/algorithms/SetSampleMaterial-v1.rst
+++ b/docs/source/algorithms/SetSampleMaterial-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetScalingPSD-v1.rst b/docs/source/algorithms/SetScalingPSD-v1.rst
index 2e4d21652095f9296fdad9eed4247bc22d953027..10f5f85cf35737bcbd5e292254feaf3150f44313 100644
--- a/docs/source/algorithms/SetScalingPSD-v1.rst
+++ b/docs/source/algorithms/SetScalingPSD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetSpecialCoordinates-v1.rst b/docs/source/algorithms/SetSpecialCoordinates-v1.rst
index 8fc2df29a2fc4ccd2a120eaf7e2720d4b9dcac09..e712aae43efe64ad4044314a50ad1cdfb129b897 100644
--- a/docs/source/algorithms/SetSpecialCoordinates-v1.rst
+++ b/docs/source/algorithms/SetSpecialCoordinates-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetUB-v1.rst b/docs/source/algorithms/SetUB-v1.rst
index b577dfa18ab91ad5d5eb48a84e39ed959f6ceb6f..ca951cb3b93c42a35675a27c456377dc32589800 100644
--- a/docs/source/algorithms/SetUB-v1.rst
+++ b/docs/source/algorithms/SetUB-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -47,11 +47,12 @@ Usage
 Output:
 
 .. testoutput:: SetUB
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
     UB matrix
-    [[-0.     0.     0.143]
-     [ 0.128 -0.128  0.   ]
-     [ 0.154  0.107 -0.   ]]
+    [[...     ...     0.143]
+     [ 0.128 -0.128  ...   ]
+     [ 0.154  0.107 ...   ]]
 
 
 .. categories::
diff --git a/docs/source/algorithms/SetUncertainties-v1.rst b/docs/source/algorithms/SetUncertainties-v1.rst
index 0c6e4e66d99fc841b837950d8721bd749e22ce38..ddd7b113893dd70952383c5838d2b08b50518433 100644
--- a/docs/source/algorithms/SetUncertainties-v1.rst
+++ b/docs/source/algorithms/SetUncertainties-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetupEQSANSReduction-v1.rst b/docs/source/algorithms/SetupEQSANSReduction-v1.rst
index 0473eefc42b8be532820090f0fadd0945a1e781f..b4927b948fa551949faa214e541c0b8327462a87 100644
--- a/docs/source/algorithms/SetupEQSANSReduction-v1.rst
+++ b/docs/source/algorithms/SetupEQSANSReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetupHFIRReduction-v1.rst b/docs/source/algorithms/SetupHFIRReduction-v1.rst
index c99561635efba677b089a8b4cdb2782dc814bab8..0ecfc4a76e174de54c6d9f7eba78aff499575287 100644
--- a/docs/source/algorithms/SetupHFIRReduction-v1.rst
+++ b/docs/source/algorithms/SetupHFIRReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SetupILLD33Reduction-v1.rst b/docs/source/algorithms/SetupILLD33Reduction-v1.rst
index 92d3513dd328c1d15459e4f06e81448de6b5b13d..e5dbb8669318c769e95786bb4bed2d6d45095e6c 100644
--- a/docs/source/algorithms/SetupILLD33Reduction-v1.rst
+++ b/docs/source/algorithms/SetupILLD33Reduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ShiftLogTime-v1.rst b/docs/source/algorithms/ShiftLogTime-v1.rst
index 4c2a0abc0905adfb7f46dd9abd4e75d75aff4a59..d66c3df887a49f4a18910264caaa00d0f9ef2808 100644
--- a/docs/source/algorithms/ShiftLogTime-v1.rst
+++ b/docs/source/algorithms/ShiftLogTime-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst b/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst
index e3dedcf03eddd580ddac2a7c8ba1951969a634da..e22d8273d34c75a53aa3c0016aa07e7d673cfde4 100644
--- a/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst
+++ b/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ShowPossibleCells-v1.rst b/docs/source/algorithms/ShowPossibleCells-v1.rst
index 9ff6b3bdec57983875cbf42b8cb27598bb67c6fd..8341b231a72dda6d074b753cb3dacfc28c076970 100644
--- a/docs/source/algorithms/ShowPossibleCells-v1.rst
+++ b/docs/source/algorithms/ShowPossibleCells-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SignalOverError-v1.rst b/docs/source/algorithms/SignalOverError-v1.rst
index ed1d90ef78b2bb2278ac9cbbea8cb79a27d2ae8c..2f8836135297394fa2b7fc1c6045a36a40f4e408 100644
--- a/docs/source/algorithms/SignalOverError-v1.rst
+++ b/docs/source/algorithms/SignalOverError-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst b/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst
index bd0fca8d81c184bf1a2afccc8a445c47bcfeb61c..2df74518e4ad2311b5c9fa7a0a16234b34415f61 100644
--- a/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst
+++ b/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst b/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst
index 29ff13b3c9aeb631a6d753fe5f31b71ecc218679..bd38f354277595cb0315c8119fd25dfc40a19245 100644
--- a/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst
+++ b/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst
index 4237e7c85e7655a3b60ba563ec3bc0530d039a0e..08639ea28bff8e51f9750639344621a43a61546e 100644
--- a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst
+++ b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst b/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst
index 6efc6c78d5fbc38d84ce6ce38dd46545b8d7f330..95a91fb389de39fd00494d9e48f327a71b78bce7 100644
--- a/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst
+++ b/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SliceMD-v1.rst b/docs/source/algorithms/SliceMD-v1.rst
index a8a1a78110e3f1dc151452452c1168a63626cae2..5da7f957078bae5ee0ba9807b9626e9b8b47647f 100644
--- a/docs/source/algorithms/SliceMD-v1.rst
+++ b/docs/source/algorithms/SliceMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SliceMDHisto-v1.rst b/docs/source/algorithms/SliceMDHisto-v1.rst
index 9014403ae152c4cead83f43b12f091b9e769b862..aaafa5507b146e263f847ebcc4a5ed524c3a98d9 100644
--- a/docs/source/algorithms/SliceMDHisto-v1.rst
+++ b/docs/source/algorithms/SliceMDHisto-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SmoothData-v1.rst b/docs/source/algorithms/SmoothData-v1.rst
index c958fa0d90ad99a92b687dfd1f6ac35be4cdce72..c6058b2799a4162e020bbaacb1f63094d1b09e19 100644
--- a/docs/source/algorithms/SmoothData-v1.rst
+++ b/docs/source/algorithms/SmoothData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SmoothMD-v1.rst b/docs/source/algorithms/SmoothMD-v1.rst
index f138b9f5cd9fa8bfa2c1a6cc11b7fdfce9ff3de2..7dca3269a721bec8d8ee8817cdcc15e1091dcfd3 100644
--- a/docs/source/algorithms/SmoothMD-v1.rst
+++ b/docs/source/algorithms/SmoothMD-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SmoothNeighbours-v1.rst b/docs/source/algorithms/SmoothNeighbours-v1.rst
index 3ade8959f5887339cef30abad4ca7cb36ddc23a3..83520295a0d204d444da6ec15a878b19a705b81e 100644
--- a/docs/source/algorithms/SmoothNeighbours-v1.rst
+++ b/docs/source/algorithms/SmoothNeighbours-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQW-v1.rst b/docs/source/algorithms/SofQW-v1.rst
index fd6f42bb860fe8057a07970e5bb7874b88ae2500..117edc41efe957db76af5cee5ac0c71a77094686 100644
--- a/docs/source/algorithms/SofQW-v1.rst
+++ b/docs/source/algorithms/SofQW-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQWCentre-v1.rst b/docs/source/algorithms/SofQWCentre-v1.rst
index c98c26f5217d96189d66b522a3420873cf0701ab..da9e7a8db996e42b1fb1f34a82fcdb3d531db8ea 100644
--- a/docs/source/algorithms/SofQWCentre-v1.rst
+++ b/docs/source/algorithms/SofQWCentre-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQWMoments-v1.rst b/docs/source/algorithms/SofQWMoments-v1.rst
index a1854bd96aea81236b145a21175e91b97b77f5f1..2da6a995b3684db379325051dcbc3af4e530843b 100644
--- a/docs/source/algorithms/SofQWMoments-v1.rst
+++ b/docs/source/algorithms/SofQWMoments-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQWMomentsScan-v1.rst b/docs/source/algorithms/SofQWMomentsScan-v1.rst
index 643c8fc903a1549a82af5d002a4d144f8acc0ced..161c38ac964a21431584e1236bdf52365bd2c07c 100644
--- a/docs/source/algorithms/SofQWMomentsScan-v1.rst
+++ b/docs/source/algorithms/SofQWMomentsScan-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst b/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst
index 8be67c4e960c89977cc52320fab46e5dc9ea0a3b..39c665271d02cafee00670ea93dbe9beb4714071 100644
--- a/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst
+++ b/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SofQWPolygon-v1.rst b/docs/source/algorithms/SofQWPolygon-v1.rst
index f07a5cd549d5a9a01c55a1ce70f4eedb1a2d98ca..de2e5385c06d55ffde0caa9cc4520473abad53b9 100644
--- a/docs/source/algorithms/SofQWPolygon-v1.rst
+++ b/docs/source/algorithms/SofQWPolygon-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SolidAngle-v1.rst b/docs/source/algorithms/SolidAngle-v1.rst
index cf54086f2b72ace7c8e6a023395de44e38c4d159..632b576e013d8b672a78385e69790eedb1b51d34 100644
--- a/docs/source/algorithms/SolidAngle-v1.rst
+++ b/docs/source/algorithms/SolidAngle-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortByQVectors-v1.rst b/docs/source/algorithms/SortByQVectors-v1.rst
index b290618a9e1fdffb4e3365495bdb688cbe82ce84..1759811c40bcf4d54c2ad71ea21764e5b6ec3fdd 100644
--- a/docs/source/algorithms/SortByQVectors-v1.rst
+++ b/docs/source/algorithms/SortByQVectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortDetectors-v1.rst b/docs/source/algorithms/SortDetectors-v1.rst
index 8e6a0fbf357f5e75fe1541bd65fd963b061b57dd..120169ba367a4edf96c8fc23f828d8ac686cc5ed 100644
--- a/docs/source/algorithms/SortDetectors-v1.rst
+++ b/docs/source/algorithms/SortDetectors-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortEvents-v1.rst b/docs/source/algorithms/SortEvents-v1.rst
index 3d188ac2e6c1bab79a42bc41d1d6fa0ce11939a0..cc2d0d78bd01325b8851083c99e125d0bc957138 100644
--- a/docs/source/algorithms/SortEvents-v1.rst
+++ b/docs/source/algorithms/SortEvents-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortHKL-v1.rst b/docs/source/algorithms/SortHKL-v1.rst
index decf6733cfad51abb5386e33c63bf960e8394657..dd135aad819af38828a624bee4bb8f9bdba37b78 100644
--- a/docs/source/algorithms/SortHKL-v1.rst
+++ b/docs/source/algorithms/SortHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -36,6 +36,15 @@ it belongs to, so that equivalent reflections have the same intensity and error
 
 Finally, the peaks in the output workspace are sorted by H, K and L.
 
+The EquivalentsWorkspace contains specta that can be plotted for each set of
+equivalent intensities.  The X axis is the wavelength and the Y axis is the corrected intensity of the
+peaks.  The error is the difference in the intensity of that peak and the average for all equivalent
+peaks.  For example, see the 424 equivalent intensities in plot below.  The intensity of the peak at 
+wavelength 0.5 is marked as an outlier by setting the error to the same value as the intensity. 
+The average intensity is 21903.
+
+.. figure:: /images/EquivalentIntensities.png
+
 Usage
 -----
 
@@ -54,7 +63,7 @@ and rhombohedral centering:
                                CellType='Hexagonal', Apply=True, Tolerance=0.2)
 
     # Run the SortHKL algorithm
-    sorted, chi2, statistics_table = SortHKL(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)',
+    sorted, chi2, statistics_table, equivI = SortHKL(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)',
                                              LatticeCentering='Rhombohedrally centred, obverse')
 
     statistics = statistics_table.row(0)
diff --git a/docs/source/algorithms/SortPeaksWorkspace-v1.rst b/docs/source/algorithms/SortPeaksWorkspace-v1.rst
index 778c0d233b5477e056caf4346f14ef5b9a91d883..96c37db81220ac23e5d3f9e2c0a063fd40b1018d 100644
--- a/docs/source/algorithms/SortPeaksWorkspace-v1.rst
+++ b/docs/source/algorithms/SortPeaksWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortTableWorkspace-v1.rst b/docs/source/algorithms/SortTableWorkspace-v1.rst
index 1bc493ab2c08876f8b03e6d773df7486d5aa8f73..0394b2223facab3a984e7da23be81a67002c93fd 100644
--- a/docs/source/algorithms/SortTableWorkspace-v1.rst
+++ b/docs/source/algorithms/SortTableWorkspace-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SortXAxis-v1.rst b/docs/source/algorithms/SortXAxis-v1.rst
index 7b14bd708d4c134a878730a0d16c99aef8ae72cd..aaef5edd17efc6c3a9804b3604811134c493cd89 100644
--- a/docs/source/algorithms/SortXAxis-v1.rst
+++ b/docs/source/algorithms/SortXAxis-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -10,14 +10,12 @@ Description
 -----------
 
 Clones the input :ref:`Matrix Workspaces <MatrixWorkspace>` and orders the
-x-axis in an ascending fashion. Ensures that the y-axis and error data
-is sorted in a consistent way with the x-axis. All x-values of the input
-workspace MUST be in either a descending or ascending fashion before
-passing to this algorithm.
+x-axis in an ascending or descending fashion. Ensures that the y-axis and error data as well as optional Dx data
+are sorted in a consistent way with the x-axis.
 
 This algorithm is for use with small workspaces loaded. It is
 particularly suitable for reformatting workspaces loaded via
-:ref:`LoadAscii <algm-LoadAscii>`. Input workspaces must be a distribution.
+:ref:`LoadAscii <algm-LoadAscii>`. Input workspaces must be point data.
 
 .. categories::
 
diff --git a/docs/source/algorithms/SpatialGrouping-v1.rst b/docs/source/algorithms/SpatialGrouping-v1.rst
index 8093ac47e6fede7f321102f176ec2e6f88c902fd..2319b9bb8d5fab5acf022d1b089b13592c654f00 100644
--- a/docs/source/algorithms/SpatialGrouping-v1.rst
+++ b/docs/source/algorithms/SpatialGrouping-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst b/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst
index faf24f237d740145d56816a29192466502f1f445..fccdd37e59184ac0ee8aff44c31e26a417c016ab 100644
--- a/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst
+++ b/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst b/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst
index 14916278a924066a440ec166e136c372ca2854c9..f5c58e38e2527a198db6821259f84cf8014cd11b 100644
--- a/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst
+++ b/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst b/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst
index ae6d4ef34e12c33b1f3b39c740fe15c6f5b85900..a2d9cffa2c2079810e58da5ffc01cf2893868b77 100644
--- a/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst
+++ b/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst b/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst
index 827a62c624b5e4e071f7428bcef4f9243a30cc61..1773378e9535431b5681566d76f58f7b87bf97e1 100644
--- a/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst
+++ b/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SphericalAbsorption-v1.rst b/docs/source/algorithms/SphericalAbsorption-v1.rst
index 3d137c98345c06118837c2bf81fb2d13923ada88..2f1262a5dda0ced9aded76bde582787e40a25183 100644
--- a/docs/source/algorithms/SphericalAbsorption-v1.rst
+++ b/docs/source/algorithms/SphericalAbsorption-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SplineBackground-v1.rst b/docs/source/algorithms/SplineBackground-v1.rst
index f42331afc3c2f11c0640bb35c696f0cd18bffce7..29e87dffd4483e6cdf56fa4a7cede6d2c4b2a6dd 100644
--- a/docs/source/algorithms/SplineBackground-v1.rst
+++ b/docs/source/algorithms/SplineBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SplineInterpolation-v1.rst b/docs/source/algorithms/SplineInterpolation-v1.rst
index 0eafdfb4828a9b03c3101619a7a1f49233bbb3c4..3599cc0adeec3a3c331e708297f0e423abf88e1f 100644
--- a/docs/source/algorithms/SplineInterpolation-v1.rst
+++ b/docs/source/algorithms/SplineInterpolation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SplineSmoothing-v1.rst b/docs/source/algorithms/SplineSmoothing-v1.rst
index 1eaf64373a0d2fa2206956762ca36bedeaede88a..074d3dc85985862b468274462a215ee44723f0ba 100644
--- a/docs/source/algorithms/SplineSmoothing-v1.rst
+++ b/docs/source/algorithms/SplineSmoothing-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Squares-v1.rst b/docs/source/algorithms/Squares-v1.rst
index 2edc154dd395784fd226c6f5c977ee18db8b751a..b958f9d217bcc36ff65e1001d3bb2847c5d4fe33 100644
--- a/docs/source/algorithms/Squares-v1.rst
+++ b/docs/source/algorithms/Squares-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StartLiveData-v1.rst b/docs/source/algorithms/StartLiveData-v1.rst
index 8f4f36f574563fd5d987ae7fd9112cf7436a8df2..03cf63fcf7ac035c691aaaab96cbb2b3afd223bd 100644
--- a/docs/source/algorithms/StartLiveData-v1.rst
+++ b/docs/source/algorithms/StartLiveData-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -123,20 +123,22 @@ Usage
     def captureLive():
         ConfigService.setFacility("TEST_LIVE")
 
-        # start a Live data listener updating every second, that rebins the data
-        # and replaces the results each time with those of the last second.
-        StartLiveData(Instrument='ISIS_Event', OutputWorkspace='wsOut', UpdateEvery=1,
-                      ProcessingAlgorithm='Rebin', ProcessingProperties='Params=10000,1000,20000;PreserveEvents=1',
-                      AccumulationMethod='Add', PreserveEvents=True)
-
-        # give it a couple of seconds before stopping it
-        time.sleep(2)
-
-        # This will cancel both algorithms
-        # you can do the same in the GUI
-        # by clicking on the details button on the bottom right
-        AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
-        AlgorithmManager.newestInstanceOf("FakeISISEventDAE").cancel()
+        try:
+            # start a Live data listener updating every second, that rebins the data
+            # and replaces the results each time with those of the last second.
+            StartLiveData(Instrument='ISIS_Event', OutputWorkspace='wsOut', UpdateEvery=1,
+                          ProcessingAlgorithm='Rebin', ProcessingProperties='Params=10000,1000,20000;PreserveEvents=1',
+                          AccumulationMethod='Add', PreserveEvents=True)
+
+            # give it a couple of seconds before stopping it
+            time.sleep(2)
+        finally:
+            # This will cancel both algorithms
+            # you can do the same in the GUI
+            # by clicking on the details button on the bottom right
+            AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
+            AlgorithmManager.newestInstanceOf("FakeISISEventDAE").cancel()
+            time.sleep(1)
     #--------------------------------------------------------------------------------------------------
 
     oldFacility = ConfigService.getFacility().name()
@@ -187,20 +189,22 @@ Output:
     def captureLive():
         ConfigService.setFacility("TEST_LIVE")
 
-        # Start a Live data listener updating every second,
-        # that replaces the results each time with those of the last second.
-        # Load only spectra 2,4, and 6 from periods 1 and 3
-        StartLiveData(Instrument='ISIS_Histogram', OutputWorkspace='wsOut', UpdateEvery=1,
-                            AccumulationMethod='Replace', PeriodList=[1,3],SpectraList=[2,4,6])
-
-        # give it a couple of seconds before stopping it
-        time.sleep(2)
-
-        # This will cancel both algorithms
-        # you can do the same in the GUI
-        # by clicking on the details button on the bottom right
-        AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
-        AlgorithmManager.newestInstanceOf("FakeISISHistoDAE").cancel()
+        try:
+            # Start a Live data listener updating every second,
+            # that replaces the results each time with those of the last second.
+            # Load only spectra 2,4, and 6 from periods 1 and 3
+            StartLiveData(Instrument='ISIS_Histogram', OutputWorkspace='wsOut', UpdateEvery=1,
+                          AccumulationMethod='Replace', PeriodList=[1,3],SpectraList=[2,4,6])
+
+            # give it a couple of seconds before stopping it
+            time.sleep(2)
+        finally:
+            # This will cancel both algorithms
+            # you can do the same in the GUI
+            # by clicking on the details button on the bottom right
+            AlgorithmManager.newestInstanceOf("MonitorLiveData").cancel()
+            AlgorithmManager.newestInstanceOf("FakeISISHistoDAE").cancel()
+            time.sleep(1)
     #--------------------------------------------------------------------------------------------------
 
     oldFacility = ConfigService.getFacility().name()
diff --git a/docs/source/algorithms/StartRemoteTransaction-v1.rst b/docs/source/algorithms/StartRemoteTransaction-v1.rst
index a8ab4a1722e0686f22e507f8357fcf1d6d51e441..130597d207c3fea7f34fa6ffe95824e4ddbb8aed 100644
--- a/docs/source/algorithms/StartRemoteTransaction-v1.rst
+++ b/docs/source/algorithms/StartRemoteTransaction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StartRemoteTransaction-v2.rst b/docs/source/algorithms/StartRemoteTransaction-v2.rst
index cade65226dd4cab358d04453654ad38a37ffdeb1..830729b6a647edd1fbfca060a3cc6e457019895e 100644
--- a/docs/source/algorithms/StartRemoteTransaction-v2.rst
+++ b/docs/source/algorithms/StartRemoteTransaction-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst b/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst
index cade0d0e2388288483e86df048562cf501245e7e..1006e3c230463e9097c855aab7e2361da2fdc736 100644
--- a/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst
+++ b/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -62,7 +62,7 @@ Usage
                                CellType='Hexagonal', Apply=True, Tolerance=0.2)
 
     # Run the SortHKL algorithm
-    sorted, statistics_table = StatisticsOfPeaksWorkspace(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)',
+    sorted, statistics_table, equivI = StatisticsOfPeaksWorkspace(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)',
                                                           LatticeCentering='Rhombohedrally centred, obverse',
                                                           SortBy='Overall')
 
diff --git a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
index 5c2ac6f561fe5b3312c3a5065477e5f7c745109c..c53256425cb77e93e359f54406064e57e344bf98 100644
--- a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
+++ b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StepScan-v1.rst b/docs/source/algorithms/StepScan-v1.rst
index a280ea6762085e4555d3ee9f6c7fc4ff15810950..1bf845a392b374ce1fec3072e050a6fd07271f1b 100644
--- a/docs/source/algorithms/StepScan-v1.rst
+++ b/docs/source/algorithms/StepScan-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Stitch1D-v3.rst b/docs/source/algorithms/Stitch1D-v3.rst
index 010ebcdb32a900f7de9c9288609b80103db4dd53..f2286a97b3098b5e1f38cb2a98f858b2b4514193 100644
--- a/docs/source/algorithms/Stitch1D-v3.rst
+++ b/docs/source/algorithms/Stitch1D-v3.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -73,52 +73,70 @@ Usage
 -----
 **Example - a basic example using stitch1D to stitch two workspaces together.**
 
-.. testcode:: ExStitch1DSimple
+.. plot::
+   :include-source:
 
-    import numpy as np
+   from mantid.simpleapi import *
+   import matplotlib.pyplot as plt
+   import numpy as np
 
-    def gaussian(x, mu, sigma):
-      """Creates a gaussian peak centered on mu and with width sigma."""
-      return (1/ sigma * np.sqrt(2 * np.pi)) * np.exp( - (x-mu)**2  / (2*sigma**2))
+   def gaussian(x, mu, sigma):
+     """Creates a gaussian peak centered on mu and with width sigma."""
+     return (1/ sigma * np.sqrt(2 * np.pi)) * np.exp( - (x-mu)**2  / (2*sigma**2))
 
-    #create two histograms with a single peak in each one
-    x1 = np.arange(-1, 1, 0.02)
-    x2 = np.arange(0.4, 1.6, 0.02)
-    ws1 = CreateWorkspace(UnitX="1/q", DataX=x1, DataY=gaussian(x1[:-1], 0, 0.1)+1)
-    ws2 = CreateWorkspace(UnitX="1/q", DataX=x2, DataY=gaussian(x2[:-1], 1, 0.05)+1)
+   #create two histograms with a single peak in each one
+   x1 = np.arange(-1, 1, 0.02)
+   x2 = np.arange(0.4, 1.6, 0.02)
+   ws1 = CreateWorkspace(UnitX="1/q", DataX=x1, DataY=gaussian(x1[:-1], 0, 0.1)+1)
+   ws2 = CreateWorkspace(UnitX="1/q", DataX=x2, DataY=gaussian(x2[:-1], 1, 0.05)+1)
 
-    #stitch the histograms together
-    stitched, scale = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, StartOverlap=0.4, EndOverlap=0.6, Params=0.02)
+   #stitch the histograms together
+   stitched, scale = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, StartOverlap=0.4, EndOverlap=0.6, Params=0.02)
 
-Output:
+   # plot the individual workspaces alongside the stitched one
+   fig, axs = plt.subplots(nrows=1, ncols=2, subplot_kw={'projection':'mantid'})
 
-.. image:: /images/Stitch1D1.png
-   :scale: 65 %
-   :alt: Stitch1D output
-   :align: center
+   axs[0].plot(mtd['ws1'], wkspIndex=0, label='ws1')
+   axs[0].plot(mtd['ws2'], wkspIndex=0, label='ws2')
+   axs[0].legend()
+   axs[1].plot(mtd['stitched'], wkspIndex=0, color='k', label='stitched')
+   axs[1].legend()
 
+   # uncomment the following line to show the plot window
+   #fig.show()
 
 **Example - a practical example using reflectometry data and a scale factor.**
 
-.. testcode:: ExStitch1DPractical
+.. plot::
+   :include-source:
 
-    trans1 = Load('INTER00013463')
-    trans2 = Load('INTER00013464')
+   from mantid.simpleapi import *
+   import matplotlib.pyplot as plt
 
-    trans1_wav = CreateTransmissionWorkspaceAuto(trans1)
-    trans2_wav = CreateTransmissionWorkspaceAuto(trans2)
+   trans1 = Load('INTER00013463')
+   trans2 = Load('INTER00013464')
 
-    stitched_wav, y = Stitch1D(trans1_wav, trans2_wav, UseManualScaleFactor=True, ManualScaleFactor=0.85)
+   trans1_wav = CreateTransmissionWorkspaceAuto(trans1)
+   trans2_wav = CreateTransmissionWorkspaceAuto(trans2)
 
-Output:
+   stitched_wav, y = Stitch1D(trans1_wav, trans2_wav, UseManualScaleFactor=True, ManualScaleFactor=0.85)
 
-.. image:: /images/Stitch1D2.png
-   :scale: 65 %
-   :alt: Stitch1D output
-   :align: center
+   # plot the individual and stitched workspaces next to each other
+   fig, axs = plt.subplots(nrows=1, ncols=2, subplot_kw={'projection':'mantid'})
 
+   axs[0].plot(trans1_wav, wkspIndex=0, label=str(trans1_wav))
+   axs[0].plot(trans2_wav, wkspIndex=0, label=str(trans2_wav))
+   axs[0].legend()
+   # use same y scale on both plots
+   ylimits = axs[0].get_ylim()
+   axs[1].plot(stitched_wav, wkspIndex=0, color='k', label='stitched')
+   axs[1].legend()
+   axs[1].set_ylim(ylimits)
+
+   # uncomment the following line to show the plot window
+   #fig.show()
 
 .. categories::
 
 .. sourcelink::
-    :filename: Stitch1D
\ No newline at end of file
+    :filename: Stitch1D
diff --git a/docs/source/algorithms/Stitch1DMany-v1.rst b/docs/source/algorithms/Stitch1DMany-v1.rst
index 1b508dcb9c6d470f54de23ddbbebf7889a229026..20d10f3058aaa0dee2e8f26936c43b91d2a11181 100644
--- a/docs/source/algorithms/Stitch1DMany-v1.rst
+++ b/docs/source/algorithms/Stitch1DMany-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StopRemoteTransaction-v1.rst b/docs/source/algorithms/StopRemoteTransaction-v1.rst
index 125656b108fe494c806b3984df79df49ecdacd18..9ac246ac8918df64d0a89a57ed51ed49b1e1cdd5 100644
--- a/docs/source/algorithms/StopRemoteTransaction-v1.rst
+++ b/docs/source/algorithms/StopRemoteTransaction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StopRemoteTransaction-v2.rst b/docs/source/algorithms/StopRemoteTransaction-v2.rst
index 70fbf3dabbfc0f488010983b5e233e43875175f5..cf35f859f7bb4129a2c333f5f2027cec55d8d181 100644
--- a/docs/source/algorithms/StopRemoteTransaction-v2.rst
+++ b/docs/source/algorithms/StopRemoteTransaction-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StringToPng-v1.rst b/docs/source/algorithms/StringToPng-v1.rst
index 8e4af71b1a73a082ac4ee32db17d26b651275abf..9b4fc275e1656801726fd67439c5b0710264196b 100644
--- a/docs/source/algorithms/StringToPng-v1.rst
+++ b/docs/source/algorithms/StringToPng-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StripPeaks-v1.rst b/docs/source/algorithms/StripPeaks-v1.rst
index d78e605fca96681079ed638e6165ba88f77a6f3f..4f80cbf26663c077cfc1f610c176f6ed1e9f2e9e 100644
--- a/docs/source/algorithms/StripPeaks-v1.rst
+++ b/docs/source/algorithms/StripPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StripVanadiumPeaks-v1.rst b/docs/source/algorithms/StripVanadiumPeaks-v1.rst
index 8f8750870176b01770c6a5c18681f148c87c6f58..d3e4307fb67b2ac60db7eaab66236099c014489a 100644
--- a/docs/source/algorithms/StripVanadiumPeaks-v1.rst
+++ b/docs/source/algorithms/StripVanadiumPeaks-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/StripVanadiumPeaks-v2.rst b/docs/source/algorithms/StripVanadiumPeaks-v2.rst
index 9e7e84e974cb2c51e5204d445e089fb2987920fd..57a03fdff2ce6bae3ec9ca52c82046826b130318 100644
--- a/docs/source/algorithms/StripVanadiumPeaks-v2.rst
+++ b/docs/source/algorithms/StripVanadiumPeaks-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SubmitRemoteJob-v1.rst b/docs/source/algorithms/SubmitRemoteJob-v1.rst
index 98739d05b7da1d0296c719578b54d8986a660c67..3f8281395e18db86fb1ec3522357ceb7c88703a7 100644
--- a/docs/source/algorithms/SubmitRemoteJob-v1.rst
+++ b/docs/source/algorithms/SubmitRemoteJob-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SubmitRemoteJob-v2.rst b/docs/source/algorithms/SubmitRemoteJob-v2.rst
index cfc51ebbe4149ede98e8f3f571078cb0fcbcfceb..bcb7b407bf9cde4e07b2d37e42fc8e6bd1d5cc64 100644
--- a/docs/source/algorithms/SubmitRemoteJob-v2.rst
+++ b/docs/source/algorithms/SubmitRemoteJob-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SuggestTibCNCS-v1.rst b/docs/source/algorithms/SuggestTibCNCS-v1.rst
index 04af26e480ae5241e2c39777686b7c0788fc9224..79fdb56fb35b03cac380eded0170fc95baf1f9a1 100644
--- a/docs/source/algorithms/SuggestTibCNCS-v1.rst
+++ b/docs/source/algorithms/SuggestTibCNCS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SuggestTibHYSPEC-v1.rst b/docs/source/algorithms/SuggestTibHYSPEC-v1.rst
index b840407d0a4a5fe041dd351de7aa3a6007195e5c..eab72f852823cf2b7db1fc8f8da1240b9138bd6e 100644
--- a/docs/source/algorithms/SuggestTibHYSPEC-v1.rst
+++ b/docs/source/algorithms/SuggestTibHYSPEC-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SumEventsByLogValue-v1.rst b/docs/source/algorithms/SumEventsByLogValue-v1.rst
index 5dd2f94f0ded72b132ba604cb15a29617ba4b47a..32b8f891ea8b3c70a836a26711be030ad28244f5 100644
--- a/docs/source/algorithms/SumEventsByLogValue-v1.rst
+++ b/docs/source/algorithms/SumEventsByLogValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -80,9 +80,9 @@ Output:
 .. testoutput:: Single-Spectrum
 
     Events were split into 3 sections based on the log 'Log2FilterBy'.
-     section 1: 615.00
-     section 2: 629.00
-     section 3: 656.00
+     section 1: 6...
+     section 2: 6...
+     section 3: 6...
     Totalling 1900 events, matching the 1900 events in the input workspace
 
 
diff --git a/docs/source/algorithms/SumNeighbours-v1.rst b/docs/source/algorithms/SumNeighbours-v1.rst
index 628123ad700e594f4f6506f61c77c2fd7fb03ff8..eead73708f1265da353807d540749ebb73c50880 100644
--- a/docs/source/algorithms/SumNeighbours-v1.rst
+++ b/docs/source/algorithms/SumNeighbours-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SumOverlappingTubes-v1.rst b/docs/source/algorithms/SumOverlappingTubes-v1.rst
index 733646374c1ed2fdb19119b2c9dc2d0f39c7e47f..f8aaa9319484d4567d0f23baf94ada994ffdaf5b 100644
--- a/docs/source/algorithms/SumOverlappingTubes-v1.rst
+++ b/docs/source/algorithms/SumOverlappingTubes-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
@@ -20,9 +20,9 @@ For the output workspace a grid is made, the x-axis is the scattering angle and
 
 If the Normalise option is set then the counts for each point in the OutputWorkspace are divided by the number of contributing points to that pixel. The scaling goes as
 
-.. math:: C_{scaled, i} = \frac{N_{max}}{N_{i}} C_i
+.. math:: C_{scaled, i} = \frac{C_i}{N_{i}}
 
-where :math:`C_{scaled, i}` is the scaled counts, :math:`C_i` the raw counts, :math:`N_{max}` is the maximum number of tube pixels contributing to any point in the OutputWorkspace, and :math:`N_{i}` is the number of tube pixels contributing to the point being scaled.
+where :math:`C_{scaled, i}` is the scaled counts, :math:`C_i` the raw counts, and :math:`N_{i}` is the number of tube pixels contributing to the point being scaled.
 
 2DTubes Option
 ++++++++++++++
@@ -51,40 +51,28 @@ Usage
 .. testcode:: SumOverlappingTubes2DComponent
 
     ws_508093 = Load('ILL/D2B/508093.nxs')
-    ws = SumOverlappingTubes(InputWorkspaces=ws_508093, OutputType='2DTubes')
+    ws = SumOverlappingTubes(InputWorkspaces=ws_508093, OutputType='2DTubes', MirrorScatteringAngles=True)
     print('X Size: ' + str(ws.blocksize()) + ', Y Size: ' + str(ws.getNumberHistograms()))
-    print('Counts: ' + str(ws.dataY(63)[2068:2078]))
-    print('Errors: ' + str(ws.dataE(63)[2068:2078]))
 
 Output:
 
 .. testoutput:: SumOverlappingTubes2DComponent
 
     X Size: 3200, Y Size: 128
-    Counts: [  4.46083333   9.72705882  13.1016      19.74509804  27.49234043
-      24.62941176  30.25076923  23.2776      10.01591837   1.06      ]
-    Errors: [ 2.03598273  3.00072517  3.46216187  4.1661015   5.29106717  4.88935243
-      5.28366714  4.68457643  3.1474581   0.96348311]
 
 **Example - an example of running SumOverlappingTubes in the 1D case.**
 
 .. testcode:: SumOverlappingTubes1DHeightRange
 
     ws_508093 = Load('ILL/D2B/508093.nxs')
-    ws = SumOverlappingTubes(InputWorkspaces=ws_508093, OutputType='1D', CropNegativeScatteringAngles=True, HeightAxis='-0.05,0.05')
+    ws = SumOverlappingTubes(InputWorkspaces=ws_508093, OutputType='1D', CropNegativeScatteringAngles=True, HeightAxis='-0.05,0.05', MirrorScatteringAngles=True)
     print('X Size: ' + str(ws.blocksize()) + ', Y Size: ' + str(ws.getNumberHistograms()))
-    print('Counts: ' + str(ws.dataY(0)[2068:2078]))
-    print('Errors: ' + str(ws.dataE(0)[2068:2078]))
 
 Output:
 
 .. testoutput:: SumOverlappingTubes1DHeightRange
 
     X Size: 2975, Y Size: 1
-    Counts: [ 127.08681254  131.10979889  201.71370827  233.54556754  296.48915172
-      286.24790285  260.59967375  188.05934431  143.70447835  113.86610964]
-    Errors: [ 12.79221591  12.49380558  15.76125177  16.4410194   20.01917432
-      19.39744376  18.06430971  15.28768958  13.52007099  11.44274953]
 
 .. categories::
 
diff --git a/docs/source/algorithms/SumRowColumn-v1.rst b/docs/source/algorithms/SumRowColumn-v1.rst
index 3515c060ba5d23cfe0c85eaaf789ea844c1b5ad7..55804d31c4366aec550af6ed1419e7930aef5fc1 100644
--- a/docs/source/algorithms/SumRowColumn-v1.rst
+++ b/docs/source/algorithms/SumRowColumn-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SumSpectra-v1.rst b/docs/source/algorithms/SumSpectra-v1.rst
index c25ddcdb0b8d30a816bf20825678661357775b15..824e84c11ba07b23188ecdb825f971858c8d8505 100644
--- a/docs/source/algorithms/SumSpectra-v1.rst
+++ b/docs/source/algorithms/SumSpectra-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/SwapWidths-v1.rst b/docs/source/algorithms/SwapWidths-v1.rst
index 72bb112d72922f63c023b9093e4835c0e45ec41b..c1360be66769c03204ed6b28cc9d6a65333b0cc1 100644
--- a/docs/source/algorithms/SwapWidths-v1.rst
+++ b/docs/source/algorithms/SwapWidths-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Symmetrise-v1.rst b/docs/source/algorithms/Symmetrise-v1.rst
index 1ff18b6d42c8359c3d06502bc736848929b12249..43edae0384ddcd4317b63b2a07c361a2252619d7 100644
--- a/docs/source/algorithms/Symmetrise-v1.rst
+++ b/docs/source/algorithms/Symmetrise-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TOFSANSResolution-v1.rst b/docs/source/algorithms/TOFSANSResolution-v1.rst
index 1de749e2a305b2576b623122936d8904607c2aba..404c8dce40d4245fe1d4a90d10327f1ed2aaee05 100644
--- a/docs/source/algorithms/TOFSANSResolution-v1.rst
+++ b/docs/source/algorithms/TOFSANSResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst b/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst
index 4c651b60bb5f059c0733f88022c229c5410c35a6..19c146448cfdfe07fc61c469ccade7564ac13a94 100644
--- a/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst
+++ b/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst
index 5401eb666efa47c9342ab0c393994f05e775b219..57c006727d5b51be9ef7e4252e8cf3661c7ed38b 100644
--- a/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst
+++ b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TOFTOFMergeRuns-v1.rst b/docs/source/algorithms/TOFTOFMergeRuns-v1.rst
index 9ebcd6ad5f0d8ad71a1ad6f750068830813bf04d..b7b8c9b38f26a5b6ea8baf9a0e1adb61e150b865 100644
--- a/docs/source/algorithms/TOFTOFMergeRuns-v1.rst
+++ b/docs/source/algorithms/TOFTOFMergeRuns-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TOSCABankCorrection-v1.rst b/docs/source/algorithms/TOSCABankCorrection-v1.rst
index 246cd57c330a0915f2610dc70df9e18f9d5879f6..9f62e5ec8bbf17a9a9c85de53fb9f9edb5e76e56 100644
--- a/docs/source/algorithms/TOSCABankCorrection-v1.rst
+++ b/docs/source/algorithms/TOSCABankCorrection-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst b/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst
index 6697bc246c57291bf8c069eb583e816c45d1e2fd..49761c3a3f36de52dd20667ff7872b34ca93f403 100644
--- a/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst
+++ b/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ThresholdMD-v1.rst b/docs/source/algorithms/ThresholdMD-v1.rst
index b093fe10fb312c62f9bcc9f8f68e5062a4cbefb0..d36b21dcb20717f7235fdc5bb4e4ac674aaf11ec 100644
--- a/docs/source/algorithms/ThresholdMD-v1.rst
+++ b/docs/source/algorithms/ThresholdMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TimeSlice-v1.rst b/docs/source/algorithms/TimeSlice-v1.rst
index 1093650e891166430a8f25312dab44c8f5e89367..fade64354530b6e210c7ec8f0469966278ee4998 100644
--- a/docs/source/algorithms/TimeSlice-v1.rst
+++ b/docs/source/algorithms/TimeSlice-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TransformHKL-v1.rst b/docs/source/algorithms/TransformHKL-v1.rst
index f7259e66b77854540c4f71f55438ba1e7c26eb1e..c45332e0205fa886e625e1c02fe7676c1a65a8c4 100644
--- a/docs/source/algorithms/TransformHKL-v1.rst
+++ b/docs/source/algorithms/TransformHKL-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TransformMD-v1.rst b/docs/source/algorithms/TransformMD-v1.rst
index e2df2485a9273ca636b9f23cc0992f5020aad00f..30d35a37f53492a9eec02f234554802b3757c7c7 100644
--- a/docs/source/algorithms/TransformMD-v1.rst
+++ b/docs/source/algorithms/TransformMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TransformToIqt-v1.rst b/docs/source/algorithms/TransformToIqt-v1.rst
index 65aa3e41c86194f75c46dfdb4604885438194705..fd6e7093f6bc586520fc4a3c0660b8cb1d2058d9 100644
--- a/docs/source/algorithms/TransformToIqt-v1.rst
+++ b/docs/source/algorithms/TransformToIqt-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Transpose-v1.rst b/docs/source/algorithms/Transpose-v1.rst
index 0f1b630b43aabf2003e227a0a3dd40c331514c1c..84cf52e8f8dc154e84921d75be91276b63a8cf70 100644
--- a/docs/source/algorithms/Transpose-v1.rst
+++ b/docs/source/algorithms/Transpose-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/Transpose3D-v1.rst b/docs/source/algorithms/Transpose3D-v1.rst
index ddb63add8e176353a946bc29be50902aaf202b18..386411cd11094d4181b14b9b016d4e1ef184c4c0 100644
--- a/docs/source/algorithms/Transpose3D-v1.rst
+++ b/docs/source/algorithms/Transpose3D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/TransposeMD-v1.rst b/docs/source/algorithms/TransposeMD-v1.rst
index 3d2715ce1eee33da28cc1dee78cc50792ddfb75c..72c3487cae2d45ff5ba715b4518a3806a5af7ad0 100644
--- a/docs/source/algorithms/TransposeMD-v1.rst
+++ b/docs/source/algorithms/TransposeMD-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/USANSReduction-v1.rst b/docs/source/algorithms/USANSReduction-v1.rst
index 9f069271b9a234ca772f423c6e4d8fc922296fcf..8779eac3736ab57c4fffde8babe45ad72573ab0b 100644
--- a/docs/source/algorithms/USANSReduction-v1.rst
+++ b/docs/source/algorithms/USANSReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/USANSSimulation-v1.rst b/docs/source/algorithms/USANSSimulation-v1.rst
index d785a71a2e2b428dce37fce865f14762b4b0386d..c549f0bfd1f6cc36464cf2658110353353ee8222 100644
--- a/docs/source/algorithms/USANSSimulation-v1.rst
+++ b/docs/source/algorithms/USANSSimulation-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UnGroupWorkspace-v1.rst b/docs/source/algorithms/UnGroupWorkspace-v1.rst
index 4e4a3c37951eac3e05f6a4b1d55e0195b5ac859e..8f84d2a36b2c9ad45abd9da1f7fad74c3759149d 100644
--- a/docs/source/algorithms/UnGroupWorkspace-v1.rst
+++ b/docs/source/algorithms/UnGroupWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UnwrapMonitor-v1.rst b/docs/source/algorithms/UnwrapMonitor-v1.rst
index 946dfe9321306d5f6923af28501076e07c6ed507..16c242f67f603fd25bea6aad661a89735c711435 100644
--- a/docs/source/algorithms/UnwrapMonitor-v1.rst
+++ b/docs/source/algorithms/UnwrapMonitor-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst b/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst
index ac81cb41e135c4655dd352112adfbaee61ffb0de..4330b6de5502c424625e8db28784ac0a2940b340 100644
--- a/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst
+++ b/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UnwrapSNS-v1.rst b/docs/source/algorithms/UnwrapSNS-v1.rst
index 2ebcc6c4e9548e1af53e0d947f3166ec0799be18..39b1d63ff8e35ce04a4ce5cbe107f6ac5a9e8ddf 100644
--- a/docs/source/algorithms/UnwrapSNS-v1.rst
+++ b/docs/source/algorithms/UnwrapSNS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst b/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst
index 93ded29927b80a03b4a74cb446ce5a231ee00052..81011f0bd5dae09b9f00aca91f8fea1ec9f88d20 100644
--- a/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst
+++ b/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst b/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst
index ac2bcafff2dedc7c70b00951b83400417d8c4e50..dea5efa30f2fec5e3397494e08acbcc291d715d0 100644
--- a/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst
+++ b/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UpdateScriptRepository-v1.rst b/docs/source/algorithms/UpdateScriptRepository-v1.rst
index a5800a9a21756d7ec15f16d7042fa4bf37ca7441..72188b53aee893c024da2aa44d81842740c52cfe 100644
--- a/docs/source/algorithms/UpdateScriptRepository-v1.rst
+++ b/docs/source/algorithms/UpdateScriptRepository-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UploadRemoteFile-v1.rst b/docs/source/algorithms/UploadRemoteFile-v1.rst
index 651dca4bb1b4febe1c098fad59582d6d7bb85368..058a5b2e4c262ec9b4e639b9773a294e4534b7a0 100644
--- a/docs/source/algorithms/UploadRemoteFile-v1.rst
+++ b/docs/source/algorithms/UploadRemoteFile-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UploadRemoteFile-v2.rst b/docs/source/algorithms/UploadRemoteFile-v2.rst
index 64e73c925b4502edba067a1024da2739ec58f4fc..83449f2f1d737370731af0b1f49d3a80e09cf3db 100644
--- a/docs/source/algorithms/UploadRemoteFile-v2.rst
+++ b/docs/source/algorithms/UploadRemoteFile-v2.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/UserFunction1D-v1.rst b/docs/source/algorithms/UserFunction1D-v1.rst
index 1d6a7543bf0f30eee1a89163fe09d090f06fa954..c0cd951ed5a69f51ff12e597d0cb3af0e69cf61e 100644
--- a/docs/source/algorithms/UserFunction1D-v1.rst
+++ b/docs/source/algorithms/UserFunction1D-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VelocityAutoCorrelations-v1.rst b/docs/source/algorithms/VelocityAutoCorrelations-v1.rst
index 79cc52d0f10d56e55ae676328d2621f16d0fd845..f7e87a97cef625d8c90eb28fdaa5231052f0f638 100644
--- a/docs/source/algorithms/VelocityAutoCorrelations-v1.rst
+++ b/docs/source/algorithms/VelocityAutoCorrelations-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst
index 1921525dadaa102300e54038144182877edb09bd..5dfdb25767afb3aeb69bbf466a4c07b50b0a4adf 100644
--- a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst
+++ b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst b/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst
index 1f627b96cbc28d9ee874707435dcedbd1ae621b7..635e2a8cf6d88507625be070eb0a9068816e628b 100644
--- a/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst
+++ b/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioCalculateMS-v1.rst b/docs/source/algorithms/VesuvioCalculateMS-v1.rst
index cbdf39587559556ed85e7e9f39cadf9617f3c4cd..8d767a4d48c5c550f46995bf1bf402656f4d0500 100644
--- a/docs/source/algorithms/VesuvioCalculateMS-v1.rst
+++ b/docs/source/algorithms/VesuvioCalculateMS-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioCorrections-v1.rst b/docs/source/algorithms/VesuvioCorrections-v1.rst
index 44259cdf5b1bbe72ad272d1c13cece74ed93aaa5..df786dfde681b710691dd874175a30d49fe63663 100644
--- a/docs/source/algorithms/VesuvioCorrections-v1.rst
+++ b/docs/source/algorithms/VesuvioCorrections-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst b/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst
index 7e040f332f19c5298052d73e831fc00546dd9c4c..cfd9527e29fafae4b4c9e942a3583d252955b768 100644
--- a/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst
+++ b/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst b/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst
index c27d0c3dc6dd974bee56930d111dbe3fe3d8aaa8..66258996068707e65d205dac2467bf66ff6ac105 100644
--- a/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst
+++ b/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioPeakPrediction-v1.rst b/docs/source/algorithms/VesuvioPeakPrediction-v1.rst
index 1277abd0fcb2f54ef2316fb7c413a36050c3a30e..6404c8dc759aeb07fdbeb4462a2faf0b242c433e 100644
--- a/docs/source/algorithms/VesuvioPeakPrediction-v1.rst
+++ b/docs/source/algorithms/VesuvioPeakPrediction-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioPreFit-v1.rst b/docs/source/algorithms/VesuvioPreFit-v1.rst
index cd754da96cc197bec1df33bc487d18d59af542ed..c58ca280e29318310e6b5fb7c847a7da74117438 100644
--- a/docs/source/algorithms/VesuvioPreFit-v1.rst
+++ b/docs/source/algorithms/VesuvioPreFit-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioResolution-v1.rst b/docs/source/algorithms/VesuvioResolution-v1.rst
index 96a8742dedabc6cc24e4514fcead1b1b8cce46a4..dd7dc085ca565b8bf4dee0d667f2de4059b76d7f 100644
--- a/docs/source/algorithms/VesuvioResolution-v1.rst
+++ b/docs/source/algorithms/VesuvioResolution-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioTOFFit-v1.rst b/docs/source/algorithms/VesuvioTOFFit-v1.rst
index 44161ced3684a58b9cfbe710f7d7f2645d822c62..559ad342a23acfd20bb295ee474715038cbc5ca7 100644
--- a/docs/source/algorithms/VesuvioTOFFit-v1.rst
+++ b/docs/source/algorithms/VesuvioTOFFit-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VesuvioThickness-v1.rst b/docs/source/algorithms/VesuvioThickness-v1.rst
index 9933d3fe52a4a0b0fa7919ddc60a6511d7012ca5..fa04a4cdd4cd3612e958f270284b81696368affd 100644
--- a/docs/source/algorithms/VesuvioThickness-v1.rst
+++ b/docs/source/algorithms/VesuvioThickness-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/ViewBOA-v1.rst b/docs/source/algorithms/ViewBOA-v1.rst
index 8593a7c111ff00b682eb8dcc7b79030a355a74fc..a32bba25f598072f4e951796e86189c6853c46c5 100644
--- a/docs/source/algorithms/ViewBOA-v1.rst
+++ b/docs/source/algorithms/ViewBOA-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/VisionReduction-v1.rst b/docs/source/algorithms/VisionReduction-v1.rst
index 505fb6688264bf715442aaec40fe1efc0fb28dd6..318a948b85bcb3e1cce8700effca3e33a9cd28fb 100644
--- a/docs/source/algorithms/VisionReduction-v1.rst
+++ b/docs/source/algorithms/VisionReduction-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/WANDPowderReduction-v1.rst b/docs/source/algorithms/WANDPowderReduction-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..02de1c633908e1fca4253c474cea6b5a07d89880
--- /dev/null
+++ b/docs/source/algorithms/WANDPowderReduction-v1.rst
@@ -0,0 +1,91 @@
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm performs powder diffraction data reduction for WAND²
+with calibration, monitor normalization and background subtraction.
+The CalibrationWorkspace will most likely be a vanadium and will
+correct for the detector sensitivity. The data can be normalized by
+monitor count or time.  The output workspace can be saved to various
+formats with :ref:`SaveFocusedXYE <algm-SaveFocusedXYE>`.
+
+It is recommenced to load WAND data with :ref:`LoadWAND
+<algm-LoadWAND>` as the wavelength/energy will be set correctly and
+monitor counts correctly taken into account for normalization. This
+algorithm will work on data loaded with :ref:`LoadEventNexus
+<algm-LoadEventNexus>` or the grouped output from :ref:`FilterEvents
+<algm-FilterEvents>` but you will need to specify `EFixed` if
+converting to anything except `Theta`.
+
+
+MaskAngle
+#########
+
+The MaskAngle option will mask any out-of-plane (phi angle) detector
+larger than this value using :ref:`MaskAngle <algm-MaskAngle>`. This
+can help with peak sharpness by removing regions where there is large
+peak broadening due to the divergent beam. The example below using
+MaskAngle of 10.
+
+.. figure:: /images/WANDPowderReduction_MaskAngle.png
+
+Usage
+-----
+
+**Silicon powder**
+
+.. code-block:: python
+
+   silicon =LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26506.nxs.h5')
+   vanadium=LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26509.nxs.h5')
+
+   WANDPowderReduction(InputWorkspace=silicon,
+                       CalibrationWorkspace=vanadium,
+                       Target='Theta',
+                       NumberBins=1000,
+                       OutputWorkspace='silicon_powder')
+
+.. figure:: /images/WANDPowderReduction_silicon_powder.png
+
+**Silicon powder to Q over limited range**
+
+.. code-block:: python
+
+   silicon =LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26506.nxs.h5')
+   vanadium=LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26509.nxs.h5')
+
+   WANDPowderReduction(InputWorkspace=silicon,
+                       CalibrationWorkspace=vanadium,
+                       Target='ElasticQ',
+                       XMin=4.5,
+                       Xmax=6.25,
+                       NumberBins=500,
+                       OutputWorkspace='silicon_powder_q')
+
+.. figure:: /images/WANDPowderReduction_silicon_powder_q.png
+
+**Silicon powder to D spacing**
+
+.. code-block:: python
+
+   silicon2=LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26507.nxs.h5')
+   vanadium=LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26509.nxs.h5')
+
+   WANDPowderReduction(InputWorkspace=silicon2,
+                       CalibrationWorkspace=vanadium,
+                       Target='ElasticDSpacing',
+                       NumberBins=1000,
+                       OutputWorkspace='silicon_powder_d_spacing')
+
+.. figure:: /images/WANDPowderReduction_silicon_powder_d.png
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/WeightedMean-v1.rst b/docs/source/algorithms/WeightedMean-v1.rst
index c442760088bbcc79487f6b5aac6f846b6dbda992..ac5a7caa55b9c8472a7d4ab487c2b0e9d82d344e 100644
--- a/docs/source/algorithms/WeightedMean-v1.rst
+++ b/docs/source/algorithms/WeightedMean-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/WeightedMeanMD-v1.rst b/docs/source/algorithms/WeightedMeanMD-v1.rst
index a3cfcda5467970de2f6d4d99ef38d620d621a6dd..d62a77c1e13b857d3500f5a7439bfec45b0127ad 100644
--- a/docs/source/algorithms/WeightedMeanMD-v1.rst
+++ b/docs/source/algorithms/WeightedMeanMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst b/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst
index 637b0379f9d50d8bd4d04b93e02c18360c76ea3b..25aee5bfda8d44d2a7b4baff211001eaeea107df 100644
--- a/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst
+++ b/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/WienerSmooth-v1.rst b/docs/source/algorithms/WienerSmooth-v1.rst
index bc20a9709c73db2cf919da55c6431504cffe6f75..6c71c5a4fd6a809b98e521df46fd6fd38586fb70 100644
--- a/docs/source/algorithms/WienerSmooth-v1.rst
+++ b/docs/source/algorithms/WienerSmooth-v1.rst
@@ -3,7 +3,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst
index b8e98b33c731f2041534d1d7d75720eba3d7ec28..026912cf5675031185dec48001d3e30bcbfd7e96 100644
--- a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst
+++ b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/algorithms/XorMD-v1.rst b/docs/source/algorithms/XorMD-v1.rst
index b25e5f071a2a363958c44cb07937a5b58df70a0f..20afc84b46bc235fdbb9d263e32a6811b1c56487 100644
--- a/docs/source/algorithms/XorMD-v1.rst
+++ b/docs/source/algorithms/XorMD-v1.rst
@@ -2,7 +2,7 @@
 
 .. summary::
 
-.. alias::
+.. relatedalgorithms::
 
 .. properties::
 
diff --git a/docs/source/api/python/index.rst b/docs/source/api/python/index.rst
index 3490c7c58bb7cd9cdb70b3e5ede4a0ce6095bdc4..916a08dcbca686f1852057cb793b7d5aa5ff5a35 100644
--- a/docs/source/api/python/index.rst
+++ b/docs/source/api/python/index.rst
@@ -11,14 +11,6 @@ If you are new to Python in Mantid then we advise first looking at our `Mantid t
 For tutorials on how to use python in MantidPlot please see `MantidPlot: Python Scripting <https://www.mantidproject.org/MantidPlot:_Python_Scripting>`_.
 
 
-Matplotlib-like plotting interface
-----------------------------------
-
-.. toctree::
-   :maxdepth: 1
-
-   mantidplot.pyplot <mantidplot/pyplot/index>
-
 Reference
 ---------
 .. toctree::
diff --git a/docs/source/api/python/mantidplot/index.rst b/docs/source/api/python/mantidplot/index.rst
index a2be3b03524fc5774817e24b4c160eb8f9ac71ef..ade8a9d5a160d17b240f8156464f6c441ea5b78e 100644
--- a/docs/source/api/python/mantidplot/index.rst
+++ b/docs/source/api/python/mantidplot/index.rst
@@ -49,7 +49,6 @@ This package defines the Python interface to the MantidPlot application. For fra
    newTable.rst
    new_proxy.rst
    note.rst
-   plot.rst
    plot2D.rst
    plot3D.rst
    plotBin.rst
@@ -72,11 +71,3 @@ This package defines the Python interface to the MantidPlot application. For fra
    waterfallPlot.rst
    windows.rst
    workspace.rst
-
-Submodules
-##########
-
-.. toctree::
-   :maxdepth: 1
-
-   pyplot/index
diff --git a/docs/source/api/python/mantidplot/plot.rst b/docs/source/api/python/mantidplot/plot.rst
deleted file mode 100644
index bd58de32ef173d502b38ecaf0c0761ad0007ca65..0000000000000000000000000000000000000000
--- a/docs/source/api/python/mantidplot/plot.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-======
- plot
-======
-
-.. module:`mantidplot`
-
-.. autofunction:: mantidplot.plot
-
diff --git a/docs/source/api/python/mantidplot/pyplot/index.rst b/docs/source/api/python/mantidplot/pyplot/index.rst
deleted file mode 100644
index 824d782aa05e6b6b660935b266beaf008c64d629..0000000000000000000000000000000000000000
--- a/docs/source/api/python/mantidplot/pyplot/index.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-===================================================
- :mod:`pyplot` --- Matplotlib-like plotting package
-===================================================
-
-New plotting interface
-----------------------
-
-This package provides a simple command line interface to the Mantid
-plotting functionality, resembling matplotlib and its pyplot package
-(http://matplotlib.org). The module is subject to changes and feedback
-is very much welcome!
-
-.. automodule:: pymantidplot.pyplot
-   :members:
-   :show-inheritance:
diff --git a/docs/source/concepts/CrystalStructureAndReflections.rst b/docs/source/concepts/CrystalStructureAndReflections.rst
index 78c8e6ead4926a699c4bf5ddc6c09820a15443ba..1b2138f8ef9287e5c12d9a48ed801ea7b74f84ec 100644
--- a/docs/source/concepts/CrystalStructureAndReflections.rst
+++ b/docs/source/concepts/CrystalStructureAndReflections.rst
@@ -253,7 +253,7 @@ to the process for :math:`F^2`:
 
     # Make list of tuples and sort by d-values, descending, include point group for multiplicity.
     reflections = sorted([(hkl, d, fsq, len(pg.getEquivalents(hkl))) for hkl, d, fsq in zip(hkls, dValues, fSquared)],
-                                    key=lambda x: x[1], reverse=True)
+                                    key=lambda x: x[1] - x[0][0]*1e-6, reverse=True)
 
     print('{0:<8}{1:>8}{2:>8}{3:>4}'.format('HKL', 'd', 'F^2', 'M'))
     for reflection in reflections:
diff --git a/docs/source/concepts/EventWorkspace.rst b/docs/source/concepts/EventWorkspace.rst
index 10237187096466eac745d4464ab069fd0950f254..ad7ba6b3e7c27e8ade87abaf95faaac1c8218239 100644
--- a/docs/source/concepts/EventWorkspace.rst
+++ b/docs/source/concepts/EventWorkspace.rst
@@ -194,12 +194,12 @@ Please note these should only be done as part of a Python Algorithm, otherwise t
    :hide:
    :options: +ELLIPSIS,+NORMALIZE_WHITESPACE
 
-   First pulse time before addPulsetime: 2010-01-01T00:32:55...
-   First pulse time after addPulsetime: 2010-01-01T00:36:15...
-   First tof before addTof: 118...
-   First tof after addTof: 121...
-   First tof before scaleTof: 121...
-   First tof after scaleTof: 181...
+   First pulse time before addPulsetime: 2010-01-01T00:3...
+   First pulse time after addPulsetime: 2010-01-01T00:3...
+   First tof before addTof: 1...
+   First tof after addTof: 1...
+   First tof before scaleTof: 1...
+   First tof after scaleTof: 2...
    First event weight before multiply: 1.0... +/- 1.0...
    First event weight after multiply: 10.0 +/- 3.34...
    First event weight before divide: 10.0 +/- 3.34...
diff --git a/docs/source/concepts/PeaksWorkspace.rst b/docs/source/concepts/PeaksWorkspace.rst
index d6c43dbd29df77dd17d972089f366459c41f7c73..1195279873f749a0475002717924a79335cf1d04 100644
--- a/docs/source/concepts/PeaksWorkspace.rst
+++ b/docs/source/concepts/PeaksWorkspace.rst
@@ -49,6 +49,27 @@ Each Peak object contains a PeakShape. Only the integration algorithms which act
 Subtypes of PeakShape will then provide additional information. For example PeakShapeSpherical provides the radius as well as background inner, and background outer radius.
 
 
+Calculate Goniometer For Constant Wavelength
+--------------------------------------------
+
+If you set the `wavelength` (in Ã…) or `energy` (in meV) property on a
+PeaksWorkspace when the createPeak method is used the goniometer
+rotation with be calculated. This allows you to use one instrument
+definition for multiple goniometer rotations, for example adding peaks
+in Slice Viewer from multiple combined MD workspaces. It only works
+for a constant wavelength source and only for Q sample workspaces. It
+also assumes the goniometer rotation is around the y-axis only. For
+details on the calculation see "Calculate Goniometer For Constant
+Wavelength" at :ref:`FindPeaksMD <algm-FindPeaksMD>`.
+
+.. code-block:: python
+
+    pws = mtd['name_of_peaks_workspace']
+    pws.run().addProperty('wavelength', 1.54, True)
+    # or
+    pws.run().addProperty('energy', 34.48, True)
+
+
 Using PeaksWorkspaces in Python
 ---------------------------------
 
diff --git a/docs/source/concepts/UnitFactory.rst b/docs/source/concepts/UnitFactory.rst
index fa884d662317037f7259a22d9fa28634835ce84e..60c483028f2fbc15caf9c12d30da34b267f412f6 100644
--- a/docs/source/concepts/UnitFactory.rst
+++ b/docs/source/concepts/UnitFactory.rst
@@ -61,7 +61,7 @@ here is the Bragg scattering angle (e.g. half of the
 Mantid z-axis)
 
 **Note on Wavelength**: If the emode property in
-:ref: `ConvertUnits <algm-ConvertUnits>`
+:ref:`ConvertUnits <algm-ConvertUnits>`
 is specified as inelastic Direct/Indirect (inelastic) then the
 conversion to wavelength will take into account the fixed initial/final
 energy respectively. Units conversion into elastic momentum transfer
diff --git a/docs/source/diagrams/DirectILLReduction-v1_wkflw.dot b/docs/source/diagrams/DirectILLReduction-v1_wkflw.dot
index 6a91ffb61d548a16f3c732297b58f17718a10d7e..f0b26f2e3987a8db84e06e71ef151a3d49ac3b65 100644
--- a/docs/source/diagrams/DirectILLReduction-v1_wkflw.dot
+++ b/docs/source/diagrams/DirectILLReduction-v1_wkflw.dot
@@ -23,6 +23,7 @@ digraph DirectILLReduction {
     $algorithm_style
     AbsoluteUnits [label="Scale to absolute units"]
     ApplyDiagnostics [label="Mask spectra"]
+    ConvertToDistribution [label="ConvertToDistribution"]
     ConvertToEnergy [label="Convert TOF to energy transfer"]
     CorrectKiKf [label="CorrectKiKf"]
     DetectorEfficiency [label="DetectorEfficiencyCorUser"]
@@ -49,7 +50,8 @@ digraph DirectILLReduction {
   ConvertToEnergy -> CorrectKiKf
   CorrectKiKf -> Rebin
   wRebinParams -> Rebin
-  Rebin -> DetectorEfficiency
+  Rebin -> ConvertToDistribution
+  ConvertToDistribution -> DetectorEfficiency
   DetectorEfficiency -> GroupDetectors
   GroupDetectors -> outputOptionalWS
   GroupDetectors -> SofQW
diff --git a/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_wkflw.dot b/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D20_wkflw.dot
similarity index 98%
rename from docs/source/diagrams/PowderDiffILLDetEffCorr-v1_wkflw.dot
rename to docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D20_wkflw.dot
index 10ceee7c46f2015604deaa7414002a0b3c72b599..7fe1b7baa06a93e86598e8bae17b396500a8a762 100644
--- a/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_wkflw.dot
+++ b/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D20_wkflw.dot
@@ -1,5 +1,5 @@
 digraph PowderDiffILLDetEffCorr {
-  label="PowderDiffILLDetEffCorr flowchart"
+  label="SequentialSummedReference1D Flowchart"
   $global_style
 
   subgraph values {
diff --git a/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D2B_wkflw.dot b/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D2B_wkflw.dot
new file mode 100644
index 0000000000000000000000000000000000000000..c05db43f1b3764b1dfdc3fbed6e684fe5b1fec39
--- /dev/null
+++ b/docs/source/diagrams/PowderDiffILLDetEffCorr-v1_D2B_wkflw.dot
@@ -0,0 +1,55 @@
+digraph PowderDiffILLDetEffCorr {
+  label="GlobalSummedReference2D Flowchart"
+  $global_style
+
+  subgraph values {
+    $value_style
+    reference
+    single_tube
+    input_data
+    factor
+  }
+
+  subgraph decision {
+    $decision_style
+    Iterate
+  }
+
+  subgraph params {
+    $param_style
+    CalibrationRun
+    ExcludedRange
+    OutputWorkspace
+  }
+
+  subgraph algorithms {
+    $algorithm_style
+    LoadILLDiffraction
+    SumOverlappingTubes
+    ApplyDetectorScanEffCorr
+    MaskBins
+    Divide
+  }
+
+  subgraph process {
+    $process_style
+    Median
+  }
+
+  CalibrationRun -> LoadILLDiffraction
+  LoadILLDiffraction -> input_data
+  input_data -> single_tube
+  input_data -> SumOverlappingTubes
+  SumOverlappingTubes -> reference
+  reference -> Divide
+  single_tube -> Divide
+  Divide -> MaskBins
+  ExcludedRange -> MaskBins
+  MaskBins -> Median
+  Median -> factor
+  factor -> Iterate
+  Iterate -> ApplyDetectorScanEffCorr [label="Yes"]
+  ApplyDetectorScanEffCorr -> input_data
+  Iterate -> OutputWorkspace [label="No"]
+
+}
diff --git a/docs/source/fitting/fitfunctions/LatticeFunction.rst b/docs/source/fitting/fitfunctions/LatticeFunction.rst
index a26b7c629c64c311fce2e16ce6bf115972e1ba34..d6d40899023248e9a81e7cc00f138632fe302f18 100644
--- a/docs/source/fitting/fitfunctions/LatticeFunction.rst
+++ b/docs/source/fitting/fitfunctions/LatticeFunction.rst
@@ -50,19 +50,18 @@ used to generate Bragg reflections that are expected for the crystal structure o
 
     a_true = 5.4311946
     a = np.round(parameters.cell(0, 1), 7)
-    a_err = np.round(parameters.cell(0, 2), 16)
+    a_err = np.round(parameters.cell(0, 2), 7)
 
     print("Refined lattice parameter: a = {0} +/- {1}".format(a, a_err))
     print("Difference from expected value: a_observed - a_expected = {0}".format(np.round(a - a_true, 7)))
-    print("Is this difference within the standard deviation? {0}".format("Yes" if np.fabs(a - a_true) <= a_err else "No"))
 
 Executing the script produces some output with information about the fit:
 
 .. testoutput:: ExSiliconTheoretical
+   :options: +ELLIPSIS +NORMALIZE_WHITESPACE
 
-    Refined lattice parameter: a = 5.4311946 +/- 2e-16
+    Refined lattice parameter: a = 5.4311946 +/- ...
     Difference from expected value: a_observed - a_expected = 0.0
-    Is this difference within the standard deviation? Yes
 
 In addition there is also an output workspace, which contains information about the peaks used for the fit and how
 well the peak positions calculated from the fitted parameters match the observed positions.
diff --git a/docs/source/fitting/fitfunctions/TeixeiraWater.rst b/docs/source/fitting/fitfunctions/TeixeiraWater.rst
index dea93d3ee4a382a4df92e119e2e9fb3f8c6ad35d..d2aaab65cbc04fb694d15088f5f8d6098a6b8fd3 100644
--- a/docs/source/fitting/fitfunctions/TeixeiraWater.rst
+++ b/docs/source/fitting/fitfunctions/TeixeiraWater.rst
@@ -12,12 +12,21 @@ Description
 Teixeira's model for water [1]_.
 
 Models the Q dependence of the QENS line width (Gamma (hwhm)), diffusion
-coefficients (D), residence times (tau) and jump lengths (length) to extract the
-associated long range diffusive motions of molecules.
+coefficients (D), residence times (tau) and jump lengths (length) to extract
+the associated long range diffusive motions of molecules.
 
 This model (1961) has the form:
 
-.. math:: Gamma(Q) = D*Q^2/(1 + D*Q^2*tau)
+.. math::
+    HWHM(Q) = \frac{\hbar}{\tau} \cdot \frac{(QL)^2}{6 + (QL)^2}
+
+    D = \frac{L^2}{6 \tau}
+
+Units of :math:`L` are inverse units of :math:`Q`.
+
+Units of :math:`HWHM` are :math:`meV` if units of :math:`\tau` are *ps*.
+Alternatively, units of :math:`HWHM` are :math:`\mu eV` if units of
+:math:`\tau` are *ns*.
 
 .. attributes::
 
diff --git a/docs/source/images/CreateSampleWorkspaceInstrument.png b/docs/source/images/CreateSampleWorkspaceInstrument.png
index b9ba27860a10c651e250aec6f4f5f824df889a62..a674aa7bbf3ca52f2f6766839846b9f213be8082 100644
Binary files a/docs/source/images/CreateSampleWorkspaceInstrument.png and b/docs/source/images/CreateSampleWorkspaceInstrument.png differ
diff --git a/docs/source/images/D20_calib.png b/docs/source/images/D20_calib.png
new file mode 100644
index 0000000000000000000000000000000000000000..89bab62244f494ce40e67e30a0c3be079c56ffff
Binary files /dev/null and b/docs/source/images/D20_calib.png differ
diff --git a/docs/source/images/D2B_calib.png b/docs/source/images/D2B_calib.png
new file mode 100644
index 0000000000000000000000000000000000000000..1eee6596fe88ec552fc6b65078c210d30c380018
Binary files /dev/null and b/docs/source/images/D2B_calib.png differ
diff --git a/docs/source/images/EnggDiffExampleGSASOutput.png b/docs/source/images/EnggDiffExampleGSASOutput.png
new file mode 100644
index 0000000000000000000000000000000000000000..243e9b1a650f0db305ba2aed4e030806a3f3282d
Binary files /dev/null and b/docs/source/images/EnggDiffExampleGSASOutput.png differ
diff --git a/docs/source/images/EquivalentIntensities.png b/docs/source/images/EquivalentIntensities.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ae944555dee084250097a0ab8ff84d6b1e0994a
Binary files /dev/null and b/docs/source/images/EquivalentIntensities.png differ
diff --git a/docs/source/images/ISIS_Reflectometry_per_angle_options.png b/docs/source/images/ISIS_Reflectometry_per_angle_options.png
new file mode 100644
index 0000000000000000000000000000000000000000..f556647014038eef6b68956cd2a939adb905ecc9
Binary files /dev/null and b/docs/source/images/ISIS_Reflectometry_per_angle_options.png differ
diff --git a/docs/source/images/MaskAngle_phi.png b/docs/source/images/MaskAngle_phi.png
new file mode 100644
index 0000000000000000000000000000000000000000..aba5f84d5474cfee2e2d514d0d8cc25394a71c58
Binary files /dev/null and b/docs/source/images/MaskAngle_phi.png differ
diff --git a/docs/source/images/WANDPowderReduction_MaskAngle.png b/docs/source/images/WANDPowderReduction_MaskAngle.png
new file mode 100644
index 0000000000000000000000000000000000000000..d046f7048ccf7596549751ac7e8a0b23d2c45ca6
Binary files /dev/null and b/docs/source/images/WANDPowderReduction_MaskAngle.png differ
diff --git a/docs/source/images/WANDPowderReduction_silicon_powder.png b/docs/source/images/WANDPowderReduction_silicon_powder.png
new file mode 100644
index 0000000000000000000000000000000000000000..c70f70165ac5e9332dd1626d276736fe4a258eb1
Binary files /dev/null and b/docs/source/images/WANDPowderReduction_silicon_powder.png differ
diff --git a/docs/source/images/WANDPowderReduction_silicon_powder_d.png b/docs/source/images/WANDPowderReduction_silicon_powder_d.png
new file mode 100644
index 0000000000000000000000000000000000000000..934e0c0ad917fbc3833997a8c8eb6d7f9eef51a0
Binary files /dev/null and b/docs/source/images/WANDPowderReduction_silicon_powder_d.png differ
diff --git a/docs/source/images/WANDPowderReduction_silicon_powder_q.png b/docs/source/images/WANDPowderReduction_silicon_powder_q.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9eaff3db29ad40fe8b2d5355ea640075a1780c4
Binary files /dev/null and b/docs/source/images/WANDPowderReduction_silicon_powder_q.png differ
diff --git a/docs/source/images/mslice_acut.png b/docs/source/images/mslice_acut.png
new file mode 100644
index 0000000000000000000000000000000000000000..fcf753b8abfbb25265cc37f337cf103f4ff65e49
Binary files /dev/null and b/docs/source/images/mslice_acut.png differ
diff --git a/docs/source/images/mslice_interface.png b/docs/source/images/mslice_interface.png
new file mode 100644
index 0000000000000000000000000000000000000000..05483944fbafda8b6ca4b9eb29af6793ff2070d1
Binary files /dev/null and b/docs/source/images/mslice_interface.png differ
diff --git a/docs/source/images/mslice_slice.png b/docs/source/images/mslice_slice.png
new file mode 100644
index 0000000000000000000000000000000000000000..380a77fffbbe555ad0e3d83c7f1c87d1be28841e
Binary files /dev/null and b/docs/source/images/mslice_slice.png differ
diff --git a/docs/source/interfaces/Engineering Diffraction Test Guide.rst b/docs/source/interfaces/Engineering Diffraction Test Guide.rst
index efd4167ac2ab2e1276e70d0aae401ec2f690393d..3cc0464e99c5b389477768fe3ef75a75cb20354b 100644
--- a/docs/source/interfaces/Engineering Diffraction Test Guide.rst	
+++ b/docs/source/interfaces/Engineering Diffraction Test Guide.rst	
@@ -156,6 +156,43 @@ Negative Testing Ideas
 - Change any unlocked dialog boxes whilst `Fit` runs
 
 
+.. _gsas-fitting-Engineering-Diffraction_test-ref:
+
+GSAS Fitting
+^^^^^^^^^^^^
+
+GSAS-style fitting allows the user to plot peaks from their focused
+NeXuS file (obtained from
+:ref:`focus-Engineering_Diffraction_test-ref`).
+
+After a fit has run, the plot should look something like below:
+
+.. image:: ../images/EnggDiffExampleGSASOutput.png
+
+If that fit output (the red line) is flat, or just follows the
+background of the data, the fit was not unsuccessful. Make sure you're
+using the right ``.cif`` and ``.prm`` files for your run. You can find
+an example of files which work nicely together on most PRs related to
+the GSAS tab or GSASIIRefineFitPeaks, or have a look `here
+<https://github.com/mantidproject/mantid/files/1739753/GSASIIRefineFitPeaks.zip>`_.
+
+.. warning:: At the moment, you will also just get background if you
+	     try to do a Pawley refinement, as this is still under
+	     development, possibly requiring input from ENGINX
+	     scientists or GSAS-II developers (probably both)
+
+You can navigate around the plot in the same way as the Fitting tab.
+
+Negative Testing Ideas
+----------------------
+
+- Using an unfocused .nxs file \- Mantid shouldn't crash
+- Enter bad input into the text entries - this should be handled
+  elegantly
+- Change any unlocked dialogs and click any unlocked buttons while
+  refinement is running
+- Cancel the algorithm before exiting the GUI, and vice verse
+
 .. _settings-Engineering_Diffraction_test-ref:
 
 Settings
diff --git a/docs/source/interfaces/Engineering Diffraction.rst b/docs/source/interfaces/Engineering Diffraction.rst
index 4885ad56c1de8da7d5111e6e30d8e3739b9d2917..2e1125af8fb1b0f169b906b53ab04dd4ea5aff61 100644
--- a/docs/source/interfaces/Engineering Diffraction.rst	
+++ b/docs/source/interfaces/Engineering Diffraction.rst	
@@ -451,6 +451,81 @@ User may plot single peak fitting workspace in separate window by using
 Plot To Separate Window button, if the *engggui_fitting_single_peaks*
 is available.
 
+.. _gsas-Engineering_Diffraction-ref:
+
+GSAS Fitting
+------------
+
+.. warning:: This is a new capability that is currently in a very
+             early stage of definition and implementation. Not all
+	     options may be supported and/or consistent at the moment.
+
+The GSAS tab provides a graphical interface to the Mantid algorithm
+:ref:`GSASIIRefineFitPeaks <algm-GSASIIRefineFitPeaks>`. This allows
+users to perform GSAS-style fitting on their data from Mantid.
+
+The user must input the following files:
+
+- **Focused run file(s)** - these must have been generated either by
+  the **Fitting** tab or :ref:`EnggFocus <algm-EnggFocus>`.
+- **Instrument Parameter File** - contains DIFA and DIFC GSAS
+  constants, will probably be of ``.prm`` format
+- **Phase file(s)** - contain crystallographic information about the
+  sample in question. Currently only ``.cif`` files are supported
+
+The following parameters are also required:
+
+- **New GSAS-II Project** - GSASIIRefineFitPeaks creates a new
+  ``.gpx`` project here, which can be opened and inspected from the
+  GSAS-II GUI
+
+  - Note, if running **Refine All** on more than one run, the run
+    number and bank ID will be appended to the filename
+- **GSAS-II Installation Directory**
+
+  - This is the directory containing the GSAS-II executables and
+    Python libraries. In particular, it must contain
+    ``GSASIIscriptable.py``. This directory will normally be called
+    `GSASII`, if GSAS-II was installed normally
+  - You must have a version of GSAS-II from at least **February 2018**
+    to use the GUI. See :ref:`Installing_GSASII` for how to install a
+    compatible version
+- **Refinement method** - can either be **Pawley** or
+  **Rietveld**. Pawley refinement is currently under development, so
+  Rietveld is recommended.
+
+Optionally, you may also supply:
+
+- **XMin** and **XMax** - the limits (in TOF) to perform fitting
+  within
+- **DMin** - the minimum dSpacing to use for refinement when
+  performing Pawley refinement
+- **Negative weight** - The weight for a penalty function applied
+  during a Pawley refinement on resulting negative intensities.
+
+To do a refinement, take the following steps:
+
+1. Load a run by selecting the focused NeXuS file using the
+   corresponding **Browse** button, then clicking **Load**. The run
+   number and bank ID (for example ``123456_1``) should appear in the
+   **Run Number** list in the **Preview** section. Click the label,
+   and the run willl be plotted
+2. Select your input files, and input any additional parameters in the
+   **GSASIIRefineFitPeaks Controls** section
+3. Click **Run Refinement**. Once complete, fitted peaks for the run
+   should be overplotted in the fitting area. In addition, Rwp
+   (goodness of fit index), Sigma and Gamma (peak broadening
+   coefficients) and lattice parameters should be displayed in the
+   **Fit Results** section.
+
+   - You can also click **Refine All** to run refinement on all runs
+     loaded into GSAS tab
+
+You can toggle the fitted peaks on and off with the **Plot Fitted
+Peaks** checkbox, remove runs from the list with the **Remove Run**
+button, and plot the run and fitted peaks to a larger, separate plot
+using **Plot to separate window**.
+
 .. _setting-Engineering_Diffraction-ref:
 
 Settings
diff --git a/docs/source/interfaces/ISIS SANS v2.rst b/docs/source/interfaces/ISIS SANS v2.rst
index 541f3c47e8ca0601c3fa1e0f5d615320a546d5ea..2bce433d08a5d67429e365fbadfab470307b09b9 100644
--- a/docs/source/interfaces/ISIS SANS v2.rst	
+++ b/docs/source/interfaces/ISIS SANS v2.rst	
@@ -284,7 +284,7 @@ Masking information
 
 The masking table shows detailed information about the masks which will be applied.
 These masks include bin masks, cylinder masks, mask files, spectrum masks, angle masks
-and masks for the beam stop. If as mask is applied only to a particular detector
+and line masks for the beam stop arm. If a mask is applied only to a particular detector
 then this will be shown in the masking table. Note that data needs to be specified
 in order to see the masking information. Also note if a manual change to the
 data table or other settings, requires you to update the row selection by
diff --git a/docs/source/release/index.rst b/docs/source/release/index.rst
index c0be396b981fa717d7b8d9542a36ae700f4f1841..6b1ea51957a7ae80c4b4e51f8d286eb954e7da48 100644
--- a/docs/source/release/index.rst
+++ b/docs/source/release/index.rst
@@ -13,6 +13,7 @@ Release Notes
 
 
 * :ref:`v3.13.0 <v3.13.0>`
+* :ref:`v3.12.1 <v3.12.1>`
 * :ref:`v3.12.0 <v3.12.0>`
 * :ref:`v3.11.0 <v3.11.0>`
 * :ref:`v3.10.1 <v3.10.1>`
diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst
index ddb35708ddf12f733ab83b28dd01d632f4de6b6b..80babc99adb171dd1c75aec13b891adfe8b840a2 100644
--- a/docs/source/release/v3.12.0/diffraction.rst
+++ b/docs/source/release/v3.12.0/diffraction.rst
@@ -7,9 +7,10 @@ Diffraction Changes
 
 Powder Diffraction
 ------------------
-- :ref:`SaveFocusedXYE <algm-SaveFocusedXYE>` has been amended to write the metadata (e.g. temperature) value in the header, in the form of the Fullprof readable keyword.
 
-- Some new functionality for POLARIS in the ISIS Powder scripts. Adjusted some default parameters and output unsplined vanadium workspace by default
+New features
+############
+
 - New features in ISIS Powder which affect all instruments:
 
   + 'suffix' parameter added for output filenames
@@ -24,6 +25,16 @@ Powder Diffraction
   + Scripts now support creation of grouping .cal files from ceria run(s)
   + Absorption corrections enabled for all samples, not just vanadium
   + ``subtract_empty_instrument`` parameter added for disabling empty subtraction, useful for focusing empties
+- New functionality for POLARIS in the ISIS Powder scripts. Some default parameters adjusted and output unsplined vanadium workspace by default.
+- New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size.
+- New algorithm :ref:`algm-SumOverlappingTubes` combines a detector scan for D2B into a single workspace.
+
+
+Improvements
+############
+
+- :ref:`CalculateDIFC <algm-CalculateDIFC>` has been extended to allow for calibration workspaces from :ref:`PDCalibration <algm-PDCalibration>`.
+- :ref:`SaveFocusedXYE <algm-SaveFocusedXYE>` has been amended to write the metadata (e.g. temperature) value in the header, in the form of the Fullprof readable keyword.
 - Improvements in ISIS Powder for HRPD:
 
   + The prompt pulse is now masked out for the long window
@@ -33,52 +44,65 @@ Powder Diffraction
 
   + The ``mode`` parameter now behaves as described in the documentation - it persists through function calls and is case insensitive
   + After calling create_vanadium and focus, the output workspaces always contain the sample material if it is set using ``set_sample_material``. (To view the sample material, right click the workspace and click 'Sample Material...')
-
+  
 - The ``CalibrationFile`` is now optional in :ref:`SNSPowderReduction <algm-SNSPowderReduction>`. In this case time focussing will use :ref:`ConvertUnits <algm-ConvertUnits>` and the instrument geometry. Care must be taken to supply a ``GroupingFile`` otherwise all of the spectra will be kept separate.
 - :ref:`SaveGSS <algm-SaveGSS>` is relaxed to accept non-TOF point data workspaces as well.
-- New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size
 - :ref:`PDCalibration <algm-PDCalibration>` returns three more diagnostic workspaces: one for the fitted peak heights, one for the fitted peak widths, and one for observed resolution.
 - :ref:`LoadILLDiffraction <algm-LoadILLDiffraction>` now supports D2B files with calibrated data.
 - :ref:`PowderDiffILLReduction <algm-PowderDiffILLReduction>` and :ref:`PowderDiffILLDetEffCorr <algm-PowderDiffILLDetEffCorr>` enable the basic data reduction for D20 scanning powder diffractometer at ILL.
 - :ref:`ApplyDetectorScanEffCorr <algm-ApplyDetectorScanEffCorr>` applies the calibration file generated by :ref:`PowderDiffILLDetEffCorr <algm-PowderDiffILLDetEffCorr>` to detector scan workspaces.
 - :ref:`PowderDiffILLDetScanReduction <algm-PowderDiffILLDetScanReduction>` supports D2B and D20 (when doing a detector scan) powder diffraction reduction at the ILL.
-- New algorithm :ref:`algm-SumOverlappingTubes` combines a detector scan for D2B into a single workspace.
-- :ref:`CalculateDIFC <algm-CalculateDIFC>` has been extended to allow for calibration workspaces from :ref:`PDCalibration <algm-PDCalibration>`
 - :ref:`SaveGSS <algm-SaveGSS>` has been extended to allow user to specify GSAS general header, each bank's header and XYE decimal precision for SLOG.
 - :ref:`SaveVulcanGSS <algm-SaveVulcanGSS>` has been moved to a workflow algorithm and largely rewritten by using recent change in histogram and Workspace2D.  It is also improved such that there is no contraint on the number of spectra and number of various binning parameters on the workspace to be saved to a GSAS file for VULCAN.
 - :ref:`PDLoadCharacterizations <algm-PDLoadCharacterizations>` now allows for the azimuthal angles to be optionally specified in the file.
 
+
 Engineering Diffraction
 -----------------------
 
-- Fixed a bug where the engineering diffraction GUI could hang when performing a long running file search.
+Improvements
+############
 
-- :ref:`GSASIIRefineFitPeaks <algm-GSASIIRefineFitPeaks>` has been re-integrated with the
-  latest version of GSAS-II, allowing Rietveld and Pawley refinement
-  within Mantid.
-  + Fitted peaks are now output as a Mantid workspace
-- Usability improvements in the GUI:
-
-  + The "Invalid RB number" popup window in the GUI has been replaced with a more user-friendly message
-  + Improved progress reporting for Calibration and Focus
-  + Enabled multi-run fitting and plotting in the Fitting tab
-  + Improved unit conversions when using the peak picker
 - GSAS Fitting tab was added to the GUI to allow convenient GSAS-style refinement using GSASIIRefineFitPeaks
 
 .. figure:: ../../images/engineering_gsas_gui.PNG
    :class: screenshot
-   :width: 385px
-   :align: center
+   :align: right
+   :figwidth: 50%
 
    The Engineering diffraction GSAS-II GUI
 
+- :ref:`GSASIIRefineFitPeaks <algm-GSASIIRefineFitPeaks>` has been re-integrated with the
+  latest version of GSAS-II, allowing Rietveld and Pawley refinement
+  within Mantid.
+  + Fitted peaks are now output as a Mantid workspace.
+  
+- Usability improvements in the GUI:
+
+  + The "Invalid RB number" popup window in the GUI has been replaced with a more user-friendly message.
+  + Improved progress reporting for Calibration and Focus.
+  + Enabled multi-run fitting and plotting in the Fitting tab.
+  + Improved unit conversions when using the peak picker.
+  
+Bug fixes
+#########
+
+- Fixed a bug where the engineering diffraction GUI could hang when performing a long running file search.
+
 
 Single Crystal Diffraction
 --------------------------
+
+New features
+############
+
+- New algorithm :ref:`LoadWAND <algm-LoadWAND>` that will load event data for WAND² integrating out the events and correctly setting the units.
+
+Improvements
+############
+
 - :ref:`FilterPeaks <algm-FilterPeaks>` now supports filtering peaks by TOF, d-spacing, and wavelength.
 - HB3A reduction interface has been enhanced.  A child window is added to it for users to pre-process scans and save the processed and merged data to NeXus files in order to save time when they start to reduce and visualize the data. A record file is generated along with processed scans to record the calibration information. During data reduction, scans that have been processed in pre-processing will be loaded automatically from corresponding MD files.
-- Fixed a bug in :ref:`IntegrateEllipsoids <algm-IntegrateEllipsoids>` and :ref:`IntegrateEllipsoidsTwoStep <algm-IntegrateEllipsoidsTwoStep>` that forced output to be weighted by the bin width.
-- Fixed a bug in :ref:`IntegrateEllipsoidsTwoStep <algm-IntegrateEllipsoidsTwoStep>` where peaks with negative intensity values would be set to zero.
 - :ref:`IntegratePeaksMDHKL <algm-IntegratePeaksMDHKL>` now has option to specify background shell instead of using default background determination.
 
 - In HB3A reduction interface, section for downloading experimental data via http server has been removed from main UI.
@@ -99,10 +123,19 @@ Single Crystal Diffraction
 
 - :ref:`StatisticsOfPeaksWorkspace <algm-StatisticsOfPeaksWorkspace>` now can accept long or short names for the point group and reflection condition.
 
-- New algorithm :ref:`LoadWAND <algm-LoadWAND>` that will load event data for WAND² integrating out the events and correctly setting the units.
+Bug fixes
+#########
+
+- Fixed a bug in :ref:`IntegrateEllipsoids <algm-IntegrateEllipsoids>` and :ref:`IntegrateEllipsoidsTwoStep <algm-IntegrateEllipsoidsTwoStep>` that forced output to be weighted by the bin width.
+- Fixed a bug in :ref:`IntegrateEllipsoidsTwoStep <algm-IntegrateEllipsoidsTwoStep>` where peaks with negative intensity values would be set to zero.
+
 
 Total Scattering
 ----------------
+
+New features
+############
+
 - A basic analysis for total scattering method ``create_total_scattering_pdf`` has been added to POLARIS. More information can be found on the POLARIS reference page.
 
 
diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst
index d6095c0aa2c829d02d42b1d7447ba4dc3c0ce24f..7a4903d60b7dc06f25d7f18731fa9314d334fbe5 100644
--- a/docs/source/release/v3.12.0/direct_inelastic.rst
+++ b/docs/source/release/v3.12.0/direct_inelastic.rst
@@ -5,41 +5,78 @@ Direct Inelastic Changes
 .. contents:: Table of Contents
    :local:
 
+Interfaces
+----------
+
 New features
-------------
+############
+
+- The `MSlice <https://github.com/mantidproject/mslice>`_ user interface can now be launched from the MantidPlot Interfaces menu.
+
+.. figure:: ../../images/mslice_interface.png
+	:class: screenshot
+	:align: center
+	:width: 500 px
+
+.. figure:: ../../images/mslice_slice.png
+	:class: screenshot
+	:align: center
+	:width: 500 px
+
+.. figure:: ../../images/mslice_acut.png
+	:class: screenshot
+	:align: center
+	:width: 500 px
+	
+
+Similar to the slice viewer, MSlice plots slices and cuts from workspaces. It creates customisable publication quality figures. Cuts can be created interactively by dragging a rectangle across a slice, and information such as recoil lines and bragg peaks can be overplotted.
 
-- The `MSlice <https://github.com/mantidproject/mslice>`_ user interface can now be lauched from the MantidPlot Interfaces menu.
 - The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes.
 - :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections.
 - The crystal field computation and fitting engine is now feature complete. It can now handle multi-site computation and simultaneous fitting of inelastic spectra and physical properties dataset. See the :ref:`Crystal Field Python Interface` help page for details, and `<http://www.mantidproject.org/Crystal_Field_Examples>`_ for examples of use.
 - A new Python module :ref:`directtools <Directtools Python module>` includes utilities for plotting :math:`S(Q,W)` workspaces and cuts (line profiles) in constant :math:`Q` and :math:`E`.
 
-Interfaces
-----------
+Improvements
+############
 - PyChop has been updated with new look-up tables for the upgraded MAPS (with guide). Some minor bugs in PyChop have been fixed.
 - TOFTOF data reduction GUI has been improved. In the new version it has options to delete intermediate workspaces, to replace NaNs in S(Q,W), to create diffractograms and to save the reduced data in NXSPE and NeXus format.
 - :ref:`algm-MonitorEfficiencyCorUser` is not anymore restricted to TOFTOF instrument.
 
-Instrument definitions
-----------------------
+Crystal Field
+-------------
+
+New features
+############
+
+- The crystal field computation and fitting engine is now feature complete. It can now handle multi-site computation and simultaneous fitting of inelastic spectra and physical properties dataset. See the :ref:`Crystal Field Python Interface` help page for details, and `<http://www.mantidproject.org/Crystal_Field_Examples>`_ for examples of use.
+- Multi-site calculations and fitting are now supported by the crystal field (Python commandline) interface.
+- Calculation of dipole transition matrix elements has been added, together with the addition of a :math:`\chi_0` term in the :ref:`CrystalFieldSusceptibility <func-CrystalFieldSusceptibility>` function.
+
+Bug fixes
+#########
 
-* The MAPS instrument definition file dating back to 2017-06-03 was changed.
+Several bugs in the Python and C++ code has been fixed - see the `github page <https://github.com/mantidproject/mantid/pull/21604>`_ for details.
 
 Algorithms
 ----------
 
-- Fixed a bug in :ref:`algm-DirectILLApplySelfShielding` which could cause confusion among workspaces when the algorithm was run without both self shielding correction and empty container workspaces.
+New features
+############
+
 - New algorithm :ref:`HyspecScharpfCorrection <algm-HyspecScharpfCorrection-v1>` that can be used to calculate spin incoherent scattering from polarized neutron data
-- A `bug <https://github.com/mantidproject/mantid/pull/20953>`_ in the handling of workspaces with fractional bin weights (generated by :ref:`algm-SofQWNormalisedPolygon`) has been fixed.
+- The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes.
+- :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections.
 
-Crystal Field
--------------
+Bug fixes
+#########
 
-Multi-site calculations and fitting are now supported by the crystal field (Python commandline) interface.
+- Fixed a bug in :ref:`algm-DirectILLApplySelfShielding` which could cause confusion among workspaces when the algorithm was run without both self shielding correction and empty container workspaces.
+- A `bug <https://github.com/mantidproject/mantid/pull/20953>`_ in the handling of workspaces with fractional bin weights (generated by :ref:`algm-SofQWNormalisedPolygon`) has been fixed.
 
-Calculation of dipole transition matrix elements has been added, together with the addition of a :math:`\chi_0` term in the :ref:`CrystalFieldSusceptibility <func-CrystalFieldSusceptibility>` function.
+Instrument definitions
+----------------------
 
-Several bugs in the Python and C++ code has been fixed - see the `github page <https://github.com/mantidproject/mantid/pull/21604>`_ for details.
+- The MAPS instrument definition file dating back to 2017-06-03 was changed.
 
 Features Removed
 ----------------
@@ -47,3 +84,5 @@ Features Removed
 * The Direct Convert To Energy graphical interface has been removed, it had not been used for several years, and was a source of bugs as well as using testing effort that is better directed elsewhere.
 
 `Full list of changes on GitHub <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.12%22+is%3Amerged+label%3A%22Component%3A+Direct+Inelastic%22>`_
+
+:ref:`Release 3.12.0 <v3.12.0>`
diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst
index 838e12ae47aedc6f037d4805ebab4c98d08e7f1b..48a170b13aa8bafd5aa709b519d4ea6503c82049 100644
--- a/docs/source/release/v3.12.0/framework.rst
+++ b/docs/source/release/v3.12.0/framework.rst
@@ -5,32 +5,33 @@ Framework Changes
 .. contents:: Table of Contents
    :local:
 
-.. warning:: **Developers:** Sort changes under appropriate heading.
-    Put new features at the top of the section, followed by
-    improvements, followed by bug fixes.
-
 Instrument Definition Updates
 -----------------------------
 
 - The MAPS IDF has been updated following its upgrade.
 
-Concepts
---------
 Instrument Definitions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+######################
 .. warning:: **Users:** Instruments in Mantid will no longer silently discard detectors defined with duplicate IDs. This has been a long-standing source of hard to find issue in Mantid. We have endeavoured to ensure that all :ref:`Instrument Definition Files <InstrumentDefinitionFile>` shipped with Mantid are now corrected. **If you have local IDFs, please update them to remove any duplicate IDs, or ask the Mantid Team for help**, the warning and error information in Mantid will give details about duplicates in IDFs that cannot be loaded.
 
     Beware that :ref:`LoadNexusProcessed <algm-LoadNexusProcessed>` will now **NOT load the Instrument from historic Processed Nexus files if the embedded IDF is corruped with duplicate detector IDs**. The workspace (data) part will still load, but the workspace will not have any Instrument attached. There are new warnings generated that describe the exact problem and the remedy when this happens. Note that the fix is generally easy. You should be able to run :ref:`LoadInstrument <algm-LoadInstrument>` on the Workspace, pointing it to an updated IDF, which is free of duplicates.
 
 Please contact the Mantid Team if you experience any further problems as a result of these changes.
 
+
 Algorithms
 ----------
+
+New
+###
 - :ref:`MostLikelyMean <algm-MostLikelyMean>` is a new algorithm that computes the mean of the given array, that has the least distance from the rest of the elements.
 - :ref:`LoadAndMerge <algm-LoadAndMerge>` is a new algorithm that can load and merge multiple runs.
 - :ref:`CropWorkspaceRagged <algm-CropWorkspaceRagged>`: New algorithm that will crop each spectrum with a different x-range.
 - :ref:`LoadLamp <algm-LoadLamp>`: New algorithm to load processed HDF5 files produced by LAMP program at ILL.
 - :ref:`SaveReflections <algm-SaveReflections>` is a new algorithm to save PeaksWorkspaces to Fullprof, Jana, GSAS, and SHELX text formats.
+
+Improved
+########
 - :ref:`NormaliseToMonitor <algm-NormaliseToMonitor>` now supports workspaces with detector scans and workspaces with single-count point data.
 - :ref:`CalculatePolynomialBackground <algm-CalculatePolynomialBackground>`: It is now possible to choose between weighted and unweighted fitting.
 - :ref:`CreateWorkspace <algm-CreateWorkspace>` will no longer create a default (and potentially wrong) mapping from spectra to detectors, unless a parent workspace is given. This change ensures that accidental bad mappings that could lead to corrupted data are not created silently anymore. This change does *not* affect the use of this algorithm if: (1) a parent workspace is given, or (2) no instrument is loaded into to workspace at a later point, or (3) an instrument is loaded at a later point but ``LoadInstrument`` is used with ``RewriteSpectraMapping=True``. See also the algorithm documentation for details.
@@ -44,14 +45,14 @@ Algorithms
 - :ref:`SaveNexus <algm-SaveNexus>` will no longer crash when passed a ``PeaksWorkspace`` with integrated peaks that have missing radius information.
 - :ref:`ConjoinXRuns <algm-ConjoinXRuns>` will now accept workspaces with varying x-axes per spectrum.
 - :ref:`LoadEXED <algm-LoadEXED>` has better handling of monitor workspace and sample logs.
+
+Bugfixes
+########
 - :ref:`Fit <algm-Fit>` has had a bug fixed that prevented a fix from being removed.
 - :ref:`LoadMask <algm-LoadMask>` has had a bug fixed that could, under certain conditions, cause detectors from previously loaded masking to be added to the currently loaded masking.
 
-
-
 Known Issues
-^^^^^^^^^^^^
-
+############
 - :ref:`LoadEventNexus <algm-LoadEventNexus>` is incorrectly ignoring the `FilterMonBy*` properties. When loading monitors as events the output
   `*_monitors` workspace then contains all recorded events rather than those accepted by the filters. To work around this issue run the
   :ref:`FilterByTime <algm-FilterByTime>` algorithm on the output `*_monitors` workspace with the same values as passed to the `FilterMonBy*`
@@ -59,64 +60,103 @@ Known Issues
 
 Fitting
 -------
+Improved
+########
 - :ref:`EISFDiffSphere <func-EISFDiffSphere>` fits the Q-dependence on the EISF of a particle undergoing continuous diffusion but confined to a spherical volume.
 - :ref:`EISFDiffSphereAlkyl <func-EISFDiffSphereAlkyl>` fits the Q-dependence on the EISF of an alkyl molecule, like a membrane lipd.
 - :ref:`EISFDiffCylinder <func-EISFDiffCylinder>` models the elastic incoherent scattering intensity of a particle diffusing within a cylinder.
+
+Bugfixes
+########
 - Fix for a bug in calculating numerical derivatives by applying ties correctly.
 
 Core Functionality
 ------------------
 
+New
+###
+- Added new classes ``ConfigObserver`` for listening for changes to any configuration property and ``ConfigPropertyObserver`` for listening to changes to an individual config property of interest.
+
+Improved
+########
+- DEB and RPM package sizes reduced by 17% and 6% respectively.
 - :class:`mantid.kernel.FloatTimeSeriesProperty` now returns :class:`numpy.datetime64` for the log times.
 - The duration reported by a running algorithm now includes time spent for validation of properties and inputs. This fixes a discrepancy between observed and reported timings if validation is expensive, e.g., when checking if a file exists. More detailed timing information is now available when setting the log level to ``debug``.
-- Fixed an issue where certain isotopes could not be accessed using the `Atom` classes, e.g Si28.
-- ``datasearch.searcharchive`` :ref:`property <Properties File>` has new functionality to only search the default facility.
 - The status of a fit in the fit window is now at the top of the of the dialog instead of the bottom.
 - Condition to check if a property is enabled when serializing.
 - Workspace locking no longer prevents simple read operations required to display the workspace conext menu in Mantidplot.
 - TableWorkspaces can now be converted to a Python dictionary by calling the ``table.toDict()`` function.
-- Added new classes ``ConfigObserver`` for listening for changes to any configuration property and ``ConfigPropertyObserver`` for listening to changes to an individual config property of interest.
+- ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``.
+
+Bugfixes
+########
+- Fixed an issue where certain isotopes could not be accessed using the `Atom` classes, e.g Si28.
+- ``datasearch.searcharchive`` :ref:`property <Properties File>` has new functionality to only search the default facility.
 - Fixed the calculation of scattering length and scattering length squared for :py:obj:`Material <mantid.kernel.Material>`.
 - Fixed the behaviour of ``UpdateInstrumentDefinitions.OnStartup`` in the :ref:`properties file <Properties File>`. It was not being used correctly for using the updated ``Facilities.xml`` file.
-- ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``.
+
 
 Live Data
 ---------
 
+New
+###
 - ``KafkaEventListener`` is a new live listener for neutron event and sample environment data which is in development for the ESS and ISIS.
 
 Performance
 -----------
 
+Improved
+########
 - :ref:`LoadEmptyInstrument <algm-LoadEmptyInstrument>` and load algorithms that are using it. Improved performance for second and consecutive loads of instrument geometry, particularly for instruments with many detector pixels. 
 - :ref:`CropToComponent <algm-CropToComponent>`: Up to 30% performance improvement, based on ongoing work on Instrument-2.0.
 - :ref:`MaxEnt <algm-MaxEnt>`: Improved rate of convergence. The  ``ChiTarget`` property has been replaced by  ``ChiTargetOverN``.
+
+Bugfixes
+########
 - A `bug <https://github.com/mantidproject/mantid/pull/20953>`_ in the handling of fractional bin weights in a specialised form (`RebinnedOutput <http://doxygen.mantidproject.org/nightly/d4/d31/classMantid_1_1DataObjects_1_1RebinnedOutput.html>`_) of :ref:`Workspace2D <Workspace2D>` has been fixed. This mainly affects the algorithms :ref:`algm-SofQWNormalisedPolygon` and :ref:`algm-Rebin2D`, which underlies the `SliceViewer <http://www.mantidproject.org/MantidPlot:_SliceViewer>`_.
 
 Python
 ------
-In ``mantid.simpleapi``, a keyword has been implemented for function-like algorithm calls to control the storing on the Analysis Data Service.
-``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS.
 
-- The standard Python operators, e.g. ``+``, ``+=``, etc., now work also with workspaces not in the ADS.
-- The ``isDefault`` attribute for workspace properties now works correctly with workspaces not in the ADS.
-- The previously mentioned ``ConfigObserver`` and ``ConfigPropertyObserver`` classes are also exposed to python.
-- ``mantid.kernel.V3D`` vectors now support negation through the usual ``-`` operator.
-- It is now possible to `pickle <https://docs.python.org/2/library/pickle.html>`_ and de-pickle :ref:`Workspace2D <Workspace2D>` and :ref:`TableWorkspace <Table Workspaces>` in Python. This has been added to make it easier to transfer your workspaces over a network. Only these two workspace types currently supports the pickling process, and there are limitations to be aware of described :ref:`here <Workspace2D>`.
+New
+###
 - ``mantid.api.IPeak`` has three new functions:
     - ``getEnergyTransfer`` which returns the difference between the initial and final energy.
     - ``getIntensityOverSigma`` which returns the peak intensity divided by the error in intensity.
     - ``getGoniometerMatrix`` which returns the goniometer rotation matrix associated with the peak.
 
-Support for unicode property names has been added to python. This means that one can run the following in python2 or python3.
+
+Improved
+########
+
+
+- In ``mantid.simpleapi``, a keyword has been implemented for function-like algorithm calls to control the storing on the Analysis Data Service.
+- ``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS.
+- The standard Python operators, e.g. ``+``, ``+=``, etc., now work also with workspaces not in the ADS.
+- The ``isDefault`` attribute for workspace properties now works correctly with workspaces not in the ADS.
+- The previously mentioned ``ConfigObserver`` and ``ConfigPropertyObserver`` classes are also exposed to Python.
+- ``mantid.kernel.V3D`` vectors now support negation through the usual ``-`` operator.
+- It is now possible to `pickle <https://docs.python.org/2/library/pickle.html>`_ and de-pickle :ref:`Workspace2D <Workspace2D>` and :ref:`TableWorkspace <Table Workspaces>` in Python. This has been added to make it easier to transfer your workspaces over a network. Only these two workspace types currently supports the pickling process, and there are limitations to be aware of described :ref:`here <Workspace2D>`.
+- Support for unicode property names has been added to Python. This means that one can run the following in Python2 or Python3.
 
 .. code-block:: python
 
-   from mantid.simpleapi import Segfault
+   from mantid.simpleapi import *
    import json
-   props = json.loads('{"DryRun":true}')
-   Segfault(**props)
+   source = json.loads('{"Filename":"CNCS_7860_event.nxs"}')
+   props = json.loads('{"InputWorkspace":"eventWS", "Params":"1000"}')
+   eventWS = Load(**source)
+   rebinned = Rebin(**props)
+
+Deprecated
+##########
+
+- `MantidPlot.pyplot <http://docs.mantidproject.org/v3.11.0/api/python/mantidplot/pyplot/index.html>`_ was an early attempt to provide Matplotlib style syntax over Mantidplot plotting.  This will be replaced in Mantid 4.0 with MatPlotlib itself, and this packages would cause namespace clashes and confusion.  This package is now deprecated, and will not be included in future releases of Mantid.  To the best of our knowledge the impact of this should be minimal as it is at best only rarely used.
+
 
+Bugfixes
+########
 - Fixed an issue with coercing data from python lists or numpy arrays where the datatype!=float64 into a workspace
 
 :ref:`Release 3.12.0 <v3.12.0>`
diff --git a/docs/source/release/v3.12.0/index.rst b/docs/source/release/v3.12.0/index.rst
index 986c57b3595e0ff1c0ccd7195ce69a499e20befe..6e4e7479a0d6828cadb9ae466d7f30192f0aab3a 100644
--- a/docs/source/release/v3.12.0/index.rst
+++ b/docs/source/release/v3.12.0/index.rst
@@ -40,7 +40,7 @@ access the source code on `GitHub release page`_.
 Citation
 --------
 
-Please cite any usage of Mantid as follows: **TODO update with current version doi**
+Please cite any usage of Mantid as follows:
 
 - *Mantid 3.12.0: Manipulation and Analysis Toolkit for Instrument Data.; Mantid Project*. `doi: 10.5286/SOFTWARE/MANTID3.12.0 <http://dx.doi.org/10.5286/SOFTWARE/MANTID3.12.0>`_
 
diff --git a/docs/source/release/v3.12.0/indirect_inelastic.rst b/docs/source/release/v3.12.0/indirect_inelastic.rst
index 7d6c680e7ecc798836e8c9db15391aaea9d8f422..8435f27760cf6aedc61a59d02eb39b6c688657ee 100644
--- a/docs/source/release/v3.12.0/indirect_inelastic.rst
+++ b/docs/source/release/v3.12.0/indirect_inelastic.rst
@@ -5,28 +5,6 @@ Indirect Inelastic Changes
 .. contents:: Table of Contents
    :local:
 
-Algorithms
-----------
-
-New
-###
-
-- :ref:`algm-ExtractQENSMembers` can be used to extract the fit members from any QENS fit.
-- New algorithm :ref:`BASISDiffraction <algm-BASISDiffraction-v1>` to determine the orientation of crystal samples for the BASIS beamline.
-
-
-Improved
-########
-
-- :ref:`algm-ApplyPaalmanPingsCorrection` now accepts a corrections group containing only an :math:`A_{s,s}` and an :math:`A_{c,c}` workspace (produced by :ref:`algm-CalculateMonteCarloAbsorption`).
-- :ref:`BASISReduction  <algm-BASISReduction>` now permits the user to exclude a contiguous time segment from the reduction process.
-- :ref:`BASISReduction <algm-BASISReduction>` option *noMonitorNorm* changed to *MonitorNorm*.
-- :ref:`BASISReduction <algm-BASISReduction>` now contains log entry *asString* storing the options passed to to the algorithm.
-- :ref:`IqtFitSequential <algm-IqtFitSequential>` and :ref:`IqtFitMultiple <algm-IqtFitMultiple>` can now both extract members from the fit (when the ExtractMembers property is set to True).
-- Loading the sample log files into a workspace can be disabled when calling the :ref:`LoadVesuvio <algm-LoadVesuvio>` algorithm by supplying *LoadLogFiles=False* to the algorithm call
-- :ref:`OSIRISDiffractionReduction <algm-OSIRISDiffractionReduction>` no longer has options *DetectDRange* and *DRange*, D-Ranges are now always calculated automatically within the algorithm.
-
-
 Vesuvio
 -------
 
@@ -54,8 +32,8 @@ New
 
 .. figure:: ../../images/Indirect_ConvFit_3_12_release.png
    :class: screenshot
-   :align: center
-   :width: 500 px
+   :align: right
+   :figwidth: 50%
 
    The new design of the Indirect Fitting tabs, shown here within ConvFit (the IndirectFitPropertyBrowser is seen on the left and can be ejected into a separate window).
 
@@ -104,10 +82,10 @@ Improved
 - The Apply Absorption Correction interface no longer requires workspaces to be in units of wavelength (this is done within :ref:`algm-ApplyPaalmanPingsCorrection`).
 - Calculate Monte Carlo Absorption interface has been restructured in a more appropriate format, as outlined in the following image:
 
-.. image::  ../../images/AbsorbtionCorrectionsGui312.png
-   :align: center
+.. figure::  ../../images/AbsorbtionCorrectionsGui312.png
+   :align: right
    :class: screenshot
-   :width: 800px
+   :figwidth: 50%
 
 - Result plotting in the Calculate Monte Carlo Absorption interface is now the same as that in Apply Absorption Correction; ability to select whether to plot result in Wavelength, Angle or Both.
 
@@ -126,4 +104,25 @@ Improved
 ########
 - Performance of Abins rebinning routines significantly improved (a factor of 10-20 times for data size of 4000).
 
+Algorithms
+----------
+
+New
+###
+
+- :ref:`algm-ExtractQENSMembers` can be used to extract the fit members from any QENS fit.
+- New algorithm :ref:`BASISDiffraction <algm-BASISDiffraction-v1>` to determine the orientation of crystal samples for the BASIS beamline.
+
+
+Improved
+########
+
+- :ref:`algm-ApplyPaalmanPingsCorrection` now accepts a corrections group containing only an :math:`A_{s,s}` and an :math:`A_{c,c}` workspace (produced by :ref:`algm-CalculateMonteCarloAbsorption`).
+- :ref:`BASISReduction  <algm-BASISReduction>` now permits the user to exclude a contiguous time segment from the reduction process.
+- :ref:`BASISReduction <algm-BASISReduction>` option *noMonitorNorm* changed to *MonitorNorm*.
+- :ref:`BASISReduction <algm-BASISReduction>` now contains log entry *asString* storing the options passed to to the algorithm.
+- :ref:`IqtFitSequential <algm-IqtFitSequential>` and :ref:`IqtFitMultiple <algm-IqtFitMultiple>` can now both extract members from the fit (when the ExtractMembers property is set to True).
+- Loading the sample log files into a workspace can be disabled when calling the :ref:`LoadVesuvio <algm-LoadVesuvio>` algorithm by supplying *LoadLogFiles=False* to the algorithm call
+- :ref:`OSIRISDiffractionReduction <algm-OSIRISDiffractionReduction>` no longer has options *DetectDRange* and *DRange*, D-Ranges are now always calculated automatically within the algorithm.
+
 :ref:`Release 3.12.0 <v3.12.0>`
diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst
index ba6d28c8c275f7c01d27ebdcf9fe00116f1ade4d..bb310b1277b2d8060cb490c5dbc955ddeeada2bf 100644
--- a/docs/source/release/v3.12.0/muon.rst
+++ b/docs/source/release/v3.12.0/muon.rst
@@ -8,16 +8,14 @@ MuSR Changes
 .. figure:: ../../images/muon_release_3_12.png
    :class: screenshot
    :align: right
-   :width: 500 px
-
-
-Bug Fixes
----------
-- :ref:`CalMuonDetectorPhases <algm-CalMuonDetectorPhases>` has had the sign of the phase shift changed, this produces data with a positive frequency spike as expected.
-- Log values are no longer filtered by start time when loaded into muon analysis.
+   :figwidth: 50%
 
 Interface
 ---------
+
+Improvements
+############
+
 - Added a cancel button to the MaxEnt widget in Frequency Domain Analysis.
 - Added checkboxes for "add all pairs" and "add all groups" to the settings tab.
 - The data plot style in the settings tab of Muon Analysis, only alters the plot range. It no longer crops the data.
@@ -34,12 +32,31 @@ Interface
 - The period summation/subtraction can now be used in multiple fitting. 
 - Muon analysis now handles the "auto background" gracefully in single and multiple fitting modes.
 - We have disabled some non functional graph right click context menu items or adding functions when in multi data fitting mode, in the Data Analysis tab of the Muon Analysis Interface.
+- Frequency domain analysis will produce a warning if there is no data to load.
 
+Bug fixes
+#########
+
+- Log values are no longer filtered by start time when loaded into muon analysis.
+- Different options under `Settings`>`Data Binning` give different options for input (OSX bug, see Issue ##22167). Fixed in patch.
 
 Algorithms
 ----------
-- :ref:`MuonProcess <algm-MuonProcess>` now has a flag to determine if to crop the input workspace (default is true). In the Muon Analysis interface this flag has been set to false.
+
+New
+###
+
 - :ref:`MuonMaxent <algm-MuonMaxent>` calculates a single frequency spectrum from multiple time domain spectra.
+
+Improvements
+############
+
+- :ref:`MuonProcess <algm-MuonProcess>` now has a flag to determine if to crop the input workspace (default is true). In the Muon Analysis interface this flag has been set to false.
 -  :ref:`EstimateMuonAsymmetryFromCounts <algm-EstimateMuonAsymmetryFromCounts-v1>`: if the number of good frames is zero, then a value of 1 is assumed for the number of good frames.
 
+Bug fixes
+#########
+
+- :ref:`CalMuonDetectorPhases <algm-CalMuonDetectorPhases>` has had the sign of the phase shift changed, this produces data with a positive frequency spike as expected.
+
 :ref:`Release 3.12.0 <v3.12.0>`
diff --git a/docs/source/release/v3.12.0/reflectometry.rst b/docs/source/release/v3.12.0/reflectometry.rst
index 08bca96b8aa7bb27ed52f865c69787fc9f6c970b..ad414a4088bc5a283f4836f64e55c233719e9477 100644
--- a/docs/source/release/v3.12.0/reflectometry.rst
+++ b/docs/source/release/v3.12.0/reflectometry.rst
@@ -12,10 +12,22 @@ ISIS Reflectometry Interface
 New features
 ############
 
-- A new table has been added to the Settings tab to allow default options to be specified on a per-angle basis. If a row in the Runs tab contains an angle, it will be looked up in this table and those options will be used if a matching angle is found (the angle does not have to be exact as it will match to within 100th of a degree). If you want to specify values that will be used by default for all runs, then simply leave the angle empty.
-- Two new boxes have been added to the settings tab of the ISIS Reflectometry interface, 'ReductionType' and 'SummationType' which are passed to the corresponding parameters of :ref:`algm-ReflectometryReductionOneAuto`.
-- The ISIS Reflectometry interface now has a checkbox 'CorrectDetectors' which maps to the corresponding property in :ref:`algm-ReflectometryReductionOneAuto`.
+.. figure:: ../../images/ISIS_Reflectometry_per_angle_options.png
+   :class: screenshot
+   :align: center
+
+   New table to specify settings on a per-angle basis
+
+- The following new options have been added to the Settings tab:
+
+  - A new table has been added to the Experiment settings which allows default options to be specified on a per-angle basis. If a row in the Runs tab contains an angle, it will be looked up in this table and those options will be used if a matching angle is found (the angle does not have to be exact as it will match to within 100th of a degree). If you want to specify values that will be used by default for all runs, then simply leave the angle empty.
+    
+  - Two new drop-down boxes have been added to the Experiment settings, 'ReductionType' and 'SummationType', which are passed to the corresponding parameters of :ref:`algm-ReflectometryReductionOneAuto`.
+
+  - A 'CorrectDetectors' check box has been added to the Instrument settings, which maps to the corresponding property in :ref:`algm-ReflectometryReductionOneAuto`.
+
 - The 'Get Defaults' button now looks for values for the following additional properties in the IDF:
+  
   - AnalysisMode
   - PolarizationAnalysis
   - TransRunStartOverlap
@@ -25,29 +37,39 @@ New features
   - CorrectDetectors
   - SummationType
   - ReductionType
+- There is a new checkbox on the SaveASCII tab which automatically saves the 'IvsQ_binned' workspace for single row reductions and the stitched workspace for group reductions.
 
 Improvements
 ############
 
-- Output workspace names for time sliced data now contain the time periods, rather than just a slice index number.
-- Grid lines are now displayed in the runs tab.
-- Plotting results in event handling mode now plots the `IvsQ_binned_` workspaces rather than `IvsQ_`, to make the behaviour consistent with non-event mode.
-- Menu items and toolbar buttons are now enabled/disabled when appropriate, e.g. to prevent table modification during processing. Directly editing table rows and settings is also disabled during processing.
-- Removed the 'DirectBeam' box from the settings tab of the ISIS Reflectometry interface because this is not used.
+- Output workspace names and plotting:
+  
+  - Output workspace names now use ``+`` to indicate preprocessed (i.e. summed) workspaces, rather than ``_``, which is used to indicate postprocessed (i.e. stitched) workspaces.
+  - Output workspace names for time sliced data now contain the time periods, rather than just a slice index number.
+  - Plotting results in event handling mode now plots the ``IvsQ_binned_`` workspaces rather than ``IvsQ_``, to make the behaviour consistent with non-event mode.
+  - The Python code generated when you tick ``Output Notebook`` has been improved to support special characters (e.g. ``+``) in workspace names.
+  - The ``Output Notebook`` option now works for all groups that are processed as non-event workspaces. Previously, if event handling was enabled but a group contained non-event workspaces, generating the notebook was not performed.
+    
 - Properties on the Runs tab now take precedence over properties on the Settings tab.
-- Output workspace names have been improved. Names now use '+' to indicate preprocessed (i.e. summed) workspaces, rather than '_', which is used to indicate postprocessed (i.e. stitched) workspaces.
-- The Python code generated when you tick `Output Notebook` has been improved to support special characters (e.g. `+`) in workspace names. Output workspaces are now set using the output properties of the algorithm rather than by variable assignment. This avoids the possibility of invalid characters being used in Python variable names.
-- The `Output Notebook` option now works for all groups that are processed as non-event workspaces. Previously, if event handling was enabled but a group contained non-event workspaces, generating the notebook was disabled.
-- Added a new `?` button to the ISIS Reflectometry Interface which links to the documentation page.
-- Added extra tooltips to the ISIS Reflectometry Interface.
+  
+- Extra tooltips have been added along with a new ``?`` button which links to the documentation page.
+  
+- The runs tab table now contains grid lines to make it easier to see where to enter text.
+  
+- Menu items and toolbar buttons are now enabled/disabled when appropriate, e.g. to prevent table modification during processing. Directly editing table rows and settings is also disabled during processing.
+  
+- The 'DirectBeam' box has been from the settings tab because this is not used.
 
 
 Bug fixes
 #########
 
 - Fixed some bugs where transmission runs entered on the Settings tab were not being found, whether entered as a run number to load or as the name of an existing workspace in the ADS.
-- The Python code generated when you tick `Output Notebook` has been changed so that all algorithm property values are enclosed in quotes. Unquoted values were causing failures in some algorithms. A bug has also been fixed in setting the legend location for the 4th (stitched) plot, which is shown when post-processing is performed.
+  
+- The Python code generated when you tick ``Output Notebook`` has been changed so that all algorithm property values are enclosed in quotes. Unquoted values were causing failures in some algorithms. A bug has also been fixed in setting the legend location for the 4th (stitched) plot, which is shown when post-processing is performed.
+  
 - If any of the mandatory parameters listed below are missing when pressing 'Get Default' a warning is shown rather than a crash.
+
   - MonitorIntegralMax
   - MonitorIntegralMin
   - MonitorBackgroundMin,
@@ -56,6 +78,7 @@ Bug fixes
   - LambdaMax,
   - I0MonitorIndex
   - TransRunStartOverlap and TransRunEndOverlap if on SURF or CRISP.
+
 - Fixed a bug where the processed state of rows was being reset when transferring additional rows into the table.
 
 Features Removed
@@ -78,8 +101,8 @@ New features
 Improvements
 ############
 
-- Removed the ``RegionOfDirectBeam`` property from :ref:`algm-ReflectometryReductionOne` and :ref:`algm-ReflectometryReductionOneAuto` because this is not used.
 - Improvements to :ref:`algm-LoadILLReflectometry`:
+
   - Figaro NeXus files are now properly handled.
   - A new property, *BeamCentre* allows user to manually specify the beam position on the detector.
   - The *BeamPosition* property was renamed to *DirectBeamPosition* to better reflect its usage.
@@ -87,6 +110,8 @@ Improvements
   - Slits S2 and S3 have been added to D17 and Figaro IDFs; the loader will adjust their positions according to the NeXus files.
   - The MagnetismReflectometryReduction now computes a Q-resolution estimate based on slit openings.
 
+- Removed the ``RegionOfDirectBeam`` property from :ref:`algm-ReflectometryReductionOne` and :ref:`algm-ReflectometryReductionOneAuto` because this is not used.
+
 Bug fixes
 #########
 
diff --git a/docs/source/release/v3.12.0/sans.rst b/docs/source/release/v3.12.0/sans.rst
index 8939231f13f582330b0719c6ab1bcd94df3b8b79..76b8f71d33d962ac4589f18c53a1caf07fb170b3 100644
--- a/docs/source/release/v3.12.0/sans.rst
+++ b/docs/source/release/v3.12.0/sans.rst
@@ -10,6 +10,9 @@ SANS Changes
 ILL SANS
 --------
 
+Improvements
+############
+
 - Minor changes of the D33 instrument definition file, e.g. detector indexing.
 - New instrument definition file for the D22 instrument
 - New instrument definition file for the D11 instrument
@@ -17,10 +20,10 @@ ILL SANS
 ISIS SANS
 ---------
 
-.. image::  ../../images/ISIS_SANS_312.png
+.. figure::  ../../images/ISIS_SANS_312.png
    :align: right
    :class: screenshot
-   :width: 800px
+   :figwidth: 50%
 
 New features
 ############
@@ -50,5 +53,9 @@ Bug fixes
 - Fixed a bug in the old GUI where 2D reductions were being run in 1D if a new user file was specified in a batch file.
 - Fixed a bug in Isis Gui v2 whereby the sum runs script was not working for ZOOM.
 
+Deprecation
+###########
+- As an advance warning we plan to remove the 1D Analysis tab from the old Gui for the next release.
+
 
 :ref:`Release 3.12.0 <v3.12.0>`
diff --git a/docs/source/release/v3.12.1/index.rst b/docs/source/release/v3.12.1/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8bd195ecd3b6f3a6d178ae7921f5dfeb30d5db55
--- /dev/null
+++ b/docs/source/release/v3.12.1/index.rst
@@ -0,0 +1,99 @@
+.. _v3.12.1:
+
+===========================
+Mantid 3.12.1 Release Notes
+===========================
+
+.. contents:: Table of Contents
+   :local:
+
+This is a patch release that corrects some significant issues since :ref:`version 3.12.0 <v3.12.0>`.
+
+The main changes are:
+
+* Several fixes to the Muon Analysis GUI, including to the results table and fit menu.
+* Several issues which caused mantid to crash have been fixed.
+* Allowing the live listener funtionality to be used outside ISIS and from the python API.
+* Fixing the header for TOPAS files.
+* Removed version 1 of ``ReflectometryReductionOne`` and ``ReflectometryReductionOneAuto``
+
+Citation
+--------
+
+Please cite any usage of Mantid as follows:
+
+- *Mantid 3.12.1: Manipulation and Analysis Toolkit for Instrument Data.; Mantid Project*.
+  `doi: 10.5286/Software/Mantid3.12.1 <http://dx.doi.org/10.5286/Software/Mantid3.12.1>`_
+
+- Arnold, O. et al. *Mantid-Data Analysis and Visualization Package for Neutron Scattering and mu-SR Experiments.* Nuclear Instruments
+  and Methods in Physics Research Section A: Accelerators, Spectrometers, Detectors and Associated Equipment 764 (2014): 156-166
+  `doi: 10.1016/j.nima.2014.07.029 <https://doi.org/10.1016/j.nima.2014.07.029>`_
+  (`download bibtex <https://raw.githubusercontent.com/mantidproject/mantid/master/docs/source/mantid.bib>`_)
+
+Changes in this version
+-----------------------
+
+* `22205 <https://github.com/mantidproject/mantid/pull/22205>`_ Fix header for TOPAS files
+* `22213 <https://github.com/mantidproject/mantid/pull/22215>`_ Fix bug when using StartLiveData through Python API
+* `22195 <https://github.com/mantidproject/mantid/pull/22195>`_ CrystalField Multi-spectrum resolution model segfault
+* `22194 <https://github.com/mantidproject/mantid/pull/22194>`_ SofQW3 segfault
+* `22190 <https://github.com/mantidproject/mantid/pull/22190>`_ OSX Muon Interface (No need for data)
+* `22182 <https://github.com/mantidproject/mantid/pull/22182>`_ Update mslice to fix issue with matplotlib < 1.5
+* `22200 <https://github.com/mantidproject/mantid/pull/22200>`_ Fix unreliable tests: Disable ClearCache doc test
+* `22244 <https://github.com/mantidproject/mantid/pull/22244>`_ MR: correct dQ
+* `22178 <https://github.com/mantidproject/mantid/pull/22178>`_ Muon Analysis bug that disabled fit menu
+* `22177 <https://github.com/mantidproject/mantid/pull/22177>`_ Muon analysis and results table
+* `21655 <https://github.com/mantidproject/mantid/pull/21655>`_ Remove dependence of Kafka Live Listener on ISIS specific event data
+* `22226 <https://github.com/mantidproject/mantid/pull/22226>`_ Error when deleting a workspace group in MantidPlot
+* `20997 <https://github.com/mantidproject/mantid/pull/20997>`_ Re #20991: Updated Reflectometry IDFs
+* `22290 <https://github.com/mantidproject/mantid/pull/22290>`_ Updated print statement to python 3 in SaveWorkspaces
+* `22152 <https://github.com/mantidproject/mantid/pull/22152>`_ Updated IDF for D2B
+* `22175 <https://github.com/mantidproject/mantid/pull/22175>`_ Fix failing Reflectometry doctests
+
+Summary of impact
+-----------------
+
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| Issue | Impact                                                                                  | Solution                  | Side Effect  |
+|       |                                                                                         |                           | Probability  |
++=======+=========================================================================================+===========================+==============+
+| 22205 | Fix header for TOPAS files                                                              | Check for header type     | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22215 | Fix bug when using StartLiveData through Python API                                     | Remove kwarg if None      | **medium**   |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22195 | CrystalField Multi-spectrum resolution model segfault                                   | Check sizes               | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22194 | SofQW3 segfault no longer occurs                                                        | Indexing change           | **medium**   |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22190 | OSX Muon Interface data requirments fixed                                               | GUI changes               | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22182 | Update mslice to fix issue with matplotlib < 1.5                                        | Update sha1               | **medium**   |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22200 | Fix unreliable tests: Disable ClearCache doc test                                       | Clear cache before build  | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22244 | Fix dQ calculation in MR Reduction                                                      | Now uses radians          | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22178 | Fix menu is Muon Analysis not disabled                                                  | Change enabled conditions | **medium**   |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22177 | Muon analysis results table generated correctly                                         | Additional checks         | **medium**   |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 21655 | Remove dependence of Kafka Live Listener on ISIS specific event data                    | Remove dependence         | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22226 | Error when deleting a workspace group in MantidPlot                                     | Better thread safety      | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 20997 | Updated Reflectometry IDFs                                                              | Changed IDFs              | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 20997 | Removed version 1 of ``ReflectometryReductionOne`` and ``ReflectometryReductionOneAuto``| Removed old algorithms    | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22290 | Updated print statement in SaveWorkspaces                                               | Made Python3 compatible   | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 11152 | Updated IDF for D2B                                                                     | Updated IDF               | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+| 22175 | Fix failing Reflectometry doctests                                                      | Updated expected values   | **low**      |
++-------+-----------------------------------------------------------------------------------------+---------------------------+--------------+
+
+.. _download page: http://download.mantidproject.org
+
+.. _forum: http://forum.mantidproject.org
+
+.. _GitHub release page: https://github.com/mantidproject/mantid/releases/tag/v3.12.1
diff --git a/docs/source/release/v3.13.0/diffraction.rst b/docs/source/release/v3.13.0/diffraction.rst
index 283f33d9fb49eee1dd1df483d80c2d4773e50656..f94d148aec88771e4cc9af749ddf559729516bfc 100644
--- a/docs/source/release/v3.13.0/diffraction.rst
+++ b/docs/source/release/v3.13.0/diffraction.rst
@@ -9,4 +9,46 @@ Diffraction Changes
     putting new features at the top of the section, followed by
     improvements, followed by bug fixes.
 
+Powder Diffraction
+------------------
+
+- Changing settings while running methods on the PEARL object no
+  longer updates the default settings. Instead, initial settings are
+  taken as the default, and any changes are reverted back to the
+  default once the line they were made on has finished executing
+
+New Features
+------------
+
+- :ref:`PowderDiffILLDetEffCorr <algm-PowderDiffILLDetEffCorr>` is extended to compute the detector efficiencies also for the 2-dimensional scanning diffractometer D2B at the ILL.
+- :ref:`WANDPowderReduction <algm-WANDPowderReduction>` performs powder diffraction data reduction for WAND² with calibration, monitor normalisation and background subtraction.
+
+
+Engineering Diffraction
+-----------------------
+
+- Improvements to the GSAS tab:
+
+  - GSASIIRefineFitPeaks is now run asynchronously in the GUI, so the
+    tab no longer locks when a refinement is run
+  - A **Refine All** button was added to run refinement on every run
+    loaded into the tab
+
+- :ref:`GSASIIRefineFitPeaks <algm-GSASIIRefineFitPeaks>` now supports Pawley refinement as well as Rietveld
+
+
 :ref:`Release 3.13.0 <v3.13.0>`
+
+Single Crystal Diffraction
+--------------------------
+
+- New algorithm :ref:`LoadDNSSCD <algm-LoadDNSSCD>` to load multiple single crystal diffraction data files from the DNS instrument into MDEventWorkspace.
+
+- :ref:`SaveLauenorm <algm-SaveLauenorm>` now has input options for crystal system and reflection condition for lscale output instead of trying to determine from lattice parameters.
+
+Improvements
+############
+
+- PeaksWorkspace has column added for the unique peak number so peaks can be found after sorting or filtering.
+
+- :ref:`StatisticsOfPeaksWorkspace <algm-StatisticsOfPeaksWorkspace>` has option to use a weighted Z score for determining which peaks are outliers and has a new output workspace for plotting intensities of equivalent peaks.
diff --git a/docs/source/release/v3.13.0/direct_inelastic.rst b/docs/source/release/v3.13.0/direct_inelastic.rst
index 5a108596d33dc28f6ef9c304eda425baffbe05d8..fc23231f8b9b61be7de5cb4f4e4d34fed69c18ba 100644
--- a/docs/source/release/v3.13.0/direct_inelastic.rst
+++ b/docs/source/release/v3.13.0/direct_inelastic.rst
@@ -12,7 +12,21 @@ Direct Inelastic Changes
 Algorithms
 ----------
 
+
+New features
+############
+
 - The *EPPWorkspace* input property has been removed from :ref:`DirectILLCollectData <algm-DirectILLCollectData>`.
 
+Improvements
+############
+
+- :ref:`DirectILLReduction <algm-DirectILLReduction>` now converts all its output workspaces to distributions, i.e. divides the histograms by the bin width.
+
+Bug fixes
+#########
+
+- Fixed a crash in :ref:`SofQW <algm-SofQW>`, :ref:`SofQWCentre <algm-SofQWCentre>`, :ref:`SofQWNormalisedPolygon <algm-SofQWNormalisedPolygon>` and :ref:`SofQWPolygon <algm-SofQWPolygon>` algorithms when they were supplied with energy or :math:`Q` binning params containing the bin width only.
+
 :ref:`Release 3.13.0 <v3.13.0>`
 
diff --git a/docs/source/release/v3.13.0/framework.rst b/docs/source/release/v3.13.0/framework.rst
index 89615c6d35261d2aed07bc4f826ef7c78cddfc20..80ce5d87e34009789066354402ab8fa138943230 100644
--- a/docs/source/release/v3.13.0/framework.rst
+++ b/docs/source/release/v3.13.0/framework.rst
@@ -9,4 +9,40 @@ Framework Changes
     putting new features at the top of the section, followed by
     improvements, followed by bug fixes.
 
+
+Algorithms
+----------
+
+New Features
+############
+
+- A list of Related Algorithms has been added to each algorithm, and is displayed in the documentation page of each algorithm as part of it's summary.
+
+New Algorithms
+##############
+
+
+Improved
+########
+
+- :ref:`Maxent <algm-Maxent>` when outputting the results of the iterations, it no longer pads with zeroes but
+  returns as many items as iterations done for each spectrum, making the iterations easy to count.
+- :ref:`ConvertToPointData <algm-ConvertToPointData>` and :ref:`ConvertToHistogram <algm-ConvertToHistogram>` now propagate the Dx errors to the output.
+- The algorithm :ref:`CreateWorkspace <algm-CreateWorkspace>` can now optionally receive the Dx errors.
+- :ref:`ConjoinXRuns <algm-ConjoinXRuns>` joins Dx errors if present
+- The algorithm :ref:`SortXAxis <algm-SortXAxis>` has a new input option that allows ascending (default) and descending sorting. Furthermore, Dx values will be considered if present. The documentation needed to be corrected.
+
+New
+###
+
+- Algorithm :ref:`FitPeaks <algm-FitPeaks>` is implemented as a generalized multiple-spectra multiple-peak fitting algorithm.
+
+Bug fixes
+#########
+
+- The documentation of the algorithm :ref:`algm-CreateSampleWorkspace` did not match its implementation. The axis in beam direction will now be correctly described as Z instead of X.
+- The :ref:`ExtractMask <algm-ExtractMask>` algorithm now returns a non-empty list of detector ID's when given a MaskWorkspace.
+- Fixed a crash when the input workspace for :ref:`GroupDetectors <algm-GroupDetectors>` contained any other units than spectrum numbers.
+- Fixed :ref:`SumSpectra <algm-SumSpectra>` to avoid a crash when validation of inputs was called with a WorkspaceGroup.
+
 :ref:`Release 3.13.0 <v3.13.0>`
diff --git a/docs/source/release/v3.13.0/index.rst b/docs/source/release/v3.13.0/index.rst
index a1dc52a6f3627e038555bcdce0f137a7271d8f88..ff34eec1b9cd51f35929d4bdf5f12502bb20c18f 100644
--- a/docs/source/release/v3.13.0/index.rst
+++ b/docs/source/release/v3.13.0/index.rst
@@ -36,6 +36,7 @@ Changes
    SANS <sans>
    Direct Inelastic <direct_inelastic>
    Indirect Inelastic <indirect_inelastic>
+   Instrument Visualization <instrument_view>
 
 Full Change Listings
 --------------------
diff --git a/docs/source/release/v3.13.0/instrument_view.rst b/docs/source/release/v3.13.0/instrument_view.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fadb882e2b08d29dddf462d71fab4869629844a8
--- /dev/null
+++ b/docs/source/release/v3.13.0/instrument_view.rst
@@ -0,0 +1,36 @@
+========================
+Instrument Visualization
+========================
+
+.. contents:: Table of Contents
+   :local:
+
+.. warning:: **Developers:** Sort changes under appropriate heading
+    putting new features at the top of the section, followed by
+    improvements, followed by bug fixes.
+
+Instrument View
+---------------
+
+The `Instrument View <https://www.mantidproject.org/MantidPlot:_Instrument_View>`__ visualization tool in Mantid has undergone some major changes under-the-hood which has resulted in a smoother, more responsive interface. 
+Instruments generally load faster as well. Below are a few noteworthy improvements to load times:
+
++------------+-----------+
+| Instrument | Speedup   |
++============+===========+
+| WISH       | 5x        |
++------------+-----------+
+| BASIS      | 5x        |
++------------+-----------+
+| GEM        | 4x        |
++------------+-----------+
+| SANS2D     | 3x        |
++------------+-----------+
+| POLARIS    | 3x        |
++------------+-----------+
+| CNCS       | 2x        |
++------------+-----------+
+
+Tested on Windows 10.
+
+:ref:`Release 3.13.0 <v3.13.0>`
\ No newline at end of file
diff --git a/docs/source/release/v3.13.0/muon.rst b/docs/source/release/v3.13.0/muon.rst
index 38a16b54f58a426ff6072735474fc87fca8d2e88..ab2cf91ed6c4141c1587ec51e400478ed6732103 100644
--- a/docs/source/release/v3.13.0/muon.rst
+++ b/docs/source/release/v3.13.0/muon.rst
@@ -4,9 +4,34 @@ MuSR Changes
 
 .. contents:: Table of Contents
    :local:
+   
+Interface
+---------
 
-.. warning:: **Developers:** Sort changes under appropriate heading
-    putting new features at the top of the section, followed by
-    improvements, followed by bug fixes.
+
+Interface
+---------
+
+
+Improvements
+############
+
+Bug fixes
+#########
+
+- Results table can now detect sequential fits.
+- Fit options are not disabled after changing tabs.
+
+Algorithms
+----------
+
+New
+###
+
+Improvements
+############
+
+Bug fixes
+#########
 
 :ref:`Release 3.13.0 <v3.13.0>`
diff --git a/docs/source/release/v3.13.0/reflectometry.rst b/docs/source/release/v3.13.0/reflectometry.rst
index 7875f5476718bb0ae1ecf8099b01eb44bb63ea75..5268cfb3c7aee0ad2d0a35ac60c33993ee50be61 100644
--- a/docs/source/release/v3.13.0/reflectometry.rst
+++ b/docs/source/release/v3.13.0/reflectometry.rst
@@ -9,4 +9,39 @@ Reflectometry Changes
     putting new features at the top of the section, followed by
     improvements, followed by bug fixes.
 
+ISIS Reflectometry Interface
+----------------------------
+
+New features
+############
+
+Improvements
+############
+
+Bug fixes
+#########
+
+Features Removed
+################
+
+* Added deprecation notice to ISIS Reflectometry (Old) due to be removed in March 2019.
+
+Algorithms
+----------
+
+* Removed version 1 of ``ReflectometryReductionOne`` and ``ReflectometryReductionOneAuto``.
+
+New features
+############
+
+- A new algorithm :ref:`algm-ReflectometryMomentumTransfer` provides conversion to momentum transfer and :math:`Q_{z}` resolution calculation for relfectivity workspaces.
+
+Improvements
+############
+
+Bug fixes
+#########
+
+* Correct the angle to the value of ``ThetaIn`` property if summing in lambda in ``ReflectometryReductionOne-v2``.
+
 :ref:`Release 3.13.0 <v3.13.0>`
diff --git a/docs/source/release/v3.13.0/sans.rst b/docs/source/release/v3.13.0/sans.rst
index 5975f8423828c85847be61ae44e7cf60e72c44d1..2c9a9f23fe801dec1650b0df228de4c7885f4343 100644
--- a/docs/source/release/v3.13.0/sans.rst
+++ b/docs/source/release/v3.13.0/sans.rst
@@ -9,4 +9,21 @@ SANS Changes
     putting new features at the top of the section, followed by
     improvements, followed by bug fixes.
 
+ISIS SANS Interface
+----------------------------
+
+New features
+############
+
+Improvements
+############
+
+Bug fixes
+#########
+* Fixed a bug where the beam stop arm was not being masked on LOQ.
+
+Features Removed
+################
+
+
 :ref:`Release 3.13.0 <v3.13.0>`
\ No newline at end of file
diff --git a/docs/source/release/v3.13.0/ui.rst b/docs/source/release/v3.13.0/ui.rst
index 95ee154539c65bee7820b8b8540501c11c065cc5..57924a01424272acb984a5a9dd05d8daa2d3c4b0 100644
--- a/docs/source/release/v3.13.0/ui.rst
+++ b/docs/source/release/v3.13.0/ui.rst
@@ -10,3 +10,9 @@ UI & Usability Changes
     improvements, followed by bug fixes.
 
 :ref:`Release 3.13.0 <v3.13.0>`
+
+
+MantidPlot
+----------
+
+- MantidPlot's pyplot API has been removed.
diff --git a/docs/source/techniques/Directtools Python module.rst b/docs/source/techniques/Directtools Python module.rst
deleted file mode 100644
index 6dcf5a66b8847f623cdb8cb439d3409d5daa4c26..0000000000000000000000000000000000000000
--- a/docs/source/techniques/Directtools Python module.rst	
+++ /dev/null
@@ -1,19 +0,0 @@
-.. _Directtools Python module:
-
-==================
-:mod:`directtools`
-==================
-
-:literal:`directtools` is a Python module for quickly plotting standardized :math:`S(Q,E)` color fill plots as well as line profiles (cuts) in constant :math:`Q` and :math:`E`. The module also provides a few utility functions for inspecting and manipulating the :math:`S(Q,E)` workspace.
-
-Reference
-=========
-
-.. autoclass:: directtools.SampleLogs
-   :members: __init__
-
-.. automodule:: directtools
-   :members: dynamicsusceptibility, nanminmax, plotcuts, plotprofiles, plotconstE,
-             plotconstQ, plotSofQW, subplots, validQ, wsreport
-
-.. categories:: Techniques
diff --git a/docs/source/techniques/DirecttoolsPythonModule.rst b/docs/source/techniques/DirecttoolsPythonModule.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c31c3f77c1ccc351c9c6e2c4eb64479384be488c
--- /dev/null
+++ b/docs/source/techniques/DirecttoolsPythonModule.rst
@@ -0,0 +1,153 @@
+.. _Directtools Python module:
+
+==================
+:mod:`directtools`
+==================
+
+:mod:`directtools` is a Python module for quickly plotting standardized :math:`S(Q,E)` color fill plots as well as line profiles (cuts) in constant :math:`Q` and :math:`E`. The module also provides a few utility functions for inspecting and manipulating the :math:`S(Q,E)` workspace.
+
+For a general introduction on using :mod:`matplotlib` with Mantid, see :ref:`this introduction <plotting>`
+
+The input workspaces are expected to have some specific sample logs, namely ``instrument.name``, ``Ei``, ``run_number``, ``start_time``, ``sample.temperature``.
+
+Examples
+########
+
+The default parameters for :func:`directtools.plotSofQW` give a view of the :math:`S(Q,E)` workspace around the elastic peak with sensible limits for the axes and intensity:
+
+.. plot::
+   :include-source:
+
+   import directtools as dt
+   from mantid.simpleapi import *
+
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+
+   fig, ax = dt.plotSofQW('SofQW')
+   #fig.show()
+
+The :math:`Q`, :math:`E` and intensity limits can be changed using the optional parameters. The utility functions :func:`directtools.validQ` and :func:`directtools.nanminmax` might be helpful when determining suitable ranges:
+
+.. plot::
+   :include-source:
+
+   import directtools as dt
+   from mantid.simpleapi import *
+
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+
+   EMin = -20.
+   QMax = dt.validQ('SofQW', EMin)[1]
+   VMax = 0.5 * dt.nanminmax('SofQW')[1]
+
+   fig, axes = dt.plotSofQW('SofQW', QMax=QMax, EMin=EMin, VMax=VMax)
+   #fig.show()
+
+An important aspect of examining the :math:`S(Q,E)` workspace is to plot cuts at constant :math:`Q` and :math:`E`. This can be done by :func:`directtools.plotconstQ` and :func:`directtools.plotconstE`:
+
+.. plot::
+   :include-source:
+
+   import directtools as dt
+   from mantid.simpleapi import *
+   import warnings
+   
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+   
+   Q = 2.
+   dQ = 0.2
+   # plotconstQ produces a warning on some versions of numpy.
+   # The "with" statement catches this warning so that the automated
+   # builds don't fail.
+   with warnings.catch_warnings():
+       warnings.simplefilter("ignore", category=UserWarning)
+       fig, axes, cuts = dt.plotconstQ('SofQW', Q, dQ)
+       #fig.show()
+
+Any of the workspace, cut centre or cut width arguments can be a :class:`list` instead. This enables data comparison:
+
+.. plot::
+   :include-source:
+
+   import directtools as dt
+   from mantid.simpleapi import *
+   
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+   
+   Q1 = 2.
+   Q2 = 3.
+   dQ = 0.2
+   fig, axes, cuts = dt.plotconstQ('SofQW', [Q1, Q2], dQ)
+   #fig.show()
+
+The :func:`directtools.plotconstQ` and :func:`directtools.plotconstE` functions use :func:`directtools.plotcuts` to do the actual line profiles and plotting. The profiles are made by the :ref:`algm-LineProfile` algorithm, and all three plotting functions return a list of the produced line profile workspace names.
+
+If a line profile already exists, it can be plotted using :func:`directtools.plotprofiles`. This also accepts either a single line profile workspace or a list of workspaces enabling comparison:
+
+.. plot::
+   :include-source:
+
+   import directtools as dt
+   from mantid.simpleapi import *
+   
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+   
+   E1 = 8.
+   dE = 2.
+   cut1 = LineProfile('SofQW', E1, dE, 'Horizontal')
+   label1 = 'At E = {} meV'.format(E1)
+   E2 = E1 - 4.
+   cut2 = LineProfile('SofQW', E2, dE, 'Horizontal')
+   label2 = 'At E = {} meV'.format(E2)
+   fig, axes = dt.plotprofiles([cut1, cut2], [label1, label2], style='m')
+   axes.legend()
+   #fig.show()
+
+:class:`directtools.SampleLogs` is a convenience class to import the sample logs of a workspace into a 'struct' like object in Python:
+
+.. testcode:: SampleLogsEx
+
+   import directtools as dt
+   from mantid.simpleapi import *
+   
+   DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data')
+   DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW')
+   
+   # Works on any workspace, not just S(Q,E).
+   logs = dt.SampleLogs('SofQW')
+   print(logs.instrument.name)
+   print(logs.run_number)
+
+.. testcleanup:: SampleLogsEx
+
+   mtd.clear()
+
+Output:
+
+.. testoutput:: SampleLogsEx
+
+   IN4
+   84447
+
+Reference
+=========
+
+Classes
+#######
+
+.. autoclass:: directtools.SampleLogs
+   :members: __init__
+
+Functions
+#########
+
+.. automodule:: directtools
+   :members: box2D, defaultrcParams, dynamicsusceptibility, nanminmax, plotconstE,
+             plotconstQ, plotcuts, plotprofiles, plotSofQW, subplots, validQ, wsreport
+
+.. categories:: Techniques
diff --git a/docs/source/techniques/ISISPowder-Pearl-v1.rst b/docs/source/techniques/ISISPowder-Pearl-v1.rst
index 00a88473e622cca8feb482ee042643ac4f1f8bf6..f9b19bb3caa43c99c9d28be5c15df66209cf95f7 100644
--- a/docs/source/techniques/ISISPowder-Pearl-v1.rst
+++ b/docs/source/techniques/ISISPowder-Pearl-v1.rst
@@ -159,6 +159,22 @@ Example
                            calibration_mapping_file=cal_mapping_file)
 
 
+.. _state_for_pearl_isis-powder-diffraction-ref:
+
+How the PEARL object holds state
+--------------------------------
+
+The PEARL object does not behave as described in
+:ref:`how_objects_hold_state_isis-powder-diffraction-ref`. For PEARL,
+any settings given in the constructor for the PEARL object, either
+explicitly or via a config file, are taken as defaults. If these are
+overriden in a call to either
+:ref:`focus_pearl_isis-powder-diffraction-ref`,
+:ref:`create_vanadium_pearl_isis-powder-diffraction-ref` or
+:ref:`create_cal_pearl_isis-powder-diffraction-ref`, then these
+settings only apply to that line, and are reverted to the defaults
+when the line has finished executing.
+
 .. _calibration_mapping_pearl_isis-powder-diffraction-ref:
 
 Calibration Mapping File
diff --git a/docs/source/techniques/ISISPowder-Tutorials.rst b/docs/source/techniques/ISISPowder-Tutorials.rst
index 90a01b0deb5e4e002b1f899e26b6b9a38df41184..1a64317e62998f910a91434428d20419a7306101 100644
--- a/docs/source/techniques/ISISPowder-Tutorials.rst
+++ b/docs/source/techniques/ISISPowder-Tutorials.rst
@@ -210,6 +210,10 @@ found for each individual instrument in the reference document:
 
 How objects hold state in ISIS Powder
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. warning:: This is NOT relevant for PEARL. PEARL scientists should
+	     refer to :ref:`state_for_pearl_isis-powder-diffraction-ref`
+
 Additionally as the objects hold state we can set a parameter
 anywhere. For example on Polaris the ``mode`` parameter indicates
 the chopper state for this/these run(s). This can either be set 
diff --git a/docs/sphinxext/mantiddoc/directives/__init__.py b/docs/sphinxext/mantiddoc/directives/__init__.py
index f6e7c496ec600f27ad1f1ae1b1f68f7995899d6d..7b4e06361b25012c7175753995a1616780980f5c 100644
--- a/docs/sphinxext/mantiddoc/directives/__init__.py
+++ b/docs/sphinxext/mantiddoc/directives/__init__.py
@@ -8,12 +8,12 @@
 """
 
 import mantiddoc.directives.algorithm
-import mantiddoc.directives.alias
 import mantiddoc.directives.attributes
 import mantiddoc.directives.categories
 import mantiddoc.directives.diagram
 import mantiddoc.directives.interface
 import mantiddoc.directives.properties
+import mantiddoc.directives.relatedalgorithms
 import mantiddoc.directives.sourcelink
 import mantiddoc.directives.summary
 
@@ -25,11 +25,11 @@ def setup(app):
       app: The main Sphinx application object
     """
     algorithm.setup(app)
-    alias.setup(app)
     attributes.setup(app)
     categories.setup(app)
     diagram.setup(app)
     interface.setup(app)
     properties.setup(app)
+    relatedalgorithms.setup(app)
     sourcelink.setup(app)
     summary.setup(app)
diff --git a/docs/sphinxext/mantiddoc/directives/alias.py b/docs/sphinxext/mantiddoc/directives/alias.py
deleted file mode 100644
index 5b6b6b9714c2334890dbfe4eaefe05a7b0d46f78..0000000000000000000000000000000000000000
--- a/docs/sphinxext/mantiddoc/directives/alias.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from mantiddoc.directives.base import AlgorithmBaseDirective #pylint: disable=unused-import
-
-
-class AliasDirective(AlgorithmBaseDirective):
-
-    """
-    Obtains the alias for a given algorithm based on it's name.
-    """
-
-    required_arguments, optional_arguments = 0, 0
-
-    def execute(self):
-        """
-        Called by Sphinx when the ..alias:: directive is encountered.
-        """
-        alg = self.create_mantid_algorithm(self.algorithm_name(), self.algorithm_version())
-        alias = alg.alias()
-        if len(alias) == 0:
-            return []
-
-        self.add_rst(self.make_header("Alias"))
-        format_str = "This algorithm is also known as: **%s**"
-        self.add_rst(format_str % alias)
-
-        return []
-
-def setup(app):
-    """
-    Setup the directives when the extension is activated
-
-    Args:
-      app: The main Sphinx application object
-    """
-    app.add_directive('alias', AliasDirective)
diff --git a/docs/sphinxext/mantiddoc/directives/base.py b/docs/sphinxext/mantiddoc/directives/base.py
index 3c73c1a4022ae9e62d0a147031753c9d195e778c..7d1884f27f21c33284b2b5059c1c61061a770c17 100644
--- a/docs/sphinxext/mantiddoc/directives/base.py
+++ b/docs/sphinxext/mantiddoc/directives/base.py
@@ -82,22 +82,32 @@ class BaseDirective(Directive):
         """
         return self.state.document.settings.env.docname
 
-    def make_header(self, name, pagetitle=False):
+    def make_header(self, name, pagetitle=False, level=2):
         """
         Makes a ReStructuredText title from the algorithm's name.
 
         Args:
           algorithm_name (str): The name of the algorithm to use for the title.
-          pagetitle (bool): If True, line is inserted above & below algorithm name.
+          pagetitle (bool): If True, this sets the level to 1 (overriding any other value).
+          level (int): 1-4 the level of the heading to be used.
 
         Returns:
           str: ReST formatted header with algorithm_name as content.
         """
+        level_dict = {1:"=", 2:"-", 3:"#", 4:"^"}
+        
         if pagetitle:
-            line = "\n" + "=" * (len(name) + 1) + "\n"
+            level = 1
+        if level not in level_dict:
+            env = self.state.document.settings.env
+            env.app.warn('base.make_header - Did not understand level ' +str(level))
+            level = 2
+            
+        line = "\n" + level_dict[level] * (len(name)) + "\n"
+        
+        if level == 1:
             return line + name + line
         else:
-            line = "\n" + "-" * len(name) + "\n"
             return name + line
 
 #----------------------------------------------------------------------------------------
@@ -178,6 +188,21 @@ class AlgorithmBaseDirective(BaseDirective):
             self._set_algorithm_name_and_version()
         return self.algm_version
 
+    def create_mantid_algorithm_by_name(self, algorithm_name):
+        """
+        Create and initializes a Mantid algorithm using tha latest version.
+
+        Args:
+          algorithm_name (str): The name of the algorithm to use for the title.
+
+        Returns:
+          algorithm: An instance of a Mantid algorithm.
+        """
+        from mantid.api import AlgorithmManager
+        alg = AlgorithmManager.createUnmanaged(algorithm_name)
+        alg.initialize()
+        return alg
+        
     def create_mantid_algorithm(self, algorithm_name, version):
         """
         Create and initializes a Mantid algorithm.
@@ -193,7 +218,7 @@ class AlgorithmBaseDirective(BaseDirective):
         alg = AlgorithmManager.createUnmanaged(algorithm_name, version)
         alg.initialize()
         return alg
-
+        
     def create_mantid_ifunction(self, function_name):
         """
         Create and initiializes a Mantid IFunction.
diff --git a/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py b/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py
new file mode 100644
index 0000000000000000000000000000000000000000..9b49d8dcc9f2e72141448e31262fc06dc68b6bd3
--- /dev/null
+++ b/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py
@@ -0,0 +1,48 @@
+from mantiddoc.directives.base import AlgorithmBaseDirective #pylint: disable=unused-import
+
+class relatedalgorithmsDirective(AlgorithmBaseDirective):
+
+    """
+    Obtains the see also section for a given algorithm based on it's name.
+    This lists similar algorithms and aliases
+    """
+
+    required_arguments, optional_arguments = 0, 0
+
+    def execute(self):
+        """
+        Called by Sphinx when the ..seealso:: directive is encountered.
+        """
+        alg = self.create_mantid_algorithm(self.algorithm_name(), self.algorithm_version())
+        seeAlsoList = alg.seeAlso()
+        alias = alg.alias()
+        link_rst = ""
+        if seeAlsoList:
+            for seeAlsoEntry in seeAlsoList:
+                #test the algorithm exists
+                try:
+                    alg = self.create_mantid_algorithm_by_name(seeAlsoEntry)
+                    link_rst += ":ref:`%s <algm-%s>`, " % (alg.name(), alg.name())
+                except RuntimeError:
+                    env = self.state.document.settings.env
+                    env.app.warn('relatedalgorithms - Could not find algorithm "{0}" listed in the seeAlso for {1}.v{2}'.format(
+                                 seeAlsoEntry,self.algorithm_name(), self.algorithm_version()))
+                      
+        if link_rst or alias:
+            self.add_rst(self.make_header("See Also",level=3))
+            if link_rst:
+                link_rst = link_rst.rstrip(", ") # remove final separator
+                self.add_rst(link_rst + "\n\n")
+            if alias:
+                format_str = "This algorithm is also known as: **%s**"
+                self.add_rst(format_str % alias)
+        return []
+        
+def setup(app):
+    """
+    Setup the directives when the extension is activated
+
+    Args:
+      app: The main Sphinx application object
+    """
+    app.add_directive('relatedalgorithms', relatedalgorithmsDirective)
diff --git a/docs/sphinxext/mantiddoc/directives/sourcelink.py b/docs/sphinxext/mantiddoc/directives/sourcelink.py
index de5b791e15f505e553995eaa7feb1918bc1c6f6d..990bfbf995912c2bb821683ade0290edb47a2647 100644
--- a/docs/sphinxext/mantiddoc/directives/sourcelink.py
+++ b/docs/sphinxext/mantiddoc/directives/sourcelink.py
@@ -7,7 +7,7 @@ from six import iteritems
 import mantid
 from .base import AlgorithmBaseDirective #pylint: disable=unused-import
 
-LAST_MODIFIED_UNKNOWN = 'unknown'
+from mantiddoc.tools.git_last_modified import get_file_last_modified_time
 
 
 class SourceLinkError(Exception):
@@ -66,6 +66,8 @@ class SourceLinkDirective(AlgorithmBaseDirective):
     }
     file_lookup = {}
 
+    git_cache = {}
+
     # will be filled in
     __source_root = None
 
@@ -90,7 +92,8 @@ class SourceLinkDirective(AlgorithmBaseDirective):
             if file_paths[extension] is None:
                 try:
                     fname = self.find_source_file(file_name, extension)
-                    file_paths[extension] = (fname, self.get_file_last_modified(fname)) \
+                    file_paths[extension] = (
+                            fname, get_file_last_modified_time(self.git_cache, self.source_root, fname)) \
                             if fname is not None else None
                 except SourceLinkError as err:
                     error_string += str(err) + "\n"
@@ -103,7 +106,7 @@ class SourceLinkDirective(AlgorithmBaseDirective):
             else:
                 # prepend the base framework directory
                 fname = os.path.join(self.source_root, file_paths[extension])
-                file_paths[extension] = (fname, self.get_file_last_modified(fname))
+                file_paths[extension] = (fname, get_file_last_modified_time(self.git_cache, self.source_root, fname))
                 if not os.path.exists(file_paths[extension][0]):
                     error_string += "Cannot find {} file at {}\n".format(
                         extension, file_paths[extension][0])
@@ -255,19 +258,6 @@ class SourceLinkDirective(AlgorithmBaseDirective):
         url = "https://github.com/mantidproject/mantid/blob/" + mantid.kernel.revision_full() + url
         return url
 
-    def get_file_last_modified(self, filename):
-        """
-        Gets the commit timestamp of the last commit to modify a given file.
-        """
-        if not filename:
-            return LAST_MODIFIED_UNKNOWN
-
-        proc = subprocess.Popen(
-            ['git', 'log', '-n 1', '--pretty=format:%cd', '--date=short', filename],
-            cwd=self.source_root,
-            stdout=subprocess.PIPE)
-        return str(proc.stdout.read().decode('utf-8'))
-
 
 def setup(app):
     """
diff --git a/docs/sphinxext/mantiddoc/tools/git_last_modified.py b/docs/sphinxext/mantiddoc/tools/git_last_modified.py
new file mode 100644
index 0000000000000000000000000000000000000000..d060d5b5be4473c4dacca945297261632eef98be
--- /dev/null
+++ b/docs/sphinxext/mantiddoc/tools/git_last_modified.py
@@ -0,0 +1,53 @@
+import os
+import re
+import subprocess
+
+
+LAST_MODIFIED_UNKNOWN = 'unknown'
+
+
+def cache_subtree(cache, root, path):
+    proc = subprocess.Popen(
+        ['git', 'log', '--pretty=format:%cd', '--date=short', '--name-only', path],
+        cwd=root,
+        stdout=subprocess.PIPE)
+
+    current_date_str = None
+
+    date_regex = re.compile('\d\d\d\d\-\d\d\-\d\d')
+    filename_regex = re.compile('[\/\w,\s\-\_]+\.[A-Za-z]+')
+
+    for line in proc.stdout:
+        line = str(line.decode('utf-8')).strip()
+
+        if date_regex.match(line):
+            # This line contains the date that the subsequent files were last modified
+            current_date_str = line
+
+        # Only take the first (most recent) appearence of each file
+        elif filename_regex.match(line) and line not in cache:
+            # This line contains a file that was modified on the last mentioned date
+            cache[line] = current_date_str
+
+
+def get_file_last_modified_time(cache, root, filename):
+    # If cache is empty then start by caching all of Framework
+    # Will usually catch all the files you need
+    if len(cache) == 0:
+        cache_subtree(cache, root, 'Framework')
+
+    source_filename = filename.replace(root, '')
+    if source_filename.startswith(os.path.sep):
+        source_filename = source_filename[1:]
+
+    # Check if details for this file have already been cached
+    if source_filename not in cache:
+        # Cache the subtree for this file
+        subtree_path = os.path.dirname(filename)
+        cache_subtree(cache, root, subtree_path)
+
+        # Make sure it is cached now
+        if source_filename not in cache:
+            return LAST_MODIFIED_UNKNOWN
+
+    return cache[source_filename]
diff --git a/instrument/D20_Parameters.xml b/instrument/D20_Parameters.xml
index 9f4ac0587877c80ecde601fa073aeaa48aa44f67..17d29c8f6f0bf58e1f891219a3f9bd1069d3cab6 100644
--- a/instrument/D20_Parameters.xml
+++ b/instrument/D20_Parameters.xml
@@ -2,9 +2,15 @@
 <parameter-file instrument="D20" valid-from="1900-01-31 23:59:59">
 	<component-link name="D20">
 
+		<!-- The detector name for the height axis used in SumOverlappingTubes -->
 		<parameter name="detector_for_height_axis" type="string">
 			<value val="panel_1" />
 		</parameter>
 
+		<!-- The flag for mirroring the angles in SumOverlappingTubes -->
+		<parameter name="mirror_scattering_angles" type="bool">
+			<value val="False" />
+	  </parameter>
+
 	</component-link>
 </parameter-file>
diff --git a/instrument/D2B_2018-03-01_Definition.xml b/instrument/D2B_2018-03-01_Definition.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ae591739459fa910f3b65d38da6868b45cedc0f8
--- /dev/null
+++ b/instrument/D2B_2018-03-01_Definition.xml
@@ -0,0 +1,324 @@
+<?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="D2B" valid-from="2018-03-01 23:59:59"
+valid-to="2100-01-31 23:59:59" last-modified="2018-03-20 14:05:02">
+  <!-- Author: bush@ill.fr -->
+  <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>
+  </defaults>
+  <!-- Source position -->
+  <component type="monochromator">
+    <location z="-2.997" />
+  </component>
+  <type name="monochromator" is="Source" />
+  <!-- Monitor position -->
+  <component type="monitor" idlist="monitors">
+    <location z="-1.594" name="monitor" />
+  </component>
+  <type name="monitor" is="monitor">
+    <cuboid id="shape">
+      <left-front-bottom-point x="-0.005" y="-0.005" z="-0.005" />
+      <left-front-top-point x="-0.005" y="0.005" z="-0.005" />
+      <left-back-bottom-point x="-0.005" y="-0.005" z="0.005" />
+      <right-front-bottom-point x="0.005" y="-0.005" z="-0.005" />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+  <idlist idname="monitors">
+    <id val="0" />
+  </idlist>
+  <!-- Sample position -->
+  <component type="sample-position">
+    <location x="0.0" y="0.0" z="0.0" />
+  </component>
+  <type name="sample-position" is="SamplePos" />
+  <!-- Detector IDs -->
+  <idlist idname="detectors">
+    <id start="1" end="16384" />
+  </idlist>
+  <!-- Detector list def -->
+  <component type="detectors" idlist="detectors">
+    <location x="0.0" y="0.0" z="0.0" />
+  </component>
+  <type name="detectors">
+    <component type="standard_tube">
+      <location r="1.296" t="-6.25" name="tube_1" />
+      <location r="1.296" t="-7.5" name="tube_2" />
+      <location r="1.296" t="-8.75" name="tube_3" />
+      <location r="1.296" t="-10.0" name="tube_4" />
+      <location r="1.296" t="-11.25" name="tube_5" />
+      <location r="1.296" t="-12.5" name="tube_6" />
+      <location r="1.296" t="-13.75" name="tube_7" />
+      <location r="1.296" t="-15.0" name="tube_8" />
+      <location r="1.296" t="-16.25" name="tube_9" />
+      <location r="1.296" t="-17.5" name="tube_10" />
+      <location r="1.296" t="-18.75" name="tube_11" />
+      <location r="1.296" t="-20.0" name="tube_12" />
+      <location r="1.296" t="-21.25" name="tube_13" />
+      <location r="1.296" t="-22.5" name="tube_14" />
+      <location r="1.296" t="-23.75" name="tube_15" />
+      <location r="1.296" t="-25.0" name="tube_16" />
+      <location r="1.296" t="-26.25" name="tube_17" />
+      <location r="1.296" t="-27.5" name="tube_18" />
+      <location r="1.296" t="-28.75" name="tube_19" />
+      <location r="1.296" t="-30.0" name="tube_20" />
+      <location r="1.296" t="-31.25" name="tube_21" />
+      <location r="1.296" t="-32.5" name="tube_22" />
+      <location r="1.296" t="-33.75" name="tube_23" />
+      <location r="1.296" t="-35.0" name="tube_24" />
+      <location r="1.296" t="-36.25" name="tube_25" />
+      <location r="1.296" t="-37.5" name="tube_26" />
+      <location r="1.296" t="-38.75" name="tube_27" />
+      <location r="1.296" t="-40.0" name="tube_28" />
+      <location r="1.296" t="-41.25" name="tube_29" />
+      <location r="1.296" t="-42.5" name="tube_30" />
+      <location r="1.296" t="-43.75" name="tube_31" />
+      <location r="1.296" t="-45.0" name="tube_32" />
+      <location r="1.296" t="-46.25" name="tube_33" />
+      <location r="1.296" t="-47.5" name="tube_34" />
+      <location r="1.296" t="-48.75" name="tube_35" />
+      <location r="1.296" t="-50.0" name="tube_36" />
+      <location r="1.296" t="-51.25" name="tube_37" />
+      <location r="1.296" t="-52.5" name="tube_38" />
+      <location r="1.296" t="-53.75" name="tube_39" />
+      <location r="1.296" t="-55.0" name="tube_40" />
+      <location r="1.296" t="-56.25" name="tube_41" />
+      <location r="1.296" t="-57.5" name="tube_42" />
+      <location r="1.296" t="-58.75" name="tube_43" />
+      <location r="1.296" t="-60.0" name="tube_44" />
+      <location r="1.296" t="-61.25" name="tube_45" />
+      <location r="1.296" t="-62.5" name="tube_46" />
+      <location r="1.296" t="-63.75" name="tube_47" />
+      <location r="1.296" t="-65.0" name="tube_48" />
+      <location r="1.296" t="-66.25" name="tube_49" />
+      <location r="1.296" t="-67.5" name="tube_50" />
+      <location r="1.296" t="-68.75" name="tube_51" />
+      <location r="1.296" t="-70.0" name="tube_52" />
+      <location r="1.296" t="-71.25" name="tube_53" />
+      <location r="1.296" t="-72.5" name="tube_54" />
+      <location r="1.296" t="-73.75" name="tube_55" />
+      <location r="1.296" t="-75.0" name="tube_56" />
+      <location r="1.296" t="-76.25" name="tube_57" />
+      <location r="1.296" t="-77.5" name="tube_58" />
+      <location r="1.296" t="-78.75" name="tube_59" />
+      <location r="1.296" t="-80.0" name="tube_60" />
+      <location r="1.296" t="-81.25" name="tube_61" />
+      <location r="1.296" t="-82.5" name="tube_62" />
+      <location r="1.296" t="-83.75" name="tube_63" />
+      <location r="1.296" t="-85.0" name="tube_64" />
+      <location r="1.296" t="-86.25" name="tube_65" />
+      <location r="1.296" t="-87.5" name="tube_66" />
+      <location r="1.296" t="-88.75" name="tube_67" />
+      <location r="1.296" t="-90.0" name="tube_68" />
+      <location r="1.296" t="-91.25" name="tube_69" />
+      <location r="1.296" t="-92.5" name="tube_70" />
+      <location r="1.296" t="-93.75" name="tube_71" />
+      <location r="1.296" t="-95.0" name="tube_72" />
+      <location r="1.296" t="-96.25" name="tube_73" />
+      <location r="1.296" t="-97.5" name="tube_74" />
+      <location r="1.296" t="-98.75" name="tube_75" />
+      <location r="1.296" t="-100.0" name="tube_76" />
+      <location r="1.296" t="-101.25" name="tube_77" />
+      <location r="1.296" t="-102.5" name="tube_78" />
+      <location r="1.296" t="-103.75" name="tube_79" />
+      <location r="1.296" t="-105.0" name="tube_80" />
+      <location r="1.296" t="-106.25" name="tube_81" />
+      <location r="1.296" t="-107.5" name="tube_82" />
+      <location r="1.296" t="-108.75" name="tube_83" />
+      <location r="1.296" t="-110.0" name="tube_84" />
+      <location r="1.296" t="-111.25" name="tube_85" />
+      <location r="1.296" t="-112.5" name="tube_86" />
+      <location r="1.296" t="-113.75" name="tube_87" />
+      <location r="1.296" t="-115.0" name="tube_88" />
+      <location r="1.296" t="-116.25" name="tube_89" />
+      <location r="1.296" t="-117.5" name="tube_90" />
+      <location r="1.296" t="-118.75" name="tube_91" />
+      <location r="1.296" t="-120.0" name="tube_92" />
+      <location r="1.296" t="-121.25" name="tube_93" />
+      <location r="1.296" t="-122.5" name="tube_94" />
+      <location r="1.296" t="-123.75" name="tube_95" />
+      <location r="1.296" t="-125.0" name="tube_96" />
+      <location r="1.296" t="-126.25" name="tube_97" />
+      <location r="1.296" t="-127.5" name="tube_98" />
+      <location r="1.296" t="-128.75" name="tube_99" />
+      <location r="1.296" t="-130.0" name="tube_100" />
+      <location r="1.296" t="-131.25" name="tube_101" />
+      <location r="1.296" t="-132.5" name="tube_102" />
+      <location r="1.296" t="-133.75" name="tube_103" />
+      <location r="1.296" t="-135.0" name="tube_104" />
+      <location r="1.296" t="-136.25" name="tube_105" />
+      <location r="1.296" t="-137.5" name="tube_106" />
+      <location r="1.296" t="-138.75" name="tube_107" />
+      <location r="1.296" t="-140.0" name="tube_108" />
+      <location r="1.296" t="-141.25" name="tube_109" />
+      <location r="1.296" t="-142.5" name="tube_110" />
+      <location r="1.296" t="-143.75" name="tube_111" />
+      <location r="1.296" t="-145.0" name="tube_112" />
+      <location r="1.296" t="-146.25" name="tube_113" />
+      <location r="1.296" t="-147.5" name="tube_114" />
+      <location r="1.296" t="-148.75" name="tube_115" />
+      <location r="1.296" t="-150.0" name="tube_116" />
+      <location r="1.296" t="-151.25" name="tube_117" />
+      <location r="1.296" t="-152.5" name="tube_118" />
+      <location r="1.296" t="-153.75" name="tube_119" />
+      <location r="1.296" t="-155.0" name="tube_120" />
+      <location r="1.296" t="-156.25" name="tube_121" />
+      <location r="1.296" t="-157.5" name="tube_122" />
+      <location r="1.296" t="-158.75" name="tube_123" />
+      <location r="1.296" t="-160.0" name="tube_124" />
+      <location r="1.296" t="-161.25" name="tube_125" />
+      <location r="1.296" t="-162.5" name="tube_126" />
+      <location r="1.296" t="-163.75" name="tube_127" />
+      <location r="1.296" t="-165.0" name="tube_128" />
+    </component>
+  </type>
+  <!-- Definition of standard_tube -->
+  <type name="standard_tube" outline="yes">
+    <component type="standard_pixel">
+      <location y="-0.175865234375" />
+      <location y="-0.173095703125" />
+      <location y="-0.170326171875" />
+      <location y="-0.167556640625" />
+      <location y="-0.164787109375" />
+      <location y="-0.162017578125" />
+      <location y="-0.159248046875" />
+      <location y="-0.156478515625" />
+      <location y="-0.153708984375" />
+      <location y="-0.150939453125" />
+      <location y="-0.148169921875" />
+      <location y="-0.145400390625" />
+      <location y="-0.142630859375" />
+      <location y="-0.139861328125" />
+      <location y="-0.137091796875" />
+      <location y="-0.134322265625" />
+      <location y="-0.131552734375" />
+      <location y="-0.128783203125" />
+      <location y="-0.126013671875" />
+      <location y="-0.123244140625" />
+      <location y="-0.120474609375" />
+      <location y="-0.117705078125" />
+      <location y="-0.114935546875" />
+      <location y="-0.112166015625" />
+      <location y="-0.109396484375" />
+      <location y="-0.106626953125" />
+      <location y="-0.103857421875" />
+      <location y="-0.101087890625" />
+      <location y="-0.098318359375" />
+      <location y="-0.095548828125" />
+      <location y="-0.092779296875" />
+      <location y="-0.090009765625" />
+      <location y="-0.087240234375" />
+      <location y="-0.084470703125" />
+      <location y="-0.081701171875" />
+      <location y="-0.078931640625" />
+      <location y="-0.076162109375" />
+      <location y="-0.073392578125" />
+      <location y="-0.070623046875" />
+      <location y="-0.067853515625" />
+      <location y="-0.065083984375" />
+      <location y="-0.062314453125" />
+      <location y="-0.059544921875" />
+      <location y="-0.056775390625" />
+      <location y="-0.054005859375" />
+      <location y="-0.051236328125" />
+      <location y="-0.048466796875" />
+      <location y="-0.045697265625" />
+      <location y="-0.042927734375" />
+      <location y="-0.040158203125" />
+      <location y="-0.037388671875" />
+      <location y="-0.034619140625" />
+      <location y="-0.031849609375" />
+      <location y="-0.029080078125" />
+      <location y="-0.026310546875" />
+      <location y="-0.023541015625" />
+      <location y="-0.020771484375" />
+      <location y="-0.018001953125" />
+      <location y="-0.015232421875" />
+      <location y="-0.012462890625" />
+      <location y="-0.009693359375" />
+      <location y="-0.006923828125" />
+      <location y="-0.004154296875" />
+      <location y="-0.001384765625" />
+      <location y="0.001384765625" />
+      <location y="0.004154296875" />
+      <location y="0.006923828125" />
+      <location y="0.009693359375" />
+      <location y="0.012462890625" />
+      <location y="0.015232421875" />
+      <location y="0.018001953125" />
+      <location y="0.020771484375" />
+      <location y="0.023541015625" />
+      <location y="0.026310546875" />
+      <location y="0.029080078125" />
+      <location y="0.031849609375" />
+      <location y="0.034619140625" />
+      <location y="0.037388671875" />
+      <location y="0.040158203125" />
+      <location y="0.042927734375" />
+      <location y="0.045697265625" />
+      <location y="0.048466796875" />
+      <location y="0.051236328125" />
+      <location y="0.054005859375" />
+      <location y="0.056775390625" />
+      <location y="0.059544921875" />
+      <location y="0.062314453125" />
+      <location y="0.065083984375" />
+      <location y="0.067853515625" />
+      <location y="0.070623046875" />
+      <location y="0.073392578125" />
+      <location y="0.076162109375" />
+      <location y="0.078931640625" />
+      <location y="0.081701171875" />
+      <location y="0.084470703125" />
+      <location y="0.087240234375" />
+      <location y="0.090009765625" />
+      <location y="0.092779296875" />
+      <location y="0.095548828125" />
+      <location y="0.098318359375" />
+      <location y="0.101087890625" />
+      <location y="0.103857421875" />
+      <location y="0.106626953125" />
+      <location y="0.109396484375" />
+      <location y="0.112166015625" />
+      <location y="0.114935546875" />
+      <location y="0.117705078125" />
+      <location y="0.120474609375" />
+      <location y="0.123244140625" />
+      <location y="0.126013671875" />
+      <location y="0.128783203125" />
+      <location y="0.131552734375" />
+      <location y="0.134322265625" />
+      <location y="0.137091796875" />
+      <location y="0.139861328125" />
+      <location y="0.142630859375" />
+      <location y="0.145400390625" />
+      <location y="0.148169921875" />
+      <location y="0.150939453125" />
+      <location y="0.153708984375" />
+      <location y="0.156478515625" />
+      <location y="0.159248046875" />
+      <location y="0.162017578125" />
+      <location y="0.164787109375" />
+      <location y="0.167556640625" />
+      <location y="0.170326171875" />
+      <location y="0.173095703125" />
+      <location y="0.175865234375" />
+    </component>
+  </type>
+  <type name="standard_pixel" is="detector">
+    <cylinder id="shape">
+      <centre-of-bottom-base x="0.0" y="-0.001384765625" z="0.0" />
+      <axis x="0.0" y="1.0" z="0.0" />
+      <radius val="0.000565486605872" />
+      <height val="0.00276953125" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>
+</instrument>
diff --git a/instrument/D2B_Parameters.xml b/instrument/D2B_Parameters.xml
index 49b19be1c5f237c146aa83a022cce4c4c207b2c4..cb1d2dee3f0ef69ede8fc45124b377acb4a31373 100644
--- a/instrument/D2B_Parameters.xml
+++ b/instrument/D2B_Parameters.xml
@@ -2,12 +2,27 @@
 <parameter-file instrument="D2B" valid-from="1900-01-31 23:59:59">
 	<component-link name="D2B">
 
-		<parameter name="mirror_detector_angles" type="bool">
-			<value val="true" />
-		</parameter>
+		<!-- The detector name for the height axis used in SumOverlappingTubes -->
 		<parameter name="detector_for_height_axis" type="string">
 			<value val="tube_1" />
 		</parameter>
 
+		<!-- The flag for mirroring the angles in SumOverlappingTubes -->
+		<parameter name="mirror_scattering_angles" type="bool">
+			<value val="True" />
+	  </parameter>
+
+		<!-- Number of pixels to trim from the top and the bottom of the tubes when
+		calculating the chiˆ2 in the detector efficiencies in case of autoiterations -->
+		<parameter name="pixels_to_trim" type="int">
+			<value val="28" />
+	  </parameter>
+
+		<!-- The chiˆ2/NdoF threshold for termination of autoiterations
+		in detector efficiency calculation -->
+		<parameter name="chi2_ndof" type="float">
+			<value val="0.01" />
+	  </parameter>
+
 	</component-link>
 </parameter-file>
diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml
index f93d09929fa45b9d30ae7889b71fb57848529b70..fa286b8d69cdb06c8bc55b37896c2c6ad7c268d2 100644
--- a/instrument/INTER_Definition.xml
+++ b/instrument/INTER_Definition.xml
@@ -1,10 +1,14 @@
 <?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="INTER" valid-from   ="1900-01-31 23:59:59"
-                          valid-to     ="2100-01-31 23:59:59"
-			last-modified="2010-11-04 00:00:00">
+            name="INTER"
+            valid-from="1900-01-31 23:59:59"
+            valid-to=  "2017-02-13 23:59:59"
+            last-modified="2018-02-16 00:00:00">
+
   <defaults>
     <length unit="meter" />
     <angle unit="degree" />
@@ -16,57 +20,34 @@
     <default-view axis-view="z+"/>
   </defaults>
 
- <!-- Definition of instrument specific parameters for data reduction (e.g. wavelength cutoffs etc.) , could go into paramter file
-	MonitorBackground= [7.6,8.5]
-	MonitorsToCorrect=[1]
-	PointDetectorStart=[0]   # Note: Since we are removing the monitors in the load raw command they are not counted here.
-	PointDetectorStop=[0]
-	MultiDetectorStart=[1]
-	I0MonitorIndex=1
- -->
-
-<!-- here we need to add the other monitors -->
-   <!-- parameters for efficiency correction -->
-  <parameter name="correction" type="string">
-    <value val="polynomial"/>
-  </parameter>
-
-  <parameter name="polystring" type="string">
-    <value val="35.5893,-24.5591,9.20375,-1.89265,0.222291,-0.0148746,0.00052709,-7.66807e-6"/>
-    <!--<value val="28.0051,-19.396,7.5629,-1.624,0.1986,-0.013783,0.00050478,-7.56647e-6"/>-->
-  </parameter>
-
-  <!-- BRIEF DESCRIPTION OF Inter INSTRUMENT:
-
-      Here Z=0 is defined by the neutron beam which slopes down at 2.3 deg.
-      from the horizon. This description is based on data provided by Tim
-      Charlton and Rob Dalgliesh.
-
-      Note from Tim spreedsheet
-      theta is a rotation about the y axis
-      phi is a rotation about the x axis
-      chi is a rotation about the z axis
-
-      Noticed the face of the monitors/detector shapes that faces the
-      beam/sample path is in this IDF defined to be the y-z plane.
-
-      Note the status of the instrument during a run is stored in the
-      logfile RunNo_status.txt
-  -->
+<!-- source and sample-position components START============================= -->
+
+  <component type="source">
+    <location z="-17.037" />
+  </component>
+  <type name="source" is="Source">
+    <properties>
+      40mm(H) x 60mm(W)
+    </properties>
+  </type>
+
+  <component type="some-surface-holder">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type name="some-surface-holder" is="SamplePos"/>
 
-  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+<!-- source and sample-position components END=============================== -->
 
-  <!-- detector components (including monitors) -->
 
+<!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+<!-- detector components (including monitors) -->
+
+<!-- ================MONITOR 1 START========================================= -->
   <component type="monitor1" idlist="monitor1">
-    <location z="6.96" />
+    <location z="-10.077" />
   </component>
 
   <type name="monitor1" is="monitor">
-    <!-- Shape specified at least big enough to cover the beam which
-         is 10mm high and 40mm wide. Note it is described as tube, hence
-	 the choice of a cylinder shape.
-    -->
     <percent-transparency val="95" />
     <cylinder id="shape">
       <centre-of-bottom-base z="0.0" x="-0.02" y="0.0" />
@@ -76,17 +57,14 @@
     </cylinder>
     <algebra val="shape" />
   </type>
+<!-- ================MONITOR 1 END=========================================== -->
 
+<!-- ================MONITOR 2 START========================================= -->
   <component type="monitor2" idlist="monitor2">
-    <location z="13.791" /> <!-- x = 23.0-5.05 -->
+    <location z="-3.246" />
   </component>
 
   <type name="monitor2" is="monitor">
-    <!-- Shape specified as a minimum needs to cover the beam which
-         is 10mm high and 40mm wide. The 'top' shape is included to
-	 more easily recognise this monitor when visualised in MantidPlot.
-	 This monitor is suppose to look a bit like a German hand grenade.
-    -->
     <percent-transparency val="95" />
     <cuboid id="base">
       <left-front-bottom-point z="0.04" x="-0.02" y="-0.01"  />
@@ -101,23 +79,16 @@
       <radius val="0.02" />
       <height val="0.04" />
     </cylinder>
-
     <algebra val="base : top" />
   </type>
+<!-- ================MONITOR 2 END=========================================== -->
 
+<!-- ================MONITOR 3 START========================================= -->
   <component type="monitor3" idlist="monitor3">
-    <location z="16.785" />  <!-- 23.0-0.425 -->
+    <location z="-0.252" />
   </component>
 
   <type name="monitor3" is="monitor">
-    <!-- Shape specified as a minimum needs to cover the beam which
-         is 10mm high and 40mm wide. The 'top' shape is included to
-	 more easily recognise this monitor when visualised in MantidPlot.
-	 This monitor is suppose to look a bit like a German hand grenade.
-
-
-
-    -->
     <percent-transparency val="95" />
     <cuboid id="base">
       <left-front-bottom-point z="0.04" x="-0.02" y="-0.01"  />
@@ -135,26 +106,15 @@
 
     <algebra val="base : top" />
   </type>
+<!-- ================MONITOR 2 END=========================================== -->
 
+<!-- ================POINT DETECTOR START==================================== -->
   <component type="point-detector" idlist="point-detector">
 
-    <location z="19.700" />  <!-- x= 23.0+2.6 -->
-
-    <!-- Link to log file that stores the z position. This angle can be used to
-    calculate the z position since the distance along the x-axis between
-    the sample and this detector is known (2.6m). Also theta in the logfile is
-    assumed to in degrees, hence the reason for the pi/180=0.0174533 transformation
-    to radians factor in the eq attribute.
-
-
-    This calculation becomes more complex due to the detector table and height stage above it.
-    It should be revisited when the log files become more stable.
-
-    We may actually want to draw in the table for clarity.
-    -->
+    <location z="2.663" />  <!-- x= 23.0+2.6 -->
     <parameter name="y">
-      <logfile id="PD1H" eq="(value+201.0)/1000." extract-single-value-as="last_value"/>
-      <!--<logfile id="theta" eq="2.6*sin(value*0.0174533)" extract-single-value-as="last_value"/>-->
+      <!-- <logfile id="PD1H" eq="(value+201.0)/1000." extract-single-value-as="last_value"/> -->
+      <logfile id="theta" eq="2.663*sin(2*value*0.0174533)" extract-single-value-as="last_value"/>
     </parameter>
 
   </component>
@@ -173,53 +133,13 @@
     </cuboid>
     <algebra val="shape" />
   </type>
+<!-- ================POINT DETECTOR END====================================== -->
 
-
- <component type="point-detector2" idlist="point-detector2">
-
-    <location z="19.700" />  <!-- x= 23.0+2.6 -->
-
-    <!-- Link to log file that stores the z position. This angle can be used to
-    calculate the z position since the distance along the x-axis between
-    the sample and this detector is known (2.6m). Also theta in the logfile is
-    assumed to in degrees, hence the reason for the pi/180=0.0174533 transformation
-    to radians factor in the eq attribute.
-
-
-    This calculation becomes more complex due to the detector table and height stage above it.
-    It should be revisited when the log files become more stable.
-
-    We may actually want to draw in the table for clarity.
-    -->
-    <parameter name="y">
-      <logfile id="PD1H" eq="(value+301.0)/1000" extract-single-value-as="last_value"/>
-      <!--<logfile id="Theta" eq="2.7*sin((value+1)*0.0174533)" extract-single-value-as="last_value"/> -->
-    </parameter>
-
-  </component>
-
-  <type name="point-detector2" is="detector">
-    <!-- Not exactly sure about the dimensions of this one. But pretty sure
-    it at least covers the beam. Also, just in front of it is a slit which
-    at the end of day will determine which neutrons get through to this
-    detector I believe.
-    -->
-    <cuboid id="shape">
-      <left-front-bottom-point z="0.01" x="-0.02" y="-0.005"  />
-      <left-front-top-point  z="0.01" x="-0.02" y="0.005"  />
-      <left-back-bottom-point  z="-0.01" x="-0.02" y="-0.005"  />
-      <right-front-bottom-point  z="0.01" x="0.02" y="-0.005"  />
-    </cuboid>
-    <algebra val="shape" />
-  </type>
-
-
-
-  <!--  ################################### -->
+<!-- ================LINEAR DETECTOR START=================================== -->
   <component type="panel" idstart="2001" idfillbyfirst="y" idstep="1" idstepbyrow="1">
-    <location z="20.200" name="linear-detector"/>
+    <location z="3.163" name="linear-detector"/>
     <parameter name="y">
-      <logfile id="Theta" eq="3.2*tan(value*0.0174533)-46*0.0012" extract-single-value-as="last_value"/>
+      <logfile id="Theta" eq="3.163*tan(2*value*0.0174533)-46*0.0012" extract-single-value-as="last_value"/>
     </parameter>
 
   </component>
@@ -239,57 +159,12 @@
     </cuboid>
     <algebra val="shape" />
   </type>
+<!-- ================LINEAR DETECTOR END-==================================== -->
 
-
-  <!-- source and sample-position components -->
-
-  <component type="source">
-    <location />
-  </component>
-
-  <type name="source" is="Source">
-    <properties>
-      40mm(H) x 60mm(W)
-    </properties>
-  </type>
-
-
-  <component type="some-surface-holder">
-    <!-- worry about linking relevant logfiles for y,z,theta,phi up later -->
-    <location z="17.037"/>
-  </component>
-
-  <type name="some-surface-holder" is="SamplePos">
-  </type>
-
-
-  <!-- other components -->
-
-  <!--  Must change the distances below to match polref -->
-
-  <component type="test" name="test1">
-    <location z="13.200"/>
-    <parameter name="y">
-      <value val="-0.1"/>
-    </parameter>
-    <location z="13.00" />
-    <parameter name="y">
-      <value val="0.1"/>
-    </parameter>
-  </component>
-
-  <type name="test">
-      <percent-transparency val="50" />
-    <cuboid id="bottom">
-      <left-front-bottom-point z="0.0005" x="-0.025" y="-0.03"  />
-      <left-front-top-point  z="0.0005" x="-0.025" y="0.0"  />
-      <left-back-bottom-point  z="-0.0005" x="-0.025" y="-0.03"  />
-      <right-front-bottom-point  z="0.0005" x="0.025" y="-0.03"  />
-    </cuboid>
-  </type>
+<!-- other components -->
 
   <component type="slit" name="slit1">
-    <location z="14.801"/>
+    <location z="-2.236"/>
      <!-- This log file stores the vertical opening of slit -->
     <parameter name="vertical gap">
       <logfile id="S1_VG" extract-single-value-as="last_value" />
@@ -297,15 +172,10 @@
     <parameter name="y">
       <logfile id="S1_VG" eq="-value*0.001/2.0" extract-single-value-as="last_value" />
     </parameter>
-
-    <parameter name="y2">
-      <logfile id="S1_VG" eq="0.3+value*0.001/2.0" extract-single-value-as="last_value" />
-    </parameter>
-    <location z="15.250" y="0.3"/>
-    </component>
+  </component>
 
   <component type="slit" name="slit2">
-    <location z="16.724"/>
+    <location z="-0.313"/>
     <!-- This log file stores the vertical opening of this. Note this
      slit can also be translated in the z. However this info not stored
      in log file since it is not used in the data analysis process. -->
@@ -315,7 +185,7 @@
   </component>
 
   <component type="slit" name="slit3">
-    <location z="18.200"/> <!-- x=23.0+0.960   -->
+    <location z="1.163"/> <!-- x=23.0+0.960   -->
     <!-- This log file stores the vertical opening of slit -->
     <parameter name="vertical gap">
       <logfile id="S3_VG" extract-single-value-as="last_value" />
@@ -323,7 +193,7 @@
   </component>
 
   <component type="slit" name="slit4">
-    <location z="19.700"/>     <!-- x=23.0+2.445   -->
+    <location z="2.663"/>     <!-- x=23.0+2.445   -->
     <!-- This log file stores the vertical opening of slit. Note this slit
      is fixed to the point detector. -->
     <parameter name="vertical gap">
@@ -340,33 +210,15 @@
       <right-front-bottom-point  z="0.0005" x="0.025" y="-0.03"  />
     </cuboid>
   </type>
- <!--    <cuboid id="top">
-      <left-front-bottom-point z="0.0005" x="-0.025" y="0.01"  />
-      <left-front-top-point  z="0.0005" x="-0.025" y="0.04"  />
-      <left-back-bottom-point  z="-0.0005" x="-0.025" y="0.01"  />
-      <right-front-bottom-point  z="0.0005" x="0.025" y="0.01"  />
-    </cuboid>
-    <algebra val="top : bottom" />
- <type name="slit2"></type>
-  <type name="slit3"></type>
-  <type name="slit4"></type>
- -->
-
 
   <component type="supermirror">
-    <!-- Worry about linking relevant logfiles for z,theta up later -->
     <location z="28.52"/>  <!-- x=32.0-3.480   -->
   </component>
-
   <type name="supermirror" />
 
 
 
-
-  <!-- DETECTOR and MONITOR ID LISTS -->
-
-
-
+<!-- DETECTOR and MONITOR ID LISTS -->
   <idlist idname="monitor1">
     <id val="1" />
   </idlist>
@@ -383,9 +235,6 @@
     <id val="4" />
   </idlist>
 
-  <idlist idname="point-detector2">
-    <id val="5" />
-  </idlist>
  <!--
   <idlist idname="linear-detector">
     <id start="2001" end="2240" />
diff --git a/instrument/INTER_Definition_2017.xml b/instrument/INTER_Definition_2017.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b29e15202d7fc3ea3acf122a9d0085d199f9f664
--- /dev/null
+++ b/instrument/INTER_Definition_2017.xml
@@ -0,0 +1,243 @@
+<?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="INTER"
+            valid-from="2017-02-14 00:00:00"
+            valid-to=  "2100-01-31 23:59:59"
+			      last-modified="2018-02-16 00:00:00">
+
+  <defaults>
+    <length unit="meter" />
+    <angle unit="degree" />
+    <reference-frame>
+      <along-beam axis="z" />
+      <pointing-up axis="y" />
+      <handedness val="right" />
+    </reference-frame>
+    <default-view axis-view="z+"/>
+  </defaults>
+
+<!-- source and sample-position components START============================= -->
+
+  <component type="source">
+    <location z="-17.037" />
+  </component>
+  <type name="source" is="Source">
+    <properties>
+      40mm(H) x 60mm(W)
+    </properties>
+  </type>
+
+  <component type="some-surface-holder">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type name="some-surface-holder" is="SamplePos"/>
+
+<!-- source and sample-position components END=============================== -->
+
+
+<!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+<!-- detector components (including monitors) -->
+
+<!-- ================MONITOR 1 START========================================= -->
+  <component type="monitor1" idlist="monitor1">
+    <location z="-10.077" />
+  </component>
+
+  <type name="monitor1" is="monitor">
+    <percent-transparency val="95" />
+    <cylinder id="shape">
+      <centre-of-bottom-base z="0.0" x="-0.02" y="0.0" />
+      <axis z="0.0" x="1.0" y="0.0" />
+      <radius val="0.01" />
+      <height val="0.04" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>
+<!-- ================MONITOR 1 END=========================================== -->
+
+<!-- ================MONITOR 2 START========================================= -->
+  <component type="monitor2" idlist="monitor2">
+    <location z="-3.246" />
+  </component>
+
+  <type name="monitor2" is="monitor">
+    <percent-transparency val="95" />
+    <cuboid id="base">
+      <left-front-bottom-point z="0.04" x="-0.02" y="-0.01"  />
+      <left-front-top-point  z="0.04" x="-0.02" y="0.01"  />
+      <left-back-bottom-point  z="-0.04" x="-0.02" y="-0.01"  />
+      <right-front-bottom-point  z="0.04" x="0.02" y="-0.01"  />
+    </cuboid>
+
+    <cylinder id="top">
+      <centre-of-bottom-base z="0.0" x="0.0" y="0.01" />
+      <axis z="0.0" x="0.0" y="1.0" />
+      <radius val="0.02" />
+      <height val="0.04" />
+    </cylinder>
+    <algebra val="base : top" />
+  </type>
+<!-- ================MONITOR 2 END=========================================== -->
+
+<!-- ================MONITOR 3 START========================================= -->
+  <component type="monitor3" idlist="monitor3">
+    <location z="-0.252" />
+  </component>
+
+  <type name="monitor3" is="monitor">
+    <percent-transparency val="95" />
+    <cuboid id="base">
+      <left-front-bottom-point z="0.04" x="-0.02" y="-0.01"  />
+      <left-front-top-point  z="0.04" x="-0.02" y="0.01"  />
+      <left-back-bottom-point  z="-0.04" x="-0.02" y="-0.01"  />
+      <right-front-bottom-point  z="0.04" x="0.02" y="-0.01"  />
+    </cuboid>
+
+    <cylinder id="top">
+      <centre-of-bottom-base z="0.0" x="0.0" y="0.01" />
+      <axis z="0.0" x="0.0" y="1.0" />
+      <radius val="0.02" />
+      <height val="0.04" />
+    </cylinder>
+
+    <algebra val="base : top" />
+  </type>
+<!-- ================MONITOR 2 END=========================================== -->
+
+<!-- ================POINT DETECTOR START==================================== -->
+  <component type="point-detector" idlist="point-detector">
+
+    <location z="2.663" />  <!-- x= 23.0+2.6 -->
+    <parameter name="y">
+      <logfile id="PD1H" eq="(value+201.0)/1000." extract-single-value-as="last_value"/>
+      <!--<logfile id="theta" eq="2.6*sin(value*0.0174533)" extract-single-value-as="last_value"/>-->
+    </parameter>
+
+  </component>
+
+  <type name="point-detector" is="detector">
+    <!-- Not exactly sure about the dimensions of this one. But pretty sure
+    it at least covers the beam. Also, just in front of it is a slit which
+    at the end of day will determine which neutrons get through to this
+    detector I believe.
+    -->
+    <cuboid id="shape">
+      <left-front-bottom-point z="0.01" x="-0.02" y="-0.005"  />
+      <left-front-top-point  z="0.01" x="-0.02" y="0.005"  />
+      <left-back-bottom-point  z="-0.01" x="-0.02" y="-0.005"  />
+      <right-front-bottom-point  z="0.01" x="0.02" y="-0.005"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+<!-- ================POINT DETECTOR END====================================== -->
+
+<!-- ================LINEAR DETECTOR START=================================== -->
+  <component type="panel" idstart="2001" idfillbyfirst="y" idstep="1" idstepbyrow="1">
+    <location z="3.163" name="linear-detector"/>
+    <parameter name="y">
+      <logfile id="Theta" eq="3.163*tan(2*value*0.0174533)-46*0.0012" extract-single-value-as="last_value"/>
+    </parameter>
+
+  </component>
+
+  <type name="panel" is="rectangular_detector" type="linear-detector-pixel"
+    xpixels="1" xstart="0.0" xstep="0.05"
+    ypixels="243" ystart="0.0" ystep="+0.0012" >
+    <properties/>
+  </type>
+  <!--"-0.0576"-->
+  <type name="linear-detector-pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point z="0.01" x="-0.025" y="-0.0006"  />
+      <left-front-top-point  z="0.01" x="-0.025" y="0.0006"  />
+      <left-back-bottom-point  z="-0.01" x="-0.025" y="-0.0006"  />
+      <right-front-bottom-point  z="0.01" x="0.025" y="-0.0006"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+<!-- ================LINEAR DETECTOR END-==================================== -->
+
+<!-- other components -->
+
+  <component type="slit" name="slit1">
+    <location z="-2.236"/>
+     <!-- This log file stores the vertical opening of slit -->
+    <parameter name="vertical gap">
+      <logfile id="S1VG" extract-single-value-as="last_value" />
+    </parameter>
+    <parameter name="y">
+      <logfile id="S1VG" eq="-value*0.001/2.0" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit2">
+    <location z="-0.313"/>
+    <!-- This log file stores the vertical opening of this. Note this
+     slit can also be translated in the z. However this info not stored
+     in log file since it is not used in the data analysis process. -->
+    <parameter name="vertical gap">
+      <logfile id="S2VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit3">
+    <location z="1.163"/> <!-- x=23.0+0.960   -->
+    <!-- This log file stores the vertical opening of slit -->
+    <parameter name="vertical gap">
+      <logfile id="S3VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit4">
+    <location z="2.663"/>     <!-- x=23.0+2.445   -->
+    <!-- This log file stores the vertical opening of slit. Note this slit
+     is fixed to the point detector. -->
+    <parameter name="vertical gap">
+      <logfile id="S4VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <type name="slit">
+    <percent-transparency val="50" />
+    <cuboid id="bottom">
+      <left-front-bottom-point z="0.0005" x="-0.025" y="-0.03"  />
+      <left-front-top-point  z="0.0005" x="-0.025" y="0.0"  />
+      <left-back-bottom-point  z="-0.0005" x="-0.025" y="-0.03"  />
+      <right-front-bottom-point  z="0.0005" x="0.025" y="-0.03"  />
+    </cuboid>
+  </type>
+
+  <component type="supermirror">
+    <location z="28.52"/>  <!-- x=32.0-3.480   -->
+  </component>
+  <type name="supermirror" />
+
+
+
+<!-- DETECTOR and MONITOR ID LISTS -->
+  <idlist idname="monitor1">
+    <id val="1" />
+  </idlist>
+
+  <idlist idname="monitor2">
+    <id val="2" />
+  </idlist>
+
+  <idlist idname="monitor3">
+    <id val="3" />
+  </idlist>
+
+  <idlist idname="point-detector">
+    <id val="4" />
+  </idlist>
+
+ <!--
+  <idlist idname="linear-detector">
+    <id start="2001" end="2240" />
+  </idlist>
+  -->
+</instrument>
diff --git a/instrument/OFFSPEC_Parameters.xml b/instrument/OFFSPEC_Parameters.xml
index e3e5d0f4383c75c378345407cdcd31878fb57f34..9f82f9daf36552947ab6474067aa78066fae98af 100644
--- a/instrument/OFFSPEC_Parameters.xml
+++ b/instrument/OFFSPEC_Parameters.xml
@@ -21,14 +21,6 @@
    <value val="14.0"/>
   </parameter>
 
-  <parameter name="PointDetectorStart">
-    <value val="3"/>
-  </parameter>
-
-  <parameter name="PointDetectorStop">
-    <value val="3"/>
-  </parameter>
-
   <parameter name="MultiDetectorStart">
   <!--
   This channel number is marks the start of all other linear and/or area detectors.
@@ -48,13 +40,27 @@
     <value val="14.0"/>
   </parameter>
   
-  <parameter name="TransRunStartOverlap"> <!-- in wavelength -->
-    <value val="10"/>
+  <parameter name="TransRunStartOverlap">
+    <value val="10.0"/>
   </parameter>
 
-  <parameter name="TransRunEndOverlap"> <!-- in wavelength -->
-    <value val="12"/>
+  <parameter name="TransRunEndOverlap"> 
+    <value val="12.0"/>
+    
+  </parameter>
+  <parameter name="ProcessingInstructions" type="string"> 
+    <value val="390-415"/>
   </parameter>
   
+<parameter name="DetectorCorrectionType" type="string">
+    <value val="RotateAroundSample"/>
+</parameter>
+
+<parameter name="AnalysisMode" type="string">
+    <value val="MultiDetectorAnalysis"/>
+</parameter>
+
+   
+   
 </component-link>
 </parameter-file>
diff --git a/instrument/SURF_Definition.xml b/instrument/SURF_Definition.xml
index 41da6e13809972cc37be02ebb7e13d45b8a1e646..382c01e0c02513a1cbf825f1153fca4640082d51 100644
--- a/instrument/SURF_Definition.xml
+++ b/instrument/SURF_Definition.xml
@@ -1,10 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<instrument xmlns="http://www.mantidproject.org/IDF/1.0" 
+<!-- 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="SRF" valid-from   ="2010-01-10 23:59:59"
-                          valid-to     ="2100-01-30 23:59:59"          
-              last-modified="2010-11-04 00:00:00">
+            name="SURF"
+            valid-from="2010-01-10 23:59:59"
+            valid-to="2017-02-13 23:59:59"
+            last-modified="2018-03-15 00:00:00">
+
   <defaults>
     <length unit="meter" />
     <angle unit="degree" />
@@ -13,99 +17,87 @@
       <pointing-up axis="y" />
       <handedness val="right" />
     </reference-frame>
-    <default-view axis-view="z-"/>
+    <default-view axis-view="z+"/>
   </defaults>
 
- <!-- Definition of instrument specific parameters for data reduction (e.g. wavelength cutoffs etc.) , could go into paramter file
-	MonitorBackground= [7.6,8.5]
-	MonitorsToCorrect=[1]
-	PointDetectorStart=[0]   # Note: Since we are removing the monitors in the load raw command they are not counted here.
-	PointDetectorStop=[0]
-	MultiDetectorStart=[1]
-	I0MonitorIndex=1
- -->
-
-  <!-- BRIEF DESCRIPTION OF CRISP INSTRUMENT: 
-  
-      Here Z=0 is defined by the neutron beam which slopes down at 1.5 deg. 
-      from the horizon. This description is based on data provided by Tim
-      Charlton and Rob Dalgliesh.
-      
-      Note from Tim spreedsheet
-      theta is a rotation about the y axis
-      phi is a rotation about the x axis
-      chi is a rotation about the z axis
-
-      Noticed the face of the monitors/detector shapes that faces the
-      beam/sample path is in this IDF defined to be the y-z plane.
-      
-      Note the status of the instrument during a run is stored in the 
-      logfile RunNo_status.txt
-  -->
-  
-  
-  <!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
-  
-  <!-- detector components (including monitors) -->
-  
+<!-- source and sample-position components START============================= -->
+
+  <component type="source">
+    <location z="-8.869" />
+  </component>
+  <type name="source" is="Source">
+    <properties>
+      40mm(H) x 60mm(W)
+    </properties>
+  </type>
+
+  <component type="some-surface-holder">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type name="some-surface-holder" is="SamplePos"/>
+
+<!-- source and sample-position components END=============================== -->
+
+
+<!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+<!-- detector components (including monitors) -->
+
+<!-- ================MONITOR 1 START========================================= -->
   <component type="monitor1" idlist="monitor1">
-    <location z="7.2055"/>
+    <location z="-1.663"/>
   </component>
-  
+
   <type name="monitor1" is="monitor">
     <!-- Shape specified at least big enough to cover the beam which
          is 10mm high and 40mm wide. Note it is described as tube, hence
 	 the choice of a cylinder shape.
-    -->    
+    -->
     <percent-transparency val="95" />
     <cylinder id="shape">
       <centre-of-bottom-base x="-0.02" y="0.0" z="0.0" />
-      <axis x="1.0" y="0.0" z="0.0" /> 
+      <axis x="1.0" y="0.0" z="0.0" />
       <radius val="0.01" />
       <height val="0.04" />
-    </cylinder> 
+    </cylinder>
     <algebra val="shape" />
-  </type>  
-  
+  </type>
+<!-- ================MONITOR 1 END=========================================== -->
+
+<!-- ================MONITOR 2 START========================================= -->
   <component type="monitor2" idlist="monitor2">
-    <location z="8.72" />
-  </component>  
-  
+    <location z="-0.149" />
+  </component>
+
   <type name="monitor2" is="monitor">
     <!-- Original shape included a Sphere attached to the cuboid
-	but that was cosmetic only as it is not in the beam, 
-	and was causing problems with opencascade on windows 8.  
-	Therefore it has been removed. -->    
+	but that was cosmetic only as it is not in the beam,
+	and was causing problems with opencascade on windows 8.
+	Therefore it has been removed. -->
     <percent-transparency val="95" />
     <cuboid id="base">
       <left-front-bottom-point x="0.02" y="-0.005" z="0.0"  />
       <left-front-top-point  x="0.02" y="0.005" z="0.0"  />
       <left-back-bottom-point  x="0.02" y="-0.005" z="-0.01"  />
-      <right-front-bottom-point  x="-0.02" y="-0.005" z="0.0"  />   
+      <right-front-bottom-point  x="-0.02" y="-0.005" z="0.0"  />
     </cuboid>
-    
-  </type>  
-  
+  </type>
+<!-- ================MONITOR 2 END=========================================== -->
+
+<!-- ================POINT DETECTOR START==================================== -->
   <component type="point-detector" idlist="point-detector">
-    <location z="11.43" />
-    
-    <!-- Link to log file that stores the z position. This angle can be used to
-    calculate the y position since the distance along the z-axis between
-    the sample and this detector is known (11.43-8.869=2.561). Also theta in the logfile is
-    assumed to in degrees, hence the reason for the pi/180=0.0174533 transformation
-    to radians factor in the eq attribute. -->
+    <location z="2.561" />
     <parameter name="y">
-      <logfile id="theta" eq="2.561*sin(value*0.0174533)" />
+      <logfile id="THETA" eq="2.561*sin(2*value*0.0174533)" extract-single-value-as="last_value"/>
     </parameter>
-    
+
   </component>
 
   <type name="point-detector" is="detector">
     <!-- Not exactly sure about the dimensions of this one. But pretty sure
     it at least covers the beam. Also, just in front of it is a slit which
-    at the end of day will determine which neutrons get through to this 
+    at the end of day will determine which neutrons get through to this
     detector I believe.
-    -->    
+    -->
     <cuboid id="shape">
       <left-front-bottom-point x="0.02" y="-0.005" z="0.0"  />
       <left-front-top-point  x="0.02" y="0.005" z="0.0"  />
@@ -113,34 +105,20 @@
       <right-front-bottom-point  x="-0.02" y="-0.005" z="0.0"  />
     </cuboid>
     <algebra val="shape" />
-  </type>    
+  </type>
+<!-- ================POINT DETECTOR END====================================== -->
 
+<!-- ================AREA DETECTOR START=================================== -->
   <component type="panel" idstart="10001" idfillbyfirst="y" idstep="1" idstepbyrow="64">
-    <location z="11.93" name="multi-detector"/>
+    <location z="3.061" name="multi-detector"/>
   </component>
- 
- <!-- 
-  <component type="multi-detector" idlist="multi-detector">
-  -->
-    <!-- Link to log file that stores the z position -->
-<!--     <parameter name="z">
-      <logfile id="multi_det_height" eq="0.001*value" extract-single-value-as="position 1" />
-    </parameter>
-  
-    <properties> 
-      square pixels 2.2mm width in z-y direction    
-    </properties>
-    
-    <location x="12.403" />
-  </component>    
--->
 
-  <type name="panel" is="rectangular_detector" type="multi-detector-pixel" 
+  <type name="panel" is="rectangular_detector" type="multi-detector-pixel"
     xpixels="40" xstart="-0.044" xstep="+0.0022"
     ypixels="46" ystart="0.0" ystep="+0.0022" >
     <properties/>
-  </type>  
-  
+  </type>
+
   <type name="multi-detector-pixel" is="detector">
     <cuboid id="shape">
       <left-front-bottom-point x="0.01" y="-0.0011" z="-0.0011"  />
@@ -149,65 +127,43 @@
       <right-front-bottom-point  x="0.01" y="0.0011" z="-0.0011"  />
     </cuboid>
     <algebra val="shape" />
-  </type>    
+  </type>
 
-  
-  <!-- source and sample-position components -->
 
-  <component type="source">
-    <location />
-  </component>
-
-  <type name="source" is="Source">
-    <properties>
-      10mm(H) x 40mm(W)
-    </properties>
-  </type> 
-  
-  
-  <component type="some-surface-holder">
-    <!-- worry about linking relevant logfiles for y,z,theta,phi up later -->
-    <location z="8.869"/>
-  </component>
+  <!-- other components -->
 
-  <type name="some-surface-holder" is="SamplePos">
-  </type>
-  
-  
-  <!-- other components -->  
-  
   <component type="slit" name="slit1">
-    <location z="7.032"/>
+    <location z="-1.873"/>
      <!-- This log file stores the vertical opening of slit -->
-    <parameter name="vertical gap"> 
+    <parameter name="vertical gap">
       <logfile id="S1" extract-single-value-as="last_value" />
     </parameter>
   </component>
-  
-  <component type="slit" name="slit2">  
-    <location z="8.532"/> 
+
+  <component type="slit" name="slit2">
+    <location z="-0.254"/>
     <!-- This log file stores the vertical opening of this. Note this
      slit can also be translated in the z. However this info not stored
      in log file since it is not used in the data analysis process. -->
-    <parameter name="vertical gap"> 
+    <parameter name="vertical gap">
       <logfile id="S2" extract-single-value-as="last_value" />
     </parameter>
-  </component>    
-  
-  <component type="slit" name="slit3">   
-    <location z="9.174"/>
-    <!-- This log file stores the vertical opening of slit -->  
+  </component>
+
+  <component type="slit" name="slit3">
+    <location z="0.298"/>
+    <!-- This log file stores the vertical opening of slit -->
     <parameter name="vertical gap">
       <logfile id="S3" extract-single-value-as="last_value" />
     </parameter>
-  </component>    
-  
-  <component type="slit" name="slit4">    
-    <location z="11.300"/> 
+  </component>
+
+  <component type="slit" name="slit4">
+    <location z="2.431"/>
     <!-- This log file stores the vertical opening of slit. Note this slit
      is fixed to the point detector. -->
-    <parameter name="vertical gap"> 
-      <logfile id="S4" extract-single-value-as="last_value" />    
+    <parameter name="vertical gap">
+      <logfile id="S4" extract-single-value-as="last_value" />
     </parameter>
   </component>
 
@@ -220,76 +176,30 @@
       <right-front-bottom-point  z="0.0005" x="0.025" y="-0.03"  />
     </cuboid>
   </type>
-  
 
-  
-  
-  
+
+
+
   <component type="supermirror">
     <!-- Worry about linking relevant logfiles for z,theta up later -->
-    <location z="7.7685"/>  
-  </component>  
-
-  <type name="supermirror" /> 
+    <location z="-1.103"/>
+  </component>
 
+  <type name="supermirror" />
 
 
-  
   <!-- DETECTOR and MONITOR ID LISTS -->
 
   <idlist idname="monitor1">
-    <id val="20001" />  
+    <id val="20001" />
   </idlist>
-  
+
   <idlist idname="monitor2">
-    <id val="20002" />  
+    <id val="20002" />
   </idlist>
 
   <idlist idname="point-detector">
-    <id val="30001" />  
+    <id val="30001" />
   </idlist>
-<!--  
-  <idlist idname="multi-detector">
-    <id start="10001" end="10046" />
-    <id start="10065" end="10110" />
-    <id start="10129" end="10174" />
-    <id start="10193" end="10238" />
-    <id start="10257" end="10302" />
-    <id start="10321" end="10366" />
-    <id start="10385" end="10430" />
-    <id start="10449" end="10494" />
-    <id start="10513" end="10558" />
-    <id start="10577" end="10622" />
-    <id start="10641" end="10686" />
-    <id start="10705" end="10750" />
-    <id start="10769" end="10814" />
-    <id start="10833" end="10878" />
-    <id start="10897" end="10942" />
-    <id start="10961" end="11006" />
-    <id start="11025" end="11070" />
-    <id start="11089" end="11134" />
-    <id start="11153" end="11198" />
-    <id start="11217" end="11262" />
-    <id start="11281" end="11326" />
-    <id start="11345" end="11390" />
-    <id start="11409" end="11454" />
-    <id start="11473" end="11518" />
-    <id start="11537" end="11582" />
-    <id start="11601" end="11646" />
-    <id start="11665" end="11710" />
-    <id start="11729" end="11774" />
-    <id start="11793" end="11838" />
-    <id start="11857" end="11902" />
-    <id start="11921" end="11966" />
-    <id start="11985" end="12030" />
-    <id start="12049" end="12094" />
-    <id start="12113" end="12158" />
-    <id start="12177" end="12222" />
-    <id start="12241" end="12286" />
-    <id start="12305" end="12350" />
-    <id start="12369" end="12414" />
-    <id start="12433" end="12478" />
-    <id start="12497" end="12542" />
-  </idlist>  
-  -->
+
 </instrument>
diff --git a/instrument/SURF_Definition_2017.xml b/instrument/SURF_Definition_2017.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4bec930ff53ae4cae65ca1babce15215822cf361
--- /dev/null
+++ b/instrument/SURF_Definition_2017.xml
@@ -0,0 +1,205 @@
+<?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="SURF"
+            valid-from="2017-02-14 00:00:00"
+            valid-to="2100-01-30 23:59:59"
+            last-modified="2018-03-15 00:00:00">
+
+  <defaults>
+    <length unit="meter" />
+    <angle unit="degree" />
+    <reference-frame>
+      <along-beam axis="z" />
+      <pointing-up axis="y" />
+      <handedness val="right" />
+    </reference-frame>
+    <default-view axis-view="z+"/>
+  </defaults>
+
+<!-- source and sample-position components START============================= -->
+
+  <component type="source">
+    <location z="-8.869" />
+  </component>
+  <type name="source" is="Source">
+    <properties>
+      40mm(H) x 60mm(W)
+    </properties>
+  </type>
+
+  <component type="some-surface-holder">
+    <location x="0.0" y="0.0" z="0.0"/>
+  </component>
+  <type name="some-surface-holder" is="SamplePos"/>
+
+<!-- source and sample-position components END=============================== -->
+
+
+<!-- LIST OF PHYSICAL COMPONENTS (which the instrument consists of) -->
+<!-- detector components (including monitors) -->
+
+<!-- ================MONITOR 1 START========================================= -->
+  <component type="monitor1" idlist="monitor1">
+    <location z="-1.663"/>
+  </component>
+
+  <type name="monitor1" is="monitor">
+    <!-- Shape specified at least big enough to cover the beam which
+         is 10mm high and 40mm wide. Note it is described as tube, hence
+	 the choice of a cylinder shape.
+    -->
+    <percent-transparency val="95" />
+    <cylinder id="shape">
+      <centre-of-bottom-base x="-0.02" y="0.0" z="0.0" />
+      <axis x="1.0" y="0.0" z="0.0" />
+      <radius val="0.01" />
+      <height val="0.04" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>
+<!-- ================MONITOR 1 END=========================================== -->
+
+<!-- ================MONITOR 2 START========================================= -->
+  <component type="monitor2" idlist="monitor2">
+    <location z="-0.149" />
+  </component>
+
+  <type name="monitor2" is="monitor">
+    <!-- Original shape included a Sphere attached to the cuboid
+	but that was cosmetic only as it is not in the beam,
+	and was causing problems with opencascade on windows 8.
+	Therefore it has been removed. -->
+    <percent-transparency val="95" />
+    <cuboid id="base">
+      <left-front-bottom-point x="0.02" y="-0.005" z="0.0"  />
+      <left-front-top-point  x="0.02" y="0.005" z="0.0"  />
+      <left-back-bottom-point  x="0.02" y="-0.005" z="-0.01"  />
+      <right-front-bottom-point  x="-0.02" y="-0.005" z="0.0"  />
+    </cuboid>
+  </type>
+<!-- ================MONITOR 2 END=========================================== -->
+
+<!-- ================POINT DETECTOR START==================================== -->
+  <component type="point-detector" idlist="point-detector">
+    <location z="2.561" />
+    <parameter name="y">
+      <logfile id="THETA" eq="2.561*sin(2*value*0.0174533)" extract-single-value-as="last_value"/>
+    </parameter>
+
+  </component>
+
+  <type name="point-detector" is="detector">
+    <!-- Not exactly sure about the dimensions of this one. But pretty sure
+    it at least covers the beam. Also, just in front of it is a slit which
+    at the end of day will determine which neutrons get through to this
+    detector I believe.
+    -->
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.02" y="-0.005" z="0.0"  />
+      <left-front-top-point  x="0.02" y="0.005" z="0.0"  />
+      <left-back-bottom-point  x="0.02" y="-0.005" z="-0.01"  />
+      <right-front-bottom-point  x="-0.02" y="-0.005" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+<!-- ================POINT DETECTOR END====================================== -->
+
+<!-- ================AREA DETECTOR START=================================== -->
+  <component type="panel" idstart="10001" idfillbyfirst="y" idstep="1" idstepbyrow="64">
+    <location z="3.061" name="multi-detector"/>
+  </component>
+
+  <type name="panel" is="rectangular_detector" type="multi-detector-pixel"
+    xpixels="40" xstart="-0.044" xstep="+0.0022"
+    ypixels="46" ystart="0.0" ystep="+0.0022" >
+    <properties/>
+  </type>
+
+  <type name="multi-detector-pixel" is="detector">
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.01" y="-0.0011" z="-0.0011"  />
+      <left-front-top-point  x="0.01" y="-0.0011" z="0.0011"  />
+      <left-back-bottom-point  x="-0.01" y="-0.0011" z="-0.0011"  />
+      <right-front-bottom-point  x="0.01" y="0.0011" z="-0.0011"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+
+
+  <!-- other components -->
+
+  <component type="slit" name="slit1">
+    <location z="-1.873"/>
+     <!-- This log file stores the vertical opening of slit -->
+    <parameter name="vertical gap">
+      <logfile id="S1VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit2">
+    <location z="-0.254"/>
+    <!-- This log file stores the vertical opening of this. Note this
+     slit can also be translated in the z. However this info not stored
+     in log file since it is not used in the data analysis process. -->
+    <parameter name="vertical gap">
+      <logfile id="S2VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit3">
+    <location z="0.298"/>
+    <!-- This log file stores the vertical opening of slit -->
+    <parameter name="vertical gap">
+      <logfile id="S3VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <component type="slit" name="slit4">
+    <location z="2.431"/>
+    <!-- This log file stores the vertical opening of slit. Note this slit
+     is fixed to the point detector. -->
+    <parameter name="vertical gap">
+      <logfile id="S4VG" extract-single-value-as="last_value" />
+    </parameter>
+  </component>
+
+  <type name="slit">
+    <percent-transparency val="50" />
+    <cuboid id="bottom">
+      <left-front-bottom-point z="0.0005" x="-0.025" y="-0.03"  />
+      <left-front-top-point  z="0.0005" x="-0.025" y="0.0"  />
+      <left-back-bottom-point  z="-0.0005" x="-0.025" y="-0.03"  />
+      <right-front-bottom-point  z="0.0005" x="0.025" y="-0.03"  />
+    </cuboid>
+  </type>
+
+
+
+
+  <component type="supermirror">
+    <!-- Worry about linking relevant logfiles for z,theta up later -->
+    <location z="-1.103"/>
+  </component>
+
+  <type name="supermirror" />
+
+
+  <!-- DETECTOR and MONITOR ID LISTS -->
+
+  <idlist idname="monitor1">
+    <id val="20001" />
+  </idlist>
+
+  <idlist idname="monitor2">
+    <id val="20002" />
+  </idlist>
+
+  <idlist idname="point-detector">
+    <id val="30001" />
+  </idlist>
+
+</instrument>
diff --git a/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx b/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx
index b1d299bcd5dc70b968364524c1473c2b76036733..0df416020400a64e4bce86f8f146f8a0ad5fd8ce 100644
--- a/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx
+++ b/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx
@@ -152,7 +152,7 @@ int vtkSplatterPlot::RequestInformation(vtkInformation *,
       ADSWorkspaceProvider<IMDWorkspace> workspaceProvider;
       Workspace_sptr result = workspaceProvider.fetchWorkspace(m_wsName);
       m_presenter->initialize(result);
-    } catch (const std::runtime_error) {
+    } catch (const std::runtime_error &) {
       // Catch incase something goes wrong. It might be that the splatter
       // plot source is not yet setup correctly and we'll need to run this
       // call again later.
diff --git a/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx b/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx
index a1124c1485d3335d41d18a9a78f0d839b1147ea0..73df2744afcee72234a0bfef4501d8bc0270e2d3 100644
--- a/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx
+++ b/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx
@@ -38,7 +38,7 @@ vtkStandardNewMacro(vtkMDEWSource)
 }
 
 /// Destructor
-vtkMDEWSource::~vtkMDEWSource() {}
+vtkMDEWSource::~vtkMDEWSource() = default;
 
 /*
  Setter for the recursion depth
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h
index 54c25aa86e650b0f4e90d8c0115f8d62f1e15f27..dd59f7d9ba4b684a247a8f72d4f2c4f327bc884e 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h
@@ -14,16 +14,16 @@ class IMDDimension;
 
 namespace VATES {
 /// Vector of IMDDimension shared pointers.
-typedef std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension>>
-    DimensionVec;
+using DimensionVec =
+    std::vector<boost::shared_ptr<Mantid::Geometry::IMDDimension>>;
 
 /// IMDDimension as shared pointer.
-typedef boost::shared_ptr<Mantid::Geometry::IMDDimension> Dimension_sptr;
+using Dimension_sptr = boost::shared_ptr<Mantid::Geometry::IMDDimension>;
 
 /// IMDDimension as const shared pointer. Note that IMDDimension is pure
 /// virtual.
-typedef boost::shared_ptr<const Mantid::Geometry::IMDDimension>
-    Dimension_const_sptr;
+using Dimension_const_sptr =
+    boost::shared_ptr<const Mantid::Geometry::IMDDimension>;
 
 std::string makeAxisTitle(const Mantid::Geometry::IMDDimension &dim);
 
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h
index fe5a61c391235cfb98b072c9134e9505be593d3a..f66f86b272172f7b919d147fc5d54745269765da 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h
@@ -4,6 +4,8 @@
 #include "MantidAPI/DllConfig.h"
 #include "MantidGeometry/MDGeometry/MDTypes.h"
 
+#include <memory>
+
 namespace Mantid {
 
 namespace API {
@@ -37,7 +39,7 @@ enum VisualNormalization {
 };
 
 // Helper typedef
-typedef Mantid::signal_t (Mantid::API::IMDNode::*NormFuncIMDNodePtr)() const;
+using NormFuncIMDNodePtr = Mantid::signal_t (Mantid::API::IMDNode::*)() const;
 
 /**
 Determine which normalization function will be called on an IMDNode
@@ -50,10 +52,10 @@ NormFuncIMDNodePtr makeMDEventNormalizationFunction(
 Determine which normalization function will be called on an IMDIterator of an
 IMDWorkspace
 */
-DLLExport Mantid::API::IMDIterator *
+DLLExport std::unique_ptr<Mantid::API::IMDIterator>
 createIteratorWithNormalization(const VisualNormalization normalizationOption,
                                 Mantid::API::IMDWorkspace const *const ws);
 }
 }
 
-#endif /*MANTID_VATES_NORMALIZATION_H_*/
\ No newline at end of file
+#endif /*MANTID_VATES_NORMALIZATION_H_*/
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h
index 49875440b54bc23cf89eb32dbf59f3f156f5fdd7..498d9a535458511400c1bc8683c9a67cdb43758e 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h
@@ -29,8 +29,8 @@ public:
                                   const bool ascending) = 0;
 };
 
-typedef boost::shared_ptr<PeaksPresenterVsi> PeaksPresenterVsi_sptr;
-typedef boost::shared_ptr<const PeaksPresenterVsi> PeaksPresenterVsi_const_sptr;
+using PeaksPresenterVsi_sptr = boost::shared_ptr<PeaksPresenterVsi>;
+using PeaksPresenterVsi_const_sptr = boost::shared_ptr<const PeaksPresenterVsi>;
 }
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h
index 7c1cbb085de4302297f98e0c331631a8b3bcadbd..ff56b7e46e1cc96aeb91507085cf39d943223084 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h
@@ -47,12 +47,12 @@ private:
   enum { m_location = I };
 };
 
-typedef FrustumPlane<LEFTPLANE, double> LeftPlane;
-typedef FrustumPlane<RIGHTPLANE, double> RightPlane;
-typedef FrustumPlane<BOTTOMPLANE, double> BottomPlane;
-typedef FrustumPlane<TOPPLANE, double> TopPlane;
-typedef FrustumPlane<FARPLANE, double> FarPlane;
-typedef FrustumPlane<NEARPLANE, double> NearPlane;
+using LeftPlane = FrustumPlane<LEFTPLANE, double>;
+using RightPlane = FrustumPlane<RIGHTPLANE, double>;
+using BottomPlane = FrustumPlane<BOTTOMPLANE, double>;
+using TopPlane = FrustumPlane<TOPPLANE, double>;
+using FarPlane = FrustumPlane<FARPLANE, double>;
+using NearPlane = FrustumPlane<NEARPLANE, double>;
 
 class DLLExport ViewFrustum {
 public:
@@ -156,9 +156,9 @@ void ViewFrustum::initializeMatrix(Mantid::Kernel::Matrix<T> &matrix,
 }
 
 /// shared pointer to the view frustum
-typedef boost::shared_ptr<Mantid::VATES::ViewFrustum> ViewFrustum_sptr;
-typedef boost::shared_ptr<const Mantid::VATES::ViewFrustum>
-    ViewFrustum_const_sptr;
+using ViewFrustum_sptr = boost::shared_ptr<Mantid::VATES::ViewFrustum>;
+using ViewFrustum_const_sptr =
+    boost::shared_ptr<const Mantid::VATES::ViewFrustum>;
 }
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h
index de95431d72b3eae8c5afcd31e2789d4ce9261932..4ef75133b75c1ae4bef219a80694bf8d2c6e7bfa 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h
@@ -247,8 +247,8 @@ private:
   bool m_bCheckDimensionality;
 };
 
-typedef boost::shared_ptr<vtkDataSetFactory> vtkDataSetFactory_sptr;
-typedef std::unique_ptr<vtkDataSetFactory> vtkDataSetFactory_uptr;
+using vtkDataSetFactory_sptr = boost::shared_ptr<vtkDataSetFactory>;
+using vtkDataSetFactory_uptr = std::unique_ptr<vtkDataSetFactory>;
 }
 }
 
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
index 0ed83ee2ced646afdebda12cd3e9cd849a4d636e..56770476a3d3034c8fed13a9a392ae8810e555fa 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
@@ -74,11 +74,9 @@ protected:
   void validate() const override;
 
 private:
-  typedef std::vector<std::vector<std::vector<UnstructuredPoint>>> PointMap;
-
-  typedef std::vector<std::vector<UnstructuredPoint>> Plane;
-
-  typedef std::vector<UnstructuredPoint> Column;
+  using PointMap = std::vector<std::vector<std::vector<UnstructuredPoint>>>;
+  using Plane = std::vector<std::vector<UnstructuredPoint>>;
+  using Column = std::vector<UnstructuredPoint>;
 
   /// timestep obtained from framework.
   double m_timestep;
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
index 3223b13f86e051e89576b04579b40b9ea4379a2d..f3d3b2916ba5f27d548a166912c64becf12ba070 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
@@ -59,7 +59,7 @@ public:
 
   void initialize(const Mantid::API::Workspace_sptr &workspace) override;
 
-  typedef std::vector<UnstructuredPoint> Column;
+  using Column = std::vector<UnstructuredPoint>;
 
   std::string getFactoryTypeName() const override {
     return "vtkMDHistoLineFactory";
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
index 8f8a643de51a9ff03c00addc9970d7fb9396ea40..5aec1739e190ae9e8c020213c0905b6c22b5edcb 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
@@ -62,9 +62,9 @@ public:
 
   void initialize(const Mantid::API::Workspace_sptr &workspace) override;
 
-  typedef std::vector<std::vector<UnstructuredPoint>> Plane;
+  using Plane = std::vector<std::vector<UnstructuredPoint>>;
 
-  typedef std::vector<UnstructuredPoint> Column;
+  using Column = std::vector<UnstructuredPoint>;
 
   std::string getFactoryTypeName() const override {
     return "vtkMDHistoQuadFactory";
diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
index ecb8b0c9570170bcaa7119bb72c8d7ce021d56fd..e6fd9c757d196cf4f629a513232e0ff9c07cf4ae 100644
--- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
+++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
@@ -18,8 +18,7 @@
 namespace Mantid {
 namespace VATES {
 
-// Helper typedef
-typedef Mantid::signal_t (Mantid::API::IMDNode::*SigFuncIMDNodePtr)() const;
+using SigFuncIMDNodePtr = Mantid::signal_t (Mantid::API::IMDNode::*)() const;
 
 /**
  * Factory that creates a simple "splatter plot" data set composed of points
diff --git a/qt/paraview_ext/VatesAPI/src/Normalization.cpp b/qt/paraview_ext/VatesAPI/src/Normalization.cpp
index bea3316f82ca7756f1490c8f45693544f775f67c..46492b4e88a20db7178d32a5e52de3eaa986d8f3 100644
--- a/qt/paraview_ext/VatesAPI/src/Normalization.cpp
+++ b/qt/paraview_ext/VatesAPI/src/Normalization.cpp
@@ -46,7 +46,7 @@ Create iterators with correct normalization normalization to an IMDIterator.
 @param ws : workspace to fetch defaults from if needed
 @return new IMDIterator
 */
-DLLExport Mantid::API::IMDIterator *
+DLLExport std::unique_ptr<Mantid::API::IMDIterator>
 createIteratorWithNormalization(const VisualNormalization normalizationOption,
                                 Mantid::API::IMDWorkspace const *const ws) {
 
@@ -63,7 +63,7 @@ createIteratorWithNormalization(const VisualNormalization normalizationOption,
   }
 
   // Create the iterator
-  IMDIterator *iterator = ws->createIterator();
+  auto iterator = ws->createIterator();
   // Set normalization
   iterator->setNormalization(targetNormalization);
   // Return it
diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp
index d4da34d2b69f59a362d4b467a14c297d65725387..ba303cfe6ac8f0047fefa9fc9964103aeb7c3de8 100644
--- a/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp
+++ b/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp
@@ -128,11 +128,9 @@ void vtkMDHexFactory::doCreate(
 
         // If slicing down to 3D, specify which dimensions to keep.
         if (this->slice) {
-          coords = std::unique_ptr<coord_t[]>(
-              box->getVertexesArray(numVertexes, 3, this->sliceMask.get()));
+          coords = box->getVertexesArray(numVertexes, 3, this->sliceMask.get());
         } else {
-          coords =
-              std::unique_ptr<coord_t[]>(box->getVertexesArray(numVertexes));
+          coords = box->getVertexesArray(numVertexes);
         }
         if (numVertexes == 8) {
           std::copy_n(coords.get(), 24, std::next(pointsPtr, i * 24));
diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp
index 71e0e15560f99b0001ea69e3d03f3a9878126f47..bbce429bbf827e6ed6bbb6887ca963879fcf5f2e 100644
--- a/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp
+++ b/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp
@@ -88,10 +88,9 @@ vtkMDHistoQuadFactory::create(ProgressAction &progressUpdating) const {
     coord_t incrementX = (maxX - minX) / static_cast<coord_t>(nBinsX);
     coord_t incrementY = (maxY - minY) / static_cast<coord_t>(nBinsY);
 
-    boost::scoped_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(m_normalizationOption,
-                                            m_workspace.get())));
+    auto it = createIteratorWithNormalization(m_normalizationOption,
+                                              m_workspace.get());
+    auto iterator = dynamic_cast<MDHistoWorkspaceIterator *>(it.get());
     if (!iterator) {
       throw std::runtime_error(
           "Could not convert IMDIterator to a MDHistoWorkspaceIterator");
diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp
index 3379a5bf4a51a0d2e2d2ed3cc3b3c96e7aba6c42..38e144b2aec2f4fd9f29fb147e911e4d1f2b100c 100644
--- a/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp
+++ b/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp
@@ -75,8 +75,8 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const {
     }
 
     // Ensure destruction in any event.
-    boost::scoped_ptr<IMDIterator> it(
-        createIteratorWithNormalization(m_normalizationOption, imdws.get()));
+    auto it =
+        createIteratorWithNormalization(m_normalizationOption, imdws.get());
 
     // Create 2 points per box.
     vtkNew<vtkPoints> points;
@@ -116,8 +116,8 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const {
         useBox[iBox] = true;
         signals->InsertNextValue(static_cast<float>(signal_normalized));
 
-        auto coords = std::unique_ptr<coord_t[]>(
-            it->getVertexesArray(nVertexes, nNonIntegrated, masks.get()));
+        auto coords =
+            it->getVertexesArray(nVertexes, nNonIntegrated, masks.get());
 
         // Iterate through all coordinates. Candidate for speed improvement.
         for (size_t v = 0; v < nVertexes; ++v) {
diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp
index 5fa55dc5f3f50d8d416945a71ad1d0064de4b72f..77fd67e7b5bd1225b8a51b1ca7f32c144c925250 100644
--- a/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp
+++ b/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp
@@ -71,8 +71,8 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const {
 
     // Make iterator, which will use the desired normalization. Ensure
     // destruction in any eventuality.
-    boost::scoped_ptr<IMDIterator> it(
-        createIteratorWithNormalization(m_normalizationOption, imdws.get()));
+    auto it =
+        createIteratorWithNormalization(m_normalizationOption, imdws.get());
 
     // Create 4 points per box.
     vtkNew<vtkPoints> points;
@@ -112,9 +112,8 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const {
         useBox[iBox] = true;
         signals->InsertNextValue(static_cast<float>(signal));
 
-        auto coords = std::unique_ptr<coord_t[]>(
-            it->getVertexesArray(nVertexes, nNonIntegrated, masks.get()));
-
+        auto coords =
+            it->getVertexesArray(nVertexes, nNonIntegrated, masks.get());
         // Iterate through all coordinates. Candidate for speed improvement.
         for (size_t v = 0; v < nVertexes; ++v) {
           coord_t *coord = coords.get() + v * 2;
diff --git a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h
index de0a70e39716a1d59865cf4d55ee4d0e9cdf938f..fade140c7764142c0672d2adb031413c2f6970be 100644
--- a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h
+++ b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h
@@ -18,8 +18,8 @@ private:
     }
   };
 
-  typedef Mantid::VATES::FilterUpdateProgressAction<MockFilter>
-      ProgressActionType;
+  using ProgressActionType =
+      Mantid::VATES::FilterUpdateProgressAction<MockFilter>;
 
 public:
   void testCallsView() {
@@ -49,4 +49,4 @@ public:
         "message", view.Message);
   }
 };
-#endif
\ No newline at end of file
+#endif
diff --git a/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h b/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h
index 02984a1716aeac42cfd125dd115511dd2f8fa271..ff24c106df62742b991c981e06fca20051ff196f 100644
--- a/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h
+++ b/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h
@@ -33,7 +33,7 @@ private:
   */
   class ConcreteMDEWLoadingPresenter : public MDEWLoadingPresenter {
   private:
-    typedef MDEWLoadingPresenter BaseClass;
+    using BaseClass = MDEWLoadingPresenter;
 
   public:
     void
diff --git a/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h b/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h
index 0a249d713b61b7d0cec26e3d53e95b9f508e4512..bf4ae0aee056cb5f2fde2b9d730ac698d6fb55b0 100644
--- a/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h
+++ b/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h
@@ -31,7 +31,7 @@ private:
   */
   class ConcreteMDHWLoadingPresenter : public MDHWLoadingPresenter {
   private:
-    typedef MDHWLoadingPresenter BaseClass;
+    using BaseClass = MDHWLoadingPresenter;
 
   public:
     ConcreteMDHWLoadingPresenter(std::unique_ptr<MDLoadingView> view)
diff --git a/qt/paraview_ext/VatesAPI/test/MockObjects.h b/qt/paraview_ext/VatesAPI/test/MockObjects.h
index 25262bdcedec86053d0f0510d89286147a5a1f8b..0a58626c34f603f3d2e8a56d72503a5718fd5cef 100644
--- a/qt/paraview_ext/VatesAPI/test/MockObjects.h
+++ b/qt/paraview_ext/VatesAPI/test/MockObjects.h
@@ -102,7 +102,7 @@ public:
     return line;
   }
 
-  std::vector<Mantid::API::IMDIterator *> createIterators(
+  std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators(
       size_t = 1,
       Mantid::Geometry::MDImplicitFunction * = NULL) const override {
     throw std::runtime_error("Not Implemented");
diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt
index fd315f848220acce656e2ec9544f7e9d00429a9a..68d604c13eb610df9e280c8dffcf4bfd5cfc12ec 100644
--- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt
+++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt
@@ -136,7 +136,7 @@ mtd_add_qt_library (TARGET_NAME VatesSimpleGuiViewWidgets
     @loader_path/../../Contents/MacOS
     @loader_path/../../Contents/Libraries
   LINUX_INSTALL_RPATH
-    "\$ORIGIN/../../${LIB_DIR}"
+    "\$ORIGIN/../../${LIB_DIR};\$ORIGIN"
 )
 
 # Set the name of the generated library
diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h
index 5fce015034299c06e410c8a205e206f6c887953e..8617dca811dd7043104068928d397b236ae0fb13 100644
--- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h
+++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h
@@ -13,7 +13,7 @@ namespace SimpleGui {
 class VsiApplyBehaviour : public pqApplyBehavior {
 public:
   Q_OBJECT
-  typedef QObject Superclass;
+  using Superclass = QObject;
 
 public:
   VsiApplyBehaviour(Mantid::VATES::ColorScaleLock *lock,
diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h
index dbe74aa098fe9cd70beea0daf77c3a27dca146d3..01d4601507b27503ff8889430bd4934ddc7559f9 100644
--- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h
+++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h
@@ -71,7 +71,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS
     pqCameraReactionNonOrthogonalAxes : public pqReaction {
   Q_OBJECT
-  typedef pqReaction Superclass;
+  using Superclass = pqReaction;
 
 public:
   enum Mode {
diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h
index 5dd075d442be6330be8ec3926cc61656544a6f8b..ddb661045784516e7dd1f8df95440a17558e4ef4 100644
--- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h
+++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h
@@ -72,7 +72,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS
     pqCameraToolbarNonOrthogonalAxes : public QToolBar {
   Q_OBJECT
-  typedef QToolBar Superclass;
+  using Superclass = QToolBar;
 
 public:
   pqCameraToolbarNonOrthogonalAxes(const QString &title,
diff --git a/qt/python/mantidqt/utils/qt/testing/__init__.py b/qt/python/mantidqt/utils/qt/testing/__init__.py
index ec30caa54e0f7ce3eec82b539a7fc892e7fbf428..7aee12dd5186f33a0a0b11f28f2051f84a7ee57a 100644
--- a/qt/python/mantidqt/utils/qt/testing/__init__.py
+++ b/qt/python/mantidqt/utils/qt/testing/__init__.py
@@ -20,6 +20,7 @@
 from __future__ import absolute_import
 
 from inspect import isfunction, ismethod
+import gc
 
 from qtpy.QtCore import Qt
 from qtpy.QtWidgets import QApplication
@@ -74,6 +75,7 @@ def _requires_qapp_impl(test_method):
             QAPP = QApplication([''])
         test_method(self)
         QAPP.closeAllWindows()
+        gc.collect()
 
     return _wrapper
 
diff --git a/qt/python/mantidqt/utils/qt/testing/modal_tester.py b/qt/python/mantidqt/utils/qt/testing/modal_tester.py
index 605b06b2d09262dffa591f5bda3efb867c5fbf64..f7588248a440d61205f725fb82b002afd1c44507 100644
--- a/qt/python/mantidqt/utils/qt/testing/modal_tester.py
+++ b/qt/python/mantidqt/utils/qt/testing/modal_tester.py
@@ -39,6 +39,8 @@ import traceback
 from qtpy.QtCore import QTimer
 from qtpy.QtWidgets import QApplication
 
+QAPP = None
+
 
 class ModalTester(object):
     """
@@ -51,9 +53,9 @@ class ModalTester(object):
             A modal widget must have exec_() method.
         :param tester: A function taking a widget as its argument that does testing.
         """
-        self.app = QApplication.instance()
-        if self.app is None:
-            self.app = QApplication([''])
+        global QAPP
+        if QAPP is None:
+            QAPP = QApplication([''])
         self.creator = creator
         self.tester = tester
         self.widget = None
@@ -68,7 +70,7 @@ class ModalTester(object):
             self.widget = self.creator()
         except:
             traceback.print_exc()
-            self.app.exit(0)
+            QAPP.exit(0)
         if self.widget is not None:
             self.widget.exec_()
 
@@ -77,7 +79,7 @@ class ModalTester(object):
         This function runs every time in QApplication's event loop.
         Call the testing function.
         """
-        modal_widget = self.app.activeModalWidget()
+        modal_widget = QAPP.activeModalWidget()
         if modal_widget is not None:
             if self.widget is modal_widget:
                 try:
@@ -85,6 +87,7 @@ class ModalTester(object):
                     self.passed = True
                 except:
                     traceback.print_exc()
+                    QAPP.exit(0)
             if modal_widget.isVisible():
                 modal_widget.close()
 
@@ -100,4 +103,4 @@ class ModalTester(object):
         # This calls __call__() method
         QTimer.singleShot(0, self)
         # Start the event loop
-        self.app.exec_()
+        QAPP.exec_()
diff --git a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py
index 411e9f4e2e2f2b5887ac61eff3d55488d627458c..c4f2d103ae610553a13011075a47b527bd38af1d 100644
--- a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py
+++ b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py
@@ -34,16 +34,18 @@ class InProcessJupyterConsoleTest(unittest.TestCase):
         self.assertTrue(hasattr(widget, "kernel_manager"))
         self.assertTrue(hasattr(widget, "kernel_client"))
         self.assertTrue(len(widget.banner) > 0)
+        del widget
 
     def test_construction_with_banner_replaces_default(self):
         widget = InProcessJupyterConsole(banner="Hello!")
         self.assertEquals("Hello!", widget.banner)
+        del widget
 
     def test_construction_with_startup_code_adds_to_banner_and_executes(self):
         widget = InProcessJupyterConsole(startup_code="x = 1")
         self.assertTrue("x = 1" in widget.banner)
         self.assertEquals(1, widget.kernel_manager.kernel.shell.user_ns['x'])
-
+        del widget
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt b/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
index 71f990d3547fb692bb83b7c0759712bc55afb729..8d9f7827172dae12201bca5493948fe99e3d3be1 100644
--- a/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
+++ b/qt/scientific_interfaces/EnggDiffraction/CMakeLists.txt
@@ -5,6 +5,7 @@ set ( SRC_FILES
 	EnggDiffGSASFittingModel.cpp
 	EnggDiffGSASFittingPresenter.cpp
 	EnggDiffGSASFittingViewQtWidget.cpp
+	EnggDiffGSASFittingWorker.cpp
 	EnggDiffMultiRunFittingQtWidget.cpp
 	EnggDiffMultiRunFittingWidgetAdder.cpp
 	EnggDiffMultiRunFittingWidgetModel.cpp
@@ -27,6 +28,7 @@ set ( INC_FILES
 	EnggDiffGSASFittingModel.h
 	EnggDiffGSASFittingPresenter.h
 	EnggDiffGSASFittingViewQtWidget.h
+	EnggDiffGSASFittingWorker.h
 	EnggDiffGSASRefinementMethod.h
 	EnggDiffMultiRunFittingQtWidget.h
 	EnggDiffMultiRunFittingWidgetAdder.h
@@ -57,7 +59,9 @@ set ( MOC_FILES
     EnggDiffFittingPresenter.h
     EnggDiffFittingPresWorker.h
     EnggDiffFittingViewQtWidget.h
+    EnggDiffGSASFittingModel.h
     EnggDiffGSASFittingViewQtWidget.h
+    EnggDiffGSASFittingWorker.h
     EnggDiffractionPresenter.h
     EnggDiffractionPresWorker.h
     EnggDiffractionViewQtGUI.h
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
index d9af851e60f2706d45b53791c8d8f0408f2b3297..8b9b47eed493b7d953be725d11e4f84989bd0308 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.cpp
@@ -13,6 +13,7 @@
 #include <sstream>
 
 #include <boost/algorithm/string.hpp>
+#include <boost/make_shared.hpp>
 
 #include <Poco/Path.h>
 
@@ -52,13 +53,11 @@ EnggDiffFittingViewQtWidget::EnggDiffFittingViewQtWidget(
     boost::shared_ptr<IEnggDiffractionPythonRunner> mainPythonRunner)
     : IEnggDiffFittingView(), m_fittedDataVector(), m_mainMsgProvider(mainMsg),
       m_mainSettings(mainSettings), m_mainPythonRunner(mainPythonRunner),
-      m_presenter(nullptr) {
+      m_presenter(boost::make_shared<EnggDiffFittingPresenter>(
+          this, Mantid::Kernel::make_unique<EnggDiffFittingModel>(), mainCalib,
+          mainParam)) {
 
   initLayout();
-
-  m_presenter.reset(new EnggDiffFittingPresenter(
-      this, Mantid::Kernel::make_unique<EnggDiffFittingModel>(), mainCalib,
-      mainParam));
   m_presenter->notify(IEnggDiffFittingPresenter::Start);
 }
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
index dfaa78baa499212229107737af8aadf5bd748dfc..cdbfdcd690648c00fd2db8974046432004950afe 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffFittingViewQtWidget.h
@@ -8,8 +8,6 @@
 
 #include "ui_EnggDiffractionQtTabFitting.h"
 
-#include <boost/scoped_ptr.hpp>
-
 // Qt classes forward declarations
 class QMessageBox;
 class QMutex;
@@ -244,7 +242,7 @@ private:
   boost::shared_ptr<IEnggDiffractionPythonRunner> m_mainPythonRunner;
 
   /// presenter as in the model-view-presenter
-  boost::scoped_ptr<IEnggDiffFittingPresenter> m_presenter;
+  boost::shared_ptr<IEnggDiffFittingPresenter> m_presenter;
 
   /// current selected instrument
   /// updated from the EnggDiffractionPresenter processInstChange
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.cpp
index 592ca3884517b5fb5cb7822027c54792ad6792b3..3b9d1d575335d95518aeea045e52fe620ab83030 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.cpp
@@ -19,20 +19,38 @@ std::string stripWSNameFromFilename(const std::string &fullyQualifiedFilename) {
   return filenameSegments[0];
 }
 
+std::string refinementMethodToString(
+    const MantidQt::CustomInterfaces::GSASRefinementMethod &method) {
+  switch (method) {
+  case MantidQt::CustomInterfaces::GSASRefinementMethod::PAWLEY:
+    return "Pawley refinement";
+  case MantidQt::CustomInterfaces::GSASRefinementMethod::RIETVELD:
+    return "Rietveld refinement";
+  default:
+    throw std::invalid_argument(
+        "Invalid refinement method: please contact the development team");
+  }
+}
+
 } // anonymous namespace
 
 namespace MantidQt {
 namespace CustomInterfaces {
+
+EnggDiffGSASFittingModel::~EnggDiffGSASFittingModel() {
+  if (m_workerThread) {
+    if (m_workerThread->isRunning()) {
+      m_workerThread->wait(10);
+    }
+  }
+}
+
 void EnggDiffGSASFittingModel::addFitResultsToMaps(
     const RunLabel &runLabel, const double rwp, const double sigma,
-    const double gamma, const std::string &latticeParamsTableName) {
+    const double gamma, const API::ITableWorkspace_sptr latticeParams) {
   addRwp(runLabel, rwp);
   addSigma(runLabel, sigma);
   addGamma(runLabel, gamma);
-
-  API::AnalysisDataServiceImpl &ADS = API::AnalysisDataService::Instance();
-  const auto latticeParams =
-      ADS.retrieveWS<API::ITableWorkspace>(latticeParamsTableName);
   addLatticeParams(runLabel, latticeParams);
 }
 
@@ -69,34 +87,14 @@ std::string generateLatticeParamsName(const RunLabel &runLabel) {
 }
 }
 
-API::MatrixWorkspace_sptr EnggDiffGSASFittingModel::doPawleyRefinement(
-    const GSASIIRefineFitPeaksParameters &params) {
-  const auto outputWSName = generateFittedPeaksWSName(params.runLabel);
-  const auto latticeParamsName = generateLatticeParamsName(params.runLabel);
-
-  const auto outputProperties = doGSASRefinementAlgorithm(
-      outputWSName, latticeParamsName, params, "Pawley refinement");
-
-  addFitResultsToMaps(params.runLabel, outputProperties.rwp,
-                      outputProperties.sigma, outputProperties.gamma,
-                      latticeParamsName);
-
-  API::AnalysisDataServiceImpl &ADS = API::AnalysisDataService::Instance();
-  const auto fittedPeaks = ADS.retrieveWS<API::MatrixWorkspace>(outputWSName);
-
-  return fittedPeaks;
-}
-
 GSASIIRefineFitPeaksOutputProperties
 EnggDiffGSASFittingModel::doGSASRefinementAlgorithm(
-    const std::string &outputWorkspaceName,
-    const std::string &latticeParamsName,
-    const GSASIIRefineFitPeaksParameters &params,
-    const std::string &refinementMethod) {
+    const GSASIIRefineFitPeaksParameters &params) {
   auto gsasAlg =
       API::AlgorithmManager::Instance().create("GSASIIRefineFitPeaks");
 
-  gsasAlg->setProperty("RefinementMethod", refinementMethod);
+  gsasAlg->setProperty("RefinementMethod",
+                       refinementMethodToString(params.refinementMethod));
   gsasAlg->setProperty("InputWorkspace", params.inputWorkspace);
   gsasAlg->setProperty("InstrumentFile", params.instParamsFile);
   gsasAlg->setProperty("PhaseInfoFiles",
@@ -118,7 +116,9 @@ EnggDiffGSASFittingModel::doGSASRefinementAlgorithm(
   gsasAlg->setProperty("RefineSigma", params.refineSigma);
   gsasAlg->setProperty("RefineGamma", params.refineGamma);
 
-  gsasAlg->setProperty("OutputWorkspace", outputWorkspaceName);
+  const auto outputWSName = generateFittedPeaksWSName(params.runLabel);
+  const auto latticeParamsName = generateLatticeParamsName(params.runLabel);
+  gsasAlg->setProperty("OutputWorkspace", outputWSName);
   gsasAlg->setProperty("LatticeParameters", latticeParamsName);
   gsasAlg->setProperty("SaveGSASIIProjectFile", params.gsasProjectFile);
   gsasAlg->execute();
@@ -126,25 +126,46 @@ EnggDiffGSASFittingModel::doGSASRefinementAlgorithm(
   const double rwp = gsasAlg->getProperty("Rwp");
   const double sigma = gsasAlg->getProperty("Sigma");
   const double gamma = gsasAlg->getProperty("Gamma");
-  return GSASIIRefineFitPeaksOutputProperties(rwp, sigma, gamma);
-}
-
-API::MatrixWorkspace_sptr EnggDiffGSASFittingModel::doRietveldRefinement(
-    const GSASIIRefineFitPeaksParameters &params) {
-  const auto outputWSName = generateFittedPeaksWSName(params.runLabel);
-  const auto latticeParamsName = generateLatticeParamsName(params.runLabel);
-
-  const auto outputProperties = doGSASRefinementAlgorithm(
-      outputWSName, latticeParamsName, params, "Rietveld refinement");
-
-  addFitResultsToMaps(params.runLabel, outputProperties.rwp,
-                      outputProperties.sigma, outputProperties.gamma,
-                      latticeParamsName);
 
   API::AnalysisDataServiceImpl &ADS = API::AnalysisDataService::Instance();
   const auto fittedPeaks = ADS.retrieveWS<API::MatrixWorkspace>(outputWSName);
-
-  return fittedPeaks;
+  const auto latticeParams =
+      ADS.retrieveWS<API::ITableWorkspace>(latticeParamsName);
+  return GSASIIRefineFitPeaksOutputProperties(rwp, sigma, gamma, fittedPeaks,
+                                              latticeParams, params.runLabel);
+}
+
+void EnggDiffGSASFittingModel::doRefinements(
+    const std::vector<GSASIIRefineFitPeaksParameters> &params) {
+  m_workerThread = Mantid::Kernel::make_unique<QThread>(this);
+  EnggDiffGSASFittingWorker *worker =
+      new EnggDiffGSASFittingWorker(this, params);
+  worker->moveToThread(m_workerThread.get());
+
+  qRegisterMetaType<
+      MantidQt::CustomInterfaces::GSASIIRefineFitPeaksOutputProperties>(
+      "GSASIIRefineFitPeaksOutputProperties");
+
+  connect(m_workerThread.get(), SIGNAL(started()), worker,
+          SLOT(doRefinements()));
+  connect(worker,
+          SIGNAL(refinementSuccessful(GSASIIRefineFitPeaksOutputProperties)),
+          this, SLOT(processRefinementSuccessful(
+                    const GSASIIRefineFitPeaksOutputProperties &)));
+  connect(worker, SIGNAL(refinementsComplete()), this,
+          SLOT(processRefinementsComplete()));
+  connect(worker, SIGNAL(refinementFailed(const std::string &)), this,
+          SLOT(processRefinementFailed(const std::string &)));
+  connect(worker, SIGNAL(refinementCancelled()), this,
+          SLOT(processRefinementCancelled()));
+  connect(m_workerThread.get(), SIGNAL(finished()), m_workerThread.get(),
+          SLOT(deleteLater()));
+  connect(worker,
+          SIGNAL(refinementSuccessful(GSASIIRefineFitPeaksOutputProperties)),
+          worker, SLOT(deleteLater()));
+  connect(worker, SIGNAL(refinementFailed(const std::string &)), worker,
+          SLOT(deleteLater()));
+  m_workerThread->start();
 }
 
 boost::optional<API::ITableWorkspace_sptr>
@@ -187,5 +208,37 @@ EnggDiffGSASFittingModel::loadFocusedRun(const std::string &filename) const {
   return ws;
 }
 
+void EnggDiffGSASFittingModel::processRefinementsComplete() {
+  m_observer->notifyRefinementsComplete();
+}
+
+void EnggDiffGSASFittingModel::processRefinementFailed(
+    const std::string &failureMessage) {
+  if (m_observer) {
+    m_observer->notifyRefinementFailed(failureMessage);
+  }
+}
+
+void EnggDiffGSASFittingModel::processRefinementSuccessful(
+    const GSASIIRefineFitPeaksOutputProperties &refinementResults) {
+  addFitResultsToMaps(refinementResults.runLabel, refinementResults.rwp,
+                      refinementResults.sigma, refinementResults.gamma,
+                      refinementResults.latticeParamsWS);
+  if (m_observer) {
+    m_observer->notifyRefinementSuccessful(refinementResults);
+  }
+}
+
+void EnggDiffGSASFittingModel::processRefinementCancelled() {
+  if (m_observer) {
+    m_observer->notifyRefinementCancelled();
+  }
+}
+
+void EnggDiffGSASFittingModel::setObserver(
+    boost::shared_ptr<IEnggDiffGSASFittingObserver> observer) {
+  m_observer = observer;
+}
+
 } // CustomInterfaces
 } // MantidQt
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.h
index 5fc0a4f4ed820fcfd2ec333c342957e2f0d3c90b..e5eb4387c582d99f94bd8434cafafdb3b865ca04 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingModel.h
@@ -2,22 +2,34 @@
 #define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASFITTINGMODEL_H_
 
 #include "DllConfig.h"
+#include "EnggDiffGSASFittingWorker.h"
 #include "GSASIIRefineFitPeaksOutputProperties.h"
 #include "IEnggDiffGSASFittingModel.h"
+#include "IEnggDiffGSASFittingObserver.h"
 #include "RunMap.h"
 
+#include <QObject>
+#include <QThread>
+
 namespace MantidQt {
 namespace CustomInterfaces {
 
 class MANTIDQT_ENGGDIFFRACTION_DLL EnggDiffGSASFittingModel
-    : public IEnggDiffGSASFittingModel {
+    : public QObject, // Must be a QObject to run GSASIIRefineFitPeaksWorker
+                      // asynchronously
+      public IEnggDiffGSASFittingModel {
+  Q_OBJECT
+
+  friend void EnggDiffGSASFittingWorker::doRefinements();
 
 public:
-  Mantid::API::MatrixWorkspace_sptr
-  doPawleyRefinement(const GSASIIRefineFitPeaksParameters &params) override;
+  ~EnggDiffGSASFittingModel();
 
-  Mantid::API::MatrixWorkspace_sptr
-  doRietveldRefinement(const GSASIIRefineFitPeaksParameters &params) override;
+  void setObserver(
+      boost::shared_ptr<IEnggDiffGSASFittingObserver> observer) override;
+
+  void doRefinements(
+      const std::vector<GSASIIRefineFitPeaksParameters> &params) override;
 
   boost::optional<Mantid::API::ITableWorkspace_sptr>
   getLatticeParams(const RunLabel &runLabel) const override;
@@ -50,6 +62,16 @@ protected:
   /// Add a sigma value to the sigma map
   void addSigma(const RunLabel &runLabel, const double sigma);
 
+protected slots:
+  void processRefinementsComplete();
+
+  void processRefinementFailed(const std::string &failureMessage);
+
+  void processRefinementSuccessful(
+      const GSASIIRefineFitPeaksOutputProperties &refinementResults);
+
+  void processRefinementCancelled();
+
 private:
   static constexpr double DEFAULT_PAWLEY_DMIN = 1;
   static constexpr double DEFAULT_PAWLEY_NEGATIVE_WEIGHT = 0;
@@ -60,11 +82,22 @@ private:
   RunMap<MAX_BANKS, double> m_rwpMap;
   RunMap<MAX_BANKS, double> m_sigmaMap;
 
+  boost::shared_ptr<IEnggDiffGSASFittingObserver> m_observer;
+
+  std::unique_ptr<QThread> m_workerThread;
+
   /// Add Rwp, sigma, gamma and lattice params table to their
   /// respective RunMaps
-  void addFitResultsToMaps(const RunLabel &runLabel, const double rwp,
-                           const double sigma, const double gamma,
-                           const std::string &latticeParamsTableName);
+  void
+  addFitResultsToMaps(const RunLabel &runLabel, const double rwp,
+                      const double sigma, const double gamma,
+                      const Mantid::API::ITableWorkspace_sptr latticeParams);
+
+  void deleteWorkerThread();
+
+  /// Run GSASIIRefineFitPeaks
+  GSASIIRefineFitPeaksOutputProperties
+  doGSASRefinementAlgorithm(const GSASIIRefineFitPeaksParameters &params);
 
   template <typename T>
   boost::optional<T> getFromRunMapOptional(const RunMap<MAX_BANKS, T> &map,
@@ -74,15 +107,6 @@ private:
     }
     return boost::none;
   }
-
-  /// Run GSASIIRefineFitPeaks
-  /// Note this must be virtual so that it can be mocked out by the helper class
-  /// in EnggDiffGSASFittingModelTest
-  virtual GSASIIRefineFitPeaksOutputProperties
-  doGSASRefinementAlgorithm(const std::string &fittedPeaksWSName,
-                            const std::string &latticeParamsWSName,
-                            const GSASIIRefineFitPeaksParameters &params,
-                            const std::string &refinementMethod);
 };
 
 } // CustomInterfaces
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.cpp
index ddf68069d18543951129e39bdf724b27ce3e60bd..ba848b99ddbb428af75b095f19d68a0fdd880ef0 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.cpp
@@ -2,6 +2,20 @@
 #include "EnggDiffGSASRefinementMethod.h"
 #include "MantidQtWidgets/LegacyQwt/QwtHelper.h"
 
+namespace {
+
+std::string addRunNumberToGSASIIProjectFile(
+    const std::string &filename,
+    const MantidQt::CustomInterfaces::RunLabel &runLabel) {
+  const auto dotPosition = filename.find_last_of(".");
+  return filename.substr(0, dotPosition) + "_" +
+         std::to_string(runLabel.runNumber) + "_" +
+         std::to_string(runLabel.bank) +
+         filename.substr(dotPosition, filename.length());
+}
+
+} // anonymous namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 
@@ -31,6 +45,10 @@ void EnggDiffGSASFittingPresenter::notify(
     processLoadRun();
     break;
 
+  case IEnggDiffGSASFittingPresenter::RefineAll:
+    processRefineAll();
+    break;
+
   case IEnggDiffGSASFittingPresenter::SelectRun:
     processSelectRun();
     break;
@@ -45,10 +63,52 @@ void EnggDiffGSASFittingPresenter::notify(
   }
 }
 
+std::vector<GSASIIRefineFitPeaksParameters>
+EnggDiffGSASFittingPresenter::collectAllInputParameters() const {
+  const auto runLabels = m_multiRunWidget->getAllRunLabels();
+  std::vector<GSASIIRefineFitPeaksParameters> inputParams;
+  std::vector<std::string> GSASIIProjectFiles;
+  inputParams.reserve(runLabels.size());
+  GSASIIProjectFiles.reserve(runLabels.size());
+
+  const auto refinementMethod = m_view->getRefinementMethod();
+  const auto instParamFile = m_view->getInstrumentFileName();
+  const auto phaseFiles = m_view->getPhaseFileNames();
+  const auto pathToGSASII = m_view->getPathToGSASII();
+  const auto GSASIIProjectFile = m_view->getGSASIIProjectPath();
+  if (runLabels.size() == 1) {
+    GSASIIProjectFiles = std::vector<std::string>({GSASIIProjectFile});
+  } else {
+    for (const auto &runLabel : runLabels) {
+      GSASIIProjectFiles.emplace_back(
+          addRunNumberToGSASIIProjectFile(GSASIIProjectFile, runLabel));
+    }
+  }
+
+  const auto dMin = m_view->getPawleyDMin();
+  const auto negativeWeight = m_view->getPawleyNegativeWeight();
+  const auto xMin = m_view->getXMin();
+  const auto xMax = m_view->getXMax();
+  const auto refineSigma = m_view->getRefineSigma();
+  const auto refineGamma = m_view->getRefineGamma();
+
+  for (size_t i = 0; i < runLabels.size(); i++) {
+    const auto &runLabel = runLabels[i];
+    const auto inputWS = *(m_multiRunWidget->getFocusedRun(runLabel));
+
+    inputParams.emplace_back(inputWS, runLabel, refinementMethod, instParamFile,
+                             phaseFiles, pathToGSASII, GSASIIProjectFiles[i],
+                             dMin, negativeWeight, xMin, xMax, refineSigma,
+                             refineGamma);
+  }
+  return inputParams;
+}
+
 GSASIIRefineFitPeaksParameters
 EnggDiffGSASFittingPresenter::collectInputParameters(
-    const RunLabel &runLabel, const Mantid::API::MatrixWorkspace_sptr inputWS,
-    const GSASRefinementMethod refinementMethod) const {
+    const RunLabel &runLabel,
+    const Mantid::API::MatrixWorkspace_sptr inputWS) const {
+  const auto refinementMethod = m_view->getRefinementMethod();
   const auto instParamFile = m_view->getInstrumentFileName();
   const auto phaseFiles = m_view->getPhaseFileNames();
   const auto pathToGSASII = m_view->getPathToGSASII();
@@ -89,16 +149,41 @@ void EnggDiffGSASFittingPresenter::displayFitResults(const RunLabel &runLabel) {
   m_view->displayGamma(*gamma);
 }
 
-Mantid::API::MatrixWorkspace_sptr
-EnggDiffGSASFittingPresenter::doPawleyRefinement(
-    const GSASIIRefineFitPeaksParameters &params) {
-  return m_model->doPawleyRefinement(params);
+void EnggDiffGSASFittingPresenter::doRefinements(
+    const std::vector<GSASIIRefineFitPeaksParameters> &params) {
+  m_model->doRefinements(params);
 }
 
-Mantid::API::MatrixWorkspace_sptr
-EnggDiffGSASFittingPresenter::doRietveldRefinement(
-    const GSASIIRefineFitPeaksParameters &params) {
-  return m_model->doRietveldRefinement(params);
+void EnggDiffGSASFittingPresenter::notifyRefinementsComplete() {
+  if (!m_viewHasClosed) {
+    m_view->setEnabled(true);
+    m_view->showStatus("Ready");
+  }
+}
+
+void EnggDiffGSASFittingPresenter::notifyRefinementCancelled() {
+  if (!m_viewHasClosed) {
+    m_view->setEnabled(true);
+    m_view->showStatus("Ready");
+  }
+}
+
+void EnggDiffGSASFittingPresenter::notifyRefinementFailed(
+    const std::string &failureMessage) {
+  if (!m_viewHasClosed) {
+    m_view->setEnabled(true);
+    m_view->userWarning("Refinement failed", failureMessage);
+    m_view->showStatus("Refinement failed");
+  }
+}
+
+void EnggDiffGSASFittingPresenter::notifyRefinementSuccessful(
+    const GSASIIRefineFitPeaksOutputProperties &refinementResults) {
+  if (!m_viewHasClosed) {
+    m_multiRunWidget->addFittedPeaks(refinementResults.runLabel,
+                                     refinementResults.fittedPeaksWS);
+    displayFitResults(refinementResults.runLabel);
+  }
 }
 
 void EnggDiffGSASFittingPresenter::processDoRefinement() {
@@ -121,31 +206,11 @@ void EnggDiffGSASFittingPresenter::processDoRefinement() {
   }
 
   m_view->showStatus("Refining run");
-  const auto refinementMethod = m_view->getRefinementMethod();
   const auto refinementParams =
-      collectInputParameters(*runLabel, *inputWSOptional, refinementMethod);
-
-  try {
-    Mantid::API::MatrixWorkspace_sptr fittedPeaks;
+      collectInputParameters(*runLabel, *inputWSOptional);
 
-    switch (refinementMethod) {
-
-    case GSASRefinementMethod::PAWLEY:
-      fittedPeaks = doPawleyRefinement(refinementParams);
-      break;
-
-    case GSASRefinementMethod::RIETVELD:
-      fittedPeaks = doRietveldRefinement(refinementParams);
-      break;
-    }
-
-    m_multiRunWidget->addFittedPeaks(*runLabel, fittedPeaks);
-    displayFitResults(*runLabel);
-  } catch (const std::exception &ex) {
-    m_view->showStatus("An error occurred in refinement");
-    m_view->userError("Refinement failed", ex.what());
-  }
-  m_view->showStatus("Ready");
+  m_view->setEnabled(false);
+  doRefinements({refinementParams});
 }
 
 void EnggDiffGSASFittingPresenter::processLoadRun() {
@@ -161,6 +226,18 @@ void EnggDiffGSASFittingPresenter::processLoadRun() {
   }
 }
 
+void EnggDiffGSASFittingPresenter::processRefineAll() {
+  const auto refinementParams = collectAllInputParameters();
+  if (refinementParams.size() == 0) {
+    m_view->userWarning("No runs loaded",
+                        "Please load at least one run before refining");
+    return;
+  }
+  m_view->showStatus("Refining run");
+  m_view->setEnabled(false);
+  doRefinements(refinementParams);
+}
+
 void EnggDiffGSASFittingPresenter::processSelectRun() {
   const auto runLabel = m_multiRunWidget->getSelectedRunLabel();
   if (runLabel && m_model->hasFitResultsForRun(*runLabel)) {
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.h
index 6e7198ed5ef15b15707b56016aa1f680c23f7568..0095215ca76e800ff3901101f70413a566864428 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingPresenter.h
@@ -2,6 +2,7 @@
 #define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFGSASFITTINGPRESENTER_H_
 
 #include "DllConfig.h"
+#include "GSASIIRefineFitPeaksOutputProperties.h"
 #include "IEnggDiffGSASFittingModel.h"
 #include "IEnggDiffGSASFittingPresenter.h"
 #include "IEnggDiffGSASFittingView.h"
@@ -35,35 +36,37 @@ public:
 
   void notify(IEnggDiffGSASFittingPresenter::Notification notif) override;
 
+  void notifyRefinementsComplete() override;
+
+  void notifyRefinementSuccessful(
+      const GSASIIRefineFitPeaksOutputProperties &refinementResults) override;
+
+  void notifyRefinementFailed(const std::string &failureMessage) override;
+
+  void notifyRefinementCancelled() override;
+
 private:
   void processDoRefinement();
   void processLoadRun();
+  void processRefineAll();
   void processSelectRun();
   void processShutDown();
   void processStart();
 
+  /// Collect GSASIIRefineFitPeaks parameters for all runs loaded in
+  std::vector<GSASIIRefineFitPeaksParameters> collectAllInputParameters() const;
+
   /// Collect GSASIIRefineFitPeaks input parameters for a given run from the
   /// presenter's various children
   GSASIIRefineFitPeaksParameters
   collectInputParameters(const RunLabel &runLabel,
-                         const Mantid::API::MatrixWorkspace_sptr ws,
-                         const GSASRefinementMethod refinementMethod) const;
-
-  /**
-   Perform a Pawley refinement on a run
-   @param params Input parameters for GSASIIRefineFitPeaks
-   @return Fitted peaks workspace resulting from refinement
-   */
-  Mantid::API::MatrixWorkspace_sptr
-  doPawleyRefinement(const GSASIIRefineFitPeaksParameters &params);
+                         const Mantid::API::MatrixWorkspace_sptr ws) const;
 
   /**
-   Perform a Rietveld refinement on a run
-   @param params Input parameters for GSASIIRefineFitPeaks
-   @return Fitted peaks workspace resulting from refinement
+   Perform refinements on a number of runs
+   @param params Input parameters for each run to pass to GSASIIRefineFitPeaks
    */
-  Mantid::API::MatrixWorkspace_sptr
-  doRietveldRefinement(const GSASIIRefineFitPeaksParameters &params);
+  void doRefinements(const std::vector<GSASIIRefineFitPeaksParameters> &params);
 
   /**
    Overplot fitted peaks for a run, and display lattice parameters and Rwp in
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.cpp
index 17f305f25a6d431712b1bef805fbed339efde27c..5012d4cdc0ee54ed179976dd71151b5d5a8907f8 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.cpp
@@ -35,8 +35,10 @@ EnggDiffGSASFittingViewQtWidget::EnggDiffGSASFittingViewQtWidget(
   setupUI();
 
   auto model = Mantid::Kernel::make_unique<EnggDiffGSASFittingModel>();
-  m_presenter = Mantid::Kernel::make_unique<EnggDiffGSASFittingPresenter>(
+  auto *model_ptr = model.get();
+  m_presenter = boost::make_shared<EnggDiffGSASFittingPresenter>(
       std::move(model), this, multiRunWidgetPresenter);
+  model_ptr->setObserver(m_presenter);
   m_presenter->notify(IEnggDiffGSASFittingPresenter::Start);
 }
 
@@ -259,6 +261,10 @@ void EnggDiffGSASFittingViewQtWidget::loadFocusedRun() {
   m_presenter->notify(IEnggDiffGSASFittingPresenter::LoadRun);
 }
 
+void EnggDiffGSASFittingViewQtWidget::refineAll() {
+  m_presenter->notify(IEnggDiffGSASFittingPresenter::RefineAll);
+}
+
 bool EnggDiffGSASFittingViewQtWidget::runFileLineEditEmpty() const {
   return m_ui.lineEdit_runFile->text().isEmpty();
 }
@@ -288,6 +294,17 @@ void EnggDiffGSASFittingViewQtWidget::setEnabled(const bool enabled) {
 
   m_ui.lineEdit_pawleyDMin->setEnabled(enabled);
   m_ui.lineEdit_pawleyNegativeWeight->setEnabled(enabled);
+
+  m_ui.lineEdit_xMin->setEnabled(enabled);
+  m_ui.lineEdit_xMax->setEnabled(enabled);
+
+  m_ui.checkBox_refineSigma->setEnabled(enabled);
+  m_ui.checkBox_refineGamma->setEnabled(enabled);
+
+  m_ui.pushButton_doRefinement->setEnabled(enabled);
+  m_ui.pushButton_refineAll->setEnabled(enabled);
+
+  m_multiRunWidgetView->setEnabled(enabled);
 }
 
 void EnggDiffGSASFittingViewQtWidget::setFocusedRunFileNames(
@@ -327,6 +344,8 @@ void EnggDiffGSASFittingViewQtWidget::setupUI() {
 
   connect(m_ui.pushButton_doRefinement, SIGNAL(clicked()), this,
           SLOT(doRefinement()));
+  connect(m_ui.pushButton_refineAll, SIGNAL(clicked()), this,
+          SLOT(refineAll()));
 
   connect(m_multiRunWidgetView.get(), SIGNAL(runSelected()), this,
           SLOT(selectRun()));
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.h
index fb35a097914e941615602d7df19d85ea122a20f3..7dbcd2075119745d993465bacd9bc8061e20cc49 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingViewQtWidget.h
@@ -8,6 +8,7 @@
 #include "IEnggDiffractionPythonRunner.h"
 #include "IEnggDiffractionUserMsg.h"
 
+#include <boost/shared_ptr.hpp>
 #include <qwt_plot_curve.h>
 #include <qwt_plot_zoomer.h>
 
@@ -63,7 +64,7 @@ public:
 
   boost::optional<double> getXMin() const override;
 
-  void setEnabled(const bool enabled);
+  void setEnabled(const bool enabled) override;
 
   void showStatus(const std::string &status) const override;
 
@@ -82,6 +83,7 @@ private slots:
   void disableLoadIfInputEmpty();
   void doRefinement();
   void loadFocusedRun();
+  void refineAll();
   void selectRun();
 
 private:
@@ -94,7 +96,7 @@ private:
 
   boost::shared_ptr<EnggDiffMultiRunFittingQtWidget> m_multiRunWidgetView;
 
-  std::unique_ptr<IEnggDiffGSASFittingPresenter> m_presenter;
+  boost::shared_ptr<IEnggDiffGSASFittingPresenter> m_presenter;
 
   Ui::EnggDiffractionQtTabGSAS m_ui;
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a62681566f849282d48fcc5ece831621d1de1be6
--- /dev/null
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.cpp
@@ -0,0 +1,32 @@
+#include "EnggDiffGSASFittingWorker.h"
+#include "EnggDiffGSASFittingModel.h"
+
+#include "MantidAPI/Algorithm.h"
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+EnggDiffGSASFittingWorker::EnggDiffGSASFittingWorker(
+    EnggDiffGSASFittingModel *model,
+    const std::vector<GSASIIRefineFitPeaksParameters> &params)
+    : m_model(model), m_refinementParams(params) {}
+
+void EnggDiffGSASFittingWorker::doRefinements() {
+  try {
+    qRegisterMetaType<
+        MantidQt::CustomInterfaces::GSASIIRefineFitPeaksOutputProperties>(
+        "GSASIIRefineFitPeaksOutputProperties");
+    for (const auto params : m_refinementParams) {
+      const auto fitResults = m_model->doGSASRefinementAlgorithm(params);
+      emit refinementSuccessful(fitResults);
+    }
+    emit refinementsComplete();
+  } catch (const Mantid::API::Algorithm::CancelException &) {
+    emit refinementCancelled();
+  } catch (const std::exception &e) {
+    emit refinementFailed(e.what());
+  }
+}
+
+} // CustomInterfaces
+} // MantidQt
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.h
new file mode 100644
index 0000000000000000000000000000000000000000..2933abca4d2b8fb87ec50aab537c6caef5bf5b71
--- /dev/null
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffGSASFittingWorker.h
@@ -0,0 +1,47 @@
+#ifndef MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFGSASFITTINGWORKER_H_
+#define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFGSASFITTINGWORKER_H_
+
+#include "GSASIIRefineFitPeaksOutputProperties.h"
+#include "GSASIIRefineFitPeaksParameters.h"
+
+#include <QObject>
+
+/**
+Worker for long-running tasks (ie GSASIIRefineFitPeaks) in the GSAS tab of the
+Engineering Diffraction GUI. Emits finished() signal when refinement is complete
+*/
+namespace MantidQt {
+namespace CustomInterfaces {
+
+class EnggDiffGSASFittingModel;
+
+class EnggDiffGSASFittingWorker : public QObject {
+  Q_OBJECT
+
+public:
+  EnggDiffGSASFittingWorker(
+      EnggDiffGSASFittingModel *model,
+      const std::vector<GSASIIRefineFitPeaksParameters> &params);
+
+public slots:
+  void doRefinements();
+
+signals:
+  void refinementsComplete();
+
+  void refinementSuccessful(GSASIIRefineFitPeaksOutputProperties);
+
+  void refinementFailed(std::string);
+
+  void refinementCancelled();
+
+private:
+  EnggDiffGSASFittingModel *m_model;
+
+  const std::vector<GSASIIRefineFitPeaksParameters> m_refinementParams;
+};
+
+} // namespace CustomInterfaces
+} // namespace MantidQt
+
+#endif // MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_ENGGDIFFGSASFITTINGWORKER_H_
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.cpp
index bae775c09683edac9d933abbbcfca03d1a8d0f4b..274bc88d40d03604246490bc308b8c3a1693b135 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.cpp
@@ -2,6 +2,22 @@
 
 #include "MantidKernel/make_unique.h"
 
+namespace {
+
+MantidQt::CustomInterfaces::RunLabel
+parseListWidgetItem(const QString &listWidgetItem) {
+  const auto pieces = listWidgetItem.split("_");
+  if (pieces.size() != 2) {
+    throw std::runtime_error(
+        "Unexpected run label: \"" + listWidgetItem.toStdString() +
+        "\". Please contact the development team with this message");
+  }
+  return MantidQt::CustomInterfaces::RunLabel(pieces[0].toInt(),
+                                              pieces[1].toUInt());
+}
+
+} // anonymous namespace
+
 namespace MantidQt {
 namespace CustomInterfaces {
 
@@ -33,17 +49,22 @@ void EnggDiffMultiRunFittingQtWidget::cleanUpPlot() {
   m_fittedPeaksCurves.clear();
 }
 
+std::vector<RunLabel> EnggDiffMultiRunFittingQtWidget::getAllRunLabels() const {
+  std::vector<RunLabel> runLabels;
+  runLabels.reserve(m_ui.listWidget_runLabels->count());
+
+  for (int i = 0; i < m_ui.listWidget_runLabels->count(); i++) {
+    const auto currentLabel = m_ui.listWidget_runLabels->item(i)->text();
+    runLabels.emplace_back(parseListWidgetItem(currentLabel));
+  }
+  return runLabels;
+}
+
 boost::optional<RunLabel>
 EnggDiffMultiRunFittingQtWidget::getSelectedRunLabel() const {
   if (hasSelectedRunLabel()) {
     const auto currentLabel = m_ui.listWidget_runLabels->currentItem()->text();
-    const auto pieces = currentLabel.split("_");
-    if (pieces.size() != 2) {
-      throw std::runtime_error(
-          "Unexpected run label: \"" + currentLabel.toStdString() +
-          "\". Please contact the development team with this message");
-    }
-    return RunLabel(pieces[0].toInt(), pieces[1].toUInt());
+    return parseListWidgetItem(currentLabel);
   } else {
     return boost::none;
   }
@@ -174,6 +195,14 @@ void EnggDiffMultiRunFittingQtWidget::resetPlotZoomLevel() {
   m_zoomTool->setZoomBase(true);
 }
 
+void EnggDiffMultiRunFittingQtWidget::setEnabled(const bool enabled) {
+  m_ui.listWidget_runLabels->setEnabled(enabled);
+  m_ui.pushButton_removeRun->setEnabled(enabled);
+  m_ui.pushButton_plotToSeparateWindow->setEnabled(enabled);
+  m_ui.checkBox_plotFittedPeaks->setEnabled(enabled);
+  m_zoomTool->setEnabled(enabled);
+}
+
 void EnggDiffMultiRunFittingQtWidget::setMessageProvider(
     boost::shared_ptr<IEnggDiffractionUserMsg> messageProvider) {
   m_userMessageProvider = messageProvider;
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.h
index dd2a830b1fa06dbabd9f25cddd8d542282ef02d5..01f7efac8ad83aa04a179bad1bf65298807587d6 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingQtWidget.h
@@ -26,6 +26,8 @@ public:
 
   ~EnggDiffMultiRunFittingQtWidget() override;
 
+  std::vector<RunLabel> getAllRunLabels() const override;
+
   boost::optional<RunLabel> getSelectedRunLabel() const override;
 
   void plotFittedPeaks(
@@ -46,6 +48,8 @@ public:
 
   void resetCanvas() override;
 
+  void setEnabled(const bool enabled) override;
+
   void setMessageProvider(
       boost::shared_ptr<IEnggDiffractionUserMsg> messageProvider) override;
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.cpp b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.cpp
index 6f9a5b7b84943d0e4d31ee50f0b5f937dfde0e13..dd335f4f8de6c92ae92838584fd5eb521faac255 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.cpp
@@ -92,6 +92,11 @@ void EnggDiffMultiRunFittingWidgetPresenter::displayFitResults(
   }
 }
 
+std::vector<RunLabel>
+EnggDiffMultiRunFittingWidgetPresenter::getAllRunLabels() const {
+  return m_view->getAllRunLabels();
+}
+
 std::unique_ptr<IEnggDiffMultiRunFittingWidgetAdder>
 EnggDiffMultiRunFittingWidgetPresenter::getWidgetAdder() const {
   return Mantid::Kernel::make_unique<EnggDiffMultiRunFittingWidgetAdder>(
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.h b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.h
index cbd8f426cf19e94d09021ef6d4bbac4131f4ff59..fc778f753255a8109eb68cec38c3373762a8e7fd 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffMultiRunFittingWidgetPresenter.h
@@ -30,6 +30,8 @@ public:
   boost::optional<Mantid::API::MatrixWorkspace_sptr>
   getFocusedRun(const RunLabel &runLabel) const override;
 
+  std::vector<RunLabel> getAllRunLabels() const override;
+
   boost::optional<RunLabel> getSelectedRunLabel() const override;
 
   std::unique_ptr<IEnggDiffMultiRunFittingWidgetAdder>
diff --git a/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabGSAS.ui b/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabGSAS.ui
index f4af2189b8050a3e1971df5f735a91d8b9de1c13..7bdd172d33347e14e16f78231a9da87ca0da8b49 100644
--- a/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabGSAS.ui
+++ b/qt/scientific_interfaces/EnggDiffraction/EnggDiffractionQtTabGSAS.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>553</width>
+    <width>560</width>
     <height>658</height>
    </rect>
   </property>
@@ -35,6 +35,13 @@
       <item row="1" column="1">
        <widget class="QLineEdit" name="lineEdit_instParamsFile"/>
       </item>
+      <item row="4" column="2">
+       <widget class="QPushButton" name="pushButton_browseGSASHome">
+        <property name="text">
+         <string>Browse</string>
+        </property>
+       </widget>
+      </item>
       <item row="1" column="0">
        <widget class="QLabel" name="label_instParamsFile">
         <property name="toolTip">
@@ -110,7 +117,7 @@
       <item row="3" column="0">
        <widget class="QLabel" name="label_gsasProjPath">
         <property name="toolTip">
-         <string>The name of a new *.gpx project to write refinement results out to. This can be opened and used for more complex refinements in GSAS-II</string>
+         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The name of a new *.gpx project to write refinement results out to. This can be opened and used for more complex refinements in GSAS-II.&lt;/p&gt;&lt;p&gt;Note, if refining more than one run, the run number and bank ID will be appended to this&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
         <property name="text">
          <string>New GSAS-II Project</string>
@@ -146,27 +153,27 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="2">
-       <widget class="QPushButton" name="pushButton_browseGSASHome">
+      <item row="5" column="0">
+       <widget class="QLabel" name="label_refinementMethod">
+        <property name="toolTip">
+         <string>Rietveld or Pawley</string>
+        </property>
         <property name="text">
-         <string>Browse</string>
+         <string>Refinement Method</string>
         </property>
        </widget>
       </item>
-      <item row="5" column="3">
+      <item row="5" column="2">
        <widget class="QPushButton" name="pushButton_doRefinement">
         <property name="text">
          <string>Run Refinement</string>
         </property>
        </widget>
       </item>
-      <item row="5" column="0">
-       <widget class="QLabel" name="label_refinementMethod">
-        <property name="toolTip">
-         <string>Rietveld or Pawley</string>
-        </property>
+      <item row="5" column="3">
+       <widget class="QPushButton" name="pushButton_refineAll">
         <property name="text">
-         <string>Refinement Method</string>
+         <string>Refine All</string>
         </property>
        </widget>
       </item>
diff --git a/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.cpp b/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.cpp
index 71a60c2d4ba44cf91e11dd66ab312b5c4fdc1738..981727e9b1b74060de63ddffbc33ec68d37d5938 100644
--- a/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.cpp
+++ b/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.cpp
@@ -4,12 +4,19 @@ namespace MantidQt {
 namespace CustomInterfaces {
 
 GSASIIRefineFitPeaksOutputProperties::GSASIIRefineFitPeaksOutputProperties(
-    const double _rwp, const double _sigma, const double _gamma)
-    : rwp(_rwp), sigma(_sigma), gamma(_gamma) {}
+    const double _rwp, const double _sigma, const double _gamma,
+    const Mantid::API::MatrixWorkspace_sptr _fittedPeaksWS,
+    const Mantid::API::ITableWorkspace_sptr _latticeParamsWS,
+    const RunLabel &_runLabel)
+    : rwp(_rwp), sigma(_sigma), gamma(_gamma), fittedPeaksWS(_fittedPeaksWS),
+      latticeParamsWS(_latticeParamsWS), runLabel(_runLabel) {}
 
 bool operator==(const GSASIIRefineFitPeaksOutputProperties &lhs,
                 const GSASIIRefineFitPeaksOutputProperties &rhs) {
-  return lhs.rwp == rhs.rwp && lhs.sigma == rhs.sigma && lhs.gamma == rhs.gamma;
+  return lhs.rwp == rhs.rwp && lhs.sigma == rhs.sigma &&
+         lhs.gamma == rhs.gamma && lhs.fittedPeaksWS == rhs.fittedPeaksWS &&
+         lhs.latticeParamsWS == rhs.latticeParamsWS &&
+         lhs.runLabel == rhs.runLabel;
 }
 
 bool operator!=(const GSASIIRefineFitPeaksOutputProperties &lhs,
diff --git a/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.h b/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.h
index 3c692c460eb8e957780f34bf204c7ae5c1da69c9..0e5dec8b810f9c28d0dbd1e8e5225dbdc2b927a7 100644
--- a/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.h
+++ b/qt/scientific_interfaces/EnggDiffraction/GSASIIRefineFitPeaksOutputProperties.h
@@ -2,17 +2,31 @@
 #define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASIIREFINEFITPEAKSOUTPUTPROPERTIES_H_
 
 #include "DllConfig.h"
+#include "RunLabel.h"
+
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+
+#include <QMetaType>
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
 struct MANTIDQT_ENGGDIFFRACTION_DLL GSASIIRefineFitPeaksOutputProperties {
-  GSASIIRefineFitPeaksOutputProperties(const double _rwp, const double _sigma,
-                                       const double _gamma);
-
-  const double rwp;
-  const double sigma;
-  const double gamma;
+  GSASIIRefineFitPeaksOutputProperties(
+      const double _rwp, const double _sigma, const double _gamma,
+      const Mantid::API::MatrixWorkspace_sptr _fittedPeaksWS,
+      const Mantid::API::ITableWorkspace_sptr _latticeParamsWS,
+      const RunLabel &_runLabel);
+
+  GSASIIRefineFitPeaksOutputProperties() = default;
+
+  double rwp;
+  double sigma;
+  double gamma;
+  Mantid::API::MatrixWorkspace_sptr fittedPeaksWS;
+  Mantid::API::ITableWorkspace_sptr latticeParamsWS;
+  RunLabel runLabel;
 };
 
 MANTIDQT_ENGGDIFFRACTION_DLL bool
@@ -26,4 +40,7 @@ operator!=(const GSASIIRefineFitPeaksOutputProperties &lhs,
 } // MantidQt
 } // CustomInterfaces
 
+Q_DECLARE_METATYPE(
+    MantidQt::CustomInterfaces::GSASIIRefineFitPeaksOutputProperties)
+
 #endif // MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASIIREFINEFITPEAKSOUTPUTPROPERTIES_H_
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
index b10bed9363f0676c9a9e3d5140b50605a98f4c6c..c23b846c24fa136e4d0f69921329cb31083dbb44 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffFittingPresenter.h
@@ -37,8 +37,6 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class IEnggDiffFittingPresenter {
 
 public:
-  virtual ~IEnggDiffFittingPresenter() = default;
-
   /// These are user actions, triggered from the (passive) view, that need
   /// handling by the presenter
   enum Notification {
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingModel.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingModel.h
index 8ae0e56fe649e52841b5f1360bafa5ed31423d83..f117389711729be178750b93714c4b9d5ca3f907 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingModel.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingModel.h
@@ -2,13 +2,14 @@
 #define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_IENGGDIFFGSASFITTINGMODEL_H_
 
 #include "GSASIIRefineFitPeaksParameters.h"
+#include "IEnggDiffGSASFittingObserver.h"
 #include "RunLabel.h"
 
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 
 #include <boost/optional.hpp>
-
+#include <boost/shared_ptr.hpp>
 #include <string>
 #include <utility>
 #include <vector>
@@ -22,22 +23,11 @@ public:
   virtual ~IEnggDiffGSASFittingModel() = default;
 
   /**
-   Perform a Pawley refinement on a run
-   @param params Parameters to be passed to GSASIIRefineFitPeaks
-   @return Fitted peaks workspace resulting from refinement
-   @throws If GSASIIRefineFitPeaks throws
+   Perform refinements on a number of runs
+   @param params Parameters for each run to be passed to GSASIIRefineFitPeaks
    */
-  virtual Mantid::API::MatrixWorkspace_sptr
-  doPawleyRefinement(const GSASIIRefineFitPeaksParameters &params) = 0;
-
-  /**
-   Perform a Rietveld refinement on a run
-   @param params Parameters to be passed to GSASIIRefineFitPeaks
-   @return Fitted peaks workspace resulting from refinement
-   @throws If GSASIIRefineFitPeaks throws
-   */
-  virtual Mantid::API::MatrixWorkspace_sptr
-  doRietveldRefinement(const GSASIIRefineFitPeaksParameters &params) = 0;
+  virtual void
+  doRefinements(const std::vector<GSASIIRefineFitPeaksParameters> &params) = 0;
 
   /**
    Get refined lattice parameters for a run
@@ -76,6 +66,10 @@ public:
    */
   virtual Mantid::API::MatrixWorkspace_sptr
   loadFocusedRun(const std::string &filename) const = 0;
+
+  /// set the observer for refinement
+  virtual void
+  setObserver(boost::shared_ptr<IEnggDiffGSASFittingObserver> observer) = 0;
 };
 
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingObserver.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingObserver.h
new file mode 100644
index 0000000000000000000000000000000000000000..04967bf4f68ed6120839d753996b17fa57e73ae3
--- /dev/null
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingObserver.h
@@ -0,0 +1,31 @@
+#ifndef MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASFITTINGOBSERVER_H_
+#define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASFITTINGOBSERVER_H_
+
+#include "GSASIIRefineFitPeaksOutputProperties.h"
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+class IEnggDiffGSASFittingObserver {
+
+public:
+  virtual ~IEnggDiffGSASFittingObserver() = default;
+
+  /// Notify the observer that all refinements have terminated successfully
+  virtual void notifyRefinementsComplete() = 0;
+
+  /// Notify the observer that a single refinement has terminated successfully
+  virtual void notifyRefinementSuccessful(
+      const GSASIIRefineFitPeaksOutputProperties &refinementResults) = 0;
+
+  /// Notify the observer that a refinement has failed
+  virtual void notifyRefinementFailed(const std::string &failureMessage) = 0;
+
+  /// Notify the observer that a single refinement was cancelled
+  virtual void notifyRefinementCancelled() = 0;
+};
+
+} // CustomInterfaces
+} // MantidQt
+
+#endif // MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_GSASFITTINGOBSERVER_H_
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingPresenter.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingPresenter.h
index 441965d04fc2845c01b23ff2655fd6ac7ed2c5ef..6eeed33d2e3de06d7d1b86c9dfc14911770eff7b 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingPresenter.h
@@ -1,10 +1,12 @@
 #ifndef MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_IENGGDIFFGSASFITTINGPRESENTER_H_
 #define MANTIDQTCUSTOMINTERFACES_ENGGDIFFRACTION_IENGGDIFFGSASFITTINGPRESENTER_H_
 
+#include "IEnggDiffGSASFittingObserver.h"
+
 namespace MantidQt {
 namespace CustomInterfaces {
 
-class IEnggDiffGSASFittingPresenter {
+class IEnggDiffGSASFittingPresenter : public IEnggDiffGSASFittingObserver {
 
 public:
   virtual ~IEnggDiffGSASFittingPresenter() = default;
@@ -14,6 +16,7 @@ public:
   enum Notification {
     DoRefinement, ///< Perform a GSAS refinement on a run
     LoadRun,      ///< Load a focused run
+    RefineAll,    ///< Do refinement on all runs loaded into the tab
     SelectRun,    ///< The user has selected a different run in the multi-run
                   /// widget
     ShutDown,     ///< Shut down the interface
@@ -28,6 +31,15 @@ public:
    * @param notif Type of notification to process.
    */
   virtual void notify(IEnggDiffGSASFittingPresenter::Notification notif) = 0;
+
+  void notifyRefinementsComplete() override = 0;
+
+  void notifyRefinementSuccessful(const GSASIIRefineFitPeaksOutputProperties &
+                                      refinementResults) override = 0;
+
+  void notifyRefinementFailed(const std::string &failureMessage) override = 0;
+
+  void notifyRefinementCancelled() override = 0;
 };
 
 } // namespace CustomInterfaces
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingView.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingView.h
index bd27f2828f1915285ece954e2a4070c81e047d3d..39ea836047970c0b708eee758c1ac2007f5063b5 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingView.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffGSASFittingView.h
@@ -103,6 +103,9 @@ public:
   /// Get XMin parameter, if it is set
   virtual boost::optional<double> getXMin() const = 0;
 
+  /// Enable or disable the GUI
+  virtual void setEnabled(const bool enabled) = 0;
+
   /// Update the view with current status
   virtual void showStatus(const std::string &status) const = 0;
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h
index 55657b8990bab2bad883577516a9408d06a0170c..03c3c3e8e2024dff5cac1b3f5f644abd0d214e98 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h
@@ -9,6 +9,7 @@ namespace CustomInterfaces {
 class IEnggDiffMultiRunFittingWidgetAdder {
 
 public:
+  virtual ~IEnggDiffMultiRunFittingWidgetAdder() = default;
   virtual void operator()(IEnggDiffMultiRunFittingWidgetOwner &owner) = 0;
 };
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetPresenter.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetPresenter.h
index ff65d489d084dc669d9bee51400f820c9ae35e66..d7a703ab2cf9728a172fd81c2e4d3d0104550ddf 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetPresenter.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetPresenter.h
@@ -58,6 +58,9 @@ public:
   virtual boost::optional<Mantid::API::MatrixWorkspace_sptr>
   getFocusedRun(const RunLabel &runLabel) const = 0;
 
+  /// Get RunLabels for all runs loaded into the tab
+  virtual std::vector<RunLabel> getAllRunLabels() const = 0;
+
   /// Get run number and bank ID of the run currently selected in the list
   virtual boost::optional<RunLabel> getSelectedRunLabel() const = 0;
 
diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetView.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetView.h
index a1eb4e0bc6ddd7115fd585d2ca3c6be55b1b8567..f3f4a460b21703c1727855deb892250bd39a7f55 100644
--- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetView.h
+++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetView.h
@@ -19,6 +19,9 @@ class IEnggDiffMultiRunFittingWidgetView {
 public:
   virtual ~IEnggDiffMultiRunFittingWidgetView() = default;
 
+  /// Get RunLabels of all runs loaded into the widget
+  virtual std::vector<RunLabel> getAllRunLabels() const = 0;
+
   /// Get run number and bank ID of the run currently selected in the list
   virtual boost::optional<RunLabel> getSelectedRunLabel() const = 0;
 
@@ -56,6 +59,9 @@ public:
   /// Clear the plot area to avoid overplotting
   virtual void resetCanvas() = 0;
 
+  /// Enable/disable the widget
+  virtual void setEnabled(const bool enabled) = 0;
+
   /// Connect a message provider to the view.  Used to remove circular
   /// dependency between view and presenter
   virtual void setMessageProvider(
diff --git a/qt/scientific_interfaces/EnggDiffraction/RunLabel.h b/qt/scientific_interfaces/EnggDiffraction/RunLabel.h
index 9bfe8d22c646a9af9429ce1a481bc4e453840780..8af126e2225f16da7d375beaf758a9700aacd6ac 100644
--- a/qt/scientific_interfaces/EnggDiffraction/RunLabel.h
+++ b/qt/scientific_interfaces/EnggDiffraction/RunLabel.h
@@ -14,8 +14,10 @@ class MANTIDQT_ENGGDIFFRACTION_DLL RunLabel {
 public:
   RunLabel(const int runNumber, const size_t bank);
 
-  const int runNumber;
-  const std::size_t bank;
+  RunLabel() = default;
+
+  int runNumber;
+  std::size_t bank;
 };
 
 MANTIDQT_ENGGDIFFRACTION_DLL bool operator==(const RunLabel &lhs,
diff --git a/qt/scientific_interfaces/General/DataComparison.cpp b/qt/scientific_interfaces/General/DataComparison.cpp
index b080ceacf0dba5bdf30a37885d07ae71b8fb6619..9271231faac32c6158fda9d1371c58e360978893 100644
--- a/qt/scientific_interfaces/General/DataComparison.cpp
+++ b/qt/scientific_interfaces/General/DataComparison.cpp
@@ -108,7 +108,7 @@ void DataComparison::addData() {
   m_uiForm.twCurrentData->blockSignals(true);
 
   // If this is a WorkspaceGroup then add all items
-  if (wsGroup != NULL) {
+  if (wsGroup != nullptr) {
     size_t numWs = wsGroup->size();
     for (size_t wsIdx = 0; wsIdx < numWs; wsIdx++) {
       addDataItem(wsGroup->getItem(wsIdx));
@@ -278,7 +278,7 @@ void DataComparison::removeSelectedData() {
 
     // Detach the old curve from the plot if it exists
     if (m_curves.contains(workspaceName))
-      m_curves[workspaceName]->attach(NULL);
+      m_curves[workspaceName]->attach(nullptr);
 
     selectedItems = m_uiForm.twCurrentData->selectedItems();
   }
@@ -304,7 +304,7 @@ void DataComparison::removeAllData() {
 
     // Detach the old curve from the plot if it exists
     if (m_curves.contains(workspaceName))
-      m_curves[workspaceName]->attach(NULL);
+      m_curves[workspaceName]->attach(nullptr);
   }
 
   // Replot the workspaces
@@ -353,7 +353,7 @@ void DataComparison::plotWorkspaces() {
 
       // Detech the curve from the plot
       if (m_curves.contains(workspaceName))
-        m_curves[workspaceName]->attach(NULL);
+        m_curves[workspaceName]->attach(nullptr);
 
       continue;
     }
@@ -369,7 +369,7 @@ void DataComparison::plotWorkspaces() {
 
     // Detach the old curve from the plot if it exists
     if (m_curves.contains(workspaceName))
-      m_curves[workspaceName]->attach(NULL);
+      m_curves[workspaceName]->attach(nullptr);
 
     QComboBox *colourSelector = dynamic_cast<QComboBox *>(
         m_uiForm.twCurrentData->cellWidget(row, COLOUR));
@@ -452,8 +452,8 @@ void DataComparison::workspaceIndexChanged() {
  */
 void DataComparison::plotDiffWorkspace() {
   // Detach old curve
-  if (m_diffCurve != NULL)
-    m_diffCurve->attach(NULL);
+  if (m_diffCurve != nullptr)
+    m_diffCurve->attach(nullptr);
 
   // Do nothing if there are not two workspaces
   if (m_diffWorkspaceNames.first.isEmpty() ||
@@ -682,7 +682,7 @@ void DataComparison::preDeleteHandle(
 
   // Detach the old curve from the plot if it exists
   if (m_curves.contains(oldWsName))
-    m_curves[oldWsName]->attach(NULL);
+    m_curves[oldWsName]->attach(nullptr);
 
   // Update the plot
   plotWorkspaces();
@@ -713,7 +713,7 @@ void DataComparison::renameHandle(const std::string &oldName,
 
   // Detach the old curve from the plot if it exists
   if (m_curves.contains(oldWsName))
-    m_curves[oldWsName]->attach(NULL);
+    m_curves[oldWsName]->attach(nullptr);
 
   // Update the plot
   plotWorkspaces();
diff --git a/qt/scientific_interfaces/General/MantidEV.cpp b/qt/scientific_interfaces/General/MantidEV.cpp
index d79ca6bef1aa9663a775046a62b98db22e1de483..e1868996ae6170f5103695b3882a2bb92f3391d8 100644
--- a/qt/scientific_interfaces/General/MantidEV.cpp
+++ b/qt/scientific_interfaces/General/MantidEV.cpp
@@ -495,7 +495,7 @@ void MantidEV::setDefaultState_slot() {
  */
 void MantidEV::help_slot() {
   MantidQt::API::HelpWindow::showCustomInterface(
-      NULL, QString("SCD Event Data Reduction"));
+      nullptr, QString("SCD Event Data Reduction"));
 }
 
 /**
diff --git a/qt/scientific_interfaces/General/StepScan.cpp b/qt/scientific_interfaces/General/StepScan.cpp
index f83ff8297d8155e0accd70ded8653babab8612dd..c91c0e63471e3ef2d7403d0a71d6bd0932b451e4 100644
--- a/qt/scientific_interfaces/General/StepScan.cpp
+++ b/qt/scientific_interfaces/General/StepScan.cpp
@@ -410,7 +410,7 @@ void StepScan::expandPlotVarCombobox(
     // Try to cast to an ITimeSeriesProperty
     auto tsp = dynamic_cast<const ITimeSeriesProperty *>(*log);
     // Move on to the next one if this is not a TSP
-    if (tsp == NULL)
+    if (tsp == nullptr)
       continue;
     // Don't keep ones with only one entry
     if (tsp->realSize() < 2)
diff --git a/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt b/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt
index c19ec5c7672d3fa9f5623d32a1612c43a7ceff4c..c7aa041b84bccb6eb027fceff8604e15c7c37f34 100644
--- a/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt
+++ b/qt/scientific_interfaces/ISISReflectometry/CMakeLists.txt
@@ -11,6 +11,8 @@ set ( SRC_FILES
     QtReflSettingsTabView.cpp
     QtReflSettingsView.cpp
     ReflCatalogSearcher.cpp
+    ReflAsciiSaver.cpp
+    IReflAsciiSaver.cpp
     ReflDataProcessorPresenter.cpp
     ReflEventPresenter.cpp
     ReflEventTabPresenter.cpp
@@ -57,7 +59,10 @@ set ( INC_FILES
     QtReflSaveTabView.h
     QtReflSettingsTabView.h
     QtReflSettingsView.h
+    QWidgetGroup.h
     ReflCatalogSearcher.h
+    ReflAsciiSaver.h
+    IReflAsciiSaver.h
     ReflDataProcessorMainPresenter.h
     ReflDataProcessorPresenter.h
     ReflEventPresenter.h
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.cpp b/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f427281db578de8cb1a7f5d5fd39659ceb342cd
--- /dev/null
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.cpp
@@ -0,0 +1,25 @@
+#include "IReflAsciiSaver.h"
+namespace MantidQt {
+namespace CustomInterfaces {
+InvalidSavePath::InvalidSavePath(std::string const &path)
+    : std::runtime_error("The path" + path +
+                         "does not exist or is not a directory."),
+      m_path(path) {}
+std::string const &InvalidSavePath::path() const { return m_path; }
+
+FileFormatOptions::FileFormatOptions(NamedFormat format,
+                                     std::string const &prefix,
+                                     bool includeTitle,
+                                     std::string const &separator,
+                                     bool includeQResolution)
+    : m_format(format), m_prefix(prefix), m_includeTitle(includeTitle),
+      m_separator(separator), m_includeQResolution(includeQResolution) {}
+bool FileFormatOptions::shouldIncludeTitle() const { return m_includeTitle; }
+bool FileFormatOptions::shouldIncludeQResolution() const {
+  return m_includeQResolution;
+}
+std::string const &FileFormatOptions::separator() const { return m_separator; }
+std::string const &FileFormatOptions::prefix() const { return m_prefix; }
+NamedFormat FileFormatOptions::format() const { return m_format; }
+}
+}
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.h b/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f11c3b35928e4517a6ab00617e4af3d9937be11
--- /dev/null
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflAsciiSaver.h
@@ -0,0 +1,51 @@
+#ifndef MANTID_ISISREFLECTOMETRY_IREFLASCIISAVER_H
+#define MANTID_ISISREFLECTOMETRY_IREFLASCIISAVER_H
+#include <vector>
+#include <string>
+#include "MantidAPI/IAlgorithm_fwd.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+namespace MantidQt {
+namespace CustomInterfaces {
+
+enum class NamedFormat { Custom, ThreeColumn, ANSTO, ILLCosmos };
+
+class FileFormatOptions {
+public:
+  FileFormatOptions(NamedFormat format, std::string const &prefix,
+                    bool includeTitle, std::string const &separator,
+                    bool includeQResolution);
+  bool shouldIncludeTitle() const;
+  bool shouldIncludeQResolution() const;
+  std::string const &separator() const;
+  std::string const &prefix() const;
+  NamedFormat format() const;
+
+private:
+  NamedFormat m_format;
+  std::string m_prefix;
+  bool m_includeTitle;
+  std::string m_separator;
+  bool m_includeQResolution;
+};
+
+class InvalidSavePath : public std::runtime_error {
+public:
+  explicit InvalidSavePath(std::string const &path);
+  std::string const &path() const;
+
+private:
+  std::string m_path;
+};
+
+class IReflAsciiSaver {
+public:
+  virtual bool isValidSaveDirectory(std::string const &filePath) const = 0;
+  virtual void save(std::string const &saveDirectory,
+                    std::vector<std::string> const &workspaceNames,
+                    std::vector<std::string> const &logParameters,
+                    FileFormatOptions const &inputParameters) const = 0;
+  virtual ~IReflAsciiSaver() = default;
+};
+}
+}
+#endif // MANTID_ISISREFLECTOMETRY_IREFLASCIISAVER_H
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflEventPresenter.h b/qt/scientific_interfaces/ISISReflectometry/IReflEventPresenter.h
index a2b5ed7d775ca9476e6eb8aa413136539e992b83..56a2f66fa2066e8fa7aacec9916d2edbf1368d46 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflEventPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflEventPresenter.h
@@ -34,6 +34,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 File change history is stored at: <https://github.com/mantidproject/mantid>.
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
+
+enum class SliceType { UniformEven, Uniform, Custom, LogValue };
+
 class IReflEventPresenter {
 public:
   virtual ~IReflEventPresenter(){};
@@ -45,6 +48,7 @@ public:
 
   virtual void onReductionPaused() = 0;
   virtual void onReductionResumed() = 0;
+  virtual void notifySliceTypeChanged(SliceType newSliceType) = 0;
 };
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflEventView.h b/qt/scientific_interfaces/ISISReflectometry/IReflEventView.h
index ce247af9d75a74e8acb1d68ad0705c5bd4d3c13e..8eeb886061df79d338f3b17913e8ae0c331de7f1 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflEventView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflEventView.h
@@ -3,12 +3,11 @@
 
 #include "DllConfig.h"
 #include <string>
+#include "IReflEventPresenter.h"
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
-class IReflEventPresenter;
-
 /** @class IReflEventView
 
 IReflEventView is the base view class for the Reflectometry "Event Handling"
@@ -39,21 +38,20 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 
 class DLLExport IReflEventView {
 public:
-  /// Constructor
   IReflEventView(){};
-  /// Destructor
   virtual ~IReflEventView(){};
-  /// Returns the presenter managing this view
   virtual IReflEventPresenter *getPresenter() const = 0;
 
-  /// Slice type enums
-  enum class SliceType { UniformEven, Uniform, Custom, LogValue };
-
-  virtual std::string getTimeSlicingValues() const = 0;
-  virtual std::string getTimeSlicingType() const = 0;
+  virtual std::string getLogValueTimeSlicingValues() const = 0;
+  virtual std::string getCustomTimeSlicingValues() const = 0;
+  virtual std::string getUniformTimeSlicingValues() const = 0;
+  virtual std::string getUniformEvenTimeSlicingValues() const = 0;
+  virtual std::string getLogValueTimeSlicingType() const = 0;
 
-  virtual void enableAll() = 0;
-  virtual void disableAll() = 0;
+  virtual void enableSliceType(SliceType sliceType) = 0;
+  virtual void disableSliceType(SliceType sliceType) = 0;
+  virtual void enableSliceTypeSelection() = 0;
+  virtual void disableSliceTypeSelection() = 0;
 };
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflMainWindowPresenter.h b/qt/scientific_interfaces/ISISReflectometry/IReflMainWindowPresenter.h
index 8594027f2dbccf47997c2521fbf2731a99e51322..3e42eff069c20c65fa4eceacf5d90a6762ee4e0b 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflMainWindowPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflMainWindowPresenter.h
@@ -2,6 +2,7 @@
 #define MANTID_ISISREFLECTOMETRY_IREFLMAINWINDOWPRESENTER_H
 
 #include "MantidQtWidgets/Common/DataProcessorUI/OptionsQMap.h"
+#include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
 
 #include <string>
 
@@ -49,6 +50,14 @@ public:
   virtual void notifyReductionPaused(int group) = 0;
   virtual void notifyReductionResumed(int group) = 0;
 
+  virtual void completedRowReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) = 0;
+
+  virtual void completedGroupReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) = 0;
+
   /// Transmission runs for a specific run angle
   virtual MantidWidgets::DataProcessor::OptionsQMap
   getOptionsForAngle(int group, const double angle) const = 0;
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabPresenter.h b/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabPresenter.h
index 88b851028eac9d0ce02371282c364805c9e6476e..6f23c0aba24f940210d56c782c00329a9244a3cb 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabPresenter.h
@@ -1,5 +1,6 @@
 #ifndef MANTID_ISISREFLECTOMETRY_IREFLSAVETABPRESENTER_H
 #define MANTID_ISISREFLECTOMETRY_IREFLSAVETABPRESENTER_H
+#include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
 
 namespace MantidQt {
 namespace CustomInterfaces {
@@ -43,9 +44,20 @@ public:
     filterWorkspaceListFlag,
     workspaceParamsFlag,
     saveWorkspacesFlag,
-    suggestSaveDirFlag
+    suggestSaveDirFlag,
+    autosaveEnabled,
+    autosaveDisabled,
+    savePathChanged
   };
 
+  virtual void completedGroupReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) = 0;
+
+  virtual void completedRowReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) = 0;
+
   /// Tell the presenter something happened
   virtual void notify(IReflSaveTabPresenter::Flag flag) = 0;
   virtual void onAnyReductionPaused() = 0;
diff --git a/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabView.h b/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabView.h
index 5eb8ff7bfaeb80485f9fa41f4c89e1638c31b002..3435d6a1694d051fe8912357f4535019c333e447 100644
--- a/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/IReflSaveTabView.h
@@ -38,14 +38,13 @@ File change history is stored at: <https://github.com/mantidproject/mantid>.
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 
-class DLLExport IReflSaveTabView {
+class MANTIDQT_ISISREFLECTOMETRY_DLL IReflSaveTabView {
 public:
   /// Constructor
   IReflSaveTabView(){};
   /// Destructor
   virtual ~IReflSaveTabView(){};
-  /// Returns the presenter managing this view
-  virtual IReflSaveTabPresenter *getPresenter() const = 0;
+  virtual void subscribe(IReflSaveTabPresenter *presenter) = 0;
 
   virtual std::string getSavePath() const = 0;
   virtual void setSavePath(const std::string &path) const = 0;
@@ -64,6 +63,17 @@ public:
   virtual void clearParametersList() const = 0;
   virtual void setWorkspaceList(const std::vector<std::string> &) const = 0;
   virtual void setParametersList(const std::vector<std::string> &) const = 0;
+  virtual void disallowAutosave() = 0;
+
+  virtual void disableAutosaveControls() = 0;
+  virtual void enableAutosaveControls() = 0;
+
+  virtual void enableFileFormatAndLocationControls() = 0;
+  virtual void disableFileFormatAndLocationControls() = 0;
+  virtual void giveUserCritical(const std::string &prompt,
+                                const std::string &title) = 0;
+  virtual void giveUserInfo(const std::string &prompt,
+                            const std::string &title) = 0;
 };
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h b/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h
index d526bf200c376b699c38b5b81c9a81c7ecdb2ede..a2c75848ce26a3ba4959feee7a86227376a9d3e3 100644
--- a/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h
+++ b/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h
@@ -33,7 +33,7 @@ namespace CustomInterfaces {
 class MANTIDQT_ISISREFLECTOMETRY_DLL MeasurementItem {
 
 public:
-  typedef std::string IDType;
+  using IDType = std::string;
 
   /// Constructor
   MeasurementItem(const IDType &measurementItemId, const IDType &subId,
diff --git a/qt/scientific_interfaces/ISISReflectometry/QWidgetGroup.h b/qt/scientific_interfaces/ISISReflectometry/QWidgetGroup.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ae1a81ee07ebabec6a78bd7c78bd52084593060
--- /dev/null
+++ b/qt/scientific_interfaces/ISISReflectometry/QWidgetGroup.h
@@ -0,0 +1,35 @@
+#ifndef MANTID_ISISREFLECTOMETRY_QWIDGETGROUP_H
+#define MANTID_ISISREFLECTOMETRY_QWIDGETGROUP_H
+#include <cstddef>
+#include <array>
+#include <QWidget>
+namespace MantidQt {
+namespace CustomInterfaces {
+template <std::size_t N> class QWidgetGroup {
+public:
+  QWidgetGroup() : m_widgets() {}
+  explicit QWidgetGroup(std::array<QWidget *, N> const &widgets)
+      : m_widgets(widgets) {}
+
+  void enable() {
+    for (auto *widget : m_widgets)
+      widget->setEnabled(true);
+  }
+
+  void disable() {
+    for (auto *widget : m_widgets)
+      widget->setEnabled(false);
+  }
+
+private:
+  std::array<QWidget *, N> m_widgets;
+};
+
+template <typename... Ts>
+QWidgetGroup<sizeof...(Ts)> makeQWidgetGroup(Ts... widgets) {
+  return QWidgetGroup<sizeof...(Ts)>(
+      std::array<QWidget *, sizeof...(Ts)>({{widgets...}}));
+}
+}
+}
+#endif // MANTID_ISISREFLECTOMETRY_QWIDGETGROUP_H
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.cpp b/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.cpp
index d18997387347c9da77bbb8f4424c1f807aaaf949..a99051a51d66776d096030174202f807f7f5953c 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.cpp
@@ -9,138 +9,142 @@ namespace CustomInterfaces {
 * @param parent :: [input] The parent of this widget
 */
 QtReflEventView::QtReflEventView(QWidget *parent) {
-
   UNUSED_ARG(parent);
   initLayout();
-
-  // Insert slice-type to string pairs
-  m_sliceTypeMap[SliceType::UniformEven] = "UniformEven";
-  m_sliceTypeMap[SliceType::Uniform] = "Uniform";
-  m_sliceTypeMap[SliceType::Custom] = "Custom";
-  m_sliceTypeMap[SliceType::LogValue] = "LogValue";
-
-  // Add slicing option buttons to list
-  m_buttonList.emplace_back(m_ui.uniformEvenButton);
-  m_buttonList.emplace_back(m_ui.uniformButton);
-  m_buttonList.emplace_back(m_ui.customButton);
-  m_buttonList.emplace_back(m_ui.logValueButton);
-
-  // Whenever one of the slicing option buttons is selected, their corresponding
-  // entry is enabled, otherwise they remain disabled.
-  for (auto &button : m_buttonList) {
-    connect(button, SIGNAL(toggled(bool)), this, SLOT(toggleSlicingOptions()));
-  }
-
-  toggleSlicingOptions(); // Run at least once
-
   m_presenter.reset(new ReflEventPresenter(this));
 }
 
-//----------------------------------------------------------------------------------------------
-/** Destructor
-*/
 QtReflEventView::~QtReflEventView() {}
 
-/**
-Initialise the Interface
-*/
-void QtReflEventView::initLayout() { m_ui.setupUi(this); }
+void QtReflEventView::initLayout() {
+  m_ui.setupUi(this);
+  initUniformSliceTypeLayout();
+  initUniformEvenSliceTypeLayout();
+  initLogValueSliceTypeLayout();
+  initCustomSliceTypeLayout();
+  m_sliceTypeRadioButtons =
+      makeQWidgetGroup(m_ui.uniformEvenButton, m_ui.uniformButton,
+                       m_ui.logValueButton, m_ui.customButton);
+}
 
-/** Returns the presenter managing this view
-* @return :: A pointer to the presenter
-*/
-IReflEventPresenter *QtReflEventView::getPresenter() const {
+void QtReflEventView::initUniformSliceTypeLayout() {
+  m_uniformGroup = makeQWidgetGroup(m_ui.uniformEdit, m_ui.uniformLabel);
+  connect(m_ui.uniformButton, SIGNAL(toggled(bool)), this,
+          SLOT(toggleUniform(bool)));
+}
 
-  return m_presenter.get();
+void QtReflEventView::initUniformEvenSliceTypeLayout() {
+  m_uniformEvenGroup =
+      makeQWidgetGroup(m_ui.uniformEvenEdit, m_ui.uniformEvenLabel);
+  connect(m_ui.uniformEvenButton, SIGNAL(toggled(bool)), this,
+          SLOT(toggleUniformEven(bool)));
 }
 
-void QtReflEventView::enableAll() {
-  m_ui.uniformEvenEdit->setEnabled(true);
-  m_ui.uniformEdit->setEnabled(true);
-  m_ui.logValueEdit->setEnabled(true);
-  m_ui.logValueTypeEdit->setEnabled(true);
-  for (auto *button : m_buttonList)
-    button->setEnabled(true);
+void QtReflEventView::initCustomSliceTypeLayout() {
+  m_customGroup = makeQWidgetGroup(m_ui.customEdit, m_ui.customLabel);
+  connect(m_ui.customButton, SIGNAL(toggled(bool)), this,
+          SLOT(toggleCustom(bool)));
 }
 
-void QtReflEventView::disableAll() {
-  m_ui.uniformEvenEdit->setEnabled(false);
-  m_ui.uniformEdit->setEnabled(false);
-  m_ui.logValueEdit->setEnabled(false);
-  m_ui.logValueTypeEdit->setEnabled(false);
-  for (auto *button : m_buttonList)
-    button->setEnabled(false);
+void QtReflEventView::initLogValueSliceTypeLayout() {
+  m_logValueGroup =
+      makeQWidgetGroup(m_ui.logValueTypeEdit, m_ui.logValueTypeLabel,
+                       m_ui.logValueEdit, m_ui.logValueLabel);
+  connect(m_ui.logValueButton, SIGNAL(toggled(bool)), this,
+          SLOT(toggleLogValue(bool)));
 }
 
-/** Returns the time slicing value(s) obtained from the selected widget
-* @return :: Time slicing values
+/** Returns the presenter managing this view
+* @return :: A pointer to the presenter
 */
-std::string QtReflEventView::getTimeSlicingValues() const {
-
-  std::string values;
+IReflEventPresenter *QtReflEventView::getPresenter() const {
+  return m_presenter.get();
+}
 
-  switch (m_sliceType) {
+void QtReflEventView::enableSliceType(SliceType sliceType) {
+  switch (sliceType) {
+  case SliceType::Uniform:
+    m_uniformGroup.enable();
+    break;
   case SliceType::UniformEven:
-    values = m_ui.uniformEvenEdit->text().toStdString();
+    m_uniformEvenGroup.enable();
+    break;
+  case SliceType::Custom:
+    m_customGroup.enable();
+    break;
+  case SliceType::LogValue:
+    m_logValueGroup.enable();
     break;
+  }
+}
+
+void QtReflEventView::disableSliceType(SliceType sliceType) {
+  switch (sliceType) {
   case SliceType::Uniform:
-    values = m_ui.uniformEdit->text().toStdString();
+    m_uniformGroup.disable();
+    break;
+  case SliceType::UniformEven:
+    m_uniformEvenGroup.disable();
     break;
   case SliceType::Custom:
-    values = m_ui.customEdit->text().toStdString();
+    m_customGroup.disable();
     break;
   case SliceType::LogValue:
-    std::string slicingValues = m_ui.logValueEdit->text().toStdString();
-    std::string logFilter = m_ui.logValueTypeEdit->text().toStdString();
-    if (!slicingValues.empty() && !logFilter.empty())
-      values = "Slicing=\"" + slicingValues + "\",LogFilter=" + logFilter;
+    m_logValueGroup.disable();
     break;
   }
+}
 
-  return values;
+std::string QtReflEventView::getLogValueTimeSlicingType() const {
+  return textFrom(m_ui.logValueTypeEdit);
 }
 
-/** Returns the type of time slicing that was selected as string
-* @return :: Time slicing type
-*/
-std::string QtReflEventView::getTimeSlicingType() const {
+std::string QtReflEventView::getLogValueTimeSlicingValues() const {
+  return textFrom(m_ui.logValueEdit);
+}
 
-  return m_sliceTypeMap.at(m_sliceType);
+std::string QtReflEventView::getCustomTimeSlicingValues() const {
+  return textFrom(m_ui.customEdit);
 }
 
-/** Enable slicing option entries for checked button and disable all others.
-*/
-void QtReflEventView::toggleSlicingOptions() const {
+std::string QtReflEventView::getUniformTimeSlicingValues() const {
+  return textFrom(m_ui.uniformEdit);
+}
+
+std::string QtReflEventView::getUniformEvenTimeSlicingValues() const {
+  return textFrom(m_ui.uniformEvenEdit);
+}
 
-  const auto checkedButton = m_ui.slicingOptionsButtonGroup->checkedButton();
+std::string QtReflEventView::textFrom(QLineEdit const *const widget) const {
+  return widget->text().toStdString();
+}
 
-  SliceType slicingTypes[4] = {SliceType::UniformEven, SliceType::Uniform,
-                               SliceType::Custom, SliceType::LogValue};
+void QtReflEventView::disableSliceTypeSelection() {
+  m_sliceTypeRadioButtons.disable();
+}
 
-  std::vector<bool> entriesEnabled(m_buttonList.size(), false);
-  for (size_t i = 0; i < m_buttonList.size(); i++) {
-    if (m_buttonList[i] == checkedButton) {
-      m_sliceType = slicingTypes[i];
-      entriesEnabled[i] = true;
-      break;
-    }
-  }
+void QtReflEventView::enableSliceTypeSelection() {
+  m_sliceTypeRadioButtons.enable();
+}
+
+void QtReflEventView::toggleUniform(bool isChecked) {
+  if (isChecked)
+    m_presenter->notifySliceTypeChanged(SliceType::Uniform);
+}
 
-  // UniformEven
-  m_ui.uniformEvenEdit->setEnabled(entriesEnabled[0]);
-  m_ui.uniformEvenLabel->setEnabled(entriesEnabled[0]);
-  // Uniform
-  m_ui.uniformEdit->setEnabled(entriesEnabled[1]);
-  m_ui.uniformLabel->setEnabled(entriesEnabled[1]);
-  // Custom
-  m_ui.customEdit->setEnabled(entriesEnabled[2]);
-  m_ui.customLabel->setEnabled(entriesEnabled[2]);
-  // LogValue
-  m_ui.logValueEdit->setEnabled(entriesEnabled[3]);
-  m_ui.logValueLabel->setEnabled(entriesEnabled[3]);
-  m_ui.logValueTypeEdit->setEnabled(entriesEnabled[3]);
-  m_ui.logValueTypeLabel->setEnabled(entriesEnabled[3]);
+void QtReflEventView::toggleUniformEven(bool isChecked) {
+  if (isChecked)
+    m_presenter->notifySliceTypeChanged(SliceType::UniformEven);
 }
 
+void QtReflEventView::toggleCustom(bool isChecked) {
+  if (isChecked)
+    m_presenter->notifySliceTypeChanged(SliceType::Custom);
+}
+
+void QtReflEventView::toggleLogValue(bool isChecked) {
+  if (isChecked)
+    m_presenter->notifySliceTypeChanged(SliceType::LogValue);
+}
 } // namespace CustomInterfaces
 } // namespace Mantid
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.h b/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.h
index c2a4f749da9734b97045f61ffa6444fa15564a9f..7e523961a0b013cf27ff5779613aa273a7953ee3 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflEventView.h
@@ -3,6 +3,7 @@
 
 #include "IReflEventView.h"
 #include "ui_ReflEventWidget.h"
+#include "QWidgetGroup.h"
 #include <memory>
 
 namespace MantidQt {
@@ -44,35 +45,44 @@ public:
   ~QtReflEventView() override;
   /// Returns the presenter managing this view
   IReflEventPresenter *getPresenter() const override;
-
   /// Returns time-slicing values
-  std::string getTimeSlicingValues() const override;
-  /// Returns time-slicing type
-  std::string getTimeSlicingType() const override;
+  void initUniformSliceTypeLayout();
+  void initUniformEvenSliceTypeLayout();
+  void initLogValueSliceTypeLayout();
+  void initCustomSliceTypeLayout();
+
+  void enableSliceType(SliceType sliceType) override;
+  void disableSliceType(SliceType sliceType) override;
+
+  void enableSliceTypeSelection() override;
+  void disableSliceTypeSelection() override;
 
-  void enableAll() override;
-  void disableAll() override;
+  std::string getLogValueTimeSlicingType() const override;
+  std::string getLogValueTimeSlicingValues() const override;
+  std::string getCustomTimeSlicingValues() const override;
+  std::string getUniformTimeSlicingValues() const override;
+  std::string getUniformEvenTimeSlicingValues() const override;
 
 public slots:
-  /// Enable / disable slicing option entry fields
-  void toggleSlicingOptions() const;
+  void toggleUniform(bool isChecked);
+  void toggleUniformEven(bool isChecked);
+  void toggleCustom(bool isChecked);
+  void toggleLogValue(bool isChecked);
 
 private:
   /// Initialise the interface
   void initLayout();
+  std::string textFrom(QLineEdit const *const widget) const;
+  QWidgetGroup<2> m_uniformGroup;
+  QWidgetGroup<2> m_uniformEvenGroup;
+  QWidgetGroup<4> m_logValueGroup;
+  QWidgetGroup<2> m_customGroup;
+  QWidgetGroup<4> m_sliceTypeRadioButtons;
 
   /// The widget
   Ui::ReflEventWidget m_ui;
   /// The presenter
   std::unique_ptr<IReflEventPresenter> m_presenter;
-
-  /// Current slice type
-  mutable SliceType m_sliceType;
-  /// Slice type to string conversion map
-  std::map<SliceType, std::string> m_sliceTypeMap;
-
-  /// List of radio buttons
-  std::vector<QRadioButton *> m_buttonList;
 };
 
 } // namespace Mantid
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.cpp b/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.cpp
index ee29e44a1c13a1c28e5bc4892342ac0be6b868ba..3ef0846c9094abe2de064bd43fd840ba6b4c0638 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.cpp
@@ -3,7 +3,10 @@
 #include "QtReflRunsTabView.h"
 #include "QtReflSaveTabView.h"
 #include "QtReflSettingsTabView.h"
+#include "ReflSaveTabPresenter.h"
 #include "ReflMainWindowPresenter.h"
+#include "ReflAsciiSaver.h"
+#include "MantidKernel/make_unique.h"
 
 #include <QMessageBox>
 
@@ -38,8 +41,9 @@ void QtReflMainWindowView::initLayout() {
   connect(m_ui.helpButton, SIGNAL(clicked()), this, SLOT(helpPressed()));
 
   // Create the presenter
-  m_presenter.reset(new ReflMainWindowPresenter(
-      this, runsPresenter, eventPresenter, settingsPresenter, savePresenter));
+  m_presenter = Mantid::Kernel::make_unique<ReflMainWindowPresenter>(
+      this, runsPresenter, eventPresenter, settingsPresenter,
+      std::move(savePresenter));
 }
 
 void QtReflMainWindowView::helpPressed() {
@@ -84,12 +88,13 @@ IReflSettingsTabPresenter *QtReflMainWindowView::createSettingsTab() {
 /** Creates the 'Save ASCII' tab and returns a pointer to its presenter
 * @return :: A pointer to the presenter managing the 'Save ASCII' tab
 */
-IReflSaveTabPresenter *QtReflMainWindowView::createSaveTab() {
+std::unique_ptr<IReflSaveTabPresenter> QtReflMainWindowView::createSaveTab() {
+  auto saveTabView = Mantid::Kernel::make_unique<QtReflSaveTabView>(this);
+  m_ui.mainTab->addTab(saveTabView.get(), QString("Save ASCII"));
 
-  QtReflSaveTabView *saveTab = new QtReflSaveTabView(this);
-  m_ui.mainTab->addTab(saveTab, QString("Save ASCII"));
-
-  return saveTab->getPresenter();
+  auto saver = Mantid::Kernel::make_unique<ReflAsciiSaver>();
+  return Mantid::Kernel::make_unique<ReflSaveTabPresenter>(
+      std::move(saver), std::move(saveTabView));
 }
 
 /**
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.h b/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.h
index 6cb5f70be8faa9205ce42622e159ed3632299e3f..b193895b9446255d481dcc8dd392309a221faa9b 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflMainWindowView.h
@@ -80,7 +80,7 @@ private:
   /// Creates the 'Settings' tab
   IReflSettingsTabPresenter *createSettingsTab();
   /// Creates the 'Save ASCII' tab
-  IReflSaveTabPresenter *createSaveTab();
+  std::unique_ptr<IReflSaveTabPresenter> createSaveTab();
 
   /// Interface definition with widgets for the main interface window
   Ui::RelMainWindowWidget m_ui;
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.cpp b/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.cpp
index 9d96d85b0169ceae1d6b7b49aef2238191343c5a..7cb6ab7fa7672b1f4940226dfd8bee684dafd502 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.cpp
@@ -2,6 +2,8 @@
 #include "ReflSaveTabPresenter.h"
 
 #include <boost/algorithm/string.hpp>
+#include <QMessageBox>
+#include <QFileDialog>
 
 namespace MantidQt {
 namespace CustomInterfaces {
@@ -9,12 +11,17 @@ namespace CustomInterfaces {
 /** Constructor
 * @param parent :: The parent of this view
 */
-QtReflSaveTabView::QtReflSaveTabView(QWidget *parent) : m_presenter() {
-
+QtReflSaveTabView::QtReflSaveTabView(QWidget *parent) : m_presenter(nullptr) {
   UNUSED_ARG(parent);
   initLayout();
 }
 
+void QtReflSaveTabView::subscribe(IReflSaveTabPresenter *presenter) {
+  m_presenter = presenter;
+  populateListOfWorkspaces();
+  suggestSaveDir();
+}
+
 /** Destructor
 */
 QtReflSaveTabView::~QtReflSaveTabView() {}
@@ -32,18 +39,50 @@ void QtReflSaveTabView::initLayout() {
           SLOT(filterWorkspaceList()));
   connect(m_ui.listOfWorkspaces, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
           this, SLOT(requestWorkspaceParams()));
+  connect(m_ui.saveReductionResultsCheckBox, SIGNAL(stateChanged(int)), this,
+          SLOT(onAutosaveChanged(int)));
+  connect(m_ui.savePathEdit, SIGNAL(editingFinished()), this,
+          SLOT(onSavePathChanged()));
+  connect(m_ui.savePathBrowseButton, SIGNAL(clicked()), this,
+          SLOT(browseToSaveDirectory()));
+}
 
-  m_presenter.reset(new ReflSaveTabPresenter(this));
-  populateListOfWorkspaces();
-  suggestSaveDir();
+void QtReflSaveTabView::browseToSaveDirectory() {
+  auto savePath = QFileDialog::getExistingDirectory(
+      this, "Select the directory to save to.");
+  if (!savePath.isEmpty()) {
+    m_ui.savePathEdit->setText(savePath);
+    onSavePathChanged();
+  }
 }
 
-/** Returns the presenter managing this view
-* @return :: A pointer to the presenter
-*/
-IReflSaveTabPresenter *QtReflSaveTabView::getPresenter() const {
+void QtReflSaveTabView::onSavePathChanged() {
+  m_presenter->notify(IReflSaveTabPresenter::Flag::savePathChanged);
+}
+
+void QtReflSaveTabView::onAutosaveChanged(int state) {
+  if (state == Qt::CheckState::Checked)
+    m_presenter->notify(IReflSaveTabPresenter::Flag::autosaveEnabled);
+  else
+    m_presenter->notify(IReflSaveTabPresenter::Flag::autosaveDisabled);
+}
+
+void QtReflSaveTabView::disableAutosaveControls() {
+  m_ui.autosaveGroup->setEnabled(false);
+}
+
+void QtReflSaveTabView::enableAutosaveControls() {
+  m_ui.autosaveGroup->setEnabled(true);
+}
 
-  return m_presenter.get();
+void QtReflSaveTabView::enableFileFormatAndLocationControls() {
+  m_ui.fileFormatGroup->setEnabled(true);
+  m_ui.fileLocationGroup->setEnabled(true);
+}
+
+void QtReflSaveTabView::disableFileFormatAndLocationControls() {
+  m_ui.fileFormatGroup->setEnabled(false);
+  m_ui.fileLocationGroup->setEnabled(false);
 }
 
 /** Returns the save path
@@ -133,6 +172,10 @@ bool QtReflSaveTabView::getQResolutionCheck() const {
   return m_ui.qResolutionCheckBox->isChecked();
 }
 
+void QtReflSaveTabView::disallowAutosave() {
+  m_ui.saveReductionResultsCheckBox->setCheckState(Qt::CheckState::Unchecked);
+}
+
 /** Returns the separator type
 * @return :: The separator
 */
@@ -204,5 +247,28 @@ void QtReflSaveTabView::suggestSaveDir() const {
   m_presenter->notify(IReflSaveTabPresenter::suggestSaveDirFlag);
 }
 
+/**
+Show an critical error dialog
+@param prompt : The prompt to appear on the dialog
+@param title : The text for the title bar of the dialog
+*/
+void QtReflSaveTabView::giveUserCritical(const std::string &prompt,
+                                         const std::string &title) {
+  QMessageBox::critical(this, QString::fromStdString(title),
+                        QString::fromStdString(prompt), QMessageBox::Ok,
+                        QMessageBox::Ok);
+}
+
+/**
+Show an information dialog
+@param prompt : The prompt to appear on the dialog
+@param title : The text for the title bar of the dialog
+*/
+void QtReflSaveTabView::giveUserInfo(const std::string &prompt,
+                                     const std::string &title) {
+  QMessageBox::information(this, QString::fromStdString(title),
+                           QString::fromStdString(prompt), QMessageBox::Ok,
+                           QMessageBox::Ok);
+}
 } // namespace CustomInterfaces
 } // namespace Mantid
diff --git a/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.h b/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.h
index f2270146072be511473d82a44bb36761e5c5726d..353f893f0e72863277b544aa7fda51716501e243 100644
--- a/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.h
+++ b/qt/scientific_interfaces/ISISReflectometry/QtReflSaveTabView.h
@@ -44,8 +44,8 @@ public:
   QtReflSaveTabView(QWidget *parent = nullptr);
   /// Destructor
   ~QtReflSaveTabView() override;
-  /// Returns the presenter managing this view
-  IReflSaveTabPresenter *getPresenter() const override;
+
+  void subscribe(IReflSaveTabPresenter *presenter) override;
 
   /// Returns the save path
   std::string getSavePath() const override;
@@ -81,6 +81,19 @@ public:
   /// Sets the 'List of logged parameters' widget
   void setParametersList(const std::vector<std::string> &) const override;
 
+  void disallowAutosave() override;
+
+  void disableAutosaveControls() override;
+  void enableAutosaveControls() override;
+
+  void enableFileFormatAndLocationControls() override;
+  void disableFileFormatAndLocationControls() override;
+
+  void giveUserCritical(const std::string &prompt,
+                        const std::string &title) override;
+  void giveUserInfo(const std::string &prompt,
+                    const std::string &title) override;
+
 public slots:
   /// Populate the 'List of workspaces' widget
   void populateListOfWorkspaces() const;
@@ -92,12 +105,16 @@ public slots:
   void saveWorkspaces() const;
   /// Suggest a save directory
   void suggestSaveDir() const;
+  void browseToSaveDirectory();
+
+  void onSavePathChanged();
+  void onAutosaveChanged(int state);
 
 private:
   /// Initialize the interface
   void initLayout();
   /// The presenter
-  std::unique_ptr<IReflSaveTabPresenter> m_presenter;
+  IReflSaveTabPresenter *m_presenter;
   /// The widget
   Ui::ReflSaveTabWidget m_ui;
 };
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c4ef14add7e9d4d6250e44dfb400ef52c7e40d54
--- /dev/null
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.cpp
@@ -0,0 +1,115 @@
+#include "ReflAsciiSaver.h"
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include <Poco/Path.h>
+#include <Poco/File.h>
+namespace MantidQt {
+namespace CustomInterfaces {
+
+Mantid::API::IAlgorithm_sptr
+ReflAsciiSaver::algorithmForFormat(NamedFormat format) {
+  auto create =
+      [](std::string const &algorithmName) -> Mantid::API::IAlgorithm_sptr {
+        return Mantid::API::AlgorithmManager::Instance().create(algorithmName);
+      };
+  switch (format) {
+  case NamedFormat::Custom:
+    return create("SaveReflCustomAscii");
+  case NamedFormat::ThreeColumn:
+    return create("SaveReflThreeColumnAscii");
+  case NamedFormat::ANSTO:
+    return create("SaveANSTOAscii");
+  case NamedFormat::ILLCosmos:
+    return create("SaveILLCosmosAscii");
+  default:
+    throw std::runtime_error("Unknown save format.");
+  }
+}
+
+std::string ReflAsciiSaver::extensionForFormat(NamedFormat format) {
+  switch (format) {
+  case NamedFormat::Custom:
+    return ".dat";
+  case NamedFormat::ThreeColumn:
+    return ".dat";
+  case NamedFormat::ANSTO:
+    return ".txt";
+  case NamedFormat::ILLCosmos:
+    return ".mft";
+  default:
+    throw std::runtime_error("Unknown save format.");
+  }
+}
+
+bool ReflAsciiSaver::isValidSaveDirectory(std::string const &path) const {
+  if (!path.empty()) {
+    try {
+      auto pocoPath = Poco::Path().parseDirectory(path);
+      auto pocoFile = Poco::File(pocoPath);
+      return pocoFile.exists() && pocoFile.canWrite();
+    } catch (Poco::PathSyntaxException &) {
+      return false;
+    }
+  } else
+    return false;
+}
+
+namespace {
+template <typename T>
+void setPropertyIfSupported(Mantid::API::IAlgorithm_sptr alg,
+                            std::string const &propertyName, T const &value) {
+  if (alg->existsProperty(propertyName))
+    alg->setProperty(propertyName, value);
+}
+}
+
+std::string ReflAsciiSaver::assembleSavePath(
+    std::string const &saveDirectory, std::string const &prefix,
+    std::string const &name, std::string const &extension) const {
+  auto path = Poco::Path(saveDirectory).makeDirectory();
+  path.append(prefix + name + extension);
+  return path.toString();
+}
+
+Mantid::API::MatrixWorkspace_sptr
+ReflAsciiSaver::workspace(std::string const &workspaceName) const {
+  return Mantid::API::AnalysisDataService::Instance()
+      .retrieveWS<Mantid::API::MatrixWorkspace>(workspaceName);
+}
+
+Mantid::API::IAlgorithm_sptr ReflAsciiSaver::setUpSaveAlgorithm(
+    std::string const &saveDirectory,
+    Mantid::API::MatrixWorkspace_sptr workspace,
+    std::vector<std::string> const &logParameters,
+    FileFormatOptions const &fileFormat) const {
+  auto saveAlg = algorithmForFormat(fileFormat.format());
+  auto extension = extensionForFormat(fileFormat.format());
+  if (fileFormat.shouldIncludeTitle())
+    setPropertyIfSupported(saveAlg, "Title", workspace->getTitle());
+
+  setPropertyIfSupported(saveAlg, "LogList", logParameters);
+  setPropertyIfSupported(saveAlg, "WriteDeltaQ",
+                         fileFormat.shouldIncludeQResolution());
+  saveAlg->setProperty("Separator", fileFormat.separator());
+  saveAlg->setProperty("Filename",
+                       assembleSavePath(saveDirectory, fileFormat.prefix(),
+                                        workspace->getName(), extension));
+  saveAlg->setProperty("InputWorkspace", workspace);
+  return saveAlg;
+}
+
+void ReflAsciiSaver::save(std::string const &saveDirectory,
+                          std::vector<std::string> const &workspaceNames,
+                          std::vector<std::string> const &logParameters,
+                          FileFormatOptions const &fileFormat) const {
+  // Setup the appropriate save algorithm
+  if (isValidSaveDirectory(saveDirectory))
+    for (auto const &name : workspaceNames)
+      setUpSaveAlgorithm(saveDirectory, workspace(name), logParameters,
+                         fileFormat)->execute();
+  else
+    throw InvalidSavePath(saveDirectory);
+}
+}
+}
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.h b/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.h
new file mode 100644
index 0000000000000000000000000000000000000000..08616d3205d8203d9d5ab6c2103436f9375a7d44
--- /dev/null
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflAsciiSaver.h
@@ -0,0 +1,39 @@
+#ifndef MANTID_ISISREFLECTOMETRY_REFLASCIISAVER_H
+#define MANTID_ISISREFLECTOMETRY_REFLASCIISAVER_H
+#include <vector>
+#include <string>
+#include "MantidAPI/IAlgorithm_fwd.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "IReflAsciiSaver.h"
+
+namespace MantidQt {
+namespace CustomInterfaces {
+class ReflAsciiSaver : public IReflAsciiSaver {
+public:
+  static Mantid::API::IAlgorithm_sptr algorithmForFormat(NamedFormat format);
+  static std::string extensionForFormat(NamedFormat format);
+
+  bool isValidSaveDirectory(std::string const &filePath) const override;
+  void save(std::string const &saveDirectory,
+            std::vector<std::string> const &workspaceNames,
+            std::vector<std::string> const &logParameters,
+            FileFormatOptions const &inputParameters) const override;
+
+private:
+  Mantid::API::IAlgorithm_sptr
+  setUpSaveAlgorithm(std::string const &saveDirectory,
+                     Mantid::API::MatrixWorkspace_sptr workspace,
+                     std::vector<std::string> const &logParameters,
+                     FileFormatOptions const &fileFormat) const;
+
+  std::string assembleSavePath(std::string const &saveDirectory,
+                               std::string const &prefix,
+                               std::string const &name,
+                               std::string const &extension) const;
+
+  Mantid::API::MatrixWorkspace_sptr
+  workspace(std::string const &workspaceName) const;
+};
+}
+}
+#endif // MANTID_ISISREFLECTOMETRY_REFLASCIISAVER_H
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorMainPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorMainPresenter.h
index 4da34c4cf5823f7f6c851ea0cb2eaf329deac021..b723fa605d5616bb8df25dc002d8f32bb5cfde36 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorMainPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorMainPresenter.h
@@ -5,8 +5,6 @@ namespace MantidQt {
 namespace CustomInterfaces {
 /** @class ReflDataProcessorMainPresenter
 
-TODO: description
-
 Copyright &copy; 2011-16 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
 National Laboratory & European Spallation Source
 
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.cpp
index 8e4c2bd4ac44007e5a230f7afe43c69c104b843a..4784b2740af3c07c1e47c96f6e0c56ac57389efa 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.cpp
@@ -539,6 +539,19 @@ bool ReflDataProcessorPresenter::processGroupAsEventWS(
   return errors;
 }
 
+void ReflDataProcessorPresenter::completedGroupReductionSuccessfully(
+    MantidWidgets::DataProcessor::GroupData const &groupData,
+    std::string const &workspaceName) {
+  m_mainPresenter->completedGroupReductionSuccessfully(groupData,
+                                                       workspaceName);
+}
+
+void ReflDataProcessorPresenter::completedRowReductionSuccessfully(
+    MantidWidgets::DataProcessor::GroupData const &groupData,
+    std::string const &workspaceName) {
+  m_mainPresenter->completedRowReductionSuccessfully(groupData, workspaceName);
+}
+
 /** Processes a group of non-event workspaces
 *
 * @param groupID :: An integer number indicating the id of this group
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.h
index d4c14b878cb09c870c350a38071b4f4fa1862982..c57e56b407de083e7612f634dbe90b3cb46a98c8 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflDataProcessorPresenter.h
@@ -105,6 +105,12 @@ public:
   // Add entry for the number of slices for all rows in a group
   void addNumGroupSlicesEntry(int groupID, size_t numSlices);
 
+  void
+  completedRowReductionSuccessfully(GroupData const &groupData,
+                                    std::string const &workspaceName) override;
+  void completedGroupReductionSuccessfully(
+      GroupData const &groupData, std::string const &workspaceName) override;
+
 private:
   // Get the processing options for this row
   OptionsMap getProcessingOptions(RowData_sptr data) override;
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.cpp
index 6bc30c3d1e985742ad7f9a3dbc611b7ed866585b..e355ecdf72f25e705a12943a12a9b372a343564d 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.cpp
@@ -10,7 +10,10 @@ namespace CustomInterfaces {
 /** Constructor
 * @param view :: The view we are handling
 */
-ReflEventPresenter::ReflEventPresenter(IReflEventView *view) : m_view(view) {}
+ReflEventPresenter::ReflEventPresenter(IReflEventView *view)
+    : m_view(view), m_sliceType(SliceType::UniformEven) {
+  m_view->enableSliceType(m_sliceType);
+}
 
 /** Destructor
 */
@@ -20,20 +23,63 @@ ReflEventPresenter::~ReflEventPresenter() {}
 * @return :: The time-slicing values
 */
 std::string ReflEventPresenter::getTimeSlicingValues() const {
+  switch (m_sliceType) {
+  case SliceType::UniformEven:
+    return m_view->getUniformEvenTimeSlicingValues();
+  case SliceType::Uniform:
+    return m_view->getUniformTimeSlicingValues();
+  case SliceType::Custom:
+    return m_view->getCustomTimeSlicingValues();
+  case SliceType::LogValue: {
+    auto slicingValues = m_view->getLogValueTimeSlicingValues();
+    auto logFilter = m_view->getLogValueTimeSlicingType();
+    return logFilterAndSliceValues(slicingValues, logFilter);
+  }
+  default:
+    throw std::runtime_error("Unrecognized slice type.");
+  }
+}
 
-  return m_view->getTimeSlicingValues();
+std::string ReflEventPresenter::logFilterAndSliceValues(
+    std::string const &slicingValues, std::string const &logFilter) const {
+  if (!slicingValues.empty() && !logFilter.empty())
+    return "Slicing=\"" + slicingValues + "\",LogFilter=" + logFilter;
+  else
+    return "";
 }
 
 /** Returns the time-slicing type
 * @return :: The time-slicing type
 */
 std::string ReflEventPresenter::getTimeSlicingType() const {
+  switch (m_sliceType) {
+  case SliceType::UniformEven:
+    return "UniformEven";
+  case SliceType::Uniform:
+    return "Uniform";
+  case SliceType::Custom:
+    return "Custom";
+  case SliceType::LogValue:
+    return "LogValue";
+  default:
+    throw std::runtime_error("Unrecognized slice type.");
+  }
+}
 
-  return m_view->getTimeSlicingType();
+void ReflEventPresenter::onReductionPaused() {
+  m_view->enableSliceType(m_sliceType);
+  m_view->enableSliceTypeSelection();
 }
 
-void ReflEventPresenter::onReductionPaused() { m_view->enableAll(); }
+void ReflEventPresenter::onReductionResumed() {
+  m_view->disableSliceType(m_sliceType);
+  m_view->disableSliceTypeSelection();
+}
 
-void ReflEventPresenter::onReductionResumed() { m_view->disableAll(); }
+void ReflEventPresenter::notifySliceTypeChanged(SliceType newSliceType) {
+  m_view->disableSliceType(m_sliceType);
+  m_view->enableSliceType(newSliceType);
+  m_sliceType = newSliceType;
+}
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.h
index 0e4dbe124c6dcc35271b9192e443203f79b344c6..37b51da3185e3329c3b7eeeee60f548b8aad41c6 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflEventPresenter.h
@@ -51,10 +51,14 @@ public:
 
   void onReductionPaused() override;
   void onReductionResumed() override;
+  void notifySliceTypeChanged(SliceType newSliceType) override;
 
 private:
+  std::string logFilterAndSliceValues(std::string const &slicingValues,
+                                      std::string const &logFilter) const;
   /// The view we are managing
   IReflEventView *m_view;
+  SliceType m_sliceType;
 };
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflEventWidget.ui b/qt/scientific_interfaces/ISISReflectometry/ReflEventWidget.ui
index 6f83ec0442cb63310d68423a6b0ad3c6d3977fd2..8aabf0c1e193b348898c622567b03a6102aa83ad 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflEventWidget.ui
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflEventWidget.ui
@@ -53,6 +53,9 @@
         </item>
         <item row="0" column="1">
          <widget class="QLineEdit" name="uniformEvenEdit">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="toolTip">
            <string>The number of evenly sized slices to split the event data into</string>
           </property>
@@ -60,6 +63,9 @@
         </item>
         <item row="0" column="2">
          <widget class="QLabel" name="uniformEvenLabel">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="text">
            <string>even time slices</string>
           </property>
@@ -87,6 +93,9 @@
         </item>
         <item row="1" column="1">
          <widget class="QLineEdit" name="uniformEdit">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="toolTip">
            <string>The length of time in seconds each slice should cover</string>
           </property>
@@ -94,6 +103,9 @@
         </item>
         <item row="1" column="2">
          <widget class="QLabel" name="uniformLabel">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="text">
            <string>(sec) slices</string>
           </property>
@@ -132,6 +144,9 @@
       </item>
       <item>
        <widget class="QLabel" name="customLabel">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="text">
          <string>Python list (sec)</string>
         </property>
@@ -139,6 +154,9 @@
       </item>
       <item>
        <widget class="QLineEdit" name="customEdit">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="toolTip">
          <string>A comma separated list of values indicating the times (in seconds) at which to slice the data</string>
         </property>
@@ -175,6 +193,9 @@
       </item>
       <item>
        <widget class="QLabel" name="logValueLabel">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="text">
          <string>Python list</string>
         </property>
@@ -182,6 +203,9 @@
       </item>
       <item>
        <widget class="QLineEdit" name="logValueEdit">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="toolTip">
          <string>A comma separated list of values indicating the log values at which to slice the data</string>
         </property>
@@ -189,6 +213,9 @@
       </item>
       <item>
        <widget class="QLabel" name="logValueTypeLabel">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="text">
          <string>Log name</string>
         </property>
@@ -196,6 +223,9 @@
       </item>
       <item>
        <widget class="QLineEdit" name="logValueTypeEdit">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="toolTip">
          <string>The name of the log value to slice on</string>
         </property>
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp
index 17ea85b0dc6e3c8fe4787619b417eb900485d3e5..25dc242eaa0aef3e56f0d7fd5e66cc216a994501 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp
@@ -88,13 +88,13 @@ ReflGenericDataProcessorPresenterFactory::create(int group) {
   std::map<QString, PreprocessingAlgorithm> preprocessMap = {
       /* 'Plus' will be applied to column 'Run(s)'*/
       {"Run(s)",
-       PreprocessingAlgorithm("Plus", "TOF_",
+       PreprocessingAlgorithm("Plus", "TOF_", "+",
                               std::set<QString>{"LHSWorkspace", "RHSWorkspace",
                                                 "OutputWorkspace"})},
       /* 'CreateTransmissionWorkspaceAuto' will be applied to column
          'Transmission Run(s)'*/
       {"Transmission Run(s)",
-       PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_",
+       PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", "_",
                               std::set<QString>{"FirstTransmissionRun",
                                                 "SecondTransmissionRun",
                                                 "OutputWorkspace"})}};
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.cpp
index 057c05ad29c669d25dfde3e554dfe07c965e6c66..ac94f825336a299ce6807ee46c5aa018d3170a9e 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.cpp
@@ -23,10 +23,10 @@ ReflMainWindowPresenter::ReflMainWindowPresenter(
     IReflMainWindowView *view, IReflRunsTabPresenter *runsPresenter,
     IReflEventTabPresenter *eventPresenter,
     IReflSettingsTabPresenter *settingsPresenter,
-    IReflSaveTabPresenter *savePresenter)
+    std::unique_ptr<IReflSaveTabPresenter> savePresenter)
     : m_view(view), m_runsPresenter(runsPresenter),
       m_eventPresenter(eventPresenter), m_settingsPresenter(settingsPresenter),
-      m_savePresenter(savePresenter), m_isProcessing(false) {
+      m_savePresenter(std::move(savePresenter)), m_isProcessing(false) {
 
   // Tell the tab presenters that this is going to be the main presenter
   m_runsPresenter->acceptMainPresenter(this);
@@ -41,6 +41,16 @@ ReflMainWindowPresenter::ReflMainWindowPresenter(
 */
 ReflMainWindowPresenter::~ReflMainWindowPresenter() {}
 
+void ReflMainWindowPresenter::completedGroupReductionSuccessfully(
+    GroupData const &group, std::string const &workspaceName) {
+  m_savePresenter->completedGroupReductionSuccessfully(group, workspaceName);
+}
+
+void ReflMainWindowPresenter::completedRowReductionSuccessfully(
+    GroupData const &group, std::string const &workspaceName) {
+  m_savePresenter->completedRowReductionSuccessfully(group, workspaceName);
+}
+
 void ReflMainWindowPresenter::notifyReductionPaused(int group) {
   m_isProcessing = false;
   m_savePresenter->onAnyReductionPaused();
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.h
index c2a24bb0715269a4bfe1b128ebcc545dc2eda0ef..4212994c0edd99d6a11851b6b68a15275d0c846f 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflMainWindowPresenter.h
@@ -3,6 +3,7 @@
 
 #include "DllConfig.h"
 #include "IReflMainWindowPresenter.h"
+#include <memory>
 
 namespace MantidQt {
 namespace CustomInterfaces {
@@ -47,7 +48,7 @@ public:
                           IReflRunsTabPresenter *runsPresenter,
                           IReflEventTabPresenter *eventPresenter,
                           IReflSettingsTabPresenter *settingsPresenter,
-                          IReflSaveTabPresenter *savePresenter);
+                          std::unique_ptr<IReflSaveTabPresenter> savePresenter);
   /// Destructor
   ~ReflMainWindowPresenter() override;
 
@@ -87,6 +88,13 @@ public:
   void notifyReductionPaused(int group) override;
   void notifyReductionResumed(int group) override;
 
+  void completedGroupReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) override;
+  void completedRowReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) override;
+
 private:
   /// Check for Settings Tab null pointer
   void checkSettingsPtrValid(IReflSettingsTabPresenter *pointer) const;
@@ -106,7 +114,7 @@ private:
   /// The presenter of tab 'Settings'
   IReflSettingsTabPresenter *m_settingsPresenter;
   /// The presenter of tab 'Save ASCII'
-  IReflSaveTabPresenter *m_savePresenter;
+  std::unique_ptr<IReflSaveTabPresenter> m_savePresenter;
   /// State boolean on whether runs are currently being processed or not
   mutable bool m_isProcessing;
 };
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp
index 30709e657448da6d049495e6d170925ee4c210a9..f56491e7a629dd57959fb5a5f0b7843f6116d9d5 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp
@@ -43,9 +43,9 @@ TransferResults
 MantidQt::CustomInterfaces::ReflMeasureTransferStrategy::transferRuns(
     SearchResultMap &searchResults, Mantid::Kernel::ProgressBase &progress) {
 
-  typedef std::vector<MeasurementItem> VecSameMeasurement;
-  typedef std::map<MeasurementItem::IDType, VecSameMeasurement>
-      MapGroupedMeasurement;
+  using VecSameMeasurement = std::vector<MeasurementItem>;
+  using MapGroupedMeasurement =
+      std::map<MeasurementItem::IDType, VecSameMeasurement>;
 
   // table-like output for successful runs
   std::vector<std::map<std::string, std::string>> runs;
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.cpp
index a6b157a098fec9494be9c3eb561bbe5730b8089f..e842a967cde20ab5ef5d1cfe93cc126b44f1672b 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.cpp
@@ -159,6 +159,16 @@ void ReflRunsTabPresenter::notify(IReflRunsTabPresenter::Flag flag) {
   // a flag we aren't handling.
 }
 
+void ReflRunsTabPresenter::completedGroupReductionSuccessfully(
+    GroupData const &group, std::string const &workspaceName) {
+  m_mainPresenter->completedGroupReductionSuccessfully(group, workspaceName);
+}
+
+void ReflRunsTabPresenter::completedRowReductionSuccessfully(
+    GroupData const &group, std::string const &workspaceNames) {
+  m_mainPresenter->completedRowReductionSuccessfully(group, workspaceNames);
+}
+
 /** Pushes the list of commands (actions) */
 void ReflRunsTabPresenter::pushCommands() {
 
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.h
index 67e3ac646319b14014b2d8d5d01d7f3ba2611cb0..facd80a7ff85d1cfb386e315ab0a6d28dd23a337 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflRunsTabPresenter.h
@@ -5,6 +5,7 @@
 #include "DllConfig.h"
 #include "IReflRunsTabPresenter.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/DataProcessorMainPresenter.h"
+#include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
 #include <boost/shared_ptr.hpp>
 
 namespace MantidQt {
@@ -89,6 +90,12 @@ public:
   void confirmReductionPaused(int group) override;
   void confirmReductionResumed(int group) override;
   void settingsChanged(int group) override;
+  void completedGroupReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &) override;
+  void completedRowReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceNames) override;
 
 private:
   /// The search model
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.cpp
index 31ee91b63b00fa440f78d60be62f82f8cd7ac162..a03a5502674c23f5392f266212f50e8f377bbea4 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.cpp
@@ -18,15 +18,17 @@ namespace CustomInterfaces {
 
 using namespace Mantid::API;
 
-/** Constructor
+/**
+* @param saver :: The model to use to save the files
 * @param view :: The view we are handling
 */
-ReflSaveTabPresenter::ReflSaveTabPresenter(IReflSaveTabView *view)
-    : m_view(view), m_mainPresenter() {
+ReflSaveTabPresenter::ReflSaveTabPresenter(
+    std::unique_ptr<IReflAsciiSaver> saver,
+    std::unique_ptr<IReflSaveTabView> view)
+    : m_view(std::move(view)), m_saver(std::move(saver)), m_mainPresenter(),
+      m_shouldAutosave(false) {
 
-  m_saveAlgs = {"SaveReflCustomAscii", "SaveReflThreeColumnAscii",
-                "SaveANSTOAscii", "SaveILLCosmosAscii"};
-  m_saveExts = {".dat", ".dat", ".txt", ".mft"};
+  m_view->subscribe(this);
 }
 
 /** Destructor
@@ -41,9 +43,17 @@ void ReflSaveTabPresenter::acceptMainPresenter(
   m_mainPresenter = mainPresenter;
 }
 
-void ReflSaveTabPresenter::onAnyReductionPaused() { populateWorkspaceList(); }
+void ReflSaveTabPresenter::onAnyReductionPaused() {
+  populateWorkspaceList();
+  m_view->enableAutosaveControls();
+  m_view->enableFileFormatAndLocationControls();
+}
 
-void ReflSaveTabPresenter::onAnyReductionResumed() {}
+void ReflSaveTabPresenter::onAnyReductionResumed() {
+  m_view->disableAutosaveControls();
+  if (shouldAutosave())
+    m_view->disableFileFormatAndLocationControls();
+}
 
 void ReflSaveTabPresenter::notify(IReflSaveTabPresenter::Flag flag) {
   switch (flag) {
@@ -57,14 +67,56 @@ void ReflSaveTabPresenter::notify(IReflSaveTabPresenter::Flag flag) {
     populateParametersList();
     break;
   case saveWorkspacesFlag:
-    saveWorkspaces();
+    saveSelectedWorkspaces();
     break;
   case suggestSaveDirFlag:
     suggestSaveDir();
     break;
+  case autosaveDisabled:
+    disableAutosave();
+    break;
+  case autosaveEnabled:
+    enableAutosave();
+    break;
+  case savePathChanged:
+    onSavePathChanged();
+  }
+}
+
+void ReflSaveTabPresenter::enableAutosave() {
+  if (isValidSaveDirectory(m_view->getSavePath())) {
+    m_shouldAutosave = true;
+  } else {
+    m_shouldAutosave = false;
+    m_view->disallowAutosave();
+    errorInvalidSaveDirectory();
   }
 }
 
+void ReflSaveTabPresenter::disableAutosave() { m_shouldAutosave = false; }
+
+void ReflSaveTabPresenter::onSavePathChanged() {
+  if (shouldAutosave() && !isValidSaveDirectory(m_view->getSavePath()))
+    warnInvalidSaveDirectory();
+}
+
+void ReflSaveTabPresenter::completedGroupReductionSuccessfully(
+    MantidWidgets::DataProcessor::GroupData const &group,
+    std::string const &workspaceName) {
+  UNUSED_ARG(group);
+  if (shouldAutosave())
+    saveWorkspaces(std::vector<std::string>({workspaceName}));
+}
+
+bool ReflSaveTabPresenter::shouldAutosave() const { return m_shouldAutosave; }
+
+void ReflSaveTabPresenter::completedRowReductionSuccessfully(
+    MantidWidgets::DataProcessor::GroupData const &group,
+    std::string const &workspaceName) {
+  if (!MantidWidgets::DataProcessor::canPostprocess(group) && shouldAutosave())
+    saveWorkspaces(std::vector<std::string>({workspaceName}));
+}
+
 /** Fills the 'List of Workspaces' widget with the names of all available
 * workspaces
 */
@@ -125,66 +177,83 @@ void ReflSaveTabPresenter::populateParametersList() {
   m_view->setParametersList(logs);
 }
 
-/** Saves selected workspaces
-*/
-void ReflSaveTabPresenter::saveWorkspaces() {
-  // Check that save directory is valid
-  std::string saveDir = m_view->getSavePath();
-  if (saveDir.empty() || Poco::File(saveDir).isDirectory() == false) {
-    m_mainPresenter->giveUserCritical("Directory specified doesn't exist or "
-                                      "was invalid for your operating system",
-                                      "Invalid directory");
-    return;
-  }
+bool ReflSaveTabPresenter::isValidSaveDirectory(std::string const &directory) {
+  return m_saver->isValidSaveDirectory(directory);
+}
 
-  // Check that at least one workspace has been selected for saving
-  auto wsNames = m_view->getSelectedWorkspaces();
-  if (wsNames.empty()) {
-    m_mainPresenter->giveUserCritical("No workspaces selected. You must select "
-                                      "the workspaces to save.",
-                                      "No workspaces selected");
+void ReflSaveTabPresenter::error(std::string const &message,
+                                 std::string const &title) {
+  m_view->giveUserCritical(message, title);
+}
+
+void ReflSaveTabPresenter::warn(std::string const &message,
+                                std::string const &title) {
+  m_view->giveUserInfo(message, title);
+}
+
+void ReflSaveTabPresenter::warnInvalidSaveDirectory() {
+  warn("You just changed the save path to a directory which "
+       "doesn't exist or is not writable.",
+       "Invalid directory");
+}
+
+void ReflSaveTabPresenter::errorInvalidSaveDirectory() {
+  error("The save path specified doesn't exist or is "
+        "not writable.",
+        "Invalid directory");
+}
+
+NamedFormat ReflSaveTabPresenter::formatFromIndex(int formatIndex) const {
+  switch (formatIndex) {
+  case 0:
+    return NamedFormat::Custom;
+  case 1:
+    return NamedFormat::ThreeColumn;
+  case 2:
+    return NamedFormat::ANSTO;
+  case 3:
+    return NamedFormat::ILLCosmos;
+  default:
+    throw std::runtime_error("Unknown save format.");
   }
+}
 
-  // Obtain workspace titles
-  std::vector<std::string> wsTitles(wsNames.size());
-  std::transform(wsNames.begin(), wsNames.end(), wsTitles.begin(),
-                 [](std::string s) {
-                   return AnalysisDataService::Instance()
-                       .retrieveWS<MatrixWorkspace>(s)
-                       ->getTitle();
-                 });
-
-  // Create the appropriate save algorithm
-  bool titleCheck = m_view->getTitleCheck();
-  auto selectedParameters = m_view->getSelectedParameters();
-  bool qResolutionCheck = m_view->getQResolutionCheck();
-  std::string separator = m_view->getSeparator();
-  std::string prefix = m_view->getPrefix();
-  int formatIndex = m_view->getFileFormatIndex();
-  std::string algName = m_saveAlgs[formatIndex];
-  std::string extension = m_saveExts[formatIndex];
-  IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create(algName);
-
-  for (size_t i = 0; i < wsNames.size(); i++) {
-    // Add any additional algorithm-specific properties and execute
-    if (algName != "SaveANSTOAscii") {
-      if (titleCheck)
-        saveAlg->setProperty("Title", wsTitles[i]);
-      saveAlg->setProperty("LogList", selectedParameters);
-    }
-    if (algName == "SaveReflCustomAscii") {
-      saveAlg->setProperty("WriteDeltaQ", qResolutionCheck);
-    }
+FileFormatOptions ReflSaveTabPresenter::getSaveParametersFromView() const {
+  return FileFormatOptions(
+      /*format=*/formatFromIndex(m_view->getFileFormatIndex()),
+      /*prefix=*/m_view->getPrefix(),
+      /*includeTitle=*/m_view->getTitleCheck(),
+      /*separator=*/m_view->getSeparator(),
+      /*includeQResolution=*/m_view->getQResolutionCheck());
+}
+
+void ReflSaveTabPresenter::saveWorkspaces(
+    std::vector<std::string> const &workspaceNames,
+    std::vector<std::string> const &logParameters) {
+  auto savePath = m_view->getSavePath();
+  if (m_saver->isValidSaveDirectory(savePath))
+    m_saver->save(savePath, workspaceNames, logParameters,
+                  getSaveParametersFromView());
+  else
+    errorInvalidSaveDirectory();
+}
 
-    auto path = Poco::Path(saveDir);
-    auto wsName = wsNames[i];
-    path.append(prefix + wsName + extension);
-    saveAlg->setProperty("Separator", separator);
-    saveAlg->setProperty("Filename", path.toString());
-    saveAlg->setProperty(
-        "InputWorkspace",
-        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName));
-    saveAlg->execute();
+/** Saves workspaces with the names specified. */
+void ReflSaveTabPresenter::saveWorkspaces(
+    std::vector<std::string> const &workspaceNames) {
+  auto selectedLogParameters = m_view->getSelectedParameters();
+  saveWorkspaces(workspaceNames, selectedLogParameters);
+}
+
+/** Saves selected workspaces */
+void ReflSaveTabPresenter::saveSelectedWorkspaces() {
+  // Check that at least one workspace has been selected for saving
+  auto workspaceNames = m_view->getSelectedWorkspaces();
+  if (workspaceNames.empty()) {
+    error("No workspaces selected", "No workspaces selected. "
+                                    "You must select the workspaces to save.");
+  } else {
+    saveWorkspaces(workspaceNames);
   }
 }
 
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.h b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.h
index 9c99f770d30f6304c213347e6e265256f63d4f37..6e9f00ecc053e5dda9c0bda4cbe867250f42efb3 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabPresenter.h
@@ -5,6 +5,10 @@
 #include "IReflSaveTabPresenter.h"
 #include <vector>
 #include <string>
+#include <memory>
+#include <MantidKernel/ConfigPropertyObserver.h>
+#include <boost/optional.hpp>
+#include "IReflAsciiSaver.h"
 
 namespace MantidQt {
 namespace CustomInterfaces {
@@ -43,16 +47,29 @@ class MANTIDQT_ISISREFLECTOMETRY_DLL ReflSaveTabPresenter
     : public IReflSaveTabPresenter {
 public:
   /// Constructor
-  ReflSaveTabPresenter(IReflSaveTabView *view);
+  ReflSaveTabPresenter(std::unique_ptr<IReflAsciiSaver> saver,
+                       std::unique_ptr<IReflSaveTabView> view);
   /// Destructor
   ~ReflSaveTabPresenter() override;
   /// Accept a main presenter
   void acceptMainPresenter(IReflMainWindowPresenter *mainPresenter) override;
   void notify(IReflSaveTabPresenter::Flag flag) override;
+  void completedGroupReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) override;
+  void completedRowReductionSuccessfully(
+      MantidWidgets::DataProcessor::GroupData const &group,
+      std::string const &workspaceName) override;
   void onAnyReductionPaused() override;
   void onAnyReductionResumed() override;
 
 private:
+  bool isValidSaveDirectory(std::string const &directory);
+  void onSavePathChanged();
+  void warnInvalidSaveDirectory();
+  void errorInvalidSaveDirectory();
+  void warn(std::string const &message, std::string const &title);
+  void error(std::string const &message, std::string const &title);
   /// Adds all workspace names to the list of workspaces
   void populateWorkspaceList();
   /// Adds all workspace params to the list of logged parameters
@@ -62,18 +79,25 @@ private:
   /// Suggest a save directory
   void suggestSaveDir();
   /// Save selected workspaces to a directory
-  void saveWorkspaces();
+  void saveSelectedWorkspaces();
+  /// Save specified workspaces to a directory
+  void saveWorkspaces(std::vector<std::string> const &workspaceNames);
+  void saveWorkspaces(std::vector<std::string> const &workspaceNames,
+                      std::vector<std::string> const &logParameters);
   /// Obtains all available workspace names
   std::vector<std::string> getAvailableWorkspaceNames();
+  NamedFormat formatFromIndex(int formatIndex) const;
+  FileFormatOptions getSaveParametersFromView() const;
+  void enableAutosave();
+  void disableAutosave();
+  bool shouldAutosave() const;
 
   /// The view
-  IReflSaveTabView *m_view;
+  std::unique_ptr<IReflSaveTabView> m_view;
+  std::unique_ptr<IReflAsciiSaver> m_saver;
   /// The main presenter
   IReflMainWindowPresenter *m_mainPresenter;
-  /// Names of possible save algorithms
-  std::vector<std::string> m_saveAlgs;
-  /// Extensions used for each save algorithm
-  std::vector<std::string> m_saveExts;
+  bool m_shouldAutosave;
 };
 }
 }
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabWidget.ui b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabWidget.ui
index f90507e4f7646bd62dcdf69741ca4a13b84607c3..d38e4f2da4170f7196a5823fa83b5dca85fcaad9 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabWidget.ui
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSaveTabWidget.ui
@@ -1,351 +1,368 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>ReflSaveTabWidget</class>
-  <widget class="QWidget" name="ReflSaveTabWidget">
-    <property name="geometry">
-      <rect>
-        <x>0</x>
-        <y>0</y>
-        <width>959</width>
-        <height>346</height>
-      </rect>
-    </property>
-    <property name="windowTitle">
-      <string>Save ASCII</string>
-    </property>
-    <layout class="QVBoxLayout" name="verticalLayout">
-      <property name="margin">
-        <number>20</number>
-      </property>
+ <widget class="QWidget" name="ReflSaveTabWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>988</width>
+    <height>672</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Save ASCII</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
+   <item>
+    <widget class="QGroupBox" name="fileLocationGroup">
+     <property name="title">
+      <string>File Names and Location</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout">
-          <item>
-            <widget class="QLabel" name="savePathLabel">
-              <property name="text">
-                <string>Save path:</string>
-              </property>
-            </widget>
-          </item>
-          <item>
-            <widget class="QLineEdit" name="savePathEdit"/>
-          </item>
-          <item>
-            <widget class="QLabel" name="prefixLabel">
-              <property name="text">
-                <string>Prefix:</string>
-              </property>
-            </widget>
-          </item>
-          <item>
-            <widget class="QLineEdit" name="prefixEdit"/>
-          </item>
-          <item>
-            <spacer name="prefixSpacer">
-              <property name="orientation">
-                <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-                <size>
-                  <width>20</width>
-                  <height>20</height>
-                </size>
-              </property>
-            </spacer>
-          </item>
-        </layout>
+       <widget class="QLabel" name="savePathLabel">
+        <property name="text">
+         <string>Save Path:</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="savePathEdit"/>
+      </item>
+      <item>
+       <widget class="QPushButton" name="savePathBrowseButton">
+        <property name="text">
+         <string>Browse To Directory</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLabel" name="fileNameLabel">
+        <property name="text">
+         <string>File Name Prefix:</string>
+        </property>
+       </widget>
       </item>
       <item>
-        <widget class="QGroupBox" name="customSaveGroup">
-          <property name="title">
-            <string>Custom save</string>
+       <widget class="QLineEdit" name="prefixEdit"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="detailedOptionsLayout" stretch="2,1">
+     <item>
+      <layout class="QVBoxLayout" name="saveTypesLayout" stretch="0,1">
+       <item>
+        <widget class="QGroupBox" name="customSaveGroupBox">
+         <property name="title">
+          <string>Custom Save</string>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <property name="leftMargin">
+           <number>6</number>
           </property>
-          <layout class="QGridLayout" name="customSaveLayout">
-            <property name="margin">
-              <number>20</number>
-            </property>
-            <item row ="0" column="0">
-            <widget class="QLabel" name="filterLabel">
+          <item>
+           <layout class="QVBoxLayout" name="workspaceListLayout">
+            <item>
+             <widget class="QLabel" name="listOfWorkspacesLabel">
               <property name="text">
-                <string>Filter</string>
+               <string>&lt;b&gt;List Of Workspaces&lt;/b&gt;</string>
               </property>
-            </widget>
-            </item>
-            <item row="0" column="1">
-              <widget class="QLineEdit" name="filterEdit"/>
-            </item>
-            <item row="0" column="2">
-              <widget class="QCheckBox" name="regexCheckBox"/>
-            </item>
-            <item row="0" column="3">
-              <widget class="QLabel" name="regexLabel">
-                <property name="text">
-                  <string>Regex</string>
-                </property>
-              </widget>
-            </item>
-            <item row="0" column="4">
-              <spacer name="customSaveSpacer0">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
-            </item>
-            <item row ="1" column="0" colspan="4">
-              <widget class="QLabel" name="listOfWorkspacesLabel">
-                <property name="text">
-                  <string>List Of Workspaces</string>
-                </property>
-              </widget>
-            </item>
-            <item row="1" column="4">
-              <spacer name="customSaveSpacer1">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
-            </item>
-            <item row ="1" column="5">
-              <widget class="QLabel" name="listOfLoggedParametersLabel">
-                <property name="text">
-                  <string>List Of Logged Parameters</string>
-                </property>
-              </widget>
-            </item>
-            <item row ="2" column="0" colspan="4">
-              <widget class="QListWidget" name="listOfWorkspaces">
-                <property name="selectionMode">
-                  <enum>QAbstractItemView::ExtendedSelection</enum>
-                </property>
-              </widget>
-            </item>
-            <item row="2" column="4">
-              <spacer name="customSaveSpacer2">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
-            </item>
-            <item row ="2" column="5">
-              <widget class="QListWidget" name="listOfLoggedParameters">
-                <property name="selectionMode">
-                  <enum>QAbstractItemView::ExtendedSelection</enum>
-                </property>
-              </widget>
-            </item>
-            <item row="3" column="0" colspan="4">
-              <widget class="QPushButton" name="refreshButton">
-                <property name="text">
-                  <string>Refresh</string>
-                </property>
-              </widget>
-            </item>
-            <item row="3" column="4">
-              <spacer name="customSaveSpacer3">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
+              <property name="textFormat">
+               <enum>Qt::RichText</enum>
+              </property>
+             </widget>
             </item>
-            <item row="3" column="5" rowspan="4">
-              <widget class="QGroupBox" name="customFormatOptionsGroup">
-                <property name="title">
-                  <string>Custom Format Options</string>
+            <item>
+             <layout class="QHBoxLayout" name="workspaceFilterLayout">
+              <item>
+               <widget class="QLineEdit" name="filterEdit">
+                <property name="placeholderText">
+                 <string>Filter Workspaces</string>
                 </property>
-                <layout class="QGridLayout" name="customFormatOptionsLayout">
-                  <item row="0" column="0">
-                    <widget class="QCheckBox" name="titleCheckBox"/>
-                  </item>
-                  <item row="0" column="1">
-                    <widget class="QLabel" name="titleLabel">
-                      <property name="text">
-                        <string>Title</string>
-                      </property>
-                    </widget>
-                  </item>
-                  <item row="0" column="2">
-                    <widget class="QCheckBox" name="qResolutionCheckBox"/>
-                  </item>
-                  <item row="0" column="3">
-                    <widget class="QLabel" name="qResolutionLabel">
-                      <property name="text">
-                        <string>Q resolution</string>
-                      </property>
-                    </widget>
-                  </item>
-                  <item row="0" column="4">
-                    <spacer name="customFormatOptionsSpacer0">
-                      <property name="orientation">
-                        <enum>Qt::Horizontal</enum>
-                      </property>
-                      <property name="sizeHint" stdset="0">
-                        <size>
-                          <width>20</width>
-                          <height>20</height>
-                        </size>
-                      </property>
-                    </spacer>
-                  </item>
-                  <item row="1" column="0" colspan="5">
-                    <widget class="QGroupBox" name="separatorGroup">
-                      <property name="title">
-                        <string>Separator</string>
-                      </property>
-                      <layout class="QGridLayout" name="separatorLayout">
-                        <item row="0" column="0">
-                          <widget class="QRadioButton" name="commaRadioButton">
-                            <property name="text">
-                              <string>Comma</string>
-                            </property>
-                            <property name="checked">
-                              <bool>true</bool>
-                            </property>
-                            <attribute name="buttonGroup">
-                              <string notr="true">separatorButtonGroup</string>
-                            </attribute>
-                          </widget>
-                        </item>
-                        <item row="0" column="1">
-                          <widget class="QRadioButton" name="spaceRadioButton">
-                            <property name="text">
-                              <string>Space</string>
-                            </property>
-                            <attribute name="buttonGroup">
-                              <string notr="true">separatorButtonGroup</string>
-                            </attribute>
-                          </widget>
-                        </item>
-                        <item row="0" column="2">
-                          <widget class="QRadioButton" name="tabRadioButton">
-                            <property name="text">
-                              <string>Tab</string>
-                            </property>
-                            <attribute name="buttonGroup">
-                              <string notr="true">separatorButtonGroup</string>
-                            </attribute>
-                          </widget>
-                        </item>
-                        <item row="0" column="3">
-                          <spacer name="separatorSpacer0">
-                            <property name="orientation">
-                              <enum>Qt::Horizontal</enum>
-                            </property>
-                            <property name="sizeHint" stdset="0">
-                              <size>
-                                <width>20</width>
-                                <height>20</height>
-                              </size>
-                            </property>
-                          </spacer>
-                        </item>
-                      </layout>
-                    </widget>
-                  </item>
-                </layout>
-              </widget>
-            </item>
-            <item row ="5" column="0">
-              <widget class="QLabel" name="fileFormatLabel">
+               </widget>
+              </item>
+              <item>
+               <widget class="QCheckBox" name="regexCheckBox">
                 <property name="text">
-                  <string>File format</string>
+                 <string>Regex</string>
                 </property>
-              </widget>
+               </widget>
+              </item>
+             </layout>
             </item>
-            <item row="5" column="1" colspan="3">
-              <widget class="QComboBox" name="fileFormatComboBox">
-                <item>
-                  <property name="text">
-                    <string>Custom format (*.dat)</string>
-                  </property>
-                </item>
-                <item>
-                  <property name="text">
-                    <string>3 column (*.dat)</string>
-                  </property>
-                </item>
-                <item>
-                  <property name="text">
-                    <string>ANSTO, MotoFit, 4 column (*.txt)</string>
-                  </property>
-                </item>
-                <item>
-                  <property name="text">
-                    <string>ILL Cosmos (*.mft)</string>
-                  </property>
-                </item>
-                <property name="font">
-                  <font>
-                    <bold>true</bold>
-                  </font>
-                </property>
-              </widget>
+            <item>
+             <widget class="QListWidget" name="listOfWorkspaces">
+              <property name="selectionMode">
+               <enum>QAbstractItemView::ExtendedSelection</enum>
+              </property>
+             </widget>
             </item>
-            <item row="5" column="4">
-              <spacer name="customSaveSpacer5">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
+            <item>
+             <widget class="QPushButton" name="refreshButton">
+              <property name="text">
+               <string>Refresh</string>
+              </property>
+             </widget>
             </item>
-            <item row="6" column="0" colspan="4">
-              <widget class="QPushButton" name="saveButton">
-                <property name="text">
-                  <string>Save</string>
-                </property>
-              </widget>
+           </layout>
+          </item>
+          <item>
+           <layout class="QVBoxLayout" name="loggedParametersLayout">
+            <item>
+             <widget class="QLabel" name="listOfLoggedParametersLabel">
+              <property name="text">
+               <string>&lt;b&gt;List Of Logged Parameters&lt;/b&gt;</string>
+              </property>
+              <property name="textFormat">
+               <enum>Qt::RichText</enum>
+              </property>
+             </widget>
             </item>
-            <item row="6" column="4">
-              <spacer name="customSaveSpacer6">
-                <property name="orientation">
-                  <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                  <size>
-                    <width>20</width>
-                    <height>20</height>
-                  </size>
-                </property>
-              </spacer>
+            <item>
+             <widget class="QListWidget" name="listOfLoggedParameters">
+              <property name="selectionMode">
+               <enum>QAbstractItemView::ExtendedSelection</enum>
+              </property>
+             </widget>
             </item>
-          </layout>
+           </layout>
+          </item>
+         </layout>
         </widget>
-      </item>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="autosaveGroup">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="title">
+          <string>Automatic Save</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_3">
+          <item>
+           <widget class="QCheckBox" name="saveReductionResultsCheckBox">
+            <property name="toolTip">
+             <string>Saves stitched workspaces for multi-row group reductions and IvsQ_binned workspaces for reductions single row reductions.</string>
+            </property>
+            <property name="text">
+             <string>Save as ASCII on completion</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="fileFormatGroup">
+       <property name="styleSheet">
+        <string notr="true">.QGroupBox {
+    border-bottom: transparent;
+	border-left: transparent;
+    border-right: transparent;
+}</string>
+       </property>
+       <property name="title">
+        <string>File Format</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,0,0,0,0">
+        <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>
+         <widget class="QCheckBox" name="titleCheckBox">
+          <property name="text">
+           <string>Title</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="qResolutionCheckBox">
+          <property name="text">
+           <string>Q resolution</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="separatorButtons">
+          <property name="sizeConstraint">
+           <enum>QLayout::SetMinimumSize</enum>
+          </property>
+          <item>
+           <widget class="QLabel" name="separatorLabel">
+            <property name="maximumSize">
+             <size>
+              <width>16777215</width>
+              <height>20</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Separator:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="commaRadioButton">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Comma</string>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+            <attribute name="buttonGroup">
+             <string notr="true">separatorButtonGroup</string>
+            </attribute>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="spaceRadioButton">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Space</string>
+            </property>
+            <attribute name="buttonGroup">
+             <string notr="true">separatorButtonGroup</string>
+            </attribute>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="tabRadioButton">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Tab</string>
+            </property>
+            <attribute name="buttonGroup">
+             <string notr="true">separatorButtonGroup</string>
+            </attribute>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QComboBox" name="fileFormatComboBox">
+          <property name="font">
+           <font>
+            <weight>75</weight>
+            <bold>true</bold>
+           </font>
+          </property>
+          <property name="styleSheet">
+           <string notr="true"/>
+          </property>
+          <item>
+           <property name="text">
+            <string>Custom format (*.dat)</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>3 column (*.dat)</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>ANSTO, MotoFit, 4 column (*.txt)</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>ILL Cosmos (*.mft)</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="saveButton">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>3</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>0</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>131</height>
+           </size>
+          </property>
+          <property name="styleSheet">
+           <string notr="true"/>
+          </property>
+          <property name="text">
+           <string>Save</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
     </layout>
-  </widget>
- <tabstops/>
- <customwidgets/>
+   </item>
+  </layout>
+ </widget>
  <resources/>
  <connections/>
-<buttongroups>
+ <buttongroups>
   <buttongroup name="separatorButtonGroup"/>
-</buttongroups>
+ </buttongroups>
 </ui>
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h b/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h
index a9e687d12eebccadc893853c7d631a164affb340..62795fc59c57f4e096c8851fb0bceb643921e976 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h
@@ -72,7 +72,7 @@ protected:
 };
 
 /// Typedef for a shared pointer to \c ReflSearchModel
-typedef boost::shared_ptr<ReflSearchModel> ReflSearchModel_sptr;
+using ReflSearchModel_sptr = boost::shared_ptr<ReflSearchModel>;
 
 } // namespace CustomInterfaces
 } // namespace Mantid
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
index 823be8d95615b019a55336b650e9bac98bcbde65..39cb0042036578a299742e729df68de0449335c9 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>764</width>
-    <height>631</height>
+    <width>858</width>
+    <height>679</height>
    </rect>
   </property>
   <property name="baseSize">
@@ -605,7 +605,11 @@
          <widget class="QLineEdit" name="lamMaxEdit"/>
         </item>
         <item row="0" column="1">
-         <widget class="QCheckBox" name="intMonCheckBox"/>
+         <widget class="QCheckBox" name="intMonCheckBox">
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
         </item>
         <item row="2" column="0">
          <widget class="QLabel" name="monBgMinLabel">
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h b/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h
index 7b439c644bb6e4b9dbb3475615e9450bd7a04376..73de805ca1e0df50a34342a92f8749ab5d4a9d50 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h
@@ -9,10 +9,10 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace ReflTableSchema {
 
-typedef std::string ColumnNameType;
-typedef std::string ColumnValueType;
-typedef std::map<int, ColumnNameType> ColumnIndexNameMap;
-typedef std::map<ColumnNameType, int> ColumnNameIndexMap;
+using ColumnNameType = std::string;
+using ColumnValueType = std::string;
+using ColumnIndexNameMap = std::map<int, ColumnNameType>;
+using ColumnNameIndexMap = std::map<ColumnNameType, int>;
 
 /// Label for run number column
 static const std::string RUNS("Run(s)");
diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h b/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h
index dc6ba41cd2ae2d1a21af4d3ce452977e92c13049..797138bc9f29df29d7fb37bca8f86c68f4781ddc 100644
--- a/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h
+++ b/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h
@@ -29,7 +29,7 @@ struct SearchResult {
 };
 
 /// Helper typdef for map of SearchResults keyed by run
-typedef std::map<std::string, SearchResult> SearchResultMap;
+using SearchResultMap = std::map<std::string, SearchResult>;
 
 /** ReflTransferStrategy : Provides an stratgegy for transferring runs from
 search results to a format suitable for processing.
diff --git a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp
index bca52e8b28c8878805307189c03f932551c52004..9574a03dd554d2560ea407cfee149cbcbbb343e9 100644
--- a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp
+++ b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp
@@ -1450,6 +1450,10 @@ QString SANSDiagnostics::createOutputWorkspaceName(
   // Detector, Min value,  and Max values,
   QString appendix = "-" + detectorName + "-" + integrationType + min + "-" +
                      integrationType + max;
+  if (min == max) {
+    // special case which means that it is all of the range
+    appendix = "-" + detectorName + "-" + integrationType + "_ALL";
+  }
   outputWorkspaceName += appendix;
 
   outputWorkspaceName.replace("-", "_");
diff --git a/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp b/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp
index e2a78dcc7d02ce157b3e07070d937b8c7b95cbba..ea6b73f4e77d1e04f117d4f32a378d41e02c2d67 100644
--- a/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp
+++ b/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp
@@ -423,16 +423,16 @@ void SANSPlotSpecial::setupTable() {
 
   m_derivatives["Rg"] = new QTableWidgetItem();
   m_derivatives["Rg"]->setToolTip("Radius of gyration");
-  m_units["Rg"] = QString::fromUtf8("\xc3\x85");
+  m_units["Rg"] = QString::fromUtf8(R"(Ã…)");
   m_derivatives["Rg,xs"] = new QTableWidgetItem(*m_emptyCell);
   m_derivatives["Rg,xs"]->setToolTip("Cross-sectional radius of gyration");
-  m_units["Rg,xs"] = QString::fromUtf8("\xc3\x85");
+  m_units["Rg,xs"] = QString::fromUtf8(R"(Ã…)");
   m_derivatives["R"] = new QTableWidgetItem(*m_emptyCell);
   m_derivatives["R"]->setToolTip("Equivalent spherical radius");
-  m_units["R"] = QString::fromUtf8("\xc3\x85");
+  m_units["R"] = QString::fromUtf8(R"(Ã…)");
   m_derivatives["T"] = new QTableWidgetItem(*m_emptyCell);
   m_derivatives["T"]->setToolTip("Thickness");
-  m_units["T"] = QString::fromUtf8("\xc3\x85");
+  m_units["T"] = QString::fromUtf8(R"(Ã…)");
   m_derivatives["C"] = new QTableWidgetItem();
   m_derivatives["C"]->setToolTip("Concentration");
   m_units["C"] = "g/cm^3";
@@ -460,7 +460,7 @@ void SANSPlotSpecial::setupTable() {
   m_units["V"] = "(unitless)";
   m_derivatives["Zeta"] = new QTableWidgetItem(*m_emptyCell);
   m_derivatives["Zeta"]->setToolTip("Characteristic length");
-  m_units["Zeta"] = QString::fromUtf8("\xc3\x85");
+  m_units["Zeta"] = QString::fromUtf8(R"(Ã…)");
   m_derivatives["(S/V)"] = new QTableWidgetItem();
   m_derivatives["(S/V)"]->setToolTip("Surface area-to-volume ratio");
   m_units["(S/V)"] = "cm^-1";
diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp
index b7d4cd41da78236a122e646f627d406c66e2f7de..31b6f24dd8ef9c28887bc86c27d7e18237137856 100644
--- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp
+++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp
@@ -61,7 +61,7 @@ Logger g_log("SANSRunWindow");
 /// static logger for centre finding
 Logger g_centreFinderLog("CentreFinder");
 
-typedef boost::shared_ptr<Kernel::PropertyManager> ReductionSettings_sptr;
+using ReductionSettings_sptr = boost::shared_ptr<Kernel::PropertyManager>;
 
 /**
  * Returns the PropertyManager object that is used to store the settings
@@ -2145,8 +2145,8 @@ bool SANSRunWindow::handleLoadButtonClick() {
       m_uiForm.sample_geomid->setCurrentIndex(geomId - 1);
 
       using namespace boost;
-      typedef tuple<QLineEdit *, function<double(const Sample *)>, std::string>
-          GeomSampleInfo;
+      using GeomSampleInfo =
+          tuple<QLineEdit *, function<double(const Sample *)>, std::string>;
 
       std::vector<GeomSampleInfo> sampleInfoList;
       sampleInfoList.push_back(make_tuple(m_uiForm.sample_thick,
diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h
index 1d39d0f96997adaf9f48e4bc9678b56131c87aed..9a0db62bb67f9d95302c0519f490e2db866ccbc9 100644
--- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h
+++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h
@@ -330,7 +330,7 @@ private:
   enum TransSettings { M3, M4, RADIUS, ROI };
 
   /// holds pointer to validators and their locations
-  typedef std::map<QWidget *const, std::pair<QWidget *, QWidget *>> ValMap;
+  using ValMap = std::map<QWidget *const, std::pair<QWidget *, QWidget *>>;
   /// The form generated by Qt Designer
   Ui::SANSRunWindow m_uiForm;
   /// this object holds the functionality in the Add Files tab
@@ -383,8 +383,8 @@ private:
   /// Holds pointers to the check box for each supported save format with the
   /// name of its save algorithm
   QHash<const QCheckBox *const, QString> m_savFormats;
-  typedef QHash<const QCheckBox *const, QString>::const_iterator
-      SavFormatsConstIt;
+  using SavFormatsConstIt =
+      QHash<const QCheckBox *const, QString>::const_iterator;
   /// Get notified when the system input directories have changed
   Poco::NObserver<SANSRunWindow, Mantid::Kernel::ConfigValChangeNotification>
       m_newInDir;
diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp
index ed5a8be8ee02d33faf3331803801e27007e612a7..20f2186aaee7a4c26a3ba786398b1601c3a7e310 100644
--- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp
+++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp
@@ -63,7 +63,7 @@ AbsorptionCorrections::AbsorptionCorrections(QWidget *parent)
     : CorrectionsTab(parent) {
   m_uiForm.setupUi(parent);
 
-  QRegExp regex("[A-Za-z0-9\\-\\(\\)]*");
+  QRegExp regex(R"([A-Za-z0-9\-\(\)]*)");
   QValidator *formulaValidator = new QRegExpValidator(regex, this);
   m_uiForm.leSampleChemicalFormula->setValidator(formulaValidator);
   m_uiForm.leCanChemicalFormula->setValidator(formulaValidator);
diff --git a/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp
index 3bf5a5a050293e750dff4ee2f5635140a2aed216..5f1dc8ab1079856cad6e539975c8d1a605343c23 100644
--- a/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp
+++ b/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp
@@ -255,7 +255,7 @@ void ApplyAbsorptionCorrections::run() {
                            "Would you like to interpolate this workspace to "
                            "match the sample?";
 
-        result = QMessageBox::question(NULL, tr("Interpolate corrections?"),
+        result = QMessageBox::question(nullptr, tr("Interpolate corrections?"),
                                        tr(text.c_str()), QMessageBox::YesToAll,
                                        QMessageBox::Yes, QMessageBox::No);
       }
diff --git a/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp b/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp
index ed80f16fc2ca9c8af6185ce271bb1696a1c5c4ec..f16c0812867e34d1eca9b1f049b72feb8dc25614 100644
--- a/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp
+++ b/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp
@@ -33,7 +33,7 @@ CalculatePaalmanPings::CalculatePaalmanPings(QWidget *parent)
   connect(m_uiForm.dsSample, SIGNAL(dataReady(const QString &)), this,
           SLOT(fillCorrectionDetails(const QString &)));
 
-  QRegExp regex("[A-Za-z0-9\\-\\(\\)]*");
+  QRegExp regex(R"([A-Za-z0-9\-\(\)]*)");
   QValidator *formulaValidator = new QRegExpValidator(regex, this);
   m_uiForm.leSampleChemicalFormula->setValidator(formulaValidator);
   m_uiForm.leCanChemicalFormula->setValidator(formulaValidator);
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp
index 4928651d5fe6ba5e67cd45cd93b8e98b7b2746c8..f84281861a466f00634e869fda41da46a04dbf12 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp
@@ -709,7 +709,7 @@ double ConvFit::getInstrumentResolution(MatrixWorkspace_sptr workspace) const {
 
     // If the analyser component is not already in the data file then load it
     // from the parameter file
-    if (inst->getComponentByName(analyser) == NULL ||
+    if (inst->getComponentByName(analyser) == nullptr ||
         inst->getComponentByName(analyser)
                 ->getNumberParameter("resolution")
                 .size() == 0) {
@@ -729,7 +729,7 @@ double ConvFit::getInstrumentResolution(MatrixWorkspace_sptr workspace) const {
 
       inst = workspace->getInstrument();
     }
-    if (inst->getComponentByName(analyser) != NULL) {
+    if (inst->getComponentByName(analyser) != nullptr) {
       resolution = inst->getComponentByName(analyser)
                        ->getNumberParameter("resolution")[0];
     } else {
diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp b/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp
index 96eaa31924158e7a5dc03f473eeff255feaf8cb9..df1c5609c6bccf6ed40f65ef5d09bc383940dbfb 100644
--- a/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp
@@ -177,9 +177,9 @@ void IndirectDataReduction::instrumentSetupChanged(
   m_instWorkspace = loadInstrumentIfNotExist(instrumentName.toStdString(),
                                              analyser.toStdString(),
                                              reflection.toStdString());
-  instrumentLoadingDone(m_instWorkspace == NULL);
+  instrumentLoadingDone(m_instWorkspace == nullptr);
 
-  if (m_instWorkspace != NULL)
+  if (m_instWorkspace != nullptr)
     emit newInstrumentConfiguration();
 }
 
@@ -270,14 +270,14 @@ QMap<QString, QString> IndirectDataReduction::getInstrumentDetails() {
   if (instrumentName == "IRIS" && analyser == "fmica")
     analyser = "mica";
 
-  if (m_instWorkspace == NULL) {
+  if (m_instWorkspace == nullptr) {
     g_log.warning("Instrument workspace not loaded");
     return instDetails;
   }
 
   // Get the instrument
   auto instrument = m_instWorkspace->getInstrument();
-  if (instrument == NULL) {
+  if (instrument == nullptr) {
     g_log.warning("Instrument workspace has no instrument");
     return instDetails;
   }
@@ -292,7 +292,7 @@ QMap<QString, QString> IndirectDataReduction::getInstrumentDetails() {
 
       QString value = getInstrumentParameterFrom(instrument, key);
 
-      if (value.isEmpty() && component != NULL)
+      if (value.isEmpty() && component != nullptr)
         value = getInstrumentParameterFrom(component, key);
 
       instDetails[QString::fromStdString(key)] = value;
diff --git a/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp b/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp
index 9c4f85695895eb6e3f3884a0aa3a42d13979b08c..3dac377a3374a2eb209791177383df61bbe2b435 100644
--- a/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp
@@ -163,7 +163,7 @@ void IndirectDiffractionReduction::run() {
  */
 void IndirectDiffractionReduction::algorithmComplete(bool error) {
   // Handles completion of the diffraction algorithm chain
-  disconnect(m_batchAlgoRunner, 0, this, SLOT(algorithmComplete(bool)));
+  disconnect(m_batchAlgoRunner, nullptr, this, SLOT(algorithmComplete(bool)));
 
   // Delete grouping workspace, if created.
   if (AnalysisDataService::Instance().doesExist(m_groupingWsName)) {
diff --git a/qt/scientific_interfaces/Indirect/IndirectTab.cpp b/qt/scientific_interfaces/Indirect/IndirectTab.cpp
index 80374143906b27f01145f021b6425ce7402e2fdf..1518c450d6ad05c5f2c42909df7d14fd5aebaa47 100644
--- a/qt/scientific_interfaces/Indirect/IndirectTab.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectTab.cpp
@@ -112,7 +112,7 @@ void IndirectTab::exportPythonScript() {
   // Create an algorithm dialog for the script export algorithm
   MantidQt::API::InterfaceManager interfaceManager;
   MantidQt::API::AlgorithmDialog *dlg = interfaceManager.createDialogFromName(
-      "GeneratePythonScript", -1, NULL, false, props, "", enabled);
+      "GeneratePythonScript", -1, nullptr, false, props, "", enabled);
 
   // Show the dialog
   dlg->show();
diff --git a/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp b/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp
index 55984fe81316772c4b8928ba3c3b0b39dfb191ae..c02192dea4c1dff197f87730e10811e73d8084a2 100644
--- a/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp
@@ -28,7 +28,7 @@ IndirectTransmissionCalc::IndirectTransmissionCalc(QWidget *parent)
  * Run any tab setup code.
  */
 void IndirectTransmissionCalc::setup() {
-  QRegExp chemicalFormulaRegex("[A-Za-z0-9\\-\\(\\)]*");
+  QRegExp chemicalFormulaRegex(R"([A-Za-z0-9\-\(\)]*)");
   QValidator *chemicalFormulaValidator =
       new QRegExpValidator(chemicalFormulaRegex, this);
   m_uiForm.leChemicalFormula->setValidator(chemicalFormulaValidator);
diff --git a/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h b/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h
index 82e0c41bd81dd7d44502dc86f06bcaaad72e6a2f..dc25f8dd5dc0f17e2f6e5e795ab55557ce1a16b4 100644
--- a/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h
+++ b/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h
@@ -40,7 +40,7 @@ class MANTIDQT_MUONINTERFACE_DLL IALCBaselineModellingModel : public QObject {
   Q_OBJECT
 
 public:
-  typedef std::pair<double, double> Section;
+  using Section = std::pair<double, double>;
 
   /**
    * @return Function produced by the last fit
diff --git a/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h b/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h
index 2a9eb8dbc04ed0c60b0cab89b6f51ccf906e86df..e09dbd73ee6adc1bebe908636066c0b3e9e2c643 100644
--- a/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h
+++ b/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h
@@ -39,8 +39,8 @@ class MANTIDQT_MUONINTERFACE_DLL IALCBaselineModellingView : public QObject {
   Q_OBJECT
 
 public:
-  typedef std::pair<QString, QString> SectionRow;
-  typedef std::pair<double, double> SectionSelector;
+  using SectionRow = std::pair<QString, QString>;
+  using SectionSelector = std::pair<double, double>;
 
   /// Function chosen to fit the data to
   /// @return Function string, or empty string if nothing chosen
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp
index 3aa8a088184bba339ea42a4ecd1d610b8b3deab4..4fb92f80dbf3e040b640069f1108cea4e020507e 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp
@@ -2591,7 +2591,7 @@ void MuonAnalysis::changeTab(int newTabIndex) {
   if (m_currentTab == m_uiForm.DataAnalysis) // Leaving DA tab
   {
     // Say MantidPlot to use default fit prop. browser
-    emit setFitPropertyBrowser(NULL);
+    emit setFitPropertyBrowser(nullptr);
 
     // Reset cached config option
     ConfigService::Instance().setString(PEAK_RADIUS_CONFIG, m_cachedPeakRadius);
@@ -2909,7 +2909,7 @@ void MuonAnalysis::hideEvent(QHideEvent *) {
 
   // If closed while on DA tab, reassign fit property browser to default one
   if (m_currentTab == m_uiForm.DataAnalysis)
-    emit setFitPropertyBrowser(NULL);
+    emit setFitPropertyBrowser(nullptr);
 }
 
 /**
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.ui b/qt/scientific_interfaces/Muon/MuonAnalysis.ui
index 3b593c28acc735b19e9d3702c6b0836a838726d2..ee5436983dc3763f0761ee3a43f7b4201438dbcf 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysis.ui
+++ b/qt/scientific_interfaces/Muon/MuonAnalysis.ui
@@ -2260,7 +2260,7 @@ p, li { white-space: pre-wrap; }
             <property name="minimumSize">
              <size>
               <width>0</width>
-              <height>100</height>
+              <height>140</height>
              </size>
             </property>
             <property name="title">
@@ -2389,6 +2389,12 @@ p, li { white-space: pre-wrap; }
                       <layout class="QGridLayout" name="gridLayout_29">
                        <item row="0" column="0">
                         <widget class="QLabel" name="optionBinStep_3">
+                         <property name="minimumSize">
+                          <size>
+                           <width>20</width>
+                           <height>30</height>
+                          </size>
+                         </property>
                          <property name="toolTip">
                           <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
@@ -2407,7 +2413,14 @@ p, li { white-space: pre-wrap; }
                         </widget>
                        </item>
                        <item row="0" column="1">
-                        <widget class="QLineEdit" name="binBoundaries"/>
+                        <widget class="QLineEdit" name="binBoundaries">
+                         <property name="minimumSize">
+                          <size>
+                           <width>10</width>
+                           <height>10</height>
+                          </size>
+                         </property>
+                        </widget>
                        </item>
                        <item row="0" column="2">
                         <spacer name="horizontalSpacer_8">
@@ -2433,6 +2446,12 @@ p, li { white-space: pre-wrap; }
                            <verstretch>0</verstretch>
                           </sizepolicy>
                          </property>
+                         <property name="minimumSize">
+                          <size>
+                           <width>10</width>
+                           <height>10</height>
+                          </size>
+                         </property>
                          <property name="maximumSize">
                           <size>
                            <width>30</width>
@@ -2641,8 +2660,8 @@ p, li { white-space: pre-wrap; }
                     <rect>
                      <x>0</x>
                      <y>0</y>
-                     <width>131</width>
-                     <height>23</height>
+                     <width>165</width>
+                     <height>26</height>
                     </rect>
                    </property>
                    <layout class="QHBoxLayout" name="horizontalLayout_KeepNPlots">
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp
index 476db8ec0082cd707249b4c479ae0cfe119e580e..866782134b55540c8a9942f3a34d8e18b4de9409 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp
@@ -23,8 +23,8 @@ using Mantid::API::ITableWorkspace;
 using Mantid::API::MatrixWorkspace;
 using Mantid::API::TableRow;
 using Mantid::API::WorkspaceGroup;
-typedef MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType
-    RebinType;
+using RebinType =
+    MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType;
 
 namespace {
 /// static logger
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h
index 22779970184ea3f7b6f4efca0e8e617a01afa5cd..40a92514a7f32844003d396092adcfda1829e031 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h
@@ -11,9 +11,9 @@
 #include <boost/optional/optional.hpp>
 
 /// Save some typing
-typedef std::pair<
+using RebinOptions = std::pair<
     MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType,
-    std::string> RebinOptions;
+    std::string>;
 
 namespace Mantid {
 namespace API {
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
index 152f003d30f5ad3dceaca682ca44e6aef0a61523..52df489c0b3073db1f022853072d3bd6746d2661 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp
@@ -1102,7 +1102,7 @@ getWorkspaceColors(const std::vector<Workspace_sptr> &workspaces) {
   QMap<int, QColor> colors; // position, color
 
   // Vector of <number of runs in fit, parameters in fit> pairs
-  typedef std::pair<size_t, std::vector<std::string>> FitProp;
+  using FitProp = std::pair<size_t, std::vector<std::string>>;
   std::vector<FitProp> fitProperties;
 
   // Get fit properties for each input workspace
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
index e6f4892dc48e12b3980b0653066acf9827a4f77b..4e4a2303fab2b675e1f81aad6b563429238034db 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h
@@ -9,8 +9,8 @@
 
 namespace MantidQt {
 namespace CustomInterfaces {
-typedef QMap<QString, QMap<QString, double>> WSParameterList;
-typedef QMap<QString, QMap<QString, QVariant>> LogValuesMap;
+using WSParameterList = QMap<QString, QMap<QString, double>>;
+using LogValuesMap = QMap<QString, QMap<QString, QVariant>>;
 
 /** MuonAnalysisResultTableCreator : Creates table of muon fit results
   Used in the "result table" tab of Muon Analysis interface
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.cpp
index a495340e88094e9dd6aa23f8565e3022012d2878..e5b520c4e7e78f1c9d054037d44e5d5fbcdc4078 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.cpp
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.cpp
@@ -305,11 +305,22 @@ MuonAnalysisResultTableTab::getMultipleFitWorkspaces(const QString &label,
 
   QStringList workspaces;
 
-  for (auto it = wsNames.begin(); it != wsNames.end(); it++) {
-    if (!isFittedWs(*it))
-      continue; // Doesn't pass basic checks
+  for (auto subGroup = wsNames.begin(); subGroup != wsNames.end(); subGroup++) {
+    auto wsGroup = ads.retrieveWS<WorkspaceGroup>(*subGroup);
+    if (sequential) {
+      std::vector<std::string> tmpNames = wsGroup->getNames();
+      for (auto it = tmpNames.begin(); it != tmpNames.end(); it++) {
+        if (!isFittedWs(*it))
+          continue; // Doesn't pass basic checks
 
-    workspaces << QString::fromStdString(wsBaseName(*it));
+        workspaces << QString::fromStdString(wsBaseName(*it));
+      }
+    } else {
+      if (!isFittedWs(*subGroup))
+        continue; // Doesn't pass basic checks
+
+      workspaces << QString::fromStdString(wsBaseName(*subGroup));
+    }
   }
 
   return workspaces;
diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h
index 0bc9675b88a1901db54c71f2a7352a1001d73a37..a59f0e29be4f13c3dd3f147246d962ee7f08858e 100644
--- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h
+++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h
@@ -16,7 +16,7 @@ class MuonAnalysis;
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace Muon {
-typedef QMap<QString, QMap<QString, double>> WSParameterList;
+using WSParameterList = QMap<QString, QMap<QString, double>>;
 
 /**
 This is a Helper class for MuonAnalysis. In particular this helper class deals
diff --git a/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h b/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h
index 2bc5d686928e0ba79101d0e25c4851e65e1b6fc0..198408673ed03647c5fd6c2da22a96db4e7dae84 100644
--- a/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h
+++ b/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h
@@ -30,7 +30,7 @@ GCC_DIAG_OFF_SUGGEST_OVERRIDE
 class MockALCDataLoadingView : public IALCDataLoadingView {
   // XXX: A workaround, needed because of the way the comma is treated in a
   // macro
-  typedef std::pair<double, double> PAIR_OF_DOUBLES;
+  using PAIR_OF_DOUBLES = std::pair<double, double>;
 
 public:
   MOCK_CONST_METHOD0(firstRun, std::string());
diff --git a/qt/scientific_interfaces/test/EnggDiffGSASFittingModelMock.h b/qt/scientific_interfaces/test/EnggDiffGSASFittingModelMock.h
index c0c652246075b66b551b6dbabae296219e1104de..b62c0cc6cac66efb0765b216836667e9c1eb6b2b 100644
--- a/qt/scientific_interfaces/test/EnggDiffGSASFittingModelMock.h
+++ b/qt/scientific_interfaces/test/EnggDiffGSASFittingModelMock.h
@@ -13,13 +13,8 @@ using namespace MantidQt::CustomInterfaces;
 class MockEnggDiffGSASFittingModel : public IEnggDiffGSASFittingModel {
 
 public:
-  MOCK_METHOD1(doPawleyRefinement,
-               Mantid::API::MatrixWorkspace_sptr(
-                   const GSASIIRefineFitPeaksParameters &params));
-
-  MOCK_METHOD1(doRietveldRefinement,
-               Mantid::API::MatrixWorkspace_sptr(
-                   const GSASIIRefineFitPeaksParameters &params));
+  MOCK_METHOD1(doRefinements,
+               void(const std::vector<GSASIIRefineFitPeaksParameters> &params));
 
   MOCK_CONST_METHOD1(getGamma,
                      boost::optional<double>(const RunLabel &runLabel));
@@ -37,6 +32,9 @@ public:
 
   MOCK_CONST_METHOD1(loadFocusedRun, Mantid::API::MatrixWorkspace_sptr(
                                          const std::string &filename));
+
+  MOCK_METHOD1(setObserver,
+               void(boost::shared_ptr<IEnggDiffGSASFittingObserver> observer));
 };
 
 GCC_DIAG_ON_SUGGEST_OVERRIDE
diff --git a/qt/scientific_interfaces/test/EnggDiffGSASFittingModelTest.h b/qt/scientific_interfaces/test/EnggDiffGSASFittingModelTest.h
index 3fab6902c3f6b3c10cf5394cd1c79b10a7a41724..fe3bf9abed6d5c1d1f1600f4b27d33e57e5b8a1c 100644
--- a/qt/scientific_interfaces/test/EnggDiffGSASFittingModelTest.h
+++ b/qt/scientific_interfaces/test/EnggDiffGSASFittingModelTest.h
@@ -16,12 +16,13 @@ using namespace MantidQt::CustomInterfaces;
 
 namespace { // Helpers
 
-GSASIIRefineFitPeaksParameters createGSASIIRefineFitPeaksParameters(
+std::vector<GSASIIRefineFitPeaksParameters>
+createGSASIIRefineFitPeaksParameters(
     const API::MatrixWorkspace_sptr &inputWS, const RunLabel &runLabel,
     const GSASRefinementMethod &refinementMethod) {
-  return GSASIIRefineFitPeaksParameters(
+  return {GSASIIRefineFitPeaksParameters(
       inputWS, runLabel, refinementMethod, "", std::vector<std::string>({}), "",
-      "", boost::none, boost::none, boost::none, boost::none, false, false);
+      "", boost::none, boost::none, boost::none, boost::none, false, false)};
 }
 
 template <size_t numColumns, size_t numRows>
@@ -53,12 +54,8 @@ public:
 
   void addSigmaValue(const RunLabel &runLabel, const double sigma);
 
-private:
-  inline GSASIIRefineFitPeaksOutputProperties
-  doGSASRefinementAlgorithm(const std::string &fittedPeaksWSName,
-                            const std::string &latticeParamsWSName,
-                            const GSASIIRefineFitPeaksParameters &params,
-                            const std::string &refinementMethod) override;
+  void doRefinements(
+      const std::vector<GSASIIRefineFitPeaksParameters> &params) override;
 };
 
 inline void
@@ -83,15 +80,10 @@ TestEnggDiffGSASFittingModel::addSigmaValue(const RunLabel &runLabel,
   addSigma(runLabel, sigma);
 }
 
-inline GSASIIRefineFitPeaksOutputProperties
-TestEnggDiffGSASFittingModel::doGSASRefinementAlgorithm(
-    const std::string &fittedPeaksWSName,
-    const std::string &latticeParamsWSName,
-    const GSASIIRefineFitPeaksParameters &params,
-    const std::string &refinementMethod) {
+void TestEnggDiffGSASFittingModel::doRefinements(
+    const std::vector<GSASIIRefineFitPeaksParameters> &params) {
   // Mock method - just create some dummy output and ignore all the parameters
   UNUSED_ARG(params);
-  UNUSED_ARG(refinementMethod);
 
   const static std::array<std::string, 3> columnHeadings = {{"a", "b", "c"}};
   const static std::array<std::array<double, 3>, 1> targetTableValues = {
@@ -100,13 +92,14 @@ TestEnggDiffGSASFittingModel::doGSASRefinementAlgorithm(
       createDummyTable(columnHeadings, targetTableValues);
 
   API::AnalysisDataServiceImpl &ADS = API::AnalysisDataService::Instance();
-  ADS.add(latticeParamsWSName, latticeParams);
+  ADS.add("LATTICEPARAMS", latticeParams);
 
   API::MatrixWorkspace_sptr ws =
       WorkspaceCreationHelper::create2DWorkspaceBinned(4, 4, 0.5);
-  ADS.add(fittedPeaksWSName, ws);
+  ADS.add("FITTEDPEAKS", ws);
 
-  return GSASIIRefineFitPeaksOutputProperties(1, 2, 3);
+  processRefinementSuccessful(GSASIIRefineFitPeaksOutputProperties(
+      1, 2, 3, ws, latticeParams, params[0].runLabel));
 }
 
 } // Anonymous namespace
@@ -237,12 +230,9 @@ public:
     API::MatrixWorkspace_sptr inputWS =
         API::WorkspaceFactory::Instance().create("Workspace2D", 1, 10, 10);
 
-    API::MatrixWorkspace_sptr fittedPeaks;
     TS_ASSERT_THROWS_NOTHING(
-        fittedPeaks =
-            model.doPawleyRefinement(createGSASIIRefineFitPeaksParameters(
-                inputWS, runLabel, GSASRefinementMethod::PAWLEY)));
-    TS_ASSERT(fittedPeaks);
+        model.doRefinements(createGSASIIRefineFitPeaksParameters(
+            inputWS, runLabel, GSASRefinementMethod::PAWLEY)));
 
     const auto rwp = model.getRwp(runLabel);
     TS_ASSERT(rwp);
@@ -269,12 +259,9 @@ public:
     API::MatrixWorkspace_sptr inputWS =
         API::WorkspaceFactory::Instance().create("Workspace2D", 1, 10, 10);
 
-    API::MatrixWorkspace_sptr fittedPeaks;
     TS_ASSERT_THROWS_NOTHING(
-        fittedPeaks =
-            model.doRietveldRefinement(createGSASIIRefineFitPeaksParameters(
-                inputWS, runLabel, GSASRefinementMethod::RIETVELD)));
-    TS_ASSERT(fittedPeaks);
+        model.doRefinements(createGSASIIRefineFitPeaksParameters(
+            inputWS, runLabel, GSASRefinementMethod::RIETVELD)));
 
     const auto rwp = model.getRwp(runLabel);
     TS_ASSERT(rwp);
diff --git a/qt/scientific_interfaces/test/EnggDiffGSASFittingPresenterTest.h b/qt/scientific_interfaces/test/EnggDiffGSASFittingPresenterTest.h
index 67c37fda45287617e3658771cf06312e17829191..bac48ed2d771eac38cef7688f446d31faf4e630d 100644
--- a/qt/scientific_interfaces/test/EnggDiffGSASFittingPresenterTest.h
+++ b/qt/scientific_interfaces/test/EnggDiffGSASFittingPresenterTest.h
@@ -68,53 +68,12 @@ public:
         RunLabel(123, 1), GSASRefinementMethod::RIETVELD, "Instrument file",
         {"Phase1", "Phase2"}, "GSASHOME", "GPX.gpx", boost::none, boost::none,
         10000, 40000, true, false);
+    setRefinementParamsExpectations(params);
 
-    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getSelectedRunLabel())
-        .Times(1)
-        .WillOnce(Return(params.runLabel));
-
-    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getFocusedRun(params.runLabel))
-        .Times(1)
-        .WillOnce(Return(params.inputWorkspace));
-    EXPECT_CALL(*m_mockViewPtr, getRefinementMethod())
-        .Times(1)
-        .WillOnce(Return(params.refinementMethod));
-    EXPECT_CALL(*m_mockViewPtr, getInstrumentFileName())
-        .Times(1)
-        .WillOnce(Return(params.instParamsFile));
-    EXPECT_CALL(*m_mockViewPtr, getPhaseFileNames())
-        .Times(1)
-        .WillOnce(Return(params.phaseFiles));
-    EXPECT_CALL(*m_mockViewPtr, getPathToGSASII())
-        .Times(1)
-        .WillOnce(Return(params.gsasHome));
-    EXPECT_CALL(*m_mockViewPtr, getGSASIIProjectPath())
-        .Times(1)
-        .WillOnce(Return(params.gsasProjectFile));
-    EXPECT_CALL(*m_mockViewPtr, getPawleyDMin())
-        .Times(1)
-        .WillOnce(Return(params.dMin));
-    EXPECT_CALL(*m_mockViewPtr, getPawleyNegativeWeight())
-        .Times(1)
-        .WillOnce(Return(params.negativeWeight));
-    EXPECT_CALL(*m_mockViewPtr, getXMin())
-        .Times(1)
-        .WillOnce(Return(params.xMin));
-    EXPECT_CALL(*m_mockViewPtr, getXMax())
-        .Times(1)
-        .WillOnce(Return(params.xMax));
-    EXPECT_CALL(*m_mockViewPtr, getRefineSigma())
-        .Times(1)
-        .WillOnce(Return(params.refineSigma));
-    EXPECT_CALL(*m_mockViewPtr, getRefineGamma())
-        .Times(1)
-        .WillOnce(Return(params.refineGamma));
-
-    EXPECT_CALL(*m_mockModelPtr, doRietveldRefinement(params))
-        .Times(1)
-        .WillOnce(Throw(std::runtime_error("Failure reason")));
-    EXPECT_CALL(*m_mockViewPtr,
-                userError("Refinement failed", "Failure reason"));
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(false)).Times(1);
+    EXPECT_CALL(*m_mockModelPtr,
+                doRefinements(std::vector<GSASIIRefineFitPeaksParameters>(
+                    {params}))).Times(1);
 
     presenter->notify(IEnggDiffGSASFittingPresenter::DoRefinement);
     assertMocksUsedCorrectly();
@@ -128,53 +87,12 @@ public:
         RunLabel(123, 1), GSASRefinementMethod::PAWLEY, "Instrument file",
         {"Phase1", "Phase2"}, "GSASHOME", "GPX.gpx", 1, 2, 10000, 40000, true,
         false);
+    setRefinementParamsExpectations(params);
 
-    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getSelectedRunLabel())
-        .Times(1)
-        .WillOnce(Return(params.runLabel));
-
-    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getFocusedRun(params.runLabel))
-        .Times(1)
-        .WillOnce(Return(params.inputWorkspace));
-    EXPECT_CALL(*m_mockViewPtr, getRefinementMethod())
-        .Times(1)
-        .WillOnce(Return(params.refinementMethod));
-    EXPECT_CALL(*m_mockViewPtr, getInstrumentFileName())
-        .Times(1)
-        .WillOnce(Return(params.instParamsFile));
-    EXPECT_CALL(*m_mockViewPtr, getPhaseFileNames())
-        .Times(1)
-        .WillOnce(Return(params.phaseFiles));
-    EXPECT_CALL(*m_mockViewPtr, getPathToGSASII())
-        .Times(1)
-        .WillOnce(Return(params.gsasHome));
-    EXPECT_CALL(*m_mockViewPtr, getGSASIIProjectPath())
-        .Times(1)
-        .WillOnce(Return(params.gsasProjectFile));
-    EXPECT_CALL(*m_mockViewPtr, getPawleyDMin())
-        .Times(1)
-        .WillOnce(Return(params.dMin));
-    EXPECT_CALL(*m_mockViewPtr, getPawleyNegativeWeight())
-        .Times(1)
-        .WillOnce(Return(params.negativeWeight));
-    EXPECT_CALL(*m_mockViewPtr, getXMin())
-        .Times(1)
-        .WillOnce(Return(params.xMin));
-    EXPECT_CALL(*m_mockViewPtr, getXMax())
-        .Times(1)
-        .WillOnce(Return(params.xMax));
-    EXPECT_CALL(*m_mockViewPtr, getRefineSigma())
-        .Times(1)
-        .WillOnce(Return(params.refineSigma));
-    EXPECT_CALL(*m_mockViewPtr, getRefineGamma())
-        .Times(1)
-        .WillOnce(Return(params.refineGamma));
-
-    EXPECT_CALL(*m_mockModelPtr, doPawleyRefinement(params))
-        .Times(1)
-        .WillOnce(Throw(std::runtime_error("Failure reason")));
-    EXPECT_CALL(*m_mockViewPtr,
-                userError("Refinement failed", "Failure reason"));
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(false)).Times(1);
+    EXPECT_CALL(*m_mockModelPtr,
+                doRefinements(std::vector<GSASIIRefineFitPeaksParameters>(
+                    {params}))).Times(1);
 
     presenter->notify(IEnggDiffGSASFittingPresenter::DoRefinement);
     assertMocksUsedCorrectly();
@@ -251,6 +169,137 @@ public:
     assertMocksUsedCorrectly();
   }
 
+  void test_notifyRefinementFailed() {
+    auto presenter = setUpPresenter();
+    EXPECT_CALL(*m_mockViewPtr,
+                userWarning("Refinement failed", "Failure Reason"));
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(true));
+    EXPECT_CALL(*m_mockViewPtr, showStatus("Refinement failed"));
+
+    presenter->notifyRefinementFailed("Failure Reason");
+    assertMocksUsedCorrectly();
+  }
+
+  void test_notifyRefinementsComplete() {
+    auto presenter = setUpPresenter();
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(true));
+    EXPECT_CALL(*m_mockViewPtr, showStatus("Ready"));
+    presenter->notifyRefinementsComplete();
+    assertMocksUsedCorrectly();
+  }
+
+  void test_notifyRefinementSuccessful() {
+    auto presenter = setUpPresenter();
+    const Mantid::API::MatrixWorkspace_sptr fittedPeaks(
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 100));
+    const auto latticeParams =
+        Mantid::API::WorkspaceFactory::Instance().createTable();
+    const RunLabel runLabel(123, 1);
+    const GSASIIRefineFitPeaksOutputProperties refinementResults(
+        1, 2, 3, fittedPeaks, latticeParams, runLabel);
+
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr,
+                addFittedPeaks(runLabel, fittedPeaks));
+
+    // make sure displayFitResults(runLabel) is getting called
+    EXPECT_CALL(*m_mockModelPtr, getLatticeParams(runLabel))
+        .Times(1)
+        .WillOnce(Return(boost::none));
+    ON_CALL(*m_mockModelPtr, getRwp(runLabel)).WillByDefault(Return(1));
+    ON_CALL(*m_mockModelPtr, getSigma(runLabel)).WillByDefault(Return(1));
+    ON_CALL(*m_mockModelPtr, getGamma(runLabel)).WillByDefault(Return(1));
+
+    presenter->notifyRefinementSuccessful(refinementResults);
+    assertMocksUsedCorrectly();
+  }
+
+  void test_notifyRefinementCancelled() {
+    auto presenter = setUpPresenter();
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(true)).Times(1);
+    EXPECT_CALL(*m_mockViewPtr, showStatus("Ready")).Times(1);
+
+    presenter->notifyRefinementCancelled();
+
+    assertMocksUsedCorrectly();
+  }
+
+  void test_refineAllPassesParamsCorrectlyFromViewToModel() {
+    auto presenter = setUpPresenter();
+
+    const GSASIIRefineFitPeaksParameters params1(
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 100),
+        RunLabel(123, 1), GSASRefinementMethod::RIETVELD, "Instrument file",
+        {"Phase1", "Phase2"}, "GSASHOME", "GPX_123_1.gpx", boost::none,
+        boost::none, 10000, 40000, true, false);
+    const GSASIIRefineFitPeaksParameters params2(
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 200),
+        RunLabel(456, 2), GSASRefinementMethod::RIETVELD, "Instrument file",
+        {"Phase1", "Phase2"}, "GSASHOME", "GPX_456_2.gpx", boost::none,
+        boost::none, 10000, 40000, true, false);
+
+    const std::vector<RunLabel> runLabels({params1.runLabel, params2.runLabel});
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getAllRunLabels())
+        .WillOnce(Return(runLabels));
+
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getFocusedRun(testing::_))
+        .Times(2)
+        .WillOnce(Return(params1.inputWorkspace))
+        .WillOnce(Return(params2.inputWorkspace));
+    EXPECT_CALL(*m_mockViewPtr, getRefinementMethod())
+        .Times(1)
+        .WillOnce(Return(params1.refinementMethod));
+    EXPECT_CALL(*m_mockViewPtr, getInstrumentFileName())
+        .Times(1)
+        .WillOnce(Return(params1.instParamsFile));
+    EXPECT_CALL(*m_mockViewPtr, getPhaseFileNames())
+        .Times(1)
+        .WillOnce(Return(params1.phaseFiles));
+    EXPECT_CALL(*m_mockViewPtr, getPathToGSASII())
+        .Times(1)
+        .WillOnce(Return(params1.gsasHome));
+    EXPECT_CALL(*m_mockViewPtr, getGSASIIProjectPath())
+        .Times(1)
+        .WillOnce(Return("GPX.gpx"));
+    EXPECT_CALL(*m_mockViewPtr, getPawleyDMin())
+        .Times(1)
+        .WillOnce(Return(params1.dMin));
+    EXPECT_CALL(*m_mockViewPtr, getPawleyNegativeWeight())
+        .Times(1)
+        .WillOnce(Return(params1.negativeWeight));
+    EXPECT_CALL(*m_mockViewPtr, getXMin())
+        .Times(1)
+        .WillOnce(Return(params1.xMin));
+    EXPECT_CALL(*m_mockViewPtr, getXMax())
+        .Times(1)
+        .WillOnce(Return(params1.xMax));
+    EXPECT_CALL(*m_mockViewPtr, getRefineSigma())
+        .Times(1)
+        .WillOnce(Return(params1.refineSigma));
+    EXPECT_CALL(*m_mockViewPtr, getRefineGamma())
+        .Times(1)
+        .WillOnce(Return(params1.refineGamma));
+
+    EXPECT_CALL(*m_mockViewPtr, showStatus("Refining run"));
+    EXPECT_CALL(*m_mockViewPtr, setEnabled(false));
+    EXPECT_CALL(*m_mockModelPtr,
+                doRefinements(std::vector<GSASIIRefineFitPeaksParameters>(
+                    {params1, params2})));
+
+    presenter->notify(IEnggDiffGSASFittingPresenter::RefineAll);
+    assertMocksUsedCorrectly();
+  }
+
+  void test_refineAllWarnsIfNoRunsLoaded() {
+    auto presenter = setUpPresenter();
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getAllRunLabels())
+        .WillOnce(Return(std::vector<RunLabel>()));
+    EXPECT_CALL(*m_mockViewPtr,
+                userWarning("No runs loaded",
+                            "Please load at least one run before refining"));
+    presenter->notify(IEnggDiffGSASFittingPresenter::RefineAll);
+    assertMocksUsedCorrectly();
+  }
+
 private:
   MockEnggDiffGSASFittingModel *m_mockModelPtr;
   MockEnggDiffGSASFittingView *m_mockViewPtr;
@@ -283,6 +332,50 @@ private:
       delete m_mockViewPtr;
     }
   }
+
+  void setRefinementParamsExpectations(
+      const GSASIIRefineFitPeaksParameters &params) {
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getSelectedRunLabel())
+        .Times(1)
+        .WillOnce(Return(params.runLabel));
+
+    EXPECT_CALL(*m_mockMultiRunWidgetPtr, getFocusedRun(params.runLabel))
+        .Times(1)
+        .WillOnce(Return(params.inputWorkspace));
+    EXPECT_CALL(*m_mockViewPtr, getRefinementMethod())
+        .Times(1)
+        .WillOnce(Return(params.refinementMethod));
+    EXPECT_CALL(*m_mockViewPtr, getInstrumentFileName())
+        .Times(1)
+        .WillOnce(Return(params.instParamsFile));
+    EXPECT_CALL(*m_mockViewPtr, getPhaseFileNames())
+        .Times(1)
+        .WillOnce(Return(params.phaseFiles));
+    EXPECT_CALL(*m_mockViewPtr, getPathToGSASII())
+        .Times(1)
+        .WillOnce(Return(params.gsasHome));
+    EXPECT_CALL(*m_mockViewPtr, getGSASIIProjectPath())
+        .Times(1)
+        .WillOnce(Return(params.gsasProjectFile));
+    EXPECT_CALL(*m_mockViewPtr, getPawleyDMin())
+        .Times(1)
+        .WillOnce(Return(params.dMin));
+    EXPECT_CALL(*m_mockViewPtr, getPawleyNegativeWeight())
+        .Times(1)
+        .WillOnce(Return(params.negativeWeight));
+    EXPECT_CALL(*m_mockViewPtr, getXMin())
+        .Times(1)
+        .WillOnce(Return(params.xMin));
+    EXPECT_CALL(*m_mockViewPtr, getXMax())
+        .Times(1)
+        .WillOnce(Return(params.xMax));
+    EXPECT_CALL(*m_mockViewPtr, getRefineSigma())
+        .Times(1)
+        .WillOnce(Return(params.refineSigma));
+    EXPECT_CALL(*m_mockViewPtr, getRefineGamma())
+        .Times(1)
+        .WillOnce(Return(params.refineGamma));
+  }
 };
 
 #endif // MANTID_CUSTOM_INTERFACES_ENGGDIFFGSASFITTINGPRESENTERTEST_H_
diff --git a/qt/scientific_interfaces/test/EnggDiffGSASFittingViewMock.h b/qt/scientific_interfaces/test/EnggDiffGSASFittingViewMock.h
index e7cfb6692de4ed44d53fe23863457c2d93d24596..09f5e555c7c33ae3f450e7ba71dfe211d8f705df 100644
--- a/qt/scientific_interfaces/test/EnggDiffGSASFittingViewMock.h
+++ b/qt/scientific_interfaces/test/EnggDiffGSASFittingViewMock.h
@@ -57,6 +57,8 @@ public:
 
   MOCK_METHOD0(resetCanvas, void());
 
+  MOCK_METHOD1(setEnabled, void(const bool));
+
   MOCK_CONST_METHOD0(showRefinementResultsSelected, bool());
 
   MOCK_CONST_METHOD1(showStatus, void(const std::string &status));
diff --git a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterMock.h b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterMock.h
index ffedca6d4bfebed9c4f5fd9b29f958c9dc7e48ad..50337ef87189eedfc991c0a8ee79b8ef21119b24 100644
--- a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterMock.h
+++ b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterMock.h
@@ -20,6 +20,8 @@ public:
 
   MOCK_METHOD1(addFocusedRun, void(const Mantid::API::MatrixWorkspace_sptr ws));
 
+  MOCK_CONST_METHOD0(getAllRunLabels, std::vector<RunLabel>());
+
   MOCK_CONST_METHOD1(getFittedPeaks,
                      boost::optional<Mantid::API::MatrixWorkspace_sptr>(
                          const RunLabel &runLabel));
diff --git a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterTest.h b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterTest.h
index 486aba4be82b990cf0d797568ef91f1b16bb2e04..81532e7c508588278e66ddeee309a42adabff8cf 100644
--- a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterTest.h
+++ b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetPresenterTest.h
@@ -352,6 +352,13 @@ public:
     assertMocksUsedCorrectly();
   }
 
+  void test_getAllRunLabelsDelegatesToView() {
+    auto presenter = setUpPresenter();
+    EXPECT_CALL(*m_mockView, getAllRunLabels());
+    presenter->getAllRunLabels();
+    assertMocksUsedCorrectly();
+  }
+
 private:
   MockEnggDiffMultiRunFittingWidgetModel *m_mockModel;
   MockEnggDiffMultiRunFittingWidgetView *m_mockView;
diff --git a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetViewMock.h b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetViewMock.h
index 064394c78fcc1bfa84481ba15a958ac653c1891b..6539ebe625d730eff67805ae8e305a163c321645 100644
--- a/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetViewMock.h
+++ b/qt/scientific_interfaces/test/EnggDiffMultiRunFittingWidgetViewMock.h
@@ -16,6 +16,8 @@ class MockEnggDiffMultiRunFittingWidgetView
     : public IEnggDiffMultiRunFittingWidgetView {
 
 public:
+  MOCK_CONST_METHOD0(getAllRunLabels, std::vector<RunLabel>());
+
   MOCK_CONST_METHOD0(getSelectedRunLabel, boost::optional<RunLabel>());
 
   MOCK_METHOD1(plotFittedPeaks,
@@ -36,6 +38,8 @@ public:
 
   MOCK_METHOD0(resetCanvas, void());
 
+  MOCK_METHOD1(setEnabled, void(const bool));
+
   MOCK_METHOD1(
       setMessageProvider,
       void(boost::shared_ptr<IEnggDiffractionUserMsg> messageProvider));
diff --git a/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h b/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h
index ff0ffe24258073e7fada37da00846265719b6590..98bfaf2258929465bf23f85077de9df9aca3dcd5 100644
--- a/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h
+++ b/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h
@@ -245,7 +245,7 @@ public:
   void test_setAssignedFirstRun_loadCurrentRun() {
     setupGroupPeriodSelections();
     const boost::optional<QString> currentRunPath{
-        "\\\\musr\\data\\MUSRauto_A.tmp"};
+        R"(\\musr\data\MUSRauto_A.tmp)"};
     const QString wsName("MUSR00061335; Pair; long; Asym; 1; #1");
     EXPECT_CALL(*m_dataSelector,
                 setWorkspaceDetails(QString("00061335"), QString("MUSR"),
@@ -706,7 +706,7 @@ public:
     const QString wsName("MUSR00061335; Group; fwd; Asym; 1; #1");
     const QStringList wsNameList{wsName};
     const boost::optional<QString> currentRunPath{
-        "\\\\musr\\data\\MUSRauto_A.tmp"};
+        R"(\\musr\data\MUSRauto_A.tmp)"};
 
     // Expect it will update the workspace names
     EXPECT_CALL(*m_fitBrowser, setWorkspaceNames(wsNameList)).Times(1);
diff --git a/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h b/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h
index 881f5075a80f321a725b5a5321ed624af6154eca..4783012bd66854395344a828f6f5b729042144cd 100644
--- a/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h
+++ b/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h
@@ -220,7 +220,7 @@ public:
     TS_ASSERT(workspaceExists("TOF_13462_monitors"));
     TS_ASSERT(workspaceExists("TRANS_13463"));
     TS_ASSERT(workspaceExists("TRANS_13464"));
-    TS_ASSERT(workspaceExists("TRANS_13463+13464"));
+    TS_ASSERT(workspaceExists("TRANS_13463_13464"));
 
     // Tidy up
     AnalysisDataService::Instance().clear();
@@ -303,7 +303,7 @@ public:
     TS_ASSERT(workspaceExists("TOF_13462_monitors"));
     TS_ASSERT(workspaceExists("TRANS_13463"));
     TS_ASSERT(workspaceExists("TRANS_13464"));
-    TS_ASSERT(workspaceExists("TRANS_13463+13464"));
+    TS_ASSERT(workspaceExists("TRANS_13463_13464"));
 
     // Tidy up
     AnalysisDataService::Instance().clear();
@@ -380,7 +380,7 @@ public:
     TS_ASSERT(workspaceExists("TOF_13462_monitors"));
     TS_ASSERT(workspaceExists("TRANS_13463"));
     TS_ASSERT(workspaceExists("TRANS_13464"));
-    TS_ASSERT(workspaceExists("TRANS_13463+13464"));
+    TS_ASSERT(workspaceExists("TRANS_13463_13464"));
 
     // Tidy up
     AnalysisDataService::Instance().clear();
@@ -456,7 +456,7 @@ public:
     TS_ASSERT(workspaceExists("TOF_13462_monitors"));
     TS_ASSERT(workspaceExists("TRANS_13463"));
     TS_ASSERT(workspaceExists("TRANS_13464"));
-    TS_ASSERT(workspaceExists("TRANS_13463+13464"));
+    TS_ASSERT(workspaceExists("TRANS_13463_13464"));
 
     // Tidy up
     AnalysisDataService::Instance().clear();
diff --git a/qt/scientific_interfaces/test/ReflEventPresenterTest.h b/qt/scientific_interfaces/test/ReflEventPresenterTest.h
index 1b609697e0b517d7c69281441d27911e4ad0de68..e52f24ad56035992331094aa32607bee3496344d 100644
--- a/qt/scientific_interfaces/test/ReflEventPresenterTest.h
+++ b/qt/scientific_interfaces/test/ReflEventPresenterTest.h
@@ -26,40 +26,50 @@ public:
 
   ReflEventPresenterTest() {}
 
-  void test_get_slicing_values() {
+  void testDefaultGetSlicingValues() {
     MockEventView mockView;
     ReflEventPresenter presenter(&mockView);
 
-    EXPECT_CALL(mockView, getTimeSlicingValues()).Times(Exactly(1));
+    EXPECT_CALL(mockView, getUniformEvenTimeSlicingValues()).Times(Exactly(1));
     presenter.getTimeSlicingValues();
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
   }
 
-  void test_get_slicing_type() {
+  void testGetSlicingType() {
     MockEventView mockView;
     ReflEventPresenter presenter(&mockView);
+    presenter.notifySliceTypeChanged(SliceType::LogValue);
+    TS_ASSERT_EQUALS("LogValue", presenter.getTimeSlicingType());
+  }
+
+  void testDisablesControlsOnReductionResumed() {
+    MockEventView mockView;
+    ReflEventPresenter presenter(&mockView);
+    EXPECT_CALL(mockView, disableSliceType(_)).Times(AtLeast(1));
+    EXPECT_CALL(mockView, disableSliceTypeSelection()).Times(AtLeast(1));
 
-    EXPECT_CALL(mockView, getTimeSlicingType()).Times(Exactly(1));
-    presenter.getTimeSlicingType();
+    presenter.onReductionResumed();
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
   }
 
-  void testDisablesControlsOnReductionResumed() {
+  void testDisablesCorrectControlsOnReductionResumed() {
     MockEventView mockView;
     ReflEventPresenter presenter(&mockView);
-    EXPECT_CALL(mockView, disableAll()).Times(AtLeast(1));
+    presenter.notifySliceTypeChanged(SliceType::Custom);
+    EXPECT_CALL(mockView, disableSliceType(SliceType::Custom))
+        .Times(AtLeast(1));
 
     presenter.onReductionResumed();
-
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
   }
 
-  void testEnabledControlsOnReductionPaused() {
+  void testEnablesControlsOnReductionPaused() {
     MockEventView mockView;
     ReflEventPresenter presenter(&mockView);
-    EXPECT_CALL(mockView, enableAll()).Times(AtLeast(1));
+    EXPECT_CALL(mockView, enableSliceType(SliceType::UniformEven))
+        .Times(AtLeast(1));
 
     presenter.onReductionPaused();
 
diff --git a/qt/scientific_interfaces/test/ReflMainWindowPresenterTest.h b/qt/scientific_interfaces/test/ReflMainWindowPresenterTest.h
index e4638da9685aee3a1ca1f9eb8e06153b4ebbaa42..327fe54a8926c643c65d61844923c80371c08325 100644
--- a/qt/scientific_interfaces/test/ReflMainWindowPresenterTest.h
+++ b/qt/scientific_interfaces/test/ReflMainWindowPresenterTest.h
@@ -6,6 +6,7 @@
 #include <gtest/gtest.h>
 
 #include "../ISISReflectometry/ReflMainWindowPresenter.h"
+#include "MantidKernel/make_unique.h"
 #include "ReflMockObjects.h"
 
 using namespace MantidQt::CustomInterfaces;
@@ -33,10 +34,11 @@ public:
     MockRunsTabPresenter mockRunsTabPresenter;
     MockEventTabPresenter mockEventTabPresenter;
     MockSettingsTabPresenter mockSettingsTabPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsTabPresenter, &mockEventTabPresenter,
-        &mockSettingsTabPresenter, &mockSaveTabPresenter);
+        &mockSettingsTabPresenter, std::move(mockSaveTabPresenter));
 
     // Should call the settings tab to get the values
     double angle = 0.5;
@@ -60,10 +62,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     // Should call the settings tab to get the options
     EXPECT_CALL(mockSettingsPresenter, getTransmissionOptions(0))
@@ -85,10 +88,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     // Should call the settings tab to get the options
     EXPECT_CALL(mockSettingsPresenter, getReductionOptions(0))
@@ -111,10 +115,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     // Should call the settings tab to get the options
     EXPECT_CALL(mockSettingsPresenter, getStitchOptions(0)).Times(Exactly(1));
@@ -131,10 +136,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     EXPECT_CALL(mockView, giveUserCritical("Prompt", "Title"))
         .Times(Exactly(1));
@@ -147,10 +153,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     EXPECT_CALL(mockView, giveUserInfo("Prompt", "Title")).Times(Exactly(1));
     presenter.giveUserInfo("Prompt", "Title");
@@ -162,10 +169,11 @@ public:
     MockRunsTabPresenter mockRunsPresenter;
     MockEventTabPresenter mockEventPresenter;
     MockSettingsTabPresenter mockSettingsPresenter;
-    MockSaveTabPresenter mockSaveTabPresenter;
+    auto mockSaveTabPresenter =
+        Mantid::Kernel::make_unique<MockSaveTabPresenter>();
     ReflMainWindowPresenter presenter(
         &mockView, &mockRunsPresenter, &mockEventPresenter,
-        &mockSettingsPresenter, &mockSaveTabPresenter);
+        &mockSettingsPresenter, std::move(mockSaveTabPresenter));
 
     EXPECT_CALL(mockView, runPythonAlgorithm("Python code to run"))
         .Times(Exactly(1));
diff --git a/qt/scientific_interfaces/test/ReflMockObjects.h b/qt/scientific_interfaces/test/ReflMockObjects.h
index 2f26bf30bba4ce23dd7530e3fdd1fab239a50aab..cf32ed1e2c17e5179793d8c4e9853ff0f9a409e0 100644
--- a/qt/scientific_interfaces/test/ReflMockObjects.h
+++ b/qt/scientific_interfaces/test/ReflMockObjects.h
@@ -20,8 +20,10 @@
 #include "../ISISReflectometry/ReflSearchModel.h"
 #include "../ISISReflectometry/ExperimentOptionDefaults.h"
 #include "../ISISReflectometry/InstrumentOptionDefaults.h"
+#include "../ISISReflectometry/IReflAsciiSaver.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/Command.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/OptionsMap.h"
+#include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
 #include <gmock/gmock.h>
 
 using namespace MantidQt::CustomInterfaces;
@@ -130,10 +132,15 @@ public:
 class MockEventView : public IReflEventView {
 public:
   // Global options
-  MOCK_CONST_METHOD0(getTimeSlicingValues, std::string());
-  MOCK_CONST_METHOD0(getTimeSlicingType, std::string());
-  MOCK_METHOD0(enableAll, void());
-  MOCK_METHOD0(disableAll, void());
+  MOCK_METHOD1(enableSliceType, void(SliceType));
+  MOCK_METHOD1(disableSliceType, void(SliceType));
+  MOCK_METHOD0(enableSliceTypeSelection, void());
+  MOCK_METHOD0(disableSliceTypeSelection, void());
+  MOCK_CONST_METHOD0(getLogValueTimeSlicingValues, std::string());
+  MOCK_CONST_METHOD0(getCustomTimeSlicingValues, std::string());
+  MOCK_CONST_METHOD0(getUniformTimeSlicingValues, std::string());
+  MOCK_CONST_METHOD0(getUniformEvenTimeSlicingValues, std::string());
+  MOCK_CONST_METHOD0(getLogValueTimeSlicingType, std::string());
 
   // Calls we don't care about
   IReflEventPresenter *getPresenter() const override { return nullptr; }
@@ -157,9 +164,17 @@ public:
   MOCK_CONST_METHOD1(setWorkspaceList, void(const std::vector<std::string> &));
   MOCK_CONST_METHOD0(clearParametersList, void());
   MOCK_CONST_METHOD1(setParametersList, void(const std::vector<std::string> &));
-
-  // Calls we don't care about
-  IReflSaveTabPresenter *getPresenter() const override { return nullptr; }
+  MOCK_CONST_METHOD0(getAutosavePrefixInput, std::string());
+  MOCK_METHOD1(subscribe, void(IReflSaveTabPresenter *));
+  MOCK_METHOD0(disallowAutosave, void());
+  MOCK_METHOD0(disableAutosaveControls, void());
+  MOCK_METHOD0(enableAutosaveControls, void());
+  MOCK_METHOD0(enableFileFormatAndLocationControls, void());
+  MOCK_METHOD0(disableFileFormatAndLocationControls, void());
+  MOCK_METHOD2(giveUserCritical,
+               void(const std::string &, const std::string &));
+  MOCK_METHOD2(giveUserInfo, void(const std::string &, const std::string &));
+  virtual ~MockSaveTabView() = default;
 };
 
 class MockMainWindowView : public IReflMainWindowView {
@@ -195,6 +210,7 @@ public:
   MOCK_CONST_METHOD0(getTimeSlicingType, std::string());
   MOCK_METHOD0(onReductionPaused, void());
   MOCK_METHOD0(onReductionResumed, void());
+  MOCK_METHOD1(notifySliceTypeChanged, void(SliceType));
   ~MockEventPresenter() override{};
 };
 
@@ -253,6 +269,12 @@ public:
 
 class MockSaveTabPresenter : public IReflSaveTabPresenter {
 public:
+  MOCK_METHOD2(completedRowReductionSuccessfully,
+               void(MantidQt::MantidWidgets::DataProcessor::GroupData const &,
+                    std::string const &));
+  MOCK_METHOD2(completedGroupReductionSuccessfully,
+               void(MantidQt::MantidWidgets::DataProcessor::GroupData const &,
+                    std::string const &));
   void notify(IReflSaveTabPresenter::Flag flag) override { UNUSED_ARG(flag); };
   void acceptMainPresenter(IReflMainWindowPresenter *presenter) override {
     UNUSED_ARG(presenter);
@@ -272,6 +294,12 @@ public:
   MOCK_CONST_METHOD1(getStitchOptions, std::string(int));
   MOCK_CONST_METHOD1(setInstrumentName, void(const std::string &instName));
   MOCK_CONST_METHOD0(getInstrumentName, std::string());
+  MOCK_METHOD2(completedRowReductionSuccessfully,
+               void(MantidQt::MantidWidgets::DataProcessor::GroupData const &,
+                    std::string const &));
+  MOCK_METHOD2(completedGroupReductionSuccessfully,
+               void(MantidQt::MantidWidgets::DataProcessor::GroupData const &,
+                    std::string const &));
   MOCK_METHOD1(notify, void(IReflMainWindowPresenter::Flag));
   MOCK_METHOD1(notifyReductionPaused, void(int));
   MOCK_METHOD1(notifyReductionResumed, void(int));
@@ -323,6 +351,16 @@ public:
   ~MockICatalogInfo() override {}
 };
 
+class MockReflAsciiSaver : public IReflAsciiSaver {
+public:
+  MOCK_CONST_METHOD1(isValidSaveDirectory, bool(std::string const &));
+  MOCK_CONST_METHOD4(save,
+                     void(std::string const &, std::vector<std::string> const &,
+                          std::vector<std::string> const &,
+                          FileFormatOptions const &));
+  virtual ~MockReflAsciiSaver() = default;
+};
+
 GCC_DIAG_ON_SUGGEST_OVERRIDE
 
 #endif /*MANTID_CUSTOMINTERFACES_REFLMOCKOBJECTS_H*/
diff --git a/qt/scientific_interfaces/test/ReflSaveTabPresenterTest.h b/qt/scientific_interfaces/test/ReflSaveTabPresenterTest.h
index b41f6c4613c6cb6ef12944ab16a4b6c8b8bdd420..62a625240ac686d2ff49da15be5a9ef666d2f8e6 100644
--- a/qt/scientific_interfaces/test/ReflSaveTabPresenterTest.h
+++ b/qt/scientific_interfaces/test/ReflSaveTabPresenterTest.h
@@ -10,6 +10,8 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/make_unique.h"
 #include "MantidAPI/Run.h"
 #include "ReflMockObjects.h"
 #include "Poco/File.h"
@@ -36,9 +38,18 @@ public:
 
   ReflSaveTabPresenterTest() { FrameworkManager::Instance(); }
 
+  bool verifyAndClearMocks() {
+    auto metViewExpections = Mock::VerifyAndClearExpectations(m_mockViewPtr);
+    TS_ASSERT(metViewExpections);
+    auto metSaverExpectations =
+        Mock::VerifyAndClearExpectations(m_mockSaverPtr);
+    TS_ASSERT(metSaverExpectations);
+    return metViewExpections && metSaverExpectations;
+  }
+
   void testPopulateWorkspaceList() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     std::vector<std::string> wsNames = {"ws1", "ws2", "ws3"};
     createWS(wsNames[0]);
@@ -53,89 +64,151 @@ public:
     groupAlg->setProperty("OutputWorkspace", "groupWs");
     groupAlg->execute();
 
-    EXPECT_CALL(mockView, clearWorkspaceList()).Times(Exactly(1));
+    EXPECT_CALL(*m_mockViewPtr, clearWorkspaceList()).Times(Exactly(1));
     // Workspaces 'groupWs' and 'tableWS' should not be included in the
     // workspace list
-    EXPECT_CALL(mockView, setWorkspaceList(wsNames)).Times(Exactly(1));
+    EXPECT_CALL(*m_mockViewPtr, setWorkspaceList(wsNames)).Times(Exactly(1));
     presenter.notify(IReflSaveTabPresenter::populateWorkspaceListFlag);
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+
+    TS_ASSERT(verifyAndClearMocks());
+  }
+
+  void testDisablesAutosaveControlsWhenProcessing() {
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
+
+    EXPECT_CALL(*m_mockViewPtr, disableAutosaveControls());
+    presenter.onAnyReductionResumed();
+
+    TS_ASSERT(verifyAndClearMocks());
+  }
+
+  void expectHasValidSaveDirectory(MockReflAsciiSaver &m_mockSaver) {
+    ON_CALL(m_mockSaver, isValidSaveDirectory(_)).WillByDefault(Return(true));
+  }
+
+  void testDisablesFileFormatControlsWhenProcessingAndAutosaveEnabled() {
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
+
+    expectHasValidSaveDirectory(*m_mockSaverPtr);
+    presenter.notify(IReflSaveTabPresenter::Flag::autosaveEnabled);
+
+    EXPECT_CALL(*m_mockViewPtr, disableFileFormatAndLocationControls());
+    presenter.onAnyReductionResumed();
+
+    TS_ASSERT(verifyAndClearMocks());
+  }
+
+  void testEnablesFileFormatControlsWhenProcessingFinishedAndAutosaveEnabled() {
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
+
+    expectHasValidSaveDirectory(*m_mockSaverPtr);
+    presenter.notify(IReflSaveTabPresenter::Flag::autosaveEnabled);
+    presenter.onAnyReductionResumed();
+
+    EXPECT_CALL(*m_mockViewPtr, enableFileFormatAndLocationControls());
+    presenter.onAnyReductionPaused();
+
+    TS_ASSERT(verifyAndClearMocks());
+  }
+
+  void testEnablesAutosaveControlsWhenProcessingFinished() {
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
+
+    expectHasValidSaveDirectory(*m_mockSaverPtr);
+    presenter.notify(IReflSaveTabPresenter::Flag::autosaveEnabled);
+
+    presenter.onAnyReductionResumed();
+    EXPECT_CALL(*m_mockViewPtr, enableFileFormatAndLocationControls());
+    presenter.onAnyReductionPaused();
+
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testRefreshWorkspaceList() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     createWS("ws1");
 
-    EXPECT_CALL(mockView, clearWorkspaceList()).Times(Exactly(2));
-    EXPECT_CALL(mockView, setWorkspaceList(std::vector<std::string>{"ws1"}))
+    EXPECT_CALL(*m_mockViewPtr, clearWorkspaceList()).Times(Exactly(2));
+    EXPECT_CALL(*m_mockViewPtr,
+                setWorkspaceList(std::vector<std::string>{"ws1"}))
         .Times(Exactly(1));
-    EXPECT_CALL(mockView,
+    EXPECT_CALL(*m_mockViewPtr,
                 setWorkspaceList(std::vector<std::string>{"ws1", "ws2"}))
         .Times(Exactly(1));
     presenter.notify(IReflSaveTabPresenter::populateWorkspaceListFlag);
     createWS("ws2");
     presenter.notify(IReflSaveTabPresenter::populateWorkspaceListFlag);
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testFilterWorkspaceNoRegex() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     createWS("anotherWs");
     createWS("different");
     createWS("someWsName");
 
-    EXPECT_CALL(mockView, clearWorkspaceList()).Times(Exactly(2));
-    EXPECT_CALL(mockView, setWorkspaceList(std::vector<std::string>{
-                              "anotherWs", "different", "someWsName"}))
+    EXPECT_CALL(*m_mockViewPtr, clearWorkspaceList()).Times(Exactly(2));
+    EXPECT_CALL(*m_mockViewPtr, setWorkspaceList(std::vector<std::string>{
+                                    "anotherWs", "different", "someWsName"}))
         .Times(Exactly(1));
-    EXPECT_CALL(mockView, getFilter()).Times(Exactly(1)).WillOnce(Return("Ws"));
-    EXPECT_CALL(mockView, getRegexCheck())
+    EXPECT_CALL(*m_mockViewPtr, getFilter())
+        .Times(Exactly(1))
+        .WillOnce(Return("Ws"));
+    EXPECT_CALL(*m_mockViewPtr, getRegexCheck())
         .Times(Exactly(1))
         .WillOnce(Return(false));
-    EXPECT_CALL(mockView, setWorkspaceList(std::vector<std::string>{
-                              "anotherWs", "someWsName"})).Times(Exactly(1));
+    EXPECT_CALL(*m_mockViewPtr, setWorkspaceList(std::vector<std::string>{
+                                    "anotherWs", "someWsName"}))
+        .Times(Exactly(1));
     presenter.notify(IReflSaveTabPresenter::populateWorkspaceListFlag);
     presenter.notify(IReflSaveTabPresenter::filterWorkspaceListFlag);
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testFilterWorkspaceWithRegex() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     createWS("_42");
     createWS("apple_113");
     createWS("grape_");
     createWS("pear_cut");
 
-    EXPECT_CALL(mockView, clearWorkspaceList()).Times(Exactly(2));
-    EXPECT_CALL(mockView, setWorkspaceList(std::vector<std::string>{
-                              "_42", "apple_113", "grape_", "pear_cut"}))
+    EXPECT_CALL(*m_mockViewPtr, clearWorkspaceList()).Times(Exactly(2));
+    EXPECT_CALL(*m_mockViewPtr, setWorkspaceList(std::vector<std::string>{
+                                    "_42", "apple_113", "grape_", "pear_cut"}))
         .Times(Exactly(1));
-    EXPECT_CALL(mockView, getFilter())
+    EXPECT_CALL(*m_mockViewPtr, getFilter())
         .Times(Exactly(1))
         .WillOnce(Return("[a-zA-Z]*_[0-9]+"));
-    EXPECT_CALL(mockView, getRegexCheck())
+    EXPECT_CALL(*m_mockViewPtr, getRegexCheck())
         .Times(Exactly(1))
         .WillOnce(Return(true));
-    EXPECT_CALL(mockView,
+    EXPECT_CALL(*m_mockViewPtr,
                 setWorkspaceList(std::vector<std::string>{"_42", "apple_113"}))
         .Times(Exactly(1));
     presenter.notify(IReflSaveTabPresenter::populateWorkspaceListFlag);
     presenter.notify(IReflSaveTabPresenter::filterWorkspaceListFlag);
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testPopulateParametersList() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     createWS("ws1");
     std::vector<std::string> logs;
@@ -147,69 +220,84 @@ public:
       logs.push_back((*it)->name());
     }
 
-    EXPECT_CALL(mockView, clearParametersList()).Times(Exactly(1));
-    EXPECT_CALL(mockView, getCurrentWorkspaceName())
+    EXPECT_CALL(*m_mockViewPtr, clearParametersList()).Times(Exactly(1));
+    EXPECT_CALL(*m_mockViewPtr, getCurrentWorkspaceName())
         .Times(Exactly(1))
         .WillOnce(Return("ws1"));
-    EXPECT_CALL(mockView, setParametersList(logs)).Times(Exactly(1));
+    EXPECT_CALL(*m_mockViewPtr, setParametersList(logs)).Times(Exactly(1));
     presenter.notify(IReflSaveTabPresenter::workspaceParamsFlag);
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testSaveWorkspaces() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
-    std::string savePath = createSavePath();
     std::vector<std::string> wsNames = {"ws1", "ws2", "ws3"};
     createWS(wsNames[0]);
     createWS(wsNames[1]);
     createWS(wsNames[2]);
 
-    EXPECT_CALL(mockView, getSavePath())
-        .Times(Exactly(1))
-        .WillOnce(Return(savePath));
-    EXPECT_CALL(mockView, getTitleCheck())
-        .Times(Exactly(1))
-        .WillOnce(Return(false));
-    EXPECT_CALL(mockView, getSelectedParameters())
-        .Times(Exactly(1))
-        .WillOnce(Return(std::vector<std::string>()));
-    EXPECT_CALL(mockView, getQResolutionCheck())
-        .Times(Exactly(1))
-        .WillOnce(Return(false));
-    EXPECT_CALL(mockView, getSeparator())
+    EXPECT_CALL(*m_mockViewPtr, getSavePath()).Times(AtLeast(1));
+    EXPECT_CALL(*m_mockViewPtr, getTitleCheck())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(*m_mockViewPtr, getSelectedParameters())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(std::vector<std::string>()));
+    EXPECT_CALL(*m_mockViewPtr, getQResolutionCheck())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(*m_mockViewPtr, getSeparator())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return("comma"));
+    EXPECT_CALL(*m_mockViewPtr, getPrefix())
         .Times(Exactly(1))
-        .WillOnce(Return("comma"));
-    EXPECT_CALL(mockView, getPrefix()).Times(Exactly(1)).WillOnce(Return(""));
-    EXPECT_CALL(mockView, getFileFormatIndex())
-        .Times(Exactly(1))
-        .WillOnce(Return(0));
-    EXPECT_CALL(mockView, getSelectedWorkspaces())
-        .Times(Exactly(1))
-        .WillOnce(Return(wsNames));
+        .WillOnce(Return(""));
+    EXPECT_CALL(*m_mockViewPtr, getFileFormatIndex())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(0));
+    EXPECT_CALL(*m_mockViewPtr, getSelectedWorkspaces())
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(wsNames));
+
+    EXPECT_CALL(*m_mockSaverPtr, isValidSaveDirectory(_))
+        .Times(AtLeast(1))
+        .WillRepeatedly(Return(true));
+    EXPECT_CALL(*m_mockSaverPtr, save(_, _, _, _)).Times(AtLeast(1));
+
     presenter.notify(IReflSaveTabPresenter::saveWorkspacesFlag);
-    for (auto it = wsNames.begin(); it != wsNames.end(); it++) {
-      Poco::File(savePath + *it + ".dat").remove();
-    }
+
     AnalysisDataService::Instance().clear();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+    TS_ASSERT(verifyAndClearMocks());
   }
 
   void testSuggestSaveDir() {
-    MockSaveTabView mockView;
-    ReflSaveTabPresenter presenter(&mockView);
+    ReflSaveTabPresenter presenter(std::move(m_mockSaver),
+                                   std::move(m_mockView));
 
     std::string saveDir = Mantid::Kernel::ConfigService::Instance().getString(
         "defaultsave.directory");
 
-    EXPECT_CALL(mockView, setSavePath(saveDir));
+    EXPECT_CALL(*m_mockViewPtr, setSavePath(saveDir));
     presenter.notify(IReflSaveTabPresenter::suggestSaveDirFlag);
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+    TS_ASSERT(verifyAndClearMocks());
   }
 
 private:
+  std::unique_ptr<NiceMock<MockReflAsciiSaver>> m_mockSaver;
+  NiceMock<MockReflAsciiSaver> *m_mockSaverPtr;
+  std::unique_ptr<MockSaveTabView> m_mockView;
+  MockSaveTabView *m_mockViewPtr;
+
+  void setUp() override {
+    m_mockSaver = Mantid::Kernel::make_unique<NiceMock<MockReflAsciiSaver>>();
+    m_mockSaverPtr = m_mockSaver.get();
+    m_mockView = Mantid::Kernel::make_unique<MockSaveTabView>();
+    m_mockViewPtr = m_mockView.get();
+  }
+
   void createWS(std::string name) {
     Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(name, ws);
@@ -220,17 +308,6 @@ private:
         WorkspaceFactory::Instance().createTable("TableWorkspace");
     AnalysisDataService::Instance().addOrReplace(name, ws);
   }
-
-  std::string createSavePath() {
-    // First attempt to obtain path from default save directory
-    std::string savePath = Mantid::Kernel::ConfigService::Instance().getString(
-        "defaultsave.directory");
-    if (savePath.empty())
-      // Otherwise use current path as save directory
-      savePath = Poco::Path::current();
-
-    return savePath;
-  }
 };
 
 #endif /* MANTID_CUSTOMINTERFACES_REFLSAVETABPRESENTERTEST_H */
diff --git a/qt/widgets/common/CMakeLists.txt b/qt/widgets/common/CMakeLists.txt
index 2a25dd34ccdcb981b9403f6316671522ca51095f..9f5d9147edf10fb8b5d7f8d8560ba517704146a4 100644
--- a/qt/widgets/common/CMakeLists.txt
+++ b/qt/widgets/common/CMakeLists.txt
@@ -54,6 +54,7 @@ set ( SRC_FILES
 	src/CatalogSelector.cpp
 	src/CheckboxHeader.cpp
 	src/DataProcessorUI/AbstractTreeModel.cpp
+	src/DataProcessorUI/TreeData.cpp
 	src/DataProcessorUI/GenerateNotebook.cpp
 	src/DataProcessorUI/OneLevelTreeManager.cpp
         src/DataProcessorUI/OptionsMap.cpp
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h
index 206b584b4d387a6f0c174227237313778ef7cf5d..25c13f5492a9dfb78efd0214f5ceb78a7efcb4b1 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h
@@ -96,8 +96,8 @@ private:
   friend struct Mantid::Kernel::CreateUsingNew<AlgorithmInputHistoryImpl>;
 };
 
-typedef Mantid::Kernel::SingletonHolder<AlgorithmInputHistoryImpl>
-    AlgorithmInputHistory;
+using AlgorithmInputHistory =
+    Mantid::Kernel::SingletonHolder<AlgorithmInputHistoryImpl>;
 }
 }
 
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h
index 53a6bb39d45b8ea04147649f1fe7304fb1cb3466..b315f69edf0c83732b4ed80de9dc5b9d4f0c873c 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h
@@ -136,7 +136,7 @@ protected:
   void keyPressEvent(QKeyEvent *e) override;
 
 private:
-  typedef std::vector<Mantid::API::AlgorithmDescriptor> AlgNamesType;
+  using AlgNamesType = std::vector<Mantid::API::AlgorithmDescriptor>;
   void addAliases(AlgNamesType &algNamesList);
   QString stripAlias(const QString &text) const;
 };
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h
index 72a0a56c5574e1a7304500c2e93bc63337a661f5..117cb8d41a5227a3c4ca19c7216b348b7b5507c5 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h
@@ -59,9 +59,9 @@ class EXPORT_OPT_MANTIDQT_COMMON BatchAlgorithmRunner : public QObject {
   Q_OBJECT
 
 public:
-  typedef std::map<std::string, std::string> AlgorithmRuntimeProps;
-  typedef std::pair<Mantid::API::IAlgorithm_sptr, AlgorithmRuntimeProps>
-      ConfiguredAlgorithm;
+  using AlgorithmRuntimeProps = std::map<std::string, std::string>;
+  using ConfiguredAlgorithm =
+      std::pair<Mantid::API::IAlgorithm_sptr, AlgorithmRuntimeProps>;
 
   explicit BatchAlgorithmRunner(QObject *parent = nullptr);
   ~BatchAlgorithmRunner() override;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/DataProcessorMainPresenter.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/DataProcessorMainPresenter.h
index 5e7d1f6e49b21836bc88dca963acd2f167fbd6f6..af2a46a457d07c78e70c80338e896804c835241c 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/DataProcessorMainPresenter.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/DataProcessorMainPresenter.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/OptionsQMap.h"
+#include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
 
 #include <QSet>
 #include <QString>
@@ -81,6 +82,10 @@ public:
   /// Handle data reduction paused/resumed confirmation
   virtual void confirmReductionPaused(int group) { UNUSED_ARG(group); }
   virtual void confirmReductionResumed(int group) { UNUSED_ARG(group); }
+  virtual void completedGroupReductionSuccessfully(GroupData const &,
+                                                   std::string const &){};
+  virtual void completedRowReductionSuccessfully(GroupData const &,
+                                                 std::string const &){};
 };
 }
 }
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenter.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenter.h
index 0006933317a2174af411ac6f36b9cf737a432d26..868e721aaaecafd4334a8e5e3f64b462a39547ce 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenter.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenter.h
@@ -39,8 +39,8 @@ class TreeManager;
 class GenericDataProcessorPresenterThread;
 
 using RowItem = std::pair<int, RowData_sptr>;
-using RowQueue = std::queue<RowItem>;
-using GroupQueue = std::queue<std::pair<int, RowQueue>>;
+using RowQueue = std::vector<RowItem>;
+using GroupQueue = std::vector<std::pair<int, RowQueue>>;
 
 /** @class GenericDataProcessorPresenter
 
@@ -224,6 +224,12 @@ protected:
   // Plotting
   virtual void plotRow();
   virtual void plotGroup();
+  virtual void
+  completedRowReductionSuccessfully(GroupData const &groupData,
+                                    std::string const &workspaceName);
+  virtual void
+  completedGroupReductionSuccessfully(GroupData const &groupData,
+                                      std::string const &workspaceName);
   void plotWorkspaces(const QOrderedSet<QString> &workspaces);
   // Get the name of a post-processed workspace
   QString getPostprocessedWorkspaceName(
@@ -240,11 +246,13 @@ protected:
   void saveNotebook(const TreeData &data);
 protected slots:
   void reductionError(QString ex);
-  void threadFinished(const int exitCode);
+  void groupThreadFinished(const int exitCode);
+  void rowThreadFinished(const int exitCode);
   void issueNotFoundWarning(QString const &granule,
                             QSet<QString> const &missingWorkspaces);
 
 private:
+  void threadFinished(const int exitCode);
   void applyDefaultOptions(std::map<QString, QVariant> &options);
   void setPropertiesFromKeyValueString(Mantid::API::IAlgorithm_sptr alg,
                                        const std::string &hiddenOptions,
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenterThread.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenterThread.h
index 5299b717ed81b1f5afc51502767ffe0780babc67..203a4f45cf4d041719167b268712ca71a7e63dc2 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenterThread.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GenericDataProcessorPresenterThread.h
@@ -46,9 +46,6 @@ public:
     // Establish connections between parent and worker
     connect(this, SIGNAL(started()), worker, SLOT(startWorker()));
     connect(worker, SIGNAL(finished(int)), this, SLOT(workerFinished(int)));
-    connect(worker, SIGNAL(finished(int)), parent, SLOT(threadFinished(int)));
-    connect(worker, SIGNAL(reductionErrorSignal(QString)), parent,
-            SLOT(reductionError(QString)), Qt::QueuedConnection);
     // Early deletion of thread and worker
     connect(this, SIGNAL(finished()), this, SLOT(deleteLater()),
             Qt::DirectConnection);
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h
index 8f8cad70c3ccb600c969a3955aa1b3b7164e36e8..d0604dda6fb704957016c4e0edc156bfe5e28b93 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h
@@ -7,7 +7,8 @@ namespace DataProcessor {
 
 class GridDelegate : public QStyledItemDelegate {
 public:
-  explicit GridDelegate(QObject *parent = 0) : QStyledItemDelegate(parent){};
+  explicit GridDelegate(QObject *parent = nullptr)
+      : QStyledItemDelegate(parent){};
 
   void paint(QPainter *painter, const QStyleOptionViewItem &option,
              const QModelIndex &index) const override {
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h
index dc489e5171cf1e362e7c72c125c456476b5cc40f..c571c33ea63908d95b1cf2c4bb0ce74832fa8cce 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h
@@ -45,7 +45,8 @@ public:
   virtual ~PreprocessMap();
   // Add a column to pre-process
   void addElement(const QString &column, const QString &algorithm,
-                  const QString &prefix = "", const QString &blacklist = "");
+                  const QString &prefix = "", const QString &separator = "",
+                  const QString &blacklist = "");
   // Returns a map where keys are columns and values pre-processing algorithms
   std::map<QString, PreprocessingAlgorithm> asMap() const;
 
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h
index bbd03c3de2380ebb079e0b588063c112afb2d128..5b2a3e08268abad577e0fa3555b44887a60a3ac5 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h
@@ -40,9 +40,10 @@ class EXPORT_OPT_MANTIDQT_COMMON PreprocessingAlgorithm
 public:
   // Constructor
   PreprocessingAlgorithm(QString name, QString prefix = "",
+                         QString separator = "",
                          std::set<QString> blacklist = std::set<QString>());
   // Delegating constructor
-  PreprocessingAlgorithm(QString name, QString prefix,
+  PreprocessingAlgorithm(QString name, QString prefix, QString separator,
                          const QString &blacklist);
   // Default constructor
   PreprocessingAlgorithm();
@@ -57,10 +58,14 @@ public:
   QString outputProperty() const;
   // The prefix to add to the output property
   QString prefix() const;
+  // The separator to use between values in the output property
+  QString separator() const;
 
 private:
   // A prefix to the name of the pre-processed output ws
   QString m_prefix;
+  // A separator between values in the pre-processed output ws name
+  QString m_separator;
   // The name of the LHS input property
   QString m_lhs;
   // The name of the RHS input property
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/TreeData.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/TreeData.h
index 271e0a810425f9ffacc5faa66596a8202ebceeaa..083d35422c0c9115ad5519f3314569ffce5349e0 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/TreeData.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/TreeData.h
@@ -26,16 +26,16 @@
     Code Documentation is available at: <http://doxygen.mantidproject.org>
     */
 
+#include <QStringList>
 #include "MantidKernel/System.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/OptionsMap.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/PostprocessingAlgorithm.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
+#include "MantidQtWidgets/Common/DllOption.h"
 #include "MantidQtWidgets/Common/DataProcessorUI/WhiteList.h"
 
-#include <QStringList>
-
 namespace MantidQt {
 namespace MantidWidgets {
 namespace DataProcessor {
@@ -144,6 +144,7 @@ private:
 
 using GroupData = std::map<int, RowData_sptr>;
 using TreeData = std::map<int, GroupData>;
+EXPORT_OPT_MANTIDQT_COMMON bool canPostprocess(GroupData const &group);
 }
 }
 }
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h
index 84afee2096b3b205db8d121302ed220542ee9bb0..3ca1d132e77b03e5cf02dacfe7bf9521a5e934d9 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h
@@ -43,10 +43,12 @@ class WhiteList;
 QStringList preprocessingStringToList(const QString &inputStr);
 // Create string of trimmed values from a list of values
 QString preprocessingListToString(const QStringList &values,
-                                  const QString prefix = QString());
+                                  const QString &prefix,
+                                  const QString &separator);
 // Returns the name of the reduced workspace for a given row
-QString DLLExport
-getReducedWorkspaceName(const RowData_sptr data, const WhiteList &whitelist);
+QString DLLExport getReducedWorkspaceName(
+    const RowData_sptr data, const WhiteList &whitelist,
+    const std::map<QString, PreprocessingAlgorithm> &preprocessor);
 // Consolidate global options with row values
 OptionsMap DLLExport getCanonicalOptions(
     const RowData_sptr data, const OptionsMap &globalOptions,
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h
index 48432fe6d999c8943e234bafdf3185c69af7654a..7252ac0cbbb66e850f84651196db1c99804d18a0 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h
@@ -21,8 +21,8 @@ namespace API {
  */
 class EXPORT_OPT_MANTIDQT_COMMON FindFilesThreadPoolManager : public QObject {
   Q_OBJECT
-  typedef std::function<FindFilesWorker *(const FindFilesSearchParameters &)>
-      ThreadAllocator;
+  using ThreadAllocator =
+      std::function<FindFilesWorker *(const FindFilesSearchParameters &)>;
 
 public:
   /// Create a new thread pool manager for finding files
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h
index f75564fb9476858ddfe1832d54e300579f88d12e..cfd3f86393bb2284c495084829846abe849195f2 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h
@@ -19,7 +19,7 @@ void qSleep(int ms) {
   Sleep(uint(ms));
 #else
   struct timespec ts = {ms / 1000, (ms % 1000) * 1000 * 1000};
-  nanosleep(&ts, NULL);
+  nanosleep(&ts, nullptr);
 #endif
 }
 } // namespace
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h
index 80cd05a4efddfb487af26c15c925cc1e61eedac7..e95c5d6f6f81ef5c53e94f78caa3ecf4250a7126 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h
@@ -164,8 +164,8 @@ private:
   /// Precision of doubles in m_doubleManager
   int m_decimals;
 
-  typedef void (FitOptionsBrowser::*SetterType)(QtProperty *, const QString &);
-  typedef QString (FitOptionsBrowser::*GetterType)(QtProperty *) const;
+  using SetterType = void (FitOptionsBrowser::*)(QtProperty *, const QString &);
+  using GetterType = QString (FitOptionsBrowser::*)(QtProperty *) const;
   /// Maps algorithm property name to the QtProperty
   QMap<QString, QtProperty *> m_propertyNameMap;
   /// Store for the properties setter methods
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h
index 094ba14c25c071d4b764ba78e1005a9f3399b275..48209257627ce149df2c2b7c7eb42120ec2fdd0c 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h
@@ -70,8 +70,8 @@ private:
 };
 
 /// The specific instantiation of the templated type
-typedef Mantid::Kernel::SingletonHolder<AlgorithmDialogFactoryImpl>
-    AlgorithmDialogFactory;
+using AlgorithmDialogFactory =
+    Mantid::Kernel::SingletonHolder<AlgorithmDialogFactoryImpl>;
 
 /**
     The UserSubWindowFactory is responsible for creating concrete instances of
@@ -180,8 +180,8 @@ void UserSubWindowFactoryImpl::saveAliasNames(const std::string &realName) {
 }
 
 /// The specific instantiation of the templated type
-typedef Mantid::Kernel::SingletonHolder<UserSubWindowFactoryImpl>
-    UserSubWindowFactory;
+using UserSubWindowFactory =
+    Mantid::Kernel::SingletonHolder<UserSubWindowFactoryImpl>;
 }
 }
 
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h
index dce046f397697f053b8c4f4d3e0bfef96bb4b66b..4dfe27cbb0051c5731921282707c767d1e5674a4 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h
@@ -20,7 +20,7 @@ class EXPORT_OPT_MANTIDQT_COMMON MantidHelpWindow
   Q_OBJECT
 
 public:
-  MantidHelpWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+  MantidHelpWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr);
   ~MantidHelpWindow() override;
 
   void showPage(const std::string &url = std::string()) override;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h b/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h
index 2b22c374a34dd8c5d4cabd0c97f04f7998a2db03..3c722c06c983b6311ce0a52ea6981544e45c4970 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h
@@ -25,7 +25,7 @@ class EXPORT_OPT_MANTIDQT_COMMON Message : public QObject {
 
 public:
   /// Priority matches Mantid Logger priority
-  typedef Mantid::Kernel::Logger::Priority Priority;
+  using Priority = Mantid::Kernel::Logger::Priority;
 
   /// Default constuctor required by Qt meta-type system
   Message();
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h
index bc5f3ecddb30965819891407bf49da709b1e52af..44d070dba1bfb736cea29100e40596f2c3ac2a46 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h
@@ -56,6 +56,6 @@ private:
 };
 
 /// Typedef for scoped lock
-typedef ScopedGIL<PythonGIL> ScopedPythonGIL;
+using ScopedPythonGIL = ScopedGIL<PythonGIL>;
 
 #endif /* PYTHONTHREADING_H_ */
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h
index 4ec5eaf81f0e5d5a9f356358b2c7a88ace6fb336..a508c7cd806ebe382570ca14127a2320d8a4e47f 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h
@@ -14,7 +14,7 @@
  */
 template <class ManagerType>
 class CompositeEditorFactory : public QtAbstractEditorFactory<ManagerType> {
-  typedef QtAbstractEditorFactory<ManagerType> FactoryBaseType;
+  using FactoryBaseType = QtAbstractEditorFactory<ManagerType>;
 
 public:
   CompositeEditorFactory(QObject *parent, FactoryBaseType *defaultFactory)
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h
index b6bb2a21e3037978979a4b83341e8984e50fdbb2..0c1ad5d5c908f9f632a8321127127b25413af31f 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h
@@ -515,9 +515,9 @@ private:
 
 template <class Editor> class EditorFactoryPrivate {
 public:
-  typedef QList<Editor *> EditorList;
-  typedef QMap<QtProperty *, EditorList> PropertyToEditorListMap;
-  typedef QMap<Editor *, QtProperty *> EditorToPropertyMap;
+  using EditorList = QList<Editor *>;
+  using PropertyToEditorListMap = QMap<QtProperty *, EditorList>;
+  using EditorToPropertyMap = QMap<Editor *, QtProperty *>;
 
   Editor *createEditor(QtProperty *property, QWidget *parent);
   void initializeEditor(QtProperty *property, Editor *e);
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h
index d1992e797a69833fc90f389dfca7b4c7fb2a866d..dedd26e011df9c2caf797b1a86ad8d050a314540 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h
@@ -942,8 +942,8 @@ template <class Value, class PrivateData>
 static Value getData(const QMap<const QtProperty *, PrivateData> &propertyMap,
                      Value PrivateData::*data, const QtProperty *property,
                      const Value &defaultValue = Value()) {
-  typedef QMap<const QtProperty *, PrivateData> PropertyToData;
-  typedef typename PropertyToData::const_iterator PropertyToDataConstIterator;
+  using PropertyToData = QMap<const QtProperty *, PrivateData>;
+  using PropertyToDataConstIterator = typename PropertyToData::const_iterator;
   const PropertyToDataConstIterator it = propertyMap.constFind(property);
   if (it == propertyMap.constEnd())
     return defaultValue;
@@ -980,8 +980,8 @@ static void setSimpleValue(
     void (PropertyManager::*valueChangedSignal)(QtProperty *,
                                                 ValueChangeParameter),
     QtProperty *property, const Value &val) {
-  typedef QMap<const QtProperty *, Value> PropertyToData;
-  typedef typename PropertyToData::iterator PropertyToDataIterator;
+  using PropertyToData = QMap<const QtProperty *, Value>;
+  using PropertyToDataIterator = typename PropertyToData::iterator;
   const PropertyToDataIterator it = propertyMap.find(property);
   if (it == propertyMap.end())
     return;
@@ -1005,9 +1005,9 @@ static void setValueInRange(
     QtProperty *property, const Value &val,
     void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *,
                                                         ValueChangeParameter)) {
-  typedef typename PropertyManagerPrivate::Data PrivateData;
-  typedef QMap<const QtProperty *, PrivateData> PropertyToData;
-  typedef typename PropertyToData::iterator PropertyToDataIterator;
+  using PrivateData = typename PropertyManagerPrivate::Data;
+  using PropertyToData = QMap<const QtProperty *, PrivateData>;
+  using PropertyToDataIterator = typename PropertyToData::iterator;
   const PropertyToDataIterator it = managerPrivate->m_values.find(property);
   if (it == managerPrivate->m_values.end())
     return;
@@ -1046,9 +1046,9 @@ static void setBorderValues(
                                                         ValueChangeParameter,
                                                         ValueChangeParameter,
                                                         ValueChangeParameter)) {
-  typedef typename PropertyManagerPrivate::Data PrivateData;
-  typedef QMap<const QtProperty *, PrivateData> PropertyToData;
-  typedef typename PropertyToData::iterator PropertyToDataIterator;
+  using PrivateData = typename PropertyManagerPrivate::Data;
+  using PropertyToData = QMap<const QtProperty *, PrivateData>;
+  using PropertyToDataIterator = typename PropertyToData::iterator;
   const PropertyToDataIterator it = managerPrivate->m_values.find(property);
   if (it == managerPrivate->m_values.end())
     return;
@@ -1097,8 +1097,8 @@ static void setBorderValue(
                                                         ValueChangeParameter,
                                                         ValueChangeParameter,
                                                         ValueChangeParameter)) {
-  typedef QMap<const QtProperty *, PrivateData> PropertyToData;
-  typedef typename PropertyToData::iterator PropertyToDataIterator;
+  using PropertyToData = QMap<const QtProperty *, PrivateData>;
+  using PropertyToDataIterator = typename PropertyToData::iterator;
   const PropertyToDataIterator it = managerPrivate->m_values.find(property);
   if (it == managerPrivate->m_values.end())
     return;
@@ -1138,7 +1138,7 @@ static void setMinimumValue(
     QtProperty *property, const Value &minVal) {
   void (PropertyManagerPrivate::*setSubPropertyRange)(
       QtProperty *, ValueChangeParameter, ValueChangeParameter,
-      ValueChangeParameter) = 0;
+      ValueChangeParameter) = nullptr;
   setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager,
                  Value, PrivateData>(
       manager, managerPrivate, propertyChangedSignal, valueChangedSignal,
@@ -1160,7 +1160,7 @@ static void setMaximumValue(
     QtProperty *property, const Value &maxVal) {
   void (PropertyManagerPrivate::*setSubPropertyRange)(
       QtProperty *, ValueChangeParameter, ValueChangeParameter,
-      ValueChangeParameter) = 0;
+      ValueChangeParameter) = nullptr;
   setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager,
                  Value, PrivateData>(
       manager, managerPrivate, propertyChangedSignal, valueChangedSignal,
@@ -1184,7 +1184,7 @@ public:
 
   QStringList m_familyNames;
 
-  typedef QMap<const QtProperty *, QFont> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QFont>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
@@ -1224,7 +1224,7 @@ public:
     QStringList flagNames;
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtBoolPropertyManager *m_boolPropertyManager;
@@ -1241,7 +1241,7 @@ public:
   void slotIntChanged(QtProperty *property, int value);
   void slotPropertyDestroyed(QtProperty *property);
 
-  typedef QMap<const QtProperty *, QColor> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QColor>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
@@ -1266,7 +1266,7 @@ public:
   void slotEnumChanged(QtProperty *property, int value);
   void slotPropertyDestroyed(QtProperty *property);
 
-  typedef QMap<const QtProperty *, QLocale> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QLocale>;
   PropertyValueMap m_values;
 
   QtEnumPropertyManager *m_enumPropertyManager;
@@ -1285,7 +1285,7 @@ public:
   void slotIntChanged(QtProperty *property, int value);
   void slotPropertyDestroyed(QtProperty *property);
 
-  typedef QMap<const QtProperty *, QPoint> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QPoint>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
@@ -1310,7 +1310,7 @@ public:
   void slotDoubleChanged(QtProperty *property, double value);
   void slotPropertyDestroyed(QtProperty *property);
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtDoublePropertyManager *m_doublePropertyManager;
@@ -1338,7 +1338,7 @@ public:
     int decimals;
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtDoublePropertyManager *m_doublePropertyManager;
@@ -1369,7 +1369,7 @@ public:
     QRect constraint;
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
@@ -1413,7 +1413,7 @@ public:
     }
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtDoublePropertyManager *m_doublePropertyManager;
@@ -1435,7 +1435,7 @@ public:
   void slotEnumChanged(QtProperty *property, int value);
   void slotPropertyDestroyed(QtProperty *property);
 
-  typedef QMap<const QtProperty *, QSizePolicy> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QSizePolicy>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
@@ -1479,7 +1479,7 @@ public:
     }
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 
   QtIntPropertyManager *m_intPropertyManager;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h
index 23334c1e56d32fb5547b03fab9f7d1a683ab45fd..1603eb634ea7674154059f8dd10a9ef4984044ab 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h
@@ -356,10 +356,10 @@ private slots:
 private:
   int indentation(const QModelIndex &index) const;
 
-  typedef QMap<QWidget *, QtProperty *> EditorToPropertyMap;
+  using EditorToPropertyMap = QMap<QWidget *, QtProperty *>;
   mutable EditorToPropertyMap m_editorToProperty;
 
-  typedef QMap<QtProperty *, QWidget *> PropertyToEditorMap;
+  using PropertyToEditorMap = QMap<QtProperty *, QWidget *>;
   mutable PropertyToEditorMap m_propertyToEditor;
   QtTreePropertyBrowserPrivate *m_editorPrivate;
   mutable QTreeWidgetItem *m_editedItem;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h
index 823cfa3c95ae562e02d094e03f5a05891f1c194a..761488c8ba7f27f75f901e95def4711eb377c87f 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h
@@ -96,7 +96,7 @@
 QT_BEGIN_NAMESPACE
 #endif
 
-typedef QMap<int, QIcon> QtIconMap;
+using QtIconMap = QMap<int, QIcon>;
 
 class QtVariantPropertyManager;
 class QtVariantPropertyPrivate;
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h
index a03d8c57b0d8a09d474773fb9b5e94c8d7beb0d0..2d2b75b10282fcd4812804834ff9ed3e8995f4fa 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h
@@ -76,7 +76,7 @@ private:
   QString m_sampleThickness;
 
   QHash<QCheckBox *const, QString> m_savFormats;
-  typedef QHash<QCheckBox *const, QString>::const_iterator SavFormatsConstIt;
+  using SavFormatsConstIt = QHash<QCheckBox *const, QString>::const_iterator;
 
   void setupLine1(QHBoxLayout *const lineOne);
   void setupLine2(QHBoxLayout *const lineTwo,
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h
index cfedb31c177560f1014d1529ec5ca6fb705d0a88..0c73de84869c1c0f44ceadc75fc94413f565bcae 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h
@@ -63,8 +63,8 @@ private:
       SelectionNotificationServiceImpl>;
 };
 
-typedef Mantid::Kernel::SingletonHolder<SelectionNotificationServiceImpl>
-    SelectionNotificationService;
+using SelectionNotificationService =
+    Mantid::Kernel::SingletonHolder<SelectionNotificationServiceImpl>;
 }
 }
 namespace Mantid {
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h
index da2a3699630ec3e80ec81ec3f954693083c48003..df640d59287d8a07ed7c14acab4156d4b2f778d6 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h
@@ -14,7 +14,7 @@
 namespace MantidQt {
 namespace MantidWidgets {
 
-typedef QMap<QString, QString> PropertyDimensionMap;
+using PropertyDimensionMap = QMap<QString, QString>;
 
 /*
 Class SlicingAlgorithmDialog
diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h
index 43914261b212705e2591fe7b70867d737f02edec..9c8200f160ee9a6a8d80ca1a9d2f685a23eef114 100644
--- a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h
+++ b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h
@@ -72,11 +72,11 @@ signals:
 /// a QHelpEngine.
 class EXPORT_OPT_MANTIDQT_COMMON pqHelpWindow : public QMainWindow {
   Q_OBJECT
-  typedef QMainWindow Superclass;
+  using Superclass = QMainWindow;
 
 public:
-  pqHelpWindow(QHelpEngine *engine, QWidget *parent = 0,
-               Qt::WindowFlags flags = 0);
+  pqHelpWindow(QHelpEngine *engine, QWidget *parent = nullptr,
+               Qt::WindowFlags flags = nullptr);
 
 public slots:
   /// Requests showing of a particular page. The url must begin with "qthelp:"
diff --git a/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp b/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp
index 625f584e735c6e92978040250335cf50a655a7a1..7f6eed9a997005cd02835f8a484cd8a3d25887c7 100644
--- a/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp
+++ b/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp
@@ -295,7 +295,7 @@ bool isCalledInputWorkspace(PropertyWidget *const candidate) {
  */
 void AlgorithmPropertiesWidget::replaceWSClicked(const QString &propName) {
   if (m_propWidgets.contains(propName)) {
-    typedef std::vector<PropertyWidget *> CollectionOfPropertyWidget;
+    using CollectionOfPropertyWidget = std::vector<PropertyWidget *>;
     CollectionOfPropertyWidget candidateReplacementSources;
     PropertyWidget *propWidget = m_propWidgets[propName];
     if (propWidget) {
diff --git a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp
index d94dfbe5290f60dc96823ff5aa0b3896aea8406a..cd42f9b917b69f95e7a119f61b49539ab6401db2 100644
--- a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp
+++ b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp
@@ -269,7 +269,7 @@ void AlgorithmTreeWidget::mouseDoubleClickEvent(QMouseEvent *e) {
 void AlgorithmTreeWidget::update() {
   this->clear();
 
-  typedef std::vector<AlgorithmDescriptor> AlgNamesType;
+  using AlgNamesType = std::vector<AlgorithmDescriptor>;
   AlgNamesType names = AlgorithmFactory::Instance().getDescriptors();
 
   // sort by category/name/version to fill QTreeWidget
@@ -293,7 +293,7 @@ void AlgorithmTreeWidget::update() {
         this->addTopLevelItem(catItem);
       } else {
         QString cn = subCats[0];
-        QTreeWidgetItem *catItem = NULL;
+        QTreeWidgetItem *catItem = nullptr;
         int n = subCats.size();
         for (int j = 0; j < n; j++) {
           if (categories.contains(cn)) {
diff --git a/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp b/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp
index fde30a6539b33b37cecf628b8cafd9a0d35bff19..a1edd93f9f720a2468be2cde1ec423e18db2ef2e 100644
--- a/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp
@@ -492,7 +492,8 @@ loadWorkspaceString(const QString &runStr, const QString &instrument,
   }
 
   const QString prefix = preprocessor.prefix();
-  const QString outputName = preprocessingListToString(runs, prefix);
+  const QString outputName =
+      preprocessingListToString(runs, prefix, preprocessor.separator());
 
   boost::tuple<QString, QString> loadString;
 
diff --git a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
index c6ed8ddf2da25dd0d00b2c39e2e5d83fb41efb80..0dc8cf342ef9726559d492661c2a32938eb4c58d 100644
--- a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
@@ -63,6 +63,10 @@ bool workspaceExists(QString const &workspaceName) {
 void removeWorkspace(QString const &workspaceName) {
   AnalysisDataService::Instance().remove(workspaceName.toStdString());
 }
+
+template <typename T> void pop_front(std::vector<T> &queue) {
+  queue.erase(queue.begin());
+}
 }
 
 namespace MantidQt {
@@ -291,7 +295,7 @@ Returns the name of the reduced workspace for a given row
 QString GenericDataProcessorPresenter::getReducedWorkspaceName(
     const RowData_sptr data) const {
   return MantidQt::MantidWidgets::DataProcessor::getReducedWorkspaceName(
-      data, m_whitelist);
+      data, m_whitelist, m_preprocessing.m_map);
 }
 
 void GenericDataProcessorPresenter::settingsChanged() {
@@ -397,7 +401,7 @@ void GenericDataProcessorPresenter::process() {
         return;
 
       // Add all row items to queue
-      rowQueue.push(row);
+      rowQueue.emplace_back(row);
 
       // Set group as unprocessed if settings have changed or the expected
       // output workspaces cannot be found
@@ -408,7 +412,7 @@ void GenericDataProcessorPresenter::process() {
       if (!isProcessed(row.first, group.first))
         maxProgress++;
     }
-    m_group_queue.emplace(group.first, rowQueue);
+    m_group_queue.emplace_back(group.first, rowQueue);
   }
 
   // Create progress reporter bar
@@ -465,29 +469,36 @@ void GenericDataProcessorPresenter::nextRow() {
     m_nextActionFlag = ReductionFlag::ReduceRowFlag;
     // Reduce next row
     m_rowItem = rqueue.front();
-    rqueue.pop();
+    pop_front(rqueue);
     // Skip reducing rows that are already processed
     if (!isProcessed(m_rowItem.first, groupIndex)) {
       startAsyncRowReduceThread(&m_rowItem, groupIndex);
       return;
     }
   } else {
-    m_group_queue.pop();
+    pop_front(m_group_queue);
     // Set next action flag
     m_nextActionFlag = ReductionFlag::ReduceGroupFlag;
 
     // Skip post-processing groups that are already processed or only contain a
     // single row
-    if (!isProcessed(groupIndex) && m_groupData.size() > 1) {
-      startAsyncGroupReduceThread(m_groupData, groupIndex);
-      return;
+    if (!isProcessed(groupIndex)) {
+      if (m_groupData.size() > 1) {
+        startAsyncGroupReduceThread(m_groupData, groupIndex);
+        return;
+      }
     }
   }
-
   // Row / group skipped, perform next action
   doNextAction();
 }
 
+void GenericDataProcessorPresenter::completedGroupReductionSuccessfully(
+    GroupData const &, std::string const &) {}
+
+void GenericDataProcessorPresenter::completedRowReductionSuccessfully(
+    GroupData const &, std::string const &) {}
+
 /**
 Process a new group
 */
@@ -500,23 +511,27 @@ void GenericDataProcessorPresenter::nextGroup() {
     return;
   }
 
-  // Clear group data from any previously processed groups
-  m_groupData.clear();
-
   if (!m_group_queue.empty()) {
     // Set next action flag
     m_nextActionFlag = ReductionFlag::ReduceRowFlag;
     // Reduce first row
     auto &rqueue = m_group_queue.front().second;
     m_rowItem = rqueue.front();
-    rqueue.pop();
+    // Clear group data from any previously processed groups
+    m_groupData.clear();
+    for (auto &&row : rqueue)
+      m_groupData[row.first] = row.second;
+    pop_front(rqueue);
+
     // Skip reducing rows that are already processed
-    if (!isProcessed(m_rowItem.first, m_group_queue.front().first))
+    if (!isProcessed(m_rowItem.first, m_group_queue.front().first)) {
       startAsyncRowReduceThread(&m_rowItem, m_group_queue.front().first);
-    else
+    } else {
       doNextAction();
+    }
   } else {
-    // If "Output Notebook" checkbox is checked then create an ipython notebook
+    // If "Output Notebook" checkbox is checked then create an ipython
+    // notebook
     if (m_view->getEnableNotebook())
       saveNotebook(m_selectedData);
     endReduction();
@@ -531,6 +546,10 @@ void GenericDataProcessorPresenter::startAsyncRowReduceThread(RowItem *rowItem,
 
   auto *worker = new GenericDataProcessorPresenterRowReducerWorker(
       this, rowItem, groupIndex);
+
+  connect(worker, SIGNAL(finished(int)), this, SLOT(rowThreadFinished(int)));
+  connect(worker, SIGNAL(reductionErrorSignal(QString)), this,
+          SLOT(reductionError(QString)), Qt::QueuedConnection);
   m_workerThread.reset(new GenericDataProcessorPresenterThread(this, worker));
   m_workerThread->start();
 }
@@ -543,6 +562,9 @@ void GenericDataProcessorPresenter::startAsyncGroupReduceThread(
 
   auto *worker = new GenericDataProcessorPresenterGroupReducerWorker(
       this, groupData, groupIndex);
+  connect(worker, SIGNAL(finished(int)), this, SLOT(groupThreadFinished(int)));
+  connect(worker, SIGNAL(reductionErrorSignal(QString)), this,
+          SLOT(reductionError(QString)), Qt::QueuedConnection);
   m_workerThread.reset(new GenericDataProcessorPresenterThread(this, worker));
   m_workerThread->start();
 }
@@ -583,6 +605,22 @@ void GenericDataProcessorPresenter::threadFinished(const int exitCode) {
   }
 }
 
+void GenericDataProcessorPresenter::groupThreadFinished(const int exitCode) {
+
+  auto postprocessedWorkspace =
+      getPostprocessedWorkspaceName(m_groupData).toStdString();
+  completedGroupReductionSuccessfully(m_groupData, postprocessedWorkspace);
+  threadFinished(exitCode);
+}
+
+void GenericDataProcessorPresenter::rowThreadFinished(const int exitCode) {
+  completedRowReductionSuccessfully(
+      m_groupData,
+      m_rowItem.second->reducedName(m_processor.defaultOutputPrefix())
+          .toStdString());
+  threadFinished(exitCode);
+}
+
 /**
 Display a dialog to choose save location for notebook, then save the notebook
 there
@@ -651,11 +689,13 @@ Workspace_sptr GenericDataProcessorPresenter::prepareRunWorkspace(
   if (runs.size() == 1)
     return getRun(runs[0], instrument, preprocessor.prefix());
 
-  auto const outputName =
-      preprocessingListToString(runs, preprocessor.prefix());
+  auto const outputName = preprocessingListToString(runs, preprocessor.prefix(),
+                                                    preprocessor.separator());
 
-  /* Ideally, this should be executed as a child algorithm to keep the ADS tidy,
-  * but that doesn't preserve history nicely, so we'll just take care of tidying
+  /* Ideally, this should be executed as a child algorithm to keep the ADS
+  * tidy,
+  * but that doesn't preserve history nicely, so we'll just take care of
+  * tidying
   * up in the event of failure.
   */
   IAlgorithm_sptr alg =
@@ -693,12 +733,14 @@ Workspace_sptr GenericDataProcessorPresenter::prepareRunWorkspace(
       alg->execute();
 
       if (runIt != --runs.end()) {
-        // After the first execution we replace the LHS with the previous output
+        // After the first execution we replace the LHS with the previous
+        // output
         setAlgorithmProperty(alg.get(), preprocessor.lhsProperty(), outputName);
       }
     }
   } catch (...) {
-    // If we're unable to create the full workspace, discard the partial version
+    // If we're unable to create the full workspace, discard the partial
+    // version
     removeWorkspace(outputName);
     // We've tidied up, now re-throw.
     throw;
@@ -1093,7 +1135,8 @@ void GenericDataProcessorPresenter::notify(DataProcessorPresenter::Flag flag) {
     pause();
     break;
   }
-  // Not having a 'default' case is deliberate. gcc issues a warning if there's
+  // Not having a 'default' case is deliberate. gcc issues a warning if
+  // there's
   // a flag we aren't handling.
 }
 
@@ -1442,7 +1485,8 @@ void GenericDataProcessorPresenter::plotWorkspaces(
 void GenericDataProcessorPresenter::showOptionsDialog() {
   auto options =
       new QtDataProcessorOptionsDialog(m_view, m_view->getPresenter());
-  // By default the dialog is only destroyed when ReflMainView is and so they'll
+  // By default the dialog is only destroyed when ReflMainView is and so
+  // they'll
   // stack up.
   // This way, they'll be deallocated as soon as they've been closed.
   options->setAttribute(Qt::WA_DeleteOnClose, true);
diff --git a/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp b/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp
index 0aecc560c3598524d160b92feaf2b4f42f68de11..5f9a6f29258c3b4b7eeee8c3c80529c354ba4d4f 100644
--- a/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp
@@ -17,14 +17,17 @@ PreprocessMap::~PreprocessMap() {}
 * applied to that column
 * @param prefix :: a list with the prefix(es) to be added to the output
 * workspace(s), as a string
+* @param separator :: the separator to use between elements of the output
+* workspace name
 * @param blacklist :: the list of algorithm properties to black list, as a
 * string
 */
 void PreprocessMap::addElement(const QString &column, const QString &algorithm,
-                               const QString &prefix,
+                               const QString &prefix, const QString &separator,
                                const QString &blacklist) {
 
-  m_map[column] = PreprocessingAlgorithm(algorithm, prefix, blacklist);
+  m_map[column] =
+      PreprocessingAlgorithm(algorithm, prefix, separator, blacklist);
 }
 
 /** Return a map where keys are columns and values pre-processing algorithms
diff --git a/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp b/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp
index 26ab39bca725270af6633028c8279539ae940af3..49be4d935a2fe4090914154d510ee2a12ac45184 100644
--- a/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp
@@ -7,13 +7,16 @@ namespace DataProcessor {
 /** Constructor
  * @param name : The name of the pre-processing algorithm
  * @param prefix : A prefix that will added to the output workspace name
+ * @param separator : A separator that will added between values in the output
+ * workspace name
  * @param blacklist : The list of properties we don't want to show
  * algorithm in the processed workspace's name
  */
 PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix,
+                                               QString separator,
                                                std::set<QString> blacklist)
     : ProcessingAlgorithmBase(std::move(name), std::move(blacklist)),
-      m_prefix(std::move(prefix)) {
+      m_prefix(std::move(prefix)), m_separator(std::move(separator)) {
 
   auto inputWsProperties = getInputWsProperties();
 
@@ -39,18 +42,22 @@ PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix,
 *
 * @param name : The name of the pre-processing algorithm
 * @param prefix : A prefix that will added to the output workspace name
+* @param separator : A separator that will used between values in the output
+* workspace name
 * @param blacklist : The list of properties we don't want to show, as a string
 * algorithm in the processed workspace's name
 */
 PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix,
+                                               QString separator,
                                                const QString &blacklist)
     : PreprocessingAlgorithm(std::move(name), std::move(prefix),
+                             std::move(separator),
                              convertStringToSet(blacklist)) {}
 
 /** Default constructor: do nothing
 */
 PreprocessingAlgorithm::PreprocessingAlgorithm()
-    : m_prefix(), m_lhs(), m_rhs(), m_outProperty() {}
+    : m_prefix(), m_separator(), m_lhs(), m_rhs(), m_outProperty() {}
 
 // Destructor
 PreprocessingAlgorithm::~PreprocessingAlgorithm() {}
@@ -66,6 +73,9 @@ QString PreprocessingAlgorithm::outputProperty() const { return m_outProperty; }
 
 // Returns the prefix to add to the output property
 QString PreprocessingAlgorithm::prefix() const { return m_prefix; }
+
+// Returns the separator to separate multiple values in the output property
+QString PreprocessingAlgorithm::separator() const { return m_separator; }
 }
 }
 }
diff --git a/qt/widgets/common/src/DataProcessorUI/TreeData.cpp b/qt/widgets/common/src/DataProcessorUI/TreeData.cpp
index 78a32013ba7f4c11ecba1ac2f1d8451da526f603..7382690c4be57ad8c196c5879ac11f1a0990929c 100644
--- a/qt/widgets/common/src/DataProcessorUI/TreeData.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/TreeData.cpp
@@ -1,7 +1,9 @@
 #include "MantidQtWidgets/Common/DataProcessorUI/TreeData.h"
+
 namespace MantidQt {
 namespace MantidWidgets {
 namespace DataProcessor {
+bool canPostprocess(GroupData const &group) { return group.size() > 1; }
 
 // Constructors
 RowData::RowData(const int columnCount) : m_isProcessed{false} {
diff --git a/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp b/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp
index cf52683fc3b0fb114f33892e5776b21e9f19c73f..a86fb0f0f97918ab3131ce26a9e965af855426e0 100644
--- a/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp
@@ -332,12 +332,17 @@ void TwoLevelTreeManager::pasteSelected(const QString &text) {
     // Add as many new rows as required
     for (auto i = 0; i < lines.size(); ++i) {
       auto values = lines[i].split("\t");
+      auto const valuesSizeLessOne = static_cast<int>(values.size()) - 1;
+
+      if (valuesSizeLessOne < 1)
+        continue;
 
       auto groupId = parseDenaryInteger(values.front());
       int rowId = numRowsInGroup(groupId);
       if (!m_model->insertRow(rowId, m_model->index(groupId, 0)))
         return;
-      for (int col = 0; col < m_model->columnCount(); col++) {
+      for (int col = 0; col < m_model->columnCount() && col < valuesSizeLessOne;
+           col++) {
         m_model->setData(m_model->index(rowId, col, m_model->index(groupId, 0)),
                          values[col + 1]);
       }
diff --git a/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp b/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp
index 4cc13be9896ef6a4f257a039e9aaec028fa2969e..1e01578654693eede6fe0e18d44851bc211516a7 100644
--- a/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp
+++ b/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp
@@ -120,19 +120,23 @@ QStringList preprocessingStringToList(const QString &inputStr) {
  * separated by '+' with an optional prefix
  */
 QString preprocessingListToString(const QStringList &values,
-                                  const QString prefix) {
-  return prefix + values.join("+");
+                                  const QString &prefix,
+                                  const QString &separator) {
+  return prefix + values.join(separator);
 }
 
 /**
 Returns the name of the reduced workspace for a given row
 @param data :: [input] The data for this row
 @param whitelist :: [input] The list of columns
+@param preprocessMap :: [input] a map of column names to the preprocessing
+algorithm for that column
 @throws std::runtime_error if the workspace could not be prepared
 @returns : The name of the workspace
 */
-QString getReducedWorkspaceName(const RowData_sptr data,
-                                const WhiteList &whitelist) {
+QString getReducedWorkspaceName(
+    const RowData_sptr data, const WhiteList &whitelist,
+    const std::map<QString, PreprocessingAlgorithm> &preprocessMap) {
   if (data->size() != static_cast<int>(whitelist.size()))
     throw std::invalid_argument("Can't find reduced workspace name");
 
@@ -153,17 +157,28 @@ QString getReducedWorkspaceName(const RowData_sptr data,
   auto columnIt = whitelist.cbegin();
   auto runNumbersIt = data->constBegin();
   for (; columnIt != whitelist.cend(); ++columnIt, ++runNumbersIt) {
+    // Check the column is relevant to the generation of the output name
     auto column = *columnIt;
-    // Do we want to use this column to generate the name of the output ws?
-    if (column.isShown()) {
-      auto const runNumbers = *runNumbersIt;
-
-      if (!runNumbers.isEmpty()) {
-        auto values = preprocessingStringToList(runNumbers);
-        if (!values.isEmpty())
-          names.append(preprocessingListToString(values, column.prefix()));
-      }
-    }
+    if (!column.isShown())
+      continue;
+
+    // Check there is a value in the column
+    auto const runNumbers = *runNumbersIt;
+    if (runNumbers.isEmpty())
+      continue;
+
+    // Convert the string value to a list
+    auto values = preprocessingStringToList(runNumbers);
+    if (values.isEmpty())
+      continue;
+
+    // Get the separator to use if preprocessing multiple input values
+    QString separator = "+";
+    if (preprocessMap.count(column.name()))
+      separator = preprocessMap.at(column.name()).separator();
+
+    // Convert the value list to a correctly-formatted output name
+    names.append(preprocessingListToString(values, column.prefix(), separator));
   } // Columns
 
   QString wsname;
diff --git a/qt/widgets/common/src/FileDialogHandler.cpp b/qt/widgets/common/src/FileDialogHandler.cpp
index 5c7f51f0b2cff664f4b2cf06154f16806a69febb..d19a00267049beb174eac3ed153d22dab6e27dd4 100644
--- a/qt/widgets/common/src/FileDialogHandler.cpp
+++ b/qt/widgets/common/src/FileDialogHandler.cpp
@@ -6,7 +6,7 @@
 #include <sstream>
 
 namespace { // anonymous namespace
-const boost::regex FILE_EXT_REG_EXP{"^.+\\s+\\((\\S+)\\)$"};
+const boost::regex FILE_EXT_REG_EXP{R"(^.+\s+\((\S+)\)$)"};
 const QString ALL_FILES("All Files (*)");
 
 QString getExtensionFromFilter(const QString &selectedFilter) {
diff --git a/qt/widgets/common/src/FitPropertyBrowser.cpp b/qt/widgets/common/src/FitPropertyBrowser.cpp
index 498f7f24cbdc6b9713296267089e4afa81a1df7c..f845baea5485f363df266ba310831a4a52f24746 100644
--- a/qt/widgets/common/src/FitPropertyBrowser.cpp
+++ b/qt/widgets/common/src/FitPropertyBrowser.cpp
@@ -1784,8 +1784,8 @@ void FitPropertyBrowser::postDeleteHandle(const std::string &wsName) {
  */
 bool FitPropertyBrowser::isWorkspaceValid(
     Mantid::API::Workspace_sptr ws) const {
-  return (dynamic_cast<Mantid::API::MatrixWorkspace *>(ws.get()) != 0 ||
-          dynamic_cast<Mantid::API::ITableWorkspace *>(ws.get()) != 0);
+  return (dynamic_cast<Mantid::API::MatrixWorkspace *>(ws.get()) != nullptr ||
+          dynamic_cast<Mantid::API::ITableWorkspace *>(ws.get()) != nullptr);
 }
 
 bool FitPropertyBrowser::isWorkspaceAGroup() const {
diff --git a/qt/widgets/common/src/FunctionBrowser.cpp b/qt/widgets/common/src/FunctionBrowser.cpp
index a56c11eb07b5fff5826d98b0e0e870b8a723ac7c..e4bf7c95b779b8289ae078bc5811ae6fdd1850f0 100644
--- a/qt/widgets/common/src/FunctionBrowser.cpp
+++ b/qt/widgets/common/src/FunctionBrowser.cpp
@@ -932,26 +932,7 @@ void FunctionBrowser::addTieProperty(QtProperty *prop, QString tie) {
   if (!isParameter(prop))
     return;
 
-  Mantid::API::Expression expr;
-  expr.parse(tie.toStdString());
-  // Do parameter names include composite function index
-  bool isComposite = false;
-  auto vars = expr.getVariables();
-  for (auto var = vars.begin(); var != vars.end(); ++var) {
-    // nesting level of a particular variable
-    int n = static_cast<int>(std::count(var->begin(), var->end(), '.'));
-    if (n != 0) {
-      isComposite = true;
-    }
-  }
-
-  // Find the property of the function that this tie will be set to:
-  // If the tie has variables that contain function indices (f0.f1. ...)
-  // then it will be set to the topmost composite function.
-  // If the tie is a number or has only simple variable names then it belongs
-  // to the local function (the one that has the tied parameter)
-  QtProperty *funProp =
-      isComposite ? getFunctionProperty().prop : m_properties[prop].parent;
+  QtProperty *funProp = getFunctionProperty().prop;
 
   // Create and add a QtProperty for the tie.
   m_tieManager->blockSignals(true);
diff --git a/qt/widgets/common/src/MWRunFiles.cpp b/qt/widgets/common/src/MWRunFiles.cpp
index d978a5363a2c2d7a61d6622c272fdc83ffa2a962..9640ea3bd7a7b099c19d65b7838e8946035f1459 100644
--- a/qt/widgets/common/src/MWRunFiles.cpp
+++ b/qt/widgets/common/src/MWRunFiles.cpp
@@ -550,9 +550,6 @@ void MWRunFiles::findFiles(bool isModified) {
 * @return search text to create search params with
 */
 const QString MWRunFiles::findFilesGetSearchText(QString &searchText) {
-
-  emit findingFiles();
-
   // If we have an override instrument then add it in appropriate places to
   // the search text
   if (!m_defaultInstrumentName.isEmpty()) {
@@ -590,6 +587,8 @@ const QString MWRunFiles::findFilesGetSearchText(QString &searchText) {
 */
 void MWRunFiles::runFindFiles(const QString &searchText) {
   if (!searchText.isEmpty()) {
+    emit findingFiles();
+
     const auto parameters =
         createFindFilesSearchParameters(searchText.toStdString());
     m_pool.createWorker(this, parameters);
diff --git a/qt/widgets/common/src/MantidWSIndexDialog.cpp b/qt/widgets/common/src/MantidWSIndexDialog.cpp
index 8347bd0bf9f2dc891cca4b8eba60f40e2c2f155b..2cf7ec17bf592c0885f3ce1fa291aa8abd1273b1 100644
--- a/qt/widgets/common/src/MantidWSIndexDialog.cpp
+++ b/qt/widgets/common/src/MantidWSIndexDialog.cpp
@@ -207,7 +207,7 @@ QMultiMap<QString, std::set<int>> MantidWSIndexWidget::getPlots() const {
           boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
               Mantid::API::AnalysisDataService::Instance().retrieve(
                   m_wsNames[i].toStdString()));
-      if (NULL == ws)
+      if (nullptr == ws)
         continue;
 
       const Mantid::spec2index_map spec2index =
@@ -690,7 +690,7 @@ void MantidWSIndexWidget::checkForSpectraAxes() {
         boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
             Mantid::API::AnalysisDataService::Instance().retrieve(
                 (*it).toStdString()));
-    if (NULL == ws)
+    if (nullptr == ws)
       continue;
     bool hasSpectra = false;
     for (int i = 0; i < ws->axes(); i++) {
@@ -718,7 +718,7 @@ void MantidWSIndexWidget::generateWsIndexIntervals() {
         boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
             Mantid::API::AnalysisDataService::Instance().retrieve(
                 (*it).toStdString()));
-    if (NULL == ws)
+    if (nullptr == ws)
       continue;
 
     const int endWs = static_cast<int>(ws->getNumberHistograms() -
diff --git a/qt/widgets/common/src/MultifitSetupDialog.cpp b/qt/widgets/common/src/MultifitSetupDialog.cpp
index db316764958ed20e5580fccbc57b3d13efe8a9b6..5bfc07aa79ee0bd2821a88e30af88e5fe194e191 100644
--- a/qt/widgets/common/src/MultifitSetupDialog.cpp
+++ b/qt/widgets/common/src/MultifitSetupDialog.cpp
@@ -32,7 +32,7 @@ MultifitSetupDialog::MultifitSetupDialog(FitPropertyBrowser *fitBrowser)
     ui.paramTable->insertRow(ui.paramTable->rowCount());
     model->setData(model->index(j, 0),
                    QString::fromStdString(f->parameterName(i)));
-    ui.paramTable->item(j, 0)->setFlags(0);
+    ui.paramTable->item(j, 0)->setFlags(nullptr);
     model->setData(model->index(j, 1), "");
     ui.paramTable->item(j, 1)->setCheckState(Qt::Unchecked);
   }
diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp
index 43d1fcd59fd0db8f039dba9885b9bd3713f0c867..b20a7f817c648dc0f87ba56ff1a3af20dc7313b8 100644
--- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp
+++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp
@@ -57,6 +57,7 @@
 #include <QSignalMapper>
 #include <QTableWidgetItem>
 #include <QCheckBox>
+#include <QMessageBox>
 
 namespace {
 Mantid::Kernel::Logger g_log("MuonFitPropertyBrowser");
@@ -335,12 +336,10 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) {
 }
 
 void MuonFitPropertyBrowser::checkFitEnabled() {
-  if (m_reselectGroupBtn->isVisible()) {
+  if (count() == 0) {
     setFitEnabled(false);
-  } else if (getAutoBackgroundString() != "") {
-    setFitEnabled(true);
   } else {
-    setFitEnabled(false);
+    setFitEnabled(true);
   }
 }
 /**
@@ -1041,7 +1040,7 @@ bool MuonFitPropertyBrowser::isWorkspaceValid(Workspace_sptr ws) const {
   if (workspaceName.endsWith("_Workspace"))
     return false;
 
-  return dynamic_cast<MatrixWorkspace *>(ws.get()) != 0;
+  return dynamic_cast<MatrixWorkspace *>(ws.get()) != nullptr;
 }
 
 void MuonFitPropertyBrowser::finishHandle(const IAlgorithm *alg) {
@@ -1197,8 +1196,8 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) {
     setAllGroups();
     setAllPeriods();
     setAutoBackgroundName("");
-
-  } else { // clear current selection
+    this->clear(); // force update of composite function
+  } else {         // clear current selection
     if (m_autoBackground != "") {
       setAutoBackgroundName(m_autoBackground);
       addAutoBackground();
@@ -1549,6 +1548,12 @@ void MuonFitPropertyBrowser::updatePeriods() {
 void MuonFitPropertyBrowser::updatePeriods(const int j) {
   // this is for switching but has a bug at the moment
   // const QStringList &selected) {
+  if (m_periodsToFitOptions.size() == 0) {
+    QMessageBox::warning(this, "Muon Analysis",
+                         "Data not found. Please turn on the data archive, "
+                         "using the Manage Directories button.");
+    return;
+  }
   m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions);
   m_enumManager->setValue(m_periodsToFit, j);
   if (m_periodsToFitOptions[j] == CUSTOM_LABEL) {
diff --git a/qt/widgets/common/src/PropertyHandler.cpp b/qt/widgets/common/src/PropertyHandler.cpp
index 337f88313b15ff0dab15b5c50b0ea41ab5b37af1..140e87261feacf23d7992e334bec45cb43e994fc 100644
--- a/qt/widgets/common/src/PropertyHandler.cpp
+++ b/qt/widgets/common/src/PropertyHandler.cpp
@@ -44,7 +44,7 @@ PropertyHandler::~PropertyHandler() {}
 /// overrides virtual init() which is called from IFunction::setHandler(...)
 void PropertyHandler::init() {
   m_browser->m_changeSlotsEnabled = false;
-  if (m_parent == NULL) { // the root composite function
+  if (m_parent == nullptr) { // the root composite function
     m_item = m_browser->m_functionsGroup;
   } else if (m_item == nullptr) {
     if (!m_parent->getHandler()) {
@@ -538,7 +538,7 @@ PropertyHandler::findCompositeFunction(QtBrowserItem *item) const {
   for (size_t i = 0; i < m_cf->nFunctions(); i++) {
     Mantid::API::CompositeFunction_const_sptr res =
         getHandler(i)->findCompositeFunction(item);
-    if (res != NULL)
+    if (res != nullptr)
       return res;
   }
   return Mantid::API::CompositeFunction_sptr();
@@ -555,7 +555,7 @@ PropertyHandler::findFunction(QtBrowserItem *item) const {
     return Mantid::API::IFunction_sptr();
   for (size_t i = 0; i < m_cf->nFunctions(); i++) {
     Mantid::API::IFunction_const_sptr res = getHandler(i)->findFunction(item);
-    if (res != NULL)
+    if (res != nullptr)
       return res;
   }
   return Mantid::API::IFunction_sptr();
@@ -927,9 +927,9 @@ Mantid::API::IFunction_sptr PropertyHandler::changeType(QtProperty *prop) {
       f = Mantid::API::FunctionFactory::Instance().createFunction(
           fnName.toStdString());
     } catch (std::exception &e) {
-      QMessageBox::critical(NULL, "Mantid - Error", "Cannot create function " +
-                                                        fnName + "\n" +
-                                                        e.what());
+      QMessageBox::critical(nullptr, "Mantid - Error",
+                            "Cannot create function " + fnName + "\n" +
+                                e.what());
       return Mantid::API::IFunction_sptr();
     }
 
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp b/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp
index 069dfec78e40dc310a1de3161f7e6b381b68d735..8833948710c46b8356fbd18f7b5e89c05e8a11a6 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp
@@ -841,7 +841,7 @@ void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
     QLineEdit *editor = itEditor.next();
     editor->blockSignals(true);
     const QValidator *oldValidator = editor->validator();
-    QValidator *newValidator = 0;
+    QValidator *newValidator = nullptr;
     if (regExp.isValid()) {
       newValidator = new QRegExpValidator(regExp, editor);
     }
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp
index 9dc93ffc64f259037c3138e368c3c5f3b4d46606..0f3a896401503d81c91f49bfe5b36dec1bff81a7 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp
@@ -1172,12 +1172,12 @@ QtBrowserItem::~QtBrowserItem() { delete d_ptr; }
 
 ////////////////////////////////////
 
-typedef QMap<QtAbstractPropertyBrowser *,
-             QMap<QtAbstractPropertyManager *, QtAbstractEditorFactoryBase *>>
-    Map1;
-typedef QMap<QtAbstractPropertyManager *,
-             QMap<QtAbstractEditorFactoryBase *,
-                  QList<QtAbstractPropertyBrowser *>>> Map2;
+using Map1 =
+    QMap<QtAbstractPropertyBrowser *,
+         QMap<QtAbstractPropertyManager *, QtAbstractEditorFactoryBase *>>;
+using Map2 =
+    QMap<QtAbstractPropertyManager *, QMap<QtAbstractEditorFactoryBase *,
+                                           QList<QtAbstractPropertyBrowser *>>>;
 Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory)
 Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews)
 
@@ -1783,7 +1783,7 @@ QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
   while (pos < pendingList.count()) {
     QtProperty *prop = pendingList.at(pos);
     if (prop == property)
-      return 0;
+      return nullptr;
     if (prop == afterProperty) {
       newPos = pos + 1;
     }
@@ -1819,10 +1819,11 @@ void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) {
     if (pendingList.at(pos) == property) {
       d_ptr->m_subItems.removeAt(pos); // perhaps this two lines
       d_ptr->removeSubTree(
-          property, 0); // should be moved down after propertyRemoved call.
+          property,
+          nullptr); // should be moved down after propertyRemoved call.
       // propertyRemoved(property, 0);
 
-      d_ptr->removeBrowserIndexes(property, 0);
+      d_ptr->removeBrowserIndexes(property, nullptr);
 
       // when item is deleted, item will call removeItem for top level items,
       // and itemRemoved for nested items.
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp
index 997c7b4111f65b5ededeb77514a22021615aaa9f..577f0648bff874b30fca4926e00588c302d14817 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp
@@ -97,7 +97,7 @@
 namespace {
 // Translation function for Qt4/Qt5. Qt5 has no encoding option
 QString translateUtf8Encoded(const char *context, const char *key,
-                             const char *disambiguation = 0, int n = -1) {
+                             const char *disambiguation = nullptr, int n = -1) {
 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
   return QApplication::translate(context, key, disambiguation,
                                  QApplication::UnicodeUTF8, n);
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp
index fc25dbddf2d34fb5a00715c106f82da311a22902..7a3c6999697037ea21a9835114e82ed8a5781737 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp
@@ -361,7 +361,7 @@ public:
     }
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 };
 
@@ -638,7 +638,7 @@ public:
     }
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 };
 
@@ -969,7 +969,7 @@ public:
     QRegExp regExp;
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   QMap<const QtProperty *, Data> m_values;
 };
 
@@ -1320,7 +1320,7 @@ public:
 
   QString m_format;
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   QMap<const QtProperty *, Data> m_values;
 };
 
@@ -1537,7 +1537,7 @@ class QtTimePropertyManagerPrivate {
 public:
   QString m_format;
 
-  typedef QMap<const QtProperty *, QTime> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QTime>;
   PropertyValueMap m_values;
 };
 
@@ -1646,7 +1646,7 @@ class QtDateTimePropertyManagerPrivate {
 public:
   QString m_format;
 
-  typedef QMap<const QtProperty *, QDateTime> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QDateTime>;
   PropertyValueMap m_values;
 };
 
@@ -1755,7 +1755,7 @@ class QtKeySequencePropertyManagerPrivate {
 public:
   QString m_format;
 
-  typedef QMap<const QtProperty *, QKeySequence> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QKeySequence>;
   PropertyValueMap m_values;
 };
 
@@ -1861,7 +1861,7 @@ class QtCharPropertyManagerPrivate {
   QtCharPropertyManager *q_ptr;
   Q_DECLARE_PUBLIC(QtCharPropertyManager)
 public:
-  typedef QMap<const QtProperty *, QChar> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QChar>;
   PropertyValueMap m_values;
 };
 
@@ -4170,7 +4170,7 @@ public:
     QMap<int, QIcon> enumIcons;
   };
 
-  typedef QMap<const QtProperty *, Data> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, Data>;
   PropertyValueMap m_values;
 };
 
@@ -5125,7 +5125,7 @@ void QtFontPropertyManagerPrivate::slotFontDatabaseChanged() {
 }
 
 void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange() {
-  typedef QMap<const QtProperty *, QtProperty *> PropertyPropertyMap;
+  using PropertyPropertyMap = QMap<const QtProperty *, QtProperty *>;
   // rescan available font names
   const QStringList oldFamilies = m_familyNames;
   m_familyNames = fontDatabase()->families();
@@ -5732,7 +5732,7 @@ class QtCursorPropertyManagerPrivate {
   QtCursorPropertyManager *q_ptr;
   Q_DECLARE_PUBLIC(QtCursorPropertyManager)
 public:
-  typedef QMap<const QtProperty *, QCursor> PropertyValueMap;
+  using PropertyValueMap = QMap<const QtProperty *, QCursor>;
   PropertyValueMap m_values;
 };
 
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp
index 80229ea10fb1b1f3574b2017140535db88980235..4ec953bc4b9c28c317287d843d8086501e7fed5e 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp
@@ -103,7 +103,7 @@
 namespace {
 // Translation function for Qt4/Qt5. Qt5 has no encoding option
 QString translateUtf8Encoded(const char *context, const char *key,
-                             const char *disambiguation = 0, int n = -1) {
+                             const char *disambiguation = nullptr, int n = -1) {
 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
   return QApplication::translate(context, key, disambiguation,
                                  QApplication::UnicodeUTF8, n);
@@ -483,8 +483,8 @@ QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const {
 void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem,
                                                   bool block) {
   const bool blocked = block ? m_treeWidget->blockSignals(true) : false;
-  if (browserItem == 0)
-    m_treeWidget->setCurrentItem(0);
+  if (browserItem == nullptr)
+    m_treeWidget->setCurrentItem(nullptr);
   else
     m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem));
   if (block)
@@ -575,7 +575,7 @@ void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) {
   QTreeWidgetItem *item = m_indexToItem.value(index);
 
   if (m_treeWidget->currentItem() == item) {
-    m_treeWidget->setCurrentItem(0);
+    m_treeWidget->setCurrentItem(nullptr);
   }
 
   delete item;
diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp
index e732afdb2ee766f9f7c5deb20b7b3873cf85a50e..afcd204455054096c6156ff6f80b5c4c6c5939e5 100644
--- a/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp
+++ b/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp
@@ -171,7 +171,7 @@ int QtVariantPropertyManager::iconMapTypeId() {
   return qMetaTypeId<QtIconMap>();
 }
 
-typedef QMap<const QtProperty *, QtProperty *> PropertyMap;
+using PropertyMap = QMap<const QtProperty *, QtProperty *>;
 Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty)
 
 static QtProperty *wrappedProperty(QtProperty *property) {
diff --git a/qt/widgets/common/src/SaveWorkspaces.cpp b/qt/widgets/common/src/SaveWorkspaces.cpp
index 9f234bb042d30532b4e66e2f4cda571347cb5eed..ef1f1d0152798604da132b87fd9d668a82b88ba2 100644
--- a/qt/widgets/common/src/SaveWorkspaces.cpp
+++ b/qt/widgets/common/src/SaveWorkspaces.cpp
@@ -342,7 +342,7 @@ void SaveWorkspaces::saveSel() {
     } // end if save in this format
   }   // end loop over formats
 
-  saveCommands += "print 'success'";
+  saveCommands += "print('success')";
   QString status(runPythonCode(saveCommands).trimmed());
 
   if (m_saveAsZeroErrorFree) {
@@ -446,7 +446,7 @@ void SaveWorkspaces::saveFileBrowse() {
                                     ? QFileDialog::DontConfirmOverwrite
                                     : static_cast<QFileDialog::Option>(0);
   QString oFile = QFileDialog::getSaveFileName(this, title, prevPath, filter,
-                                               NULL, userCon);
+                                               nullptr, userCon);
 
   if (!oFile.isEmpty()) {
     m_fNameEdit->setText(oFile);
diff --git a/qt/widgets/common/src/SelectWorkspacesDialog.cpp b/qt/widgets/common/src/SelectWorkspacesDialog.cpp
index 723c1fac9af3a065e12291b0f2d0dca8bfe2925b..02988668ed265ad43fcc568023cfac6efe671f63 100644
--- a/qt/widgets/common/src/SelectWorkspacesDialog.cpp
+++ b/qt/widgets/common/src/SelectWorkspacesDialog.cpp
@@ -56,7 +56,7 @@ SelectWorkspacesDialog::SelectWorkspacesDialog(
 
   Mantid::API::AnalysisDataServiceImpl &ADS =
       Mantid::API::AnalysisDataService::Instance();
-  typedef std::vector<Mantid::API::Workspace_sptr> VecWorkspaces;
+  using VecWorkspaces = std::vector<Mantid::API::Workspace_sptr>;
   VecWorkspaces workspaces = ADS.getObjects();
   WorkspaceIsNotOfType comparitor(typeFilter);
   workspaces.erase(
diff --git a/qt/widgets/common/src/SlitCalculator.cpp b/qt/widgets/common/src/SlitCalculator.cpp
index f908023a796b777305c61ff4494316fd23273151..594217bd700c38437ffdf57f1e1dcdf90589953f 100644
--- a/qt/widgets/common/src/SlitCalculator.cpp
+++ b/qt/widgets/common/src/SlitCalculator.cpp
@@ -62,8 +62,8 @@ void SlitCalculator::setupSlitCalculatorWithInstrumentValues(
   auto slit2Component = instrument->getComponentByName("slit2");
   auto sampleComponent = instrument->getComponentByName("some-surface-holder");
   // check that they have been fetched from the IDF
-  if (slit1Component.get() != NULL && slit2Component.get() != NULL &&
-      sampleComponent.get() != NULL) {
+  if (slit1Component.get() != nullptr && slit2Component.get() != nullptr &&
+      sampleComponent.get() != nullptr) {
     // convert from meters to millimeters
     const double s1s2 = 1e3 * (slit1Component->getDistance(*slit2Component));
     // set value in field of slitCalculator
diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
index b491ee8266ef555bfac3935c6b429eb2d5ffb41f..5b785c9b3f2f3292f0477eb08293c11f91f2f26a 100644
--- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
+++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp
@@ -491,7 +491,7 @@ void WorkspaceTreeWidget::filterWorkspaces(const std::string &filterText) {
               item->setHidden(false);
             }
 
-            if (item->parent() == NULL) {
+            if (item->parent() == nullptr) {
               // No parent, I am a top level workspace - show me
               item->setHidden(false);
             } else {
@@ -733,9 +733,8 @@ void WorkspaceTreeWidget::populateChildData(QTreeWidgetItem *item) {
   Workspace_sptr workspace = userData.value<Workspace_sptr>();
 
   if (auto group = boost::dynamic_pointer_cast<WorkspaceGroup>(workspace)) {
-    const size_t nmembers = group->getNumberOfEntries();
-    for (size_t i = 0; i < nmembers; ++i) {
-      auto ws = group->getItem(i);
+    auto members = group->getAllItems();
+    for (const auto &ws : members) {
       auto *node = addTreeEntry(std::make_pair(ws->getName(), ws), item);
       excludeItemFromSort(node);
       if (shouldBeSelected(node->text(0)))
diff --git a/qt/widgets/common/src/WorkspaceSelector.cpp b/qt/widgets/common/src/WorkspaceSelector.cpp
index ff46217badec91527bc80ff30c635fe40541507d..5e885ea90aa91e5c7ee1d2711ae3437731781235 100644
--- a/qt/widgets/common/src/WorkspaceSelector.cpp
+++ b/qt/widgets/common/src/WorkspaceSelector.cpp
@@ -145,7 +145,7 @@ void WorkspaceSelector::setValidatingAlgorithm(const QString &algName) {
         // try to cast property to WorkspaceProperty
         Mantid::API::WorkspaceProperty<> *wsProp =
             dynamic_cast<Mantid::API::WorkspaceProperty<> *>(*it);
-        if (wsProp != NULL) {
+        if (wsProp != nullptr) {
           m_algPropName = QString::fromStdString((*it)->name());
           break;
         }
diff --git a/qt/widgets/common/src/pqHelpWindow.cxx b/qt/widgets/common/src/pqHelpWindow.cxx
index 07f81f424fded698039bd9e212ab27a9c22611c1..f9d19ee4229ab77596b622b77bc5acb30f512beb 100644
--- a/qt/widgets/common/src/pqHelpWindow.cxx
+++ b/qt/widgets/common/src/pqHelpWindow.cxx
@@ -58,7 +58,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /// Internal class used to add support to QWeb(Engine)View to load files from
 /// QHelpEngine.
 class pqHelpWindowNetworkReply : public QNetworkReply {
-  typedef QNetworkReply Superclass;
+  using Superclass = QNetworkReply;
 
 public:
   pqHelpWindowNetworkReply(const QUrl &url, QHelpEngineCore *helpEngine,
@@ -139,14 +139,14 @@ qint64 pqHelpWindowNetworkReply::readData(char *data, qint64 maxSize) {
 // ****************************************************************************
 //-----------------------------------------------------------------------------
 class pqHelpWindow::pqNetworkAccessManager : public QNetworkAccessManager {
-  typedef QNetworkAccessManager Superclass;
+  using Superclass = QNetworkAccessManager;
   QPointer<QHelpEngineCore> Engine;
 
 public:
   pqNetworkAccessManager(QHelpEngineCore *helpEngine,
                          QNetworkAccessManager *manager, QObject *parentObject)
       : Superclass(parentObject), Engine(helpEngine) {
-    Q_ASSERT(manager != NULL && helpEngine != NULL);
+    Q_ASSERT(manager != nullptr && helpEngine != nullptr);
 
     this->setCache(manager->cache());
     this->setCookieJar(manager->cookieJar());
@@ -205,7 +205,7 @@ private:
 pqHelpWindow::pqHelpWindow(QHelpEngine *engine, QWidget *parentObject,
                            Qt::WindowFlags parentFlags)
     : Superclass(parentObject, parentFlags), m_helpEngine(engine) {
-  Q_ASSERT(engine != NULL);
+  Q_ASSERT(engine != nullptr);
 
   Ui::pqHelpWindow ui;
   ui.setupUi(this);
diff --git a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h
index 19f911f5ed8ddae6ad15d97ec3daad39e7c97c65..fda3bd3be5d3dd154ef01b1321bc0399832abff3 100644
--- a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h
+++ b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h
@@ -26,17 +26,18 @@ class GenerateNotebookTest : public CxxTest::TestSuite {
 private:
   // Creates a map with pre-processing instruction for reflectometry
   std::map<QString, PreprocessingAlgorithm>
-  reflPreprocessMap(const QString &plusPrefix = "") {
+  reflPreprocessMap(const QString &plusPrefix = "",
+                    const QString &transPrefix = "TRANS_") {
 
     // Reflectometry pre-process map
     return std::map<QString, PreprocessingAlgorithm>{
         {"Run(s)",
-         PreprocessingAlgorithm("Plus", plusPrefix, std::set<QString>())},
+         PreprocessingAlgorithm("Plus", plusPrefix, "+", std::set<QString>())},
         {"Transmission Run(s)",
-         PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_",
-                                std::set<QString>{"FirstTransmissionRun",
-                                                  "SecondTransmissionRun",
-                                                  "OutputWorkspace"})}};
+         PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", transPrefix,
+                                "_", std::set<QString>{"FirstTransmissionRun",
+                                                       "SecondTransmissionRun",
+                                                       "OutputWorkspace"})}};
   }
 
   // Creates a reflectometry processing algorithm
@@ -151,10 +152,10 @@ public:
 
     auto notebookLines = splitIntoLines(generatedNotebook);
     const QString result[] = {
-        "{", "   \"metadata\" : {", "      \"name\" : \"Mantid Notebook\"",
+        "{", "   \"metadata\" : {", R"(      "name" : "Mantid Notebook")",
         "   },", "   \"nbformat\" : 3,", "   \"nbformat_minor\" : 0,",
         "   \"worksheets\" : [", "      {", "         \"cells\" : [",
-        "            {", "               \"cell_type\" : \"markdown\",",
+        "            {", R"(               "cell_type" : "markdown",)",
     };
 
     // Check that the first 10 lines are output as expected
@@ -265,7 +266,7 @@ public:
   }
 
   void testLoadWorkspaceStringThreeRunsWithOptions() {
-    PreprocessingAlgorithm preprocessor("WeightedMean");
+    PreprocessingAlgorithm preprocessor("WeightedMean", "", "+");
     auto output = loadWorkspaceString("RUN1+RUN2,RUN3", "INST_", preprocessor,
                                       "Property1 = 1, Property2 = 2");
     auto outputLines = splitIntoLines(boost::get<0>(output));
@@ -345,7 +346,8 @@ public:
 
     // Create a pre-process map
     std::map<QString, PreprocessingAlgorithm> preprocessMap = {
-        {"Run", PreprocessingAlgorithm("Plus", "RUN_", std::set<QString>())}};
+        {"Run",
+         PreprocessingAlgorithm("Plus", "RUN_", "+", std::set<QString>())}};
     // Specify some pre-processing options
     auto runOptions = OptionsMap{{"Property", "prop"}};
     auto userPreProcessingOptions = ColumnOptionsMap{{"Run", runOptions}};
@@ -425,16 +427,18 @@ public:
     // Create some data
     const auto data = makeRowData(
         {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""});
-    TS_ASSERT_THROWS_ANYTHING(getReducedWorkspaceName(data, whitelist));
+    auto reflectometryPreprocessMap = reflPreprocessMap();
+    TS_ASSERT_THROWS_ANYTHING(
+        getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap));
   }
 
   void testReducedWorkspaceNameOnlyRun() {
 
     // Create a whitelist
     WhiteList whitelist;
-    whitelist.addElement("Run", "", "", true, "run_");
+    whitelist.addElement("Run(s)", "", "", true, "run_");
     whitelist.addElement("Angle", "", "", false, "");
-    whitelist.addElement("Trans", "", "", false, "");
+    whitelist.addElement("Transmission Run(s)", "", "", false, "");
     whitelist.addElement("Q min", "MomentumTransferMinimum", "");
     whitelist.addElement("Q max", "MomentumTransferMaximum", "");
     whitelist.addElement("dQ/Q", "MomentumTransferStep", "");
@@ -446,7 +450,9 @@ public:
     const auto data = makeRowData(
         {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""});
 
-    auto name = getReducedWorkspaceName(data, whitelist);
+    auto reflectometryPreprocessMap = reflPreprocessMap("run_", "");
+    auto name =
+        getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap);
     TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001")
   }
 
@@ -454,9 +460,9 @@ public:
 
     // Create a whitelist
     WhiteList whitelist;
-    whitelist.addElement("Run", "", "", true, "run_");
+    whitelist.addElement("Run(s)", "", "", true, "run_");
     whitelist.addElement("Angle", "", "", false, "");
-    whitelist.addElement("Trans", "", "", true, "trans_");
+    whitelist.addElement("Transmission Run(s)", "", "", true, "trans_");
     whitelist.addElement("Q min", "MomentumTransferMinimum", "");
     whitelist.addElement("Q max", "MomentumTransferMaximum", "");
     whitelist.addElement("dQ/Q", "MomentumTransferStep", "");
@@ -468,17 +474,19 @@ public:
     const auto data = makeRowData(
         {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""});
 
-    auto name = getReducedWorkspaceName(data, whitelist);
-    TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001_trans_2000+2001")
+    auto reflectometryPreprocessMap = reflPreprocessMap("run_", "trans_");
+    auto name =
+        getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap);
+    TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001_trans_2000_2001")
   }
 
   void testReducedWorkspaceNameTransNoPrefix() {
 
     // Create a whitelist
     WhiteList whitelist;
-    whitelist.addElement("Run", "", "", false, "");
+    whitelist.addElement("Run(s)", "", "", false, "");
     whitelist.addElement("Angle", "", "", false, "");
-    whitelist.addElement("Trans", "", "", true, "");
+    whitelist.addElement("Transmission Run(s)", "", "", true, "");
     whitelist.addElement("Q min", "MomentumTransferMinimum", "");
     whitelist.addElement("Q max", "MomentumTransferMaximum", "");
     whitelist.addElement("dQ/Q", "MomentumTransferStep", "");
@@ -489,8 +497,10 @@ public:
     const auto data = makeRowData(
         {"1000,1001", "0.5", "2000+2001", "1.4", "2.9", "0.04", "1", "", ""});
 
-    auto name = getReducedWorkspaceName(data, whitelist);
-    TS_ASSERT_EQUALS(name.toStdString(), "2000+2001")
+    auto reflectometryPreprocessMap = reflPreprocessMap("", "");
+    auto name =
+        getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap);
+    TS_ASSERT_EQUALS(name.toStdString(), "2000_2001")
   }
 
   void testPostprocessGroupString() {
@@ -831,7 +841,7 @@ public:
         "'IvsLam_TOF_12345', ScaleFactor = '1', ThetaIn = '0.5')\\n\",");
     TS_ASSERT_EQUALS(notebookLines[48].toStdString(), loadAndReduceString);
 
-    auto postProcessString = QString("               \"input\" : \"\",");
+    auto postProcessString = QString(R"(               "input" : "",)");
     TS_ASSERT_EQUALS(notebookLines[56], postProcessString);
 
     auto groupWorkspacesString = std::string(
@@ -866,7 +876,7 @@ public:
         "'IvsLam_TOF_12346', ScaleFactor = '1', ThetaIn = '1.5')\\n\",";
     TS_ASSERT_EQUALS(notebookLines[77].toStdString(), loadAndReduceString);
 
-    postProcessString = "               \"input\" : \"\",";
+    postProcessString = R"(               "input" : "",)";
     TS_ASSERT_EQUALS(notebookLines[85], postProcessString);
 
     groupWorkspacesString =
diff --git a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h
index c6317dcaf4f2045b8579f1a05f939b3c998e527a..c36523b94b6b078a137322a9fea24540af8779e1 100644
--- a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h
+++ b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h
@@ -101,9 +101,9 @@ private:
       m_manager->setProcessed(true, rowItem->first, groupIndex);
     } catch (std::exception &ex) {
       reductionError(QString(ex.what()));
-      threadFinished(1);
+      rowThreadFinished(1);
     }
-    threadFinished(0);
+    rowThreadFinished(0);
   }
 
   // non-async group reduce
@@ -115,9 +115,9 @@ private:
         m_manager->setProcessed(true, groupIndex);
     } catch (std::exception &ex) {
       reductionError(QString(ex.what()));
-      threadFinished(1);
+      groupThreadFinished(1);
     }
-    threadFinished(0);
+    groupThreadFinished(0);
   }
 
   // Overriden non-async methods have same implementation as parent class
@@ -148,15 +148,16 @@ private:
 
   const std::map<QString, PreprocessingAlgorithm>
   createReflectometryPreprocessingStep() {
-    return {{"Run(s)", PreprocessingAlgorithm(
-                           "Plus", "TOF_",
-                           std::set<QString>{"LHSWorkspace", "RHSWorkspace",
-                                             "OutputWorkspace"})},
-            {"Transmission Run(s)",
-             PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_",
-                                    std::set<QString>{"FirstTransmissionRun",
-                                                      "SecondTransmissionRun",
-                                                      "OutputWorkspace"})}};
+    return {
+        {"Run(s)", PreprocessingAlgorithm(
+                       "Plus", "TOF_", "+",
+                       std::set<QString>{"LHSWorkspace", "RHSWorkspace",
+                                         "OutputWorkspace"})},
+        {"Transmission Run(s)",
+         PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_",
+                                "_", std::set<QString>{"FirstTransmissionRun",
+                                                       "SecondTransmissionRun",
+                                                       "OutputWorkspace"})}};
   }
 
   ProcessingAlgorithm createReflectometryProcessor() {
@@ -2951,13 +2952,13 @@ public:
 
     // Test the names of the reduced workspaces
     TS_ASSERT_EQUALS(row0->reducedName().toStdString(),
-                     "TOF_12345_TRANS_11115+11116");
+                     "TOF_12345_TRANS_11115_11116");
     TS_ASSERT_EQUALS(row1->reducedName().toStdString(),
-                     "TOF_12346_TRANS_11115+11116");
+                     "TOF_12346_TRANS_11115_11116");
     // Test the names of the post-processed ws
     TS_ASSERT_EQUALS(
         presenter->getPostprocessedWorkspaceName(group).toStdString(),
-        "IvsQ_TOF_12345_TRANS_11115+11116_TOF_12346_TRANS_11115+11116");
+        "IvsQ_TOF_12345_TRANS_11115_11116_TOF_12346_TRANS_11115_11116");
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockDataProcessorView));
   }
diff --git a/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h b/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h
index 60bac99346df65537d914372c05e5b3971a8b634..f1284069265b6316eae050f1b02242ae50d3decf 100644
--- a/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h
+++ b/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h
@@ -28,9 +28,9 @@ public:
 
   void test_add_element() {
     PreprocessMap preprocessMap;
-    preprocessMap.addElement("Runs", "Plus");
+    preprocessMap.addElement("Runs", "Plus", "", "+");
     preprocessMap.addElement("Transmission Runs",
-                             "CreateTransmissionWorkspaceAuto", "TRANS_",
+                             "CreateTransmissionWorkspaceAuto", "TRANS_", "_",
                              "FirstTransmissionRun,SecondTransmissionRun");
 
     auto preprocessingInstructions = preprocessMap.asMap();
@@ -38,12 +38,14 @@ public:
     PreprocessingAlgorithm algPlus = preprocessingInstructions["Runs"];
     TS_ASSERT_EQUALS(algPlus.name(), "Plus");
     TS_ASSERT_EQUALS(algPlus.prefix(), "");
+    TS_ASSERT_EQUALS(algPlus.separator(), "+");
     TS_ASSERT_EQUALS(algPlus.blacklist(), std::set<QString>());
 
     PreprocessingAlgorithm algTrans =
         preprocessingInstructions["Transmission Runs"];
     TS_ASSERT_EQUALS(algTrans.name(), "CreateTransmissionWorkspaceAuto");
     TS_ASSERT_EQUALS(algTrans.prefix(), "TRANS_");
+    TS_ASSERT_EQUALS(algTrans.separator(), "_");
     std::set<QString> blacklist = {"FirstTransmissionRun",
                                    "SecondTransmissionRun"};
     TS_ASSERT_EQUALS(algTrans.blacklist(), blacklist);
diff --git a/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h b/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h
index 15f0109aab708adde74607d4f7f31613c8917b1b..f47a0b99b42c9e6638a715ed95e4d97ccd0a52d3 100644
--- a/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h
+++ b/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h
@@ -61,6 +61,7 @@ public:
     TS_ASSERT_EQUALS(plus.rhsProperty(), "");
     TS_ASSERT_EQUALS(plus.outputProperty(), "");
     TS_ASSERT_EQUALS(plus.prefix(), "");
+    TS_ASSERT_EQUALS(plus.separator(), "");
     TS_ASSERT_EQUALS(plus.blacklist().size(), 0);
   }
 
@@ -69,7 +70,7 @@ public:
     // WeightedMean
     std::set<QString> blacklist = {"InputWorkspace1", "InputWorkspace2",
                                    "OutputWorkspace"};
-    auto mean = PreprocessingAlgorithm("WeightedMean", "", blacklist);
+    auto mean = PreprocessingAlgorithm("WeightedMean", "", "+", blacklist);
     TS_ASSERT_EQUALS(mean.lhsProperty(), "InputWorkspace1");
     TS_ASSERT_EQUALS(mean.rhsProperty(), "InputWorkspace2");
     TS_ASSERT_EQUALS(mean.outputProperty(), "OutputWorkspace");
diff --git a/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h
index 5d5996179b3274ed2824bb0862aea672e74b70f5..e1cc013e734b2f8145314a66649b2a8c1317a777 100644
--- a/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h
+++ b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h
@@ -29,7 +29,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
     // Arrange
     FakeMWRunFiles *widget = new FakeMWRunFiles();
 
@@ -56,7 +56,7 @@ public:
     poolManager.createWorker(widget, parameters);
     // Block and wait for all the threads to process
     poolManager.waitForDone();
-    QApplication::processEvents();
+    QCoreApplication::processEvents();
 
     // Assert
     const auto results = widget->getResults();
@@ -72,7 +72,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
     // Arrange
     FakeMWRunFiles widget;
 
@@ -118,7 +118,7 @@ public:
 
     // Block and wait for all the threads to process
     poolManager.waitForDone();
-    QApplication::processEvents();
+    QCoreApplication::processEvents();
 
     // Assert
     const auto results = widget.getResults();
diff --git a/qt/widgets/common/test/FindFilesWorkerTest.h b/qt/widgets/common/test/FindFilesWorkerTest.h
index f491c72bc0e8bb8db73131cb21c6f0487de0122f..6f1469861009a76ea27284fe530a4d740c3127b5 100644
--- a/qt/widgets/common/test/FindFilesWorkerTest.h
+++ b/qt/widgets/common/test/FindFilesWorkerTest.h
@@ -28,7 +28,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
 
     auto parameters = createFileSearch("IRS26173");
     auto worker = new FindFilesWorker(parameters);
@@ -52,7 +52,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
 
     auto parameters = createFileSearch("IRS26173");
     parameters.algorithmName = "";
@@ -79,7 +79,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
 
     auto parameters = createFileSearch("ThisFileDoesNotExist");
     auto worker = new FindFilesWorker(parameters);
@@ -100,7 +100,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
 
     auto parameters = createFileSearch("");
     auto worker = new FindFilesWorker(parameters);
@@ -121,7 +121,7 @@ public:
     int argc = 1;
     char name[] = "DummyTestingApplication";
     char *argv = name;
-    QApplication app(argc, &argv);
+    QCoreApplication app(argc, &argv);
 
     auto parameters = createFileSearch("");
     parameters.isOptional = true;
diff --git a/qt/widgets/common/test/ParseKeyValueStringTest.h b/qt/widgets/common/test/ParseKeyValueStringTest.h
index ee09cdd2afaf2e553ef2c3f57ceb8f05164c304f..9b2f84085088a2df25bd2aba63ba212d428b718a 100644
--- a/qt/widgets/common/test/ParseKeyValueStringTest.h
+++ b/qt/widgets/common/test/ParseKeyValueStringTest.h
@@ -12,7 +12,7 @@ class ParseKeyValueStringTest : public CxxTest::TestSuite {
 public:
   void testParseKeyValueString() {
     std::map<std::string, std::string> kvp = parseKeyValueString(
-        "a = 1,b=2.0, c=3, d='1,2,3',e=\"4,5,6\",f=1+1=2, g = '\\''");
+        R"(a = 1,b=2.0, c=3, d='1,2,3',e="4,5,6",f=1+1=2, g = '\'')");
 
     TS_ASSERT_EQUALS(kvp["a"], "1");
     TS_ASSERT_EQUALS(kvp["b"], "2.0");
@@ -33,7 +33,7 @@ public:
 
   void testParseKeyValueQString() {
     std::map<QString, QString> kvp = parseKeyValueQString(
-        "a = 1,b=2.0, c=3, d='1,2,3',e=\"4,5,6\",f=1+1=2, g = '\\''");
+        R"(a = 1,b=2.0, c=3, d='1,2,3',e="4,5,6",f=1+1=2, g = '\'')");
 
     TS_ASSERT_EQUALS(kvp["a"], "1");
     TS_ASSERT_EQUALS(kvp["b"], "2.0");
diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt
index 04520f23ba7b3144942462938bbafc22889f97e5..acf4828ccf872ad39f5fcc1a837e3a4d1b036091 100644
--- a/qt/widgets/instrumentview/CMakeLists.txt
+++ b/qt/widgets/instrumentview/CMakeLists.txt
@@ -1,16 +1,11 @@
 set ( SRC_FILES
+        src/BankRenderingHelpers.cpp
 	src/BinDialog.cpp
 	src/CollapsiblePanel.cpp
 	src/ColorMapWidget.cpp
-	src/CompAssemblyActor.cpp
-	src/ComponentActor.cpp
 	src/DetXMLFile.cpp
-	src/GLActor.cpp
-	src/GLActorCollection.cpp
-	src/GLActorVisitor.cpp
 	src/GLColor.cpp
 	src/GLObject.cpp
-	src/ICompAssemblyActor.cpp
 	src/InstrumentActor.cpp
 	src/InstrumentTreeModel.cpp
 	src/InstrumentTreeWidget.cpp
@@ -18,12 +13,11 @@ set ( SRC_FILES
 	src/InstrumentWidgetMaskTab.cpp
 	src/InstrumentWidgetPickTab.cpp
 	src/InstrumentWidgetRenderTab.cpp
+        src/InstrumentRenderer.cpp
 	src/InstrumentWidgetTab.cpp
 	src/InstrumentWidgetTreeTab.cpp
 	src/MantidGLWidget.cpp
 	src/MaskBinsData.cpp
-	src/ObjCompAssemblyActor.cpp
-	src/ObjComponentActor.cpp
 	src/OneCurvePlot.cpp
 	src/OpenGLError.cpp
 	src/PanelsSurface.cpp
@@ -32,15 +26,13 @@ set ( SRC_FILES
 	src/Projection3D.cpp
 	src/ProjectionSurface.cpp
 	src/RectF.cpp
-	src/RectangularDetectorActor.cpp
 	src/RotationSurface.cpp
-	src/SampleActor.cpp
 	src/Shape2D.cpp
 	src/Shape2DCollection.cpp
 	src/SimpleWidget.cpp
-	src/StructuredDetectorActor.cpp
 	src/UCorrectionDialog.cpp
 	src/UnwrappedCylinder.cpp
+	src/UnwrappedDetector.cpp
 	src/UnwrappedSphere.cpp
 	src/UnwrappedSurface.cpp
 	src/Viewport.cpp
@@ -72,23 +64,19 @@ set ( MOC_FILES
 )
 
 set ( INC_FILES
+	inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h
 	inc/MantidQtWidgets/InstrumentView/BinDialog.h
 	inc/MantidQtWidgets/InstrumentView/CollapsiblePanel.h
 	inc/MantidQtWidgets/InstrumentView/ColorMapWidget.h
-	inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h
-	inc/MantidQtWidgets/InstrumentView/ComponentActor.h
 	inc/MantidQtWidgets/InstrumentView/DetXMLFile.h
 	inc/MantidQtWidgets/InstrumentView/DllOption.h
-	inc/MantidQtWidgets/InstrumentView/GLActor.h
-	inc/MantidQtWidgets/InstrumentView/GLActorCollection.h
-	inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h
 	inc/MantidQtWidgets/InstrumentView/GLColor.h
 	inc/MantidQtWidgets/InstrumentView/GLObject.h
-	inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h
+        inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentWidgetMaskTab.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h
 	inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h
@@ -97,8 +85,6 @@ set ( INC_FILES
 	inc/MantidQtWidgets/InstrumentView/InstrumentWidgetTypes.h
 	inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h
 	inc/MantidQtWidgets/InstrumentView/MaskBinsData.h
-	inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h
-	inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h
 	inc/MantidQtWidgets/InstrumentView/OneCurvePlot.h
 	inc/MantidQtWidgets/InstrumentView/OpenGLError.h
 	inc/MantidQtWidgets/InstrumentView/PanelsSurface.h
@@ -107,15 +93,13 @@ set ( INC_FILES
 	inc/MantidQtWidgets/InstrumentView/Projection3D.h
 	inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
 	inc/MantidQtWidgets/InstrumentView/RectF.h
-	inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h
 	inc/MantidQtWidgets/InstrumentView/RotationSurface.h
-	inc/MantidQtWidgets/InstrumentView/SampleActor.h
 	inc/MantidQtWidgets/InstrumentView/Shape2D.h
 	inc/MantidQtWidgets/InstrumentView/Shape2DCollection.h
 	inc/MantidQtWidgets/InstrumentView/SimpleWidget.h
-	inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h
 	inc/MantidQtWidgets/InstrumentView/UCorrectionDialog.h
 	inc/MantidQtWidgets/InstrumentView/UnwrappedCylinder.h
+	inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h
 	inc/MantidQtWidgets/InstrumentView/UnwrappedSphere.h
 	inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h
 	inc/MantidQtWidgets/InstrumentView/Viewport.h
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a8fd3b296da0521abc361c1296ef2ffff232b10
--- /dev/null
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h
@@ -0,0 +1,39 @@
+#ifndef BANKRENDERINGHELPERS_H
+#define BANKRENDERINGHELPERS_H
+#include "DllOption.h"
+#include "MantidQtWidgets/InstrumentView/GLColor.h"
+#include <vector>
+
+namespace Mantid {
+namespace Geometry {
+class ComponentInfo;
+}
+} // namespace Mantid
+
+namespace MantidQt {
+namespace MantidWidgets {
+namespace BankRenderingHelpers {
+
+EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW std::pair<size_t, size_t>
+getCorrectedTextureSize(const size_t width, const size_t height);
+
+/** Render RectangularDetector Bank as bitmap texture
+Makes OpenGL calls for drawing the bank in an OpenGL window. NB glBegin() and
+glEnd() are called within this function.
+*/
+EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW void
+renderRectangularBank(const Mantid::Geometry::ComponentInfo &compInfo,
+                      size_t index);
+
+/** Render Structured Detector Bank as quads
+Makes OpenGL calls for drawing the bank in an OpenGL window. NB glBegin() and
+glEnd() are called within this function.
+*/
+EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW void
+renderStructuredBank(const Mantid::Geometry::ComponentInfo &compInfo,
+                     size_t index, const std::vector<GLColor> &color);
+} // namespace RenderingHelpers
+} // namespace MantidWidgets
+} // namespace MantidQt
+
+#endif // BANKRENDERINGHELPERS_H
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h
deleted file mode 100644
index 9116c22d17a99060ca3771bd6bba980159ba57cf..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef COMPASSEMBLY_ACTOR__H_
-#define COMPASSEMBLY_ACTOR__H_
-
-#include "ICompAssemblyActor.h"
-#include "GLActor.h"
-
-#include "MantidGeometry/IComponent.h"
-#include "MantidKernel/V3D.h"
-/**
-  \class  CompAssemblyActor
-  \brief  This class wraps the ICompAssembly into Actor.
-  \author Srikanth Nagella
-  \date   March 2009
-  \version 1.0
-
-  This class has the implementation for calling the children of ICompAssembly's
-  IObjComponent to render themselves
-  and call the ICompAssemblys. This maintains the count of the children for easy
-  lookup.
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class ICompAssembly;
-class CSGObject;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class InstrumentActor;
-
-class ObjComponentActor;
-
-class CompAssemblyActor : public ICompAssemblyActor {
-public:
-  CompAssemblyActor(
-      const InstrumentActor &instrActor,
-      const Mantid::Geometry::ComponentID &compID); ///< Constructor
-  ~CompAssemblyActor() override;
-  std::string type() const override {
-    return "CompAssemblyActor";
-  }                                               ///< Type of the GL object
-  void draw(bool picking = false) const override; ///< Method that defines
-  /// ObjComponent geometry. Calls
-  /// ObjComponent draw method
-  void setChildVisibility(bool) override;
-  bool hasChildVisible() const override;
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-  void setColors() override;
-
-protected:
-  mutable std::vector<ObjComponentActor *>
-      mChildObjCompActors; ///< List of ObjComponent Actors
-  mutable std::vector<ICompAssemblyActor *>
-      mChildCompAssemActors; ///< List of CompAssembly Actors
-private:
-  void AppendBoundingBox(const Mantid::Kernel::V3D &minBound,
-                         const Mantid::Kernel::V3D &maxBound);
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif /*GLTRIANGLE_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h
deleted file mode 100644
index ce4a12ef49c401ed1bcc026386a7782ca10d7e90..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef COMPONENT_ACTOR_H_
-#define COMPONENT_ACTOR_H_
-#include "GLActor.h"
-#include "GLColor.h"
-
-#include "MantidGeometry/IComponent.h"
-
-/**
-  \class  ObjComponentActor
-  \brief  ObjComponentActor is an actor class for rendering ObjComponents.
-  \author Srikanth Nagella
-  \date   March 2009
-  \version 1.0
-
-   This class has the implementation for rendering ObjComponents in OpenGL and
-  it inherits from the GLActor
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Geometry {
-class IObjComponent;
-class IDetector;
-class ObjCompAssembly;
-class CompAssembly;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class InstrumentActor;
-
-class ComponentActor : public GLActor {
-public:
-  ComponentActor(
-      const InstrumentActor &instrActor,
-      const Mantid::Geometry::ComponentID &compID); ///< Default Constructor
-  virtual std::string type() const {
-    return "ComponentActor";
-  } ///< Type of the GL object
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-  boost::shared_ptr<const Mantid::Geometry::IComponent> getComponent() const;
-  boost::shared_ptr<const Mantid::Geometry::IObjComponent>
-  getObjComponent() const;
-  boost::shared_ptr<const Mantid::Geometry::IDetector> getDetector() const;
-  boost::shared_ptr<const Mantid::Geometry::ObjCompAssembly>
-  getObjCompAssembly() const;
-  boost::shared_ptr<const Mantid::Geometry::CompAssembly>
-  getCompAssembly() const;
-  virtual void setColors() {}
-  /// Check if the component is a non-detector.
-  bool isNonDetector() const;
-
-protected:
-  const InstrumentActor &m_instrActor;
-  Mantid::Geometry::ComponentID m_id; ///< Component ID
-};
-} // MantidWidgets
-} // MantidQt
-
-#endif /*COMPONENT_ACTOR_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h
deleted file mode 100644
index 35d61fe78e9efae526986745f14fcda45ebb48c4..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/**________________________________________________
-* Library        : NTK
-* Name           : GLActor.h
-* Author         : L.C.Chapon
-* Date           : 8 Nov 2006
-* Description    : Base class for all objects in a 3D Scene.
-*                  Methods are provide to position and
-*                  rotate the objects. The objects can also
-*                  be set as active or not. Actors maintian safe pointer
-*                  to a GLObject.
-*________________________________________________
-*/
-#ifndef GLACTOR_H_
-#define GLACTOR_H_
-#include "MantidKernel/V3D.h"
-#include "GLObject.h"
-#include "GLColor.h"
-#include <boost/shared_ptr.hpp>
-
-#include <ostream>
-
-#include <QObject>
-#include <QList>
-#include <QRgb>
-
-namespace Mantid {
-namespace Geometry {
-class IDetector;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class GLActorVisitor;
-class GLActorConstVisitor;
-
-/**
-\class  GLActor
-\brief  An actor class that holds geometry objects with its position.
-\author Chapon Laurent & Srikanth Nagella
-\date   August 2008
-\version 1.0
-
-Base class for all objects in a 3D Scene. Methods are provided to position and
-rotate the objects.
-The objects can also be set as active or not. Actors maintain safe pointer to a
-GLObject.
-
-Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-enum class GLActorVisiblity : char { VISIBLE, HIDDEN, ALWAYS_HIDDEN };
-
-class GLActor : public QObject {
-public:
-  /// Rules for visitor propagation. If vistor's visit(...) method returns true
-  /// the propagation can be continued (VisitAll) or abandoned (Finish)
-  enum VisitorAcceptRule { VisitAll, Finish };
-  GLActor() : m_visible(GLActorVisiblity::VISIBLE) {}
-  ///< Virtual destructor
-  ~GLActor() override;
-  /// Toggle the visibility of the actor.
-  virtual void setVisibility(bool on);
-  /// Toggle the visibility of the child actors (if exist).
-  virtual void setChildVisibility(bool on) { setVisibility(on); }
-  /// Sets the current component to always hide
-  void setAlwaysHidden() { m_visible = GLActorVisiblity::ALWAYS_HIDDEN; }
-  /// Check if any child is visible
-  virtual bool hasChildVisible() const { return true; }
-  /// Get the visibility status.
-  bool isVisible() const { return m_visible == GLActorVisiblity::VISIBLE; }
-  /// Draw the actor in 3D.
-  virtual void draw(bool picking = false) const = 0;
-  /// Get the 3D bounding box of the actor
-  virtual void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                              Mantid::Kernel::V3D &maxBound) const = 0;
-  /// Accept a visitor
-  virtual bool accept(GLActorVisitor &visitor,
-                      VisitorAcceptRule rule = VisitAll);
-  /// Accept a const visitor
-  virtual bool accept(GLActorConstVisitor &visitor,
-                      VisitorAcceptRule rule = VisitAll) const;
-  /// Convert a "pick ID" to a colour to put into the pick image.
-  static GLColor makePickColor(size_t pickID);
-  /// Decode a pick colour and return corresponding "pick ID"
-  static size_t decodePickColor(const QRgb &c);
-  /// Decode a pick colour and return corresponding "pick ID"
-  static size_t decodePickColor(unsigned char r, unsigned char g,
-                                unsigned char b);
-  /// Get colour of a component which doesn't have any counts associated with
-  /// it.
-  static GLColor defaultDetectorColor();
-
-protected:
-  GLActorVisiblity m_visible; ///< Flag whether the actor is visible or not
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif /*GLACTOR_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h
deleted file mode 100644
index 78c2d909ac6778f08d226d784e69396515688a7e..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef GLACTORCOLLECTION_H_
-#define GLACTORCOLLECTION_H_
-#include "GLActor.h"
-
-#include "MantidKernel/V3D.h"
-
-#include <vector>
-
-namespace MantidQt {
-namespace MantidWidgets {
-/**
-\class  GLActorCollection
-\brief  An actor class collection
-\author Chapon Laurent & Srikanth Nagella
-\date   August 2008
-\version 1.0
-
-
-GLActorCollection has the list of GLActor.
-
-Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-
-class GLActorCollection : public GLActor {
-public:
-  GLActorCollection();           ///< Default Constructor
-  ~GLActorCollection() override; ///< Destructor
-  void setChildVisibility(bool) override;
-  bool hasChildVisible() const override;
-  void draw(bool picking = false) const override;
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-
-  void addActor(GLActor *);
-  void removeActor(GLActor *);
-  int getNumberOfActors();
-  GLActor *getActor(int index);
-  void invalidateDisplayList() const;
-
-private:
-  void drawGL(bool picking = false) const;
-  mutable std::vector<GLActor *>
-      mActorsList; ///< Vector of GLActors for fast access.
-  Mantid::Kernel::V3D m_minBound;
-  Mantid::Kernel::V3D m_maxBound;
-  mutable GLuint m_displayListId[2];
-  mutable bool m_useDisplayList[2];
-};
-} // MantidWidgets
-} // MantidQt
-
-#endif /*GLACTORCOLLECTION_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h
deleted file mode 100644
index 401783ed5355f659a9c80ae5475ced6dd7ab4ab0..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef GLACTORVISITOR_H
-#define GLACTORVISITOR_H
-
-namespace MantidQt {
-namespace MantidWidgets {
-class GLActor;
-class GLActorCollection;
-class ComponentActor;
-class CompAssemblyActor;
-class ObjCompAssemblyActor;
-class RectangularDetectorActor;
-class StructuredDetectorActor;
-class InstrumentActor;
-
-/**
-* A base class for an actor visitor.
-*/
-class GLActorVisitor {
-public:
-  /// Virtual destructor.
-  virtual ~GLActorVisitor() {}
-  /// Abstract method that must be implemented in sub-classes
-  virtual bool visit(GLActor *) = 0;
-  virtual bool visit(GLActorCollection *);
-  virtual bool visit(CompAssemblyActor *);
-  virtual bool visit(ObjCompAssemblyActor *);
-  virtual bool visit(ComponentActor *);
-  virtual bool visit(InstrumentActor *);
-  virtual bool visit(RectangularDetectorActor *);
-  virtual bool visit(StructuredDetectorActor *);
-};
-
-/**
-* A base class for an actor visitor (const version).
-*/
-class GLActorConstVisitor {
-public:
-  /// Virtual destructor.
-  virtual ~GLActorConstVisitor() {}
-  /// Abstract method that must be implemented in sub-classes
-  virtual bool visit(const GLActor *) = 0;
-  virtual bool visit(const GLActorCollection *);
-  virtual bool visit(const CompAssemblyActor *);
-  virtual bool visit(const ObjCompAssemblyActor *);
-  virtual bool visit(const ComponentActor *);
-  virtual bool visit(const InstrumentActor *);
-  virtual bool visit(const RectangularDetectorActor *);
-  virtual bool visit(const StructuredDetectorActor *);
-};
-
-/*
-* The visit() method implemented by sub-classes must return true if an actor
-* is set visible and false otherwise. This is requered by
-*GLActorCollection::accept()
-* method to determine whether the collection itself is visible or not.
-*
-* All visitors changing visibility should be sub-classed from this base class.
-*/
-class SetVisibilityVisitor : public GLActorVisitor {};
-
-/**
-* Set all actors visible.
-*/
-class SetAllVisibleVisitor : public SetVisibilityVisitor {
-public:
-  explicit SetAllVisibleVisitor(bool showNonDet) : m_showNonDet(showNonDet) {}
-  using GLActorVisitor::visit;
-  bool visit(GLActor *) override;
-  bool visit(ComponentActor *actor) override;
-
-private:
-  bool m_showNonDet;
-};
-} // MantidWidgets
-} // MantidQt
-
-#endif // GLACTORVISITOR_H
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h
index 5cda5822dd6ab57edea8e1d88e9f5964f1b56e97..6ea19cc70dbc64962f98c36fa3df7053ccf704ba 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h
@@ -41,7 +41,7 @@ class GLColor {
 public:
   /// Default Constructor
   GLColor(float red = 0, float green = 0, float blue = 0, float alpha = 1.0f);
-  GLColor(int r, int g, int b);
+  GLColor(int r, int g, int b, int a = 255);
   /// Destructor
   virtual ~GLColor();
 
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h
deleted file mode 100644
index 21cbebe5e5465bb6635a765674dd87a5eab1a0bb..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef ICOMPASSEMBLY_ACTOR__H_
-#define ICOMPASSEMBLY_ACTOR__H_
-#include "ComponentActor.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidKernel/V3D.h"
-
-#include <boost/shared_ptr.hpp>
-
-#include <map>
-
-/**
-  \class  ICompAssemblyActor
-  \brief  This class wraps the ICompAssembly into Actor.
-  \author Srikanth Nagella
-  \date   March 2009
-  \version 1.0
-
-  This class has the interface Comp assembly actors.
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-
-namespace Geometry {
-class ICompAssembly;
-class CSGObject;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class InstrumentActor;
-class ObjComponentActor;
-
-class ICompAssemblyActor : public ComponentActor {
-public:
-  ICompAssemblyActor(
-      const InstrumentActor &instrActor,
-      const Mantid::Geometry::ComponentID &compID); ///< Constructor
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-
-  std::string type() const override {
-    return "ICompAssemblyActor";
-  } ///< Type of the GL object
-  size_t getNumberOfDetectors() const { return mNumberOfDetectors; }
-
-protected:
-  size_t mNumberOfDetectors;
-  Mantid::Kernel::V3D minBoundBox;
-  Mantid::Kernel::V3D maxBoundBox;
-};
-} // MantidWidgets
-} // MantidQt
-
-#endif /*GLTRIANGLE_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
index a68f04d17423992f241c3543040ff1c7e814960f..28d355b6699bcef806e226b4478f1b37f8a24acd 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
@@ -2,19 +2,14 @@
 #define INSTRUMENTACTOR_H_
 
 #include "DllOption.h"
-#include "GLActor.h"
-#include "GLActorCollection.h"
-#include "GLActorVisitor.h"
+#include "MantidGeometry/Rendering/OpenGL_Headers.h"
 #include "GLColor.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAPI/SpectraDetectorTypes.h"
-#include "MantidGeometry/IObjComponent.h"
 #include "MantidQtWidgets/LegacyQwt/MantidColorMap.h"
 #include "MaskBinsData.h"
-#include "SampleActor.h"
-
+#include "MantidGeometry/IComponent.h"
 #include <boost/weak_ptr.hpp>
-#include <map>
 #include <vector>
 
 //------------------------------------------------------------------
@@ -26,15 +21,16 @@ class MatrixWorkspace;
 class IMaskWorkspace;
 }
 namespace Geometry {
-class IObjComponent;
 class Instrument;
-class IDetector;
+class ComponentInfo;
+class DetectorInfo;
 }
 }
 
 namespace MantidQt {
 namespace MantidWidgets {
-class ObjComponentActor;
+
+class InstrumentRenderer;
 
 /**
 \class  InstrumentActor
@@ -48,37 +44,34 @@ interface for picked ObjComponent and other
 operation for selective rendering of the instrument
 
 */
-class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor {
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject {
   Q_OBJECT
 public:
+  /// Invalid workspace index in detector index to workspace index lookup
+  static const size_t INVALID_INDEX;
   /// Constructor
   InstrumentActor(const QString &wsName, bool autoscaling = true,
                   double scaleMin = 0.0, double scaleMax = 0.0);
   ///< Destructor
-  ~InstrumentActor() override;
-  ///< Type of the GL object
-  virtual std::string type() const { return "InstrumentActor"; }
+  ~InstrumentActor();
   /// Draw the instrument in 3D
-  void draw(bool picking = false) const override;
+  void draw(bool picking = false) const;
   /// Return the bounding box in 3D
   void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override {
-    m_scene.getBoundingBox(minBound, maxBound);
-  }
-  /// Run visitors callback on each component
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  /// Run visitors callback on each component (const version)
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
+                      Mantid::Kernel::V3D &maxBound) const;
+  /// Set a component (and all its children) visible.
+  void setComponentVisible(size_t componentIndex);
   /// Toggle the visibility of the child actors (if exist).
-  void setChildVisibility(bool) override;
+  void setChildVisibility(bool);
   /// Check if any child is visible
-  bool hasChildVisible() const override;
+  bool hasChildVisible() const;
   /// Get the underlying instrument
+  std::vector<size_t> getMonitors() const;
   boost::shared_ptr<const Mantid::Geometry::Instrument> getInstrument() const;
   /// Get the associated data workspace
   boost::shared_ptr<const Mantid::API::MatrixWorkspace> getWorkspace() const;
+  const Mantid::Geometry::ComponentInfo &componentInfo() const;
+  const Mantid::Geometry::DetectorInfo &detectorInfo() const;
   /// Get the mask displayed but not yet applied as a MatrxWorkspace
   boost::shared_ptr<Mantid::API::MatrixWorkspace>
   getMaskMatrixWorkspace() const;
@@ -88,10 +81,12 @@ public:
   void invertMaskWorkspace() const;
   /// Get the mask displayed but not yet applied as a IMaskWorkspace
   boost::shared_ptr<Mantid::API::IMaskWorkspace> getMaskWorkspace() const;
+  boost::shared_ptr<Mantid::API::IMaskWorkspace>
+  getMaskWorkspaceIfExists() const;
   /// Apply the mask in the attached mask workspace to the data.
   void applyMaskWorkspace();
   /// Add a range of bins for masking
-  void addMaskBinsData(const QList<int> &detIDs);
+  void addMaskBinsData(const std::vector<size_t> &indices);
   /// Remove the attached mask workspace without applying the mask.
   /// Remove the bin masking data.
   void clearMasks();
@@ -137,32 +132,27 @@ public:
   bool wholeRange() const;
 
   /// Get the number of detectors in the instrument.
-  size_t ndetectors() const { return m_detIDs.size(); }
-  /// Get a reference to a detector by a pick ID converted form a color in
-  /// the pick image.
-  const Mantid::Geometry::IDetector &getDetectorByPickID(size_t pickID) const;
-  /// Get a reference to a detector by a detector ID.
-  const Mantid::Geometry::IDetector &
-  getDetectorByDetID(Mantid::detid_t detID) const;
+  size_t ndetectors() const;
+  /// Get a detector index by a detector ID.
+  size_t getDetectorByDetID(Mantid::detid_t detID) const;
   /// Get a detector ID by a pick ID converted form a color in the pick image.
   Mantid::detid_t getDetID(size_t pickID) const;
+  QList<Mantid::detid_t> getDetIDs(const std::vector<size_t> &dets) const;
   /// Get a component ID for a non-detector.
   Mantid::Geometry::ComponentID getComponentID(size_t pickID) const;
-  /// Cache detector positions.
-  void cacheDetPos() const;
   /// Get position of a detector by a pick ID converted form a color in the pick
   /// image.
-  const Mantid::Kernel::V3D &getDetPos(size_t pickID) const;
+  const Mantid::Kernel::V3D getDetPos(size_t pickID) const;
   /// Get a vector of IDs of all detectors in the instrument.
-  const std::vector<Mantid::detid_t> &getAllDetIDs() const { return m_detIDs; }
-  /// Get displayed color of a detector by its detector ID.
-  GLColor getColor(Mantid::detid_t id) const;
-  /// Get the workspace index of a detector by its detector ID.
-  size_t getWorkspaceIndex(Mantid::detid_t id) const;
-  /// Get the integrated counts of a detector by its detector ID.
-  double getIntegratedCounts(Mantid::detid_t id) const;
+  const std::vector<Mantid::detid_t> &getAllDetIDs() const;
+  /// Get displayed color of a detector by its index.
+  GLColor getColor(size_t index) const;
+  /// Get the workspace index of a detector by its detector Index.
+  size_t getWorkspaceIndex(size_t index) const;
+  /// Get the integrated counts of a detector by its detector Index.
+  double getIntegratedCounts(size_t index) const;
   /// Sum the counts in detectors
-  void sumDetectors(QList<int> &dets, std::vector<double> &x,
+  void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x,
                     std::vector<double> &y, size_t size = 0) const;
   /// Calc indexes for min and max bin values
   void getBinMinMaxIndex(size_t wi, size_t &imin, size_t &imax) const;
@@ -170,9 +160,6 @@ public:
   /// Update the detector colors to match the integrated counts within the
   /// current integration range.
   void updateColors();
-  /// Invalidate the OpenGL display lists to force full re-drawing of the
-  /// instrument and creation of new lists.
-  void invalidateDisplayLists() const { m_scene.invalidateDisplayList(); }
   /// Toggle display of the guide and other non-detector instrument components
   void showGuides(bool);
   /// Get the guide visibility status
@@ -195,10 +182,18 @@ public:
   void initMaskHelper() const;
   bool hasMaskWorkspace() const;
   bool hasBinMask() const;
+  QString getParameterInfo(size_t index) const;
+  std::string getDefaultAxis() const;
+  std::string getDefaultView() const;
+  std::string getInstrumentName() const;
+  std::vector<std::string> getStringParameter(const std::string &name,
+                                              bool recursive = true) const;
   /// Load the state of the actor from a Mantid project file.
   void loadFromProject(const std::string &lines);
   /// Save the state of the actor to a Mantid project file.
   std::string saveToProject() const;
+  /// Returns indices of all non-detector components in Instrument.
+  const std::vector<size_t> &components() const { return m_components; }
 
 signals:
   void colorMapChanged();
@@ -207,6 +202,7 @@ private:
   void setUpWorkspace(
       boost::shared_ptr<const Mantid::API::MatrixWorkspace> sharedWorkspace,
       double scaleMin, double scaleMax);
+  void setupPhysicalInstrumentIfExists();
   void resetColors();
   void loadSettings();
   void saveSettings();
@@ -216,19 +212,13 @@ private:
   calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace);
   /// Sum the counts in detectors if the workspace has equal bins for all
   /// spectra
-  void sumDetectorsUniform(QList<int> &dets, std::vector<double> &x,
+  void sumDetectorsUniform(const std::vector<size_t> &dets,
+                           std::vector<double> &x,
                            std::vector<double> &y) const;
   /// Sum the counts in detectors if the workspace is ragged
-  void sumDetectorsRagged(QList<int> &dets, std::vector<double> &x,
-                          std::vector<double> &y, size_t size) const;
-
-  size_t pushBackDetid(Mantid::detid_t) const;
-  void pushBackNonDetid(ObjComponentActor *actor,
-                        Mantid::Geometry::ComponentID compID) const;
-  void setupPickColors();
-
-  boost::shared_ptr<Mantid::API::IMaskWorkspace>
-  getMaskWorkspaceIfExists() const;
+  void sumDetectorsRagged(const std::vector<size_t> &dets,
+                          std::vector<double> &x, std::vector<double> &y,
+                          size_t size) const;
 
   /// The workspace whose data are shown
   const boost::weak_ptr<const Mantid::API::MatrixWorkspace> m_workspace;
@@ -237,8 +227,6 @@ private:
   mutable boost::shared_ptr<Mantid::API::MatrixWorkspace> m_maskWorkspace;
   /// A helper object that keeps bin masking data.
   mutable MaskBinsData m_maskBinsData;
-  /// The colormap
-  MantidColorMap m_colorMap;
   QString m_currentColorMapFilename;
   /// integrated spectra
   std::vector<double> m_specIntegrs;
@@ -260,97 +248,22 @@ private:
   bool m_showGuides;
   /// Color map scale type: linear or log
   GraphOptions::ScaleType m_scaleType;
-
-  /// The workspace's detector ID to workspace index map
-  Mantid::detid2index_map m_detid2index_map;
-
-  /// All det ids in the instrument in order of pickIDs, populated by Obj..Actor
-  /// constructors
-  mutable std::vector<Mantid::detid_t> m_detIDs;
-  /// All non-detector component IDs in order of pickIDs. For any index i a
-  /// pickID of the component
-  /// is m_detIDs.size() + i.
-  mutable std::vector<Mantid::Geometry::ComponentID> m_nonDetIDs;
-  /// Temporary stores addresses of actors for non-detector components until
-  /// initialisation completes
-  mutable std::vector<ObjComponentActor *> m_nonDetActorsTemp;
-
-  /// All detector positions, in order of pickIDs, populated by Obj..Actor
-  /// constructors
-  mutable std::vector<Mantid::Kernel::V3D> m_detPos;
   /// Position to refer to when detector not found
   const Mantid::Kernel::V3D m_defaultPos;
 
-  /// Colors in order of workspace indexes
-  mutable std::vector<GLColor> m_colors;
-  /// Colour of a masked detector
-  GLColor m_maskedColor;
-  /// Colour of a "failed" detector
-  GLColor m_failedColor;
-  /// The collection of actors for the instrument components
-  GLActorCollection m_scene;
+  /// Colors in order of component info
+  std::vector<size_t> m_monitors;
+  std::vector<size_t> m_components;
 
   static double m_tolerance;
 
-  friend class ObjComponentActor;
-  friend class ObjCompAssemblyActor;
-  friend class RectangularDetectorActor;
-  friend class StructuredDetectorActor;
-};
-
-/**
-* Sets visibility of an actor with a particular ComponentID
-* and makes all other components invisible.
-*/
-class SetVisibleComponentVisitor : public SetVisibilityVisitor {
-public:
-  explicit SetVisibleComponentVisitor(const Mantid::Geometry::ComponentID id)
-      : m_id(id) {}
-  bool visit(GLActor *) override;
-  bool visit(GLActorCollection *) override;
-  bool visit(ComponentActor *actor) override;
-  bool visit(CompAssemblyActor *actor) override;
-  bool visit(ObjCompAssemblyActor *actor) override;
-  bool visit(InstrumentActor *actor) override;
-  bool visit(RectangularDetectorActor *actor) override;
-  bool visit(StructuredDetectorActor *actor) override;
-  Mantid::Geometry::ComponentID getID() const { return m_id; }
-
-private:
-  Mantid::Geometry::ComponentID m_id;
-};
-
-/**
-* Set visibility of all actors of non-detector components.
-* Pass true to constructor to set them visible and false to make them invisible.
-*/
-class SetVisibleNonDetectorVisitor : public SetVisibilityVisitor {
-public:
-  /// Constructor
-  /// @param on :: If true then all non-detectors will be made visible or
-  /// invisible if false.
-  explicit SetVisibleNonDetectorVisitor(bool on) : m_on(on) {}
-  using GLActorVisitor::visit;
-  bool visit(GLActor *) override;
-
-private:
-  bool m_on;
-};
-
-/**
-* Finds an actor with a particular ComponentID
-*/
-class FindComponentVisitor : public GLActorVisitor {
-public:
-  explicit FindComponentVisitor(const Mantid::Geometry::ComponentID id)
-      : m_id(id), m_actor(nullptr) {}
-  using GLActorVisitor::visit;
-  bool visit(GLActor *) override;
-  ComponentActor *getActor() const { return m_actor; }
+  std::vector<bool> m_isCompVisible;
+  std::vector<size_t> m_detIndex2WsIndex;
 
-private:
-  Mantid::Geometry::ComponentID m_id;
-  mutable ComponentActor *m_actor;
+  bool m_isPhysicalInstrument;
+  std::unique_ptr<Mantid::Geometry::ComponentInfo> m_physicalComponentInfo;
+  std::unique_ptr<Mantid::Geometry::DetectorInfo> m_physicalDetectorInfo;
+  std::unique_ptr<InstrumentRenderer> m_renderer;
 };
 
 } // MantidWidgets
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h
new file mode 100644
index 0000000000000000000000000000000000000000..880cbc9e36617e3cb48fac3336abfc9bd5c010d7
--- /dev/null
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h
@@ -0,0 +1,74 @@
+#ifndef INSTRUMENTRENDERER_H_
+#define INSTRUMENTRENDERER_H_
+
+#include "DllOption.h"
+#include "GLColor.h"
+#include "MantidGeometry/Rendering/OpenGL_Headers.h"
+#include "MantidQtWidgets/LegacyQwt/MantidColorMap.h"
+#include <QString>
+
+namespace MantidQt {
+namespace MantidWidgets {
+class InstrumentActor;
+
+class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentRenderer {
+private:
+  const InstrumentActor &m_actor;
+  std::vector<GLColor> m_colors;
+  std::vector<GLColor> m_pickColors;
+  mutable GLuint m_displayListId[2];
+  mutable bool m_useDisplayList[2];
+  mutable std::vector<GLuint> m_textureIDs;
+  mutable std::vector<size_t> m_textureIndices;
+  mutable std::map<size_t, size_t> m_reverseTextureIndexMap;
+  mutable std::vector<std::vector<char>> colorTextures;
+  mutable std::vector<std::vector<char>> pickTextures;
+  std::vector<double> m_specIntegrs;
+  MantidColorMap m_colorMap;
+
+public:
+  InstrumentRenderer(const InstrumentActor &actor);
+  ~InstrumentRenderer();
+  void renderInstrument(const std::vector<bool> &visibleComps, bool showGuides,
+                        bool picking = false);
+  void reset();
+
+  void changeScaleType(int type);
+
+  void changeNthPower(double nth_power);
+
+  void loadColorMap(const QString &fname);
+
+  const MantidColorMap &getColorMap() const { return m_colorMap; }
+
+  GLColor getColor(size_t index) const;
+
+  static GLColor makePickColor(size_t pickID);
+
+  static size_t decodePickColor(const QRgb &c);
+
+private:
+  void resetColors();
+  void resetPickColors();
+  void draw(const std::vector<bool> &visibleComps, bool showGuides,
+            bool picking);
+  void drawRectangularBank(size_t bankIndex, bool picking);
+  void drawStructuredBank(size_t bankIndex, bool picking);
+  void drawTube(size_t bankIndex, bool picking);
+  void drawSingleDetector(size_t detIndex, bool picking);
+  void generateRectangularTexture(std::vector<char> &texture,
+                                  const std::vector<GLColor> &colors,
+                                  size_t bankIndex);
+
+  void uploadRectangularTexture(const std::vector<char> &texture,
+                                size_t textureIndex) const;
+
+  void generateTubeTexture(std::vector<char> &texture,
+                           const std::vector<GLColor> &colors,
+                           size_t bankIndex);
+  void uploadTubeTexture(const std::vector<char> &texture,
+                         size_t textureIndex) const;
+};
+} // namespace MantidWidgets
+} // namespace MantidQt
+#endif // INSTRUMENTRENDERER_H_
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
index a53cd4cac13fd1ee408d7a372621d67edbfb7024..86d54b58d767ba1a35fc49c8e6825facbb0e5b0f 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
@@ -33,10 +33,12 @@ public:
   QModelIndex parent(const QModelIndex &index) const override;
   int rowCount(const QModelIndex &paren = QModelIndex()) const override;
   int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+  static size_t extractIndex(const QModelIndex &index);
 
 private:
   /// instrument widget to which the model corresponds
   const InstrumentWidget *m_instrWidget;
+  mutable std::vector<size_t> m_componentIndices;
 };
 } // MantidWidgets
 } // MantidQt
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h
index 7cd33fc0129cacec17e07d469e17e75b2522f8a0..1e22e4bbd533ceb353a09e98b737e8632712342a 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h
@@ -36,7 +36,7 @@ public:
 public slots:
   void sendComponentSelectedSignal(const QModelIndex);
 signals:
-  void componentSelected(const Mantid::Geometry::ComponentID);
+  void componentSelected(size_t);
 
 private:
   InstrumentWidget *m_instrWidget;
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h
index eefd8644c4bfc5f3773b9ed97eb66e12766c80fa..2260a08c1e45bdb14554e1401774bcc070e7a47d 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h
@@ -172,7 +172,7 @@ protected:
 
 public slots:
   void tabChanged(int);
-  void componentSelected(Mantid::Geometry::ComponentID id);
+  void componentSelected(size_t componentIndex);
   void executeAlgorithm(const QString &, const QString &);
   void executeAlgorithm(Mantid::API::IAlgorithm_sptr);
 
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h
index ff9ac33ad3975560ded738728b910a90dd18d381..83ce8c02bc5ac380c25d2492161645e9958b3740 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h
@@ -200,12 +200,11 @@ public slots:
   void clear();
 
 private:
-  QString displayDetectorInfo(Mantid::detid_t detid);
+  QString displayDetectorInfo(size_t index);
   QString displayNonDetectorInfo(Mantid::Geometry::ComponentID compID);
   QString displayPeakInfo(Mantid::Geometry::IPeak *peak);
   QString displayPeakAngles(const std::pair<Mantid::Geometry::IPeak *,
                                             Mantid::Geometry::IPeak *> &peaks);
-  QString getParameterInfo(const Mantid::Geometry::IComponent &comp);
   QString getPeakOverlayInfo();
 
   InstrumentWidgetPickTab *m_tab;
@@ -238,7 +237,7 @@ public:
                          InstrumentWidget *instrWidget, OneCurvePlot *plot);
   void setEnabled(bool on) { m_enabled = on; }
   void setPlotData(size_t pickID);
-  void setPlotData(QList<int> detIDs);
+  void setPlotData(const std::vector<size_t> &detIndices);
   void updatePlot();
   void clear();
   void savePlotToWorkspace();
@@ -256,17 +255,17 @@ private slots:
   void addPeak(double x, double y);
 
 private:
-  void plotSingle(int detid);
-  void plotTube(int detid);
-  void plotTubeSums(int detid);
-  void plotTubeIntegrals(int detid);
-  void prepareDataForSinglePlot(int detid, std::vector<double> &x,
+  void plotSingle(size_t detindex);
+  void plotTube(size_t detindex);
+  void plotTubeSums(size_t detindex);
+  void plotTubeIntegrals(size_t detindex);
+  void prepareDataForSinglePlot(size_t detindex, std::vector<double> &x,
                                 std::vector<double> &y,
                                 std::vector<double> *err = nullptr);
-  void prepareDataForSumsPlot(int detid, std::vector<double> &x,
+  void prepareDataForSumsPlot(size_t detindex, std::vector<double> &x,
                               std::vector<double> &y,
                               std::vector<double> *err = nullptr);
-  void prepareDataForIntegralsPlot(int detid, std::vector<double> &x,
+  void prepareDataForIntegralsPlot(size_t detindex, std::vector<double> &x,
                                    std::vector<double> &y,
                                    std::vector<double> *err = nullptr);
   static double getOutOfPlaneAngle(const Mantid::Kernel::V3D &pos,
@@ -281,7 +280,7 @@ private:
   bool m_enabled;
   TubeXUnits
       m_tubeXUnits; ///< quantity the time bin integrals to be plotted against
-  int m_currentDetID;
+  size_t m_currentPickID;
 };
 
 } // MantidWidgets
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h
index 6407cc16b80dc41ae471995ba790aa1eebe4154c..0a06893e4a2d755e1eb79e7277c7b697779cf8a1 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h
@@ -34,7 +34,7 @@ public slots:
   void enableLighting(bool);
   void updateView(bool picking = true);
   void updateDetectors();
-  void componentSelected(Mantid::Geometry::ComponentID id);
+  void componentSelected(size_t componentIndex);
 
 protected:
   void initializeGL() override;
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h
index f50f2554b98f1562fbf17236cdcaac2d34291c57..2ffd97d42783b466f6725c6bffd7aa9b6307bc52 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h
@@ -36,7 +36,7 @@ File change history is stored at: <https://github.com/mantidproject/mantid>
 */
 class MaskBinsData {
 public:
-  void addXRange(double start, double end, const QList<int> &indices);
+  void addXRange(double start, double end, const std::vector<size_t> &indices);
   void mask(const std::string &wsName) const;
   bool isEmpty() const;
   void subtractIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace,
@@ -53,7 +53,7 @@ private:
     BinMask(double s = 0.0, double e = 0.0) : start(s), end(e) {}
     double start;
     double end;
-    QList<int> spectra;
+    std::vector<size_t> spectra;
   };
   QList<BinMask> m_masks;
 };
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h
deleted file mode 100644
index 8cde9c9a31afd8b7fe8a86968dee755097658063..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef OBJCOMPASSEMBLY_ACTOR__H_
-#define OBJCOMPASSEMBLY_ACTOR__H_
-#include "ICompAssemblyActor.h"
-
-#include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidKernel/V3D.h"
-
-class TexObject;
-namespace Mantid {
-namespace Geometry {
-class ObjCompAssembly;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-/**
-\class  ObjCompAssemblyActor
-\brief  This class wraps the ICompAssembly into Actor.
-\author Srikanth Nagella
-\date   March 2009
-\version 1.0
-
-This class has the implementation for calling the children of ICompAssembly's
-IObjComponent to render themselves
-and call the ICompAssemblys. This maintains the count of the children for easy
-lookup.
-
-Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-class ObjCompAssemblyActor : public ICompAssemblyActor {
-public:
-  /// Constructor
-  ObjCompAssemblyActor(const InstrumentActor &instrActor,
-                       Mantid::Geometry::ComponentID compID);
-  ~ObjCompAssemblyActor() override; ///< Destructor
-  std::string type() const override {
-    return "ObjCompAssemblyActor";
-  }                                               ///< Type of the GL object
-  void draw(bool picking = false) const override; ///< Method that defines
-  /// ObjComponent geometry. Calls
-  /// ObjComponent draw method
-  // virtual void getBoundingBox(Mantid::Kernel::V3D&
-  // minBound,Mantid::Kernel::V3D& maxBound)const;
-  void setColors() override;
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-
-private:
-  void setDetectorColor(unsigned char *data, size_t i,
-                        GLColor c) const; ///< set colour to a detector
-  void setDataColors() const;
-  void setPickColors() const;
-  void generateTexture(unsigned char *data, unsigned int &id) const;
-  /// Swap between drawing counts and drawing detector code colours
-  void swap();
-  const unsigned char *getColor(int i) const;
-
-  std::vector<Mantid::detid_t> m_detIDs; ///< List of Component IDs
-  mutable unsigned int m_idData;         ///< OpenGL texture id
-  mutable unsigned int m_idPick;         ///< OpenGL texture id
-  int m_n; ///< texture size in one dimension, the other dimension is 1
-  unsigned char *m_data;      ///< texture colour data
-  unsigned char *m_pick_data; ///< texture with detector code colours
-  mutable bool
-      m_texturesGenerated; ///< true if the textures have been generated
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif /*OBJCOMPASSEMBLY_ACTOR__H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h
deleted file mode 100644
index 6ffe582de33f1320781dbb6857e10fc32481172d..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef OBJCOMPONENT_ACTOR_H_
-#define OBJCOMPONENT_ACTOR_H_
-#include "ComponentActor.h"
-#include "GLColor.h"
-/**
-  \class  ObjComponentActor
-  \brief  ObjComponentActor is an actor class for rendering ObjComponents.
-  \author Srikanth Nagella
-  \date   March 2009
-  \version 1.0
-
-   This class has the implementation for rendering ObjComponents in OpenGL and
-  it inherits from the GLActor
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-
-namespace Geometry {
-class IObjComponent;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class InstrumentActor;
-
-class ObjComponentActor : public ComponentActor {
-public:
-  ObjComponentActor(
-      const InstrumentActor &instrActor,
-      Mantid::Geometry::ComponentID compID); ///< Default Constructor
-  ~ObjComponentActor() override;             ///< Destructor
-  std::string type() const override {
-    return "ObjComponentActor";
-  }                                               ///< Type of the GL object
-  void draw(bool picking = false) const override; ///< Method that defines
-  /// ObjComponent geometry. Calls
-  /// ObjComponent draw method
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-  void setColors() override;
-
-  void setColor(const GLColor &c) { m_dataColor = c; }
-
-private:
-  void setPickColor(const GLColor &c) { m_pickColor = c; }
-
-  GLColor m_dataColor;
-  GLColor m_pickColor;
-
-  friend class InstrumentActor;
-};
-} // MantidWidgets
-} // MantidQt
-
-#endif /*OBJCOMPONENT_ACTOR_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h
index b397935ac3cdf92b3da0a15cb1025fcfb27d009f..950a7742afd885c0f8ced3c62944d95f5b09fbb3 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h
@@ -4,6 +4,7 @@
 #include "UnwrappedSurface.h"
 
 #include <QPolygonF>
+#include <boost/optional.hpp>
 
 namespace MantidQt {
 namespace MantidWidgets {
@@ -11,8 +12,6 @@ class PanelsSurface;
 
 struct FlatBankInfo {
   explicit FlatBankInfo(PanelsSurface *s);
-  /// Component id of the bank
-  Mantid::Geometry::ComponentID id;
   /// Bank's rotation
   Mantid::Kernel::Quat rotation;
   /// Starting index of bank's detectors in m_unwrappedDetectors vector
@@ -53,41 +52,31 @@ public:
                double &) const override;
 
 protected:
+  boost::optional<std::pair<std::vector<size_t>, Mantid::Kernel::V3D>>
+  findFlatPanels(size_t rootIndex, const std::vector<size_t> &children,
+                 std::vector<bool> &visited);
+
+  void processStructured(const std::vector<size_t> &children, size_t rootIndex);
+
+  void processTubes(size_t rootIndex, std::vector<bool> &visited);
+
+  std::pair<std::vector<size_t>, Mantid::Kernel::V3D>
+  processUnstructured(const std::vector<size_t> &children, size_t rootIndex,
+                      std::vector<bool> &visited);
+
   void rotate(const UnwrappedDetector &udet,
               Mantid::Kernel::Quat &R) const override;
-  // void drawCustom(QPainter *painter) const;
-
   // Setup the projection axes
   void setupAxes();
-  // Setup the projection axes
-  void setupBasisAxes(const Mantid::Kernel::V3D &zaxis,
-                      Mantid::Kernel::V3D &xaxis,
-                      Mantid::Kernel::V3D &yaxis) const;
-  // Find all flat banks of detectors.
-  void findFlatBanks();
-  // Add a flat bank
-  void addFlatBank(Mantid::Geometry::ComponentID bankId,
-                   const Mantid::Kernel::V3D &normal,
-                   QList<Mantid::Geometry::ComponentID> objCompAssemblies);
   // Add a flat bank
-  void addFlatBankOfDetectors(Mantid::Geometry::ComponentID bankId,
-                              const Mantid::Kernel::V3D &normal,
-                              QList<Mantid::Geometry::ComponentID> detectors);
-  // Add a component assembly containing a flat array of ObjCompAssemblies
-  void addObjCompAssemblies(Mantid::Geometry::ComponentID bankId);
-  // Add a component assembly
-  void addCompAssembly(Mantid::Geometry::ComponentID bankId);
-  // Add a rectangular detector
-  void addRectangularDetector(Mantid::Geometry::ComponentID bankId);
-  // Add a structured detector
-  void addStructuredDetector(Mantid::Geometry::ComponentID bankId);
-  // Calculate bank rotation
+  void addFlatBankOfDetectors(const Mantid::Kernel::V3D &normal,
+                              const std::vector<size_t> &detectors);
+  void constructFromComponentInfo();
   Mantid::Kernel::Quat calcBankRotation(const Mantid::Kernel::V3D &detPos,
                                         Mantid::Kernel::V3D normal) const;
   // Add a detector from an assembly
-  void addDetector(const Mantid::Geometry::IDetector &det,
-                   const Mantid::Kernel::V3D &refPos, int index,
-                   Mantid::Kernel::Quat &rotation);
+  void addDetector(size_t detIndex, const Mantid::Kernel::V3D &refPos,
+                   int index, Mantid::Kernel::Quat &rotation);
   // Spread the banks over the projection plane
   void spreadBanks();
   // Find index of the largest bank
@@ -109,9 +98,8 @@ protected:
   /// Keep info of the flat banks
   QList<FlatBankInfo *> m_flatBanks;
   /// Maps detector ids to indices of FlatBankInfos in m_flatBanks
-  QMap<Mantid::detid_t, int> m_detector2bankMap;
+  QMap<size_t, int> m_detector2bankMap;
 
-  friend class FlatBankFinder;
   friend struct FlatBankInfo;
 };
 
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h
index 5d9f901a5d5854bd3f9c403ab6d00abf27a8100c..045a6b751c21acfeaf04dfb8bebf0459e0b4f90a 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h
@@ -39,9 +39,9 @@ public:
   void set3DAxesState(bool on);
   void setWireframe(bool on);
 
-  void componentSelected(Mantid::Geometry::ComponentID = nullptr) override;
-  void getSelectedDetectors(QList<int> &dets) override;
-  void getMaskedDetectors(QList<int> &dets) const override;
+  void componentSelected(size_t componentIndex) override;
+  void getSelectedDetectors(std::vector<size_t> &detIndices) override;
+  void getMaskedDetectors(std::vector<size_t> &detIndices) const override;
   void resize(int, int) override;
   QString getInfoText() const override;
   /// Load settings for the 3D projection from a project file
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
index 2d38ea074650a32254f0d652ad4c5e2695b6f947..ec0a58801bb248da75feb22af393b4fd44a3a609 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h
@@ -109,13 +109,14 @@ public:
   virtual bool hasSelection() const;
 
   virtual int getDetectorID(int x, int y) const;
-  virtual const Mantid::Geometry::IDetector &getDetector(int x, int y) const;
+  virtual size_t getDetector(int x, int y) const;
   /// NULL deselects components and selects the whole instrument
-  virtual void componentSelected(Mantid::Geometry::ComponentID = nullptr) = 0;
-  /// fill in a list of detector ids which were selected by the selction tool
-  virtual void getSelectedDetectors(QList<int> &dets) = 0;
-  /// fill in a list of detector ids which were masked by the mask shapes
-  virtual void getMaskedDetectors(QList<int> &dets) const = 0;
+  virtual void componentSelected(size_t componentIndex) = 0;
+  /// fill in a list of detector indices which were selected by the selction
+  /// tool
+  virtual void getSelectedDetectors(std::vector<size_t> &detIndices) = 0;
+  /// fill in a list of detector indices which were masked by the mask shapes
+  virtual void getMaskedDetectors(std::vector<size_t> &detIndices) const = 0;
 
   virtual QString getInfoText() const;
   /// Change the interaction mode
@@ -380,7 +381,7 @@ private:
   mutable bool m_redrawPicking;
 };
 
-typedef boost::shared_ptr<ProjectionSurface> ProjectionSurface_sptr;
+using ProjectionSurface_sptr = boost::shared_ptr<ProjectionSurface>;
 
 } // MantidWidgets
 } // MantidQt
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h
deleted file mode 100644
index 887dcf9a2bb41a13fe961c11b674f66574ce9cac..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef RECTANGULAR_DETECTOR_ACTOR__H_
-#define RECTANGULAR_DETECTOR_ACTOR__H_
-#include "GLActor.h"
-#include "ObjComponentActor.h"
-#include "ICompAssemblyActor.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-#include "MantidKernel/V3D.h"
-/**
-  \class  RectangularDetectorActor
-  \brief  This class wraps a RectangularDetector into Actor.
-  \author Janik Zikovsky
-  \date   October 7 2010
-  \version 1.0
-
-  This class is used to render a RectangularDetector as a bitmap and plot it.
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class ICompAssembly;
-class CSGObject;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class ObjComponentActor;
-
-class RectangularDetectorActor : public ICompAssemblyActor {
-public:
-  /// Constructor
-  RectangularDetectorActor(const InstrumentActor &instrActor,
-                           const Mantid::Geometry::ComponentID &compID);
-  /// Destructor
-  ~RectangularDetectorActor() override;
-
-private:
-  void AppendBoundingBox(const Mantid::Kernel::V3D &minBound,
-                         const Mantid::Kernel::V3D &maxBound);
-
-protected:
-  /// The rectangular detector
-  boost::shared_ptr<const Mantid::Geometry::RectangularDetector> mDet;
-
-  void init() const;
-  void redraw();
-  int findDetectorIDUsingColor(int rgb);
-  virtual void initChilds(bool) {}
-
-public:
-  std::string type() const override {
-    return "RectangularDetectorActor";
-  } ///< Type of the GL object
-
-  void draw(bool picking = false) const override; ///< Method that
-  /// defines
-  /// ObjComponent
-  /// geometry. Calls
-  /// ObjComponent
-  /// draw method
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-  bool isChildDetector(const Mantid::Geometry::ComponentID &id) const;
-  void setColors() override;
-
-  int genTexture(char *&image_data, std::vector<GLColor> &list,
-                 bool useDetectorIDs);
-  void uploadTexture(char *&image_data) const;
-
-private:
-  /// Texture ID that holds the texture.
-  mutable unsigned int mTextureID;
-
-  /// Pointer to the array holding the texture color data
-  mutable char *image_data;
-
-  /// Pointer to the array holding the color data for picking the scene
-  mutable char *pick_data;
-
-  /// pick ids
-  std::vector<size_t> m_pickIDs;
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif /*RECTANGULAR_DETECTOR_ACTOR__H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h
deleted file mode 100644
index cb46c0c637f357391b73d6be01f0068eec750a2c..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef SMAPLE_ACTOR_H_
-#define SMAPLE_ACTOR_H_
-#include "GLActor.h"
-#include "GLColor.h"
-#include "ObjComponentActor.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
-  \class  SampleActor
-  \brief  SampleActor is an actor class for rendering Samples.
-  \author Roman Tolchenov
-  \date   04/07/2011
-  \version 1.0
-
-   This class has the implementation for rendering SampleActor in OpenGL and it
-  inherits from the GLActor
-
-  Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-  National Laboratory & European Spallation Source
-
-  This file is part of Mantid.
-
-  Mantid is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  Mantid is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace API {
-class Sample;
-}
-namespace Geometry {
-class IObjComponent;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class InstrumentActor;
-
-class SampleActor : public GLActor {
-public:
-  SampleActor(const InstrumentActor &instrActor,
-              const Mantid::API::Sample &sample,
-              const ObjComponentActor *samplePosActor); ///< Constructor
-  virtual std::string type() const {
-    return "SampleActor";
-  } ///< Type of the GL object
-  void draw(bool picking) const override;
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-  void setColor(const GLColor &c) { m_color = c; }
-  const ObjComponentActor *getSamplePosActor() const {
-    return m_samplePosActor;
-  }
-
-protected:
-  const InstrumentActor &m_instrActor;
-  const Mantid::API::Sample &m_sample;
-  const ObjComponentActor *m_samplePosActor;
-  boost::shared_ptr<const Mantid::Geometry::IObjComponent> m_samplePos;
-  GLColor m_color;
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif /*SMAPLE_ACTOR_H_*/
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h
deleted file mode 100644
index 07e72cb3e303f2ae96213cfaeaa477444d12839a..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef STRUCTUREDDETECTORACTOR
-#define STRUCTUREDDETECTORACTOR
-#include "GLActor.h"
-#include "ICompAssemblyActor.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidKernel/V3D.h"
-#include "ObjComponentActor.h"
-/**
-\class  StructuredDetectorActor
-\brief  This class wraps a StructuredDetector into Actor.
-\author Lamar Moore
-\date   March 9 2016
-\version 1.0
-
-This class is used to render a StructuredDetector as a bitmap and plot it.
-
-Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
-National Laboratory & European Spallation Source
-
-This file is part of Mantid.
-
-Mantid is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3 of the License, or
-(at your option) any later version.
-
-Mantid is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-File change history is stored at: <https://github.com/mantidproject/mantid>
-*/
-namespace Mantid {
-namespace Kernel {
-class V3D;
-}
-namespace Geometry {
-class ICompAssembly;
-class CSGObject;
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-class ObjComponentActor;
-
-class StructuredDetectorActor : public ICompAssemblyActor {
-public:
-  /// Constructor
-  StructuredDetectorActor(const InstrumentActor &instrActor,
-                          const Mantid::Geometry::ComponentID &compID);
-  /// Destructor
-  ~StructuredDetectorActor() override;
-
-private:
-  void AppendBoundingBox(const Mantid::Kernel::V3D &minBound,
-                         const Mantid::Kernel::V3D &maxBound);
-
-protected:
-  /// The structured detector
-  boost::shared_ptr<const Mantid::Geometry::StructuredDetector> m_det;
-  std::vector<GLColor> m_clist;
-  std::vector<size_t> m_pickIds;
-  std::vector<GLColor> m_pickColors;
-
-  void init() const;
-  void redraw();
-  int findDetectorIDUsingColor(int rgb);
-  virtual void initChilds(bool) {}
-
-public:
-  std::string type() const override {
-    return "StructuredDetectorActor";
-  } ///< Type of the GL object
-
-  void draw(bool picking = false) const override; ///< Method that
-                                                  /// defines
-  /// ObjComponent
-  /// geometry. Calls
-  /// ObjComponent
-  /// draw method
-  void getBoundingBox(Mantid::Kernel::V3D &minBound,
-                      Mantid::Kernel::V3D &maxBound) const override;
-  bool accept(GLActorVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) override;
-  bool accept(GLActorConstVisitor &visitor,
-              VisitorAcceptRule rule = VisitAll) const override;
-  bool isChildDetector(const Mantid::Geometry::ComponentID &id) const;
-  void setColors() override;
-};
-
-} // MantidWidgets
-} // MantidQt
-
-#endif // STRUCTUREDDETECTORACTOR
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5482189f25d59d55193988399ac0c222dcb4187
--- /dev/null
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h
@@ -0,0 +1,48 @@
+#ifndef UNWRAPPEDDETECTOR_H
+#define UNWRAPPEDDETECTOR_H
+
+#include "MantidGeometry/IDTypes.h"
+#include "MantidKernel/Quat.h"
+#include "MantidKernel/V3D.h"
+#include "MantidQtWidgets/InstrumentView/GLColor.h"
+#include <boost/shared_ptr.hpp>
+#include <limits>
+
+namespace Mantid {
+namespace Geometry {
+class IDetector;
+class IObject;
+} // namespace Geometry
+} // namespace Mantid
+
+namespace MantidQt {
+namespace MantidWidgets {
+/**
+\class UnwrappedDetector
+\brief Class helper for drawing detectors on unwraped surfaces
+\date 15 Nov 2010
+\author Roman Tolchenov, Tessella plc
+
+This class keeps information used to draw a detector on an unwrapped surface.
+
+*/
+class UnwrappedDetector {
+public:
+  UnwrappedDetector();
+  UnwrappedDetector(GLColor color, size_t detIndex);
+  UnwrappedDetector(const UnwrappedDetector &other);
+  UnwrappedDetector &operator=(const UnwrappedDetector &other);
+  bool empty() const;
+  GLColor color; ///< red, green, blue colour components (0 - 255)
+  double u;      ///< horizontal "unwrapped" coordinate
+  double v;      ///< vertical "unwrapped" coordinate
+  double width;  ///< detector width in units of u
+  double height; ///< detector height in units of v
+  double uscale; ///< scaling factor in u direction
+  double vscale; ///< scaling factor in v direction
+  size_t detIndex = std::numeric_limits<size_t>::max(); ///< Detector Index in
+  ///< ComponentInfo/DetectorInfo.
+};
+} // namespace MantidWidgets
+} // namespace MantidQt
+#endif
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h
index 3dab3355bba4787b9ac7a8a684ccd3b86432190d..82549f3f16ee68c63c01f2d90c683ff5660e1ff8 100644
--- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h
+++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h
@@ -3,10 +3,10 @@
 
 #include "MantidKernel/V3D.h"
 #include "MantidKernel/Quat.h"
-#include "MantidGeometry/IComponent.h"
 #include "MantidGeometry/Objects/IObject.h"
 #include "InstrumentActor.h"
 #include "ProjectionSurface.h"
+#include "UnwrappedDetector.h"
 #include <boost/shared_ptr.hpp>
 
 #include <QImage>
@@ -31,39 +31,6 @@ class GL3DWidget;
 
 namespace MantidQt {
 namespace MantidWidgets {
-
-/**
-\class UnwrappedDetector
-\brief Class helper for drawing detectors on unwraped surfaces
-\date 15 Nov 2010
-\author Roman Tolchenov, Tessella plc
-
-This class keeps information used to draw a detector on an unwrapped surface.
-
-*/
-class UnwrappedDetector {
-public:
-  UnwrappedDetector();
-  UnwrappedDetector(const unsigned char *c,
-                    const Mantid::Geometry::IDetector &det);
-  UnwrappedDetector(const UnwrappedDetector &other);
-  UnwrappedDetector &operator=(const UnwrappedDetector &other);
-  bool isValid() const;
-  unsigned char color[3]; ///< red, green, blue colour components (0 - 255)
-  double u;               ///< horizontal "unwrapped" coordinate
-  double v;               ///< vertical "unwrapped" coordinate
-  double width;           ///< detector width in units of u
-  double height;          ///< detector height in units of v
-  double uscale;          ///< scaling factor in u direction
-  double vscale;          ///< scaling factor in v direction
-  Mantid::detid_t detID;  ///< Detector ID
-  Mantid::Kernel::V3D position;  ///< Detector position
-  Mantid::Kernel::Quat rotation; ///< Detector orientation
-  boost::shared_ptr<const Mantid::Geometry::IObject>
-      shape;                       ///< Shape of the detector
-  Mantid::Kernel::V3D scaleFactor; ///< Detector's scale factor
-};
-
 /**
 * @class UnwrappedSurface
 * @brief Performs projection of an instrument onto a 2D surface and unwrapping
@@ -92,9 +59,9 @@ public:
 
   /** @name Implemented public virtual methods */
   //@{
-  void componentSelected(Mantid::Geometry::ComponentID = nullptr) override;
-  void getSelectedDetectors(QList<int> &dets) override;
-  void getMaskedDetectors(QList<int> &dets) const override;
+  void componentSelected(size_t componentIndex) override;
+  void getSelectedDetectors(std::vector<size_t> &detIndices) override;
+  void getMaskedDetectors(std::vector<size_t> &detIndices) const override;
   void setPeaksWorkspace(boost::shared_ptr<Mantid::API::IPeaksWorkspace> pws);
   QString getInfoText() const override;
   RectF getSurfaceBounds() const override;
@@ -179,10 +146,7 @@ protected:
 
   /** @name Protected methods */
   //@{
-  void setColor(int index, bool picking) const;
-  void calcAssemblies(const Mantid::Geometry::IComponent *comp,
-                      const QRectF &compRect);
-  void cacheAllAssemblies();
+  void setColor(size_t index, bool picking) const;
   void createPeakShapes(const QRect &viewport) const;
   //@}
 
@@ -196,9 +160,6 @@ protected:
   /// Info needed to draw detectors onto unwrapped image
   std::vector<UnwrappedDetector> m_unwrappedDetectors;
 
-  /// Bounding rectangles of detector assemblies
-  QMap<Mantid::Geometry::ComponentID, QRectF> m_assemblies;
-
   bool m_flippedView; ///< if false the image is seen from the sample. if true
   /// the view is looking towards the sample.
   mutable bool m_startPeakShapes; ///< set to true to start creating
diff --git a/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp b/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..586a8f324fe210e5fbc1ff977365610bc43ec37e
--- /dev/null
+++ b/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp
@@ -0,0 +1,193 @@
+#include "MantidQtWidgets/InstrumentView/BankRenderingHelpers.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Objects/IObject.h"
+#include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Rendering/OpenGL_Headers.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidKernel/Quat.h"
+
+using Mantid::Kernel::V3D;
+using Mantid::Kernel::Quat;
+namespace {
+struct Corners {
+  V3D bottomLeft;
+  V3D bottomRight;
+  V3D topRight;
+  V3D topLeft;
+};
+
+Mantid::Kernel::Logger g_log("BankRenderingHelpers");
+
+// Round a number up to the nearest power  of 2
+size_t roundToNearestPowerOfTwo(size_t val) {
+  size_t rounded = 2;
+  while (val > rounded)
+    rounded *= 2;
+  return rounded;
+}
+
+Corners findCorners(const Mantid::Geometry::ComponentInfo &compInfo,
+                    size_t bankIndex) {
+  auto rotation = compInfo.rotation(bankIndex);
+  auto position = compInfo.position(bankIndex);
+  auto bank = compInfo.quadrilateralComponent(bankIndex);
+  Corners c;
+  c.bottomLeft = compInfo.position(bank.bottomLeft);
+  c.bottomRight = compInfo.position(bank.bottomRight);
+  c.topRight = compInfo.position(bank.topRight);
+  c.topLeft = compInfo.position(bank.topLeft);
+  rotation.conjugate();
+  rotation.rotate(c.bottomLeft);
+  rotation.rotate(c.bottomRight);
+  rotation.rotate(c.topLeft);
+  rotation.rotate(c.topRight);
+  rotation.rotate(position);
+  c.bottomLeft -= position;
+  c.bottomRight -= position;
+  c.topRight -= position;
+  c.topLeft -= position;
+  return c;
+}
+
+void addVertex(const V3D &pos) {
+  glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()),
+             static_cast<GLfloat>(pos.Z()));
+}
+
+void setBankNormal(const V3D &pos1, const V3D &pos2, const V3D &basePos) {
+  // Set the bank normal to facilitate lighting effects
+  auto vec1 = pos1 - basePos;
+  auto vec2 = pos2 - basePos;
+  auto normal = vec1.cross_prod(vec2);
+  normal.normalize();
+  glNormal3f(static_cast<GLfloat>(normal.X()), static_cast<GLfloat>(normal.Y()),
+             static_cast<GLfloat>(normal.Z()));
+}
+
+void extractHexahedron(const Mantid::Geometry::IObject &shape,
+                       std::vector<V3D> &hex) {
+  const auto &shapeInfo = shape.getGeometryHandler()->shapeInfo();
+  const auto &points = shapeInfo.points();
+  hex.assign(points.begin(), points.begin() + 4);
+}
+
+void rotateHexahedron(std::vector<V3D> &hex, const Quat &rotation) {
+  for (auto &pos : hex)
+    rotation.rotate(pos);
+}
+
+void offsetHexahedronPosition(std::vector<V3D> &hex, const V3D &offset) {
+  for (auto &pos : hex)
+    pos += offset;
+}
+} // namespace
+
+namespace MantidQt {
+namespace MantidWidgets {
+namespace BankRenderingHelpers {
+
+std::pair<size_t, size_t> getCorrectedTextureSize(const size_t width,
+                                                  const size_t height) {
+  return {roundToNearestPowerOfTwo(width), roundToNearestPowerOfTwo(height)};
+}
+
+void renderRectangularBank(const Mantid::Geometry::ComponentInfo &compInfo,
+                           size_t index) {
+  auto c = findCorners(compInfo, index);
+  auto bank = compInfo.quadrilateralComponent(index);
+  auto xstep =
+      (c.bottomRight.X() - c.bottomLeft.X()) / static_cast<double>(bank.nX);
+  auto ystep =
+      (c.topRight.Y() - c.bottomLeft.Y()) / static_cast<double>(bank.nY);
+  auto name = compInfo.name(index);
+  // Because texture colours are combined with the geometry colour
+  // make sure the current colour is white
+  glColor3f(1.0f, 1.0f, 1.0f);
+
+  // Nearest-neighbor scaling
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glEnable(GL_TEXTURE_2D); // enable texture mapping
+
+  size_t texx, texy;
+  auto res = getCorrectedTextureSize(bank.nX, bank.nY);
+  texx = res.first;
+  texy = res.second;
+  double tex_frac_x = static_cast<double>(bank.nX) / static_cast<double>(texx);
+  double tex_frac_y = static_cast<double>(bank.nY) / static_cast<double>(texy);
+
+  glBegin(GL_QUADS);
+
+  auto basePos = c.bottomLeft;
+
+  // Set the bank normal to facilitate lighting effects
+  setBankNormal(c.bottomRight, c.topLeft, basePos);
+
+  glTexCoord2f(0.0, 0.0);
+  addVertex(c.bottomLeft - basePos + V3D((xstep * -0.5), (ystep * -0.5), 0.0));
+
+  glTexCoord2f(static_cast<GLfloat>(tex_frac_x), 0.0);
+  addVertex(c.bottomRight - basePos + V3D((xstep * 0.5), (ystep * -0.5), 0.0));
+
+  glTexCoord2f(static_cast<GLfloat>(tex_frac_x),
+               static_cast<GLfloat>(tex_frac_y));
+  addVertex(c.topRight - basePos + V3D((xstep * 0.5), (ystep * 0.5), 0.0));
+
+  glTexCoord2f(0.0, static_cast<GLfloat>(tex_frac_y));
+  addVertex(c.topLeft - basePos + V3D((xstep * -0.5), (ystep * 0.5), 0.0));
+
+  glEnd();
+
+  if (glGetError() > 0)
+    g_log.error() << "OpenGL error in renderRectangularBank() \n";
+
+  glDisable(
+      GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary.
+}
+
+void renderStructuredBank(const Mantid::Geometry::ComponentInfo &compInfo,
+                          size_t index, const std::vector<GLColor> &color) {
+  glBegin(GL_QUADS);
+
+  const auto &columns = compInfo.children(index);
+  auto colWidth = (columns.size()) * 3;
+  auto baseIndex = compInfo.children(columns[0])[0];
+  const auto &baseShapeInfo =
+      compInfo.shape(baseIndex).getGeometryHandler()->shapeInfo();
+  auto basePos = baseShapeInfo.points()[0];
+  std::vector<V3D> hex(4);
+
+  setBankNormal(baseShapeInfo.points()[1], baseShapeInfo.points()[3], basePos);
+
+  for (size_t x = 0; x < colWidth; x += 3) {
+    auto index = x / 3;
+    const auto &column = compInfo.children(columns[index]);
+    for (size_t y = 0; y < column.size() - 1; ++y) {
+      extractHexahedron(compInfo.shape(column[y]), hex);
+      offsetHexahedronPosition(hex, -basePos);
+      rotateHexahedron(hex, compInfo.rotation(column[y]));
+      offsetHexahedronPosition(hex, compInfo.position(column[y]));
+
+      glColor3ub((GLubyte)color[column[y]].red(),
+                 (GLubyte)color[column[y]].green(),
+                 (GLubyte)color[column[y]].blue());
+      glVertex3f(static_cast<GLfloat>(hex[0].X()),
+                 static_cast<GLfloat>(hex[0].Y()), 0);
+      glVertex3f(static_cast<GLfloat>(hex[1].X()),
+                 static_cast<GLfloat>(hex[1].Y()), 0);
+      glVertex3f(static_cast<GLfloat>(hex[2].X()),
+                 static_cast<GLfloat>(hex[2].Y()), 0);
+      glVertex3f(static_cast<GLfloat>(hex[3].X()),
+                 static_cast<GLfloat>(hex[3].Y()), 0);
+    }
+  }
+
+  glEnd();
+
+  if (glGetError() > 0)
+    g_log.error() << "OpenGL error in renderStructuredBank() \n";
+}
+} // namespace BankRenderingHelpers
+} // namespace MantidWidgets
+} // namespace MantidQt
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/src/CompAssemblyActor.cpp b/qt/widgets/instrumentview/src/CompAssemblyActor.cpp
deleted file mode 100644
index e60b5679340609c77b8f5a38cc74ad3ce11f140b..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/CompAssemblyActor.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-
-#include "MantidGeometry/Instrument.h"
-#include "MantidKernel/V3D.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/ICompAssembly.h"
-#include "MantidGeometry/Instrument/ObjCompAssembly.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidKernel/Exception.h"
-
-#include <cfloat>
-
-using Mantid::Geometry::IComponent;
-using Mantid::Geometry::IObjComponent;
-using Mantid::Geometry::ICompAssembly;
-using Mantid::Geometry::ObjCompAssembly;
-using Mantid::Geometry::ComponentID;
-using Mantid::Geometry::RectangularDetector;
-using Mantid::Geometry::StructuredDetector;
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-/**
-* This is a constructor for CompAssembly Actor
-* @param instrActor :: the current instrument actor
-* @param compID :: the current component ID
-*/
-CompAssemblyActor::CompAssemblyActor(
-    const InstrumentActor &instrActor,
-    const Mantid::Geometry::ComponentID &compID)
-    : ICompAssemblyActor(instrActor, compID) {
-  boost::shared_ptr<const IComponent> CompPtr = getComponent();
-
-  // bounding box of the overall instrument
-  Mantid::Kernel::V3D minBound;
-  Mantid::Kernel::V3D maxBound;
-  // Iterate through CompAssembly children
-  boost::shared_ptr<const ICompAssembly> CompAssemPtr =
-      boost::dynamic_pointer_cast<const ICompAssembly>(CompPtr);
-  if (CompAssemPtr != boost::shared_ptr<ICompAssembly>()) {
-    int nChild = CompAssemPtr->nelements();
-    for (int i = 0; i < nChild; i++) {
-      boost::shared_ptr<IComponent> ChildCompPtr = (*CompAssemPtr)[i];
-      boost::shared_ptr<ICompAssembly> ChildCAPtr =
-          boost::dynamic_pointer_cast<ICompAssembly>(ChildCompPtr);
-
-      // If the child is a CompAssembly then create a CompAssemblyActor for the
-      // child
-      if (ChildCAPtr) {
-        boost::shared_ptr<ObjCompAssembly> ChildOCAPtr =
-            boost::dynamic_pointer_cast<ObjCompAssembly>(ChildCompPtr);
-        boost::shared_ptr<RectangularDetector> ChildRDPtr =
-            boost::dynamic_pointer_cast<RectangularDetector>(ChildCompPtr);
-        boost::shared_ptr<StructuredDetector> ChildSDPtr =
-            boost::dynamic_pointer_cast<StructuredDetector>(ChildCompPtr);
-
-        if (ChildSDPtr) {
-          StructuredDetectorActor *iActor = new StructuredDetectorActor(
-              instrActor, ChildSDPtr->getComponentID());
-          iActor->getBoundingBox(minBound, maxBound);
-          AppendBoundingBox(minBound, maxBound);
-          mNumberOfDetectors += iActor->getNumberOfDetectors();
-          mChildCompAssemActors.push_back(iActor);
-        } else if (ChildRDPtr) {
-          // If the child is a RectangularDetector, then create a
-          // RectangularDetectorActor for it.
-          RectangularDetectorActor *iActor = new RectangularDetectorActor(
-              instrActor, ChildCAPtr->getComponentID());
-          iActor->getBoundingBox(minBound, maxBound);
-          AppendBoundingBox(minBound, maxBound);
-          mNumberOfDetectors += iActor->getNumberOfDetectors();
-          mChildCompAssemActors.push_back(iActor);
-        } else if (ChildOCAPtr) {
-          ObjCompAssemblyActor *iActor = new ObjCompAssemblyActor(
-              instrActor, ChildCAPtr->getComponentID());
-          iActor->getBoundingBox(minBound, maxBound);
-          AppendBoundingBox(minBound, maxBound);
-          mNumberOfDetectors += iActor->getNumberOfDetectors();
-          mChildCompAssemActors.push_back(iActor);
-        } else {
-          CompAssemblyActor *iActor =
-              new CompAssemblyActor(instrActor, ChildCAPtr->getComponentID());
-          iActor->getBoundingBox(minBound, maxBound);
-          AppendBoundingBox(minBound, maxBound);
-          mNumberOfDetectors += iActor->getNumberOfDetectors();
-          mChildCompAssemActors.push_back(iActor);
-        }
-      } else // it has to be a ObjComponent child, create a ObjComponentActor
-             // for the child use the same display list attribute
-      {
-        boost::shared_ptr<Mantid::Geometry::IObjComponent> ChildObjPtr =
-            boost::dynamic_pointer_cast<Mantid::Geometry::IObjComponent>(
-                ChildCompPtr);
-        ObjComponentActor *iActor =
-            new ObjComponentActor(instrActor, ChildCompPtr->getComponentID());
-        iActor->getBoundingBox(minBound, maxBound);
-        AppendBoundingBox(minBound, maxBound);
-        mChildObjCompActors.push_back(iActor);
-        mNumberOfDetectors++;
-      }
-    }
-  }
-}
-
-/**
-* Destructor which removes the actors created by this object
-*/
-CompAssemblyActor::~CompAssemblyActor() {
-  // Remove all the child CompAssembly Actors
-  for (std::vector<ICompAssemblyActor *>::iterator iAssem =
-           mChildCompAssemActors.begin();
-       iAssem != mChildCompAssemActors.end(); ++iAssem)
-    delete (*iAssem);
-  mChildCompAssemActors.clear();
-  // Remove all the child ObjComponent Actors
-  for (std::vector<ObjComponentActor *>::iterator iObjComp =
-           mChildObjCompActors.begin();
-       iObjComp != mChildObjCompActors.end(); ++iObjComp)
-    delete (*iObjComp);
-  mChildObjCompActors.clear();
-}
-
-/**
-* This function is concrete implementation that renders the Child ObjComponents
-* and Child CompAssembly's
-*/
-void CompAssemblyActor::draw(bool picking) const {
-  OpenGLError::check("CompAssemblyActor::draw(0)");
-  // Only draw the CompAssembly Children only if they are visible
-  if (isVisible()) {
-    // Iterate through the ObjCompActor children and draw them
-    for (std::vector<ObjComponentActor *>::iterator itrObjComp =
-             mChildObjCompActors.begin();
-         itrObjComp != mChildObjCompActors.end(); ++itrObjComp) {
-      // Only draw the ObjCompActor if its visible
-      if ((*itrObjComp)->isVisible()) {
-        // std::cout << (*itrObjComp)->getName() << " is gonna draw. From
-        // define()\n";
-        (*itrObjComp)->draw(picking);
-        OpenGLError::check("draw " + (*itrObjComp)->getComponent()->getName());
-      } else {
-        // std::cout << (*itrObjComp)->getName() << " is not visible\n";
-      }
-    }
-    // Iterate through the CompAssemblyActor children and draw them
-    for (std::vector<ICompAssemblyActor *>::iterator itrObjAssem =
-             mChildCompAssemActors.begin();
-         itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) {
-      if ((*itrObjAssem)->isVisible()) {
-        // std::cout << (*itrObjAssem)->getName() << " is gonna draw. From
-        // define()\n";
-        (*itrObjAssem)->draw(picking);
-      }
-    }
-  } else {
-    // std::cout << this->getName() << " is not visible\n";
-  }
-  OpenGLError::check("CompAssemblyActor::draw()");
-}
-
-bool CompAssemblyActor::accept(GLActorVisitor &visitor,
-                               VisitorAcceptRule rule) {
-  for (std::vector<ObjComponentActor *>::iterator itrObjComp =
-           mChildObjCompActors.begin();
-       itrObjComp != mChildObjCompActors.end(); ++itrObjComp) {
-    if ((**itrObjComp).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  for (std::vector<ICompAssemblyActor *>::iterator itrObjAssem =
-           mChildCompAssemActors.begin();
-       itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) {
-    if ((**itrObjAssem).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  return visitor.visit(this);
-}
-
-bool CompAssemblyActor::accept(GLActorConstVisitor &visitor,
-                               GLActor::VisitorAcceptRule rule) const {
-  for (std::vector<ObjComponentActor *>::iterator itrObjComp =
-           mChildObjCompActors.begin();
-       itrObjComp != mChildObjCompActors.end(); ++itrObjComp) {
-    if ((**itrObjComp).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  for (std::vector<ICompAssemblyActor *>::iterator itrObjAssem =
-           mChildCompAssemActors.begin();
-       itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) {
-    if ((**itrObjAssem).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  return visitor.visit(this);
-}
-
-//------------------------------------------------------------------------------------------------
-/**
-* Append the bounding box CompAssembly bounding box
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void CompAssemblyActor::AppendBoundingBox(const Mantid::Kernel::V3D &minBound,
-                                          const Mantid::Kernel::V3D &maxBound) {
-  if (minBoundBox[0] > minBound[0])
-    minBoundBox[0] = minBound[0];
-  if (minBoundBox[1] > minBound[1])
-    minBoundBox[1] = minBound[1];
-  if (minBoundBox[2] > minBound[2])
-    minBoundBox[2] = minBound[2];
-  if (maxBoundBox[0] < maxBound[0])
-    maxBoundBox[0] = maxBound[0];
-  if (maxBoundBox[1] < maxBound[1])
-    maxBoundBox[1] = maxBound[1];
-  if (maxBoundBox[2] < maxBound[2])
-    maxBoundBox[2] = maxBound[2];
-}
-
-void CompAssemblyActor::setColors() {
-  for (std::vector<ICompAssemblyActor *>::iterator iAssem =
-           mChildCompAssemActors.begin();
-       iAssem != mChildCompAssemActors.end(); ++iAssem) {
-    (**iAssem).setColors();
-  }
-  for (std::vector<ObjComponentActor *>::iterator iObjComp =
-           mChildObjCompActors.begin();
-       iObjComp != mChildObjCompActors.end(); ++iObjComp) {
-    (**iObjComp).setColors();
-  }
-}
-
-void CompAssemblyActor::setChildVisibility(bool on) {
-  GLActor::setVisibility(on);
-  for (std::vector<ObjComponentActor *>::iterator itrObjComp =
-           mChildObjCompActors.begin();
-       itrObjComp != mChildObjCompActors.end(); ++itrObjComp) {
-    (**itrObjComp).setVisibility(on);
-  }
-  for (std::vector<ICompAssemblyActor *>::iterator itrObjAssem =
-           mChildCompAssemActors.begin();
-       itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) {
-    (**itrObjAssem).setChildVisibility(on);
-  }
-}
-
-bool CompAssemblyActor::hasChildVisible() const {
-  for (std::vector<ObjComponentActor *>::iterator itrObjComp =
-           mChildObjCompActors.begin();
-       itrObjComp != mChildObjCompActors.end(); ++itrObjComp) {
-    if ((**itrObjComp).isVisible())
-      return true;
-  }
-  for (std::vector<ICompAssemblyActor *>::iterator itrObjAssem =
-           mChildCompAssemActors.begin();
-       itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) {
-    if ((**itrObjAssem).hasChildVisible())
-      return true;
-  }
-  return false;
-}
-
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/ComponentActor.cpp b/qt/widgets/instrumentview/src/ComponentActor.cpp
deleted file mode 100644
index 36a0b1108b96c3118e0d99df4768684d082dcdab..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/ComponentActor.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/ComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-
-#include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Instrument/ObjCompAssembly.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidGeometry/Instrument/CompAssembly.h"
-
-using namespace Mantid;
-using namespace Geometry;
-
-namespace MantidQt {
-namespace MantidWidgets {
-ComponentActor::ComponentActor(const InstrumentActor &instrActor,
-                               const Mantid::Geometry::ComponentID &compID)
-    : GLActor(), m_instrActor(instrActor), m_id(compID) {}
-
-bool ComponentActor::accept(GLActorVisitor &visitor,
-                            GLActor::VisitorAcceptRule) {
-  return visitor.visit(this);
-}
-
-bool ComponentActor::accept(GLActorConstVisitor &visitor,
-                            GLActor::VisitorAcceptRule) const {
-  return visitor.visit(this);
-}
-
-boost::shared_ptr<const Mantid::Geometry::IComponent>
-ComponentActor::getComponent() const {
-  return m_instrActor.getInstrument()->getComponentByID(m_id);
-}
-
-boost::shared_ptr<const Mantid::Geometry::IObjComponent>
-ComponentActor::getObjComponent() const {
-  return boost::dynamic_pointer_cast<const Mantid::Geometry::IObjComponent>(
-      getComponent());
-}
-
-boost::shared_ptr<const Mantid::Geometry::IDetector>
-ComponentActor::getDetector() const {
-  return boost::dynamic_pointer_cast<const Mantid::Geometry::IDetector>(
-      getComponent());
-}
-
-boost::shared_ptr<const Mantid::Geometry::ObjCompAssembly>
-ComponentActor::getObjCompAssembly() const {
-  return boost::dynamic_pointer_cast<const Mantid::Geometry::ObjCompAssembly>(
-      getComponent());
-}
-
-boost::shared_ptr<const Mantid::Geometry::CompAssembly>
-ComponentActor::getCompAssembly() const {
-  return boost::dynamic_pointer_cast<const Mantid::Geometry::CompAssembly>(
-      getComponent());
-}
-
-/**
-* A component is a non-detector if it's an ObjComponent (has a shape) and not an
-ObjCompAssembly
-* (a single object) and not a RectangularDetector (which is an assembly) or a
-StructuredDetector
-(which is an assembly).
-*/
-bool ComponentActor::isNonDetector() const {
-  auto obj = getObjComponent();
-  return obj && !getObjCompAssembly() && !getDetector() &&
-         !boost::dynamic_pointer_cast<
-             const Mantid::Geometry::RectangularDetector>(obj) &&
-         !boost::dynamic_pointer_cast<
-             const Mantid::Geometry::StructuredDetector>(obj);
-}
-
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/DetXMLFile.cpp b/qt/widgets/instrumentview/src/DetXMLFile.cpp
index ec8aefa181632f422dfa41f7995b128b8950987c..f4b6ab1853f670b5ff50ae6ef7897d1d890dc85e 100644
--- a/qt/widgets/instrumentview/src/DetXMLFile.cpp
+++ b/qt/widgets/instrumentview/src/DetXMLFile.cpp
@@ -21,7 +21,7 @@ DetXMLFile::DetXMLFile(const std::vector<int> &detector_list,
   m_delete = false;
   std::ofstream out(m_fileName.toStdString().c_str());
   out << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \n<detector-grouping> \n";
-  out << "<group name=\"sum\"> <detids val=\"";
+  out << R"(<group name="sum"> <detids val=")";
   std::vector<int>::const_iterator idet = detector_list.begin();
   for (; idet != detector_list.end(); ++idet) {
     if (!exclude.contains(*idet)) {
@@ -82,7 +82,7 @@ void DetXMLFile::makeListFile(const QList<int> &dets) {
 void DetXMLFile::makeSumFile(const QList<int> &dets) {
   std::ofstream out(m_fileName.toStdString().c_str());
   out << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \n<detector-grouping> \n";
-  out << "<group name=\"sum\"> <detids val=\"";
+  out << R"(<group name="sum"> <detids val=")";
   foreach (int det, dets) { out << det << ','; }
   out << "\"/> </group> \n</detector-grouping>\n";
 }
diff --git a/qt/widgets/instrumentview/src/GLActor.cpp b/qt/widgets/instrumentview/src/GLActor.cpp
deleted file mode 100644
index 452855bcafe0f666ccb6fbdd0e5d6876eccbe9f9..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/GLActor.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/GLActor.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-
-namespace MantidQt {
-namespace MantidWidgets {
-GLActor::~GLActor() {}
-
-void GLActor::setVisibility(bool on) {
-  if (m_visible == GLActorVisiblity::ALWAYS_HIDDEN) {
-    // If we are always hidden do not change the visibility
-    return;
-  }
-  if (on) {
-    m_visible = GLActorVisiblity::VISIBLE;
-  } else {
-    m_visible = GLActorVisiblity::HIDDEN;
-  }
-}
-
-bool GLActor::accept(GLActorVisitor &visitor, VisitorAcceptRule) {
-  return visitor.visit(this);
-}
-
-bool GLActor::accept(GLActorConstVisitor &visitor,
-                     GLActor::VisitorAcceptRule) const {
-  return visitor.visit(this);
-}
-
-GLColor GLActor::makePickColor(size_t pickID) {
-  pickID += 1;
-  unsigned char r, g, b;
-  r = (unsigned char)(pickID / 65536);
-  g = (unsigned char)((pickID % 65536) / 256);
-  b = (unsigned char)((pickID % 65536) % 256);
-  return GLColor(r, g, b);
-}
-
-size_t GLActor::decodePickColor(const QRgb &c) {
-  return decodePickColor((unsigned char)qRed(c), (unsigned char)qGreen(c),
-                         (unsigned char)qBlue(c));
-}
-
-size_t GLActor::decodePickColor(unsigned char r, unsigned char g,
-                                unsigned char b) {
-  unsigned int index = r;
-  index *= 256;
-  index += g;
-  index *= 256;
-  index += b - 1;
-  return index;
-}
-
-GLColor GLActor::defaultDetectorColor() { return GLColor(200, 200, 200); }
-
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/GLActorCollection.cpp b/qt/widgets/instrumentview/src/GLActorCollection.cpp
deleted file mode 100644
index 4e092285e6ed4f53ab9e810bed9524605c236557..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/GLActorCollection.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/GLActorCollection.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-
-#include "MantidKernel/Exception.h"
-
-#include <algorithm>
-#include <cfloat>
-#include <functional>
-#include <stdexcept>
-
-namespace MantidQt {
-namespace MantidWidgets {
-GLActorCollection::GLActorCollection()
-    : GLActor(), m_minBound(DBL_MAX, DBL_MAX, DBL_MAX),
-      m_maxBound(-DBL_MAX, -DBL_MAX, -DBL_MAX) {
-  m_displayListId[0] = 0;
-  m_displayListId[1] = 0;
-  m_useDisplayList[0] = false;
-  m_useDisplayList[1] = false;
-}
-
-GLActorCollection::~GLActorCollection() {
-  for (std::vector<GLActor *>::iterator i = mActorsList.begin();
-       i != mActorsList.end(); ++i) {
-    delete (*i);
-  }
-  mActorsList.clear();
-  for (size_t i = 0; i < 2; ++i) {
-    if (m_displayListId[i] != 0) {
-      glDeleteLists(m_displayListId[i], 1);
-    }
-  }
-}
-
-/**
-* This method does the drawing by calling the list of actors to draw themselfs
-*/
-void GLActorCollection::draw(bool picking) const {
-  if (!isVisible())
-    return;
-  OpenGLError::check("GLActorCollection::draw(0)");
-  size_t i = picking ? 1 : 0;
-  if (m_useDisplayList[i]) {
-    glCallList(m_displayListId[i]);
-  } else if (m_displayListId[i] == 0) {
-    m_displayListId[i] = glGenLists(1);
-    // child actors can also create display lists, so delay
-    // until all the children have finished making theirs
-    drawGL(picking);
-  } else {
-    m_useDisplayList[i] = true;
-    glNewList(m_displayListId[i],
-              GL_COMPILE); // Construct display list for object representation
-    drawGL(picking);
-    glEndList();
-    if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception
-      throw Mantid::Kernel::Exception::OpenGLError(
-          "OpenGL: Out of video memory");
-    glCallList(m_displayListId[i]);
-  }
-  OpenGLError::check("GLActorCollection::draw()");
-}
-
-void GLActorCollection::drawGL(bool picking) const {
-  for (std::vector<GLActor *>::const_iterator it = mActorsList.begin();
-       it != mActorsList.end(); ++it) {
-    (**it).draw(picking);
-  }
-}
-
-bool GLActorCollection::accept(GLActorVisitor &visitor,
-                               VisitorAcceptRule rule) {
-  for (std::vector<GLActor *>::const_iterator it = mActorsList.begin();
-       it != mActorsList.end(); ++it) {
-    if ((**it).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  return visitor.visit(this);
-}
-
-bool GLActorCollection::accept(GLActorConstVisitor &visitor,
-                               GLActor::VisitorAcceptRule rule) const {
-  for (std::vector<GLActor *>::const_iterator it = mActorsList.begin();
-       it != mActorsList.end(); ++it) {
-    if ((**it).accept(visitor, rule) && rule == Finish)
-      return true;
-  }
-  return visitor.visit(this);
-}
-
-/**
-* This method addes a new actor to the collection.
-* @param a :: input actor to be added to the list
-*/
-void GLActorCollection::addActor(GLActor *a) {
-  if (!a) {
-    return;
-  }
-  mActorsList.push_back(a);
-  Mantid::Kernel::V3D minBound;
-  Mantid::Kernel::V3D maxBound;
-  a->getBoundingBox(minBound, maxBound);
-  if (m_minBound[0] > minBound[0])
-    m_minBound[0] = minBound[0];
-  if (m_minBound[1] > minBound[1])
-    m_minBound[1] = minBound[1];
-  if (m_minBound[2] > minBound[2])
-    m_minBound[2] = minBound[2];
-  if (m_maxBound[0] < maxBound[0])
-    m_maxBound[0] = maxBound[0];
-  if (m_maxBound[1] < maxBound[1])
-    m_maxBound[1] = maxBound[1];
-  if (m_maxBound[2] < maxBound[2])
-    m_maxBound[2] = maxBound[2];
-}
-
-/**
-* Remove the input actor from the collection
-* @param :: input actor to be removed from the list
-*/
-void GLActorCollection::removeActor(GLActor *) {
-  throw std::runtime_error("Removing actor not implemented");
-}
-
-/**
-* This method returns the number of actors in the collection
-* @return integer value of number of actors in collection
-*/
-int GLActorCollection::getNumberOfActors() {
-  return static_cast<int>(mActorsList.size());
-}
-
-/**
-* This method returns the actor at the given index
-* @param index :: is the index in actor collection to be returned
-* @return a pointer to the actor at a given index
-*/
-GLActor *GLActorCollection::getActor(int index) {
-  if (index < 0 || index > static_cast<int>(mActorsList.size()))
-    return nullptr;
-  return mActorsList.at(index);
-}
-
-void GLActorCollection::getBoundingBox(Mantid::Kernel::V3D &minBound,
-                                       Mantid::Kernel::V3D &maxBound) const {
-  minBound = m_minBound;
-  maxBound = m_maxBound;
-}
-
-void GLActorCollection::invalidateDisplayList() const {
-  for (size_t i = 0; i < 2; ++i) {
-    if (m_displayListId[i] != 0) {
-      glDeleteLists(m_displayListId[i], 1);
-      m_displayListId[i] = 0;
-      m_useDisplayList[i] = false;
-    }
-  }
-}
-
-void GLActorCollection::setChildVisibility(bool on) {
-  GLActor::setVisibility(on);
-  for (std::vector<GLActor *>::const_iterator it = mActorsList.begin();
-       it != mActorsList.end(); ++it) {
-    (**it).setChildVisibility(on);
-  }
-}
-
-bool GLActorCollection::hasChildVisible() const {
-  for (std::vector<GLActor *>::const_iterator it = mActorsList.begin();
-       it != mActorsList.end(); ++it) {
-    if ((**it).hasChildVisible())
-      return true;
-  }
-  return false;
-}
-}
-}
diff --git a/qt/widgets/instrumentview/src/GLActorVisitor.cpp b/qt/widgets/instrumentview/src/GLActorVisitor.cpp
deleted file mode 100644
index 176bd6992502b34b00345e82e9f69ee61df8a78d..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/GLActorVisitor.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-#include "MantidQtWidgets/InstrumentView/GLActor.h"
-#include "MantidQtWidgets/InstrumentView/GLActorCollection.h"
-#include "MantidQtWidgets/InstrumentView/ComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h"
-
-namespace MantidQt {
-namespace MantidWidgets {
-//   Default visit implementations just call visit(GLActor*)
-
-bool GLActorVisitor::visit(GLActorCollection *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(CompAssemblyActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(ObjCompAssemblyActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(ComponentActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(InstrumentActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(RectangularDetectorActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorVisitor::visit(StructuredDetectorActor *actor) {
-  return this->visit(static_cast<GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const GLActorCollection *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const CompAssemblyActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const ObjCompAssemblyActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const ComponentActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const InstrumentActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const RectangularDetectorActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool GLActorConstVisitor::visit(const StructuredDetectorActor *actor) {
-  return this->visit(static_cast<const GLActor *>(actor));
-}
-
-bool SetAllVisibleVisitor::visit(GLActor *actor) {
-  actor->setVisibility(true);
-  return true;
-}
-
-bool SetAllVisibleVisitor::visit(ComponentActor *actor) {
-  bool on = (!actor->isNonDetector()) || m_showNonDet;
-  actor->setVisibility(on);
-  return true;
-}
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/GLColor.cpp b/qt/widgets/instrumentview/src/GLColor.cpp
index 37b30138a1ae20baf3c9da5fcd38d2824dce99fe..7a31a62fa863c355bd164dd1c7fe929c29b9c104 100644
--- a/qt/widgets/instrumentview/src/GLColor.cpp
+++ b/qt/widgets/instrumentview/src/GLColor.cpp
@@ -24,11 +24,11 @@ GLColor::GLColor(float red, float green, float blue, float alpha) {
   m_rgba[3] = (unsigned char)(alpha * 255);
 }
 
-GLColor::GLColor(int r, int g, int b) {
+GLColor::GLColor(int r, int g, int b, int a) {
   m_rgba[0] = (unsigned char)r;
   m_rgba[1] = (unsigned char)g;
   m_rgba[2] = (unsigned char)b;
-  m_rgba[3] = 255;
+  m_rgba[3] = (unsigned char)a;
 }
 
 /**
diff --git a/qt/widgets/instrumentview/src/GLObject.cpp b/qt/widgets/instrumentview/src/GLObject.cpp
index a4eb4a7838bfc8ec2d09bcddd3dfb4732be40da2..c071256d77372ba82604fa40cc56d4eedcca4496 100644
--- a/qt/widgets/instrumentview/src/GLObject.cpp
+++ b/qt/widgets/instrumentview/src/GLObject.cpp
@@ -2,7 +2,6 @@
 #include <windows.h>
 #endif
 #include "MantidQtWidgets/InstrumentView/GLObject.h"
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/System.h"
 
diff --git a/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp b/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp
deleted file mode 100644
index 6c8d90c69eb0a6d01194675ceb4fa0be4d430de6..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/ICompAssemblyActor.h"
-#include <cfloat>
-
-#include "MantidKernel/V3D.h"
-#include "MantidGeometry/IComponent.h"
-
-using namespace Mantid;
-using namespace Geometry;
-
-namespace MantidQt {
-namespace MantidWidgets {
-/**
-* This is a constructor for CompAssembly Actor
-* @param instrActor :: the instrument actor
-* @param compID :: the component ID
-*/
-ICompAssemblyActor::ICompAssemblyActor(
-    const InstrumentActor &instrActor,
-    const Mantid::Geometry::ComponentID &compID)
-    : ComponentActor(instrActor, compID), mNumberOfDetectors(0),
-      minBoundBox(DBL_MAX, DBL_MAX, DBL_MAX),
-      maxBoundBox(-DBL_MAX, -DBL_MAX, -DBL_MAX) {}
-
-//------------------------------------------------------------------------------------------------
-/**
-* Return the bounding box
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void ICompAssemblyActor::getBoundingBox(Mantid::Kernel::V3D &minBound,
-                                        Mantid::Kernel::V3D &maxBound) const {
-  minBound = minBoundBox;
-  maxBound = maxBoundBox;
-}
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp
index 633e33f7c1cec4097bce89cab0f45fc10e793059..fefaed54470cd3f0a50b8d3ab83a640cc0c26276 100644
--- a/qt/widgets/instrumentview/src/InstrumentActor.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp
@@ -1,12 +1,7 @@
 #include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
 #include "MantidQtWidgets/Common/TSVSerialiser.h"
-#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/ComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h"
+#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h"
+#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
 
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/CommonBinsValidator.h"
@@ -15,10 +10,13 @@
 #include "MantidAPI/IMaskWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/SpectrumInfo.h"
+#include "MantidTypes/SpectrumDefinition.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidGeometry/Instrument/InstrumentVisitor.h"
 
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Exception.h"
@@ -31,6 +29,7 @@
 #include <QMessageBox>
 #include <QSettings>
 
+#include <limits>
 #include <numeric>
 
 using namespace Mantid::Kernel::Exception;
@@ -40,115 +39,120 @@ using namespace Mantid;
 
 namespace MantidQt {
 namespace MantidWidgets {
+namespace {
+bool isPhysicalView() {
+  std::string view = Mantid::Kernel::ConfigService::Instance().getString(
+      "instrument.view.geometry");
+
+  return boost::iequals("Default", view) || boost::iequals("Physical", view);
+}
 
-/// to be used in std::transform
-struct Sqrt {
-  double operator()(double x) { return sqrt(x); }
-};
+} // namespace
 
+const size_t InstrumentActor::INVALID_INDEX =
+    std::numeric_limits<size_t>::max();
 double InstrumentActor::m_tolerance = 0.00001;
 
 /**
-* Constructor. Creates a tree of GLActors. Each actor is responsible for
-* displaying insrument components in 3D.
-* Some of the components have "pick ID" assigned to them. Pick IDs can be
-* uniquely converted to a RGB colour value
-* which in turn can be used for picking the component from the screen.
-* @param wsName :: Workspace name
-* @param autoscaling :: True to start with autoscaling option on. If on the min
-* and max of
-*   the colormap scale are defined by the min and max of the data.
-* @param scaleMin :: Minimum value of the colormap scale. Used to assign
-* detector colours. Ignored if autoscaling == true.
-* @param scaleMax :: Maximum value of the colormap scale. Used to assign
-* detector colours. Ignored if autoscaling == true.
-*/
+ * Constructor. Creates a tree of GLActors. Each actor is responsible for
+ * displaying insrument components in 3D.
+ * Some of the components have "pick ID" assigned to them. Pick IDs can be
+ * uniquely converted to a RGB colour value
+ * which in turn can be used for picking the component from the screen.
+ * @param wsName :: Workspace name
+ * @param autoscaling :: True to start with autoscaling option on. If on the min
+ * and max of
+ *   the colormap scale are defined by the min and max of the data.
+ * @param scaleMin :: Minimum value of the colormap scale. Used to assign
+ * detector colours. Ignored if autoscaling == true.
+ * @param scaleMax :: Maximum value of the colormap scale. Used to assign
+ * detector colours. Ignored if autoscaling == true.
+ */
 InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling,
                                  double scaleMin, double scaleMax)
     : m_workspace(AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
           wsName.toStdString())),
       m_ragged(true), m_autoscaling(autoscaling), m_defaultPos(),
-      m_maskedColor(100, 100, 100), m_failedColor(200, 200, 200) {
+      m_isPhysicalInstrument(false) {
   // settings
   loadSettings();
 
   auto sharedWorkspace = m_workspace.lock();
+
   if (!sharedWorkspace)
     throw std::logic_error(
         "InstrumentActor passed a workspace that isn't a MatrixWorkspace");
+  setupPhysicalInstrumentIfExists();
+
+  for (size_t i = 0; i < componentInfo().size(); ++i) {
+    if (!componentInfo().isDetector(i))
+      m_components.push_back(i);
+    else if (detectorInfo().isMonitor(i))
+      m_monitors.push_back(i);
+  }
+
+  m_isCompVisible.assign(componentInfo().size(), true);
+
+  m_renderer.reset(new InstrumentRenderer(*this));
+  m_renderer->changeScaleType(m_scaleType);
 
   // set up the color map
   if (!m_currentColorMapFilename.isEmpty()) {
     loadColorMap(m_currentColorMapFilename, false);
   }
-  m_colorMap.changeScaleType(m_scaleType);
 
   // set up data ranges and colours
   setUpWorkspace(sharedWorkspace, scaleMin, scaleMax);
 
-  Instrument_const_sptr instrument = getInstrument();
-
   // If the instrument is empty, maybe only having the sample and source
-  const int nelements = instrument->nelements();
-  if ((nelements == 0) || (nelements == 1 && (instrument->getSource() ||
-                                              instrument->getSample())) ||
-      (nelements == 2 && instrument->getSource() && instrument->getSample())) {
+  if (detectorInfo().size() == 0) {
     QMessageBox::warning(nullptr, "MantidPlot - Warning",
                          "This instrument appears to contain no detectors",
                          "OK");
   }
-
-  // this adds actors for all instrument components to the scene and fills in
-  // m_detIDs
-  m_scene.addActor(new CompAssemblyActor(*this, instrument->getComponentID()));
-  setupPickColors();
-
-  if (!m_showGuides) {
-    // hide guide and other components
-    showGuides(m_showGuides);
-  }
 }
 
 /**
-* Destructor
-*/
+ * Destructor
+ */
 InstrumentActor::~InstrumentActor() { saveSettings(); }
 
 /**
-* Set up the workspace: calculate the value ranges, set the colours.
-* @param sharedWorkspace :: A shared pointer to the workspace.
-* @param scaleMin :: Minimum limit on the color map axis. If autoscale this
-* value is ignored.
-* @param scaleMax :: Maximum limit on the color map axis. If autoscale this
-* value is ignored.
-*/
+ * Set up the workspace: calculate the value ranges, set the colours.
+ * @param sharedWorkspace :: A shared pointer to the workspace.
+ * @param scaleMin :: Minimum limit on the color map axis. If autoscale this
+ * value is ignored.
+ * @param scaleMax :: Maximum limit on the color map axis. If autoscale this
+ * value is ignored.
+ */
 void InstrumentActor::setUpWorkspace(
     boost::shared_ptr<const Mantid::API::MatrixWorkspace> sharedWorkspace,
     double scaleMin, double scaleMax) {
-  const size_t nHist = sharedWorkspace->getNumberHistograms();
   m_WkspBinMinValue = DBL_MAX;
   m_WkspBinMaxValue = -DBL_MAX;
-  for (size_t i = 0; i < nHist; ++i) {
-    const auto &values = sharedWorkspace->x(i);
+  const auto &spectrumInfo = sharedWorkspace->spectrumInfo();
+  m_detIndex2WsIndex.resize(componentInfo().size(), INVALID_INDEX);
+  for (size_t wi = 0; wi < spectrumInfo.size(); ++wi) {
+    const auto &values = sharedWorkspace->x(wi);
     double xtest = values.front();
     if (!std::isinf(xtest)) {
-      if (xtest < m_WkspBinMinValue) {
+      if (xtest < m_WkspBinMinValue)
         m_WkspBinMinValue = xtest;
-      } else if (xtest > m_WkspBinMaxValue) {
+      else if (xtest > m_WkspBinMaxValue)
         m_WkspBinMaxValue = xtest;
-      } else {
-      }
     }
 
     xtest = values.back();
     if (!std::isinf(xtest)) {
-      if (xtest < m_WkspBinMinValue) {
+      if (xtest < m_WkspBinMinValue)
         m_WkspBinMinValue = xtest;
-      } else if (xtest > m_WkspBinMaxValue) {
+      else if (xtest > m_WkspBinMaxValue)
         m_WkspBinMaxValue = xtest;
-      } else {
-      }
     }
+
+    const auto &specDef = spectrumInfo.spectrumDefinition(wi);
+    for (auto info : specDef)
+      m_detIndex2WsIndex[info.first] = wi;
   }
 
   // set some values as the variables will be used
@@ -156,54 +160,57 @@ void InstrumentActor::setUpWorkspace(
   m_DataMinValue = -DBL_MAX;
   m_DataMaxValue = DBL_MAX;
 
-  if (!m_autoscaling) {
+  if (!m_autoscaling)
     setDataMinMaxRange(scaleMin, scaleMax);
-  }
+
   setDataIntegrationRange(m_WkspBinMinValue, m_WkspBinMaxValue);
   resetColors();
 
   // set the ragged flag using a workspace validator
   auto wsValidator = Mantid::API::CommonBinsValidator();
   m_ragged = !wsValidator.isValid(sharedWorkspace).empty();
-
-  /// Keep the pointer to the detid2index map
-  m_detid2index_map = sharedWorkspace->getDetectorIDToWorkspaceIndexMap();
 }
 
-/** Used to set visibility of an actor corresponding to a particular component
-* When selecting a component in the InstrumentTreeWidget
-*
-* @param visitor :: Visitor to be accepted bu this actor.
-* @param rule :: A rule defining visitor acceptance by assembly actors.
-*/
-bool InstrumentActor::accept(GLActorVisitor &visitor, VisitorAcceptRule rule) {
-  bool ok = m_scene.accept(visitor, rule);
-  visitor.visit(this);
-  invalidateDisplayLists();
-  return ok;
+void InstrumentActor::setupPhysicalInstrumentIfExists() {
+  if (!isPhysicalView())
+    return;
+
+  auto sharedWorkspace = getWorkspace();
+  Mantid::Kernel::ReadLock _lock(*sharedWorkspace);
+
+  auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument();
+  if (instr) {
+    auto infos = InstrumentVisitor::makeWrappers(*instr);
+    m_physicalComponentInfo = std::move(infos.first);
+    m_physicalDetectorInfo = std::move(infos.second);
+    m_isPhysicalInstrument = true;
+  }
 }
 
-bool InstrumentActor::accept(GLActorConstVisitor &visitor,
-                             GLActor::VisitorAcceptRule rule) const {
-  bool ok = m_scene.accept(visitor, rule);
-  visitor.visit(this);
-  return ok;
+void InstrumentActor::setComponentVisible(size_t componentIndex) {
+  setChildVisibility(false);
+  const auto &compInfo = componentInfo();
+  auto children = compInfo.componentsInSubtree(componentIndex);
+  m_isCompVisible[componentIndex] = true;
+  for (auto child : children)
+    m_isCompVisible[child] = true;
+
+  resetColors();
 }
 
 void InstrumentActor::setChildVisibility(bool on) {
-  m_scene.setChildVisibility(on);
-  auto guidesVisitor = SetVisibleNonDetectorVisitor(m_showGuides);
-  m_scene.accept(guidesVisitor);
+  std::fill(m_isCompVisible.begin(), m_isCompVisible.end(), on);
 }
 
 bool InstrumentActor::hasChildVisible() const {
-  return m_scene.hasChildVisible();
+  return std::any_of(m_isCompVisible.begin(), m_isCompVisible.end(),
+                     [](bool visible) { return visible; });
 }
 
 /** Returns the workspace relating to this instrument view.
-*  !!!! DON'T USE THIS TO GET HOLD OF THE INSTRUMENT !!!!
-*  !!!! USE InstrumentActor::getInstrument() BELOW !!!!
-*/
+ *  !!!! DON'T USE THIS TO GET HOLD OF THE INSTRUMENT !!!!
+ *  !!!! USE InstrumentActor::getInstrument() BELOW !!!!
+ */
 MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const {
   auto sharedWorkspace = m_workspace.lock();
 
@@ -214,9 +221,17 @@ MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const {
   return sharedWorkspace;
 }
 
+void InstrumentActor::getBoundingBox(Mantid::Kernel::V3D &minBound,
+                                     Mantid::Kernel::V3D &maxBound) const {
+  const auto &compInfo = componentInfo();
+  auto bb = compInfo.boundingBox(compInfo.root());
+  minBound = bb.minPoint();
+  maxBound = bb.maxPoint();
+}
+
 /** Returns the mask workspace relating to this instrument view as a
  * MatrixWorkspace
-*/
+ */
 MatrixWorkspace_sptr InstrumentActor::getMaskMatrixWorkspace() const {
   if (!m_maskWorkspace) {
     initMaskHelper();
@@ -225,7 +240,7 @@ MatrixWorkspace_sptr InstrumentActor::getMaskMatrixWorkspace() const {
 }
 
 /** set the mask workspace
-*/
+ */
 void InstrumentActor::setMaskMatrixWorkspace(
     MatrixWorkspace_sptr wsMask) const {
   m_maskWorkspace = wsMask;
@@ -252,10 +267,10 @@ void InstrumentActor::invertMaskWorkspace() const {
 }
 
 /**
-* Returns the mask workspace relating to this instrument view as a
-* IMaskWorkspace.
-* Guarantees to return a valid pointer
-*/
+ * Returns the mask workspace relating to this instrument view as a
+ * IMaskWorkspace.
+ * Guarantees to return a valid pointer
+ */
 IMaskWorkspace_sptr InstrumentActor::getMaskWorkspace() const {
   if (!m_maskWorkspace) {
     initMaskHelper();
@@ -264,10 +279,10 @@ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspace() const {
 }
 
 /**
-* Returns the mask workspace relating to this instrument view as a
-* IMaskWorkspace
-* if it exists or empty pointer if it doesn't.
-*/
+ * Returns the mask workspace relating to this instrument view as a
+ * IMaskWorkspace
+ * if it exists or empty pointer if it doesn't.
+ */
 IMaskWorkspace_sptr InstrumentActor::getMaskWorkspaceIfExists() const {
   if (!m_maskWorkspace)
     return IMaskWorkspace_sptr();
@@ -275,8 +290,8 @@ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspaceIfExists() const {
 }
 
 /**
-* Apply mask stored in the helper mask workspace to the data workspace.
-*/
+ * Apply mask stored in the helper mask workspace to the data workspace.
+ */
 void InstrumentActor::applyMaskWorkspace() {
   auto wsName = getWorkspace()->getName();
   if (m_maskWorkspace) {
@@ -304,8 +319,8 @@ void InstrumentActor::applyMaskWorkspace() {
 }
 
 /**
-* Removes the mask workspace.
-*/
+ * Removes the mask workspace.
+ */
 void InstrumentActor::clearMasks() {
   bool needColorRecalc = false;
   if (m_maskWorkspace) {
@@ -323,97 +338,79 @@ void InstrumentActor::clearMasks() {
   }
 }
 
-Instrument_const_sptr InstrumentActor::getInstrument() const {
-  Instrument_const_sptr retval;
-
-  // Look to see if we have set the property in the properties file
-  // to define our 'default' view
-  std::string view = Mantid::Kernel::ConfigService::Instance().getString(
-      "instrument.view.geometry");
+std::vector<size_t> InstrumentActor::getMonitors() const { return m_monitors; }
 
+Instrument_const_sptr InstrumentActor::getInstrument() const {
   auto sharedWorkspace = getWorkspace();
   Mantid::Kernel::ReadLock _lock(*sharedWorkspace);
 
-  if (boost::iequals("Default", view) || boost::iequals("Physical", view)) {
+  if (isPhysicalView()) {
     // First see if there is a 'physical' instrument available. Use it if there
     // is.
-    retval = sharedWorkspace->getInstrument()->getPhysicalInstrument();
-  } else if (boost::iequals("Neutronic", view)) {
-    retval = sharedWorkspace->getInstrument();
+    auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument();
+    if (instr)
+      return instr;
   }
 
-  if (!retval) {
-    // Otherwise get hold of the 'main' instrument and use that
-    retval = sharedWorkspace->getInstrument();
-  }
-
-  return retval;
+  return sharedWorkspace->getInstrument();
 }
 
 const MantidColorMap &InstrumentActor::getColorMap() const {
-  return m_colorMap;
-}
-
-/// Get a detector reference given a pick ID.
-const Mantid::Geometry::IDetector &
-InstrumentActor::getDetectorByPickID(size_t pickID) const {
-  return getDetectorByDetID(m_detIDs.at(pickID));
+  return m_renderer->getColorMap();
 }
 
-/// Get a reference to a detector by a detector ID.
-const Mantid::Geometry::IDetector &
-InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const {
-  const auto &detectorInfo = getWorkspace()->detectorInfo();
-  auto detectorIndex = detectorInfo.indexOf(detID);
-  return detectorInfo.detector(detectorIndex);
+size_t InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const {
+  const auto &detInfo = detectorInfo();
+  return detInfo.indexOf(detID);
 }
 
 Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const {
-  if (pickID < m_detIDs.size()) {
-    return m_detIDs[pickID];
+  const auto &detInfo = detectorInfo();
+  if (pickID < detInfo.size()) {
+    return detInfo.detectorIDs()[pickID];
   }
   return -1;
 }
 
+QList<Mantid::detid_t>
+InstrumentActor::getDetIDs(const std::vector<size_t> &dets) const {
+  QList<Mantid::detid_t> detIDs;
+  detIDs.reserve(static_cast<int>(dets.size()));
+  for (auto det : dets)
+    detIDs.append(getDetID(det));
+  return detIDs;
+}
+
 /**
-* Get a component id of a picked component.
-*/
+ * Get a component id of a picked component.
+ */
 Mantid::Geometry::ComponentID
 InstrumentActor::getComponentID(size_t pickID) const {
-  size_t ndet = m_detIDs.size();
   auto compID = Mantid::Geometry::ComponentID();
-  if (pickID < ndet) {
-    auto &det = getDetectorByPickID(m_detIDs[pickID]);
-    compID = det.getComponentID();
-  } else if (pickID < ndet + m_nonDetIDs.size()) {
-    compID = m_nonDetIDs[pickID - ndet];
-  }
+  const auto &compInfo = componentInfo();
+  if (pickID < compInfo.size())
+    compID = compInfo.componentID(pickID)->getComponentID();
   return compID;
 }
 
 /** Retrieve the workspace index corresponding to a particular detector
-*  @param id The detector id
-*  @returns  The workspace index containing data for this detector
-*  @throws Exception::NotFoundError If the detector is not represented in the
-* workspace
-*/
-size_t InstrumentActor::getWorkspaceIndex(Mantid::detid_t id) const {
-  auto mapEntry = m_detid2index_map.find(id);
-  if (mapEntry == m_detid2index_map.end()) {
-    throw Kernel::Exception::NotFoundError("Detector ID not in workspace", id);
-  }
-
-  return mapEntry->second;
+ *  @param index The detector index
+ *  @returns  The workspace index containing data for this detector
+ *  @throws Exception::NotFoundError If the detector is not represented in the
+ * workspace
+ */
+size_t InstrumentActor::getWorkspaceIndex(size_t index) const {
+  return m_detIndex2WsIndex[index];
 }
 
 /**
-* Set an interval in the data workspace x-vector's units in which the data are
-* to be
-* integrated to calculate the detector colours.
-*
-* @param xmin :: The lower bound.
-* @param xmax :: The upper bound.
-*/
+ * Set an interval in the data workspace x-vector's units in which the data are
+ * to be
+ * integrated to calculate the detector colours.
+ *
+ * @param xmin :: The lower bound.
+ * @param xmax :: The upper bound.
+ */
 void InstrumentActor::setIntegrationRange(const double &xmin,
                                           const double &xmax) {
   setDataIntegrationRange(xmin, xmax);
@@ -421,34 +418,32 @@ void InstrumentActor::setIntegrationRange(const double &xmin,
 }
 
 /** Gives the total signal in the spectrum relating to the given detector
-*  @param id The detector id
-*  @return The signal, or -1 if the detector is not represented in the workspace
-*/
-double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const {
-  try {
-    size_t i = getWorkspaceIndex(id);
-    return m_specIntegrs.at(i);
-  } catch (NotFoundError &) {
-    // If the detector is not represented in the workspace
+ *  @param index The detector index
+ *  @return The signal
+ */
+double InstrumentActor::getIntegratedCounts(size_t index) const {
+  auto i = getWorkspaceIndex(index);
+  if (i == INVALID_INDEX)
     return -1.0;
-  }
+  return m_specIntegrs.at(i);
 }
 
 /**
-* Sum counts in detectors for purposes of rough plotting against the units on
-* the x-axis.
-* Checks (approximately) if the workspace is ragged or not and uses the
-* appropriate summation
-* method.
-*
-* @param dets :: A list of detector IDs to sum.
-* @param x :: (output) Time of flight values (or whatever values the x axis has)
-* to plot against.
-* @param y :: (output) The sums of the counts for each bin.
-* @param size :: (optional input) Size of the output vectors. If not given it
-* will be determined automatically.
-*/
-void InstrumentActor::sumDetectors(QList<int> &dets, std::vector<double> &x,
+ * Sum counts in detectors for purposes of rough plotting against the units on
+ * the x-axis.
+ * Checks (approximately) if the workspace is ragged or not and uses the
+ * appropriate summation
+ * method.
+ *
+ * @param dets :: A list of detector Indices to sum.
+ * @param x :: (output) Time of flight values (or whatever values the x axis
+ * has) to plot against.
+ * @param y :: (output) The sums of the counts for each bin.
+ * @param size :: (optional input) Size of the output vectors. If not given it
+ * will be determined automatically.
+ */
+void InstrumentActor::sumDetectors(const std::vector<size_t> &dets,
+                                   std::vector<double> &x,
                                    std::vector<double> &y, size_t size) const {
   Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
   if (size > ws->blocksize() || size == 0) {
@@ -465,30 +460,25 @@ void InstrumentActor::sumDetectors(QList<int> &dets, std::vector<double> &x,
 }
 
 /**
-* Sum counts in detectors for purposes of rough plotting against the units on
-* the x-axis.
-* Assumes that all spectra share the x vector.
-*
-* @param dets :: A list of detector IDs to sum.
-* @param x :: (output) Time of flight values (or whatever values the x axis has)
-* to plot against.
-* @param y :: (output) The sums of the counts for each bin.
-*/
-void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
+ * Sum counts in detectors for purposes of rough plotting against the units on
+ * the x-axis.
+ * Assumes that all spectra share the x vector.
+ *
+ * @param dets :: A list of detector Indices to sum.
+ * @param x :: (output) Time of flight values (or whatever values the x axis
+ * has) to plot against.
+ * @param y :: (output) The sums of the counts for each bin.
+ */
+void InstrumentActor::sumDetectorsUniform(const std::vector<size_t> &dets,
                                           std::vector<double> &x,
                                           std::vector<double> &y) const {
 
-  size_t wi;
-  bool isDataEmpty = dets.isEmpty();
+  bool isDataEmpty = dets.empty();
 
-  if (!isDataEmpty) {
-    try {
-      wi = getWorkspaceIndex(dets[0]);
-    } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      isDataEmpty =
-          true; // Detector doesn't have a workspace index relating to it
-    }
-  }
+  auto wi = getWorkspaceIndex(dets[0]);
+
+  if (wi == INVALID_INDEX)
+    isDataEmpty = true;
 
   if (isDataEmpty) {
     x.clear();
@@ -498,6 +488,7 @@ void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
 
   // find the bins inside the integration range
   size_t imin, imax;
+
   getBinMinMaxIndex(wi, imin, imax);
 
   Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
@@ -505,34 +496,32 @@ void InstrumentActor::sumDetectorsUniform(QList<int> &dets,
   x.assign(XPoints.begin() + imin, XPoints.begin() + imax);
   y.resize(x.size(), 0);
   // sum the spectra
-  foreach (int id, dets) {
-    try {
-      size_t index = getWorkspaceIndex(id);
-      const auto &Y = ws->y(index);
-      std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
-                     std::plus<double>());
-    } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      continue; // Detector doesn't have a workspace index relating to it
-    }
+  for (auto det : dets) {
+    auto index = getWorkspaceIndex(det);
+    if (index == INVALID_INDEX)
+      continue;
+    const auto &Y = ws->y(index);
+    std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
+                   std::plus<double>());
   }
 }
 
 /**
-* Sum counts in detectors for purposes of rough plotting against the units on
-* the x-axis.
-* Assumes that all spectra have different x vectors.
-*
-* @param dets :: A list of detector IDs to sum.
-* @param x :: (output) Time of flight values (or whatever values the x axis has)
-* to plot against.
-* @param y :: (output) The sums of the counts for each bin.
-* @param size :: (input) Size of the output vectors.
-*/
-void InstrumentActor::sumDetectorsRagged(QList<int> &dets,
+ * Sum counts in detectors for purposes of rough plotting against the units on
+ * the x-axis.
+ * Assumes that all spectra have different x vectors.
+ *
+ * @param dets :: A list of detector IDs to sum.
+ * @param x :: (output) Time of flight values (or whatever values the x axis
+ * has) to plot against.
+ * @param y :: (output) The sums of the counts for each bin.
+ * @param size :: (input) Size of the output vectors.
+ */
+void InstrumentActor::sumDetectorsRagged(const std::vector<size_t> &dets,
                                          std::vector<double> &x,
                                          std::vector<double> &y,
                                          size_t size) const {
-  if (dets.isEmpty() || size == 0) {
+  if (dets.empty() || size == 0) {
     x.clear();
     y.clear();
     return;
@@ -549,20 +538,18 @@ void InstrumentActor::sumDetectorsRagged(QList<int> &dets,
 
   size_t nSpec = 0; // number of actual spectra to add
   // fill in the temp workspace with the data from the detectors
-  foreach (int id, dets) {
-    try {
-      size_t index = getWorkspaceIndex(id);
-      dws->setHistogram(nSpec, ws->histogram(index));
-      double xmin = dws->x(nSpec).front();
-      double xmax = dws->x(nSpec).back();
-      if (xmin < xStart)
-        xStart = xmin;
-      if (xmax > xEnd)
-        xEnd = xmax;
-      ++nSpec;
-    } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      continue; // Detector doesn't have a workspace index relating to it
-    }
+  for (auto det : dets) {
+    auto index = getWorkspaceIndex(det);
+    if (index == INVALID_INDEX)
+      continue;
+    dws->setHistogram(nSpec, ws->histogram(index));
+    double xmin = dws->x(nSpec).front();
+    double xmax = dws->x(nSpec).back();
+    if (xmin < xStart)
+      xStart = xmin;
+    if (xmax > xEnd)
+      xEnd = xmax;
+    ++nSpec;
   }
 
   if (nSpec == 0) {
@@ -615,50 +602,12 @@ void InstrumentActor::sumDetectorsRagged(QList<int> &dets,
 }
 
 /**
-* Recalculate the detector colors based on the integrated values in
-* m_specIntegrs and
-* the masking information in ....
-*/
+ * Recalculate the detector colors based on the integrated values in
+ * m_specIntegrs and
+ * the masking information in ....
+ */
 void InstrumentActor::resetColors() {
-  QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue);
-  m_colors.resize(m_specIntegrs.size());
-
-  auto sharedWorkspace = getWorkspace();
-  const auto &spectrumInfo = sharedWorkspace->spectrumInfo();
-
-  IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists();
-
-  for (int iwi = 0; iwi < int(m_specIntegrs.size()); iwi++) {
-    size_t wi = size_t(iwi);
-    double integratedValue = m_specIntegrs[wi];
-    try {
-      // Find if the detector is masked
-      const auto &dets = sharedWorkspace->getSpectrum(wi).getDetectorIDs();
-      bool masked = false;
-
-      if (mask) {
-        masked = mask->isMasked(dets);
-      } else {
-        masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi);
-      }
-
-      if (masked) {
-        m_colors[wi] = m_maskedColor;
-      } else {
-        QRgb color = m_colorMap.rgb(qwtInterval, integratedValue);
-        m_colors[wi] = GLColor(qRed(color), qGreen(color), qBlue(color));
-      }
-    } catch (NotFoundError &) {
-      m_colors[wi] = m_failedColor;
-      continue;
-    }
-  }
-  if (m_scene.getNumberOfActors() > 0) {
-    if (auto actor = dynamic_cast<CompAssemblyActor *>(m_scene.getActor(0))) {
-      actor->setColors();
-      invalidateDisplayLists();
-    }
-  }
+  m_renderer->reset();
   emit colorMapChanged();
 }
 
@@ -668,114 +617,61 @@ void InstrumentActor::updateColors() {
 }
 
 /**
-* @param on :: True or false for on or off.
-*/
+ * @param on :: True or false for on or off.
+ */
 void InstrumentActor::showGuides(bool on) {
-  auto visitor = SetVisibleNonDetectorVisitor(on);
-  this->accept(visitor);
   m_showGuides = on;
+  resetColors();
 }
 
-GLColor InstrumentActor::getColor(Mantid::detid_t id) const {
-  try {
-    size_t i = getWorkspaceIndex(id);
-    return m_colors.at(i);
-  } catch (NotFoundError &) {
-    // Return the first color if the detector is not represented in the
-    // workspace
-    return m_colors.front();
-  }
+GLColor InstrumentActor::getColor(size_t index) const {
+  return m_renderer->getColor(index);
 }
 
-void InstrumentActor::draw(bool picking) const { m_scene.draw(picking); }
+void InstrumentActor::draw(bool picking) const {
+  m_renderer->renderInstrument(m_isCompVisible, m_showGuides, picking);
+}
 
 /**
-* @param fname :: A color map file name.
-* @param reset_colors :: An option to reset the detector colors.
-*/
+ * @param fname :: A color map file name.
+ * @param reset_colors :: An option to reset the detector colors.
+ */
 void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) {
-  m_colorMap.loadMap(fname);
+  m_renderer->loadColorMap(fname);
   m_currentColorMapFilename = fname;
-  if (reset_colors) {
+  if (reset_colors)
     resetColors();
-  }
-}
-
-//------------------------------------------------------------------------------
-/** Add a detector ID to the pick list (m_detIDs)
-* The order of detids define the pickIDs for detectors.
-*
-* @param id :: detector ID to add.
-* @return pick ID of the added detector
-*/
-size_t InstrumentActor::pushBackDetid(Mantid::detid_t id) const {
-  m_detIDs.push_back(id);
-  return m_detIDs.size() - 1;
 }
 
 //------------------------------------------------------------------------------
-/** Add a non-detector component ID to the pick list (m_nonDetIDs)
-*
-* @param actor :: ObjComponentActor for the component added.
-* @param compID :: component ID to add.
-*/
-void InstrumentActor::pushBackNonDetid(
-    ObjComponentActor *actor, Mantid::Geometry::ComponentID compID) const {
-  m_nonDetActorsTemp.push_back(actor);
-  m_nonDetIDs.push_back(compID);
-}
-
-//------------------------------------------------------------------------------
-/**
-* Set pick colors to non-detectors strored by calls to pushBackNonDetid().
-*/
-void InstrumentActor::setupPickColors() {
-  assert(m_nonDetActorsTemp.size() == m_nonDetIDs.size());
-  auto nDets = m_detIDs.size();
-  for (size_t i = 0; i < m_nonDetActorsTemp.size(); ++i) {
-    m_nonDetActorsTemp[i]->setPickColor(makePickColor(nDets + i));
+/** Get the detector position
+ *
+ * @param pickID :: pick Index maching the getDetector() calls;
+ * @return the real-space position of the detector
+ */
+const Mantid::Kernel::V3D InstrumentActor::getDetPos(size_t pickID) const {
+  const auto &detInfo = detectorInfo();
+  if (pickID < detInfo.size()) {
+    return detInfo.position(pickID);
   }
-  m_nonDetActorsTemp.clear();
+  return m_defaultPos;
 }
 
-//------------------------------------------------------------------------------
-/** If needed, cache the detector positions for all detectors.
-* Call this BEFORE getDetPos().
-* Does nothing if the positions have already been cached.
-*/
-void InstrumentActor::cacheDetPos() const {
-  if (m_detPos.size() != m_detIDs.size()) {
-    m_detPos.clear();
-    for (size_t pickID = 0; pickID < m_detIDs.size(); pickID++) {
-      auto &det = this->getDetectorByPickID(pickID);
-      m_detPos.push_back(det.getPos());
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-/** Get the cached detector position
-*
-* @param pickID :: pick Index maching the getDetector() calls;
-* @return the real-space position of the detector
-*/
-const Mantid::Kernel::V3D &InstrumentActor::getDetPos(size_t pickID) const {
-  if (pickID < m_detPos.size()) {
-    return m_detPos.at(pickID);
-  }
-  return m_defaultPos;
+const std::vector<Mantid::detid_t> &InstrumentActor::getAllDetIDs() const {
+  const auto &detInfo = detectorInfo();
+  return detInfo.detectorIDs();
 }
 
 /**
-* @param type :: 0 - linear, 1 - log10.
-*/
+ * @param type :: 0 - linear, 1 - log10.
+ */
 void InstrumentActor::changeScaleType(int type) {
-  m_colorMap.changeScaleType(static_cast<GraphOptions::ScaleType>(type));
+  m_renderer->changeScaleType(type);
   resetColors();
 }
 
 void InstrumentActor::changeNthPower(double nth_power) {
-  m_colorMap.setNthPower(nth_power);
+  m_renderer->changeNthPower(nth_power);
   resetColors();
 }
 
@@ -795,7 +691,7 @@ void InstrumentActor::saveSettings() {
   QSettings settings;
   settings.beginGroup("Mantid/InstrumentWidget");
   settings.setValue("ColormapFile", m_currentColorMapFilename);
-  settings.setValue("ScaleType", (int)m_colorMap.getScaleType());
+  settings.setValue("ScaleType", (int)m_renderer->getColorMap().getScaleType());
   settings.setValue("ShowGuides", m_showGuides);
   settings.endGroup();
 }
@@ -830,28 +726,31 @@ bool InstrumentActor::wholeRange() const {
          m_BinMaxValue == m_WkspBinMaxValue;
 }
 
+size_t InstrumentActor::ndetectors() const {
+  return m_detIndex2WsIndex.size() - m_components.size();
+}
+
 /**
-* Set autoscaling of the y axis. If autoscaling is on the minValue() and
-* maxValue()
-* return the actual min and max values in the data. If autoscaling is off
-*  minValue() and maxValue() are fixed and do not change after changing the x
-* integration range.
-* @param on :: On or Off.
-*/
+ * Set autoscaling of the y axis. If autoscaling is on the minValue() and
+ * maxValue()
+ * return the actual min and max values in the data. If autoscaling is off
+ *  minValue() and maxValue() are fixed and do not change after changing the x
+ * integration range.
+ * @param on :: On or Off.
+ */
 void InstrumentActor::setAutoscaling(bool on) {
   m_autoscaling = on;
   if (on) {
     m_DataMinScaleValue = m_DataMinValue;
     m_DataMaxScaleValue = m_DataMaxValue;
-    // setIntegrationRange(m_DataMinValue,m_DataMaxValue);
     resetColors();
   }
 }
 
 /**
-* Extracts the current applied mask to the main workspace
-* @returns the current applied mask to the main workspace
-*/
+ * Extracts the current applied mask to the main workspace
+ * @returns the current applied mask to the main workspace
+ */
 Mantid::API::MatrixWorkspace_sptr InstrumentActor::extractCurrentMask() const {
   const std::string maskName = "__InstrumentActor_MaskWorkspace";
   Mantid::API::IAlgorithm *alg =
@@ -869,8 +768,8 @@ Mantid::API::MatrixWorkspace_sptr InstrumentActor::extractCurrentMask() const {
 }
 
 /**
-* Initialize the helper mask workspace with the mask from the data workspace.
-*/
+ * Initialize the helper mask workspace with the mask from the data workspace.
+ */
 void InstrumentActor::initMaskHelper() const {
   if (m_maskWorkspace)
     return;
@@ -885,30 +784,30 @@ void InstrumentActor::initMaskHelper() const {
 }
 
 /**
-* Checks if the actor has a mask workspace attached.
-*/
+ * Checks if the actor has a mask workspace attached.
+ */
 bool InstrumentActor::hasMaskWorkspace() const {
   return m_maskWorkspace != nullptr;
 }
 
 /**
-* Find a rotation from one orthonormal basis set (Xfrom,Yfrom,Zfrom) to
-* another orthonormal basis set (Xto,Yto,Zto). Both sets must be right-handed
-* (or same-handed, I didn't check). The method doesn't check the sets for
-* orthogonality
-* or normality. The result is a rotation quaternion such that:
-*   R.rotate(Xfrom) == Xto
-*   R.rotate(Yfrom) == Yto
-*   R.rotate(Zfrom) == Zto
-* @param Xfrom :: The X axis of the original basis set
-* @param Yfrom :: The Y axis of the original basis set
-* @param Zfrom :: The Z axis of the original basis set
-* @param Xto :: The X axis of the final basis set
-* @param Yto :: The Y axis of the final basis set
-* @param Zto :: The Z axis of the final basis set
-* @param R :: The output rotation as a quaternion
-* @param out :: Debug printout flag
-*/
+ * Find a rotation from one orthonormal basis set (Xfrom,Yfrom,Zfrom) to
+ * another orthonormal basis set (Xto,Yto,Zto). Both sets must be right-handed
+ * (or same-handed, I didn't check). The method doesn't check the sets for
+ * orthogonality
+ * or normality. The result is a rotation quaternion such that:
+ *   R.rotate(Xfrom) == Xto
+ *   R.rotate(Yfrom) == Yto
+ *   R.rotate(Zfrom) == Zto
+ * @param Xfrom :: The X axis of the original basis set
+ * @param Yfrom :: The Y axis of the original basis set
+ * @param Zfrom :: The Z axis of the original basis set
+ * @param Xto :: The X axis of the final basis set
+ * @param Yto :: The Y axis of the final basis set
+ * @param Zto :: The Z axis of the final basis set
+ * @param R :: The output rotation as a quaternion
+ * @param out :: Debug printout flag
+ */
 void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D &Xfrom,
                                     const Mantid::Kernel::V3D &Yfrom,
                                     const Mantid::Kernel::V3D &Zfrom,
@@ -994,15 +893,15 @@ void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D &Xfrom,
 }
 
 /**
-* Calculate a rotation to look in a particular direction.
-*
-* @param eye :: A direction to look in
-* @param up :: A vector showing the 'up' direction after the rotation. It
-* doesn't have to be normal to eye
-*   just non-collinear. If up is collinear to eye the actual 'up' direction is
-* undefined.
-* @param R :: The result rotation.
-*/
+ * Calculate a rotation to look in a particular direction.
+ *
+ * @param eye :: A direction to look in
+ * @param up :: A vector showing the 'up' direction after the rotation. It
+ * doesn't have to be normal to eye
+ *   just non-collinear. If up is collinear to eye the actual 'up' direction is
+ * undefined.
+ * @param R :: The result rotation.
+ */
 void InstrumentActor::rotateToLookAt(const Mantid::Kernel::V3D &eye,
                                      const Mantid::Kernel::V3D &up,
                                      Mantid::Kernel::Quat &R) {
@@ -1039,11 +938,11 @@ void InstrumentActor::rotateToLookAt(const Mantid::Kernel::V3D &eye,
 }
 
 /**
-* Find the offsets in the spectrum's x vector of the bounds of integration.
-* @param wi :: The works[ace index of the spectrum.
-* @param imin :: Index of the lower bound: x_min == x(wi)[imin]
-* @param imax :: Index of the upper bound: x_max == x(wi)[imax]
-*/
+ * Find the offsets in the spectrum's x vector of the bounds of integration.
+ * @param wi :: The works[ace index of the spectrum.
+ * @param imin :: Index of the lower bound: x_min == x(wi)[imin]
+ * @param imax :: Index of the upper bound: x_max == x(wi)[imax]
+ */
 void InstrumentActor::getBinMinMaxIndex(size_t wi, size_t &imin,
                                         size_t &imax) const {
   Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
@@ -1078,8 +977,8 @@ void InstrumentActor::getBinMinMaxIndex(size_t wi, size_t &imin,
 }
 
 /**
-* Set the minimum and the maximum data values on the color map scale.
-*/
+ * Set the minimum and the maximum data values on the color map scale.
+ */
 void InstrumentActor::setDataMinMaxRange(double vmin, double vmax) {
   if (vmin < m_DataMinValue) {
     vmin = m_DataMinValue;
@@ -1105,15 +1004,14 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
 
   auto workspace = getWorkspace();
   calculateIntegratedSpectra(*workspace);
+  std::set<size_t> monitorIndices;
 
-  // get the workspace indices of monitors in order to exclude them from finding
-  // of the max value
-  auto monitorIDs = getInstrument()->getMonitors();
-  // clang-format off
-      // because it indents this line half way across the page (?)
-			auto monitorIndices = workspace->getIndicesFromDetectorIDs(monitorIDs);
-  // clang-format on
-
+  for (auto monitor : m_monitors) {
+    auto index = getWorkspaceIndex(monitor);
+    if (index == INVALID_INDEX)
+      continue;
+    monitorIndices.emplace(index);
+  }
   // check that there is at least 1 non-monitor spectrum
   if (monitorIndices.size() == m_specIntegrs.size()) {
     // there are only monitors - cannot skip them
@@ -1129,31 +1027,31 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
     m_DataMinValue = DBL_MAX;
     m_DataMaxValue = -DBL_MAX;
 
-    // Now we need to convert to a vector where each entry is the sum for the
-    // detector ID at that spot (in integrated_values).
+    if (std::any_of(m_specIntegrs.begin(), m_specIntegrs.end(),
+                    [](double val) { return !std::isfinite(val); }))
+      throw std::runtime_error(
+          "The workspace contains values that cannot be displayed (infinite "
+          "or NaN).\n"
+          "Please run ReplaceSpecialValues algorithm for correction.");
+
+    const auto &spectrumInfo = workspace->spectrumInfo();
+
+    // Ignore monitors if multiple detectors aren't grouped.
     for (size_t i = 0; i < m_specIntegrs.size(); i++) {
-      // skip the monitors
-      if (std::find(monitorIndices.begin(), monitorIndices.end(), i) !=
-          monitorIndices.end()) {
+      const auto &spectrumDefinition = spectrumInfo.spectrumDefinition(i);
+      if (spectrumDefinition.size() == 1 &&
+          std::find(monitorIndices.begin(), monitorIndices.end(), i) !=
+              monitorIndices.end())
         continue;
-      }
-      double sum = m_specIntegrs[i];
-      if (!std::isfinite(sum)) {
-        throw std::runtime_error(
-            "The workspace contains values that cannot be displayed (infinite "
-            "or NaN).\n"
-            "Please run ReplaceSpecialValues algorithm for correction.");
-      }
-      // integrated_values[i] = sum;
-      if (sum < m_DataMinValue) {
+
+      auto sum = m_specIntegrs[i];
+
+      if (sum < m_DataMinValue)
         m_DataMinValue = sum;
-      }
-      if (sum > m_DataMaxValue) {
+      if (sum > m_DataMaxValue)
         m_DataMaxValue = sum;
-      }
-      if (sum > 0 && sum < m_DataPositiveMinValue) {
+      if (sum > 0 && sum < m_DataPositiveMinValue)
         m_DataPositiveMinValue = sum;
-      }
     }
   }
 
@@ -1164,14 +1062,17 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin,
 }
 
 /// Add a range of bins for masking
-void InstrumentActor::addMaskBinsData(const QList<int> &detIDs) {
-  QList<int> indices;
-  foreach (int id, detIDs) {
-    auto index = m_detid2index_map[id];
-    indices.append(static_cast<int>(index));
+void InstrumentActor::addMaskBinsData(const std::vector<size_t> &indices) {
+  std::vector<size_t> wsIndices;
+  wsIndices.reserve(indices.size());
+  for (auto det : indices) {
+    auto index = getWorkspaceIndex(det);
+    if (index == INVALID_INDEX)
+      continue;
+    wsIndices.emplace_back(index);
   }
-  if (!indices.isEmpty()) {
-    m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, indices);
+  if (!indices.empty()) {
+    m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices);
     auto workspace = getWorkspace();
     calculateIntegratedSpectra(*workspace);
     resetColors();
@@ -1181,95 +1082,79 @@ void InstrumentActor::addMaskBinsData(const QList<int> &detIDs) {
 /// Show if bin masks have been defined.
 bool InstrumentActor::hasBinMask() const { return !m_maskBinsData.isEmpty(); }
 
-//-------------------------------------------------------------------------//
-bool SetVisibleComponentVisitor::visit(GLActor *actor) {
-  actor->setVisibility(false);
-  return false;
-}
-
-bool SetVisibleComponentVisitor::visit(GLActorCollection *actor) {
-  bool visible = actor->hasChildVisible();
-  actor->setVisibility(visible);
-  return visible;
-}
-
-bool SetVisibleComponentVisitor::visit(ComponentActor *actor) {
-  bool on = actor->getComponent()->getComponentID() == m_id;
-  actor->setVisibility(on);
-  return on;
-}
-
-bool SetVisibleComponentVisitor::visit(CompAssemblyActor *actor) {
-  bool visible = false;
-  if (actor->getComponent()->getComponentID() == m_id) {
-    visible = true;
-    actor->setChildVisibility(true);
-  } else {
-    visible = actor->hasChildVisible();
-    actor->setVisibility(visible);
+QString InstrumentActor::getParameterInfo(size_t index) const {
+  auto instr = getInstrument();
+  const auto &compInfo = componentInfo();
+
+  auto compID = compInfo.componentID(index);
+  auto comp = instr->getComponentByID(compID);
+
+  QString text = "";
+  std::map<Mantid::Geometry::ComponentID, std::vector<std::string>>
+      mapCmptToNameVector;
+
+  auto paramNames = comp->getParameterNamesByComponent();
+  for (auto itParamName = paramNames.begin(); itParamName != paramNames.end();
+       ++itParamName) {
+    // build the data structure I need Map comp id -> vector of names
+    std::string paramName = itParamName->first;
+    Mantid::Geometry::ComponentID paramCompId = itParamName->second;
+    // attempt to insert this will fail silently if the key already exists
+    if (mapCmptToNameVector.find(paramCompId) == mapCmptToNameVector.end()) {
+      mapCmptToNameVector.emplace(paramCompId, std::vector<std::string>());
+    }
+    // get the vector out and add the name
+    mapCmptToNameVector[paramCompId].emplace_back(paramName);
   }
-  return visible;
-}
-
-bool SetVisibleComponentVisitor::visit(ObjCompAssemblyActor *actor) {
-  bool on = actor->getComponent()->getComponentID() == m_id;
-  actor->setVisibility(on);
-  return on;
-}
 
-bool SetVisibleComponentVisitor::visit(InstrumentActor *actor) {
-  bool visible = false;
-  if (actor->getInstrument()->getComponentID() == m_id) {
-    visible = true;
-    actor->setChildVisibility(true);
-  } else {
-    visible = actor->hasChildVisible();
-    actor->setVisibility(visible);
+  // walk out from the selected component
+  const Mantid::Geometry::IComponent *paramComp = comp.get();
+  boost::shared_ptr<const Mantid::Geometry::IComponent> parentComp;
+  while (paramComp) {
+    auto id = paramComp->getComponentID();
+    auto &compParamNames = mapCmptToNameVector[id];
+    if (compParamNames.size() > 0) {
+      text += QString::fromStdString("\nParameters from: " +
+                                     paramComp->getName() + "\n");
+      std::sort(compParamNames.begin(), compParamNames.end(),
+                Mantid::Kernel::CaseInsensitiveStringComparator());
+      for (auto itParamName = compParamNames.begin();
+           itParamName != compParamNames.end(); ++itParamName) {
+        std::string paramName = *itParamName;
+        // no need to search recursively as we are asking from the matching
+        // component
+        std::string paramValue =
+            paramComp->getParameterAsString(paramName, false);
+        if (paramValue != "") {
+          text += QString::fromStdString(paramName + ": " + paramValue + "\n");
+        }
+      }
+    }
+    parentComp = paramComp->getParent();
+    paramComp = parentComp.get();
   }
-  return visible;
-}
 
-bool SetVisibleComponentVisitor::visit(RectangularDetectorActor *actor) {
-  bool on = actor->getComponent()->getComponentID() == m_id ||
-            actor->isChildDetector(m_id);
-  actor->setVisibility(on);
-  return on;
+  return text;
 }
 
-bool SetVisibleComponentVisitor::visit(StructuredDetectorActor *actor) {
-  bool on = actor->getComponent()->getComponentID() == m_id ||
-            actor->isChildDetector(m_id);
-  actor->setVisibility(on);
-  return on;
+std::string InstrumentActor::getDefaultAxis() const {
+  return getInstrument()->getDefaultAxis();
 }
 
-//-------------------------------------------------------------------------//
-/**
-* Visits an actor and if it is a "non-detector" sets its visibility.
-*
-* @param actor :: A visited actor.
-* @return always false to traverse all the instrument tree.
-*/
-bool SetVisibleNonDetectorVisitor::visit(GLActor *actor) {
-  ComponentActor *comp = dynamic_cast<ComponentActor *>(actor);
-  if (comp && comp->isNonDetector()) {
-    actor->setVisibility(m_on);
-  }
-  return false;
+std::string InstrumentActor::getDefaultView() const {
+  return getInstrument()->getDefaultView();
 }
 
-//-------------------------------------------------------------------------//
-bool FindComponentVisitor::visit(GLActor *actor) {
-  ComponentActor *comp = dynamic_cast<ComponentActor *>(actor);
-  if (comp) {
-    if (comp->getComponent()->getComponentID() == m_id) {
-      m_actor = comp;
-      return true;
-    }
-  }
-  return false;
+std::string InstrumentActor::getInstrumentName() const {
+  const auto &compInfo = componentInfo();
+  return compInfo.name(compInfo.root());
 }
 
+std::vector<std::string>
+InstrumentActor::getStringParameter(const std::string &name,
+                                    bool recursive) const {
+  return getInstrument()->getStringParameter(name, recursive);
+}
 /**
  * Save the state of the instrument actor to a project file.
  * @return string representing the current state of the instrumet actor.
@@ -1304,5 +1189,26 @@ void InstrumentActor::loadFromProject(const std::string &lines) {
   }
 }
 
-} // MantidWidgets
-} // MantidQt
+/** If instrument.geometry.view is set to Default or Physical, then the physical
+ * instrument componentInfo is returned. Othewise this returns the neutronic
+ * version.
+ */
+const Mantid::Geometry::ComponentInfo &InstrumentActor::componentInfo() const {
+  if (m_isPhysicalInstrument)
+    return *m_physicalComponentInfo;
+  else
+    return getWorkspace()->componentInfo();
+}
+
+/** If instrument.geometry.view is set to Default or Physical, then the physical
+* instrument detectorInfo is returned. Othewise this returns the neutronic
+* version.
+*/
+const Mantid::Geometry::DetectorInfo &InstrumentActor::detectorInfo() const {
+  if (m_isPhysicalInstrument)
+    return *m_physicalDetectorInfo;
+  else
+    return getWorkspace()->detectorInfo();
+}
+} // namespace MantidWidgets
+} // namespace MantidQt
diff --git a/qt/widgets/instrumentview/src/InstrumentRenderer.cpp b/qt/widgets/instrumentview/src/InstrumentRenderer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..72aa10f1f53c8ada5feb77ccea0c5a2daff148a2
--- /dev/null
+++ b/qt/widgets/instrumentview/src/InstrumentRenderer.cpp
@@ -0,0 +1,442 @@
+#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h"
+#include "MantidAPI/IMaskWorkspace.h"
+#include "MantidBeamline/ComponentType.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidGeometry/Objects/IObject.h"
+#include "MantidGeometry/Rendering/GeometryHandler.h"
+#include "MantidGeometry/Rendering/ShapeInfo.h"
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/Quat.h"
+#include "MantidQtWidgets/InstrumentView/BankRenderingHelpers.h"
+#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
+#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
+
+using namespace MantidQt::MantidWidgets;
+
+namespace MantidQt {
+namespace MantidWidgets {
+
+namespace {
+size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) {
+  unsigned int index = r;
+  index *= 256;
+  index += g;
+  index *= 256;
+  index += b - 1;
+  return index;
+}
+
+void updateVisited(std::vector<bool> &visited,
+                   const std::vector<size_t> &components) {
+  for (auto component : components)
+    visited[component] = true;
+}
+} // namespace
+
+InstrumentRenderer::InstrumentRenderer(const InstrumentActor &actor)
+    : m_actor(actor) {
+
+  m_displayListId[0] = 0;
+  m_displayListId[1] = 0;
+  m_useDisplayList[0] = false;
+  m_useDisplayList[1] = false;
+
+  const auto &componentInfo = actor.componentInfo();
+  size_t numTextures = 0;
+  for (size_t i = componentInfo.root(); !componentInfo.isDetector(i); --i) {
+    auto type = componentInfo.componentType(i);
+    if (type == Mantid::Beamline::ComponentType::Rectangular ||
+        type == Mantid::Beamline::ComponentType::OutlineComposite) {
+      m_textureIndices.push_back(i);
+      m_reverseTextureIndexMap[i] = numTextures;
+      numTextures++;
+    }
+  }
+
+  if (numTextures > 0) {
+    m_textureIDs.resize(numTextures, 0);
+    colorTextures.resize(numTextures);
+    pickTextures.resize(numTextures);
+  }
+}
+
+InstrumentRenderer::~InstrumentRenderer() {
+  for (size_t i = 0; i < 2; ++i) {
+    if (m_displayListId[i] != 0) {
+      glDeleteLists(m_displayListId[i], 1);
+    }
+  }
+}
+
+void InstrumentRenderer::renderInstrument(const std::vector<bool> &visibleComps,
+                                          bool showGuides, bool picking) {
+  if (std::none_of(visibleComps.cbegin(), visibleComps.cend(),
+                   [](bool visible) { return visible; }))
+    return;
+
+  OpenGLError::check("InstrumentActor::draw()");
+  size_t i = picking ? 1 : 0;
+  if (m_useDisplayList[i]) {
+    glCallList(m_displayListId[i]);
+  } else {
+    m_displayListId[i] = glGenLists(1);
+    m_useDisplayList[i] = true;
+    glNewList(m_displayListId[i],
+              GL_COMPILE); // Construct display list for object representation
+    draw(visibleComps, showGuides, picking);
+    glEndList();
+    if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception
+      throw Mantid::Kernel::Exception::OpenGLError(
+          "OpenGL: Out of video memory");
+    glCallList(m_displayListId[i]);
+  }
+  OpenGLError::check("InstrumentActor::draw()");
+}
+
+void InstrumentRenderer::draw(const std::vector<bool> &visibleComps,
+                              bool showGuides, bool picking) {
+  const auto &compInfo = m_actor.componentInfo();
+  std::vector<bool> visited(compInfo.size(), false);
+
+  for (size_t i = compInfo.root(); i != std::numeric_limits<size_t>::max();
+       --i) {
+    auto type = compInfo.componentType(i);
+    if (type == Mantid::Beamline::ComponentType::Infinite)
+      continue;
+
+    if (type == Mantid::Beamline::ComponentType::Rectangular) {
+      updateVisited(visited, compInfo.componentsInSubtree(i));
+      if (visibleComps[i])
+        drawRectangularBank(i, picking);
+      continue;
+    }
+
+    if (type == Mantid::Beamline::ComponentType::OutlineComposite) {
+      updateVisited(visited, compInfo.componentsInSubtree(i));
+      if (visibleComps[i])
+        drawTube(i, picking);
+      continue;
+    }
+
+    if (type == Mantid::Beamline::ComponentType::Structured) {
+      updateVisited(visited, compInfo.componentsInSubtree(i));
+      if (visibleComps[i])
+        drawStructuredBank(i, picking);
+      continue;
+    }
+
+    if (!compInfo.isDetector(i) && !showGuides) {
+      visited[i] = true;
+      continue;
+    }
+
+    if (compInfo.hasValidShape(i) && visibleComps[i] && !visited[i]) {
+      visited[i] = true;
+      drawSingleDetector(i, picking);
+    }
+  }
+}
+
+void InstrumentRenderer::drawRectangularBank(size_t bankIndex, bool picking) {
+  const auto &compInfo = m_actor.componentInfo();
+  glPushMatrix();
+
+  auto bank = compInfo.quadrilateralComponent(bankIndex);
+  auto pos = compInfo.position(bank.bottomLeft);
+  auto scale = compInfo.scaleFactor(bankIndex);
+  glTranslated(pos.X(), pos.Y(), pos.Z());
+  glScaled(scale[0], scale[1], scale[2]);
+
+  auto rot = compInfo.rotation(bankIndex);
+  if (!(rot.isNull())) {
+    double deg, ax0, ax1, ax2;
+    rot.getAngleAxis(deg, ax0, ax1, ax2);
+    glRotated(deg, ax0, ax1, ax2);
+  }
+
+  auto ti = m_reverseTextureIndexMap[bankIndex];
+  glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]);
+  uploadRectangularTexture(picking ? pickTextures[ti] : colorTextures[ti],
+                           bankIndex);
+
+  BankRenderingHelpers::renderRectangularBank(compInfo, bankIndex);
+
+  glBindTexture(GL_TEXTURE_2D, 0);
+  glPopMatrix();
+}
+
+void InstrumentRenderer::drawStructuredBank(size_t bankIndex, bool picking) {
+  const auto &compInfo = m_actor.componentInfo();
+  glPushMatrix();
+
+  auto bank = compInfo.quadrilateralComponent(bankIndex);
+  const auto &shapeInfo =
+      compInfo.shape(bank.bottomLeft).getGeometryHandler()->shapeInfo();
+  auto pos = shapeInfo.points()[0];
+  pos.setZ(compInfo.position(bank.bottomLeft).Z());
+  auto scale = compInfo.scaleFactor(bankIndex);
+  glTranslated(pos.X(), pos.Y(), pos.Z());
+  glScaled(scale[0], scale[1], scale[2]);
+
+  BankRenderingHelpers::renderStructuredBank(compInfo, bankIndex,
+                                             picking ? m_pickColors : m_colors);
+
+  glPopMatrix();
+}
+
+void InstrumentRenderer::drawTube(size_t bankIndex, bool picking) {
+  const auto &compInfo = m_actor.componentInfo();
+  glPushMatrix();
+
+  auto pos = compInfo.position(bankIndex);
+  auto rot = compInfo.rotation(bankIndex);
+  auto scale = compInfo.scaleFactor(bankIndex);
+  glTranslated(pos.X(), pos.Y(), pos.Z());
+  glScaled(scale[0], scale[1], scale[2]);
+  double deg, ax0, ax1, ax2;
+  rot.getAngleAxis(deg, ax0, ax1, ax2);
+  glRotated(deg, ax0, ax1, ax2);
+
+  auto ti = m_reverseTextureIndexMap[bankIndex];
+  glColor3f(1.0f, 1.0f, 1.0f);
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]);
+  uploadTubeTexture(picking ? pickTextures[ti] : colorTextures[ti], bankIndex);
+
+  compInfo.shape(bankIndex).draw();
+
+  glBindTexture(GL_TEXTURE_2D, 0);
+  glPopMatrix();
+}
+
+void InstrumentRenderer::drawSingleDetector(size_t detIndex, bool picking) {
+  const auto &compInfo = m_actor.componentInfo();
+  if (picking)
+    m_pickColors[detIndex].paint();
+  else
+    m_colors[detIndex].paint();
+  glPushMatrix();
+  // Translate
+  auto pos = compInfo.position(detIndex);
+  if (!pos.nullVector())
+    glTranslated(pos[0], pos[1], pos[2]);
+
+  // Rotate
+  auto rot = compInfo.rotation(detIndex);
+  if (!rot.isNull()) {
+    double deg, ax0, ax1, ax2;
+    rot.getAngleAxis(deg, ax0, ax1, ax2);
+    glRotated(deg, ax0, ax1, ax2);
+  }
+
+  // Scale
+  auto scale = compInfo.scaleFactor(detIndex);
+  if (scale != Mantid::Kernel::V3D(1, 1, 1))
+    glScaled(scale[0], scale[1], scale[2]);
+
+  compInfo.shape(detIndex).draw();
+  glPopMatrix();
+}
+
+void InstrumentRenderer::reset() {
+  resetColors();
+  resetPickColors();
+
+  if (m_textureIDs.size() > 0) {
+    const auto &compInfo = m_actor.componentInfo();
+    for (size_t i = 0; i < m_textureIDs.size(); i++) {
+      auto type = compInfo.componentType(m_textureIndices[i]);
+
+      if (type == Mantid::Beamline::ComponentType::Rectangular) {
+        generateRectangularTexture(colorTextures[i], m_colors,
+                                   m_textureIndices[i]);
+        generateRectangularTexture(pickTextures[i], m_pickColors,
+                                   m_textureIndices[i]);
+      } else if (type == Mantid::Beamline::ComponentType::OutlineComposite) {
+        generateTubeTexture(colorTextures[i], m_colors, m_textureIndices[i]);
+        generateTubeTexture(pickTextures[i], m_pickColors, m_textureIndices[i]);
+      }
+    }
+  }
+
+  /// Invalidate the OpenGL display lists to force full re-drawing of the
+  /// instrument and creation of new lists.
+  for (size_t i = 0; i < 2; ++i) {
+    if (m_displayListId[i] != 0) {
+      glDeleteLists(m_displayListId[i], 1);
+      m_displayListId[i] = 0;
+      m_useDisplayList[i] = false;
+    }
+  }
+}
+
+void InstrumentRenderer::resetColors() {
+  QwtDoubleInterval qwtInterval(m_actor.minValue(), m_actor.maxValue());
+  auto sharedWorkspace = m_actor.getWorkspace();
+  const auto &compInfo = m_actor.componentInfo();
+  const auto &detInfo = m_actor.detectorInfo();
+  auto color = m_colorMap.rgb(qwtInterval, 0);
+  m_colors.assign(compInfo.size(),
+                  GLColor(qRed(color), qGreen(color), qBlue(color), 1));
+  auto invalidColor = GLColor(80, 80, 80, 1);
+  auto maskedColor = GLColor(100, 100, 100, 1);
+
+  Mantid::API::IMaskWorkspace_sptr mask = m_actor.getMaskWorkspaceIfExists();
+  const auto &detectorIDs = detInfo.detectorIDs();
+  for (size_t det = 0; det < detInfo.size(); ++det) {
+    auto masked = false;
+
+    if (mask)
+      masked = mask->isMasked(detectorIDs[det]);
+    if (detInfo.isMasked(det) || masked)
+      m_colors[det] = maskedColor;
+    else {
+      auto integratedValue = m_actor.getIntegratedCounts(det);
+      if (integratedValue > -1) {
+        auto color = m_colorMap.rgb(qwtInterval, integratedValue);
+        m_colors[det] = GLColor(
+            qRed(color), qGreen(color), qBlue(color),
+            static_cast<int>(255 * (integratedValue / m_actor.maxValue())));
+      } else
+        m_colors[det] = invalidColor;
+    }
+  }
+
+  for (const auto comp : m_actor.components())
+    m_colors[comp] = maskedColor;
+}
+
+void InstrumentRenderer::resetPickColors() {
+  const auto &compInfo = m_actor.componentInfo();
+  m_pickColors.resize(compInfo.size());
+
+  for (size_t i = 0; i < compInfo.size(); ++i) {
+    m_pickColors[i] = makePickColor(i);
+  }
+}
+
+void InstrumentRenderer::changeScaleType(int type) {
+  m_colorMap.changeScaleType(static_cast<GraphOptions::ScaleType>(type));
+}
+
+void InstrumentRenderer::changeNthPower(double nth_power) {
+  m_colorMap.setNthPower(nth_power);
+}
+
+GLColor InstrumentRenderer::getColor(size_t index) const {
+  if (index <= m_colors.size() - 1)
+    return m_colors.at(index);
+
+  return m_colors.front();
+}
+
+GLColor InstrumentRenderer::makePickColor(size_t pickID) {
+  pickID += 1;
+  unsigned char r, g, b;
+  r = static_cast<unsigned char>(pickID / 65536);
+  g = static_cast<unsigned char>((pickID % 65536) / 256);
+  b = static_cast<unsigned char>((pickID % 65536) % 256);
+  return GLColor(r, g, b);
+}
+
+size_t InstrumentRenderer::decodePickColor(const QRgb &c) {
+  return decodePickColorRGB(static_cast<unsigned char>(qRed(c)),
+                            static_cast<unsigned char>(qGreen(c)),
+                            static_cast<unsigned char>(qBlue(c)));
+}
+
+void InstrumentRenderer::loadColorMap(const QString &fname) {
+  m_colorMap.loadMap(fname);
+}
+
+void InstrumentRenderer::generateRectangularTexture(
+    std::vector<char> &texture, const std::vector<GLColor> &colors,
+    size_t bankIndex) {
+  const auto &compInfo = m_actor.componentInfo();
+  auto bank = compInfo.quadrilateralComponent(bankIndex);
+  // Round size up to nearest power of 2
+  auto res = BankRenderingHelpers::getCorrectedTextureSize(bank.nX, bank.nY);
+  auto texSizeX = res.first;
+  auto texSizeY = res.second;
+
+  // Texture width is 3 times wider due to RGB values
+  texture.resize(texSizeX * texSizeY * 3, 0); // fill with black
+
+  const auto &children = compInfo.children(bankIndex);
+  auto colWidth = children.size() * 3;
+  for (size_t x = 0; x < colWidth; x += 3) {
+    const auto &dets = compInfo.detectorsInSubtree(children[x / 3]);
+    for (size_t y = 0; y < dets.size(); ++y) {
+      auto det = dets[y];
+      auto ti = (y * texSizeX * 3) + x;
+      texture[ti] = static_cast<char>(colors[det].red());
+      texture[ti + 1] = static_cast<char>(colors[det].green());
+      texture[ti + 2] = static_cast<char>(colors[det].blue());
+    }
+  }
+}
+
+void InstrumentRenderer::generateTubeTexture(std::vector<char> &texture,
+                                             const std::vector<GLColor> &colors,
+                                             size_t bankIndex) {
+  const auto &compInfo = m_actor.componentInfo();
+  const auto &children = compInfo.children(bankIndex);
+  texture.resize(children.size() * 3);
+
+  for (size_t i = 0; i < children.size(); ++i) {
+    auto col = colors[children[i]];
+    auto pos = i * 3;
+    texture[pos] = static_cast<unsigned char>(col.red());
+    texture[pos + 1] = static_cast<unsigned char>(col.green());
+    texture[pos + 2] = static_cast<unsigned char>(col.blue());
+  }
+}
+
+void InstrumentRenderer::uploadRectangularTexture(
+    const std::vector<char> &texture, size_t textureIndex) const {
+  auto bank = m_actor.componentInfo().quadrilateralComponent(textureIndex);
+  auto res = BankRenderingHelpers::getCorrectedTextureSize(bank.nX, bank.nY);
+  auto xsize = res.first;
+  auto ysize = res.second;
+
+  auto ti = m_reverseTextureIndexMap[textureIndex];
+  if (m_textureIDs[ti] != 0)
+    glDeleteTextures(1, &m_textureIDs[ti]);
+
+  glGenTextures(1, &m_textureIDs[ti]);
+  glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]);
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+  // Allow lighting effects
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast<GLsizei>(xsize),
+               static_cast<GLsizei>(ysize), 0, GL_RGB, GL_UNSIGNED_BYTE,
+               texture.data());
+}
+
+void InstrumentRenderer::uploadTubeTexture(const std::vector<char> &texture,
+                                           size_t textureIndex) const {
+  auto ti = m_reverseTextureIndexMap[textureIndex];
+  if (m_textureIDs[ti] > 0)
+    glDeleteTextures(1, &m_textureIDs[ti]);
+
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+  glGenTextures(1, &m_textureIDs[ti]);
+  glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]);
+
+  glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, static_cast<GLsizei>(texture.size() / 3),
+               0, GL_RGB, GL_UNSIGNED_BYTE, texture.data());
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+}
+
+} // namespace MantidWidgets
+} // namespace MantidQt
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp
index 73c8037b4b1ee8b27b55bee3d545a3977bbb9bc2..e9be7feccfb9a08f365cb1c0c26c7bb28c28605c 100644
--- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp
@@ -5,6 +5,7 @@
 #endif
 #include "MantidKernel/Exception.h"
 #include "MantidGeometry/ICompAssembly.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
@@ -14,13 +15,17 @@ using Mantid::Geometry::IObjComponent;
 
 namespace MantidQt {
 namespace MantidWidgets {
-
 /**
-* Constructor for tree model to display instrument tree
-*/
+ * Constructor for tree model to display instrument tree
+ */
 InstrumentTreeModel::InstrumentTreeModel(const InstrumentWidget *instrWidget,
                                          QObject *parent)
-    : QAbstractItemModel(parent), m_instrWidget(instrWidget) {}
+    : QAbstractItemModel(parent), m_instrWidget(instrWidget) {
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  m_componentIndices.resize(componentInfo.size());
+  std::iota(m_componentIndices.begin(), m_componentIndices.end(), 0);
+}
 
 /**
 * Destructor for instrument display tree
@@ -34,22 +39,16 @@ InstrumentTreeModel::~InstrumentTreeModel() {}
 *  Returns 0 for the ObjComponent = I'm an end point.
 */
 int InstrumentTreeModel::columnCount(const QModelIndex &parent) const {
-  try {
-    if (parent.isValid()) {
-      auto instr = m_instrWidget->getInstrumentActor().getInstrument();
-      boost::shared_ptr<const IComponent> comp = instr->getComponentByID(
-          static_cast<Mantid::Geometry::ComponentID>(parent.internalPointer()));
-      boost::shared_ptr<const ICompAssembly> objcomp =
-          boost::dynamic_pointer_cast<const ICompAssembly>(comp);
-      if (objcomp)
-        return 1;
-      return 0;
-    } else
-      return 1;
-  } catch (...) {
-    // std::cout<<"Exception :: columnCount"<<'\n';
-    return 0;
-  }
+  if (!parent.isValid())
+    return 1;
+
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  auto index = extractIndex(parent);
+  if (componentInfo.children(index).size() > 0)
+    return 1;
+
+  return 0;
 }
 
 /**
@@ -57,25 +56,17 @@ int InstrumentTreeModel::columnCount(const QModelIndex &parent) const {
 * string will be instrument name
 */
 QVariant InstrumentTreeModel::data(const QModelIndex &index, int role) const {
-  try {
-    if (role != Qt::DisplayRole)
-      return QVariant();
-
-    auto instr = m_instrWidget->getInstrumentActor().getInstrument();
-
-    if (!index.isValid()) // not valid has to return the root node
-      return QString(instr->getName().c_str());
-
-    boost::shared_ptr<const IComponent> ins = instr->getComponentByID(
-        static_cast<Mantid::Geometry::ComponentID>(index.internalPointer()));
-    if (ins) {
-      return QString(ins->getName().c_str());
-    }
-    return QString("Error");
-  } catch (...) {
-    // std::cout<<" Exception: in data"<<'\n';
-    return 0;
-  }
+  if (role != Qt::DisplayRole)
+    return QVariant();
+
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+
+  if (!index.isValid()) // not valid has to return the root node
+    return QString::fromStdString(componentInfo.name(componentInfo.root()));
+
+  auto compIndex = extractIndex(index);
+  return QString::fromStdString(componentInfo.name(compIndex));
 }
 
 /**
@@ -104,79 +95,52 @@ QVariant InstrumentTreeModel::headerData(int section,
 */
 QModelIndex InstrumentTreeModel::index(int row, int column,
                                        const QModelIndex &parent) const {
-  //	std::cout<<"Index +++++++++ row"<<row<<" column "<<column<<" is valid
-  //"<<parent.isValid()<<'\n';
-  try {
-    boost::shared_ptr<const ICompAssembly> parentItem;
-    auto instr = m_instrWidget->getInstrumentActor().getInstrument();
-    if (!parent.isValid()) // invalid parent, has to be the root node i.e
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  if (!parent.isValid()) { // invalid parent, has to be the root node i.e
                            // instrument
-      return createIndex(row, column, instr->getComponentID());
-
-    boost::shared_ptr<const IComponent> comp = instr->getComponentByID(
-        static_cast<Mantid::Geometry::ComponentID>(parent.internalPointer()));
-    parentItem = boost::dynamic_pointer_cast<const ICompAssembly>(comp);
-    if (!parentItem) {
-      boost::shared_ptr<const IObjComponent> objcomp =
-          boost::dynamic_pointer_cast<const IObjComponent>(comp);
-      if (objcomp)
-        return QModelIndex();
-      // Not an instrument so check for Component Assembly
-      parentItem = boost::dynamic_pointer_cast<const ICompAssembly>(instr);
-    }
-    // If component assembly pick the Component at the row index. if row index
-    // is higher than number
-    // of components in assembly return empty model index
-    if (parentItem->nelements() < row) {
-      return QModelIndex();
-    } else {
-      return createIndex(row, column,
-                         (void *)((*parentItem)[row]->getComponentID()));
-    }
-  } catch (...) {
-    std::cout << "InstrumentTreeModel::index(" << row << "," << column
-              << ") threw an exception.\n";
+    return createIndex(row, column, &m_componentIndices[componentInfo.root()]);
   }
-  return QModelIndex();
+  auto index = extractIndex(parent);
+  const auto &children = componentInfo.children(index);
+
+  if (index == componentInfo.source() || index == componentInfo.sample() ||
+      static_cast<int>(children.size()) <= row)
+    return QModelIndex();
+
+  return createIndex(row, column, &m_componentIndices[children[row]]);
 }
 
 /**
 * Returns the parent model index.
 */
 QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const {
-  //	std::cout<<"parent +++++++++ row"<<index.row()<<" column
-  //"<<index.column()<<" is valid "<<index.isValid()<<'\n';
-  try {
-    if (!index.isValid()) // the index corresponds to root so there is no parent
-                          // for root return empty.
-      return QModelIndex();
-
-    auto instr = m_instrWidget->getInstrumentActor().getInstrument();
-
-    if (instr->getComponentID() ==
-        static_cast<Mantid::Geometry::ComponentID>(index.internalPointer()))
-      return QModelIndex();
-
-    boost::shared_ptr<const IComponent> child = instr->getComponentByID(
-        static_cast<Mantid::Geometry::ComponentID>(index.internalPointer()));
-    if (child->getParent()->getComponentID() == instr->getComponentID())
-      return createIndex(0, 0, instr->getComponentID());
-    boost::shared_ptr<const IComponent> parent =
-        instr->getComponentByID(child->getParent()->getComponentID());
-    boost::shared_ptr<const IComponent> greatParent =
-        instr->getComponentByID(parent->getParent()->getComponentID());
-    boost::shared_ptr<const ICompAssembly> greatParentAssembly =
-        boost::dynamic_pointer_cast<const ICompAssembly>(greatParent);
-    int iindex = 0;
-    for (int i = 0; i < greatParentAssembly->nelements(); i++)
-      if ((*greatParentAssembly)[i]->getComponentID() ==
-          parent->getComponentID())
-        iindex = i;
-    return createIndex(iindex, 0, (void *)parent->getComponentID());
-  } catch (...) {
-    //		std::cout<<"Exception: in parent"<<'\n';
+  if (!index.isValid()) // the index corresponds to root so there is no parent
+                        // for root return empty.
+    return QModelIndex();
+
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  auto compIndex = extractIndex(index);
+
+  if (compIndex == componentInfo.root())
+    return QModelIndex();
+
+  auto parent = componentInfo.parent(compIndex);
+  if (parent == componentInfo.root())
+    return createIndex(0, 0, &m_componentIndices[componentInfo.root()]);
+
+  auto grandParent = componentInfo.parent(parent);
+  const auto &grandParentElems = componentInfo.children(grandParent);
+
+  int row = 0;
+  for (auto child : grandParentElems) {
+    if (child == parent)
+      break;
+    row++;
   }
-  return QModelIndex();
+
+  return createIndex(row, 0, &m_componentIndices[parent]);
 }
 
 /**
@@ -184,37 +148,22 @@ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const {
 * ObjComponent row count will be 0.
 */
 int InstrumentTreeModel::rowCount(const QModelIndex &parent) const {
-  //	std::cout<<"rowCount +++++++++ row"<<parent.row()<<" column
-  //"<<parent.column()<<" is valid "<<parent.isValid()<<'\n';
-
-  try {
-    if (!parent.isValid()) // Root node row count is one.
-    {
-      return 1; // boost::dynamic_pointer_cast<ICompAssembly>(m_instrument)->nelements();
-    } else {
-      auto instr = m_instrWidget->getInstrumentActor().getInstrument();
-      if (instr->getComponentID() == static_cast<Mantid::Geometry::ComponentID>(
-                                         parent.internalPointer())) {
-        return instr->nelements();
-      }
-      boost::shared_ptr<const IComponent> comp =
-          instr->getComponentByID(static_cast<Mantid::Geometry::ComponentID>(
-              parent
-                  .internalPointer())); // static_cast<IComponent*>(parent.internalPointer());
-      boost::shared_ptr<const ICompAssembly> assembly =
-          boost::dynamic_pointer_cast<const ICompAssembly>(comp);
-      if (assembly) {
-        return assembly->nelements();
-      }
-      boost::shared_ptr<const IObjComponent> objcomp =
-          boost::dynamic_pointer_cast<const IObjComponent>(comp);
-      if (objcomp)
-        return 0;
-    }
-  } catch (...) {
-    // std::cout<<"Exception: in rowCount"<<'\n';
-  }
+  if (!parent.isValid()) // Root node row count is one.
+    return 1;
+
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  auto index = extractIndex(parent);
+  const auto &children = componentInfo.children(index);
+  if (children.size() > 0)
+    return static_cast<int>(children.size());
+
   return 0;
 }
+
+size_t InstrumentTreeModel::extractIndex(const QModelIndex &index) {
+  auto indexPtr = static_cast<size_t *>(index.internalPointer());
+  return *indexPtr;
+}
 } // MantidWidgets
 } // MantidQt
diff --git a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp
index 7c544f93935c4a9da0b21bf04f370f004a54adb4..b1413de658ea0ab178dbf1ddd2320a1bfaf9b26d 100644
--- a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp
@@ -6,9 +6,9 @@
 #include "MantidKernel/Exception.h"
 #include "MantidGeometry/ICompAssembly.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Sample.h"
-#include "MantidQtWidgets/InstrumentView/GLActor.h"
 #include <queue>
 #include <QMessageBox>
 #include <QString>
@@ -35,73 +35,17 @@ void InstrumentTreeWidget::getSelectedBoundingBox(const QModelIndex &index,
                                                   double &xmax, double &ymax,
                                                   double &zmax, double &xmin,
                                                   double &ymin, double &zmin) {
-  Mantid::Geometry::Instrument_const_sptr instrument =
-      m_instrWidget->getInstrumentActor().getInstrument();
-  // Check whether its instrument
-  boost::shared_ptr<const Mantid::Geometry::IComponent> selectedComponent;
-  if (instrument->getComponentID() ==
-      static_cast<Mantid::Geometry::ComponentID>(index.internalPointer()))
-    selectedComponent =
-        boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-            instrument);
-  else
-    selectedComponent = instrument->getComponentByID(
-        static_cast<Mantid::Geometry::ComponentID>(index.internalPointer()));
+  const auto &componentInfo =
+      m_instrWidget->getInstrumentActor().componentInfo();
+  auto compIndex = InstrumentTreeModel::extractIndex(index);
+  auto bb = componentInfo.boundingBox(compIndex);
 
-  // get the bounding box for the component
-  xmax = ymax = zmax = -DBL_MAX;
-  xmin = ymin = zmin = DBL_MAX;
-  Mantid::Geometry::BoundingBox boundBox;
-  std::queue<boost::shared_ptr<const Mantid::Geometry::IComponent>> CompList;
-  CompList.push(selectedComponent);
-  while (!CompList.empty()) {
-    boost::shared_ptr<const Mantid::Geometry::IComponent> tmp =
-        CompList.front();
-    CompList.pop();
-    boost::shared_ptr<const Mantid::Geometry::IObjComponent> tmpObj =
-        boost::dynamic_pointer_cast<const Mantid::Geometry::IObjComponent>(tmp);
-    if (tmpObj) {
-      try {
-        // std::cerr << int(tmpObj->getComponentID()) << ' ' <<
-        // int(instrument->getSample()->getComponentID()) << '\n';
-        if (tmpObj->getComponentID() ==
-            instrument->getSample()->getComponentID()) {
-          boundBox = m_instrWidget->getInstrumentActor()
-                         .getWorkspace()
-                         ->sample()
-                         .getShape()
-                         .getBoundingBox();
-          boundBox.moveBy(tmpObj->getPos());
-        } else {
-          tmpObj->getBoundingBox(boundBox);
-        }
-        double txmax(boundBox.xMax()), tymax(boundBox.yMax()),
-            tzmax(boundBox.zMax()), txmin(boundBox.xMin()),
-            tymin(boundBox.yMin()), tzmin(boundBox.zMin());
-        if (txmax > xmax)
-          xmax = txmax;
-        if (tymax > ymax)
-          ymax = tymax;
-        if (tzmax > zmax)
-          zmax = tzmax;
-        if (txmin < xmin)
-          xmin = txmin;
-        if (tymin < ymin)
-          ymin = tymin;
-        if (tzmin < zmin)
-          zmin = tzmin;
-      } catch (Mantid::Kernel::Exception::NullPointerException &) {
-      }
-    } else if (boost::dynamic_pointer_cast<
-                   const Mantid::Geometry::ICompAssembly>(tmp)) {
-      boost::shared_ptr<const Mantid::Geometry::ICompAssembly> tmpAssem =
-          boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-              tmp);
-      for (int idx = 0; idx < tmpAssem->nelements(); idx++) {
-        CompList.push((*tmpAssem)[idx]);
-      }
-    }
-  }
+  xmax = bb.xMax();
+  ymax = bb.yMax();
+  zmax = bb.zMax();
+  xmin = bb.xMin();
+  ymin = bb.yMin();
+  zmin = bb.zMin();
 }
 
 QModelIndex
@@ -121,11 +65,9 @@ InstrumentTreeWidget::findComponentByName(const QString &name) const {
 
 void InstrumentTreeWidget::sendComponentSelectedSignal(
     const QModelIndex index) {
-  Mantid::Geometry::ComponentID id =
-      static_cast<Mantid::Geometry::ComponentID>(index.internalPointer());
-  auto visitor = SetVisibleComponentVisitor(id);
-  m_instrWidget->getInstrumentActor().accept(visitor);
-  emit componentSelected(id);
+  auto selectedIndex = InstrumentTreeModel::extractIndex(index);
+  m_instrWidget->getInstrumentActor().setComponentVisible(selectedIndex);
+  emit componentSelected(selectedIndex);
 }
 
 /** Get a list of components that have been expanded
diff --git a/qt/widgets/instrumentview/src/InstrumentWidget.cpp b/qt/widgets/instrumentview/src/InstrumentWidget.cpp
index a7f95ce00e731a280b2fc77054eeca320ca5ef9e..0031049fc8c3eec53b898d25ea286aa5fdfd3d84 100644
--- a/qt/widgets/instrumentview/src/InstrumentWidget.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentWidget.cpp
@@ -7,6 +7,8 @@
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
 
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/IMaskWorkspace.h"
@@ -259,8 +261,8 @@ void InstrumentWidget::init(bool resetGeometry, bool autoscaling,
   if (resetGeometry || !surface) {
     if (setDefaultView) {
       // set the view type to the instrument's default view
-      QString defaultView = QString::fromStdString(
-          m_instrumentActor->getInstrument()->getDefaultView());
+      QString defaultView =
+          QString::fromStdString(m_instrumentActor->getDefaultView());
       if (defaultView == "3D" &&
           Mantid::Kernel::ConfigService::Instance().getString(
               "MantidOptions.InstrumentView.UseOpenGL") != "On") {
@@ -400,13 +402,11 @@ void InstrumentWidget::setSurfaceType(int type) {
     // If anything throws during surface creation, store error message here
     QString errorMessage;
     try {
-      Mantid::Geometry::Instrument_const_sptr instr =
-          m_instrumentActor->getInstrument();
-      Mantid::Geometry::IComponent_const_sptr sample = instr->getSample();
-      if (!sample) {
+      const auto &componentInfo = m_instrumentActor->componentInfo();
+      if (!componentInfo.hasSample()) {
         throw InstrumentHasNoSampleError();
       }
-      Mantid::Kernel::V3D sample_pos = sample->getPos();
+      auto sample_pos = componentInfo.samplePosition();
       auto axis = getSurfaceAxis(surfaceType);
 
       // create the surface
@@ -824,11 +824,10 @@ void InstrumentWidget::setBinRange(double xmin, double xmax) {
 * is visible the rest of the instrument is hidden.
 * @param id :: The component id.
 */
-void InstrumentWidget::componentSelected(ComponentID id) {
+void InstrumentWidget::componentSelected(size_t componentIndex) {
   auto surface = getSurface();
   if (surface) {
-    surface->componentSelected(id);
-    // surface->updateView();
+    surface->componentSelected(componentIndex);
     updateInstrumentView();
   }
 }
@@ -1215,8 +1214,7 @@ QString InstrumentWidget::getSettingsGroupName() const {
 */
 QString InstrumentWidget::getInstrumentSettingsGroupName() const {
   return QString::fromAscii(InstrumentWidgetSettingsGroup) + "/" +
-         QString::fromStdString(
-             getInstrumentActor().getInstrument()->getName());
+         QString::fromStdString(getInstrumentActor().getInstrumentName());
 }
 
 bool InstrumentWidget::hasWorkspace(const std::string &wsName) const {
@@ -1232,29 +1230,22 @@ void InstrumentWidget::handleWorkspaceReplacement(
       // the same name)
       auto matrixWS =
           boost::dynamic_pointer_cast<const MatrixWorkspace>(workspace);
-      if (!matrixWS) {
+      if (!matrixWS || matrixWS->detectorInfo().size() == 0) {
         emit preDeletingHandle();
         close();
         return;
       }
-      bool sameWS = false;
-      try {
-        sameWS = (matrixWS == m_instrumentActor->getWorkspace());
-      } catch (std::runtime_error &) {
-        // Carry on, sameWS should stay false
-      }
-
       // try to detect if the instrument changes (unlikely if the workspace
       // hasn't, but theoretically possible)
-      bool resetGeometry = matrixWS->getInstrument()->getNumberDetectors() !=
-                           m_instrumentActor->ndetectors();
-
-      // if workspace and instrument don't change keep the scaling
-      if (sameWS && !resetGeometry) {
-        m_instrumentActor->updateColors();
-        setupColorMap();
-        updateInstrumentView();
-      } else {
+      bool resetGeometry =
+          matrixWS->detectorInfo().size() != m_instrumentActor->ndetectors();
+      try {
+        if (matrixWS == m_instrumentActor->getWorkspace() && !resetGeometry) {
+          m_instrumentActor->updateColors();
+          setupColorMap();
+          updateInstrumentView();
+        }
+      } catch (std::runtime_error &) {
         resetInstrument(resetGeometry);
       }
     }
diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp
index 75bc66eb95cd63a41fc923b0555e063fcbcfe1d7..a70b38899dd489ba248ddc06f0511b1522af1859 100644
--- a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp
@@ -729,9 +729,10 @@ void InstrumentWidgetMaskTab::saveMaskToTable() {
 */
 void InstrumentWidgetMaskTab::extractDetsToWorkspace() {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-  QList<int> dets;
+  std::vector<size_t> dets;
   m_instrWidget->getSurface()->getMaskedDetectors(dets);
-  DetXMLFile mapFile(dets);
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  DetXMLFile mapFile(actor.getDetIDs(dets));
   std::string fname = mapFile();
   if (!fname.empty()) {
     std::string workspaceName = m_instrWidget->getWorkspaceName().toStdString();
@@ -751,9 +752,10 @@ void InstrumentWidgetMaskTab::extractDetsToWorkspace() {
 */
 void InstrumentWidgetMaskTab::sumDetsToWorkspace() {
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-  QList<int> dets;
+  std::vector<size_t> dets;
   m_instrWidget->getSurface()->getMaskedDetectors(dets);
-  DetXMLFile mapFile(dets, DetXMLFile::Sum);
+  DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets),
+                     DetXMLFile::Sum);
   std::string fname = mapFile();
 
   if (!fname.empty()) {
@@ -773,9 +775,10 @@ void InstrumentWidgetMaskTab::saveIncludeGroupToFile() {
   QString fname = m_instrWidget->getSaveFileName("Save grouping file",
                                                  "XML files (*.xml);;All (*)");
   if (!fname.isEmpty()) {
-    QList<int> dets;
+    std::vector<size_t> dets;
     m_instrWidget->getSurface()->getMaskedDetectors(dets);
-    DetXMLFile mapFile(dets, DetXMLFile::Sum, fname);
+    DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets),
+                       DetXMLFile::Sum, fname);
   }
 }
 
@@ -783,10 +786,10 @@ void InstrumentWidgetMaskTab::saveExcludeGroupToFile() {
   QString fname = m_instrWidget->getSaveFileName("Save grouping file",
                                                  "XML files (*.xml);;All (*)");
   if (!fname.isEmpty()) {
-    QList<int> dets;
+    std::vector<size_t> dets;
     m_instrWidget->getSurface()->getMaskedDetectors(dets);
-    DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getAllDetIDs(), dets,
-                       fname);
+    const auto &actor = m_instrWidget->getInstrumentActor();
+    DetXMLFile mapFile(actor.getAllDetIDs(), actor.getDetIDs(dets), fname);
   }
 }
 
@@ -1109,11 +1112,12 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
   m_instrWidget->updateInstrumentView(); // to refresh the pick image
   Mantid::API::IMaskWorkspace_sptr wsFresh;
 
-  QList<int> dets;
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  std::vector<size_t> dets;
   // get detectors covered by the shapes
   m_instrWidget->getSurface()->getMaskedDetectors(dets);
-  if (!dets.isEmpty()) {
-    auto wsMask = m_instrWidget->getInstrumentActor().getMaskWorkspace();
+  if (!dets.empty()) {
+    auto wsMask = actor.getMaskWorkspace();
     // have to cast up to the MaskWorkspace to get access to clone()
 
     std::set<Mantid::detid_t> detList;
@@ -1122,21 +1126,22 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
       // but not if the mask is fresh and empty
       if (wsMask->getNumberMasked() > 0) {
         wsFresh = boost::dynamic_pointer_cast<Mantid::API::IMaskWorkspace>(
-            m_instrWidget->getInstrumentActor().extractCurrentMask());
-        m_instrWidget->getInstrumentActor().invertMaskWorkspace();
+            actor.extractCurrentMask());
+        actor.invertMaskWorkspace();
       }
     }
-    foreach (int id, dets) { detList.insert(id); }
+    for (auto det : dets)
+      detList.insert(actor.getDetID(det));
 
     if (!detList.empty()) {
       // try to mask each detector separately and ignore any failure
-      for (auto det = detList.begin(); det != detList.end(); ++det) {
+      for (auto det : detList) {
         try {
           if (isROI && wsFresh) {
-            if (wsMask->isMasked(*det))
-              wsFresh->setMasked(*det);
+            if (wsMask->isMasked(det))
+              wsFresh->setMasked(det);
           } else {
-            wsMask->setMasked(*det);
+            wsMask->setMasked(det);
           }
         } catch (...) {
         }
@@ -1160,7 +1165,7 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) {
 }
 
 void InstrumentWidgetMaskTab::storeBinMask() {
-  QList<int> dets;
+  std::vector<size_t> dets;
   // get detectors covered by the shapes
   m_instrWidget->getSurface()->getMaskedDetectors(dets);
   // mask some bins
diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp
index 496923915c005bed1c06245cdf02d353e0591335..5b38aa26b77d345da00c8383f69718701331eccc 100644
--- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp
@@ -18,6 +18,8 @@
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
 #include "MantidKernel/V3D.h"
 
 #include "qwt_scale_widget.h"
@@ -51,10 +53,20 @@ namespace MantidWidgets {
 
 using namespace boost::math;
 
-/// to be used in std::transform
-struct Sqrt {
-  double operator()(double x) { return sqrt(x); }
-};
+namespace {
+// Get the phi angle between the detector with reference to the origin
+// Makes assumptions about beam direction. Legacy code and not robust.
+double getPhi(const Mantid::Kernel::V3D &pos) {
+  return std::atan2(pos[1], pos[0]);
+}
+
+// Calculate the phi angle between detector and beam, and then offset.
+// Makes assumptions about beam direction. Legacy code and not robust.
+double getPhiOffset(const Mantid::Kernel::V3D &pos, const double offset) {
+  double avgPos = getPhi(pos);
+  return avgPos < 0 ? -(offset + avgPos) : offset - avgPos;
+}
+} // namespace
 
 /**
 * Constructor.
@@ -729,7 +741,7 @@ void InstrumentWidgetPickTab::updatePlotMultipleDetectors() {
     return;
   ProjectionSurface &surface = *getSurface();
   if (surface.hasMasks()) {
-    QList<int> dets;
+    std::vector<size_t> dets;
     surface.getMaskedDetectors(dets);
     m_plotController->setPlotData(dets);
   } else {
@@ -804,7 +816,8 @@ ComponentInfoController::ComponentInfoController(
     QTextEdit *infoDisplay)
     : QObject(tab), m_tab(tab), m_instrWidget(instrWidget),
       m_selectionInfoDisplay(infoDisplay), m_freezePlot(false),
-      m_instrWidgetBlocked(false), m_currentPickID(-1) {}
+      m_instrWidgetBlocked(false),
+      m_currentPickID(std::numeric_limits<size_t>::max()) {}
 
 /**
 * Display info on a component refered to by a pick ID.
@@ -817,10 +830,10 @@ void ComponentInfoController::displayInfo(size_t pickID) {
   }
 
   const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
   QString text = "";
-  int detid = actor.getDetID(pickID);
-  if (detid >= 0) {
-    text += displayDetectorInfo(detid);
+  if (componentInfo.isDetector(pickID)) {
+    text += displayDetectorInfo(pickID);
   } else if (auto componentID = actor.getComponentID(pickID)) {
     text += displayNonDetectorInfo(componentID);
   } else {
@@ -838,57 +851,52 @@ void ComponentInfoController::displayInfo(size_t pickID) {
 
 /**
 * Return string with info on a detector.
-* @param detid :: A detector ID.
+* @param index :: A detector Index.
 */
-QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) {
+QString ComponentInfoController::displayDetectorInfo(size_t index) {
   if (m_instrWidgetBlocked) {
     clear();
     return "";
   }
 
   QString text;
-  if (detid >= 0) {
-    // collect info about selected detector and add it to text
-    const auto &actor = m_instrWidget->getInstrumentActor();
-    auto &det = actor.getDetectorByDetID(detid);
-
-    text = "Selected detector: " + QString::fromStdString(det.getName()) + "\n";
-    text += "Detector ID: " + QString::number(detid) + '\n';
-    QString wsIndex;
-    try {
-      wsIndex = QString::number(actor.getWorkspaceIndex(detid));
-    } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      // Detector doesn't have a workspace index relating to it
-      wsIndex = "None";
-    }
-    text += "Workspace index: " + wsIndex + '\n';
-    Mantid::Kernel::V3D pos = det.getPos();
-    text += "xyz: " + QString::number(pos.X()) + "," +
-            QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n';
-    double r, t, p;
-    pos.getSpherical(r, t, p);
-    text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," +
-            QString::number(p) + '\n';
-    Mantid::Geometry::ICompAssembly_const_sptr parent =
-        boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-            det.getParent());
-    if (parent) {
-      QString textpath;
-      while (parent) {
-        textpath = "/" + QString::fromStdString(parent->getName()) + textpath;
-        parent =
-            boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-                parent->getParent());
-      }
-      text += "Component path:" + textpath + "/" +
-              QString::fromStdString(det.getName()) + '\n';
+
+  // collect info about selected detector and add it to text
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
+  auto detid = actor.getDetID(index);
+
+  text = "Selected detector: " +
+         QString::fromStdString(componentInfo.name(index)) + "\n";
+  text += "Detector ID: " + QString::number(detid) + '\n';
+  QString wsIndex;
+  auto ws = actor.getWorkspaceIndex(index);
+  wsIndex = ws == InstrumentActor::INVALID_INDEX ? "None" : QString::number(ws);
+  text += "Workspace index: " + wsIndex + '\n';
+  Mantid::Kernel::V3D pos = componentInfo.position(index);
+  text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) +
+          "," + QString::number(pos.Z()) + '\n';
+  double r, t, p;
+  pos.getSpherical(r, t, p);
+  text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," +
+          QString::number(p) + '\n';
+  if (componentInfo.hasParent(index)) {
+    QString textpath;
+    auto parent = index;
+    while (componentInfo.hasParent(parent)) {
+      parent = componentInfo.parent(parent);
+      textpath =
+          "/" + QString::fromStdString(componentInfo.name(parent)) + textpath;
     }
-    const double integrated = actor.getIntegratedCounts(detid);
+    text += "Component path:" + textpath + "/" +
+            QString::fromStdString(componentInfo.name(index)) + '\n';
+
+    const double integrated = actor.getIntegratedCounts(index);
     const QString counts =
         integrated == -1.0 ? "N/A" : QString::number(integrated);
     text += "Counts: " + counts + '\n';
     // display info about peak overlays
-    text += getParameterInfo(det);
+    text += actor.getParameterInfo(index);
   }
   return text;
 }
@@ -900,19 +908,19 @@ QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) {
 */
 QString ComponentInfoController::displayNonDetectorInfo(
     Mantid::Geometry::ComponentID compID) {
-  auto component =
-      m_instrWidget->getInstrumentActor().getInstrument()->getComponentByID(
-          compID);
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
+  auto component = componentInfo.indexOf(compID);
   QString text = "Selected component: ";
-  text += QString::fromStdString(component->getName()) + '\n';
-  Mantid::Kernel::V3D pos = component->getPos();
+  text += QString::fromStdString(componentInfo.name(component)) + '\n';
+  Mantid::Kernel::V3D pos = componentInfo.position(component);
   text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) +
           "," + QString::number(pos.Z()) + '\n';
   double r, t, p;
   pos.getSpherical(r, t, p);
   text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," +
           QString::number(p) + '\n';
-  text += getParameterInfo(*component);
+  text += actor.getParameterInfo(component);
   return text;
 }
 
@@ -1040,59 +1048,6 @@ void ComponentInfoController::displayAlignPeaksInfo(
   m_selectionInfoDisplay->setText(QString::fromStdString(text.str()));
 }
 
-/**
-* Form a string for output from the components instrument parameters
-*/
-QString ComponentInfoController::getParameterInfo(
-    const Mantid::Geometry::IComponent &comp) {
-  QString text = "";
-  std::map<Mantid::Geometry::ComponentID, std::vector<std::string>>
-      mapCmptToNameVector;
-
-  auto paramNames = comp.getParameterNamesByComponent();
-  for (auto itParamName = paramNames.begin(); itParamName != paramNames.end();
-       ++itParamName) {
-    // build the data structure I need Map comp id -> vector of names
-    std::string paramName = itParamName->first;
-    Mantid::Geometry::ComponentID paramCompId = itParamName->second;
-    // attempt to insert this will fail silently if the key already exists
-    if (mapCmptToNameVector.find(paramCompId) == mapCmptToNameVector.end()) {
-      mapCmptToNameVector.emplace(paramCompId, std::vector<std::string>());
-    }
-    // get the vector out and add the name
-    mapCmptToNameVector[paramCompId].push_back(paramName);
-  }
-
-  // walk out from the selected component
-  const Mantid::Geometry::IComponent *paramComp = &comp;
-  boost::shared_ptr<const Mantid::Geometry::IComponent> parentComp;
-  while (paramComp) {
-    auto id = paramComp->getComponentID();
-    auto &compParamNames = mapCmptToNameVector[id];
-    if (compParamNames.size() > 0) {
-      text += QString::fromStdString("\nParameters from: " +
-                                     paramComp->getName() + "\n");
-      std::sort(compParamNames.begin(), compParamNames.end(),
-                Mantid::Kernel::CaseInsensitiveStringComparator());
-      for (auto itParamName = compParamNames.begin();
-           itParamName != compParamNames.end(); ++itParamName) {
-        std::string paramName = *itParamName;
-        // no need to search recursively as we are asking from the matching
-        // component
-        std::string paramValue =
-            paramComp->getParameterAsString(paramName, false);
-        if (paramValue != "") {
-          text += QString::fromStdString(paramName + ": " + paramValue + "\n");
-        }
-      }
-    }
-    parentComp = paramComp->getParent();
-    paramComp = parentComp.get();
-  }
-
-  return text;
-}
-
 /**
 * Return non-detector info to be displayed in the selection info display.
 */
@@ -1123,7 +1078,7 @@ DetectorPlotController::DetectorPlotController(InstrumentWidgetPickTab *tab,
                                                OneCurvePlot *plot)
     : QObject(tab), m_tab(tab), m_instrWidget(instrWidget), m_plot(plot),
       m_plotType(Single), m_enabled(true), m_tubeXUnits(DETECTOR_ID),
-      m_currentDetID(-1) {
+      m_currentPickID(std::numeric_limits<size_t>::max()) {
   connect(m_plot, SIGNAL(clickedAt(double, double)), this,
           SLOT(addPeak(double, double)));
 }
@@ -1134,25 +1089,25 @@ DetectorPlotController::DetectorPlotController(InstrumentWidgetPickTab *tab,
 * @param pickID :: A pick ID of an instrument component.
 */
 void DetectorPlotController::setPlotData(size_t pickID) {
-  m_currentDetID = -1;
+  m_currentPickID = std::numeric_limits<size_t>::max();
 
   if (m_plotType == DetectorSum) {
     m_plotType = Single;
   }
 
-  const int detid = m_instrWidget->getInstrumentActor().getDetID(pickID);
-
   if (!m_enabled) {
     m_plot->clearCurve();
     return;
   }
 
-  if (detid >= 0) {
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
+  if (componentInfo.isDetector(pickID)) {
     if (m_plotType == Single) {
-      m_currentDetID = detid;
-      plotSingle(detid);
+      m_currentPickID = pickID;
+      plotSingle(pickID);
     } else if (m_plotType == TubeSum || m_plotType == TubeIntegral) {
-      plotTube(detid);
+      plotTube(pickID);
     } else {
       throw std::logic_error("setPlotData: Unexpected plot type.");
     }
@@ -1163,15 +1118,16 @@ void DetectorPlotController::setPlotData(size_t pickID) {
 
 /**
 * Set curev data from multiple detectors: sum their spectra.
-* @param detIDs :: A list of detector IDs.
+* @param detIndices :: A list of detector Indices.
 */
-void DetectorPlotController::setPlotData(QList<int> detIDs) {
+void DetectorPlotController::setPlotData(
+    const std::vector<size_t> &detIndices) {
   setPlotType(DetectorSum);
   clear();
   std::vector<double> x, y;
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   const auto &actor = m_instrWidget->getInstrumentActor();
-  actor.sumDetectors(detIDs, x, y, static_cast<size_t>(m_plot->width()));
+  actor.sumDetectors(detIndices, x, y, static_cast<size_t>(m_plot->width()));
   QApplication::restoreOverrideCursor();
   if (!x.empty()) {
     m_plot->setData(&x[0], &y[0], static_cast<int>(y.size()),
@@ -1198,23 +1154,20 @@ void DetectorPlotController::clear() {
 
 /**
 * Plot data for a detector.
-* @param detid :: ID of the detector to be plotted.
+* @param detindex :: Index of the detector to be plotted.
 */
-void DetectorPlotController::plotSingle(int detid) {
-
+void DetectorPlotController::plotSingle(size_t detindex) {
   clear();
   std::vector<double> x, y;
-  prepareDataForSinglePlot(detid, x, y);
+  prepareDataForSinglePlot(detindex, x, y);
   if (x.empty() || y.empty())
     return;
 
+  const auto &actor = m_instrWidget->getInstrumentActor();
   // set the data
   m_plot->setData(&x[0], &y[0], static_cast<int>(y.size()),
-                  m_instrWidget->getInstrumentActor()
-                      .getWorkspace()
-                      ->getAxis(0)
-                      ->unit()
-                      ->unitID());
+                  actor.getWorkspace()->getAxis(0)->unit()->unitID());
+  auto detid = actor.getDetID(detindex);
   m_plot->setLabel("Detector " + QString::number(detid));
 
   // find any markers
@@ -1237,50 +1190,53 @@ void DetectorPlotController::plotSingle(int detid) {
 *   LENGTH
 *   PHI
 * The units can be set with setTubeXUnits(...) method.
-* @param detid :: A detector id. The miniplot will display data for a component
+* @param detindex :: A detector index. The miniplot will display data for a
+* component
 * containing the detector
 *   with this id.
 */
-void DetectorPlotController::plotTube(int detid) {
+void DetectorPlotController::plotTube(size_t detindex) {
   const auto &actor = m_instrWidget->getInstrumentActor();
-  auto &det = actor.getDetectorByDetID(detid);
-  boost::shared_ptr<const Mantid::Geometry::IComponent> parent =
-      det.getParent();
-  Mantid::Geometry::ICompAssembly_const_sptr ass =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-          parent);
-  if (parent && ass) {
+  const auto &componentInfo = actor.componentInfo();
+
+  if (!componentInfo.hasParent(detindex)) {
+    m_plot->clearCurve();
+    return;
+  }
+
+  auto parent = componentInfo.parent(detindex);
+  if (componentInfo.detectorsInSubtree(parent).size() > 0) {
     if (m_plotType == TubeSum) // plot sums over detectors vs time bins
     {
-      plotTubeSums(detid);
+      plotTubeSums(detindex);
     } else // plot detector integrals vs detID or a function of detector
            // position in the tube
     {
       assert(m_plotType == TubeIntegral);
-      plotTubeIntegrals(detid);
+      plotTubeIntegrals(detindex);
     }
-  } else {
-    m_plot->clearCurve();
   }
 }
 
 /**
 * Plot the accumulated data in a tube against time of flight.
-* @param detid :: A detector id. The miniplot will display data for a component
+* @param detindex :: A detector id. The miniplot will display data for a
+* component
 * containing the detector
 *   with this id.
 */
-void DetectorPlotController::plotTubeSums(int detid) {
+void DetectorPlotController::plotTubeSums(size_t detindex) {
   std::vector<double> x, y;
-  prepareDataForSumsPlot(detid, x, y);
+  prepareDataForSumsPlot(detindex, x, y);
   if (x.empty() || y.empty()) {
     clear();
     return;
   }
   const auto &actor = m_instrWidget->getInstrumentActor();
-  auto &det = actor.getDetectorByDetID(detid);
-  auto parent = det.getParent();
-  QString label = QString::fromStdString(parent->getName()) + " (" +
+  const auto &componentInfo = actor.componentInfo();
+  auto parent = componentInfo.parent(detindex);
+  auto detid = actor.getDetID(detindex);
+  QString label = QString::fromStdString(componentInfo.name(parent)) + " (" +
                   QString::number(detid) + ") Sum";
   m_plot->setData(&x[0], &y[0], static_cast<int>(y.size()),
                   actor.getWorkspace()->getAxis(0)->unit()->unitID());
@@ -1295,14 +1251,16 @@ void DetectorPlotController::plotTubeSums(int detid) {
 *   LENGTH
 *   PHI
 * The units can be set with setTubeXUnits(...) method.
-* @param detid :: A detector id. The miniplot will display data for a component
+* @param detindex :: A detector index. The miniplot will display data for a
+* component
 * containing the detector
 *   with this id.
 */
-void DetectorPlotController::plotTubeIntegrals(int detid) {
-  auto &det = m_instrWidget->getInstrumentActor().getDetectorByDetID(detid);
+void DetectorPlotController::plotTubeIntegrals(size_t detindex) {
+  const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
   std::vector<double> x, y;
-  prepareDataForIntegralsPlot(detid, x, y);
+  prepareDataForIntegralsPlot(detindex, x, y);
   if (x.empty() || y.empty()) {
     clear();
     return;
@@ -1314,32 +1272,30 @@ void DetectorPlotController::plotTubeIntegrals(int detid) {
   }
   m_plot->setData(&x[0], &y[0], static_cast<int>(y.size()),
                   xAxisCaption.toStdString());
-  auto parent = det.getParent();
+  auto parent = componentInfo.parent(detindex);
   // curve label: "tube_name (detid) Integrals"
   // detid is included to distiguish tubes with the same name
-  QString label = QString::fromStdString(parent->getName()) + " (" +
-                  QString::number(detid) + ") Integrals/" + getTubeXUnitsName();
+  QString label = QString::fromStdString(componentInfo.name(parent)) + " (" +
+                  QString::number(actor.getDetID(detindex)) + ") Integrals/" +
+                  getTubeXUnitsName();
   m_plot->setLabel(label);
 }
 
 /**
 * Prepare data for plotting a spectrum of a single detector.
-* @param detid :: ID of the detector to be plotted.
+* @param detindex :: Index of the detector to be plotted.
 * @param x :: Vector of x coordinates (output)
 * @param y :: Vector of y coordinates (output)
 * @param err :: Optional pointer to a vector of errors (output)
 */
 void DetectorPlotController::prepareDataForSinglePlot(
-    int detid, std::vector<double> &x, std::vector<double> &y,
+    size_t detindex, std::vector<double> &x, std::vector<double> &y,
     std::vector<double> *err) {
   const auto &actor = m_instrWidget->getInstrumentActor();
   Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace();
-  size_t wi;
-  try {
-    wi = actor.getWorkspaceIndex(detid);
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-    return; // Detector doesn't have a workspace index relating to it
-  }
+  auto wi = actor.getWorkspaceIndex(detindex);
+  if (wi == InstrumentActor::INVALID_INDEX)
+    return;
   // get the data
   const auto &XPoints = ws->points(wi);
   const auto &Y = ws->y(wi);
@@ -1358,29 +1314,28 @@ void DetectorPlotController::prepareDataForSinglePlot(
 
 /**
 * Prepare data for plotting accumulated data in a tube against time of flight.
-* @param detid :: A detector id. The miniplot will display data for a component
-* containing the detector
-*   with this id.
+* @param detindex :: A detector index. The miniplot will display data for a
+* component
+* containing the detector with this index.
 * @param x :: Vector of x coordinates (output)
 * @param y :: Vector of y coordinates (output)
 * @param err :: Optional pointer to a vector of errors (output)
 */
-void DetectorPlotController::prepareDataForSumsPlot(int detid,
+void DetectorPlotController::prepareDataForSumsPlot(size_t detindex,
                                                     std::vector<double> &x,
                                                     std::vector<double> &y,
                                                     std::vector<double> *err) {
   const auto &actor = m_instrWidget->getInstrumentActor();
   auto ws = actor.getWorkspace();
-  auto &det = actor.getDetectorByDetID(detid);
-  auto parent = det.getParent();
-  auto ass = boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-      parent);
-  size_t wi;
-  try {
-    wi = actor.getWorkspaceIndex(detid);
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-    return; // Detector doesn't have a workspace index relating to it
-  }
+  const auto &componentInfo = actor.componentInfo();
+  auto parent = componentInfo.parent(detindex);
+  auto ass = componentInfo.detectorsInSubtree(parent);
+
+  auto wi = actor.getWorkspaceIndex(detindex);
+
+  if (wi == InstrumentActor::INVALID_INDEX)
+    return;
+
   size_t imin, imax;
   actor.getBinMinMaxIndex(wi, imin, imax);
 
@@ -1390,33 +1345,29 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid,
   if (err)
     err->resize(x.size(), 0);
 
-  const int n = ass->nelements();
-  for (int i = 0; i < n; ++i) {
-    Mantid::Geometry::IDetector_sptr idet =
-        boost::dynamic_pointer_cast<Mantid::Geometry::IDetector>((*ass)[i]);
-    if (idet) {
-      try {
-        size_t index = actor.getWorkspaceIndex(idet->getID());
-        const auto &Y = ws->y(index);
-        std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
+  for (auto det : ass) {
+    if (componentInfo.isDetector(det)) {
+      auto index = actor.getWorkspaceIndex(det);
+      if (index == InstrumentActor::INVALID_INDEX)
+        continue;
+      const auto &Y = ws->y(index);
+      std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(),
+                     std::plus<double>());
+      if (err) {
+        const auto &E = ws->e(index);
+        std::vector<double> tmp;
+        tmp.assign(E.begin() + imin, E.begin() + imax);
+        std::transform(tmp.begin(), tmp.end(), tmp.begin(), tmp.begin(),
+                       std::multiplies<double>());
+        std::transform(err->begin(), err->end(), tmp.begin(), err->begin(),
                        std::plus<double>());
-        if (err) {
-          const auto &E = ws->e(index);
-          std::vector<double> tmp;
-          tmp.assign(E.begin() + imin, E.begin() + imax);
-          std::transform(tmp.begin(), tmp.end(), tmp.begin(), tmp.begin(),
-                         std::multiplies<double>());
-          std::transform(err->begin(), err->end(), tmp.begin(), err->begin(),
-                         std::plus<double>());
-        }
-      } catch (Mantid::Kernel::Exception::NotFoundError &) {
-        continue; // Detector doesn't have a workspace index relating to it
       }
     }
   }
 
   if (err)
-    std::transform(err->begin(), err->end(), err->begin(), Sqrt());
+    std::transform(err->begin(), err->end(), err->begin(),
+                   [](double val) { return sqrt(val); });
 }
 
 /**
@@ -1430,14 +1381,13 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid,
 *   OUT_OF_PLANE_ANGLE
 * The units can be set with setTubeXUnits(...) method.
 * @param detid :: A detector id. The miniplot will display data for a component
-* containing the detector
-*   with this id.
+* containing the detector with this index.
 * @param x :: Vector of x coordinates (output)
 * @param y :: Vector of y coordinates (output)
 * @param err :: Optional pointer to a vector of errors (output)
 */
 void DetectorPlotController::prepareDataForIntegralsPlot(
-    int detid, std::vector<double> &x, std::vector<double> &y,
+    size_t detindex, std::vector<double> &x, std::vector<double> &y,
     std::vector<double> *err) {
 
 #define PREPAREDATAFORINTEGRALSPLOT_RETURN_FAILED                              \
@@ -1448,32 +1398,26 @@ void DetectorPlotController::prepareDataForIntegralsPlot(
   return;
 
   const auto &actor = m_instrWidget->getInstrumentActor();
+  const auto &componentInfo = actor.componentInfo();
   Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace();
 
   // Does the instrument definition specify that psi should be offset.
-  std::vector<std::string> parameters =
-      ws->getInstrument()->getStringParameter("offset-phi");
+  std::vector<std::string> parameters = actor.getStringParameter("offset-phi");
   const bool bOffsetPsi = (!parameters.empty()) &&
                           std::find(parameters.begin(), parameters.end(),
                                     "Always") != parameters.end();
-
-  auto &det = actor.getDetectorByDetID(detid);
-  auto parent = det.getParent();
-  auto ass = boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-      parent);
-  size_t wi;
-  try {
-    wi = actor.getWorkspaceIndex(detid);
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-    return; // Detector doesn't have a workspace index relating to it
-  }
+  auto parent = componentInfo.parent(detindex);
+  auto ass = componentInfo.detectorsInSubtree(parent);
+  auto wi = actor.getWorkspaceIndex(detindex);
+  if (wi == InstrumentActor::INVALID_INDEX)
+    return;
   // imin and imax give the bin integration range
   size_t imin, imax;
   actor.getBinMinMaxIndex(wi, imin, imax);
 
-  Mantid::Kernel::V3D samplePos = actor.getInstrument()->getSample()->getPos();
+  auto samplePos = actor.componentInfo().samplePosition();
 
-  const int n = ass->nelements();
+  auto n = ass.size();
   if (n == 0) {
     // don't think it's ever possible but...
     throw std::runtime_error("PickTab miniplot: empty instrument assembly");
@@ -1485,56 +1429,52 @@ void DetectorPlotController::prepareDataForIntegralsPlot(
   // collect and sort xy pairs in xymap
   std::map<double, double> xymap, errmap;
   // get the first detector in the tube for lenth calculation
-  Mantid::Geometry::IDetector_sptr idet0 =
-      boost::dynamic_pointer_cast<Mantid::Geometry::IDetector>((*ass)[0]);
-  if (!idet0) {
+  if (!componentInfo.isDetector(ass[0])) {
     // it's not an assembly of detectors,
     // could be a mixture of monitors and other components
     PREPAREDATAFORINTEGRALSPLOT_RETURN_FAILED
   }
-  Mantid::Kernel::V3D normal = (*ass)[1]->getPos() - idet0->getPos();
+
+  auto normal = componentInfo.position(ass[1]) - componentInfo.position(ass[0]);
   normal.normalize();
-  for (int i = 0; i < n; ++i) {
-    Mantid::Geometry::IDetector_sptr idet =
-        boost::dynamic_pointer_cast<Mantid::Geometry::IDetector>((*ass)[i]);
-    if (idet) {
-      try {
-        const int id = idet->getID();
-        // get the x-value for detector idet
-        double xvalue = 0;
-        switch (m_tubeXUnits) {
-        case LENGTH:
-          xvalue = idet->getDistance(*idet0);
-          break;
-        case PHI:
-          xvalue = bOffsetPsi ? idet->getPhiOffset(M_PI) : idet->getPhi();
-          break;
-        case OUT_OF_PLANE_ANGLE: {
-          Mantid::Kernel::V3D pos = idet->getPos();
-          xvalue = getOutOfPlaneAngle(pos, samplePos, normal);
-          break;
-        }
-        default:
-          xvalue = static_cast<double>(id);
-        }
-        size_t index = actor.getWorkspaceIndex(id);
-        // get the y-value for detector idet
-        const auto &Y = ws->y(index);
-        double sum = std::accumulate(Y.begin() + imin, Y.begin() + imax, 0);
-        xymap[xvalue] = sum;
-        if (err) {
-          const auto &E = ws->e(index);
-          std::vector<double> tmp(imax - imin);
-          // take squares of the errors
-          std::transform(E.begin() + imin, E.begin() + imax, E.begin() + imin,
-                         tmp.begin(), std::multiplies<double>());
-          // sum them
-          double sum = std::accumulate(tmp.begin(), tmp.end(), 0);
-          // take sqrt
-          errmap[xvalue] = sqrt(sum);
-        }
-      } catch (Mantid::Kernel::Exception::NotFoundError &) {
-        continue; // Detector doesn't have a workspace index relating to it
+  const auto &detectorInfo = actor.detectorInfo();
+  for (auto det : ass) {
+    if (componentInfo.isDetector(det)) {
+      auto id = detectorInfo.detectorIDs()[det];
+      // get the x-value for detector idet
+      double xvalue = 0;
+      auto pos = detectorInfo.position(det);
+      switch (m_tubeXUnits) {
+      case LENGTH:
+        xvalue = pos.distance(detectorInfo.position(ass[0]));
+        break;
+      case PHI:
+        xvalue = bOffsetPsi ? getPhiOffset(pos, M_PI) : getPhi(pos);
+        break;
+      case OUT_OF_PLANE_ANGLE: {
+        xvalue = getOutOfPlaneAngle(pos, samplePos, normal);
+        break;
+      }
+      default:
+        xvalue = static_cast<double>(id);
+      }
+      auto index = actor.getWorkspaceIndex(det);
+      if (index == InstrumentActor::INVALID_INDEX)
+        continue;
+      // get the y-value for detector idet
+      const auto &Y = ws->y(index);
+      double sum = std::accumulate(Y.begin() + imin, Y.begin() + imax, 0);
+      xymap[xvalue] = sum;
+      if (err) {
+        const auto &E = ws->e(index);
+        std::vector<double> tmp(imax - imin);
+        // take squares of the errors
+        std::transform(E.begin() + imin, E.begin() + imax, E.begin() + imin,
+                       tmp.begin(), std::multiplies<double>());
+        // sum them
+        double sum = std::accumulate(tmp.begin(), tmp.end(), 0);
+        // take sqrt
+        errmap[xvalue] = sqrt(sum);
       }
     }
   }
@@ -1590,7 +1530,7 @@ void DetectorPlotController::savePlotToWorkspace() {
       if (X.empty()) {
         // label doesn't have any info on how to reproduce the curve:
         // only the current curve can be saved
-        QList<int> dets;
+        std::vector<size_t> dets;
         m_tab->getSurface()->getMaskedDetectors(dets);
         actor.sumDetectors(dets, x, y);
         unitX = parentWorkspace->getAxis(0)->unit()->unitID();
@@ -1747,7 +1687,7 @@ QString DetectorPlotController::getPlotCaption() const {
 * @param y :: Peak height (counts)
 */
 void DetectorPlotController::addPeak(double x, double y) {
-  if (m_currentDetID < 0)
+  if (m_currentPickID == std::numeric_limits<size_t>::max())
     return;
 
   try {
@@ -1798,11 +1738,13 @@ void DetectorPlotController::addPeak(double x, double y) {
     // Run the AddPeak algorithm
     auto alg =
         Mantid::API::FrameworkManager::Instance().createAlgorithm("AddPeak");
+    const auto &detIDs =
+        m_instrWidget->getInstrumentActor().detectorInfo().detectorIDs();
     alg->setPropertyValue("RunWorkspace", ws->getName());
     alg->setPropertyValue("PeaksWorkspace", peakTableName);
-    alg->setProperty("DetectorID", m_currentDetID);
+    alg->setProperty("DetectorID", detIDs[m_currentPickID]);
     alg->setProperty("TOF", x);
-    alg->setProperty("Height", actor.getIntegratedCounts(m_currentDetID));
+    alg->setProperty("Height", actor.getIntegratedCounts(m_currentPickID));
     alg->setProperty("BinCount", y);
     alg->execute();
 
diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp
index 6b33c5fe23b420a57029fd5a2ce1762670a113bf..f491739ba5f22db1130ef844d221fa729395603e 100644
--- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp
@@ -287,7 +287,7 @@ void InstrumentWidgetRenderTab::enable3DSurface(bool on) {
 */
 void InstrumentWidgetRenderTab::initSurface() {
   setAxis(QString::fromStdString(
-      m_instrWidget->getInstrumentActor().getInstrument()->getDefaultAxis()));
+      m_instrWidget->getInstrumentActor().getDefaultAxis()));
   auto surface = getSurface();
 
   // 3D axes switch needs to be shown for the 3D surface
@@ -474,9 +474,7 @@ void InstrumentWidgetRenderTab::showEvent(QShowEvent *) {
   if (surface) {
     surface->setInteractionMode(ProjectionSurface::MoveMode);
   }
-  auto &actor = m_instrWidget->getInstrumentActor();
-  auto visitor = SetAllVisibleVisitor(actor.areGuidesShown());
-  actor.accept(visitor);
+
   getSurface()->updateView();
   getSurface()->requestRedraw();
 }
diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp
index c703547ff0b7fa8a98c4bf2a988528b88fb2f079..a1c43a6ae19afaf8c4ccda088ede1b2b351791b3 100644
--- a/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp
+++ b/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp
@@ -1,6 +1,5 @@
 #include "MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h"
 #include "MantidQtWidgets/Common/TSVSerialiser.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h"
 #include "MantidQtWidgets/InstrumentView/InstrumentWidget.h"
@@ -18,10 +17,8 @@ InstrumentWidgetTreeTab::InstrumentWidgetTreeTab(InstrumentWidget *instrWidget)
   // Tree Controls
   m_instrumentTree = new InstrumentTreeWidget(nullptr);
   layout->addWidget(m_instrumentTree);
-  connect(m_instrumentTree,
-          SIGNAL(componentSelected(Mantid::Geometry::ComponentID)),
-          m_instrWidget,
-          SLOT(componentSelected(Mantid::Geometry::ComponentID)));
+  connect(m_instrumentTree, SIGNAL(componentSelected(size_t)), m_instrWidget,
+          SLOT(componentSelected(size_t)));
   connect(m_instrWidget, SIGNAL(requestSelectComponent(QString)), this,
           SLOT(selectComponentByName(QString)));
 }
diff --git a/qt/widgets/instrumentview/src/MantidGLWidget.cpp b/qt/widgets/instrumentview/src/MantidGLWidget.cpp
index a4ecdee8ce2592f396364c97c17b6ecc301e1d57..2c9a39339847575243683ccf36d1a1c1714c4f72 100644
--- a/qt/widgets/instrumentview/src/MantidGLWidget.cpp
+++ b/qt/widgets/instrumentview/src/MantidGLWidget.cpp
@@ -283,9 +283,9 @@ void MantidGLWidget::draw() {
   OpenGLError::check("MantidGLWidget::drawUnwrapped()");
 }
 
-void MantidGLWidget::componentSelected(Mantid::Geometry::ComponentID id) {
+void MantidGLWidget::componentSelected(size_t componentIndex) {
   if (m_surface) {
-    m_surface->componentSelected(id);
+    m_surface->componentSelected(componentIndex);
     m_surface->updateView();
     update();
   }
diff --git a/qt/widgets/instrumentview/src/MaskBinsData.cpp b/qt/widgets/instrumentview/src/MaskBinsData.cpp
index 5369b49164e2262e85298cec7b9dadc498396211..5c49f576ed9c5aa1940de1d24a1390c9b842b767 100644
--- a/qt/widgets/instrumentview/src/MaskBinsData.cpp
+++ b/qt/widgets/instrumentview/src/MaskBinsData.cpp
@@ -10,7 +10,7 @@ namespace MantidWidgets {
 
 /// Add a range of x values for bin masking.
 void MaskBinsData::addXRange(double start, double end,
-                             const QList<int> &indices) {
+                             const std::vector<size_t> &indices) {
   BinMask range(start, end);
   range.spectra = indices;
   m_masks.append(range);
@@ -21,7 +21,10 @@ void MaskBinsData::addXRange(double start, double end,
 void MaskBinsData::mask(const std::string &wsName) const {
   for (auto mask = m_masks.begin(); mask != m_masks.end(); ++mask) {
     auto &spectra = mask->spectra;
-    std::vector<int> spectraList(spectra.begin(), spectra.end());
+    std::vector<int> spectraList(spectra.size());
+    std::transform(spectra.cbegin(), spectra.cend(), spectraList.begin(),
+                   [](const size_t spec)
+                       -> int { return static_cast<int>(spec); });
     auto alg = Mantid::API::AlgorithmManager::Instance().create("MaskBins", -1);
     alg->setPropertyValue("InputWorkspace", wsName);
     alg->setPropertyValue("OutputWorkspace", wsName);
@@ -69,12 +72,12 @@ void MaskBinsData::loadFromProject(const std::string &lines) {
     double start, end;
     mask >> start >> end;
 
-    QList<int> spectra;
+    std::vector<size_t> spectra;
     const size_t numSpectra = mask.values("Spectra").size();
     for (size_t i = 0; i < numSpectra; ++i) {
-      int spectrum;
+      size_t spectrum;
       mask >> spectrum;
-      spectra.append(spectrum);
+      spectra.push_back(spectrum);
     }
 
     addXRange(start, end, spectra);
@@ -90,7 +93,7 @@ std::string MaskBinsData::saveToProject() const {
     API::TSVSerialiser mask;
     mask.writeLine("Range") << binMask.start << binMask.end;
     mask.writeLine("Spectra");
-    for (const int spectrum : binMask.spectra) {
+    for (auto spectrum : binMask.spectra) {
       mask << spectrum;
     }
     tsv.writeSection("Mask", mask.outputLines());
diff --git a/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp b/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp
deleted file mode 100644
index 3c5da76700f8583e9bf27461e4337d935e8cf0dc..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-
-#include "MantidKernel/V3D.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/ICompAssembly.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Instrument/ObjCompAssembly.h"
-#include "MantidKernel/Exception.h"
-#include <cfloat>
-using namespace Mantid;
-using namespace Geometry;
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-ObjCompAssemblyActor::ObjCompAssemblyActor(const InstrumentActor &instrActor,
-                                           Mantid::Geometry::ComponentID compID)
-    : ICompAssemblyActor(instrActor, compID), m_idData(0), m_idPick(0),
-      m_n(getObjCompAssembly()->nelements()), m_pick_data(),
-      m_texturesGenerated(false) {
-
-  ObjCompAssembly_const_sptr objAss = getObjCompAssembly();
-  mNumberOfDetectors = objAss->nelements();
-  assert(static_cast<size_t>(m_n) == mNumberOfDetectors);
-  m_data = new unsigned char[m_n * 3];
-  m_pick_data = new unsigned char[m_n * 3];
-  for (size_t i = 0; i < getNumberOfDetectors(); ++i) {
-    IDetector_const_sptr det = boost::dynamic_pointer_cast<const IDetector>(
-        objAss->getChild(static_cast<int>(i)));
-    assert(det);
-    detid_t id = det->getID();
-    m_detIDs.push_back(id);
-    size_t pickID = instrActor.pushBackDetid(id);
-    setDetectorColor(m_pick_data, i, GLActor::makePickColor(pickID));
-  }
-  Mantid::Geometry::BoundingBox boundBox;
-  objAss->getBoundingBox(boundBox);
-  minBoundBox[0] = boundBox.xMin();
-  minBoundBox[1] = boundBox.yMin();
-  minBoundBox[2] = boundBox.zMin();
-  maxBoundBox[0] = boundBox.xMax();
-  maxBoundBox[1] = boundBox.yMax();
-  maxBoundBox[2] = boundBox.zMax();
-}
-
-/**
-* Destructor which removes the actors created by this object
-*/
-ObjCompAssemblyActor::~ObjCompAssemblyActor() {
-  if (m_data) {
-    delete[] m_data;
-    delete[] m_pick_data;
-  }
-  if (m_texturesGenerated) {
-    glDeleteTextures(1, &m_idData);
-    glDeleteTextures(1, &m_idPick);
-  }
-}
-
-/**
-* This function is concrete implementation that renders the Child ObjComponents
-* and Child CompAssembly's
-*/
-void ObjCompAssemblyActor::draw(bool picking) const {
-  OpenGLError::check("ObjCompAssemblyActor::draw(0)");
-
-  if (!m_texturesGenerated) {
-    setDataColors();
-    setPickColors();
-    m_texturesGenerated = true;
-  }
-
-  ObjCompAssembly_const_sptr objAss = getObjCompAssembly();
-  glPushMatrix();
-
-  unsigned int texID = picking ? m_idPick : m_idData;
-  // Because texture colours are combined with the geometry colour
-  // make sure the current colour is white
-  glColor3f(1.0f, 1.0f, 1.0f);
-  glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, texID);
-  objAss->draw();
-  glBindTexture(GL_TEXTURE_2D, 0);
-  OpenGLError::check("ObjCompAssemblyActor::draw()");
-
-  glPopMatrix();
-}
-
-void ObjCompAssemblyActor::generateTexture(unsigned char *data,
-                                           unsigned int &id) const {
-  if (id > 0) {
-    glDeleteTextures(1, &id);
-    OpenGLError::check("TexObject::generateTexture()[delete texture] ");
-  }
-
-  int width = 1;
-  int height = m_n;
-
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-  glGenTextures(1, &id); // Create The Texture
-  OpenGLError::check("TexObject::generateTexture()[generate] ");
-  glBindTexture(GL_TEXTURE_2D, id);
-  OpenGLError::check("TexObject::generateTexture()[bind] ");
-
-  GLint texParam = GL_NEAREST;
-  glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,
-               data);
-  OpenGLError::check("TexObject::generateTexture()[set data] ");
-  /* If the above call to glTexImage2D has generated an error, it is likely as a
-  * result
-  * of outline="yes" being set in the IDF. If this is enabled then the texture
-  * above
-  * is generated with a width being equal to the number of points that make up
-  * the
-  * outline. However, some OpenGL implementations only support textures with a
-  * 2^n size.
-  * On the machines tested (Ubuntu 14.04, Windows 7, and RHEL6), this was not an
-  * issue,
-  * but we can't guarantee that a user wont try this on a system that doesn't
-  * support
-  * non power of 2 textures. In that case, the best thing to do would be to
-  * create a
-  * texture with a width of the next 2^n up, and adjust the texture coordinates
-  * accordingly. However, this is not a trivial change to make, and as far as we
-  * can tell
-  * no one has ever run into this issue, so it's being left for now. If this
-  * does prove
-  * problematic in the future, hopefully this note will save you some time
-  * figuring out
-  * the problem.
-  */
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam);
-  OpenGLError::check("TexObject::generateTexture()[parameters] ");
-}
-
-/**
-* Set colour to a detector.
-* @param data :: pointer to color array
-* @param i :: Index of the detector in ObjCompAssembly
-* @param c :: The colour
-*/
-void ObjCompAssemblyActor::setDetectorColor(unsigned char *data, size_t i,
-                                            GLColor c) const {
-  size_t pos = 3 * i;
-  float r, g, b, a;
-  c.get(r, g, b, a);
-  data[pos] = (unsigned char)(r * 255);
-  data[pos + 1] = (unsigned char)(g * 255);
-  data[pos + 2] = (unsigned char)(b * 255);
-}
-
-void ObjCompAssemblyActor::swap() {
-  if (!m_pick_data) {
-    m_pick_data = new unsigned char[m_n * 3];
-  }
-  unsigned char *tmp = m_data;
-  m_data = m_pick_data;
-  m_pick_data = tmp;
-}
-
-const unsigned char *ObjCompAssemblyActor::getColor(int i) const {
-  return &m_data[3 * i];
-}
-
-void ObjCompAssemblyActor::setColors() { setDataColors(); }
-
-void ObjCompAssemblyActor::setDataColors() const {
-  for (size_t i = 0; i < size_t(m_n); ++i) {
-    GLColor c = m_instrActor.getColor(m_detIDs[i]);
-    setDetectorColor(m_data, i, c);
-  }
-  generateTexture(m_data, m_idData);
-}
-
-void ObjCompAssemblyActor::setPickColors() const {
-  generateTexture(m_pick_data, m_idPick);
-}
-
-bool ObjCompAssemblyActor::accept(GLActorVisitor &visitor,
-                                  GLActor::VisitorAcceptRule) {
-  return visitor.visit(this);
-}
-
-bool ObjCompAssemblyActor::accept(GLActorConstVisitor &visitor,
-                                  GLActor::VisitorAcceptRule) const {
-  return visitor.visit(this);
-}
-
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/ObjComponentActor.cpp b/qt/widgets/instrumentview/src/ObjComponentActor.cpp
deleted file mode 100644
index dd1c140ffc9f0513009f2aadc761e50617ceafb7..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/ObjComponentActor.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-
-#include "MantidKernel/V3D.h"
-#include "MantidKernel/Quat.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidKernel/Exception.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Objects/BoundingBox.h"
-
-using namespace Mantid;
-using namespace Geometry;
-
-namespace {
-// Anonymous namespace
-
-/**
-  * Returns if the current component is finite or
-  * has 'infinite' length based on all axis found
-  * within the bounding box
-  *
-  * @param compID:: The component to check
-  * @return :: True if the component has finite size else False
-  */
-bool isComponentFinite(const Mantid::Geometry::ComponentID &compID) {
-  Geometry::BoundingBox boundedBox;
-  compID->getBoundingBox(boundedBox);
-  const auto width = boundedBox.width();
-  const double x = width[0];
-  const double y = width[1];
-  const double z = width[2];
-
-  // Currently an 'infinite' component will have length 1000
-  // on one of its axis. Check all to make sure it is not greater
-  // than 1000 units in length.
-  const double maximumSize = 999;
-  if (x > maximumSize || y > maximumSize || z > maximumSize) {
-    return false;
-  } else {
-    return true;
-  }
-}
-}
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-ObjComponentActor::ObjComponentActor(const InstrumentActor &instrActor,
-                                     Mantid::Geometry::ComponentID compID)
-    : ComponentActor(instrActor, compID) {
-  // set the displayed colour
-  setColors();
-
-  if (!isComponentFinite(compID)) {
-    // If the component does not have finite length we set it always
-    // hidden so scale is not messed up and it is not displayed.
-    setAlwaysHidden();
-  }
-
-  // register the component with InstrumentActor and set the pick colour
-  IDetector_const_sptr det = getDetector();
-  if (det) {
-    size_t pickID = instrActor.pushBackDetid(det->getID());
-    m_pickColor = makePickColor(pickID);
-  } else {
-    instrActor.pushBackNonDetid(this, compID);
-  }
-}
-
-ObjComponentActor::~ObjComponentActor() {}
-
-//-------------------------------------------------------------------------------------------------
-/**
-* Concrete implementation of rendering ObjComponent.
-*/
-void ObjComponentActor::draw(bool picking) const {
-  OpenGLError::check("ObjComponentActor::draw(0)");
-  glPushMatrix();
-  if (picking) {
-    m_pickColor.paint();
-  } else {
-    m_dataColor.paint();
-  }
-  getObjComponent()->draw();
-  glPopMatrix();
-  OpenGLError::check("ObjComponentActor::draw()");
-}
-
-/**
-* Set displayed component colour. If it's a detector the colour maps to the
-* integrated counts in it.
-*/
-void ObjComponentActor::setColors() {
-  IDetector_const_sptr det = getDetector();
-  if (det) {
-    setColor(m_instrActor.getColor(det->getID()));
-  } else {
-    setColor(defaultDetectorColor());
-  }
-}
-
-/**
-* Return the bounding box of visible components.
-* If this is not visible an empty V3D object will
-* be returned.
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void ObjComponentActor::getBoundingBox(Mantid::Kernel::V3D &minBound,
-                                       Mantid::Kernel::V3D &maxBound) const {
-  if (!isVisible()) {
-    // If this is not visible we should not consider this component
-    minBound = Kernel::V3D();
-    maxBound = Kernel::V3D();
-  } else {
-    Mantid::Geometry::BoundingBox boundBox;
-    getComponent()->getBoundingBox(boundBox);
-    minBound = boundBox.minPoint();
-    maxBound = boundBox.maxPoint();
-  }
-}
-
-} // MantidWidgets
-} // MantidQt
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp
index 345257f1be1b74d97eb93f5619e34a590970a4df..18fea668c0970dd9db7b398c770e34722d0a1098 100644
--- a/qt/widgets/instrumentview/src/PanelsSurface.cpp
+++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp
@@ -1,13 +1,9 @@
-#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h"
 #include "MantidQtWidgets/InstrumentView/PanelsSurface.h"
-#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h"
+#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h"
 
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
-#include "MantidGeometry/Instrument/ObjCompAssembly.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/Tolerance.h"
 #include "MantidKernel/V3D.h"
@@ -18,12 +14,124 @@
 #include <QtDebug>
 
 using namespace Mantid::Geometry;
+using Mantid::Beamline::ComponentType;
 
 namespace {
+
 /// static logger
 Mantid::Kernel::Logger g_log("PanelsSurface");
+
+/**
+ * Given the z axis, define the x and y ones.
+ * @param zaxis :: A given vector in 3d space to become the z axis of a
+ * coordinate system.
+ * @param xaxis :: An output arbitrary vector perpendicular to zaxis.
+ * @param yaxis :: An output arbitrary vector perpendicular to both zaxis and
+ * xaxis.
+ */
+void setupBasisAxes(const Mantid::Kernel::V3D &zaxis,
+                    Mantid::Kernel::V3D &xaxis, Mantid::Kernel::V3D &yaxis) {
+  double R, theta, phi;
+  zaxis.getSpherical(R, theta, phi);
+  if (theta <= 45.0) {
+    xaxis = Mantid::Kernel::V3D(1, 0, 0);
+  } else if (phi <= 45.0) {
+    xaxis = Mantid::Kernel::V3D(0, 1, 0);
+  } else {
+    xaxis = Mantid::Kernel::V3D(0, 0, 1);
+  }
+  yaxis = zaxis.cross_prod(xaxis);
+  yaxis.normalize();
+  xaxis = yaxis.cross_prod(zaxis);
+}
+
+std::vector<Mantid::Kernel::V3D>
+retrievePanelCorners(const Mantid::Geometry::ComponentInfo &componentInfo,
+                     size_t rootIndex) {
+  auto panel = componentInfo.quadrilateralComponent(rootIndex);
+  return {componentInfo.position(panel.bottomLeft),
+          componentInfo.position(panel.bottomRight),
+          componentInfo.position(panel.topRight),
+          componentInfo.position(panel.topLeft)};
+}
+
+Mantid::Kernel::V3D
+calculatePanelNormal(const std::vector<Mantid::Kernel::V3D> &panelCorners) {
+  // find the normal
+  auto xaxis = panelCorners[1] - panelCorners[0];
+  auto yaxis = panelCorners[3] - panelCorners[0];
+  auto normal = xaxis.cross_prod(yaxis);
+  normal.normalize();
+  return normal;
+}
+
+size_t findParentBank(const ComponentInfo &componentInfo, size_t rootIndex) {
+  // Search for parent component which contains tubes
+  auto parent = componentInfo.parent(rootIndex);
+  while (componentInfo.children(parent).size() <= 1)
+    parent = componentInfo.parent(parent);
+
+  return parent;
 }
 
+std::vector<size_t> findBankTubes(const ComponentInfo &componentInfo,
+                                  size_t rootIndex) {
+  auto comps = componentInfo.componentsInSubtree(rootIndex);
+  std::vector<size_t> tubes;
+
+  for (auto comp : comps) {
+    if (componentInfo.componentType(comp) == ComponentType::OutlineComposite)
+      tubes.push_back(comp);
+  }
+
+  return tubes;
+}
+
+bool isBankFlat(const ComponentInfo &componentInfo, size_t bankIndex,
+                const std::vector<size_t> &tubes,
+                const Mantid::Kernel::V3D &normal) {
+  for (auto tube : tubes) {
+    const auto &children = componentInfo.children(tube);
+    auto vector = componentInfo.position(children[0]) -
+                  componentInfo.position(children[1]);
+    vector.normalize();
+    if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) {
+      g_log.warning() << "Assembly " << componentInfo.name(bankIndex)
+                      << " isn't flat.\n";
+      return false;
+    }
+  }
+  return true;
+}
+
+Mantid::Kernel::V3D calculateBankNormal(const ComponentInfo &componentInfo,
+                                        const std::vector<size_t> &tubes) {
+  // calculate normal from first two tubes in bank as before
+  const auto &tube0 = componentInfo.children(tubes[0]);
+  const auto &tube1 = componentInfo.children(tubes[1]);
+  auto pos = componentInfo.position(tube0[0]);
+  auto x = componentInfo.position(tube0[1]) - pos;
+  x.normalize();
+
+  auto y = componentInfo.position(tube1[0]) - pos;
+  y.normalize();
+  auto normal = x.cross_prod(y);
+
+  if (normal.nullVector()) {
+    y = componentInfo.position(tube1[1]) - componentInfo.position(tube1[0]);
+    y.normalize();
+    normal = x.cross_prod(y);
+  }
+
+  normal.normalize();
+
+  if (normal.nullVector())
+    g_log.warning() << "Colinear Assembly.\n";
+
+  return normal;
+}
+} // namespace
+
 namespace MantidQt {
 namespace MantidWidgets {
 
@@ -31,8 +139,8 @@ namespace MantidWidgets {
 * @param s The surface of the panel
 */
 FlatBankInfo::FlatBankInfo(PanelsSurface *s)
-    : id(nullptr), rotation(), startDetectorIndex(0), endDetectorIndex(0),
-      polygon(), surface(s) {}
+    : rotation(), startDetectorIndex(0), endDetectorIndex(0), polygon(),
+      surface(s) {}
 
 /**
 * Translate the bank by a vector.
@@ -42,7 +150,7 @@ void FlatBankInfo::translate(const QPointF &shift) {
   double du = shift.x();
   double dv = shift.y();
   polygon.translate(shift);
-  for (size_t i = startDetectorIndex; i < endDetectorIndex; ++i) {
+  for (size_t i = startDetectorIndex; i <= endDetectorIndex; ++i) {
     UnwrappedDetector &udet = surface->m_unwrappedDetectors[i];
     udet.u += du;
     udet.v += dv;
@@ -64,17 +172,14 @@ PanelsSurface::~PanelsSurface() { clearBanks(); }
 */
 void PanelsSurface::init() {
   m_unwrappedDetectors.clear();
-  m_assemblies.clear();
 
   size_t ndet = m_instrActor->ndetectors();
+  m_unwrappedDetectors.resize(ndet);
   if (ndet == 0)
     return;
 
-  // Pre-calculate all the detector positions (serial because
-  // I suspect the IComponent->getPos() method to not be properly thread safe)
-  m_instrActor->cacheDetPos();
-
-  findFlatBanks();
+  clearBanks();
+  constructFromComponentInfo();
   spreadBanks();
 
   RectF surfaceRect;
@@ -105,9 +210,10 @@ void PanelsSurface::project(const Mantid::Kernel::V3D &, double &, double &,
 
 void PanelsSurface::rotate(const UnwrappedDetector &udet,
                            Mantid::Kernel::Quat &R) const {
-  int index = m_detector2bankMap[udet.detID];
+  const auto &detectorInfo = m_instrActor->detectorInfo();
+  int index = m_detector2bankMap[udet.detIndex];
   FlatBankInfo &info = *m_flatBanks[index];
-  R = info.rotation * udet.rotation;
+  R = info.rotation * detectorInfo.rotation(udet.detIndex);
 }
 
 /**
@@ -119,316 +225,161 @@ void PanelsSurface::setupAxes() {
   m_origin.ry() = m_yaxis.scalar_prod(m_pos);
 }
 
-/**
-* Given the z axis, define the x and y ones.
-* @param zaxis :: A given vector in 3d space to become the z axis of a
-* coordinate system.
-* @param xaxis :: An output arbitrary vector perpendicular to zaxis.
-* @param yaxis :: An output arbitrary vector perpendicular to both zaxis and
-* xaxis.
-*/
-void PanelsSurface::setupBasisAxes(const Mantid::Kernel::V3D &zaxis,
-                                   Mantid::Kernel::V3D &xaxis,
-                                   Mantid::Kernel::V3D &yaxis) const {
-  double R, theta, phi;
-  zaxis.getSpherical(R, theta, phi);
-  if (theta <= 45.0) {
-    xaxis = Mantid::Kernel::V3D(1, 0, 0);
-  } else if (phi <= 45.0) {
-    xaxis = Mantid::Kernel::V3D(0, 1, 0);
-  } else {
-    xaxis = Mantid::Kernel::V3D(0, 0, 1);
-  }
-  yaxis = zaxis.cross_prod(xaxis);
-  yaxis.normalize();
-  xaxis = yaxis.cross_prod(zaxis);
-}
-
 //-----------------------------------------------------------------------------------------------//
 
-class FlatBankFinder : public GLActorConstVisitor {
-  PanelsSurface &m_surface;
-
-public:
-  explicit FlatBankFinder(PanelsSurface &surface) : m_surface(surface) {}
-
-  bool visit(const GLActor *) override { return false; }
-  bool visit(const GLActorCollection *) override { return false; }
-  bool visit(const ComponentActor *) override { return false; }
-  bool visit(const InstrumentActor *) override { return false; }
-  bool visit(const ObjCompAssemblyActor *) override { return false; }
-
-  bool visit(const CompAssemblyActor *actor) override {
-    m_surface.addObjCompAssemblies(actor->getComponent()->getComponentID());
-    return false;
-  }
-
-  bool visit(const RectangularDetectorActor *actor) override {
-    m_surface.addRectangularDetector(actor->getComponent()->getComponentID());
-    return false;
-  }
-
-  bool visit(const StructuredDetectorActor *actor) override {
-    m_surface.addStructuredDetector(actor->getComponent()->getComponentID());
-    return false;
-  }
-};
-
 /**
-* Traverse the instrument tree and find the banks which detectors lie in the
-* same plane.
-*
-*/
-void PanelsSurface::findFlatBanks() {
-  clearBanks();
-  FlatBankFinder finder(*this);
-  m_instrActor->accept(finder);
-}
-
-//-----------------------------------------------------------------------------------------------//
-
-/**
-* Add a flat bank from an assembly of ObjCompAssemblies.
+* Add a flat bank from an assembly of detectors.
 * @param bankId :: Component ID of the bank.
 * @param normal :: Normal vector to the bank's plane.
-* @param objCompAssemblies :: List of component IDs. Each component must cast to
-* ObjCompAssembly.
+* @param detectors :: List of detectorIndices.
 */
-void PanelsSurface::addFlatBank(ComponentID bankId,
-                                const Mantid::Kernel::V3D &normal,
-                                QList<ComponentID> objCompAssemblies) {
+void PanelsSurface::addFlatBankOfDetectors(
+    const Mantid::Kernel::V3D &normal, const std::vector<size_t> &detectors) {
   int index = m_flatBanks.size();
   // save bank info
   FlatBankInfo *info = new FlatBankInfo(this);
   m_flatBanks << info;
-  info->id = bankId;
   // record the first detector index of the bank
-  info->startDetectorIndex = m_unwrappedDetectors.size();
-  bool doneRotation = false;
+  info->startDetectorIndex = detectors.front();
+  info->endDetectorIndex = detectors.back();
+
   // keep reference position on the bank's plane
-  Mantid::Kernel::V3D pos0;
-  QPointF p0, p1;
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  // loop over the assemblies and process the detectors
-  foreach (ComponentID id, objCompAssemblies) {
-    Mantid::Geometry::ICompAssembly_const_sptr assembly =
-        boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(
-            instr->getComponentByID(id));
-    assert(assembly);
-    int nelem = assembly->nelements();
-    m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem);
-    for (int i = 0; i < nelem; ++i) {
-      // setup detector info
-      auto det = boost::dynamic_pointer_cast<const Mantid::Geometry::IDetector>(
-          assembly->getChild(i));
-      if (!doneRotation) {
-        pos0 = det->getPos();
-        // find the rotation to put the bank on the plane
-        info->rotation = calcBankRotation(pos0, normal);
-        Mantid::Kernel::V3D pos1 = assembly->getChild(nelem - 1)->getPos();
-        pos1 -= pos0;
-        info->rotation.rotate(pos1);
-        pos1 += pos0;
-        // start forming the outline polygon
-        p0.rx() = m_xaxis.scalar_prod(pos0);
-        p0.ry() = m_yaxis.scalar_prod(pos0);
-        p1.rx() = m_xaxis.scalar_prod(pos1);
-        p1.ry() = m_yaxis.scalar_prod(pos1);
-        QVector<QPointF> vert;
-        vert << p1 << p0;
-        info->polygon = QPolygonF(vert);
-        doneRotation = true;
-      }
-      // add the detector
-      addDetector(*det, pos0, index, info->rotation);
-    }
+  const auto &detectorInfo = m_instrActor->detectorInfo();
+  auto pos0 = detectorInfo.position(detectors[0]);
+  auto pos1 = detectorInfo.position(detectors[1]) - pos0;
+
+  info->rotation = calcBankRotation(pos0, normal);
+  info->rotation.rotate(pos1);
+  pos1 += pos0;
+  QPointF p0(m_xaxis.scalar_prod(pos0), m_yaxis.scalar_prod(pos0));
+  QPointF p1(m_xaxis.scalar_prod(pos1), m_yaxis.scalar_prod(pos1));
+  QVector<QPointF> vert;
+  vert << p1 << p0;
+  info->polygon = QPolygonF(vert);
+
+  for (auto detector : detectors) {
+    addDetector(detector, pos0, index, info->rotation);
     // update the outline polygon
-    UnwrappedDetector &udet0 = *(m_unwrappedDetectors.end() - nelem);
-    UnwrappedDetector &udet1 = m_unwrappedDetectors.back();
-    //      get the tube end points
-    QPointF p3 = QPointF(udet0.u, udet0.v);
-    QPointF p4 = QPointF(udet1.u, udet1.v);
-    QVector<QPointF> vert;
-    //      add a quadrilateral formed by end points of two nearest tubes
-    //      assumption is made here that any two adjacent tubes in an assembly's
-    //      children's list
-    //      are close to each other
-    vert << p0 << p1 << p4 << p3;
+    UnwrappedDetector &udet = m_unwrappedDetectors[detector];
+    auto p2 = QPointF(udet.u, udet.v);
+    vert.clear();
+    vert << p0 << p1 << p2;
     info->polygon = info->polygon.united(QPolygonF(vert));
-    p0 = p3;
-    p1 = p4;
   }
-  // record the end detector index of the bank
-  info->endDetectorIndex = m_unwrappedDetectors.size();
 }
 
-/**
-* Add a flat bank from an assembly of detectors.
-* @param bankId :: Component ID of the bank.
-* @param normal :: Normal vector to the bank's plane.
-* @param detectors :: List of component IDs. Each component must cast to
-* Detector.
-*/
-void PanelsSurface::addFlatBankOfDetectors(ComponentID bankId,
-                                           const Mantid::Kernel::V3D &normal,
-                                           QList<ComponentID> detectors) {
+void PanelsSurface::processStructured(const std::vector<size_t> &children,
+                                      size_t rootIndex) {
   int index = m_flatBanks.size();
+  const auto &componentInfo = m_instrActor->componentInfo();
+  auto corners = retrievePanelCorners(componentInfo, rootIndex);
+  auto normal = calculatePanelNormal(corners);
   // save bank info
   FlatBankInfo *info = new FlatBankInfo(this);
   m_flatBanks << info;
-  info->id = bankId;
+  // find the rotation to put the bank on the plane
+  info->rotation = calcBankRotation(corners[0], normal);
   // record the first detector index of the bank
-  info->startDetectorIndex = m_unwrappedDetectors.size();
-  int nelem = detectors.size();
-  m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem);
-
-  // keep reference position on the bank's plane
-  Mantid::Kernel::V3D pos0, pos1;
-  QPointF p0, p1;
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  // loop over the detectors
-  for (int i = 0; i < detectors.size(); ++i) {
-    ComponentID id = detectors[i];
-    auto det = boost::dynamic_pointer_cast<const Mantid::Geometry::IDetector>(
-        instr->getComponentByID(id));
-
-    if (i == 0) {
-      pos0 = det->getPos();
-    } else if (i == 1) {
-      // find the rotation to put the bank on the plane
-      info->rotation = calcBankRotation(pos0, normal);
-      pos1 = det->getPos();
-      pos1 -= pos0;
-      info->rotation.rotate(pos1);
-      pos1 += pos0;
-      // start forming the outline polygon
-      p0.rx() = m_xaxis.scalar_prod(pos0);
-      p0.ry() = m_yaxis.scalar_prod(pos0);
-      p1.rx() = m_xaxis.scalar_prod(pos1);
-      p1.ry() = m_yaxis.scalar_prod(pos1);
-      QVector<QPointF> vert;
-      vert << p1 << p0;
-      info->polygon = QPolygonF(vert);
-    }
-    // add the detector
-    addDetector(*det, pos0, index, info->rotation);
-    // update the outline polygon
-    UnwrappedDetector &udet = *(m_unwrappedDetectors.end() - 1);
-    QPointF p2 = QPointF(udet.u, udet.v);
-    QVector<QPointF> vert;
-    vert << p0 << p1 << p2;
-    info->polygon = info->polygon.united(QPolygonF(vert));
+  info->startDetectorIndex = children.front();
+  info->endDetectorIndex = children.back();
+  // set the outline
+  QVector<QPointF> verts;
+  for (auto &corner : corners) {
+    auto pos = corner - corners[0];
+    info->rotation.rotate(pos);
+    pos += corners[0];
+    verts << QPointF(pos.X(), pos.Y());
   }
 
-  // record the end detector index of the bank
-  info->endDetectorIndex = m_unwrappedDetectors.size();
+  info->polygon = QPolygonF(verts);
+
+  for (auto child : children)
+    addDetector(child, corners[0], index, info->rotation);
 }
 
-/**
-* Add a component assembly containing a flat array of ObjCompAssemblies.
-* @param bankId :: Component id of an assembly.
-*/
-void PanelsSurface::addObjCompAssemblies(ComponentID bankId) {
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  boost::shared_ptr<const Mantid::Geometry::CompAssembly> assembly =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::CompAssembly>(
-          instr->getComponentByID(bankId));
-
-  size_t nelem = static_cast<size_t>(assembly->nelements());
-  // assemblies with one element cannot be flat (but its element can be)
-  if (nelem == 1) {
+void PanelsSurface::processTubes(size_t rootIndex, std::vector<bool> &visited) {
+  const auto &componentInfo = m_instrActor->componentInfo();
+  auto bankIndex = findParentBank(componentInfo, rootIndex);
+  auto name = componentInfo.name(bankIndex);
+  auto tubes = findBankTubes(componentInfo, bankIndex);
+  auto normal = calculateBankNormal(componentInfo, tubes);
+
+  if (normal.nullVector() ||
+      !isBankFlat(componentInfo, bankIndex, tubes, normal))
     return;
-  }
 
-  QList<ComponentID> objCompAssemblies;
-  // normal to the plane, undefined at first
-  Mantid::Kernel::V3D normal(0, 0, 0);
-  Mantid::Kernel::V3D x, y, pos;
-  for (size_t i = 0; i < nelem; ++i) {
-    auto elem = assembly->getChild((int)i);
-    ObjCompAssembly *objCompAssembly =
-        dynamic_cast<ObjCompAssembly *>(elem.get());
-    if (!objCompAssembly) {
-      CompAssembly *compAssembly = dynamic_cast<CompAssembly *>(elem.get());
-      if (!compAssembly || compAssembly->nelements() != 1) {
-        // m_surface.g_log.warning() << "Not a CompAssembly\n";
-        addCompAssembly(bankId);
-        return;
-      }
-      elem = compAssembly->getChild(0);
-      objCompAssembly = dynamic_cast<ObjCompAssembly *>(elem.get());
-      if (!objCompAssembly) {
-        // m_surface.g_log.warning() << "Not a ObjCompAssembly\n";
-        return;
-      }
-    }
-    if (i == 0) {
-      pos = objCompAssembly->getChild(0)->getPos();
-      x = objCompAssembly->getChild(1)->getPos() - pos;
-      x.normalize();
-    } else if (i == 1) {
-      y = objCompAssembly->getChild(0)->getPos() - pos;
-      y.normalize();
-      normal = x.cross_prod(y);
-      if (normal.nullVector()) {
-        y = objCompAssembly->getChild(1)->getPos() -
-            objCompAssembly->getChild(0)->getPos();
-        y.normalize();
-        normal = x.cross_prod(y);
-      }
-      if (normal.nullVector()) {
-        g_log.warning() << "Colinear ObjCompAssemblies\n";
-        return;
-      }
-      normal.normalize();
-    } else {
-      Mantid::Kernel::V3D vector = objCompAssembly->getChild(0)->getPos() -
-                                   objCompAssembly->getChild(1)->getPos();
-      vector.normalize();
-      if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) {
-        g_log.warning() << "Assembly " << assembly->getName()
-                        << " isn't flat.\n";
-        return;
-      }
+  // save bank info
+  auto index = m_flatBanks.size();
+  FlatBankInfo *info = new FlatBankInfo(this);
+  m_flatBanks << info;
+  // record the first detector index of the bank
+  info->startDetectorIndex = componentInfo.children(tubes.front()).front();
+  info->endDetectorIndex = componentInfo.children(tubes.back()).back();
+
+  auto pos0 =
+      componentInfo.position(componentInfo.children(tubes.front()).front());
+  auto pos1 =
+      componentInfo.position(componentInfo.children(tubes.front()).back());
+
+  info->rotation = calcBankRotation(pos0, normal);
+  pos1 -= pos0;
+  info->rotation.rotate(pos1);
+  pos1 += pos0;
+
+  QPointF p0(m_xaxis.scalar_prod(pos0), m_yaxis.scalar_prod(pos0));
+  QPointF p1(m_xaxis.scalar_prod(pos1), m_yaxis.scalar_prod(pos1));
+  QVector<QPointF> vert;
+  vert << p0 << p1;
+  info->polygon = QPolygonF(vert);
+
+  for (auto tube : tubes) {
+    const auto &children = componentInfo.children(tube);
+    visited[tube] = true;
+    for (auto child : children) {
+      if (visited[child])
+        continue;
+      visited[child] = true;
+      addDetector(child, pos0, index, info->rotation);
     }
-    objCompAssemblies << objCompAssembly->getComponentID();
-  }
-  if (!objCompAssemblies.isEmpty()) {
-    addFlatBank(assembly->getComponentID(), normal, objCompAssemblies);
+
+    auto &udet0 = m_unwrappedDetectors[children.front()];
+    auto &udet1 = m_unwrappedDetectors[children.back()];
+    QPointF p2(udet0.u, udet0.v);
+    QPointF p3(udet1.u, udet1.v);
+    //      add a quadrilateral formed by end points of two nearest tubes
+    //      assumption is made here that any two adjacent tubes in an assembly's
+    //      children's list
+    //      are close to each other
+    vert << p0 << p1 << p3 << p2;
+    info->polygon = info->polygon.united(QPolygonF(vert));
+    p0 = p2;
+    p1 = p3;
   }
 }
 
-/**
-* Add an assembly if its detectors are in the same plane.
-* @param bankId :: Component id of an assembly.
-*/
-void PanelsSurface::addCompAssembly(ComponentID bankId) {
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  boost::shared_ptr<const Mantid::Geometry::CompAssembly> assembly =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::CompAssembly>(
-          instr->getComponentByID(bankId));
-
-  size_t nelem = static_cast<size_t>(assembly->nelements());
-  // normal to the plane, undefined at first
-  Mantid::Kernel::V3D normal, x, y;
+std::pair<std::vector<size_t>, Mantid::Kernel::V3D>
+PanelsSurface::processUnstructured(const std::vector<size_t> &children,
+                                   size_t rootIndex,
+                                   std::vector<bool> &visited) {
+  Mantid::Kernel::V3D normal;
+  const auto &detectorInfo = m_instrActor->detectorInfo();
   Mantid::Kernel::V3D pos0;
+  Mantid::Kernel::V3D x, y;
   bool normalFound = false;
-  QList<ComponentID> detectors;
-  const auto &detectorInfo = m_instrActor->getWorkspace()->detectorInfo();
-  for (size_t i = 0; i < nelem; ++i) {
-    auto elem = assembly->getChild((int)i);
-    Mantid::Geometry::IDetector_const_sptr det =
-        boost::dynamic_pointer_cast<const Mantid::Geometry::IDetector>(elem);
-    if (!det) {
-      return;
-    }
-    size_t detIndex = detectorInfo.indexOf(det->getID());
-    if (detectorInfo.isMonitor(detIndex))
+  const auto &componentInfo = m_instrActor->componentInfo();
+  std::vector<size_t> detectors;
+  detectors.reserve(children.size());
+  for (auto child : children) {
+    if (visited[child])
       continue;
-    Mantid::Kernel::V3D pos = detectorInfo.position(detIndex);
-    if (i == 0) {
+    visited[child] = true;
+
+    if (detectorInfo.isMonitor(child))
+      continue;
+    auto pos = detectorInfo.position(child);
+    if (child == children[0])
       pos0 = pos;
-    } else if (i == 1) {
+    else if (child == children[1]) {
       // at first set the normal to an argbitrary vector orthogonal to
       // the line between the first two detectors
       y = pos - pos0;
@@ -445,157 +396,70 @@ void PanelsSurface::addCompAssembly(ComponentID bankId) {
         x = y.cross_prod(normal);
         normalFound = true;
       } else {
-        g_log.warning() << "Assembly " << assembly->getName()
+        g_log.warning() << "Assembly " << componentInfo.name(rootIndex)
                         << " isn't flat.\n";
-        return;
+        break;
       }
     }
-    detectors << det->getComponentID();
-  }
-
-  // normalFound doesn't have to be true at this point
-  // if it is false then the normal was found by the first guess
-
-  // add the detectors
-  if (!detectors.isEmpty()) {
-    addFlatBankOfDetectors(bankId, normal, detectors);
+    detectors.push_back(child);
   }
+  return std::make_pair(detectors, normal);
 }
 
-/**
-* Add a rectangular detector which is flat.
-* @param bankId :: Component id of a rectangular detector.
-*/
-void PanelsSurface::addRectangularDetector(ComponentID bankId) {
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  Mantid::Geometry::RectangularDetector_const_sptr rectDetector =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::RectangularDetector>(
-          instr->getComponentByID(bankId));
-
-  int nx = rectDetector->xpixels();
-  int ny = rectDetector->ypixels();
-  Mantid::Kernel::V3D pos0 = rectDetector->getAtXY(0, 0)->getPos();
-  Mantid::Kernel::V3D pos1 = rectDetector->getAtXY(nx - 1, 0)->getPos();
-  Mantid::Kernel::V3D pos2 = rectDetector->getAtXY(nx - 1, ny - 1)->getPos();
-  Mantid::Kernel::V3D pos3 = rectDetector->getAtXY(0, ny - 1)->getPos();
-
-  // find the normal
-  Mantid::Kernel::V3D xaxis = pos1 - pos0;
-  Mantid::Kernel::V3D yaxis = pos3 - pos0;
-  Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis);
-  normal.normalize();
-
-  int index = m_flatBanks.size();
-  // save bank info
-  FlatBankInfo *info = new FlatBankInfo(this);
-  m_flatBanks << info;
-  info->id = bankId;
-  // find the rotation to put the bank on the plane
-  info->rotation = calcBankRotation(pos0, normal);
-  // record the first detector index of the bank
-  info->startDetectorIndex = m_unwrappedDetectors.size();
-  // set the outline
-  QVector<QPointF> verts;
-  Mantid::Kernel::V3D pos = pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos1 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos2 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos3 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  info->polygon = QPolygonF(verts);
+boost::optional<std::pair<std::vector<size_t>, Mantid::Kernel::V3D>>
+PanelsSurface::findFlatPanels(size_t rootIndex,
+                              const std::vector<size_t> &children,
+                              std::vector<bool> &visited) {
+  const auto &componentInfo = m_instrActor->componentInfo();
+  auto parentIndex = componentInfo.parent(rootIndex);
+  auto componentType = componentInfo.componentType(parentIndex);
+  if (componentType == ComponentType::Rectangular ||
+      componentType == ComponentType::Structured) {
+    /* Do nothing until the root index of the structured bank. */
+    return boost::none;
+  }
 
-  int nelem = rectDetector->nelements();
-  m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem);
+  componentType = componentInfo.componentType(rootIndex);
+  if (componentType == ComponentType::Rectangular ||
+      componentType == ComponentType::Structured) {
+    processStructured(children, rootIndex);
+    for (auto child : children)
+      visited[child] = true;
+    return boost::none;
+  }
 
-  for (int i = 0; i < nx; ++i)
-    for (int j = 0; j < ny; ++j) {
-      Mantid::Geometry::IDetector_const_sptr det = rectDetector->getAtXY(i, j);
-      addDetector(*det, pos0, index, info->rotation);
-    }
+  if (componentType == ComponentType::OutlineComposite) {
+    processTubes(rootIndex, visited);
+    for (auto child : children)
+      visited[child] = true;
+    return boost::none;
+  }
 
-  // record the end detector index of the bank
-  info->endDetectorIndex = m_unwrappedDetectors.size();
+  return processUnstructured(children, rootIndex, visited);
 }
 
-/**
-* Add a structured detector which is flat.
-* @param bankId :: Component id of a structured detector.
-*/
-void PanelsSurface::addStructuredDetector(
-    Mantid::Geometry::ComponentID bankId) {
-  Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument();
-  Mantid::Geometry::StructuredDetector_const_sptr structDetector =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::StructuredDetector>(
-          instr->getComponentByID(bankId));
-
-  auto nx = structDetector->xPixels();
-  auto ny = structDetector->yPixels();
-  Mantid::Kernel::V3D pos0 = structDetector->getAtXY(0, 0)->getPos();
-  Mantid::Kernel::V3D pos1 = structDetector->getAtXY(nx - 1, 0)->getPos();
-  Mantid::Kernel::V3D pos2 = structDetector->getAtXY(nx - 1, ny - 1)->getPos();
-  Mantid::Kernel::V3D pos3 = structDetector->getAtXY(0, ny - 1)->getPos();
-
-  // find the normal
-  Mantid::Kernel::V3D xaxis = pos1 - pos0;
-  Mantid::Kernel::V3D yaxis = pos3 - pos0;
-  Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis);
-  normal.normalize();
-
-  int index = m_flatBanks.size();
-  // save bank info
-  FlatBankInfo *info = new FlatBankInfo(this);
-  m_flatBanks << info;
-  info->id = bankId;
-  // find the rotation to put the bank on the plane
-  info->rotation = calcBankRotation(pos0, normal);
-  // record the first detector index of the bank
-  info->startDetectorIndex = m_unwrappedDetectors.size();
-  // set the outline
-  QVector<QPointF> verts;
-  Mantid::Kernel::V3D pos = pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos1 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos2 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  pos = pos3 - pos0;
-  info->rotation.rotate(pos);
-  pos += pos0;
-  verts << QPointF(pos.X(), pos.Y());
-
-  info->polygon = QPolygonF(verts);
-
-  int nelem = structDetector->nelements();
-  m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem);
-
-  for (size_t i = 0; i < nx; ++i)
-    for (size_t j = 0; j < ny; ++j) {
-      Mantid::Geometry::IDetector_const_sptr det =
-          structDetector->getAtXY(i, j);
-      addDetector(*det, pos0, index, info->rotation);
+void PanelsSurface::constructFromComponentInfo() {
+  const auto &componentInfo = m_instrActor->componentInfo();
+  std::vector<bool> visited(componentInfo.size(), false);
+
+  for (size_t i = 0; i < componentInfo.size() - 1; ++i) {
+    auto children = componentInfo.detectorsInSubtree(i);
+
+    if (children.size() > 1 && !visited[i]) {
+      auto res = findFlatPanels(i, children, visited);
+      if (res != boost::none) {
+        std::vector<size_t> detectors;
+        Mantid::Kernel::V3D normal;
+        std::tie(detectors, normal) = res.get();
+        if (!detectors.empty())
+          addFlatBankOfDetectors(normal, detectors);
+      }
+    } else if (children.size() > 0 &&
+               componentInfo.parent(children[0]) == componentInfo.root()) {
+      auto child = children[0];
+      visited[child] = true;
     }
-
-  // record the end detector index of the bank
-  info->endDetectorIndex = m_unwrappedDetectors.size();
+  }
 }
 
 /**
@@ -624,17 +488,15 @@ PanelsSurface::calcBankRotation(const Mantid::Kernel::V3D &detPos,
   return Mantid::Kernel::Quat(normal, m_zaxis);
 }
 
-void PanelsSurface::addDetector(const Mantid::Geometry::IDetector &det,
+void PanelsSurface::addDetector(size_t detIndex,
                                 const Mantid::Kernel::V3D &refPos, int index,
                                 Mantid::Kernel::Quat &rotation) {
-  // setup detector info
-  Mantid::Kernel::V3D pos = det.getPos();
-  Mantid::detid_t detid = det.getID();
-  m_detector2bankMap[detid] = index;
+  const auto &detectorInfo = m_instrActor->detectorInfo();
+
+  Mantid::Kernel::V3D pos = detectorInfo.position(detIndex);
+  m_detector2bankMap[detIndex] = index;
   // get the colour
-  unsigned char color[3];
-  m_instrActor->getColor(detid).getUB3(&color[0]);
-  UnwrappedDetector udet(color, det);
+  UnwrappedDetector udet(m_instrActor->getColor(detIndex), detIndex);
   // apply bank's rotation
   pos -= refPos;
   rotation.rotate(pos);
@@ -643,7 +505,7 @@ void PanelsSurface::addDetector(const Mantid::Geometry::IDetector &det,
   udet.v = m_yaxis.scalar_prod(pos);
   udet.uscale = udet.vscale = 1.0;
   this->calcSize(udet);
-  m_unwrappedDetectors.push_back(udet);
+  m_unwrappedDetectors[detIndex] = udet;
 }
 
 /**
diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp
index 14d17c86f993b8d21c6d3cd98935c0e02c8a5176..d0bb629aa767e1e0430e352e2c3b827a7f38dc66 100644
--- a/qt/widgets/instrumentview/src/Projection3D.cpp
+++ b/qt/widgets/instrumentview/src/Projection3D.cpp
@@ -2,13 +2,12 @@
 #include <windows.h>
 #endif
 #include "MantidQtWidgets/InstrumentView/Projection3D.h"
-#include "MantidQtWidgets/InstrumentView/GLActor.h"
 #include "MantidQtWidgets/InstrumentView/GLColor.h"
 #include "MantidQtWidgets/InstrumentView/UnwrappedCylinder.h"
 #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h"
 #include "MantidQtWidgets/InstrumentView/OpenGLError.h"
 
-#include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidGeometry/Objects/CSGObject.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidQtWidgets/Common/InputController.h"
@@ -42,9 +41,6 @@ Projection3D::Projection3D(const InstrumentActor *rootActor, int winWidth,
                            int winHeight)
     : ProjectionSurface(rootActor), m_drawAxes(true), m_wireframe(false),
       m_viewport(0, 0) {
-
-  Instrument_const_sptr instr = rootActor->getInstrument();
-
   m_viewport.resize(winWidth, winHeight);
   V3D minBounds, maxBounds;
   m_instrActor->getBoundingBox(minBounds, maxBounds);
@@ -52,7 +48,6 @@ Projection3D::Projection3D(const InstrumentActor *rootActor, int winWidth,
   m_viewport.setProjection(minBounds, maxBounds);
 
   changeColorMap();
-  rootActor->invalidateDisplayLists();
 
   // create and connect the move input controller
   InputController3DMove *moveController = new InputController3DMove(this);
@@ -200,10 +195,10 @@ void Projection3D::setWireframe(bool on) { m_wireframe = on; }
 /** This seems to be called when the user has selected a rectangle
 * using the mouse.
 *
-* @param dets :: returns a list of detector IDs selected.
+* @param detIndices :: returns a list of detector Indices selected.
 */
-void Projection3D::getSelectedDetectors(QList<int> &dets) {
-  dets.clear();
+void Projection3D::getSelectedDetectors(std::vector<size_t> &detIndices) {
+  detIndices.clear();
   if (!hasSelection())
     return;
   double xmin, xmax, ymin, ymax, zmin, zmax;
@@ -218,16 +213,12 @@ void Projection3D::getSelectedDetectors(QList<int> &dets) {
   double yTop = ymin + (ymax - ymin) * (h - rect.top()) / h;
   size_t ndet = m_instrActor->ndetectors();
 
-  // Cache all the detector positions if needed. This is slow, but just once.
-  m_instrActor->cacheDetPos();
-
   for (size_t i = 0; i < ndet; ++i) {
-    detid_t detId = m_instrActor->getDetID(i);
     V3D pos = m_instrActor->getDetPos(i);
     m_viewport.transform(pos);
     if (pos.X() >= xLeft && pos.X() <= xRight && pos.Y() >= yBottom &&
         pos.Y() <= yTop) {
-      dets.push_back(detId);
+      detIndices.push_back(i);
     }
   }
 }
@@ -236,12 +227,9 @@ void Projection3D::getSelectedDetectors(QList<int> &dets) {
 /** Select detectors to mask, using the mouse.
 * From the Instrument Window's mask tab.
 *
-* @param dets :: returns a list of detector IDs to mask.
+* @param dets :: returns a list of detector Indices to mask.
 */
-void Projection3D::getMaskedDetectors(QList<int> &dets) const {
-  // Cache all the detector positions if needed. This is slow, but just once.
-  m_instrActor->cacheDetPos();
-
+void Projection3D::getMaskedDetectors(std::vector<size_t> &detIndices) const {
   // find the layer of visible detectors
   QList<QPoint> pixels = m_maskShapes.getMaskedPixels();
   double zmin = 1.0;
@@ -266,7 +254,7 @@ void Projection3D::getMaskedDetectors(QList<int> &dets) const {
   }
 
   // find masked detector in that layer
-  dets.clear();
+  detIndices.clear();
   if (m_maskShapes.isEmpty())
     return;
   size_t ndet = m_instrActor->ndetectors();
@@ -274,13 +262,12 @@ void Projection3D::getMaskedDetectors(QList<int> &dets) const {
     // Find the cached ID and position. This is much faster than getting the
     // detector.
     V3D pos = m_instrActor->getDetPos(i);
-    detid_t id = m_instrActor->getDetID(i);
     // project pos onto the screen plane
     m_viewport.transform(pos);
     if (pos.Z() < zmin || pos.Z() > zmax)
       continue;
     if (m_maskShapes.isMasked(pos.X(), pos.Y())) {
-      dets.push_back(int(id));
+      detIndices.push_back(i);
     }
   }
 }
@@ -289,19 +276,18 @@ void Projection3D::getMaskedDetectors(QList<int> &dets) const {
 * Orient the viewport to look at a selected component.
 * @param id :: The ID of a selected component.
 */
-void Projection3D::componentSelected(Mantid::Geometry::ComponentID id) {
+void Projection3D::componentSelected(size_t componentIndex) {
 
-  Instrument_const_sptr instr = m_instrActor->getInstrument();
+  const auto &componentInfo = m_instrActor->componentInfo();
 
-  if (id == NULL || id == instr->getComponentID()) {
+  if (componentIndex == componentInfo.root()) {
     m_viewport.reset();
     return;
   }
 
-  IComponent_const_sptr comp = instr->getComponentByID(id);
-  V3D pos = comp->getPos();
+  auto pos = componentInfo.position(componentIndex);
 
-  V3D compDir = comp->getPos() - instr->getSample()->getPos();
+  auto compDir = pos - componentInfo.samplePosition();
   compDir.normalize();
   V3D up(0, 0, 1);
   V3D x = up.cross_prod(compDir);
diff --git a/qt/widgets/instrumentview/src/ProjectionSurface.cpp b/qt/widgets/instrumentview/src/ProjectionSurface.cpp
index c8991e796c30f2bb22c570cc0f2fc16e8c56ba38..3d1b1eb45b31390c8029d0b0f783e68b3c6360f2 100644
--- a/qt/widgets/instrumentview/src/ProjectionSurface.cpp
+++ b/qt/widgets/instrumentview/src/ProjectionSurface.cpp
@@ -1,9 +1,10 @@
 #include "MantidQtWidgets/InstrumentView/ProjectionSurface.h"
 #include "MantidQtWidgets/Common/InputController.h"
+#include "MantidQtWidgets/Common/TSVSerialiser.h"
 #include "MantidQtWidgets/InstrumentView/GLColor.h"
+#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h"
 #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h"
 #include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-#include "MantidQtWidgets/Common/TSVSerialiser.h"
 
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/IPeaksWorkspace.h"
@@ -441,10 +442,8 @@ int ProjectionSurface::getDetectorID(int x, int y) const {
 }
 
 //------------------------------------------------------------------------------
-const Mantid::Geometry::IDetector &ProjectionSurface::getDetector(int x,
-                                                                  int y) const {
-  size_t pickID = getPickID(x, y);
-  return m_instrActor->getDetectorByPickID(pickID);
+size_t ProjectionSurface::getDetector(int x, int y) const {
+  return getPickID(x, y);
 }
 
 /**
@@ -500,7 +499,7 @@ size_t ProjectionSurface::getPickID(int x, int y) const {
   if (!m_pickImage || !m_pickImage->valid(x, y))
     return -1;
   QRgb pixel = m_pickImage->pixel(x, y);
-  return GLActor::decodePickColor(pixel);
+  return InstrumentRenderer::decodePickColor(pixel);
 }
 
 /**
@@ -769,7 +768,7 @@ void ProjectionSurface::clearComparisonPeaks() {
 */
 void ProjectionSurface::setPeakLabelPrecision(int n) {
   if (n < 1) {
-    QMessageBox::critical(NULL, "MantidPlot - Error",
+    QMessageBox::critical(nullptr, "MantidPlot - Error",
                           "Precision must be a positive number");
     return;
   }
diff --git a/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp b/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp
deleted file mode 100644
index 3f4bc833162df9048735dbda105c0ac088ac187f..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-
-#include "MantidKernel/V3D.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidGeometry/Objects/BoundingBox.h"
-#include "MantidGeometry/ICompAssembly.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Instrument/RectangularDetector.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidKernel/Exception.h"
-#include <cfloat>
-#include "MantidGeometry/IComponent.h"
-using namespace Mantid;
-using namespace Geometry;
-using Mantid::Kernel::V3D;
-using Mantid::Kernel::Quat;
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-static const bool VERBOSE = false;
-
-/**
-* Constructor.
-*
-* @param instrActor :: the instrument actor
-* @param compID :: the component ID
-*/
-RectangularDetectorActor::RectangularDetectorActor(
-    const InstrumentActor &instrActor,
-    const Mantid::Geometry::ComponentID &compID)
-    : ICompAssemblyActor(instrActor, compID), mTextureID(0),
-      image_data(nullptr), pick_data(nullptr) {
-  mNumberOfDetectors = 0;
-  mDet = boost::dynamic_pointer_cast<const RectangularDetector>(getComponent());
-
-  if (!mDet)
-    return;
-
-  BoundingBox compBox;
-  mDet->getBoundingBox(compBox);
-  mNumberOfDetectors = mDet->xpixels() * mDet->ypixels();
-  this->AppendBoundingBox(compBox.minPoint(), compBox.maxPoint());
-
-  std::vector<GLColor> clist;
-  for (int y = 0; y < mDet->ypixels(); y++) {
-    for (int x = 0; x < mDet->xpixels(); x++) {
-      // Getting the detector is slow. Get the ID directly
-      detid_t id = mDet->getDetectorIDAtXY(x, y);
-      size_t pickID = instrActor.pushBackDetid(id);
-      m_pickIDs.push_back(pickID);
-      clist.push_back(instrActor.getColor(id));
-    }
-  }
-
-  genTexture(image_data, clist, false);
-  genTexture(pick_data, clist, true);
-  uploadTexture(image_data);
-}
-
-//-------------------------------------------------------------------------------------------------
-/**
-* Destructor which removes the actors created by this object
-*/
-RectangularDetectorActor::~RectangularDetectorActor() {
-  delete[] image_data;
-  delete[] pick_data;
-}
-
-//-------------------------------------------------------------------------------------------------
-/**
-* This function is concrete implementation that renders the Child ObjComponents
-* and Child CompAssembly's
-*/
-void RectangularDetectorActor::draw(bool picking) const {
-  if (VERBOSE)
-    std::cout << "RectangularDetectorActor::define() called for "
-              << mDet->getName() << "\n";
-
-  glPushMatrix();
-  // Translation first
-  V3D pos = mDet->getPos();
-  if (!(pos.nullVector())) {
-    glTranslated(pos[0], pos[1], pos[2]);
-  }
-  // Rotation
-  Quat rot = mDet->getRotation();
-  if (!(rot.isNull())) {
-    double deg, ax0, ax1, ax2;
-    rot.getAngleAxis(deg, ax0, ax1, ax2);
-    glRotated(deg, ax0, ax1, ax2);
-  }
-  // Scale
-  V3D scaleFactor = mDet->getScaleFactor();
-  if (!(scaleFactor == V3D(1, 1, 1))) {
-    glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  }
-
-  // glBindTexture(GL_TEXTURE_2D, mTextureID);
-  if (picking) {
-    this->uploadTexture(pick_data);
-  } else {
-    this->uploadTexture(image_data);
-  }
-  // RectangularDetector will use.
-  mDet->draw();
-  glBindTexture(GL_TEXTURE_2D, 0);
-
-  glPopMatrix();
-}
-
-//------------------------------------------------------------------------------------------------
-/**
-* Accept a visitor. This sets the matching component's visibility to True.
-* It looks if the given component is a child (pixel) of the parent rectangular
-* detector, and sets the visibility of the whole panel to true if so.
-*
-* @param visitor :: A visitor.
-* @param rule :: A rule defining visitor acceptance by assembly actors. Unused.
-*
-*/
-bool RectangularDetectorActor::accept(GLActorVisitor &visitor,
-                                      VisitorAcceptRule) {
-  return visitor.visit(this);
-}
-
-bool RectangularDetectorActor::accept(GLActorConstVisitor &visitor,
-                                      GLActor::VisitorAcceptRule) const {
-  return visitor.visit(this);
-}
-
-bool RectangularDetectorActor::isChildDetector(const ComponentID &id) const {
-  // ID of the parent RectangularDetector
-  Mantid::Geometry::ComponentID thisID = this->m_id;
-
-  // Get the component object
-  IComponent_const_sptr comp =
-      m_instrActor.getInstrument()->getComponentByID(id);
-  if (comp) {
-    // Get the parent (e.g. the column)
-    IComponent_const_sptr parent1 = comp->getParent();
-    if (parent1) {
-      if (parent1->getComponentID() == thisID) {
-        return true;
-      }
-      // Go to grandparent
-      IComponent_const_sptr parent2 = parent1->getParent();
-      if (parent2) {
-        if (parent2->getComponentID() == thisID) {
-          return true;
-        }
-      } // valid grandparent
-    }   // valid parent
-  }     // valid component
-  return false;
-}
-
-//------------------------------------------------------------------------------------------------
-/**
-* Generate a texture for the RectangularDetector
-*
-* @param image_data :: pointer to where the image data will be filled in.
-* @param list :: Color list iterator. Only used if useDetectorIDs is false.
-* @param useDetectorIDs :: set to true to make a fake texture using the detector
-*IDs. If false, the iterator is used.
-*
-*/
-int RectangularDetectorActor::genTexture(char *&image_data,
-                                         std::vector<GLColor> &list,
-                                         bool useDetectorIDs) {
-  int num = mDet->xpixels() * mDet->ypixels();
-
-  // The texture size must be 2^n power.
-  int text_x_size, text_y_size;
-  mDet->getTextureSize(text_x_size, text_y_size);
-
-  // std::cerr << "Texture size: " << text_x_size << ',' << text_y_size
-  // <<'\n';
-
-  //------ Create the image data buffer -------
-  if (!image_data) {
-    // Delete the old memory
-    delete[] image_data;
-    image_data = new char[3 * text_x_size * text_y_size];
-  }
-  // Pointer to where we are in it.
-  char *image_data_ptr = image_data;
-
-  // Fill with 0 (black) everywhere
-  std::fill(image_data, image_data + 3 * text_x_size * text_y_size, 0);
-
-  // For using color IDs
-  int rgb = 0;
-  std::vector<GLColor>::iterator list_it = list.begin();
-
-  for (int y = 0; y < mDet->ypixels(); y++) {
-    for (int x = 0; x < mDet->xpixels(); x++) {
-      // Use black as the default color (for going off the edges)
-      unsigned char r, g, b;
-
-      if (useDetectorIDs) {
-        GLColor c = GLActor::makePickColor(m_pickIDs[rgb]);
-        c.get(r, g, b);
-        rgb++;
-      } else {
-        // Get the current color
-        list_it->get(r, g, b);
-        // Go to the next color
-        ++list_it;
-      }
-
-      //      //TEMP: way to show the colors
-      //      r=x;
-      //      g=y;
-      //      b=x;
-
-      // Save the color data to the buffer
-      *image_data_ptr = r;
-      image_data_ptr++;
-      *image_data_ptr = g;
-      image_data_ptr++;
-      *image_data_ptr = b;
-      image_data_ptr++;
-    }
-
-    // Skip any padding in x. 3 bytes per pixel
-    image_data_ptr += 3 * (text_x_size - mDet->xpixels());
-  }
-
-  if (VERBOSE)
-    std::cout << "RectangularDetectorActor::genTexture() called for "
-              << mDet->getName() << " with " << num << " entries set\n";
-
-  return num;
-}
-
-//------------------------------------------------------------------------------------------------
-/** Upload the texture to the video card. */
-void RectangularDetectorActor::uploadTexture(char *&image_data) const {
-  if (!image_data)
-    throw std::runtime_error(
-        "Empty pointer passed to RectangularDetectorActor::uploadTexture()!");
-
-  // The texture size must be 2^n power.
-  int text_x_size, text_y_size;
-  mDet->getTextureSize(text_x_size, text_y_size);
-
-  // Set up before uploading a texture
-  if (mTextureID > 0)
-    glDeleteTextures(1, &mTextureID);
-  glGenTextures(1, &mTextureID); // Create The Texture
-  if (VERBOSE)
-    std::cout << mDet->getName() << " is drawing with texture id " << mTextureID
-              << "\n";
-  // mDet->setTextureID(mTextureID);
-
-  glBindTexture(GL_TEXTURE_2D, mTextureID);
-
-  if (glGetError() > 0)
-    std::cout << "OpenGL error in glBindTexture \n";
-
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
-            GL_MODULATE); // This one allows lighting effects
-  // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //This one
-  // doesn't
-
-  // Upload the texture to video card
-  if (glGetError() > 0)
-    std::cout << "OpenGL error BEFORE glTexImage2D \n";
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, text_x_size, text_y_size, 0, GL_RGB,
-               GL_UNSIGNED_BYTE, image_data);
-  if (glGetError() > 0)
-    std::cout << "OpenGL error in glTexImage2D \n";
-}
-
-//-------------------------------------------------------------------------------------------------
-/**
-* Return the bounding box, from the one calculated in the cache previously.
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void RectangularDetectorActor::getBoundingBox(
-    Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const {
-  minBound = minBoundBox;
-  maxBound = maxBoundBox;
-}
-
-/**
-* Append the bounding box CompAssembly bounding box
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void RectangularDetectorActor::AppendBoundingBox(
-    const Mantid::Kernel::V3D &minBound, const Mantid::Kernel::V3D &maxBound) {
-  if (minBoundBox[0] > minBound[0])
-    minBoundBox[0] = minBound[0];
-  if (minBoundBox[1] > minBound[1])
-    minBoundBox[1] = minBound[1];
-  if (minBoundBox[2] > minBound[2])
-    minBoundBox[2] = minBound[2];
-  if (maxBoundBox[0] < maxBound[0])
-    maxBoundBox[0] = maxBound[0];
-  if (maxBoundBox[1] < maxBound[1])
-    maxBoundBox[1] = maxBound[1];
-  if (maxBoundBox[2] < maxBound[2])
-    maxBoundBox[2] = maxBound[2];
-}
-
-void RectangularDetectorActor::setColors() {
-  std::vector<GLColor> clist;
-  for (int y = 0; y < mDet->ypixels(); y++) {
-    for (int x = 0; x < mDet->xpixels(); x++) {
-      detid_t id = mDet->getDetectorIDAtXY(x, y);
-      clist.push_back(m_instrActor.getColor(id));
-    }
-  }
-  genTexture(image_data, clist, false);
-  uploadTexture(image_data);
-}
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp
index 0f3bea59cdd292bc6b920915c1ebb33538af9357..a9288fabceb2e7110972539c8d0010d6e9ae6ad3 100644
--- a/qt/widgets/instrumentview/src/RotationSurface.cpp
+++ b/qt/widgets/instrumentview/src/RotationSurface.cpp
@@ -1,7 +1,9 @@
 #include "MantidQtWidgets/InstrumentView/RotationSurface.h"
+#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h"
 #include "MantidKernel/Logger.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 
 #include <QCursor>
 #include <QMessageBox>
@@ -29,7 +31,6 @@ RotationSurface::RotationSurface(const InstrumentActor *rootActor,
 void RotationSurface::init() {
   // the actor calls this->callback for each detector
   m_unwrappedDetectors.clear();
-  m_assemblies.clear();
 
   // if u-correction is applied manually then m_u_min and m_u_max
   // have valid values and have to be saved
@@ -41,12 +42,6 @@ void RotationSurface::init() {
   if (ndet == 0)
     return;
 
-  // Pre-calculate all the detector positions (serial because
-  // I suspect the IComponent->getPos() method to not be properly thread safe)
-  m_instrActor->cacheDetPos();
-
-  Instrument_const_sptr inst = m_instrActor->getInstrument();
-
   // First detector defines the surface's x axis
   if (m_xaxis.nullVector()) {
     Mantid::Kernel::V3D pos = m_instrActor->getDetPos(0) - m_pos;
@@ -78,8 +73,8 @@ void RotationSurface::init() {
   m_u_min = -DBL_MAX;
   m_u_max = DBL_MAX;
 
-  const auto &detectorInfo = m_instrActor->getWorkspace()->detectorInfo();
-
+  const auto &detectorInfo = m_instrActor->detectorInfo();
+  const auto &detIds = detectorInfo.detectorIDs();
   // Set if one of the threads in the following loop
   // throws an exception
   bool exceptionThrown = false;
@@ -91,36 +86,20 @@ void RotationSurface::init() {
                           if (!exceptionThrown)
                             try {
                               size_t i = size_t(ii);
-
-                              unsigned char color[3];
-                              Mantid::detid_t id = m_instrActor->getDetID(i);
-
                               try {
-                                auto &det =
-                                    m_instrActor->getDetectorByDetID(id);
-
-                                if (detectorInfo.isMonitor(
-                                        detectorInfo.indexOf(id)) ||
-                                    (id < 0)) {
-                                  // Not a detector or a monitor
-                                  // Make some blank, empty thing that won't
-                                  // draw
+                                if (detectorInfo.isMonitor(i) ||
+                                    detIds[i] < 0) {
                                   m_unwrappedDetectors[i] = UnwrappedDetector();
                                 } else {
                                   // A real detector.
-                                  m_instrActor->getColor(id).getUB3(&color[0]);
-
                                   // Position, relative to origin
-                                  // Mantid::Kernel::V3D pos = det->getPos() -
-                                  // m_pos;
-                                  Mantid::Kernel::V3D pos =
-                                      m_instrActor->getDetPos(i) - m_pos;
-
+                                  auto rpos = detectorInfo.position(i) - m_pos;
                                   // Create the unwrapped shape
-                                  UnwrappedDetector udet(&color[0], det);
+                                  UnwrappedDetector udet(
+                                      m_instrActor->getColor(i), i);
                                   // Calculate its position/size in UV
                                   // coordinates
-                                  this->calcUV(udet, pos);
+                                  this->calcUV(udet, rpos);
 
                                   m_unwrappedDetectors[i] = udet;
                                 } // is a real detector
@@ -209,7 +188,8 @@ void RotationSurface::findUVBounds() {
   m_v_max = -DBL_MAX;
   for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) {
     const UnwrappedDetector &udet = m_unwrappedDetectors[i];
-    if (!udet.isValid())
+    if (udet.empty() ||
+        !m_instrActor->componentInfo().hasValidShape(udet.detIndex))
       continue;
     if (udet.u < m_u_min)
       m_u_min = udet.u;
@@ -239,12 +219,11 @@ void RotationSurface::findAndCorrectUGap() {
     return;
   }
 
-  std::vector<UnwrappedDetector>::const_iterator ud =
-      m_unwrappedDetectors.begin();
-  for (; ud != m_unwrappedDetectors.end(); ++ud) {
-    if (!ud->isValid())
+  for (const auto &udet : m_unwrappedDetectors) {
+    if (udet.empty() ||
+        !m_instrActor->componentInfo().hasValidShape(udet.detIndex))
       continue;
-    double u = ud->u;
+    double u = udet.u;
     int i = int((u - m_u_min) / bin_width);
     ubins[i] = true;
   }
@@ -278,11 +257,11 @@ void RotationSurface::findAndCorrectUGap() {
       m_u_max += period;
     }
 
-    std::vector<UnwrappedDetector>::iterator ud = m_unwrappedDetectors.begin();
-    for (; ud != m_unwrappedDetectors.end(); ++ud) {
-      if (!ud->isValid())
+    for (auto &udet : m_unwrappedDetectors) {
+      if (udet.empty() ||
+          !m_instrActor->componentInfo().hasValidShape(udet.detIndex))
         continue;
-      double &u = ud->u;
+      double &u = udet.u;
       u = applyUCorrection(u);
     }
   }
diff --git a/qt/widgets/instrumentview/src/SampleActor.cpp b/qt/widgets/instrumentview/src/SampleActor.cpp
deleted file mode 100644
index a2fc83fe23be649801ac7519e0e83cd5e686b3e2..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/SampleActor.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/SampleActor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/OpenGLError.h"
-
-#include "MantidAPI/Sample.h"
-#include "MantidGeometry/IObjComponent.h"
-
-using namespace Mantid;
-using namespace Geometry;
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-SampleActor::SampleActor(const InstrumentActor &instrActor,
-                         const Mantid::API::Sample &sample,
-                         const ObjComponentActor *samplePosActor)
-    : GLActor(), m_instrActor(instrActor), m_sample(sample),
-      m_samplePosActor(samplePosActor),
-      m_samplePos(samplePosActor->getObjComponent()), m_color(255, 255, 255) {}
-
-/**
-* Implementation of rendering Sample.
-*/
-void SampleActor::draw(bool picking) const {
-  if (!picking && isVisible()) {
-    OpenGLError::check("SampleActor::draw()");
-    glPushAttrib(GL_ENABLE_BIT);
-    GLboolean hasLight0;
-    glGetBooleanv(GL_LIGHT0, &hasLight0);
-    if (hasLight0) {
-      glEnable(GL_LIGHTING);
-    }
-    glPushMatrix();
-    m_color.paint();
-    Mantid::Kernel::V3D pos = m_samplePos->getPos();
-    glTranslated(pos.X(), pos.Y(), pos.Z());
-    m_sample.getShape().draw();
-    glPopMatrix();
-    glPopAttrib();
-    OpenGLError::check("SampleActor::draw()");
-  }
-}
-
-void SampleActor::getBoundingBox(Mantid::Kernel::V3D &minBound,
-                                 Mantid::Kernel::V3D &maxBound) const {
-  Mantid::Geometry::BoundingBox boundBox = m_sample.getShape().getBoundingBox();
-  minBound = boundBox.minPoint();
-  maxBound = boundBox.maxPoint();
-}
-} // MantidWidgets
-} // MantidQt
diff --git a/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp b/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp
deleted file mode 100644
index 5e539f666986cd5ba7b76532a29399218b0967d2..0000000000000000000000000000000000000000
--- a/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h"
-#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
-#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h"
-#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h"
-
-#include "MantidGeometry/ICompAssembly.h"
-#include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/StructuredDetector.h"
-#include "MantidGeometry/Objects/BoundingBox.h"
-#include "MantidGeometry/Objects/CSGObject.h"
-#include "MantidKernel/Exception.h"
-#include "MantidKernel/V3D.h"
-#include <cfloat>
-using namespace Mantid;
-using namespace Geometry;
-using Mantid::Kernel::V3D;
-using Mantid::Kernel::Quat;
-
-namespace MantidQt {
-namespace MantidWidgets {
-
-/**
-* Constructor.
-*
-* @param instrActor :: the instrument actor
-* @param compID :: the component ID
-*/
-StructuredDetectorActor::StructuredDetectorActor(
-    const InstrumentActor &instrActor,
-    const Mantid::Geometry::ComponentID &compID)
-    : ICompAssemblyActor(instrActor, compID) {
-
-  mNumberOfDetectors = 0;
-  m_det = boost::dynamic_pointer_cast<const StructuredDetector>(getComponent());
-
-  if (!m_det)
-    return;
-
-  BoundingBox compBox;
-  m_det->getBoundingBox(compBox);
-  mNumberOfDetectors = m_det->xPixels() * m_det->yPixels();
-  this->AppendBoundingBox(compBox.minPoint(), compBox.maxPoint());
-
-  for (size_t y = 0; y < m_det->yPixels(); y++) {
-    for (size_t x = 0; x < m_det->xPixels(); x++) {
-      // Getting the detector is slow. Get the ID directly
-      detid_t id = m_det->getDetectorIDAtXY(x, y);
-      size_t pickID = instrActor.pushBackDetid(id);
-      m_pickIds.push_back(pickID);
-      m_pickColors.push_back(GLActor::makePickColor(pickID));
-      m_clist.push_back(instrActor.getColor(id));
-    }
-  }
-}
-
-/**
-* Destructor which removes the actors created by this object
-*/
-StructuredDetectorActor::~StructuredDetectorActor() {}
-
-void StructuredDetectorActor::draw(bool picking) const {
-  glPushMatrix();
-  // Translation first
-  V3D pos = m_det->getPos();
-  if (!(pos.nullVector())) {
-    glTranslated(pos[0], pos[1], pos[2]);
-  }
-  // Rotation
-  Quat rot = m_det->getRotation();
-  if (!(rot.isNull())) {
-    double deg, ax0, ax1, ax2;
-    rot.getAngleAxis(deg, ax0, ax1, ax2);
-    glRotated(deg, ax0, ax1, ax2);
-  }
-  // Scale
-  V3D scaleFactor = m_det->getScaleFactor();
-  if (!(scaleFactor == V3D(1, 1, 1))) {
-    glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
-  }
-
-  // StructuredDetector will use.
-  std::vector<int> r, g, b;
-
-  if (picking) {
-    for (std::vector<GLColor>::const_iterator i = m_pickColors.cbegin();
-         i != m_pickColors.cend(); ++i) {
-      r.push_back((*i).red());
-      g.push_back((*i).green());
-      b.push_back((*i).blue());
-    }
-  } else {
-    for (std::vector<GLColor>::const_iterator i = m_clist.cbegin();
-         i != m_clist.cend(); ++i) {
-      r.push_back((*i).red());
-      g.push_back((*i).green());
-      b.push_back((*i).blue());
-    }
-  }
-
-  m_det->setColors(r, g, b);
-  m_det->draw();
-
-  glPopMatrix();
-}
-
-/**
-* Accept a visitor. This sets the matching component's visibility to True.
-* It looks if the given component is a child (pixel) of the parent rectangular
-* detector, and sets the visibility of the whole panel to true if so.
-*
-* @param visitor :: A visitor.
-* @param rule :: A rule defining visitor acceptance by assembly actors. Unused.
-*
-*/
-bool StructuredDetectorActor::accept(GLActorVisitor &visitor,
-                                     VisitorAcceptRule) {
-  return visitor.visit(this);
-}
-
-bool StructuredDetectorActor::accept(GLActorConstVisitor &visitor,
-                                     VisitorAcceptRule) const {
-  return visitor.visit(this);
-}
-
-bool StructuredDetectorActor::isChildDetector(
-    const Mantid::Geometry::ComponentID &id) const {
-  // ID of the parent RectangularDetector
-  Mantid::Geometry::ComponentID thisID = this->m_id;
-
-  // Get the component object
-  IComponent_const_sptr comp =
-      m_instrActor.getInstrument()->getComponentByID(id);
-  if (comp) {
-    // Get the parent (e.g. the column)
-    IComponent_const_sptr parent1 = comp->getParent();
-    if (parent1) {
-      if (parent1->getComponentID() == thisID) {
-        return true;
-      }
-      // Go to grandparent
-      IComponent_const_sptr parent2 = parent1->getParent();
-      if (parent2) {
-        if (parent2->getComponentID() == thisID) {
-          return true;
-        }
-      } // valid grandparent
-    }   // valid parent
-  }     // valid component
-  return false;
-}
-
-//-------------------------------------------------------------------------------------------------
-/**
-* Return the bounding box, from the one calculated in the cache previously.
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void StructuredDetectorActor::getBoundingBox(
-    Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const {
-  minBound = minBoundBox;
-  maxBound = maxBoundBox;
-}
-
-/**
-* Append the bounding box CompAssembly bounding box
-* @param minBound :: min point of the bounding box
-* @param maxBound :: max point of the bounding box
-*/
-void StructuredDetectorActor::AppendBoundingBox(
-    const Mantid::Kernel::V3D &minBound, const Mantid::Kernel::V3D &maxBound) {
-  if (minBoundBox[0] > minBound[0])
-    minBoundBox[0] = minBound[0];
-  if (minBoundBox[1] > minBound[1])
-    minBoundBox[1] = minBound[1];
-  if (minBoundBox[2] > minBound[2])
-    minBoundBox[2] = minBound[2];
-  if (maxBoundBox[0] < maxBound[0])
-    maxBoundBox[0] = maxBound[0];
-  if (maxBoundBox[1] < maxBound[1])
-    maxBoundBox[1] = maxBound[1];
-  if (maxBoundBox[2] < maxBound[2])
-    maxBoundBox[2] = maxBound[2];
-}
-
-void StructuredDetectorActor::setColors() {
-  // do nothing
-}
-
-} // namespace MantidWidgets
-} // namespace MantidQt
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp
index ce2f3e4277af1a3bfeaf6697feedfa9a7416d84d..c7c8e5cacd04d30ec644c396119ed411aff42e5d 100644
--- a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp
+++ b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtWidgets/InstrumentView/UnwrappedCylinder.h"
+#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h"
 
-#include "MantidGeometry/IDetector.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 
 namespace MantidQt {
 namespace MantidWidgets {
@@ -38,10 +39,11 @@ void UnwrappedCylinder::rotate(const UnwrappedDetector &udet,
                                Mantid::Kernel::Quat &R) const {
   // direction in which to look
   Mantid::Kernel::V3D eye;
+  const auto &componentInfo = m_instrActor->componentInfo();
   // rotation from the global axes to those where
   // the z axis points to the detector
   Mantid::Kernel::Quat R1;
-  eye = m_pos - udet.position;
+  eye = m_pos - componentInfo.position(udet.detIndex);
   if (!eye.nullVector()) {
     // eye must point towards the detector and be perpendicular to the
     // cylinder's axis
@@ -54,7 +56,7 @@ void UnwrappedCylinder::rotate(const UnwrappedDetector &udet,
     }
   }
   // add detector's own rotation
-  R = R1 * udet.rotation;
+  R = R1 * componentInfo.rotation(udet.detIndex);
 }
 
 } // MantidWidgets
diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3ad0c7281581027e2e9e651d5dd8a201213c7aa
--- /dev/null
+++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp
@@ -0,0 +1,45 @@
+#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h"
+#include "MantidGeometry/IDetector.h"
+#include "MantidGeometry/Objects/CSGObject.h"
+
+using namespace Mantid::Geometry;
+
+namespace MantidQt {
+namespace MantidWidgets {
+
+UnwrappedDetector::UnwrappedDetector()
+    : u(0), v(0), width(0), height(0), uscale(0), vscale(0) {
+  color = GLColor(0, 0, 0);
+}
+
+UnwrappedDetector::UnwrappedDetector(GLColor color, size_t detIndex)
+    : u(0), v(0), width(0), height(0), uscale(0), vscale(0),
+      detIndex(detIndex) {
+  this->color = color;
+}
+
+/** Copy constructor */
+UnwrappedDetector::UnwrappedDetector(const UnwrappedDetector &other) {
+  this->operator=(other);
+}
+
+/** Assignment operator */
+UnwrappedDetector &UnwrappedDetector::
+operator=(const UnwrappedDetector &other) {
+  color = other.color;
+  u = other.u;
+  v = other.v;
+  width = other.width;
+  height = other.height;
+  uscale = other.uscale;
+  vscale = other.vscale;
+  detIndex = other.detIndex;
+  return *this;
+}
+
+bool UnwrappedDetector::empty() const {
+  return detIndex == std::numeric_limits<size_t>::max();
+}
+
+} // namespace MantidWidgets
+} // namespace MantidQt
\ No newline at end of file
diff --git a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp
index 71ad108ce3c72c027c9debeec868592b97e8dac8..9f142e6577b76a665448975912cddf38838b3c3c 100644
--- a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp
+++ b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp
@@ -1,5 +1,6 @@
 #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h"
-#include "MantidGeometry/IDetector.h"
+#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include <cmath>
 
 namespace MantidQt {
@@ -43,12 +44,13 @@ void UnwrappedSphere::rotate(const UnwrappedDetector &udet,
   Mantid::Kernel::Quat R1;
   // direction in which to look: from sample to detector
   Mantid::Kernel::V3D eye;
-  eye = m_pos - udet.position;
+  const auto &componentInfo = m_instrActor->componentInfo();
+  eye = m_pos - componentInfo.position(udet.detIndex);
   if (!eye.nullVector()) {
     InstrumentActor::rotateToLookAt(eye, m_zaxis, R1);
   }
   // add detector's own rotation
-  R = R1 * udet.rotation;
+  R = R1 * componentInfo.rotation(udet.detIndex);
 }
 
 } // MantidWidgets
diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp
index 5bf94a32d8d1c05a43f9173523a37cac22567c76..2e4efc1da7030aaea1c8879c5a91be90dc3bf91e 100644
--- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp
+++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp
@@ -1,82 +1,47 @@
 #include "MantidQtWidgets/InstrumentView/UnwrappedSurface.h"
 #include "MantidQtWidgets/InstrumentView/GLColor.h"
+#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h"
 #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h"
 #include "MantidQtWidgets/InstrumentView/OpenGLError.h"
 #include "MantidQtWidgets/InstrumentView/PeakMarker2D.h"
 
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/DetectorInfo.h"
+#include "MantidGeometry/Instrument/ComponentInfo.h"
 #include "MantidGeometry/Objects/CSGObject.h"
 #include "MantidQtWidgets/Common/InputController.h"
 
-#include <QRgb>
-#include <QSet>
 #include <QMenu>
 #include <QMouseEvent>
 #include <QApplication>
-#include <QMessageBox>
 #include <QTransform>
 
 #include <cfloat>
 #include <limits>
 #include <cmath>
-#include "MantidKernel/Exception.h"
 
 using namespace Mantid::Geometry;
 
 namespace MantidQt {
 namespace MantidWidgets {
-
-UnwrappedDetector::UnwrappedDetector()
-    : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0) {
-  color[0] = 0;
-  color[1] = 0;
-  color[2] = 0;
-}
-
-UnwrappedDetector::UnwrappedDetector(const unsigned char *c,
-                                     const IDetector &det)
-    : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(det.getID()),
-      position(det.getPos()), rotation(det.getRotation()), shape(det.shape()),
-      scaleFactor(det.getScaleFactor()) {
-  color[0] = *c;
-  color[1] = *(c + 1);
-  color[2] = *(c + 2);
-}
-
-/** Copy constructor */
-UnwrappedDetector::UnwrappedDetector(const UnwrappedDetector &other) {
-  this->operator=(other);
-}
-
-/** Assignment operator */
-UnwrappedDetector &UnwrappedDetector::
-operator=(const UnwrappedDetector &other) {
-  color[0] = other.color[0];
-  color[1] = other.color[1];
-  color[2] = other.color[2];
-  u = other.u;
-  v = other.v;
-  width = other.width;
-  height = other.height;
-  uscale = other.uscale;
-  vscale = other.vscale;
-  detID = other.detID;
-  position = other.position;
-  rotation = other.rotation;
-  shape = other.shape;
-  scaleFactor = other.scaleFactor;
-  return *this;
+namespace {
+
+QRectF getArea(const UnwrappedDetector &udet, double maxWidth,
+               double maxHeight) {
+  auto w = udet.width;
+  if (w > maxWidth)
+    w = maxWidth;
+  auto h = udet.height;
+  if (h > maxHeight)
+    h = maxHeight;
+  return QRectF(udet.u - w, udet.v - h, w * 2, h * 2);
 }
-
-/** Check if the object is valid*/
-bool UnwrappedDetector::isValid() const { return static_cast<bool>(shape); }
-
-/**
-* Constructor.
-* @param rootActor :: The instrument actor.
-*/
+} // namespace
+  /**
+   * Constructor.
+   * @param rootActor :: The instrument actor.
+   */
 UnwrappedSurface::UnwrappedSurface(const InstrumentActor *rootActor)
     : ProjectionSurface(rootActor), m_u_min(DBL_MAX), m_u_max(-DBL_MAX),
       m_v_min(DBL_MAX), m_v_max(-DBL_MAX), m_height_max(0), m_width_max(0),
@@ -103,52 +68,6 @@ QString UnwrappedSurface::getDimInfo() const {
       .arg(m_viewRect.y1());
 }
 
-//------------------------------------------------------------------------------
-/** Calculate the rectangular region in uv coordinates occupied by an assembly.
-*
-* @param comp :: A member of the assembly. The total area of the assembly is a
-*sum of areas of its members
-* @param compRect :: A rect. area occupied by comp in uv space
-*/
-void UnwrappedSurface::calcAssemblies(const Mantid::Geometry::IComponent *comp,
-                                      const QRectF &compRect) {
-  // We don't need the parametrized version = use the bare parent for speed
-  const Mantid::Geometry::IComponent *parent = comp->getBareParent();
-  if (parent) {
-    QRectF &r = m_assemblies[parent->getComponentID()];
-    r |= compRect;
-    calcAssemblies(parent, r);
-  }
-}
-
-//------------------------------------------------------------------------------
-/** If needed, recalculate the cached bounding rectangles of all assemblies. */
-void UnwrappedSurface::cacheAllAssemblies() {
-  if (!m_assemblies.empty())
-    return;
-
-  for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) {
-    const UnwrappedDetector &udet = m_unwrappedDetectors[i];
-    if (!udet.isValid())
-      continue;
-    // Get the BARE parent (not parametrized) to speed things up.
-    auto &detector = m_instrActor->getDetectorByDetID(udet.detID);
-    const Mantid::Geometry::IComponent *bareDet = detector.getComponentID();
-    const Mantid::Geometry::IComponent *parent = bareDet->getBareParent();
-    if (parent) {
-      QRectF detRect;
-      detRect.setLeft(udet.u - udet.width);
-      detRect.setRight(udet.u + udet.width);
-      detRect.setBottom(udet.v - udet.height);
-      detRect.setTop(udet.v + udet.height);
-      Mantid::Geometry::ComponentID id = parent->getComponentID();
-      QRectF &r = m_assemblies[id];
-      r |= detRect;
-      calcAssemblies(parent, r);
-    }
-  }
-}
-
 //------------------------------------------------------------------------------
 /**
 * Draw the unwrapped instrument onto the screen
@@ -220,10 +139,9 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const {
     glShadeModel(GL_FLAT);
   }
 
-  for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) {
-    const UnwrappedDetector &udet = m_unwrappedDetectors[i];
-
-    if (!udet.isValid())
+  const auto &componentInfo = m_instrActor->componentInfo();
+  for (const auto &udet : m_unwrappedDetectors) {
+    if (udet.empty() || !componentInfo.hasValidShape(udet.detIndex))
       continue;
 
     int iw = int(udet.width / dw);
@@ -237,7 +155,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const {
       continue;
 
     // apply the detector's colour
-    setColor(int(i), picking);
+    setColor(udet.detIndex, picking);
 
     // if the detector is too small to see its shape draw a rectangle
     if (iw < 6 || ih < 6) {
@@ -261,10 +179,11 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const {
       rot.getAngleAxis(deg, ax0, ax1, ax2);
       glRotated(deg, ax0, ax1, ax2);
 
-      Mantid::Kernel::V3D scaleFactor = udet.scaleFactor;
+      Mantid::Kernel::V3D scaleFactor =
+          componentInfo.scaleFactor(udet.detIndex);
       glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]);
 
-      udet.shape->draw();
+      m_instrActor->componentInfo().shape(udet.detIndex).draw();
 
       glPopMatrix();
     }
@@ -285,14 +204,16 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const {
 * @param picking :: True if detector is being drawn in the picking mode.
 *   In this case index is transformed into color
 */
-void UnwrappedSurface::setColor(int index, bool picking) const {
+void UnwrappedSurface::setColor(size_t index, bool picking) const {
   if (picking) {
-    GLColor c = GLActor::makePickColor(index);
+    auto c = InstrumentRenderer::makePickColor(index);
     unsigned char r, g, b;
     c.get(r, g, b);
     glColor3ub(r, g, b);
   } else {
-    glColor3ubv(&m_unwrappedDetectors[index].color[0]);
+    unsigned char col[3];
+    m_unwrappedDetectors[index].color.getUB3(&col[0]);
+    glColor3ub(col[0], col[1], col[2]);
   }
 }
 
@@ -314,51 +235,28 @@ bool hasParent(boost::shared_ptr<const Mantid::Geometry::IComponent> comp,
 *
 * @param id :: ComponentID to zoom to.
 */
-void UnwrappedSurface::componentSelected(Mantid::Geometry::ComponentID id) {
-  boost::shared_ptr<const Mantid::Geometry::Instrument> instr =
-      m_instrActor->getInstrument();
-  if (id == nullptr) {
-    id = instr->getComponentID();
-  }
-  boost::shared_ptr<const Mantid::Geometry::IComponent> comp =
-      instr->getComponentByID(id);
-  boost::shared_ptr<const Mantid::Geometry::ICompAssembly> ass =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::ICompAssembly>(comp);
-  boost::shared_ptr<const Mantid::Geometry::IDetector> det =
-      boost::dynamic_pointer_cast<const Mantid::Geometry::IDetector>(comp);
-  if (det) {
-    int detID = det->getID();
-
-    std::vector<UnwrappedDetector>::const_iterator it;
-    for (it = m_unwrappedDetectors.begin(); it != m_unwrappedDetectors.end();
-         ++it) {
-      const UnwrappedDetector &udet = *it;
-      if (udet.detID == detID) {
-        double w = udet.width;
-        if (w > m_width_max)
-          w = m_width_max;
-        double h = udet.height;
-        if (h > m_height_max)
-          h = m_height_max;
-        QRectF area(udet.u - w, udet.v - h, w * 2, h * 2);
-        zoom(area);
-        break;
-      }
-    }
-  }
-  if (ass) {
-    this->cacheAllAssemblies();
-    QMap<Mantid::Geometry::ComponentID, QRectF>::iterator assRect =
-        m_assemblies.find(ass->getComponentID());
-    if (assRect != m_assemblies.end())
-      zoom(*assRect);
-    else {
-      // std::cout << "Assembly not found \n";
+void UnwrappedSurface::componentSelected(size_t componentIndex) {
+  const auto &componentInfo = m_instrActor->componentInfo();
+  if (componentInfo.isDetector(componentIndex)) {
+    const auto &udet = m_unwrappedDetectors[componentIndex];
+    zoom(getArea(udet, m_width_max, m_height_max));
+  } else {
+    auto detectors = componentInfo.detectorsInSubtree(componentIndex);
+    QRectF area;
+    for (auto det : detectors) {
+      QRectF detRect;
+      const auto &udet = m_unwrappedDetectors[det];
+      detRect.setLeft(udet.u - udet.width);
+      detRect.setRight(udet.u + udet.width);
+      detRect.setBottom(udet.v - udet.height);
+      detRect.setTop(udet.v + udet.height);
+      area |= detRect;
     }
+    zoom(area);
   }
 }
 
-void UnwrappedSurface::getSelectedDetectors(QList<int> &dets) {
+void UnwrappedSurface::getSelectedDetectors(std::vector<size_t> &detIndices) {
   if (m_selectRect.isNull()) {
     return;
   }
@@ -417,19 +315,20 @@ void UnwrappedSurface::getSelectedDetectors(QList<int> &dets) {
     UnwrappedDetector &udet = m_unwrappedDetectors[i];
     if (udet.u >= uleft && udet.u <= uright && udet.v >= vbottom &&
         udet.v <= vtop) {
-      dets.push_back(udet.detID);
+      detIndices.push_back(udet.detIndex);
     }
   }
 }
 
-void UnwrappedSurface::getMaskedDetectors(QList<int> &dets) const {
-  dets.clear();
+void UnwrappedSurface::getMaskedDetectors(
+    std::vector<size_t> &detIndices) const {
+  detIndices.clear();
   if (m_maskShapes.isEmpty())
     return;
   for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) {
     const UnwrappedDetector &udet = m_unwrappedDetectors[i];
     if (m_maskShapes.isMasked(udet.u, udet.v)) {
-      dets.append(udet.detID);
+      detIndices.push_back(udet.detIndex);
     }
   }
 }
@@ -437,11 +336,7 @@ void UnwrappedSurface::getMaskedDetectors(QList<int> &dets) const {
 void UnwrappedSurface::changeColorMap() {
   for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) {
     UnwrappedDetector &udet = m_unwrappedDetectors[i];
-    unsigned char color[3];
-    m_instrActor->getColor(udet.detID).getUB3(&color[0]);
-    udet.color[0] = color[0];
-    udet.color[1] = color[1];
-    udet.color[2] = color[2];
+    udet.color = m_instrActor->getColor(udet.detIndex);
   }
 }
 
@@ -565,13 +460,13 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const {
     QColor color;
     int index = int(i);
     if (picking) {
-      GLColor c = GLActor::makePickColor(index);
+      GLColor c = InstrumentRenderer::makePickColor(index);
       unsigned char r, g, b;
       c.get(r, g, b);
       color = QColor(r, g, b);
     } else {
-      auto c = &m_unwrappedDetectors[index].color[0];
-      color = QColor(c[0], c[1], c[2]);
+      auto c = m_unwrappedDetectors[index].color;
+      color = QColor(c.red(), c.green(), c.blue());
     }
 
     paint.fillRect(u - iw / 2, v - ih / 2, iw, ih, color);
@@ -701,8 +596,9 @@ void UnwrappedSurface::calcSize(UnwrappedDetector &udet) {
   Mantid::Kernel::Quat R;
   this->rotate(udet, R);
 
-  Mantid::Geometry::BoundingBox bbox = udet.shape->getBoundingBox();
-  Mantid::Kernel::V3D scale = udet.scaleFactor;
+  const auto &componentInfo = m_instrActor->componentInfo();
+  const auto &bbox = componentInfo.shape(udet.detIndex).getBoundingBox();
+  auto scale = componentInfo.scaleFactor(udet.detIndex);
 
   // sizes of the detector along each 3D axis
   Mantid::Kernel::V3D size = bbox.maxPoint() - bbox.minPoint();
diff --git a/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h b/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h
index a505acc0a8638b5676210ca8c54c6e05f9b81a6e..79cd4629b557e6ef469cbc26f8512ac36c9f7a83 100644
--- a/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h
+++ b/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h
@@ -54,8 +54,8 @@ private:
                      Mantid::Geometry::MDImplicitFunction *function);
 
   /// Get the range of signal, in parallel, given an iterator
-  QwtDoubleInterval
-  getRange(const std::vector<Mantid::API::IMDIterator *> &iterators);
+  QwtDoubleInterval getRange(
+      const std::vector<std::unique_ptr<Mantid::API::IMDIterator>> &iterators);
   /// Get the range of signal given an iterator
   QwtDoubleInterval getRange(Mantid::API::IMDIterator *it);
 
diff --git a/qt/widgets/legacyqwt/src/MWView.cpp b/qt/widgets/legacyqwt/src/MWView.cpp
index aaacf5d3ea691862d13b5ba8244c8c48f219427e..bc76328e8b65ff73b54b1e919f6c66f1fe8fce99 100644
--- a/qt/widgets/legacyqwt/src/MWView.cpp
+++ b/qt/widgets/legacyqwt/src/MWView.cpp
@@ -185,7 +185,7 @@ void MWView::loadSettings() {
   // used.
   // If the user selected a unified color map for the SliceViewer and the VSI,
   // then this is loaded.
-  if (m_mdSettings != NULL && m_mdSettings->getUsageGeneralMdColorMap()) {
+  if (m_mdSettings != nullptr && m_mdSettings->getUsageGeneralMdColorMap()) {
     m_currentColorMapFile = m_mdSettings->getGeneralMdColorMapFile();
   } else {
     m_currentColorMapFile = settings.value("ColormapFile", "").toString();
diff --git a/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp b/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp
index e6a3d3abaa00e12b61d00828da11b270d60e8184..855b10cfa9d0f806e2272d212c2a4a1b12789fd5 100644
--- a/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp
+++ b/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp
@@ -316,7 +316,7 @@ void MantidQwtIMDWorkspaceData::choosePlotAxis() {
         regularBinnedMDWorkspace = atLeastOneDimNotIntegrated;
       }
 
-      if (NULL !=
+      if (nullptr !=
               boost::dynamic_pointer_cast<const Mantid::API::IMDHistoWorkspace>(
                   originalWS) ||
           regularBinnedMDWorkspace) {
diff --git a/qt/widgets/legacyqwt/src/SignalRange.cpp b/qt/widgets/legacyqwt/src/SignalRange.cpp
index 62dc07304855e024b652d6cfa461d6a26741b88e..b1e9d8c4c254ba956ce825f2a71369f928ff76a1 100644
--- a/qt/widgets/legacyqwt/src/SignalRange.cpp
+++ b/qt/widgets/legacyqwt/src/SignalRange.cpp
@@ -65,12 +65,12 @@ void SignalRange::findFullRange(
  * @return the min/max range, or 0-1.0 if not found
  */
 QwtDoubleInterval SignalRange::getRange(
-    const std::vector<Mantid::API::IMDIterator *> &iterators) {
+    const std::vector<std::unique_ptr<Mantid::API::IMDIterator>> &iterators) {
   std::vector<QwtDoubleInterval> intervals(iterators.size());
   // cppcheck-suppress syntaxError
       PRAGMA_OMP( parallel for schedule(dynamic, 1))
       for (int i = 0; i < int(iterators.size()); i++) {
-        Mantid::API::IMDIterator *it = iterators[i];
+        auto it = iterators[i].get();
         intervals[i] = this->getRange(it);
         // don't delete iterator in parallel. MSVC doesn't like it
         // when the iterator points to a mock object.
@@ -80,8 +80,6 @@ QwtDoubleInterval SignalRange::getRange(
       double minSignal = DBL_MAX;
       double maxSignal = -DBL_MAX;
       for (size_t i = 0; i < iterators.size(); i++) {
-        delete iterators[i];
-
         double signal;
         signal = intervals[i].minValue();
         if (!std::isfinite(signal))
diff --git a/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp
index 0d091f7cd13d49192b0e0195061c95f119482e38..b0dff8bcc61535df9ae5d1fd9beb6926351ac92c 100644
--- a/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp
+++ b/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp
@@ -216,7 +216,7 @@ void LoadDialog::tieStaticWidgets(const bool readHistory) {
   }
   tie(m_form.workspaceEdit, "OutputWorkspace", m_form.workspaceLayout,
       readHistory);
-  tie(m_form.fileWidget, "Filename", NULL, readHistory);
+  tie(m_form.fileWidget, "Filename", nullptr, readHistory);
 }
 
 /**
@@ -386,7 +386,7 @@ int LoadDialog::createWidgetsForProperty(const Mantid::Kernel::Property *prop,
   if (addValidator)
     tie(inputWidget, propName, widgetLayout);
   else
-    tie(inputWidget, propName, NULL);
+    tie(inputWidget, propName, nullptr);
 
   return inputWidget->geometry().height();
 }
diff --git a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp
index 596a517fadb05453d6bdd4feb549bbb5558ed009..d012208585e5b55be143df8b599750fee86bbed1 100644
--- a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp
+++ b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp
@@ -40,8 +40,8 @@ private:
 template class Mantid::Kernel::SingletonHolder<LiveDataAlgInputHistoryImpl>;
 #endif /* _WIN32 */
 /// The specific instantiation of the templated type
-typedef Mantid::Kernel::SingletonHolder<LiveDataAlgInputHistoryImpl>
-    LiveDataAlgInputHistory;
+using LiveDataAlgInputHistory =
+    Mantid::Kernel::SingletonHolder<LiveDataAlgInputHistoryImpl>;
 
 class LiveDataPostProcessingAlgInputHistoryImpl
     : public AbstractAlgorithmInputHistory {
@@ -61,9 +61,8 @@ template class Mantid::Kernel::SingletonHolder<
     LiveDataPostProcessingAlgInputHistoryImpl>;
 #endif /* _WIN32 */
 /// The specific instantiation of the templated type
-typedef Mantid::Kernel::SingletonHolder<
-    LiveDataPostProcessingAlgInputHistoryImpl>
-    LiveDataPostProcessingAlgInputHistory;
+using LiveDataPostProcessingAlgInputHistory =
+    Mantid::Kernel::SingletonHolder<LiveDataPostProcessingAlgInputHistoryImpl>;
 }
 
 // Add this class to the list of specialised dialogs in this namespace
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h
index 3d0db9f5f3b07d674f77db2da429441ea9f33e7b..27d4f11897511411c5dd860778d45acab5211283 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h
@@ -166,7 +166,7 @@ private:
                        boost::shared_ptr<const Mantid::API::IPeaksWorkspace>
                            toWorkspace) override;
   /// Alias for container of subjects type.
-  typedef std::vector<PeaksPresenter_sptr> SubjectContainer;
+  using SubjectContainer = std::vector<PeaksPresenter_sptr>;
   /// Subject presenters.
   SubjectContainer m_subjects;
   /// Use default
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h
index 2f2fd9eaaca7a9e3adf00faa33b9f7cb53fd4f5b..1db7c3294635d1ec34b6b77e7c05112cae014993 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h
@@ -14,7 +14,7 @@
 namespace MantidQt {
 namespace SliceViewer {
 /// Alias for Vector of Peak Overlay Views
-typedef std::vector<boost::shared_ptr<PeakOverlayView>> VecPeakOverlayView;
+using VecPeakOverlayView = std::vector<boost::shared_ptr<PeakOverlayView>>;
 
 /// Coordinate System Enum to String.
 std::string DLLExport
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h
index 6042efc4cff80e01aa361256c1af196dd1159b7c..1982ab9b1402a6f42ed65e1ea7d5fd2c019c2a8e 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h
@@ -27,7 +27,7 @@ template <typename T>
 class DLLExport FirstExperimentInfoQueryAdapter
     : public FirstExperimentInfoQuery {
 public:
-  typedef boost::shared_ptr<const T> Adaptee_sptr;
+  using Adaptee_sptr = boost::shared_ptr<const T>;
 
 private:
   Adaptee_sptr m_ws;
@@ -70,4 +70,4 @@ public:
 }
 }
 
-#endif /* MANTID_SLICEVIEWER_FIRSTEXPERIMENTINFOQUERY_H_ */
\ No newline at end of file
+#endif /* MANTID_SLICEVIEWER_FIRSTEXPERIMENTINFOQUERY_H_ */
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h
index 16d4323e9a5f8b9ce136ef7f1353687199b3d3c2..b57cf4b2ff057c36a2dca135e115cd9d8d23819f 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h
@@ -29,13 +29,13 @@ private:
   enum { typeValue = I };
 };
 
-typedef DoubleParam<0> Left;
-typedef DoubleParam<1> Right;
-typedef DoubleParam<2> Top;
-typedef DoubleParam<3> Bottom;
-typedef DoubleParam<4> SlicePoint;
-typedef DoubleParam<5> Front;
-typedef DoubleParam<6> Back;
+using Left = DoubleParam<0>;
+using Right = DoubleParam<1>;
+using Top = DoubleParam<2>;
+using Bottom = DoubleParam<3>;
+using SlicePoint = DoubleParam<4>;
+using Front = DoubleParam<5>;
+using Back = DoubleParam<6>;
 
 /** A bounding box for a peak. Allows the SliceViewer to zoom to that region.
 
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h
index 848740645bc9837d0b4eb81dfc681d6ba0fd09a0..c287fb7e5fb66c127a619f80358552e79f751ef1 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h
@@ -91,8 +91,8 @@ public:
   virtual ~PeakOverlayView() {}
 };
 
-typedef boost::shared_ptr<const PeakOverlayView> PeakOverlayView_const_sptr;
-typedef boost::shared_ptr<PeakOverlayView> PeakOverlayView_sptr;
+using PeakOverlayView_const_sptr = boost::shared_ptr<const PeakOverlayView>;
+using PeakOverlayView_sptr = boost::shared_ptr<PeakOverlayView>;
 }
 }
 
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h
index 5b5eabd18d0148fe3f3b653112562db3752230cb..d6b453339180efadb3ee51a9ce0fa36686f89353 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h
@@ -64,7 +64,7 @@ public:
 };
 
 /// Factory Shared Pointer typedef.
-typedef boost::shared_ptr<PeakOverlayViewFactory> PeakOverlayViewFactory_sptr;
+using PeakOverlayViewFactory_sptr = boost::shared_ptr<PeakOverlayViewFactory>;
 }
 }
 
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h
index 5bbbbcfa111d8651b2c2f87a8d6e5bcf7c17c81e..d126155960e4ce822e25807955589cf71e1174f3 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h
@@ -26,7 +26,7 @@ public:
   ~PeakPalette();
 
 private:
-  typedef std::map<int, C> ColourMapType;
+  using ColourMapType = std::map<int, C>;
   ColourMapType m_backgroundMap;
   ColourMapType m_foregroundMap;
   typename ColourMapType::iterator safeFetchPair(ColourMapType &map,
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h
index ffc350bdb1b10c7cd870621a5ed0e70b6c203c64..91c44dce7d156419f0e565d9248275be938b565b 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h
@@ -22,7 +22,7 @@ struct EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakRepresentationViewInformation {
 class PeakBoundingBox;
 
 /// Alisas for a boost optional double.
-typedef boost::optional<double> optional_double;
+using optional_double = boost::optional<double>;
 
 /** PeakRepresentation : Allows the draw a general visual peak shape.
 
@@ -82,8 +82,8 @@ protected:
                       PeakRepresentationViewInformation viewInformation) = 0;
 };
 
-typedef std::shared_ptr<PeakRepresentation> PeakRepresentation_sptr;
-typedef std::vector<PeakRepresentation_sptr> VecPeakRepresentation;
+using PeakRepresentation_sptr = std::shared_ptr<PeakRepresentation>;
+using VecPeakRepresentation = std::vector<PeakRepresentation_sptr>;
 }
 }
 
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h
index 182073415b33671f78325190f4b83b996453a21e..27bac238237afc5d742da4daba57dd68b95602ab 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h
@@ -35,8 +35,8 @@ class PeakOverlayView;
 class UpdateableOnDemand;
 
 // Alias
-typedef std::set<boost::shared_ptr<const Mantid::API::IPeaksWorkspace>>
-    SetPeaksWorkspaces;
+using SetPeaksWorkspaces =
+    std::set<boost::shared_ptr<const Mantid::API::IPeaksWorkspace>>;
 
 /*---------------------------------------------------------
 Abstract PeaksPresenter.
@@ -79,8 +79,8 @@ public:
   ~PeaksPresenter() override{};
 };
 
-typedef boost::shared_ptr<PeaksPresenter> PeaksPresenter_sptr;
-typedef boost::shared_ptr<const PeaksPresenter> PeaksPresenter_const_sptr;
+using PeaksPresenter_sptr = boost::shared_ptr<PeaksPresenter>;
+using PeaksPresenter_const_sptr = boost::shared_ptr<const PeaksPresenter>;
 }
 }
 
diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
index 246d2bf018b8f9a7c4e2ac78d4d88d020d4b324d..4d41a695fbd2c52a1d466437711b8657241d6ecf 100644
--- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
+++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h
@@ -70,10 +70,10 @@ signals:
   void peaksSorted(const std::string &, const bool);
 
 private:
-  typedef QString ColumnNameType;
-  typedef QString ColumnValueType;
-  typedef std::map<ColumnNameType, bool> ColumnNameSortableMap;
-  typedef std::map<int, ColumnNameType> ColumnIndexNameMap;
+  using ColumnNameType = QString;
+  using ColumnValueType = QString;
+  using ColumnNameSortableMap = std::map<ColumnNameType, bool>;
+  using ColumnIndexNameMap = std::map<int, ColumnNameType>;
 
 public:
   /// Label for run number column
@@ -116,6 +116,8 @@ public:
   static const QString QLAB;
   /// Label for Q-vector in the sample column
   static const QString QSAMPLE;
+  /// Label for Q-vector in the peak number column
+  static const QString PEAKNUM;
 
 private:
   /// Find the correct column name for this column index
@@ -161,6 +163,8 @@ private:
   static const int COL_QLAB;
   /// Index for Q-vector in the sample column
   static const int COL_QSAMPLE;
+  /// Unique peak number
+  static const int COL_PEAKNUM;
   /// The number of digits past the decimal to display in the table
   int m_hklPrec;
   /// Map from column index to raw peak data
diff --git a/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp b/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp
index 2b80d68addfe8f8d99114e01e93ecd164713d75a..9bd23870c0f7045031f0e7818a341915f2babbff 100644
--- a/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp
+++ b/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp
@@ -286,7 +286,7 @@ bool ConcretePeaksPresenter::isDimensionNameOfFreeAxis(
  Request that each owned view makes its self visible.
  */
 void ConcretePeaksPresenter::showAll() {
-  if (m_viewPeaks != NULL)
+  if (m_viewPeaks != nullptr)
     m_viewPeaks->showView();
 }
 
@@ -295,7 +295,7 @@ void ConcretePeaksPresenter::showAll() {
  */
 void ConcretePeaksPresenter::hideAll() {
   // Hide all views.
-  if (m_viewPeaks != NULL)
+  if (m_viewPeaks != nullptr)
     m_viewPeaks->hideView();
 }
 
@@ -319,7 +319,7 @@ PeakViewColor ConcretePeaksPresenter::getForegroundPeakViewColor() const {
 
 void ConcretePeaksPresenter::setForegroundColor(const PeakViewColor color) {
   // Change foreground colors
-  if (m_viewPeaks != NULL) {
+  if (m_viewPeaks != nullptr) {
     m_viewPeaks->changeForegroundColour(color);
     m_viewPeaks->updateView();
   }
@@ -329,7 +329,7 @@ void ConcretePeaksPresenter::setForegroundColor(const PeakViewColor color) {
 
 void ConcretePeaksPresenter::setBackgroundColor(const PeakViewColor color) {
   // Change background colours
-  if (m_viewPeaks != NULL) {
+  if (m_viewPeaks != nullptr) {
     m_viewPeaks->changeBackgroundColour(color);
     m_viewPeaks->updateView();
   }
@@ -343,7 +343,7 @@ std::string ConcretePeaksPresenter::getTransformName() const {
 
 void ConcretePeaksPresenter::showBackgroundRadius(const bool show) {
   // Change background colours
-  if (m_viewPeaks != NULL) {
+  if (m_viewPeaks != nullptr) {
     m_viewPeaks->showBackgroundRadius(show);
     doFindPeaksInRegion();
   }
@@ -353,7 +353,7 @@ void ConcretePeaksPresenter::showBackgroundRadius(const bool show) {
 
 void ConcretePeaksPresenter::setShown(const bool shown) {
   m_isHidden = !shown;
-  if (m_viewPeaks != NULL) {
+  if (m_viewPeaks != nullptr) {
     if (shown) {
       m_viewPeaks->showView();
     } else {
@@ -417,7 +417,7 @@ void ConcretePeaksPresenter::setPeakSizeIntoProjection(const double fraction) {
 
 double ConcretePeaksPresenter::getPeakSizeOnProjection() const {
   double result = 0;
-  if (m_viewPeaks != NULL && m_peaksWS->getNumberPeaks() > 0) {
+  if (m_viewPeaks != nullptr && m_peaksWS->getNumberPeaks() > 0) {
     result = m_viewPeaks->getOccupancyInView();
   }
   return result;
@@ -425,7 +425,7 @@ double ConcretePeaksPresenter::getPeakSizeOnProjection() const {
 
 double ConcretePeaksPresenter::getPeakSizeIntoProjection() const {
   double result = 0;
-  if (m_viewPeaks != NULL && m_peaksWS->getNumberPeaks() > 0) {
+  if (m_viewPeaks != nullptr && m_peaksWS->getNumberPeaks() > 0) {
     result = m_viewPeaks->getOccupancyIntoView();
   }
   return result;
diff --git a/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp b/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp
index 966a4b29409326af1b7770b36b9c7d1e901767e2..9ca18beb52fdf6d2e45c14837a24e52828974145 100644
--- a/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp
+++ b/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp
@@ -62,6 +62,7 @@ const QString QPeaksTableModel::ROW("Row");
 const QString QPeaksTableModel::COL("Col");
 const QString QPeaksTableModel::QLAB = "QLab";
 const QString QPeaksTableModel::QSAMPLE = "QSample";
+const QString QPeaksTableModel::PEAKNUM = "PeakNumber";
 
 const int QPeaksTableModel::COL_RUNNUMBER(0);
 const int QPeaksTableModel::COL_DETID(1);
@@ -83,6 +84,7 @@ const int QPeaksTableModel::COL_ROW(16);
 const int QPeaksTableModel::COL_COL(17);
 const int QPeaksTableModel::COL_QLAB(18);
 const int QPeaksTableModel::COL_QSAMPLE(19);
+const int QPeaksTableModel::COL_PEAKNUM(20);
 
 /**
  * @param column The column to get the number of characters
@@ -132,6 +134,8 @@ int QPeaksTableModel::numCharacters(const int column) const {
     return 3 * 6;
   else if (column == COL_QSAMPLE)
     return 3 * 6;
+  else if (column == COL_PEAKNUM)
+    return 6;
   else
     return 3;
 }
@@ -162,7 +166,8 @@ QPeaksTableModel::QPeaksTableModel(
                      {16, ROW},
                      {17, COL},
                      {18, QLAB},
-                     {19, QSAMPLE}};
+                     {19, QSAMPLE},
+                     {20, PEAKNUM}};
 
   m_hklPrec = getHKLPrecision();
 
@@ -193,6 +198,7 @@ QPeaksTableModel::QPeaksTableModel(
       [](const IPeak &peak) { return QVariant(peak.getCol()); },
       [](const IPeak &peak) { return QVariant(peak.getQLabFrame().norm()); },
       [](const IPeak &peak) { return QVariant(peak.getQSampleFrame().norm()); },
+      [](const IPeak &peak) { return QVariant(int(peak.getPeakNumber())); },
   };
 
   // Mapping member functions of the Peak object to a column index with
@@ -244,6 +250,7 @@ QPeaksTableModel::QPeaksTableModel(
       [](const IPeak &peak) { return QString::number(peak.getCol()); },
       [](const IPeak &peak) { return v3dAsString(peak.getQLabFrame()); },
       [](const IPeak &peak) { return v3dAsString(peak.getQSampleFrame()); },
+      [](const IPeak &peak) { return QString::number(peak.getPeakNumber()); },
   };
 }
 
diff --git a/qt/widgets/sliceviewer/src/SliceViewer.cpp b/qt/widgets/sliceviewer/src/SliceViewer.cpp
index 4f2763b5f0e7ff73046a984c00f69837efbf9d7b..7f8e690049add0c4618ec9a979408bb1ec92729f 100644
--- a/qt/widgets/sliceviewer/src/SliceViewer.cpp
+++ b/qt/widgets/sliceviewer/src/SliceViewer.cpp
@@ -261,7 +261,7 @@ void SliceViewer::loadSettings() {
   // used.
   // If the user selected a unified color map for the SliceViewer and the VSI,
   // then this is loaded.
-  if (m_mdSettings != NULL && m_mdSettings->getUsageGeneralMdColorMap()) {
+  if (m_mdSettings != nullptr && m_mdSettings->getUsageGeneralMdColorMap()) {
     m_currentColorMapFile = m_mdSettings->getGeneralMdColorMapFile();
   } else {
     m_currentColorMapFile = settings.value("ColormapFile", "").toString();
diff --git a/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp b/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp
index f0c25fcde89e9588b5353163189a428d5318da4f..0083113256ec4a3c782d5e0df63104897eaebc31 100644
--- a/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp
+++ b/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp
@@ -32,7 +32,7 @@ namespace SliceViewer {
  */
 SliceViewerWindow::SliceViewerWindow(const QString &wsName,
                                      const QString &label, Qt::WindowFlags f)
-    : QMainWindow(NULL, f), WorkspaceObserver(), m_lastLinerWidth(0),
+    : QMainWindow(nullptr, f), WorkspaceObserver(), m_lastLinerWidth(0),
       m_lastPeaksViewerWidth(0) {
 
 #ifdef Q_OS_MAC
diff --git a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h
index 6988b6df9438c98f233971a05a1c382c868088de..a73b280ba0ec801824fccf62f465f6d1a4cb8c1d 100644
--- a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h
+++ b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h
@@ -26,12 +26,12 @@ using namespace testing;
 using boost::regex;
 
 // Alias.
-typedef boost::shared_ptr<Mantid::API::MDGeometry> MDGeometry_sptr;
+using MDGeometry_sptr = boost::shared_ptr<Mantid::API::MDGeometry>;
 
 class ConcretePeaksPresenterTest : public CxxTest::TestSuite {
   /// Alias.
-  typedef boost::shared_ptr<MantidQt::SliceViewer::ConcretePeaksPresenter>
-      ConcretePeaksPresenter_sptr;
+  using ConcretePeaksPresenter_sptr =
+      boost::shared_ptr<MantidQt::SliceViewer::ConcretePeaksPresenter>;
 
   /// Helper method to create a good 'Integrated' peaks workspace
   Mantid::API::IPeaksWorkspace_sptr
diff --git a/qt/widgets/sliceviewer/test/MockObjects.h b/qt/widgets/sliceviewer/test/MockObjects.h
index 8e5c21d29e16f59b4b61bb38e541a3a2721662ea..52b357fc4e4d57c66c4e5d58084d143cf38ef5c3 100644
--- a/qt/widgets/sliceviewer/test/MockObjects.h
+++ b/qt/widgets/sliceviewer/test/MockObjects.h
@@ -160,66 +160,6 @@ public:
                void(boost::shared_ptr<Mantid::API::IPeaksWorkspace> &));
 };
 
-/*------------------------------------------------------------
-Mock IPeak
-------------------------------------------------------------*/
-class MockIPeak : public Mantid::Geometry::IPeak {
-public:
-  MOCK_METHOD1(setInstrument,
-               void(const Geometry::Instrument_const_sptr &inst));
-  MOCK_CONST_METHOD0(getDetectorID, int());
-  MOCK_METHOD1(setDetectorID, void(int m_DetectorID));
-  MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr());
-  MOCK_CONST_METHOD0(getInstrument, Geometry::Instrument_const_sptr());
-  MOCK_CONST_METHOD0(getRunNumber, int());
-  MOCK_METHOD1(setRunNumber, void(int m_RunNumber));
-  MOCK_CONST_METHOD0(getMonitorCount, double());
-  MOCK_METHOD1(setMonitorCount, void(double m_MonitorCount));
-  MOCK_CONST_METHOD0(getH, double());
-  MOCK_CONST_METHOD0(getK, double());
-  MOCK_CONST_METHOD0(getL, double());
-  MOCK_CONST_METHOD0(getHKL, 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_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
-  MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
-  MOCK_METHOD0(findDetector, bool());
-  MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame,
-                                     boost::optional<double> detectorDistance));
-  MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame,
-                                  boost::optional<double> detectorDistance));
-  MOCK_METHOD1(setWavelength, void(double wavelength));
-  MOCK_CONST_METHOD0(getWavelength, double());
-  MOCK_CONST_METHOD0(getScattering, double());
-  MOCK_CONST_METHOD0(getDSpacing, double());
-  MOCK_CONST_METHOD0(getTOF, double());
-  MOCK_CONST_METHOD0(getInitialEnergy, double());
-  MOCK_CONST_METHOD0(getFinalEnergy, double());
-  MOCK_METHOD1(setInitialEnergy, void(double m_InitialEnergy));
-  MOCK_METHOD1(setFinalEnergy, void(double m_FinalEnergy));
-  MOCK_CONST_METHOD0(getIntensity, double());
-  MOCK_CONST_METHOD0(getSigmaIntensity, double());
-  MOCK_METHOD1(setIntensity, void(double m_Intensity));
-  MOCK_METHOD1(setSigmaIntensity, void(double m_SigmaIntensity));
-  MOCK_CONST_METHOD0(getBinCount, double());
-  MOCK_METHOD1(setBinCount, void(double m_BinCount));
-  MOCK_CONST_METHOD0(getGoniometerMatrix, Mantid::Kernel::Matrix<double>());
-  MOCK_METHOD1(setGoniometerMatrix,
-               void(const Mantid::Kernel::Matrix<double> &m_GoniometerMatrix));
-  MOCK_CONST_METHOD0(getBankName, std::string());
-  MOCK_CONST_METHOD0(getRow, int());
-  MOCK_CONST_METHOD0(getCol, int());
-  MOCK_CONST_METHOD0(getDetPos, Mantid::Kernel::V3D());
-  MOCK_CONST_METHOD0(getL1, double());
-  MOCK_CONST_METHOD0(getL2, double());
-  MOCK_CONST_METHOD0(getDetectorPosition, Mantid::Kernel::V3D());
-  MOCK_CONST_METHOD0(getDetectorPositionNoCheck, Mantid::Kernel::V3D());
-  MOCK_CONST_METHOD0(getPeakShape, const Mantid::Geometry::PeakShape &());
-};
-
 /*------------------------------------------------------------
 Mock MDGeometry
 ------------------------------------------------------------*/
diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h
index 2859d9b7203320772c50e43f6aaf9bee3863bdba..1c90d4c47f1c804414ab633efe73431567f1fc9d 100644
--- a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h
+++ b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h
@@ -182,11 +182,11 @@ public:
 
 class PeakRepresentationCrossTestPerformance : public CxxTest::TestSuite {
 private:
-  typedef std::vector<boost::shared_ptr<PeakRepresentationCross>>
-      VecPeakRepCross;
+  using VecPeakRepCross =
+      std::vector<boost::shared_ptr<PeakRepresentationCross>>;
 
-  typedef std::vector<boost::shared_ptr<
-      PeakRepresentationCrossExposeProtectedWrapper>> VecPeakRepCrossWrapped;
+  using VecPeakRepCrossWrapped = std::vector<
+      boost::shared_ptr<PeakRepresentationCrossExposeProtectedWrapper>>;
 
   /// Collection to store a large number of PeakRepresentationCross.
   VecPeakRepCross m_peaks;
diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h
index 487b38031335cff2de320aaaa1bc12527b843a43..a1a589a3f1658ab6636067156d23d800acf874f4 100644
--- a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h
+++ b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h
@@ -316,10 +316,10 @@ public:
   }
 
 private:
-  typedef boost::shared_ptr<PeakRepresentationSphereExposeProtectedWrapper>
-      PeaksRepresentationSphere_sptr;
-  typedef std::vector<PeaksRepresentationSphere_sptr>
-      VecPeaksRepresentationSphere;
+  using PeaksRepresentationSphere_sptr =
+      boost::shared_ptr<PeakRepresentationSphereExposeProtectedWrapper>;
+  using VecPeaksRepresentationSphere =
+      std::vector<PeaksRepresentationSphere_sptr>;
 
   /// Collection to store a large number of physicalPeaks.
   VecPeaksRepresentationSphere m_peaks;
diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h
index 88cd8aad3aea13ed5f85e1a6fb7619c636ff7606..598c5a87447500ab71ba05ba09752930885c9a89 100644
--- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h
+++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h
@@ -67,8 +67,8 @@ private:
   std::vector<float> m_data;
 };
 
-typedef boost::shared_ptr<ArrayDataSource> ArrayDataSource_sptr;
-typedef boost::shared_ptr<const ArrayDataSource> ArrayDataSource_const_sptr;
+using ArrayDataSource_sptr = boost::shared_ptr<ArrayDataSource>;
+using ArrayDataSource_const_sptr = boost::shared_ptr<const ArrayDataSource>;
 
 } // namespace SpectrumView
 } // namespace MantidQt
diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h
index 16a65493683152d680cf6bc0062311adb81c3266..0b8af1ded382b70318a6675ed5f9dda3da84f6c6 100644
--- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h
+++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h
@@ -124,8 +124,8 @@ private:
   std::vector<float> m_data;
 };
 
-typedef boost::shared_ptr<DataArray> DataArray_sptr;
-typedef boost::shared_ptr<const DataArray> DataArray_const_sptr;
+using DataArray_sptr = boost::shared_ptr<DataArray>;
+using DataArray_const_sptr = boost::shared_ptr<const DataArray>;
 
 } // namespace SpectrumView
 } // namespace MantidQt
diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h
index fb3c7c88f7d46e4633250e9843e2a5365747f975..58aec195aaed025e275c0c6d3a6e70cb46a6829c 100644
--- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h
+++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h
@@ -103,9 +103,9 @@ private:
   const Mantid::API::SpectrumInfo &m_spectrumInfo;
 };
 
-typedef boost::shared_ptr<MatrixWSDataSource> MatrixWSDataSource_sptr;
-typedef boost::shared_ptr<const MatrixWSDataSource>
-    MatrixWSDataSource_const_sptr;
+using MatrixWSDataSource_sptr = boost::shared_ptr<MatrixWSDataSource>;
+using MatrixWSDataSource_const_sptr =
+    boost::shared_ptr<const MatrixWSDataSource>;
 
 } // namespace SpectrumView
 } // namespace MantidQt
diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h
index 70cab21712a367d45ea1222515e1e8257aa16fed..d084570ac5c2bc2e9295443cd846b92851f5916c 100644
--- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h
+++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h
@@ -106,9 +106,9 @@ protected:
   size_t m_totalCols;
 };
 
-typedef boost::shared_ptr<SpectrumDataSource> SpectrumDataSource_sptr;
-typedef boost::shared_ptr<const SpectrumDataSource>
-    SpectrumDataSource_const_sptr;
+using SpectrumDataSource_sptr = boost::shared_ptr<SpectrumDataSource>;
+using SpectrumDataSource_const_sptr =
+    boost::shared_ptr<const SpectrumDataSource>;
 
 } // namespace SpectrumView
 } // namespace MantidQt
diff --git a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp
index 2c7e702ac69cc4ba6a869a5e94e28f69f3781632..7d438bb60c7379c5be9f2efbb483f16e6785d171 100644
--- a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp
+++ b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp
@@ -242,7 +242,7 @@ std::vector<std::string> MatrixWSDataSource::getInfoList(double x, double y) {
 
   std::string x_label = "";
   Unit_sptr &old_unit = m_matWs->getAxis(0)->unit();
-  if (old_unit != 0) {
+  if (old_unit) {
     x_label = old_unit->caption();
     SVUtils::PushNameValue(x_label, 8, 3, x, list);
   }
@@ -262,7 +262,7 @@ std::vector<std::string> MatrixWSDataSource::getInfoList(double x, double y) {
 
   try {
 
-    if (old_unit == 0) {
+    if (!old_unit) {
       g_log.debug("No UNITS on MatrixWorkspace X-axis");
       return list;
     }
diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py
index 9edd66163c0f0dea5e14137f16ff719df15953e6..f2d9804361b6c2dc222453ee7b4615d13386439f 100644
--- a/scripts/Diffraction/isis_powder/pearl.py
+++ b/scripts/Diffraction/isis_powder/pearl.py
@@ -1,5 +1,7 @@
 from __future__ import (absolute_import, division, print_function)
 
+from contextlib import contextmanager
+
 import mantid.simpleapi as mantid
 
 from isis_powder.routines import common, instrument_settings
@@ -7,6 +9,8 @@ from isis_powder.abstract_inst import AbstractInst
 from isis_powder.pearl_routines import pearl_advanced_config, pearl_algs, pearl_calibration_algs, pearl_output, \
     pearl_param_mapping
 
+import copy
+
 
 class Pearl(AbstractInst):
 
@@ -14,6 +18,7 @@ class Pearl(AbstractInst):
         self._inst_settings = instrument_settings.InstrumentSettings(
            param_map=pearl_param_mapping.attr_mapping, adv_conf_dict=pearl_advanced_config.get_all_adv_variables(),
            kwargs=kwargs)
+        self._default_inst_settings = copy.deepcopy(self._inst_settings)
 
         super(Pearl, self).__init__(user_name=self._inst_settings.user_name,
                                     calibration_dir=self._inst_settings.calibration_dir,
@@ -22,48 +27,52 @@ class Pearl(AbstractInst):
         self._cached_run_details = {}
 
     def focus(self, **kwargs):
-        self._switch_long_mode_inst_settings(kwargs.get("long_mode"))
-        self._inst_settings.update_attributes(kwargs=kwargs)
-        return self._focus(run_number_string=self._inst_settings.run_number,
-                           do_absorb_corrections=self._inst_settings.absorb_corrections,
-                           do_van_normalisation=self._inst_settings.van_norm)
+        with self._apply_temporary_inst_settings(kwargs):
+            return self._focus(run_number_string=self._inst_settings.run_number,
+                               do_absorb_corrections=self._inst_settings.absorb_corrections,
+                               do_van_normalisation=self._inst_settings.van_norm)
 
     def create_vanadium(self, **kwargs):
-        self._switch_long_mode_inst_settings(kwargs.get("long_mode"))
         kwargs["perform_attenuation"] = None  # Hard code this off as we do not need an attenuation file
-        self._inst_settings.update_attributes(kwargs=kwargs)
 
-        if str(self._inst_settings.tt_mode).lower() == "all":
-            for new_tt_mode in ["tt35", "tt70", "tt88"]:
-                self._inst_settings.tt_mode = new_tt_mode
+        with self._apply_temporary_inst_settings(kwargs):
+            if str(self._inst_settings.tt_mode).lower() == "all":
+                for new_tt_mode in ["tt35", "tt70", "tt88"]:
+                    self._inst_settings.tt_mode = new_tt_mode
+                    self._run_create_vanadium()
+            else:
                 self._run_create_vanadium()
-        else:
-            self._run_create_vanadium()
 
     def create_cal(self, **kwargs):
+        with self._apply_temporary_inst_settings(kwargs):
+            run_details = self._get_run_details(self._inst_settings.run_number)
+
+            cross_correlate_params = {"ReferenceSpectra": self._inst_settings.reference_spectra,
+                                      "WorkspaceIndexMin": self._inst_settings.cross_corr_ws_min,
+                                      "WorkspaceIndexMax": self._inst_settings.cross_corr_ws_max,
+                                      "XMin": self._inst_settings.cross_corr_x_min,
+                                      "XMax": self._inst_settings.cross_corr_x_max}
+            get_detector_offsets_params = {"DReference": self._inst_settings.d_reference,
+                                           "Step": self._inst_settings.get_det_offsets_step,
+                                           "XMin": self._inst_settings.get_det_offsets_x_min,
+                                           "XMax": self._inst_settings.get_det_offsets_x_max}
+
+            return pearl_calibration_algs.create_calibration(calibration_runs=self._inst_settings.run_number,
+                                                             instrument=self,
+                                                             offset_file_name=run_details.offset_file_path,
+                                                             grouping_file_name=run_details.grouping_file_path,
+                                                             calibration_dir=self._inst_settings.calibration_dir,
+                                                             rebin_1_params=self._inst_settings.cal_rebin_1,
+                                                             rebin_2_params=self._inst_settings.cal_rebin_2,
+                                                             cross_correlate_params=cross_correlate_params,
+                                                             get_det_offset_params=get_detector_offsets_params)
+
+    @contextmanager
+    def _apply_temporary_inst_settings(self, kwargs):
         self._switch_long_mode_inst_settings(kwargs.get("long_mode"))
         self._inst_settings.update_attributes(kwargs=kwargs)
-        run_details = self._get_run_details(self._inst_settings.run_number)
-
-        cross_correlate_params = {"ReferenceSpectra": self._inst_settings.reference_spectra,
-                                  "WorkspaceIndexMin": self._inst_settings.cross_corr_ws_min,
-                                  "WorkspaceIndexMax": self._inst_settings.cross_corr_ws_max,
-                                  "XMin": self._inst_settings.cross_corr_x_min,
-                                  "XMax": self._inst_settings.cross_corr_x_max}
-        get_detector_offsets_params = {"DReference": self._inst_settings.d_reference,
-                                       "Step": self._inst_settings.get_det_offsets_step,
-                                       "XMin": self._inst_settings.get_det_offsets_x_min,
-                                       "XMax": self._inst_settings.get_det_offsets_x_max}
-
-        return pearl_calibration_algs.create_calibration(calibration_runs=self._inst_settings.run_number,
-                                                         instrument=self,
-                                                         offset_file_name=run_details.offset_file_path,
-                                                         grouping_file_name=run_details.grouping_file_path,
-                                                         calibration_dir=self._inst_settings.calibration_dir,
-                                                         rebin_1_params=self._inst_settings.cal_rebin_1,
-                                                         rebin_2_params=self._inst_settings.cal_rebin_2,
-                                                         cross_correlate_params=cross_correlate_params,
-                                                         get_det_offset_params=get_detector_offsets_params)
+        yield
+        self._inst_settings = copy.deepcopy(self._default_inst_settings)
 
     def _run_create_vanadium(self):
         # Provides a minimal wrapper so if we have tt_mode 'all' we can loop round
diff --git a/scripts/ErrorReporter/errorreport.py b/scripts/ErrorReporter/errorreport.py
index 267d962ca7cf102a804d91b30eefcae4d7ebd5cc..5f2ead585956db0b93d1fca0b232eda98ada1ee6 100644
--- a/scripts/ErrorReporter/errorreport.py
+++ b/scripts/ErrorReporter/errorreport.py
@@ -19,6 +19,9 @@ class CrashReportPage(QtGui.QWidget, ui_errorreport.Ui_Errorreport):
 
         self.requestTextBrowser.anchorClicked.connect(MantidQt.API.MantidDesktopServices.openUrl)
 
+        self.input_name_line_edit.textChanged.connect(self.set_button_status)
+        self.input_email_line_edit.textChanged.connect(self.set_button_status)
+
 #  The options on what to do after closing the window (exit/continue)
         self.radioButtonContinue.setChecked(True)     # Set continue to be checked by default
 
@@ -47,6 +50,12 @@ class CrashReportPage(QtGui.QWidget, ui_errorreport.Ui_Errorreport):
         value_as_string = gui_element.text()
         return expected_type(value_as_string) if value_as_string else None
 
+    def set_button_status(self):
+        if not self.input_name and not self.input_email:
+            self.nonIDShareButton.setEnabled(True)
+        else:
+            self.nonIDShareButton.setEnabled(False)
+
     @property
     def input_name(self):
         return self.get_simple_line_edit_field(line_edit="input_name_line_edit", expected_type=str)
diff --git a/scripts/ExternalInterfaces/CMakeLists.txt b/scripts/ExternalInterfaces/CMakeLists.txt
index 2d2e986408d033ea7c7aa09c0ad5175e6c023604..9f8cee956a296afe9b5841a474804783bd1e4e5c 100644
--- a/scripts/ExternalInterfaces/CMakeLists.txt
+++ b/scripts/ExternalInterfaces/CMakeLists.txt
@@ -6,7 +6,7 @@ set ( _mslice_external_root ${CMAKE_CURRENT_BINARY_DIR}/mslice )
 ExternalProject_Add ( mslice
   PREFIX ${_mslice_external_root}
   GIT_REPOSITORY "https://github.com/mantidproject/mslice.git"
-  GIT_TAG d8932699da4a76dfd88eb1d3d6dcde580debafce
+  GIT_TAG 01292c88ccc508acb16735aa5f96450e076161bb
   EXCLUDE_FROM_ALL 1
 
   CONFIGURE_COMMAND ""
diff --git a/scripts/Frequency_Domain_Analysis.py b/scripts/Frequency_Domain_Analysis.py
index be4a39c69495c7ad98428b84b36ff9204ed1f00e..c8eefe082472f1bbfda9193831dbf26ff84ae6c8 100644
--- a/scripts/Frequency_Domain_Analysis.py
+++ b/scripts/Frequency_Domain_Analysis.py
@@ -37,7 +37,11 @@ def qapp():
 
 
 app = qapp()
-ex= FrequencyDomainAnalysisGui()
-ex.resize(700,700)
-ex.show()
-app.exec_()
+try:
+    ex= FrequencyDomainAnalysisGui()
+    ex.resize(700,700)
+    ex.show()
+    app.exec_()
+except RuntimeError as error:
+    ex = QtGui.QWidget()
+    QtGui.QMessageBox.warning(ex,"Frequency Domain Analysis",str(error))
diff --git a/scripts/GSAS-II/install_gsas_common.bat b/scripts/GSAS-II/install_gsas_common.bat
index 91e2f6e4f3cbe5e143208b26b8a3e9ff44cd6547..45dab1c54ecdc021c460cc58d9fbde3593c77bd5 100755
--- a/scripts/GSAS-II/install_gsas_common.bat
+++ b/scripts/GSAS-II/install_gsas_common.bat
@@ -1,25 +1,31 @@
+setlocal enableextensions enabledelayedexpansion
+
 @echo off
 @echo Running install_gsas_latest.bat
 @echo Run with -b flag for non-interactive (quiet) mode
 @echo (don't pause after installation and install in Python user site package directory)
 
+:: find python
 @set DEV_PYTHON_EXE=%~dp0..\..\external\src\ThirdParty\lib\python2.7\python.exe
 @set RELEASE_PYTHON_EXE=%~dp0..\..\bin\python.exe
+@set PATH_PYTHON_EXE=
+python --version 2>nul
+if %ERRORLEVEL%==0 @set PATH_PYTHON_EXE=python
 
-if exist %DEV_PYTHON_EXE% goto runDev
-
-if exist %RELEASE_PYTHON_EXE% goto runRelease
-
-@echo Could not find Mantid Python executable
-goto commonExit
-
-:runDev
-%DEV_PYTHON_EXE% install_gsas_proxy.py %*
-goto commonExit
+if not "!PATH_PYTHON_EXE!" == "" (
+  set PYTHON_EXE=!PATH_PYTHON_EXE!
+) else (
+  if EXIST "%DEV_PYTHON_EXE%" (
+    @set PYTHON_EXE=%DEV_PYTHON_EXE%
+  ) else if EXIST %RELEASE_PYTHON_EXE% (
+    @set PYTHON_EXE=%RELEASE_PYTHON_EXE%
+  ) else (
+    @echo Cannot find python executable
+    exit /b 1
+  )
+) 
 
-:runRelease
-%RELEASE_PYTHON_EXE% install_gsas_proxy.py %*
-goto commonExit
+@echo Using '!PYTHON_EXE!' to install GSAS
+!PYTHON_EXE! %~dp0install_gsas_proxy.py %*
 
-:commonExit
 if not "%1"=="-b" pause
diff --git a/scripts/GSAS-II/install_gsas_latest.bat b/scripts/GSAS-II/install_gsas_latest.bat
index 0b054cbe7c989bfa511b2a0ca82e544848aa688b..fe17f665db5fa2d0a3a9e7945ffafb4703797148 100755
--- a/scripts/GSAS-II/install_gsas_latest.bat
+++ b/scripts/GSAS-II/install_gsas_latest.bat
@@ -1,2 +1,2 @@
 @echo off
-install_gsas_common.bat %*
+%~dp0install_gsas_common.bat %*
diff --git a/scripts/GSAS-II/install_gsas_proxy.py b/scripts/GSAS-II/install_gsas_proxy.py
index e8242656276456dc4c39c5df989a0afbabb5e92f..c5e10b7a56c6c3b08e83182d80890c7a1ae5c514 100644
--- a/scripts/GSAS-II/install_gsas_proxy.py
+++ b/scripts/GSAS-II/install_gsas_proxy.py
@@ -1,6 +1,7 @@
 import argparse
 import os
 import pip
+import shutil
 import site
 import subprocess
 import urllib2
@@ -53,9 +54,13 @@ def install_package(package_name):
     pip.main(["install", package_name])
 
 
-def install_gsasii(install_directory, revision_number):
+def install_gsasii(install_directory, revision_number, force_overwrite):
     gsas_home_dir = os.path.join(install_directory, GSAS_HOME_DIR_NAME)
 
+    if force_overwrite and os.path.exists(gsas_home_dir):
+        print("Removing {}".format(gsas_home_dir))
+        shutil.rmtree(gsas_home_dir)
+
     if not os.path.exists(gsas_home_dir):
         # This is the first time installing GSAS-II, so we have to make a home directory and download the SVN kit
         print("Downloading GSAS mini-SVN kit")
@@ -81,7 +86,8 @@ def install_gsasii(install_directory, revision_number):
         install_package("wxPython")
 
     print("Installing GSAS-II")
-    subprocess.call(["python", bootstrap_file_name])
+    bootstrap_process = subprocess.Popen(["python", bootstrap_file_name], stdin=subprocess.PIPE)
+    bootstrap_process.communicate(input="\n\n")
 
 
 if __name__ == "__main__":
@@ -107,6 +113,13 @@ if __name__ == "__main__":
                         help="Build server mode. Install GSAS-II in Python user site package directory "
                              "and don't wait for prompt before exiting")
 
+    parser.add_argument("-f", "--force-overwrite",
+                        action="store_true",
+                        default=False,
+                        dest="force_overwrite",
+                        help="Force overwrite mode. If a GSAS-II installation is found at the requested "
+                             "directory, remove it and perform a fresh install")
+
     args = parser.parse_args()
 
     if args.build_server_mode:
@@ -114,4 +127,4 @@ if __name__ == "__main__":
     else:
         install_dir = args.install_dir
 
-    install_gsasii(install_directory=install_dir, revision_number=args.version)
+    install_gsasii(install_directory=install_dir, revision_number=args.version, force_overwrite=args.force_overwrite)
diff --git a/scripts/GSAS-II/install_gsas_vetted.bat b/scripts/GSAS-II/install_gsas_vetted.bat
index 17255c0bc64e30648776e4b3649a538ed8f38b9e..7fb154936c99549c6316a4642a34e1096ef8e798 100755
--- a/scripts/GSAS-II/install_gsas_vetted.bat
+++ b/scripts/GSAS-II/install_gsas_vetted.bat
@@ -1,3 +1,3 @@
 @echo off
 @set VETTED_REVISION_NUMBER=3216
-install_gsas_common.bat -v %VETTED_REVISION_NUMBER% %*
+%~dp0install_gsas_common.bat -v %VETTED_REVISION_NUMBER% %*
diff --git a/scripts/Inelastic/CrystalField/fitting.py b/scripts/Inelastic/CrystalField/fitting.py
index f07526d4cfd5b9ca3a1a6fed0a54e474269757c4..91f1a34f1a7e4c6430f4f529acd32d4211021503 100644
--- a/scripts/Inelastic/CrystalField/fitting.py
+++ b/scripts/Inelastic/CrystalField/fitting.py
@@ -327,7 +327,10 @@ class CrystalField(object):
         return out
 
     def makeMultiSpectrumFunction(self):
-        return re.sub(r'FWHM[X|Y]\d+=\(\),', '', str(self.function))
+        fun = re.sub(r'FWHM[X|Y]\d+=\(\),', '', str(self.function))
+        fun = re.sub(r'(name=.*?,)(.*?)(Temperatures=\(.*?\),)',r'\1\3\2', fun)
+        fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun)
+        return fun
 
     @property
     def Ion(self):
@@ -1319,8 +1322,6 @@ class CrystalFieldFit(object):
         """
         from mantid.api import AlgorithmManager
         fun = self.model.makeMultiSpectrumFunction()
-        if 'CrystalFieldMultiSpectrum' in fun:
-            fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun)
         alg = AlgorithmManager.createUnmanaged('EstimateFitParameters')
         alg.initialize()
         alg.setProperty('Function', fun)
@@ -1375,8 +1376,6 @@ class CrystalFieldFit(object):
             fun = str(self.model.function)
         else:
             fun = self.model.makeMultiSpectrumFunction()
-        if 'CrystalFieldMultiSpectrum' in fun:
-            fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun)
         alg = AlgorithmManager.createUnmanaged('Fit')
         alg.initialize()
         alg.setProperty('Function', fun)
diff --git a/scripts/Inelastic/CrystalField/function.py b/scripts/Inelastic/CrystalField/function.py
index c92547e806ad2d4cbd3b5a842cb8fe38368c2121..38813e9d020fb18d5b38a50496dcecb60f42e5f2 100644
--- a/scripts/Inelastic/CrystalField/function.py
+++ b/scripts/Inelastic/CrystalField/function.py
@@ -364,6 +364,10 @@ class ResolutionModel:
                 self.model = [self._makeModel(m, xstart, xend, accuracy) for m in model]
                 self.multi = True
                 return
+            elif hasattr(model[0], 'model'):
+                self.model = [m.model for m in model]
+                self.multi = True
+                return
             elif isinstance(model[0], tuple):
                 for m in model:
                     self._checkModel(m)
diff --git a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
index 2a142259f03cb927db674ee71cf019d8aa870e70..a53c05ed4383ba4d0dbe9877c697c0fc3ca124d3 100644
--- a/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
+++ b/scripts/Inelastic/Direct/ISISDirecInelasticConfig.py
@@ -82,7 +82,8 @@ class UserProperties(object):
         self._rb_exist[recent_date_id] = rb_exist
 
         # a data which define the cycle ID e.g 2014_3 or something
-        self._cycle_IDs[recent_date_id] = (str(cycle[5:9]), str(cycle[9:10]))
+        self._cycle_IDs[recent_date_id] = (str(cycle[5:9]), str(cycle[9:]))
+
         self._instrument[recent_date_id] = str(instrument).upper()
         self._rb_dirs[recent_date_id] = rb_folder_or_id
         if self._recent_dateID:
@@ -259,7 +260,15 @@ class UserProperties(object):
         if isinstance(cycle, int):
             cycle = convert_cycle_int(cycle)
         if isinstance(cycle, str):
-            if len(cycle) != 10:
+            if len(cycle) == 11:
+                last_letter = cycle[-1]
+                if not last_letter.upper() in {'A','B','C','D','E'}:
+                    raise  RuntimeError("Cycle should be a string in the form CYCLEYYYYN[A,B,C,D "
+                                        "N-- the cycle's number in a year or integer in the form: YYYYN or YYN "
+                                        "but it is {0}".format(cycle))
+                else:
+                    cycle = cycle.upper()
+            elif len(cycle) < 10:
                 cycle = cycle.replace('_', '')
                 try:
                     cycle = int(cycle)
@@ -384,7 +393,7 @@ class MantidConfigDirectInelastic(object):
         # instrument and cycle number.
         # the common part of all strings, generated dynamically as function of input class parameters.
         self._dynamic_options_base = ['default.facility=ISIS']
-        # Path to python scripts, defined and used by mantid wrt to Mantid Root (this path may be version specific)
+        # Path to python scripts, defined and used by Mantid wrt to Mantid Root (this path may be version specific)
         self._python_mantid_path = ['scripts/Calibration/', 'scripts/Examples/', 'scripts/Interface/', 'scripts/Vates/']
         # Static paths to user scripts, defined wrt script repository root
         self._python_user_scripts = set(['direct_inelastic/ISIS/qtiGenie/'])
@@ -653,7 +662,7 @@ class MantidConfigDirectInelastic(object):
         # does not work if user is not defined
         if self._user is None:
             return None
-        # parse job description file, fail down on default behavior if
+        # parse job description file, fail down on default behaviour if
         # user files description is not there
         try:
             domObj = minidom.parse(job_description_file)
@@ -692,11 +701,13 @@ class MantidConfigDirectInelastic(object):
            (cycle ID)
            The agreement on the naming as currently in ISIS:
            e.g: /archive/NDXMERLIN/Instrument/data/cycle_08_1
+
+            Note: will fail if cycle numbers ever become a 2-digit numbers e.g. cycle_22_10
         """
         # cycle folder have short form without leading numbers
         cycle_fold_n = int(cycle_ID[0]) - 2000
         folder = os.path.join(self._root_data_folder, 'NDX' + instr.upper(),
-                              "Instrument/data/cycle_{0:02}_{1}".format(cycle_fold_n, str(cycle_ID[1])))
+                              "Instrument/data/cycle_{0:02}_{1}".format(cycle_fold_n, str(cycle_ID[1][0])))
         return folder
 
     def is_inelastic(self, instr_name):
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py
index ea3a39182351d02acfae4c7ba38b63f875b4b143..38e32a99e771be116de5944369773ac4cbe31947 100644
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py
+++ b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py
@@ -1,8 +1,6 @@
-#pylint: disable=R0902, W0221, W0621
 """
-    Classes for each reduction step. Those are kept separately
-    from the the interface class so that the HFIRReduction class could
-    be used independently of the interface implementation
+    Legacy class that old LR reduction options.
+    This is still in use for backward compatibility.
 """
 from __future__ import (absolute_import, division, print_function)
 import xml.dom.minidom
@@ -77,62 +75,13 @@ class DataSets(BaseScriptElement):
         super(DataSets, self).__init__()
         self.reset()
 
+#pylint: disable = unused-argument, arguments-differ
     def to_script(self, for_automated_reduction=False):
         """
             Generate reduction script
             @param execute: if true, the script will be executed
         """
-
-#        if for_automated_reduction:
-#            script =  "RefLReduction(RunNumbers=[%s],\n" % ','.join([str(i) for i in self.data_files])
-#        else:
-#            script =  "RefLReduction(RunNumbers=[int(%s)],\n" % str(self.data_files[0])
-        script =  "RefLReduction(RunNumbers=[%s],\n" % ','.join([str(i) for i in self.data_files])
-        script += "              NormalizationRunNumber=%d,\n" % self.norm_file
-        script += "              SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels)
-        script += "              SubtractSignalBackground=%s,\n" % str(self.DataBackgroundFlag)
-        script += "              SignalBackgroundPixelRange=%s,\n" % str(self.DataBackgroundRoi[:2])
-        script += "              NormFlag=%s,\n" % str(self.NormFlag)
-        script += "              NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels)
-        script += "              NormBackgroundPixelRange=%s,\n" % str(self.NormBackgroundRoi)
-        script += "              SubtractNormBackground=%s,\n" % str(self.NormBackgroundFlag)
-        script += "              LowResDataAxisPixelRangeFlag=%s,\n" % str(self.data_x_range_flag)
-        script += "              LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range)
-        script += "              LowResNormAxisPixelRangeFlag=%s,\n" % str(self.norm_x_range_flag)
-        script += "              LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range)
-        script += "              TOFRange=%s,\n" % str(self.DataTofRange)
-
-        _incident_medium_str = str(self.incident_medium_list[0])
-        _list = _incident_medium_str.split(',')
-
-        script += "              IncidentMediumSelected='%s',\n" % str(_list[self.incident_medium_index_selected])
-        script += "              GeometryCorrectionFlag=%s,\n" % str(self.geometry_correction_switch)
-        script += "              QMin=%s,\n" % str(self.q_min)
-        script += "              QStep=%s,\n" % str(self.q_step)
-
-        # Angle offset
-        if self.angle_offset != 0.0:
-            script += "              AngleOffset=%s,\n" % str(self.angle_offset)
-            script += "              AngleOffsetError=%s,\n" % str(self.angle_offset_error)
-
-        # sf configuration file
-#        if self.scaling_factor_file != '':
-        if self.scaling_factor_file_flag:
-            script += "ScalingFactorFile='%s',\n" % str(self.scaling_factor_file)
-        else:
-            script += "ScalingFactorFile='',\n"
-
-        script += "SlitsWidthFlag=%s,\n" % str(self.slits_width_flag)
-
-        # The output should be slightly different if we are generating
-        # a script for the automated reduction
-        if for_automated_reduction:
-            script += "              OutputWorkspace='reflectivity_'+%s)" % str(self.data_files[0])
-        else:
-            script += "              OutputWorkspace='reflectivity_%s')" % str(self.data_files[0])
-        script += "\n"
-
-        return script
+        raise RuntimeError("refl_data_script.DataSets.to_script is deprecated")
 
     def update(self):
         """
@@ -144,75 +93,75 @@ class DataSets(BaseScriptElement):
         """
             Create XML from the current data.
         """
-        xml  = "<RefLData>\n"
-        xml += "<peak_selection_type>%s</peak_selection_type>\n" % self.DataPeakSelectionType
-        xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0])
-        xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1])
-        xml += "<peak_discrete_selection>%s</peak_discrete_selection>\n" % self.DataPeakDiscreteSelection
-        xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag)
-        xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0])
-        xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1])
-        xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2])
-        xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3])
-        xml += "<tof_range_flag>%s</tof_range_flag>\n" % str(self.TofRangeFlag)
-        xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0])
-        xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1])
-        xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files])
-        xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0])
-        xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1])
-        xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag)
-
-        xml += "<tthd_value>%s</tthd_value>\n" % str(self.tthd_value)
-        xml += "<ths_value>%s</ths_value>\n" % str(self.ths_value)
-
-        xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag)
-        xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag)
-        xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1])
-        xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0])
-
-        xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0])
-        xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1])
-        xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag)
-        xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0])
-        xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1])
-        xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file)
+        _xml  = "<RefLData>\n"
+        _xml += "<peak_selection_type>%s</peak_selection_type>\n" % self.DataPeakSelectionType
+        _xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0])
+        _xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1])
+        _xml += "<peak_discrete_selection>%s</peak_discrete_selection>\n" % self.DataPeakDiscreteSelection
+        _xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag)
+        _xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0])
+        _xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1])
+        _xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2])
+        _xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3])
+        _xml += "<tof_range_flag>%s</tof_range_flag>\n" % str(self.TofRangeFlag)
+        _xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0])
+        _xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1])
+        _xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files])
+        _xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0])
+        _xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1])
+        _xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag)
+
+        _xml += "<tthd_value>%s</tthd_value>\n" % str(self.tthd_value)
+        _xml += "<ths_value>%s</ths_value>\n" % str(self.ths_value)
+
+        _xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag)
+        _xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag)
+        _xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1])
+        _xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0])
+
+        _xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0])
+        _xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1])
+        _xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag)
+        _xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0])
+        _xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1])
+        _xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file)
 
         # Q cut
-        xml += "<q_min>%s</q_min>\n" % str(self.q_min)
-        xml += "<q_step>%s</q_step>\n" % str(self.q_step)
-        xml += "<auto_q_binning>%s</auto_q_binning>\n" % str(self.auto_q_binning)
-        xml += "<overlap_lowest_error>%s</overlap_lowest_error>\n" % str(self.overlap_lowest_error)
-        xml += "<overlap_mean_value>%s</overlap_mean_value>\n" % str(self.overlap_mean_value)
+        _xml += "<q_min>%s</q_min>\n" % str(self.q_min)
+        _xml += "<q_step>%s</q_step>\n" % str(self.q_step)
+        _xml += "<auto_q_binning>%s</auto_q_binning>\n" % str(self.auto_q_binning)
+        _xml += "<overlap_lowest_error>%s</overlap_lowest_error>\n" % str(self.overlap_lowest_error)
+        _xml += "<overlap_mean_value>%s</overlap_mean_value>\n" % str(self.overlap_mean_value)
 
         # Angle offset
-        xml += "<angle_offset>%s</angle_offset>\n" % str(self.angle_offset)
-        xml += "<angle_offset_error>%s</angle_offset_error>\n" % str(self.angle_offset_error)
+        _xml += "<angle_offset>%s</angle_offset>\n" % str(self.angle_offset)
+        _xml += "<angle_offset_error>%s</angle_offset_error>\n" % str(self.angle_offset_error)
 
         # scaling factor file name
-        xml += "<scaling_factor_flag>%s</scaling_factor_flag>\n" % str(self.scaling_factor_file_flag)
-        xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file)
-        xml += "<slits_width_flag>%s</slits_width_flag>\n" % str(self.slits_width_flag)
+        _xml += "<scaling_factor_flag>%s</scaling_factor_flag>\n" % str(self.scaling_factor_file_flag)
+        _xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file)
+        _xml += "<slits_width_flag>%s</slits_width_flag>\n" % str(self.slits_width_flag)
 
         # geometry correction
-        xml += "<geometry_correction_switch>%s</geometry_correction_switch>\n" % str(self.geometry_correction_switch)
+        _xml += "<geometry_correction_switch>%s</geometry_correction_switch>\n" % str(self.geometry_correction_switch)
 
         #incident medium
-        xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0])
-        xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected)
+        _xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0])
+        _xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected)
 
         #fourth column precision
-        xml += "<fourth_column_flag>%s</fourth_column_flag>\n" % str(self.fourth_column_flag)
-        xml += "<fourth_column_dq0>%s</fourth_column_dq0>\n" % str(self.fourth_column_dq0)
-        xml += "<fourth_column_dq_over_q>%s</fourth_column_dq_over_q>\n" % str(self.fourth_column_dq_over_q)
+        _xml += "<fourth_column_flag>%s</fourth_column_flag>\n" % str(self.fourth_column_flag)
+        _xml += "<fourth_column_dq0>%s</fourth_column_dq0>\n" % str(self.fourth_column_dq0)
+        _xml += "<fourth_column_dq_over_q>%s</fourth_column_dq_over_q>\n" % str(self.fourth_column_dq_over_q)
 
         # Primary fraction
         if self.clocking_from is not None and self.clocking_to is not None:
-            xml += "<clocking_from>%s</clocking_from>\n" % str(self.clocking_from)
-            xml += "<clocking_to>%s</clocking_to>\n" % str(self.clocking_to)
+            _xml += "<clocking_from>%s</clocking_from>\n" % str(self.clocking_from)
+            _xml += "<clocking_to>%s</clocking_to>\n" % str(self.clocking_to)
 
-        xml += "</RefLData>\n"
+        _xml += "</RefLData>\n"
 
-        return xml
+        return _xml
 
     def from_xml(self, xml_str):
         self.reset()
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py
index 7061a8ec7e6b1a084646f95ecd7ca754551a865d..224d72ce088fd5d154121348302f47092661db78 100644
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py
+++ b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py
@@ -7,7 +7,6 @@ from __future__ import (absolute_import, division, print_function)
 import xml.dom.minidom
 from reduction_gui.reduction.scripter import BaseScriptElement
 from reduction_gui.reduction.reflectometer.refl_data_script import DataSets as REFLDataSets
-from reduction_gui.reduction.reflectometer.refm_data_script import DataSets as REFMDataSets
 
 
 class DataSeries(BaseScriptElement):
@@ -24,18 +23,7 @@ class DataSeries(BaseScriptElement):
             Generate reduction script
             @param execute: if true, the script will be executed
         """
-        script = "import os\n"
-        script += "import time\n"
-        script += "t0=time.time()\n"
-        script += "from reduction.command_interface import ReductionSingleton\n"
-        script += "ReductionSingleton.clean()\n"
-
-        for item in self.data_sets:
-            script += item.to_script()
-            script += "\n"
-        script += "print \"Reduction time: %g\\n\" % (time.time()-t0)\n"
-
-        return script
+        raise RuntimeError("refl_data_series.DataSeries.to_script is deprecated")
 
     def update(self):
         """
@@ -47,12 +35,12 @@ class DataSeries(BaseScriptElement):
         """
             Create XML from the current data.
         """
-        xml  = "<DataSeries>\n"
+        _xml  = "<DataSeries>\n"
         for item in self.data_sets:
-            xml += item.to_xml()
-        xml += "</DataSeries>\n"
+            _xml += item.to_xml()
+        _xml += "</DataSeries>\n"
 
-        return xml
+        return _xml
 
     def from_xml(self, xml_str):
         """
@@ -70,9 +58,6 @@ class DataSeries(BaseScriptElement):
         element_list = dom.getElementsByTagName("Data")
         if len(element_list)==0:
             element_list = dom.getElementsByTagName("RefLData")
-        if len(element_list)==0:
-            self._data_class = REFMDataSets
-            element_list = dom.getElementsByTagName("RefMData")
 
         if len(element_list)>0:
             for item in element_list:
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py
deleted file mode 100644
index 83201441fcc3ac43e31d34103fec0b7a6b4b2f6e..0000000000000000000000000000000000000000
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#pylint: disable = invalid-name
-"""
-    This class holds all the necessary information to create a reduction script.
-"""
-from __future__ import (absolute_import, division, print_function)
-import time
-from reduction_gui.reduction.scripter import BaseReductionScripter
-
-
-class REFLReductionScripter(BaseReductionScripter):
-    """
-        Reduction scripter for REFL
-    """
-
-    def __init__(self, name="REFL"):
-        super(REFLReductionScripter, self).__init__(name=name)
-
-    def to_script(self, file_name=None):
-        """
-            Spits out the text of a reduction script with the current state.
-            @param file_name: name of the file to write the script to
-        """
-        """
-            Spits out the text of a reduction script with the current state.
-            @param file_name: name of the file to write the script to
-        """
-        script = "# %s reduction script\n" % self.instrument_name
-        script += "# Script automatically generated on %s\n\n" % time.ctime(time.time())
-
-        script += "import mantid\n"
-        script += "from mantid.simpleapi import *\n"
-        script += "\n"
-        script += "#remove all previous workspaces\n"
-        script += "list_mt = AnalysisDataService.getObjectNames()\n"
-        script += "for _mt in list_mt:\n"
-        script += "    if _mt.find('_scaled') != -1:\n"
-        script += "        AnalysisDataService.remove(_mt)\n"
-        script += "    if _mt.find('reflectivity') != -1:\n"
-        script += "        AnalysisDataService.remove(_mt)\n"
-        script += "\n"
-
-        for item in self._observers:
-            if item.state() is not None:
-                script += str(item.state())
-
-        if file_name is not None:
-            f = open(file_name, 'w')
-            f.write(script)
-            f.close()
-
-        return script
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py
deleted file mode 100644
index e7edad83b8f2e462351c94fd9caa3f715ac7ba35..0000000000000000000000000000000000000000
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py
+++ /dev/null
@@ -1,179 +0,0 @@
-from __future__ import (absolute_import, division, print_function)
-
-# pylint: disable=invalid-name
-"""
-    This class holds all the necessary information to create a reduction script.
-    This is a fake version of the Reducer for testing purposes.
-"""
-import time
-from reduction_gui.reduction.scripter import BaseReductionScripter
-import sys
-
-# Check whether Mantid is available
-try:
-    import mantidplot  # noqa
-
-    HAS_MANTID = True
-except:
-    HAS_MANTID = False
-
-
-class REFLSFCalculatorScripter(BaseReductionScripter):
-    """
-        Organizes the set of reduction parameters that will be used to
-        create a reduction script. Parameters are organized by groups that
-        will each have their own UI representation.
-    """
-
-    def __init__(self, name="REFL"):
-        super(REFLSFCalculatorScripter, self).__init__(name=name)
-
-    def create_script(self, script_part2):
-        """
-        This creates the special script for the sfCalculator algorithm
-        """
-        algo = 'sfCalculator.calculate'
-
-        script_split = script_part2.split('\n')
-
-        run_number = []
-        attenuator = []
-
-        peak_from = []
-        peak_to = []
-        back_from = []
-        back_to = []
-
-        tof_range = [0.0, 200000.0]
-        incident_medium = ''
-        incident_medium_index = -1
-
-        scaling_factor_file = ''
-
-        for _line in script_split:
-            if _line != '':
-                _line_split = _line.split(':')
-                _arg = _line_split[0]
-                _val = _line_split[1]
-
-                if _arg == 'Scaling factor file' and scaling_factor_file == '':
-                    scaling_factor_file = _val.strip()
-
-                elif _arg == 'Run number':
-                    run_number.append(_val)
-
-                elif _arg == 'TOF from' and tof_range[0] == 0.0:
-                    tof_range[0] = float(_val)
-
-                elif _arg == 'TOF to' and tof_range[1] == 200000.0:
-                    tof_range[1] = float(_val)
-
-                elif _arg == 'Incident medium' and incident_medium.strip() == '':
-                    incident_medium = _val[4:-3]
-
-                elif _arg == 'Incident medium index' and incident_medium_index == -1:
-                    incident_medium_index = int(_val)
-
-                elif _arg == 'Number of attenuator':
-                    attenuator.append(_val)
-
-                elif _arg == 'Peak from pixel':
-                    peak_from.append(_val)
-
-                elif _arg == 'Peak to pixel':
-                    peak_to.append(_val)
-
-                elif _arg == 'Back from pixel':
-                    back_from.append(_val)
-
-                elif _arg == 'Back to pixel':
-                    back_to.append(_val)
-
-        run_attenuator = [run.strip() + ":" + att.strip() for (run, att) in zip(run_number, attenuator)]
-        join_string = ','
-        script_run_attenuator = join_string.join(run_attenuator)
-
-        list_peak_back = [[int(pixel) for pixel in line] for line in zip(peak_from, peak_to, back_from, back_to)]
-
-        new_script = algo + '(string_runs="' + script_run_attenuator + '"'
-        new_script += ',list_peak_back=' + str(list_peak_back)
-
-        # retrieve right incident medium
-
-        incident_medium_list = incident_medium.split(',')
-        incident_medium = incident_medium_list[incident_medium_index]
-        new_script += ',incident_medium="' + incident_medium.strip() + '"'
-
-        new_script += ',output_file_name="' + scaling_factor_file + '"'
-
-        new_script += ',tof_range=' + str(tof_range) + ')'
-
-        if scaling_factor_file == '':
-            return ''
-
-        return new_script
-
-    def to_script(self, file_name=None):
-        """
-            Spits out the text of a reduction script with the current state.
-            @param file_name: name of the file to write the script to
-        """
-        script = "# %s scaling factor calculation script\n" % self.instrument_name
-        script += "# Script automatically generated on %s\n\n" % time.ctime(time.time())
-
-        script += "import os\n"
-        script += "import mantid\n"
-        script += "from mantid.simpleapi import *\n"
-        script += "import sfCalculator\n"
-
-        script += "REF_RED_OUTPUT_MESSAGE = ''\n\n"
-
-        script_part2 = ''
-        for item in self._observers:
-            if item.state() is not None:
-                script_part2 += str(item.state())
-
-        _script = self.create_script(script_part2)
-        if _script == '':
-            print('Please define a Scaling Factor File Name')
-            raise RuntimeError
-
-        script += _script
-
-        if file_name is not None:
-            f = open(file_name, 'w')
-            f.write(script)
-            f.close()
-
-        return script
-
-    def apply(self):
-        """
-            Apply the reduction process
-        """
-        if HAS_MANTID:
-            script = self.to_script(None)
-
-            print(script)
-
-            try:
-                t0 = time.time()
-                exec (script)
-                delta_t = time.time() - t0
-                print("SF calculation time: %5.2g sec" % delta_t)
-                # Update scripter
-                for item in self._observers:
-                    if item.state() is not None:
-                        item.state().update()
-            except:
-                # Update scripter [Duplicated code because we can't use 'finally' on python 2.4]
-                for item in self._observers:
-                    if item.state() is not None:
-                        # Things might be broken, so update what we can
-                        try:
-                            item.state().update()
-                        except:
-                            pass
-                raise RuntimeError(sys.exc_info()[1])
-        else:
-            raise RuntimeError("SF calculation could not be executed: Mantid could not be imported")
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py
deleted file mode 100644
index 5f617c4811143e36541f9404eb68e4922687d1fb..0000000000000000000000000000000000000000
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py
+++ /dev/null
@@ -1,150 +0,0 @@
-"""
-    Classes for each reduction step. Those are kept separately
-    from the the interface class so that the HFIRReduction class could
-    be used independently of the interface implementation
-"""
-from __future__ import (absolute_import, division, print_function)
-import xml.dom.minidom
-from reduction_gui.reduction.scripter import BaseScriptElement
-
-
-class DataSets(BaseScriptElement):
-
-    data_file = 0
-    incident_medium_list = ['H2O']
-    incident_medium_index_selected = 0
-    number_attenuator = 0
-    peak_selection = [0, 0]
-    back_selection = [0, 0]
-    lambda_requested = 'N/A'
-    s1h = 'N/A'
-    s2h = 'N/A'
-    s1w = 'N/A'
-    s2w = 'N/A'
-    scaling_factor_file = ''
-    tof_min = 0.
-    tof_max = 200000.
-
-    def __init__(self):
-        super(DataSets, self).__init__()
-        self.reset()
-
-    def to_script(self):
-        """
-            Generate reduction script
-            @param execute: if true, the script will be executed
-        """
-        script = 'Run number: %s \n' % str(self.data_file)
-
-#        _u_list = self.incident_medium_list
-#        _list = str(_u_list[0]).split(',')
-
-        script += 'Incident medium: %s \n' % str(self.incident_medium_list)
-#        script += 'Incident medium: %s \n' % str(self.incident_medium_list[self.incident_medium_index_selected])
-#        script += 'Incident medium: %s \n' % str(_list[self.incident_medium_index_selected])
-        script += 'Incident medium index: %s \n' % str(self.incident_medium_index_selected)
-        script += 'TOF from: %s \n' % str(self.tof_min)
-        script += 'TOF to: %s \n' % str(self.tof_max)
-        script += 'Scaling factor file: %s \n' % str(self.scaling_factor_file)
-        script += 'Number of attenuator: %s \n' % str(self.number_attenuator)
-        script += 'Peak from pixel: %s \n' % str(self.peak_selection[0])
-        script += 'Peak to pixel: %s \n' % str(self.peak_selection[1])
-        script += 'Back from pixel: %s \n' % str(self.back_selection[0])
-        script += 'Back to pixel: %s \n' % str(self.back_selection[1])
-
-        return script
-
-    def update(self):
-        """
-            Update transmission from reduction output
-        """
-        pass
-
-    def to_xml(self):
-        """
-            Create XML from the current data.
-        """
-        xml = "<RefLSFCalculator>\n"
-#        xml += "<incident_medium_list>%s</incident_medium_list>\n" % ','.join([str(i) for i in self.incident_medium_list])
-        xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0])
-        xml += "<tof_min>%s</tof_min>\n" % str(self.tof_min)
-        xml += "<tof_max>%s</tof_max>\n" % str(self.tof_max)
-        xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected)
-        xml += "<data_file>%s</data_file>\n" % str(self.data_file)
-        xml += "<number_attenuator>%s</number_attenuator>\n" % str(self.number_attenuator)
-        xml += "<peak_selection_from_pixel>%s</peak_selection_from_pixel>\n" % str(self.peak_selection[0])
-        xml += "<peak_selection_to_pixel>%s</peak_selection_to_pixel>\n" % str(self.peak_selection[1])
-        xml += "<back_selection_from_pixel>%s</back_selection_from_pixel>\n" % str(self.back_selection[0])
-        xml += "<back_selection_to_pixel>%s</back_selection_to_pixel>\n" % str(self.back_selection[1])
-        xml += "<lambda_requested>%s</lambda_requested>\n" % str(self.lambda_requested)
-        xml += "<s1h>%s</s1h>\n" % str(self.s1h)
-        xml += "<s2h>%s</s2h>\n" % str(self.s2h)
-        xml += "<s1w>%s</s1w>\n" % str(self.s1w)
-        xml += "<s2w>%s</s2w>\n" % str(self.s2w)
-        xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file)
-        xml += "</RefLSFCalculator>\n"
-
-        return xml
-
-    def from_xml(self, xml_str):
-        self.reset()
-        dom = xml.dom.minidom.parseString(xml_str)
-        self.from_xml_element(dom)
-        dom.getElementsByTagName("RefLSFCalculator")
-
-    def from_xml_element(self, instrument_dom):
-        """
-            Read in data from XML
-            @param xml_str: text to read the data from
-        """
-        # incident medium
-        self.incident_medium_list = BaseScriptElement.getStringList(instrument_dom, "incident_medium_list")
-        self.incident_medium_index_selected = BaseScriptElement.getIntElement(instrument_dom, "incident_medium_index_selected")
-
-        self.tof_min = BaseScriptElement.getFloatElement(instrument_dom, "tof_min")
-        self.tof_max = BaseScriptElement.getFloatElement(instrument_dom, "tof_max")
-
-        # run number
-        self.data_file = BaseScriptElement.getIntElement(instrument_dom, "data_file")
-
-        # number of attenuator
-        self.number_attenuator = BaseScriptElement.getIntElement(instrument_dom, "number_attenuator")
-
-        # peak selection from and to
-        self.peak_selection = [BaseScriptElement.getIntElement(instrument_dom, "peak_selection_from_pixel"),
-                               BaseScriptElement.getIntElement(instrument_dom, "peak_selection_to_pixel")]
-
-        # background flag and selection from and to
-        self.back_selection = [BaseScriptElement.getIntElement(instrument_dom, "back_selection_from_pixel"),
-                               BaseScriptElement.getIntElement(instrument_dom, "back_selection_to_pixel")]
-
-        # lambda requested
-        self.lambda_requested = BaseScriptElement.getStringElement(instrument_dom, "lambda_requested")
-
-        # s1h, s2h, s1w, s2w
-        self.s1h = BaseScriptElement.getStringElement(instrument_dom, "s1h")
-        self.s2h = BaseScriptElement.getStringElement(instrument_dom, "s2h")
-        self.s1w = BaseScriptElement.getStringElement(instrument_dom, "s1w")
-        self.s2w = BaseScriptElement.getStringElement(instrument_dom, "s2w")
-
-        # scaling factor file
-        self.scaling_factor_file = BaseScriptElement.getStringElement(instrument_dom, "scaling_factor_file")
-
-    def reset(self):
-        """
-            Reset state
-        """
-        self.data_file = DataSets.data_file
-        self.incident_medium_list = DataSets.incident_medium_list
-        self.incident_medium_index_selected = DataSets.incident_medium_index_selected
-        self.number_attenuator = DataSets.number_attenuator
-        self.peak_selection = DataSets.peak_selection
-        self.back_selection = DataSets.back_selection
-        self.lambda_requested = DataSets.lambda_requested
-        self.s1h = DataSets.s1h
-        self.s2h = DataSets.s2h
-        self.s1w = DataSets.s1w
-        self.s2w = DataSets.s2w
-        self.tof_min = DataSets.tof_min
-        self.tof_max = DataSets.tof_max
-        self.scaling_factor_file = DataSets.scaling_factor_file
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py
deleted file mode 100644
index 170889b7b4e4b25135ade0a8c6c6f76053e0dab9..0000000000000000000000000000000000000000
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py
+++ /dev/null
@@ -1,82 +0,0 @@
-"""
-    Classes for each reduction step. Those are kept separately
-    from the the interface class so that the HFIRReduction class could
-    be used independently of the interface implementation
-"""
-from __future__ import (absolute_import, division, print_function)
-import xml.dom.minidom
-from reduction_gui.reduction.scripter import BaseScriptElement
-from reduction_gui.reduction.reflectometer.refl_sf_calculator_data_script import DataSets as REFLDataSets
-
-
-class DataSeries(BaseScriptElement):
-
-    data_sets = []
-
-    def __init__(self, data_class=REFLDataSets):
-        super(DataSeries, self).__init__()
-        self._data_class = data_class
-        self.reset()
-
-    def to_script(self):
-        """
-            Generate reduction script
-            @param execute: if true, the script will be executed
-        """
-        script = ""
-        for item in self.data_sets:
-            script += item.to_script()
-            script += "\n"
-
-        return script
-
-    def update(self):
-        """
-            Update transmission from reduction output
-        """
-        pass
-
-    def to_xml(self):
-        """
-            Create XML from the current data.
-        """
-
-        xml  = "<DataSeries>\n"
-        for item in self.data_sets:
-            xml += item.to_xml()
-        xml += "</DataSeries>\n"
-
-        return xml
-
-    def from_xml(self, xml_str):
-        """
-            Read in data from XML
-            @param xml_str: text to read the data from
-        """
-        self.reset()
-        self.data_sets = []
-        dom = xml.dom.minidom.parseString(xml_str)
-
-#        # Get Mantid version
-#        mtd_version = BaseScriptElement.getMantidBuildVersion(dom)
-
-        self._data_class = REFLDataSets
-        element_list = dom.getElementsByTagName("Data")
-        if len(element_list)==0:
-            element_list = dom.getElementsByTagName("RefLSFCalculator")
-
-        if len(element_list)>0:
-            for item in element_list:
-                if item is not None:
-                    data_set = self._data_class()
-                    data_set.from_xml_element(item)
-                    self.data_sets.append(data_set)
-
-        if len(self.data_sets)==0:
-            self.data_sets = [self._data_class()]
-
-    def reset(self):
-        """
-            Reset state
-        """
-        self.data_sets = [self._data_class()]
diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py
deleted file mode 100644
index 4918bb4002216c473e3d168c7f66aa0a96f0796c..0000000000000000000000000000000000000000
--- a/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""
-    Reduction script for REFM
-"""
-from __future__ import (absolute_import, division, print_function)
-import xml.dom.minidom
-import os
-from reduction_gui.reduction.scripter import BaseScriptElement
-
-
-class DataSets(BaseScriptElement):
-
-    DataPeakPixels = [215, 225]
-    DataBackgroundFlag = False
-    DataBackgroundRoi = [115, 137, 123, 137]
-    DataTofRange = [10700., 24500.]
-    crop_TOF_range = True
-    TOFstep = 400.0
-
-    data_x_range_flag = False
-    data_x_range = [115, 210]
-
-    norm_x_range_flag = False
-    norm_x_range = [90, 160]
-
-    NormFlag = True
-    NormPeakPixels = [120, 130]
-    NormBackgroundFlag = False
-    NormBackgroundRoi = [115, 137]
-
-    # Data files
-    data_files = [0]
-    norm_file = 0
-
-    # Q range
-    q_min = 0.0025
-    q_step = -0.01
-    q_bins = 40
-    q_log = True
-
-    # scattering angle
-    theta = 0.0
-    use_center_pixel = True
-
-    # Sample log overwrites
-    set_detector_angle = False
-    detector_angle = 0.0
-    set_detector_angle_offset = False
-    detector_angle_offset = 0.0
-    set_direct_pixel = False
-    direct_pixel = 0.0
-
-    output_dir = ''
-
-    def __init__(self):
-        super(DataSets, self).__init__()
-        self.reset()
-
-    def to_script(self, for_automated_reduction=False):
-        """
-            Generate reduction script
-            @param execute: if true, the script will be executed
-        """
-        if for_automated_reduction:
-            return self._automated_reduction()
-
-        script = "import mantid\n"
-        script += "from mantid.api import *\n"
-        script += "from mantid.kernel import *\n"
-        script += "from mantid.simpleapi import *\n"
-
-        script = "a = RefReduction(DataRun='%s',\n" % ','.join([str(i) for i in self.data_files])
-        script += "              NormalizationRun='%s',\n" % str(self.norm_file)
-        script += "              Instrument='REF_M',\n"
-        script += "              PolarizedData=True,\n"
-
-        script += "              SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels)
-        script += "              SubtractSignalBackground=%s,\n" % str(self.DataBackgroundFlag)
-        script += "              SignalBackgroundPixelRange=%s,\n" % str(self.DataBackgroundRoi[:2])
-        script += "              PerformNormalization=%s,\n" % str(self.NormFlag)
-        script += "              NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels)
-        script += "              NormBackgroundPixelRange=%s,\n" % str(self.NormBackgroundRoi)
-        script += "              SubtractNormBackground=%s,\n" % str(self.NormBackgroundFlag)
-
-        script += "              CropLowResDataAxis=%s,\n" % str(self.data_x_range_flag)
-        if self.data_x_range_flag:
-            script += "              LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range)
-
-        script += "              CropLowResNormAxis=%s,\n" % str(self.norm_x_range_flag)
-        if self.norm_x_range_flag:
-            script += "              LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range)
-
-        if self.crop_TOF_range:
-            script += "              TOFMin=%s,\n" % str(self.DataTofRange[0])
-            script += "              TOFMax=%s,\n" % str(self.DataTofRange[1])
-            script += "              TOFStep=%s,\n" % str(self.TOFstep)
-        else:
-            script += "              NBins=%s,\n" % str(self.q_bins)
-
-        # Scattering angle options
-        if self.use_center_pixel:
-            if self.set_detector_angle:
-                script += "              DetectorAngle=%s,\n" % str(self.detector_angle)
-            if self.set_detector_angle_offset:
-                script += "              DetectorAngle0=%s,\n" % str(self.detector_angle_offset)
-            if self.set_direct_pixel:
-                script += "              DirectPixel=%s,\n" % str(self.direct_pixel)
-
-        else:
-            script += "              Theta=%s,\n" % str(self.theta)
-
-        # The output should be slightly different if we are generating
-        # a script for the automated reduction
-        basename = os.path.basename(str(self.data_files[0]))
-        script += "              OutputWorkspacePrefix='reflectivity_%s')\n" % basename
-        script += "\n"
-
-        # Store the log output so it can be shown in the UI
-        script += "from reduction_workflow.command_interface import ReductionSingleton\n"
-        script += "reducer_log = ReductionSingleton()\n"
-        script += "output_log = 'Please make sure the new-style Python API is turned ON by default\\n'\n"
-        script += "output_log += 'In MantiPlot, go in View > Preferences > Mantid > Options '\n"
-        script += "output_log += 'and check the appropriate box at the bottom.'\n"
-        script += "for item in a:\n"
-        script += "    if type(item)==str: output_log = item\n"
-        script += "reducer_log.log_text += output_log\n\n"
-
-        # Save the reduced data
-        script += "ws_list = ['reflectivity_%s-Off_Off',\n" % basename
-        script += "           'reflectivity_%s-On_Off',\n" % basename
-        script += "           'reflectivity_%s-Off_On',\n" % basename
-        script += "           'reflectivity_%s-On_On']\n" % basename
-
-        script += "outdir = '%s'\n" % self.output_dir
-        script += "if not os.path.isdir(outdir):\n"
-        script += "    outdir = os.path.expanduser('~')\n\n"
-
-        script += "for ws in ws_list:\n"
-        script += "    if AnalysisDataService.doesExist(ws):\n"
-        script += "        outpath = os.path.join(outdir, ws+'.txt')\n"
-        script += "        SaveAscii(Filename=outpath, InputWorkspace=ws, Separator='Space')\n\n"
-
-        return script
-
-    def _automated_reduction(self):
-        script = "# REF_M automated reduction\n"
-        script += "RefReduction(DataRun='%s',\n" % ','.join([str(i) for i in self.data_files])
-        script += "              NormalizationRun='%s',\n" % str(self.norm_file)
-        script += "              Instrument='REF_M',\n"
-        script += "              PolarizedData=True,\n"
-        script += "              SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels)
-        script += "              SubtractSignalBackground=False,\n"
-        script += "              PerformNormalization=%s,\n" % str(self.NormFlag)
-        script += "              NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels)
-        script += "              SubtractNormBackground=False,\n"
-
-        script += "              CropLowResDataAxis=%s,\n" % str(self.data_x_range_flag)
-        if self.data_x_range_flag:
-            script += "              LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range)
-
-        script += "              CropLowResNormAxis=%s,\n" % str(self.norm_x_range_flag)
-        if self.norm_x_range_flag:
-            script += "              LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range)
-
-        # The output should be slightly different if we are generating
-        # a script for the automated reduction
-        basename = os.path.basename(str(self.data_files[0]))
-        script += "              OutputWorkspacePrefix='reflectivity_'+%s)\n" % basename
-
-        return script
-
-    def update(self):
-        """
-            Update transmission from reduction output
-        """
-        pass
-
-    def to_xml(self):
-        """
-            Create XML from the current data.
-        """
-        xml = "<RefMData>\n"
-        xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0])
-        xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1])
-        xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag)
-        xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0])
-        xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1])
-        xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2])
-        xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3])
-        xml += "<crop_tof>%s</crop_tof>\n" % str(self.crop_TOF_range)
-        xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0])
-        xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1])
-        xml += "<tof_step>%s</tof_step>\n" % str(self.TOFstep)
-        xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files])
-        xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0])
-        xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1])
-        xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag)
-
-        xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag)
-        xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag)
-        xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1])
-        xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0])
-
-        xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0])
-        xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1])
-        xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag)
-        xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0])
-        xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1])
-        xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file)
-
-        # Q cut
-        xml += "<q_min>%s</q_min>\n" % str(self.q_min)
-        xml += "<q_step>%s</q_step>\n" % str(self.q_step)
-        xml += "<q_bins>%s</q_bins>\n" % str(self.q_bins)
-        xml += "<q_log>%s</q_log>\n" % str(self.q_log)
-
-        # Scattering angle
-        xml += "<theta>%s</theta>\n" % str(self.theta)
-        xml += "<use_center_pixel>%s</use_center_pixel>\n" % str(self.use_center_pixel)
-
-        # Sample log overwrites
-        xml += "<set_detector_angle>%s</set_detector_angle>\n" % str(self.set_detector_angle)
-        xml += "<detector_angle>%s</detector_angle>\n" % str(self.detector_angle)
-        xml += "<set_detector_angle_offset>%s</set_detector_angle_offset>\n" % str(self.set_detector_angle_offset)
-        xml += "<detector_angle_offset>%s</detector_angle_offset>\n" % str(self.detector_angle_offset)
-        xml += "<set_direct_pixel>%s</set_direct_pixel>\n" % str(self.set_direct_pixel)
-        xml += "<direct_pixel>%s</direct_pixel>\n" % str(self.direct_pixel)
-
-        xml += "<output_dir>%s</output_dir>\n" % str(self.output_dir)
-
-        xml += "</RefMData>\n"
-
-        return xml
-
-    def from_xml(self, xml_str):
-        self.reset()
-        dom = xml.dom.minidom.parseString(xml_str)
-        self.from_xml_element(dom)
-        dom.getElementsByTagName("RefMData")
-
-    def from_xml_element(self, instrument_dom):
-        """
-            Read in data from XML
-            @param xml_str: text to read the data from
-        """
-        # Peak from/to pixels
-        self.DataPeakPixels = [BaseScriptElement.getIntElement(instrument_dom, "from_peak_pixels"),
-                               BaseScriptElement.getIntElement(instrument_dom, "to_peak_pixels")]
-
-        # low resolution range
-        self.data_x_range_flag = BaseScriptElement.getBoolElement(instrument_dom, "x_range_flag",
-                                                                  default=DataSets.data_x_range_flag)
-
-        self.data_x_range = [BaseScriptElement.getIntElement(instrument_dom, "x_min_pixel"),
-                             BaseScriptElement.getIntElement(instrument_dom, "x_max_pixel")]
-
-        self.norm_x_range_flag = BaseScriptElement.getBoolElement(instrument_dom, "norm_x_range_flag",
-                                                                  default=DataSets.norm_x_range_flag)
-
-        self.norm_x_range = [BaseScriptElement.getIntElement(instrument_dom, "norm_x_min"),
-                             BaseScriptElement.getIntElement(instrument_dom, "norm_x_max")]
-
-        # discrete selection string
-        self.DataPeakDiscreteSelection = BaseScriptElement.getStringElement(instrument_dom, "peak_discrete_selection")
-
-        # background flag
-        self.DataBackgroundFlag = BaseScriptElement.getBoolElement(instrument_dom,
-                                                                   "background_flag",
-                                                                   default=DataSets.DataBackgroundFlag)
-
-        # background from/to pixels
-        self.DataBackgroundRoi = [BaseScriptElement.getIntElement(instrument_dom, "back_roi1_from"),
-                                  BaseScriptElement.getIntElement(instrument_dom, "back_roi1_to"),
-                                  BaseScriptElement.getIntElement(instrument_dom, "back_roi2_from"),
-                                  BaseScriptElement.getIntElement(instrument_dom, "back_roi2_to")]
-
-        # from TOF and to TOF
-        # self.crop_TOF_range = BaseScriptElement.getBoolElement(instrument_dom, "crop_tof",
-        #                                                       default=DataSets.crop_TOF_range)
-        self.DataTofRange = [BaseScriptElement.getFloatElement(instrument_dom, "from_tof_range"),
-                             BaseScriptElement.getFloatElement(instrument_dom, "to_tof_range")]
-        self.TOFstep = BaseScriptElement.getFloatElement(instrument_dom, "tof_step",
-                                                         default=DataSets.TOFstep)
-
-        self.data_files = BaseScriptElement.getStringList(instrument_dom, "data_sets")
-
-        # with or without norm
-        self.NormFlag = BaseScriptElement.getBoolElement(instrument_dom, "norm_flag",
-                                                         default=DataSets.NormFlag)
-
-        # Peak from/to pixels
-        self.NormPeakPixels = [BaseScriptElement.getIntElement(instrument_dom, "norm_from_peak_pixels"),
-                               BaseScriptElement.getIntElement(instrument_dom, "norm_to_peak_pixels")]
-
-        # background flag
-        self.NormBackgroundFlag = BaseScriptElement.getBoolElement(instrument_dom,
-                                                                   "norm_background_flag",
-                                                                   default=DataSets.NormBackgroundFlag)
-
-        # background from/to pixels
-        self.NormBackgroundRoi = [BaseScriptElement.getIntElement(instrument_dom, "norm_from_back_pixels"),
-                                  BaseScriptElement.getIntElement(instrument_dom, "norm_to_back_pixels")]
-
-        self.norm_file = BaseScriptElement.getStringElement(instrument_dom, "norm_dataset")
-
-        # Q cut
-        self.q_min = BaseScriptElement.getFloatElement(instrument_dom, "q_min", default=DataSets.q_min)
-        self.q_step = BaseScriptElement.getFloatElement(instrument_dom, "q_step", default=DataSets.q_step)
-        self.q_bins = BaseScriptElement.getIntElement(instrument_dom, "q_bins", default=DataSets.q_bins)
-        self.q_log = BaseScriptElement.getBoolElement(instrument_dom, "q_log", default=DataSets.q_log)
-
-        # scattering angle
-        self.theta = BaseScriptElement.getFloatElement(instrument_dom, "theta", default=DataSets.theta)
-        # self.use_center_pixel = BaseScriptElement.getBoolElement(instrument_dom,
-        #                                                         "use_center_pixel",
-        #                                                         default=DataSets.use_center_pixel)
-
-        # Sample log overwrites
-        self.set_detector_angle = BaseScriptElement.getBoolElement(instrument_dom,
-                                                                   "set_detector_angle",
-                                                                   default=DataSets.set_detector_angle)
-        self.detector_angle = BaseScriptElement.getFloatElement(instrument_dom,
-                                                                "detector_angle",
-                                                                default=DataSets.detector_angle)
-        self.set_detector_angle_offset = BaseScriptElement.getBoolElement(instrument_dom,
-                                                                          "set_detector_angle_offset",
-                                                                          default=DataSets.set_detector_angle_offset)
-        self.detector_angle_offset = BaseScriptElement.getFloatElement(instrument_dom,
-                                                                       "detector_angle_offset",
-                                                                       default=DataSets.detector_angle_offset)
-        self.set_direct_pixel = BaseScriptElement.getBoolElement(instrument_dom,
-                                                                 "set_direct_pixel",
-                                                                 default=DataSets.set_direct_pixel)
-        self.direct_pixel = BaseScriptElement.getFloatElement(instrument_dom,
-                                                              "direct_pixel",
-                                                              default=DataSets.direct_pixel)
-
-        self.output_dir = BaseScriptElement.getStringElement(instrument_dom,
-                                                             "output_dir",
-                                                             default=DataSets.output_dir)
-
-    def reset(self):
-        """
-            Reset state
-        """
-        self.DataBackgroundFlag = DataSets.DataBackgroundFlag
-        self.DataBackgroundRoi = DataSets.DataBackgroundRoi
-        self.DataPeakPixels = DataSets.DataPeakPixels
-        self.DataTofRange = DataSets.DataTofRange
-        self.TOFstep = DataSets.TOFstep
-        self.crop_TOF_range = DataSets.crop_TOF_range
-        self.data_files = DataSets.data_files
-
-        self.NormFlag = DataSets.NormFlag
-        self.NormBackgroundFlag = DataSets.NormBackgroundFlag
-        self.NormBackgroundRoi = DataSets.NormBackgroundRoi
-        self.NormPeakPixels = DataSets.NormPeakPixels
-        self.norm_file = DataSets.norm_file
-        self.data_x_range_flag = DataSets.data_x_range_flag
-        self.data_x_range = DataSets.data_x_range
-        self.norm_x_range_flag = DataSets.norm_x_range_flag
-        self.norm_x_range = DataSets.norm_x_range
-
-        # Q range
-        self.q_min = DataSets.q_min
-        self.q_step = DataSets.q_step
-        self.q_bins = DataSets.q_bins
-        self.q_log = DataSets.q_log
-
-        # Scattering angle
-        self.theta = DataSets.theta
-        self.use_center_pixel = DataSets.use_center_pixel
-
-        # Sample log overwrites
-        self.set_detector_angle = DataSets.set_detector_angle
-        self.detector_angle = DataSets.detector_angle
-        self.set_detector_angle_offset = DataSets.set_detector_angle_offset
-        self.detector_angle_offset = DataSets.detector_angle_offset
-        self.set_direct_pixel = DataSets.set_direct_pixel
-        self.direct_pixel = DataSets.direct_pixel
-
-        self.output_dir = DataSets.output_dir
diff --git a/scripts/Interface/ui/reflectometer/refl_gui.py b/scripts/Interface/ui/reflectometer/refl_gui.py
index 3c9adc6f190d7a8546aa838fd0dc1b526c04976b..5f37b1a2cfc0492a4b4d6bb6a588737860977b9c 100644
--- a/scripts/Interface/ui/reflectometer/refl_gui.py
+++ b/scripts/Interface/ui/reflectometer/refl_gui.py
@@ -21,6 +21,7 @@ from isis_reflectometry.combineMulti import *
 import mantidqtpython
 from mantid.api import Workspace, WorkspaceGroup, CatalogManager, AlgorithmManager
 from mantid import UsageService
+from mantid import logger
 
 from ui.reflectometer.ui_refl_window import Ui_windowRefl
 from ui.reflectometer.refl_save import Ui_SaveWindow
@@ -43,12 +44,19 @@ class ReflGui(QtGui.QMainWindow, Ui_windowRefl):
     labelStatus = None
     accMethod = None
 
+    def show_deprecation_warning(self):
+        logger.warning("""
+The ISIS Reflectometry (Old) interface has been deprecated and will be removed from Mantid in March 2019
+We recommend you use ISIS Reflectometry instead, If this is not possible contact the development team using the "Help->Ask For Help" menu.
+""")
+
     def __init__(self):
         """
         Initialise the interface
         """
         super(QtGui.QMainWindow, self).__init__()
         self.setupUi(self)
+        self.show_deprecation_warning()
         self.loading = False
         self.clip = QtGui.QApplication.clipboard()
         self.shown_cols = {}
diff --git a/scripts/Interface/ui/reflectometer/refl_window.ui b/scripts/Interface/ui/reflectometer/refl_window.ui
index 861fbff42c8cdc5a24a3ada6c408e915720fb589..a0709949d0fbfdd883b4aee9e2d16083c24331be 100644
--- a/scripts/Interface/ui/reflectometer/refl_window.ui
+++ b/scripts/Interface/ui/reflectometer/refl_window.ui
@@ -14,7 +14,7 @@
    <bool>true</bool>
   </property>
   <property name="windowTitle">
-   <string>ISIS Reflectometry (Old)</string>
+   <string>ISIS Reflectometry (Old) - DEPRECATED</string>
   </property>
   <widget class="QWidget" name="widgetMainRow">
    <layout class="QVBoxLayout" name="layoutBase">
diff --git a/scripts/Interface/ui/sans_isis/beam_centre.py b/scripts/Interface/ui/sans_isis/beam_centre.py
index 55053098c22597caeaf863e3134b813bcb95616d..0ded1c83bd4ccf8f87ae70797c31ad534d9d755f 100644
--- a/scripts/Interface/ui/sans_isis/beam_centre.py
+++ b/scripts/Interface/ui/sans_isis/beam_centre.py
@@ -176,7 +176,7 @@ class BeamCentre(QtGui.QWidget, ui_beam_centre.Ui_BeamCentre):
 
     @property
     def up_down(self):
-        return self.left_right_check_box.isChecked()
+        return self.up_down_check_box.isChecked()
 
     @up_down.setter
     def up_down(self, value):
diff --git a/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py b/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py
deleted file mode 100644
index c40a9b791a8293156090a7a031c231293d6c978e..0000000000000000000000000000000000000000
--- a/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py
+++ /dev/null
@@ -1,952 +0,0 @@
-from __future__ import (absolute_import, division, print_function)
-from mantid import *
-from mantid.simpleapi import *
-from numpy import zeros
-from pylab import *
-import os.path
-
-PRECISION = 0.010
-
-
-class sfCalculator():
-
-    tof_min = None  #microS
-    tof_max = None  #microS
-
-    #range of x pixel to use in the X integration (we found out that there
-    #is a frame effect that introduces noise)
-    x_pixel_min = 90
-    x_pixel_max = 190
-
-    #from,width,to in microS
-    rebin_parameters = '0,200,200000'
-
-    #turn on or off the plots
-    bPlot = False
-    bFittingPlot = False
-
-    #size of detector
-    alpha_pixel_nbr = 256
-    beta_pixel_nbr = 304  #will be integrated over this dimension
-
-    #name of numerators and denominators
-    numerator = None #ex: AiD0
-    denominator = None   #ex: AiD1
-
-    y_axis_numerator = None
-    y_axis_error_numerator = None
-    y_axis_denominator = None
-    y_axis_error_denominator = None
-    x_axis = None
-
-    #define the peak region
-    n_peak_pixel_min = 130
-    n_peak_pixel_max = 135
-    d_peak_pixel_min = 130
-    d_peak_pixel_max = 135
-
-    peak_pixel_min = None
-    peak_pixel_max = None
-    back_pixel_min = None
-    back_pixel_max = None
-
-    #define the background range used in the background subtraction
-    n_back_pixel_min = 125
-    n_back_pixel_max = 140
-    d_back_pixel_min = 125
-    d_back_pixel_max = 140
-
-    y_axis_ratio = None
-    y_axis_error_ratio = None
-    x_axis_ratio = None
-
-    def __init__(self, numerator=None, denominator=None,
-                 tof_range=None):
-
-        print('---> initialize calculation')
-
-        if (tof_range is None):
-            self.tof_min = 10000
-            self.tof_max = 21600
-        else:
-            self.tof_min = tof_range[0]
-            self.tof_max = tof_range[1]
-
-        self.numerator = numerator
-        self.denominator = denominator
-
-        self.x_axis_ratio = None
-        self.y_axis_error_ratio = None
-        self.y_axis_ratio = None
-
-    def setNumerator(self, minPeak, maxPeak, minBack, maxBack):
-
-        print('---> set numerator (' + self.numerator + ')')
-
-        if minPeak != 0:
-            self.n_peak_pixel_min = minPeak
-        if maxPeak != 0 :
-            self.n_peak_pixel_max = maxPeak
-        if minBack != 0:
-            self.n_back_pixel_min = minBack
-        if maxBack != 0:
-            self.n_back_pixel_max = maxBack
-
-    def setDenominator(self, minPeak, maxPeak, minBack, maxBack):
-
-        print('---> set denominator (' + self.denominator + ')')
-
-        if minPeak != 0:
-            self.d_peak_pixel_min = minPeak
-        if maxPeak != 0:
-            self.d_peak_pixel_max = maxPeak
-        if minBack != 0:
-            self.d_back_pixel_min = minBack
-        if maxBack != 0:
-            self.d_back_pixel_max = maxBack
-
-    def run(self):
-        """
-        Perform the calculation
-
-        """
-
-        #perform calculation for numerator
-        self._calculateFinalYAxis(bNumerator=True)
-
-        #perform calculation for denominator
-        self._calculateFinalYAxis(bNumerator=False)
-
-        #calculate y_axis of numerator/denominator
-#        self._x_axis_ratio = self._x_axis
-        self.y_axis_ratio = self.y_axis_numerator / self.y_axis_denominator
-
-        self.y_axis_error_ratio = ((self.y_axis_error_numerator /
-                                    self.y_axis_numerator) ** 2 +
-                                   (self.y_axis_error_denominator /
-                                    self.y_axis_denominator) ** 2)
-        self.y_axis_error_ratio = sqrt(self.y_axis_error_ratio)
-        self.y_axis_error_ratio *= self.y_axis_ratio
-
-    def _calculateFinalYAxis(self, bNumerator=True):
-        """
-        run full calculation for numerator or denominator
-        """
-        if bNumerator is True:
-            file = self.numerator
-#            _id = self.id_numerator
-            self.peak_pixel_min = self.n_peak_pixel_min
-            self.peak_pixel_max = self.n_peak_pixel_max
-            self.back_pixel_min = self.n_back_pixel_min
-            self.back_pixel_max = self.n_back_pixel_max
-        else:
-            file = self.denominator
-#            _id = self.id_denominator
-            self.peak_pixel_min = self.d_peak_pixel_min
-            self.peak_pixel_max = self.d_peak_pixel_max
-            self.back_pixel_min = self.d_back_pixel_min
-            self.back_pixel_max = self.d_back_pixel_max
-
-        nexus_file_numerator = file
-        ws_event_data = LoadEventNexus(Filename=nexus_file_numerator,
-                                       OutputWorkspace='EventDataWks')
-        mt1 = mtd['EventDataWks']
-
-        is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value)
-        if is_nexus_detector_rotated_flag:
-            self.alpha_pixel_nbr = 304
-            self.beta_pixel_nbr = 256
-        else:
-            self.alpha_pixel_nbr = 256
-            self.beta_pixel_nbr = 304
-
-        proton_charge = self._getProtonCharge(mt1)
-        rebin(InputWorkspace='EventDataWks',
-              OutputWorkspace='HistoDataWks',
-              Params=self.rebin_parameters)
-
-        mt2 = mtd['HistoDataWks']
-        x_axis = mt2.readX(0)[:]
-        self.x_axis = x_axis
-
-        self._createIntegratedWorkspace(InputWorkspace=mt2,
-                                        OutputWorkspace='IntegratedDataWks',
-                                        proton_charge=proton_charge,
-                                        from_pixel=self.x_pixel_min,
-                                        to_pixel=self.x_pixel_max)
-        ConvertToHistogram(InputWorkspace='IntegratedDataWks',
-                           OutputWorkspace='IntegratedDataWks')
-
-        Transpose(InputWorkspace='IntegratedDataWks',
-                  OutputWorkspace='TransposeIntegratedDataWks')
-
-        ConvertToHistogram(InputWorkspace='TransposeIntegratedDataWks',
-                           OutputWorkspace='TransposeIntegratedDataWks_t')
-
-        FlatBackground(InputWorkspace='TransposeIntegratedDataWks_t',
-                       OutputWorkspace='TransposeHistoFlatDataWks_1',
-                       StartX=self.back_pixel_min,
-                       EndX=self.peak_pixel_min,
-                       Mode='Mean',
-                       OutputMode="Return Background")
-
-        FlatBackground(InputWorkspace='TransposeIntegratedDataWks_t',
-                       OutputWorkspace='TransposeHistoFlatDataWks_2',
-                       StartX=self.peak_pixel_max,
-                       EndX=self.back_pixel_max,
-                       Mode='Mean',
-                       OutputMode="Return Background")
-
-        Transpose(InputWorkspace='TransposeHistoFlatDataWks_1',
-                  OutputWorkspace='DataWks_1')
-
-        Transpose(InputWorkspace='TransposeHistoFlatDataWks_2',
-                  OutputWorkspace='DataWks_2')
-
-        ConvertToHistogram(InputWorkspace='DataWks_1',
-                           OutputWorkspace='DataWks_1')
-
-        ConvertToHistogram(InputWorkspace='DataWks_2',
-                           OutputWorkspace='DataWks_2')
-
-        RebinToWorkspace(WorkspaceToRebin='DataWks_1',
-                         WorkspacetoMatch='IntegratedDataWks',
-                         OutputWorkspace='DataWks_1')
-
-        RebinToWorkspace(WorkspaceToRebin='DataWks_2',
-                         WorkspacetoMatch='IntegratedDataWks',
-                         OutputWorkspace='DataWks_2')
-
-        WeightedMean(InputWorkspace1='DataWks_1',
-                     InputWorkspace2='DataWks_2',
-                     OutputWorkspace='DataWks')
-
-        Minus(LHSWorkspace='IntegratedDataWks',
-              RHSWorkspace='DataWks',
-              OutputWorkspace='DataWks')
-
-        mt3 = mtd['DataWks']
-        self._calculateFinalAxis(Workspace=mt3,
-                                 bNumerator=bNumerator)
-
-        #cleanup workspaces
-        mtd.remove('EventDataWks')
-        mtd.remove('HistoDataWks')
-        mtd.remove('IntegratedDataWks')
-        mtd.remove('TransposeIntegratedDataWks')
-        mtd.remove('TransposeIntegratedDataWks_t')
-        mtd.remove('TransposeHistoFlatDataWks')
-        mtd.remove('DataWks')
-
-    def _calculateFinalAxis(self, Workspace=None, bNumerator=None):
-        """
-        this calculates the final y_axis and y_axis_error of numerator
-        and denominator
-        """
-        mt = Workspace
-        x_axis = mt.readX(0)[:]
-        self.x_axis = x_axis
-
-        counts_vs_tof = zeros(len(x_axis)-1)
-        counts_vs_tof_error = zeros(len(x_axis)-1)
-
-        for x in range(self.alpha_pixel_nbr):
-            counts_vs_tof += mt.readY(x)[:]
-            counts_vs_tof_error += mt.readE(x)[:] ** 2
-        counts_vs_tof_error = sqrt(counts_vs_tof_error)
-        index_tof_min = self._getIndex(self.tof_min, x_axis)
-        index_tof_max = self._getIndex(self.tof_max, x_axis)
-
-        if (bNumerator is True):
-            self.y_axis_numerator = counts_vs_tof[index_tof_min:index_tof_max]
-            self.y_axis_error_numerator = counts_vs_tof_error[index_tof_min:index_tof_max]
-            self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max]
-        else:
-            self.y_axis_denominator = counts_vs_tof[index_tof_min:index_tof_max]
-            self.y_axis_error_denominator = counts_vs_tof_error[index_tof_min:index_tof_max]
-            self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max]
-
-    def _createIntegratedWorkspace(self,
-                                   InputWorkspace=None,
-                                   OutputWorkspace=None,
-                                   proton_charge=None,
-                                   from_pixel=0,
-                                   to_pixel=303):
-        """
-        This creates the integrated workspace over the second pixel range
-        (beta_pixel_nbr here) and
-        returns the new workspace handle
-        """
-
-        x_axis = InputWorkspace.readX(0)[:]
-        x_size = to_pixel - from_pixel + 1
-        y_axis = zeros((self.alpha_pixel_nbr, len(x_axis) - 1))
-        y_error_axis = zeros((self.alpha_pixel_nbr, len(x_axis) - 1))
-        y_range = arange(x_size) + from_pixel
-
-        for x in range(self.beta_pixel_nbr):
-            for y in y_range:
-                index = int(self.alpha_pixel_nbr * x + y)
-                y_axis[y, :] += InputWorkspace.readY(index)[:]
-                y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) *
-                                       (InputWorkspace.readE(index)[:]))
-
-        y_axis = y_axis.flatten()
-        y_error_axis = sqrt(y_error_axis)
-        #plot_y_error_axis = _y_error_axis #for output testing only
-        #-> plt.imshow(plot_y_error_axis, aspect='auto', origin='lower')
-        y_error_axis = y_error_axis.flatten()
-
-        #normalization by proton charge
-        y_axis /= (proton_charge * 1e-12)
-
-        CreateWorkspace(OutputWorkspace=OutputWorkspace,
-                        DataX=x_axis,
-                        DataY=y_axis,
-                        DataE=y_error_axis,
-                        Nspec=self.alpha_pixel_nbr)
-#        mt3 = mtd[OutputWorkspace]
-#        return mt3
-
-    def _getIndex(self, value, array):
-        """
-        returns the index where the value has been found
-        """
-        return array.searchsorted(value)
-
-    def _getProtonCharge(self, st=None):
-        """
-        Returns the proton charge of the given workspace in picoCoulomb
-        """
-        if st is not None:
-            mt_run = st.getRun()
-            proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value
-            proton_charge = proton_charge_mtd_unit / 2.77777778e-10
-            return proton_charge
-        return None
-
-    def __mul__(self, other):
-        """
-        operator * between two instances of the class
-        """
-
-        product = sfCalculator()
-
-        product.numerator = self.numerator + '*' + other.numerator
-        product.denominator = self.denominator + '*' + other.denominator
-
-        product.x_axis_ratio = self.x_axis_ratio
-        product.y_axis_ratio = self.y_axis_ratio * other.y_axis_ratio
-        product.y_axis_error_ratio = sqrt((other.y_axis_ratio * self.y_axis_error_ratio) ** 2 +
-                                          (other.y_axis_error_ratio * self.y_axis_ratio) ** 2)
-        return product
-
-    def fit(self):
-        """
-        This is going to fit the counts_vs_tof with a linear expression and return the a and
-        b coefficients (y=a+bx)
-        """
-        CreateWorkspace(OutputWorkspace='DataToFit',
-                        DataX=self.x_axis_ratio,
-                        DataY=self.y_axis_ratio,
-                        DataE=self.y_axis_error_ratio,
-                        Nspec=1)
-
-        Fit(InputWorkspace='DataToFit',
-            Function="name=UserFunction, Formula=a+b*x, a=1, b=2",
-            Output='Res')
-        res = mtd['Res_Parameters']
-
-        self.a = res.getDouble("Value", 0)
-        self.b = res.getDouble("Value", 1)
-        self.error_a = res.getDouble("Error", 0)
-        self.error_b = res.getDouble("Error", 1)
-
-
-def plotObject(instance):
-
-#    return
-
-#    print 'a: ' + str(instance.a[-1])
-#    print 'b: ' + str(instance.b[-1])
-
-    figure()
-    errorbar(instance.x_axis_ratio,
-             instance.y_axis_ratio,
-             instance.y_axis_error_ratio,
-             marker='s',
-             mfc='red',
-             linestyle='',
-             label='Exp. data')
-
-    if instance.a is not None:
-        x = linspace(10000, 22000, 100)
-        _label = "%.3f + x*%.2e" % (instance.a, instance.b)
-        plot(x, instance.a + instance.b * x, label=_label)
-
-    xlabel("TOF (microsS)")
-    ylabel("Ratio")
-
-    title(instance.numerator + '/' + instance.denominator)
-    show()
-    legend()
-
-
-def recordSettings(a, b, error_a, error_b, name, instance):
-    """
-    This function will record the various fitting parameters and the
-    name of the ratio
-    """
-    a.append(instance.a)
-    b.append(instance.b)
-    error_a.append(instance.error_a)
-    error_b.append(instance.error_b)
-    name.append(instance.numerator + '/' + instance.denominator)
-
-
-def variable_value_splitter(variable_value):
-    """
-        This function split the variable that looks like "LambdaRequested:3.75"
-        and returns a dictionnary of the variable name and value
-    """
-
-    _split = variable_value.split('=')
-    variable = _split[0]
-    value = float(_split[1])
-    return {'variable':variable, 'value':value}
-
-
-def isWithinRange(value1, value2):
-    """
-        This function checks if the two values and return true if their
-        difference is <= PRECISION
-    """
-    print('value1: ' + str(value1))
-    print('value2: ' + str(value2))
-
-    diff = abs(float(value1)) - abs(float(value2))
-    if abs(diff) <= PRECISION:
-        return True
-    else:
-        return False
-
-
-def outputFittingParameters(a, b, error_a, error_b,
-                            lambda_requested,
-                            incident_medium,
-                            S1H, S2H,
-                            S1W, S2W,
-                            output_file_name):
-    """
-    Create an ascii file of the various fittings parameters
-    y=a+bx
-    1st column: incident medium
-    2nd column: lambda requested
-    3rd column: S1H value
-    4th column: S2H value
-    5th column: S1W value
-    6th column: S2W value
-    7th column: a
-    7th column: b
-    8th column: error_a
-    9th column: error_b
-    """
-
-    bFileExist = False
-    #First we need to check if the file already exist
-    if os.path.isfile(output_file_name):
-        bFileExist = True
-
-    #then if it does, parse the file and check if following infos are
-    #already defined:
-    #  lambda_requested, S1H, S2H, S1W, S2W
-    if (bFileExist):
-        f = open(output_file_name, 'r')
-        text = f.readlines()
-#        split_lines = text.split('\n')
-        split_lines = text
-
-        entry_list_to_add = []
-
-        sz = len(a)
-        for i in range(sz):
-
-            _match = False
-
-            for _line in split_lines:
-                if _line[0] == '#':
-                    continue
-
-                _line_split = _line.split(' ')
-                _incident_medium = _line_split[0]
-                if (_incident_medium == incident_medium):
-                    _lambdaRequested = variable_value_splitter(_line_split[1])
-                    if (isWithinRange(_lambdaRequested['value'], lambda_requested)):
-                        _s1h = variable_value_splitter(_line_split[2])
-                        if (isWithinRange(_s1h['value'], S1H[i])):
-                            _s2h = variable_value_splitter(_line_split[3])
-                            if (isWithinRange(_s2h['value'],S2H[i])):
-                                _s1w = variable_value_splitter(_line_split[4])
-                                if (isWithinRange(_s1w['value'],S1W[i])):
-                                    _s2w = variable_value_splitter(_line_split[5])
-                                    if (isWithinRange(_s2w['value'],S2W[i])):
-                                        _match = True
-                                        break
-
-            if not _match:
-                entry_list_to_add.append(i)
-
-        _content = []
-        for j in entry_list_to_add:
-
-            _line = 'IncidentMedium=' + incident_medium + ' '
-            _line += 'LambdaRequested=' + str(lambda_requested) + ' '
-
-            _S1H = "{0:.8f}".format(abs(S1H[j]))
-            _S2H = "{0:.8f}".format(abs(S2H[j]))
-            _S1W = "{0:.8f}".format(abs(S1W[j]))
-            _S2W = "{0:.8f}".format(abs(S2W[j]))
-            _a = "{0:.8f}".format(a[j])
-            _b = "{0:.8f}".format(b[j])
-            _error_a = "{0:.8f}".format(float(error_a[j]))
-            _error_b = "{0:.8f}".format(float(error_b[j]))
-
-            _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' '
-            _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' '
-            _line += 'a=' + _a + ' '
-            _line += 'b=' + _b + ' '
-            _line += 'error_a=' + _error_a + ' '
-            _line += 'error_b=' + _error_b + '\n'
-            _content.append(_line)
-
-        f = open(output_file_name, 'a')
-        f.writelines(_content)
-        f.close()
-
-    else:
-
-        _content = ['#y=a+bx\n', '#\n',
-                    '#lambdaRequested[Angstroms] S1H[mm] S2H[mm] S1W[mm] S2W[mm] a b error_a error_b\n', '#\n']
-        sz = len(a)
-        for i in range(sz):
-
-            _line = 'IncidentMedium=' + incident_medium.strip() + ' '
-            _line += 'LambdaRequested=' + str(lambda_requested) + ' '
-
-            _S1H = "{0:.8f}".format(abs(S1H[i]))
-            _S2H = "{0:.8f}".format(abs(S2H[i]))
-            _S1W = "{0:.8f}".format(abs(S1W[i]))
-            _S2W = "{0:.8f}".format(abs(S2W[i]))
-            _a = "{0:.8f}".format(a[i])
-            _b = "{0:.8f}".format(b[i])
-            _error_a = "{0:.8f}".format(float(error_a[i]))
-            _error_b = "{0:.8f}".format(float(error_b[i]))
-
-            _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' '
-            _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' '
-            _line += 'a=' + _a + ' '
-            _line += 'b=' + _b + ' '
-            _line += 'error_a=' + _error_a + ' '
-            _line += 'error_b=' + _error_b + '\n'
-            _content.append(_line)
-
-        f = open(output_file_name, 'w')
-        f.writelines(_content)
-        f.close()
-
-
-def createIndividualList(string_list_files):
-    """
-    Using the list_files, will produce a dictionary of the run
-    number and number of attenuator
-    ex:
-        list_files = "1000:0, 1001:1, 1002:1, 1003:2"
-        return {1000:0, 1001:1, 1002:2, 1003:2}
-    """
-    if (string_list_files == ''):
-        return None
-    first_split = string_list_files.split(',')
-
-    list_runs = []
-    list_attenuator= []
-
-    _nbr_files = len(first_split)
-    for i in range(_nbr_files):
-        _second_split = first_split[i].split(':')
-        list_runs.append(_second_split[0].strip())
-        list_attenuator.append(int(_second_split[1].strip()))
-
-    return {'list_runs':list_runs,
-            'list_attenuator':list_attenuator}
-
-
-def getLambdaValue(mt):
-    """
-    return the lambdaRequest value
-    """
-    mt_run = mt.getRun()
-    _lambda = mt_run.getProperty('LambdaRequest').value
-    return _lambda
-
-
-def getSh(mt, top_tag, bottom_tag):
-    """
-        returns the height and units of the given slits
-    """
-    mt_run = mt.getRun()
-    st = mt_run.getProperty(top_tag).value
-    sb = mt_run.getProperty(bottom_tag).value
-    sh = float(sb[0]) - float(st[0])
-    units = mt_run.getProperty(top_tag).units
-    return sh, units
-
-
-def getS1h(mt=None):
-    """
-        returns the height and units of the slit #1
-    """
-    if mt is not None:
-        _h, units = getSh(mt, 's1t', 's1b')
-        return _h, units
-    return None, ''
-
-
-def getS2h(mt=None):
-    """
-        returns the height and units of the slit #2
-    """
-    if mt is not None:
-        _h, units = getSh(mt, 's2t', 's2b')
-        return _h, units
-    return None, None
-
-
-def getSw(mt, left_tag, right_tag):
-    """
-        returns the width and units of the given slits
-    """
-    mt_run = mt.getRun()
-    sl = mt_run.getProperty(left_tag).value
-    sr = mt_run.getProperty(right_tag).value
-    sw = float(sl[0]) - float(sr[0])
-    units = mt_run.getProperty(left_tag).units
-    return sw, units
-
-
-def getS1w(mt=None):
-    """
-        returns the width and units of the slit #1
-    """
-    if mt is not None:
-        _w, units = getSw(mt, 's1l', 's1r')
-        return _w, units
-    return None, ''
-
-
-def getS2w(mt=None):
-    """
-        returns the width and units of the slit #2
-    """
-    if mt is not None:
-        _w, units = getSh(mt, 's2l', 's2r')
-        return _w, units
-    return None, None
-
-
-def getSlitsValueAndLambda(full_list_runs,
-                           S1H, S2H,
-                           S1W, S2W, lambdaRequest):
-    """
-    Retrieve the S1H (slit 1 height),
-                 S2H (slit 2 height),
-                 S1W (slit 1 width),
-                 S2W (slit 2 width) and
-                 lambda requested values
-    """
-    _nbr_files = len(full_list_runs)
-    print('> Retrieving Slits and Lambda Requested for each file:')
-    for i in range(_nbr_files):
-        _full_file_name = full_list_runs[i]
-        print('-> ' + _full_file_name)
-        LoadEventNexus(Filename=_full_file_name,
-                       OutputWorkspace='tmpWks',
-                       MetaDataOnly='1')
-        mt1 = mtd['tmpWks']
-        _s1h_value, _s1h_units = getS1h(mt1)
-        _s2h_value, _s2h_units = getS2h(mt1)
-        S1H[i] = _s1h_value
-        S2H[i] = _s2h_value
-
-        _s1w_value, _s1w_units = getS1w(mt1)
-        _s2w_value, _s2w_units = getS2w(mt1)
-        S1W[i] = _s1w_value
-        S2W[i] = _s2w_value
-
-        _lambda_value = getLambdaValue(mt1)
-        lambdaRequest[i] = _lambda_value
-
-
-def isRunsSorted(list_runs, S1H, S2H):
-    """
-    Make sure the files have been sorted
-    """
-    sz = len(S1H)
-    sTotal = zeros(sz)
-    for i in range(sz):
-        sTotal[i] = S1H[i] + S2H[i]
-
-    sorted_sTotal = sorted(sTotal)
-
-    for i in range(len(sTotal)):
-        _left = list(sTotal)[i]
-        _right = sorted_sTotal[i]
-
-        _left_formated = "%2.1f" % _left
-        _right_formated = "%2.1f" % _right
-        if (_left_formated != _right_formated):
-            return False
-
-    return True
-
-
-def calculateAndFit(numerator='',
-                    denominator='',
-                    list_peak_back_numerator=None,
-                    list_peak_back_denominator=None,
-                    list_objects=[],
-                    tof_range=None):
-
-    print('--> running calculate and fit algorithm')
-
-    cal1 = sfCalculator(numerator=numerator,
-                        denominator=denominator,
-                        tof_range=tof_range)
-
-    cal1.setNumerator(minPeak=list_peak_back_numerator[0],
-                      maxPeak=list_peak_back_numerator[1],
-                      minBack=list_peak_back_numerator[2],
-                      maxBack=list_peak_back_numerator[3])
-
-    cal1.setDenominator(minPeak=list_peak_back_denominator[0],
-                        maxPeak=list_peak_back_denominator[1],
-                        minBack=list_peak_back_denominator[2],
-                        maxBack=list_peak_back_denominator[3])
-
-    cal1.run()
-
-    if (list_objects != [] and list_objects[-1] is not None):
-        new_cal1 = cal1 * list_objects[-1]
-        new_cal1.fit()
-        return new_cal1
-    else:
-        cal1.fit()
-        return cal1
-
-
-def help():
-    """
-        Here the user will have information about how the command line
-        works
-    """
-    print('sfCalculator help:')
-    print()
-    print('example:')
-    print(' > sfCalculator.calculate(string_runs="55889:0, 55890:1, 55891:1, 55892:2",')
-    print('                          list_')
-
-
-#if __name__ == '__main__':
-def calculate(string_runs=None,
-              #              list_attenuator=None,
-              list_peak_back=None,
-              output_file_name=None,
-              incident_medium=None,
-              tof_range=None):
-    """
-    In this current version, the program will automatically calculates
-    the scaling function for up to, and included, 6 attenuators.
-    A output file will then be produced with the following format:
-        S1H  S2H    a   b   error_a    error_b
-        ....
-        where y=a+bx
-        x axis is in microS
-
-        The string runs has to be specified this way:
-        string_runs = "run#1:nbr_attenuator, run#2:nbr_attenuator...."
-
-        the list_peak_back is specified this way:
-        list_peak_back =
-            [[peak_min_run1, peak_max_run1, back_min_run1, back_max_run1],
-             [peak_min_run2, peak_max_run2, back_min_run2, back_max_run2],
-             [...]]
-
-        output_path = where the scaling factor files will be written
-        tof_range
-
-    """
-
-    list_attenuator = None
-
-    #use default string files if not provided
-    if (string_runs is None):
-        #Input from user
-#        list_runs = ['55889', '55890', '55891', '55892', '55893', '55894',
-#                     '55895', '55896', '55897', '55898', '55899', '55900',
-#                     '55901', '55902']
-        list_runs = ['55889', '55890', '55891', '55892', '55893', '55894']
-        nexus_path = '/mnt/hgfs/j35/results/'
-        pre = 'REF_L_'
-        nexus_path_pre = nexus_path + pre
-        post = '_event.nxs'
-
-        for (offset, item) in enumerate(list_runs):
-            list_runs[offset] = nexus_path_pre + item + post
-
-    else:
-        dico = createIndividualList(string_runs)
-        list_runs = dico['list_runs']
-
-        for (offset, item) in enumerate(list_runs):
-            try:
-                _File = FileFinder.findRuns("REF_L%d" %int(item))[0]
-                list_runs[offset] = _File
-            except:
-                msg = "RefLReduction: could not find run %s\n" %item
-                msg += "Add your data folder to your User Data Directories in the File menu"
-                raise RuntimeError(msg)
-
-        list_attenuator = dico['list_attenuator']
-
-    if (incident_medium is None):
-        incident_medium = "H20" #default value
-
-    if (list_attenuator is None):
-#        list_attenuator = [0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4]
-        list_attenuator = [0, 1, 1, 1, 1, 1]
-
-    if (list_peak_back is None):
-        list_peak_back = zeros((len(list_runs), 4))   #[peak_min, peak_max, back_min, back_max]
-#        list_peak_back[9, ] = [128, 136, 120, 145]
-#        list_peak_back[11, ] = [125, 140, 115, 150]
-#        list_peak_back[10, ] = [128, 136, 120, 145]
-#        list_peak_back[13, ] = [120, 145, 105, 155]
-#        list_peak_back[12, ] = [125, 140, 115, 150]
-
-    #####
-    #Input file should be as it is here !
-    #####
-
-    #retrieve the S1H and S2H val/units for each NeXus
-    #retrieve the lambdaRequest value (Angstrom)
-    S1H = {}
-    S2H = {}
-    S1W = {}
-    S2W = {}
-    lambdaRequest = {}
-    getSlitsValueAndLambda(list_runs, S1H, S2H, S1W, S2W, lambdaRequest)
-
-    #Make sure all the lambdaRequested are identical within a given range
-    lambdaRequestPrecision = 0.01 #1%
-    for i in lambdaRequest:
-        _localValue = float(lambdaRequest[i][0])
-        _localValueRate = lambdaRequestPrecision * _localValue
-        _leftValue = _localValue - _localValueRate
-        _rightValue = _localValue + _localValueRate
-
-        if (_localValue < _leftValue) or (_localValue > _rightValue):
-            raise Exception("lambda requested do not match !")
-
-    #make sure the file are sorted from smaller to bigger openning
-    if isRunsSorted(list_runs, S1H, S2H):
-
-        #initialize record fitting parameters arrays
-        a = []
-        b = []
-        error_a = []
-        error_b = []
-        name = []
-
-        finalS1H = []
-        finalS2H = []
-
-        finalS1W = []
-        finalS2W = []
-
-        #array of True/False flags that will allow us
-        #to rescale the calculation on the first attenuator
-        _first_A = []
-        for j in range(len(unique(list_attenuator))):
-            _first_A.append(True)
-
-        #array of index of first attenuator
-        _index_first_A = []
-        for j in range(len(unique(list_attenuator))):
-            _index_first_A.append(-1)
-
-        index_numerator = -1
-        index_denominator = -1
-
-        list_objects = []
-
-        for i in range(len(list_runs)):
-
-            print('> Working with index: ' + str(i))
-            _attenuator = list_attenuator[i]
-
-            if _attenuator == 0:
-                continue
-            else:
-                if _first_A[_attenuator] is True:
-                    _first_A[_attenuator] = False
-                    _index_first_A[_attenuator] = i
-                    continue
-                else:
-                    index_numerator = i
-                    index_denominator = _index_first_A[_attenuator]
-
-                print('-> numerator  : ' + str(list_runs[index_numerator]))
-                print('-> denominator: ' + str(list_runs[index_denominator]))
-                cal = calculateAndFit(numerator=list_runs[index_numerator],
-                                      denominator=list_runs[index_denominator],
-                                      list_peak_back_numerator=list_peak_back[index_numerator],
-                                      list_peak_back_denominator=list_peak_back[index_denominator],
-                                      list_objects=list_objects,
-                                      tof_range=tof_range)
-
-                recordSettings(a, b, error_a, error_b, name, cal)
-
-                if (i < (len(list_runs) - 1) and list_attenuator[i + 1] == (_attenuator+1)):
-                    list_objects.append(cal)
-
-            #record S1H and S2H
-            finalS1H.append(S1H[index_numerator])
-            finalS2H.append(S2H[index_numerator])
-
-            #record S1W and S2W
-            finalS1W.append(S1W[index_numerator])
-            finalS2W.append(S2W[index_numerator])
-
-        #output the fitting parameters in an ascii
-        _lambdaRequest = "{0:.2f}".format(lambdaRequest[0][0])
-
-#        output_pre = 'SFcalculator_lr' + str(_lambdaRequest)
-#        output_ext = '.txt'
-#        output_file = output_path + '/' + output_pre + output_ext
-
-        if output_file_name is None:
-            output_file_name = "/home/j35/Desktop/RefLsf.cfg"
-
-        outputFittingParameters(a, b, error_a, error_b,
-                                _lambdaRequest,
-                                incident_medium,
-                                finalS1H, finalS2H,
-                                finalS1W, finalS2W,
-                                output_file_name)
-
-        print('Done !')
-
-    else:
-        """
-        sort the files
-        """
-        pass
diff --git a/scripts/Muon/load_utils.py b/scripts/Muon/load_utils.py
index 6a4b9718a50e6656a2526857a626eba850da27db..26a9a4ad8beec69a2258af7a1cfe4dd4455a7dc2 100644
--- a/scripts/Muon/load_utils.py
+++ b/scripts/Muon/load_utils.py
@@ -13,7 +13,7 @@ class LoadUtils(object):
         if exists:
             self.setUp(tmpWS)
         else:
-            mantid.logger.error("Muon Analysis workspace does not exist - no data loaded")
+            raise RuntimeError("No data loaded. \n Please load data using Muon Analysis")
 
     def setUp(self,tmpWS):
         # get everything from the ADS
diff --git a/scripts/REFL_Reduction.py b/scripts/REFL_Reduction.py
deleted file mode 100644
index 2c45991060373a51dca2881faee4b6d39f95bee0..0000000000000000000000000000000000000000
--- a/scripts/REFL_Reduction.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#pylint: disable=invalid-name
-"""
-    Script used to start the REFL reduction gui from Mantidplot
-"""
-from __future__ import (absolute_import, division, print_function)
-from reduction_application import ReductionGUI
-
-reducer = ReductionGUI(instrument="REFL", instrument_list=["REFL"])
-if reducer.setup_layout(load_last=True):
-    reducer.show()
diff --git a/scripts/REFL_SF_Calculator.py b/scripts/REFL_SF_Calculator.py
deleted file mode 100644
index a6ce27641874470d7591de8c938d8f3ef418e0ae..0000000000000000000000000000000000000000
--- a/scripts/REFL_SF_Calculator.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#pylint: disable=invalid-name
-"""
-    Script used to start the REFL SF calculator gui from Mantidplot
-"""
-from __future__ import (absolute_import, division, print_function)
-from reduction_application import ReductionGUI
-
-reducer = ReductionGUI(instrument="REFLSF", instrument_list=["REFLSF"])
-if reducer.setup_layout(load_last=True):
-    reducer.show()
diff --git a/scripts/REFM_Reduction.py b/scripts/REFM_Reduction.py
deleted file mode 100644
index f755196eb030347b141a0fed9bebf032f30e7182..0000000000000000000000000000000000000000
--- a/scripts/REFM_Reduction.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#pylint: disable=invalid-name
-"""
-    Script used to start the REFL reduction gui from Mantidplot
-"""
-from __future__ import (absolute_import, division, print_function)
-from reduction_application import ReductionGUI
-
-reducer = ReductionGUI(instrument="REFM", instrument_list=["REFM"])
-if reducer.setup_layout(load_last=True):
-    reducer.show()
diff --git a/scripts/Reflectometry/isis_reflectometry/l2q.py b/scripts/Reflectometry/isis_reflectometry/l2q.py
index b192b4ef490ef2907ce414746d4e6e5245884126..79aba311d21bcd29a93cdcc6339062287f1310ed 100644
--- a/scripts/Reflectometry/isis_reflectometry/l2q.py
+++ b/scripts/Reflectometry/isis_reflectometry/l2q.py
@@ -1,11 +1,11 @@
-#pylint: disable=invalid-name
+# pylint: disable=invalid-name
 
 from __future__ import (absolute_import, division, print_function)
 import math
 from mantid.simpleapi import *  # New API
 
 
-def l2q(ws,whichDet,theta, sample_component_name):
+def l2q(ws, whichDet, theta, sample_component_name):
     '''
     call signature::call signature::
 
@@ -33,30 +33,41 @@ def l2q(ws,whichDet,theta, sample_component_name):
     else:
         inst = ws.getInstrument()
 
-    sampleLocation=inst.getComponentByName(sample_component_name).getPos()
-    detLocation=inst.getComponentByName(whichDet).getPos()
-    sample2detector=detLocation-sampleLocation    # meters
+    sampleLocation = inst.getComponentByName(sample_component_name).getPos()
+    detLocation = inst.getComponentByName(whichDet).getPos()
+    sample2detector = detLocation - sampleLocation    # meters
 
-    theta=theta*math.pi/180.0     # convert to radians
+    theta = theta * math.pi / 180.0     # convert to radians
 
     # Fetch the reference frame to determine the instrument orientation.
     reference_frame = inst.getReferenceFrame()
 
-    sample_to_detector_along_beam = sample2detector.scalar_prod( reference_frame.vecPointingAlongBeam() )
+    sample_to_detector_along_beam = sample2detector.scalar_prod(
+        reference_frame.vecPointingAlongBeam())
 
     # calculate new detector position based on angle theta in degrees:
-    across_offset = 0.0                            # Across the beam    (side to side)
-    up_offset = sample_to_detector_along_beam * math.sin(2.0 * theta)        # Normal to the beam     (up)
-    beam_offset = detLocation.scalar_prod( reference_frame.vecPointingAlongBeam() )
+    # Across the beam    (side to side)
+    across_offset = 0.0
+    up_offset = sample_to_detector_along_beam * \
+        math.sin(2.0 * theta)        # Normal to the beam     (up)
+    beam_offset = detLocation.scalar_prod(
+        reference_frame.vecPointingAlongBeam())
 
     coord_args = dict()
-    coord_args[ reference_frame.pointingAlongBeamAxis() ] = beam_offset
-    coord_args[ reference_frame.pointingUpAxis() ] = up_offset
-    coord_args[ reference_frame.pointingHorizontalAxis() ] = across_offset
+    coord_args[reference_frame.pointingAlongBeamAxis()] = beam_offset
+    coord_args[reference_frame.pointingUpAxis()] = up_offset
+    coord_args[reference_frame.pointingHorizontalAxis()] = across_offset
 
     logger.information('Correcting detector location')
-    MoveInstrumentComponent(ws, ComponentName=whichDet, RelativePosition=False, **coord_args )
+    MoveInstrumentComponent(
+        ws,
+        ComponentName=whichDet,
+        RelativePosition=False,
+        **coord_args)
 
     # Now convert to momentum transfer
-    IvsQ = ConvertUnits(InputWorkspace=ws,OutputWorkspace="IvsQ",Target="MomentumTransfer")
+    IvsQ = ConvertUnits(
+        InputWorkspace=ws,
+        OutputWorkspace="IvsQ",
+        Target="MomentumTransfer")
     return IvsQ
diff --git a/scripts/SANS/sans/algorithm_detail/mask_workspace.py b/scripts/SANS/sans/algorithm_detail/mask_workspace.py
index 10caf14904c97a8cd0e277d8087150da9927e1eb..951a5bee34c9de7104eeba0eb1a5c70223c2f158 100644
--- a/scripts/SANS/sans/algorithm_detail/mask_workspace.py
+++ b/scripts/SANS/sans/algorithm_detail/mask_workspace.py
@@ -299,9 +299,9 @@ def mask_angle(mask_info, workspace):
     return workspace
 
 
-def mask_beam_stop(mask_info, workspace, instrument):
+def mask_beam_stop(mask_info, workspace, instrument, detector_names):
     """
-    The beam stop is being masked here. Note that this is only implemented for SANS2D
+    The beam stop is being masked here.
 
     :param mask_info: a SANSStateMask object.
     :param workspace: the workspace which is to be masked.
@@ -313,18 +313,17 @@ def mask_beam_stop(mask_info, workspace, instrument):
     beam_stop_arm_pos1 = mask_info.beam_stop_arm_pos1
     beam_stop_arm_pos2 = mask_info.beam_stop_arm_pos2
     if beam_stop_arm_width is not None and beam_stop_arm_angle is not None:
-        if instrument is SANSInstrument.SANS2D:
-            detector = workspace.getInstrument().getComponentByName('rear-detector')
-            z_position = detector.getPos().getZ()
-            start_point = [beam_stop_arm_pos1, beam_stop_arm_pos2, z_position]
-            line_mask = create_line_mask(start_point, 100., beam_stop_arm_width, beam_stop_arm_angle)
+        detector = workspace.getInstrument().getComponentByName(detector_names['LAB'])
+        z_position = detector.getPos().getZ()
+        start_point = [beam_stop_arm_pos1, beam_stop_arm_pos2, z_position]
+        line_mask = create_line_mask(start_point, 100., beam_stop_arm_width, beam_stop_arm_angle)
 
-            mask_name = "MaskDetectorsInShape"
-            mask_options = {"Workspace": workspace,
-                            "ShapeXML": line_mask}
-            mask_alg = create_unmanaged_algorithm(mask_name, **mask_options)
-            mask_alg.execute()
-            workspace = mask_alg.getProperty("Workspace").value
+        mask_name = "MaskDetectorsInShape"
+        mask_options = {"Workspace": workspace,
+                        "ShapeXML": line_mask}
+        mask_alg = create_unmanaged_algorithm(mask_name, **mask_options)
+        mask_alg.execute()
+        workspace = mask_alg.getProperty("Workspace").value
     return workspace
 
 
@@ -351,10 +350,11 @@ class NullMasker(Masker):
 
 
 class MaskerISIS(Masker):
-    def __init__(self, spectra_block, instrument):
+    def __init__(self, spectra_block, instrument, detector_names):
         super(MaskerISIS, self).__init__()
         self._spectra_block = spectra_block
         self._instrument = instrument
+        self._detector_names = detector_names
 
     def mask_workspace(self, mask_info, workspace_to_mask, detector_type, progress):
         """
@@ -388,7 +388,7 @@ class MaskerISIS(Masker):
 
         # Mask beam stop
         progress.report("Masking beam stop.")
-        return mask_beam_stop(mask_info, workspace_to_mask, self._instrument)
+        return mask_beam_stop(mask_info, workspace_to_mask, self._instrument, self._detector_names)
 
 
 class MaskFactory(object):
@@ -406,13 +406,14 @@ class MaskFactory(object):
         """
         data_info = state.data
         instrument = data_info.instrument
+        detector_names = state.reduction.detector_names
         if instrument is SANSInstrument.LARMOR or instrument is SANSInstrument.LOQ or\
                         instrument is SANSInstrument.SANS2D or instrument is SANSInstrument.ZOOM:  # noqa
             run_number = data_info.sample_scatter_run_number
             file_name = data_info.sample_scatter
             _, ipf_path = get_instrument_paths_for_sans_file(file_name)
             spectra_block = SpectraBlock(ipf_path, run_number, instrument, detector_type)
-            masker = MaskerISIS(spectra_block, instrument)
+            masker = MaskerISIS(spectra_block, instrument, detector_names)
         else:
             masker = NullMasker()
             NotImplementedError("MaskFactory: Other instruments are not implemented yet.")
diff --git a/scripts/SANS/sans/command_interface/command_interface_state_director.py b/scripts/SANS/sans/command_interface/command_interface_state_director.py
index cdcb6780b5f574fe2c64cc8116b8a1fb5193761b..44062441b4a7d08a0e132d2c4b05ce3f30c94bc9 100644
--- a/scripts/SANS/sans/command_interface/command_interface_state_director.py
+++ b/scripts/SANS/sans/command_interface/command_interface_state_director.py
@@ -8,6 +8,7 @@ from sans.user_file.settings_tags import (MonId, monitor_spectrum, OtherId, Samp
                                           fit_general, FitId, monitor_file, mask_angle_entry, LimitsId, range_entry,
                                           simple_range, DetectorId, event_binning_string_values, det_fit_range,
                                           single_entry_with_detector)
+from sans.common.file_information import SANSFileInformationFactory
 
 # ----------------------------------------------------------------------------------------------------------------------
 # Commands
@@ -140,9 +141,14 @@ class CommandInterfaceStateDirector(object):
     def _get_data_state(self):
         # Get the data commands
         data_commands = self._get_data_commands()
+        data_elements = self._get_elements_with_key(DataCommandId.sample_scatter, data_commands)
+        data_element = data_elements[-1]
+        file_name = data_element.file_name
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information(file_name)
 
         # Build the state data
-        data_builder = get_data_builder(self._facility)
+        data_builder = get_data_builder(self._facility, file_information)
         self._set_data_element(data_builder.set_sample_scatter, data_builder.set_sample_scatter_period,
                                DataCommandId.sample_scatter, data_commands)
         self._set_data_element(data_builder.set_sample_transmission, data_builder.set_sample_transmission_period,
@@ -215,7 +221,11 @@ class CommandInterfaceStateDirector(object):
         @param data_state: the data state.
         @return: a SANSState object.
         """
-        self._state_director = StateDirectorISIS(data_state)
+        file_name = data_state.sample_scatter
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information(file_name)
+
+        self._state_director = StateDirectorISIS(data_state, file_information)
 
         # If we have a clean instruction in there, then we should apply it to all commands
         self._apply_clean_if_required()
diff --git a/scripts/SANS/sans/common/file_information.py b/scripts/SANS/sans/common/file_information.py
index 0de6cb8b637b6bad23f9ad460b5aea3341a01a35..5675ac3a29381d1d942abf40d0dcfc92d08abcd9 100644
--- a/scripts/SANS/sans/common/file_information.py
+++ b/scripts/SANS/sans/common/file_information.py
@@ -1022,8 +1022,11 @@ class SANSFileInformationFactory(object):
         super(SANSFileInformationFactory, self).__init__()
 
     def create_sans_file_information(self, file_name):
+        if not file_name:
+            raise ValueError("The filename given to FileInformation is empty")
 
         full_file_name = find_sans_file(file_name)
+
         if is_isis_nexus_single_period(full_file_name) or is_isis_nexus_multi_period(full_file_name):
             file_information = SANSFileInformationISISNexus(full_file_name)
         elif is_raw_single_period(full_file_name) or is_raw_multi_period(full_file_name):
diff --git a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py
index d9278e7d46d04e6e65dc4e79be59832b93e133a1..74b29cdb2367ce30af37470b9d19f92736c13fc1 100644
--- a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py
+++ b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py
@@ -1,4 +1,5 @@
 from sans.common.enums import (SANSInstrument, FindDirectionEnum)
+from mantid.kernel import (Logger)
 
 
 class BeamCentreModel(object):
@@ -53,9 +54,13 @@ class BeamCentreModel(object):
         if self.up_down and self.left_right:
             find_direction = FindDirectionEnum.All
         elif self.up_down:
-            find_direction = FindDirectionEnum.Left_Right
-        elif self.left_right:
             find_direction = FindDirectionEnum.Up_Down
+        elif self.left_right:
+            find_direction = FindDirectionEnum.Left_Right
+        else:
+            logger = Logger("CentreFinder")
+            logger.notice("Have chosen no find direction exiting early")
+            return {"pos1": self.lab_pos_1, "pos2": self.lab_pos_2}
 
         if self.q_min:
             state.convert_to_q.q_min = self.q_min
diff --git a/scripts/SANS/sans/gui_logic/presenter/gui_state_director.py b/scripts/SANS/sans/gui_logic/presenter/gui_state_director.py
index 2cc513fa8923d5bdf860fd0f6b9c06b05ded92d2..6a46e54b906fa881a6cd8f7738ee12b5c87a51a9 100644
--- a/scripts/SANS/sans/gui_logic/presenter/gui_state_director.py
+++ b/scripts/SANS/sans/gui_logic/presenter/gui_state_director.py
@@ -10,6 +10,7 @@ import copy
 
 from sans.state.data import get_data_builder
 from sans.user_file.state_director import StateDirectorISIS
+from sans.common.file_information import SANSFileInformationFactory
 
 
 class GuiStateDirector(object):
@@ -22,7 +23,10 @@ class GuiStateDirector(object):
     def create_state(self, row):
         # 1. Get the data settings, such as sample_scatter, etc... and create the data state.
         table_index_model = self._table_model.get_table_entry(row)
-        data_builder = get_data_builder(self._facility)
+        file_name = table_index_model.sample_scatter
+        file_information_factory = SANSFileInformationFactory()
+        file_information = file_information_factory.create_sans_file_information(file_name)
+        data_builder = get_data_builder(self._facility, file_information)
 
         self._set_data_entry(data_builder.set_sample_scatter, table_index_model.sample_scatter)
         self._set_data_period_entry(data_builder.set_sample_scatter_period, table_index_model.sample_scatter_period)
@@ -50,7 +54,7 @@ class GuiStateDirector(object):
             state_gui_model.output_name = output_name
 
         # 4. Create the rest of the state based on the builder.
-        user_file_state_director = StateDirectorISIS(data)
+        user_file_state_director = StateDirectorISIS(data, file_information)
         settings = copy.deepcopy(state_gui_model.settings)
         user_file_state_director.add_state_settings(settings)
 
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 315bad89e2a15d3fee20ed9234698957c0a9eb84..a08f481129587c6960daffd007301fd7998d4cba 100644
--- a/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py
+++ b/scripts/SANS/sans/gui_logic/presenter/run_tab_presenter.py
@@ -927,6 +927,7 @@ class RunTabPresenter(object):
         else:
             rows = range(number_of_rows)
         states = {}
+
         gui_state_director = GuiStateDirector(table_model, state_model, self._facility)
         for row in rows:
             self.sans_logger.information("Generating state for row {}".format(row))
diff --git a/scripts/SANS/sans/state/data.py b/scripts/SANS/sans/state/data.py
index 93e2835f8d71edb5594fef40eadad9ea35d8df1a..59ab291246644ef6a9535330e065f806c1fe96ce 100644
--- a/scripts/SANS/sans/state/data.py
+++ b/scripts/SANS/sans/state/data.py
@@ -10,7 +10,6 @@ from sans.state.state_base import (StateBase, StringParameter, PositiveIntegerPa
 from sans.common.enums import (SANSInstrument, SANSFacility)
 import sans.common.constants
 from sans.state.state_functions import (is_pure_none_or_not_none, validation_message)
-from sans.common.file_information import SANSFileInformationFactory
 from sans.state.automatic_setters import automatic_setters
 
 
@@ -106,10 +105,7 @@ class StateData(StateBase):
 # ----------------------------------------------------------------------------------------------------------------------
 # Builder
 # ----------------------------------------------------------------------------------------------------------------------
-def set_information_from_file(data_info):
-    file_name = data_info.sample_scatter
-    file_information_factory = SANSFileInformationFactory()
-    file_information = file_information_factory.create_sans_file_information(file_name)
+def set_information_from_file(data_info, file_information):
     instrument = file_information.get_instrument()
     facility = file_information.get_facility()
     run_number = file_information.get_run_number()
@@ -123,18 +119,20 @@ def set_information_from_file(data_info):
 
 class StateDataBuilder(object):
     @automatic_setters(StateData)
-    def __init__(self):
+    def __init__(self, file_information):
         super(StateDataBuilder, self).__init__()
         self.state = StateData()
+        self._file_information = file_information
 
     def build(self):
         # Make sure that the product is in a valid state, ie not incomplete
         self.state.validate()
 
-        # There are some elements which need to be read from the file. This is currently:
+        # There are some elements which need to be read from the file information object.
+        #  This is currently:
         # 1. instrument
         # 2. sample_scatter_run_number
-        set_information_from_file(self.state)
+        set_information_from_file(self.state, self._file_information)
 
         return copy.copy(self.state)
 
@@ -142,9 +140,9 @@ class StateDataBuilder(object):
 # ------------------------------------------
 # Factory method for StateDataBuilder
 # ------------------------------------------
-def get_data_builder(facility):
+def get_data_builder(facility, file_information=None):
     if facility is SANSFacility.ISIS:
-        return StateDataBuilder()
+        return StateDataBuilder(file_information)
     else:
         raise NotImplementedError("StateDataBuilder: The selected facility {0} does not seem"
                                   " to exist".format(str(facility)))
diff --git a/scripts/SANS/sans/state/scale.py b/scripts/SANS/sans/state/scale.py
index 43fb51bbeebdd20d36a3235c683fb3039588459f..47189ec6f1008297c90e42e71b936e4bdf200d68 100644
--- a/scripts/SANS/sans/state/scale.py
+++ b/scripts/SANS/sans/state/scale.py
@@ -4,7 +4,6 @@ from __future__ import (absolute_import, division, print_function)
 import copy
 from sans.state.state_base import (StateBase, rename_descriptor_names, PositiveFloatParameter, ClassTypeParameter)
 from sans.common.enums import (SampleShape, SANSFacility)
-from sans.common.file_information import (SANSFileInformationFactory)
 from sans.state.automatic_setters import (automatic_setters)
 
 
@@ -43,11 +42,7 @@ class StateScale(StateBase):
 # ----------------------------------------------------------------------------------------------------------------------
 #  Builder
 # ----------------------------------------------------------------------------------------------------------------------
-def set_geometry_from_file(state, date_info):
-    sample_scatter = date_info.sample_scatter
-    file_information_factory = SANSFileInformationFactory()
-    file_information = file_information_factory.create_sans_file_information(sample_scatter)
-
+def set_geometry_from_file(state, date_info, file_information):
     # Get the geometry
     state.height_from_file = file_information.get_height()
     state.width_from_file = file_information.get_width()
@@ -57,10 +52,10 @@ def set_geometry_from_file(state, date_info):
 
 class StateScaleBuilder(object):
     @automatic_setters(StateScale, exclusions=[])
-    def __init__(self, data_info):
+    def __init__(self, data_info, file_information):
         super(StateScaleBuilder, self).__init__()
         self.state = StateScale()
-        set_geometry_from_file(self.state, data_info)
+        set_geometry_from_file(self.state, data_info, file_information)
 
     def build(self):
         self.state.validate()
@@ -70,12 +65,12 @@ class StateScaleBuilder(object):
 # ---------------------------------------
 # Factory method for SANStateScaleBuilder
 # ---------------------------------------
-def get_scale_builder(data_info):
+def get_scale_builder(data_info, file_information=None):
     # The data state has most of the information that we require to define the scaling. For the factory method, only
     # the facility/instrument is of relevance.
     facility = data_info.facility
     if facility is SANSFacility.ISIS:
-        return StateScaleBuilder(data_info)
+        return StateScaleBuilder(data_info, file_information)
     else:
         raise NotImplementedError("StateScaleBuilder: Could not find any valid scale builder for the "
                                   "specified StateData object {0}".format(str(data_info)))
diff --git a/scripts/SANS/sans/test_helper/file_information_mock.py b/scripts/SANS/sans/test_helper/file_information_mock.py
new file mode 100644
index 0000000000000000000000000000000000000000..0bdf001aa78ed85eb02eaebce226790d33cd73cc
--- /dev/null
+++ b/scripts/SANS/sans/test_helper/file_information_mock.py
@@ -0,0 +1,61 @@
+from sans.common.file_information import SANSFileInformation
+from mantid.kernel import DateAndTime
+from sans.common.enums import (SANSFacility, SANSInstrument, FileType, SampleShape)
+
+
+class SANSFileInformationMock(SANSFileInformation):
+    def __init__(self, instrument=SANSInstrument.LOQ, facility=SANSFacility.ISIS, run_number=00000, file_name='file_name',
+                 height=8.0, width=8.0, thickness=1.0, shape=SampleShape.Cuboid, date='2012-10-22T22:41:27', periods=1,
+                 event_mode=True, added_data=False):
+        super(SANSFileInformationMock, self).__init__(file_name)
+        self._instrument = instrument
+        self._facility = facility
+        self._run_number = run_number
+        self._height = height
+        self._width = width
+        self._thickness = thickness
+        self._shape = shape
+        self._date = date
+        self._file_name = file_name
+        self._periods = periods
+        self._event_mode = event_mode
+        self._added_data = added_data
+
+    def get_file_name(self):
+        return self._file_name
+
+    def get_instrument(self):
+        return self._instrument
+
+    def get_facility(self):
+        return self._facility
+
+    def get_date(self):
+        return DateAndTime(self._date)
+
+    def get_number_of_periods(self):
+        return self._periods
+
+    def get_run_number(self):
+        return self._run_number
+
+    def get_type(self):
+        return FileType.ISISNexus
+
+    def is_event_mode(self):
+        return self._event_mode
+
+    def is_added_data(self):
+        return self._added_data
+
+    def get_height(self):
+        return self._height
+
+    def get_width(self):
+        return self._width
+
+    def get_thickness(self):
+        return self._thickness
+
+    def get_shape(self):
+        return self._shape
diff --git a/scripts/SANS/sans/test_helper/test_director.py b/scripts/SANS/sans/test_helper/test_director.py
index 2ddb9f48b4be36f6904d3b0c13de9fb85eff05d6..0f2b7fda8d7c8142bca6aabf314616692a38b969 100644
--- a/scripts/SANS/sans/test_helper/test_director.py
+++ b/scripts/SANS/sans/test_helper/test_director.py
@@ -16,7 +16,8 @@ from sans.state.adjustment import get_adjustment_builder
 from sans.state.convert_to_q import get_convert_to_q_builder
 
 from sans.common.enums import (SANSFacility, ISISReductionMode, ReductionDimensionality,
-                               FitModeForMerge, RebinType, RangeStepType, SaveType, FitType, SampleShape)
+                               FitModeForMerge, RebinType, RangeStepType, SaveType, FitType, SampleShape, SANSInstrument)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 class TestDirector(object):
@@ -51,10 +52,11 @@ class TestDirector(object):
 
     def construct(self):
         facility = SANSFacility.ISIS
+        file_information = SANSFileInformationMock(run_number=22024, instrument=SANSInstrument.SANS2D)
 
         # Build the SANSStateData
         if self.data_state is None:
-            data_builder = get_data_builder(facility)
+            data_builder = get_data_builder(facility, file_information)
             data_builder.set_sample_scatter("SANS2D00022024")
             data_builder.set_can_scatter("SANS2D00022024")
             self.data_state = data_builder.build()
@@ -110,7 +112,7 @@ class TestDirector(object):
 
         # Build the SANSStateScale
         if self.scale_state is None:
-            scale_builder = get_scale_builder(self.data_state)
+            scale_builder = get_scale_builder(self.data_state, file_information)
             scale_builder.set_shape(SampleShape.Cuboid)
             scale_builder.set_width(1.0)
             scale_builder.set_height(2.0)
diff --git a/scripts/SANS/sans/user_file/state_director.py b/scripts/SANS/sans/user_file/state_director.py
index 224ea588e1cd7ff339b129084dc8351ef7feeff5..8ca3dd696f396185d9df84b0c3d3c5452298b9ae 100644
--- a/scripts/SANS/sans/user_file/state_director.py
+++ b/scripts/SANS/sans/user_file/state_director.py
@@ -160,7 +160,7 @@ def set_single_entry(builder, method_name, tag, all_entries, apply_to_value=None
 
 
 class StateDirectorISIS(object):
-    def __init__(self, data_info):
+    def __init__(self, data_info, file_information):
         super(StateDirectorISIS, self).__init__()
         data_info.validate()
         self._data = data_info
@@ -174,7 +174,7 @@ class StateDirectorISIS(object):
         self._slice_event_builder = get_slice_event_builder(self._data)
         self._wavelength_builder = get_wavelength_builder(self._data)
         self._save_builder = get_save_builder(self._data)
-        self._scale_builder = get_scale_builder(self._data)
+        self._scale_builder = get_scale_builder(self._data, file_information)
 
         self._adjustment_builder = get_adjustment_builder(self._data)
         self._normalize_to_monitor_builder = get_normalize_to_monitor_builder(self._data)
@@ -666,8 +666,8 @@ class StateDirectorISIS(object):
                     start_times_hab.append(times.start)
                     stop_times_hab.append(times.stop)
                 elif times.detector_type is DetectorType.LAB:
-                    start_times_hab.append(times.start)
-                    stop_times_hab.append(times.stop)
+                    start_times_lab.append(times.start)
+                    stop_times_lab.append(times.stop)
                 else:
                     RuntimeError("UserFileStateDirector: The specified detector {0} is not "
                                  "known".format(times.detector_type))
diff --git a/scripts/SANS/sans/user_file/user_file_parser.py b/scripts/SANS/sans/user_file/user_file_parser.py
index 1913eed239182b37b6088abddc2a6933286c1889..7365bc41db2cb07b7541ac9bcb8c701f10cba861 100644
--- a/scripts/SANS/sans/user_file/user_file_parser.py
+++ b/scripts/SANS/sans/user_file/user_file_parser.py
@@ -443,7 +443,7 @@ class DetParser(UserFileComponentParser):
                 merge_range = extract_float_range(merge_range_string)
                 value = det_fit_range(start=merge_range[0], stop=merge_range[1], use_fit=True)
             else:
-                value = det_fit_range(start=None, stop=None, use_fit=True)
+                raise RuntimeError("DetParser: Could not extract line: {0}".format(line))
             return {DetectorId.merge_range: value}
         else:
             raise RuntimeError("DetParser: Could not extract line: {0}".format(line))
@@ -839,9 +839,10 @@ class MaskParser(UserFileComponentParser):
 
         # Time Mask
         self._time_or_t = "\\s*(TIME|T)\\s*"
-        self._detector_time = "\\s*((" + self._hab + "|" + self._lab + ")"+"\\s*/\\s*)?\\s*"
-        self._time_pattern = re.compile(start_string + self._detector_time + self._time_or_t + space_string +
-                                        self._two_floats + end_string)
+        self._detector_time = "\\s*((" + self._hab + "|" + self._lab + ")"+"\\s*)?\\s*"
+        self._time_pattern = re.compile(start_string + self._detector_time + "/?" + self._time_or_t + space_string +
+                                        self._two_floats + end_string + "|" + start_string + self._time_or_t +
+                                        "/?" + self._detector_time + space_string + self._two_floats + end_string)
 
         # Block mask
         self._v_plus_h = "\\s*" + self._v + integer_number + "\\s*\\+\\s*" + self._h + integer_number
@@ -859,7 +860,6 @@ class MaskParser(UserFileComponentParser):
     def parse_line(self, line):
         # Get the settings, ie remove command
         setting = UserFileComponentParser.get_settings(line, MaskParser.get_type_pattern())
-
         # Determine the qualifier and extract the user setting
         if self._is_block_mask(setting):
             output = self._extract_block_mask(setting)
@@ -983,12 +983,13 @@ class MaskParser(UserFileComponentParser):
         if has_hab is not None or has_lab is not None:
             key = MaskId.time_detector
             detector_type = DetectorType.HAB if has_hab is not None else DetectorType.LAB
-            regex_string = "\s*(" + self._hab + ")\s*/\s*" if has_hab else "\s*(" + self._lab + ")\s*/\s*"
+            regex_string = "\s*(" + self._hab + ")\s*" if has_hab else "\s*(" + self._lab + ")\s*"
             min_and_max_time_range = re.sub(regex_string, "", line)
         else:
             key = MaskId.time
             detector_type = None
             min_and_max_time_range = line
+        min_and_max_time_range = re.sub("\s*/\s*", "", min_and_max_time_range)
         min_and_max_time_range = re.sub(self._time_or_t, "", min_and_max_time_range)
         min_and_max_time = extract_float_range(min_and_max_time_range)
         return {key: range_entry_with_detector(start=min_and_max_time[0], stop=min_and_max_time[1],
@@ -2079,17 +2080,18 @@ class PrintParser(UserFileComponentParser):
     def __init__(self):
         super(PrintParser, self).__init__()
 
-        # Print
-        self._print = "\\s*PRINT\\s+"
-        self._print_pattern = re.compile(start_string + self._print + "\\s*.*\\s*" + end_string)
-
     def parse_line(self, line):
         # Get the settings, ie remove command
-        setting = UserFileComponentParser.get_settings(line, PrintParser.get_type_pattern())
 
-        # Determine the qualifier and extract the user setting
-        original_setting = re.search(setting.strip(), line, re.IGNORECASE).group(0)
-        return {PrintId.print_line: original_setting}
+        setting = line.strip()
+
+        if setting.upper().startswith(PrintParser.Type):
+            setting = setting[len(PrintParser.Type):]
+            setting = setting.strip()
+        else:
+            raise RuntimeError("PrintParser: Failed to extract line {} it does not start with {}".format(line, PrintParser.Type))
+
+        return {PrintId.print_line: setting}
 
     @staticmethod
     def get_type():
diff --git a/scripts/directtools/__init__.py b/scripts/directtools/__init__.py
index 6aea8a736947533a55793b7dccd3310b84b34e1d..bc91cfe55510da98e534397566ee564ac17794e9 100644
--- a/scripts/directtools/__init__.py
+++ b/scripts/directtools/__init__.py
@@ -33,6 +33,11 @@ def _clearlatex(s):
     return s
 
 
+def _configurematplotlib(params):
+    """Set matplotlib rc parameters from the params dictionary."""
+    matplotlib.rcParams.update(params)
+
+
 def _finalizeprofileE(axes):
     """Set axes for const E axes."""
     axes.set_xlim(xmin=0.)
@@ -111,6 +116,11 @@ def _binCentres(edges):
     return (edges[:-1] + edges[1:]) / 2
 
 
+def _mantidsubplotsetup():
+    """Return the Mantid projection setup."""
+    return {'projection': 'mantid'}
+
+
 def _profiletitle(workspaces, scan, units, cuts, widths, figure):
     """Add title to line profile figure."""
     workspaces = _normwslist(workspaces)
@@ -180,7 +190,22 @@ def _SofQWtitle(workspace, figure):
 
 
 def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, vertMax=numpy.inf):
-    """Return slicing for a 2D numpy array limited by given min and max values."""
+    """Return slicing for a 2D numpy array limited by given min and max values.
+
+    :param xs: the 2D X data of a workspace from :func:`mantid.api.MatrixWorkspace.extractX`
+    :type xs: a 2D :class:`numpy.ndarray`
+    :param vertAxis: the vertical axis values of a workspace
+    :type vertAxis: a 1D :class:`numpy.ndarray`
+    :param horMin: the left edge of the box
+    :type horMin: float
+    :param horMax: the right edge of the box
+    :type horMax: float
+    :param vertMin: the bottom edge of the box
+    :type vertMin: float
+    :param vertMax: the top edge of the box
+    :type vertMax: float
+    :returns: a tuple of two :class:`slice` objects, the first one for vertical dimension, the second for horizontal.
+    """
     if len(vertAxis) > xs.shape[0]:
         vertAxis = _binCentres(vertAxis)
     horBegin = numpy.argwhere(xs[0, :] >= horMin)[0][0]
@@ -190,13 +215,11 @@ def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf,
     return slice(vertBegin, vertEnd), slice(horBegin, horEnd)
 
 
-def configurematplotlib(params):
-    """Set matplotlib rc parameters from the params dictionary."""
-    matplotlib.rcParams.update(params)
-
-
 def defaultrcParams():
-    """Return a dictionary of directtools default matplotlib rc parameters."""
+    """Return a dictionary of directtools default matplotlib rc parameters.
+
+    :returns: a :class:`dict` of default :mod:`matplotlib` rc parameters needed by :mod:`directtools`
+    """
     params = {
         'legend.numpoints': 1,
         'text.usetex': True,
@@ -205,7 +228,23 @@ def defaultrcParams():
 
 
 def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEpsilon=1e-6):
-    """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`."""
+    """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`.
+
+    #. If the X units are not in DeltaE, the workspace is transposed
+    #. The Y data in *workspace* is multiplied by :math:`1 - e^{\Delta E / (kT)}`
+    #. Y data in the bin closest to 0 meV and within -*zeroEnergyEpsilon* < :math:`\Delta E` < *zeroEnergyEpsilon* is set to 0
+    #. If the input was transposed, transpose the output as well
+
+    :param workspace: a :math:`S(Q,E)` workspace to convert
+    :type workspace: :class:`mantid.api.MatrixWorkspace`
+    :param temperature: temperature in Kelvin
+    :type temperature: float
+    :param outputName: name of the output workspace. If :class:`None`, the output will be given some generated name.
+    :type outputName: str or None
+    :param zeroEnergyEpsilon: if a bin center is within this value from 0, the bin's value is set to zero.
+    :type zeroEnergyEpsilon: float
+    :returns: a :class:`mantid.api.MatrixWorkspace` containing :math:`\chi''(Q,E)`
+    """
     workspace = _normws(workspace)
     horAxis = workspace.getAxis(0)
     horUnit = horAxis.getUnit().unitID()
@@ -224,13 +263,24 @@ def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEps
     return outWS
 
 
-def mantidsubplotsetup():
-    """Return a dict for the matplotlib.pyplot.subplots()."""
-    return {'projection': 'mantid'}
-
-
 def nanminmax(workspace, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, vertMax=numpy.inf):
-    """Return min and max intensities of a workspace."""
+    """Return min and max intensities of a workspace ignoring NaNs.
+
+    The search region can be limited by *horMin*, *horMax*, *vertMin* and *vertMax*.
+
+    :param workspace: a workspace
+    :type workspace: :class:`mantid.api.MatrixWorkspace`
+    :param horMin: the left edge of the search region
+    :type horMin: float
+    :param horMax: the right edge of the search region
+    :type horMax: float
+    :param vertMin: the bottom edge of the search region
+    :type vertMin: float
+    :param vertMax: the top edge of the search region
+    :type vertMax: float
+
+    :returns: a tuple containing the minimum and maximum
+    """
     workspace = _normws(workspace)
     xs = workspace.extractX()
     ys = workspace.extractY()
@@ -245,7 +295,26 @@ def nanminmax(workspace, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf
 
 
 def plotconstE(workspaces, E, dE, style='l', keepCutWorkspaces=True):
-    """Plot line profiles at constant energy."""
+    """Plot line profiles at constant energy transfer from :math:`S(Q,E)` workspace.
+
+    Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces,
+    constant energy transfers, or cut widths, or any combination thereof can be given as parameters.
+
+    The last entry in the returned tuple is a list of cut workspace names. This will be an empty list
+    is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS.
+
+    :param workspaces: a single :math:`S(Q,E)` workspace or list of workspaces to cut
+    :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a list thereof
+    :param E: a constant energy transfer or a :class:`list` thereof
+    :type E: float or :class:`list` of floats
+    :param dE: width of the cut or a list of widths
+    :type dE: float or :class:`list` of floats
+    :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both
+    :type style: str
+    :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS
+    :type keepCutWorkspaces: bool
+    :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names)
+    """
     figure, axes, cutWSList = plotcuts('Horizontal', workspaces, E, dE, '$E$', 'meV', style, keepCutWorkspaces)
     _profiletitle(workspaces, '$E$', 'meV', E, dE, figure)
     axes.legend()
@@ -258,7 +327,26 @@ def plotconstE(workspaces, E, dE, style='l', keepCutWorkspaces=True):
 
 
 def plotconstQ(workspaces, Q, dQ, style='l', keepCutWorkspaces=True):
-    """Plot line profiles at constant momentum transfer."""
+    """Plot line profiles at constant momentum transfer from :math:`S(Q,E)` workspace.
+
+    Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces,
+    constant momentum transfers, or cut widths, or any combination thereof can be given as parameters.
+
+    The last entry in the returned tuple is a list of cut workspace names. This will be an empty list
+    is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS.
+
+    :param workspaces: a single :math:`S(Q,E)` workspace or list of workspaces to cut
+    :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a list thereof
+    :param Q: a constant momentum transfer or a :class:`list` thereof
+    :type Q: float or :class:`list` of floats
+    :param dQ: width of the cut or a list of widths
+    :type dQ: float or :class:`list` of floats
+    :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both
+    :type style: str
+    :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS
+    :type keepCutWorkspaces: bool
+    :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names)
+    """
     figure, axes, cutWSList = plotcuts('Vertical', workspaces, Q, dQ, '$Q$', '\\AA$^{-1}$', style, keepCutWorkspaces)
     _profiletitle(workspaces, '$Q$', '\\AA$^{-1}$', Q, dQ, figure)
     axes.legend()
@@ -272,7 +360,32 @@ def plotconstQ(workspaces, Q, dQ, style='l', keepCutWorkspaces=True):
 
 
 def plotcuts(direction, workspaces, cuts, widths, quantity, unit, style='l', keepCutWorkspaces=True):
-    """Cut and plot multiple line profiles."""
+    """Cut and plot multiple line profiles.
+
+    Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces,
+    cut centres, or cut widths, or any combination thereof can be given as parameters.
+
+    The last entry in the returned tuple is a list of cut workspace names. This will be an empty list
+    is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS.
+
+    :param direction: Cut direction. Only ``'Horizontal'`` and ``'Vertical'`` are accepted
+    :type direction: str
+    :param workspaces: a single workspace or a list thereof
+    :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a :class:`list` thereof
+    :param cuts: the center of the cut or a list of centers
+    :type cuts: float or a :class:`list` thereof
+    :param widths: the width of the cut or a list of widths
+    :type widths: float or a :class:`list` thereof
+    :param quantity: name of the physical quantity along which the cut is made, used for legend label
+    :type quantity: str
+    :param unit: unit of *quantity*
+    :type unit: str
+    :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both
+    :type style: str
+    :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS
+    :type keepCutWorkspaces: bool
+    :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names)
+    """
     workspaces = _normwslist(workspaces)
     if not isinstance(cuts, collections.Iterable):
         cuts = [cuts]
@@ -308,7 +421,18 @@ def plotcuts(direction, workspaces, cuts, widths, quantity, unit, style='l', kee
 
 
 def plotprofiles(workspaces, labels=None, style='l'):
-    """Plot given line profile workspaces."""
+    """Plot line profile workspaces.
+
+    Plots the first histograms from given workspaces.
+
+    :param workspaces: a single workspace or a list thereof
+    :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a :class:`list` thereof
+    :param labels: a list of cut labels for the plot legend
+    :type labels: str, a :class:`list` of strings or None
+    :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both
+    :type style: str
+    :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`)
+    """
     workspaces = _normwslist(workspaces)
     if not isinstance(labels, collections.Iterable) or isinstance(labels, str):
         if labels is None:
@@ -336,7 +460,26 @@ def plotprofiles(workspaces, labels=None, style='l'):
 
 
 def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax=None, colormap='jet'):
-    """Plot a 2D plot with given axis limits and return the plotting layer."""
+    """Plot a 2D :math:`S(Q,E)` workspace.
+
+    :param workspace: a workspace to plot
+    :type workspace: str or :class:`mantid.api.MatrixWorkspace`
+    :param QMin: minimum :math:`Q` to include in the plot
+    :type QMin: float or None
+    :param QMax: maximum :math:`Q` to include in the plot
+    :type QMax: float or None
+    :param EMin: minimum energy transfer to include in the plot
+    :type EMin: float or None
+    :param EMax: maximum energy transfer to include in the plot
+    :type EMax: float or None
+    :param VMin: minimum intensity to show on the color bar
+    :type VMin: float or None
+    :param VMax: maximum intensity to show on the color bar
+    :type VMax: float or None
+    :param colormap: name of the colormap
+    :type colormap: str
+    :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`)
+    """
     # Accept both workspace names and actual workspaces.
     workspace = _normws(workspace)
     isSusceptibility = workspace.YUnit() == 'Dynamic susceptibility'
@@ -378,12 +521,28 @@ def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax
 
 
 def subplots(**kwargs):
-    """Return matplotlib figure and axes."""
-    return pyplot.subplots(subplot_kw=mantidsubplotsetup(), **kwargs)
+    """Return matplotlib figure and axes with Mantid projection.
+
+    The returned figure and axes have the proper projection to plot Mantid workspaces directly.
+
+    :param kwargs: keyword arguments that are directly passed to :func:`matplotlib.pyplot.subplots`.
+    :type kwargs: dict
+    :returns: a tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`)
+    """
+    return pyplot.subplots(subplot_kw=_mantidsubplotsetup(), **kwargs)
 
 
 def validQ(workspace, E=0.0):
-    """Return a :math:`Q` range at given energy transfer where :math:`S(Q,E)` is defined."""
+    """Return a :math:`Q` range at given energy transfer where :math:`S(Q,E)` is defined.
+
+    :math:`S(Q,E)` is undefined when Y = NaN
+
+    :param workspace: A :math:`S(Q,E)` workspace to investigate
+    :type workspace: str or :class:`mantid.api.MatrixWorkspace`
+    :param E: energy transfer at which to evaluate the range
+    :type E: float
+    :returns: a tuple of (:math:`Q_{min}`, :math:`Q_{max}`)
+    """
     workspace = _normws(workspace)
     vertBins = workspace.getAxis(1).extractValues()
     if len(vertBins) > workspace.getNumberHistograms():
@@ -401,7 +560,14 @@ def validQ(workspace, E=0.0):
 
 
 def wsreport(workspace):
-    """Print some useful information from sample logs."""
+    """Print some useful information from sample logs.
+
+    The logs are expected to contain some ILL specific fields.
+
+    :param workspace: a workspace from which to extract the logs
+    :type workspace: str or :class:`mantid.api.MatrixWorkspace`
+    :returns: None
+    """
     workspace = _normws(workspace)
     print(str(workspace))
     logs = SampleLogs(workspace)
@@ -420,8 +586,27 @@ def wsreport(workspace):
 
 
 class SampleLogs:
+    """A convenience class to access the sample logs of :class:`mantid.api.MatrixWorkspace`.
+
+    Upon initialization, this class adds the sample logs as data attributes to itself. The
+    attributes get their names from the logs. Log names containing dots result in nested
+    log objects. Thus, if a workspace contains logs ``'a'`` and ``'b.c'``:
+
+    .. code::
+
+        logs = SampleLogs(workspace)
+        # This is equivalent of calling workspace.run().getProperty('a').value
+        logs.a
+        # This is equivalent of calling workspace.run().getProperty('b.c').value
+        logs.b.c
+    """
     def __init__(self, workspace):
-        """Transform sample log entries from workspace into attributes of this object."""
+        """Initialize a `SampleLogs` object.
+        Transform sample log entries from workspace into attributes of this object.
+
+        :param workspace: the workspace from which to extract the sample logs
+        :type workspace: :class:`mantid.api.MatrixWorkspace`
+        """
         class Log:
             pass
         workspace = _normws(workspace)
@@ -442,4 +627,4 @@ class SampleLogs:
 
 
 # Set default matplotlib rc parameters.
-configurematplotlib(defaultrcParams())
+_configurematplotlib(defaultrcParams())
diff --git a/scripts/reduction/instruments/reflectometer/__init__.py b/scripts/reduction/instruments/reflectometer/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/scripts/reduction/instruments/reflectometer/data_manipulation.py b/scripts/reduction/instruments/reflectometer/data_manipulation.py
deleted file mode 100644
index eac12d1bba57df4c5b05b6976749ca2385996da5..0000000000000000000000000000000000000000
--- a/scripts/reduction/instruments/reflectometer/data_manipulation.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# pylint: disable=invalid-name
-from __future__ import (absolute_import, division, print_function)
-import os
-from mantid.simpleapi import *
-
-
-def tof_distribution(file_path, callback=None,
-                     range_min=None, range_max=None):
-    """
-        Plot counts as a function of TOF for a given REF_L data file
-    """
-
-    print('entering tof_distribution')
-
-    basename = os.path.basename(file_path)
-    ws_raw = "__%s" % basename
-    ws = "__TOF_distribution"
-
-    # if not mtd.workspaceExists(ws_raw):
-    LoadEventNexus(Filename=file_path, OutputWorkspace=ws_raw)
-
-    Rebin(InputWorkspace=ws_raw, OutputWorkspace=ws, Params="0,200,200000")
-    SumSpectra(InputWorkspace=ws, OutputWorkspace=ws)
-
-    # Get range of TOF where we have data
-    x = mtd[ws].readX(0)
-    y = mtd[ws].readY(0)
-    xmin = x[0]
-    xmax = None
-    for i in range(len(y)):
-        if y[i] == 0.0 and xmax is None:
-            xmin = x[i]
-        if y[i] > 0:
-            xmax = x[i]
-
-    if callback is not None:
-        from LargeScaleStructures import data_stitching
-        data_stitching.RangeSelector.connect([ws], callback,
-                                             xmin=xmin, xmax=xmax,
-                                             range_min=range_min,
-                                             range_max=range_max)
-
-
-def _load_entry(entry, ws_output_base, file_path, is_pixel_y, ws_list, tof_min, tof_max, title=""):
-    # 1D plot
-    ws_output = "%s %s" % (ws_output_base, title)
-
-    ws = LoadEventNexus(Filename=file_path, NXentryName=entry)
-
-    if ws.getNumberEvents() == 0:
-        print('No data in entry %s' % entry)
-        return
-
-    instr_dir = config.getInstrumentDirectory()
-
-    # check date of input file
-    date = mtd['ws'].getRun().getProperty('run_start').value
-    nexus_acquisition = date.split('T')[0]
-    if nexus_acquisition > '2014-10-01':
-        geo_base_file_x = "REFL_Detector_Grouping_Sum_X_rot.xml"
-        geo_base_file_y = "REFL_Detector_Grouping_Sum_Y_rot.xml"
-    else:
-        geo_base_file_x = "REFL_Detector_Grouping_Sum_X.xml"
-        geo_base_file_y = "REFL_Detector_Grouping_Sum_Y.xml"
-
-    if is_pixel_y:
-        grouping_file = os.path.join(instr_dir, "Grouping", geo_base_file_x)
-    else:
-        grouping_file = os.path.join(instr_dir, "Grouping", geo_base_file_y)
-
-    GroupDetectors(InputWorkspace=ws, OutputWorkspace=ws_output, MapFile=grouping_file)
-    ws_output = Transpose(InputWorkspace=ws_output)
-
-    # Copy over the units
-    ws_list.append(ws_output)
-
-    # 2D plot
-    output_2d = Rebin(InputWorkspace=ws, Params="%d,200,%d" % (tof_min, tof_max))
-
-    if is_pixel_y:
-        grouping_file = os.path.join(instr_dir, "Grouping", "REFL_Detector_Grouping_Sum_X.xml")
-        output_2d = GroupDetectors(InputWorkspace=output_2d, MapFile=grouping_file)
-    else:
-        grouping_file = os.path.join(instr_dir, "Grouping", "REFL_Detector_Grouping_Sum_Y.xml")
-        output_2d = GroupDetectors(InputWorkspace=output_2d, MapFile=grouping_file)
-
-    return ws_list
-
-
-def counts_vs_pixel_distribution(file_path, is_pixel_y=True, callback=None,
-                                 range_min=None, range_max=None,
-                                 high_res=True, instrument="REFL",
-                                 isPeak=True,
-                                 tof_min=None, tof_max=None):
-    """
-        Display counts vs pixel of data or normalization data
-
-        @param isPeak: are we working with peak or with background
-
-    """
-    basename = os.path.basename(file_path)
-    ws_base = "__%s" % basename
-
-    ws_output_base = ''
-    if instrument == 'REFL':
-        if isPeak:
-            type = 'Peak'
-        else:
-            type = 'Background'
-        if is_pixel_y is False:
-            x_title = "X pixel"
-        else:
-            x_title = "Y pixel"
-        ws_output_base = type + " - " + basename + " - " + x_title
-    else:
-        ws_output_base = "Counts vs Y pixel - %s" % basename
-        x_title = "Y pixel"
-        if is_pixel_y is False:
-            ws_output_base = "Counts vs X pixel - %s" % basename
-            x_title = "X pixel"
-
-    ws_list = []
-
-    if tof_min is None:
-        tof_min = 0
-    if tof_max is None:
-        tof_max = 200000
-
-    if instrument == "REFM":
-        for p in ['Off_Off', 'On_Off', 'Off_On', 'On_On']:
-            ws_list = _load_entry(entry="entry-{0}".format(p), ws_output_base=ws_output_base, title=p,
-                                  file_path=file_path, is_pixel_y=is_pixel_y, ws_list=ws_list, tof_min=tof_min,
-                                  tof_max=tof_max)
-    else:
-        ws_list = _load_entry(entry="entry", ws_output_base=ws_output_base, title=p, file_path=file_path,
-                              is_pixel_y=is_pixel_y, ws_list=ws_list, tof_min=tof_min, tof_max=tof_max)
-
-    if callback is not None:
-        from LargeScaleStructures import data_stitching
-        data_stitching.RangeSelector.connect(ws_list, callback,
-                                             range_min=range_min,
-                                             range_max=range_max,
-                                             x_title=x_title,
-                                             log_scale=True,
-                                             ws_output_base=ws_output_base)
-
-    # Estimate peak limits
-    ws_output = ws_base + '_all'
-    CloneWorkspace(InputWorkspace=ws_list[0], OutputWorkspace=ws_output)
-    for i in range(1, len(ws_list)):
-        Plus(LHSWorkspace=ws_output, RHSWorkspace=ws_list[i],
-             OutputWorkspace=ws_output)
-
-    x = mtd[ws_output].readX(0)
-    if not high_res:
-        Rebin(InputWorkspace=ws_output, OutputWorkspace='__' + ws_output,
-              Params="0,10,%d" % len(x))
-        ws_output = '__' + ws_output
-        x = mtd[ws_output].readX(0)
-    y = mtd[ws_output].readY(0)
-
-    n = []
-    slope_data = []
-    sum = 0.0
-    min_id = 0
-    max_id = 0
-    max_slope = 0
-    min_slope = 0
-    for i in range(len(y)):
-        sum += y[i]
-        n.append(sum)
-        if i > 0:
-            slope_data.append(y[i] - y[i - 1])
-            if slope_data[i - 1] < min_slope:
-                min_slope = slope_data[i - 1]
-                min_id = x[i - 1]
-            if slope_data[i - 1] > max_slope:
-                max_slope = slope_data[i - 1]
-                max_id = x[i - 1]
-
-    sigma = (min_id - max_id) / 2.0
-    mean = (min_id + max_id) / 2.0
-    return mean - 2 * sigma, mean + 2 * sigma
-
-
-def get_logs(instrument, run):
-    sangle = 0
-    dangle = 0
-    dangle0 = 0
-    direct_beam_pix = 0
-    det_distance = 2.562
-
-    ws = "__%s_metadata" % run
-    if instrument == "REFM":
-        ws = '%s_%s' % (ws, 'Off_Off')
-
-    if not mtd.workspaceExists(ws):
-        try:
-            f = FileFinder.findRuns("%s%s" % (instrument, run))[0]
-
-            LoadEventNexus(Filename=f, OutputWorkspace=ws,
-                           NXentryName='entry-Off_Off', MetaDataOnly=True)
-        except:
-            pass
-
-    if mtd.workspaceExists(ws):
-        if mtd[ws].getRun().hasProperty("SANGLE"):
-            sangle = mtd[ws].getRun().getProperty("SANGLE").value[0]
-
-        if mtd[ws].getRun().hasProperty("DANGLE"):
-            dangle = mtd[ws].getRun().getProperty("DANGLE").value[0]
-
-        if mtd[ws].getRun().hasProperty("DANGLE0"):
-            dangle0 = mtd[ws].getRun().getProperty("DANGLE0").value[0]
-
-        if mtd[ws].getRun().hasProperty("DIRPIX"):
-            direct_beam_pix = mtd[ws].getRun().getProperty("DIRPIX").value[0]
-
-        if mtd[ws].getRun().hasProperty("SampleDetDis"):
-            det_distance = mtd[ws].getRun().getProperty("SampleDetDis").value[0] / 1000.0
-
-    return {"SANGLE": sangle,
-            "DANGLE": dangle,
-            "DANGLE0": dangle0,
-            "DIRPIX": direct_beam_pix,
-            "DET_DISTANCE": det_distance}
diff --git a/scripts/reduction/instruments/reflectometer/wks_utility.py b/scripts/reduction/instruments/reflectometer/wks_utility.py
deleted file mode 100644
index c1ec57fb120ec996484ceafd75077812bb3bd583..0000000000000000000000000000000000000000
--- a/scripts/reduction/instruments/reflectometer/wks_utility.py
+++ /dev/null
@@ -1,1999 +0,0 @@
-#pylint: disable=too-many-lines,invalid-name,too-many-arguments, too-many-locals, unused-argument
-from __future__ import (absolute_import, division, print_function)
-from numpy import zeros, arctan2, arange, shape, sqrt, fliplr, asfarray, mean, sum, NAN
-from mantid.simpleapi import *
-import math
-import os.path
-from six.moves import range
-
-h = 6.626e-34 #m^2 kg s^-1
-m = 1.675e-27 #kg
-ref_date = '2014-10-01' #when the detector has been rotated
-
-
-def getSequenceRuns(run_numbers):
-    """
-    This will return the sequence of runs
-    ex:
-        input: 10,11,12
-        output: 10,11,12
-
-        input: 10,13-15
-        output: 10,13,14,15
-    """
-    final_list = []
-    for _run in run_numbers:
-        _run = str(_run)
-        _result = _run.find('-')
-        if _result == -1:
-            final_list.append(_run)
-        else:
-            _split = _run.split('-')
-            start = int(_split[0])
-            end = int(_split[1])
-            _range = arange(end-start+1)+start
-            for _r in _range:
-                final_list.append(_r)
-    return final_list
-
-
-def getProtonCharge(st=None):
-    """
-    Returns the proton charge of the given workspace in picoCoulomb
-    """
-    if st is not None:
-        mt_run = st.getRun()
-        proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value
-#        proton_charge = proton_charge_mtd_unit / 2.77777778e-10
-        return proton_charge_mtd_unit
-    return None
-
-
-def getIndex(value, array):
-    """
-    returns the index where the value has been found
-    """
-#    sz = len(array)
-#    for i in range(sz):
-#        if value == array[i]:
-#            return i
-#    return -1
-    return array.searchsorted(value)
-
-
-def getSh(mt, top_tag, bottom_tag):
-    """
-    returns the height and units of the given slit#
-    """
-    mt_run = mt.getRun()
-    st = mt_run.getProperty(top_tag).value
-    sb = mt_run.getProperty(bottom_tag).value
-    sh = math.fabs(float(sb[0]) - float(st[0]))
-    units = mt_run.getProperty(top_tag).units
-    return sh, units
-
-
-def getSheight(mt, index):
-    """
-    return the DAS hardware slits height of slits # index
-    """
-    mt_run = mt.getRun()
-    if index == 2:
-        isSi = False
-        try:
-            tag = 'SiVHeight'
-            value = mt_run.getProperty(tag).value
-            isSi = True
-        except:
-            tag = 'S2VHeight'
-            value = mt_run.getProperty(tag).value
-        return [isSi, value[0]]
-    else:
-        tag = 'S1VHeight'
-        value = mt_run.getProperty(tag).value
-
-    return value[0]
-
-
-def getS1h(mt=None):
-    """
-    returns the height and units of the slit #1
-    """
-    if mt is not None:
-#        _h, units = getSh(mt, 's1t', 's1b')
-        _h = getSheight(mt, 1)
-        return _h
-    return None
-
-
-def getS2h(mt=None):
-    """
-    returns the height and units of the slit #2
-    """
-    if mt is not None:
-        [isSi, _h] = getSheight(mt, 2)
-        return [isSi,_h]
-    return [False, None]
-
-
-def getSwidth(mt, index):
-    """
-    returns the width and units of the given index slits
-    defined by the DAS hardware
-    """
-    mt_run = mt.getRun()
-    if index==2:
-        isSi = False
-        try:
-            tag = 'SiHWidth'
-            value = mt_run.getProperty(tag).value
-            isSi = True
-        except:
-            tag = 'S2HWidth'
-            value = mt_run.getProperty(tag).value
-        return [isSi, value[0]]
-    else:
-        tag = 'S1HWidth'
-        value = mt_run.getProperty(tag).value
-    return value[0]
-
-
-def getSw(mt, left_tag, right_tag):
-    """
-    returns the width and units of the given slits
-    """
-    mt_run = mt.getRun()
-    sl = mt_run.getProperty(left_tag).value
-    sr = mt_run.getProperty(right_tag).value
-    sw = math.fabs(float(sl[0]) - float(sr[0]))
-    units = mt_run.getProperty(left_tag).units
-    return sw, units
-
-
-def getS1w(mt=None):
-    """
-    returns the width and units of the slit #1
-    """
-    if mt is not None:
-#        _w, units = getSw(mt, 's1l', 's1r')
-        _w = getSwidth(mt, 1)
-        return _w
-    return None
-
-
-def getS2w(mt=None):
-    """
-    returns the width and units of the slit #2
-    """
-    if mt is not None:
-        [isSi, _w] = getSwidth(mt, 2)
-        return [isSi,_w]
-    return [False,None]
-
-
-def getLambdaValue(mt_name):
-    """
-    return the lambdaRequest value
-    """
-    mt_run = mtd[mt_name].getRun()
-    _lambda = mt_run.getProperty('LambdaRequest').value
-    return _lambda
-
-
-def getPixelXPixelY(mt1, maxX=304, maxY=256):
-    """
-    returns the PixelX_vs_PixelY array of the workspace data specified
-    """
-    pixelX_vs_pixelY = zeros((maxY, maxX))
-    for x in range(maxX):
-        for y in range(maxY):
-            _index = maxY * x + y
-            _sum = sum(mt1.readY(_index)[:])
-            pixelX_vs_pixelY[y, x] = _sum
-    return pixelX_vs_pixelY
-
-
-def getPixelXPixelYError(mt1):
-    """
-    returns the PixelX_vs_PixelY_error array of the workspace data specified
-    """
-    pixel_error = zeros((256, 304))
-    for x in range(304):
-        for y in range(256):
-            _index = 256 * x + y
-            _sum = sum(mt1.readE(_index)[:])
-            pixel_error[y, x] = _sum
-    return pixel_error
-
-
-def getPixelXTOF(mt1, maxX=304, maxY=256):
-    """
-    returns the PixelX_vs_TOF array of the workspace data specified
-    """
-    _init = mt1.readY(0)[:]
-    pixelX_vs_tof = zeros((maxY, len(_init)))
-    for x in range(maxX):
-        for y in range(maxY):
-            _index = maxY * x + y
-            _array = mt1.readY(_index)[:]
-            pixelX_vs_tof[y, :] += _array
-    return pixelX_vs_tof
-
-
-def findQaxisMinMax(q_axis):
-    """
-    Find the position of the common Qmin and Qmax in
-    each q array
-    """
-
-    nbr_row = shape(q_axis)[0]
-    nbr_col = shape(q_axis)[1]
-    q_min = min(q_axis[0])
-    q_max = max(q_axis[0])
-
-    for i in arange(nbr_row - 1) + 1:
-        _q_min = q_axis[i][-1]
-        _q_max = q_axis[i][0]
-        if _q_min > q_min:
-            q_min = _q_min
-        if _q_max < q_max:
-            q_max = _q_max
-
-    #find now the index of those min and max in each row
-    _q_axis_min_max_index = zeros((nbr_row, 2))
-    for i in arange(nbr_row):
-        for j in arange(nbr_col - 1):
-            _q = q_axis[i, j]
-            _q_next = q_axis[i, j + 1]
-            if (_q >= q_max) and (_q_next <= q_max):
-                _q_axis_min_max_index[i, 0] = j
-            if (_q >= q_min) and (_q_next <= q_min):
-                _q_axis_min_max_index[i, 1] = j
-
-    return _q_axis_min_max_index
-
-
-def cleanup_data(InputWorkspace=None,
-                 OutputWorkspace=None,
-                 maxY=256):
-    mti = mtd[InputWorkspace]
-    _tof_axis = mti.readX(0)[:]
-    nbr_tof = shape(_tof_axis)[0]-1
-
-    _new_y = zeros((maxY, nbr_tof))
-    _new_e = zeros((maxY, nbr_tof))
-    for px in range(maxY):
-        for tof in range(nbr_tof-1):
-            _y = mti.readY(px)[tof]
-            if _y != 0:
-                _e = mti.readE(px)[tof]
-#                if _y < _e:
-                if _y < 0 or _y < _e:
-                    _y = 0.
-                    _e = 0.
-                _new_y[px,tof] = float(_y)
-                _new_e[px,tof] = float(_e)
-
-    _y_error_axis = _new_e.flatten()
-    _y_axis = _new_y.flatten()
-
-    CreateWorkspace(OutputWorkspace=OutputWorkspace,
-                    DataX=_tof_axis,
-                    DataY=_y_axis,
-                    DataE=_y_error_axis,
-                    Nspec=maxY,
-                    UnitX="TOF",
-                    ParentWorkspace=mti)
-
-
-def createIntegratedWorkspace(mt1,
-                              fromXpixel, toXpixel,
-                              fromYpixel, toYpixel,
-                              maxX=304, maxY=256,
-                              bCleaning=False):
-    """
-    This creates the integrated workspace over the second pixel range (304 here) and
-    returns the new workspace handle
-    """
-
-    _tof_axis = mt1.readX(0)[:]
-
-    _fromXpixel = min([fromXpixel, toXpixel])
-    _toXpixel = max([fromXpixel, toXpixel])
-    fromXpixel = _fromXpixel
-    toXpixel = _toXpixel
-
-    _fromYpixel = min([fromYpixel, toYpixel])
-    _toYpixel = max([fromYpixel, toYpixel])
-    fromYpixel = _fromYpixel
-    toYpixel = _toYpixel
-
-    _y_axis = zeros((maxY, len(_tof_axis) - 1))
-    _y_error_axis = zeros((maxY, len(_tof_axis) - 1))
-
-    x_size = toXpixel - fromXpixel + 1
-    x_range = arange(x_size) + fromXpixel
-
-    y_size = toYpixel - fromYpixel + 1
-    y_range = arange(y_size) + fromYpixel
-
-    for x in x_range:
-        for y in y_range:
-            _index = int((maxY) * x + y)
-            _y_axis[y, :] += mt1.readY(_index)[:]
-            _y_error_axis[y, :] += ((mt1.readE(_index)[:]) * (mt1.readE(_index)[:]))
-
-    _y_axis = _y_axis.flatten()
-    _y_error_axis = sqrt(_y_error_axis)
-    _y_error_axis = _y_error_axis.flatten()
-
-    outputWorkspace = CreateWorkspace(DataX=_tof_axis,
-                                      DataY=_y_axis,
-                                      DataE=_y_error_axis,
-                                      Nspec=maxY,
-                                      UnitX="TOF",
-                                      ParentWorkspace=mt1.name())
-
-    return outputWorkspace
-
-
-def convertWorkspaceToQ(ws_data,
-                        fromYpixel, toYpixel,
-                        maxX=304, maxY=256,
-                        cpix=None,
-                        source_to_detector=None,
-                        sample_to_detector=None,
-                        theta=None,
-                        geo_correction=False,
-                        q_binning=None):
-    """
-    This creates the integrated workspace over the second pixel range (304 here) and
-    returns the new workspace handle
-    """
-
-    mt1 = ws_data
-    _tof_axis = mt1.readX(0)[:]
-    _fromYpixel = min([fromYpixel, toYpixel])
-    _toYpixel = max([fromYpixel, toYpixel])
-    fromYpixel = _fromYpixel
-    toYpixel = _toYpixel
-
-    if geo_correction:
-
-        yrange = arange(toYpixel - fromYpixel + 1) + fromYpixel
-        _q_axis = convertToRvsQWithCorrection(mt1,
-                                              dMD=source_to_detector,
-                                              theta=theta,
-                                              tof=_tof_axis,
-                                              yrange=yrange,
-                                              cpix=cpix)
-
-        #find the common Qmin and Qmax values and their index (position)
-        #in each _q_axis row
-        _q_axis_min_max_index = findQaxisMinMax(_q_axis)
-
-        #replace the _q_axis of the yrange of interest by the new
-        #individual _q_axis
-        y_size = toYpixel - fromYpixel + 1
-        y_range = arange(y_size) + fromYpixel
-
-        _y_axis = zeros((y_size, len(_tof_axis) - 1))
-        _y_error_axis = zeros((y_size, len(_tof_axis) - 1))
-
-        #now determine the y_axis
-        for _q_index in range(y_size):
-
-            _tmp_q_axis = _q_axis[_q_index]
-            q_axis = _tmp_q_axis[::-1] #reverse the axis (now increasing order)
-
-            _a = yrange[_q_index]
-            _y_axis_tmp = list(mt1.readY(int(_a))[:])
-            _y_error_axis_tmp = list(mt1.readE(int(_a))[:])
-
-            #keep only the overlap region of Qs
-            _q_min = _q_axis_min_max_index[_q_index, 0]
-            if _q_min != 0:
-                _y_axis_tmp[0:_q_min] = 0
-                _y_error_axis_tmp[0:_q_min] = 0
-
-            _q_max = int(_q_axis_min_max_index[_q_index, 1])
-            sz = shape(_y_axis_tmp)[0]
-            if _q_max != sz:
-                _index_q_max_range = arange(sz - _q_max) + _q_max
-                for i in _index_q_max_range:
-                    _y_axis_tmp[i] = 0
-                    _y_error_axis_tmp[i] = 0
-
-            _y_axis[_q_index, :] = _y_axis_tmp[::-1]
-            _y_error_axis[_q_index, :] = _y_error_axis_tmp[::-1]
-
-        x_axis = q_axis.flatten()
-        y_axis = _y_axis.flatten()
-        y_error_axis = _y_error_axis.flatten()
-
-        outputWorkspace = CreateWorkspace(DataX=x_axis,
-                                          DataY=y_axis,
-                                          DataE=y_error_axis,
-                                          Nspec=int(y_size),
-                                          UnitX="MomentumTransfer",
-                                          ParentWorkspace=mt1.name())
-
-        outputWorkspace.setDistribution(True)
-
-        outputWorkspace = Rebin(InputWorkspace=outputWorkspace,
-                                Params=q_binning)
-
-    else:
-
-        if source_to_detector is not None and theta is not None:
-            _const = float(4) * math.pi * m * source_to_detector / h
-            _q_axis = 1e-10 * _const * math.sin(theta) / (_tof_axis * 1e-6)
-        else:
-            _q_axis = _tof_axis
-            print('should not reach this condition !')
-
-        y_size = toYpixel - fromYpixel + 1
-        y_range = arange(y_size) + fromYpixel
-
-        _y_axis = zeros((y_size, len(_q_axis) -1 ))
-        _y_error_axis = zeros((y_size, len(_q_axis) - 1))
-
-        for y in range(y_size):
-
-            a = y_range[y]
-
-            _tmp_y_axis = mt1.readY(int(a))[:]
-            _y_axis[int(y), :] = _tmp_y_axis
-            _tmp_y_error_axis = mt1.readE(int(a))[:]
-            _y_error_axis[int(y),:] = _tmp_y_error_axis
-
-        _x_axis = _q_axis.flatten()
-        _y_axis = _y_axis.flatten()
-        _y_error_axis = _y_error_axis.flatten()
-
-        # reverse order
-        _x_axis = _x_axis[::-1]
-        _y_axis = _y_axis[::-1]
-        _y_error_axis = _y_error_axis[::-1]
-
-        outputWorkspace = CreateWorkspace(DataX=_x_axis,
-                                          DataY=_y_axis,
-                                          DataE=_y_error_axis,
-                                          Nspec=int(y_size),
-                                          UnitX="MomentumTransfer",
-                                          ParentWorkspace=mt1.name())
-
-        outputWorkspace.setDistribution(True)
-
-        outputWorkspace = Rebin(InputWorkspace=outputWorkspace,
-                                Params=q_binning)
-
-    return outputWorkspace
-
-
-def create_grouping(workspace=None, xmin=0, xmax=None, filename=".refl_grouping.xml"):
-    # This should be read from the
-    npix_x = 304
-    npix_y = 256
-    if workspace is not None:
-        if mtd[workspace].getInstrument().hasParameter("number-of-x-pixels"):
-            npix_x = int(mtd[workspace].getInstrument().getNumberParameter("number-of-x-pixels")[0])
-        if mtd[workspace].getInstrument().hasParameter("number-of-y-pixels"):
-            npix_y = int(mtd[workspace].getInstrument().getNumberParameter("number-of-y-pixels")[0])
-
-    f = open(filename, 'w')
-    f.write("<detector-grouping description=\"Integrated over X\">\n")
-
-    if xmax is None:
-        xmax = npix_x
-
-    for y in range(npix_y):
-        # index = max_y * x + y
-        indices = []
-        for x in range(xmin, xmax + 1):
-            indices.append(str(npix_y * x + y))
-
-        # Detector IDs start at zero, but spectrum numbers start at 1
-        # Grouping works on spectrum numbers
-        indices_str = ','.join(indices)
-        f.write("  <group name='%d'>\n" % y)
-        f.write("    <ids val='%s'/>\n" % indices_str)
-        f.write("  </group>\n")
-
-    f.write("</detector-grouping>\n")
-    f.close()
-
-
-def angleUnitConversion(value, from_units='degree', to_units='rad'):
-    """
-    This function converts the angle units
-    """
-
-    if from_units == to_units:
-        return value
-
-    from_factor = 1.0
-    #convert everything into rad
-    if from_units == 'degree':
-        from_factor = 1.745329252e-2
-    value_rad = from_factor * value
-
-    if to_units == 'rad':
-        return value_rad
-    else:
-        to_factor = 57.2957795
-        return to_factor * value_rad
-
-
-def convertToThetaVsLambda(_tof_axis,
-                           _pixel_axis,
-                           central_pixel,
-                           pixel_size=0.0007,
-                           theta= -1,
-                           dSD= -1,
-                           dMD= -1):
-    """
-    This function converts the pixel/tof array
-    to theta/lambda
-    """
-    # h = 6.626e-34 #m^2 kg s^-1
-    # m = 1.675e-27 #kg
-
-    #convert tof_axis into seconds
-    _tof_axis = _tof_axis * 1e-6
-
-    vel_array = dMD / _tof_axis         #mm/ms = m/s
-    _lambda = h / (m * vel_array)  #m
-    _lambda = _lambda * 1e10  #angstroms
-
-    d_vec = (_pixel_axis - central_pixel) * pixel_size
-    theta_vec = arctan2(d_vec, dSD) + theta
-
-    dico = {'lambda_vec': _lambda, 'theta_vec': theta_vec}
-
-    return dico
-
-
-def convertToRvsQWithCorrection(mt, dMD= -1, theta= -1.0, tof=None, yrange=None, cpix=None):
-    """
-    This function converts the pixel/TOF array to the R(Q) array
-    using Q = (4.Pi.Mn)/h  *  L.sin(theta/2)/TOF
-    with    L: distance central_pixel->source
-            TOF: TOF of pixel
-            theta: angle of detector
-    """
-
-    # h = 6.626e-34 #m^2 kg s^-1
-    # m = 1.675e-27 #kg
-
-    sample = mt.getInstrument().getSample()
-
-    maxY = 256
-
-    dPS_array = zeros(maxY)
-    for y in range(maxY):
-        detector = mt.getDetector(y)
-        dPS_array[y] = sample.getDistance(detector)
-
-    #distance sample->center of detector
-    dSD = dPS_array[maxY / 2]
-
-    _const = float(4) * math.pi * m * dMD / h
-    sz_tof = len(tof)
-    q_array = zeros((len(yrange), sz_tof - 1))
-
-    for _px in range(len(yrange)):
-        dangle = ref_beamdiv_correct(cpix, mt, dSD, _px)
-
-        if dangle is not None:
-            _theta = theta + dangle
-        else:
-            _theta = theta
-
-        for t in range(sz_tof - 1):
-            tof1 = tof[t]
-            tof2 = tof[t+1]
-            tofm = (tof1+tof2)/2.
-            _Q = _const * math.sin(_theta) / (tofm*1e-6)
-            q_array[_px, t] = _Q * 1e-10
-
-    return q_array
-
-
-def getQHisto(source_to_detector, theta, tof_array):
-    _const = float(4) * math.pi * m * source_to_detector / h
-    sz_tof = len(tof_array)
-    q_array = zeros(sz_tof)
-    for t in range(sz_tof):
-        _Q = _const * math.sin(theta) / (tof_array[t] * 1e-6)
-        q_array[t] = _Q * 1e-10
-
-    return q_array
-
-
-def ref_beamdiv_correct(cpix, det_secondary,
-                        pixel_index,
-                        pixel_width = 0.0007,
-                        first_slit_size = None,
-                        last_slit_size = None):
-    """
-    This function calculates the acceptance diagram, determines pixel overlap
-    and computes the offset to the scattering angle.
-    """
-
-    # This is currently set to the same number for both REF_L and REF_M
-    epsilon = 0.5 * 1.3 * 1.0e-3
-
-    # Set the center pixel
-    if cpix is None:
-        cpix = 133.5
-
-#     first_slit_size = getSheight(mt, '1')
-#     last_slit_size = getSheight(mt,'2')
-
-    last_slit_dist = 0.654 #m
-    slit_dist = 0.885000050068 #m
-
-    first_slit_size = float(first_slit_size) * 0.001
-    last_slit_size = float(last_slit_size) * 0.001
-
-    _y = 0.5 * (first_slit_size + last_slit_size)
-    _x = slit_dist
-    gamma_plus = math.atan2(_y, _x)
-
-    _y = 0.5 * (first_slit_size - last_slit_size)
-    _x = slit_dist
-    gamma_minus = math.atan2(_y, _x)
-
-    half_last_aperture = 0.5 * last_slit_size
-    neg_half_last_aperture = -1.0 * half_last_aperture
-
-    last_slit_to_det = last_slit_dist + det_secondary
-    dist_last_aper_det_sin_gamma_plus = last_slit_to_det * math.sin(gamma_plus)
-    dist_last_aper_det_sin_gamma_minus = last_slit_to_det * math.sin(gamma_minus)
-
-    #set the delta theta coordinates of the acceptance polygon
-    accept_poly_x = []
-    accept_poly_x.append(-1.0 * gamma_minus)
-    accept_poly_x.append(gamma_plus)
-    accept_poly_x.append(gamma_plus)
-    accept_poly_x.append(gamma_minus)
-    accept_poly_x.append(-1.0 * gamma_plus)
-    accept_poly_x.append(-1.0 * gamma_plus)
-    accept_poly_x.append(accept_poly_x[0])
-
-    #set the z coordinates of the acceptance polygon
-    accept_poly_y = []
-    accept_poly_y.append(half_last_aperture - dist_last_aper_det_sin_gamma_minus + epsilon)
-    accept_poly_y.append(half_last_aperture + dist_last_aper_det_sin_gamma_plus + epsilon)
-    accept_poly_y.append(half_last_aperture + dist_last_aper_det_sin_gamma_plus - epsilon)
-    accept_poly_y.append(neg_half_last_aperture + dist_last_aper_det_sin_gamma_minus - epsilon)
-    accept_poly_y.append(neg_half_last_aperture - dist_last_aper_det_sin_gamma_plus - epsilon)
-    accept_poly_y.append(neg_half_last_aperture - dist_last_aper_det_sin_gamma_plus + epsilon)
-    accept_poly_y.append(accept_poly_y[0])
-
-    cur_index = pixel_index
-
-    #set the z band for the pixel
-    xMinus = (cur_index - cpix - 0.5) * pixel_width
-    xPlus = (cur_index - cpix + 0.5) * pixel_width
-
-    #calculate the intersection
-    yLeftCross = -1
-    yRightCross = -1
-
-    xI = accept_poly_x[0]
-    yI = accept_poly_y[0]
-
-    int_poly_x = []
-    int_poly_y = []
-
-    for i in range(len(accept_poly_x)):
-
-        xF = accept_poly_y[i]
-        yF = accept_poly_x[i]
-
-        if xI < xF:
-
-            if xI < xMinus and xF > xMinus:
-                yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI)
-                int_poly_x.append(yLeftCross)
-                int_poly_y.append(xMinus)
-
-            if xI < xPlus and xF >= xPlus:
-                yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI)
-                int_poly_x.append(yRightCross)
-                int_poly_y.append(xPlus)
-
-        else:
-
-            if xF < xPlus and xI >= xPlus:
-                yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI)
-                int_poly_x.append(yRightCross)
-                int_poly_y.append(xPlus)
-
-            if xF < xMinus and xI >= xMinus:
-                yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI)
-                int_poly_x.append(yLeftCross)
-                int_poly_y.append(xMinus)
-
-        #This catches points on the polygon inside the range of interest
-        if xF >= xMinus and xF < xPlus:
-            int_poly_x.append(yF)
-            int_poly_y.append(xF)
-
-        xI = xF
-        yI = yF
-
-    if len(int_poly_x) > 2:
-        int_poly_x.append(int_poly_x[0])
-        int_poly_y.append(int_poly_y[0])
-        int_poly_x.append(int_poly_x[1])
-        int_poly_y.append(int_poly_y[1])
-    else:
-        #Intersection polygon is null, point or line, so has no area
-        #therefore there is no angle corrction
-        return None
-
-    #Calculate intersection polygon area
-    area = calc_area_2D_polygon(int_poly_x,
-                                int_poly_y,
-                                len(int_poly_x) - 2)
-
-    center_of_mass = calc_center_of_mass(int_poly_x,
-                                         int_poly_y,
-                                         area)
-
-    return center_of_mass
-
-
-def calc_area_2D_polygon(x_coord, y_coord, size_poly):
-    """
-    Calculation of the area defined by the 2D polygon
-    """
-    _range = arange(size_poly) + 1
-    area = 0
-    for i in _range:
-        area += (x_coord[i] * (y_coord[i + 1] - y_coord[i - 1]))
-    return area / 2.
-
-
-def calc_center_of_mass(arr_x, arr_y, A):
-    """
-    Function that calculates the center-of-mass for the given polygon
-
-    @param arr_x: The array of polygon x coordinates
-    @param arr_y: The array of polygon y coordinates
-    @param A: The signed area of the polygon
-
-    @return: The polygon center-of-mass
-    """
-
-    center_of_mass = 0.0
-    SIXTH = 1. / 6.
-    for j in arange(len(arr_x) - 2):
-        center_of_mass += (arr_x[j] + arr_x[j + 1]) \
-                * ((arr_x[j] * arr_y[j + 1]) -
-                   (arr_x[j + 1] * arr_y[j]))
-
-    if A != 0.0:
-        return (SIXTH * center_of_mass) / A
-    else:
-        return 0.0
-
-
-def getFieldValue(table, row, column):
-    _tag_value = table[row][column]
-    _tag_value_split = _tag_value.split('=')
-    return _tag_value_split[1]
-
-
-def isWithinPrecisionRange(value_file, value_run, precision):
-    diff = abs(float(value_file)) - abs(float(value_run))
-    if abs(diff) <= precision:
-        return True
-    else:
-        return False
-
-
-def _applySFtoArray(workspace, a, b, a_error, b_error):
-    """
-    This function will create for each x-axis value the corresponding
-    scaling factor using the formula y=a+bx and
-    """
-
-    mt = mtd[workspace]
-    x_axis = mt.readX(0)[:]
-    sz = len(x_axis)
-    x_axis_factors = zeros(sz)
-    x_axis_factors_error = zeros(sz)
-    for i in range(sz):
-        _x_value = float(x_axis[i])
-        _factor = _x_value * b + a
-        x_axis_factors[i] = _factor
-        _factor_error = _x_value * b_error + a_error
-        x_axis_factors_error[i] = _factor_error
-
-    #create workspace
-    CreateWorkspace(OutputWorkspace='sfWorkspace',
-                    DataX=x_axis,
-                    DataY=x_axis_factors,
-                    DataE=x_axis_factors_error,
-                    Nspec=1,
-                    UnitX="TOF")
-
-    Divide(workspace, 'sfWorkspace', workspace)
-
-    return workspace
-
-
-def loadNeXus(runNumbers, type):
-    """
-    will retrieve the data from the runNumbers specify and will
-    add them or just return the workspace created
-    """
-
-    wks_name = ''
-    if type == 'data':
-        wks_name = 'ws_event_data'
-    else:
-        wks_name = 'ws_event_norm'
-
-    print('-> loading ', type)
-    if (type == 'data') and len(runNumbers) > 1:
-
-        _list = []
-        for _run in runNumbers:
-            _list.append(str(_run))
-        list_run = ','.join(_list)
-        print('--> working with runs:', str(list_run))
-
-        _index = 0
-        for _run in runNumbers:
-
-        # Find full path to event NeXus data file
-            try:
-                data_file = FileFinder.findRuns("REF_L%d" %_run)[0]
-            except RuntimeError:
-                msg = "RefLReduction: could not find run %d\n" % _run
-                msg += "Add your data folder to your User Data Directories in the File menu"
-                raise RuntimeError(msg)
-
-            if _index == 0:
-                ws_event_data = LoadEventNexus(Filename=data_file,OutputWorskpace=wks_name)
-                _index += 1
-            else:
-                tmp = LoadEventNexus(Filename=data_file)
-                Plus(LHSWorkspace=ws_event_data,
-                     RHSWorkspace=tmp,
-                     OutputWorkspace=wks_name)
-                DeleteWorkspace(tmp)
-    else:
-
-        print('--> Working with run: ' + str(runNumbers))
-
-        try:
-            data_file = FileFinder.findRuns("REF_L%d" %runNumbers)[0]
-        except RuntimeError:
-            msg = "RefLReduction: could not find run %d\n" %runNumbers[0]
-            msg += "Add your data folder to your User Data Directories in the File menu"
-            raise RuntimeError(msg)
-
-        ws_event_data = LoadEventNexus(Filename=data_file, OutputWorkspace=wks_name)
-
-    return ws_event_data
-
-
-def rebinNeXus(inputWorkspace, params, type):
-    """
-    will rebin the event workspace according to the params
-    params[0]: min value
-    params[1]: bin size
-    params[2]: max value
-    """
-    print('--> rebin ', type)
-    ws_histo_data = Rebin(InputWorkspace=inputWorkspace,
-                          Params=params,
-                          PreserveEvents=True)
-    return ws_histo_data
-
-
-def cropTOF(inputWorkspace, min, max, type):
-    """
-    will crop the nexus (workspace) using min and max value
-    used here to crop the TOF range
-    """
-    print('--> crop ' , type , ' workspace in TOF')
-    ws_histo_data = CropWorkspace(InputWorkspace = inputWorkspace,
-                                  XMin = min,
-                                  XMax = max)
-    return ws_histo_data
-
-
-def normalizeNeXus(inputWorkspace, type):
-    """
-    normalize nexus by proton charge
-    """
-    print('--> normalize ', type)
-    ws_histo_data = NormaliseByCurrent(InputWorkspace=inputWorkspace)
-    return ws_histo_data
-
-
-def integrateOverLowResRange(mt1,
-                             dataLowResRange,
-                             type,
-                             is_nexus_detector_rotated_flag):
-    """
-        This creates the integrated workspace over the low resolution range leaving
-        us with a [256,nbr TOF] workspace
-        returns the new workspace handle
-        BUT this algorithm also makes sure that the error value is 1 when counts
-        is 0 !
-    """
-
-    print('--> integrated over low res range of ', type)
-    _tof_axis = mt1.readX(0)[:].copy()
-#     t_range = arange(nbr_tof-1)
-
-    # -1 to work with index directly
-    fromXpixel = min(dataLowResRange) - 1
-    toXpixel = max(dataLowResRange) - 1
-
-    if is_nexus_detector_rotated_flag:
-        sz_y_axis = 304
-    else:
-        sz_y_axis = 256
-
-    _y_axis = zeros((sz_y_axis, len(_tof_axis) - 1))
-    _y_error_axis = zeros((sz_y_axis, len(_tof_axis) - 1))
-
-    x_size = toXpixel - fromXpixel + 1
-    x_range = arange(x_size) + fromXpixel
-
-    y_range = arange(sz_y_axis)
-
-    for x in x_range:
-        for y in y_range:
-            _index = int((sz_y_axis) * x + y)
-            _y_axis[y, :] += mt1.readY(_index)[:].copy()
-            _tmp_error_axis = mt1.readE(_index)[:].copy()
-            # 0 -> 1
-#             index_where_0 = where(_tmp_error_axis == 0)
-#             _tmp_error_axis[index_where_0] = 1
-
-            _y_error_axis[y, :] += _tmp_error_axis * _tmp_error_axis
-#             _y_error_axis[y, :] += ((mt1.readE(_index)[:]) * (mt1.readE(_index)[:]))
-
-    _y_error_axis = sqrt(_y_error_axis)
-
-    return [_tof_axis, _y_axis, _y_error_axis]
-
-
-def substractBackground(tof_axis, y_axis, y_error_axis,
-                        peakRange, backFlag, backRange,
-                        error_0, type):
-    """
-    shape of y_axis : [sz_y_axis, nbr_tof]
-    This routine will calculate the background, remove it from the peak
-    and will return only the range of peak  -> [peak_size, nbr_tof]
-
-    """
-
-    # give a friendly name to peak and back ranges
-    # -1 because we are working with 0 index arrays
-    peakMin = peakRange[0]-1
-    peakMax = peakRange[1]-1
-    backMin = backRange[0]-1
-    backMax = backRange[1]-1
-
-    if not backFlag:
-        print('---> no ', type, ' background requested!')
-        return [y_axis[peakMin:peakMax+1,:], y_error_axis[peakMin:peakMax+1,:]]
-
-    print('--> background subtraction of ', type)
-
-    # retrieve data
-    _tofAxis = tof_axis
-    nbrTof = len(_tofAxis)
-
-    # size peak
-    szPeak = peakMax - peakMin + 1
-
-    # init arrays
-    final_y_axis = zeros((szPeak, nbrTof))
-    final_y_error_axis = zeros((szPeak, nbrTof))
-
-#    final_y_axis = empty((szPeak, nbrTof))
-#    final_y_error_axis = empty((szPeak, nbrTof))
-#    final_y_axis[:] = NAN
-#    final_y_error_axis[:] = NAN
-
-    for t in range(nbrTof):
-
-        # by default, no space for background subtraction below and above peak
-        bMinBack = False
-        bMaxBack = False
-
-        if backMin < (peakMin):
-            bMinBack = True
-            _backMinArray = y_axis[backMin:peakMin, t]
-            _backMinErrorArray = y_error_axis[backMin:peakMin, t]
-            [_backMin, _backMinError] = weightedMean(_backMinArray,
-                                                     _backMinErrorArray, error_0)
-
-        if (peakMax) < backMax:
-            bMaxBack = True
-            _backMaxArray = y_axis[peakMax+1:backMax+1, t]
-            _backMaxErrorArray = y_error_axis[peakMax+1:backMax+1, t]
-            [_backMax, _backMaxError] = weightedMean(_backMaxArray, _backMaxErrorArray, error_0)
-
-        # if no max background use min background
-        if not bMaxBack:
-            background = _backMin
-            background_error = _backMinError
-
-        # if no min background use max background
-        if not bMinBack:
-            background = _backMax
-            background_error = _backMaxError
-
-        if bMinBack and bMaxBack:
-            [background, background_error] = weightedMean([_backMin, _backMax], [_backMinError, _backMaxError], error_0)
-
-        # remove background for each pixel of the peak
-        for x in range(szPeak):
-            final_y_axis[x,t] = float(y_axis[peakMin + x,t]) - float(background)
-            final_y_error_axis[x,t] = float(math.sqrt(pow(y_error_axis[peakMin+x,t],2) + pow(background_error,2)))
-
-#         if t == nbrTof-2:
-#             print(float(y_axis[peakMin + x,t]) - float(background))
-
-    return [final_y_axis, final_y_error_axis]
-
-
-def weightedMean(data_array, error_array, error_0):
-
-    sz = len(data_array)
-
-    # calculate the numerator of mean
-    dataNum = 0
-    for i in range(sz):
-        if error_array[i] == 0:
-            error_array[i] = error_0
-
-        tmpFactor = float(data_array[i]) / float((pow(error_array[i],2)))
-        dataNum += tmpFactor
-
-    # calculate denominator
-    dataDen = 0
-    for i in range(sz):
-        if error_array[i] == 0:
-            error_array[i] = error_0
-        tmpFactor = 1./float((pow(error_array[i],2)))
-        dataDen += tmpFactor
-
-    if dataDen == 0:
-        data_mean = NAN
-        mean_error = NAN
-    else:
-        data_mean = float(dataNum) / float(dataDen)
-        mean_error = math.sqrt(1/dataDen)
-
-    return [data_mean, mean_error]
-
-
-def weightedMeanOfRange(norm_y_axis, norm_y_error_axis):
-    """
-    will calculate the weighted Mean of the region given
-    """
-
-    # get nbr tof
-    dim = norm_y_axis.shape
-    nbr_tof = dim[1]
-
-    final_array = zeros(nbr_tof)
-    final_array_error = zeros(nbr_tof)
-
-    for t in range(nbr_tof):
-        _tmp_range = norm_y_axis[:, t]
-        _tmp_range_error = norm_y_error_axis[:,t]
-        [_mean,_mean_error] = weightedMean(_tmp_range, _tmp_range_error)
-        final_array[t] = _mean
-        final_array_error[t] = _mean_error
-
-    return [final_array, final_array_error]
-
-
-def meanOfRange(norm_y_axis, norm_y_error_axis):
-    """
-    will calculate the mean of range
-    """
-
-    # get nbr tof
-    dim = norm_y_axis.shape
-    nbr_tof = dim[1]
-
-    final_array = zeros(nbr_tof)
-    final_array_error = zeros(nbr_tof)
-
-    for t in range(nbr_tof):
-        _tmp_range = norm_y_axis[:,t]
-        _tmp_range_error = norm_y_error_axis[:,t]
-        [_mean,_mean_error] = myMean(_tmp_range, _tmp_range_error)
-        final_array[t] = _mean
-        final_array_error[t] = _mean_error
-
-    return [final_array, final_array_error]
-
-
-def myMean(data_array, error_array):
-
-    sz=size(data_array)
-
-    _mean = mean(data_array)
-    _mean_error = sqrt(sum(_mean*_mean))/float(sz[0])
-
-    return [_mean, _mean_error]
-
-
-def divideDataByNormalization(data_y_axis,
-                              data_y_error_axis,
-                              av_norm,
-                              av_norm_error):
-
-    print('-> divide data by normalization')
-
-    data_size = data_y_axis.shape
-    nbr_pixel = data_size[0]
-    nbr_tof = data_size[1]
-
-    new_data_y_axis = zeros((nbr_pixel, nbr_tof))
-    new_data_y_error_axis = zeros((nbr_pixel, nbr_tof))
-
-    for t in range(nbr_tof):
-        for x in range(nbr_pixel):
-
-            if (av_norm[t] != 0) and (data_y_axis[x, t] != 0):
-
-                tmp_value = float(data_y_axis[x,t]) / float(av_norm[t])
-
-                tmp_error_1 = pow(float(data_y_error_axis[x,t]) / float(data_y_axis[x,t]),2)
-                tmp_error_2 = pow(float(av_norm_error[t]) / float(av_norm[t]),2)
-                tmp_error = sqrt(tmp_error_1 + tmp_error_2) * abs(float(data_y_axis[x,t]) / float(av_norm[t]))
-
-                new_data_y_axis[x,t] = tmp_value
-                new_data_y_error_axis[x,t] = tmp_error
-
-    return [new_data_y_axis, new_data_y_error_axis]
-
-
-def sumWithError(value, error):
-    """ will sume the array of values and will return the sum and the
-    error that goes with it
-    """
-
-    sum_value = sum(value)
-
-    tmp_sum_error = 0
-    for i in range(len(value)):
-        tmp_value = pow(error[i],2)
-        tmp_sum_error += tmp_value
-
-    sum_error = math.sqrt(tmp_sum_error)
-
-    return [sum_value, sum_error]
-
-
-def integratedOverPixelDim(data_y_axis, data_y_error_axis):
-
-    size = data_y_axis.shape
-    nbr_tof = size[1]
-
-    final_data = zeros(nbr_tof)
-    final_data_error = zeros(nbr_tof)
-    for t in range(nbr_tof):
-        [data, error] = sumWithError(data_y_axis[:,t], data_y_error_axis[:,t])
-        final_data[t] = data
-        final_data_error[t] = error
-
-    return [final_data, final_data_error]
-
-
-def fullSumWithError(data_y_axis, data_y_error_axis):
-    size = data_y_axis.shape
-    nbr_tof = size[1]
-
-    final_data = zeros(nbr_tof)
-    final_data_error = zeros(nbr_tof)
-#    final_data = empty(nbr_tof)
-#    final_data_error = empty(nbr_tof)
-#    final_data[:] = NAN
-#    final_data_error[:] = NAN
-    for t in range(nbr_tof):
-        [data, error] = sumWithError(data_y_axis[:,t], data_y_error_axis[:,t])
-        final_data[t] = data
-        final_data_error[t] = error
-
-    return [final_data, final_data_error]
-
-
-def ouput_ascii_file(file_name,
-                     x_axis,
-                     y_axis,
-                     y_error_axis):
-
-    f=open(file_name,'w')
-
-    sz_x_axis = len(x_axis)
-    for i in range(sz_x_axis-1):
-        f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n")
-
-    f.close()
-
-
-def ouput_big_ascii_file(file_name,
-                         x_axis,
-                         y_axis,
-                         y_error_axis):
-
-    f=open(file_name,'w')
-
-    sz = y_axis.shape # (nbr_pixel, nbr_tof)
-    nbr_tof = sz[1]
-    nbr_pixel = sz[0]
-
-    for t in range(nbr_tof):
-        _tmp_str = str(x_axis[t])
-        for x in range(nbr_pixel):
-            _tmp_str += ' ,' + str(y_axis[x,t]) + " ," + str(y_error_axis[x,t])
-
-        _tmp_str += '\n'
-        f.write(_tmp_str)
-
-    f.close()
-
-
-def ouput_big_Q_ascii_file(file_name,
-                           x_axis,
-                           y_axis,
-                           y_error_axis):
-
-    f=open(file_name,'w')
-
-    sz = y_axis.shape # (nbr_pixel, nbr_tof)
-    nbr_tof = sz[1]
-    nbr_pixel = sz[0]
-
-    for t in range(nbr_tof):
-        _tmp_str = ''
-        for x in range(nbr_pixel):
-            _tmp_str += str(x_axis[x,t]) +  ',' + str(y_axis[x,t]) + " ," + str(y_error_axis[x,t]) + ',,'
-        _tmp_str += '\n'
-        f.write(_tmp_str)
-
-    f.close()
-
-
-def divideData1DbyNormalization(inte_data_y_axis,
-                                inte_data_y_error_axis,
-                                av_norm,
-                                av_norm_error):
-
-    print('-> divide data by normalization')
-
-    nbrPixel = inte_data_y_axis.shape
-
-    final_data = zeros(nbrPixel)
-    final_data_error = zeros(nbrPixel)
-
-    for x in range(nbrPixel[0]):
-        if av_norm[x] != 0:
-
-            final_data[x] = inte_data_y_axis[x] / av_norm[x]
-
-            tmp1 = pow(float(inte_data_y_error_axis[x]) / float(inte_data_y_axis[x]),2)
-            tmp2 = pow(float(av_norm_error[x]) / float(av_norm[x]),2)
-            tmp_error = sqrt(tmp1 + tmp2) * (float(inte_data_y_axis[x] / av_norm[x]))
-
-            final_data_error[x] = tmp_error
-
-    return [final_data, final_data_error]
-
-
-def applyScalingFactor(tof_axis,
-                       y_data,
-                       y_data_error,
-                       incident_medium,
-                       sf_file,
-                       valuePrecision,
-                       slitsWidthFlag):
-    """"
-    function that apply scaling factor to data using sfCalculator.txt
-    file created by the sfCalculator procedure
-    """
-    isSFfound = False
-
-    #sf_file = 'NaN'
-    if os.path.isfile(sf_file):
-
-        print('-> scaling factor file FOUND! (', sf_file, ')')
-
-        #parse file and put info into array
-        f = open(sf_file, 'r')
-        sfFactorTable = []
-        for line in f.read().split('\n'):
-            if len(line) > 0 and line[0] != '#':
-                sfFactorTable.append(line.split(' '))
-        f.close()
-
-        sz_table = shape(sfFactorTable)
-        nbr_row = sz_table[0]
-
-        _incidentMedium = incident_medium.strip()
-
-        _lr = getLambdaValue('ws_event_data')
-        _lr_value = _lr[0]
-        _lr_value = float("{0:.2f}".format(_lr_value))
-
-        #retrieve s1h and s2h or sih values
-        s1h = getS1h(mtd['ws_event_data'])
-        [isSih, s2h] = getS2h(mtd['ws_event_data'])
-
-        s1h_value = abs(s1h)
-        s2h_value = abs(s2h)
-
-        #retrieve s1w and s2w values
-        s1w = getS1w(mtd['ws_event_data'])
-        [isSiw, s2w] = getS2w(mtd['ws_event_data'])
-
-        s1w_value = abs(s1w)
-        s2w_value = abs(s2w)
-
-        print('--> Data Lambda Requested: {0:2f}'.format(_lr_value))
-        print('--> Data S1H: {0:2f}'.format(s1h_value))
-        if isSih:
-            print('--> Data SiH: {0:2f}'.format(s2h_value))
-        else:
-            print('--> Data S2H: {0:2f}'.format(s2h_value))
-        print('--> Data S1W: {0:2f}'.format(s1w_value))
-        if isSiw:
-            print('--> Data SiW: {0:2f}'.format(s2w_value))
-        else:
-            print('--> Data S2W: {0:2f}'.format(s2w_value))
-
-        for i in range(nbr_row):
-
-            _file_incidentMedium = getFieldValue(sfFactorTable,i,0)
-            if _file_incidentMedium.strip() == _incidentMedium.strip():
-                print('*** incident medium match ***')
-                _file_lambdaRequested = getFieldValue(sfFactorTable,i,1)
-                if (isWithinPrecisionRange(_file_lambdaRequested,
-                                           _lr_value,
-                                           valuePrecision)):
-                    print('*** lambda requested match ***')
-                    _file_s1h = getFieldValue(sfFactorTable,i,2)
-                    if(isWithinPrecisionRange(_file_s1h,
-                                              s1h_value,
-                                              valuePrecision)):
-                        print('*** s1h match ***')
-                        _file_s2h = getFieldValue(sfFactorTable,i,3)
-                        if(isWithinPrecisionRange(_file_s2h,
-                                                  s2h_value,
-                                                  valuePrecision)):
-                            print('*** s2h match ***')
-                            if slitsWidthFlag:
-                                print('*** (with slits width flag) ***')
-                                _file_s1w = getFieldValue(sfFactorTable,i,4)
-                                if(isWithinPrecisionRange(_file_s1w,
-                                                          s1w_value,
-                                                          valuePrecision)):
-                                    print('*** s1w match ***')
-                                    _file_s2w = getFieldValue(sfFactorTable,i,5)
-                                    if(isWithinPrecisionRange(_file_s2w,
-                                                              s2w_value,
-                                                              valuePrecision)):
-                                        print('*** s2w match ***')
-
-                                        print('--> Found a perfect match')
-                                        a = float(getFieldValue(sfFactorTable,i,6))
-                                        b = float(getFieldValue(sfFactorTable,i,7))
-                                        a_error = float(getFieldValue(sfFactorTable,i,8))
-                                        b_error = float(getFieldValue(sfFactorTable,i,9))
-
-                                        [y_data, y_data_error] = applyScalingFactorToArray(tof_axis,
-                                                                                           y_data,
-                                                                                           y_data_error,
-                                                                                           a, b,
-                                                                                           a_error, b_error)
-
-                                        return [tof_axis, y_data, y_data_error, True]
-
-                            else:
-
-                                print('--> Found a perfect match')
-                                a = float(getFieldValue(sfFactorTable,i,6))
-                                b = float(getFieldValue(sfFactorTable,i,7))
-                                a_error = float(getFieldValue(sfFactorTable,i,8))
-                                b_error = float(getFieldValue(sfFactorTable,i,9))
-
-                                [y_data, y_data_error] = applyScalingFactorToArray(tof_axis,
-                                                                                   y_data,
-                                                                                   y_data_error,
-                                                                                   a, b,
-                                                                                   a_error, b_error)
-                                isSFfound = True
-
-        return [tof_axis, y_data, y_data_error, isSFfound]
-
-    else:
-
-        print('-> scaling factor file for requested lambda NOT FOUND!')
-        return [tof_axis, y_data, y_data_error]
-
-
-def applyScalingFactorToArray(tof_axis, y_data, y_data_error, a, b, a_error, b_error):
-    """
-    This function will create for each x-axis value the corresponding
-    scaling factor using the formula y=a+bx and
-    """
-
-    x_axis = tof_axis
-    nbr_tof = len(x_axis)-1
-    x_axis_factors = zeros(nbr_tof)
-    x_axis_factors_error = zeros(nbr_tof)
-#    x_axis_factors = empty(nbr_tof)
-#    x_axis_factors_error = empty(nbr_tof)
-#    x_axis_factors[:] = NAN
-#    x_axis_factors_error[:] = NAN
-    for i in range(nbr_tof):
-        _x_value = float(x_axis[i])
-        _factor = _x_value * b + a
-        x_axis_factors[i] = _factor
-        _factor_error = _x_value * b_error + a_error
-        x_axis_factors_error[i] = _factor_error
-
-    sz = y_data.shape
-    nbr_pixel = sz[0]
-
-    final_y_data = zeros((nbr_pixel, nbr_tof))
-    final_y_data_error = zeros((nbr_pixel, nbr_tof))
-#    final_y_data = empty((nbr_pixel, nbr_tof))
-#    final_y_data_error = empty((nbr_pixel, nbr_tof))
-#    final_y_data[:] = NAN
-#    final_y_data_error[:] = NAN
-    for x in range(nbr_pixel):
-
-        [ratio_array, ratio_array_error] = divideArrays(y_data[x,:],
-                                                        y_data_error[x,:],
-                                                        x_axis_factors,
-                                                        x_axis_factors_error)
-
-        final_y_data[x,:] = ratio_array[:]
-        final_y_data_error[x,:] = ratio_array_error
-
-    return [final_y_data, final_y_data_error]
-
-
-def divideArrays(num_array, num_error_array, den_array, den_error_array):
-    """
-    This function calculates the ratio of two arrays and calculate the
-    respective error values
-    """
-
-    sz = num_array.shape
-    nbr_elements = sz[0]
-
-    # calculate the ratio array
-    ratio_array = zeros(nbr_elements)
-    for i in range(nbr_elements):
-        if den_array[i] is 0:
-            _tmp_ratio = 0
-        else:
-            _tmp_ratio = num_array[i] / den_array[i]
-        ratio_array[i] = _tmp_ratio
-
-    # calculate the error of the ratio array
-    ratio_error_array = zeros(nbr_elements)
-    for i in range(nbr_elements):
-
-        if (num_array[i] == 0) or (den_array[i] == 0):
-            ratio_error_array[i] = 0
-        else:
-            tmp1 = pow(num_error_array[i] / num_array[i],2)
-            tmp2 = pow(den_error_array[i] / den_array[i],2)
-            ratio_error_array[i] = sqrt(tmp1+tmp2)*(num_array[i]/den_array[i])
-
-    return [ratio_array, ratio_error_array]
-
-
-def getCentralPixel(ws_event_data, dataPeakRange, is_new_geometry):
-    """
-    This function will calculate the central pixel position
-    """
-
-    if is_new_geometry:
-        _maxX = 256
-        _maxY = 304
-    else:
-        _maxX = 304
-        _maxY = 256
-
-    pixelXtof_data = getPixelXTOF(ws_event_data, maxX=_maxX, maxY=_maxY)
-    pixelXtof_1d = pixelXtof_data.sum(axis=1)
-    # Keep only range of pixels
-    pixelXtof_roi = pixelXtof_1d[dataPeakRange[0]:dataPeakRange[1]]
-    sz = pixelXtof_roi.size
-    _num = 0
-    _den = 0
-    start_pixel = dataPeakRange[0]
-    for i in range(sz):
-        _num += (start_pixel * pixelXtof_roi[i])
-        start_pixel = start_pixel + 1
-        _den += pixelXtof_roi[i]
-    data_cpix = _num / _den
-    print('--> central pixel is {0:.1f}'.format(data_cpix))
-
-    return data_cpix
-
-
-def getDistances(ws_event_data):
-    """
-    calculates the distance between the moderator and the detector (dMD)
-    and the distance between the sample and the detector
-    """
-
-    print('--> calculating dMD (moderator-detector) and dSD (sample-detector)')
-    sample = ws_event_data.getInstrument().getSample()
-    source = ws_event_data.getInstrument().getSource()
-    dSM = sample.getDistance(source)
-
-    # Create array of distances pixel->sample
-    dPS_array = zeros((256, 304))
-    for x in range(304):
-        for y in range(256):
-            _index = 256 * x + y
-            detector = ws_event_data.getDetector(_index)
-            dPS_array[y, x] = sample.getDistance(detector)
-
-    # Distance sample->center of detector
-    dSD = dPS_array[256//2,304//2]
-    # Distance source->center of detector
-    dMD = dSD + dSM
-
-    return [dMD, dSD]
-
-
-def  getTheta(ws_event_data, angleOffsetDeg):
-    """
-    will calculate the theta angle offset
-    """
-    print('--> retrieving thi and tthd')
-    mt_run = ws_event_data.getRun()
-    thi_value = mt_run.getProperty('thi').value[0]
-    thi_units = mt_run.getProperty('thi').units
-    tthd_value = mt_run.getProperty('tthd').value[0]
-    tthd_units = mt_run.getProperty('tthd').units
-    thi_rad = angleUnitConversion(value=thi_value,
-                                  from_units=thi_units,
-                                  to_units='rad')
-    print('---> thi (rad): ', thi_rad)
-    tthd_rad = angleUnitConversion(value=tthd_value,
-                                   from_units=tthd_units,
-                                   to_units='rad')
-    print('---> tthd (rad): ', tthd_rad)
-
-    theta = math.fabs(tthd_rad - thi_rad)/2.
-    angleOffsetRad = (angleOffsetDeg * math.pi) / 180.
-    theta += angleOffsetRad
-    print('---> theta (rad): ', theta)
-
-    return theta
-
-
-def getSlitsSize(mt):
-    print('---> retrieving slits size')
-    first_slit_size = getSheight(mt, '1')
-    last_slit_size = getSheight(mt,'2')
-    print('----> first_slit_size: ' , first_slit_size)
-    print('----> last_slit_size: ' , last_slit_size)
-    return [first_slit_size, last_slit_size]
-
-
-def getQrange(ws_histo_data, theta, dMD, q_min, q_step):
-    """
-    will determine the true q axis according to the qMin and qStep specified
-    and the geometry of the instrument
-    """
-    print('---> calculating Qrange')
-    _tof_axis = ws_histo_data.readX(0)
-    _const = float(4) * math.pi * m * dMD / h
-    sz_tof = shape(_tof_axis)[0]
-    _q_axis = zeros(sz_tof-1)
-    for t in range(sz_tof-1):
-        tof1 = _tof_axis[t]
-        tof2 = _tof_axis[t+1]
-        tofm = (tof1+tof2)/2.
-        _Q = _const * math.sin(theta) / (tofm*1e-6)
-        _q_axis[t] = _Q*1e-10
-    q_max = max(_q_axis)
-    if q_min >= q_max:
-        q_min = min(_q_axis)
-    print('----> q_min: ', q_min)
-    print('----> q_step: ', q_step)
-    print('----> q_max: ', q_max)
-
-    return [q_min, q_step, q_max]
-
-
-def convertToQ(tof_axis,
-               y_axis,
-               y_error_axis,
-               peak_range = None,
-               central_pixel = None,
-               source_to_detector_distance = None,
-               sample_to_detector_distance = None,
-               theta = None,
-               first_slit_size = None,
-               last_slit_size = None):
-    """
-    will convert the tof_axis into q_axis according to q range specified
-    """
-
-    y_size = (peak_range[1] - peak_range[0] + 1)
-    y_range = arange(y_size) + peak_range[0]
-    _q_axis = getQaxis(source_to_detector_distance,
-                       sample_to_detector_distance,
-                       theta,
-                       tof_axis,
-                       y_range,
-                       central_pixel,
-                       first_slit_size,
-                       last_slit_size)
-
-    _q_axis_min_max_index = findQaxisMinMax(_q_axis)
-
-    # now we need to put the various counts from y_axis into the right
-    # boxes
-    _y_axis = zeros((y_size, len(tof_axis)-1))
-    _y_error_axis = zeros((y_size, len(tof_axis)-1))
-#    _y_axis = empty((y_size, len(tof_axis)-1))
-#    _y_error_axis = empty((y_size, len(tof_axis)-1))
-#    _y_axis[:] = NAN
-#    _y_error_axis[:] = NAN
-
-    # now determine the _y_axis and _y_error_axis
-    for _y_index in range(y_size):
-
-        # get the q_axis of the given peak pixel
-        _tmp_q_axis = _q_axis[_y_index]
-        _q_axis = _tmp_q_axis[::-1] #reverse the axis (now in increasing order)
-
-        _y_axis_tmp = y_axis[_y_index,:]
-        _y_error_axis_tmp = y_error_axis[_y_index,:]
-
-        # keep only the overlap region of Qs
-        _q_min = _q_axis_min_max_index[_y_index, 0]
-        if _q_min != 0:
-            _y_axis_tmp[0:_q_min] = 0
-            _y_error_axis_tmp[0:_q_min] = 0
-
-        _q_max = int(_q_axis_min_max_index[_y_index, 1])
-        sz = shape(_y_axis_tmp)[0]
-        if _q_max != sz:
-            _index_q_max_range = arange(sz - _q_max) + _q_max
-            for i in _index_q_max_range:
-                _y_axis_tmp[i] = 0
-                _y_error_axis_tmp[i] = 0
-
-        _y_axis[_y_index, :] = _y_axis_tmp[::-1]
-        _y_error_axis[_y_index, :] = _y_error_axis_tmp[::-1]
-
-    # reverse the _q_axis here as well
-    q_axis_reverse = reverseQAxis(_q_axis)
-
-    return [q_axis_reverse, _y_axis, _y_error_axis]
-
-
-def convertToQWithoutCorrection(tof_axis,
-                                y_axis,
-                                y_error_axis,
-                                peak_range = None,
-                                source_to_detector_distance = None,
-                                sample_to_detector_distance = None,
-                                theta = None,
-                                first_slit_size = None,
-                                last_slit_size = None):
-    """
-    will convert the tof_axis into q_axis according to q range specified
-    but without using any geometry correction
-    """
-
-    _const = float(4) * math.pi * m * source_to_detector_distance / h
-    _q_axis = 1e-10 * _const * math.sin(theta) / (tof_axis[0:-1] * 1e-6)
-
-    sz = y_axis.shape
-    nbr_pixel = sz[0]
-
-    sz_q_axis = _q_axis.shape
-    nbr_q = sz_q_axis[0]
-
-    q_axis_2d = zeros((nbr_pixel, nbr_q))
-    for p in range(nbr_pixel):
-        q_axis_2d[p,:] = _q_axis
-
-    q_axis_reverse = reverseQAxis(q_axis_2d)
-    y_axis_reverse = fliplr(y_axis)
-    y_error_axis_reverse = fliplr(y_error_axis)
-
-    return [q_axis_reverse, y_axis_reverse, y_error_axis_reverse]
-
-
-def reverseQAxis(q_axis):
-    """
-    will reverse each q_axis for the respective pixels
-    """
-    new_q_axis = fliplr(q_axis)
-    return new_q_axis
-
-
-def getQaxis(dMD, dSD, theta,
-             tof_axis, y_range, central_pixel,
-             first_slit_size,
-             last_slit_size):
-    """
-    This function converts the pixel/TOF array to the R(Q) array
-    using Q = (4.Pi.Mn)/h  *  L.sin(theta/2)/TOF
-    with    L: distance central_pixel->source
-            TOF: TOF of pixel
-            theta: angle of detector
-    """
-
-    _const = float(4) * math.pi * m * dMD / h
-    sz_tof = len(tof_axis)
-    q_array = zeros((len(y_range), sz_tof))
-
-    for y in range(len(y_range)):
-        _px = y_range[y]
-        dangle = ref_beamdiv_correct(central_pixel,
-                                     dSD,
-                                     _px,
-                                     0.0007,
-                                     first_slit_size,
-                                     last_slit_size)
-
-        if dangle is not None:
-            _theta = theta + dangle
-        else:
-            _theta = theta
-
-        for t in range(sz_tof):
-#            tof1 = tof_axis[t]
-#            tof2 = tof_axis[t+1]
-#            tofm = (tof1+tof2)/2.
-            tof = tof_axis[t]
-#            _Q = _const * math.sin(_theta) / (tofm*1e-6)
-            _Q = _const * math.sin(_theta) / (tof*1e-6)
-            q_array[y, t] = _Q * 1e-10
-
-    return q_array
-
-
-def integrateOverPeakRange(wks, dataPeakRange):
-    """
-        getting just the mean of the peak
-    """
-
-    final_x_axis = wks.readX(0)[:]
-    sz = final_x_axis.shape
-    nbr_q = sz[0]
-
-    # make temp big array
-    nbrPixel = dataPeakRange[1] - dataPeakRange[0] + 1
-    bigY = zeros((nbrPixel, nbr_q))
-    bigE = zeros((nbrPixel, nbr_q))
-#    bigY = empty((nbrPixel, nbr_q))
-#    bigE = empty((nbrPixel, nbr_q))
-#    bigY[:]= NAN
-#    bigE[:]= NAN
-    for x in range(nbrPixel):
-        _tmp_y = wks.readY(x)[:]
-        bigY[x,:] = _tmp_y
-        _tmp_e = wks.readE(x)[:]
-        bigE[x,:] = _tmp_e
-
-    final_y_axis = zeros(nbr_q)
-    final_y_error_axis = zeros(nbr_q)
-#
-#    final_y_axis = empty(nbr_q)
-#    final_y_error_axis = empty(nbr_q)
-#    final_y_axis[:] = NAN
-#    final_y_error_axis[:] = NAN
-
-    # range(nbr_q -2) + 1 to get rid of first and last q values (edge effect)
-    rangeOfQ = arange(nbr_q-1)
-#    for q in rangeOfQ[1:-1]:
-    for q in rangeOfQ:
-
-        _tmp_y = bigY[:,q]
-        _tmp_y_error = bigE[:,q]
-
-#         [_y, _y_error] = myMean(_tmp_y, _tmp_y_error)
-        [_y, _y_error] = sumWithError(_tmp_y, _tmp_y_error)
-
-        final_y_axis[q] = _y
-        final_y_error_axis[q] = _y_error
-
-    return [final_x_axis, final_y_axis, final_y_error_axis]
-
-
-def createQworkspace(q_axis, y_axis, y_error_axis):
-
-    sz = q_axis.shape
-    nbr_pixel = sz[0]
-
-    q_axis_1d = q_axis.flatten()
-    y_axis_1d = y_axis.flatten()
-    y_error_axis_1d = y_error_axis.flatten()
-
-    q_workspace = CreateWorkspace(DataX=q_axis_1d,
-                                  DataY=y_axis_1d,
-                                  DataE=y_error_axis_1d,
-                                  Nspec=nbr_pixel,
-                                  UnitX="Wavelength")
-    q_workspace.setDistribution(True)
-
-    return q_workspace
-
-
-def createFinalWorkspace(q_axis, final_y_axis, final_error_axis, name_output_ws, parent_workspace):
-
-    final_workspace = CreateWorkspace(OutputWorkspace=name_output_ws,
-                                      DataX=q_axis,
-                                      DataY=final_y_axis,
-                                      DataE=final_error_axis,
-                                      Nspec=1,
-                                      UnitX="Wavelength",
-                                      ParentWorkspace=parent_workspace)
-    final_workspace.setDistribution(True)
-
-    return final_workspace
-
-
-def cropAxisToOnlyNonzeroElements(q_rebin, dataPeakRange):
-    """
-    This function will only keep the range of Q that have only nonzero counts
-    """
-    nbrPixel = dataPeakRange[1] - dataPeakRange[0] + 1
-
-    x_axis = q_rebin.readX(0)[:]
-    sz = x_axis.shape[0]-1
-
-    index_first_non_zero_value = sz
-    index_last_non_zero_value = 0
-
-    for x in range(nbrPixel):
-        _pixel_axis = q_rebin.readY(x)[:]
-
-        for t in range(sz):
-            _value = _pixel_axis[t]
-            if _value != float(0):
-                if index_first_non_zero_value > t:
-                    index_first_non_zero_value = t
-                break
-
-        for t in range(sz-1,-1,-1):
-            _value = _pixel_axis[t]
-            if _value != float(0):
-                if index_last_non_zero_value < t:
-                    index_last_non_zero_value = t
-                break
-
-    # crop data
-    new_x_axis = x_axis[index_first_non_zero_value:index_last_non_zero_value+1]
-    new_xrange = index_last_non_zero_value - index_first_non_zero_value + 1
-
-    new_y_axis = zeros((nbrPixel, new_xrange))
-    new_y_error_axis = zeros((nbrPixel, new_xrange))
-#    new_y_axis = empty((nbrPixel, new_xrange))
-#    new_y_error_axis = empty((nbrPixel, new_xrange))
-#    new_y_axis[:] = NAN
-#    new_y_error_axis[:] = NAN
-
-    for x in range(nbrPixel):
-        _tmp = q_rebin.readY(x)[:]
-        _tmp_E = q_rebin.readE(x)[:]
-        new_y_axis[x,:] = _tmp[index_first_non_zero_value:index_last_non_zero_value+1]
-        new_y_error_axis[x,:] = _tmp_E[index_first_non_zero_value:index_last_non_zero_value+1]
-
-    new_y_axis = new_y_axis.flatten()
-    new_y_error_axis = new_y_error_axis.flatten()
-
-    new_x_axis = asfarray(new_x_axis)
-    new_y_axis = asfarray(new_y_axis)
-    new_y_error_axis = asfarray(new_y_error_axis)
-
-    nonzero_q_rebin_wks = CreateWorkspace(DataX=new_x_axis,
-                                          DataY=new_y_axis,
-                                          DataE=new_y_error_axis,
-                                          Nspec=int(nbrPixel),
-                                          UnitX="Wavelength")
-
-    return nonzero_q_rebin_wks
-
-
-def cleanupData(final_data_y_axis, final_data_y_error_axis):
-
-    sz = final_data_y_axis.shape
-    nbrPixel = sz[0]
-    nbrQ = sz[1]
-
-    for x in range(nbrPixel):
-        for q in range(nbrQ):
-
-            _data = final_data_y_axis[x,q]
-            _error = final_data_y_error_axis[x,q]
-
-            # if error is > value, remove point
-            if _error >= _data:
-                _data = 0
-                _error = 1
-
-            # if value is below 10^-12
-            if _data < 1e-12:
-                _data = 0
-                _error = 1
-
-            final_data_y_axis[x,q] = _data
-            final_data_y_error_axis[x,q] = _error
-
-    return [final_data_y_axis, final_data_y_error_axis]
-
-
-def cleanupData1D(final_data_y_axis, final_data_y_error_axis):
-
-    sz = final_data_y_axis.shape
-    nbrTof = sz[0]
-
-    notYetRemoved = True
-
-    for t in range(nbrTof):
-
-        _data = final_data_y_axis[t]
-        _error = final_data_y_error_axis[t]
-
-        if _data > 0 and notYetRemoved:
-            notYetRemoved = False
-            final_data_y_axis[t] = 0
-            final_data_y_error_axis[t] = 1
-            continue
-
-        # if error is > value, remove point
-        if abs(_error) >= abs(_data):
-            _data_tmp = 0
-            _error_tmp = 1
-        elif _data< 1e-12:
-        # if value is below 10^-12
-            _data_tmp = 0
-            _error_tmp = 1
-        else:
-            _data_tmp = _data
-            _error_tmp = _error
-
-        final_data_y_axis[t] = _data_tmp
-        final_data_y_error_axis[t] = _error_tmp
-
-#        print('final_data_y_axis[t]: ' , _data_tmp , ' final_data_y_error_axis[t]: ' , _error_tmp)
-
-    return [final_data_y_axis, final_data_y_error_axis]
-
-
-def isNexusTakeAfterRefDate(nexus_date):
-    '''
-    This function parses the output.date and returns true if this date is after the ref date
-    '''
-    nexus_date_acquistion = nexus_date.split('T')[0]
-
-    if nexus_date_acquistion > ref_date:
-        return True
-    else:
-        return False
diff --git a/scripts/test/ISISDirecInelasticConfigTest.py b/scripts/test/ISISDirecInelasticConfigTest.py
index caa9ee12fad5b769eb384f93bf538d0d409838b1..f05db915240efca41bd0e00544076de240f86e60 100644
--- a/scripts/test/ISISDirecInelasticConfigTest.py
+++ b/scripts/test/ISISDirecInelasticConfigTest.py
@@ -110,6 +110,9 @@ class ISISDirectInelasticConfigTest(unittest.TestCase):
     def test_UserProperties(self):
         user = UserProperties(self.userID)
 
+        user.set_user_properties(self.instrument,self.rbdir,'CYCLE20144B',self.start_date)
+        self.assertEqual(user.cycleID,'2014_4B')
+
         #set_user_properties(self,instrument,rb_folder_or_id,cycle,start_date):
         user.set_user_properties(self.instrument,self.rbdir,self.cycle,self.start_date)
 
diff --git a/scripts/test/SANS/algorithm_detail/scale_helper_test.py b/scripts/test/SANS/algorithm_detail/scale_helper_test.py
index b69ffc1cc7165aa436e2c5f59dc04ced72b42a40..a12e3902005db32cbec0d94cb698761169fa0141 100644
--- a/scripts/test/SANS/algorithm_detail/scale_helper_test.py
+++ b/scripts/test/SANS/algorithm_detail/scale_helper_test.py
@@ -7,9 +7,10 @@ from sans.algorithm_detail.scale_helpers import (DivideByVolumeFactory, DivideBy
                                                  MultiplyByAbsoluteScaleFactory, MultiplyByAbsoluteScaleLOQ,
                                                  MultiplyByAbsoluteScaleISIS)
 from sans.common.general_functions import create_unmanaged_algorithm
-from sans.common.enums import (SampleShape, SANSFacility, DataType)
+from sans.common.enums import (SampleShape, SANSFacility, DataType, SANSInstrument)
 from sans.state.scale import get_scale_builder
 from sans.state.data import get_data_builder
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 class ScaleHelperTest(unittest.TestCase):
@@ -44,11 +45,13 @@ class ScaleHelperTest(unittest.TestCase):
     def test_that_divide_uses_settings_from_workspace(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22024, height=8.0,
+                                                   width=8.0, thickness=1.0, shape=SampleShape.CylinderAxisAlong)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("SANS2D00022024")
         data_state = data_builder.build()
 
-        scale_builder = get_scale_builder(data_state)
+        scale_builder = get_scale_builder(data_state, file_information)
         scale_state = scale_builder.build()
 
         test_director = TestDirector()
@@ -78,11 +81,12 @@ class ScaleHelperTest(unittest.TestCase):
     def test_that_divide_uses_settings_from_state_if_they_are_set(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("SANS2D00022024")
         data_state = data_builder.build()
 
-        scale_builder = get_scale_builder(data_state)
+        scale_builder = get_scale_builder(data_state, file_information)
         width = 10.
         height = 5.
         thickness = 2.
@@ -123,11 +127,12 @@ class ScaleHelperTest(unittest.TestCase):
     def test_that_correct_scale_strategy_is_selected_for_loq(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_state = data_builder.build()
 
-        scale_builder = get_scale_builder(data_state)
+        scale_builder = get_scale_builder(data_state, file_information)
         scale_state = scale_builder.build()
 
         test_director = TestDirector()
@@ -144,11 +149,12 @@ class ScaleHelperTest(unittest.TestCase):
     def test_that_correct_scale_strategy_is_selected_for_loq_2(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_state = data_builder.build()
 
-        scale_builder = get_scale_builder(data_state)
+        scale_builder = get_scale_builder(data_state, file_information)
         scale_builder.set_scale(2.4)
         scale_state = scale_builder.build()
 
diff --git a/scripts/test/SANS/gui_logic/property_manager_service_test.py b/scripts/test/SANS/gui_logic/property_manager_service_test.py
index 97852827cfd8f105b5c8a2bc8ed0c407fd197f8f..1d16ee7bb8075bec02f534cbe644bfb2e888914b 100644
--- a/scripts/test/SANS/gui_logic/property_manager_service_test.py
+++ b/scripts/test/SANS/gui_logic/property_manager_service_test.py
@@ -9,7 +9,8 @@ from mantid.api import Algorithm
 from sans.gui_logic.presenter.property_manager_service import PropertyManagerService
 from sans.state.data import get_data_builder
 from sans.test_helper.test_director import TestDirector
-from sans.common.enums import SANSFacility
+from sans.common.enums import SANSFacility, SANSInstrument
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 class FakeAlgorithm(Algorithm):
@@ -22,7 +23,8 @@ class FakeAlgorithm(Algorithm):
 
 def get_example_state():
     ws_name_sample = "SANS2D00022024"
-    data_builder = get_data_builder(SANSFacility.ISIS)
+    file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22024)
+    data_builder = get_data_builder(SANSFacility.ISIS, file_information)
     data_builder.set_sample_scatter(ws_name_sample)
     data = data_builder.build()
 
diff --git a/scripts/test/SANS/gui_logic/state_gui_model_test.py b/scripts/test/SANS/gui_logic/state_gui_model_test.py
index 4383af9f10d8525a7bf7867b1ba6768ac1698a2e..671cb525f105c9f8c0da7e5f6081e10433f637fd 100644
--- a/scripts/test/SANS/gui_logic/state_gui_model_test.py
+++ b/scripts/test/SANS/gui_logic/state_gui_model_test.py
@@ -4,6 +4,7 @@ from sans.gui_logic.models.state_gui_model import StateGuiModel
 from sans.user_file.settings_tags import (OtherId, event_binning_string_values, DetectorId, det_fit_range)
 from sans.common.enums import (ReductionDimensionality, ISISReductionMode, RangeStepType, SampleShape, SaveType,
                                FitType)
+from sans.user_file.settings_tags import (det_fit_range)
 
 
 class StateGuiModelTest(unittest.TestCase):
@@ -129,7 +130,7 @@ class StateGuiModelTest(unittest.TestCase):
         self.assertTrue(state_gui_model.reduction_mode is ISISReductionMode.All)
 
     # ------------------------------------------------------------------------------------------------------------------
-    # Reduction range
+    # Merge range
     # ------------------------------------------------------------------------------------------------------------------
     def test_that_merge_mask_is_false_by_default(self):
         state_gui_model = StateGuiModel({"test": [1]})
@@ -153,6 +154,12 @@ class StateGuiModelTest(unittest.TestCase):
         state_gui_model.merge_min = 78.9
         self.assertTrue(state_gui_model.merge_min == 78.9)
 
+    def test_that_merge_range_set_correctly(self):
+        state_gui_model = StateGuiModel({DetectorId.merge_range: [det_fit_range(use_fit=True, start=0.13, stop=0.15)]})
+        self.assertEqual(state_gui_model.merge_min, 0.13)
+        self.assertEqual(state_gui_model.merge_max, 0.15)
+        self.assertTrue(state_gui_model.merge_mask)
+
     # ------------------------------------------------------------------------------------------------------------------
     # Reduction dimensionality
     # ------------------------------------------------------------------------------------------------------------------
diff --git a/scripts/test/SANS/state/adjustment_test.py b/scripts/test/SANS/state/adjustment_test.py
index 1566c7df76af5d80bd2ba0f548141ef0c7aafd84..28810a487ec83121a4551687edeb4b18bb46452c 100644
--- a/scripts/test/SANS/state/adjustment_test.py
+++ b/scripts/test/SANS/state/adjustment_test.py
@@ -8,6 +8,7 @@ from sans.state.calculate_transmission import StateCalculateTransmission
 from sans.state.normalize_to_monitor import StateNormalizeToMonitor
 from sans.state.wavelength_and_pixel_adjustment import StateWavelengthAndPixelAdjustment
 from sans.common.enums import (SANSFacility, SANSInstrument, FitType)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -70,7 +71,8 @@ class StateAdjustmentBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/calculate_transmission_test.py b/scripts/test/SANS/state/calculate_transmission_test.py
index fdaa2353d9ca575cb5c3e80139e43e6d062b0483..d1a47225e71ad133b2aa41ba548f0316d802fc85 100644
--- a/scripts/test/SANS/state/calculate_transmission_test.py
+++ b/scripts/test/SANS/state/calculate_transmission_test.py
@@ -5,8 +5,9 @@ import mantid
 from sans.state.calculate_transmission import (StateCalculateTransmission, StateCalculateTransmissionLOQ,
                                                get_calculate_transmission_builder)
 from sans.state.data import get_data_builder
-from sans.common.enums import (RebinType, RangeStepType, FitType, DataType, SANSFacility)
+from sans.common.enums import (RebinType, RangeStepType, FitType, DataType, SANSFacility, SANSInstrument)
 from state_test_helper import assert_validate_error, assert_raises_nothing
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -194,7 +195,8 @@ class StateCalculateTransmissionBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/convert_to_q_test.py b/scripts/test/SANS/state/convert_to_q_test.py
index e48c6356ff6d078a04c79859b8091cb298163230..760e90cc93f87c3cb818381d8cb1d543f9608495 100644
--- a/scripts/test/SANS/state/convert_to_q_test.py
+++ b/scripts/test/SANS/state/convert_to_q_test.py
@@ -4,8 +4,9 @@ import mantid
 
 from sans.state.convert_to_q import (StateConvertToQ, get_convert_to_q_builder)
 from sans.state.data import get_data_builder
-from sans.common.enums import (RangeStepType, ReductionDimensionality, SANSFacility)
+from sans.common.enums import (RangeStepType, ReductionDimensionality, SANSFacility, SANSInstrument)
 from state_test_helper import (assert_validate_error, assert_raises_nothing)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -96,7 +97,8 @@ class StateConvertToQBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/data_test.py b/scripts/test/SANS/state/data_test.py
index efd45a105e15223a28a0d520f55a7c3125262e56..fcfe9f83d813e8c7f8f3641e4117b605cc1f272d 100644
--- a/scripts/test/SANS/state/data_test.py
+++ b/scripts/test/SANS/state/data_test.py
@@ -5,6 +5,7 @@ import mantid
 from sans.state.data import (StateData, get_data_builder)
 from state_test_helper import (assert_validate_error, assert_raises_nothing)
 from sans.common.enums import (SANSFacility, SANSInstrument)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -71,9 +72,9 @@ class StateDataBuilderTest(unittest.TestCase):
     def test_that_data_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-
+        file_information = SANSFileInformationMock(run_number=74044)
         # Act
-        data_builder = get_data_builder(facility)
+        data_builder = get_data_builder(facility, file_information)
 
         data_builder.set_sample_scatter("LOQ74044")
         data_builder.set_sample_scatter_period(3)
diff --git a/scripts/test/SANS/state/mask_test.py b/scripts/test/SANS/state/mask_test.py
index f6ab89fe9330e9c9dc15518cf323512925d1acac..66e0eeb5809c4e0b394fe22b7ad671a30f54ed4f 100644
--- a/scripts/test/SANS/state/mask_test.py
+++ b/scripts/test/SANS/state/mask_test.py
@@ -6,6 +6,8 @@ from sans.state.mask import (StateMaskSANS2D, get_mask_builder)
 from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, SANSInstrument, DetectorType)
 from state_test_helper import (assert_validate_error, assert_raises_nothing)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
+
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -192,7 +194,8 @@ class StateMaskBuilderTest(unittest.TestCase):
     def test_that_mask_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_builder.set_sample_scatter_period(3)
         data_info = data_builder.build()
diff --git a/scripts/test/SANS/state/move_test.py b/scripts/test/SANS/state/move_test.py
index 3ad2eb2f6e9614ddc26146924c910ea131d51218..1e0d83f55678b8adf7204a7e153c777fb30a0993 100644
--- a/scripts/test/SANS/state/move_test.py
+++ b/scripts/test/SANS/state/move_test.py
@@ -5,8 +5,9 @@ import mantid
 from sans.state.move import (StateMoveLOQ, StateMoveSANS2D, StateMoveLARMOR, StateMoveZOOM, StateMove,
                              StateMoveDetector, get_move_builder)
 from sans.state.data import get_data_builder
-from sans.common.enums import (CanonicalCoordinates, SANSFacility, DetectorType)
+from sans.common.enums import (CanonicalCoordinates, SANSFacility, DetectorType, SANSInstrument)
 from state_test_helper import assert_validate_error, assert_raises_nothing
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -115,7 +116,8 @@ class StateMoveBuilderTest(unittest.TestCase):
     def test_that_state_for_loq_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_builder.set_sample_scatter_period(3)
         data_info = data_builder.build()
@@ -141,7 +143,8 @@ class StateMoveBuilderTest(unittest.TestCase):
     def test_that_state_for_sans2d_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22048)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("SANS2D00022048")
         data_info = data_builder.build()
 
@@ -162,7 +165,8 @@ class StateMoveBuilderTest(unittest.TestCase):
     def test_that_state_for_larmor_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LARMOR, run_number=2260)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LARMOR00002260")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/normalize_to_monitor_test.py b/scripts/test/SANS/state/normalize_to_monitor_test.py
index c469e0889056e21fd67b82068d088ee1dea08684..5179ee093fc7ed29c12ad4e9950b23fe16c57b8e 100644
--- a/scripts/test/SANS/state/normalize_to_monitor_test.py
+++ b/scripts/test/SANS/state/normalize_to_monitor_test.py
@@ -5,8 +5,9 @@ import mantid
 from sans.state.normalize_to_monitor import (StateNormalizeToMonitor, StateNormalizeToMonitorLOQ,
                                              get_normalize_to_monitor_builder)
 from sans.state.data import get_data_builder
-from sans.common.enums import (RebinType, RangeStepType, SANSFacility)
+from sans.common.enums import (RebinType, RangeStepType, SANSFacility, SANSInstrument)
 from state_test_helper import assert_validate_error, assert_raises_nothing
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -87,7 +88,8 @@ class StateReductionBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/reduction_mode_test.py b/scripts/test/SANS/state/reduction_mode_test.py
index 02a9fa850214f242b15432cb405ec7ee8bef4501..b353d80f6191a22523c4f3b0f72395f92557b6b5 100644
--- a/scripts/test/SANS/state/reduction_mode_test.py
+++ b/scripts/test/SANS/state/reduction_mode_test.py
@@ -6,6 +6,7 @@ from sans.state.reduction_mode import (StateReductionMode, get_reduction_mode_bu
 from sans.state.data import get_data_builder
 from sans.common.enums import (ISISReductionMode, ReductionDimensionality, FitModeForMerge,
                                SANSFacility, SANSInstrument, DetectorType)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -55,7 +56,8 @@ class StateReductionModeBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/save_test.py b/scripts/test/SANS/state/save_test.py
index 00c43c2d7204578196e07ef22369731897a94197..6600fccb61eded891d546e6aeb4e0fac06c5dc1d 100644
--- a/scripts/test/SANS/state/save_test.py
+++ b/scripts/test/SANS/state/save_test.py
@@ -4,7 +4,8 @@ import mantid
 
 from sans.state.save import (get_save_builder)
 from sans.state.data import (get_data_builder)
-from sans.common.enums import (SANSFacility, SaveType)
+from sans.common.enums import (SANSFacility, SaveType, SANSInstrument)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -20,7 +21,8 @@ class StateReductionBuilderTest(unittest.TestCase):
     def test_that_reduction_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/scale_test.py b/scripts/test/SANS/state/scale_test.py
index 6fe837552dabe0addb24164e0625220c516f5887..6d259a9dc3326325a9f1b3304a66fea51ed5c6a3 100644
--- a/scripts/test/SANS/state/scale_test.py
+++ b/scripts/test/SANS/state/scale_test.py
@@ -5,6 +5,8 @@ import mantid
 from sans.state.scale import get_scale_builder
 from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, SANSInstrument, SampleShape)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
+
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -19,12 +21,14 @@ class StateSliceEventBuilderTest(unittest.TestCase):
     def test_that_slice_event_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
+
         # Act
-        builder = get_scale_builder(data_info)
+        builder = get_scale_builder(data_info, file_information)
         self.assertTrue(builder)
 
         builder.set_scale(1.0)
diff --git a/scripts/test/SANS/state/slice_event_test.py b/scripts/test/SANS/state/slice_event_test.py
index ef3f3b505df4a6950a07b8cc823978bc99c2b5b1..acda6d552629be91c5307dcf94cb7cefab8f0819 100644
--- a/scripts/test/SANS/state/slice_event_test.py
+++ b/scripts/test/SANS/state/slice_event_test.py
@@ -6,6 +6,7 @@ from sans.state.slice_event import (StateSliceEvent, get_slice_event_builder)
 from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, SANSInstrument)
 from state_test_helper import (assert_validate_error)
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -44,7 +45,8 @@ class StateSliceEventBuilderTest(unittest.TestCase):
     def test_that_slice_event_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/wavelength_and_pixel_adjustment_test.py b/scripts/test/SANS/state/wavelength_and_pixel_adjustment_test.py
index fdcf5508cd7539af32c9b7bdfe8324028ec0ea2f..0d919d34e7cebfab34eddbb8373a4c739081eea4 100644
--- a/scripts/test/SANS/state/wavelength_and_pixel_adjustment_test.py
+++ b/scripts/test/SANS/state/wavelength_and_pixel_adjustment_test.py
@@ -7,6 +7,7 @@ from sans.state.wavelength_and_pixel_adjustment import (StateWavelengthAndPixelA
 from sans.state.data import get_data_builder
 from sans.common.enums import (RebinType, RangeStepType, DetectorType, SANSFacility, SANSInstrument)
 from state_test_helper import assert_validate_error, assert_raises_nothing
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -42,7 +43,8 @@ class StateWavelengthAndPixelAdjustmentBuilderTest(unittest.TestCase):
     def test_that_wavelength_and_pixel_adjustment_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/state/wavelength_test.py b/scripts/test/SANS/state/wavelength_test.py
index d38ef564095f9c9734a3c7c948806dc3cb8a02d4..b3a1c2c8769a4c32a48d2bc2aa684695e21b6888 100644
--- a/scripts/test/SANS/state/wavelength_test.py
+++ b/scripts/test/SANS/state/wavelength_test.py
@@ -6,6 +6,7 @@ from sans.state.wavelength import (StateWavelength, get_wavelength_builder)
 from sans.state.data import get_data_builder
 from sans.common.enums import (SANSFacility, SANSInstrument, RebinType, RangeStepType)
 from state_test_helper import assert_validate_error, assert_raises_nothing
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # ----------------------------------------------------------------------------------------------------------------------
@@ -44,7 +45,8 @@ class StateSliceEventBuilderTest(unittest.TestCase):
     def test_that_slice_event_state_can_be_built(self):
         # Arrange
         facility = SANSFacility.ISIS
-        data_builder = get_data_builder(facility)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.LOQ, run_number=74044)
+        data_builder = get_data_builder(facility, file_information)
         data_builder.set_sample_scatter("LOQ74044")
         data_info = data_builder.build()
 
diff --git a/scripts/test/SANS/user_file/state_director_test.py b/scripts/test/SANS/user_file/state_director_test.py
index ea36086c97394c8947d61c0b92a42f56938a27a7..acfad053ad28bf487ad4260bc9e2ff7cadce3fb9 100644
--- a/scripts/test/SANS/user_file/state_director_test.py
+++ b/scripts/test/SANS/user_file/state_director_test.py
@@ -6,11 +6,12 @@ import mantid
 
 from sans.user_file.state_director import StateDirectorISIS
 from sans.common.enums import (SANSFacility, ISISReductionMode, RangeStepType, RebinType, DataType, FitType,
-                               DetectorType, SampleShape)
+                               DetectorType, SampleShape, SANSInstrument)
 from sans.common.configurations import Configurations
 from sans.state.data import get_data_builder
 
 from sans.test_helper.user_file_test_helper import create_user_file, sample_user_file
+from sans.test_helper.file_information_mock import SANSFileInformationMock
 
 
 # -----------------------------------------------------------------
@@ -170,12 +171,13 @@ class UserFileStateDirectorISISTest(unittest.TestCase):
 
     def test_state_can_be_created_from_valid_user_file_with_data_information(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22024)
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00022024")
         data_builder.set_sample_scatter_period(3)
         data_state = data_builder.build()
 
-        director = StateDirectorISIS(data_state)
+        director = StateDirectorISIS(data_state, file_information)
         user_file_path = create_user_file(sample_user_file)
 
         director.set_user_file(user_file_path)
@@ -197,12 +199,13 @@ class UserFileStateDirectorISISTest(unittest.TestCase):
 
     def test_stat_can_be_crated_from_valid_user_file_and_later_on_reset(self):
         # Arrange
-        data_builder = get_data_builder(SANSFacility.ISIS)
+        file_information = SANSFileInformationMock(instrument=SANSInstrument.SANS2D, run_number=22024)
+        data_builder = get_data_builder(SANSFacility.ISIS, file_information)
         data_builder.set_sample_scatter("SANS2D00022024")
         data_builder.set_sample_scatter_period(3)
         data_state = data_builder.build()
 
-        director = StateDirectorISIS(data_state)
+        director = StateDirectorISIS(data_state, file_information)
         user_file_path = create_user_file(sample_user_file)
         director.set_user_file(user_file_path)
 
diff --git a/scripts/test/SANS/user_file/user_file_parser_test.py b/scripts/test/SANS/user_file/user_file_parser_test.py
index 5c765f67dccd572fafbb8916fa85f9a9d7881376..18d8ec015d110cb7f3eea8028401afa35f7ed917 100644
--- a/scripts/test/SANS/user_file/user_file_parser_test.py
+++ b/scripts/test/SANS/user_file/user_file_parser_test.py
@@ -8,7 +8,7 @@ from sans.user_file.user_file_parser import (DetParser, LimitParser, MaskParser,
                                              MaskFileParser, MonParser, PrintParser, BackParser, SANS2DParser, LOQParser,
                                              UserFileParser, LARMORParser, CompatibilityParser)
 from sans.user_file.settings_tags import (DetectorId, BackId, range_entry, back_single_monitor_entry,
-                                          single_entry_with_detector, mask_angle_entry, LimitsId, rebin_string_values,
+                                          single_entry_with_detector, mask_angle_entry, LimitsId,
                                           simple_range, complex_range, MaskId, mask_block, mask_block_cross,
                                           mask_line, range_entry_with_detector, SampleId, SetId, set_scales_entry,
                                           position_entry, TransId, TubeCalibrationFileId, QResolutionId, FitId,
@@ -131,6 +131,20 @@ class DetParserTest(unittest.TestCase):
                             "DeT/ CORR /reAR/SIDE D 12.3": RuntimeError,
                             " DET/CoRR/FRONT/ SidE -i3": RuntimeError}
 
+        det_parser = DetParser()
+
+        do_test(det_parser, valid_settings, invalid_settings, self.assertTrue, self.assertRaises)
+
+    def test_that_DET_OVERLAP_option_is_parsed_correctly(self):
+        valid_settings = {"DET/OVERLAP 0.13 0.15": {DetectorId.merge_range: det_fit_range(start=0.13, stop=0.15, use_fit=True)},
+                          "DeT/OverLAP 0.13 0.15": {DetectorId.merge_range: det_fit_range(start=0.13, stop=0.15, use_fit=True)}
+                          }
+
+        invalid_settings = {"DET/OVERLAP 0.13 0.15 0.17": RuntimeError,
+                            "DET/OVERLAP 0.13": RuntimeError,
+                            "DET/OVERLAP": RuntimeError,
+                            "DET/OVERLAP 0.13 five": RuntimeError}
+
         det_parser = DetParser()
         do_test(det_parser, valid_settings, invalid_settings, self.assertTrue, self.assertRaises)
 
@@ -302,7 +316,11 @@ class MaskParserTest(unittest.TestCase):
                           "MASK/REAR/T 13 35": {MaskId.time_detector: range_entry_with_detector(start=13, stop=35,
                                                 detector_type=DetectorType.LAB)},
                           "MASK/FRONT/TIME 33 35": {MaskId.time_detector: range_entry_with_detector(start=33, stop=35,
-                                                    detector_type=DetectorType.HAB)}
+                                                    detector_type=DetectorType.HAB)},
+                          "MASK/TIME/REAR 13 35": {MaskId.time_detector: range_entry_with_detector(start=13, stop=35,
+                                                   detector_type=DetectorType.LAB)},
+                          "MASK/T/FRONT 33 35": {MaskId.time_detector: range_entry_with_detector(start=33, stop=35,
+                                                 detector_type=DetectorType.HAB)}
                           }
 
         invalid_settings = {"MASK/TIME 12 34 4 ": RuntimeError,
@@ -888,9 +906,13 @@ class PrintParserTest(unittest.TestCase):
         self.assertTrue(PrintParser.get_type(), "PRINT")
 
     def test_that_print_is_parsed_correctly(self):
-        valid_settings = {"PRINT OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"}}
+        valid_settings = {"PRINT OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"},
+                          "PRiNt OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"},
+                          "  PRINT Loaded: USER_LOQ_174J, 12/03/18, Xuzhi (Lu), 12mm, Sample Changer, Banjo cells":
+                          {PrintId.print_line: "Loaded: USER_LOQ_174J, 12/03/18, Xuzhi (Lu), 12mm, Sample Changer, Banjo cells"}
+                          }
 
-        invalid_settings = {}
+        invalid_settings = {"j PRINT OdlfP slsk 23lksdl2 34l ": RuntimeError,}
 
         print_parser = PrintParser()
         do_test(print_parser, valid_settings, invalid_settings, self.assertTrue, self.assertRaises)
@@ -1051,5 +1073,6 @@ class UserFileParserTest(unittest.TestCase):
         # Act + Assert
         self.assertRaises(ValueError, user_file_parser.parse_line, "DetT/DKDK/ 23 23")
 
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/scripts/test/SANSReductionStepsUserFileTest.py b/scripts/test/SANSReductionStepsUserFileTest.py
index eeb3d709beec5499ad20090cc439986200259fba..b253a6f9c344f6b0dd4cbad9c2b0277337c41d90 100644
--- a/scripts/test/SANSReductionStepsUserFileTest.py
+++ b/scripts/test/SANSReductionStepsUserFileTest.py
@@ -41,6 +41,70 @@ class SANSReductionStepsUserFileTest(unittest.TestCase):
         self.assertEqual(None, start_TOF_ROI, 'The start time should not have been set')
         self.assertEqual(None, end_TOF_ROI, 'The end time should not have been set')
 
+    def test_can_parse_DET_OVERLAP_line(self):
+        # Arrange
+        line = 'DET/OVERLAP 0.13 0.15'
+        command_iface.Clean()
+        command_iface.LOQ()
+        user_file = reduction_steps.UserFile()
+
+        # Act
+        user_file.read_line(line = line, reducer = ReductionSingleton())
+        merge_Range = ReductionSingleton().instrument.getDetector('FRONT').mergeRange
+
+        # Assert
+        self.assertEqual(merge_Range.q_min, 0.13, 'The q_min should have been read in')
+        self.assertEqual(merge_Range.q_max, 0.15, 'The q_max should have been read in')
+        self.assertEqual(merge_Range.q_merge_range, True, 'q_merge_range should be true')
+
+    def test_that_will_not_parse_DET_OVERLAP_with_no_subsequent_commands(self):
+        # Arrange
+        line = 'DET/OVERLAP'
+        command_iface.Clean()
+        command_iface.LOQ()
+        user_file = reduction_steps.UserFile()
+
+        # Act
+        user_file.read_line(line = line, reducer = ReductionSingleton())
+        merge_Range = ReductionSingleton().instrument.getDetector('FRONT').mergeRange
+
+        # Assert
+        self.assertEqual(merge_Range.q_min, None, 'The q_min should have been read in')
+        self.assertEqual(merge_Range.q_max, None, 'The q_max should have been read in')
+        self.assertEqual(merge_Range.q_merge_range, False, 'q_merge_range should be true')
+
+    def test_that_will_not_parse_DET_OVERLAP_with_one_subsequent_commands(self):
+        # Arrange
+        line = 'DET/OVERLAP 0.13'
+        command_iface.Clean()
+        command_iface.LOQ()
+        user_file = reduction_steps.UserFile()
+
+        # Act
+        user_file.read_line(line = line, reducer = ReductionSingleton())
+        merge_Range = ReductionSingleton().instrument.getDetector('FRONT').mergeRange
+
+        # Assert
+        self.assertEqual(merge_Range.q_min, None, 'The q_min should have been read in')
+        self.assertEqual(merge_Range.q_max, None, 'The q_max should have been read in')
+        self.assertEqual(merge_Range.q_merge_range, False, 'q_merge_range should be true')
+
+    def test_that_will_not_parse_DET_OVERLAP_with_three_subsequent_commands(self):
+        # Arrange
+        line = 'DET/OVERLAP 0.13 0.15 0.17'
+        command_iface.Clean()
+        command_iface.LOQ()
+        user_file = reduction_steps.UserFile()
+
+        # Act
+        user_file.read_line(line=line, reducer=ReductionSingleton())
+        merge_Range = ReductionSingleton().instrument.getDetector('FRONT').mergeRange
+
+        # Assert
+        self.assertEqual(merge_Range.q_min, None, 'The q_min should have been read in')
+        self.assertEqual(merge_Range.q_max, None, 'The q_max should have been read in')
+        self.assertEqual(merge_Range.q_merge_range, False, 'q_merge_range should be true')
+
 class MockConvertTOQISISQResolution(object):
     def __init__(self):
         super(MockConvertTOQISISQResolution, self).__init__()
diff --git a/scripts/test/directtools/DirectToolsTest.py b/scripts/test/directtools/DirectToolsTest.py
index 82b22d58bd8813f4e2ab5c4f6f68ceb6ad932c7b..a1877a98dcc3f476ce0b0ccd153783290a6c093d 100644
--- a/scripts/test/directtools/DirectToolsTest.py
+++ b/scripts/test/directtools/DirectToolsTest.py
@@ -56,7 +56,7 @@ class DirectTest(unittest.TestCase):
 
     def test_configurematplotlib(self):
         defaultParams = directtools.defaultrcParams()
-        directtools.configurematplotlib(defaultParams)
+        directtools._configurematplotlib(defaultParams)
         for key in defaultParams:
             self.assertTrue(key in matplotlib.rcParams)
             self.assertEqual(matplotlib.rcParams[key], defaultParams[key])
@@ -98,7 +98,7 @@ class DirectTest(unittest.TestCase):
         self.assertEqual(outEs[2], 0.)
 
     def test_mantidsubplotsetup(self):
-        result = directtools.mantidsubplotsetup()
+        result = directtools._mantidsubplotsetup()
         self.assertEqual(result, {'projection': 'mantid'})
 
     def _nanminmaxSetup(self):
diff --git a/tools/DOI/authors.py b/tools/DOI/authors.py
index 6f8b1f5613f2306c669bddf3cd4c505ae20579a6..1f2f42c7cf85f990dde94ad7dbb65d23acb76699 100644
--- a/tools/DOI/authors.py
+++ b/tools/DOI/authors.py
@@ -113,6 +113,7 @@ _translations = {
     'Matthew D Jones'         : 'Jones, Matthew D.',
     'Matt King'               : 'King, Matt',
     'Jiao Lin'                : 'Lin, Jiao',
+    'Jiao'                    : 'Lin, Jiao',
     'Simon Heybrock'          : 'Heybrock, Simon',
     'Elliot Oram'             : 'Oram, Elliot',
     'Dominic Oram'            : 'Oram, Dominic',
@@ -141,9 +142,12 @@ _translations = {
     'reimundILL'              : 'Reimund, Verena',
     'Krzysztof Dymkowski'     : 'Dymkowski, Krzysztof',
     'dymkowsk'                : 'Dymkowski, Krzysztof',
+    'krzych'                  : 'Dymkowski, Krzysztof',
     'Gemma Guest'             : 'Guest, Gemma',
     'Anthony Lim'             : 'Lim, Anthony',
+    'Anthony Lim'             : 'Lim, Anthony',
     'AnthonyLim23'            : 'Lim, Anthony',
+    'Anthony'                 : 'Lim, Anthony',
     'CipPruteanu'             : 'Ciprian Pruteanu',
     'Tasev'                   : 'Tasev, Dimitar',
     'Mayer Alexandra'         : 'Mayer, Alexandra',
@@ -154,11 +158,18 @@ _translations = {
     'Thomas Lohnert'          : 'Lohnert, Thomas',
     'James Tricker'           : 'Tricker, James',
     'Matthew Bowles'          : 'Bowles, Matthew',
+    'MatthewBowles'           : 'Bowles, Matthew',
     'josephframsay'           : 'Ramsay, Joseph F.',
     'Joseph Ramsay'           : 'Ramsay, Joseph F.',
+    '='                       : 'Ramsay, Joseph F.',
+    'Joe Ramsay'              : 'Ramsay, Joseph F.',
     'Adam Washington'         : 'Wahington, Adam',
     'Edward Brown'            : 'Brown, Edward',
-    'Matthew Andrew'          : 'Andrew, Matthew'
+    'Matthew Andrew'          : 'Andrew, Matthew',
+    'Mantid-Matthew'          : 'Andrew, Matthew',
+    'Keith Butler'            : 'Butler, Keith T.',
+    'fodblog'                 : 'Butler, Keith T.',
+    'Marshall McDonnell'      : 'Mcdonnell, Marshall'
 }
 
 # Used to ensure a Git author does not appear in any of the DOIs.  This is NOT
@@ -172,6 +183,10 @@ _blacklist = [
     'Chris Kerr',
     'Thomas Brooks',
     'mantid-builder',
+    'Erik B Knudsen',
+    'Bartomeu Llopis',
+    'dpaj',
+    'Daniel Pajerowski',
 ]
 
 # The whitelist is used for sponsors / contributors who should be included,